public static bool TryFindCastPosition(CastPositionRequest newReq, out IntVec3 dest) { req = newReq; casterLoc = req.caster.Position; targetLoc = req.target.Position; verb = req.verb; avoidGrid = newReq.caster.GetAvoidGrid(onlyIfLordAllows: false); if (verb == null) { Log.Error(req.caster + " tried to find casting position without a verb."); dest = IntVec3.Invalid; return(false); } if (req.maxRegions > 0) { Region region = casterLoc.GetRegion(req.caster.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, newReq.maxRegions, inRadiusMark); if (req.maxRangeFromLocus > 0.01f) { Region locusReg = req.locus.GetRegion(req.caster.Map); if (locusReg == null) { Log.Error("locus " + req.locus + " has no region"); dest = IntVec3.Invalid; return(false); } if (locusReg.mark != inRadiusMark) { inRadiusMark = Rand.Int; RegionTraverser.BreadthFirstTraverse(region, null, delegate(Region r) { r.mark = inRadiusMark; req.maxRegions++; return(r == locusReg); }); } } } CellRect cellRect = CellRect.WholeMap(req.caster.Map); if (req.maxRangeFromCaster > 0.01f) { int num = Mathf.CeilToInt(req.maxRangeFromCaster); CellRect otherRect = new CellRect(casterLoc.x - num, casterLoc.z - num, num * 2 + 1, num * 2 + 1); cellRect.ClipInsideRect(otherRect); } int num2 = Mathf.CeilToInt(req.maxRangeFromTarget); CellRect otherRect2 = new CellRect(targetLoc.x - num2, targetLoc.z - num2, num2 * 2 + 1, num2 * 2 + 1); cellRect.ClipInsideRect(otherRect2); if (req.maxRangeFromLocus > 0.01f) { int num3 = Mathf.CeilToInt(req.maxRangeFromLocus); CellRect otherRect3 = new CellRect(targetLoc.x - num3, targetLoc.z - num3, num3 * 2 + 1, num3 * 2 + 1); cellRect.ClipInsideRect(otherRect3); } bestSpot = IntVec3.Invalid; bestSpotPref = 0.001f; maxRangeFromCasterSquared = req.maxRangeFromCaster * req.maxRangeFromCaster; maxRangeFromTargetSquared = req.maxRangeFromTarget * req.maxRangeFromTarget; maxRangeFromLocusSquared = req.maxRangeFromLocus * req.maxRangeFromLocus; rangeFromTarget = (req.caster.Position - req.target.Position).LengthHorizontal; rangeFromTargetSquared = (req.caster.Position - req.target.Position).LengthHorizontalSquared; optimalRangeSquared = verb.verbProps.range * 0.8f * (verb.verbProps.range * 0.8f); EvaluateCell(req.caster.Position); if ((double)bestSpotPref >= 1.0) { dest = req.caster.Position; return(true); } float slope = -1f / CellLine.Between(req.target.Position, req.caster.Position).Slope; CellLine cellLine = new CellLine(req.target.Position, slope); bool flag = cellLine.CellIsAbove(req.caster.Position); foreach (IntVec3 item in cellRect) { if (cellLine.CellIsAbove(item) == flag && cellRect.Contains(item)) { EvaluateCell(item); } } if (bestSpot.IsValid && bestSpotPref > 0.33f) { dest = bestSpot; return(true); } foreach (IntVec3 item2 in cellRect) { if (cellLine.CellIsAbove(item2) != flag && cellRect.Contains(item2)) { EvaluateCell(item2); } } if (bestSpot.IsValid) { dest = bestSpot; return(true); } dest = casterLoc; return(false); }
// 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); }
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(); if (CastPositionFinder.verb == null) { Log.Error(CastPositionFinder.req.caster + " tried to find casting position without a verb."); dest = IntVec3.Invalid; return(false); } if (CastPositionFinder.req.maxRegionsRadius > 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."); dest = IntVec3.Invalid; return(false); } CastPositionFinder.inRadiusMark = Rand.Int; RegionTraverser.MarkRegionsBFS(region, null, newReq.maxRegionsRadius, CastPositionFinder.inRadiusMark, RegionType.Set_Passable); if (CastPositionFinder.req.maxRangeFromLocus > 0.01f) { Region region2 = CastPositionFinder.req.locus.GetRegion(CastPositionFinder.req.caster.Map, RegionType.Set_Passable); if (region2 == null) { Log.Error("locus " + CastPositionFinder.req.locus + " has no region"); dest = IntVec3.Invalid; return(false); } if (region2.mark != CastPositionFinder.inRadiusMark) { Log.Error(string.Concat(new object[] { CastPositionFinder.req.caster, " can't possibly get to locus ", CastPositionFinder.req.locus, " as it's not in a maxRegionsRadius of ", CastPositionFinder.req.maxRegionsRadius, ". Overriding maxRegionsRadius." })); CastPositionFinder.req.maxRegionsRadius = 0; } } } 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; return(true); } 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); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (cellLine.CellIsAbove(current) == flag && cellRect.Contains(current)) { CastPositionFinder.EvaluateCell(current); } iterator.MoveNext(); } if (CastPositionFinder.bestSpot.IsValid && CastPositionFinder.bestSpotPref > 0.33f) { dest = CastPositionFinder.bestSpot; return(true); } CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { IntVec3 current2 = iterator2.Current; if (cellLine.CellIsAbove(current2) != flag && cellRect.Contains(current2)) { CastPositionFinder.EvaluateCell(current2); } iterator2.MoveNext(); } if (CastPositionFinder.bestSpot.IsValid) { dest = CastPositionFinder.bestSpot; return(true); } dest = CastPositionFinder.casterLoc; return(false); }
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); }