using 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)); } } }