Core/Spells: enable and implement SMSG_MISSILE_CANCEL (#25215)
This commit is contained in:
@@ -78,6 +78,7 @@ class TC_COMMON_API EventProcessor
|
||||
void AddEvent(BasicEvent* Event, uint64 e_time, bool set_addtime = true);
|
||||
void ModifyEventTime(BasicEvent* Event, uint64 newTime);
|
||||
uint64 CalculateTime(uint64 t_offset) const;
|
||||
std::multimap<uint64, BasicEvent*> const& GetEvents() const { return m_events; }
|
||||
|
||||
protected:
|
||||
uint64 m_time;
|
||||
|
||||
@@ -12361,6 +12361,31 @@ void Unit::SendPlaySpellVisualKit(uint32 id, uint32 type, uint32 duration) const
|
||||
SendMessageToSet(playSpellVisualKit.Write(), true);
|
||||
}
|
||||
|
||||
void Unit::CancelSpellMissiles(uint32 spellId, bool reverseMissile /*= false*/)
|
||||
{
|
||||
bool hasMissile = false;
|
||||
for (std::pair<uint64 const, BasicEvent*> const& itr : m_Events.GetEvents())
|
||||
{
|
||||
if (Spell const* spell = Spell::ExtractSpellFromEvent(itr.second))
|
||||
{
|
||||
if (spell->GetSpellInfo()->Id == spellId)
|
||||
{
|
||||
itr.second->ScheduleAbort();
|
||||
hasMissile = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasMissile)
|
||||
{
|
||||
WorldPackets::Spells::MissileCancel packet;
|
||||
packet.OwnerGUID = GetGUID();
|
||||
packet.SpellID = spellId;
|
||||
packet.Reverse = reverseMissile;
|
||||
SendMessageToSet(packet.Write(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void Unit::ApplyResilience(Unit const* victim, int32* damage) const
|
||||
{
|
||||
// player mounted on multi-passenger mount is also classified as vehicle
|
||||
|
||||
@@ -1340,6 +1340,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SendPlaySpellVisual(Position const& targetPosition, float o, uint32 spellVisualId, uint16 missReason, uint16 reflectStatus, float travelSpeed, bool speedAsTime = false);
|
||||
void SendCancelSpellVisualKit(uint32 id);
|
||||
void SendPlaySpellVisualKit(uint32 id, uint32 type, uint32 duration) const;
|
||||
void CancelSpellMissiles(uint32 spellId, bool reverseMissile = false);
|
||||
|
||||
void DeMorph();
|
||||
|
||||
|
||||
@@ -967,3 +967,13 @@ WorldPacket const* WorldPackets::Spells::MountResult::Write()
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
WorldPacket const* WorldPackets::Spells::MissileCancel::Write()
|
||||
{
|
||||
_worldPacket << OwnerGUID;
|
||||
_worldPacket << int32(SpellID);
|
||||
_worldPacket.WriteBit(Reverse);
|
||||
_worldPacket.FlushBits();
|
||||
|
||||
return &_worldPacket;
|
||||
}
|
||||
|
||||
@@ -1009,6 +1009,18 @@ namespace WorldPackets
|
||||
|
||||
uint32 Result = 0;
|
||||
};
|
||||
|
||||
class MissileCancel final : public ServerPacket
|
||||
{
|
||||
public:
|
||||
MissileCancel() : ServerPacket(SMSG_MISSILE_CANCEL, 21) { }
|
||||
|
||||
WorldPacket const* Write() override;
|
||||
|
||||
ObjectGuid OwnerGUID;
|
||||
bool Reverse = false;
|
||||
int32 SpellID = 0;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1450,7 +1450,7 @@ void OpcodeTable::Initialize()
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MINIMAP_PING, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_COMPONENTED_DATA, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MIRROR_IMAGE_CREATURE_DATA, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_UNHANDLED, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MISSILE_CANCEL, STATUS_NEVER, CONNECTION_TYPE_REALM);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_CHARGE_RECOVERY_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN, STATUS_NEVER, CONNECTION_TYPE_INSTANCE);
|
||||
DEFINE_SERVER_OPCODE_HANDLER(SMSG_MODIFY_COOLDOWN_RECOVERY_SPEED, STATUS_UNHANDLED, CONNECTION_TYPE_INSTANCE);
|
||||
|
||||
@@ -511,9 +511,11 @@ public:
|
||||
SpellEvent(Spell* spell);
|
||||
virtual ~SpellEvent();
|
||||
|
||||
virtual bool Execute(uint64 e_time, uint32 p_time) override;
|
||||
virtual void Abort(uint64 e_time) override;
|
||||
virtual bool IsDeletable() const override;
|
||||
bool Execute(uint64 e_time, uint32 p_time) override;
|
||||
void Abort(uint64 e_time) override;
|
||||
bool IsDeletable() const override;
|
||||
Spell const* GetSpell() const { return m_Spell; }
|
||||
|
||||
protected:
|
||||
Spell* m_Spell;
|
||||
};
|
||||
@@ -4880,6 +4882,14 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT
|
||||
}
|
||||
}
|
||||
|
||||
/*static*/ Spell const* Spell::ExtractSpellFromEvent(BasicEvent* event)
|
||||
{
|
||||
if (SpellEvent* spellEvent = dynamic_cast<SpellEvent*>(event))
|
||||
return spellEvent->GetSpell();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint32* param2 /*= nullptr*/)
|
||||
{
|
||||
// check death state
|
||||
|
||||
@@ -38,6 +38,7 @@ namespace WorldPackets
|
||||
|
||||
class Aura;
|
||||
class AuraEffect;
|
||||
class BasicEvent;
|
||||
class Corpse;
|
||||
class DynamicObject;
|
||||
class GameObject;
|
||||
@@ -598,6 +599,7 @@ class TC_GAME_API Spell
|
||||
|
||||
void HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOTarget, uint32 i, SpellEffectHandleMode mode);
|
||||
void HandleThreatSpells();
|
||||
static Spell const* ExtractSpellFromEvent(BasicEvent* event);
|
||||
|
||||
SpellInfo const* const m_spellInfo;
|
||||
Item* m_CastItem;
|
||||
|
||||
Reference in New Issue
Block a user