RunUO/Scripts/Holiday Stuff/Halloween/2012/Engines/PlayerZombies.cs

290 lines
No EOL
7.6 KiB
C#

using System;
using Server.Items;
using Server.Mobiles;
using System.Collections.Generic;
using Server.Events.Halloween;
namespace Server.Engines.Events
{
public class HalloweenHauntings
{
public static Dictionary<PlayerMobile, ZombieSkeleton> ReAnimated { get { return m_ReAnimated; } set { m_ReAnimated = value; } }
private static Timer m_Timer;
private static Timer m_ClearTimer;
private static int m_TotalZombieLimit;
private static int m_DeathQueueLimit;
private static int m_QueueDelaySeconds;
private static int m_QueueClearIntervalSeconds;
private static Dictionary<PlayerMobile, ZombieSkeleton> m_ReAnimated;
private static List<PlayerMobile> m_DeathQueue;
private static Rectangle2D[] m_Cemetaries = new Rectangle2D[]
{
new Rectangle2D(1272,3712,30,20), // Jhelom
new Rectangle2D(1337,1444,48,52), // Britain
new Rectangle2D(2424,1098,20,28), // Trinsic
new Rectangle2D(2728,840,54,54), // Vesper
new Rectangle2D(4528,1314,20,28), // Moonglow
new Rectangle2D(712,1104,30,22), // Yew
new Rectangle2D(5824,1464,22,6), // Fire Dungeon
new Rectangle2D(5224,3655,14,5), // T2A
new Rectangle2D(1272,3712,20,30), // Jhelom
new Rectangle2D(1337,1444,52,48), // Britain
new Rectangle2D(2424,1098,28,20), // Trinsic
new Rectangle2D(2728,840,54,54), // Vesper
new Rectangle2D(4528,1314,28,20), // Moonglow
new Rectangle2D(712,1104,22,30), // Yew
new Rectangle2D(5824,1464,6,22), // Fire Dungeon
new Rectangle2D(5224,3655,5,14), // T2A
};
public static void Initialize()
{
m_TotalZombieLimit = 200;
m_DeathQueueLimit = 200;
m_QueueDelaySeconds = 120;
m_QueueClearIntervalSeconds = 1800;
DateTime today = DateTime.UtcNow;
TimeSpan tick = TimeSpan.FromSeconds( m_QueueDelaySeconds );
TimeSpan clear = TimeSpan.FromSeconds( m_QueueClearIntervalSeconds );
m_ReAnimated = new Dictionary<PlayerMobile, ZombieSkeleton>();
m_DeathQueue = new List<PlayerMobile>();
if( today >= HolidaySettings.StartHalloween && today <= HolidaySettings.FinishHalloween )
{
m_Timer = Timer.DelayCall( tick, tick, new TimerCallback( Timer_Callback ) );
m_ClearTimer = Timer.DelayCall( clear, clear, new TimerCallback( Clear_Callback ) );
EventSink.PlayerDeath += new PlayerDeathEventHandler( EventSink_PlayerDeath );
}
}
public static void EventSink_PlayerDeath( PlayerDeathEventArgs e )
{
if( e.Mobile != null && !e.Mobile.Deleted ) /* not sure .. better safe than sorry? */
{
if( e.Mobile is PlayerMobile )
{
PlayerMobile player = e.Mobile as PlayerMobile;
if( m_Timer.Running && !m_DeathQueue.Contains( player ) && m_DeathQueue.Count < m_DeathQueueLimit )
{
m_DeathQueue.Add( player );
}
}
}
}
private static void Clear_Callback()
{
m_ReAnimated.Clear();
m_DeathQueue.Clear();
if( DateTime.UtcNow <= HolidaySettings.FinishHalloween )
{
m_ClearTimer.Stop();
}
}
private static void Timer_Callback()
{
PlayerMobile player = null;
if( DateTime.UtcNow <= HolidaySettings.FinishHalloween )
{
for( int index = 0; m_DeathQueue.Count > 0 && index < m_DeathQueue.Count; index++ )
{
if( !m_ReAnimated.ContainsKey( m_DeathQueue[ index ] ) )
{
player = m_DeathQueue[ index ];
break;
}
}
if( player != null && !player.Deleted && m_ReAnimated.Count < m_TotalZombieLimit )
{
Map map = Utility.RandomBool() ? Map.Trammel : Map.Felucca;
Point3D home = ( GetRandomPointInRect( m_Cemetaries[ Utility.Random( m_Cemetaries.Length ) ], map ));
if( map.CanSpawnMobile( home ) )
{
ZombieSkeleton zombieskel = new ZombieSkeleton( player );
m_ReAnimated.Add( player, zombieskel );
zombieskel.Home = home;
zombieskel.RangeHome = 10;
zombieskel.MoveToWorld( home, map );
m_DeathQueue.Remove( player );
}
}
}
else
{
m_Timer.Stop();
}
}
private static Point3D GetRandomPointInRect( Rectangle2D rect, Map map )
{
int x = Utility.Random( rect.X, rect.Width );
int y = Utility.Random( rect.Y, rect.Height );
return new Point3D( x, y, map.GetAverageZ( x, y ) );
}
}
public class PlayerBones : BaseContainer
{
[Constructable]
public PlayerBones( String name )
: base( Utility.RandomMinMax( 0x0ECA, 0x0ED2 ) )
{
Name = String.Format( "{0}'s bones", name );
switch( Utility.Random( 10 ) )
{
case 0: Hue = 0xa09; break;
case 1: Hue = 0xa93; break;
case 2: Hue = 0xa47; break;
default: break;
}
}
public PlayerBones( 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();
}
}
[CorpseName( "a rotting corpse" )]
public class ZombieSkeleton : BaseCreature
{
private static readonly string m_Name = "Zombie Skeleton";
private PlayerMobile m_DeadPlayer;
public ZombieSkeleton()
: this( null )
{
}
public ZombieSkeleton( PlayerMobile player )
: base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
m_DeadPlayer = player;
Name = ( player != null ) ? String.Format( "{0}'s {1}", player.Name, m_Name ) : m_Name;
Body = 0x93;
BaseSoundID = 0x1c3;
SetStr( 500 );
SetDex( 500 );
SetInt( 500 );
SetHits( 2500 );
SetMana( 500 );
SetStam( 500 );
SetDamage( 8, 18 );
SetDamageType( ResistanceType.Physical, 40 );
SetDamageType( ResistanceType.Cold, 60 );
SetResistance( ResistanceType.Fire, 50 );
SetResistance( ResistanceType.Energy, 50 );
SetResistance( ResistanceType.Physical, 50 );
SetResistance( ResistanceType.Cold, 50 );
SetResistance( ResistanceType.Poison, 50 );
SetSkill( SkillName.MagicResist, 65.1, 80.0 );
SetSkill( SkillName.Tactics, 95.1, 100 );
SetSkill( SkillName.Wrestling, 85.1, 95 );
Fame = 1000;
Karma = -1000;
VirtualArmor = 18;
}
public override void GenerateLoot()
{
switch( Utility.Random( 10 ) )
{
case 0: PackItem( new LeftArm() ); break;
case 1: PackItem( new RightArm() ); break;
case 2: PackItem( new Torso() ); break;
case 3: PackItem( new Bone() ); break;
case 4: PackItem( new RibCage() ); break;
case 5: if( m_DeadPlayer != null && !m_DeadPlayer.Deleted ) { PackItem( new PlayerBones( m_DeadPlayer.Name ) ); } break;
default: break;
}
AddLoot( LootPack.Meager );
}
public override bool BleedImmune { get { return true; } }
public override Poison PoisonImmune { get { return Poison.Regular; } }
public ZombieSkeleton( Serial serial )
: base( serial )
{
}
public override void OnDelete()
{
if( HalloweenHauntings.ReAnimated != null )
{
if( m_DeadPlayer != null && !m_DeadPlayer.Deleted )
{
if( HalloweenHauntings.ReAnimated.Count > 0 && HalloweenHauntings.ReAnimated.ContainsKey( m_DeadPlayer ) )
{
HalloweenHauntings.ReAnimated.Remove( m_DeadPlayer );
}
}
}
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.Write( ( int )0 );
writer.WriteMobile( m_DeadPlayer );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadInt();
m_DeadPlayer = ( PlayerMobile )reader.ReadMobile();
}
}
}