Exemplo n.º 1
0
        // servuo
        public static bool CheckMovement(Mobile mobile, Position loc, Direction d, out sbyte newZ, bool forceOK = false)
        {
            Facet map = World.Map;

            if (map == null)
            {
                newZ = 0;

                return(true);
            }

            int  xStart = loc.X;
            int  yStart = loc.Y;
            int  xForward = xStart, yForward = yStart;
            int  xRight = xStart, yRight = yStart;
            int  xLeft = xStart, yLeft = yStart;
            bool checkDiagonals = ((int)d & 0x1) == 0x1;

            OffsetXY(d, ref xForward, ref yForward);
            OffsetXY((Direction)(((int)d - 1) & 0x7), ref xLeft, ref yLeft);
            OffsetXY((Direction)(((int)d + 1) & 0x7), ref xRight, ref yRight);

            if (xForward < 0 || yForward < 0 || xForward >= IO.Resources.Map.MapsDefaultSize[map.Index][0] || yForward >= IO.Resources.Map.MapsDefaultSize[map.Index][1])
            {
                newZ = 0;

                return(false);
            }

            List <IDynamicItem> itemsStart   = _pool[0];
            List <IDynamicItem> itemsForward = _pool[1];
            List <IDynamicItem> itemsLeft    = _pool[2];
            List <IDynamicItem> itemsRight   = _pool[3];
            const long          REQ_FLAGS    = IMPASSABLE_SURFACE;

            if (checkDiagonals)
            {
                Tile tileStart   = map.GetTile(xStart, yStart);
                Tile tileForward = map.GetTile(xForward, yForward);
                Tile tileLeft    = map.GetTile(xLeft, yLeft);
                Tile tileRight   = map.GetTile(xRight, yRight);

                if (tileForward == null || tileStart == null || tileLeft == null || tileRight == null)
                {
                    newZ = loc.Z;

                    return(false);
                }

                List <Tile> tiles = _tiles;
                tiles.Add(tileStart);
                tiles.Add(tileForward);
                tiles.Add(tileLeft);
                tiles.Add(tileRight);

                for (int i = 0; i < tiles.Count; ++i)
                {
                    Tile tile = tiles[i];

                    for (int j = 0; j < tile.ObjectsOnTiles.Count; ++j)
                    {
                        GameObject entity = tile.ObjectsOnTiles[j];

                        // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable)
                        //     continue;

                        if (entity is IDynamicItem item)
                        {
                            if (((long)item.ItemData.Flags & REQ_FLAGS) == 0)
                            {
                                continue;
                            }

                            if (tile == tileStart && item.IsAtWorld(xStart, yStart) && item.Graphic < 0x4000)
                            {
                                itemsStart.Add(item);
                            }
                            else if (tile == tileForward && item.IsAtWorld(xForward, yForward) && item.Graphic < 0x4000)
                            {
                                itemsForward.Add(item);
                            }
                            else if (tile == tileLeft && item.IsAtWorld(xLeft, yLeft) && item.Graphic < 0x4000)
                            {
                                itemsLeft.Add(item);
                            }
                            else if (tile == tileRight && item.IsAtWorld(xRight, yRight) && item.Graphic < 0x4000)
                            {
                                itemsRight.Add(item);
                            }
                        }
                    }
                }

                if (_tiles.Count > 0)
                {
                    _tiles.Clear();
                }
            }
            else
            {
                Tile tileStart   = map.GetTile(xStart, yStart);
                Tile tileForward = map.GetTile(xForward, yForward);

                if (tileForward == null || tileStart == null)
                {
                    newZ = loc.Z;

                    return(false);
                }

                if (tileStart == tileForward)
                {
                    for (int i = 0; i < tileStart.ObjectsOnTiles.Count; i++)
                    {
                        GameObject entity = tileStart.ObjectsOnTiles[i];

                        // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable)
                        //     continue;

                        if (entity is IDynamicItem item)
                        {
                            if (((long)item.ItemData.Flags & REQ_FLAGS) == 0)
                            {
                                continue;
                            }

                            if (item.IsAtWorld(xStart, yStart) && item.Graphic < 0x4000)
                            {
                                itemsStart.Add(item);
                            }
                            else if (item.IsAtWorld(xForward, yForward) && item.Graphic < 0x4000)
                            {
                                itemsForward.Add(item);
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < tileForward.ObjectsOnTiles.Count; i++)
                    {
                        GameObject entity = tileForward.ObjectsOnTiles[i];

                        // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable)
                        //     continue;

                        if (entity is IDynamicItem item)
                        {
                            if (((long)item.ItemData.Flags & REQ_FLAGS) == 0)
                            {
                                continue;
                            }
                            if (item.IsAtWorld(xForward, yForward) && item.Graphic < 0x4000)
                            {
                                itemsForward.Add(item);
                            }
                        }
                    }

                    for (int i = 0; i < tileStart.ObjectsOnTiles.Count; i++)
                    {
                        GameObject entity = tileStart.ObjectsOnTiles[i];

                        // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable)
                        //     continue;

                        if (entity is IDynamicItem item)
                        {
                            if (((long)item.ItemData.Flags & REQ_FLAGS) == 0)
                            {
                                continue;
                            }
                            if (item.IsAtWorld(xStart, yStart) && item.Graphic < 0x4000)
                            {
                                itemsStart.Add(item);
                            }
                        }
                    }
                }
            }

            GetStartZ(mobile, loc, itemsStart, out sbyte startZ, out sbyte startTop);
            bool moveIsOk = Check(mobile, itemsForward, xForward, yForward, startTop, startZ, out newZ) || forceOK;

            if (moveIsOk && checkDiagonals)
            {
                if (!Check(mobile, itemsLeft, xLeft, yLeft, startTop, startZ, out sbyte hold) || !Check(mobile, itemsRight, xRight, yRight, startTop, startZ, out hold))
                {
                    moveIsOk = false;
                }
            }

            for (int i = 0; i < (checkDiagonals ? 4 : 2); i++)
            {
                if (_pool[i].Count > 0)
                {
                    _pool[i].Clear();
                }
            }
            if (!moveIsOk)
            {
                newZ = startZ;
            }

            return(moveIsOk);
        }