/Server/WorldServer/Spells/SpellBook.cs
https://bitbucket.org/arcanosteam/arcanos · C# · 357 lines · 328 code · 28 blank · 1 comment · 67 complexity · 38dee13c21ab07670a2404f2c3c5ccf9 MD5 · raw file
- using System;
- using System.Collections.Generic;
- using Arcanos.Server.WorldServer.Data;
- using Arcanos.Shared;
- using Arcanos.Shared.Objects;
- using Arcanos.Shared.Spells;
- using Arcanos.Shared.Timing;
- using Microsoft.Xna.Framework;
- namespace Arcanos.Server.WorldServer.Spells
- {
- public class SpellBook : SpellBookBase
- {
- public SpellBook(CreatureBase owner) : base(owner) { }
- public override void Update()
- {
- int count = AppliedAuras.Count;
- for (int i = 0; i < count; ++i)
- {
- Aura aura = AppliedAuras[i] as Aura;
- if (aura.ToBeRemoved)
- {
- AppliedAuras.RemoveAt(i--);
- --count;
- continue;
- }
- aura.Update();
- if (aura.ToBeRemoved)
- {
- AppliedAuras.RemoveAt(i--);
- --count;
- RemoveAura(aura);
- }
- }
- if (IsCasting)
- {
- CastingTime += Time.PerSecond;
- if (CastingTime >= CastingSpell.CastingTime)
- {
- CastSpellResult result;
- if (CastingTarget == null)
- result = FinishCast(CastingSpell, CastingGroundTarget, CastingFlags | CastSpellFlags.IgnoreAlreadyCasting);
- else
- result = FinishCast(CastingSpell, CastingTarget, CastingFlags | CastSpellFlags.IgnoreAlreadyCasting);
- if (result == CastSpellResult.Ok)
- StopCasting();
- else
- FailCasting(result);
- }
- }
- if (GlobalCooldown > 0)
- {
- GlobalCooldown -= Time.PerSecond;
- if (GlobalCooldown < 0)
- GlobalCooldown = 0;
- }
- foreach (KeyValuePair<int, CooldownInstance> pair in Cooldowns)
- if (pair.Value.Left > 0)
- {
- pair.Value.Left -= Time.PerSecond;
- if (pair.Value.Left < 0)
- pair.Value.Left = 0;
- }
- }
- public override CastSpellResult CastSpell(SpellTemplateBase spell, CreatureBase target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner;
- CastSpellResult result;
- if ((flags & CastSpellFlags.IgnoreCastingTime) == 0 && !spell.IsInstantCast())
- result = StartCasting(spell, target, flags);
- else
- result = FinishCast(spell, target, flags);
- if (result != CastSpellResult.Ok)
- Owner.SpellCastingFailed(spell, target, result);
- return result;
- }
- public override CastSpellResult CastSpell(SpellTemplateBase spell, Vector3 target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner.Position;
- CastSpellResult result;
- if ((flags & CastSpellFlags.IgnoreCastingTime) == 0 && !spell.IsInstantCast())
- result = StartCasting(spell, target, flags);
- else
- result = FinishCast(spell, target, flags);
- if (result != CastSpellResult.Ok)
- Owner.SpellCastingFailed(spell, target, result);
- return result;
- }
- public override CastSpellResult CanCastSpell(SpellTemplateBase spell, CreatureBase target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner;
- CastSpellResult genericCheckResult = CanCastSpell(spell, flags);
- if (genericCheckResult != CastSpellResult.Ok)
- return genericCheckResult;
- if ((flags & CastSpellFlags.IgnoreTargetCheck) == 0)
- {
- CastSpellResult targetCheckResult = spell.CanBeCastOn(Owner, target);
- if (targetCheckResult != CastSpellResult.Ok)
- return targetCheckResult;
- }
- return CastSpellResult.Ok;
- }
- public override CastSpellResult CanCastSpell(SpellTemplateBase spell, Vector3 target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner.Position;
- CastSpellResult genericCheckResult = CanCastSpell(spell, flags);
- if (genericCheckResult != CastSpellResult.Ok)
- return genericCheckResult;
- if ((flags & CastSpellFlags.IgnoreTargetCheck) == 0)
- {
- CastSpellResult targetCheckResult = spell.CanBeCastAt(Owner, target);
- if (targetCheckResult != CastSpellResult.Ok)
- return targetCheckResult;
- }
- return CastSpellResult.Ok;
- }
- public override void Interrupt(InterruptMask interrupt)
- {
- if (IsCasting)
- InterruptCasting(interrupt);
- InterruptAuras(interrupt);
- }
- public override void InterruptCasting(InterruptMask interrupt)
- {
- if (!IsCasting)
- return;
- if (!CastingSpell.IsCastingInterruptedBy(interrupt))
- return;
- FailCasting(CastSpellResult.Interrupted);
- }
- public override void InterruptAuras(InterruptMask interrupt)
- {
- foreach (AuraBase aura in AppliedAuras)
- if (aura.Spell.IsAuraInterruptedBy(interrupt))
- RemoveAura(aura);
- }
- public override CastSpellResult FinishCast(SpellTemplateBase spell, CreatureBase target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner;
- CastSpellResult result = CanCastSpell(spell, target, flags);
- if (result != CastSpellResult.Ok)
- return result;
- Owner.SpellCasted(spell, target);
- spell.Create(Owner, target);
- PutOnCooldown(spell);
- TakeRequirements(spell);
- return CastSpellResult.Ok;
- }
- public override CastSpellResult FinishCast(SpellTemplateBase spell, Vector3 target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner.Position;
- CastSpellResult result = CanCastSpell(spell, target, flags);
- if (result != CastSpellResult.Ok)
- return result;
- Owner.SpellCasted(spell, target);
- spell.Create(Owner, target);
- PutOnCooldown(spell);
- TakeRequirements(spell);
- return CastSpellResult.Ok;
- }
- public override CastSpellResult StartCasting(SpellTemplateBase spell, CreatureBase target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner;
- CastSpellResult result = CanCastSpell(spell, target, flags);
- if (result != CastSpellResult.Ok)
- return result;
- CastingSpell = spell;
- CastingTarget = target;
- CastingGroundTarget = Vector3.Zero;
- CastingTime = 0;
- CastingFlags = flags;
- Owner.SpellCastingStarted(spell, target);
- return CastSpellResult.Ok;
- }
- public override CastSpellResult StartCasting(SpellTemplateBase spell, Vector3 target, CastSpellFlags flags)
- {
- if (spell.HasFlag(SpellFlags.AutoTargetSelf))
- target = Owner.Position;
- CastSpellResult result = CanCastSpell(spell, target, flags);
- if (result != CastSpellResult.Ok)
- return result;
- CastingSpell = spell;
- CastingTarget = null;
- CastingGroundTarget = target;
- CastingTime = 0;
- CastingFlags = flags;
- Owner.SpellCastingStarted(spell, target);
- return CastSpellResult.Ok;
- }
- public override void FailCasting(CastSpellResult result)
- {
- if (CastingTarget == null)
- Owner.SpellCastingFailed(CastingSpell, CastingGroundTarget, result);
- else
- Owner.SpellCastingFailed(CastingSpell, CastingTarget, result);
- StopCasting();
- }
- public override void StopCasting()
- {
- CastingSpell = null;
- CastingTarget = null;
- CastingGroundTarget = Vector3.Zero;
- CastingTime = 0;
- CastingFlags = 0;
- }
- public override void AddSpell(SpellTemplateBase spell)
- {
- base.AddSpell(spell);
- RebuildSpellCache();
- }
- public override void RemoveSpell(SpellTemplateBase spell)
- {
- base.RemoveSpell(spell);
- RebuildSpellCache();
- }
- public override void RemoveAllSpells()
- {
- base.RemoveAllSpells();
- RebuildSpellCache();
- }
- public void AddCooldown(int categoryID, float left, float total)
- {
- Cooldowns.Add(categoryID, new CooldownInstance(total) { Left = left });
- }
- public override void ApplyAura(ulong casterGUID, SpellTemplateBase spell, int effectID)
- {
- Aura aura = new Aura(Owner, casterGUID, spell, effectID);
- AppliedAuras.Add(aura);
- AuraHandlers.Handle(aura, effectID, true);
- Owner.AuraApplied(aura);
- }
- public override void ApplyAura(ulong casterGUID, SpellTemplateBase spell, int effectID, float duration)
- {
- Aura aura = new Aura(Owner, casterGUID, spell, effectID);
- aura.DurationTotal = aura.DurationLeft = duration;
- AppliedAuras.Add(aura);
- AuraHandlers.Handle(aura, effectID, true);
- Owner.AuraApplied(aura);
- }
- public void ApplyAura(Aura aura)
- {
- aura.Owner = Owner;
- AppliedAuras.Add(aura);
- AuraHandlers.Handle(aura, aura.EffectID, true);
- }
- public override void RemoveAura(AuraBase aura)
- {
- aura.ToBeRemoved = true;
- AuraHandlers.Handle(aura as Aura, aura.EffectID, false);
- Owner.AuraRemoved(aura);
- }
- public void TakeRequirements(SpellTemplateBase spell)
- {
- if (spell.RequiredPowerAmount != 0)
- Owner.ModityPower(spell.RequiredPowerType, -spell.RequiredPowerAmount);
- // TODO: Reagents
- }
- public void ProcessProc(AuraType proc, CreatureBase target)
- {
- switch (proc)
- {
- case AuraType.MeleeHitProc:
- case AuraType.MeleeMissProc:
- break;
- default:
- throw new Exception();
- }
- foreach (Aura aura in GetAuras(proc))
- {
- if (R.Float() <= aura.Effect.FloatValue1)
- {
- SpellTemplate procSpell = DatabaseManager.Spells[aura.Effect.IntValue1];
- CastSpell(procSpell, target, CastSpellFlags.ProcSpellIgnores);
- }
- }
- }
- private readonly List<SpellTemplate> offensiveSpells = new List<SpellTemplate>();
- private readonly List<SpellTemplate> defensiveSpells = new List<SpellTemplate>();
- private readonly List<SpellTemplate> healingSpells = new List<SpellTemplate>();
- private void RebuildSpellCache()
- {
- foreach (SpellTemplate spell in Spells)
- {
- if (spell.HasOffensiveEffects())
- offensiveSpells.Add(spell);
- if (spell.HasDefensiveEffects())
- defensiveSpells.Add(spell);
- if (spell.HasHealingEffects())
- healingSpells.Add(spell);
- }
- }
- public IEnumerable<SpellTemplate> FindOffensiveSpells()
- {
- return offensiveSpells;
- }
- public IEnumerable<SpellTemplate> FindDefensiveSpells()
- {
- return defensiveSpells;
- }
- public IEnumerable<SpellTemplate> FindHealingSpells()
- {
- return healingSpells;
- }
- public IEnumerable<SpellTemplate> FindAvailableOffensiveSpells()
- {
- foreach (SpellTemplate spell in offensiveSpells)
- if (!IsOnCooldown(spell))
- yield return spell;
- }
- public IEnumerable<SpellTemplate> FindAvailableDefensiveSpells()
- {
- foreach (SpellTemplate spell in defensiveSpells)
- if (!IsOnCooldown(spell))
- yield return spell;
- }
- public IEnumerable<SpellTemplate> FindAvailableHealingSpells()
- {
- foreach (SpellTemplate spell in healingSpells)
- if (!IsOnCooldown(spell))
- yield return spell;
- }
- }
- }