public bool TryFindCEShootLineFromTo(IntVec3 root, LocalTargetInfo targ, out ShootLine resultingLine) { if (targ.HasThing && targ.Thing.Map != this.caster.Map) { resultingLine = default(ShootLine); return(false); } if (this.verbProps.MeleeRange) { resultingLine = new ShootLine(root, targ.Cell); return(ReachabilityImmediate.CanReachImmediate(root, targ, this.caster.Map, PathEndMode.Touch, null)); } CellRect cellRect = (!targ.HasThing) ? CellRect.SingleCell(targ.Cell) : targ.Thing.OccupiedRect(); float num = cellRect.ClosestDistSquaredTo(root); if (num > this.verbProps.range * this.verbProps.range || num < this.verbProps.minRange * this.verbProps.minRange) { resultingLine = new ShootLine(root, targ.Cell); return(false); } //if (!this.verbProps.NeedsLineOfSight) This method doesn't consider the currently loaded projectile if (Projectile.projectile.flyOverhead) { resultingLine = new ShootLine(root, targ.Cell); return(true); } if (this.CasterIsPawn) { IntVec3 dest; if (this.CanHitFromCellIgnoringRange(root, targ, out dest)) { resultingLine = new ShootLine(root, dest); return(true); } ShootLeanUtility.LeanShootingSourcesFromTo(root, cellRect.ClosestCellTo(root), this.caster.Map, tempLeanShootSources); for (int i = 0; i < tempLeanShootSources.Count; i++) { IntVec3 intVec = tempLeanShootSources[i]; if (this.CanHitFromCellIgnoringRange(intVec, targ, out dest)) { resultingLine = new ShootLine(intVec, dest); return(true); } } } else { CellRect.CellRectIterator iterator = this.caster.OccupiedRect().GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; IntVec3 dest; if (this.CanHitFromCellIgnoringRange(current, targ, out dest)) { resultingLine = new ShootLine(current, dest); return(true); } iterator.MoveNext(); } } resultingLine = new ShootLine(root, targ.Cell); return(false); }
private void SpawnRoofOver(Thing thing) { CellRect cellRect = thing.OccupiedRect(); bool flag = true; CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { if (!iterator.Current.Roofed(thing.Map)) { flag = false; break; } iterator.MoveNext(); } if (flag) { return; } int num = 0; CellRect cellRect2 = cellRect.ExpandedBy(2); CellRect.CellRectIterator iterator2 = cellRect2.GetIterator(); while (!iterator2.Done()) { if (iterator2.Current.InBounds(thing.Map) && iterator2.Current.GetRoofHolderOrImpassable(thing.Map) != null) { num++; } iterator2.MoveNext(); } if (num < 2) { ThingDef stuff = Rand.Element <ThingDef>(ThingDefOf.WoodLog, ThingDefOf.Steel); foreach (IntVec3 current in cellRect2.Corners) { if (current.InBounds(thing.Map)) { if (current.Standable(thing.Map)) { if (current.GetFirstItem(thing.Map) == null && current.GetFirstBuilding(thing.Map) == null && current.GetFirstPawn(thing.Map) == null) { if (!GenAdj.CellsAdjacent8Way(new TargetInfo(current, thing.Map, false)).Any((IntVec3 x) => !x.InBounds(thing.Map) || !x.Walkable(thing.Map))) { if (current.SupportsStructureType(thing.Map, ThingDefOf.Wall.terrainAffordanceNeeded)) { Thing thing2 = ThingMaker.MakeThing(ThingDefOf.Wall, stuff); GenSpawn.Spawn(thing2, current, thing.Map, WipeMode.Vanish); thing2.SetFaction(thing.Faction, null); num++; } } } } } } } if (num > 0) { CellRect.CellRectIterator iterator3 = cellRect2.GetIterator(); while (!iterator3.Done()) { if (iterator3.Current.InBounds(thing.Map) && !iterator3.Current.Roofed(thing.Map)) { thing.Map.roofGrid.SetRoof(iterator3.Current, RoofDefOf.RoofConstructed); } iterator3.MoveNext(); } } }
public override void Resolve(ResolveParams rp) { CellRect.CellRectIterator iterator = rp.rect.ContractedBy(1).GetIterator(); while (!iterator.Done()) { if (rp.clearEdificeOnly.HasValue && rp.clearEdificeOnly.Value) { Building edifice = iterator.Current.GetEdifice(BaseGen.globalSettings.map); if (edifice != null && edifice.def.destroyable) { if (edifice.def != CthulhuFactionsDefOf.ROM_TemporaryDoorMarker) { edifice.Destroy(DestroyMode.Vanish); } } } else { SymbolResolverAgency.tmpThingsToDestroy.Clear(); SymbolResolverAgency.tmpThingsToDestroy.AddRange(iterator.Current.GetThingList(BaseGen.globalSettings.map)); for (int i = 0; i < SymbolResolverAgency.tmpThingsToDestroy.Count; i++) { if (SymbolResolverAgency.tmpThingsToDestroy[i].def.destroyable) { if (SymbolResolverAgency.tmpThingsToDestroy[i].def != CthulhuFactionsDefOf.ROM_TemporaryDoorMarker) { SymbolResolverAgency.tmpThingsToDestroy[i].Destroy(DestroyMode.Vanish); } } } } iterator.MoveNext(); } foreach (IntVec3 cell in rp.rect.Cells) { ResolveParams resolveParams3 = rp; resolveParams3.rect = CellRect.SingleCell(cell); resolveParams3.singleThingDef = CthulhuFactionsDefOf.ROM_TemporaryRegionBarrier; BaseGen.symbolStack.Push("thing", resolveParams3); } PassingParameters(rp); instanceMap = map; instanceFaction = rp.faction ?? Find.FactionManager.FirstFactionOfDef(FactionDef.Named("TheAgency")); //ResolveParams resolveParams4 = rp; //BaseGen.symbolStack.Push("clear", resolveParams4); UnfogRoomCenter(rp.rect.CenterCell); LongEventHandler.QueueLongEvent(delegate { if (SymbolResolverAgency.instanceMap == null) { return; } foreach (IntVec3 cell in SymbolResolverAgency.instanceMap.AllCells) { Thing thing = cell.GetThingList(instanceMap).Find((Thing x) => x.def == CthulhuFactionsDefOf.ROM_TemporaryDoorMarker); if (thing == null) { //Log.Warning("Could not destroy temporary region barrier at " + cell + " because it's not here."); } else { if (thing.def == CthulhuFactionsDefOf.ROM_TemporaryDoorMarker) { SymbolResolverAgency.newThing = null; SymbolResolverAgency.newThing = ThingMaker.MakeThing(ThingDefOf.Door, ThingDefOf.Steel); SymbolResolverAgency.newThing.SetFaction(SymbolResolverAgency.instanceFaction, null); //newThing.Rotation = thing.Rotation; tempIntVec = new IntVec3(cell.x, 0, cell.z); GenSpawn.Spawn(SymbolResolverAgency.newThing, SymbolResolverAgency.tempIntVec, SymbolResolverAgency.instanceMap); } thing.Destroy(DestroyMode.Vanish); } } foreach (Pawn pawn in SymbolResolverAgency.instanceMap.mapPawns.AllPawnsSpawned.FindAll((Pawn x) => x != null && x.Spawned && x.RaceProps.intelligence >= Intelligence.ToolUser && !x.IsColonist && x.Faction != instanceFaction && x.guest != null && SymbolResolver_FillCells.IsCosmicHorrorFaction(x.Faction) == false)) { pawn.guest.SetGuestStatus(instanceFaction, true); } foreach (Building_Bed bed in SymbolResolverAgency.instanceMap.listerThings.AllThings.FindAll((Thing x) => x != null && x is Building_Bed && x.def == ThingDefOf.SleepingSpot && x.Faction == instanceFaction)) { bed.ForPrisoners = true; } }, "doorResolver", true, null); }
private static bool TryFindSiegePosition(IntVec3 entrySpot, float minDistToColony, Map map, out IntVec3 result) { CellRect cellRect = CellRect.CenteredOn(entrySpot, 60); cellRect.ClipInsideMap(map); cellRect = cellRect.ContractedBy(14); List <IntVec3> list = new List <IntVec3>(); foreach (Pawn current in map.mapPawns.FreeColonistsSpawned) { list.Add(current.Position); } foreach (Building current2 in map.listerBuildings.allBuildingsColonistCombatTargets) { list.Add(current2.Position); } float num = minDistToColony * minDistToColony; int num2 = 0; IntVec3 randomCell; while (true) { num2++; if (num2 > 200) { break; } randomCell = cellRect.RandomCell; if (randomCell.Standable(map)) { if (randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Heavy) && randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Light)) { if (map.reachability.CanReach(randomCell, entrySpot, PathEndMode.OnCell, TraverseMode.NoPassClosedDoors, Danger.Some)) { if (map.reachability.CanReachColony(randomCell)) { bool flag = false; for (int i = 0; i < list.Count; i++) { if ((float)(list[i] - randomCell).LengthHorizontalSquared < num) { flag = true; break; } } if (!flag) { if (!randomCell.Roofed(map)) { int num3 = 0; CellRect.CellRectIterator iterator = CellRect.CenteredOn(randomCell, 10).ClipInsideMap(map).GetIterator(); while (!iterator.Done()) { if (randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Heavy) && randomCell.SupportsStructureType(map, TerrainAffordanceDefOf.Light)) { num3++; } iterator.MoveNext(); } if (num3 >= 35) { goto IL_223; } } } } } } } } result = IntVec3.Invalid; return(false); IL_223: result = randomCell; return(true); }
public static bool TryFindRandomSpotJustOutsideColony(IntVec3 root, Map map, Pawn searcher, out IntVec3 result, Predicate <IntVec3> extraValidator = null) { bool desperate = false; int minColonyBuildingsLOS = 0; int walkRadius = 0; int walkRadiusMaxImpassable = 0; Predicate <IntVec3> validator = delegate(IntVec3 c) { if (!c.Standable(map)) { return(false); } Room room = c.GetRoom(map, RegionType.Set_Passable); if (!room.PsychologicallyOutdoors || !room.TouchesMapEdge) { return(false); } if (room == null || room.CellCount < 60) { return(false); } if (root.IsValid) { TraverseParms traverseParams = (searcher == null) ? TraverseMode.PassDoors : TraverseParms.For(searcher, Danger.Deadly, TraverseMode.ByPawn, false); if (!map.reachability.CanReach(root, c, PathEndMode.Touch, traverseParams)) { return(false); } } if (!desperate && !map.reachability.CanReachColony(c)) { return(false); } if (extraValidator != null && !extraValidator(c)) { return(false); } int num = 0; CellRect.CellRectIterator iterator = CellRect.CenteredOn(c, walkRadius).GetIterator(); while (!iterator.Done()) { Room room2 = iterator.Current.GetRoom(map, RegionType.Set_Passable); if (room2 != room) { num++; if (!desperate && room2 != null && room2.IsDoorway) { return(false); } } if (num > walkRadiusMaxImpassable) { return(false); } iterator.MoveNext(); } if (minColonyBuildingsLOS > 0) { int colonyBuildingsLOSFound = 0; RCellFinder_Zombiefied.tmpBuildings.Clear(); RegionTraverser.BreadthFirstTraverse(c, map, (Region from, Region to) => true, delegate(Region reg) { Faction ofPlayer = Faction.OfPlayer; List <Thing> list = reg.ListerThings.ThingsInGroup(ThingRequestGroup.BuildingArtificial); for (int l = 0; l < list.Count; l++) { Thing thing = list[l]; if (thing.Faction == ofPlayer && thing.Position.InHorDistOf(c, 16f) && GenSight.LineOfSight(thing.Position, c, map, true, null, 0, 0) && !RCellFinder_Zombiefied.tmpBuildings.Contains(thing)) { RCellFinder_Zombiefied.tmpBuildings.Add(thing); colonyBuildingsLOSFound++; if (colonyBuildingsLOSFound >= minColonyBuildingsLOS) { return(true); } } } return(false); }, 12, RegionType.Set_Passable); RCellFinder_Zombiefied.tmpBuildings.Clear(); if (colonyBuildingsLOSFound < minColonyBuildingsLOS) { return(false); } } return(true); }; IEnumerable <Building> source = from b in map.listerBuildings.allBuildingsColonist where b.def.building.ai_chillDestination select b; for (int i = 0; i < 120; i++) { Building building = null; if (!source.TryRandomElement(out building)) { break; } desperate = (i > 60); walkRadius = 6 - i / 20; walkRadiusMaxImpassable = 6 - i / 20; minColonyBuildingsLOS = 5 - i / 30; if (CellFinder.TryFindRandomCellNear(building.Position, map, 10, validator, out result, 50)) { return(true); } } List <Building> allBuildingsColonist = map.listerBuildings.allBuildingsColonist; for (int j = 0; j < 120; j++) { Building building2 = null; if (!allBuildingsColonist.TryRandomElement(out building2)) { break; } desperate = (j > 60); walkRadius = 6 - j / 20; walkRadiusMaxImpassable = 6 - j / 20; minColonyBuildingsLOS = 4 - j / 30; if (CellFinder.TryFindRandomCellNear(building2.Position, map, 15, validator, out result, 50)) { return(true); } } for (int k = 0; k < 50; k++) { Pawn pawn = null; if (!map.mapPawns.FreeColonistsAndPrisonersSpawned.TryRandomElement(out pawn)) { break; } desperate = (k > 25); walkRadius = 3; walkRadiusMaxImpassable = 6; minColonyBuildingsLOS = 0; if (CellFinder.TryFindRandomCellNear(pawn.Position, map, 15, validator, out result, 50)) { return(true); } } desperate = true; walkRadius = 3; walkRadiusMaxImpassable = 6; minColonyBuildingsLOS = 0; return(CellFinderLoose.TryGetRandomCellWith(validator, map, 1000, out result)); }
private static string TemperatureString() { IntVec3 intVec = UI.MouseCell(); IntVec3 c = intVec; Room room = intVec.GetRoom(Find.VisibleMap, RegionType.Set_All); if (room == null) { for (int i = 0; i < 9; i++) { IntVec3 intVec2 = intVec + GenAdj.AdjacentCellsAndInside[i]; Room room2; if (intVec2.InBounds(Find.VisibleMap)) { room2 = intVec2.GetRoom(Find.VisibleMap, RegionType.Set_All); if (room2 != null) { if (!room2.PsychologicallyOutdoors && !room2.UsesOutdoorTemperature) { goto IL_00a8; } if (!room2.PsychologicallyOutdoors && (room == null || room.PsychologicallyOutdoors)) { goto IL_00a8; } if (room2.PsychologicallyOutdoors && room == null) { goto IL_00a8; } } } continue; IL_00a8: c = intVec2; room = room2; } } if (room == null && intVec.InBounds(Find.VisibleMap)) { Building edifice = intVec.GetEdifice(Find.VisibleMap); if (edifice != null) { CellRect.CellRectIterator iterator = edifice.OccupiedRect().ExpandedBy(1).ClipInsideMap(Find.VisibleMap) .GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; room = current.GetRoom(Find.VisibleMap, RegionType.Set_All); if (room != null && !room.PsychologicallyOutdoors) { c = current; break; } iterator.MoveNext(); } } } string str = (!c.InBounds(Find.VisibleMap) || c.Fogged(Find.VisibleMap) || room == null || room.PsychologicallyOutdoors) ? "Outdoors".Translate() : ((room.OpenRoofCount != 0) ? ("IndoorsUnroofed".Translate() + " (" + room.OpenRoofCount.ToStringCached() + ")") : "Indoors".Translate()); float celsiusTemp = (room != null && !c.Fogged(Find.VisibleMap)) ? room.Temperature : Find.VisibleMap.mapTemperature.OutdoorTemp; return(str + " " + celsiusTemp.ToStringTemperature("F0")); }
public static bool TryFindCastPosition(CastPositionRequest newReq, out IntVec3 dest) { CastPositionFinder.req = newReq; CastPositionFinder.casterLoc = CastPositionFinder.req.caster.Position; CastPositionFinder.targetLoc = CastPositionFinder.req.target.Position; CastPositionFinder.verb = CastPositionFinder.req.verb; CastPositionFinder.avoidGrid = newReq.caster.GetAvoidGrid(); bool result; if (CastPositionFinder.verb == null) { Log.Error(CastPositionFinder.req.caster + " tried to find casting position without a verb.", false); dest = IntVec3.Invalid; result = false; } else { if (CastPositionFinder.req.maxRegions > 0) { Region region = CastPositionFinder.casterLoc.GetRegion(CastPositionFinder.req.caster.Map, RegionType.Set_Passable); if (region == null) { Log.Error("TryFindCastPosition requiring region traversal but root region is null.", false); dest = IntVec3.Invalid; return(false); } CastPositionFinder.inRadiusMark = Rand.Int; RegionTraverser.MarkRegionsBFS(region, null, newReq.maxRegions, CastPositionFinder.inRadiusMark, RegionType.Set_Passable); if (CastPositionFinder.req.maxRangeFromLocus > 0.01f) { Region locusReg = CastPositionFinder.req.locus.GetRegion(CastPositionFinder.req.caster.Map, RegionType.Set_Passable); if (locusReg == null) { Log.Error("locus " + CastPositionFinder.req.locus + " has no region", false); dest = IntVec3.Invalid; return(false); } if (locusReg.mark != CastPositionFinder.inRadiusMark) { CastPositionFinder.inRadiusMark = Rand.Int; RegionTraverser.BreadthFirstTraverse(region, null, delegate(Region r) { r.mark = CastPositionFinder.inRadiusMark; CastPositionFinder.req.maxRegions = CastPositionFinder.req.maxRegions + 1; return(r == locusReg); }, 999999, RegionType.Set_Passable); } } } CellRect cellRect = CellRect.WholeMap(CastPositionFinder.req.caster.Map); if (CastPositionFinder.req.maxRangeFromCaster > 0.01f) { int num = Mathf.CeilToInt(CastPositionFinder.req.maxRangeFromCaster); CellRect otherRect = new CellRect(CastPositionFinder.casterLoc.x - num, CastPositionFinder.casterLoc.z - num, num * 2 + 1, num * 2 + 1); cellRect.ClipInsideRect(otherRect); } int num2 = Mathf.CeilToInt(CastPositionFinder.req.maxRangeFromTarget); CellRect otherRect2 = new CellRect(CastPositionFinder.targetLoc.x - num2, CastPositionFinder.targetLoc.z - num2, num2 * 2 + 1, num2 * 2 + 1); cellRect.ClipInsideRect(otherRect2); if (CastPositionFinder.req.maxRangeFromLocus > 0.01f) { int num3 = Mathf.CeilToInt(CastPositionFinder.req.maxRangeFromLocus); CellRect otherRect3 = new CellRect(CastPositionFinder.targetLoc.x - num3, CastPositionFinder.targetLoc.z - num3, num3 * 2 + 1, num3 * 2 + 1); cellRect.ClipInsideRect(otherRect3); } CastPositionFinder.bestSpot = IntVec3.Invalid; CastPositionFinder.bestSpotPref = 0.001f; CastPositionFinder.maxRangeFromCasterSquared = CastPositionFinder.req.maxRangeFromCaster * CastPositionFinder.req.maxRangeFromCaster; CastPositionFinder.maxRangeFromTargetSquared = CastPositionFinder.req.maxRangeFromTarget * CastPositionFinder.req.maxRangeFromTarget; CastPositionFinder.maxRangeFromLocusSquared = CastPositionFinder.req.maxRangeFromLocus * CastPositionFinder.req.maxRangeFromLocus; CastPositionFinder.rangeFromTarget = (CastPositionFinder.req.caster.Position - CastPositionFinder.req.target.Position).LengthHorizontal; CastPositionFinder.rangeFromTargetSquared = (float)(CastPositionFinder.req.caster.Position - CastPositionFinder.req.target.Position).LengthHorizontalSquared; CastPositionFinder.optimalRangeSquared = CastPositionFinder.verb.verbProps.range * 0.8f * (CastPositionFinder.verb.verbProps.range * 0.8f); CastPositionFinder.EvaluateCell(CastPositionFinder.req.caster.Position); if ((double)CastPositionFinder.bestSpotPref >= 1.0) { dest = CastPositionFinder.req.caster.Position; result = true; } else { float slope = -1f / CellLine.Between(CastPositionFinder.req.target.Position, CastPositionFinder.req.caster.Position).Slope; CellLine cellLine = new CellLine(CastPositionFinder.req.target.Position, slope); bool flag = cellLine.CellIsAbove(CastPositionFinder.req.caster.Position); Profiler.BeginSample("TryFindCastPosition scan near side"); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 c = iterator.Current; if (cellLine.CellIsAbove(c) == flag && cellRect.Contains(c)) { CastPositionFinder.EvaluateCell(c); } iterator.MoveNext(); } Profiler.EndSample(); if (CastPositionFinder.bestSpot.IsValid && CastPositionFinder.bestSpotPref > 0.33f) { dest = CastPositionFinder.bestSpot; result = true; } else { Profiler.BeginSample("TryFindCastPosition scan far side"); CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { IntVec3 c2 = iterator2.Current; if (cellLine.CellIsAbove(c2) != flag && cellRect.Contains(c2)) { CastPositionFinder.EvaluateCell(c2); } iterator2.MoveNext(); } Profiler.EndSample(); if (CastPositionFinder.bestSpot.IsValid) { dest = CastPositionFinder.bestSpot; result = true; } else { dest = CastPositionFinder.casterLoc; result = false; } } } } return(result); }
// Verse.AI.CastPositionFinder public bool TryFindCastPosition(CastPositionRequest req, out IntVec3 dest) { ByteGrid avoidGrid = null; int inRadiusMark = 0; if (this.pawn.CurJob.verbToUse == null) { Log.Error(this.pawn + " tried to find casting position without a verb."); dest = IntVec3.Invalid; return(false); } if (req.maxRegionsRadius > 0) { Region region = req.caster.PositionHeld.GetRegion(this.pawn.Map); if (region == null) { Log.Error("TryFindCastPosition requiring region traversal but root region is null."); dest = IntVec3.Invalid; return(false); } inRadiusMark = Rand.Int; RegionTraverser.MarkRegionsBFS(region, null, req.maxRegionsRadius, inRadiusMark); if (req.maxRangeFromLocus > 0.01f) { Region region2 = req.locus.GetRegion(this.pawn.Map); if (region2 == null) { Log.Error("locus " + req.locus + " has no region"); dest = IntVec3.Invalid; return(false); } if (region2.mark != inRadiusMark) { Log.Error(string.Concat(new object[] { req.caster, " can't possibly get to locus ", req.locus, " as it's not in a maxRegionsRadius of ", req.maxRegionsRadius, ". Overriding maxRegionsRadius." })); req.maxRegionsRadius = 0; } } } CellRect cellRect = CellRect.WholeMap(req.caster.Map); if (req.maxRangeFromCaster > 0.01f) { int numSolo = Mathf.CeilToInt(req.maxRangeFromCaster); CellRect otherRect = new CellRect(this.pawn.PositionHeld.x - numSolo, this.pawn.PositionHeld.z - numSolo, numSolo * 2 + 1, numSolo * 2 + 1); cellRect.ClipInsideRect(otherRect); } int num2 = Mathf.CeilToInt(req.maxRangeFromTarget); CellRect otherRect2 = new CellRect(this.TargetA.Cell.x - num2, this.TargetA.Cell.z - num2, num2 * 2 + 1, num2 * 2 + 1); cellRect.ClipInsideRect(otherRect2); if (req.maxRangeFromLocus > 0.01f) { int numThree = Mathf.CeilToInt(req.maxRangeFromLocus); CellRect otherRect3 = new CellRect(this.TargetA.Cell.x - numThree, this.TargetA.Cell.z - numThree, numThree * 2 + 1, numThree * 2 + 1); cellRect.ClipInsideRect(otherRect3); } IntVec3 bestSpot = IntVec3.Invalid; float bestSpotPref = 0.001f; float maxRangeFromCasterSquared = req.maxRangeFromCaster * req.maxRangeFromCaster; float maxRangeFromTargetSquared = req.maxRangeFromTarget * req.maxRangeFromTarget; float maxRangeFromLocusSquared = req.maxRangeFromLocus * req.maxRangeFromLocus; float rangeFromTarget = (req.caster.Position - this.TargetA.Cell).LengthHorizontal; float rangeFromTargetSquared = (req.caster.Position - this.TargetA.Cell).LengthHorizontalSquared; float rangeFromCasterToCellSquared = 0f; float optimalRangeSquared = this.pawn.CurJob.verbToUse.verbProps.range * 0.8f * (this.pawn.CurJob.verbToUse.verbProps.range * 0.8f); /////////////////// Evaluate Cell method IntVec3 c = req.caster.PositionHeld; EvaluateCell(c, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark); float num = -1f; /////////////////// CAST POSITION PREFERENCE bool flag = true; List <Thing> list = req.caster.Map.thingGrid.ThingsListAtFast(c); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; if (thing is Fire fire && fire.parent == null) { num = -1f; goto MainSequenceTwo; } if (thing.def.passability == Traversability.PassThroughOnly) { flag = false; } } num = 0.3f; if (req.caster.kindDef.aiAvoidCover) { num += 8f - CoverUtility.TotalSurroundingCoverScore(c, req.caster.Map); } if (req.wantCoverFromTarget) { num += CoverUtility.CalculateOverallBlockChance(c, this.TargetLocA, req.caster.Map); } float numTwo = (req.caster.Position - c).LengthHorizontal; if (rangeFromTarget > 100f) { numTwo -= rangeFromTarget - 100f; if (numTwo < 0f) { numTwo = 0f; } } num *= Mathf.Pow(0.967f, num2); float num3 = 1f; float rangeFromTargetToCellSquared = (c - this.TargetLocA).LengthHorizontalSquared; //rangeFromCasterToCellSquared = (req.target.Position - c).LengthHorizontalSquared; float num4 = Mathf.Abs(rangeFromTargetToCellSquared - optimalRangeSquared) / optimalRangeSquared; num4 = 1f - num4; num4 = 0.7f + 0.3f * num4; num3 *= num4; if (rangeFromTargetToCellSquared < 25f) { num3 *= 0.5f; } num *= num3; if (rangeFromCasterToCellSquared > rangeFromTargetSquared) { num *= 0.4f; } if (!flag) { num *= 0.2f; } /////////////////////////////////////////////// MainSequenceTwo: if (avoidGrid != null) { byte b = avoidGrid[c]; num *= Mathf.Max(0.1f, (37f - b) / 37f); } if (DebugViewSettings.drawCastPositionSearch) { req.caster.Map.debugDrawer.FlashCell(c, num / 4f, num.ToString("F3")); } if (num < bestSpotPref) { goto MainSequence; } if (!this.pawn.CurJob.verbToUse.CanHitTargetFrom(c, this.TargetLocA)) { if (DebugViewSettings.drawCastPositionSearch) { req.caster.Map.debugDrawer.FlashCell(c, 0.6f, "can't hit"); } goto MainSequence; } if (req.caster.Map.pawnDestinationManager.DestinationIsReserved(c, req.caster)) { if (DebugViewSettings.drawCastPositionSearch) { req.caster.Map.debugDrawer.FlashCell(c, num * 0.9f, "resvd"); } goto MainSequence; } bestSpot = c; bestSpotPref = num; ///////////////////////////////////////////////////// MainSequence: if (bestSpotPref >= 1.0) { dest = req.caster.Position; return(true); } float slope = -1f / CellLine.Between(this.TargetLocA, req.caster.Position).Slope; CellLine cellLine = new CellLine(this.TargetLocA, slope); bool flagTwo = cellLine.CellIsAbove(req.caster.Position); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (cellLine.CellIsAbove(current) == flagTwo && cellRect.Contains(current)) { EvaluateCell(current, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark); } iterator.MoveNext(); } if (bestSpot.IsValid && bestSpotPref > 0.33f) { dest = bestSpot; return(true); } CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { IntVec3 current2 = iterator2.Current; if (cellLine.CellIsAbove(current2) != flag && cellRect.Contains(current2)) { EvaluateCell(current2, req, maxRangeFromTargetSquared, maxRangeFromLocusSquared, maxRangeFromCasterSquared, rangeFromCasterToCellSquared, inRadiusMark); } iterator2.MoveNext(); } if (bestSpot.IsValid) { dest = bestSpot; return(true); } dest = req.caster.PositionHeld; return(false); }
protected override IEnumerable <Toil> MakeNewToils() { var followAndAttack = new Toil(); followAndAttack.initAction = delegate() { var actor = followAndAttack.actor; var curJob = actor.jobs.curJob; var thing = curJob.GetTarget(this.a).Thing; var pawn1 = thing as Pawn; if (thing != actor.pather.Destination.Thing || (!this.pawn.pather.Moving && !this.pawn.Position.AdjacentTo8WayOrInside(thing))) { RoofDef roofDef = actor.Map.roofGrid.RoofAt(actor.Position); if (roofDef != null) { if (roofDef != RoofDefOf.RoofConstructed) { return; } if (!SoundDefHelper.NullOrUndefined(roofDef.soundPunchThrough)) { SoundStarter.PlayOneShot(roofDef.soundPunchThrough, new TargetInfo(actor.Position, actor.Map, false)); CellRect.CellRectIterator iterator = CellRect.CenteredOn(actor.Position, 1).GetIterator(); while (!iterator.Done()) { Find.CurrentMap.roofGrid.SetRoof(iterator.Current, null); iterator.MoveNext(); } } } RoofDef roofDef2 = actor.Map.roofGrid.RoofAt(thing.Position); if (roofDef2 != null) { if (roofDef2 != RoofDefOf.RoofConstructed) { return; } if (!SoundDefHelper.NullOrUndefined(roofDef2.soundPunchThrough)) { SoundStarter.PlayOneShot(roofDef2.soundPunchThrough, new TargetInfo(actor.Position, actor.Map, false)); CellRect.CellRectIterator iterator2 = CellRect.CenteredOn(thing.Position, 1).GetIterator(); while (!iterator2.Done()) { Find.CurrentMap.roofGrid.SetRoof(iterator2.Current, null); iterator2.MoveNext(); } } } } actor.pather.StartPath(thing, PathEndMode.OnCell); actor.Position = thing.Position; actor.pather.StopDead(); pawn1.pather.StopDead(); pawn1.TakeDamage(new DamageInfo(PurpleIvyDefOf.AlienToxicSting, 3, 0f, -1f, actor, null, null)); if (actor.jobs.curJob != null) { actor.jobs.curDriver.Notify_PatherArrived(); } actor.jobs.TryTakeOrderedJob(PurpleIvyUtils.MeleeAttackJob(actor, pawn1)); }; followAndAttack.defaultCompleteMode = ToilCompleteMode.Never; followAndAttack.EndOnDespawnedOrNull <Toil>(this.a, JobCondition.Succeeded); followAndAttack.FailOn <Toil>(new Func <bool>(this.hunterIsKilled)); yield return(followAndAttack); yield break; }
public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false) { Thing searcherThing = searcher.Thing; Pawn searcherPawn = searcher as Pawn; Verb verb = searcher.CurrentEffectiveVerb; if (verb == null) { Log.Error("BestAttackTarget with " + searcher + " who has no attack verb."); return(null); } bool onlyTargetMachines = verb != null && verb.IsEMP(); float minDistanceSquared = 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 (minDistanceSquared > 0.0 && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistanceSquared) { return(false); } if (maxTravelRadiusFromLocus < 9999.0 && (float)(thing.Position - locus).LengthHorizontalSquared > maxLocusDistSquared) { return(false); } if (!searcherThing.HostileTo(thing)) { return(false); } if (validator != null && !validator(thing)) { return(false); } if ((flags & TargetScanFlags.NeedLOSToAll) != 0 && !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 && t.ThreatDisabled()) { return(false); } Pawn pawn2 = t as Pawn; if (onlyTargetMachines && pawn2 != null && pawn2.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; CellRect.CellRectIterator iterator = thing.OccupiedRect().GetIterator(); while (!iterator.Done()) { if (iterator.Current.Fogged(thing.Map)) { iterator.MoveNext(); continue; } flag2 = true; break; } if (!flag2) { return(false); } } return(true); }; if (AttackTargetFinder.HasRangedAttack(searcher)) { AttackTargetFinder.tmpTargets.Clear(); AttackTargetFinder.tmpTargets.AddRange(searcherThing.Map.attackTargetsCache.GetPotentialTargetsFor(searcher)); if ((flags & TargetScanFlags.NeedReachable) != 0) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && AttackTargetFinder.CanReach(searcherThing, t.Thing, canBash)); } bool flag = false; if (searcherThing.Faction != Faction.OfPlayer) { for (int i = 0; i < AttackTargetFinder.tmpTargets.Count; i++) { IAttackTarget attackTarget = AttackTargetFinder.tmpTargets[i]; if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && AttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb)) { flag = true; break; } } } IAttackTarget result; if (flag) { AttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x)); result = AttackTargetFinder.GetRandomShootingTargetByScore(AttackTargetFinder.tmpTargets, searcher, verb); } else { Predicate <Thing> validator2 = ((flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) == TargetScanFlags.None || (flags & TargetScanFlags.NeedReachable) != 0) ? ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t))) : ((Predicate <Thing>)((Thing t) => innerValidator((IAttackTarget)t) && (AttackTargetFinder.CanReach(searcherThing, t, canBash) || AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb)))); result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, AttackTargetFinder.tmpTargets, maxDist, validator2, null); } AttackTargetFinder.tmpTargets.Clear(); return(result); } if (searcherPawn != null && searcherPawn.mindState.duty != null && searcherPawn.mindState.duty.radius > 0.0 && !searcherPawn.InMentalState) { Predicate <IAttackTarget> oldValidator2 = innerValidator; innerValidator = delegate(IAttackTarget t) { if (!oldValidator2(t)) { return(false); } if (!t.Thing.Position.InHorDistOf(searcherPawn.mindState.duty.focus.Cell, searcherPawn.mindState.duty.radius)) { return(false); } return(true); }; } IntVec3 root = searcherThing.Position; Map map = searcherThing.Map; ThingRequest thingReq = ThingRequest.ForGroup(ThingRequestGroup.AttackTarget); PathEndMode peMode = PathEndMode.Touch; Pawn pawn = searcherPawn; Danger maxDanger = Danger.Deadly; bool canBash2 = canBash; TraverseParms traverseParams = TraverseParms.For(pawn, maxDanger, TraverseMode.ByPawn, canBash2); float maxDistance = maxDist; Predicate <Thing> validator3 = (Thing x) => innerValidator((IAttackTarget)x); int searchRegionsMax = (!(maxDist > 800.0)) ? 40 : (-1); IAttackTarget attackTarget2 = (IAttackTarget)GenClosest.ClosestThingReachable(root, map, thingReq, peMode, traverseParams, maxDistance, validator3, null, 0, searchRegionsMax, false, RegionType.Set_Passable, false); if (attackTarget2 != null && PawnUtility.ShouldCollideWithPawns(searcherPawn)) { IAttackTarget attackTarget3 = AttackTargetFinder.FindBestReachableMeleeTarget(innerValidator, searcherPawn, maxDist, canBash); if (attackTarget3 != null) { root = searcherPawn.Position - attackTarget2.Thing.Position; float lengthHorizontal = root.LengthHorizontal; float lengthHorizontal2 = (searcherPawn.Position - attackTarget3.Thing.Position).LengthHorizontal; if (Mathf.Abs(lengthHorizontal - lengthHorizontal2) < 50.0) { attackTarget2 = attackTarget3; } } } return(attackTarget2); }
public override IEnumerable <IntVec3> PotentialWorkCellsGlobal(Pawn pawn) { Danger maxDanger = pawn.NormalMaxDanger(); List <Building> bList = pawn.Map.listerBuildings.allBuildingsColonist; for (int i = 0; i < bList.Count; i++) { Building_PlantGrower b = bList[i] as Building_PlantGrower; if (b != null) { if (this.ExtraRequirements(b, pawn)) { if (!b.IsForbidden(pawn)) { if (pawn.CanReach(b, PathEndMode.OnCell, maxDanger, false, TraverseMode.ByPawn)) { if (!b.IsBurning()) { CellRect.CellRectIterator cri = b.OccupiedRect().GetIterator(); while (!cri.Done()) { yield return(cri.Current); cri.MoveNext(); } WorkGiver_Grower.wantedPlantDef = null; } } } } } } WorkGiver_Grower.wantedPlantDef = null; List <Zone> zonesList = pawn.Map.zoneManager.AllZones; for (int j = 0; j < zonesList.Count; j++) { Zone_Growing growZone = zonesList[j] as Zone_Growing; if (growZone != null) { if (growZone.cells.Count == 0) { Log.ErrorOnce("Grow zone has 0 cells: " + growZone, -563487, false); } else if (this.ExtraRequirements(growZone, pawn)) { if (!growZone.ContainsStaticFire) { if (pawn.CanReach(growZone.Cells[0], PathEndMode.OnCell, maxDanger, false, TraverseMode.ByPawn)) { for (int k = 0; k < growZone.cells.Count; k++) { yield return(growZone.cells[k]); } WorkGiver_Grower.wantedPlantDef = null; } } } } } WorkGiver_Grower.wantedPlantDef = null; }
public static IAttackTarget BestAttackTarget(IAttackTargetSearcher searcher, TargetScanFlags flags, Predicate <Thing> validator = null, float minDist = 0f, float maxDist = 9999f, IntVec3 locus = default(IntVec3), float maxTravelRadiusFromLocus = 3.40282347E+38f, bool canBash = false) { Thing searcherThing = searcher.Thing; Pawn searcherPawn = searcher as Pawn; Verb verb = searcher.CurrentEffectiveVerb; if (verb == null) { //Log.Error("BestAttackTarget with " + searcher + " who has no attack verb."); return(null); } bool onlyTargetMachines = verb != null && verb.IsEMP(); float minDistanceSquared = 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 (minDistanceSquared > 0f && (float)(searcherThing.Position - thing.Position).LengthHorizontalSquared < minDistanceSquared) { 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 ((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); } Pawn pawn = t as Pawn; if (onlyTargetMachines && pawn != null && 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; CellRect.CellRectIterator iterator = thing.OccupiedRect().GetIterator(); while (!iterator.Done()) { if (!iterator.Current.Fogged(thing.Map)) { flag2 = true; break; } iterator.MoveNext(); } if (!flag2) { return(false); } } return(true); }; if (ARA_AttackTargetFinder.HasRangedAttack(searcher)) { //Log.Warning("Finder: Range detected. Verb is " + verb); //Log.Warning("Finder: Pawn " + searcherPawn.Faction); ARA_AttackTargetFinder.tmpTargets.Clear(); //This needs to be fixed. Can't use searcherThing. Doing this the hard way. //Set request for all attackable. ThingRequest thingReq = ThingRequest.ForGroup(ThingRequestGroup.AttackTarget); IEnumerable <Thing> searchSet = searcherThing.Map.listerThings.ThingsMatching(thingReq); foreach (IAttackTarget iTarget in searchSet) { ARA_AttackTargetFinder.tmpTargets.Add(iTarget); } if ((byte)(flags & TargetScanFlags.NeedReachable) != 0) { Predicate <IAttackTarget> oldValidator = innerValidator; innerValidator = ((IAttackTarget t) => oldValidator(t) && ARA_AttackTargetFinder.CanReach(searcherThing, t.Thing, canBash)); } bool flag = false; if (searcherThing.Faction != Faction.OfPlayer) { //Log.Warning("Finder: Target available : " + ARA_AttackTargetFinder.tmpTargets.Count); for (int i = 0; i < ARA_AttackTargetFinder.tmpTargets.Count; i++) { IAttackTarget attackTarget = ARA_AttackTargetFinder.tmpTargets[i]; if (attackTarget.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) && innerValidator(attackTarget) && ARA_AttackTargetFinder.CanShootAtFromCurrentPosition(attackTarget, searcher, verb)) { //Log.Warning("Finder: flag is true"); flag = true; break; } } } IAttackTarget result; if (flag) { //Log.Warning("Finder: FlagTrue result"); ARA_AttackTargetFinder.tmpTargets.RemoveAll((IAttackTarget x) => !x.Thing.Position.InHorDistOf(searcherThing.Position, maxDist) || !innerValidator(x)); //Log.Warning("Finder: Target Avaliable : " + ARA_AttackTargetFinder.tmpTargets.Count); result = ARA_AttackTargetFinder.GetRandomShootingTargetByScore(ARA_AttackTargetFinder.tmpTargets, searcher, verb); } else { Predicate <Thing> validator2; if ((byte)(flags & TargetScanFlags.NeedReachableIfCantHitFromMyPos) != 0 && (byte)(flags & TargetScanFlags.NeedReachable) == 0) { //Log.Warning("Finder: Needs reachable"); validator2 = ((Thing t) => innerValidator((IAttackTarget)t) && (ARA_AttackTargetFinder.CanReach(searcherThing, t, canBash) || ARA_AttackTargetFinder.CanShootAtFromCurrentPosition((IAttackTarget)t, searcher, verb))); } else { //Log.Warning("Finder: Running normal validator"); validator2 = ((Thing t) => innerValidator((IAttackTarget)t)); } result = (IAttackTarget)GenClosest.ClosestThing_Global(searcherThing.Position, ARA_AttackTargetFinder.tmpTargets, maxDist, validator2, null); } ARA_AttackTargetFinder.tmpTargets.Clear(); //Log.Warning("Trying to return result " + result); return(result); } //Log.Warning("Returning Null"); return(null); }