ModernUO/Projects/Scripts/Engines/Khaldun/RaisableItem.cs
2019-08-02 18:16:11 -07:00

170 lines
No EOL
4 KiB
C#

using System;
namespace Server.Items
{
public class RaisableItem : Item
{
private int m_Elevation;
private int m_MaxElevation;
private RaiseTimer m_RaiseTimer;
[Constructible]
public RaisableItem(int itemID) : this(itemID, 20, -1, -1, TimeSpan.FromMinutes(1.0))
{
}
[Constructible]
public RaisableItem(int itemID, int maxElevation, TimeSpan closeDelay) : this(itemID, maxElevation, -1, -1,
closeDelay)
{
}
[Constructible]
public RaisableItem(int itemID, int maxElevation, int moveSound, int stopSound, TimeSpan closeDelay) : base(itemID)
{
Movable = false;
m_MaxElevation = maxElevation;
MoveSound = moveSound;
StopSound = stopSound;
CloseDelay = closeDelay;
}
public RaisableItem(Serial serial) : base(serial)
{
}
[CommandProperty(AccessLevel.GameMaster)]
public int MaxElevation
{
get => m_MaxElevation;
set
{
if (value <= 0)
m_MaxElevation = 0;
else if (value >= 60)
m_MaxElevation = 60;
else
m_MaxElevation = value;
}
}
[CommandProperty(AccessLevel.GameMaster)]
public int MoveSound{ get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public int StopSound{ get; set; }
[CommandProperty(AccessLevel.GameMaster)]
public TimeSpan CloseDelay{ get; set; }
public bool IsRaisable => m_RaiseTimer == null;
public void Raise()
{
if (!IsRaisable)
return;
m_RaiseTimer = new RaiseTimer(this);
m_RaiseTimer.Start();
}
public override void Serialize(GenericWriter writer)
{
base.Serialize(writer);
writer.WriteEncodedInt(0); // version
writer.WriteEncodedInt(m_MaxElevation);
writer.WriteEncodedInt(MoveSound);
writer.WriteEncodedInt(StopSound);
writer.Write(CloseDelay);
writer.WriteEncodedInt(m_Elevation);
}
public override void Deserialize(GenericReader reader)
{
base.Deserialize(reader);
int version = reader.ReadEncodedInt();
m_MaxElevation = reader.ReadEncodedInt();
MoveSound = reader.ReadEncodedInt();
StopSound = reader.ReadEncodedInt();
CloseDelay = reader.ReadTimeSpan();
int elevation = reader.ReadEncodedInt();
Z -= elevation;
}
private class RaiseTimer : Timer
{
private DateTime m_CloseTime;
private RaisableItem m_Item;
private int m_Step;
private bool m_Up;
public RaiseTimer(RaisableItem item) : base(TimeSpan.Zero, TimeSpan.FromSeconds(0.5))
{
m_Item = item;
m_CloseTime = DateTime.UtcNow + item.CloseDelay;
m_Up = true;
Priority = TimerPriority.TenMS;
}
protected override void OnTick()
{
if (m_Item.Deleted)
{
Stop();
return;
}
if (m_Step++ % 3 == 0)
{
if (m_Up)
{
m_Item.Z++;
if (++m_Item.m_Elevation >= m_Item.MaxElevation)
{
Stop();
if (m_Item.StopSound >= 0)
Effects.PlaySound(m_Item.Location, m_Item.Map, m_Item.StopSound);
m_Up = false;
m_Step = 0;
TimeSpan delay = m_CloseTime - DateTime.UtcNow;
DelayCall(delay > TimeSpan.Zero ? delay : TimeSpan.Zero, Start);
return;
}
}
else
{
m_Item.Z--;
if (--m_Item.m_Elevation <= 0)
{
Stop();
if (m_Item.StopSound >= 0)
Effects.PlaySound(m_Item.Location, m_Item.Map, m_Item.StopSound);
m_Item.m_RaiseTimer = null;
return;
}
}
}
if (m_Item.MoveSound >= 0)
Effects.PlaySound(m_Item.Location, m_Item.Map, m_Item.MoveSound);
}
}
}
}