Files
abysmal-isle/Scripts/Abilities/ForceArrow.cs
Unstable Kitsune b918192e4e Overwrite
Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
2023-11-28 23:20:26 -05:00

168 lines
5.1 KiB
C#

using System;
using Server;
using System.Collections;
using System.Collections.Generic;
using Server.Spells;
namespace Server.Items
{
public class ForceArrow : WeaponAbility
{
public ForceArrow()
{
}
public override int BaseMana { get { return 20; } }
public override void OnHit(Mobile attacker, Mobile defender, int damage)
{
if (!Validate(attacker) || !CheckMana(attacker, true))
return;
ClearCurrentAbility(attacker);
attacker.SendLocalizedMessage(1074381); // You fire an arrow of pure force.
defender.SendLocalizedMessage(1074382); // You are struck by a force arrow!
if (.4 > Utility.RandomDouble())
{
defender.Combatant = null;
defender.Warmode = false;
}
ForceArrowInfo info = GetInfo(attacker, defender);
if (info == null)
BeginForceArrow(attacker, defender);
else
{
if (info.Timer != null && info.Timer.Running)
{
info.Timer.IncreaseExpiration();
BuffInfo.RemoveBuff(defender, BuffIcon.ForceArrow);
BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.ForceArrow, 1151285, 1151286, info.DefenseChanceMalus.ToString()));
}
}
Spell spell = defender.Spell as Spell;
if (spell != null && spell.IsCasting)
spell.Disturb(DisturbType.Hurt, false, true);
}
private static Dictionary<Mobile, List<ForceArrowInfo>> m_Table = new Dictionary<Mobile, List<ForceArrowInfo>>();
public static void BeginForceArrow(Mobile attacker, Mobile defender)
{
ForceArrowInfo info = new ForceArrowInfo(attacker, defender);
info.Timer = new ForceArrowTimer(info);
if (!m_Table.ContainsKey(attacker))
m_Table[attacker] = new List<ForceArrowInfo>();
m_Table[attacker].Add(info);
BuffInfo.AddBuff(defender, new BuffInfo(BuffIcon.ForceArrow, 1151285, 1151286, info.DefenseChanceMalus.ToString()));
}
public static void EndForceArrow(ForceArrowInfo info)
{
if (info == null)
return;
Mobile attacker = info.Attacker;
if (m_Table.ContainsKey(attacker) && m_Table[attacker].Contains(info))
{
m_Table[attacker].Remove(info);
if (m_Table[attacker].Count == 0)
m_Table.Remove(attacker);
}
BuffInfo.RemoveBuff(info.Defender, BuffIcon.ForceArrow);
}
public static bool HasForceArrow(Mobile attacker, Mobile defender)
{
if (!m_Table.ContainsKey(attacker))
return false;
foreach (ForceArrowInfo info in m_Table[attacker])
{
if (info.Defender == defender)
return true;
}
return false;
}
public static ForceArrowInfo GetInfo(Mobile attacker, Mobile defender)
{
if (!m_Table.ContainsKey(attacker))
return null;
foreach (ForceArrowInfo info in m_Table[attacker])
{
if (info.Defender == defender)
return info;
}
return null;
}
public class ForceArrowInfo
{
private Mobile m_Attacker;
private Mobile m_Defender;
private ForceArrowTimer m_Timer;
private int m_DefenseChanceMalus;
public Mobile Attacker { get { return m_Attacker; } }
public Mobile Defender { get { return m_Defender; } }
public ForceArrowTimer Timer { get { return m_Timer; } set { m_Timer = value; } }
public int DefenseChanceMalus { get { return m_DefenseChanceMalus; } set { m_DefenseChanceMalus = value; } }
public ForceArrowInfo(Mobile attacker, Mobile defender)
{
m_Attacker = attacker;
m_Defender = defender;
m_DefenseChanceMalus = 10;
}
}
public class ForceArrowTimer : Timer
{
private ForceArrowInfo m_Info;
private DateTime m_Expires;
public ForceArrowTimer(ForceArrowInfo info)
: base(TimeSpan.FromSeconds(1.0), TimeSpan.FromSeconds(1))
{
m_Info = info;
Priority = TimerPriority.OneSecond;
m_Expires = DateTime.UtcNow + TimeSpan.FromSeconds(10);
Start();
}
protected override void OnTick()
{
if (m_Expires < DateTime.UtcNow)
{
Stop();
EndForceArrow(m_Info);
}
}
public void IncreaseExpiration()
{
m_Expires = m_Expires + TimeSpan.FromSeconds(2);
m_Info.DefenseChanceMalus += 5;
}
}
}
}