private static void SpawnPawnQuality() { List <DebugMenuOption> list = new List <DebugMenuOption>(); foreach (PawnKindDef item in DefDatabase <PawnKindDef> .AllDefs.Where(x => x.GetModExtension <DefExtension_Hybrid>() != null || x.race.tradeTags?.Contains("AnimalGeneticMechanoid") == true).OrderBy((PawnKindDef kd) => kd.defName)) { PawnKindDef localKindDef = item; list.Add(new DebugMenuOption(localKindDef.defName, DebugMenuOptionMode.Tool, delegate { Faction faction = FactionUtility.DefaultFactionFrom(localKindDef.defaultFactionType); Pawn newPawn = PawnGenerator.GeneratePawn(localKindDef, faction); GenSpawn.Spawn(newPawn, UI.MouseCell(), Find.CurrentMap); CompHybrid compHybrid = newPawn.TryGetComp <CompHybrid>(); if (compHybrid != null) { compHybrid.quality = QualityUtility.GenerateQualityRandomEqualChance(); } if (faction != null && faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { lord = ((Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null)).GetLord(); } if (lord == null) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, Find.CurrentMap); } lord.AddPawn(newPawn); } })); } Find.WindowStack.Add(new Dialog_DebugOptionListLister(list)); }
public Job TryEquipFreeTool(Pawn pawn) { // find proper tools of the specific work type IEnumerable <Thing> availableTools = Find.ListerThings.AllThings.FindAll( tool => !tool.IsForbidden(pawn.Faction) && pawn.CanReserveAndReach(tool, PathEndMode.ClosestTouch, pawn.NormalMaxDanger())); if (availableTools.Any()) { // find closest reachable tool of the specific work type closestAvailableTool = GenClosest.ClosestThing_Global(pawn.Position, availableTools) as ThingWithComps; if (closestAvailableTool != null) { // if pawn has equipped weapon, put it in inventory if (pawn.equipment.Primary != null) { previousPawnWeapons.Add(pawn, pawn.equipment.Primary); ThingWithComps leftover; pawn.equipment.TryTransferEquipmentToContainer(pawn.equipment.Primary, pawn.inventory.container, out leftover); } // reserve and set as auto equipped pawn.Reserve(closestAvailableTool); closestAvailableTool.TryGetComp <CompTool>().wasAutoEquipped = true; return(new Job(JobDefOf.Equip, closestAvailableTool)); } } return(null); }
public static Pawn GetAnimal(Pawn pawn) { bool animalValidator(Thing animalThing) { if (!AnimalIsGood(animalThing as Pawn)) { return(false); } else if (!pawn.CanReserveAndReach(new LocalTargetInfo(animalThing), PathEndMode.ClosestTouch, Danger.None)) { PetThemAll.Debug($"cannot reserve and reach: {animalThing.ToStringSafe()}"); return(false); } else { return(true); } } var searchSet = ( from maybeAnimal in pawn.MapHeld.listerThings.ThingsMatching(ThingRequest.ForGroup(ThingRequestGroup.Pawn)) where maybeAnimal.Faction == pawn.Faction select maybeAnimal ); var thing = GenClosest.ClosestThing_Global(pawn.Position, searchSet, 30f, animalValidator); return(thing as Pawn); }
public override void CompTick() { base.CompTick(); if (!AlphaAnimalsEvents_Mod.settings.flagAlphaMechanoidsSappers) { if (parent.Map != null) { PawnGenerationRequest request = new PawnGenerationRequest(PawnKindDef.Named(Props.defToChangeTo), Find.FactionManager.FirstFactionOfDef(FactionDefOf.Mechanoid), PawnGenerationContext.NonPlayer, -1, false, false, false, false, true, false, 1f, false, true, true, false, false); Pawn pawn = PawnGenerator.GeneratePawn(request); GenSpawn.Spawn(pawn, this.parent.Position, parent.Map, WipeMode.Vanish); Lord lord = null; if (pawn.Map.mapPawns.SpawnedPawnsInFaction(Faction.OfMechanoids).Any((Pawn p) => p != pawn)) { lord = ((Pawn)GenClosest.ClosestThing_Global(pawn.Position, pawn.Map.mapPawns.SpawnedPawnsInFaction(Faction.OfMechanoids), 99999f, (Thing p) => p != pawn && ((Pawn)p).GetLord() != null, null)).GetLord(); } if (lord == null) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(pawn.Position, null, false, true); lord = LordMaker.MakeNewLord(Faction.OfMechanoids, lordJob, Find.CurrentMap, null); } lord.AddPawn(pawn); this.parent.Destroy(); } } }
public PawnSummoned SpawnPawn(SpawnThings spawnables, Faction faction) { var newPawn = (PawnSummoned)PawnGenerator.GeneratePawn(spawnables.kindDef, faction); newPawn.Spawner = Caster; newPawn.Temporary = spawnables.temporary; if (newPawn.Faction != Faction.OfPlayerSilentFail && this?.Caster?.Faction is Faction f) { newPawn.SetFaction(f); } GenSpawn.Spawn(newPawn, PositionHeld, Find.CurrentMap); if (faction != null && faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any(p => p != newPawn)) { Predicate <Thing> validator = p => p != newPawn && ((Pawn)p).GetLord() != null; var p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator); lord = p2.GetLord(); } if (lord == null) { var lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, Find.CurrentMap, null); } lord.AddPawn(newPawn); } return(newPawn); }
public static IEnumerable <Rule> ExtraRules(Pawn initiator, Pawn recipient) { string initPrefix = "INITIATOR_", reciPrefix = "RECIPIENT_"; foreach (var rule in ExtraRulesForPawn(initPrefix, initiator /*, person.firstSingular*/)) { yield return(rule); } foreach (var rule in ExtraRulesForPawn(reciPrefix, recipient /*, person.secondSingular*/)) { yield return(rule); } //clima yield return(new Rule_String("WEATHER", initiator.Map.weatherManager.CurWeatherPerceived.label)); //hora yield return(new Rule_String("HOUR", GenLocalDate.HourInteger(initiator).ToString())); yield return(new Rule_String("DAYPERIOD", DayPeriod(initiator))); //arte ou planta por perto foreach (var group in subjects) { var thing = GenClosest.ClosestThing_Global(initiator.Position, initiator.Map.listerThings.ThingsInGroup(group), lookRadius); if (thing != null) { yield return(new Rule_String($"NEAREST_{group.ToString().ToLower()}", $"{thing.def.label}")); } } }
public static TMPawnSummoned SpawnPawn(Pawn caster, SpawnThings spawnables, Faction faction, IntVec3 position, int duration) { TMPawnSummoned newPawn = (TMPawnSummoned)PawnGenerator.GeneratePawn(spawnables.kindDef, faction); newPawn.validSummoning = true; newPawn.Spawner = caster; newPawn.Temporary = spawnables.temporary; newPawn.TicksToDestroy = duration; //Faction val = default(Faction); //int num; //if (newPawn.Faction != Faction.OfPlayerSilentFail) //{ // Faction obj = null; // obj = ((caster != null) ? caster.Faction : null); // val = obj; // num = ((obj != null) ? 1 : 0); //} //else //{ // num = 0; //} //if (num != 0) //{ // newPawn.SetFaction(val, null); //} GenSpawn.Spawn(newPawn, position, Find.CurrentMap, 0); if (newPawn.Faction != null && newPawn.Faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { Predicate <Thing> validator = (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null; Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator, null); lord = p2.GetLord(); } bool flag4 = lord == null; if (flag4) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, newPawn.Map, null); } else { try { newPawn.mindState.duty = new PawnDuty(DutyDefOf.Defend); } catch { Log.Message("error attempting to assign a duty to summoned object"); } } lord.AddPawn(newPawn); } return(newPawn); }
public static Thing ClosestThingReachable2( IntVec3 root, Map map, ThingRequest thingReq, PathEndMode peMode, TraverseParms traverseParams, float maxDistance = 9999f, Predicate <Thing> validator = null, IEnumerable <Thing> customGlobalSearchSet = null, int searchRegionsMin = 0, int searchRegionsMax = -1, bool forceAllowGlobalSearch = false, RegionType traversableRegionTypes = RegionType.Set_Passable, bool ignoreEntirelyForbiddenRegions = false) { bool flag = searchRegionsMax < 0 || forceAllowGlobalSearch; if (!flag && customGlobalSearchSet != null) { Log.ErrorOnce("searchRegionsMax >= 0 && customGlobalSearchSet != null && !forceAllowGlobalSearch. customGlobalSearchSet will never be used.", 634984); } if (!flag && !thingReq.IsUndefined && !thingReq.CanBeFoundInRegion) { Log.ErrorOnce(string.Concat("ClosestThingReachable with thing request group ", thingReq.group, " and global search not allowed. This will never find anything because this group is never stored in regions. Either allow global search or don't call this method at all."), 518498981); } if (EarlyOutSearch(root, map, thingReq, customGlobalSearchSet, validator)) { return(null); } Thing thing = null; bool flag2 = false; if (!thingReq.IsUndefined && thingReq.CanBeFoundInRegion) { int num = (searchRegionsMax > 0) ? searchRegionsMax : 30; thing = GenClosest.RegionwiseBFSWorker(root, map, thingReq, peMode, traverseParams, validator, null, searchRegionsMin, num, maxDistance, out int regionsSeen, traversableRegionTypes, ignoreEntirelyForbiddenRegions); flag2 = (thing == null && regionsSeen < num); } if (thing == null && flag && !flag2) { if (traversableRegionTypes != RegionType.Set_Passable) { Log.ErrorOnce("ClosestThingReachable had to do a global search, but traversableRegionTypes is not set to passable only. It's not supported, because Reachability is based on passable regions only.", 14384767); } bool validator2(Thing t) { if (validator != null && !validator(t)) { return(false); } if (!map.reachability.CanReach(root, t, peMode, traverseParams)) { return(false); } return(true); } IEnumerable <Thing> searchSet = customGlobalSearchSet ?? map.listerThings.ThingsMatching(thingReq); thing = GenClosest.ClosestThing_Global(root, searchSet, maxDistance, validator2); } return(thing); }
public static bool ClosestThingReachable(ref Thing __result, IntVec3 root, Map map, ThingRequest thingReq, PathEndMode peMode, TraverseParms traverseParams, float maxDistance = 9999f, Predicate <Thing> validator = null, IEnumerable <Thing> customGlobalSearchSet = null, int searchRegionsMin = 0, int searchRegionsMax = -1, bool forceAllowGlobalSearch = false, RegionType traversableRegionTypes = RegionType.Set_Passable, bool ignoreEntirelyForbiddenRegions = false) { bool flag1 = searchRegionsMax < 0 | forceAllowGlobalSearch; if (!flag1 && customGlobalSearchSet != null) { Log.ErrorOnce("searchRegionsMax >= 0 && customGlobalSearchSet != null && !forceAllowGlobalSearch. customGlobalSearchSet will never be used.", 634984, false); } if (!flag1 && !thingReq.IsUndefined && !thingReq.CanBeFoundInRegion) { Log.ErrorOnce("ClosestThingReachable with thing request group " + thingReq.group + " and global search not allowed. This will never find anything because this group is never stored in regions. Either allow global search or don't call this method at all.", 518498981, false); __result = null; return(false); } if (EarlyOutSearch(root, map, thingReq, customGlobalSearchSet, validator)) { __result = null; return(false); } Thing thing = null; bool flag2 = false; if (!thingReq.IsUndefined && thingReq.CanBeFoundInRegion) { int maxRegions = searchRegionsMax > 0 ? searchRegionsMax : 30; int regionsSeen; thing = GenClosest.RegionwiseBFSWorker(root, map, thingReq, peMode, traverseParams, validator, null, searchRegionsMin, maxRegions, maxDistance, out regionsSeen, traversableRegionTypes, ignoreEntirelyForbiddenRegions); flag2 = thing == null && regionsSeen < maxRegions; } if (thing == null & flag1 && !flag2) { if (traversableRegionTypes != RegionType.Set_Passable) { Log.ErrorOnce("ClosestThingReachable had to do a global search, but traversableRegionTypes is not set to passable only. It's not supported, because Reachability is based on passable regions only.", 14384767, false); } // Predicate<Thing> validator1 = t => map.reachability.CanReach(root, t, peMode, traverseParams) && (validator == null || validator(t)); Predicate <Thing> validator1 = t => Reachability_Patch.CanReach2(map.reachability, root, t, peMode, traverseParams) && (validator == null || validator(t)); IEnumerable <Thing> things = customGlobalSearchSet ?? map.listerThings.ThingsMatching(thingReq); thing = GenClosest.ClosestThing_Global(root, things, maxDistance, validator1, null); } __result = thing; return(false); }
} //end FindClosestIngForBill public static Thing FindClosestIngToBillGiver(Bill theBill, IngredientCount curIng) { IBillGiver billGiver = theBill.billStack.billGiver; IThingHolder holder = billGiver as IThingHolder; Thing building = billGiver as Thing; ThingOwner vatStoredIngredients = holder?.GetDirectlyHeldThings(); if (billGiver == null || building == null || billGiver == null || vatStoredIngredients == null) { return(null); } int storedCount = vatStoredIngredients.FirstOrDefault(thing => thing.def == curIng.FixedIngredient)?.stackCount ?? 0; int countNeededFromRecipe = (int)(curIng.CountRequiredOfFor(curIng.FixedIngredient, theBill.recipe) * QEESettings.instance.organTotalResourcesFloat); int countNeededForCrafting = countNeededFromRecipe - storedCount; countNeededForCrafting = countNeededForCrafting < 0 ? 0 : countNeededForCrafting; //only check the map for Things if the vat still needs some of this ingredient if (countNeededForCrafting > 0) { //find the closest accessible Thing of that ThingDef on the map ThingRequest tRequest = ThingRequest.ForDef(curIng.FixedIngredient); IEnumerable <Thing> searchSet = billGiver.Map.listerThings.ThingsMatching(tRequest); Thing result = GenClosest.ClosestThing_Global(building.Position, searchSet, validator : delegate(Thing testThing) { if (testThing.def.defName != curIng.FixedIngredient.defName) { return(false); } if (testThing.IsForbidden(building.Faction)) { return(false); } return(true); }); //return the Thing, if we found one if (result != null) { //QEEMod.TryLog("Ingredient found: " + curIng.FixedIngredient.label + " | stackCount: " + result.stackCount + " | recipe: " // + countNeededFromRecipe); return(result); } } return(null); } //end function FindClosestIngToBillGiver
public void SingleSpawnLoop(SpawnThings spawnables, IntVec3 position, Map map) { bool flag = spawnables.def != null; if (flag) { Faction faction = Find.FactionManager.FirstFactionOfDef(FactionDef.Named("TM_ElementalFaction")); TMPawnSummoned newPawn = new TMPawnSummoned(); bool flag2 = spawnables.def.race != null; if (flag2) { bool flag3 = spawnables.kindDef == null; if (flag3) { Log.Error("Missing kinddef"); } else { newPawn = (TMPawnSummoned)PawnGenerator.GeneratePawn(spawnables.kindDef, faction); newPawn.validSummoning = true; //newPawn.Spawner = this.Caster; newPawn.Temporary = false; if (newPawn.Faction == null || !newPawn.Faction.HostileTo(Faction.OfPlayer)) { Log.Message("elemental faction was null or not hostile - fixing"); newPawn.SetFaction(faction, null); faction.TrySetRelationKind(Faction.OfPlayer, FactionRelationKind.Hostile, false, null); } GenSpawn.Spawn(newPawn, position, this.Map); if (newPawn.Faction != null && newPawn.Faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { Predicate <Thing> validator = (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null; Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator, null); lord = p2.GetLord(); } bool flag4 = lord == null; if (flag4) { LordJob_AssaultColony lordJob = new LordJob_AssaultColony(newPawn.Faction, false, false, false, true, false); lord = LordMaker.MakeNewLord(faction, lordJob, this.Map, null); } lord.AddPawn(newPawn); } } } else { Log.Message("Missing race"); } } }
private static void TryDistributeTo(Thing thing, Map map, List <Thing> containers, bool setForbidden) { Dictionary <Thing, List <IntVec3> > containerPlaces = new Dictionary <Thing, List <IntVec3> >(); for (int num = containers.Count - 1; num >= 0; num--) { var c = containers[num]; foreach (var pos in c.OccupiedRect().Cells) { bool canPlace = true; foreach (var t in pos.GetThingList(map)) { if (t != c && !(t is Filth)) { canPlace = false; break; } } if (canPlace) { if (containerPlaces.ContainsKey(c)) { containerPlaces[c].Add(pos); } else { containerPlaces[c] = new List <IntVec3> { pos }; } } } } if (containerPlaces != null && containerPlaces.Any()) { var container = (Building_Storage)GenClosest.ClosestThing_Global(thing.Position, containerPlaces.Keys, 9999f); if (container != null && containerPlaces.TryGetValue(container, out var positions)) { var choosenPos = positions.RandomElement(); containerPlaces[container].Remove(choosenPos); thing.Position = choosenPos; if (setForbidden) { thing.SetForbidden(true); } if (!containerPlaces[container].Any()) { containerPlaces.Remove(container); } } } }
public void SingleSpawnLoop(SpawnThings spawnables, IntVec3 position, Map map) { Log.Message("single spawn loop start"); bool flag = spawnables.def != null; if (flag) { Faction faction = Faction.OfPlayer; bool flag2 = spawnables.def.race != null; if (flag2) { bool flag3 = spawnables.kindDef == null; if (flag3) { Log.Error("Missing kinddef"); } else { PawnSummoned newPawn = (PawnSummoned)PawnGenerator.GeneratePawn(spawnables.kindDef, faction); newPawn.Spawner = this.CasterPawn; newPawn.Temporary = false; if (newPawn.Faction != Faction.OfPlayerSilentFail) { Log.Message("Failing check for newpawn faction: " + newPawn.Faction); newPawn.SetFaction(this.CasterPawn.Faction, null); } Log.Message("attempting to spawn " + newPawn.def.defName + " of " + newPawn.kindDef.defName + " of faction " + newPawn.Faction); GenSpawn.Spawn(newPawn, position, Find.VisibleMap); if (newPawn.Faction != null && newPawn.Faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { Predicate <Thing> validator = (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null; Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator, null); lord = p2.GetLord(); } bool flag4 = lord == null; if (flag4) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, Find.VisibleMap, null); } lord.AddPawn(newPawn); } } } else { Log.Message("Missing race"); } } }
private static void CallDeepstrikeOf() { List <DebugMenuOption> list = new List <DebugMenuOption>(); foreach (PawnKindDef localKindDef2 in from f in DefDatabase <PawnKindDef> .AllDefs // where f.RoyalTitlesAwardableInSeniorityOrderForReading.Count > 0 orderby f.defName select f) { PawnKindDef localKindDef = localKindDef2; /* * if (!localKindDef.HasModExtension<DeepStrikeExtension>()) * { * continue; * } */ list.Add(new DebugMenuOption(localKindDef.defName, DebugMenuOptionMode.Tool, delegate() { List <FloatMenuOption> list2 = new List <FloatMenuOption>(); IntVec3 cell = UI.MouseCell(); for (int i = 0; i < 6; i++) { DeepStrikeType strikeType = (DeepStrikeType)i; list2.Add(new FloatMenuOption(DeepStrikeUtility.DeepstrikeArrivalmode(strikeType) + " - ", delegate() { Faction faction = FactionUtility.DefaultFactionFrom(localKindDef.defaultFactionType); Pawn newPawn = PawnGenerator.GeneratePawn(localKindDef, faction); DeepStrikeUtility.DropThingsNear(cell, Find.CurrentMap, Gen.YieldSingle <Thing>(newPawn), 110, false, false, true, strikeType); if (faction != null && faction != Faction.OfPlayer) { Lord lord = null; if (Find.CurrentMap.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { lord = ((Pawn)GenClosest.ClosestThing_Global(cell, Find.CurrentMap.mapPawns.SpawnedPawnsInFaction(faction), 99999f, (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null, null)).GetLord(); } if (lord == null) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(cell, null, false, true); lord = LordMaker.MakeNewLord(faction, lordJob, Find.CurrentMap, null); } lord.AddPawn(newPawn); } }, MenuOptionPriority.Default, null, null, 0f, null, null)); } Find.WindowStack.Add(new FloatMenu(list2)); })); } Find.WindowStack.Add(new Dialog_DebugOptionListLister(list)); }
public static IEnumerable <Rule> ExtraRules() { Pawn initiator = DialogManager.Initiator; if (initiator == null) { yield break; } //pawn parameters if (PawnCheck()) { Pawn recipient = DialogManager.Recipient; string initPrefix = "INITIATOR_", reciPrefix = "RECIPIENT_"; foreach (var rule in ExtraRulesForPawn(initPrefix, initiator, recipient)) { yield return(rule); } foreach (var rule in ExtraRulesForPawn(reciPrefix, recipient, initiator)) { yield return(rule); } } //climate yield return(new Rule_String("WEATHER", initiator.Map.weatherManager.CurWeatherPerceived.label)); //time yield return(new Rule_String("HOUR", GenLocalDate.HourInteger(initiator).ToString())); yield return(new Rule_String("DAYPERIOD", DayPeriod(initiator))); //temperature yield return(new Rule_String("TEMPERATURE", GenTemperature.GetTemperatureForCell(initiator.Position, initiator.Map).ToString())); //outdoor? yield return(new Rule_String("OUTDOORS", initiator.Position.UsesOutdoorTemperature(initiator.Map).ToStringYesNo())); //nearest things foreach (var group in subjects) { var thing = GenClosest.ClosestThing_Global(initiator.Position, initiator.Map.listerThings.ThingsInGroup(group), lookRadius); if (thing != null) { yield return(new Rule_String($"NEAREST_{group.ToString().ToLower()}", $"{thing.def.label}")); } } }
public override void CompTick() { base.CompTick(); if (parent.DestroyedOrNull() || !parent.Spawned || (parent as Pawn).Dead) { return; } if ((GenTicks.TicksAbs + frameskip_offset) % frameskip != 0) { return; } if (fullness == 0) { return; } var battery = GenClosest.ClosestThing_Global( center: parent.Position, searchSet: parent.Map.listerThings.ThingsMatching(ThingRequest.ForDef(ThingDefOf.Battery)), maxDistance: 2f + 5f * fullness, validator: t => !t.Destroyed); if (battery != null) { battery.TryGetComp <CompPowerBattery>()?.AddEnergy(fullness * ResourceAmount * GatherResourcesIntervalDays); SoundDef.Named("PowerOnSmall").PlayOneShot(new TargetInfo(parent.Position, parent.Map, false)); var loc = parent.Position.ToVector3Shifted(); MoteMaker.ThrowLightningGlow(loc, parent.Map, 0.5f + fullness); if (fullness > 0.3) { MoteMaker.ThrowMicroSparks(loc, parent.Map); } fullness = 0; (parent as RimStarvePawn)?.UpdateActiveGraphic(); } if (Fullness == 1f && Rand.Chance(0.01f) && weathers.Contains(parent.Map.weatherManager.curWeather)) { new WeatherEvent_LightningStrike(parent.Map, parent.Position).FireEvent(); fullness = 0; (parent as RimStarvePawn)?.UpdateActiveGraphic(); } }
public Lord GetLord(Pawn forPawn) { Lord lord = null; Faction faction = forPawn.Faction; if (forPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != forPawn)) { Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(forPawn.Position, forPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), SpawnerProps.lordJoinRadius, (Thing p) => p != forPawn && ((Pawn)p).GetLord() != null, null); lord = p2.GetLord(); } if (lord == null) { LordJob lordJob = SpawnerProps.CreateJobForLord(forPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, Map, null); } return(lord); }
public static void TargetFinderPostfix(ref Thing __result, Thing searcher, float maxDist) { Pawn pawn = searcher as Pawn; if (!(pawn?.equipment?.Primary?.def?.Equals(obj: ThingDef.Named(defName: "Healing_Gun")) ?? false)) { return; } IEnumerable <Pawn> pawns = searcher.Map.mapPawns.AllPawnsSpawned.Where(predicate: p => !p.Dead && !p.Faction.HostileTo(other: pawn.Faction) && p != searcher && GenSight.LineOfSight(start: searcher.Position, end: p.Position, map: searcher.Map) && p.health.hediffSet.GetHediffs <Hediff_Injury>().Any(predicate: h => h.CanHealNaturally() && !h.IsPermanent())).ToArray(); __result = ((GenClosest.ClosestThing_Global(center: searcher.Position, searchSet: pawns.Where(predicate: p => p.RaceProps.Humanlike && p.Faction == searcher.Faction), maxDistance: maxDist) ?? GenClosest.ClosestThing_Global(center: searcher.Position, searchSet: pawns.Where(predicate: p => p.Faction == searcher.Faction), maxDistance: maxDist)) ?? GenClosest.ClosestThing_Global(center: searcher.Position, searchSet: pawns.Where(predicate: p => p.RaceProps.Humanlike), maxDistance: maxDist)) ?? GenClosest.ClosestThing_Global(center: searcher.Position, searchSet: pawns, maxDistance: maxDist); }
public override void Place(Map map, IntVec3 position, TerrainDef rockDef) { base.Place(map, position, rockDef); if (this.place is TerrainDef) { if (this.proximitySpacing != 0) { Log.ErrorOnce("Proximity spacing used for road terrain placement; not yet supported", 60936625); } TerrainDef terrainDef = map.terrainGrid.TerrainAt(position); if (terrainDef.HasTag("Road") && !terrainDef.Removable) { map.terrainGrid.SetTerrain(position, TerrainDefOf.Gravel); } TerrainDef terrainDef2 = this.place as TerrainDef; if (terrainDef2 == TerrainDefOf.FlagstoneSandstone) { terrainDef2 = rockDef; } map.terrainGrid.SetTerrain(position, terrainDef2); if (position.OnEdge(map)) { map.roadInfo.roadEdgeTiles.Add(position); } } else if (this.place is ThingDef) { if (this.proximitySpacing > 0 && GenClosest.ClosestThing_Global(position, map.listerThings.ThingsOfDef(this.place as ThingDef), (float)this.proximitySpacing, null, null) != null) { return; } while (position.GetThingList(map).Count > 0) { position.GetThingList(map)[0].Destroy(DestroyMode.Vanish); } RoadDefGenStep_DryWithFallback.PlaceWorker(map, position, TerrainDefOf.Gravel); GenSpawn.Spawn(ThingMaker.MakeThing(this.place as ThingDef, null), position, map); } else { Log.ErrorOnce(string.Format("Can't figure out how to place object {0} while building road", this.place), 10785584); } }
public static void AddHumanlikeOrdersPostfix(Vector3 clickPos, Pawn pawn, ref List <FloatMenuOption> opts) { foreach (LocalTargetInfo localTargetInfo in GenUI.TargetsAt(clickPos, TargetingParameters.ForRescue(pawn), true)) { Pawn target = (Pawn)localTargetInfo.Thing; if (target.Faction == PurpleIvyData.AlienFaction && target.Downed && ReservationUtility.CanReserveAndReach(pawn, target, PathEndMode.OnCell, Danger.Deadly, 1, -1, null, true)) { var containers = target.Map.listerBuildings.AllBuildingsColonistOfClass <Building_СontainmentBreach>().Where(x => x.maxNumAliens > x.innerContainer.Count); var containmentBreach = (Building_СontainmentBreach)GenClosest.ClosestThing_Global (target.Position, containers, 9999f); if (containmentBreach != null) { JobDef jobDef = PurpleIvyDefOf.PI_TakeAlienToContainmentBreach; Action action = delegate() { Job job = JobMaker.MakeJob(jobDef, target, containmentBreach); job.count = 1; pawn.jobs.TryTakeOrderedJob(job, 0); }; string text = TranslatorFormattedStringExtensions.Translate("TakeAlienToContainmentBreach", target.LabelCap, target); FloatMenuOption opt = new FloatMenuOption (text, action, MenuOptionPriority.RescueOrCapture, null, target, 0f, null, null); if (opts.Where(x => x.Label == text).Count() == 0) { opts.Add(opt); } } else { string text = "NoContainersToTake".Translate(); if (opts.Where(x => x.Label == text).Count() == 0) { opts.Add(new FloatMenuOption(text, null, MenuOptionPriority.Default, null, null, 0f, null, null)); } } } } }
public override void TickRare() { if (Spawned) { ticksLeft--; if (!triggered) { if (ticksLeft < 0) { ticksLeft = (int)Math.Abs(Rand.Gaussian(0, referenceTimeoutAfterTriggered)); triggered = true; Debug.Log("Battle", "Auto triggered raid at {0}, {1} of value {2} after {3} long ticks (approximately max speed seconds)", base.Position.x, base.Position.z, value, ticksLeft); } List <Thing> searchSet = PawnsFinder.AllMaps_FreeColonistsSpawned.ToList().ConvertAll(pawn => (Thing)pawn); Thing thing = GenClosest.ClosestThing_Global(base.Position, searchSet, 10.0f); if (thing != null) { ticksLeft = (int)Math.Abs(Rand.Gaussian(0, 200)); triggered = true; Debug.Log("Battle", "Triggered raid at {0}, {1} of value {2} after {3} long ticks (approximately max speed seconds)", base.Position.x, base.Position.z, value, ticksLeft); } } else { if (ticksLeft < 0) { IncidentDef incidentDef = IncidentDefOf.RaidEnemy; IncidentParms parms = new IncidentParms { faction = faction, points = value, target = base.Map }; incidentDef.Worker.TryExecute(parms); Destroy(); } } } }
public void SpawnPawn(SpawnThings spawnables, Faction faction) { Pawn newPawn = PawnGenerator.GeneratePawn(spawnables.kindDef, faction); GenSpawn.Spawn(newPawn, this.PositionHeld, Find.VisibleMap); if (faction != null && faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { Predicate <Thing> validator = (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null; Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator); lord = p2.GetLord(); } if (lord == null) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, Find.VisibleMap, null); } lord.AddPawn(newPawn); } }
public void Mutate() { mutationActive = true; this.Severity = 1f; foreach (var tool in pawn.Tools) { if (tool.power > 0) { tool.power *= 1.25f; } } if (this.pawn.Faction != PurpleIvyData.AlienFaction) { this.pawn.SetFaction(PurpleIvyData.AlienFaction); } this.pawn.RaceProps.thinkTreeMain = PurpleIvyDefOf.PI_HumanlikeMutant; Lord lord = null; if (this.pawn.Map.mapPawns.SpawnedPawnsInFaction(pawn.Faction).Any((Pawn p) => p != this.pawn)) { lord = ((Pawn)GenClosest.ClosestThing_Global(this.pawn.Position, this.pawn.Map.mapPawns.SpawnedPawnsInFaction(this.pawn.Faction), 99999f, (Thing p) => p != this.pawn && ((Pawn)p).GetLord() != null, null)).GetLord(); } if (lord == null) { var lordJob = new LordJob_AssaultColony(this.pawn.Faction); lord = LordMaker.MakeNewLord(this.pawn.Faction, lordJob, this.pawn.Map, null); } if (!lord.ownedPawns.Contains(this.pawn)) { lord.AddPawn(this.pawn); } }
public void SingleSpawnLoop(SpawnThings spawnables, IntVec3 position, Map map) { bool flag = spawnables.def != null; if (flag) { Faction faction = this.sustainerPawn.Faction; bool flag2 = spawnables.def.race != null; if (flag2) { bool flag3 = spawnables.kindDef == null; if (flag3) { Log.Error("Missing kinddef"); } else { newPawn = (TMPawnSummoned)PawnGenerator.GeneratePawn(spawnables.kindDef, faction); newPawn.validSummoning = true; newPawn.Temporary = false; //if (newPawn.Faction != Faction.OfPlayerSilentFail) //{ // newPawn.SetFaction(this.Caster.Faction, null); //} try { GenSpawn.Spawn(newPawn, position, map, Rot4.North, WipeMode.Vanish, false); //GenPlace.TryPlaceThing(newPawn, position, map, ThingPlaceMode.Near, null, null); CompSentinel compSentinel = newPawn.TryGetComp <CompSentinel>(); compSentinel.target = this.hostilePawn; compSentinel.sentinelLoc = position; compSentinel.rotation = this.Rotation; compSentinel.sustainerPawn = this.sustainerPawn; } catch { Log.Message("TM_Exception".Translate( "sentinel building", this.def.defName )); this.Destroy(DestroyMode.Vanish); } if (newPawn.Faction != null && newPawn.Faction != Faction.OfPlayer) { try { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { Predicate <Thing> validator = (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null; Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator, null); lord = p2.GetLord(); } bool flag4 = lord == null; if (flag4) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, map, null); } lord.AddPawn(newPawn); } catch (NullReferenceException ex) { // } } } } else { Log.Message("Missing race"); } } }
// Method from RimWorld.JobGiver_Work.TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) // I modified the line if (!workGiver.ShouldSkip(pawn)) #pragma warning disable public ThinkResult TryIssueJobPackageDrone(Pawn pawn, bool emergency) { List <WorkGiver> list = emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; int num = -999; TargetInfo targetInfo = TargetInfo.Invalid; WorkGiver_Scanner workGiver_Scanner = null; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && targetInfo.IsValid) { break; } if (!workGiver.ShouldSkip(pawn)) { try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, null, new JobTag?(list[j].def.tagToGive), false)); } WorkGiver_Scanner scanner = workGiver as WorkGiver_Scanner; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> predicate = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t, false); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable2; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; IEnumerable <Thing> searchSet = enumerable2; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global_Reachable(position, map, searchSet, pathEndMode, traverseParams, 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } IntVec3 position = pawn.Position; IEnumerable <Thing> searchSet = enumerable3; Predicate <Thing> validator = predicate; thing = GenClosest.ClosestThing_Global(position, searchSet, 99999f, validator, null); } else { IntVec3 position = pawn.Position; Map map = pawn.Map; ThingRequest potentialWorkThingRequest = scanner.PotentialWorkThingRequest; PathEndMode pathEndMode = scanner.PathEndMode; TraverseParms traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn), TraverseMode.ByPawn, false); Predicate <Thing> validator = predicate; bool forceGlobalSearch = enumerable != null; thing = GenClosest.ClosestThingReachable(position, map, potentialWorkThingRequest, pathEndMode, traverseParams, 9999f, validator, enumerable, 0, scanner.LocalRegionsToScanFirst, forceGlobalSearch, RegionType.Set_Passable, false); } if (thing != null) { targetInfo = thing; workGiver_Scanner = scanner; } } if (scanner.def.scanCells) { IntVec3 position2 = pawn.Position; float num2 = 99999f; float num3 = float.MinValue; bool prioritized = scanner.Prioritized; bool allowUnreachable = scanner.AllowUnreachable; Danger maxDanger = scanner.MaxPathDanger(pawn); foreach (IntVec3 intVec in scanner.PotentialWorkCellsGlobal(pawn)) { bool flag = false; float num4 = (float)(intVec - position2).LengthHorizontalSquared; float num5 = 0f; if (prioritized) { if (scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > num3 || (num5 == num3 && num4 < num2)) { flag = true; } } } else if (num4 < num2 && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger, false, TraverseMode.ByPawn)) { continue; } flag = true; } if (flag) { targetInfo = new TargetInfo(intVec, pawn.Map, false); workGiver_Scanner = scanner; num2 = num4; num3 = num5; } } } } } catch (Exception ex) { Log.Error(string.Concat(new object[] { pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString() })); } finally { } if (targetInfo.IsValid) { pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (targetInfo.HasThing) { job3 = workGiver_Scanner.JobOnThing(pawn, targetInfo.Thing, false); } else { job3 = workGiver_Scanner.JobOnCell(pawn, targetInfo.Cell); } if (job3 != null) { return(new ThinkResult(job3, null, new JobTag?(list[j].def.tagToGive), false)); } Log.ErrorOnce(string.Concat(new object[] { workGiver_Scanner, " provided target ", targetInfo, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized." }), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }
public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, Verb verb, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true) { Thing searcherThing = searcher.Thing; Pawn searcherPawn = searcher as Pawn; if (verb == null) { Log.Error("BestAttackTarget with " + searcher.ToStringSafe <IAttackTargetSearcher>() + " who has no attack verb.", false); return(null); } bool onlyTargetMachines = verb.IsEMP(); float minDistSquared = minDist * minDist; float num = maxTravelRadiusFromLocus + verb.verbProps.range; float maxLocusDistSquared = num * num; Func <IntVec3, bool> losValidator = null; if ((byte)(flags & TargetScanFlags.LOSBlockableByGas) != 0) { losValidator = delegate(IntVec3 vec3) { Gas gas = vec3.GetGas(searcherThing.Map); return(gas == null || !gas.def.gas.blockTurretTracking); }; } Predicate <IAttackTarget> innerValidator = delegate(IAttackTarget t) { Thing thing = t.Thing; if (t == searcher) { return(false); } if (minDistSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistSquared) { return(false); } if (!canTakeTargetsCloserThanEffectiveMinRange) { float num2 = verb.verbProps.EffectiveMinRange(thing, searcherThing); if (num2 > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < num2 * num2) { return(false); } } if (maxTravelRadiusFromLocus < 9999f && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared) { return(false); } if (!searcherThing.HostileTo(thing)) { return(false); } if (validator != null && !validator(thing)) { return(false); } if (searcherPawn != null) { Lord lord = searcherPawn.GetLord(); if (lord != null && !lord.LordJob.ValidateAttackTarget(searcherPawn, thing)) { return(false); } } if ((byte)(flags & TargetScanFlags.NeedLOSToAll) != 0 && !searcherThing.CanSee(thing, losValidator)) { if (t is Pawn) { if ((byte)(flags & TargetScanFlags.NeedLOSToPawns) != 0) { return(false); } } else if ((byte)(flags & TargetScanFlags.NeedLOSToNonPawns) != 0) { return(false); } } if ((byte)(flags & TargetScanFlags.NeedThreat) != 0 && t.ThreatDisabled(searcher)) { return(false); } if (onlyTargetMachines && t is Pawn pawn && pawn.RaceProps.IsFlesh) { return(false); } if ((byte)(flags & TargetScanFlags.NeedNonBurning) != 0 && thing.IsBurning()) { return(false); } if (searcherThing.def.race != null && searcherThing.def.race.intelligence >= Intelligence.Humanlike) { CompExplosive compExplosive = thing.TryGetComp <CompExplosive>(); if (compExplosive != null && compExplosive.wickStarted) { return(false); } } if (thing.def.size.x == 1 && thing.def.size.z == 1) { if (thing.Position.Fogged(thing.Map)) { return(false); } } else { bool flag2 = false; foreach (IntVec3 cellRect in thing.OccupiedRect()) { if (cellRect.Fogged(thing.Map)) { flag2 = true; break; } } if (!flag2) { return(false); } } return(true); }; if (PCF_AttackTargetFinder.HasRangedAttack(searcher, verb)) { PCF_AttackTargetFinder.tmpTargets.Clear(); PCF_AttackTargetFinder.tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher)); if ((byte)(flags & TargetScanFlags.NeedReachable) != 0) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && PCF_AttackTargetFinder.CanReach(searcherThing, t.Thing, canBash)); } bool flag = false; for (int i = 0; i < PCF_AttackTargetFinder.tmpTargets.Count; i++) { IAttackTarget attackTarget = PCF_AttackTargetFinder.tmpTargets[i]; if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && PCF_AttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb)) { flag = true; break; } } IAttackTarget result; if (flag) { PCF_AttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x)); result = PCF_AttackTargetFinder.GetRandomShootingTargetByScore(PCF_AttackTargetFinder.tmpTargets, searcher, verb); } else { Predicate <Thing> validator2; if ((byte)(flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != 0 && (byte)(flags & TargetScanFlags.NeedReachable) == 0) { validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && (PCF_AttackTargetFinder.CanReach(searcherThing, t, canBash) || PCF_AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb))); } else { validator2 = ((Thing t) => innerValidator((IAttackTarget)t)); } result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, PCF_AttackTargetFinder.tmpTargets, maxDist, validator2, null); } PCF_AttackTargetFinder.tmpTargets.Clear(); return(result); } if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0f && !searcherPawn.InMentalState) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius)); } IntVec3 position = searcherThing.Position; Map map = searcherThing.Map; ThingRequest thingReq = ThingRequest.ForGroup(ThingRequestGroup.AttackTarget); PathEndMode peMode = PathEndMode.Touch; Pawn searcherPawn2 = searcherPawn; Danger maxDanger = Danger.Deadly; bool canBash2 = canBash; TraverseParms traverseParams = TraverseParms.For(searcherPawn2, maxDanger, TraverseMode.ByPawn, canBash2); float maxDist2 = maxDist; bool validator3(Thing x) => innerValidator((IAttackTarget)x); int searchRegionsMax = (maxDist <= 800f) ? 40 : -1; IAttackTarget attackTarget2 = (IAttackTarget)GenClosest.ClosestThingReachable(position, map, thingReq, peMode, traverseParams, maxDist2, validator3, null, 0, searchRegionsMax, false, RegionType.Set_Passable, false); if (attackTarget2 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn)) { IAttackTarget attackTarget3 = PCF_AttackTargetFinder.FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash); if (attackTarget3 != null) { float lengthHorizontal = (searcherPawn.Position - attackTarget2.Thing.Position).LengthHorizontal; float lengthHorizontal2 = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal; if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50f) { attackTarget2 = attackTarget3; } } } return(attackTarget2); }
public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = float.MaxValue, bool canBash = false, bool canTakeTargetsCloserThanEffectiveMinRange = true) { Thing searcherThing = searcher.Thing; Pawn searcherPawn = searcher as Pawn; Verb verb = searcher.CurrentEffectiveVerb; if (verb == null) { Log.Error("BestAttackTarget with " + searcher.ToStringSafe() + " who has no attack verb."); return(null); } bool onlyTargetMachines = verb.IsEMP(); float minDistSquared = minDist * minDist; float num = maxTravelRadiusFromLocus + verb.verbProps.range; float maxLocusDistSquared = num * num; Func <IntVec3, bool> losValidator = null; if ((flags & TargetScanFlags.LOSBlockableByGas) != 0) { losValidator = delegate(IntVec3 vec3) { Gas gas = vec3.GetGas(searcherThing.Map); return(gas == null || !gas.def.gas.blockTurretTracking); }; } Predicate <IAttackTarget> innerValidator = delegate(IAttackTarget t) { Thing thing = t.Thing; if (t == searcher) { return(false); } if (minDistSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistSquared) { return(false); } if (!canTakeTargetsCloserThanEffectiveMinRange) { float num2 = verb.verbProps.EffectiveMinRange(thing, searcherThing); if (num2 > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < num2 * num2) { return(false); } } if (maxTravelRadiusFromLocus < 9999f && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared) { return(false); } if (!searcherThing.HostileTo(thing)) { return(false); } if (validator != null && !validator(thing)) { return(false); } if (searcherPawn != null) { Lord lord = searcherPawn.GetLord(); if (lord != null && !lord.LordJob.ValidateAttackTarget(searcherPawn, thing)) { return(false); } } if ((flags & TargetScanFlags.NeedLOSToAll) != 0) { if (losValidator != null && (!losValidator(searcherThing.Position) || !losValidator(thing.Position))) { return(false); } if (!searcherThing.CanSee(thing, losValidator)) { if (t is Pawn) { if ((flags & TargetScanFlags.NeedLOSToPawns) != 0) { return(false); } } else if ((flags & TargetScanFlags.NeedLOSToNonPawns) != 0) { return(false); } } } if (((flags & TargetScanFlags.NeedThreat) != 0 || (flags & TargetScanFlags.NeedAutoTargetable) != 0) && t.ThreatDisabled(searcher)) { return(false); } if ((flags & TargetScanFlags.NeedAutoTargetable) != 0 && !IsAutoTargetable(t)) { return(false); } if ((flags & TargetScanFlags.NeedActiveThreat) != 0 && !GenHostility.IsActiveThreatTo(t, searcher.Thing.Faction)) { return(false); } Pawn pawn = t as Pawn; if (onlyTargetMachines && pawn != null && pawn.RaceProps.IsFlesh) { return(false); } if ((flags & TargetScanFlags.NeedNonBurning) != 0 && thing.IsBurning()) { return(false); } if (searcherThing.def.race != null && (int)searcherThing.def.race.intelligence >= 2) { CompExplosive compExplosive = thing.TryGetComp <CompExplosive>(); if (compExplosive != null && compExplosive.wickStarted) { return(false); } } if (thing.def.size.x == 1 && thing.def.size.z == 1) { if (thing.Position.Fogged(thing.Map)) { return(false); } } else { bool flag2 = false; foreach (IntVec3 item in thing.OccupiedRect()) { if (!item.Fogged(thing.Map)) { flag2 = true; break; } } if (!flag2) { return(false); } } return(true); }; if (HasRangedAttack(searcher) && (searcherPawn == null || !searcherPawn.InAggroMentalState)) { tmpTargets.Clear(); tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher)); if ((flags & TargetScanFlags.NeedReachable) != 0) { Predicate <IAttackTarget> oldValidator2 = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator2(t) && CanReach(searcherThing, t.Thing, canBash)); } bool flag = false; for (int i = 0; i < tmpTargets.Count; i++) { IAttackTarget attackTarget = tmpTargets[i]; if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && CanShootAtFromCurrentPosition(attackTarget, searcher, verb)) { flag = true; break; } } IAttackTarget result; if (flag) { tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x)); result = GetRandomShootingTargetByScore(tmpTargets, searcher, verb); } else { result = (IAttackTarget)GenClosest.ClosestThing_Global(validator: ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) == 0 || (flags & TargetScanFlags.NeedReachable) != 0) ? ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t))) : ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t) && (CanReach(searcherThing, t, canBash) || CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)))), center: searcherThing.Position, searchSet: tmpTargets, maxDistance: maxDist); } tmpTargets.Clear(); return(result); } if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0f && !searcherPawn.InMentalState) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = delegate(IAttackTarget t) { if (!oldValidator(t)) { return(false); } return(t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius) ? true : false); }; } IAttackTarget attackTarget2 = (IAttackTarget)GenClosest.ClosestThingReachable(searcherThing.Position, searcherThing.Map, ThingRequest.ForGroup(ThingRequestGroup.AttackTarget), PathEndMode.Touch, TraverseParms.For(searcherPawn, Danger.Deadly, TraverseMode.ByPawn, canBash), maxDist, (Thing x) => innerValidator((IAttackTarget)x), null, 0, (maxDist > 800f) ? (-1) : 40); if (attackTarget2 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn)) { IAttackTarget attackTarget3 = FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash); if (attackTarget3 != null) { float lengthHorizontal = (searcherPawn.Position - attackTarget2.Thing.Position).LengthHorizontal; float lengthHorizontal2 = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal; if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50f) { attackTarget2 = attackTarget3; } } } return(attackTarget2); }
public void SingleSpawnLoop(SpawnThings spawnables, IntVec3 position, Map map) { bool flag = spawnables.def != null; if (flag) { Faction faction = pawn.Faction; bool flag2 = spawnables.def.race != null; if (flag2) { bool flag3 = spawnables.kindDef == null; if (flag3) { Log.Error("Missing kinddef"); } else { newPawn = (TMPawnSummoned)PawnGenerator.GeneratePawn(spawnables.kindDef, faction); newPawn.Spawner = this.Caster; newPawn.Temporary = true; newPawn.TicksToDestroy = this.duration; //if (newPawn.Faction != Faction.OfPlayerSilentFail) //{ // newPawn.SetFaction(this.Caster.Faction, null); //} //newPawn.playerSettings.master = this.Caster; if (comp.summonedMinions.Count >= 4) { Thing dismissMinion = comp.summonedMinions[0]; if (dismissMinion != null && dismissMinion.Position.IsValid) { MoteMaker.ThrowSmoke(dismissMinion.Position.ToVector3(), base.Map, 1); MoteMaker.ThrowHeatGlow(dismissMinion.Position, base.Map, 1); } comp.summonedMinions.Remove(comp.summonedMinions[0]); if (!dismissMinion.Destroyed) { dismissMinion.Destroy(); Messages.Message("TM_SummonedCreatureLimitExceeded".Translate(new object[] { this.launcher.LabelShort }), MessageTypeDefOf.NeutralEvent); } if (comp.summonedMinions.Count > 4) { while (comp.summonedMinions.Count > 4) { Pawn excessMinion = comp.summonedMinions[comp.summonedMinions.Count - 1] as Pawn; comp.summonedMinions.Remove(excessMinion); if (excessMinion != null && !excessMinion.Dead && !excessMinion.Destroyed) { excessMinion.Destroy(); } } } } try { GenSpawn.Spawn(newPawn, position, this.Map); } catch { this.age = this.duration; comp.Mana.CurLevel += comp.ActualManaCost(TorannMagicDefOf.TM_SummonMinion); Log.Message("TM_Exception".Translate(new object[] { pawn.LabelShort, this.def.defName })); this.Destroy(DestroyMode.Vanish); } comp.summonedMinions.Add(newPawn); if (newPawn.Faction != null && newPawn.Faction != Faction.OfPlayer) { Lord lord = null; if (newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction).Any((Pawn p) => p != newPawn)) { Predicate <Thing> validator = (Thing p) => p != newPawn && ((Pawn)p).GetLord() != null; Pawn p2 = (Pawn)GenClosest.ClosestThing_Global(newPawn.Position, newPawn.Map.mapPawns.SpawnedPawnsInFaction(faction), 99999f, validator, null); lord = p2.GetLord(); } bool flag4 = lord == null; if (flag4) { LordJob_DefendPoint lordJob = new LordJob_DefendPoint(newPawn.Position); lord = LordMaker.MakeNewLord(faction, lordJob, this.Map, null); } lord.AddPawn(newPawn); } } } else { Log.Message("Missing race"); } } }
public override ThinkResult TryIssueJobPackage(Pawn pawn, JobIssueParams jobParams) { X2_AIRobot robot = pawn as X2_AIRobot; if (robot == null || !robot.Spawned || robot.Destroyed || robot.GetWorkGivers(false) == null) { return(ThinkResult.NoJob); } //Profiler.BeginSample("JobGiver_Work"); //if (emergency && pawn.mindState.priorityWork.IsPrioritized) //{ // List<WorkGiverDef> workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; // for (int i = 0; i < workGiversByPriority.Count; i++) // { // WorkGiver worker = workGiversByPriority[i].Worker; // if (WorkGiversRelated(pawn.mindState.priorityWork.WorkGiver, worker.def)) // { // Job job = GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); // if (job != null) // { // job.playerForced = true; // return new ThinkResult(job, this, workGiversByPriority[i].tagToGive); // } // } // } // pawn.mindState.priorityWork.Clear(); //} List <WorkGiver> list = robot.GetWorkGivers(false); // Get Non-Emergency WorkGivers int num = -999; TargetInfo bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; WorkGiver_Scanner scanner; IntVec3 pawnPosition; bool prioritized; bool allowUnreachable; Danger maxPathDanger; for (int j = 0; j < list.Count; j++) { WorkGiver workGiver = list[j]; if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (!PawnCanUseWorkGiver(pawn, workGiver)) { continue; } try { Job job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, this, list[j].def.tagToGive)); } scanner = (workGiver as WorkGiver_Scanner); float closestDistSquared; float bestPriority; if (scanner != null) { if (scanner.def.scanThings) { Predicate <Thing> validator = (Thing t) => !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t); IEnumerable <Thing> enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; try { if (scanner.Prioritized) { IEnumerable <Thing> enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = ((!scanner.AllowUnreachable) ? GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, (Thing x) => scanner.GetPriority(pawn, x)) : GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, validator, (Thing x) => scanner.GetPriority(pawn, x))); } else if (scanner.AllowUnreachable) { IEnumerable <Thing> enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, validator); } else { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, validator, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); } } catch (Exception ex) { Log.Error("Error in WorkGiver: " + ex.Message); thing = null; } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { pawnPosition = pawn.Position; closestDistSquared = 99999f; bestPriority = float.MinValue; prioritized = scanner.Prioritized; allowUnreachable = scanner.AllowUnreachable; maxPathDanger = scanner.MaxPathDanger(pawn); IEnumerable <IntVec3> enumerable4 = scanner.PotentialWorkCellsGlobal(pawn); IList <IntVec3> list2; if ((list2 = (enumerable4 as IList <IntVec3>)) != null) { for (int k = 0; k < list2.Count; k++) { ProcessCell(list2[k]); } } else { foreach (IntVec3 item in enumerable4) { ProcessCell(item); } } } } void ProcessCell(IntVec3 c) { bool flag = false; float num2 = (c - pawnPosition).LengthHorizontalSquared; float num3 = 0f; if (prioritized) { if (!c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } num3 = scanner.GetPriority(pawn, c); if (num3 > bestPriority || (num3 == bestPriority && num2 < closestDistSquared)) { flag = true; } } } else if (num2 < closestDistSquared && !c.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, c)) { if (!allowUnreachable && !pawn.CanReach(c, scanner.PathEndMode, maxPathDanger)) { return; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(c, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num2; bestPriority = num3; } } } catch (Exception ex) { Log.Error(pawn + " threw exception in WorkGiver " + workGiver.def.defName + ": " + ex.ToString()); } finally { } if (bestTargetOfLastPriority.IsValid) { Job job3 = (!bestTargetOfLastPriority.HasThing) ? scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell) : scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, this, list[j].def.tagToGive)); } Log.ErrorOnce(scannerWhoProvidedTarget + " provided target " + bestTargetOfLastPriority + " but yielded no actual job for pawn " + pawn + ". The CanGiveJob and JobOnX methods may not be synchronized.", 6112651); } num = workGiver.def.priorityInType; } return(ThinkResult.NoJob); }
private static ThinkResult Detour(JobGiver_Work __instance, Pawn pawn) { if (__instance.emergency && pawn.mindState.priorityWork.IsPrioritized) { var workGiversByPriority = pawn.mindState.priorityWork.WorkGiver.workType.workGiversByPriority; for (var i = 0; i < workGiversByPriority.Count; i++) { var worker = workGiversByPriority[i].Worker; var job = __instance.GiverTryGiveJobPrioritized(pawn, worker, pawn.mindState.priorityWork.Cell); if (job != null) { job.playerForced = true; return(new ThinkResult(job, __instance, workGiversByPriority[i].tagToGive)); } } pawn.mindState.priorityWork.Clear(); } var list = __instance.emergency ? pawn.workSettings.WorkGiversInOrderEmergency : pawn.workSettings.WorkGiversInOrderNormal; var num = -999; var bestTargetOfLastPriority = TargetInfo.Invalid; WorkGiver_Scanner scannerWhoProvidedTarget = null; var coo = list.Count; for (var j = 0; j < coo; j++) { var workGiver = list[j]; string namer() { var daffy = string.Empty; if (ByWorkType) { daffy = workGiver.def?.workType?.defName; } else { daffy = $"{workGiver.def?.defName} - {workGiver.def?.workType.defName} - {workGiver.def?.modContentPack?.Name}"; } //if (true) //{ // daffy += $" - { TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)).ToString()} - {pawn.Name.ToStringShort}"; //} if (RequestTypes && workGiver is WorkGiver_Scanner scan) { daffy += $" - {scan.PotentialWorkThingRequest}"; if (scan.PotentialWorkThingRequest.group == ThingRequestGroup.BuildingArtificial) { daffy += " VERY BAD!"; } } return(daffy); } if (workGiver.def.priorityInType != num && bestTargetOfLastPriority.IsValid) { break; } if (__instance.PawnCanUseWorkGiver(pawn, workGiver)) { var name = string.Empty; if (ByWorkType) { name = workGiver.def.workType.defName; } else { name = workGiver.def.defName; } //if (true) //{ // name = string.Intern(name + pawn.Name.ToStringShort); //} if (workGiver is WorkGiver_Scanner scanny) { name += $"{scanny.PotentialWorkThingRequest}"; } try { var job2 = workGiver.NonScanJob(pawn); if (job2 != null) { return(new ThinkResult(job2, __instance, list[j].def.tagToGive)); } if (workGiver is WorkGiver_Scanner scanner) { Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn); if (scanner.def.scanThings) { bool Predicate(Thing t) { return(!t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t)); } var enumerable = scanner.PotentialWorkThingsGlobal(pawn); Thing thing; if (scanner.Prioritized) { var enumerable2 = enumerable; if (enumerable2 == null) { enumerable2 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } if (scanner.AllowUnreachable) { thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable2, 99999f, Predicate, x => scanner.GetPriority(pawn, x)); } else { var traverseParams = TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)); var validator = (Predicate <Thing>)Predicate; thing = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, enumerable2, scanner.PathEndMode, traverseParams, 9999f, validator, x => scanner.GetPriority(pawn, x)); } } else if (scanner.AllowUnreachable) { var enumerable3 = enumerable; if (enumerable3 == null) { enumerable3 = pawn.Map.listerThings.ThingsMatching(scanner.PotentialWorkThingRequest); } thing = GenClosest.ClosestThing_Global(pawn.Position, enumerable3, 99999f, Predicate); } else { giver = workGiver; key = name; Analyzer.Start(name, namer, workGiver.GetType(), workGiver.def, pawn); thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, scanner.PotentialWorkThingRequest, scanner.PathEndMode, TraverseParms.For(pawn, scanner.MaxPathDanger(pawn)), 9999f, Predicate, enumerable, 0, scanner.MaxRegionsToScanBeforeGlobalSearch, enumerable != null); giver = null; } if (thing != null) { bestTargetOfLastPriority = thing; scannerWhoProvidedTarget = scanner; } } if (scanner.def.scanCells) { var closestDistSquared = 99999f; var bestPriority = float.MinValue; var prioritized = scanner.Prioritized; var allowUnreachable = scanner.AllowUnreachable; var maxDanger = scanner.MaxPathDanger(pawn); foreach (var intVec in scanner.PotentialWorkCellsGlobal(pawn)) { var flag = false; var num4 = (intVec - pawn.Position).LengthHorizontalSquared; var num5 = 0f; if (prioritized) { if (!intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { continue; } num5 = scanner.GetPriority(pawn, intVec); if (num5 > bestPriority || num5 == bestPriority && num4 < closestDistSquared) { flag = true; } } } else if (num4 < closestDistSquared && !intVec.IsForbidden(pawn) && scanner.HasJobOnCell(pawn, intVec)) { if (!allowUnreachable && !pawn.CanReach(intVec, scanner.PathEndMode, maxDanger)) { continue; } flag = true; } if (flag) { bestTargetOfLastPriority = new TargetInfo(intVec, pawn.Map); scannerWhoProvidedTarget = scanner; closestDistSquared = num4; bestPriority = num5; } } } Analyzer.Stop(name); } } catch (Exception ex) { Log.Error(string.Concat(pawn, " threw exception in WorkGiver ", workGiver.def.defName, ": ", ex.ToString())); } if (bestTargetOfLastPriority.IsValid) { // pawn.mindState.lastGivenWorkType = workGiver.def.workType; Job job3; if (bestTargetOfLastPriority.HasThing) { job3 = scannerWhoProvidedTarget.JobOnThing(pawn, bestTargetOfLastPriority.Thing); } else { job3 = scannerWhoProvidedTarget.JobOnCell(pawn, bestTargetOfLastPriority.Cell); } if (job3 != null) { job3.workGiverDef = scannerWhoProvidedTarget.def; return(new ThinkResult(job3, __instance, list[j].def.tagToGive)); } Log.ErrorOnce( string.Concat(scannerWhoProvidedTarget, " provided target ", bestTargetOfLastPriority, " but yielded no actual job for pawn ", pawn, ". The CanGiveJob and JobOnX methods may not be synchronized."), 6112651); } num = workGiver.def.priorityInType; } } return(ThinkResult.NoJob); }