Beispiel #1
0
        private void InitialLoadTiles()
        {
            int px = Position.X;
            int py = Position.Y;

            foreach (MultiComponentList.MultiItem item in m_Components.Items)
            {
                int x = px + item.OffsetX;
                int y = py + item.OffsetY;

                MapTile tile = Map.GetMapTile(x, y);
                if (tile != null)
                {
                    if (tile.ItemExists(item.ItemID, item.OffsetZ))
                    {
                        continue;
                    }

                    StaticItem staticItem = new StaticItem(item.ItemID, 0, 0, Map);
                    if (staticItem.ItemData.IsDoor)
                    {
                        continue;
                    }
                    staticItem.Position.Set(x, y, Z + item.OffsetZ);
                }
            }
        }
Beispiel #2
0
        private void PlaceTilesIntoNewlyLoadedBlock(MapBlock block)
        {
            int px = Position.X;
            int py = Position.Y;

            Rectangle bounds = new Rectangle(block.X * 8, block.Y * 8, 8, 8);

            foreach (MultiComponentList.MultiItem item in m_Components.Items)
            {
                int x = px + item.OffsetX;
                int y = py + item.OffsetY;

                if (bounds.Contains(x, y))
                {
                    // would it be faster to get the tile from the block?
                    MapTile tile = Map.GetMapTile(x, y);
                    if (tile != null)
                    {
                        if (!tile.ItemExists(item.ItemID, item.OffsetZ))
                        {
                            StaticItem staticItem = new StaticItem(item.ItemID, 0, 0, Map);
                            staticItem.Position.Set(x, y, Z + item.OffsetZ);
                        }
                    }
                }
            }
        }
        private static bool IsOk(bool ignoreDoors, int ourZ, int ourTop, StaticItem[] tiles, List <Item> items)
        {
            for (int i = 0; i < tiles.Length; ++i)
            {
                StaticItem check = tiles[i];

                if ((check.ItemData.Flags & ImpassableSurface) != 0) // Impassable || Surface
                {
                    int checkZ   = (int)check.Z;
                    int checkTop = checkZ + check.ItemData.CalcHeight;

                    if (checkTop > ourZ && ourTop > checkZ)
                    {
                        return(false);
                    }
                }
            }

            for (int i = 0; i < items.Count; ++i)
            {
                Item item   = items[i];
                int  itemID = item.ItemID & 0x3FFF;
                UltimaData.ItemData itemData = UltimaData.TileData.ItemData[itemID];
                TileFlag            flags    = itemData.Flags;

                if ((flags & ImpassableSurface) != 0) // Impassable || Surface
                {
                    if (ignoreDoors && ((flags & TileFlag.Door) != 0 || itemID == 0x692 || itemID == 0x846 || itemID == 0x873 || (itemID >= 0x6F5 && itemID <= 0x6F6)))
                    {
                        continue;
                    }

                    int checkZ   = item.Z;
                    int checkTop = checkZ + itemData.CalcHeight;

                    if (checkTop > ourZ && ourTop > checkZ)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
        private static void getStartZ(AEntity m, Map map, Position3D loc, List <Item> itemList, out int zLow, out int zTop)
        {
            int xCheck = (int)loc.X, yCheck = (int)loc.Y;

            MapTile mapTile = map.GetMapTile(xCheck, yCheck);

            if (mapTile == null)
            {
                zLow = int.MinValue;
                zTop = int.MinValue;
            }

            bool landBlocks = mapTile.Ground.LandData.IsImpassible; //(TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Impassable) != 0;

            // if (landBlocks && m.CanSwim && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) != 0)
            //     landBlocks = false;
            // else if (m.CantWalk && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == 0)
            //     landBlocks = true;

            int landLow = 0, landCenter = 0, landTop = 0;

            landCenter = map.GetAverageZ(xCheck, yCheck, ref landLow, ref landTop);

            bool considerLand = !mapTile.Ground.IsIgnored;

            int  zCenter = zLow = zTop = 0;
            bool isSet   = false;

            if (considerLand && !landBlocks && loc.Z >= landCenter)
            {
                zLow    = landLow;
                zCenter = landCenter;

                if (!isSet || landTop > zTop)
                {
                    zTop = landTop;
                }

                isSet = true;
            }

            StaticItem[] staticTiles = mapTile.GetStatics().ToArray();

            for (int i = 0; i < staticTiles.Length; ++i)
            {
                StaticItem tile = staticTiles[i];

                int calcTop = ((int)tile.Z + tile.ItemData.CalcHeight);

                if ((!isSet || calcTop >= zCenter) && ((tile.ItemData.Flags & TileFlag.Surface) != 0) && loc.Z >= calcTop)
                {
                    //  || (m.CanSwim && (id.Flags & TileFlag.Wet) != 0)
                    // if (m.CantWalk && (id.Flags & TileFlag.Wet) == 0)
                    //     continue;

                    zLow    = (int)tile.Z;
                    zCenter = calcTop;

                    int top = (int)tile.Z + tile.ItemData.Height;

                    if (!isSet || top > zTop)
                    {
                        zTop = top;
                    }

                    isSet = true;
                }
            }

            for (int i = 0; i < itemList.Count; ++i)
            {
                Item item = itemList[i];

                UltimaData.ItemData id = item.ItemData;

                int calcTop = item.Z + id.CalcHeight;

                if ((!isSet || calcTop >= zCenter) && ((id.Flags & TileFlag.Surface) != 0) && loc.Z >= calcTop)
                {
                    //  || (m.CanSwim && (id.Flags & TileFlag.Wet) != 0)
                    // if (m.CantWalk && (id.Flags & TileFlag.Wet) == 0)
                    //     continue;

                    zLow    = item.Z;
                    zCenter = calcTop;

                    int top = item.Z + id.Height;

                    if (!isSet || top > zTop)
                    {
                        zTop = top;
                    }

                    isSet = true;
                }
            }

            if (!isSet)
            {
                zLow = zTop = (int)loc.Z;
            }
            else if (loc.Z > zTop)
            {
                zTop = (int)loc.Z;
            }
        }
        private static bool check(Map map, Mobile m, List <Item> items, int x, int y, int startTop, int startZ, out int newZ)
        {
            newZ = 0;

            MapTile mapTile = map.GetMapTile(x, y);

            if (mapTile == null)
            {
                return(false);
            }

            StaticItem[] tiles = mapTile.GetStatics().ToArray();

            bool landBlocks   = (mapTile.Ground.LandData.Flags & TileFlag.Impassable) != 0;
            bool considerLand = !mapTile.Ground.IsIgnored;

            //if (landBlocks && canSwim && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) != 0)	//Impassable, Can Swim, and Is water.  Don't block it.
            //    landBlocks = false;
            // else
            // if (cantWalk && (TileData.LandTable[landTile.ID & 0x3FFF].Flags & TileFlag.Wet) == 0)	//Can't walk and it's not water
            //     landBlocks = true;

            int landLow = 0, landCenter = 0, landTop = 0;

            landCenter = map.GetAverageZ(x, y, ref landLow, ref landTop);

            bool moveIsOk = false;

            int stepTop  = startTop + StepHeight;
            int checkTop = startZ + PersonHeight;

            bool ignoreDoors = (!m.Alive || m.BodyID == 0x3DB);

            #region Tiles
            for (int i = 0; i < tiles.Length; ++i)
            {
                StaticItem tile = tiles[i];

                if ((tile.ItemData.Flags & ImpassableSurface) == TileFlag.Surface) //  || (canSwim && (flags & TileFlag.Wet) != 0) Surface && !Impassable
                {
                    // if (cantWalk && (flags & TileFlag.Wet) == 0)
                    //     continue;

                    int itemZ   = (int)tile.Z;
                    int itemTop = itemZ;
                    int ourZ    = itemZ + tile.ItemData.CalcHeight;
                    int ourTop  = ourZ + PersonHeight;
                    int testTop = checkTop;

                    if (moveIsOk)
                    {
                        int cmp = Math.Abs(ourZ - m.Z) - Math.Abs(newZ - m.Z);

                        if (cmp > 0 || (cmp == 0 && ourZ > newZ))
                        {
                            continue;
                        }
                    }

                    if (ourZ + PersonHeight > testTop)
                    {
                        testTop = ourZ + PersonHeight;
                    }

                    if (!tile.ItemData.IsBridge)
                    {
                        itemTop += tile.ItemData.Height;
                    }

                    if (stepTop >= itemTop)
                    {
                        int landCheck = itemZ;

                        if (tile.ItemData.Height >= StepHeight)
                        {
                            landCheck += StepHeight;
                        }
                        else
                        {
                            landCheck += tile.ItemData.Height;
                        }

                        if (considerLand && landCheck < landCenter && landCenter > ourZ && testTop > landLow)
                        {
                            continue;
                        }

                        if (IsOk(ignoreDoors, ourZ, testTop, tiles, items))
                        {
                            newZ     = ourZ;
                            moveIsOk = true;
                        }
                    }
                }
            }
            #endregion

            #region Items
            for (int i = 0; i < items.Count; ++i)
            {
                Item item = items[i];
                UltimaData.ItemData itemData = item.ItemData;
                TileFlag            flags    = itemData.Flags;

                if ((flags & ImpassableSurface) == TileFlag.Surface) // Surface && !Impassable && !Movable
                {
                    //  || (m.CanSwim && (flags & TileFlag.Wet) != 0))
                    // !item.Movable &&
                    // if (cantWalk && (flags & TileFlag.Wet) == 0)
                    //     continue;

                    int itemZ   = item.Z;
                    int itemTop = itemZ;
                    int ourZ    = itemZ + itemData.CalcHeight;
                    int ourTop  = ourZ + PersonHeight;
                    int testTop = checkTop;

                    if (moveIsOk)
                    {
                        int cmp = Math.Abs(ourZ - m.Z) - Math.Abs(newZ - m.Z);

                        if (cmp > 0 || (cmp == 0 && ourZ > newZ))
                        {
                            continue;
                        }
                    }

                    if (ourZ + PersonHeight > testTop)
                    {
                        testTop = ourZ + PersonHeight;
                    }

                    if (!itemData.IsBridge)
                    {
                        itemTop += itemData.Height;
                    }

                    if (stepTop >= itemTop)
                    {
                        int landCheck = itemZ;

                        if (itemData.Height >= StepHeight)
                        {
                            landCheck += StepHeight;
                        }
                        else
                        {
                            landCheck += itemData.Height;
                        }

                        if (considerLand && landCheck < landCenter && landCenter > ourZ && testTop > landLow)
                        {
                            continue;
                        }

                        if (IsOk(ignoreDoors, ourZ, testTop, tiles, items))
                        {
                            newZ     = ourZ;
                            moveIsOk = true;
                        }
                    }
                }
            }

            #endregion

            if (considerLand && !landBlocks && (stepTop) >= landLow)
            {
                int ourZ    = landCenter;
                int ourTop  = ourZ + PersonHeight;
                int testTop = checkTop;

                if (ourZ + PersonHeight > testTop)
                {
                    testTop = ourZ + PersonHeight;
                }

                bool shouldCheck = true;

                if (moveIsOk)
                {
                    int cmp = Math.Abs(ourZ - m.Z) - Math.Abs(newZ - m.Z);

                    if (cmp > 0 || (cmp == 0 && ourZ > newZ))
                    {
                        shouldCheck = false;
                    }
                }

                if (shouldCheck && IsOk(ignoreDoors, ourZ, testTop, tiles, items))
                {
                    newZ     = ourZ;
                    moveIsOk = true;
                }
            }

            return(moveIsOk);
        }