public static IntVec3 BestOrderedGotoDestNear(IntVec3 root, Pawn searcher) { Map map = searcher.Map; Predicate <IntVec3> predicate = (IntVec3 c) => map.pawnDestinationReservationManager.CanReserve(c, searcher) && c.Standable(map) && searcher.CanReach(c, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn); if (predicate(root)) { return(root); } int num = 1; IntVec3 result = default(IntVec3); float num2 = -1000f; bool flag = false; while (true) { IntVec3 intVec = root + GenRadial.RadialPattern[num]; if (predicate(intVec)) { float num3 = CoverUtility.TotalSurroundingCoverScore(intVec, map); if (num3 > num2) { num2 = num3; result = intVec; flag = true; } } if (num >= 8 && flag) { break; } num++; } return(result); }
public static IntVec3 BestOrderedGotoDestNear(IntVec3 root, Pawn searcher) { Map map = searcher.Map; Predicate <IntVec3> predicate = delegate(IntVec3 c) { if (!map.pawnDestinationReservationManager.CanReserve(c, searcher, true) || !c.Standable(map) || !searcher.CanReach(c, PathEndMode.OnCell, Danger.Deadly, false, TraverseMode.ByPawn)) { return(false); } List <Thing> thingList = c.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Pawn pawn = thingList[i] as Pawn; if (pawn != null && pawn != searcher && pawn.RaceProps.Humanlike) { return(false); } } return(true); }; if (predicate(root)) { return(root); } int num = 1; IntVec3 result = default(IntVec3); float num2 = -1000f; bool flag = false; int num3 = GenRadial.NumCellsInRadius(30f); while (true) { IntVec3 intVec = root + GenRadial.RadialPattern[num]; if (predicate(intVec)) { float num4 = CoverUtility.TotalSurroundingCoverScore(intVec, map); if (num4 > num2) { num2 = num4; result = intVec; flag = true; } } if (num >= 8 && flag) { break; } num++; if (num >= num3) { goto Block_6; } } return(result); Block_6: return(searcher.Position); }
private static IntVec3 GetRestSpot(IntVec3 originCell, Danger maxDanger, Pawn me) { if (!(me is PawnConverted)) { return(originCell); } var currentDanger = me.Position.GetDangerFor(me); var danger = (Danger)Math.Max((int)maxDanger, (int)currentDanger); Predicate <IntVec3> validator = c => c.Standable() && Find.RoofGrid.Roofed(c) && CoverUtility.TotalSurroundingCoverScore(c) > 2.5f && !NextToDoor(c, me) && originCell.CanReach(c, PathEndMode.OnCell, TraverseMode.PassDoors, danger); if (validator(originCell) && InRange(originCell, me, 20)) { return(originCell); } for (int i = 0; i < 50; i++) { Thing thing = GetRandom(Find.ListerBuildings.allBuildingsColonist); if (thing == null) { thing = GetRandom(Find.ListerBuildings.allBuildingsColonistCombatTargets); } if (thing == null) { thing = GetRandom(Find.ListerPawns.FreeColonists); } if (thing == null) { thing = GetRandom(Find.ListerPawns.ColonistsAndPrisoners); } if (thing == null) { break; } IntVec3 result; if (CellFinder.TryFindRandomCellNear(thing.Position, 10, validator, out result)) { return(result); } } Predicate <IntVec3> simpleValidator = c => c.Standable() && CoverUtility.TotalSurroundingCoverScore(c) > 1 && !NextToDoor(c, me) && originCell.CanReach(c, PathEndMode.OnCell, TraverseMode.PassDoors, danger); IntVec3 randomCell; return(CellFinder.TryFindRandomCellNear(originCell, 20, simpleValidator, out randomCell) ? randomCell : originCell); }
private static float CastPositionPreference(IntVec3 c) { bool flag = true; List <Thing> list = req.caster.Map.thingGrid.ThingsListAtFast(c); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; Fire fire = thing as Fire; if (fire != null && fire.parent == null) { return(-1f); } if (thing.def.passability == Traversability.PassThroughOnly) { flag = false; } } float num = 0.3f; if (req.caster.kindDef.aiAvoidCover) { num += 8f - CoverUtility.TotalSurroundingCoverScore(c, req.caster.Map); } if (req.wantCoverFromTarget) { num += CoverUtility.CalculateOverallBlockChance(c, req.target.Position, req.caster.Map) * 0.55f; } float num2 = (req.caster.Position - c).LengthHorizontal; if (rangeFromTarget > 100f) { num2 -= rangeFromTarget - 100f; if (num2 < 0f) { num2 = 0f; } } num *= Mathf.Pow(0.967f, num2); float num3 = 1f; rangeFromTargetToCellSquared = (c - req.target.Position).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; } return(num); }
// 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 void ScatterAt(IntVec3 c, Map map, GenStepParams parms, int stackCount = 1) { Log.Message("Horrors: Initiating Hive Spawn"); var noiseArray = new double[map.Size.x, map.Size.z]; var caveNoise = GeneratePerlinNoiseForCaves(map); Log.Message("Horrors: Noise Generated Successfully"); Log.Message("Horrors: Stepping through noise grid"); for (var i = 0; i < map.Size.x; i++) { for (var n = 0; n < map.Size.z; n++) { noiseArray[i, n] = caveNoise.layeredNoise(Convert.ToDouble(i) / 10, Convert.ToDouble(n) / 10); } } Log.Message("Horrors: Digging out tunnels"); for (var i = 0; i < map.Size.x; i++) { for (var n = 0; n < map.Size.z; n++) { var loc = new IntVec3(i, 0, n); if (CoverUtility.TotalSurroundingCoverScore(loc, map) > 0.2) { GenSpawn.Spawn(ThingDef.Named("HorrorWeb"), loc, map); } if (!(noiseArray[i, n] > 0.5)) { continue; } if (loc.GetEdifice(map) != null) { loc.GetEdifice(map).Destroy(DestroyMode.KillFinalize); } if (map.fogGrid.IsFogged(loc)) { map.fogGrid.Unfog(loc); } // map.terrainGrid.SetTerrain(loc, TerrainDef.Named("FloorWebs")); } } Log.Message("Horrors: Generating Hive Rect"); var rect = new CellRect(0, 0, 0, 0); Faction faction; if (map.info.parent?.Faction == null || map.info.parent.Faction == Faction.OfPlayer) { faction = Find.FactionManager.RandomEnemyFaction(); } else { faction = map.info.parent.Faction; } rect = rect.ExpandedBy(4); rect.ClipInsideMap(map); var resolveParams = default(ResolveParams); resolveParams.rect = rect; resolveParams.faction = faction; BaseGen.globalSettings.map = map; Log.Message("Horrors: Validating Spawns"); bool Validator(IntVec3 p) { return(DropCellFinder.IsGoodDropSpot(p, map, true, true)); } // Pawns var queenPawn = PawnGenerator.GeneratePawn(PawnKindDef.Named("Pirate"), faction); Log.Message("Horrors: Spawning Sinkhole"); CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out var cellReturned); GenSpawn.Spawn(ThingDef.Named("SinkHole"), map.Center, map); Log.Message("Horrors: Spawning Sinkhole"); CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned); GenSpawn.Spawn(ThingDef.Named("SinkHole"), cellReturned, map); Log.Message("Horrors: Spawning Sinkhole"); CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned); GenSpawn.Spawn(ThingDef.Named("SinkHole"), cellReturned, map); Log.Message("Horrors: Spawning Sinkhole"); CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned); GenSpawn.Spawn(ThingDef.Named("SinkHole"), cellReturned, map); Log.Message("Horrors: Spawning Sinkhole"); CellFinder.TryFindRandomCellNear(map.Center, map, 20, Validator, out cellReturned); var queen = GenSpawn.Spawn(queenPawn, cellReturned, map); var pawnToSpawn = PawnGenerator.GeneratePawn(PawnKindDef.Named("BroodLord"), faction); GenSpawn.Spawn(pawnToSpawn, cellReturned, map); pawnToSpawn.training.Train(TrainableDefOf.Obedience, (Pawn)queen); }
private static float CastPositionPreference(IntVec3 c) { bool flag = true; List <Thing> list = CastPositionFinder.req.caster.Map.thingGrid.ThingsListAtFast(c); for (int i = 0; i < list.Count; i++) { Thing thing = list[i]; Fire fire = thing as Fire; if (fire != null && fire.parent == null) { return(-1f); } if (thing.def.passability == Traversability.PassThroughOnly) { flag = false; } } float num = 0.3f; if (CastPositionFinder.req.caster.kindDef.aiAvoidCover) { num = (float)(num + (8.0 - CoverUtility.TotalSurroundingCoverScore(c, CastPositionFinder.req.caster.Map))); } if (CastPositionFinder.req.wantCoverFromTarget) { num += CoverUtility.CalculateOverallBlockChance(c, CastPositionFinder.req.target.Position, CastPositionFinder.req.caster.Map); } float num2 = (CastPositionFinder.req.caster.Position - c).LengthHorizontal; if (CastPositionFinder.rangeFromTarget > 100.0) { num2 = (float)(num2 - (CastPositionFinder.rangeFromTarget - 100.0)); if (num2 < 0.0) { num2 = 0f; } } num *= Mathf.Pow(0.967f, num2); float num3 = 1f; CastPositionFinder.rangeFromTargetToCellSquared = (float)(c - CastPositionFinder.req.target.Position).LengthHorizontalSquared; float num4 = Mathf.Abs(CastPositionFinder.rangeFromTargetToCellSquared - CastPositionFinder.optimalRangeSquared) / CastPositionFinder.optimalRangeSquared; num4 = (float)(1.0 - num4); num4 = (float)(0.699999988079071 + 0.30000001192092896 * num4); num3 *= num4; if (CastPositionFinder.rangeFromTargetToCellSquared < 25.0) { num3 = (float)(num3 * 0.5); } num *= num3; if (CastPositionFinder.rangeFromCasterToCellSquared > CastPositionFinder.rangeFromTargetSquared) { num = (float)(num * 0.40000000596046448); } if (!flag) { num = (float)(num * 0.20000000298023224); } return(num); }
protected override bool Satisfied(Pawn pawn) { var coverValue = CoverUtility.TotalSurroundingCoverScore(pawn.Position, pawn.Map); return(coverValue >= min); }