ModernUO/Scripts/Mobiles/Monsters/Misc/Melee/PlagueBeastLord.cs
2018-09-11 18:59:11 -07:00

364 lines
8.4 KiB
C#

using System;
using Server.Items;
using Server.Network;
namespace Server.Mobiles
{
public class PlagueBeastLord : BaseCreature, ICarvable, IScissorable
{
public override string CorpseName => "a plague beast lord corpse";
public override Poison PoisonImmune => Poison.Lethal;
private Mobile m_OpenedBy;
[CommandProperty( AccessLevel.GameMaster )]
public Mobile OpenedBy
{
get { return m_OpenedBy; }
set { m_OpenedBy = value; }
}
[CommandProperty( AccessLevel.GameMaster )]
public bool IsBleeding
{
get
{
Container pack = Backpack;
if ( pack != null )
{
for ( int i = 0; i < pack.Items.Count; i++ )
{
if ( pack.Items[ i ] is PlagueBeastBlood blood && !blood.Patched )
return true;
}
}
return false;
}
}
private DecayTimer m_Timer;
public override string DefaultName => "a plague beast lord";
[Constructible]
public PlagueBeastLord() : base( AIType.AI_Melee, FightMode.Closest, 10, 1, 0.2, 0.4 )
{
Body = 775;
BaseSoundID = 679;
SpeechHue = 0x3B2;
SetStr( 500 );
SetDex( 100 );
SetInt( 30 );
SetHits( 1800 );
SetDamage( 20, 25 );
SetDamageType( ResistanceType.Physical, 50 );
SetDamageType( ResistanceType.Fire, 25 );
SetDamageType( ResistanceType.Poison, 25 );
SetResistance( ResistanceType.Physical, 45, 55 );
SetResistance( ResistanceType.Fire, 40, 50 );
SetResistance( ResistanceType.Cold, 25, 35 );
SetResistance( ResistanceType.Poison, 75, 85 );
SetResistance( ResistanceType.Energy, 25, 35 );
SetSkill( SkillName.Tactics, 100 );
SetSkill( SkillName.Wrestling, 100 );
Fame = 2000;
Karma = -2000;
VirtualArmor = 50;
}
public override void OnDoubleClick( Mobile from )
{
if ( IsAccessibleTo( from ) )
{
if ( m_OpenedBy != null && Backpack != null )
Backpack.DisplayTo( from );
else
PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1071917, from.NetState ); // * You attempt to tear open the amorphous flesh, but it resists *
}
}
public override bool OnDragDrop( Mobile from, Item dropped )
{
if ( IsAccessibleTo( from ) && ( dropped is PlagueBeastInnard || dropped is PlagueBeastGland ) )
return base.OnDragDrop( from, dropped );
return false;
}
public override void OnDeath( Container c )
{
base.OnDeath( c );
for ( int i = c.Items.Count - 1; i >= 0; i-- )
c.Items[ i ].Delete();
}
public override void OnDelete()
{
if ( m_OpenedBy?.Holding is PlagueBeastInnard )
m_OpenedBy.Holding.Delete();
if ( Backpack != null )
{
for ( int i = Backpack.Items.Count - 1; i >= 0; i-- )
Backpack.Items[ i ].Delete();
Backpack.Delete();
}
base.OnDelete();
}
public override void OnMovement( Mobile m, Point3D oldLocation )
{
base.OnMovement( m, oldLocation );
if ( Backpack != null && IsAccessibleTo( m ) && m.InRange( oldLocation, 3 ) && !m.InRange( this, 3 ) )
Backpack.SendRemovePacket();
}
public override bool CheckNonlocalLift( Mobile from, Item item )
{
return true;
}
public override bool CheckNonlocalDrop( Mobile from, Item item, Item target )
{
return true;
}
public override bool IsSnoop( Mobile from )
{
return false;
}
public override int GetIdleSound()
{
return 0x1BF;
}
public override int GetAttackSound()
{
return 0x1C0;
}
public override int GetHurtSound()
{
return 0x1C1;
}
public override int GetDeathSound()
{
return 0x1C2;
}
public virtual void OnParalyzed( Mobile from )
{
FightMode = FightMode.None;
Frozen = true;
Blessed = true;
Combatant = null;
Hue = 0x480;
from.Combatant = null;
from.Warmode = false;
m_Timer = new DecayTimer( this );
m_Timer.Start();
Timer.DelayCall( TimeSpan.Zero, new TimerCallback( BroadcastMessage ) );
}
private void BroadcastMessage()
{
PublicOverheadMessage( MessageType.Regular, 0x3B2, 1071920 ); // * The plague beast's amorphous flesh hardens and becomes immobilized *
}
public virtual bool IsAccessibleTo( Mobile check )
{
if ( check.AccessLevel >= AccessLevel.GameMaster )
return true;
if ( !InRange( check, 2 ) )
PrivateOverheadMessage( MessageType.Label, 0x3B2, 500446, check.NetState ); // That is too far away.
else if ( m_OpenedBy != null && m_OpenedBy != check )
PrivateOverheadMessage( MessageType.Label, 0x3B2, 500365, check.NetState ); // That is being used by someone else
else if ( Frozen )
return true;
return false;
}
public virtual void Carve( Mobile from, Item item )
{
if ( m_OpenedBy == null && IsAccessibleTo( from ) )
{
m_OpenedBy = from;
if ( m_Timer == null )
m_Timer = new DecayTimer( this );
if ( !m_Timer.Running )
m_Timer.Start();
m_Timer.StartDissolving();
PlagueBeastBackpack pack = new PlagueBeastBackpack();
AddItem( pack );
pack.Initialize();
foreach ( NetState state in GetClientsInRange( 12 ) )
{
Mobile m = state.Mobile;
if ( m != null && m.Player && m != from )
PrivateOverheadMessage( MessageType.Regular, 0x3B2, 1071919, from.Name, m.NetState ); // * ~1_VAL~ slices through the plague beast's amorphous tissue *
}
from.LocalOverheadMessage( MessageType.Regular, 0x21, 1071904 ); // * You slice through the plague beast's amorphous tissue *
Timer.DelayCall<Mobile>( TimeSpan.Zero, new TimerStateCallback<Mobile>( pack.Open ), from );
}
}
public virtual bool Scissor( Mobile from, Scissors scissors )
{
if ( IsAccessibleTo( from ) )
scissors.PublicOverheadMessage( MessageType.Regular, 0x3B2, 1071918 ); // You can't cut through the plague beast's amorphous skin with scissors!
return false;
}
public void Unfreeze()
{
FightMode = FightMode.Closest;
Frozen = false;
Blessed = false;
if ( m_OpenedBy == null )
Hue = 0;
}
public PlagueBeastLord( Serial serial ) : base( serial )
{
}
public override void Serialize( GenericWriter writer )
{
base.Serialize( writer );
writer.WriteEncodedInt( 0 ); // version
writer.Write( m_OpenedBy );
if ( m_Timer != null )
{
writer.Write( (bool) true );
writer.Write( (int) m_Timer.Count );
writer.Write( (int) m_Timer.Deadline );
}
else
writer.Write( (bool) false );
}
public override void Deserialize( GenericReader reader )
{
base.Deserialize( reader );
int version = reader.ReadEncodedInt();
m_OpenedBy = reader.ReadMobile();
if ( reader.ReadBool() )
{
int count = reader.ReadInt();
int deadline = reader.ReadInt();
m_Timer = new DecayTimer( this, count, deadline );
m_Timer.Start();
}
if ( FightMode == FightMode.None )
Frozen = true;
}
private class DecayTimer : Timer
{
private PlagueBeastLord m_Lord;
private int m_Count;
private int m_Deadline;
public int Count
{
get { return m_Count; }
}
public int Deadline
{
get { return m_Deadline; }
}
public DecayTimer( PlagueBeastLord lord ) : this( lord, 0, 120 )
{
}
public DecayTimer( PlagueBeastLord lord, int count, int deadline ) : base( TimeSpan.Zero, TimeSpan.FromSeconds( 1 ) )
{
m_Lord = lord;
m_Count = count;
m_Deadline = deadline;
}
protected override void OnTick()
{
if ( m_Lord == null || m_Lord.Deleted )
{
Stop();
return;
}
if ( m_Count + 15 == m_Deadline )
{
if ( m_Lord.OpenedBy != null )
m_Lord.PublicOverheadMessage( MessageType.Regular, 0x3B2, 1071921 ); // * The plague beast begins to bubble and dissolve! *
m_Lord.PlaySound( 0x103 );
}
else if ( m_Count + 10 == m_Deadline )
{
m_Lord.PlaySound( 0x21 );
}
else if ( m_Count + 5 == m_Deadline )
{
m_Lord.PlaySound( 0x1C2 );
}
else if ( m_Count == m_Deadline )
{
m_Lord.Unfreeze();
if ( m_Lord.OpenedBy != null )
m_Lord.Kill();
Stop();
}
else if ( m_Count % 15 == 0 )
m_Lord.PlaySound( 0x1BF );
m_Count++;
}
public void StartDissolving()
{
m_Deadline = Math.Min( m_Count + 60, m_Deadline );
}
}
}
}