예제 #1
0
파일: MiniMap.cs 프로젝트: Crwth/UltimaXNA
 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);
     }
 }
예제 #2
0
        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;
                        }
                    }
                }
            }
        }
예제 #3
0
파일: MiniMap.cs 프로젝트: Crwth/UltimaXNA
 public WorldTexture(GraphicsDevice graphics, Map map, int x, int y)
 {
     _texture = new Texture2D(graphics, 64, 64);
     _map = map;
     _x = x;
     _y = y;
 }
예제 #4
0
파일: MiniMap.cs 프로젝트: Crwth/UltimaXNA
 public Texture2D Texture(Map map, int renderBeginX, int renderBeginY)
 {
     update(map, renderBeginX, renderBeginY);
     return _texture;
 }
예제 #5
0
        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;
        }
예제 #6
0
        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;
        }
예제 #7
0
        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;
        }
예제 #8
0
        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();
        }
예제 #9
0
        public void UpdateSurroundingsIfNecessary(Map map)
        {
            if (!_mustUpdateSurroundings)
                return;

            updateSurroundingsAndNormals(map);
            _mustUpdateSurroundings = false;
        }