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