Exemple #1
0
    public void GetTrimmedRange(LocAndOffsets originLoc, LocAndOffsets tgtLoc, float radiusInch, float maxRangeInch,
                                float incrementInches)
    {
        trimmedRangeInches = maxRangeInch;

        using var rayPkt      = new RaycastPacket();
        rayPkt.sourceObj      = null;
        rayPkt.origin         = originLoc;
        rayPkt.rayRangeInches = maxRangeInch;
        rayPkt.targetLoc      = tgtLoc;
        rayPkt.radius         = radiusInch;
        rayPkt.flags          = RaycastFlag.ExcludeItemObjects | RaycastFlag.HasRadius | RaycastFlag.HasRangeLimit;
        rayPkt.Raycast();

        foreach (var rayRes in rayPkt)
        {
            if (rayRes.obj == null)
            {
                var dist = rayPkt.origin.DistanceTo(rayRes.loc);
                if (dist < trimmedRangeInches)
                {
                    trimmedRangeInches = dist;
                }
            }
        }

        if (incrementInches > 0)
        {
            trimmedRangeInches = MathF.Ceiling(trimmedRangeInches / incrementInches) * incrementInches;
        }
    }
Exemple #2
0
    // must have valid trimmedRangeInches value; must also free preexisting ObjectList!
    public void GetTargetsInPath(LocAndOffsets originLoc, LocAndOffsets tgtLoc, float radiusInch)
    {
        using var rayPkt      = new RaycastPacket();
        rayPkt.sourceObj      = null;
        rayPkt.origin         = originLoc;
        rayPkt.rayRangeInches = trimmedRangeInches;
        rayPkt.targetLoc      = tgtLoc;
        rayPkt.radius         = radiusInch;
        rayPkt.flags          = RaycastFlag.ExcludeItemObjects | RaycastFlag.HasRadius | RaycastFlag.HasRangeLimit;
        rayPkt.Raycast();

        if (rayPkt.Count > 0)
        {
            result.objList = new List <GameObject>();

            foreach (var resultItem in rayPkt)
            {
                if (resultItem.obj != null)
                {
                    result.objList.Add(resultItem.obj);
                }
            }

            // is this ok? what if no ObjectHandles.were found? (this is in the original)
            result.flags |= PickerResultFlags.PRF_HAS_MULTI_OBJ;
        }
    }
    private int SearchInStraightLine(ref AnimPathData boPkt)
    {
        if (boPkt.srcLoc.EstimateDistance(boPkt.destLoc) > 32)
        {
            return(0);
        }

        var regardSinks = (boPkt.flags & AnimPathDataFlags.UNK_8) != 0;

        MapObjectSystem.ObstacleFlag flags = 0;
        if ((boPkt.flags & AnimPathDataFlags.CantOpenDoors) != 0)
        {
            flags = MapObjectSystem.ObstacleFlag.UNK_1;
        }

        if ((boPkt.flags & AnimPathDataFlags.UNK_4) != 0)
        {
            flags |= MapObjectSystem.ObstacleFlag.UNK_2;
        }

        if ((boPkt.flags & AnimPathDataFlags.UNK10) != 0)
        {
            flags |= MapObjectSystem.ObstacleFlag.UNK_4;
        }

        var curLoc = boPkt.srcLoc;

        int i;

        for (i = 0; i < boPkt.size; i++)
        {
            if (curLoc == boPkt.destLoc)
            {
                break;
            }

            var direction = curLoc.GetCompassDirection(boPkt.destLoc);
            boPkt.deltas[i] = (sbyte)direction;
            var nextLoc      = curLoc.Offset(direction);
            var backoffFlags = boPkt.flags;
            if ((backoffFlags & AnimPathDataFlags.UNK40) == 0)
            {
                if (nextLoc == boPkt.destLoc && (backoffFlags & AnimPathDataFlags.UNK_1) != 0)
                {
                    curLoc = nextLoc;
                    continue;
                }

                if (!regardSinks &&
                    (backoffFlags & AnimPathDataFlags.UNK_4000) == 0 &&
                    GameSystems.Tile.IsBlockingOldVersion(nextLoc))
                {
                    break;
                }

                if (GameSystems.MapObject.HasBlockingObjectInDir(boPkt.handle, new LocAndOffsets(curLoc), direction,
                                                                 flags))
                {
                    break;
                }

                if ((boPkt.flags & AnimPathDataFlags.UNK_2000) != 0)
                {
                    using var objIterator = new RaycastPacket();
                    objIterator.flags    |= RaycastFlag.StopAfterFirstFlyoverFound
                                            | RaycastFlag.StopAfterFirstBlockerFound
                                            | RaycastFlag.HasSourceObj
                                            | RaycastFlag.HasRadius;
                    objIterator.targetLoc.location.locx = nextLoc.locx;
                    objIterator.origin = new LocAndOffsets(curLoc);
                    objIterator.targetLoc.location.locy = nextLoc.locy;
                    objIterator.radius    = boPkt.handle.GetRadius() * 0.5f;
                    objIterator.sourceObj = boPkt.handle;
                    if (objIterator.Raycast() > 0)
                    {
                        break;
                    }
                }

                var trap = FindTrapAtLocation(nextLoc);
                if (trap != null && GameSystems.Trap.KnowsAboutDangerousTrap(boPkt.handle, trap))
                {
                    break;
                }

                if ((boPkt.flags & AnimPathDataFlags.UNK400) != 0)
                {
                    if (FindBurningScenery(nextLoc) != null)
                    {
                        break;
                    }
                }
            }

            curLoc = nextLoc;
        }

        // Did not reach the destination
        if (curLoc != boPkt.destLoc)
        {
            boPkt.distTiles = i;
            return(0);
        }

        if ((boPkt.flags & AnimPathDataFlags.UNK_1) != 0)
        {
            return(i - 1);
        }

        return(i);
    }