private unsafe void update(Map map, int renderBeginX, int renderBeginY) { if ((map.UpdateTicker != _lastUpdateTicker) || (_texture == null)) { int size = ClientVars.EngineVars.RenderSize * 2; _lastUpdateTicker = map.UpdateTicker; _texture = new Texture2D(_graphics, size, size, false, SurfaceFormat.Bgra5551); ushort[] data = new ushort[size * size]; fixed (ushort* pData = data) { for (int y = 0; y < ClientVars.EngineVars.RenderSize; y++) { ushort* cur = pData + ((size /2 - 1) + (size - 1) * y); for (int x = 0; x < ClientVars.EngineVars.RenderSize; x++) { MapTile m = map.GetMapTile(renderBeginX + x, renderBeginY + y, true); List<MapObject> o = m.Items; int i; for (i = o.Count - 1; i > 0; i--) { if (o[i] is MapObjectStatic) { *cur++ = (ushort)(Data.Radarcol.Colors[o[i].ItemID] | 0x8000); *cur = (ushort)(Data.Radarcol.Colors[o[i].ItemID] | 0x8000); cur += size; break; } } if (i == 0) { *cur++ = (ushort)(Data.Radarcol.Colors[m.GroundTile.ItemID] | 0x8000); *cur = (ushort)(Data.Radarcol.Colors[o[i].ItemID] | 0x8000); cur += size; } } } } _texture.SetData<ushort>(data); } }
public void Update(GameTime gameTime) { if (ClientVars.EngineVars.Map != -1) { if ((Map == null) || (Map.Index != ClientVars.EngineVars.Map)) Map = new Map(ClientVars.EngineVars.Map); // Update the Map's position so it loads the tiles we're going to be drawing Map.Update(CenterPosition.X, CenterPosition.Y); // Are we inside (under a roof)? Do not draw tiles above our head. _maxItemAltitude = 255; MapTile t; if ((t = Map.GetMapTile(CenterPosition.X, CenterPosition.Y, true)) != null) { MapObject underObject, underTerrain; t.IsUnder(CenterPosition.Z, out underObject, out underTerrain); // if we are under terrain, then do not draw any terrain at all. DrawTerrain = !(underTerrain == null); if (!(underObject == null)) { // Roofing and new floors ALWAYS begin at intervals of 20. // if we are under a ROOF, then get rid of everything above me.Z + 20 // (this accounts for A-frame roofs). Otherwise, get rid of everything // at the object above us.Z. if (((MapObjectStatic)underObject).ItemData.Roof) { _maxItemAltitude = CenterPosition.Z - (CenterPosition.Z % 20) + 20; } else { _maxItemAltitude = (int)(underObject.Z - (underObject.Z % 20)); } // If we are under a roof tile, do not make roofs transparent if we are on an edge. if (underObject is MapObjectStatic && ((MapObjectStatic)underObject).ItemData.Roof) { bool isRoofSouthEast = true; if ((t = Map.GetMapTile(CenterPosition.X + 1, CenterPosition.Y + 1, true)) != null) { t.IsUnder(CenterPosition.Z, out underObject, out underTerrain); isRoofSouthEast = !(underObject == null); } if (!isRoofSouthEast) _maxItemAltitude = 255; } } } } }
public WorldTexture(GraphicsDevice graphics, Map map, int x, int y) { _texture = new Texture2D(graphics, 64, 64); _map = map; _x = x; _y = y; }
public Texture2D Texture(Map map, int renderBeginX, int renderBeginY) { update(map, renderBeginX, renderBeginY); return _texture; }
public static bool CheckMovement(Mobile m, Map map, Vector3 loc, Direction d, out int newZ) { if (map == null) { newZ = 0; return true; } int xStart = (int)loc.X; int yStart = (int)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 >= map.Width || yForward >= map.Height) { newZ = 0; return false; } int startZ, startTop; List<Item> itemsStart = m_Pools[0]; List<Item> itemsForward = m_Pools[1]; List<Item> itemsLeft = m_Pools[2]; List<Item> itemsRight = m_Pools[3]; OpenUO.Ultima.TileFlag reqFlags = ImpassableSurface; // if (m.CanSwim) // reqFlags |= TileFlag.Wet; if (checkDiagonals) { MapTile sectorStart = map.GetMapTile(xStart, yStart, false); MapTile sectorForward = map.GetMapTile(xForward, yForward, false); MapTile sectorLeft = map.GetMapTile(xLeft, yLeft, false); MapTile sectorRight = map.GetMapTile(xRight, yRight, false); if ((sectorForward == null) || (sectorStart == null) || (sectorLeft == null) || (sectorRight == null)) { newZ = (int)loc.Z; return false; } List<MapTile> sectors = new List<MapTile>(); //m_Sectors; sectors.Add(sectorStart); sectors.Add(sectorForward); sectors.Add(sectorLeft); sectors.Add(sectorRight); for (int i = 0; i < sectors.Count; ++i) { MapTile sector = sectors[i]; for (int j = 0; j < sector.Items.Count; ++j) { Entity entity = sector.Items[j].OwnerEntity; //Item item = sector.Items[j]; // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable) // continue; if (entity is Item) { Item item = (Item)entity; if ((item.ItemData.Flags & reqFlags) == 0) continue; if (sector == sectorStart && item.AtWorldPoint(xStart, yStart) && item.ItemID < 0x4000) itemsStart.Add(item); else if (sector == sectorForward && item.AtWorldPoint(xForward, yForward) && item.ItemID < 0x4000) itemsForward.Add(item); else if (sector == sectorLeft && item.AtWorldPoint(xLeft, yLeft) && item.ItemID < 0x4000) itemsLeft.Add(item); else if (sector == sectorRight && item.AtWorldPoint(xRight, yRight) && item.ItemID < 0x4000) itemsRight.Add(item); } } } } else { MapTile sectorStart = map.GetMapTile(xStart, yStart, false); MapTile sectorForward = map.GetMapTile(xForward, yForward, false); if ((sectorForward == null) || (sectorStart == null)) { newZ = (int)loc.Z; return false; } if (sectorStart == sectorForward) { for (int i = 0; i < sectorStart.Items.Count; ++i) { Entity entity = sectorStart.Items[i].OwnerEntity; // Item item = sectorStart.Items[i]; if (entity is Item) { Item item = (Item)entity; // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable) // continue; if ((item.ItemData.Flags & reqFlags) == 0) continue; if (item.AtWorldPoint(xStart, yStart) && item.ItemID < 0x4000) itemsStart.Add(item); else if (item.AtWorldPoint(xForward, yForward) && item.ItemID < 0x4000) itemsForward.Add(item); } } } else { for (int i = 0; i < sectorForward.Items.Count; ++i) { Entity entity = sectorForward.Items[i].OwnerEntity; // Item item = sectorForward.Items[i]; if (entity is Item) { Item item = (Item)entity; // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable) // continue; if ((item.ItemData.Flags & reqFlags) == 0) continue; if (item.AtWorldPoint(xForward, yForward) && item.ItemID < 0x4000) itemsForward.Add(item); } } for (int i = 0; i < sectorStart.Items.Count; ++i) { Entity entity = sectorStart.Items[i].OwnerEntity; // Item item = sectorStart.Items[i]; if (entity is Item) { Item item = (Item)entity; // if (ignoreMovableImpassables && item.Movable && item.ItemData.Impassable) // continue; if ((item.ItemData.Flags & reqFlags) == 0) continue; if (item.AtWorldPoint(xStart, yStart) && item.ItemID < 0x4000) itemsStart.Add(item); } } } } getStartZ(m, map, loc, itemsStart, out startZ, out startTop); bool moveIsOk = check(map, m, itemsForward, xForward, yForward, startTop, startZ, out newZ); if (moveIsOk && checkDiagonals) { int hold; if (!check(map, m, itemsLeft, xLeft, yLeft, startTop, startZ, out hold) && !check(map, m, itemsRight, xRight, yRight, startTop, startZ, out hold)) moveIsOk = false; } for (int i = 0; i < (checkDiagonals ? 4 : 2); ++i) { if (m_Pools[i].Count > 0) m_Pools[i].Clear(); } if (!moveIsOk) newZ = startZ; 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 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 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(); }
public void UpdateSurroundingsIfNecessary(Map map) { if (!_mustUpdateSurroundings) return; updateSurroundingsAndNormals(map); _mustUpdateSurroundings = false; }