From 5a0d2b527bc7e0742d9e3ad84b1de8788a931dd4 Mon Sep 17 00:00:00 2001 From: "Michael Cook (mackal)" Date: Tue, 16 Aug 2016 17:52:14 -0400 Subject: [PATCH] Add a StopCasting function and make some use of it Unsure if all of these cases should use interrupt or stop casting --- zone/mob.h | 1 + zone/spells.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/zone/mob.h b/zone/mob.h index b80667b02..927ecf862 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -272,6 +272,7 @@ public: virtual float GetAOERange(uint16 spell_id); void InterruptSpell(uint16 spellid = SPELL_UNKNOWN); void InterruptSpell(uint16, uint16, uint16 spellid = SPELL_UNKNOWN); + void StopCasting(); inline bool IsCasting() const { return((casting_spell_id != 0)); } uint16 CastingSpellID() const { return casting_spell_id; } bool DoCastingChecks(); diff --git a/zone/spells.cpp b/zone/spells.cpp index 701f0355f..4e79ede91 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -470,6 +470,10 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, // cast time is 0, just finish it right now and be done with it if(cast_time == 0) { + if (!DoCastingChecks()) { + StopCasting(); + return false; + } CastedSpellFinished(spell_id, target_id, slot, mana_cost, item_slot, resist_adjust); return(true); } @@ -498,7 +502,7 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, } if (!DoCastingChecks()) { - InterruptSpell(); + StopCasting(); return false; } @@ -882,6 +886,32 @@ void Mob::InterruptSpell(uint16 message, uint16 color, uint16 spellid) } +// this is like interrupt, just it doesn't spam interrupt packets to everyone +// There are a few cases where this is what live does :P +void Mob::StopCasting() +{ + if (casting_spell_id && IsNPC()) { + CastToNPC()->AI_Event_SpellCastFinished(false, static_cast(casting_spell_slot)); + } + + if (IsClient()) { + auto c = CastToClient(); + if (casting_spell_aa_id) { //Rest AA Timer on failed cast + c->Message_StringID(MT_SpellFailure, ABILITY_FAILED); + c->ResetAlternateAdvancementTimer(casting_spell_aa_id); + } + + auto outapp = new EQApplicationPacket(OP_ManaChange, sizeof(ManaChange_Struct)); + auto mc = (ManaChange_Struct *)outapp->pBuffer; + mc->new_mana = GetMana(); + mc->stamina = GetEndurance(); + mc->spell_id = casting_spell_id; + mc->keepcasting = 0; + c->FastQueuePacket(&outapp); + } + ZeroCastingVars(); +} + // this is called after the timer is up and the spell is finished // casting. everything goes through here, including items with zero cast time // only to be used from SpellProcess