237 lines
7.0 KiB
C#
237 lines
7.0 KiB
C#
using System;
|
|
using Server;
|
|
using Server.Mobiles;
|
|
|
|
namespace Server.Items
|
|
{
|
|
public class HealingStone : Item
|
|
{
|
|
private Mobile m_Caster;
|
|
private int m_LifeForce;
|
|
private int m_MaxLifeForce;
|
|
private int m_MaxHeal;
|
|
private int m_MaxHealTotal;
|
|
private Timer m_Timer;
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public Mobile Caster { get { return m_Caster; } }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int LifeForce { get { return m_LifeForce; } set { m_LifeForce = value; InvalidateProperties(); } }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int MaxLifeForce { get { return m_MaxLifeForce; } }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int MaxHeal { get { return m_MaxHeal; } }
|
|
|
|
[CommandProperty(AccessLevel.GameMaster)]
|
|
public int MaxHealTotal { get { return m_MaxHealTotal; } }
|
|
|
|
public override bool Nontransferable { get { return true; } }
|
|
|
|
[Constructable]
|
|
public HealingStone( Mobile caster, int amount, int maxHeal ) : base( 0x4078 )
|
|
{
|
|
m_Caster = caster;
|
|
m_LifeForce = amount;
|
|
m_MaxHeal = maxHeal;
|
|
|
|
m_MaxLifeForce = amount;
|
|
m_MaxHealTotal = maxHeal;
|
|
|
|
LootType = LootType.Blessed;
|
|
}
|
|
|
|
public override void OnDoubleClick( Mobile from )
|
|
{
|
|
if ( !from.InRange( this.GetWorldLocation(), 1 ) )
|
|
{
|
|
from.SendLocalizedMessage( 502138 ); // That is too far away for you to use
|
|
return;
|
|
}
|
|
else if ( from != m_Caster )
|
|
{
|
|
}
|
|
else if (!BasePotion.HasFreeHand(from))
|
|
{
|
|
from.SendLocalizedMessage(1080116); // You must have a free hand to use a Healing Stone.
|
|
}
|
|
else if (from.Hits >= from.HitsMax && !from.Poisoned)
|
|
{
|
|
from.SendLocalizedMessage(1049547); //You are already at full health.
|
|
}
|
|
else if (from.BeginAction(typeof(HealingStone)))
|
|
{
|
|
if (m_MaxHeal > m_LifeForce)
|
|
m_MaxHeal = m_LifeForce;
|
|
|
|
if (from.Poisoned)
|
|
{
|
|
int toUse = Math.Min(120, from.Poison.RealLevel * 25);
|
|
|
|
if (m_MaxLifeForce < toUse)
|
|
from.SendLocalizedMessage(1115265); //Your Mysticism, Focus, or Imbuing Skills are not enough to use the heal stone to cure yourself.
|
|
else if (m_LifeForce < toUse)
|
|
{
|
|
from.SendLocalizedMessage(1115264); //Your healing stone does not have enough energy to remove the poison.
|
|
LifeForce -= toUse / 3;
|
|
}
|
|
else
|
|
{
|
|
from.CurePoison(from);
|
|
|
|
from.SendLocalizedMessage(500231); // You feel cured of poison!
|
|
|
|
from.FixedEffect(0x373A, 10, 15);
|
|
from.PlaySound(0x1E0);
|
|
|
|
LifeForce -= toUse;
|
|
}
|
|
|
|
if (m_LifeForce <= 0)
|
|
this.Consume();
|
|
|
|
Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerStateCallback(ReleaseHealLock), from);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
int toHeal = Math.Min(m_MaxHeal, from.HitsMax - from.Hits);
|
|
from.Heal(toHeal);
|
|
Timer.DelayCall(TimeSpan.FromSeconds(2.0), new TimerStateCallback(ReleaseHealLock), from);
|
|
|
|
from.FixedParticles(0x376A, 9, 32, 5030, EffectLayer.Waist);
|
|
from.PlaySound(0x202);
|
|
|
|
LifeForce -= toHeal;
|
|
m_MaxHeal = 1;
|
|
}
|
|
|
|
if (m_LifeForce <= 0)
|
|
{
|
|
from.SendLocalizedMessage(1115266); //The healing stone has used up all its energy and has been destroyed.
|
|
this.Consume();
|
|
}
|
|
else
|
|
{
|
|
if (m_Timer != null)
|
|
m_Timer.Stop();
|
|
|
|
m_Timer = new InternalTimer(this);
|
|
}
|
|
}
|
|
else
|
|
from.SendLocalizedMessage(1095172); // You must wait a few seconds before using another Healing Stone.
|
|
}
|
|
|
|
public void OnTick()
|
|
{
|
|
if (m_MaxHeal < m_MaxHealTotal)
|
|
{
|
|
int maxToHeal = m_MaxHealTotal - m_MaxHeal;
|
|
m_MaxHeal += Math.Min(maxToHeal, m_MaxHealTotal / 15);
|
|
|
|
if (m_MaxHeal > m_MaxHealTotal)
|
|
m_MaxHeal = m_MaxHealTotal;
|
|
}
|
|
}
|
|
|
|
private class InternalTimer : Timer
|
|
{
|
|
private HealingStone m_Stone;
|
|
private int m_Ticks;
|
|
|
|
public InternalTimer ( HealingStone stone ) : base(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1))
|
|
{
|
|
m_Stone = stone;
|
|
m_Ticks = 0;
|
|
this.Start();
|
|
}
|
|
|
|
protected override void OnTick()
|
|
{
|
|
m_Ticks++;
|
|
|
|
m_Stone.OnTick();
|
|
|
|
if (m_Ticks >= 15)
|
|
this.Stop();
|
|
}
|
|
}
|
|
|
|
public override bool DropToWorld( Mobile from, Point3D p )
|
|
{
|
|
Delete();
|
|
return false;
|
|
}
|
|
|
|
public override bool AllowSecureTrade( Mobile from, Mobile to, Mobile newOwner, bool accepted )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
private static void ReleaseHealLock( object state )
|
|
{
|
|
((Mobile)state).EndAction( typeof( HealingStone ) );
|
|
}
|
|
|
|
public override void Delete()
|
|
{
|
|
if (m_Timer != null)
|
|
{
|
|
m_Timer.Stop();
|
|
m_Timer = null;
|
|
}
|
|
|
|
base.Delete();
|
|
}
|
|
|
|
public override void GetProperties(ObjectPropertyList list)
|
|
{
|
|
base.GetProperties(list);
|
|
|
|
list.Add(1115274, m_LifeForce.ToString());
|
|
}
|
|
|
|
public HealingStone( Serial serial ) : base( serial )
|
|
{
|
|
}
|
|
|
|
public override void Serialize(GenericWriter writer)
|
|
{
|
|
base.Serialize(writer);
|
|
writer.Write((int)1);
|
|
|
|
writer.Write(m_Caster);
|
|
writer.Write(m_LifeForce);
|
|
writer.Write(m_MaxLifeForce);
|
|
writer.Write(m_MaxHeal);
|
|
writer.Write(m_MaxHealTotal);
|
|
}
|
|
|
|
public override void Deserialize(GenericReader reader)
|
|
{
|
|
base.Deserialize(reader);
|
|
int version = reader.ReadInt();
|
|
|
|
switch (version)
|
|
{
|
|
case 1:
|
|
m_Caster = reader.ReadMobile();
|
|
m_LifeForce = reader.ReadInt();
|
|
m_MaxLifeForce = reader.ReadInt();
|
|
m_MaxHeal = reader.ReadInt();
|
|
m_MaxHealTotal = reader.ReadInt();
|
|
break;
|
|
case 0:
|
|
break;
|
|
}
|
|
|
|
if (m_LifeForce <= 0)
|
|
{
|
|
Delete();
|
|
}
|
|
}
|
|
}
|
|
} |