コード例 #1
0
ファイル: TileMatrix.cs プロジェクト: vsemchenkov/ServUO
        private unsafe LandTile[] ReadLandBlock(int x, int y)
        {
            try
            {
                int offset = ((x * m_BlockHeight) + y) * 196 + 4;

                if (m_MapIndex != null)
                {
                    offset = m_MapIndex.Lookup(offset);
                }

                m_Map.Seek(offset, SeekOrigin.Begin);

                LandTile[] tiles = new LandTile[64];

                fixed(LandTile *pTiles = tiles)
                {
                    NativeReader.Read(m_Map.SafeFileHandle.DangerousGetHandle(), pTiles, 192);
                }

                return(tiles);
            }
            catch
            {
                if (DateTime.UtcNow >= m_NextLandWarning)
                {
                    Console.WriteLine("Warning: Land EOS for {0} ({1}, {2})", m_Owner, x, y);
                    m_NextLandWarning = DateTime.UtcNow + TimeSpan.FromMinutes(1.0);
                }

                return(m_InvalidLandBlock);
            }
        }
コード例 #2
0
        private static bool GetFloorZ(Map map, int x, int y, out int z)
        {
            LandTile lt = map.Tiles.GetLandTile(x, y);

            if (IsFloor(lt.ID) && map.CanFit(x, y, lt.Z, 16, false, false))
            {
                z = lt.Z;
                return(true);
            }

            StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y);

            for (int i = 0; i < tiles.Length; ++i)
            {
                StaticTile t  = tiles[i];
                ItemData   id = TileData.ItemTable[t.ID & TileData.MaxItemValue];

                if (IsStaticFloor(t.ID) && map.CanFit(x, y, t.Z + (id.Surface ? id.CalcHeight : 0), 16, false, false))
                {
                    z = t.Z + (id.Surface ? id.CalcHeight : 0);
                    return(true);
                }
            }

            z = 0;
            return(false);
        }
コード例 #3
0
        private unsafe LandTile[] ReadLandBlock(int x, int y)
        {
            try
            {
                m_Map.Seek(((x * m_BlockHeight) + y) * 196 + 4, SeekOrigin.Begin);

                LandTile[] tiles = new LandTile[64];

                fixed(LandTile *pTiles = tiles)
                {
#if !MONO
                    NativeReader.Read(m_Map.SafeFileHandle.DangerousGetHandle(), pTiles, 192);
#else
                    NativeReader.Read(m_Map.Handle, pTiles, 192);
#endif
                }

                return(tiles);
            }
            catch
            {
                if (DateTime.Now >= m_NextLandWarning)
                {
                    Console.WriteLine("Warning: Land EOS for {0} ({1}, {2})", m_Owner, x, y);
                    m_NextLandWarning = DateTime.Now + TimeSpan.FromMinutes(1.0);
                }

                return(m_InvalidLandBlock);
            }
        }
コード例 #4
0
ファイル: TileMatrixPatch.cs プロジェクト: Evad-lab/ServUOX
        private unsafe int PatchLand(TileMatrix matrix, string dataPath, string indexPath)
        {
            using (FileStream fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                using (FileStream fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    BinaryReader indexReader = new BinaryReader(fsIndex);

                    int count = (int)(indexReader.BaseStream.Length / 4);

                    for (int i = 0; i < count; ++i)
                    {
                        int blockID = indexReader.ReadInt32();
                        int x       = blockID / matrix.BlockHeight;
                        int y       = blockID % matrix.BlockHeight;

                        fsData.Seek(4, SeekOrigin.Current);

                        var tiles = new LandTile[64];

                        fixed(LandTile *pTiles = tiles)
                        {
                            NativeReader.Read(fsData.SafeFileHandle.DangerousGetHandle(), pTiles, 192);
                        }

                        matrix.SetLandBlock(x, y, tiles);
                    }

                    indexReader.Close();

                    return(count);
                }
            }
        }
コード例 #5
0
        public LandTile[] GetLandBlock(int x, int y)
        {
            if (x < 0 || y < 0 || x >= m_BlockWidth || y >= m_BlockHeight || m_Map == null)
            {
                return(m_InvalidLandBlock);
            }

            if (m_LandTiles[x] == null)
            {
                m_LandTiles[x] = new LandTile[m_BlockHeight][];
            }

            var tiles = m_LandTiles[x][y];

            if (tiles == null)
            {
                lock (m_FileShare)
                {
                    for (int i = 0; tiles == null && i < m_FileShare.Count; ++i)
                    {
                        TileMatrix shared = m_FileShare[i];

                        lock (shared)
                        {
                            if (x >= 0 && x < shared.m_BlockWidth && y >= 0 && y < shared.m_BlockHeight)
                            {
                                var theirTiles = shared.m_LandTiles[x];

                                if (theirTiles != null)
                                {
                                    tiles = theirTiles[y];
                                }

                                if (tiles != null)
                                {
                                    var theirBits = shared.m_LandPatches[x];

                                    if (theirBits != null && (theirBits[y >> 5] & (1 << (y & 0x1F))) != 0)
                                    {
                                        tiles = null;
                                    }
                                }
                            }
                        }
                    }
                }

                if (tiles == null)
                {
                    tiles = ReadLandBlock(x, y);
                }

                m_LandTiles[x][y] = tiles;
            }

            return(tiles);
        }
コード例 #6
0
ファイル: TileMatrix.cs プロジェクト: twlizer/runuo
        public void SetLandBlock(int x, int y, LandTile[] value)
        {
            if (x < 0 || y < 0 || x >= m_BlockWidth || y >= m_BlockHeight)
            {
                return;
            }

            if (m_LandTiles[x] == null)
            {
                m_LandTiles[x] = new LandTile[m_BlockHeight][];
            }

            m_LandTiles[x][y] = value;

            if (m_LandPatches[x] == null)
            {
                m_LandPatches[x] = new int[(m_BlockHeight + 31) >> 5];
            }

            m_LandPatches[x][y >> 5] |= 1 << (y & 0x1F);
        }
コード例 #7
0
ファイル: TileMatrixPatch.cs プロジェクト: Crome696/ServUO
		private unsafe int PatchLand(TileMatrix matrix, string dataPath, string indexPath)
		{
			using (FileStream fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
			{
				using (FileStream fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read))
				{
					BinaryReader indexReader = new BinaryReader(fsIndex);

					int count = (int)(indexReader.BaseStream.Length / 4);

					for (int i = 0; i < count; ++i)
					{
						int blockID = indexReader.ReadInt32();
						int x = blockID / matrix.BlockHeight;
						int y = blockID % matrix.BlockHeight;

						fsData.Seek(4, SeekOrigin.Current);

						var tiles = new LandTile[64];

						fixed (LandTile* pTiles = tiles)
						{
#if !MONO
							NativeReader.Read(fsData.SafeFileHandle.DangerousGetHandle(), pTiles, 192);
#else
							NativeReader.Read( fsData.Handle, pTiles, 192 );
#endif
						}

						matrix.SetLandBlock(x, y, tiles);
					}

					indexReader.Close();

					return count;
				}
			}
		}
コード例 #8
0
        private unsafe int PatchLand(TileMatrix matrix, string dataPath, string indexPath)
        {
            using var fsData  = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            using var fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read);
            var indexReader = new BinaryReader(fsIndex);

            var count = (int)(indexReader.BaseStream.Length / 4);

            for (var i = 0; i < count; ++i)
            {
                var blockID = indexReader.ReadInt32();
                var x       = blockID / matrix.BlockHeight;
                var y       = blockID % matrix.BlockHeight;

                fsData.Seek(4, SeekOrigin.Current);

                var tiles = new LandTile[64];

                fixed(LandTile *pTiles = tiles)
                {
                    var ptr = fsData.SafeFileHandle?.DangerousGetHandle();

                    if (ptr == null)
                    {
                        throw new Exception($"Cannot open {fsData.Name}");
                    }

                    NativeReader.Read(ptr.Value, pTiles, 192);
                }

                matrix.SetLandBlock(x, y, tiles);
            }

            indexReader.Close();

            return(count);
        }
コード例 #9
0
        private static bool IsFloor(Map map, int x, int y, bool canFit)
        {
            LandTile lt = map.Tiles.GetLandTile(x, y);

            if (IsFloor(lt.ID) && (canFit || CanFit(map, x, y, lt.Z)))
            {
                return(true);
            }

            StaticTile[] tiles = map.Tiles.GetStaticTiles(x, y);

            for (int i = 0; i < tiles.Length; ++i)
            {
                StaticTile t  = tiles[i];
                ItemData   id = TileData.ItemTable[t.ID & TileData.MaxItemValue];

                if (IsStaticFloor(t.ID) && (canFit || CanFit(map, x, y, t.Z + (id.Surface ? id.CalcHeight : 0))))
                {
                    return(true);
                }
            }

            return(false);
        }
コード例 #10
0
ファイル: TileMatrix.cs プロジェクト: Godkong/RunUO
		public void SetLandBlock( int x, int y, LandTile[] value )
		{
			if ( x < 0 || y < 0 || x >= m_BlockWidth || y >= m_BlockHeight )
				return;

			if ( m_LandTiles[x] == null )
				m_LandTiles[x] = new LandTile[m_BlockHeight][];

			m_LandTiles[x][y] = value;

			if ( m_LandPatches[x] == null )
				m_LandPatches[x] = new int[(m_BlockHeight + 31) >> 5];

			m_LandPatches[x][y >> 5] |= 1 << (y & 0x1F);
		}
コード例 #11
0
        private static bool CanFit(Map map, int x, int y, int z)
        {
            bool hasSurface = false;

            LandTile lt = map.Tiles.GetLandTile(x, y);
            int      lowZ = 0, avgZ = 0, topZ = 0;

            map.GetAverageZ(x, y, ref lowZ, ref avgZ, ref topZ);
            TileFlag landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;

            if ((landFlags & TileFlag.Impassable) != 0 && topZ > z && (z + 16) > lowZ)
            {
                return(false);
            }
            else if ((landFlags & TileFlag.Impassable) == 0 && z == avgZ && !lt.Ignored)
            {
                hasSurface = true;
            }

            StaticTile[] staticTiles = map.Tiles.GetStaticTiles(x, y);

            bool surface, impassable;

            for (int i = 0; i < staticTiles.Length; ++i)
            {
                if (IsDisplayCase(staticTiles[i].ID))
                {
                    continue;
                }

                ItemData id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue];

                surface    = id.Surface;
                impassable = id.Impassable;

                if ((surface || impassable) && (staticTiles[i].Z + id.CalcHeight) > z && (z + 16) > staticTiles[i].Z)
                {
                    return(false);
                }
                else if (surface && !impassable && z == (staticTiles[i].Z + id.CalcHeight))
                {
                    hasSurface = true;
                }
            }

            Sector      sector = map.GetSector(x, y);
            List <Item> items  = sector.Items;

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

                if (item.AtWorldPoint(x, y))
                {
                    ItemData id = item.ItemData;
                    surface    = id.Surface;
                    impassable = id.Impassable;

                    if ((surface || impassable) && (item.Z + id.CalcHeight) > z && (z + 16) > item.Z)
                    {
                        return(false);
                    }
                    else if (surface && !impassable && z == (item.Z + id.CalcHeight))
                    {
                        hasSurface = true;
                    }
                }
            }

            return(hasSurface);
        }
コード例 #12
0
        private IEnumerable <Point3D> Compute(Rectangle3D area)
        {
            // Check all corners to skip large bodies of water.
            for (var index = 0; index < Filters.Length; index++)
            {
                var filter = Filters[index];

                if (Equals(filter, TileFlag.Wet))
                {
                    LandTile land1 = Facet.Tiles.GetLandTile(area.Start.X, area.Start.Y); // TL
                    LandTile land2 = Facet.Tiles.GetLandTile(area.End.X, area.Start.Y);   // TR
                    LandTile land3 = Facet.Tiles.GetLandTile(area.Start.X, area.End.Y);   // BL
                    LandTile land4 = Facet.Tiles.GetLandTile(area.End.X, area.End.Y);     // BR

                    bool ignore1 = land1.Ignored || TileData.LandTable[land1.ID].Flags.HasFlag(TileFlag.Wet);
                    bool ignore2 = land2.Ignored || TileData.LandTable[land2.ID].Flags.HasFlag(TileFlag.Wet);
                    bool ignore3 = land3.Ignored || TileData.LandTable[land3.ID].Flags.HasFlag(TileFlag.Wet);
                    bool ignore4 = land4.Ignored || TileData.LandTable[land4.ID].Flags.HasFlag(TileFlag.Wet);

                    if (ignore1 && ignore2 && ignore3 && ignore4)
                    {
                        yield break;
                    }

                    break;
                }
            }

            Point3D p = Point3D.Zero;

            for (p.X = area.Start.X; p.X <= area.End.X; p.X++)
            {
                for (p.Y = area.Start.Y; p.Y <= area.End.Y; p.Y++)
                {
                    LandTile land = Facet.Tiles.GetLandTile(p.X, p.Y);

                    p.Z = land.Z;

                    if (Contains(p))
                    {
                        continue;
                    }

                    if (!CanSpawn(p.X, p.Y, p.Z))
                    {
                        continue;
                    }

                    if (Filters.Length > 0)
                    {
                        if (land.Ignored)
                        {
                            continue;
                        }

                        TileFlag flags = TileData.LandTable[land.ID].Flags;

                        bool any1 = false;

                        for (var index = 0; index < Filters.Length; index++)
                        {
                            var f = Filters[index];

                            if (flags.HasFlag(f))
                            {
                                any1 = true;
                                break;
                            }
                        }

                        if (any1)
                        {
                            continue;
                        }

                        bool valid = true;

                        var tiles = Facet.Tiles.GetStaticTiles(p.X, p.Y);

                        for (var index = 0; index < tiles.Length; index++)
                        {
                            StaticTile tile = tiles[index];
                            flags = TileData.ItemTable[tile.ID].Flags;

                            bool any2 = false;

                            for (var i = 0; i < Filters.Length; i++)
                            {
                                var f = Filters[i];

                                if (flags.HasFlag(f))
                                {
                                    any2 = true;
                                    break;
                                }
                            }

                            if (any2)
                            {
                                valid = false;
                                break;
                            }
                        }

                        if (!valid)
                        {
                            continue;
                        }
                    }

                    if (Validator != null && !Validator(Facet, p.X, p.Y, p.Z))
                    {
                        continue;
                    }

                    yield return(p);
                }
            }
        }
コード例 #13
0
ファイル: LOS.cs プロジェクト: ITLongwell/Ulmeta
        //--------------------------------------------------------------------------
        //  Determine whether or not a tile is an 'invalid' one. These are the black
        //  tiles that sepearate the spaces between dungeons--they are intrinsically
        //  impassable, block everything.
        //--------------------------------------------------------------------------
        private bool IsInvalidLandTile( LandTile tile )
        {
            int id = tile.ID;

            int[] invalidLandTiles = Map.InvalidLandTiles;

            for ( int i = 0; i < invalidLandTiles.Length; i++ )
            if( id == invalidLandTiles[i] )
                return true;

            return false;
        }
コード例 #14
0
ファイル: LOS.cs プロジェクト: ITLongwell/Ulmeta
        //--------------------------------------------------------------------------
        //  Does the land block my vision?
        //--------------------------------------------------------------------------
        public bool LandBlocksVis( LandTile landTile, int x, int y, int eyelevel, Point3D beholder )
        {
            if( !Config.GetInstance().Mountain( landTile.ID ) )
            {
            return false;
            }

            //ItemData    data = TileData.ItemTable[landTile.ID];
            int minZ = 0, avgZ = 0, maxZ = 0;

            m_map.GetAverageZ( x, y, ref minZ, ref avgZ, ref maxZ );

            if (
            minZ <= eyelevel // for caves
            &&
            maxZ >= eyelevel
            &&
            !landTile.Ignored
            )
            {
            return true;
            }

            return false;
        }
コード例 #15
0
ファイル: LOS.cs プロジェクト: ITLongwell/Ulmeta
        //--------------------------------------------------------------------------
        //   Is this an invalid tile which also blocks vix?
        //--------------------------------------------------------------------------
        public bool IsVizBlockingInvalidLand( LandTile landTile, StaticTile[] staticTiles, int x, int y )
        {
            if( IsInvalidLandTile( landTile ) )
            {
            if( staticTiles.Length == 0 )
            {
                if( !ContainsVisibleItem( x, y ) )
                {
                    return true;
                }
            }
            }

            return false;
        }
コード例 #16
0
ファイル: Charybdis.cs プロジェクト: Crome696/ServUO
 public bool IsSeaTile(LandTile t)
 {
     return t.Z == -5 && ((t.ID >= 0xA8 && t.ID <= 0xAB) || (t.ID >= 0x136 && t.ID <= 0x137));
 }
コード例 #17
0
        private void Compute(Rectangle3D area)
        {
            // Check all corners to skip large bodies of water.
            if (Filters.Contains(TileFlag.Wet))
            {
                LandTile land1 = Facet.Tiles.GetLandTile(area.Start.X, area.Start.Y); // TL
                LandTile land2 = Facet.Tiles.GetLandTile(area.End.X, area.Start.Y);   // TR
                LandTile land3 = Facet.Tiles.GetLandTile(area.Start.X, area.End.Y);   // BL
                LandTile land4 = Facet.Tiles.GetLandTile(area.End.X, area.End.Y);     // BR

                if ((land1.Ignored || TileData.LandTable[land1.ID].Flags.HasFlag(TileFlag.Wet)) &&
                    (land2.Ignored || TileData.LandTable[land2.ID].Flags.HasFlag(TileFlag.Wet)) &&
                    (land3.Ignored || TileData.LandTable[land3.ID].Flags.HasFlag(TileFlag.Wet)) &&
                    (land4.Ignored || TileData.LandTable[land4.ID].Flags.HasFlag(TileFlag.Wet)))
                {
                    return;
                }
            }

            int x, y, z, h;

            for (x = area.Start.X; x < area.End.X; x++)
            {
                for (y = area.Start.Y; y < area.End.Y; y++)
                {
                    h = GetHashCode(x, y);

                    if (_Points.ContainsKey(h))
                    {
                        continue;
                    }

                    z = Facet.Tiles.GetLandTile(x, y).Z;//.GetAverageZ(x, y);

                    if (!CanSpawn(x, y, z))
                    {
                        continue;
                    }

                    if (Filters.Length > 0)
                    {
                        LandTile land = Facet.Tiles.GetLandTile(x, y);

                        if (land.Ignored)
                        {
                            continue;
                        }

                        TileFlag flags = TileData.LandTable[land.ID].Flags;

                        if (Filters.Any(f => flags.HasFlag(f)))
                        {
                            continue;
                        }

                        bool valid = true;

                        foreach (StaticTile tile in Facet.Tiles.GetStaticTiles(x, y))
                        {
                            flags = TileData.ItemTable[tile.ID].Flags;

                            if (Filters.Any(f => flags.HasFlag(f)))
                            {
                                valid = false;
                                break;
                            }
                        }

                        if (!valid)
                        {
                            continue;
                        }
                    }

                    if (Validator != null && !Validator(Facet, x, y, z))
                    {
                        continue;
                    }

                    lock (_Points)
                    {
                        _Points[h] = new Point3D(x, y, z);
                    }
                }
            }
        }
コード例 #18
0
ファイル: TileMatrix.cs プロジェクト: Godkong/RunUO
		private unsafe LandTile[] ReadLandBlock( int x, int y )
		{
			try
			{
				m_Map.Seek( ((x * m_BlockHeight) + y) * 196 + 4, SeekOrigin.Begin );

				LandTile[] tiles = new LandTile[64];

				fixed ( LandTile *pTiles = tiles )
				{
#if !MONO
					NativeReader.Read( m_Map.SafeFileHandle.DangerousGetHandle(), pTiles, 192 );
#else
					NativeReader.Read( m_Map.Handle, pTiles, 192 );
#endif
				}

				return tiles;
			}
			catch
			{
				if ( DateTime.Now >= m_NextLandWarning )
				{
					Console.WriteLine( "Warning: Land EOS for {0} ({1}, {2})", m_Owner, x, y );
					m_NextLandWarning = DateTime.Now + TimeSpan.FromMinutes( 1.0 );
				}

				return m_InvalidLandBlock;
			}
		}
コード例 #19
0
 public static bool IsWater(this LandTile tile)
 {
     return(LandWaterTiles.Contains(tile.ID) || TileData.LandTable[tile.ID].Flags.HasFlag(TileFlag.Wet) ||
            Insensitive.Contains(TileData.LandTable[tile.ID].Name, "water"));
 }
コード例 #20
0
ファイル: Map.cs プロジェクト: phpjunkie420/RunUO
		/* This could be probably be re-implemented if necessary (perhaps via an ITile interface?).
		public List<Tile> GetTilesAt( Point2D p, bool items, bool land, bool statics )
		{
			List<Tile> list = new List<Tile>();

			if ( this == Map.Internal )
				return list;

			if ( land )
				list.Add( Tiles.GetLandTile( p.m_X, p.m_Y ) );

			if ( statics )
				list.AddRange( Tiles.GetStaticTiles( p.m_X, p.m_Y, true ) );

			if ( items )
			{
				Sector sector = GetSector( p );

				foreach ( Item item in sector.Items )
					if ( item.AtWorldPoint( p.m_X, p.m_Y ) )
						list.Add( new StaticTile( (ushort)item.ItemID, (sbyte) item.Z ) );
			}

			return list;
		}
		*/

		/// <summary>
		/// Gets the highest surface that is lower than <paramref name="p"/>.
		/// </summary>
		/// <param name="p">The reference point.</param>
		/// <returns>A surface <typeparamref name="Tile"/> or <typeparamref name="Item"/>.</returns>
		public object GetTopSurface( Point3D p )
		{
			if ( this == Map.Internal )
				return null;

			object surface = null;
			int surfaceZ = int.MinValue;


			LandTile lt = Tiles.GetLandTile( p.X, p.Y );

			if ( !lt.Ignored )
			{
				int avgZ = GetAverageZ( p.X, p.Y );

				if ( avgZ <= p.Z )
				{
					surface = lt;
					surfaceZ = avgZ;

					if ( surfaceZ == p.Z )
						return surface;
				}
			}


			StaticTile[] staticTiles = Tiles.GetStaticTiles( p.X, p.Y, true );

			for ( int i = 0; i < staticTiles.Length; i++ )
			{
				StaticTile tile = staticTiles[i];
				ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];

				if ( id.Surface || ( id.Flags & TileFlag.Wet ) != 0 )
				{
					int tileZ = tile.Z + id.CalcHeight;

					if ( tileZ > surfaceZ && tileZ <= p.Z )
					{
						surface = tile;
						surfaceZ = tileZ;

						if ( surfaceZ == p.Z )
							return surface;
					}
				}
			}


			Sector sector = GetSector( p.X, p.Y );

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

				if ( !(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint( p.X, p.Y ) && !item.Movable )
				{
					ItemData id = item.ItemData;

					if ( id.Surface || ( id.Flags & TileFlag.Wet ) != 0 )
					{
						int itemZ = item.Z + id.CalcHeight;

						if ( itemZ > surfaceZ && itemZ <= p.Z )
						{
							surface = item;
							surfaceZ = itemZ;

							if ( surfaceZ == p.Z )
								return surface;
						}
					}
				}
			}


			return surface;
		}
コード例 #21
0
ファイル: Map.cs プロジェクト: phpjunkie420/RunUO
		public void FixColumn( int x, int y )
		{
			LandTile landTile = Tiles.GetLandTile( x, y );

			int landZ = 0, landAvg = 0, landTop = 0;
			GetAverageZ( x, y, ref landZ, ref landAvg, ref landTop );

			StaticTile[] tiles = Tiles.GetStaticTiles( x, y, true );

			List<Item> items = new List<Item>();

			IPooledEnumerable eable = GetItemsInRange( new Point3D( x, y, 0 ), 0 );

			foreach ( Item item in eable )
			{
				if ( !(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue )
				{
					items.Add( item );

					if ( items.Count > 100 )
						break;
				}
			}

			eable.Free();

			if ( items.Count > 100 )
				return;

			items.Sort( ZComparer.Default );

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

				if ( !toFix.Movable )
					continue;

				int z = int.MinValue;
				int currentZ = toFix.Z;

				if ( !landTile.Ignored && landAvg <= currentZ )
					z = landAvg;

				for ( int j = 0; j < tiles.Length; ++j )
				{
					StaticTile tile = tiles[j];
					ItemData id = TileData.ItemTable[tile.ID & TileData.MaxItemValue];

					int checkZ = tile.Z;
					int checkTop = checkZ + id.CalcHeight;

					if ( checkTop == checkZ && !id.Surface )
						++checkTop;

					if ( checkTop > z && checkTop <= currentZ )
						z = checkTop;
				}

				for ( int j = 0; j < items.Count; ++j )
				{
					if ( j == i )
						continue;

					Item item = items[j];
					ItemData id = item.ItemData;

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

					if ( checkTop == checkZ && !id.Surface )
						++checkTop;

					if ( checkTop > z && checkTop <= currentZ )
						z = checkTop;
				}

				if ( z != int.MinValue )
					toFix.Location = new Point3D( toFix.X, toFix.Y, z );
			}
		}
コード例 #22
0
ファイル: Map.cs プロジェクト: phpjunkie420/RunUO
		public bool CanFit( int x, int y, int z, int height, bool checkBlocksFit, bool checkMobiles, bool requireSurface )
		{
			if ( this == Map.Internal )
				return false;

			if ( x < 0 || y < 0 || x >= m_Width || y >= m_Height )
				return false;

			bool hasSurface = false;

			LandTile lt = Tiles.GetLandTile( x, y );
			int lowZ = 0, avgZ = 0, topZ = 0;

			GetAverageZ( x, y, ref lowZ, ref avgZ, ref topZ );
			TileFlag landFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;

			if ( ( landFlags & TileFlag.Impassable ) != 0 && avgZ > z && ( z + height ) > lowZ )
				return false;
			else if ( ( landFlags & TileFlag.Impassable ) == 0 && z == avgZ && !lt.Ignored )
				hasSurface = true;

			StaticTile[] staticTiles = Tiles.GetStaticTiles( x, y, true );

			bool surface, impassable;

			for ( int i = 0; i < staticTiles.Length; ++i )
			{
				ItemData id = TileData.ItemTable[staticTiles[i].ID & TileData.MaxItemValue];
				surface = id.Surface;
				impassable = id.Impassable;

				if ( ( surface || impassable ) && ( staticTiles[i].Z + id.CalcHeight ) > z && ( z + height ) > staticTiles[i].Z )
					return false;
				else if ( surface && !impassable && z == ( staticTiles[i].Z + id.CalcHeight ) )
					hasSurface = true;
			}

			Sector sector = GetSector( x, y );
			List<Item> items  = sector.Items;
			List<Mobile> mobs = sector.Mobiles;

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

				if ( !(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint( x, y ) )
				{
					ItemData id = item.ItemData;
					surface = id.Surface;
					impassable = id.Impassable;

					if ( ( surface || impassable || ( checkBlocksFit && item.BlocksFit ) ) && ( item.Z + id.CalcHeight ) > z && ( z + height ) > item.Z )
						return false;
					else if ( surface && !impassable && !item.Movable && z == ( item.Z + id.CalcHeight ) )
						hasSurface = true;
				}
			}

			if ( checkMobiles )
			{
				for ( int i = 0; i < mobs.Count; ++i )
				{
					Mobile m = mobs[i];

					if ( m.Location.m_X == x && m.Location.m_Y == y && ( m.AccessLevel == AccessLevel.Player || !m.Hidden ) )
						if ( ( m.Z + 16 ) > z && ( z + height ) > m.Z )
							return false;
				}
			}

			return !requireSurface || hasSurface;
		}
コード例 #23
0
ファイル: Map.cs プロジェクト: phpjunkie420/RunUO
		public bool LineOfSight( Point3D org, Point3D dest )
		{
			if( this == Map.Internal )
				return false;

			if( !Utility.InRange( org, dest, m_MaxLOSDistance ) )
				return false;

			Point3D start = org;
			Point3D end = dest;

			if( org.X > dest.X || (org.X == dest.X && org.Y > dest.Y) || (org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) )
			{
				Point3D swap = org;
				org = dest;
				dest = swap;
			}

			double rise, run, zslp;
			double sq3d;
			double x, y, z;
			int xd, yd, zd;
			int ix, iy, iz;
			int height;
			bool found;
			Point3D p;
			Point3DList path = m_PathList;
			TileFlag flags;

			if( org == dest )
				return true;

			if( path.Count > 0 )
				path.Clear();

			xd = dest.m_X - org.m_X;
			yd = dest.m_Y - org.m_Y;
			zd = dest.m_Z - org.m_Z;
			zslp = Math.Sqrt( xd * xd + yd * yd );
			if( zd != 0 )
				sq3d = Math.Sqrt( zslp * zslp + zd * zd );
			else
				sq3d = zslp;

			rise = ((float)yd) / sq3d;
			run = ((float)xd) / sq3d;
			zslp = ((float)zd) / sq3d;

			y = org.m_Y;
			z = org.m_Z;
			x = org.m_X;
			while( Utility.NumberBetween( x, dest.m_X, org.m_X, 0.5 ) && Utility.NumberBetween( y, dest.m_Y, org.m_Y, 0.5 ) && Utility.NumberBetween( z, dest.m_Z, org.m_Z, 0.5 ) )
			{
				ix = (int)Math.Round( x );
				iy = (int)Math.Round( y );
				iz = (int)Math.Round( z );
				if( path.Count > 0 )
				{
					p = path.Last;

					if( p.m_X != ix || p.m_Y != iy || p.m_Z != iz )
						path.Add( ix, iy, iz );
				}
				else
				{
					path.Add( ix, iy, iz );
				}
				x += run;
				y += rise;
				z += zslp;
			}

			if( path.Count == 0 )
				return true;//<--should never happen, but to be safe.

			p = path.Last;

			if( p != dest )
				path.Add( dest );

			Point3D pTop = org, pBottom = dest;
			Utility.FixPoints( ref pTop, ref pBottom );

			int pathCount = path.Count;

			for( int i = 0; i < pathCount; ++i )
			{
				Point3D point = path[i];

				LandTile landTile = Tiles.GetLandTile( point.X, point.Y );
				int landZ = 0, landAvg = 0, landTop = 0;
				GetAverageZ( point.m_X, point.m_Y, ref landZ, ref landAvg, ref landTop );

				if( landZ <= point.m_Z && landTop >= point.m_Z && (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > end.m_Z || landTop < end.m_Z) && !landTile.Ignored )
					return false;

				/* --Do land tiles need to be checked?  There is never land between two people, always statics.--
				LandTile landTile = Tiles.GetLandTile( point.X, point.Y );
				if ( landTile.Z-1 >= point.Z && landTile.Z+1 <= point.Z && (TileData.LandTable[landTile.ID & TileData.MaxLandValue].Flags & TileFlag.Impassable) != 0 )
					return false;
				*/

				StaticTile[] statics = Tiles.GetStaticTiles( point.m_X, point.m_Y, true );

				bool contains = false;
				int ltID = landTile.ID;

				for( int j = 0; !contains && j < m_InvalidLandTiles.Length; ++j )
					contains = (ltID == m_InvalidLandTiles[j]);

				if( contains && statics.Length == 0 )
				{
					IPooledEnumerable eable = GetItemsInRange( point, 0 );

					foreach( Item item in eable )
					{
						if( item.Visible )
							contains = false;

						if( !contains )
							break;
					}

					eable.Free();

					if( contains )
						return false;
				}

				for( int j = 0; j < statics.Length; ++j )
				{
					StaticTile t = statics[j];

					ItemData id = TileData.ItemTable[t.ID & TileData.MaxItemValue];

					flags = id.Flags;
					height = id.CalcHeight;

					if( t.Z <= point.Z && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0 )
					{
						if( point.m_X == end.m_X && point.m_Y == end.m_Y && t.Z <= end.m_Z && t.Z + height >= end.m_Z )
							continue;

						return false;
					}

					/*if ( t.Z <= point.Z && t.Z+height >= point.Z && (flags&TileFlag.Window)==0 && (flags&TileFlag.NoShoot)!=0
						&& ( (flags&TileFlag.Wall)!=0 || (flags&TileFlag.Roof)!=0 || (((flags&TileFlag.Surface)!=0 && zd != 0)) ) )*/
					/*{
						//Console.WriteLine( "LoS: Blocked by Static \"{0}\" Z:{1} T:{3} P:{2} F:x{4:X}", TileData.ItemTable[t.ID&TileData.MaxItemValue].Name, t.Z, point, t.Z+height, flags );
						//Console.WriteLine( "if ( {0} && {1} && {2} && ( {3} || {4} || {5} || ({6} && {7} && {8}) ) )", t.Z <= point.Z, t.Z+height >= point.Z, (flags&TileFlag.Window)==0, (flags&TileFlag.Impassable)!=0, (flags&TileFlag.Wall)!=0, (flags&TileFlag.Roof)!=0, (flags&TileFlag.Surface)!=0, t.Z != dest.Z, zd != 0 ) ;
						return false;
					}*/
				}
			}

			Rectangle2D rect = new Rectangle2D( pTop.m_X, pTop.m_Y, (pBottom.m_X - pTop.m_X) + 1, (pBottom.m_Y - pTop.m_Y) + 1 );

			IPooledEnumerable area = GetItemsInBounds( rect );

			foreach( Item i in area )
			{
				if( !i.Visible )
					continue;

				if( i is BaseMulti || i.ItemID > TileData.MaxItemValue )
					continue;

				ItemData id = i.ItemData;
				flags = id.Flags;

				if( (flags & (TileFlag.Window | TileFlag.NoShoot)) == 0 )
					continue;

				height = id.CalcHeight;

				found = false;

				int count = path.Count;

				for( int j = 0; j < count; ++j )
				{
					Point3D point = path[j];
					Point3D loc = i.Location;

					//if ( t.Z <= point.Z && t.Z+height >= point.Z && ( height != 0 || ( t.Z == dest.Z && zd != 0 ) ) )
					if( loc.m_X == point.m_X && loc.m_Y == point.m_Y &&
						loc.m_Z <= point.m_Z && loc.m_Z + height >= point.m_Z )
					{
						if( loc.m_X == end.m_X && loc.m_Y == end.m_Y && loc.m_Z <= end.m_Z && loc.m_Z + height >= end.m_Z )
							continue;

						found = true;
						break;
					}
				}

				if( !found )
					continue;

				area.Free();
				return false;

				/*if ( (flags & (TileFlag.Impassable | TileFlag.Surface | TileFlag.Roof)) != 0 )

				//flags = TileData.ItemTable[i.ItemID&TileData.MaxItemValue].Flags;
				//if ( (flags&TileFlag.Window)==0 && (flags&TileFlag.NoShoot)!=0 && ( (flags&TileFlag.Wall)!=0 || (flags&TileFlag.Roof)!=0 || (((flags&TileFlag.Surface)!=0 && zd != 0)) ) )
				{
					//height = TileData.ItemTable[i.ItemID&TileData.MaxItemValue].Height;
					//Console.WriteLine( "LoS: Blocked by ITEM \"{0}\" P:{1} T:{2} F:x{3:X}", TileData.ItemTable[i.ItemID&TileData.MaxItemValue].Name, i.Location, i.Location.Z+height, flags );
					area.Free();
					return false;
				}*/
			}

			area.Free();

			return true;
		}
コード例 #24
0
 public static bool IsCoastline(this LandTile tile)
 {
     return(LandCoastlineTiles.Contains(tile.ID) || (TileData.LandTable[tile.ID].Flags == TileFlag.Impassable &&
                                                     Insensitive.Contains(TileData.LandTable[tile.ID].Name, "sand")));
 }
コード例 #25
0
ファイル: TileMatrix.cs プロジェクト: Godkong/RunUO
		public LandTile[] GetLandBlock( int x, int y )
		{
			if ( x < 0 || y < 0 || x >= m_BlockWidth || y >= m_BlockHeight || m_Map == null )
				return m_InvalidLandBlock;

			if ( m_LandTiles[x] == null )
				m_LandTiles[x] = new LandTile[m_BlockHeight][];

			LandTile[] tiles = m_LandTiles[x][y];

			if ( tiles == null )
			{
				for ( int i = 0; tiles == null && i < m_FileShare.Count; ++i )
				{
					TileMatrix shared = m_FileShare[i];

					if ( x >= 0 && x < shared.m_BlockWidth && y >= 0 && y < shared.m_BlockHeight )
					{
						LandTile[][] theirTiles = shared.m_LandTiles[x];

						if ( theirTiles != null )
							tiles = theirTiles[y];

						if ( tiles != null )
						{
							int[] theirBits = shared.m_LandPatches[x];

							if ( theirBits != null && (theirBits[y >> 5] & (1 << (y & 0x1F))) != 0 )
								tiles = null;
						}
					}
				}

				if ( tiles == null )
					tiles = ReadLandBlock( x, y );

				m_LandTiles[x][y] = tiles;
			}

			return tiles;
		}