Esempio n. 1
0
        public void Execute(IOrderable ord)
        {
            if (ord is IMobileSpaceObject sobj)
            {
                // error checking
                var errors = GetErrors(sobj);
                foreach (var error in errors)
                {
                    sobj.Owner.Log.Add(error);
                }

                // let only one colony ship from a fleet colonize
                if (sobj is Fleet f)
                {
                    sobj = f.LeafVehicles.FirstOrDefault(q => q.HasAbility(Planet.ColonizationAbilityName));
                }

                if (!errors.Any())
                {
                    // colonize now!!!
                    Planet.Colony = new Colony {
                        Owner = sobj.Owner
                    };
                    Owner.TriggerHappinessChange(hm => hm.PlanetColonized);
                    Planet.Colony.ConstructionQueue = new ConstructionQueue(Planet);
                    if (sobj is ICargoContainer cc)
                    {
                        foreach (var kvp in cc.Cargo.Population)
                        {
                            // place population on planet
                            Planet.AddPopulation(kvp.Key, kvp.Value);
                        }
                        foreach (var unit in cc.Cargo.Units)
                        {
                            // planet unit on planet
                            Planet.AddUnit(unit);
                        }
                    }

                    // ruins?
                    var ruinsTechs = Planet.GetAbilityValue("Ancient Ruins").ToInt();
                    for (int i = 0; i < ruinsTechs; i++)
                    {
                        var msg = "We have discovered new technology from the ancient ruins on " + Planet + ".";
                        // pick a random tech that's unlocked but not fully researched and level it up
                        var tech = Mod.Current.Technologies.Where(t => sobj.Owner.HasUnlocked(t) && sobj.Owner.ResearchedTechnologies[t] < t.MaximumLevel).PickRandom();
                        if (tech == null)
                        {
                            msg = "We have discovered ancient ruins on " + Planet + ", but there is nothing left for us to learn.";
                        }
                        else
                        {
                            var oldlvl   = sobj.Owner.ResearchedTechnologies[tech];
                            var newStuff = tech.GetExpectedResults(sobj.Owner);
                            sobj.Owner.ResearchedTechnologies[tech]++;
                            var newlvl   = sobj.Owner.ResearchedTechnologies[tech];
                            var progress = sobj.Owner.ResearchProgress.SingleOrDefault(p => p.Item == tech);
                            if (progress != null)
                            {
                                progress.Value = 0;
                            }
                            sobj.Owner.Log.Add(tech.CreateLogMessage("We have advanced from level " + oldlvl + " to level " + newlvl + " in " + tech + "!", LogMessageType.ResearchComplete));
                            foreach (var item in newStuff)
                            {
                                sobj.Owner.Log.Add(item.CreateLogMessage("We have unlocked a new " + item.ResearchGroup.ToLower() + ", the " + item + "!", LogMessageType.ResearchComplete));
                            }
                        }
                        if (i == 0)
                        {
                            sobj.Owner.Log.Add(Planet.CreateLogMessage(msg, LogMessageType.PlanetColonised));
                        }
                    }

                    // unique ruins?
                    foreach (var abil in Planet.Abilities().Where(a => a.Rule.Name == "Ancient Ruins Unique"))
                    {
                        if (sobj.Owner.UniqueTechsFound.Contains(abil.Value1))
                        {
                            sobj.Owner.Log.Add(Planet.CreateLogMessage("We have discovered \"unique\" technology from the ancient ruins on " + Planet + ", but it appears we have already found this one elsewhere. Perhaps it was not as unique as we had thought...", LogMessageType.ResearchComplete));
                        }
                        else
                        {
                            sobj.Owner.Log.Add(Planet.CreateLogMessage("We have discovered new unique technology from the ancient ruins on " + Planet + ".", LogMessageType.ResearchComplete));
                            sobj.Owner.UniqueTechsFound.Add(abil.Value1);
                            foreach (var tech in Mod.Current.Technologies.Where(t => t.UniqueTechID == abil.Value1 && sobj.Owner.HasUnlocked(t)))
                            {
                                sobj.Owner.Log.Add(tech.CreateLogMessage("We have unlocked a new " + tech.ResearchGroup.ToLower() + ", the " + tech + "!", LogMessageType.ResearchComplete));
                            }
                        }
                    }

                    // delete ruins and unique ruins abilities
                    foreach (var a in Planet.IntrinsicAbilities.Where(a => a.Rule.Name == "Ancient Ruins" || a.Rule.Name == "Ancient Ruins Unique").ToArray())
                    {
                        Planet.IntrinsicAbilities.Remove(a);
                    }

                    // log it!
                    sobj.Owner.Log.Add(Planet.CreateLogMessage(sobj + " has founded a new colony on " + Planet + ".", LogMessageType.PlanetColonised));

                    // update pursue/evade orders to target planet now instead of ship
                    foreach (var o in Galaxy.Current.Referrables.OfType <PursueOrder>().Where(q => q.Target == sobj))
                    {
                        if (o.Owner.CanSee(sobj) && o.Owner.CanSee(Planet))
                        {
                            o.Target = Planet;
                        }
                    }
                    foreach (var o in Galaxy.Current.Referrables.OfType <EvadeOrder>().Where(q => q.Target == sobj))
                    {
                        if (o.Owner.CanSee(sobj) && o.Owner.CanSee(Planet))
                        {
                            o.Target = Planet;
                        }
                    }

                    // bye bye colony ship
                    sobj.Dispose();
                }

                // either done colonizing, or we failed
                IsComplete = true;

                // spend time
                sobj.SpendTime(sobj.TimePerMove);
            }
            else
            {
                Owner.Log.Append(Owner.CreateLogMessage($"Could not assign a colonize order to ${ord} because it is not a mobile space object.", LogMessageType.Error));
            }
        }