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)); } }