/// <summary> /// gets all targets from the given raycast and store them in the given buffer. /// </summary> /// <param name="map">The map.</param> /// <param name="p0">The p0.</param> /// <param name="p1">The p1.</param> /// <param name="buffer">The buffer.</param> /// <param name="targets">The targets.</param> /// <returns>the number of hits</returns> public static int RaycastAllNoAlloc([NotNull] Map map, IntVec3 p0, IntVec3 p1, [NotNull] RWRaycastHit[] buffer, RaycastTargets targets) { var p0IV2 = p0.ToIntVec2; var p1IV2 = p1.ToIntVec2; var dir = p1IV2.ToVector2() - p0IV2.ToVector2(); return(RaycastAllNoAlloc(map, p0IV2, dir, buffer, targets)); }
/// <summary> /// gets all targets from the given raycast and store them in the given buffer. /// </summary> /// <param name="map">The map.</param> /// <param name="cell">The cell.</param> /// <param name="dir">The dir.</param> /// <param name="buffer">The buffer.</param> /// <param name="targets">The targets.</param> /// <returns>the number of hits</returns> public static int RaycastAllNoAlloc([NotNull] Map map, IntVec2 cell, Vector2 dir, [NotNull] RWRaycastHit[] buffer, RaycastTargets targets) { if (map == null) { throw new ArgumentNullException(nameof(map)); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } var dSqr = dir.sqrMagnitude; if (Math.Abs(dSqr) < 0.01f) { Log.Warning($"trying to raycast with very small dir {dir}"); return(0); } if (debug) { debugBuilder.Clear(); } var dHat = dir.normalized; var cellPos = cell.ToVector2(); var eCell = new IntVec2(cellPos + dir); var curPos = cellPos; var curCell = cell; int hits = 0; if (debug) { debugBuilder.AppendLine($"curPos:{curCell} dir:{dir} dHat:{dHat} eCell{eCell}"); } _testSet.Clear(); while (hits < buffer.Length && eCell != curCell && (curCell - cell).ToVector2().sqrMagnitude < dSqr) { var lPos = curPos; curPos += dHat; var tCell = new IntVec2(curPos); if (debug) { debugBuilder.AppendLine($"testing {tCell} from {lPos} + {dHat} : curCell:{curCell}"); } if (tCell != curCell) { if (!tCell.ToIntVec3.InBounds(map)) { break; } TestCell(map, tCell, targets, buffer, ref hits); curCell = tCell; } } if (debug) { if (hits > 0) { debugBuilder.AppendLine($"hits:[{hits}:{string.Join(",", buffer.Take(hits))}]"); } else { debugBuilder.AppendLine("no hits"); } Log.Message(debugBuilder.ToString()); } return(hits); }
private static void TestCell(Map map, IntVec2 cell, RaycastTargets targets, RWRaycastHit[] buffer, ref int hits) { var thingGrid = map.thingGrid; var things = thingGrid.ThingsListAt(cell.ToIntVec3); if (things == null || things.Count == 0) { return; } foreach (Thing thing in things) { if (_testSet.Contains(thing)) { continue; } else { _testSet.Add(thing); } if (debug) { debugBuilder.AppendLine($"testing cell:{cell} found {thing.Label}"); } if (targets == RaycastTargets.All) { buffer[hits] = new RWRaycastHit() { hitThing = thing }; hits++; } else { if ((targets & RaycastTargets.Impassible) != 0 && thing.def?.passability == Traversability.Impassable) { buffer[hits] = new RWRaycastHit() { hitThing = thing }; hits++; } else if ((targets & RaycastTargets.Walls) != 0 && thing.def == ThingDefOf.Wall) { buffer[hits] = new RWRaycastHit() { hitThing = thing }; hits++; } else if ((targets & RaycastTargets.Pawns) != 0 && thing is Pawn p) { buffer[hits] = new RWRaycastHit() { hitThing = thing, hitPawn = p }; hits++; } } if (hits == buffer.Length) { break; } } }