コード例 #1
0
        /// <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));
        }
コード例 #2
0
        /// <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);
        }
コード例 #3
0
        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;
                }
            }
        }