All pastes #108569 Raw Edit

Milkboy

public text v1 · immutable
#108569 ·published 2006-07-31 15:52 UTC
rendered paste body
using System;
using System.Collections.Generic;
using System.Collections;

using Server;
using Server.Mobiles;

namespace Server.Items
{
	public class MonsterSpawnEntry
	{
		private Type m_Monster;
		private int m_Amount;

		public Type Monster { get { return m_Monster; } set { m_Monster = value; } }
		public int Amount { get { return m_Amount; } set { m_Amount = value; } }

		public MonsterSpawnEntry( Type monster, int amount )
		{
			m_Monster = monster;
			m_Amount = amount;
		}
	}

	public class ChampSpawner : Item
	{
		private bool m_Enabled;
		private bool m_Broadcast;

		private Point3D m_Top;
		private Point3D m_Bottom;

		private List<Mobile> m_Spawned;

		private Timer m_Timer;

		[CommandProperty(AccessLevel.GameMaster)]
		public bool Enabled
		{
			get { return m_Enabled; }
			set
			{
				m_Enabled = value;

				if ( m_Enabled )
					Spawn();
				else
					Despawn();
			}
		}

		[CommandProperty( AccessLevel.GameMaster )]
		public bool Broadcast { get { return m_Broadcast; } set { m_Broadcast = value; } }

		[CommandProperty( AccessLevel.GameMaster )]
		public Point3D Top { get { return m_Top; } set { m_Top = value; } }
		[CommandProperty( AccessLevel.GameMaster )]
		public Point3D Bottom { get { return m_Bottom; } set { m_Bottom = value; } }

		public List<Mobile> Spawned { get { return m_Spawned; } set { m_Spawned = value; } }

		private MonsterSpawnEntry[] m_Entries = new MonsterSpawnEntry[]
			{
									//Monster							//Amount
				new MonsterSpawnEntry(typeof(BoneKnight),					50),
				new MonsterSpawnEntry(typeof(ChaosDaemon),					50),
				new MonsterSpawnEntry(typeof(StoneGargoyle),				50),
				new MonsterSpawnEntry(typeof(StoneHarpy),					50),
				new MonsterSpawnEntry(typeof(Zombie),						80),
				new MonsterSpawnEntry(typeof(OgreLord),						50),
				new MonsterSpawnEntry(typeof(Cyclops),						50),
				new MonsterSpawnEntry(typeof(RottingCorpse),				20),
				new MonsterSpawnEntry(typeof(Mummy),						50),
				new MonsterSpawnEntry(typeof(BlackSolenInfiltratorWarrior),	50)
			};

		[Constructable]
		public ChampSpawner() : base( 0xFA6 )
		{
			m_Spawned = new List<Mobile>();

			Visible = false;
			Movable = false;

			Name = "a champion spawner";
		}

		public void Spawn()
		{
			Despawn();

			for ( int i = 0; i < m_Entries.Length; ++i )
				for ( int count = 0; count < m_Entries[i].Amount; ++count )
					AddMonster( m_Entries[i].Monster, false );

			m_Timer = new InternalTimer( this, false );
			m_Timer.Start();
		}

		public void Despawn()
		{
			if ( m_Timer != null )
				m_Timer.Stop();

			for ( int i = 0; i < m_Spawned.Count; ++i )
				if ( m_Spawned[i] != null && !m_Spawned[i].Deleted )
					m_Spawned[i].Delete();

			m_Spawned.Clear();
		}

		public void Restart()
		{
			Despawn();

			//Wait 10 hours before next respawn
			Timer.DelayCall(TimeSpan.FromHours(10.0), new TimerStateCallback(delegate(object state)
			{
				if ( m_Broadcast )
					World.Broadcast( 1161, false, "[System Message]: Attention! The champion spawn has now respawned." );

				Spawn();

			}), null);
		}

		public void AddMonster( Type type, bool champ )
		{
			object monster = Activator.CreateInstance( type );

			if ( monster != null && monster is Mobile )
			{
				int x = Utility.Random( m_Top.X, ( m_Bottom.X - m_Top.X ) );
				int y = Utility.Random( m_Top.Y, ( m_Bottom.Y - m_Top.Y ) );

				Point3D location = new Point3D( x, y, m_Top.Z );

				Mobile from = (Mobile)monster;

				if ( champ && Utility.Random(100) == 50 )
					from.AddItem( new ClothingBlessDeed() );

				from.MoveToWorld( location, this.Map );

				m_Spawned.Add( from );
			}
		}

		public void SpawnChamp()
		{
			Despawn();

			AddMonster( typeof( Neira ), true ); //Champion that is spawned

			m_Timer = new InternalTimer( this, true );
			m_Timer.Start();
		}

		public ChampSpawner( Serial serial )
			: base( serial )
		{
		}

		public override void OnDelete()
		{
			Despawn();

			base.OnDelete();
		}

		public override void Serialize( GenericWriter writer )
		{
			base.Serialize( writer );

			writer.Write( (int)0 ); //version

			writer.Write( m_Enabled );
			writer.Write( m_Broadcast );

			writer.Write( m_Top );
			writer.Write( m_Bottom );
		}

		public override void Deserialize( GenericReader reader )
		{
			base.Deserialize( reader );

			int version = reader.ReadInt();

			switch ( version )
			{
				case 0:
					{
						m_Enabled = reader.ReadBool();
						m_Broadcast = reader.ReadBool();

						m_Top = reader.ReadPoint3D();
						m_Bottom = reader.ReadPoint3D();

						break;
					}
			}

			m_Spawned = new List<Mobile>();
		}

		public class InternalTimer : Timer
		{
			ChampSpawner m_Spawner;

			bool m_Champ;
			int lastCount; //Prevent spamming the shard

			public InternalTimer(ChampSpawner spawner, bool champ)
				: base( TimeSpan.FromSeconds( 5.0 ), TimeSpan.FromSeconds( 5.0 ) )
			{
				m_Spawner = spawner;
				m_Champ = champ;
			}

			protected override void OnTick()
			{
				int count = 0;

				for ( int i = 0; i < m_Spawner.Spawned.Count; ++i )
					if ( m_Spawner.Spawned[i] != null && !m_Spawner.Spawned[i].Deleted && m_Spawner.Spawned[i].Alive )
						++count;

				if ( !m_Champ ) //Monsters
				{
					if ( m_Spawner.Broadcast && lastCount != count && ( count % 50 ) == 0 )
					{
						World.Broadcast( 1161, false, String.Format( "[System Message]: Attention! There are {0} monsters left to kill at the champion spawn.", count ) );
						lastCount = count;
					}

					if ( count == 0 ) //All monsters have been slayed
						m_Spawner.SpawnChamp();
				}
				else //Champion
				{
					if ( count == 0 ) //Champion is dead
					{
						if ( m_Spawner.Broadcast )
							World.Broadcast( 1161, false, "[System Message]: Attention! The champion has been slayed. The monsters will respawn in ten hours." );

						m_Spawner.Restart();
					}
				}
			}
		}
	}
}