rendered paste bodyusing System;
using Server.Mobiles;
namespace Server
{
public class SpeechLock : Timer
{
private const int MAX_WARNINGS = 15;
private const int FIRST_WARNING = 5;
private const int SECOND_WARNING = 10;
private const int ALLOWED_WARNINGS = 2;
private int m_Warnings, m_OldWarnings, m_Offences, m_OldOffences, m_CurrentTick, m_SpokenLinesThisTick, m_SpokenLinesTotal;
private PlayerMobile m_Owner;
private DateTime m_LastUpdate = DateTime.Now;
private Timer m_CallbackTimer;
public int Warnings
{
get {return m_Warnings; }
set
{
if (value > MAX_WARNINGS)
{
Offences += 1;
value -= 10;
}
else if (m_Warnings < SECOND_WARNING && value > SECOND_WARNING) //25 sec squelch
{
if (m_CallbackTimer != null)
{
m_CallbackTimer.Stop();
m_CallbackTimer = null;
}
m_Owner.EndAction(typeof (SpeechLock));
m_Owner.BeginAction(typeof (SpeechLock));
m_CallbackTimer = DelayCall(TimeSpan.FromSeconds(25.5), new TimerStateCallback(ReleaseSpeechLock), m_Owner);
}
else if (m_Warnings < FIRST_WARNING && value > FIRST_WARNING) // 12.5 sec squelce
{
if (m_CallbackTimer != null)
{
m_CallbackTimer.Stop();
m_CallbackTimer = null;
}
m_Owner.EndAction(typeof(SpeechLock));
m_Owner.BeginAction(typeof(SpeechLock));
DelayCall(TimeSpan.FromSeconds(12.5), new TimerStateCallback(ReleaseSpeechLock), m_Owner);
}
else if (value < 0)
value = 0;
m_Warnings = value;
}
}
public int OldWarnings
{
get { return m_OldWarnings; }
set { m_OldWarnings = value; }
}
public int Offences
{
get { return m_Offences; }
set
{
m_Offences = value;
}
}
public int OldOffences
{
get { return m_OldOffences; }
set { m_OldOffences = value; }
}
public Timer CallbackTimer
{
get { return m_CallbackTimer; }
set { m_CallbackTimer = value; }
}
public DateTime LastUpdate
{
get { return m_LastUpdate; }
set
{
m_SpokenLinesThisTick++;
m_SpokenLinesTotal++;
m_LastUpdate = value;
}
}
public SpeechLock(PlayerMobile owner) : base(TimeSpan.FromSeconds(2.5), TimeSpan.FromSeconds(2.5))
{
if (owner != null)
{
m_Owner = owner;
Start();
}
else
EndTimer();
}
protected override void OnTick()
{
#region Killing the timer IF
if (!m_Owner.Alive) //Kill the timer on death.
{
EndTimer();
return;
}
else if (m_Owner.NetState == null) //Kill the timer on disc.
{
EndTimer();
return;
}
else if (m_LastUpdate+TimeSpan.FromMinutes(1.0) < DateTime.Now)
{
EndTimer();
return;
}
#endregion
++m_CurrentTick;
//4 = 10 sec
if (m_CurrentTick == 4) // 10 secs
{
if (m_SpokenLinesTotal >= 20) //Max 20 words after 10 secs
Warnings += 13;
}
else if (m_CurrentTick == 3) // 7.5 secs
{
if (m_SpokenLinesTotal >= 15) //Max 15 words after 7.5 secs
Warnings += 10;
}
else if (m_CurrentTick == 2) // 5 secs
{
if (m_SpokenLinesTotal >= 10) //Max 10 words after 5 secs
Warnings += 7;
}
//Maximum amount of words spoken every tick
if (m_SpokenLinesThisTick >= 8)
m_Warnings += ALLOWED_WARNINGS;
if ( m_OldOffences <= m_Offences)
Offences -= 1;
if (m_OldWarnings <= m_Warnings + ALLOWED_WARNINGS)
Warnings -= ALLOWED_WARNINGS;
#region Variable set
m_OldOffences = m_Offences;
m_OldWarnings = m_Warnings;
m_SpokenLinesThisTick = 0;
if (m_CurrentTick == 4)
{
m_SpokenLinesTotal = 0;
m_CurrentTick = 0;
}
#endregion
base.OnTick();
}
public void EndTimer()
{
m_Owner.SpeechLock = null;
Stop();
}
public static bool CanBeginSpeech(PlayerMobile from)
{
if (from.SpeechLock == null)
from.SpeechLock = new SpeechLock(from);
from.SpeechLock.LastUpdate = DateTime.Now;
if (from.BeginAction(typeof(SpeechLock)))
{
DelayCall(TimeSpan.FromMilliseconds(100.0), new TimerStateCallback(ReleaseSpeechLock), from);
return true;
}
else
{
from.SpeechLock.Warnings += 1;
return false;
}
}
public static void ReleaseSpeechLock(object state)
{
((PlayerMobile)state).SpeechLock.CallbackTimer = null;
((PlayerMobile)state).EndAction(typeof(SpeechLock));
}
}
}