Server.Regions.BaseRegion.RandomSpawnLocation C# (CSharp) Méthode

RandomSpawnLocation() public méthode

public RandomSpawnLocation ( int spawnHeight, bool land, bool water, Point3D home, int range ) : Point3D
spawnHeight int
land bool
water bool
home Point3D
range int
Résultat Point3D
		public Point3D RandomSpawnLocation( int spawnHeight, bool land, bool water, Point3D home, int range )
		{
			Map map = this.Map;

			if ( map == Map.Internal )
				return Point3D.Zero;

			InitRectangles();

			if ( m_TotalWeight <= 0 )
				return Point3D.Zero;

			for ( int i = 0; i < 10; i++ ) // Try 10 times
			{
				int x, y, minZ, maxZ;

				if ( home == Point3D.Zero )
				{
					int rand = Utility.Random( m_TotalWeight );

					x = int.MinValue; y = int.MinValue;
					minZ = int.MaxValue; maxZ = int.MinValue;
					for ( int j = 0; j < m_RectangleWeights.Length; j++ )
					{
						int curWeight = m_RectangleWeights[j];

						if ( rand < curWeight )
						{
							Rectangle3D rect = m_Rectangles[j];

							x = rect.Start.X + rand % rect.Width;
							y = rect.Start.Y + rand / rect.Width;

							minZ = rect.Start.Z;
							maxZ = rect.End.Z;

							break;
						}

						rand -= curWeight;
					}
				}
				else
				{
					x = Utility.RandomMinMax( home.X - range, home.X + range );
					y = Utility.RandomMinMax( home.Y - range, home.Y + range );

					minZ = int.MaxValue; maxZ = int.MinValue;
					for ( int j = 0; j < this.Area.Length; j++ )
					{
						Rectangle3D rect = this.Area[j];

						if ( x >= rect.Start.X && x < rect.End.X && y >= rect.Start.Y && y < rect.End.Y )
						{
							minZ = rect.Start.Z;
							maxZ = rect.End.Z;
							break;
						}
					}

					if ( minZ == int.MaxValue )
						continue;
				}

				if ( x < 0 || y < 0 || x >= map.Width || y >= map.Height )
					continue;

				LandTile lt = map.Tiles.GetLandTile( x, y );

				int ltLowZ = 0, ltAvgZ = 0, ltTopZ = 0;
				map.GetAverageZ( x, y, ref ltLowZ, ref ltAvgZ, ref ltTopZ );

				TileFlag ltFlags = TileData.LandTable[lt.ID & TileData.MaxLandValue].Flags;
				bool ltImpassable = ( (ltFlags & TileFlag.Impassable) != 0 );

				if ( !lt.Ignored && ltAvgZ >= minZ && ltAvgZ < maxZ )
					if ( (ltFlags & TileFlag.Wet) != 0 ) {
						if ( water )
							m_SpawnBuffer1.Add( ltAvgZ );
					}
					else if ( land && !ltImpassable )
						m_SpawnBuffer1.Add( ltAvgZ );

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

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

					if ( tileZ >= minZ && tileZ < maxZ )
						if ( (id.Flags & TileFlag.Wet) != 0 ) {
							if ( water )
								m_SpawnBuffer1.Add( tileZ );
						}
						else if ( land && id.Surface && !id.Impassable )
							m_SpawnBuffer1.Add( tileZ );
				}


				Sector sector = map.GetSector( x, y );

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

					if ( !(item is BaseMulti) && item.ItemID <= TileData.MaxItemValue && item.AtWorldPoint( x, y ) )
					{
						m_SpawnBuffer2.Add( item );

						if ( !item.Movable )
						{
							ItemData id = item.ItemData;
							int itemZ = item.Z + id.CalcHeight;

							if ( itemZ >= minZ && itemZ < maxZ )
								if ( (id.Flags & TileFlag.Wet) != 0 ) {
									if ( water )
										m_SpawnBuffer1.Add( itemZ );
								}
								else if ( land && id.Surface && !id.Impassable )
									m_SpawnBuffer1.Add( itemZ );
						}
					}
				}


				if ( m_SpawnBuffer1.Count == 0 )
				{
					m_SpawnBuffer1.Clear();
					m_SpawnBuffer2.Clear();
					continue;
				}

				int z;
				switch ( m_SpawnZLevel )
				{
					case SpawnZLevel.Lowest:
					{
						z = int.MaxValue;

						for ( int j = 0; j < m_SpawnBuffer1.Count; j++ )
						{
							int l = m_SpawnBuffer1[j];

							if ( l < z )
								z = l;
						}

						break;
					}
					case SpawnZLevel.Highest:
					{
						z = int.MinValue;

						for ( int j = 0; j < m_SpawnBuffer1.Count; j++ )
						{
							int l = m_SpawnBuffer1[j];

							if ( l > z )
								z = l;
						}

						break;
					}
					default: // SpawnZLevel.Random
					{
						int index = Utility.Random( m_SpawnBuffer1.Count );
						z = m_SpawnBuffer1[index];

						break;
					}
				}

				m_SpawnBuffer1.Clear();


				if ( !Region.Find( new Point3D( x, y, z ), map ).AcceptsSpawnsFrom( this ) )
				{
					m_SpawnBuffer2.Clear();
					continue;
				}

				int top = z + spawnHeight;

				bool ok = true;
				for ( int j = 0; j < m_SpawnBuffer2.Count; j++ )
				{
					Item item = m_SpawnBuffer2[j];
					ItemData id = item.ItemData;

					if ( ( id.Surface || id.Impassable ) && item.Z + id.CalcHeight > z && item.Z < top )
					{
						ok = false;
						break;
					}
				}

				m_SpawnBuffer2.Clear();

				if ( !ok )
					continue;

				if ( ltImpassable && ltAvgZ > z && ltLowZ < top )
					continue;

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

					if ( ( id.Surface || id.Impassable ) && tile.Z + id.CalcHeight > z && tile.Z < top )
					{
						ok = false;
						break;
					}
				}

				if ( !ok )
					continue;

				for ( int j = 0; j < sector.Mobiles.Count; j++ )
				{
					Mobile m = sector.Mobiles[j];

					if ( m.X == x && m.Y == y && ( m.AccessLevel == AccessLevel.Player || !m.Hidden ) )
						if ( m.Z + 16 > z && m.Z < top )
						{
							ok = false;
							break;
						}
				}

				if ( ok )
					return new Point3D( x, y, z );
			}

			return Point3D.Zero;
		}

Usage Example

Exemple #1
0
 public Point3D RandomSpawnLocation(int spawnHeight, bool land, bool water)
 {
     return(m_Region.RandomSpawnLocation(spawnHeight, land, water, m_Home, m_Range));
 }