diff options
Diffstat (limited to 'src')
24 files changed, 262 insertions, 235 deletions
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 0fa99cfe2cc..92e218bf25f 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -746,7 +746,7 @@ void Creature::Update(uint32 diff) else if (m_corpseRemoveTime <= GameTime::GetGameTime()) { RemoveCorpse(false); - TC_LOG_DEBUG("entities.unit", "Removing corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY)); + TC_LOG_DEBUG("entities.unit", "Removing corpse... %u ", GetEntry()); } break; } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index a207088ec5b..7d0c92b5335 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -1331,7 +1331,7 @@ void GameObject::Respawn() } } -bool GameObject::ActivateToQuest(Player* target) const +bool GameObject::ActivateToQuest(Player const* target) const { if (target->HasQuestForGO(GetEntry())) return true; @@ -1344,7 +1344,7 @@ bool GameObject::ActivateToQuest(Player* target) const case GAMEOBJECT_TYPE_QUESTGIVER: { GameObject* go = const_cast<GameObject*>(this); - QuestGiverStatus questStatus = target->GetQuestDialogStatus(go); + QuestGiverStatus questStatus = const_cast<Player*>(target)->GetQuestDialogStatus(go); if (questStatus > DIALOG_STATUS_UNAVAILABLE) return true; break; @@ -2595,7 +2595,7 @@ GameObject* GameObject::GetLinkedTrap() return ObjectAccessor::GetGameObject(*this, m_linkedTrap); } -void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player const* target) const { if (!target) return; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 84128744eee..0646b53b85f 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -83,7 +83,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> explicit GameObject(); ~GameObject(); - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; + void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player const* target) const override; void AddToWorld() override; void RemoveFromWorld() override; @@ -225,7 +225,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> bool hasQuest(uint32 quest_id) const override; bool hasInvolvedQuest(uint32 quest_id) const override; - bool ActivateToQuest(Player* target) const; + bool ActivateToQuest(Player const* target) const; void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = nullptr); // 0 = use `gameobject`.`spawntimesecs` void ResetDoorOrButton(); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index cbc5f448e11..96749c87b43 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -220,7 +220,7 @@ void Object::SendUpdateToPlayer(Player* player) player->SendDirectMessage(&packet); } -void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const +void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const* target) const { ByteBuffer buf(500); @@ -468,7 +468,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const *data << int64(ToGameObject()->GetPackedLocalRotation()); } -void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player const* target) const { if (!target) return; @@ -2812,7 +2812,7 @@ bool WorldObject::IsNeutralToAll() const return my_faction->IsNeutralToAll(); } -SpellCastResult WorldObject::CastSpell(SpellCastTargets const& targets, uint32 spellId, CastSpellExtraArgs const& args /*= { }*/) +SpellCastResult WorldObject::CastSpell(CastSpellTargetArg const& targets, uint32 spellId, CastSpellExtraArgs const& args /*= { }*/) { SpellInfo const* info = sSpellMgr->GetSpellInfo(spellId); if (!info) @@ -2821,37 +2821,18 @@ SpellCastResult WorldObject::CastSpell(SpellCastTargets const& targets, uint32 s return SPELL_FAILED_SPELL_UNAVAILABLE; } + if (!targets.Targets) + { + TC_LOG_ERROR("entities.unit", "CastSpell: Invalid target passed to spell cast %u by %s", spellId, GetGUID().ToString().c_str()); + return SPELL_FAILED_BAD_TARGETS; + } + Spell* spell = new Spell(this, info, args.TriggerFlags, args.OriginalCaster); for (auto const& pair : args.SpellValueOverrides) spell->SetSpellValue(pair.first, pair.second); spell->m_CastItem = args.CastItem; - return spell->prepare(targets, args.TriggeringAura); -} - -SpellCastResult WorldObject::CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args /*= { }*/) -{ - SpellCastTargets targets; - if (target) - { - if (Unit* unitTarget = target->ToUnit()) - targets.SetUnitTarget(unitTarget); - else if (GameObject* goTarget = target->ToGameObject()) - targets.SetGOTarget(goTarget); - else - { - TC_LOG_ERROR("entities.unit", "CastSpell: Invalid target %s passed to spell cast by %s", target->GetGUID().ToString().c_str(), GetGUID().ToString().c_str()); - return SPELL_FAILED_BAD_TARGETS; - } - } - return CastSpell(targets, spellId, args); -} - -SpellCastResult WorldObject::CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args /*= { }*/) -{ - SpellCastTargets targets; - targets.SetDst(dest); - return CastSpell(targets, spellId, args); + return spell->prepare(*targets.Targets, args.TriggeringAura); } // function based on function Unit::CanAttack from 13850 client diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 7a32337a74b..f1fd3825eca 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -94,7 +94,7 @@ class TC_GAME_API Object virtual void BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) const; void SendUpdateToPlayer(Player* player); - void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const; + void BuildValuesUpdateBlockForPlayer(UpdateData* data, Player const* target) const; void BuildOutOfRangeUpdateBlock(UpdateData* data) const; void BuildMovementUpdateBlock(UpdateData* data, uint32 flags = 0) const; @@ -163,40 +163,40 @@ class TC_GAME_API Object void ForceValuesUpdateAtIndex(uint32); inline bool IsPlayer() const { return GetTypeId() == TYPEID_PLAYER; } - static Player* ToPlayer(Object* o) { if (o && o->IsPlayer()) return reinterpret_cast<Player*>(o); else return nullptr; } - static Player const* ToPlayer(Object const* o) { if (o && o->IsPlayer()) return reinterpret_cast<Player const*>(o); else return nullptr; } - Player* ToPlayer() { return ToPlayer(this); } - Player const* ToPlayer() const { return ToPlayer(this); } + static Player* ToPlayer(Object* o) { return o ? o->ToPlayer() : nullptr; } + static Player const* ToPlayer(Object const* o) { return o ? o->ToPlayer() : nullptr; } + Player* ToPlayer() { if (IsPlayer()) return reinterpret_cast<Player*>(this); else return nullptr; } + Player const* ToPlayer() const { if (IsPlayer()) return reinterpret_cast<Player const*>(this); else return nullptr; } inline bool IsCreature() const { return GetTypeId() == TYPEID_UNIT; } - static Creature* ToCreature(Object* o) { if (o && o->IsCreature()) return reinterpret_cast<Creature*>(o); else return nullptr; } - static Creature const* ToCreature(Object const* o) { if (o && o->IsCreature()) return reinterpret_cast<Creature const*>(o); else return nullptr; } - Creature* ToCreature() { return ToCreature(this); } - Creature const* ToCreature() const { return ToCreature(this); } + static Creature* ToCreature(Object* o) { return o ? o->ToCreature() : nullptr; } + static Creature const* ToCreature(Object const* o) { return o ? o->ToCreature() : nullptr; } + Creature* ToCreature() { if (IsCreature()) return reinterpret_cast<Creature*>(this); else return nullptr; } + Creature const* ToCreature() const { if (IsCreature()) return reinterpret_cast<Creature const*>(this); else return nullptr; } inline bool IsUnit() const { return isType(TYPEMASK_UNIT); } - static Unit* ToUnit(Object* o) { if (o && o->IsUnit()) return reinterpret_cast<Unit*>(o); else return nullptr; } - static Unit const* ToUnit(Object const* o) { if (o && o->IsUnit()) return reinterpret_cast<Unit const*>(o); else return nullptr; } - Unit* ToUnit() { return ToUnit(this); } - Unit const* ToUnit() const { return ToUnit(this); } + static Unit* ToUnit(Object* o) { return o ? o->ToUnit() : nullptr; } + static Unit const* ToUnit(Object const* o) { return o ? o->ToUnit() : nullptr; } + Unit* ToUnit() { if (IsUnit()) return reinterpret_cast<Unit*>(this); else return nullptr; } + Unit const* ToUnit() const { if (IsUnit()) return reinterpret_cast<Unit const*>(this); else return nullptr; } inline bool IsGameObject() const { return GetTypeId() == TYPEID_GAMEOBJECT; } - static GameObject* ToGameObject(Object* o) { if (o && o->IsGameObject()) return reinterpret_cast<GameObject*>(o); else return nullptr; } - static GameObject const* ToGameObject(Object const* o) { if (o && o->IsGameObject()) return reinterpret_cast<GameObject const*>(o); else return nullptr; } - GameObject* ToGameObject() { return ToGameObject(this); } - GameObject const* ToGameObject() const { return ToGameObject(this); } + static GameObject* ToGameObject(Object* o) { return o ? o->ToGameObject() : nullptr; } + static GameObject const* ToGameObject(Object const* o) { return o ? o->ToGameObject() : nullptr; } + GameObject* ToGameObject() { if (IsGameObject()) return reinterpret_cast<GameObject*>(this); else return nullptr; } + GameObject const* ToGameObject() const { if (IsGameObject()) return reinterpret_cast<GameObject const*>(this); else return nullptr; } inline bool IsCorpse() const { return GetTypeId() == TYPEID_CORPSE; } - static Corpse* ToCorpse(Object* o) { if (o && o->IsCorpse()) return reinterpret_cast<Corpse*>(o); else return nullptr; } - static Corpse const* ToCorpse(Object const* o) { if (o && o->IsCorpse()) return reinterpret_cast<Corpse const*>(o); else return nullptr; } - Corpse* ToCorpse() { return ToCorpse(this); } - Corpse const* ToCorpse() const { return ToCorpse(this); } + static Corpse* ToCorpse(Object* o) { return o ? o->ToCorpse() : nullptr; } + static Corpse const* ToCorpse(Object const* o) { return o ? o->ToCorpse() : nullptr; } + Corpse* ToCorpse() { if (IsCorpse()) return reinterpret_cast<Corpse*>(this); else return nullptr; } + Corpse const* ToCorpse() const { if (IsCorpse()) return reinterpret_cast<Corpse const*>(this); else return nullptr; } inline bool IsDynObject() const { return GetTypeId() == TYPEID_DYNAMICOBJECT; } - static DynamicObject* ToDynObject(Object* o) { if (o && o->IsDynObject()) return reinterpret_cast<DynamicObject*>(o); else return nullptr; } - static DynamicObject const* ToDynObject(Object const* o) { if (o && o->IsDynObject()) return reinterpret_cast<DynamicObject const*>(o); else return nullptr; } - DynamicObject* ToDynObject() { return ToDynObject(this); } - DynamicObject const* ToDynObject() const { return ToDynObject(this); } + static DynamicObject* ToDynObject(Object* o) { return o ? o->ToDynObject() : nullptr; } + static DynamicObject const* ToDynObject(Object const* o) { return o ? o->ToDynObject() : nullptr; } + DynamicObject* ToDynObject() { if (IsDynObject()) return reinterpret_cast<DynamicObject*>(this); else return nullptr; } + DynamicObject const* ToDynObject() const { if (IsDynObject()) return reinterpret_cast<DynamicObject const*>(this); else return nullptr; } virtual std::string GetDebugInfo() const; @@ -211,7 +211,7 @@ class TC_GAME_API Object uint32 GetUpdateFieldData(Player const* target, uint32*& flags) const; void BuildMovementUpdate(ByteBuffer* data, uint16 flags) const; - virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const; + virtual void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player const* target) const; uint16 m_objectType; @@ -246,10 +246,12 @@ class TC_GAME_API Object // for output helpfull error messages from asserts bool PrintIndexError(uint32 index, bool set) const; Object(Object const& right) = delete; + Object(Object&& right) = delete; Object& operator=(Object const& right) = delete; + Object& operator=(Object&& right) = delete; }; -template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, uint8 ARRAY_SIZE> +template <class T_VALUES, class T_FLAGS, class FLAG_TYPE, size_t ARRAY_SIZE> class FlaggedValuesArray32 { public: @@ -322,9 +324,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation InstanceScript* GetInstanceScript() const; std::string const& GetName() const { return m_name; } - void SetName(std::string const& newname) { m_name = newname; } + void SetName(std::string newname) { m_name = std::move(newname); } - virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale_idx*/) const { return m_name; } + virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale*/) const { return m_name; } float GetDistance(WorldObject const* obj) const; float GetDistance(Position const& pos) const; @@ -451,9 +453,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation bool IsNeutralToAll() const; // CastSpell's third arg can be a variety of things - check out CastSpellExtraArgs' constructors! - SpellCastResult CastSpell(SpellCastTargets const& targets, uint32 spellId, CastSpellExtraArgs const& args = { }); - SpellCastResult CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args = { }); - SpellCastResult CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args = { }); + SpellCastResult CastSpell(CastSpellTargetArg const& targets, uint32 spellId, CastSpellExtraArgs const& args = { }); bool IsValidAttackTarget(WorldObject const* target, SpellInfo const* bySpell = nullptr) const; bool IsValidAssistTarget(WorldObject const* target, SpellInfo const* bySpell = nullptr) const; @@ -475,7 +475,6 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation void UpdatePositionData(); void BuildUpdate(UpdateDataMapType&) override; - bool AddToObjectUpdate() override; void RemoveFromObjectUpdate() override; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2ab7e8f9b92..8eb22328511 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -17194,9 +17194,6 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol return false; } - // overwrite possible wrong/corrupted guid - SetGuidValue(OBJECT_FIELD_GUID, guid); - Gender gender = Gender(fields[5].GetUInt8()); if (!IsValidGender(gender)) { @@ -17871,7 +17868,7 @@ bool Player::LoadFromDB(ObjectGuid guid, CharacterDatabaseQueryHolder const& hol return true; } -bool Player::isAllowedToLoot(Creature const* creature) +bool Player::isAllowedToLoot(Creature const* creature) const { if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward()) return false; @@ -17888,7 +17885,7 @@ bool Player::isAllowedToLoot(Creature const* creature) if (loot->loot_type == LOOT_SKINNING) return creature->GetLootRecipientGUID() == GetGUID(); - Group* thisGroup = GetGroup(); + Group const* thisGroup = GetGroup(); if (!thisGroup) return this == creature->GetLootRecipient(); else if (thisGroup != creature->GetLootRecipientGroup()) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index b4aafb4c65c..b08fd00b72b 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2116,7 +2116,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetMap(Map* map) override; void ResetMap() override; - bool isAllowedToLoot(Creature const* creature); + bool isAllowedToLoot(Creature const* creature) const; DeclinedName const* GetDeclinedNames() const { return m_declinedname; } uint8 GetRunesState() const { return m_runes->runeState; } diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 13ef25a631d..ecf4322e68c 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -13404,7 +13404,7 @@ bool Unit::IsSplineEnabled() const return movespline->Initialized() && !movespline->Finalized(); } -void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* target) const +void Unit::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player const* target) const { if (!target) return; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index bf8e2b2753e..88075ef895e 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1830,7 +1830,7 @@ class TC_GAME_API Unit : public WorldObject protected: explicit Unit (bool isWorldObject); - void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player* target) const override; + void BuildValuesUpdate(uint8 updatetype, ByteBuffer* data, Player const* target) const override; void _UpdateSpells(uint32 time); void _DeleteRemovedAuras(); diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp index a31ad9db23e..e08da5a251a 100644 --- a/src/server/game/Loot/Loot.cpp +++ b/src/server/game/Loot/Loot.cpp @@ -524,7 +524,7 @@ bool Loot::hasItemForAll() const } // return true if there is any FFA, quest or conditional item for the player. -bool Loot::hasItemFor(Player* player) const +bool Loot::hasItemFor(Player const* player) const { NotNormalLootItemMap const& lootPlayerQuestItems = GetPlayerQuestItems(); NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID()); diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h index 2b618b97287..696d39d39e9 100644 --- a/src/server/game/Loot/Loot.h +++ b/src/server/game/Loot/Loot.h @@ -251,7 +251,7 @@ struct TC_GAME_API Loot LootItem* LootItemInSlot(uint32 lootslot, Player* player, NotNormalLootItem** qitem = nullptr, NotNormalLootItem** ffaitem = nullptr, NotNormalLootItem** conditem = nullptr); uint32 GetMaxSlotInLootFor(Player* player) const; bool hasItemForAll() const; - bool hasItemFor(Player* player) const; + bool hasItemFor(Player const* player) const; bool hasOverThresholdItem() const; private: diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 87730762cba..ba5239a78ed 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -205,7 +205,7 @@ bool LootStore::HaveQuestLootFor(uint32 loot_id) const return itr->second->HasQuestDrop(m_LootTemplates); } -bool LootStore::HaveQuestLootForPlayer(uint32 loot_id, Player* player) const +bool LootStore::HaveQuestLootForPlayer(uint32 loot_id, Player const* player) const { LootTemplateMap::const_iterator tab = m_LootTemplates.find(loot_id); if (tab != m_LootTemplates.end()) diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index d3d2b6a19f7..675abb5061d 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -77,7 +77,7 @@ class TC_GAME_API LootStore bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); } bool HaveQuestLootFor(uint32 loot_id) const; - bool HaveQuestLootForPlayer(uint32 loot_id, Player* player) const; + bool HaveQuestLootForPlayer(uint32 loot_id, Player const* player) const; LootTemplate const* GetLootFor(uint32 loot_id) const; void ResetConditions(); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index a72bffb6aa3..a3627a3c684 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -8326,3 +8326,20 @@ bool WorldObjectSpellTrajTargetCheck::operator()(WorldObject* target) const } } //namespace Trinity + +CastSpellTargetArg::CastSpellTargetArg(WorldObject* target) +{ + if (target) + { + if (Unit* unitTarget = target->ToUnit()) + { + Targets.emplace(); + Targets->SetUnitTarget(unitTarget); + } + else if (GameObject* goTarget = target->ToGameObject()) + { + Targets.emplace(); + Targets->SetGOTarget(goTarget); + } + } +} diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index dbd461ee655..c8668dd791e 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -23,6 +23,7 @@ #include "ObjectGuid.h" #include "Position.h" #include "SharedDefines.h" +#include "SpellDefines.h" #include <memory> namespace WorldPackets @@ -114,110 +115,6 @@ enum SpellRangeFlag SPELL_RANGE_RANGED = 2 //hunter range and ranged weapon }; -struct TC_GAME_API SpellDestination -{ - SpellDestination(); - SpellDestination(float x, float y, float z, float orientation = 0.0f, uint32 mapId = MAPID_INVALID); - SpellDestination(Position const& pos); - SpellDestination(WorldObject const& wObj); - - void Relocate(Position const& pos); - void RelocateOffset(Position const& offset); - - WorldLocation _position; - ObjectGuid _transportGUID; - Position _transportOffset; -}; - -class TC_GAME_API SpellCastTargets -{ - public: - SpellCastTargets(); - ~SpellCastTargets(); - - void Read(ByteBuffer& data, Unit* caster); - void Write(WorldPackets::Spells::SpellTargetData& data); - - uint32 GetTargetMask() const { return m_targetMask; } - void SetTargetMask(uint32 newMask) { m_targetMask = newMask; } - - void SetTargetFlag(SpellCastTargetFlags flag) { m_targetMask |= flag; } - - ObjectGuid GetUnitTargetGUID() const; - Unit* GetUnitTarget() const; - void SetUnitTarget(Unit* target); - - ObjectGuid GetGOTargetGUID() const; - GameObject* GetGOTarget() const; - void SetGOTarget(GameObject* target); - - ObjectGuid GetCorpseTargetGUID() const; - Corpse* GetCorpseTarget() const; - - WorldObject* GetObjectTarget() const; - ObjectGuid GetObjectTargetGUID() const; - void RemoveObjectTarget(); - - ObjectGuid GetItemTargetGUID() const { return m_itemTargetGUID; } - Item* GetItemTarget() const { return m_itemTarget; } - uint32 GetItemTargetEntry() const { return m_itemTargetEntry; } - void SetItemTarget(Item* item); - void SetTradeItemTarget(Player* caster); - void UpdateTradeSlotItem(); - - SpellDestination const* GetSrc() const; - Position const* GetSrcPos() const; - void SetSrc(float x, float y, float z); - void SetSrc(Position const& pos); - void SetSrc(WorldObject const& wObj); - void ModSrc(Position const& pos); - void RemoveSrc(); - - SpellDestination const* GetDst() const; - WorldLocation const* GetDstPos() const; - void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID); - void SetDst(Position const& pos); - void SetDst(WorldObject const& wObj); - void SetDst(SpellDestination const& spellDest); - void SetDst(SpellCastTargets const& spellTargets); - void ModDst(Position const& pos); - void ModDst(SpellDestination const& spellDest); - void RemoveDst(); - - bool HasSrc() const; - bool HasDst() const; - bool HasTraj() const { return m_speed != 0; } - - float GetElevation() const { return m_elevation; } - void SetElevation(float elevation) { m_elevation = elevation; } - float GetSpeed() const { return m_speed; } - void SetSpeed(float speed) { m_speed = speed; } - - float GetDist2d() const { return m_src._position.GetExactDist2d(&m_dst._position); } - float GetSpeedXY() const { return m_speed * std::cos(m_elevation); } - float GetSpeedZ() const { return m_speed * std::sin(m_elevation); } - - void Update(WorldObject* caster); - - private: - uint32 m_targetMask; - - // objects (can be used at spell creating and after Update at casting) - WorldObject* m_objectTarget; - Item* m_itemTarget; - - // object GUID/etc, can be used always - ObjectGuid m_objectTargetGUID; - ObjectGuid m_itemTargetGUID; - uint32 m_itemTargetEntry; - - SpellDestination m_src; - SpellDestination m_dst; - - float m_elevation, m_speed; - std::string m_strTarget; -}; - struct SpellValue { explicit SpellValue(SpellInfo const* proto); diff --git a/src/server/game/Spells/SpellDefines.h b/src/server/game/Spells/SpellDefines.h index 9efd9d40e60..fd362f31726 100644 --- a/src/server/game/Spells/SpellDefines.h +++ b/src/server/game/Spells/SpellDefines.h @@ -20,10 +20,25 @@ #include "Define.h" #include "ObjectGuid.h" +#include "Optional.h" +#include "Position.h" #include <vector> -class Item; class AuraEffect; +class Corpse; +class GameObject; +class Item; +class Player; +class Unit; +class WorldObject; + +namespace WorldPackets +{ + namespace Spells + { + struct SpellTargetData; + } +} enum SpellInterruptFlags : uint32 { @@ -157,6 +172,165 @@ enum TriggerCastFlags : uint32 TRIGGERED_FULL_DEBUG_MASK = 0xFFFFFFFF }; +enum SpellCastTargetFlags : uint32 +{ + TARGET_FLAG_NONE = 0x00000000, + TARGET_FLAG_UNUSED_1 = 0x00000001, // not used + TARGET_FLAG_UNIT = 0x00000002, // pguid + TARGET_FLAG_UNIT_RAID = 0x00000004, // not sent, used to validate target (if raid member) + TARGET_FLAG_UNIT_PARTY = 0x00000008, // not sent, used to validate target (if party member) + TARGET_FLAG_ITEM = 0x00000010, // pguid + TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // pguid, 3 float + TARGET_FLAG_DEST_LOCATION = 0x00000040, // pguid, 3 float + TARGET_FLAG_UNIT_ENEMY = 0x00000080, // not sent, used to validate target (if enemy) + TARGET_FLAG_UNIT_ALLY = 0x00000100, // not sent, used to validate target (if ally) + TARGET_FLAG_CORPSE_ENEMY = 0x00000200, // pguid + TARGET_FLAG_UNIT_DEAD = 0x00000400, // not sent, used to validate target (if dead creature) + TARGET_FLAG_GAMEOBJECT = 0x00000800, // pguid, used with TARGET_GAMEOBJECT_TARGET + TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid + TARGET_FLAG_STRING = 0x00002000, // string + TARGET_FLAG_GAMEOBJECT_ITEM = 0x00004000, // not sent, used with TARGET_GAMEOBJECT_ITEM_TARGET + TARGET_FLAG_CORPSE_ALLY = 0x00008000, // pguid + TARGET_FLAG_UNIT_MINIPET = 0x00010000, // pguid, used to validate target (if non combat pet) + TARGET_FLAG_GLYPH_SLOT = 0x00020000, // used in glyph spells + TARGET_FLAG_DEST_TARGET = 0x00040000, // sometimes appears with DEST_TARGET spells (may appear or not for a given spell) + TARGET_FLAG_UNUSED20 = 0x00080000, // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far + TARGET_FLAG_UNIT_PASSENGER = 0x00100000, // guessed, used to validate target (if vehicle passenger) + + TARGET_FLAG_UNIT_MASK = TARGET_FLAG_UNIT | TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY + | TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_DEAD | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER, + TARGET_FLAG_GAMEOBJECT_MASK = TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM, + TARGET_FLAG_CORPSE_MASK = TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY, + TARGET_FLAG_ITEM_MASK = TARGET_FLAG_TRADE_ITEM | TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM +}; + +struct TC_GAME_API SpellDestination +{ + SpellDestination(); + SpellDestination(float x, float y, float z, float orientation = 0.0f, uint32 mapId = MAPID_INVALID); + SpellDestination(Position const& pos); + SpellDestination(WorldObject const& wObj); + + void Relocate(Position const& pos); + void RelocateOffset(Position const& offset); + + WorldLocation _position; + ObjectGuid _transportGUID; + Position _transportOffset; +}; + +class TC_GAME_API SpellCastTargets +{ +public: + SpellCastTargets(); + ~SpellCastTargets(); + + void Read(ByteBuffer& data, Unit* caster); + void Write(WorldPackets::Spells::SpellTargetData& data); + + uint32 GetTargetMask() const { return m_targetMask; } + void SetTargetMask(uint32 newMask) { m_targetMask = newMask; } + + void SetTargetFlag(SpellCastTargetFlags flag) { m_targetMask |= flag; } + + ObjectGuid GetUnitTargetGUID() const; + Unit* GetUnitTarget() const; + void SetUnitTarget(Unit* target); + + ObjectGuid GetGOTargetGUID() const; + GameObject* GetGOTarget() const; + void SetGOTarget(GameObject* target); + + ObjectGuid GetCorpseTargetGUID() const; + Corpse* GetCorpseTarget() const; + + WorldObject* GetObjectTarget() const; + ObjectGuid GetObjectTargetGUID() const; + void RemoveObjectTarget(); + + ObjectGuid GetItemTargetGUID() const { return m_itemTargetGUID; } + Item* GetItemTarget() const { return m_itemTarget; } + uint32 GetItemTargetEntry() const { return m_itemTargetEntry; } + void SetItemTarget(Item* item); + void SetTradeItemTarget(Player* caster); + void UpdateTradeSlotItem(); + + SpellDestination const* GetSrc() const; + Position const* GetSrcPos() const; + void SetSrc(float x, float y, float z); + void SetSrc(Position const& pos); + void SetSrc(WorldObject const& wObj); + void ModSrc(Position const& pos); + void RemoveSrc(); + + SpellDestination const* GetDst() const; + WorldLocation const* GetDstPos() const; + void SetDst(float x, float y, float z, float orientation, uint32 mapId = MAPID_INVALID); + void SetDst(Position const& pos); + void SetDst(WorldObject const& wObj); + void SetDst(SpellDestination const& spellDest); + void SetDst(SpellCastTargets const& spellTargets); + void ModDst(Position const& pos); + void ModDst(SpellDestination const& spellDest); + void RemoveDst(); + + bool HasSrc() const; + bool HasDst() const; + bool HasTraj() const { return m_speed != 0; } + + float GetElevation() const { return m_elevation; } + void SetElevation(float elevation) { m_elevation = elevation; } + float GetSpeed() const { return m_speed; } + void SetSpeed(float speed) { m_speed = speed; } + + float GetDist2d() const { return m_src._position.GetExactDist2d(&m_dst._position); } + float GetSpeedXY() const { return m_speed * std::cos(m_elevation); } + float GetSpeedZ() const { return m_speed * std::sin(m_elevation); } + + void Update(WorldObject* caster); + +private: + uint32 m_targetMask; + + // objects (can be used at spell creating and after Update at casting) + WorldObject* m_objectTarget; + Item* m_itemTarget; + + // object GUID/etc, can be used always + ObjectGuid m_objectTargetGUID; + ObjectGuid m_itemTargetGUID; + uint32 m_itemTargetEntry; + + SpellDestination m_src; + SpellDestination m_dst; + + float m_elevation, m_speed; + std::string m_strTarget; +}; + +struct TC_GAME_API CastSpellTargetArg +{ + CastSpellTargetArg() { Targets.emplace(); } + CastSpellTargetArg(std::nullptr_t) { Targets.emplace(); } + CastSpellTargetArg(WorldObject* target); + CastSpellTargetArg(Item* itemTarget) + { + Targets.emplace(); + Targets->SetItemTarget(itemTarget); + } + CastSpellTargetArg(Position const& dest) + { + Targets.emplace(); + Targets->SetDst(dest); + } + CastSpellTargetArg(SpellCastTargets&& targets) + { + Targets.emplace(std::move(targets)); + } + + Optional<SpellCastTargets> Targets; // empty optional used to signal error state +}; + struct TC_GAME_API CastSpellExtraArgs { CastSpellExtraArgs() {} diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 45e7a53603e..5123cad6a23 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -829,7 +829,7 @@ void Spell::EffectTriggerSpell() args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), damage); // original caster guid only for GO cast - m_caster->CastSpell(targets, spellInfo->Id, args); + m_caster->CastSpell(std::move(targets), spellInfo->Id, args); } void Spell::EffectTriggerMissileSpell() @@ -881,7 +881,7 @@ void Spell::EffectTriggerMissileSpell() args.AddSpellMod(SpellValueMod(SPELLVALUE_BASE_POINT0 + i), damage); // original caster guid only for GO cast - m_caster->CastSpell(targets, spellInfo->Id, args); + m_caster->CastSpell(std::move(targets), spellInfo->Id, args); } void Spell::EffectForceCast() @@ -3509,13 +3509,9 @@ void Spell::EffectScriptEffect() if (!m_targets.HasDst()) return; - float x, y, z; float radius = effectInfo->CalcRadius(); for (uint8 i = 0; i < 15; ++i) - { - m_caster->GetRandomPoint(*destTarget, radius, x, y, z); - m_caster->CastSpell({x, y, z}, 54522, true); - } + m_caster->CastSpell(m_caster->GetRandomPoint(*destTarget, radius), 54522, true); break; } case 52173: // Coyote Spirit Despawn diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index b837f9b3efc..51d34e2d443 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -43,38 +43,6 @@ struct SpellRadiusEntry; struct SpellEntry; struct SpellCastTimesEntry; -enum SpellCastTargetFlags : uint32 -{ - TARGET_FLAG_NONE = 0x00000000, - TARGET_FLAG_UNUSED_1 = 0x00000001, // not used - TARGET_FLAG_UNIT = 0x00000002, // pguid - TARGET_FLAG_UNIT_RAID = 0x00000004, // not sent, used to validate target (if raid member) - TARGET_FLAG_UNIT_PARTY = 0x00000008, // not sent, used to validate target (if party member) - TARGET_FLAG_ITEM = 0x00000010, // pguid - TARGET_FLAG_SOURCE_LOCATION = 0x00000020, // pguid, 3 float - TARGET_FLAG_DEST_LOCATION = 0x00000040, // pguid, 3 float - TARGET_FLAG_UNIT_ENEMY = 0x00000080, // not sent, used to validate target (if enemy) - TARGET_FLAG_UNIT_ALLY = 0x00000100, // not sent, used to validate target (if ally) - TARGET_FLAG_CORPSE_ENEMY = 0x00000200, // pguid - TARGET_FLAG_UNIT_DEAD = 0x00000400, // not sent, used to validate target (if dead creature) - TARGET_FLAG_GAMEOBJECT = 0x00000800, // pguid, used with TARGET_GAMEOBJECT_TARGET - TARGET_FLAG_TRADE_ITEM = 0x00001000, // pguid - TARGET_FLAG_STRING = 0x00002000, // string - TARGET_FLAG_GAMEOBJECT_ITEM = 0x00004000, // not sent, used with TARGET_GAMEOBJECT_ITEM_TARGET - TARGET_FLAG_CORPSE_ALLY = 0x00008000, // pguid - TARGET_FLAG_UNIT_MINIPET = 0x00010000, // pguid, used to validate target (if non combat pet) - TARGET_FLAG_GLYPH_SLOT = 0x00020000, // used in glyph spells - TARGET_FLAG_DEST_TARGET = 0x00040000, // sometimes appears with DEST_TARGET spells (may appear or not for a given spell) - TARGET_FLAG_UNUSED20 = 0x00080000, // uint32 counter, loop { vec3 - screen position (?), guid }, not used so far - TARGET_FLAG_UNIT_PASSENGER = 0x00100000, // guessed, used to validate target (if vehicle passenger) - - TARGET_FLAG_UNIT_MASK = TARGET_FLAG_UNIT | TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY - | TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_DEAD | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER, - TARGET_FLAG_GAMEOBJECT_MASK = TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM, - TARGET_FLAG_CORPSE_MASK = TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY, - TARGET_FLAG_ITEM_MASK = TARGET_FLAG_TRADE_ITEM | TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM -}; - enum SpellTargetSelectionCategories { TARGET_SELECT_CATEGORY_NYI, diff --git a/src/server/scripts/Commands/cs_cast.cpp b/src/server/scripts/Commands/cs_cast.cpp index 1e4910bd75a..8b0729a9701 100644 --- a/src/server/scripts/Commands/cs_cast.cpp +++ b/src/server/scripts/Commands/cs_cast.cpp @@ -142,7 +142,7 @@ public: float x, y, z; handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, dist); - handler->GetSession()->GetPlayer()->CastSpell({ x, y, z }, spell->Id, *triggerFlags); + handler->GetSession()->GetPlayer()->CastSpell(Position{ x, y, z }, spell->Id, *triggerFlags); return true; } @@ -215,7 +215,7 @@ public: if (!triggerFlags) return false; - caster->CastSpell({ x, y, z }, spell->Id, *triggerFlags); + caster->CastSpell(Position{ x, y, z }, spell->Id, *triggerFlags); return true; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp index 7025555e253..f607c7faeb8 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp +++ b/src/server/scripts/Kalimdor/CavernsOfTime/BattleForMountHyjal/hyjal_trash.cpp @@ -1379,7 +1379,7 @@ public: { if (StrikeTimer <= diff) { - me->CastSpell({ DummyTarget[0], DummyTarget[1], DummyTarget[2] }, SPELL_GARGOYLE_STRIKE, false); + me->CastSpell(Position{ DummyTarget[0], DummyTarget[1], DummyTarget[2] }, SPELL_GARGOYLE_STRIKE, false); StrikeTimer = 2000 + rand32() % 1000; } else StrikeTimer -= diff; } diff --git a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h index a4ead46b8a4..00ae53d5308 100644 --- a/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h +++ b/src/server/scripts/Kalimdor/CavernsOfTime/CullingOfStratholme/culling_of_stratholme.h @@ -20,6 +20,8 @@ #include "CreatureAIImpl.h" +struct Position; + #define DataHeader "CS" #define CoSScriptName "instance_culling_of_stratholme" @@ -83,8 +85,6 @@ uint32 constexpr EncounterCount = 5; * - gets current instance state using GetData, then checks if we should despawn ourselves (bitmask check) * \***********************************************************************************************************************/ -struct Position; - // Note: These are bitmask values to allow combining, but only a single bit will ever be true in instance script enum COSProgressStates : uint32 { diff --git a/src/server/scripts/Kalimdor/zone_silithus.cpp b/src/server/scripts/Kalimdor/zone_silithus.cpp index 916b1b98756..e012dfd4e82 100644 --- a/src/server/scripts/Kalimdor/zone_silithus.cpp +++ b/src/server/scripts/Kalimdor/zone_silithus.cpp @@ -507,7 +507,7 @@ public: DoCast(player, SPELL_ARCANE_CHANNELING, true);//Arcane Channeling break; case 35: - me->CastSpell({ -8088, 1520.43f, 2.67f }, SPELL_TIME_STOP, true); + me->CastSpell(Position(-8088, 1520.43f, 2.67f), SPELL_TIME_STOP, true); break; case 36: DoCast(player, SPELL_CALL_PRISMATIC_BARRIER, true); @@ -557,7 +557,7 @@ public: break; case 50: Fandral->AI()->Talk(FANDRAL_EMOTE_2); - Fandral->CastSpell({ -8127, 1525, 17.5f }, SPELL_THROW_HAMMER, true); + Fandral->CastSpell(Position(-8127, 1525, 17.5f), SPELL_THROW_HAMMER, true); break; case 51: { diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index 6b2ea29b217..4942b608875 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -682,12 +682,10 @@ class spell_rotface_unstable_ooze_explosion : public SpellScript uint32 triggered_spell_id = GetEffectInfo().TriggerSpell; - float x, y, z; - GetExplTargetDest()->GetPosition(x, y, z); // let Rotface handle the cast - caster dies before this executes if (InstanceScript* script = GetCaster()->GetInstanceScript()) if (Creature* rotface = script->instance->GetCreature(script->GetGuidData(DATA_ROTFACE))) - rotface->CastSpell({x, y, z}, triggered_spell_id, GetCaster()->GetGUID()); + rotface->CastSpell(*GetExplTargetDest(), triggered_spell_id, GetCaster()->GetGUID()); } void Register() override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp index 3153a91f7b9..496f85ea76f 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp @@ -525,7 +525,7 @@ struct boss_sindragosa : public BossAI destY = float(rand_norm()) * 75.0f + 2450.0f; destZ = 205.0f; // random number close to ground, get exact in next call me->UpdateGroundPositionZ(destX, destY, destZ); - me->CastSpell({ destX, destY, destZ }, SPELL_FROST_BOMB_TRIGGER, false); + me->CastSpell(Position{ destX, destY, destZ }, SPELL_FROST_BOMB_TRIGGER, false); events.ScheduleEvent(EVENT_FROST_BOMB, 6s, 8s); break; } |