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, false); if (mapTile == null) return false; MapObjectStatic[] tiles = mapTile.GetStatics().ToArray(); MapObjectGround landTile = mapTile.GroundTile; OpenUO.Ultima.LandData landData = Data.TileData.LandData[landTile.ItemID & 0x3FFF]; bool landBlocks = (landData.Flags & OpenUO.Ultima.TileFlag.Impassable) != 0; bool considerLand = !landTile.Ignored; //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) { MapObjectStatic tile = tiles[i]; OpenUO.Ultima.ItemData itemData = Data.TileData.ItemData[tile.ItemID & 0x3FFF]; OpenUO.Ultima.TileFlag flags = itemData.Flags; if ((flags & ImpassableSurface) == OpenUO.Ultima.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 + 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.Bridge) 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 #region Items for (int i = 0; i < items.Count; ++i) { Item item = items[i]; OpenUO.Ultima.ItemData itemData = item.ItemData; OpenUO.Ultima.TileFlag flags = itemData.Flags; if ((flags & ImpassableSurface) == OpenUO.Ultima.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.Bridge) 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; }
private static void getStartZ(Entity m, Map map, Vector3 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, false); if (mapTile == null) { zLow = int.MinValue; zTop = int.MinValue; } MapObjectGround landTile = mapTile.GroundTile; //map.Tiles.GetLandTile(xCheck, yCheck); bool landBlocks = (Data.TileData.LandData[landTile.ItemID & 0x3FFF].Flags & OpenUO.Ultima.TileFlag.Impassable) != 0; //(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 = !landTile.Ignored; 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; } MapObjectStatic[] staticTiles = mapTile.GetStatics().ToArray(); for (int i = 0; i < staticTiles.Length; ++i) { MapObjectStatic tile = staticTiles[i]; OpenUO.Ultima.ItemData id = Data.TileData.ItemData[tile.ItemID & 0x3FFF]; int calcTop = ((int)tile.Z + id.CalcHeight); if ((!isSet || calcTop >= zCenter) && ((id.Flags & OpenUO.Ultima.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 + id.Height; if (!isSet || top > zTop) zTop = top; isSet = true; } } for (int i = 0; i < itemList.Count; ++i) { Item item = itemList[i]; OpenUO.Ultima.ItemData id = item.ItemData; int calcTop = item.Z + id.CalcHeight; if ((!isSet || calcTop >= zCenter) && ((id.Flags & OpenUO.Ultima.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 void updateSurroundingsAndNormals(Map map) { Point origin = new Point(Position.X, Position.Y); float[] surroundingTilesZ = new float[kSurroundingsIndexes.Length]; for (int i = 0; i < kSurroundingsIndexes.Length; i++) surroundingTilesZ[i] = map.GetTileZ(origin.X + kSurroundingsIndexes[i].X, origin.Y + kSurroundingsIndexes[i].Y); _surroundingTiles = new Surroundings( surroundingTilesZ[7], surroundingTilesZ[3], surroundingTilesZ[6]); bool isFlat = _surroundingTiles.IsFlat && _surroundingTiles.East == Z; if (!isFlat) { int low = 0, high = 0, sort = 0; sort = map.GetAverageZ((int)Z, (int)_surroundingTiles.South, (int)_surroundingTiles.East, (int)_surroundingTiles.Down, ref low, ref high); if (sort != SortZ) { SortZ = sort; map.GetMapTile(Position.X, Position.Y, false).Resort(); } } _normals[0] = calculateNormal_Old( surroundingTilesZ[2], surroundingTilesZ[3], surroundingTilesZ[0], surroundingTilesZ[6]); _normals[1] = calculateNormal_Old( Z, surroundingTilesZ[4], surroundingTilesZ[1], surroundingTilesZ[7]); _normals[2] = calculateNormal_Old( surroundingTilesZ[5], surroundingTilesZ[7], Z, surroundingTilesZ[9]); _normals[3] = calculateNormal_Old( surroundingTilesZ[6], surroundingTilesZ[8], surroundingTilesZ[3], surroundingTilesZ[10]); updateVertexBuffer(); }