using System; using Server; namespace Server.Items { public abstract class BaseSpawner : Item, ISpawner { private Mobile m_TrackedMobile; public bool UnlinkOnTaming { get { return true; } } public Point3D HomeLocation { get { return this.Location; } } public int HomeRange { get { return 5; } } public void Remove( ISpawnable spawn ) { if ( !this.Deleted ) this.Delete(); } public BaseSpawner() : base( 0x6519 ) { Name = "spawn ref"; Visible = false; Movable = false; Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerCallback( ExecuteSpawn ) ); } public BaseSpawner( Serial serial ) : base( serial ) { } public override void Serialize( GenericWriter writer ) { base.Serialize( writer ); writer.Write( (int) 0 ); writer.Write( m_TrackedMobile ); } public override void Deserialize( GenericReader reader ) { base.Deserialize( reader ); int version = reader.ReadInt(); m_TrackedMobile = reader.ReadMobile(); if ( m_TrackedMobile != null && !m_TrackedMobile.Deleted && m_TrackedMobile.Alive ) { if ( m_TrackedMobile is ISpawnable ) { ((ISpawnable)m_TrackedMobile).Spawner = this; } } else { Timer.DelayCall( TimeSpan.FromSeconds( 1.0 ), new TimerCallback( this.Delete ) ); } } private void ExecuteSpawn() { if ( !this.Deleted && this.Map != null && this.Map != Map.Internal ) { Point3D savedLocation = this.Location; Map savedMap = this.Map; // --- REGION SAFETY CHECK --- Region reg = Region.Find( savedLocation, savedMap ); if ( reg is Server.Regions.TownRegion || reg is Server.Regions.GuardedRegion || reg is Server.Regions.DungeonRegion || reg is Server.Regions.HouseRegion ) { this.Delete(); return; } // --------------------------- m_TrackedMobile = Server.SpawnList.RandomSpawn( this, savedLocation, savedMap ); if ( m_TrackedMobile != null ) { if ( m_TrackedMobile is ISpawnable ) { ((ISpawnable)m_TrackedMobile).Spawner = this; } // --- NEW SCATTER LOGIC --- int scatterRange = 25; // Default fallback range // 1. Look down at our feet to find the parent spawner and borrow its HomeRange! foreach ( Item item in savedMap.GetItemsInRange( savedLocation, 0 ) ) { if ( item is ISpawner ) { scatterRange = ((ISpawner)item).HomeRange; break; } } Point3D spawnPoint = savedLocation; // 2. Try up to 15 times to find a valid tile within that range for ( int i = 0; i < 15; i++ ) { int x = savedLocation.X + Utility.RandomMinMax( -scatterRange, scatterRange ); int y = savedLocation.Y + Utility.RandomMinMax( -scatterRange, scatterRange ); int z = savedMap.GetAverageZ( x, y ); Point3D testPoint = new Point3D( x, y, z ); // If this is the water proxy, specifically seek out water tiles using your SpawnList system if ( this is SpawnWater ) { if ( Server.SpawnList.GetTerrain( savedMap, testPoint, x, y ) == Server.Terrain.Water ) { spawnPoint = testPoint; break; // Found a valid water spot! } } // If it's a land proxy, ensure the mob doesn't accidentally spawn in the ocean else { if ( savedMap.CanFit( x, y, z, 16, false, false ) ) { spawnPoint = testPoint; break; // Found a valid land spot! } } } // ------------------------- // Move the mob to the scattered location instead of the center m_TrackedMobile.MoveToWorld( spawnPoint, savedMap ); this.Internalize(); } else { this.Delete(); } } else if ( !this.Deleted ) { this.Delete(); } } } public class SpawnAnimals : BaseSpawner { [Constructable] public SpawnAnimals(){} public SpawnAnimals( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class SpawnBirds : BaseSpawner { [Constructable] public SpawnBirds(){} public SpawnBirds( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class SpawnCritters : BaseSpawner { [Constructable] public SpawnCritters(){} public SpawnCritters( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class Spawn_A : BaseSpawner { [Constructable] public Spawn_A(){} public Spawn_A( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class Spawn_B : BaseSpawner { [Constructable] public Spawn_B(){} public Spawn_B( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class Spawn_C : BaseSpawner { [Constructable] public Spawn_C(){} public Spawn_C( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class Spawn_D : BaseSpawner { [Constructable] public Spawn_D(){} public Spawn_D( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class Spawn_E : BaseSpawner { [Constructable] public Spawn_E(){} public Spawn_E( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } public class SpawnWater : BaseSpawner { [Constructable] public SpawnWater(){} public SpawnWater( Serial serial ) : base( serial ){} public override void Serialize( GenericWriter writer ){ base.Serialize( writer ); writer.Write( (int) 0 ); } public override void Deserialize( GenericReader reader ){ base.Deserialize( reader ); int version = reader.ReadInt(); } } }