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); } } }
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); }