Overwrite

Complete Overwrite of the Folder with the free shard. ServUO 57.3 has been added.
This commit is contained in:
Unstable Kitsune
2023-11-28 23:20:26 -05:00
parent 3cd54811de
commit b918192e4e
11608 changed files with 2644205 additions and 47 deletions

View File

@@ -0,0 +1,317 @@
using System;
using Server.Mobiles;
using System.Collections.Generic;
namespace Server.Spells.Chivalry
{
public class EnemyOfOneSpell : PaladinSpell
{
private static readonly SpellInfo m_Info = new SpellInfo(
"Enemy of One", "Forul Solum",
-1,
9002);
public EnemyOfOneSpell(Mobile caster, Item scroll)
: base(caster, scroll, m_Info)
{
}
public override TimeSpan CastDelayBase { get { return TimeSpan.FromSeconds(0.5); } }
public override double RequiredSkill { get { return 45.0; } }
public override int RequiredMana { get { return 20; } }
public override int RequiredTithing { get { return 10; } }
public override int MantraNumber { get { return 1060723; } } // Forul Solum
public override bool BlocksMovement { get { return false; } }
public override TimeSpan GetCastDelay()
{
TimeSpan delay = base.GetCastDelay();
if (Core.SA && UnderEffect(Caster))
{
double milliseconds = delay.TotalMilliseconds / 2;
delay = TimeSpan.FromMilliseconds(milliseconds);
}
return delay;
}
public override void OnCast()
{
if (Core.SA && UnderEffect(Caster))
{
PlayEffects();
// As per Pub 71, Enemy of one has now been changed to a Spell Toggle. You can remove the effect
// before the duration expires by recasting the spell.
RemoveEffect(Caster);
}
else if (CheckSequence())
{
PlayEffects();
// TODO: validate formula
var seconds = ComputePowerValue(1);
Utility.FixMinMax(ref seconds, 67, 228);
var delay = TimeSpan.FromSeconds(seconds);
var timer = Timer.DelayCall(delay, RemoveEffect, Caster);
var expire = DateTime.UtcNow + delay;
var context = new EnemyOfOneContext(Caster, timer, expire);
context.OnCast();
m_Table[Caster] = context;
}
FinishSequence();
}
private void PlayEffects()
{
Caster.PlaySound(0x0F5);
Caster.PlaySound(0x1ED);
Caster.FixedParticles(0x375A, 1, 30, 9966, 33, 2, EffectLayer.Head);
Caster.FixedParticles(0x37B9, 1, 30, 9502, 43, 3, EffectLayer.Head);
}
private static readonly Dictionary<Mobile, EnemyOfOneContext> m_Table = new Dictionary<Mobile, EnemyOfOneContext>();
public static EnemyOfOneContext GetContext(Mobile m)
{
if (!m_Table.ContainsKey(m))
return null;
return m_Table[m];
}
public static bool UnderEffect(Mobile m)
{
return m_Table.ContainsKey(m);
}
public static void RemoveEffect(Mobile m)
{
if (m_Table.ContainsKey(m))
{
var context = m_Table[m];
m_Table.Remove(m);
context.OnRemoved();
m.PlaySound(0x1F8);
}
}
public static Dictionary<Type, string> NameCache { get; set; }
public static void Configure()
{
if (NameCache == null)
NameCache = new Dictionary<Type, string>();
}
public static string GetTypeName(Mobile defender)
{
if (defender is PlayerMobile || (defender is BaseCreature && ((BaseCreature)defender).GetMaster() is PlayerMobile))
{
return defender.Name;
}
Type t = defender.GetType();
if (NameCache.ContainsKey(t))
{
return NameCache[t];
}
return AddNameToCache(t);
}
public static string AddNameToCache(Type t)
{
string name = t.Name;
if (name != null)
{
for (int i = 0; i < name.Length; i++)
{
if (i > 0 && Char.IsUpper(name[i]))
{
name = name.Insert(i, " ");
i++;
}
}
if (name.EndsWith("y"))
{
name = name.Substring(0, name.Length - 1);
name = name + "ies";
}
else if (!name.EndsWith("s"))
{
name = name + "s";
}
NameCache[t] = name.ToLower();
}
return name;
}
}
public class EnemyOfOneContext
{
private Mobile m_Owner;
private Timer m_Timer;
private DateTime m_Expire;
private Type m_TargetType;
private int m_DamageScalar;
private string m_TypeName;
private Mobile m_PlayerOrPet;
public Mobile Owner { get { return m_Owner; } }
public Timer Timer { get { return m_Timer; } }
public Type TargetType { get { return m_TargetType; } }
public int DamageScalar { get { return m_DamageScalar; } }
public string TypeName { get { return m_TypeName; } }
public EnemyOfOneContext(Mobile owner, Timer timer, DateTime expire)
{
m_Owner = owner;
m_Timer = timer;
m_Expire = expire;
m_TargetType = null;
m_DamageScalar = 50;
}
public bool IsWaitingForEnemy { get { return m_TargetType == null; } }
public bool IsEnemy(Mobile m)
{
if (m is BaseCreature && ((BaseCreature)m).GetMaster() == Owner)
{
return false;
}
if (m_PlayerOrPet != null)
{
if (m_PlayerOrPet == m)
{
return true;
}
}
else if (m_TargetType == m.GetType())
{
return true;
}
return false;
}
public void OnCast()
{
UpdateBuffInfo();
}
private void UpdateDamage()
{
var chivalry = (int)m_Owner.Skills.Chivalry.Value;
m_DamageScalar = 10 + ((chivalry - 40) * 9) / 10;
if (m_PlayerOrPet != null)
m_DamageScalar /= 2;
}
private void UpdateBuffInfo()
{
if (m_TypeName == null)
{
BuffInfo.AddBuff(m_Owner, new BuffInfo(BuffIcon.EnemyOfOne, 1075653, 1075902, m_Expire - DateTime.UtcNow, m_Owner, string.Format("{0}\t{1}", m_DamageScalar, "100"), true));
}
else
{
BuffInfo.AddBuff(m_Owner, new BuffInfo(BuffIcon.EnemyOfOne, 1075653, 1075654, m_Expire - DateTime.UtcNow, m_Owner, string.Format("{0}\t{1}\t{2}\t{3}", m_DamageScalar, TypeName, ".", "100"), true));
}
}
public void OnHit(Mobile defender)
{
if (m_TargetType == null)
{
m_TypeName = EnemyOfOneSpell.GetTypeName(defender);
if (defender is PlayerMobile || (defender is BaseCreature && ((BaseCreature)defender).GetMaster() is PlayerMobile))
{
m_PlayerOrPet = defender;
TimeSpan duration = TimeSpan.FromSeconds(8);
if (DateTime.UtcNow + duration < m_Expire)
{
m_Expire = DateTime.UtcNow + duration;
}
if (m_Timer != null)
{
m_Timer.Stop();
m_Timer = null;
}
m_Timer = Timer.DelayCall(duration, EnemyOfOneSpell.RemoveEffect, m_Owner);
}
else
{
m_TargetType = defender.GetType();
}
UpdateDamage();
DeltaEnemies();
UpdateBuffInfo();
}
else if (Core.SA)
{
// Odd but OSI recalculates when the target changes...
UpdateDamage();
}
}
public void OnRemoved()
{
if (m_Timer != null)
m_Timer.Stop();
DeltaEnemies();
BuffInfo.RemoveBuff(m_Owner, BuffIcon.EnemyOfOne);
}
private void DeltaEnemies()
{
IPooledEnumerable eable = m_Owner.GetMobilesInRange(18);
foreach (Mobile m in eable)
{
if (m_PlayerOrPet != null)
{
if (m == m_PlayerOrPet)
{
m.Delta(MobileDelta.Noto);
}
}
else if (m.GetType() == m_TargetType)
{
m.Delta(MobileDelta.Noto);
}
}
eable.Free();
}
}
}