diff options
author | ariel- <ariel-@users.noreply.github.com> | 2017-06-19 23:20:06 -0300 |
---|---|---|
committer | ariel- <ariel-@users.noreply.github.com> | 2017-06-19 23:20:06 -0300 |
commit | 85a7d5ce9ac68b30da2277cc91d4b70358f1880d (patch) | |
tree | df3d2084ee2e35008903c03178039b9c986e2d08 /src/server/game | |
parent | 052fc24315ace866ea1cf610e85df119b68100c9 (diff) |
Core: ported headers cleanup from master branch
Diffstat (limited to 'src/server/game')
356 files changed, 10465 insertions, 8571 deletions
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp index 86858de04dd..f7143591060 100644 --- a/src/server/game/AI/CoreAI/CombatAI.cpp +++ b/src/server/game/AI/CoreAI/CombatAI.cpp @@ -17,11 +17,16 @@ */ #include "CombatAI.h" -#include "SpellMgr.h" -#include "SpellInfo.h" -#include "Vehicle.h" +#include "ConditionMgr.h" +#include "Creature.h" +#include "CreatureAIImpl.h" +#include "Log.h" +#include "MotionMaster.h" #include "ObjectAccessor.h" #include "Player.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "Vehicle.h" ///////////////// // AggressorAI @@ -232,7 +237,7 @@ TurretAI::TurretAI(Creature* c) : CreatureAI(c) me->m_SightDistance = me->m_CombatDistance; } -bool TurretAI::CanAIAttack(const Unit* /*who*/) const +bool TurretAI::CanAIAttack(Unit const* /*who*/) const { /// @todo use one function to replace it if (!me->IsWithinCombatRange(me->GetVictim(), me->m_CombatDistance) diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h index 86e95e0b209..872d02b1531 100644 --- a/src/server/game/AI/CoreAI/CombatAI.h +++ b/src/server/game/AI/CoreAI/CombatAI.h @@ -20,8 +20,6 @@ #define TRINITY_COMBATAI_H #include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "ConditionMgr.h" class Creature; diff --git a/src/server/game/AI/CoreAI/GameObjectAI.cpp b/src/server/game/AI/CoreAI/GameObjectAI.cpp index 204f4c16275..4d511cdc353 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.cpp +++ b/src/server/game/AI/CoreAI/GameObjectAI.cpp @@ -17,5 +17,16 @@ */ #include "GameObjectAI.h" +#include "CreatureAI.h" + +int32 GameObjectAI::Permissible(GameObject const* /*go*/) +{ + return PERMIT_BASE_NO; +} NullGameObjectAI::NullGameObjectAI(GameObject* g) : GameObjectAI(g) { } + +int32 NullGameObjectAI::Permissible(GameObject const* /*go*/) +{ + return PERMIT_BASE_IDLE; +} diff --git a/src/server/game/AI/CoreAI/GameObjectAI.h b/src/server/game/AI/CoreAI/GameObjectAI.h index 84ead51cc91..80ab11d6792 100644 --- a/src/server/game/AI/CoreAI/GameObjectAI.h +++ b/src/server/game/AI/CoreAI/GameObjectAI.h @@ -20,11 +20,11 @@ #define TRINITY_GAMEOBJECTAI_H #include "Define.h" -#include <list> -#include "Object.h" #include "QuestDef.h" -#include "GameObject.h" -#include "CreatureAI.h" + +class GameObject; +class Unit; +class SpellInfo; class TC_GAME_API GameObjectAI { @@ -45,7 +45,7 @@ class TC_GAME_API GameObjectAI virtual void SetGUID(uint64 /*guid*/, int32 /*id = 0 */) { } virtual uint64 GetGUID(int32 /*id = 0 */) const { return 0; } - static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_NO; } + static int32 Permissible(GameObject const* go); // Called when a player opens a gossip dialog with the gameobject. virtual bool GossipHello(Player* /*player*/) { return false; } @@ -81,7 +81,7 @@ class TC_GAME_API GameObjectAI virtual void OnLootStateChanged(uint32 /*state*/, Unit* /*unit*/) { } virtual void OnStateChanged(uint32 /*state*/) { } virtual void EventInform(uint32 /*eventId*/) { } - virtual void SpellHit(Unit* /*unit*/, const SpellInfo* /*spellInfo*/) { } + virtual void SpellHit(Unit* /*unit*/, SpellInfo const* /*spellInfo*/) { } }; class TC_GAME_API NullGameObjectAI : public GameObjectAI @@ -91,6 +91,6 @@ class TC_GAME_API NullGameObjectAI : public GameObjectAI void UpdateAI(uint32 /*diff*/) override { } - static int32 Permissible(GameObject const* /*go*/) { return PERMIT_BASE_IDLE; } + static int32 Permissible(GameObject const* go); }; #endif diff --git a/src/server/game/AI/CoreAI/GuardAI.cpp b/src/server/game/AI/CoreAI/GuardAI.cpp index 1da03952dc9..f216059e492 100644 --- a/src/server/game/AI/CoreAI/GuardAI.cpp +++ b/src/server/game/AI/CoreAI/GuardAI.cpp @@ -17,9 +17,16 @@ */ #include "GuardAI.h" +#include "Creature.h" #include "Errors.h" +#include "Log.h" +#include "MotionMaster.h" #include "Player.h" +GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature) +{ +} + int32 GuardAI::Permissible(Creature const* creature) { if (creature->IsGuard()) @@ -28,7 +35,13 @@ int32 GuardAI::Permissible(Creature const* creature) return PERMIT_BASE_NO; } -GuardAI::GuardAI(Creature* creature) : ScriptedAI(creature) { } +void GuardAI::UpdateAI(uint32 /*diff*/) +{ + if (!UpdateVictim()) + return; + + DoMeleeAttackIfReady(); +} bool GuardAI::CanSeeAlways(WorldObject const* obj) { diff --git a/src/server/game/AI/CoreAI/GuardAI.h b/src/server/game/AI/CoreAI/GuardAI.h index 0b0ac1f0983..77b83340c91 100644 --- a/src/server/game/AI/CoreAI/GuardAI.h +++ b/src/server/game/AI/CoreAI/GuardAI.h @@ -29,6 +29,7 @@ class TC_GAME_API GuardAI : public ScriptedAI explicit GuardAI(Creature* creature); static int32 Permissible(Creature const* creature); + void UpdateAI(uint32 diff) override; bool CanSeeAlways(WorldObject const* obj) override; void EnterEvadeMode(EvadeReason /*why*/) override; diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index f27f9a0adb9..1fad18a2713 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -17,17 +17,19 @@ */ #include "PetAI.h" +#include "Creature.h" #include "Errors.h" +#include "Group.h" +#include "Log.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" #include "Pet.h" #include "Player.h" #include "Spell.h" -#include "ObjectAccessor.h" #include "SpellHistory.h" +#include "SpellInfo.h" #include "SpellMgr.h" -#include "Creature.h" #include "Util.h" -#include "Group.h" -#include "SpellInfo.h" int32 PetAI::Permissible(Creature const* creature) { @@ -264,7 +266,7 @@ void PetAI::UpdateAllies() if (!owner) return; - Group* group = NULL; + Group* group = nullptr; if (Player* player = owner->ToPlayer()) group = player->GetGroup(); @@ -280,7 +282,7 @@ void PetAI::UpdateAllies() m_AllySet.insert(me->GetGUID()); if (group) //add group { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* Target = itr->GetSource(); if (!Target || !Target->IsInMap(owner) || !group->SameSubGroup(owner->ToPlayer(), Target)) @@ -389,7 +391,7 @@ Unit* PetAI::SelectNextTarget(bool allowAutoSelect) const // Passive pets don't do next target selection if (me->HasReactState(REACT_PASSIVE)) - return NULL; + return nullptr; // Check pet attackers first so we don't drag a bunch of targets to the owner if (Unit* myAttacker = me->getAttackerForHelper()) @@ -398,7 +400,7 @@ Unit* PetAI::SelectNextTarget(bool allowAutoSelect) const // Not sure why we wouldn't have an owner but just in case... if (!me->GetCharmerOrOwner()) - return NULL; + return nullptr; // Check owner attackers if (Unit* ownerAttacker = me->GetCharmerOrOwner()->getAttackerForHelper()) @@ -421,7 +423,7 @@ Unit* PetAI::SelectNextTarget(bool allowAutoSelect) const } // Default - no valid targets - return NULL; + return nullptr; } void PetAI::HandleReturnMovement() @@ -568,7 +570,7 @@ bool PetAI::CanAttack(Unit* target) if (me->GetVictim() && me->GetVictim() != target) { // Check if our owner selected this target and clicked "attack" - Unit* ownerTarget = NULL; + Unit* ownerTarget = nullptr; if (Player* owner = me->GetCharmerOrOwner()->ToPlayer()) ownerTarget = owner->GetSelectedUnit(); else diff --git a/src/server/game/AI/CoreAI/ReactorAI.cpp b/src/server/game/AI/CoreAI/ReactorAI.cpp index 8ad251776b6..0f2e7437104 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.cpp +++ b/src/server/game/AI/CoreAI/ReactorAI.cpp @@ -16,8 +16,8 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ByteBuffer.h" #include "ReactorAI.h" +#include "Creature.h" int32 ReactorAI::Permissible(Creature const* creature) { diff --git a/src/server/game/AI/CoreAI/ReactorAI.h b/src/server/game/AI/CoreAI/ReactorAI.h index 412849a955b..db1f60fc263 100644 --- a/src/server/game/AI/CoreAI/ReactorAI.h +++ b/src/server/game/AI/CoreAI/ReactorAI.h @@ -21,8 +21,6 @@ #include "CreatureAI.h" -class Unit; - class TC_GAME_API ReactorAI : public CreatureAI { public: diff --git a/src/server/game/AI/CoreAI/TotemAI.cpp b/src/server/game/AI/CoreAI/TotemAI.cpp index a44c4532e60..da484e20983 100644 --- a/src/server/game/AI/CoreAI/TotemAI.cpp +++ b/src/server/game/AI/CoreAI/TotemAI.cpp @@ -64,14 +64,14 @@ void TotemAI::UpdateAI(uint32 /*diff*/) // SPELLMOD_RANGE not applied in this place just because not existence range mods for attacking totems // pointer to appropriate target if found any - Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*me, i_victimGuid) : NULL; + Unit* victim = i_victimGuid ? ObjectAccessor::GetUnit(*me, i_victimGuid) : nullptr; // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end) if (!victim || !victim->isTargetableForAttack() || !me->IsWithinDistInMap(victim, max_range) || me->IsFriendlyTo(victim) || !me->CanSeeOrDetect(victim)) { - victim = NULL; + victim = nullptr; Trinity::NearestAttackableUnitInObjectRangeCheck u_check(me, me, max_range); Trinity::UnitLastSearcher<Trinity::NearestAttackableUnitInObjectRangeCheck> checker(me, victim, u_check); Cell::VisitAllObjects(me, checker, max_range); diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 055abc99d96..9f13f7901bc 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -17,14 +17,15 @@ */ #include "UnitAI.h" -#include "Player.h" #include "Creature.h" -#include "SpellAuras.h" +#include "CreatureAIImpl.h" +#include "MotionMaster.h" +#include "Player.h" +#include "Spell.h" #include "SpellAuraEffects.h" -#include "SpellMgr.h" +#include "SpellAuras.h" #include "SpellInfo.h" -#include "Spell.h" -#include "CreatureAIImpl.h" +#include "SpellMgr.h" void UnitAI::AttackStart(Unit* victim) { @@ -40,6 +41,12 @@ void UnitAI::AttackStart(Unit* victim) } } +void UnitAI::InitializeAI() +{ + if (!me->isDead()) + Reset(); +} + void UnitAI::AttackStartCaster(Unit* victim, float dist) { if (victim && me->Attack(victim, false)) @@ -112,37 +119,9 @@ float UnitAI::DoGetSpellMaxRange(uint32 spellId, bool positive) return spellInfo ? spellInfo->GetMaxRange(positive) : 0; } -void UnitAI::DoAddAuraToAllHostilePlayers(uint32 spellid) -{ - if (me->IsInCombat()) - { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) - { - if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) - if (unit->GetTypeId() == TYPEID_PLAYER) - me->AddAura(spellid, unit); - } - } -} - -void UnitAI::DoCastToAllHostilePlayers(uint32 spellid, bool triggered) -{ - if (me->IsInCombat()) - { - ThreatContainer::StorageType threatlist = me->getThreatManager().getThreatList(); - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) - { - if (Unit* unit = ObjectAccessor::GetUnit(*me, (*itr)->getUnitGuid())) - if (unit->GetTypeId() == TYPEID_PLAYER) - me->CastSpell(unit, spellid, triggered); - } - } -} - void UnitAI::DoCast(uint32 spellId) { - Unit* target = NULL; + Unit* target = nullptr; switch (AISpellInfo[spellId].target) { @@ -211,7 +190,12 @@ void UnitAI::DoCastAOE(uint32 spellId, bool triggered) if (!triggered && me->HasUnitState(UNIT_STATE_CASTING)) return; - me->CastSpell((Unit*)NULL, spellId, triggered); + me->CastSpell((Unit*)nullptr, spellId, triggered); +} + +uint32 UnitAI::GetDialogStatus(Player* /*player*/) +{ + return DIALOG_STATUS_SCRIPTED_NO_STATUS; } #define UPDATE_TARGET(a) {if (AIInfo->target<a) AIInfo->target=a;} @@ -221,11 +205,9 @@ void UnitAI::FillAISpellInfo() AISpellInfo = new AISpellInfoType[sSpellMgr->GetSpellInfoStoreSize()]; AISpellInfoType* AIInfo = AISpellInfo; - const SpellInfo* spellInfo; - for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i, ++AIInfo) { - spellInfo = sSpellMgr->GetSpellInfo(i); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(i); if (!spellInfo) continue; @@ -267,6 +249,45 @@ void UnitAI::FillAISpellInfo() } } +ThreatManager& UnitAI::GetThreatManager() +{ + return me->getThreatManager(); +} + +bool DefaultTargetSelector::operator()(Unit const* target) const +{ + if (!me) + return false; + + if (!target) + return false; + + if (m_playerOnly && (target->GetTypeId() != TYPEID_PLAYER)) + return false; + + if (m_dist > 0.0f && !me->IsWithinCombatRange(target, m_dist)) + return false; + + if (m_dist < 0.0f && me->IsWithinCombatRange(target, -m_dist)) + return false; + + if (m_aura) + { + if (m_aura > 0) + { + if (!target->HasAura(m_aura)) + return false; + } + else + { + if (target->HasAura(-m_aura)) + return false; + } + } + + return true; +} + SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) : _caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster)) { @@ -384,3 +405,8 @@ bool FarthestTargetSelector::operator()(Unit const* target) const return true; } + +void SortByDistanceTo(Unit* reference, std::list<Unit*>& targets) +{ + targets.sort(Trinity::ObjectDistanceOrderPred(reference)); +} diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 0e0d2200280..d164b9fe6d5 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -19,16 +19,29 @@ #ifndef TRINITY_UNITAI_H #define TRINITY_UNITAI_H -#include "Define.h" -#include "Unit.h" #include "Containers.h" #include "EventMap.h" -#include "QuestDef.h" -#include <list> +#include "ObjectGuid.h" +#include "ThreatManager.h" + +#define CAST_AI(a, b) (dynamic_cast<a*>(b)) +#define ENSURE_AI(a,b) (EnsureAI<a>(b)) + +template<class T, class U> +T* EnsureAI(U* ai) +{ + T* cast_ai = dynamic_cast<T*>(ai); + ASSERT(cast_ai); + return cast_ai; +}; class Player; class Quest; +class SpellInfo; +class Unit; struct AISpellInfoType; +enum DamageEffectType : uint8; +enum SpellEffIndex : uint8; //Selection method used by SelectTarget enum SelectAggroTarget @@ -41,9 +54,9 @@ enum SelectAggroTarget }; // default predicate function to select target based on distance, player and/or aura criteria -struct TC_GAME_API DefaultTargetSelector : public std::unary_function<Unit*, bool> +struct TC_GAME_API DefaultTargetSelector { - const Unit* me; + Unit const* me; float m_dist; bool m_playerOnly; int32 m_aura; @@ -54,44 +67,12 @@ struct TC_GAME_API DefaultTargetSelector : public std::unary_function<Unit*, boo // aura: if 0: ignored, if > 0: the target shall have the aura, if < 0, the target shall NOT have the aura DefaultTargetSelector(Unit const* unit, float dist, bool playerOnly, int32 aura) : me(unit), m_dist(dist), m_playerOnly(playerOnly), m_aura(aura) { } - bool operator()(Unit const* target) const - { - if (!me) - return false; - - if (!target) - return false; - - if (m_playerOnly && (target->GetTypeId() != TYPEID_PLAYER)) - return false; - - if (m_dist > 0.0f && !me->IsWithinCombatRange(target, m_dist)) - return false; - - if (m_dist < 0.0f && me->IsWithinCombatRange(target, -m_dist)) - return false; - - if (m_aura) - { - if (m_aura > 0) - { - if (!target->HasAura(m_aura)) - return false; - } - else - { - if (target->HasAura(-m_aura)) - return false; - } - } - - return true; - } + bool operator()(Unit const* target) const; }; // Target selector for spell casts checking range, auras and attributes /// @todo Add more checks from Spell::CheckCast -struct TC_GAME_API SpellTargetSelector : public std::unary_function<Unit*, bool> +struct TC_GAME_API SpellTargetSelector { public: SpellTargetSelector(Unit* caster, uint32 spellId); @@ -105,7 +86,7 @@ struct TC_GAME_API SpellTargetSelector : public std::unary_function<Unit*, bool> // Very simple target selector, will just skip main target // NOTE: When passing to UnitAI::SelectTarget remember to use 0 as position for random selection // because tank will not be in the temporary list -struct TC_GAME_API NonTankTargetSelector : public std::unary_function<Unit*, bool> +struct TC_GAME_API NonTankTargetSelector { public: NonTankTargetSelector(Unit* source, bool playerOnly = true) : _source(source), _playerOnly(playerOnly) { } @@ -137,12 +118,14 @@ struct TC_GAME_API FarthestTargetSelector bool operator()(Unit const* target) const; private: - const Unit* _me; + Unit const* _me; float _dist; bool _playerOnly; bool _inLos; }; +TC_GAME_API void SortByDistanceTo(Unit* reference, std::list<Unit*>& targets); + class TC_GAME_API UnitAI { protected: @@ -155,7 +138,7 @@ class TC_GAME_API UnitAI virtual void AttackStart(Unit* /*target*/); virtual void UpdateAI(uint32 diff) = 0; - virtual void InitializeAI() { if (!me->isDead()) Reset(); } + virtual void InitializeAI(); virtual void Reset() { } @@ -172,15 +155,16 @@ class TC_GAME_API UnitAI Unit* SelectTarget(SelectAggroTarget targetType, uint32 position = 0, float dist = 0.0f, bool playerOnly = false, int32 aura = 0); // Select the targets satisfying the predicate. // predicate shall extend std::unary_function<Unit*, bool> - template<class PREDICATE> Unit* SelectTarget(SelectAggroTarget targetType, uint32 position, PREDICATE const& predicate) + template<class PREDICATE> + Unit* SelectTarget(SelectAggroTarget targetType, uint32 position, PREDICATE const& predicate) { - ThreatContainer::StorageType const& threatlist = me->getThreatManager().getThreatList(); + ThreatContainer::StorageType const& threatlist = GetThreatManager().getThreatList(); if (position >= threatlist.size()) return nullptr; std::list<Unit*> targetList; Unit* currentVictim = nullptr; - if (auto currentVictimReference = me->getThreatManager().getCurrentVictim()) + if (auto currentVictimReference = GetThreatManager().getCurrentVictim()) { currentVictim = currentVictimReference->getTarget(); @@ -189,42 +173,38 @@ class TC_GAME_API UnitAI targetList.push_back(currentVictim); } - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) + for (HostileReference* hostileRef : threatlist) { - if (currentVictim != nullptr && (*itr)->getTarget() != currentVictim && predicate((*itr)->getTarget())) - targetList.push_back((*itr)->getTarget()); - else if (currentVictim == nullptr && predicate((*itr)->getTarget())) - targetList.push_back((*itr)->getTarget()); + if (currentVictim != nullptr && hostileRef->getTarget() != currentVictim && predicate(hostileRef->getTarget())) + targetList.push_back(hostileRef->getTarget()); + else if (currentVictim == nullptr && predicate(hostileRef->getTarget())) + targetList.push_back(hostileRef->getTarget()); } if (position >= targetList.size()) return nullptr; if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - targetList.sort(Trinity::ObjectDistanceOrderPred(me)); + SortByDistanceTo(me, targetList); switch (targetType) { case SELECT_TARGET_NEAREST: case SELECT_TARGET_TOPAGGRO: { - std::list<Unit*>::iterator itr = targetList.begin(); + auto itr = targetList.begin(); std::advance(itr, position); return *itr; } case SELECT_TARGET_FARTHEST: case SELECT_TARGET_BOTTOMAGGRO: { - std::list<Unit*>::reverse_iterator ritr = targetList.rbegin(); + auto ritr = targetList.rbegin(); std::advance(ritr, position); return *ritr; } case SELECT_TARGET_RANDOM: - { - std::list<Unit*>::iterator itr = targetList.begin(); - std::advance(itr, urand(position, targetList.size() - 1)); - return *itr; - } + return Trinity::Containers::SelectRandomContainerElement(targetList); default: break; } @@ -236,21 +216,22 @@ class TC_GAME_API UnitAI // Select the targets satifying the predicate. // predicate shall extend std::unary_function<Unit*, bool> - template <class PREDICATE> void SelectTargetList(std::list<Unit*>& targetList, PREDICATE const& predicate, uint32 maxTargets, SelectAggroTarget targetType) + template <class PREDICATE> + void SelectTargetList(std::list<Unit*>& targetList, PREDICATE const& predicate, uint32 maxTargets, SelectAggroTarget targetType) { - ThreatContainer::StorageType const& threatlist = me->getThreatManager().getThreatList(); + ThreatContainer::StorageType const& threatlist = GetThreatManager().getThreatList(); if (threatlist.empty()) return; - for (ThreatContainer::StorageType::const_iterator itr = threatlist.begin(); itr != threatlist.end(); ++itr) - if (predicate((*itr)->getTarget())) - targetList.push_back((*itr)->getTarget()); + for (HostileReference* hostileRef : threatlist) + if (predicate(hostileRef->getTarget())) + targetList.push_back(hostileRef->getTarget()); if (targetList.size() < maxTargets) return; if (targetType == SELECT_TARGET_NEAREST || targetType == SELECT_TARGET_FARTHEST) - targetList.sort(Trinity::ObjectDistanceOrderPred(me)); + SortByDistanceTo(me, targetList); if (targetType == SELECT_TARGET_FARTHEST || targetType == SELECT_TARGET_BOTTOMAGGRO) targetList.reverse(); @@ -280,11 +261,9 @@ class TC_GAME_API UnitAI void AttackStartCaster(Unit* victim, float dist); - void DoAddAuraToAllHostilePlayers(uint32 spellid); void DoCast(uint32 spellId); void DoCast(Unit* victim, uint32 spellId, bool triggered = false); void DoCastSelf(uint32 spellId, bool triggered = false) { DoCast(me, spellId, triggered); } - void DoCastToAllHostilePlayers(uint32 spellid, bool triggered = false); void DoCastVictim(uint32 spellId, bool triggered = false); void DoCastAOE(uint32 spellId, bool triggered = false); @@ -305,7 +284,7 @@ class TC_GAME_API UnitAI virtual bool GossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) { return false; } // Called when a player selects a gossip with a code in the creature's gossip menu. - virtual bool GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, const char* /*code*/) { return false; } + virtual bool GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/) { return false; } // Called when a player accepts a quest from the creature. virtual void QuestAccept(Player* /*player*/, Quest const* /*quest*/) { } @@ -317,12 +296,13 @@ class TC_GAME_API UnitAI virtual void OnGameEvent(bool /*start*/, uint16 /*eventId*/) { } // Called when the dialog status between a player and the creature is requested. - virtual uint32 GetDialogStatus(Player* /*player*/) { return DIALOG_STATUS_SCRIPTED_NO_STATUS; } - + virtual uint32 GetDialogStatus(Player* /*player*/); private: UnitAI(UnitAI const& right) = delete; UnitAI& operator=(UnitAI const& right) = delete; + + ThreatManager& GetThreatManager(); }; #endif diff --git a/src/server/game/AI/CreatureAI.cpp b/src/server/game/AI/CreatureAI.cpp index 281795c0ed1..7ecee7cc14c 100644 --- a/src/server/game/AI/CreatureAI.cpp +++ b/src/server/game/AI/CreatureAI.cpp @@ -17,16 +17,20 @@ */ #include "CreatureAI.h" -#include "CreatureAIImpl.h" +#include "AreaBoundary.h" #include "Creature.h" -#include "World.h" -#include "SpellMgr.h" -#include "Vehicle.h" +#include "CreatureAIImpl.h" +#include "CreatureTextMgr.h" +#include "Language.h" #include "Log.h" +#include "Map.h" #include "MapReference.h" +#include "MotionMaster.h" #include "Player.h" -#include "CreatureTextMgr.h" -#include "Language.h" +#include "SpellMgr.h" +#include "TemporarySummon.h" +#include "Vehicle.h" +#include "World.h" //Disable CreatureAI when charmed void CreatureAI::OnCharmed(bool apply) @@ -39,7 +43,15 @@ void CreatureAI::OnCharmed(bool apply) } AISpellInfoType* UnitAI::AISpellInfo; -AISpellInfoType* GetAISpellInfo(uint32 i) { return &CreatureAI::AISpellInfo[i]; } +AISpellInfoType* GetAISpellInfo(uint32 i) { return &UnitAI::AISpellInfo[i]; } + +CreatureAI::CreatureAI(Creature* creature) : UnitAI(creature), me(creature), _boundary(nullptr), _negateBoundary(false), m_MoveInLineOfSight_locked(false) +{ +} + +CreatureAI::~CreatureAI() +{ +} void CreatureAI::Talk(uint8 id, WorldObject const* whisperTarget /*= nullptr*/) { @@ -391,7 +403,7 @@ void CreatureAI::SetBoundary(CreatureBoundary const* boundary, bool negateBounda me->DoImmediateBoundaryCheck(); } -Creature* CreatureAI::DoSummon(uint32 entry, const Position& pos, uint32 despawnTime, TempSummonType summonType) +Creature* CreatureAI::DoSummon(uint32 entry, Position const& pos, uint32 despawnTime, TempSummonType summonType) { return me->SummonCreature(entry, pos, summonType, despawnTime); } diff --git a/src/server/game/AI/CreatureAI.h b/src/server/game/AI/CreatureAI.h index 79bcefb3946..a787082bf9d 100644 --- a/src/server/game/AI/CreatureAI.h +++ b/src/server/game/AI/CreatureAI.h @@ -19,17 +19,19 @@ #ifndef TRINITY_CREATUREAI_H #define TRINITY_CREATUREAI_H -#include "Creature.h" #include "UnitAI.h" -#include "AreaBoundary.h" #include "Common.h" +#include "ObjectDefines.h" -class WorldObject; -class Unit; +class AreaBoundary; class Creature; -class Player; +class DynamicObject; +class GameObject; class PlayerAI; -class SpellInfo; +class WorldObject; +struct Position; + +typedef std::vector<AreaBoundary const*> CreatureBoundary; #define TIME_INTERVAL_LOOK 5000 #define VISIBILITY_RANGE 10000 @@ -65,7 +67,6 @@ enum SCEquip EQUIP_UNEQUIP = 0 }; -typedef std::vector<AreaBoundary const*> CreatureBoundary; class TC_GAME_API CreatureAI : public UnitAI { protected: @@ -92,11 +93,11 @@ class TC_GAME_API CreatureAI : public UnitAI EVADE_REASON_OTHER }; - void Talk(uint8 id, WorldObject const* whisperTarget = nullptr); + explicit CreatureAI(Creature* creature); - explicit CreatureAI(Creature* creature) : UnitAI(creature), me(creature), _boundary(nullptr), _negateBoundary(false), m_MoveInLineOfSight_locked(false) { } + virtual ~CreatureAI(); - virtual ~CreatureAI() { } + void Talk(uint8 id, WorldObject const* whisperTarget = nullptr); /// == Reactions At ================================= diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h index 6681ba8bc89..feb73ce11de 100644 --- a/src/server/game/AI/CreatureAIFactory.h +++ b/src/server/game/AI/CreatureAIFactory.h @@ -22,6 +22,9 @@ #include "ObjectRegistry.h" #include "FactoryHolder.h" +class Creature; +class CreatureAI; + typedef FactoryHolder<CreatureAI, Creature> CreatureAICreator; struct SelectableAI : public CreatureAICreator, public Permissible<Creature> diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index e0346eac10a..b2036d815bd 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -17,17 +17,13 @@ #ifndef CREATUREAIIMPL_H #define CREATUREAIIMPL_H -#include "Common.h" -#include "Define.h" -#include "TemporarySummon.h" -#include "CreatureAI.h" -#include "SpellMgr.h" - -#include <functional> +#include "Random.h" #include <type_traits> +class WorldObject; + template<typename First, typename Second, typename... Rest> -static inline First const& RAND(First const& first, Second const& second, Rest const&... rest) +inline First const& RAND(First const& first, Second const& second, Rest const&... rest) { std::reference_wrapper<typename std::add_const<First>::type> const pack[] = { first, second, rest... }; return pack[urand(0, sizeof...(rest) + 1)].get(); @@ -65,5 +61,15 @@ struct AISpellInfoType AISpellInfoType* GetAISpellInfo(uint32 i); -#endif +TC_GAME_API bool InstanceHasScript(WorldObject const* obj, char const* scriptName); + +template <class AI, class T> +AI* GetInstanceAI(T* obj, char const* scriptName) +{ + if (InstanceHasScript(obj, scriptName)) + return new AI(obj); + + return nullptr; +} +#endif diff --git a/src/server/game/AI/CreatureAIRegistry.cpp b/src/server/game/AI/CreatureAIRegistry.cpp index 25dcd98c5db..a89c410a93b 100644 --- a/src/server/game/AI/CreatureAIRegistry.cpp +++ b/src/server/game/AI/CreatureAIRegistry.cpp @@ -16,19 +16,20 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "PassiveAI.h" -#include "ReactorAI.h" +#include "CreatureAIFactory.h" +#include "GameObjectAIFactory.h" + #include "CombatAI.h" #include "GuardAI.h" +#include "PassiveAI.h" #include "PetAI.h" +#include "ReactorAI.h" +#include "SmartAI.h" #include "TotemAI.h" -#include "RandomMovementGenerator.h" + #include "MovementGenerator.h" -#include "CreatureAIRegistry.h" +#include "RandomMovementGenerator.h" #include "WaypointMovementGenerator.h" -#include "CreatureAIFactory.h" -#include "GameObjectAIFactory.h" -#include "SmartAI.h" namespace AIRegistry { diff --git a/src/server/game/AI/GameObjectAIFactory.h b/src/server/game/AI/GameObjectAIFactory.h index 2ff799ab7ea..a52f4279223 100644 --- a/src/server/game/AI/GameObjectAIFactory.h +++ b/src/server/game/AI/GameObjectAIFactory.h @@ -21,6 +21,9 @@ #include "ObjectRegistry.h" #include "FactoryHolder.h" +class GameObject; +class GameObjectAI; + typedef FactoryHolder<GameObjectAI, GameObject> GameObjectAICreator; struct SelectableGameObjectAI : public GameObjectAICreator, public Permissible<GameObject> diff --git a/src/server/game/AI/PlayerAI/PlayerAI.cpp b/src/server/game/AI/PlayerAI/PlayerAI.cpp index 0edd6097026..589b7162c3f 100644 --- a/src/server/game/AI/PlayerAI/PlayerAI.cpp +++ b/src/server/game/AI/PlayerAI/PlayerAI.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -16,8 +16,16 @@ */ #include "PlayerAI.h" +#include "Creature.h" +#include "Item.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "Spell.h" #include "SpellAuras.h" #include "SpellAuraEffects.h" +#include "SpellHistory.h" +#include "SpellMgr.h" static const uint8 NUM_TALENT_TREES = 3; static const uint8 NUM_SPEC_ICONICS = 3; @@ -496,6 +504,20 @@ static const uint32 SPEC_ICONICS[MAX_CLASSES][NUM_TALENT_TREES][NUM_SPEC_ICONICS } }; +PlayerAI::PlayerAI(Player* player) : UnitAI(player), me(player), + _selfSpec(PlayerAI::GetPlayerSpec(player)), + _isSelfHealer(PlayerAI::IsPlayerHealer(player)), + _isSelfRangedAttacker(PlayerAI::IsPlayerRangedAttacker(player)) +{ +} + +Creature* PlayerAI::GetCharmer() const +{ + if (me->GetCharmerGUID().IsCreature()) + return ObjectAccessor::GetCreature(*me, me->GetCharmerGUID()); + return nullptr; +} + uint8 PlayerAI::GetPlayerSpec(Player const* who) { if (!who) @@ -664,6 +686,13 @@ PlayerAI::TargetedSpell PlayerAI::SelectSpellCast(PossibleSpellVector& spells) return selected; } +void PlayerAI::DoCastAtTarget(TargetedSpell spell) +{ + SpellCastTargets targets; + targets.SetUnitTarget(spell.second); + spell.first->prepare(&targets); +} + void PlayerAI::DoRangedAttackIfReady() { if (me->HasUnitState(UNIT_STATE_CASTING)) @@ -735,13 +764,19 @@ void PlayerAI::CancelAllShapeshifts() me->RemoveOwnedAura(aura, AURA_REMOVE_BY_CANCEL); } -struct UncontrolledTargetSelectPredicate : public std::unary_function<Unit*, bool> +Unit* PlayerAI::SelectAttackTarget() const +{ + return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr; +} + +struct UncontrolledTargetSelectPredicate { bool operator()(Unit const* target) const { return !target->HasBreakableByDamageCrowdControlAura(); } }; + Unit* SimpleCharmedPlayerAI::SelectAttackTarget() const { if (Unit* charmer = me->GetCharmer()) diff --git a/src/server/game/AI/PlayerAI/PlayerAI.h b/src/server/game/AI/PlayerAI/PlayerAI.h index fce24b2dc0e..8afc5ab3ce9 100644 --- a/src/server/game/AI/PlayerAI/PlayerAI.h +++ b/src/server/game/AI/PlayerAI/PlayerAI.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -19,24 +19,18 @@ #define TRINITY_PLAYERAI_H #include "UnitAI.h" -#include "Player.h" -#include "Spell.h" -#include "Creature.h" + +class Spell; class TC_GAME_API PlayerAI : public UnitAI { public: - explicit PlayerAI(Player* player) : UnitAI(static_cast<Unit*>(player)), me(player), _selfSpec(PlayerAI::GetPlayerSpec(player)), _isSelfHealer(PlayerAI::IsPlayerHealer(player)), _isSelfRangedAttacker(PlayerAI::IsPlayerRangedAttacker(player)) { } + explicit PlayerAI(Player* player); void OnCharmed(bool /*apply*/) override { } // charm AI application for players is handled by Unit::SetCharmedBy / Unit::RemoveCharmedBy - Creature* GetCharmer() const - { - if (ObjectGuid charmerGUID = me->GetCharmerGUID()) - if (charmerGUID.IsCreature()) - return ObjectAccessor::GetCreature(*me, charmerGUID); - return nullptr; - } + Creature* GetCharmer() const; + // helper functions to determine player info // Return values range from 0 (left-most spec) to 2 (right-most spec). If two specs have the same number of talent points, the left-most of those specs is returned. static uint8 GetPlayerSpec(Player const* who); @@ -85,14 +79,9 @@ class TC_GAME_API PlayerAI : public UnitAI This invalidates the vector, and empties it to prevent accidental misuse. */ TargetedSpell SelectSpellCast(PossibleSpellVector& spells); /* Helper method - casts the included spell at the included target */ - inline void DoCastAtTarget(TargetedSpell spell) - { - SpellCastTargets targets; - targets.SetUnitTarget(spell.second); - spell.first->prepare(&targets); - } + void DoCastAtTarget(TargetedSpell spell); - virtual Unit* SelectAttackTarget() const { return me->GetCharmer() ? me->GetCharmer()->GetVictim() : nullptr; } + virtual Unit* SelectAttackTarget() const; void DoRangedAttackIfReady(); void DoAutoAttackIfReady(); diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 5464b99f8c9..d32ac53cb9f 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -17,13 +17,19 @@ */ #include "ScriptedCreature.h" -#include "Spell.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" +#include "AreaBoundary.h" #include "Cell.h" #include "CellImpl.h" -#include "ObjectMgr.h" -#include "AreaBoundary.h" +#include "DBCStores.h" +#include "GridNotifiers.h" +#include "GridNotifiersImpl.h" +#include "InstanceScript.h" +#include "Log.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Spell.h" +#include "SpellMgr.h" +#include "TemporarySummon.h" // Spell summary for ScriptedAI::SelectSpell struct TSpellSummary @@ -32,6 +38,16 @@ struct TSpellSummary uint8 Effects; // set of enum SelectEffect } extern* SpellSummary; +void SummonList::Summon(Creature const* summon) +{ + storage_.push_back(summon->GetGUID()); +} + +void SummonList::Despawn(Creature const* summon) +{ + storage_.remove(summon->GetGUID()); +} + void SummonList::DoZoneInCombat(uint32 entry, float maxRangeToNearestTarget) { for (StorageType::iterator i = storage_.begin(); i != storage_.end();) @@ -97,6 +113,16 @@ bool SummonList::HasEntry(uint32 entry) const return false; } +void SummonList::DoActionImpl(int32 action, StorageType const& summons) +{ + for (auto const& guid : summons) + { + Creature* summon = ObjectAccessor::GetCreature(*me, guid); + if (summon && summon->IsAIEnabled) + summon->AI()->DoAction(action); + } +} + ScriptedAI::ScriptedAI(Creature* creature) : CreatureAI(creature), IsFleeing(false), _isCombatMovementAllowed(true) @@ -179,6 +205,16 @@ Creature* ScriptedAI::DoSpawnCreature(uint32 entry, float offsetX, float offsetY return me->SummonCreature(entry, me->GetPositionX() + offsetX, me->GetPositionY() + offsetY, me->GetPositionZ() + offsetZ, angle, TempSummonType(type), despawntime); } +bool ScriptedAI::HealthBelowPct(uint32 pct) const +{ + return me->HealthBelowPct(pct); +} + +bool ScriptedAI::HealthAbovePct(uint32 pct) const +{ + return me->HealthAbovePct(pct); +} + SpellInfo const* ScriptedAI::SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effects) { //No target so we can't cast @@ -444,6 +480,11 @@ void BossAI::_JustDied() instance->SetBossState(_bossId, DONE); } +void BossAI::_JustReachedHome() +{ + me->setActive(false); +} + void BossAI::_EnterCombat() { if (instance) @@ -507,6 +548,11 @@ void BossAI::UpdateAI(uint32 diff) DoMeleeAttackIfReady(); } +bool BossAI::CanAIAttack(Unit const* target) const +{ + return CheckBoundary(target); +} + void BossAI::_DespawnAtEvade(uint32 delayToRespawn /*= 30*/, Creature* who /*= nullptr*/) { if (delayToRespawn < 2) diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.h b/src/server/game/AI/ScriptedAI/ScriptedCreature.h index b4db664a980..3b24203a146 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.h +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.h @@ -19,23 +19,11 @@ #ifndef SCRIPTEDCREATURE_H_ #define SCRIPTEDCREATURE_H_ -#include "Creature.h" #include "CreatureAI.h" -#include "CreatureAIImpl.h" -#include "InstanceScript.h" +#include "Creature.h" // convenience include for scripts, all uses of ScriptedCreature also need Creature (except ScriptedCreature itself doesn't need Creature) +#include "DBCEnums.h" #include "TaskScheduler.h" -#define CAST_AI(a, b) (dynamic_cast<a*>(b)) -#define ENSURE_AI(a,b) (EnsureAI<a>(b)) - -template<class T, class U> -T* EnsureAI(U* ai) -{ - T* cast_ai = dynamic_cast<T*>(ai); - ASSERT(cast_ai); - return cast_ai; -}; - class InstanceScript; class TC_GAME_API SummonList @@ -95,13 +83,13 @@ public: storage_.clear(); } - void Summon(Creature const* summon) { storage_.push_back(summon->GetGUID()); } - void Despawn(Creature const* summon) { storage_.remove(summon->GetGUID()); } + void Summon(Creature const* summon); + void Despawn(Creature const* summon); void DespawnEntry(uint32 entry); void DespawnAll(); template <typename T> - void DespawnIf(T const &predicate) + void DespawnIf(T const& predicate) { storage_.remove_if(predicate); } @@ -112,12 +100,7 @@ public: // We need to use a copy of SummonList here, otherwise original SummonList would be modified StorageType listCopy = storage_; Trinity::Containers::RandomResize<StorageType, Predicate>(listCopy, std::forward<Predicate>(predicate), max); - for (StorageType::iterator i = listCopy.begin(); i != listCopy.end(); ) - { - Creature* summon = ObjectAccessor::GetCreature(*me, *i++); - if (summon && summon->IsAIEnabled) - summon->AI()->DoAction(info); - } + DoActionImpl(info, listCopy); } void DoZoneInCombat(uint32 entry = 0, float maxRangeToNearestTarget = 250.0f); @@ -125,6 +108,8 @@ public: bool HasEntry(uint32 entry) const; private: + void DoActionImpl(int32 action, StorageType const& summons); + Creature* me; StorageType storage_; }; @@ -256,8 +241,8 @@ struct TC_GAME_API ScriptedAI : public CreatureAI //Spawns a creature relative to me Creature* DoSpawnCreature(uint32 entry, float offsetX, float offsetY, float offsetZ, float angle, uint32 type, uint32 despawntime); - bool HealthBelowPct(uint32 pct) const { return me->HealthBelowPct(pct); } - bool HealthAbovePct(uint32 pct) const { return me->HealthAbovePct(pct); } + bool HealthBelowPct(uint32 pct) const; + bool HealthAbovePct(uint32 pct) const; //Returns spells that meet the specified criteria from the creatures spell list SpellInfo const* SelectSpell(Unit* target, uint32 school, uint32 mechanic, SelectTargetType targets, uint32 powerCostMin, uint32 powerCostMax, float rangeMin, float rangeMax, SelectEffect effect); @@ -369,13 +354,13 @@ class TC_GAME_API BossAI : public ScriptedAI void JustDied(Unit* /*killer*/) override { _JustDied(); } void JustReachedHome() override { _JustReachedHome(); } - bool CanAIAttack(Unit const* target) const override { return CheckBoundary(target); } + bool CanAIAttack(Unit const* target) const override; protected: void _Reset(); void _EnterCombat(); void _JustDied(); - void _JustReachedHome() { me->setActive(false); } + void _JustReachedHome(); void _DespawnAtEvade(uint32 delayToRespawn = 30, Creature* who = nullptr); void _DespawnAtEvade(Seconds const& time, Creature* who = nullptr) { _DespawnAtEvade(uint32(time.count()), who); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index 085ef9c4047..6f5b7f1aa71 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -23,10 +23,14 @@ SDComment: SDCategory: Npc EndScriptData */ -#include "Player.h" -#include "ScriptedCreature.h" #include "ScriptedEscortAI.h" +#include "Creature.h" #include "Group.h" +#include "Log.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Player.h" enum Points { @@ -39,7 +43,7 @@ npc_escortAI::npc_escortAI(Creature* creature) : ScriptedAI(creature), m_uiPlayerCheckTimer(1000), m_uiEscortState(STATE_ESCORT_NONE), MaxPlayerDistance(DEFAULT_MAX_PLAYER_DISTANCE), - m_pQuestForEscort(NULL), + m_pQuestForEscort(nullptr), m_bIsActiveAttacker(true), m_bIsRunning(false), m_bCanInstantRespawn(false), @@ -65,6 +69,11 @@ void npc_escortAI::AttackStart(Unit* who) } } +Player* npc_escortAI::GetPlayerForEscort() +{ + return ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID); +} + //see followerAI bool npc_escortAI::AssistPlayerInCombatAgainst(Unit* who) { @@ -148,7 +157,7 @@ void npc_escortAI::JustDied(Unit* /*killer*/) { if (Group* group = player->GetGroup()) { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) if (Player* member = groupRef->GetSource()) if (member->IsInMap(player)) member->FailQuest(m_pQuestForEscort->GetQuestId()); @@ -186,7 +195,7 @@ void npc_escortAI::EnterEvadeMode(EvadeReason /*why*/) me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(true); - me->SetLootRecipient(NULL); + me->SetLootRecipient(nullptr); if (HasEscortState(STATE_ESCORT_ESCORTING)) { @@ -209,7 +218,7 @@ bool npc_escortAI::IsPlayerOrGroupInRange() { if (Group* group = player->GetGroup()) { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) if (Player* member = groupRef->GetSource()) if (me->IsWithinDistInMap(member, GetMaxPlayerDistance())) return true; @@ -431,7 +440,7 @@ void npc_escortAI::SetRun(bool on) } /// @todo get rid of this many variables passed in function. -void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, ObjectGuid playerGUID /* = 0 */, Quest const* quest /* = NULL */, bool instantRespawn /* = false */, bool canLoopPath /* = false */, bool resetWaypoints /* = true */) +void npc_escortAI::Start(bool isActiveAttacker /* = true*/, bool run /* = false */, ObjectGuid playerGUID /* = 0 */, Quest const* quest /* = nullptr */, bool instantRespawn /* = false */, bool canLoopPath /* = false */, bool resetWaypoints /* = true */) { if (me->GetVictim()) { diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h index e1bf3af5343..754d96dced9 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.h @@ -19,8 +19,11 @@ #ifndef SC_ESCORTAI_H #define SC_ESCORTAI_H +#include "ScriptedCreature.h" #include "ScriptSystem.h" +class Quest; + #define DEFAULT_MAX_PLAYER_DISTANCE 50 struct Escort_Waypoint @@ -88,7 +91,7 @@ struct TC_GAME_API npc_escortAI : public ScriptedAI virtual void WaypointReached(uint32 pointId) = 0; virtual void WaypointStart(uint32 /*pointId*/) { } - void Start(bool isActiveAttacker = true, bool run = false, ObjectGuid playerGUID = ObjectGuid::Empty, Quest const* quest = NULL, bool instantRespawn = false, bool canLoopPath = false, bool resetWaypoints = true); + void Start(bool isActiveAttacker = true, bool run = false, ObjectGuid playerGUID = ObjectGuid::Empty, Quest const* quest = nullptr, bool instantRespawn = false, bool canLoopPath = false, bool resetWaypoints = true); void SetRun(bool on = true); void SetEscortPaused(bool on); @@ -106,7 +109,7 @@ struct TC_GAME_API npc_escortAI : public ScriptedAI ObjectGuid GetEventStarterGUID() const { return m_uiPlayerGUID; } protected: - Player* GetPlayerForEscort() { return ObjectAccessor::GetPlayer(*me, m_uiPlayerGUID); } + Player* GetPlayerForEscort(); private: bool AssistPlayerInCombatAgainst(Unit* who); diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index 79c3c17d610..d18876fc439 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -23,10 +23,14 @@ SDComment: This AI is under development SDCategory: Npc EndScriptData */ -#include "Player.h" -#include "ScriptedCreature.h" #include "ScriptedFollowerAI.h" +#include "Creature.h" #include "Group.h" +#include "Log.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Player.h" const float MAX_PLAYER_DISTANCE = 100.0f; @@ -38,7 +42,7 @@ enum Points FollowerAI::FollowerAI(Creature* creature) : ScriptedAI(creature), m_uiUpdateFollowTimer(2500), m_uiFollowState(STATE_FOLLOW_NONE), - m_pQuestForFollow(NULL) + m_pQuestForFollow(nullptr) { } void FollowerAI::AttackStart(Unit* who) @@ -146,7 +150,7 @@ void FollowerAI::JustDied(Unit* /*killer*/) { if (Group* group = player->GetGroup()) { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) if (Player* member = groupRef->GetSource()) if (member->IsInMap(player)) member->FailQuest(m_pQuestForFollow->GetQuestId()); @@ -174,7 +178,7 @@ void FollowerAI::EnterEvadeMode(EvadeReason /*why*/) me->RemoveAllAuras(); me->DeleteThreatList(); me->CombatStop(true); - me->SetLootRecipient(NULL); + me->SetLootRecipient(nullptr); if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { @@ -224,7 +228,7 @@ void FollowerAI::UpdateAI(uint32 uiDiff) if (Group* group = player->GetGroup()) { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) { Player* member = groupRef->GetSource(); if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE)) @@ -282,7 +286,7 @@ void FollowerAI::MovementInform(uint32 motionType, uint32 pointId) } } -void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, const Quest* quest) +void FollowerAI::StartFollow(Player* player, uint32 factionForFollower, Quest const* quest) { if (me->GetVictim()) { @@ -330,7 +334,7 @@ Player* FollowerAI::GetLeaderForFollower() { if (Group* group = player->GetGroup()) { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) { Player* member = groupRef->GetSource(); if (member && me->IsWithinDistInMap(member, MAX_PLAYER_DISTANCE) && member->IsAlive()) @@ -345,7 +349,7 @@ Player* FollowerAI::GetLeaderForFollower() } TC_LOG_DEBUG("scripts", "FollowerAI GetLeader can not find suitable leader."); - return NULL; + return nullptr; } void FollowerAI::SetFollowComplete(bool bWithEndEvent) diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h index 6b5b06490f0..7fe877a7589 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.h @@ -19,8 +19,11 @@ #ifndef SC_FOLLOWERAI_H #define SC_FOLLOWERAI_H +#include "ScriptedCreature.h" #include "ScriptSystem.h" +class Quest; + enum eFollowState { STATE_FOLLOW_NONE = 0x000, @@ -55,7 +58,7 @@ class TC_GAME_API FollowerAI : public ScriptedAI void UpdateAI(uint32) override; //the "internal" update, calls UpdateFollowerAI() virtual void UpdateFollowerAI(uint32); //used when it's needed to add code in update (abilities, scripted events, etc) - void StartFollow(Player* player, uint32 factionForFollower = 0, const Quest* quest = NULL); + void StartFollow(Player* player, uint32 factionForFollower = 0, Quest const* quest = nullptr); void SetFollowPaused(bool bPaused); //if special event require follow mode to hold/resume during the follow void SetFollowComplete(bool bWithEndEvent = false); @@ -75,7 +78,7 @@ class TC_GAME_API FollowerAI : public ScriptedAI uint32 m_uiUpdateFollowTimer; uint32 m_uiFollowState; - const Quest* m_pQuestForFollow; //normally we have a quest + Quest const* m_pQuestForFollow; //normally we have a quest }; #endif diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index df5fe1d6b7b..682f92f1ee6 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -15,15 +15,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "DatabaseEnv.h" -#include "ObjectMgr.h" -#include "ObjectDefines.h" -#include "GridDefines.h" -#include "GridNotifiers.h" -#include "SpellMgr.h" -#include "Cell.h" -#include "Group.h" #include "SmartAI.h" +#include "Creature.h" +#include "DBCStructure.h" +#include "GameObject.h" +#include "Group.h" +#include "Log.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "PetDefines.h" +#include "Player.h" #include "ScriptMgr.h" #include "Vehicle.h" @@ -530,7 +531,7 @@ void SmartAI::MoveInLineOfSight(Unit* who) CreatureAI::MoveInLineOfSight(who); } -bool SmartAI::CanAIAttack(const Unit* /*who*/) const +bool SmartAI::CanAIAttack(Unit const* /*who*/) const { return !(me->HasReactState(REACT_PASSIVE)); } @@ -663,12 +664,12 @@ void SmartAI::AttackStart(Unit* who) } } -void SmartAI::SpellHit(Unit* unit, const SpellInfo* spellInfo) +void SmartAI::SpellHit(Unit* unit, SpellInfo const* spellInfo) { GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, unit, 0, 0, false, spellInfo); } -void SmartAI::SpellHitTarget(Unit* target, const SpellInfo* spellInfo) +void SmartAI::SpellHitTarget(Unit* target, SpellInfo const* spellInfo) { GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT_TARGET, target, 0, 0, false, spellInfo); } @@ -816,7 +817,7 @@ bool SmartAI::GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) return _gossipReturn; } -bool SmartAI::GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, const char* /*code*/) +bool SmartAI::GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/) { return false; } @@ -1005,7 +1006,7 @@ bool SmartGameObjectAI::GossipSelect(Player* player, uint32 sender, uint32 actio } // Called when a player selects a gossip with a code in the gameobject's gossip menu. -bool SmartGameObjectAI::GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, const char* /*code*/) +bool SmartGameObjectAI::GossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/) { return false; } @@ -1055,7 +1056,7 @@ void SmartGameObjectAI::EventInform(uint32 eventId) GetScript()->ProcessEventsFor(SMART_EVENT_GO_EVENT_INFORM, nullptr, eventId); } -void SmartGameObjectAI::SpellHit(Unit* unit, const SpellInfo* spellInfo) +void SmartGameObjectAI::SpellHit(Unit* unit, SpellInfo const* spellInfo) { GetScript()->ProcessEventsFor(SMART_EVENT_SPELLHIT, unit, 0, 0, false, spellInfo); } diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index e295f1bc7c4..b5ed74c4edb 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -18,15 +18,13 @@ #ifndef TRINITY_SMARTAI_H #define TRINITY_SMARTAI_H -#include "Common.h" -#include "Creature.h" +#include "Define.h" #include "CreatureAI.h" -#include "Unit.h" -#include "Spell.h" - -#include "SmartScript.h" -#include "SmartScriptMgr.h" #include "GameObjectAI.h" +#include "Position.h" +#include "SmartScript.h" + +struct WayPoint; enum SmartEscortState { @@ -100,10 +98,10 @@ class TC_GAME_API SmartAI : public CreatureAI void MoveInLineOfSight(Unit* who) override; // Called when hit by a spell - void SpellHit(Unit* unit, const SpellInfo* spellInfo) override; + void SpellHit(Unit* unit, SpellInfo const* spellInfo) override; // Called when spell hits a target - void SpellHitTarget(Unit* target, const SpellInfo* spellInfo) override; + void SpellHitTarget(Unit* target, SpellInfo const* spellInfo) override; // Called at any Damage from any attacker (before damage apply) void DamageTaken(Unit* doneBy, uint32& damage) override; @@ -142,7 +140,7 @@ class TC_GAME_API SmartAI : public CreatureAI void OnCharmed(bool apply) override; // Called when victim is in line of sight - bool CanAIAttack(const Unit* who) const override; + bool CanAIAttack(Unit const* who) const override; // Used in scripts to share variables void DoAction(int32 param = 0) override; @@ -180,7 +178,7 @@ class TC_GAME_API SmartAI : public CreatureAI bool GossipHello(Player* player) override; bool GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override; - bool GossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, const char* code) override; + bool GossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, char const* code) override; void QuestAccept(Player* player, Quest const* quest) override; void QuestReward(Player* player, Quest const* quest, uint32 opt) override; void OnGameEvent(bool start, uint16 eventId) override; @@ -262,7 +260,7 @@ class TC_GAME_API SmartGameObjectAI : public GameObjectAI bool GossipHello(Player* player) override; bool OnReportUse(Player* player) override; bool GossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override; - bool GossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, const char* code) override; + bool GossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, char const* code) override; void QuestAccept(Player* player, Quest const* quest) override; void QuestReward(Player* player, Quest const* quest, uint32 opt) override; void Destroyed(Player* player, uint32 eventId) override; @@ -271,7 +269,7 @@ class TC_GAME_API SmartGameObjectAI : public GameObjectAI void OnGameEvent(bool start, uint16 eventId) override; void OnLootStateChanged(uint32 state, Unit* unit) override; void EventInform(uint32 eventId) override; - void SpellHit(Unit* unit, const SpellInfo* spellInfo) override; + void SpellHit(Unit* unit, SpellInfo const* spellInfo) override; void SetGossipReturn(bool val) { _gossipReturn = val; } diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 6dc0bd62256..fe86978b0db 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -15,27 +15,31 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Cell.h" +#include "SmartScript.h" #include "CellImpl.h" #include "ChatTextBuilder.h" +#include "Creature.h" #include "CreatureTextMgr.h" -#include "DatabaseEnv.h" +#include "CreatureTextMgrImpl.h" +#include "GameEventMgr.h" +#include "GameObject.h" #include "GossipDef.h" -#include "GridDefines.h" -#include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "InstanceScript.h" #include "Language.h" -#include "ObjectDefines.h" +#include "Log.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "ScriptedCreature.h" -#include "ScriptedGossip.h" +#include "Random.h" #include "SmartAI.h" -#include "SmartScript.h" +#include "SpellAuras.h" #include "SpellMgr.h" +#include "TemporarySummon.h" #include "Vehicle.h" -#include "GameEventMgr.h" +#include <G3D/Quat.h> SmartScript::SmartScript() { @@ -57,6 +61,97 @@ SmartScript::~SmartScript() { } +bool SmartScript::IsSmart(Creature* c /*= nullptr*/) +{ + bool smart = true; + if (c && c->GetAIName() != "SmartAI") + smart = false; + + if (!me || me->GetAIName() != "SmartAI") + smart = false; + + if (!smart) + TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action called by Creature (GUID: %u Entry: %u) skipped to prevent crash.", c ? c->GetSpawnId() : 0, c ? c->GetEntry() : 0, me ? me->GetSpawnId() : 0, me ? me->GetEntry() : 0); + + return smart; +} + +bool SmartScript::IsSmartGO(GameObject* g /*= nullptr*/) +{ + bool smart = true; + if (g && g->GetAIName() != "SmartGameObjectAI") + smart = false; + + if (!go || go->GetAIName() != "SmartGameObjectAI") + smart = false; + if (!smart) + TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: %u Entry: %u) skipped to prevent crash.", g ? g->GetSpawnId() : 0, g ? g->GetEntry() : 0, go ? go->GetSpawnId() : 0, go ? go->GetEntry() : 0); + + return smart; +} + +void SmartScript::StoreTargetList(ObjectVector const& targets, uint32 id) +{ + // insert or replace + _storedTargets.erase(id); + _storedTargets.emplace(id, ObjectGuidVector(targets)); +} + +ObjectVector const* SmartScript::GetStoredTargetVector(uint32 id, WorldObject const& ref) const +{ + auto itr = _storedTargets.find(id); + if (itr != _storedTargets.end()) + return itr->second.GetObjectVector(ref); + return nullptr; +} + +void SmartScript::StoreCounter(uint32 id, uint32 value, uint32 reset) +{ + CounterMap::iterator itr = mCounterList.find(id); + if (itr != mCounterList.end()) + { + if (reset == 0) + itr->second += value; + else + itr->second = value; + } + else + mCounterList.insert(std::make_pair(id, value)); + + ProcessEventsFor(SMART_EVENT_COUNTER_SET, nullptr, id); +} + +uint32 SmartScript::GetCounterValue(uint32 id) const +{ + CounterMap::const_iterator itr = mCounterList.find(id); + if (itr != mCounterList.end()) + return itr->second; + return 0; +} + +GameObject* SmartScript::FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const +{ + auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; + + return bounds.first->second; +} + +Creature* SmartScript::FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const +{ + auto bounds = searchObject->GetMap()->GetCreatureBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; + + auto creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair) + { + return pair.second->IsAlive(); + }); + + return creatureItr != bounds.second ? creatureItr->second : bounds.first->second; +} + void SmartScript::OnReset() { ResetBaseObject(); @@ -73,7 +168,37 @@ void SmartScript::OnReset() mCounterList.clear(); } -void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob) +void SmartScript::ResetBaseObject() +{ + WorldObject* lookupRoot = me; + if (!lookupRoot) + lookupRoot = go; + + if (lookupRoot) + { + if (!meOrigGUID.IsEmpty()) + { + if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID)) + { + me = m; + go = nullptr; + } + } + + if (!goOrigGUID.IsEmpty()) + { + if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID)) + { + me = nullptr; + go = o; + } + } + } + goOrigGUID.Clear(); + meOrigGUID.Clear(); +} + +void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob) { for (SmartAIEventList::iterator i = mEvents.begin(); i != mEvents.end(); ++i) { @@ -87,7 +212,7 @@ void SmartScript::ProcessEventsFor(SMART_EVENT e, Unit* unit, uint32 var0, uint3 } } -void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob) +void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob) { // calc random if (e.GetEventType() != SMART_EVENT_LINK && e.event.event_chance < 100 && e.event.event_chance) @@ -314,7 +439,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_RANDOM_EMOTE: { std::vector<uint32> emotes; - std::copy_if(e.action.randomEmote.emotes.begin(), e.action.randomEmote.emotes.end(), + std::copy_if(std::begin(e.action.randomEmote.emotes), std::end(e.action.randomEmote.emotes), std::back_inserter(emotes), [](uint32 emote) { return emote != 0; }); for (WorldObject* target : targets) @@ -736,7 +861,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; std::vector<uint32> phases; - std::copy_if(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(), + std::copy_if(std::begin(e.action.randomPhase.phases), std::end(e.action.randomPhase.phases), std::back_inserter(phases), [](uint32 phase) { return phase != 0; }); uint32 phase = Trinity::Containers::SelectRandomContainerElement(phases); @@ -1064,14 +1189,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u for (WorldObject* target : targets) { Position pos = target->GetPositionWithOffset(Position(e.target.x, e.target.y, e.target.z, e.target.o)); - G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f); GetBaseObject()->SummonGameObject(e.action.summonGO.entry, pos, rot, e.action.summonGO.despawnTime); } if (e.GetTargetType() != SMART_TARGET_POSITION) break; - G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(e.target.o, 0.f, 0.f); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(e.target.o, 0.f, 0.f); GetBaseObject()->SummonGameObject(e.action.summonGO.entry, Position(e.target.x, e.target.y, e.target.z, e.target.o), rot, e.action.summonGO.despawnTime); break; } @@ -1350,7 +1475,11 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u std::copy(std::begin(eInfo->ItemEntry), std::end(eInfo->ItemEntry), std::begin(slot)); } else - std::copy(std::begin(e.action.equip.slots), std::end(e.action.equip.slots), std::begin(slot)); + { + slot[0] = e.action.equip.slot1; + slot[1] = e.action.equip.slot2; + slot[2] = e.action.equip.slot3; + } for (uint32 i = 0; i < MAX_EQUIPMENT_ITEMS; ++i) if (!e.action.equip.mask || (e.action.equip.mask & (1 << i))) @@ -1498,7 +1627,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; ObjectVector casters; - GetTargets(casters, CreateEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit); + GetTargets(casters, CreateSmartEvent(SMART_EVENT_UPDATE_IC, 0, 0, 0, 0, 0, SMART_ACTION_NONE, 0, 0, 0, 0, 0, 0, (SMARTAI_TARGETS)e.action.crossCast.targetType, e.action.crossCast.targetParam1, e.action.crossCast.targetParam2, e.action.crossCast.targetParam3, 0), unit); for (WorldObject* caster : casters) { @@ -1533,7 +1662,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: { std::vector<uint32> actionLists; - std::copy_if(e.action.randTimedActionList.actionLists.begin(), e.action.randTimedActionList.actionLists.end(), + std::copy_if(std::begin(e.action.randTimedActionList.actionLists), std::end(e.action.randTimedActionList.actionLists), std::back_inserter(actionLists), [](uint32 actionList) { return actionList != 0; }); uint32 id = Trinity::Containers::SelectRandomContainerElement(actionLists); @@ -1738,9 +1867,9 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (e.action.sendGossipMenu.gossipMenuId) player->PrepareGossipMenu(GetBaseObject(), e.action.sendGossipMenu.gossipMenuId, true); else - ClearGossipMenuFor(player); + player->PlayerTalkClass->ClearMenus(); - SendGossipMenuFor(player, e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID()); + player->PlayerTalkClass->SendGossipMenu(e.action.sendGossipMenu.gossipNpcTextId, GetBaseObject()->GetGUID()); } } break; @@ -1861,7 +1990,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_START_CLOSEST_WAYPOINT: { std::vector<uint32> waypoints; - std::copy_if(e.action.closestWaypointFromList.wps.begin(), e.action.closestWaypointFromList.wps.end(), + std::copy_if(std::begin(e.action.closestWaypointFromList.wps), std::end(e.action.closestWaypointFromList.wps), std::back_inserter(waypoints), [](uint32 wp) { return wp != 0; }); float distanceToClosest = std::numeric_limits<float>::max(); @@ -1904,7 +2033,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_RANDOM_SOUND: { std::vector<uint32> sounds; - std::copy_if(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), + std::copy_if(std::begin(e.action.randomSound.sounds), std::end(e.action.randomSound.sounds), std::back_inserter(sounds), [](uint32 sound) { return sound != 0; }); bool onlySelf = e.action.randomSound.onlySelf != 0; @@ -1975,7 +2104,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u case SMART_ACTION_TRIGGER_RANDOM_TIMED_EVENT: { uint32 eventId = urand(e.action.randomTimedEvent.minId, e.action.randomTimedEvent.maxId); - ProcessEventsFor((SMART_EVENT)SMART_EVENT_TIMED_EVENT_TRIGGERED, NULL, eventId); + ProcessEventsFor((SMART_EVENT)SMART_EVENT_TIMED_EVENT_TRIGGERED, nullptr, eventId); break; } @@ -2015,7 +2144,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u } } -void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob) +void SmartScript::ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob) { // We may want to execute action rarely and because of this if condition is not fulfilled the action will be rechecked in a long time if (sConditionMgr->IsObjectMeetingSmartEventConditions(e.entryOrGuid, e.event_id, e.source_type, unit, GetBaseObject())) @@ -2105,10 +2234,10 @@ void SmartScript::InstallTemplate(SmartScriptHolder const& e) void SmartScript::AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask) { - mInstallEvents.push_back(CreateEvent(e, event_flags, event_param1, event_param2, event_param3, event_param4, action, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, t, target_param1, target_param2, target_param3, phaseMask)); + mInstallEvents.push_back(CreateSmartEvent(e, event_flags, event_param1, event_param2, event_param3, event_param4, action, action_param1, action_param2, action_param3, action_param4, action_param5, action_param6, t, target_param1, target_param2, target_param3, phaseMask)); } -SmartScriptHolder SmartScript::CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask) +SmartScriptHolder SmartScript::CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask) { SmartScriptHolder script; script.event.type = e; @@ -2373,13 +2502,13 @@ void SmartScript::GetTargets(ObjectVector& targets, SmartScriptHolder const& e, } case SMART_TARGET_CLOSEST_CREATURE: { - if (Creature* target = GetClosestCreatureWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead)) + if (Creature* target = baseObject->FindNearestCreature(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100), !e.target.closest.dead)) targets.push_back(target); break; } case SMART_TARGET_CLOSEST_GAMEOBJECT: { - if (GameObject* target = GetClosestGameObjectWithEntry(baseObject, e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100))) + if (GameObject* target = baseObject->FindNearestGameObject(e.target.closest.entry, float(e.target.closest.dist ? e.target.closest.dist : 100))) targets.push_back(target); break; } @@ -2496,7 +2625,7 @@ void SmartScript::GetWorldObjectsInDist(ObjectVector& targets, float dist) const Cell::VisitAllObjects(obj, searcher, dist); } -void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, const SpellInfo* spell, GameObject* gob) +void SmartScript::ProcessEvent(SmartScriptHolder& e, Unit* unit, uint32 var0, uint32 var1, bool bvar, SpellInfo const* spell, GameObject* gob) { if (!e.active && e.GetEventType() != SMART_EVENT_LINK) return; @@ -3182,6 +3311,62 @@ void SmartScript::InstallEvents() } } +void SmartScript::RemoveStoredEvent(uint32 id) +{ + if (!mStoredEvents.empty()) + { + for (auto i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i) + { + if (i->event_id == id) + { + mStoredEvents.erase(i); + return; + } + } + } +} + +WorldObject* SmartScript::GetBaseObject() const +{ + WorldObject* obj = nullptr; + if (me) + obj = me; + else if (go) + obj = go; + return obj; +} + +bool SmartScript::IsUnit(WorldObject* obj) +{ + return obj && (obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER); +} + +bool SmartScript::IsPlayer(WorldObject* obj) +{ + return obj && obj->GetTypeId() == TYPEID_PLAYER; +} + +bool SmartScript::IsCreature(WorldObject* obj) +{ + return obj && obj->GetTypeId() == TYPEID_UNIT; +} + +bool SmartScript::IsCharmedCreature(WorldObject* obj) +{ + if (!obj) + return false; + + if (Creature* creatureObj = obj->ToCreature()) + return creatureObj->IsCharmed(); + + return false; +} + +bool SmartScript::IsGameObject(WorldObject* obj) +{ + return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT; +} + void SmartScript::OnUpdate(uint32 const diff) { if ((mScriptType == SMART_SCRIPT_TYPE_CREATURE || mScriptType == SMART_SCRIPT_TYPE_GAMEOBJECT) && !GetBaseObject()) diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index cf10f7d15f4..b0269bc45c2 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -18,15 +18,16 @@ #ifndef TRINITY_SMARTSCRIPT_H #define TRINITY_SMARTSCRIPT_H -#include "Common.h" -#include "Creature.h" -#include "CreatureAI.h" -#include "Unit.h" -#include "Spell.h" -#include "GridNotifiers.h" - +#include "Define.h" #include "SmartScriptMgr.h" -//#include "SmartAI.h" + +class Creature; +class GameObject; +class Player; +class SpellInfo; +class Unit; +class WorldObject; +struct AreaTriggerEntry; class TC_GAME_API SmartScript { @@ -38,61 +39,27 @@ class TC_GAME_API SmartScript void GetScript(); void FillScript(SmartAIEventList e, WorldObject* obj, AreaTriggerEntry const* at); - void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr); - void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr); + void ProcessEventsFor(SMART_EVENT e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr); + void ProcessEvent(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr); bool CheckTimer(SmartScriptHolder const& e) const; static void RecalcTimer(SmartScriptHolder& e, uint32 min, uint32 max); void UpdateTimer(SmartScriptHolder& e, uint32 const diff); static void InitTimer(SmartScriptHolder& e); - void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr); - void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, const SpellInfo* spell = nullptr, GameObject* gob = nullptr); + void ProcessAction(SmartScriptHolder& e, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr); + void ProcessTimedAction(SmartScriptHolder& e, uint32 const& min, uint32 const& max, Unit* unit = nullptr, uint32 var0 = 0, uint32 var1 = 0, bool bvar = false, SpellInfo const* spell = nullptr, GameObject* gob = nullptr); void GetTargets(ObjectVector& targets, SmartScriptHolder const& e, Unit* invoker = nullptr) const; void GetWorldObjectsInDist(ObjectVector& objects, float dist) const; void InstallTemplate(SmartScriptHolder const& e); - static SmartScriptHolder CreateEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask = 0); + static SmartScriptHolder CreateSmartEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask = 0); void AddEvent(SMART_EVENT e, uint32 event_flags, uint32 event_param1, uint32 event_param2, uint32 event_param3, uint32 event_param4, SMART_ACTION action, uint32 action_param1, uint32 action_param2, uint32 action_param3, uint32 action_param4, uint32 action_param5, uint32 action_param6, SMARTAI_TARGETS t, uint32 target_param1, uint32 target_param2, uint32 target_param3, uint32 phaseMask = 0); void SetPathId(uint32 id) { mPathId = id; } uint32 GetPathId() const { return mPathId; } - WorldObject* GetBaseObject() const - { - WorldObject* obj = nullptr; - if (me) - obj = me; - else if (go) - obj = go; - return obj; - } - - static bool IsUnit(WorldObject* obj) - { - return obj && (obj->GetTypeId() == TYPEID_UNIT || obj->GetTypeId() == TYPEID_PLAYER); - } - - static bool IsPlayer(WorldObject* obj) - { - return obj && obj->GetTypeId() == TYPEID_PLAYER; - } - - static bool IsCreature(WorldObject* obj) - { - return obj && obj->GetTypeId() == TYPEID_UNIT; - } - - static bool IsCharmedCreature(WorldObject* obj) - { - if (!obj) - return false; - - if (Creature* creatureObj = obj->ToCreature()) - return creatureObj->IsCharmed(); - - return false; - } - - static bool IsGameObject(WorldObject* obj) - { - return obj && obj->GetTypeId() == TYPEID_GAMEOBJECT; - } + WorldObject* GetBaseObject() const; + static bool IsUnit(WorldObject* obj); + static bool IsPlayer(WorldObject* obj); + static bool IsCreature(WorldObject* obj); + static bool IsCharmedCreature(WorldObject* obj); + static bool IsGameObject(WorldObject* obj); void OnUpdate(const uint32 diff); void OnMoveInLineOfSight(Unit* who); @@ -102,127 +69,20 @@ class TC_GAME_API SmartScript void DoFindFriendlyMissingBuff(std::vector<Creature*>& creatures, float range, uint32 spellid) const; Unit* DoFindClosestFriendlyInRange(float range, bool playerOnly) const; - void StoreTargetList(ObjectVector const& targets, uint32 id) - { - // insert or replace - _storedTargets.erase(id); - _storedTargets.emplace(id, ObjectGuidVector(targets)); - } - - bool IsSmart(Creature* c = nullptr) - { - bool smart = true; - if (c && c->GetAIName() != "SmartAI") - smart = false; - - if (!me || me->GetAIName() != "SmartAI") - smart = false; - - if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action called by Creature (GUID: %u Entry: %u) skipped to prevent crash.", c ? c->GetSpawnId() : 0, c ? c->GetEntry() : 0, me ? me->GetSpawnId() : 0, me ? me->GetEntry() : 0); + bool IsSmart(Creature* c = nullptr); + bool IsSmartGO(GameObject* g = nullptr); - return smart; - } + void StoreTargetList(ObjectVector const& targets, uint32 id); + ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const; - bool IsSmartGO(GameObject* g = nullptr) - { - bool smart = true; - if (g && g->GetAIName() != "SmartGameObjectAI") - smart = false; + void StoreCounter(uint32 id, uint32 value, uint32 reset); + uint32 GetCounterValue(uint32 id) const; - if (!go || go->GetAIName() != "SmartGameObjectAI") - smart = false; - if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: %u Entry: %u) skipped to prevent crash.", g ? g->GetSpawnId() : 0, g ? g->GetEntry() : 0, go ? go->GetSpawnId() : 0, go ? go->GetEntry() : 0); - - return smart; - } - - ObjectVector const* GetStoredTargetVector(uint32 id, WorldObject const& ref) const - { - auto itr = _storedTargets.find(id); - if (itr != _storedTargets.end()) - return itr->second.GetObjectVector(ref); - return nullptr; - } - - void StoreCounter(uint32 id, uint32 value, uint32 reset) - { - CounterMap::iterator itr = mCounterList.find(id); - if (itr != mCounterList.end()) - { - if (reset == 0) - itr->second += value; - else - itr->second = value; - } - else - mCounterList.insert(std::make_pair(id, value)); - - ProcessEventsFor(SMART_EVENT_COUNTER_SET, nullptr, id); - } - - uint32 GetCounterValue(uint32 id) const - { - CounterMap::const_iterator itr = mCounterList.find(id); - if (itr != mCounterList.end()) - return itr->second; - return 0; - } - - GameObject* FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const - { - auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid); - if (bounds.first == bounds.second) - return nullptr; - - return bounds.first->second; - } - - Creature* FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const - { - auto bounds = searchObject->GetMap()->GetCreatureBySpawnIdStore().equal_range(guid); - if (bounds.first == bounds.second) - return nullptr; - - auto creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair) - { - return pair.second->IsAlive(); - }); - - return creatureItr != bounds.second ? creatureItr->second : bounds.first->second; - } + GameObject* FindGameObjectNear(WorldObject* searchObject, ObjectGuid::LowType guid) const; + Creature* FindCreatureNear(WorldObject* searchObject, ObjectGuid::LowType guid) const; void OnReset(); - void ResetBaseObject() - { - WorldObject* lookupRoot = me; - if (!lookupRoot) - lookupRoot = go; - - if (lookupRoot) - { - if (!meOrigGUID.IsEmpty()) - { - if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID)) - { - me = m; - go = nullptr; - } - } - - if (!goOrigGUID.IsEmpty()) - { - if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID)) - { - me = nullptr; - go = o; - } - } - } - goOrigGUID.Clear(); - meOrigGUID.Clear(); - } + void ResetBaseObject(); //TIMED_ACTIONLIST (script type 9 aka script9) void SetScript9(SmartScriptHolder& e, uint32 entry); @@ -265,20 +125,7 @@ class TC_GAME_API SmartScript SMARTAI_TEMPLATE mTemplate; void InstallEvents(); - void RemoveStoredEvent(uint32 id) - { - if (!mStoredEvents.empty()) - { - for (auto i = mStoredEvents.begin(); i != mStoredEvents.end(); ++i) - { - if (i->event_id == id) - { - mStoredEvents.erase(i); - return; - } - } - } - } + void RemoveStoredEvent(uint32 id); }; #endif diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index d2910208155..31282a934ac 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -15,18 +15,20 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "SmartScriptMgr.h" +#include "CreatureTextMgr.h" #include "DatabaseEnv.h" -#include "ObjectMgr.h" -#include "GridDefines.h" -#include "GridNotifiers.h" -#include "InstanceScript.h" -#include "SpellMgr.h" -#include "Cell.h" +#include "DBCStores.h" #include "GameEventMgr.h" -#include "CreatureTextMgr.h" +#include "InstanceScript.h" +#include "Log.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "SpellInfo.h" - -#include "SmartScriptMgr.h" +#include "SpellMgr.h" +#include "Timer.h" +#include "UnitDefines.h" SmartWaypointMgr* SmartWaypointMgr::instance() { @@ -380,6 +382,43 @@ void SmartAIMgr::LoadSmartAIFromDB() UnLoadHelperStores(); } +SmartAIEventList SmartAIMgr::GetScript(int32 entry, SmartScriptType type) +{ + SmartAIEventList temp; + if (mEventMap[uint32(type)].find(entry) != mEventMap[uint32(type)].end()) + return mEventMap[uint32(type)][entry]; + else + { + if (entry > 0)//first search is for guid (negative), do not drop error if not found + TC_LOG_DEBUG("scripts.ai", "SmartAIMgr::GetScript: Could not load Script for Entry %d ScriptType %u.", entry, uint32(type)); + return temp; + } +} + +SmartScriptHolder& SmartAIMgr::FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId) +{ + SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), + [eventId](SmartScriptHolder& source) { return source.link == eventId; }); + + if (itr != list.end()) + return *itr; + + static SmartScriptHolder SmartScriptHolderDummy; + return SmartScriptHolderDummy; +} + +SmartScriptHolder& SmartAIMgr::FindLinkedEvent(SmartAIEventList& list, uint32 link) +{ + SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), + [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; }); + + if (itr != list.end()) + return *itr; + + static SmartScriptHolder SmartScriptHolderDummy; + return SmartScriptHolderDummy; +} + bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) { if (std::abs(e.target.o) > 2 * float(M_PI)) @@ -463,6 +502,116 @@ bool SmartAIMgr::IsTargetValid(SmartScriptHolder const& e) return true; } +bool SmartAIMgr::IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max) +{ + if (max < min) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses min/max params wrong (%u/%u), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), min, max); + return false; + } + return true; +} + +bool SmartAIMgr::NotNULL(SmartScriptHolder const& e, uint32 data) +{ + if (!data) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Parameter can not be NULL, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); + return false; + } + return true; +} + +bool SmartAIMgr::IsCreatureValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sObjectMgr->GetCreatureTemplate(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Creature entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsQuestValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sObjectMgr->GetQuestTemplate(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Quest entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsGameObjectValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sObjectMgr->GetGameObjectTemplate(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent GameObject entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsSpellValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sSpellMgr->GetSpellInfo(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsItemValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sItemStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Item entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sEmotesTextStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Text Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsEmoteValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sEmotesStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsAreaTriggerValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sAreaTriggerStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent AreaTrigger entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + +bool SmartAIMgr::IsSoundValid(SmartScriptHolder const& e, uint32 entry) +{ + if (!sSoundEntriesStore.LookupEntry(entry)) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Sound entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); + return false; + } + return true; +} + bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) { if (e.event.type >= SMART_EVENT_END) @@ -916,7 +1065,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } case SMART_ACTION_RANDOM_EMOTE: { - if (std::all_of(e.action.randomEmote.emotes.begin(), e.action.randomEmote.emotes.end(), [](uint32 emote) { return emote == 0; })) + if (std::all_of(std::begin(e.action.randomEmote.emotes), std::end(e.action.randomEmote.emotes), [](uint32 emote) { return emote == 0; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u does not have any non-zero emote", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -930,7 +1079,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } case SMART_ACTION_CALL_RANDOM_TIMED_ACTIONLIST: { - if (std::all_of(e.action.randTimedActionList.actionLists.begin(), e.action.randTimedActionList.actionLists.end(), [](uint32 actionList) { return actionList == 0; })) + if (std::all_of(std::begin(e.action.randTimedActionList.actionLists), std::end(e.action.randTimedActionList.actionLists), [](uint32 actionList) { return actionList == 0; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u does not have any non-zero action list", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -940,7 +1089,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } case SMART_ACTION_START_CLOSEST_WAYPOINT: { - if (std::all_of(e.action.closestWaypointFromList.wps.begin(), e.action.closestWaypointFromList.wps.end(), [](uint32 wp) { return wp == 0; })) + if (std::all_of(std::begin(e.action.closestWaypointFromList.wps), std::end(e.action.closestWaypointFromList.wps), [](uint32 wp) { return wp == 0; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u does not have any non-zero waypoint id", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -950,7 +1099,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } case SMART_ACTION_RANDOM_SOUND: { - if (std::all_of(e.action.randomSound.sounds.begin(), e.action.randomSound.sounds.end(), [](uint32 sound) { return sound == 0; })) + if (std::all_of(std::begin(e.action.randomSound.sounds), std::end(e.action.randomSound.sounds), [](uint32 sound) { return sound == 0; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u does not have any non-zero sound", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); @@ -1032,14 +1181,14 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) break; case SMART_ACTION_RANDOM_PHASE: { - if (std::all_of(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(), [](uint32 phase) { return phase == 0; })) + if (std::all_of(std::begin(e.action.randomPhase.phases), std::end(e.action.randomPhase.phases), [](uint32 phase) { return phase == 0; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u does not have any non-zero phase", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); return false; } - if (std::any_of(e.action.randomPhase.phases.begin(), e.action.randomPhase.phases.end(), [](uint32 phase) { return phase >= SMART_EVENT_PHASE_MAX; })) + if (std::any_of(std::begin(e.action.randomPhase.phases), std::end(e.action.randomPhase.phases), [](uint32 phase) { return phase >= SMART_EVENT_PHASE_MAX; })) { TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u attempts to set invalid phase, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); return false; @@ -1164,21 +1313,21 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) return false; break; case SMART_ACTION_WP_START: + { + if (!sSmartWaypointMgr->GetPath(e.action.wpStart.pathID)) { - if (!sSmartWaypointMgr->GetPath(e.action.wpStart.pathID)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Creature %d Event %u Action %u uses non-existent WaypointPath id %u, skipped.", e.entryOrGuid, e.event_id, e.GetActionType(), e.action.wpStart.pathID); - return false; - } - if (e.action.wpStart.quest && !IsQuestValid(e, e.action.wpStart.quest)) - return false; - if (e.action.wpStart.reactState > REACT_AGGRESSIVE) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Creature %d Event %u Action %u uses invalid React State %u, skipped.", e.entryOrGuid, e.event_id, e.GetActionType(), e.action.wpStart.reactState); - return false; - } - break; + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Creature %d Event %u Action %u uses non-existent WaypointPath id %u, skipped.", e.entryOrGuid, e.event_id, e.GetActionType(), e.action.wpStart.pathID); + return false; + } + if (e.action.wpStart.quest && !IsQuestValid(e, e.action.wpStart.quest)) + return false; + if (e.action.wpStart.reactState > REACT_AGGRESSIVE) + { + TC_LOG_ERROR("sql.sql", "SmartAIMgr: Creature %d Event %u Action %u uses invalid React State %u, skipped.", e.entryOrGuid, e.event_id, e.GetActionType(), e.action.wpStart.reactState); + return false; } + break; + } case SMART_ACTION_CREATE_TIMED_EVENT: { if (!IsMinMaxValid(e, e.action.timeEvent.min, e.action.timeEvent.max)) @@ -1419,7 +1568,7 @@ void SmartAIMgr::LoadHelperStores() { uint32 oldMSTime = getMSTime(); - SpellInfo const* spellInfo = NULL; + SpellInfo const* spellInfo = nullptr; for (uint32 i = 0; i < sSpellMgr->GetSpellInfoStoreSize(); ++i) { spellInfo = sSpellMgr->GetSpellInfo(i); @@ -1473,3 +1622,18 @@ CacheSpellContainerBounds SmartAIMgr::GetCreateItemSpellContainerBounds(uint32 i return CreateItemSpellStore.equal_range(itemId); } +ObjectGuidVector::ObjectGuidVector(ObjectVector const& objectVector) : _objectVector(objectVector) +{ + _guidVector.reserve(_objectVector.size()); + for (WorldObject* obj : _objectVector) + _guidVector.push_back(obj->GetGUID()); +} + +void ObjectGuidVector::UpdateObjects(WorldObject const& ref) const +{ + _objectVector.clear(); + + for (ObjectGuid const& guid : _guidVector) + if (WorldObject* obj = ObjectAccessor::GetWorldObject(ref, guid)) + _objectVector.push_back(obj); +} diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 29b76ae0dd9..7a1433bc7fb 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -18,14 +18,14 @@ #ifndef TRINITY_SMARTSCRIPTMGR_H #define TRINITY_SMARTSCRIPTMGR_H -#include "Common.h" -#include "Creature.h" -#include "CreatureAI.h" -#include "Unit.h" -#include "Spell.h" +#include "Define.h" +#include "ObjectGuid.h" +#include <map> +#include <string> +#include <unordered_map> -//#include "SmartScript.h" -//#include "SmartAI.h" +class WorldObject; +enum SpellEffIndex : uint8; struct WayPoint { @@ -646,7 +646,7 @@ struct SmartAction struct { - std::array<uint32, SMART_ACTION_PARAM_COUNT> emotes; + uint32 emotes[SMART_ACTION_PARAM_COUNT]; } randomEmote; struct @@ -739,7 +739,7 @@ struct SmartAction struct { - std::array<uint32, SMART_ACTION_PARAM_COUNT> phases; + uint32 phases[SMART_ACTION_PARAM_COUNT]; } randomPhase; struct @@ -930,7 +930,9 @@ struct SmartAction { uint32 entry; uint32 mask; - std::array<uint32, MAX_EQUIPMENT_ITEMS> slots; + uint32 slot1; + uint32 slot2; + uint32 slot3; } equip; struct @@ -964,7 +966,7 @@ struct SmartAction struct { - std::array<uint32, SMART_ACTION_PARAM_COUNT> actionLists; + uint32 actionLists[SMART_ACTION_PARAM_COUNT]; } randTimedActionList; struct @@ -1074,12 +1076,12 @@ struct SmartAction struct { - std::array<uint32, SMART_ACTION_PARAM_COUNT> wps; + uint32 wps[SMART_ACTION_PARAM_COUNT]; } closestWaypointFromList; struct { - std::array<uint32, SMART_ACTION_PARAM_COUNT - 1> sounds; + uint32 sounds[SMART_ACTION_PARAM_COUNT - 1]; uint32 onlySelf; } randomSound; @@ -1500,12 +1502,7 @@ typedef std::vector<WorldObject*> ObjectVector; class ObjectGuidVector { public: - explicit ObjectGuidVector(ObjectVector const& objectVector) : _objectVector(objectVector) - { - _guidVector.reserve(_objectVector.size()); - for (WorldObject* obj : _objectVector) - _guidVector.push_back(obj->GetGUID()); - } + explicit ObjectGuidVector(ObjectVector const& objectVector); ObjectVector const* GetObjectVector(WorldObject const& ref) const { @@ -1520,14 +1517,7 @@ class ObjectGuidVector mutable ObjectVector _objectVector; //sanitize vector using _guidVector - void UpdateObjects(WorldObject const& ref) const - { - _objectVector.clear(); - - for (ObjectGuid const& guid : _guidVector) - if (WorldObject* obj = ObjectAccessor::GetWorldObject(ref, guid)) - _objectVector.push_back(obj); - } + void UpdateObjects(WorldObject const& ref) const; }; typedef std::unordered_map<uint32, ObjectGuidVector> ObjectVectorMap; @@ -1575,42 +1565,11 @@ class TC_GAME_API SmartAIMgr void LoadSmartAIFromDB(); - SmartAIEventList GetScript(int32 entry, SmartScriptType type) - { - SmartAIEventList temp; - if (mEventMap[uint32(type)].find(entry) != mEventMap[uint32(type)].end()) - return mEventMap[uint32(type)][entry]; - else - { - if (entry > 0)//first search is for guid (negative), do not drop error if not found - TC_LOG_DEBUG("scripts.ai", "SmartAIMgr::GetScript: Could not load Script for Entry %d ScriptType %u.", entry, uint32(type)); - return temp; - } - } + SmartAIEventList GetScript(int32 entry, SmartScriptType type); - static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId) - { - SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), - [eventId](SmartScriptHolder& source) { return source.link == eventId; }); + static SmartScriptHolder& FindLinkedSourceEvent(SmartAIEventList& list, uint32 eventId); - if (itr != list.end()) - return *itr; - - static SmartScriptHolder SmartScriptHolderDummy; - return SmartScriptHolderDummy; - } - - static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link) - { - SmartAIEventList::iterator itr = std::find_if(list.begin(), list.end(), - [link](SmartScriptHolder& linked) { return linked.event_id == link && linked.GetEventType() == SMART_EVENT_LINK; }); - - if (itr != list.end()) - return *itr; - - static SmartScriptHolder SmartScriptHolderDummy; - return SmartScriptHolderDummy; - } + static SmartScriptHolder& FindLinkedEvent(SmartAIEventList& list, uint32 link); private: //event stores @@ -1619,127 +1578,19 @@ class TC_GAME_API SmartAIMgr bool IsEventValid(SmartScriptHolder& e); bool IsTargetValid(SmartScriptHolder const& e); - bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max) - { - if (max < min) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses min/max params wrong (%u/%u), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), min, max); - return false; - } - return true; - } - - /*inline bool IsPercentValid(SmartScriptHolder e, int32 pct) - { - if (pct < -100 || pct > 100) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u has invalid Percent set (%d), skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), pct); - return false; - } - return true; - }*/ - - bool NotNULL(SmartScriptHolder const& e, uint32 data) - { - if (!data) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u Parameter can not be NULL, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType()); - return false; - } - return true; - } - - bool IsCreatureValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sObjectMgr->GetCreatureTemplate(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Creature entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsQuestValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sObjectMgr->GetQuestTemplate(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Quest entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsGameObjectValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sObjectMgr->GetGameObjectTemplate(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent GameObject entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsSpellValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sSpellMgr->GetSpellInfo(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Spell entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsItemValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sItemStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Item entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sEmotesTextStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Text Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsEmoteValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sEmotesStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Emote entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsAreaTriggerValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sAreaTriggerStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent AreaTrigger entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsSoundValid(SmartScriptHolder const& e, uint32 entry) - { - if (!sSoundEntriesStore.LookupEntry(entry)) - { - TC_LOG_ERROR("sql.sql", "SmartAIMgr: Entry %d SourceType %u Event %u Action %u uses non-existent Sound entry %u, skipped.", e.entryOrGuid, e.GetScriptType(), e.event_id, e.GetActionType(), entry); - return false; - } - return true; - } - - bool IsTextValid(SmartScriptHolder const& e, uint32 id); + static bool IsMinMaxValid(SmartScriptHolder const& e, uint32 min, uint32 max); + + static bool NotNULL(SmartScriptHolder const& e, uint32 data); + static bool IsCreatureValid(SmartScriptHolder const& e, uint32 entry); + static bool IsQuestValid(SmartScriptHolder const& e, uint32 entry); + static bool IsGameObjectValid(SmartScriptHolder const& e, uint32 entry); + static bool IsSpellValid(SmartScriptHolder const& e, uint32 entry); + static bool IsItemValid(SmartScriptHolder const& e, uint32 entry); + static bool IsTextEmoteValid(SmartScriptHolder const& e, uint32 entry); + static bool IsEmoteValid(SmartScriptHolder const& e, uint32 entry); + static bool IsAreaTriggerValid(SmartScriptHolder const& e, uint32 entry); + static bool IsSoundValid(SmartScriptHolder const& e, uint32 entry); + static bool IsTextValid(SmartScriptHolder const& e, uint32 id); // Helpers void LoadHelperStores(); diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 14b04856ce1..b7aebd74f0c 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -19,11 +19,14 @@ #include "AccountMgr.h" #include "Config.h" #include "DatabaseEnv.h" +#include "Log.h" #include "ObjectAccessor.h" #include "Player.h" +#include "Realm.h" #include "ScriptMgr.h" -#include "Util.h" #include "SHA1.h" +#include "Util.h" +#include "World.h" #include "WorldSession.h" AccountMgr::AccountMgr() { } @@ -438,7 +441,7 @@ void AccountMgr::LoadRBAC() } uint32 permissionId = 0; - rbac::RBACPermission* permission = NULL; + rbac::RBACPermission* permission = nullptr; do { @@ -470,12 +473,12 @@ void AccountMgr::LoadRBAC() } uint8 secId = 255; - rbac::RBACPermissionContainer* permissions = NULL; + rbac::RBACPermissionContainer* permissions = nullptr; do { Field* field = result->Fetch(); uint32 newId = field[0].GetUInt32(); - if (secId != newId || permissions == NULL) + if (secId != newId || permissions == nullptr) { secId = newId; permissions = &_defaultPermissions[secId]; @@ -530,7 +533,7 @@ rbac::RBACPermission const* AccountMgr::GetRBACPermission(uint32 permissionId) c if (it != _permissions.end()) return it->second; - return NULL; + return nullptr; } bool AccountMgr::HasPermission(uint32 accountId, uint32 permissionId, uint32 realmId) diff --git a/src/server/game/Accounts/RBAC.cpp b/src/server/game/Accounts/RBAC.cpp index 951223a9257..bef26f25039 100644 --- a/src/server/game/Accounts/RBAC.cpp +++ b/src/server/game/Accounts/RBAC.cpp @@ -17,8 +17,9 @@ #include "RBAC.h" #include "AccountMgr.h" +#include "DatabaseEnv.h" #include "Log.h" -#include "QueryCallback.h" +#include <sstream> namespace rbac { diff --git a/src/server/game/Accounts/RBAC.h b/src/server/game/Accounts/RBAC.h index c7096ecd628..cb547216841 100644 --- a/src/server/game/Accounts/RBAC.h +++ b/src/server/game/Accounts/RBAC.h @@ -40,7 +40,8 @@ #ifndef _RBAC_H #define _RBAC_H -#include "DatabaseEnv.h" +#include "Define.h" +#include "DatabaseEnvFwd.h" #include <string> #include <set> #include <map> diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index bc8400f4a73..4e6ed998687 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -17,12 +17,9 @@ */ #include "AchievementMgr.h" -#include "ArenaTeam.h" #include "ArenaTeamMgr.h" #include "Battleground.h" -#include "CellImpl.h" #include "ChatTextBuilder.h" -#include "Common.h" #include "DatabaseEnv.h" #include "DBCEnums.h" #include "DisableMgr.h" @@ -32,16 +29,20 @@ #include "Guild.h" #include "GuildMgr.h" #include "InstanceScript.h" +#include "Item.h" #include "Language.h" +#include "Log.h" +#include "Mail.h" #include "Map.h" #include "MapManager.h" #include "ObjectMgr.h" #include "Player.h" #include "ReputationMgr.h" #include "ScriptMgr.h" +#include "SpellInfo.h" #include "SpellMgr.h" #include "World.h" -#include "WorldPacket.h" +#include "WorldSession.h" bool AchievementCriteriaData::IsValid(AchievementCriteriaEntry const* criteria) { @@ -323,7 +324,7 @@ bool AchievementCriteriaData::Meets(uint32 criteria_id, Player const* source, Un return !target->HealthAbovePct(health.percent); case ACHIEVEMENT_CRITERIA_DATA_TYPE_T_PLAYER_DEAD: if (target && !target->IsAlive()) - if (const Player* player = target->ToPlayer()) + if (Player const* player = target->ToPlayer()) if (player->GetDeathTimer() != 0) // flag set == must be same team, not set == different team return (player->GetTeam() == source->GetTeam()) == (player_dead.own_team_flag != 0); @@ -622,7 +623,7 @@ void AchievementMgr::LoadFromDB(PreparedQueryResult achievementResult, PreparedQ continue; } - if (criteria->StartTimer && time_t(date + criteria->StartTimer) < time(NULL)) + if (criteria->StartTimer && time_t(date + criteria->StartTimer) < time(nullptr)) continue; CriteriaProgress& progress = m_criteriaProgress[id]; @@ -682,7 +683,7 @@ void AchievementMgr::SendAchievementEarned(AchievementEntry const* achievement) WorldPacket data(SMSG_ACHIEVEMENT_EARNED, 8+4+8); data << GetPlayer()->GetPackGUID(); data << uint32(achievement->ID); - data.AppendPackedTime(time(NULL)); + data.AppendPackedTime(time(nullptr)); data << uint32(0); GetPlayer()->SendMessageToSetInRange(&data, sWorld->getFloatConfig(CONFIG_LISTEN_RANGE_SAY), true); } @@ -721,7 +722,7 @@ static const uint32 achievIdByArenaSlot[MAX_ARENA_SLOT] = { 1057, 1107, 1108 }; /** * this function will be called whenever the user might have done a criteria relevant action */ -void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) +void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= nullptr*/) { if (type >= ACHIEVEMENT_CRITERIA_TYPE_TOTAL) { @@ -903,7 +904,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui { uint32 counter = 0; - const RewardedQuestSet &rewQuests = GetPlayer()->getRewardedQuests(); + RewardedQuestSet const& rewQuests = GetPlayer()->getRewardedQuests(); for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr) { Quest const* quest = sObjectMgr->GetQuestTemplate(*itr); @@ -1325,7 +1326,7 @@ CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry c CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); if (iter == m_criteriaProgress.end()) - return NULL; + return nullptr; return &(iter->second); } @@ -1378,7 +1379,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, } progress->changed = true; - progress->date = time(NULL); // set the date to the latest update. + progress->date = time(nullptr); // set the date to the latest update. uint32 timeElapsed = 0; bool timedCompleted = false; @@ -1494,7 +1495,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; - ca.date = time(NULL); + ca.date = time(nullptr); ca.changed = true; if (achievement->Flags & (ACHIEVEMENT_FLAG_REALM_FIRST_REACH | ACHIEVEMENT_FLAG_REALM_FIRST_KILL)) @@ -1531,7 +1532,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) std::string text = reward->Text; LocaleConstant localeConstant = GetPlayer()->GetSession()->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) { if (AchievementRewardLocale const* loc = sAchievementMgr->GetAchievementRewardLocale(achievement)) { @@ -1545,7 +1546,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) SQLTransaction trans = CharacterDatabase.BeginTransaction(); - Item* item = reward->ItemID ? Item::CreateItem(reward->ItemID, 1, GetPlayer()) : NULL; + Item* item = reward->ItemID ? Item::CreateItem(reward->ItemID, 1, GetPlayer()) : nullptr; if (item) { // save new item before send @@ -1564,7 +1565,7 @@ void AchievementMgr::SendAllAchievementData() const { WorldPacket data(SMSG_ALL_ACHIEVEMENT_DATA, m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4); BuildAllDataPacket(&data); - GetPlayer()->GetSession()->SendPacket(&data); + GetPlayer()->SendDirectMessage(&data); } void AchievementMgr::SendRespondInspectAchievements(Player* player) const @@ -1572,7 +1573,7 @@ void AchievementMgr::SendRespondInspectAchievements(Player* player) const WorldPacket data(SMSG_RESPOND_INSPECT_ACHIEVEMENTS, 9+m_completedAchievements.size()*8+4+m_criteriaProgress.size()*38+4); data << GetPlayer()->GetPackGUID(); BuildAllDataPacket(&data); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } /** @@ -2510,7 +2511,7 @@ void AchievementGlobalMgr::LoadAchievementCriteriaData() continue; } - if (!GetCriteriaDataSet(criteria) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, entryId, NULL)) + if (!GetCriteriaDataSet(criteria) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_ACHIEVEMENT_CRITERIA, entryId, nullptr)) TC_LOG_ERROR("sql.sql", "Table `achievement_criteria_data` does not contain expected data for criteria (Entry: %u Type: %u) for achievement %u.", criteria->ID, criteria->Type, criteria->ReferredAchievement); } @@ -2542,7 +2543,7 @@ void AchievementGlobalMgr::LoadCompletedAchievements() Field* fields = result->Fetch(); uint16 achievementId = fields[0].GetUInt16(); - const AchievementEntry* achievement = sAchievementMgr->GetAchievement(achievementId); + AchievementEntry const* achievement = sAchievementMgr->GetAchievement(achievementId); if (!achievement) { // Remove non-existing achievements from all characters diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index e4b994fcb5f..2f0f30b2408 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -19,14 +19,13 @@ #ifndef __TRINITY_ACHIEVEMENTMGR_H #define __TRINITY_ACHIEVEMENTMGR_H -#include <map> -#include <string> - -#include "Common.h" -#include "DatabaseEnv.h" +#include "DatabaseEnvFwd.h" #include "DBCEnums.h" #include "DBCStores.h" #include "ObjectGuid.h" +#include <string> +#include <unordered_map> +#include <vector> class Unit; class Player; @@ -282,7 +281,7 @@ class TC_GAME_API AchievementMgr void LoadFromDB(PreparedQueryResult achievementResult, PreparedQueryResult criteriaResult); void SaveToDB(SQLTransaction& trans); void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = nullptr); void CompletedAchievement(AchievementEntry const* entry); void CheckAllAchievementCriteria(); void SendAllAchievementData() const; @@ -342,31 +341,31 @@ class TC_GAME_API AchievementGlobalMgr AchievementCriteriaEntryList const* GetAchievementCriteriaByAchievement(uint32 id) const { AchievementCriteriaListByAchievement::const_iterator itr = m_AchievementCriteriaListByAchievement.find(id); - return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : NULL; + return itr != m_AchievementCriteriaListByAchievement.end() ? &itr->second : nullptr; } AchievementEntryList const* GetAchievementByReferencedId(uint32 id) const { AchievementListByReferencedId::const_iterator itr = m_AchievementListByReferencedId.find(id); - return itr != m_AchievementListByReferencedId.end() ? &itr->second : NULL; + return itr != m_AchievementListByReferencedId.end() ? &itr->second : nullptr; } AchievementReward const* GetAchievementReward(AchievementEntry const* achievement) const { AchievementRewards::const_iterator iter = m_achievementRewards.find(achievement->ID); - return iter != m_achievementRewards.end() ? &iter->second : NULL; + return iter != m_achievementRewards.end() ? &iter->second : nullptr; } AchievementRewardLocale const* GetAchievementRewardLocale(AchievementEntry const* achievement) const { AchievementRewardLocales::const_iterator iter = m_achievementRewardLocales.find(achievement->ID); - return iter != m_achievementRewardLocales.end() ? &iter->second : NULL; + return iter != m_achievementRewardLocales.end() ? &iter->second : nullptr; } AchievementCriteriaDataSet const* GetCriteriaDataSet(AchievementCriteriaEntry const* achievementCriteria) const { AchievementCriteriaDataMap::const_iterator iter = m_criteriaDataMap.find(achievementCriteria->ID); - return iter != m_criteriaDataMap.end() ? &iter->second : NULL; + return iter != m_criteriaDataMap.end() ? &iter->second : nullptr; } bool IsRealmCompleted(AchievementEntry const* achievement) const; diff --git a/src/server/game/Addons/AddonMgr.cpp b/src/server/game/Addons/AddonMgr.cpp index 7371cfb5f4f..075daabce78 100644 --- a/src/server/game/Addons/AddonMgr.cpp +++ b/src/server/game/Addons/AddonMgr.cpp @@ -119,7 +119,7 @@ SavedAddon const* GetAddonInfo(const std::string& name) return &addon; } - return NULL; + return nullptr; } BannedAddonList const* GetBannedAddons() diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index a6ff7f558a7..1dabff8a76e 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -16,23 +16,27 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "AuctionHouseMgr.h" +#include "AuctionHouseBot.h" +#include "AccountMgr.h" +#include "Bag.h" #include "Common.h" -#include "ObjectMgr.h" -#include "Player.h" -#include "World.h" -#include "WorldPacket.h" -#include "WorldSession.h" +#include "CharacterCache.h" #include "DatabaseEnv.h" #include "DBCStores.h" -#include "ScriptMgr.h" -#include "AccountMgr.h" -#include "AuctionHouseMgr.h" -#include "AuctionHouseBot.h" +#include "GameTime.h" #include "Item.h" #include "Language.h" #include "Log.h" -#include "CharacterCache.h" -#include "GameTime.h" +#include "Mail.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Realm.h" +#include "ScriptMgr.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" enum eAuctionHouse { @@ -437,7 +441,7 @@ bool AuctionHouseMgr::PendingAuctionAdd(Player* player, AuctionEntry* aEntry, It return true; } -uint32 AuctionHouseMgr::PendingAuctionCount(const Player* player) const +uint32 AuctionHouseMgr::PendingAuctionCount(Player const* player) const { auto const itr = pendingAuctionMap.find(player->GetGUID()); if (itr != pendingAuctionMap.end()) @@ -523,7 +527,7 @@ void AuctionHouseMgr::UpdatePendingAuctions() { AuctionEntry* AH = (*AHitr); ++AHitr; - AH->expire_time = time(NULL); + AH->expire_time = time(nullptr); AH->DeleteFromDB(trans); AH->SaveToDB(trans); } @@ -754,7 +758,7 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player continue; // local name - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (ItemLocale const* il = sObjectMgr->GetItemLocale(proto->ItemId)) ObjectMgr::GetLocaleString(il->Name, localeConstant, name); @@ -773,13 +777,13 @@ void AuctionHouseObject::BuildListAuctionItems(WorldPacket& data, Player* player if (propRefID < 0) { - const ItemRandomSuffixEntry* itemRandSuffix = sItemRandomSuffixStore.LookupEntry(-propRefID); + ItemRandomSuffixEntry const* itemRandSuffix = sItemRandomSuffixStore.LookupEntry(-propRefID); if (itemRandSuffix) suffix = itemRandSuffix->nameSuffix; } else { - const ItemRandomPropertiesEntry* itemRandProp = sItemRandomPropertiesStore.LookupEntry(propRefID); + ItemRandomPropertiesEntry const* itemRandProp = sItemRandomPropertiesStore.LookupEntry(propRefID); if (itemRandProp) suffix = itemRandProp->nameSuffix; } @@ -838,7 +842,7 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket& data, Item* sourceItem) const data << uint32(bid ? GetAuctionOutBid() : 0); // Minimal outbid data << uint32(buyout); // Auction->buyout - data << uint32((expire_time - time(NULL)) * IN_MILLISECONDS); // time left + data << uint32((expire_time - time(nullptr)) * IN_MILLISECONDS); // time left data << uint64(bidder); // auction->bidder current data << uint32(bid); // current bid return true; diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index fb3f11052bc..2fad4264d15 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -19,14 +19,17 @@ #ifndef _AUCTION_HOUSE_MGR_H #define _AUCTION_HOUSE_MGR_H -#include "Common.h" -#include "DatabaseEnv.h" -#include "DBCStructure.h" +#include "Define.h" +#include "DatabaseEnvFwd.h" +#include "ObjectGuid.h" +#include <map> #include <set> +#include <unordered_map> class Item; class Player; class WorldPacket; +struct AuctionHouseEntry; #define MIN_AUCTION_TIME (12*HOUR) #define MAX_AUCTION_ITEMS 160 @@ -121,7 +124,7 @@ class TC_GAME_API AuctionHouseObject AuctionEntry* GetAuction(uint32 id) const { AuctionEntryMap::const_iterator itr = AuctionsMap.find(id); - return itr != AuctionsMap.end() ? itr->second : NULL; + return itr != AuctionsMap.end() ? itr->second : nullptr; } void AddAuction(AuctionEntry* auction); @@ -169,7 +172,7 @@ class TC_GAME_API AuctionHouseMgr if (itr != mAitems.end()) return itr->second; - return NULL; + return nullptr; } //auction messages @@ -192,7 +195,7 @@ class TC_GAME_API AuctionHouseMgr void AddAItem(Item* it); bool RemoveAItem(ObjectGuid::LowType id, bool deleteItem = false, SQLTransaction* trans = nullptr); bool PendingAuctionAdd(Player* player, AuctionEntry* aEntry, Item* item); - uint32 PendingAuctionCount(const Player* player) const; + uint32 PendingAuctionCount(Player const* player) const; void PendingAuctionProcess(Player* player); void UpdatePendingAuctions(); void Update(); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp index c7724fa144a..4b433930e93 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.cpp @@ -15,17 +15,18 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Containers.h" -#include "Log.h" -#include "Item.h" -#include "World.h" -#include "Config.h" -#include "AccountMgr.h" -#include "AuctionHouseMgr.h" #include "AuctionHouseBot.h" +#include "AccountMgr.h" #include "AuctionHouseBotBuyer.h" #include "AuctionHouseBotSeller.h" +#include "AuctionHouseMgr.h" +#include "Config.h" +#include "Containers.h" +#include "DatabaseEnv.h" #include "GameTime.h" +#include "Item.h" +#include "Log.h" +#include "World.h" AuctionBotConfig* AuctionBotConfig::instance() { diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouseBot/AuctionHouseBot.h index 73cfd764946..162647c58bc 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBot.h +++ b/src/server/game/AuctionHouseBot/AuctionHouseBot.h @@ -19,6 +19,9 @@ #define AUCTION_HOUSE_BOT_H #include "Define.h" +#include "SharedDefines.h" +#include <string> +#include <vector> class AuctionBotSeller; class AuctionBotBuyer; @@ -211,8 +214,8 @@ public: static AuctionBotConfig* instance(); bool Initialize(); - const std::string& GetAHBotIncludes() const { return _AHBotIncludes; } - const std::string& GetAHBotExcludes() const { return _AHBotExcludes; } + std::string const& GetAHBotIncludes() const { return _AHBotIncludes; } + std::string const& GetAHBotExcludes() const { return _AHBotExcludes; } uint32 GetConfig(AuctionBotConfigUInt32Values index) const { return _configUint32Values[index]; } bool GetConfig(AuctionBotConfigBoolValues index) const { return _configBoolValues[index]; } diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp index 8396ab94622..4d7ad22eef5 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp @@ -15,10 +15,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Log.h" +#include "AuctionHouseBotBuyer.h" +#include "DatabaseEnv.h" #include "Item.h" #include "ItemTemplate.h" -#include "AuctionHouseBotBuyer.h" +#include "Log.h" +#include "Random.h" AuctionBotBuyer::AuctionBotBuyer() : _checkInterval(20 * MINUTE) { @@ -156,7 +158,7 @@ uint32 AuctionBotBuyer::GetItemInformation(BuyerConfiguration& config) } // ahInfo can be NULL -bool AuctionBotBuyer::RollBuyChance(const BuyerItemInfo* ahInfo, const Item* item, const AuctionEntry* auction, uint32 /*bidPrice*/) +bool AuctionBotBuyer::RollBuyChance(BuyerItemInfo const* ahInfo, Item const* item, AuctionEntry const* auction, uint32 /*bidPrice*/) { if (!auction->buyout) return false; @@ -195,7 +197,7 @@ bool AuctionBotBuyer::RollBuyChance(const BuyerItemInfo* ahInfo, const Item* ite } // ahInfo can be NULL -bool AuctionBotBuyer::RollBidChance(const BuyerItemInfo* ahInfo, const Item* item, const AuctionEntry* auction, uint32 bidPrice) +bool AuctionBotBuyer::RollBidChance(BuyerItemInfo const* ahInfo, Item const* item, AuctionEntry const* auction, uint32 bidPrice) { float itemBidPrice = float(bidPrice / item->GetCount()); float itemPrice = float(item->GetTemplate()->SellPrice ? item->GetTemplate()->SellPrice : GetVendorPrice(item->GetTemplate()->Quality)); @@ -306,7 +308,7 @@ void AuctionBotBuyer::BuyAndBidItems(BuyerConfiguration& config) bidPrice = auction->startbid; } - const BuyerItemInfo* ahInfo = nullptr; + BuyerItemInfo const* ahInfo = nullptr; BuyerItemInfoMap::const_iterator sameItemItr = config.SameItemInfo.find(item->GetEntry()); if (sameItemItr != config.SameItemInfo.end()) ahInfo = &sameItemItr->second; @@ -392,7 +394,7 @@ void AuctionBotBuyer::BuyEntry(AuctionEntry* auction, AuctionHouseObject* auctio // Send mail to previous bidder if any if (auction->bidder && !sAuctionBotConfig->IsBotChar(auction->bidder)) - sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, NULL, trans); + sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, nullptr, trans); // Set bot as bidder and set new bid amount auction->bidder = sAuctionBotConfig->GetRandCharExclude(auction->owner); @@ -423,7 +425,7 @@ void AuctionBotBuyer::PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice) // Send mail to previous bidder if any if (auction->bidder && !sAuctionBotConfig->IsBotChar(auction->bidder)) - sAuctionMgr->SendAuctionOutbiddedMail(auction, bidPrice, NULL, trans); + sAuctionMgr->SendAuctionOutbiddedMail(auction, bidPrice, nullptr, trans); // Set bot as bidder and set new bid amount auction->bidder = sAuctionBotConfig->GetRandCharExclude(auction->owner); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h index ba4326ffabf..1770451f323 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.h @@ -86,8 +86,8 @@ private: void LoadBuyerValues(BuyerConfiguration& config); // ahInfo can be NULL - bool RollBuyChance(const BuyerItemInfo* ahInfo, const Item* item, const AuctionEntry* auction, uint32 bidPrice); - bool RollBidChance(const BuyerItemInfo* ahInfo, const Item* item, const AuctionEntry* auction, uint32 bidPrice); + bool RollBuyChance(BuyerItemInfo const* ahInfo, Item const* item, AuctionEntry const* auction, uint32 bidPrice); + bool RollBidChance(BuyerItemInfo const* ahInfo, Item const* item, AuctionEntry const* auction, uint32 bidPrice); void PlaceBidToEntry(AuctionEntry* auction, uint32 bidPrice); void BuyEntry(AuctionEntry* auction, AuctionHouseObject* auctionHouse); void PrepareListOfEntry(BuyerConfiguration& config); diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp index 6fd11aa6406..7c1ba67d547 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -15,12 +15,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Log.h" +#include "AuctionHouseBotSeller.h" +#include "AuctionHouseMgr.h" #include "Containers.h" +#include "DatabaseEnv.h" #include "DBCStores.h" +#include "Item.h" +#include "Log.h" #include "ObjectMgr.h" -#include "AuctionHouseMgr.h" -#include "AuctionHouseBotSeller.h" +#include "Random.h" +#include <sstream> AuctionBotSeller::AuctionBotSeller() { @@ -62,13 +66,9 @@ bool AuctionBotSeller::Initialize() TC_LOG_DEBUG("ahbot", "Loading npc vendor items for filter.."); CreatureTemplateContainer const* creatures = sObjectMgr->GetCreatureTemplates(); for (CreatureTemplateContainer::const_iterator it = creatures->begin(); it != creatures->end(); ++it) - { if (VendorItemData const* data = sObjectMgr->GetNpcVendorItemList(it->first)) - { - for (VendorItemList::const_iterator it2 = data->m_items.begin(); it2 != data->m_items.end(); ++it2) - npcItems.insert((*it2)->item); - } - } + for (VendorItem const& it2 : data->m_items) + npcItems.insert(it2.item); TC_LOG_DEBUG("ahbot", "Npc vendor filter has %u items", (uint32)npcItems.size()); @@ -108,7 +108,6 @@ bool AuctionBotSeller::Initialize() for (uint32 itemId = 0; itemId < sItemStore.GetNumRows(); ++itemId) { ItemTemplate const* prototype = sObjectMgr->GetItemTemplate(itemId); - if (!prototype) continue; @@ -890,7 +889,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config) // Update the just created item so that if it needs random properties it has them. // Ex: Notched Shortsword of Stamina will only generate as a Notched Shortsword without this. - if (int32 randomPropertyId = Item::GenerateItemRandomPropertyId(itemId)) + if (int32 randomPropertyId = GenerateItemRandomPropertyId(itemId)) item->SetItemRandomProperties(randomPropertyId); uint32 buyoutPrice; @@ -927,7 +926,7 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config) auctionEntry->bid = 0; auctionEntry->deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, etime, item, stackCount); auctionEntry->auctionHouseEntry = ahEntry; - auctionEntry->expire_time = time(NULL) + urand(config.GetMinTime(), config.GetMaxTime()) * HOUR; + auctionEntry->expire_time = time(nullptr) + urand(config.GetMinTime(), config.GetMaxTime()) * HOUR; item->SaveToDB(trans); sAuctionMgr->AddAItem(item); diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index 2c75d75f0b4..27e83185e27 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -20,15 +20,18 @@ #include "Battleground.h" #include "CellImpl.h" #include "CreatureTextMgr.h" +#include "DBCStores.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "GroupMgr.h" +#include "Log.h" #include "Map.h" #include "MapManager.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "WorldPacket.h" +#include <G3D/g3dmath.h> Battlefield::Battlefield() { @@ -563,7 +566,7 @@ BfGraveyard* Battlefield::GetGraveyardById(uint32 id) const return nullptr; } -WorldSafeLocsEntry const* Battlefield::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* Battlefield::GetClosestGraveyard(Player* player) { BfGraveyard* closestGY = nullptr; float maxdist = -1; @@ -738,7 +741,7 @@ void BfGraveyard::RelocateDeadPlayers() player->TeleportTo(player->GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation()); else { - closestGrave = m_Bf->GetClosestGraveYard(player); + closestGrave = m_Bf->GetClosestGraveyard(player); if (closestGrave) player->TeleportTo(player->GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation()); } @@ -794,7 +797,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, Position const& pos) } // Method for spawning gameobject on map -GameObject* Battlefield::SpawnGameObject(uint32 entry, Position const& pos, G3D::Quat const& rot) +GameObject* Battlefield::SpawnGameObject(uint32 entry, Position const& pos, QuaternionData const& rot) { // Get map object Map* map = sMapMgr->CreateBaseMap(m_MapId); diff --git a/src/server/game/Battlefield/Battlefield.h b/src/server/game/Battlefield/Battlefield.h index 2889a53a3be..0ede10657e6 100644 --- a/src/server/game/Battlefield/Battlefield.h +++ b/src/server/game/Battlefield/Battlefield.h @@ -18,8 +18,10 @@ #ifndef BATTLEFIELD_H_ #define BATTLEFIELD_H_ +#include "Position.h" #include "SharedDefines.h" #include "ZoneScript.h" +#include <map> enum BattlefieldTypes { @@ -55,14 +57,17 @@ enum BattlefieldTimers }; // some class predefs -class Player; -class GameObject; -class WorldPacket; -class Creature; -class Unit; - class Battlefield; class BfGraveyard; +class Creature; +class GameObject; +class Group; +class Map; +class Player; +class Unit; +class WorldPacket; +struct QuaternionData; +struct WorldSafeLocsEntry; typedef std::vector<BfGraveyard*> GraveyardVect; typedef std::map<ObjectGuid, time_t> PlayerTimerMap; @@ -272,7 +277,7 @@ class TC_GAME_API Battlefield : public ZoneScript // Graveyard methods // Find which graveyard the player must be teleported to to be resurrected by spiritguide - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player); virtual void AddPlayerToResurrectQueue(ObjectGuid npc_guid, ObjectGuid player_guid); void RemovePlayerFromResurrectQueue(ObjectGuid player_guid); @@ -281,7 +286,7 @@ class TC_GAME_API Battlefield : public ZoneScript // Misc methods Creature* SpawnCreature(uint32 entry, Position const& pos); - GameObject* SpawnGameObject(uint32 entry, Position const& pos, G3D::Quat const& rot); + GameObject* SpawnGameObject(uint32 entry, Position const& pos, QuaternionData const& rot); Creature* GetCreature(ObjectGuid guid); GameObject* GetGameObject(ObjectGuid guid); @@ -405,7 +410,7 @@ class TC_GAME_API Battlefield : public ZoneScript Battlefield::BfCapturePointMap::const_iterator itr = m_capturePoints.find(lowguid); if (itr != m_capturePoints.end()) return itr->second; - return NULL; + return nullptr; } void RegisterZone(uint32 zoneid); diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 5130dafa254..fde19810bfd 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -17,6 +17,7 @@ #include "BattlefieldMgr.h" #include "BattlefieldWG.h" +#include "Log.h" #include "Player.h" BattlefieldMgr::BattlefieldMgr() diff --git a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp index edb1753b01f..bd5f47f67c9 100644 --- a/src/server/game/Battlefield/Zones/BattlefieldWG.cpp +++ b/src/server/game/Battlefield/Zones/BattlefieldWG.cpp @@ -21,14 +21,19 @@ #include "BattlefieldWG.h" #include "AchievementMgr.h" -#include "CreatureTextMgr.h" #include "Battleground.h" +#include "CreatureTextMgr.h" +#include "GameObject.h" +#include "Log.h" #include "MapManager.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" +#include "Random.h" #include "SpellAuras.h" #include "TemporarySummon.h" +#include "World.h" #include "WorldSession.h" struct BfWGCoordGY @@ -40,7 +45,7 @@ struct BfWGCoordGY }; // 7 in sql, 7 in header -BfWGCoordGY const WGGraveYard[BATTLEFIELD_WG_GRAVEYARD_MAX] = +BfWGCoordGY const WGGraveyard[BATTLEFIELD_WG_GRAVEYARD_MAX] = { { { 5104.750f, 2300.940f, 368.579f, 0.733038f }, 1329, BATTLEFIELD_WG_GOSSIPTEXT_GY_NE, TEAM_NEUTRAL }, { { 5099.120f, 3466.036f, 368.484f, 5.317802f }, 1330, BATTLEFIELD_WG_GOSSIPTEXT_GY_NW, TEAM_NEUTRAL }, @@ -57,7 +62,7 @@ uint32 const WintergraspFaction[] = { FACTION_ALLIANCE_GENERIC_WG, FACTION_ Position const WintergraspStalkerPos = { 4948.985f, 2937.789f, 550.5172f, 1.815142f }; Position const WintergraspRelicPos = { 5440.379f, 2840.493f, 430.2816f, -1.832595f }; -G3D::Quat const WintergraspRelicRot = { 0.f, 0.f, -0.7933531f, 0.6087617f }; +QuaternionData const WintergraspRelicRot = { 0.f, 0.f, -0.7933531f, 0.6087617f }; uint8 const WG_MAX_OBJ = 32; uint8 const WG_MAX_TURRET = 15; @@ -74,7 +79,7 @@ struct WintergraspBuildingSpawnData uint32 entry; uint32 WorldState; Position pos; - G3D::Quat rot; + QuaternionData rot; WintergraspGameObjectBuildingType type; }; @@ -177,7 +182,7 @@ struct WintergraspObjectPositionData struct WintergraspGameObjectData { Position Pos; - G3D::Quat Rot; + QuaternionData Rot; uint32 HordeEntry; uint32 AllianceEntry; }; @@ -431,7 +436,7 @@ bool BattlefieldWG::SetupBattlefield() m_saveTimer = 60000; - // Init GraveYards + // Init Graveyards SetGraveyardNumber(BATTLEFIELD_WG_GRAVEYARD_MAX); // Load from db @@ -463,12 +468,12 @@ bool BattlefieldWG::SetupBattlefield() BfGraveyardWG* graveyard = new BfGraveyardWG(this); // When between games, the graveyard is controlled by the defending team - if (WGGraveYard[i].StartControl == TEAM_NEUTRAL) - graveyard->Initialize(m_DefenderTeam, WGGraveYard[i].GraveyardID); + if (WGGraveyard[i].StartControl == TEAM_NEUTRAL) + graveyard->Initialize(m_DefenderTeam, WGGraveyard[i].GraveyardID); else - graveyard->Initialize(WGGraveYard[i].StartControl, WGGraveYard[i].GraveyardID); + graveyard->Initialize(WGGraveyard[i].StartControl, WGGraveyard[i].GraveyardID); - graveyard->SetTextId(WGGraveYard[i].TextID); + graveyard->SetTextId(WGGraveyard[i].TextID); m_GraveyardList[i] = graveyard; } diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index fb4f6b965ca..b9ec40c7f13 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -19,11 +19,45 @@ #include "ArenaScore.h" #include "ArenaTeamMgr.h" #include "Language.h" +#include "Log.h" #include "ObjectAccessor.h" #include "Player.h" #include "World.h" #include "WorldSession.h" +void ArenaScore::AppendToPacket(WorldPacket& data) +{ + data << uint64(PlayerGuid); + + data << uint32(KillingBlows); + data << uint8(TeamId); + data << uint32(DamageDone); + data << uint32(HealingDone); + + BuildObjectivesBlock(data); +} + +void ArenaScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(0); // Objectives Count +} + +void ArenaTeamScore::BuildRatingInfoBlock(WorldPacket& data) +{ + uint32 ratingLost = std::abs(std::min(RatingChange, 0)); + uint32 ratingWon = std::max(RatingChange, 0); + + // should be old rating, new rating, and client will calculate rating change itself + data << uint32(ratingLost); + data << uint32(ratingWon); + data << uint32(MatchmakerRating); +} + +void ArenaTeamScore::BuildTeamInfoBlock(WorldPacket& data) +{ + data << TeamName; +} + Arena::Arena() { StartDelayTimes[BG_STARTING_EVENT_FIRST] = BG_START_DELAY_1M; @@ -144,17 +178,17 @@ void Arena::EndBattleground(uint32 winner) // In case of arena draw, follow this logic: // winnerArenaTeam => ALLIANCE, loserArenaTeam => HORDE - ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner == 0 ? ALLIANCE : winner)); - ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner == 0 ? HORDE : GetOtherTeam(winner))); + ArenaTeam* winnerArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner == 0 ? uint32(ALLIANCE) : winner)); + ArenaTeam* loserArenaTeam = sArenaTeamMgr->GetArenaTeamById(GetArenaTeamIdForTeam(winner == 0 ? uint32(HORDE) : GetOtherTeam(winner))); if (winnerArenaTeam && loserArenaTeam && winnerArenaTeam != loserArenaTeam) { // In case of arena draw, follow this logic: // winnerMatchmakerRating => ALLIANCE, loserMatchmakerRating => HORDE loserTeamRating = loserArenaTeam->GetRating(); - loserMatchmakerRating = GetArenaMatchmakerRating(winner == 0 ? HORDE : GetOtherTeam(winner)); + loserMatchmakerRating = GetArenaMatchmakerRating(winner == 0 ? uint32(HORDE) : GetOtherTeam(winner)); winnerTeamRating = winnerArenaTeam->GetRating(); - winnerMatchmakerRating = GetArenaMatchmakerRating(winner == 0 ? ALLIANCE : winner); + winnerMatchmakerRating = GetArenaMatchmakerRating(winner == 0 ? uint32(ALLIANCE) : winner); if (winner != 0) { diff --git a/src/server/game/Battlegrounds/ArenaScore.h b/src/server/game/Battlegrounds/ArenaScore.h index a2914337322..f4ab82034cf 100644 --- a/src/server/game/Battlegrounds/ArenaScore.h +++ b/src/server/game/Battlegrounds/ArenaScore.h @@ -19,7 +19,7 @@ #define TRINITY_ARENA_SCORE_H #include "BattlegroundScore.h" -#include "SharedDefines.h" +#include <sstream> struct TC_GAME_API ArenaScore : public BattlegroundScore { @@ -28,22 +28,8 @@ struct TC_GAME_API ArenaScore : public BattlegroundScore protected: ArenaScore(ObjectGuid playerGuid, uint32 team) : BattlegroundScore(playerGuid), TeamId(team == ALLIANCE ? BG_TEAM_ALLIANCE : BG_TEAM_HORDE) { } - void AppendToPacket(WorldPacket& data) final override - { - data << uint64(PlayerGuid); - - data << uint32(KillingBlows); - data << uint8(TeamId); - data << uint32(DamageDone); - data << uint32(HealingDone); - - BuildObjectivesBlock(data); - } - - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(0); // Objectives Count - } + void AppendToPacket(WorldPacket& data) final override; + void BuildObjectivesBlock(WorldPacket& data) final override; // For Logging purpose std::string ToString() const override @@ -80,21 +66,8 @@ struct TC_GAME_API ArenaTeamScore TeamName = teamName; } - void BuildRatingInfoBlock(WorldPacket& data) - { - uint32 ratingLost = std::abs(std::min(RatingChange, 0)); - uint32 ratingWon = std::max(RatingChange, 0); - - // should be old rating, new rating, and client will calculate rating change itself - data << uint32(ratingLost); - data << uint32(ratingWon); - data << uint32(MatchmakerRating); - } - - void BuildTeamInfoBlock(WorldPacket& data) - { - data << TeamName; - } + void BuildRatingInfoBlock(WorldPacket& data); + void BuildTeamInfoBlock(WorldPacket& data); int32 RatingChange; uint32 MatchmakerRating; diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 1c5a2dac3eb..cda870fdba8 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -16,16 +16,19 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "ArenaTeam.h" +#include "ArenaTeamMgr.h" +#include "CharacterCache.h" +#include "DatabaseEnv.h" +#include "Group.h" +#include "Log.h" +#include "Map.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" -#include "WorldPacket.h" -#include "ArenaTeam.h" #include "World.h" -#include "Group.h" -#include "ArenaTeamMgr.h" +#include "WorldPacket.h" #include "WorldSession.h" -#include "Opcodes.h" -#include "CharacterCache.h" ArenaTeam::ArenaTeam() : TeamId(0), Type(0), TeamName(), CaptainGuid(), BackgroundColor(0), EmblemStyle(0), EmblemColor(0), @@ -399,7 +402,7 @@ void ArenaTeam::Disband() void ArenaTeam::Roster(WorldSession* session) { - Player* player = NULL; + Player* player = nullptr; uint8 unk308 = 0; @@ -516,7 +519,7 @@ void ArenaTeam::BroadcastPacket(WorldPacket* packet) { for (MemberList::const_iterator itr = Members.begin(); itr != Members.end(); ++itr) if (Player* player = ObjectAccessor::FindConnectedPlayer(itr->Guid)) - player->GetSession()->SendPacket(packet); + player->SendDirectMessage(packet); } void ArenaTeam::BroadcastEvent(ArenaTeamEvents event, ObjectGuid guid, uint8 strCount, std::string const& str1, std::string const& str2, std::string const& str3) @@ -811,7 +814,7 @@ void ArenaTeam::OfflineMemberLost(ObjectGuid guid, uint32 againstMatchmakerRatin { // update personal rating int32 mod = GetRatingMod(itr->PersonalRating, againstMatchmakerRating, false); - itr->ModifyPersonalRating(NULL, mod, GetType()); + itr->ModifyPersonalRating(nullptr, mod, GetType()); // update matchmaker rating itr->ModifyMatchmakerRating(MatchmakerRatingChange, GetSlot()); @@ -960,7 +963,7 @@ ArenaTeamMember* ArenaTeam::GetMember(const std::string& name) if (itr->Name == name) return &(*itr); - return NULL; + return nullptr; } ArenaTeamMember* ArenaTeam::GetMember(ObjectGuid guid) @@ -969,5 +972,5 @@ ArenaTeamMember* ArenaTeam::GetMember(ObjectGuid guid) if (itr->Guid == guid) return &(*itr); - return NULL; + return nullptr; } diff --git a/src/server/game/Battlegrounds/ArenaTeam.h b/src/server/game/Battlegrounds/ArenaTeam.h index c88afc8c65e..38f2b7daaaa 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.h +++ b/src/server/game/Battlegrounds/ArenaTeam.h @@ -131,7 +131,7 @@ class TC_GAME_API ArenaTeam static uint8 GetSlotByType(uint32 type); ObjectGuid GetCaptain() const { return CaptainGuid; } std::string const& GetName() const { return TeamName; } - const ArenaTeamStats& GetStats() const { return Stats; } + ArenaTeamStats const& GetStats() const { return Stats; } uint32 GetRating() const { return Stats.Rating; } uint32 GetAverageMMR(Group* group) const; diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index 3e991c1a1b7..56749e0bf4f 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -48,7 +48,7 @@ ArenaTeam* ArenaTeamMgr::GetArenaTeamById(uint32 arenaTeamId) const if (itr != ArenaTeamStore.end()) return itr->second; - return NULL; + return nullptr; } ArenaTeam* ArenaTeamMgr::GetArenaTeamByName(const std::string& arenaTeamName) const @@ -62,7 +62,7 @@ ArenaTeam* ArenaTeamMgr::GetArenaTeamByName(const std::string& arenaTeamName) co if (search == teamName) return itr->second; } - return NULL; + return nullptr; } ArenaTeam* ArenaTeamMgr::GetArenaTeamByCaptain(ObjectGuid guid) const @@ -71,7 +71,7 @@ ArenaTeam* ArenaTeamMgr::GetArenaTeamByCaptain(ObjectGuid guid) const if (itr->second->GetCaptain() == guid) return itr->second; - return NULL; + return nullptr; } void ArenaTeamMgr::AddArenaTeam(ArenaTeam* arenaTeam) @@ -127,7 +127,7 @@ void ArenaTeamMgr::LoadArenaTeams() if (!newArenaTeam->LoadArenaTeamFromDB(result) || !newArenaTeam->LoadMembersFromDB(result2)) { - newArenaTeam->Disband(NULL); + newArenaTeam->Disband(nullptr); delete newArenaTeam; continue; } diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.h b/src/server/game/Battlegrounds/ArenaTeamMgr.h index b5769c0c536..1663ee54711 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.h +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.h @@ -19,6 +19,7 @@ #define _ARENATEAMMGR_H #include "ArenaTeam.h" +#include <unordered_map> class TC_GAME_API ArenaTeamMgr { diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 6a2275ed415..41591c419e9 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -16,32 +16,50 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ArenaScore.h" #include "Battleground.h" +#include "ArenaScore.h" #include "BattlegroundMgr.h" #include "BattlegroundScore.h" +#include "Chat.h" #include "Creature.h" #include "CreatureTextMgr.h" -#include "Chat.h" +#include "DatabaseEnv.h" #include "Formulas.h" +#include "GameTime.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "Object.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" #include "ReputationMgr.h" #include "SpellAuras.h" +#include "TemporarySummon.h" +#include "Transport.h" #include "Util.h" #include "WorldPacket.h" -#include "Transport.h" -#include "GameTime.h" +#include <cstdarg> + +void BattlegroundScore::AppendToPacket(WorldPacket& data) +{ + data << uint64(PlayerGuid); + + data << uint32(KillingBlows); + data << uint32(HonorableKills); + data << uint32(Deaths); + data << uint32(BonusHonor); + data << uint32(DamageDone); + data << uint32(HealingDone); + + BuildObjectivesBlock(data); +} namespace Trinity { class BattlegroundChatBuilder { public: - BattlegroundChatBuilder(ChatMsg msgtype, uint32 textId, Player const* source, va_list* args = NULL) + BattlegroundChatBuilder(ChatMsg msgtype, uint32 textId, Player const* source, va_list* args = nullptr) : _msgtype(msgtype), _textId(textId), _source(source), _args(args) { } void operator()(WorldPacket& data, LocaleConstant loc_idx) @@ -144,7 +162,7 @@ Battleground::Battleground() m_MinPlayers = 0; m_MapId = 0; - m_Map = NULL; + m_Map = nullptr; m_StartMaxDist = 0.0f; ScriptId = 0; @@ -154,8 +172,8 @@ Battleground::Battleground() m_ArenaTeamMMR[TEAM_ALLIANCE] = 0; m_ArenaTeamMMR[TEAM_HORDE] = 0; - m_BgRaids[TEAM_ALLIANCE] = NULL; - m_BgRaids[TEAM_HORDE] = NULL; + m_BgRaids[TEAM_ALLIANCE] = nullptr; + m_BgRaids[TEAM_HORDE] = nullptr; m_PlayersCount[TEAM_ALLIANCE] = 0; m_PlayersCount[TEAM_HORDE] = 0; @@ -197,8 +215,8 @@ Battleground::~Battleground() { m_Map->SetUnload(); //unlink to prevent crash, always unlink all pointer reference before destruction - m_Map->SetBG(NULL); - m_Map = NULL; + m_Map->SetBG(nullptr); + m_Map = nullptr; } // remove from bg free slot queue RemoveFromBGFreeSlotQueue(); @@ -220,7 +238,7 @@ void Battleground::Update(uint32 diff) // [[ but if you use battleground object again (more battles possible to be played on 1 instance) // then this condition should be removed and code: // if (!GetInvitedCount(HORDE) && !GetInvitedCount(ALLIANCE)) - // this->AddToFreeBGObjectsQueue(); // not yet implemented + // AddToFreeBGObjectsQueue(); // not yet implemented // should be used instead of current // ]] // Battleground Template instance cannot be updated, because it would be deleted @@ -342,7 +360,7 @@ inline void Battleground::_ProcessResurrect(uint32 diff) { for (std::map<ObjectGuid, GuidVector>::iterator itr = m_ReviveQueue.begin(); itr != m_ReviveQueue.end(); ++itr) { - Creature* sh = NULL; + Creature* sh = nullptr; for (GuidVector::const_iterator itr2 = (itr->second).begin(); itr2 != (itr->second).end(); ++itr2) { Player* player = ObjectAccessor::FindPlayer(*itr2); @@ -423,13 +441,13 @@ inline void Battleground::_ProcessProgress(uint32 diff) if (newtime > (MINUTE * IN_MILLISECONDS)) { if (newtime / (MINUTE * IN_MILLISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS)) - PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS))); + PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, nullptr, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILLISECONDS))); } else { //announce every 15 seconds if (newtime / (15 * IN_MILLISECONDS) != m_PrematureCountDownTimer / (15 * IN_MILLISECONDS)) - PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / IN_MILLISECONDS)); + PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, nullptr, (uint32)(m_PrematureCountDownTimer / IN_MILLISECONDS)); } m_PrematureCountDownTimer = newtime; } @@ -570,7 +588,7 @@ inline void Battleground::_ProcessLeave(uint32 diff) Player* Battleground::_GetPlayer(ObjectGuid guid, bool offlineRemove, char const* context) const { - Player* player = NULL; + Player* player = nullptr; if (!offlineRemove) { // should this be ObjectAccessor::FindConnectedPlayer() to return players teleporting ? @@ -591,7 +609,7 @@ Player* Battleground::_GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::co if (!team) team = player->GetTeam(); if (team != teamId) - player = NULL; + player = nullptr; } return player; } @@ -627,7 +645,7 @@ void Battleground::SendPacketToTeam(uint32 TeamID, WorldPacket* packet, Player* } } -void Battleground::SendChatMessage(Creature* source, uint8 textId, WorldObject* target /*= NULL*/) +void Battleground::SendChatMessage(Creature* source, uint8 textId, WorldObject* target /*= nullptr*/) { sCreatureTextMgr->SendChat(source, textId, target); } @@ -922,7 +940,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen bgTypeId = BATTLEGROUND_AA; // set the bg type to all arenas (it will be used for queue refreshing) // unsummon current and summon old pet if there was one and there isn't a current pet - player->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT); + player->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT); player->ResummonPetTemporaryUnSummonedIfAny(); } @@ -941,7 +959,7 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen if (Group* group = GetBgRaid(team)) { if (!group->RemoveMember(guid)) // group was disbanded - SetBgRaid(team, NULL); + SetBgRaid(team, nullptr); } DecreaseInvitedCount(team); //we should update battleground queue, but only if bg isn't ending @@ -1274,7 +1292,7 @@ bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, return false; if (type == SCORE_BONUS_HONOR && doAddHonor && isBattleground()) - player->RewardHonor(NULL, 1, value); // RewardHonor calls UpdatePlayerScore with doAddHonor = false + player->RewardHonor(nullptr, 1, value); // RewardHonor calls UpdatePlayerScore with doAddHonor = false else itr->second->UpdateScore(type, value); @@ -1315,7 +1333,7 @@ void Battleground::RelocateDeadPlayers(ObjectGuid guideGuid) GuidVector& ghostList = m_ReviveQueue[guideGuid]; if (!ghostList.empty()) { - WorldSafeLocsEntry const* closestGrave = NULL; + WorldSafeLocsEntry const* closestGrave = nullptr; for (GuidVector::const_iterator itr = ghostList.begin(); itr != ghostList.end(); ++itr) { Player* player = ObjectAccessor::FindPlayer(*itr); @@ -1323,7 +1341,7 @@ void Battleground::RelocateDeadPlayers(ObjectGuid guideGuid) continue; if (!closestGrave) - closestGrave = GetClosestGraveYard(player); + closestGrave = GetClosestGraveyard(player); if (closestGrave) player->TeleportTo(GetMapId(), closestGrave->x, closestGrave->y, closestGrave->z, player->GetOrientation()); @@ -1341,14 +1359,14 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float if (!map) return false; - G3D::Quat rot(rotation0, rotation1, rotation2, rotation3); + QuaternionData rot(rotation0, rotation1, rotation2, rotation3); // Temporally add safety check for bad spawns and send log (object rotations need to be rechecked in sniff) if (!rotation0 && !rotation1 && !rotation2 && !rotation3) { TC_LOG_DEBUG("bg.battleground", "Battleground::AddObject: gameoobject [entry: %u, object type: %u] for BG (map: %u) has zeroed rotation fields, " "orientation used temporally, but please fix the spawn", entry, type, m_MapId); - rot = G3D::Matrix3::fromEulerAnglesZYX(o, 0.f, 0.f); + rot = QuaternionData::fromEulerAnglesZYX(o, 0.f, 0.f); } // Must be created this way, adding to godatamap would add it to the base map of the instance @@ -1482,7 +1500,7 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, Map* map = FindBgMap(); if (!map) - return NULL; + return nullptr; if (transport) { @@ -1492,7 +1510,7 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, return creature; } - return NULL; + return nullptr; } Creature* creature = new Creature(); @@ -1502,7 +1520,7 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: %u) for BG (map: %u, instance id: %u)!", entry, m_MapId, m_InstanceID); delete creature; - return NULL; + return nullptr; } creature->SetHomePosition(x, y, z, o); @@ -1513,13 +1531,13 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: creature template (entry: %u) does not exist for BG (map: %u, instance id: %u)!", entry, m_MapId, m_InstanceID); delete creature; - return NULL; + return nullptr; } if (!map->AddToMap(creature)) { delete creature; - return NULL; + return nullptr; } BgCreatures[type] = creature->GetGUID(); @@ -1644,7 +1662,7 @@ void Battleground::SendWarningToAll(uint32 entry, ...) vsnprintf(str, 1024, format, ap); va_end(ap); - ChatHandler::BuildChatPacket(localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()], CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, NULL, NULL, str); + ChatHandler::BuildChatPacket(localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()], CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, nullptr, nullptr, str); } player->SendDirectMessage(&localizedPackets[player->GetSession()->GetSessionDbLocaleIndex()]); @@ -1813,15 +1831,15 @@ void Battleground::SetBgRaid(uint32 TeamID, Group* bg_raid) { Group*& old_raid = TeamID == ALLIANCE ? m_BgRaids[TEAM_ALLIANCE] : m_BgRaids[TEAM_HORDE]; if (old_raid) - old_raid->SetBattlegroundGroup(NULL); + old_raid->SetBattlegroundGroup(nullptr); if (bg_raid) bg_raid->SetBattlegroundGroup(this); old_raid = bg_raid; } -WorldSafeLocsEntry const* Battleground::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* Battleground::GetClosestGraveyard(Player* player) { - return sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam()); + return sObjectMgr->GetClosestGraveyard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam()); } void Battleground::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index e012ead3d73..b19d9c470b2 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -20,23 +20,23 @@ #define __BATTLEGROUND_H #include "ArenaScore.h" -#include "Common.h" -#include "SharedDefines.h" #include "DBCEnums.h" -#include "WorldPacket.h" -#include "Object.h" -#include "GameObject.h" -#include "EventMap.h" +#include "ObjectGuid.h" +#include "Position.h" +#include "SharedDefines.h" +#include <map> +class BattlegroundMap; class Creature; class GameObject; class Group; class Player; +class Transport; class Unit; class WorldObject; class WorldPacket; -class BattlegroundMap; +struct BattlegroundScore; struct PvPDifficultyEntry; struct WorldSafeLocsEntry; @@ -172,7 +172,7 @@ struct BattlegroundPlayer struct BattlegroundObjectInfo { - BattlegroundObjectInfo() : object(NULL), timer(0), spellid(0) { } + BattlegroundObjectInfo() : object(nullptr), timer(0), spellid(0) { } GameObject *object; int32 timer; @@ -243,7 +243,7 @@ class TC_GAME_API Battleground /* achievement req. */ virtual bool IsAllNodesControlledByTeam(uint32 /*team*/) const { return false; } void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); - virtual bool CheckAchievementCriteriaMeet(uint32 /*criteriaId*/, Player const* /*player*/, Unit const* /*target*/ = NULL, uint32 /*miscvalue1*/ = 0); + virtual bool CheckAchievementCriteriaMeet(uint32 /*criteriaId*/, Player const* /*player*/, Unit const* /*target*/ = nullptr, uint32 /*miscvalue1*/ = 0); /* Battleground */ // Get methods: @@ -352,10 +352,10 @@ class TC_GAME_API Battleground // Packet Transfer // method that should fill worldpacket with actual world states (not yet implemented for all battlegrounds!) virtual void FillInitialWorldStates(WorldPacket& /*data*/) { } - void SendPacketToTeam(uint32 TeamID, WorldPacket* packet, Player* sender = NULL, bool self = true); + void SendPacketToTeam(uint32 TeamID, WorldPacket* packet, Player* sender = nullptr, bool self = true); void SendPacketToAll(WorldPacket* packet); - void SendChatMessage(Creature* source, uint8 textId, WorldObject* target = NULL); + void SendChatMessage(Creature* source, uint8 textId, WorldObject* target = nullptr); template<class Do> void BroadcastWorker(Do& _do); @@ -372,7 +372,7 @@ class TC_GAME_API Battleground void BlockMovement(Player* player); void SendWarningToAll(uint32 entry, ...); - void SendMessageToAll(uint32 entry, ChatMsg type, Player const* source = NULL); + void SendMessageToAll(uint32 entry, ChatMsg type, Player const* source = nullptr); void PSendMessageToAll(uint32 entry, ChatMsg type, Player const* source, ...); // specialized version with 2 string id args @@ -417,7 +417,7 @@ class TC_GAME_API Battleground virtual void EventPlayerClickedOnFlag(Player* /*player*/, GameObject* /*target_obj*/) { } void EventPlayerLoggedIn(Player* player); void EventPlayerLoggedOut(Player* player); - virtual void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/ = NULL) { } + virtual void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/ = nullptr) { } // this function can be used by spell to interact with the BG map virtual void DoAction(uint32 /*action*/, ObjectGuid /*var*/) { } @@ -425,7 +425,7 @@ class TC_GAME_API Battleground virtual void HandlePlayerResurrect(Player* /*player*/) { } // Death related - virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); + virtual WorldSafeLocsEntry const* GetClosestGraveyard(Player* player); virtual void AddPlayer(Player* player); // must be implemented in BG subclass @@ -443,8 +443,8 @@ class TC_GAME_API Battleground void SpawnBGObject(uint32 type, uint32 respawntime); virtual bool AddObject(uint32 type, uint32 entry, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY); bool AddObject(uint32 type, uint32 entry, Position const& pos, float rotation0, float rotation1, float rotation2, float rotation3, uint32 respawnTime = 0, GOState goState = GO_STATE_READY); - virtual Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = NULL); - Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = NULL); + virtual Creature* AddCreature(uint32 entry, uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = nullptr); + Creature* AddCreature(uint32 entry, uint32 type, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 respawntime = 0, Transport* transport = nullptr); bool DelCreature(uint32 type); bool DelObject(uint32 type); virtual bool AddSpiritGuide(uint32 type, float x, float y, float z, float o, TeamId teamId = TEAM_NEUTRAL); @@ -484,10 +484,10 @@ class TC_GAME_API Battleground void EndNow(); void PlayerAddedToBGCheckIfBGIsRunning(Player* player); - Player* _GetPlayer(ObjectGuid guid, bool offlineRemove, const char* context) const; - Player* _GetPlayer(BattlegroundPlayerMap::iterator itr, const char* context) { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, context); } - Player* _GetPlayer(BattlegroundPlayerMap::const_iterator itr, const char* context) const { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, context); } - Player* _GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::const_iterator itr, const char* context) const; + Player* _GetPlayer(ObjectGuid guid, bool offlineRemove, char const* context) const; + Player* _GetPlayer(BattlegroundPlayerMap::iterator itr, char const* context) { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, context); } + Player* _GetPlayer(BattlegroundPlayerMap::const_iterator itr, char const* context) const { return _GetPlayer(itr->first, itr->second.OfflineRemoveTime != 0, context); } + Player* _GetPlayerForTeam(uint32 teamId, BattlegroundPlayerMap::const_iterator itr, char const* context) const; void _ProcessOfflineQueue(); void _ProcessResurrect(uint32 diff); diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.cpp b/src/server/game/Battlegrounds/BattlegroundMgr.cpp index 0416a021d16..1b8fb8ee907 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.cpp +++ b/src/server/game/Battlegrounds/BattlegroundMgr.cpp @@ -16,12 +16,7 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "ObjectMgr.h" #include "ArenaTeamMgr.h" -#include "World.h" -#include "WorldPacket.h" - #include "BattlegroundMgr.h" #include "BattlegroundAV.h" #include "BattlegroundAB.h" @@ -34,15 +29,26 @@ #include "BattlegroundDS.h" #include "BattlegroundRV.h" #include "BattlegroundIC.h" +#include "Common.h" +#include "Containers.h" #include "Chat.h" +#include "DatabaseEnv.h" +#include "DisableMgr.h" +#include "Formulas.h" +#include "GameEventMgr.h" #include "Map.h" #include "MapManager.h" -#include "Player.h" -#include "GameEventMgr.h" #include "SharedDefines.h" -#include "Formulas.h" -#include "DisableMgr.h" +#include "ObjectMgr.h" #include "Opcodes.h" +#include "Player.h" +#include "World.h" +#include "WorldPacket.h" + +bool BattlegroundTemplate::IsArena() const +{ + return BattlemasterEntry->type == MAP_ARENA; +} /*********************************************************/ /*** BATTLEGROUND MANAGER ***/ @@ -160,7 +166,7 @@ void BattlegroundMgr::Update(uint32 diff) { if (m_AutoDistributionTimeChecker < diff) { - if (time(NULL) > m_NextAutoDistributionTime) + if (time(nullptr) > m_NextAutoDistributionTime) { sArenaTeamMgr->DistributeArenaPoints(); m_NextAutoDistributionTime = m_NextAutoDistributionTime + BATTLEGROUND_ARENA_POINT_DISTRIBUTION_DAY * sWorld->getIntConfig(CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS); @@ -265,14 +271,14 @@ Battleground* BattlegroundMgr::GetBattlegroundThroughClientInstance(uint32 insta //SMSG_BATTLEFIELD_LIST we need to find the battleground with this clientinstance-id Battleground* bg = GetBattlegroundTemplate(bgTypeId); if (!bg) - return NULL; + return nullptr; if (bg->isArena()) return GetBattleground(instanceId, bgTypeId); BattlegroundDataContainer::const_iterator it = bgDataStore.find(bgTypeId); if (it == bgDataStore.end()) - return NULL; + return nullptr; for (BattlegroundContainer::const_iterator itr = it->second.m_Battlegrounds.begin(); itr != it->second.m_Battlegrounds.end(); ++itr) { @@ -280,13 +286,13 @@ Battleground* BattlegroundMgr::GetBattlegroundThroughClientInstance(uint32 insta return itr->second; } - return NULL; + return nullptr; } Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTypeId bgTypeId) { if (!instanceId) - return NULL; + return nullptr; BattlegroundDataContainer::const_iterator begin, end; @@ -299,7 +305,7 @@ Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTy { end = bgDataStore.find(bgTypeId); if (end == bgDataStore.end()) - return NULL; + return nullptr; begin = end++; } @@ -311,18 +317,18 @@ Battleground* BattlegroundMgr::GetBattleground(uint32 instanceId, BattlegroundTy return itr->second; } - return NULL; + return nullptr; } Battleground* BattlegroundMgr::GetBattlegroundTemplate(BattlegroundTypeId bgTypeId) { BattlegroundDataContainer::const_iterator itr = bgDataStore.find(bgTypeId); if (itr == bgDataStore.end()) - return NULL; + return nullptr; BattlegroundContainer const& bgs = itr->second.m_Battlegrounds; //map is sorted and we can be sure that lowest instance id has only BG template - return bgs.empty() ? NULL : bgs.begin()->second; + return bgs.empty() ? nullptr : bgs.begin()->second; } uint32 BattlegroundMgr::CreateClientVisibleInstanceId(BattlegroundTypeId bgTypeId, BattlegroundBracketId bracket_id) @@ -361,10 +367,10 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original if (!bg_template) { TC_LOG_ERROR("bg.battleground", "Battleground: CreateNewBattleground - bg template not found for %u", bgTypeId); - return NULL; + return nullptr; } - Battleground* bg = NULL; + Battleground* bg = nullptr; // create a copy of the BG template switch (bgTypeId) { @@ -404,7 +410,7 @@ Battleground* BattlegroundMgr::CreateNewBattleground(BattlegroundTypeId original case BATTLEGROUND_RB: case BATTLEGROUND_AA: default: - return NULL; + return nullptr; } bool isRandom = bgTypeId != originalBgTypeId && !bg->isArena(); @@ -541,7 +547,7 @@ void BattlegroundMgr::LoadBattlegroundTemplates() BattlegroundTypeId bgTypeId = BattlegroundTypeId(fields[0].GetUInt32()); - if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId, NULL)) + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId, nullptr)) continue; // can be overwrite by values from DB @@ -624,7 +630,7 @@ void BattlegroundMgr::InitAutomaticArenaPointDistribution() return; time_t wstime = time_t(sWorld->getWorldState(WS_ARENA_DISTRIBUTION_TIME)); - time_t curtime = time(NULL); + time_t curtime = time(nullptr); TC_LOG_DEBUG("bg.battleground", "Initializing Automatic Arena Point Distribution"); if (wstime < curtime) { @@ -724,7 +730,7 @@ void BattlegroundMgr::SendAreaSpiritHealerQueryOpcode(Player* player, Battlegrou if (time_ == uint32(-1)) time_ = 0; data << guid << time_; - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } bool BattlegroundMgr::IsArenaType(BattlegroundTypeId bgTypeId) @@ -967,9 +973,11 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) { if (BattlegroundTemplate const* bgTemplate = GetBattlegroundTemplateByTypeId(bgTypeId)) { - uint32 weight = 0; BattlegroundSelectionWeightMap selectionWeights; - + std::vector<BattlegroundTypeId> ids; + ids.reserve(16); + std::vector<double> weights; + weights.reserve(16); for (int32 mapId : bgTemplate->BattlemasterEntry->mapid) { if (mapId == -1) @@ -977,28 +985,12 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId) if (BattlegroundTemplate const* bg = GetBattlegroundTemplateByMapId(mapId)) { - weight += bg->Weight; - selectionWeights[bg->Id] = bg->Weight; + ids.push_back(bg->Id); + weights.push_back(bg->Weight); } } - // there is only one bg to select - if (selectionWeights.size() == 1) - return selectionWeights.begin()->first; - - if (weight) - { - // Select a random value - uint32 selectedWeight = urand(0, weight - 1); - // Select the correct bg (if we have in DB A(10), B(20), C(10), D(15) --> [0---A---9|10---B---29|30---C---39|40---D---54]) - weight = 0; - for (auto it : selectionWeights) - { - weight += it.second; - if (selectedWeight < weight) - return it.first; - } - } + return *Trinity::Containers::SelectRandomWeightedContainerElement(ids, weights); } return BATTLEGROUND_TYPE_NONE; diff --git a/src/server/game/Battlegrounds/BattlegroundMgr.h b/src/server/game/Battlegrounds/BattlegroundMgr.h index 84dfb482a9f..da5e89a5a5d 100644 --- a/src/server/game/Battlegrounds/BattlegroundMgr.h +++ b/src/server/game/Battlegrounds/BattlegroundMgr.h @@ -23,6 +23,9 @@ #include "DBCEnums.h" #include "Battleground.h" #include "BattlegroundQueue.h" +#include <unordered_map> + +struct BattlemasterListEntry; typedef std::map<uint32, Battleground*> BattlegroundContainer; typedef std::set<uint32> BattlegroundClientIdsContainer; @@ -56,7 +59,7 @@ struct BattlegroundTemplate uint32 ScriptId; BattlemasterListEntry const* BattlemasterEntry; - bool IsArena() const { return BattlemasterEntry->type == MAP_ARENA; } + bool IsArena() const; }; class TC_GAME_API BattlegroundMgr diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index 7643e1d3f5e..ea83422c205 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -16,17 +16,20 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "BattlegroundQueue.h" #include "ArenaTeam.h" #include "ArenaTeamMgr.h" #include "BattlegroundMgr.h" -#include "BattlegroundQueue.h" #include "Chat.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "GameTime.h" #include "Group.h" -#include "Log.h" #include "Language.h" -#include "Player.h" +#include "Log.h" #include "ObjectAccessor.h" +#include "Player.h" +#include "World.h" /*********************************************************/ /*** BATTLEGROUND QUEUE SYSTEM ***/ @@ -170,7 +173,7 @@ GroupQueueInfo* BattlegroundQueue::AddGroup(Player* leader, Group* grp, Battlegr //add players from group to ginfo if (grp) { - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) @@ -396,7 +399,7 @@ void BattlegroundQueue::RemovePlayer(ObjectGuid guid, bool decreaseInvitedCount) // queue->removeplayer, it causes bugs WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0); - plr2->GetSession()->SendPacket(&data); + plr2->SendDirectMessage(&data); } // then actually delete, this may delete the group as well! RemovePlayer(group->Players.begin()->first, decreaseInvitedCount); @@ -481,7 +484,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, // send status packet sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType, 0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } return true; } @@ -890,8 +893,8 @@ void BattlegroundQueue::BattlegroundQueueUpdate(uint32 /*diff*/, BattlegroundTyp // 0 is on (automatic update call) and we must set it to team's with longest wait time if (!arenaRating) { - GroupQueueInfo* front1 = NULL; - GroupQueueInfo* front2 = NULL; + GroupQueueInfo* front1 = nullptr; + GroupQueueInfo* front2 = nullptr; if (!m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].empty()) { front1 = m_QueuedGroups[bracket_id][BG_QUEUE_PREMADE_ALLIANCE].front(); @@ -1031,7 +1034,7 @@ bool BGQueueInviteEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) WorldPacket data; //we must send remaining time in queue sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME - INVITATION_REMIND_TIME, 0, m_ArenaType, 0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } } return true; //event will be deleted @@ -1089,7 +1092,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) WorldPacket data; sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_NONE, 0, 0, 0, 0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } } diff --git a/src/server/game/Battlegrounds/BattlegroundScore.h b/src/server/game/Battlegrounds/BattlegroundScore.h index 8776a1d7c39..41fdbbf3117 100644 --- a/src/server/game/Battlegrounds/BattlegroundScore.h +++ b/src/server/game/Battlegrounds/BattlegroundScore.h @@ -18,8 +18,11 @@ #ifndef TRINITY_BATTLEGROUND_SCORE_H #define TRINITY_BATTLEGROUND_SCORE_H -#include "WorldPacket.h" +#include "Errors.h" #include "ObjectGuid.h" +#include "SharedDefines.h" + +class WorldPacket; enum ScoreType { @@ -89,20 +92,7 @@ struct BattlegroundScore } } - virtual void AppendToPacket(WorldPacket& data) - { - data << uint64(PlayerGuid); - - data << uint32(KillingBlows); - data << uint32(HonorableKills); - data << uint32(Deaths); - data << uint32(BonusHonor); - data << uint32(DamageDone); - data << uint32(HealingDone); - - BuildObjectivesBlock(data); - } - + virtual void AppendToPacket(WorldPacket& data); virtual void BuildObjectivesBlock(WorldPacket& /*data*/) = 0; // For Logging purpose diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index c47662893b1..6ef3bbcc3c3 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -17,14 +17,26 @@ */ #include "BattlegroundAB.h" -#include "WorldPacket.h" #include "BattlegroundMgr.h" #include "Creature.h" +#include "DBCStores.h" +#include "GameObject.h" #include "Language.h" +#include "Log.h" +#include "Map.h" #include "Player.h" +#include "Random.h" #include "Util.h" +#include "WorldPacket.h" #include "WorldSession.h" +void BattlegroundABScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(2); + data << uint32(BasesAssaulted); + data << uint32(BasesDefended); +} + BattlegroundAB::BattlegroundAB() { m_IsInformedNearVictory = false; @@ -104,13 +116,13 @@ void BattlegroundAB::PostUpdateImpl(uint32 diff) if (teamIndex == 0) { // FIXME: team and node names not localized - SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node)); + SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_ALLIANCE, nullptr, LANG_BG_AB_ALLY, _GetNodeNameId(node)); PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_ALLIANCE); } else { // FIXME: team and node names not localized - SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node)); + SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_HORDE, nullptr, LANG_BG_AB_HORDE, _GetNodeNameId(node)); PlaySoundToAll(BG_AB_SOUND_NODE_CAPTURED_HORDE); } } @@ -390,7 +402,7 @@ void BattlegroundAB::_NodeOccupied(uint8 node, Team team) if (capturedNodes >= 4) CastSpellOnTeam(SPELL_AB_QUEST_REWARD_4_BASES, team); - Creature* trigger = !BgCreatures[node + 7] ? GetBGCreature(node + 7) : NULL; // 0-6 spirit guides + Creature* trigger = !BgCreatures[node + 7] ? GetBGCreature(node + 7) : nullptr; // 0-6 spirit guides if (!trigger) trigger = AddCreature(WORLD_TRIGGER, node+7, BG_AB_NodePositions[node], GetTeamIndexByTeamId(team)); @@ -541,9 +553,9 @@ void BattlegroundAB::EventPlayerClickedOnFlag(Player* source, GameObject* /*targ { // FIXME: team and node names not localized if (teamIndex == TEAM_ALLIANCE) - SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, LANG_BG_AB_ALLY, _GetNodeNameId(node)); + SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_ALLIANCE, nullptr, LANG_BG_AB_ALLY, _GetNodeNameId(node)); else - SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_HORDE, NULL, LANG_BG_AB_HORDE, _GetNodeNameId(node)); + SendMessage2ToAll(LANG_BG_AB_NODE_TAKEN, CHAT_MSG_BG_SYSTEM_HORDE, nullptr, LANG_BG_AB_HORDE, _GetNodeNameId(node)); } PlaySoundToAll(sound); } @@ -651,7 +663,7 @@ void BattlegroundAB::EndBattleground(uint32 winner) Battleground::EndBattleground(winner); } -WorldSafeLocsEntry const* BattlegroundAB::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* BattlegroundAB::GetClosestGraveyard(Player* player) { TeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam()); @@ -661,7 +673,7 @@ WorldSafeLocsEntry const* BattlegroundAB::GetClosestGraveYard(Player* player) if (m_Nodes[i] == teamIndex + 3) nodes.push_back(i); - WorldSafeLocsEntry const* good_entry = NULL; + WorldSafeLocsEntry const* good_entry = nullptr; // If so, select the closest node to place ghost on if (!nodes.empty()) { @@ -671,7 +683,7 @@ WorldSafeLocsEntry const* BattlegroundAB::GetClosestGraveYard(Player* player) float mindist = 999999.0f; for (uint8 i = 0; i < nodes.size(); ++i) { - WorldSafeLocsEntry const*entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[nodes[i]]); + WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(BG_AB_GraveyardIds[nodes[i]]); if (!entry) continue; float dist = (entry->x - plr_x)*(entry->x - plr_x)+(entry->y - plr_y)*(entry->y - plr_y); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h index 71c8c0f71de..7f68ef3eb0d 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.h @@ -260,12 +260,7 @@ struct BattlegroundABScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(2); - data << uint32(BasesAssaulted); - data << uint32(BasesDefended); - } + void BuildObjectivesBlock(WorldPacket& data) final override; uint32 GetAttr1() const final override { return BasesAssaulted; } uint32 GetAttr2() const final override { return BasesDefended; } @@ -288,7 +283,7 @@ class BattlegroundAB : public Battleground bool SetupBattleground() override; void Reset() override; void EndBattleground(uint32 winner) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override; /* Scorekeeping */ bool UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor = true) override; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index c78b5439a75..fc2bee156ee 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -17,16 +17,27 @@ */ #include "BattlegroundAV.h" - -#include "ObjectMgr.h" -#include "WorldPacket.h" - +#include "Creature.h" +#include "CreatureAI.h" +#include "DBCStores.h" #include "GameObject.h" #include "Language.h" +#include "Log.h" +#include "MotionMaster.h" +#include "ObjectMgr.h" #include "Player.h" -#include "ScriptedCreature.h" #include "WorldSession.h" +void BattlegroundAVScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(5); // Objectives Count + data << uint32(GraveyardsAssaulted); + data << uint32(GraveyardsDefended); + data << uint32(TowersAssaulted); + data << uint32(TowersDefended); + data << uint32(MinesCaptured); +} + BattlegroundAV::BattlegroundAV() { BgObjects.resize(BG_AV_OBJECT_MAX); @@ -273,7 +284,7 @@ void BattlegroundAV::UpdateScore(uint16 team, int16 points) Creature* BattlegroundAV::AddAVCreature(uint16 cinfoid, uint16 type) { bool isStatic = false; - Creature* creature = NULL; + Creature* creature = nullptr; ASSERT(type <= AV_CPLACE_MAX + AV_STATICCPLACE_MAX); if (type >= AV_CPLACE_MAX) //static { @@ -292,7 +303,7 @@ Creature* BattlegroundAV::AddAVCreature(uint16 cinfoid, uint16 type) creature = AddCreature(BG_AV_CreatureInfo[cinfoid], type, BG_AV_CreaturePos[type]); } if (!creature) - return NULL; + return nullptr; if (creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_A_CAPTAIN] || creature->GetEntry() == BG_AV_CreatureInfo[AV_NPC_H_CAPTAIN]) creature->SetRespawnDelay(RESPAWN_ONE_DAY); /// @todo look if this can be done by database + also add this for the wingcommanders @@ -392,7 +403,7 @@ void BattlegroundAV::PostUpdateImpl(uint32 diff) } } if (m_Mine_Timer <= 0) - m_Mine_Timer=AV_MINE_TICK_TIMER; //this is at the end, cause we need to update both mines + m_Mine_Timer = AV_MINE_TICK_TIMER; //this is at the end, cause we need to update both mines //looks for all timers of the nodes and destroy the building (for graveyards the building wont get destroyed, it goes just to the other team for (BG_AV_Nodes i = BG_AV_NODES_FIRSTAID_STATION; i < BG_AV_NODES_MAX; ++i) @@ -1092,10 +1103,10 @@ void BattlegroundAV::SendMineWorldStates(uint32 mine) UpdateWorldState(BG_AV_MineWorldStates[mine2][prevowner], 0); } -WorldSafeLocsEntry const* BattlegroundAV::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* BattlegroundAV::GetClosestGraveyard(Player* player) { - WorldSafeLocsEntry const* pGraveyard = NULL; - WorldSafeLocsEntry const* entry = NULL; + WorldSafeLocsEntry const* pGraveyard = nullptr; + WorldSafeLocsEntry const* entry = nullptr; float dist = 0; float minDist = 0; float x, y; @@ -1486,7 +1497,7 @@ void BattlegroundAV::ResetBGSubclass() InitNode(i, HORDE, true); InitNode(BG_AV_NODES_SNOWFALL_GRAVE, AV_NEUTRAL_TEAM, false); //give snowfall neutral owner - m_Mine_Timer=AV_MINE_TICK_TIMER; + m_Mine_Timer = AV_MINE_TICK_TIMER; for (uint16 i = 0; i < AV_CPLACE_MAX+AV_STATICCPLACE_MAX; i++) if (BgCreatures[i]) DelCreature(i); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index 5f687ec4eb1..9adaea025d3 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -1581,15 +1581,7 @@ struct BattlegroundAVScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(5); // Objectives Count - data << uint32(GraveyardsAssaulted); - data << uint32(GraveyardsDefended); - data << uint32(TowersAssaulted); - data << uint32(TowersDefended); - data << uint32(MinesCaptured); - } + void BuildObjectivesBlock(WorldPacket& data) final override; uint32 GetAttr1() const final override { return GraveyardsAssaulted; } uint32 GetAttr2() const final override { return GraveyardsDefended; } @@ -1633,7 +1625,7 @@ class BattlegroundAV : public Battleground void EndBattleground(uint32 winner) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override; // Achievement: Av perfection and Everything counts bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = nullptr, uint32 miscvalue1 = 0) override; @@ -1669,7 +1661,7 @@ class BattlegroundAV : public Battleground bool IsTower(BG_AV_Nodes node) { return m_Nodes[node].Tower; } /*mine*/ - void ChangeMineOwner(uint8 mine, uint32 team, bool initial=false); + void ChangeMineOwner(uint8 mine, uint32 team, bool initial = false); /*worldstates*/ void FillInitialWorldStates(WorldPacket& data) override; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp index 21e041fafe1..ca406413325 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundBE.cpp @@ -17,6 +17,7 @@ */ #include "BattlegroundBE.h" +#include "Log.h" #include "Player.h" #include "WorldPacket.h" diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp index e4940add01c..4ba43b85e15 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.cpp @@ -18,7 +18,9 @@ #include "BattlegroundDS.h" #include "Creature.h" +#include "Log.h" #include "Player.h" +#include "Random.h" #include "WorldPacket.h" BattlegroundDS::BattlegroundDS() diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h index f55c8fedd01..e112e5cae6a 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundDS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundDS.h @@ -20,6 +20,7 @@ #define __BATTLEGROUNDDS_H #include "Arena.h" +#include "EventMap.h" enum BattlegroundDSObjectTypes { @@ -109,4 +110,5 @@ class BattlegroundDS : public Arena uint32 _pipeKnockBackTimer; uint8 _pipeKnockBackCount; }; + #endif diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index 3f363a4bd19..e1d1394cb05 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -20,8 +20,13 @@ #include "WorldPacket.h" #include "BattlegroundMgr.h" #include "Creature.h" +#include "DBCStores.h" +#include "GameObject.h" #include "Language.h" +#include "Log.h" +#include "Map.h" #include "Player.h" +#include "Random.h" #include "Util.h" #include "ObjectAccessor.h" @@ -32,6 +37,12 @@ uint32 BG_EY_HonorScoreTicks[BG_HONOR_MODE_NUM] = 160 // holiday }; +void BattlegroundEYScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(1); // Objectives Count + data << uint32(FlagCaptures); +} + BattlegroundEY::BattlegroundEY() { m_BuffChange = true; @@ -107,10 +118,10 @@ void BattlegroundEY::PostUpdateImpl(uint32 diff) /*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times but we can count of players on current point in CheckSomeoneLeftPoint */ - this->CheckSomeoneJoinedPoint(); + CheckSomeoneJoinedPoint(); //check if player left point - this->CheckSomeoneLeftPoint(); - this->UpdatePointStatuses(); + CheckSomeoneLeftPoint(); + UpdatePointStatuses(); m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME; } } @@ -158,7 +169,7 @@ void BattlegroundEY::AddPoints(uint32 Team, uint32 Points) void BattlegroundEY::CheckSomeoneJoinedPoint() { - GameObject* obj = NULL; + GameObject* obj = nullptr; for (uint8 i = 0; i < EY_POINTS_MAX; ++i) { obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); @@ -199,7 +210,7 @@ void BattlegroundEY::CheckSomeoneLeftPoint() //reset current point counts for (uint8 i = 0; i < 2*EY_POINTS_MAX; ++i) m_CurrentPointPlayersCount[i] = 0; - GameObject* obj = NULL; + GameObject* obj = nullptr; for (uint8 i = 0; i < EY_POINTS_MAX; ++i) { obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); @@ -223,7 +234,7 @@ void BattlegroundEY::CheckSomeoneLeftPoint() { m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]); m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j); - this->UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, player); + UpdateWorldStateForPlayer(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW, player); } else { @@ -266,17 +277,17 @@ void BattlegroundEY::UpdatePointStatuses() Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[point][i]); if (player) { - this->UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], player); + UpdateWorldStateForPlayer(PROGRESS_BAR_STATUS, m_PointBarStatus[point], player); //if point owner changed we must evoke event! if (pointOwnerTeamId != m_PointOwnedByTeam[point]) { //point was uncontrolled and player is from team which captured point if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && player->GetTeam() == pointOwnerTeamId) - this->EventTeamCapturedPoint(player, point); + EventTeamCapturedPoint(player, point); //point was under control and player isn't from team which controlled it if (m_PointState[point] == EY_POINT_UNDER_CONTROL && player->GetTeam() != m_PointOwnedByTeam[point]) - this->EventTeamLostPoint(player, point); + EventTeamLostPoint(player, point); } /// @workaround The original AreaTrigger is covered by a bigger one and not triggered on client side. @@ -518,7 +529,7 @@ bool BattlegroundEY::SetupBattleground() TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Could not spawn Speedbuff Fel Reaver."); } - WorldSafeLocsEntry const* sg = NULL; + WorldSafeLocsEntry const* sg = nullptr; sg = sWorldSafeLocsStore.LookupEntry(EY_GRAVEYARD_MAIN_ALLIANCE); if (!sg || !AddSpiritGuide(EY_SPIRIT_MAIN_ALLIANCE, sg->x, sg->y, sg->z, 3.124139f, TEAM_ALLIANCE)) { @@ -640,9 +651,9 @@ void BattlegroundEY::EventPlayerDroppedFlag(Player* player) UpdateWorldState(NETHERSTORM_FLAG_STATE_ALLIANCE, BG_EY_FLAG_STATE_WAIT_RESPAWN); if (player->GetTeam() == ALLIANCE) - SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL); + SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, nullptr); else - SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL); + SendMessageToAll(LANG_BG_EY_DROPPED_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, nullptr); } void BattlegroundEY::EventPlayerClickedOnFlag(Player* player, GameObject* target_obj) @@ -672,9 +683,9 @@ void BattlegroundEY::EventPlayerClickedOnFlag(Player* player, GameObject* target player->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_ENTER_PVP_COMBAT); if (player->GetTeam() == ALLIANCE) - PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, NULL, player->GetName().c_str()); + PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_ALLIANCE, nullptr, player->GetName().c_str()); else - PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, NULL, player->GetName().c_str()); + PSendMessageToAll(LANG_BG_EY_HAS_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, nullptr, player->GetName().c_str()); } void BattlegroundEY::EventTeamLostPoint(Player* player, uint32 Point) @@ -763,11 +774,11 @@ void BattlegroundEY::EventTeamCapturedPoint(Player* player, uint32 Point) if (BgCreatures[Point]) DelCreature(Point); - WorldSafeLocsEntry const* sg = NULL; - sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveYardId); + WorldSafeLocsEntry const* sg = nullptr; + sg = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[Point].GraveyardId); if (!sg || !AddSpiritGuide(Point, sg->x, sg->y, sg->z, 3.124139f, GetTeamIndexByTeamId(Team))) TC_LOG_ERROR("bg.battleground", "BatteGroundEY: Failed to spawn spirit guide. point: %u, team: %u, graveyard_id: %u", - Point, Team, m_CapturingPointTypes[Point].GraveYardId); + Point, Team, m_CapturingPointTypes[Point].GraveyardId); // SpawnBGCreature(Point, RESPAWN_IMMEDIATELY); @@ -893,7 +904,7 @@ void BattlegroundEY::FillInitialWorldStates(WorldPacket& data) data << uint32(0xc0d) << uint32(0x17b); } -WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveyard(Player* player) { uint32 g_id = 0; @@ -901,20 +912,20 @@ WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveYard(Player* player) { case ALLIANCE: g_id = EY_GRAVEYARD_MAIN_ALLIANCE; break; case HORDE: g_id = EY_GRAVEYARD_MAIN_HORDE; break; - default: return NULL; + default: return nullptr; } float distance, nearestDistance; - WorldSafeLocsEntry const* entry = NULL; - WorldSafeLocsEntry const* nearestEntry = NULL; + WorldSafeLocsEntry const* entry = nullptr; + WorldSafeLocsEntry const* nearestEntry = nullptr; entry = sWorldSafeLocsStore.LookupEntry(g_id); nearestEntry = entry; if (!entry) { TC_LOG_ERROR("bg.battleground", "BattlegroundEY: The main team graveyard could not be found. The graveyard system will not be operational!"); - return NULL; + return nullptr; } float plr_x = player->GetPositionX(); @@ -928,9 +939,9 @@ WorldSafeLocsEntry const* BattlegroundEY::GetClosestGraveYard(Player* player) { if (m_PointOwnedByTeam[i] == player->GetTeam() && m_PointState[i] == EY_POINT_UNDER_CONTROL) { - entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveYardId); + entry = sWorldSafeLocsStore.LookupEntry(m_CapturingPointTypes[i].GraveyardId); if (!entry) - TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Graveyard %u could not be found.", m_CapturingPointTypes[i].GraveYardId); + TC_LOG_ERROR("bg.battleground", "BattlegroundEY: Graveyard %u could not be found.", m_CapturingPointTypes[i].GraveyardId); else { distance = (entry->x - plr_x)*(entry->x - plr_x) + (entry->y - plr_y)*(entry->y - plr_y) + (entry->z - plr_z)*(entry->z - plr_z); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h index 53f511f9f1d..2555bc40a29 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.h @@ -282,11 +282,11 @@ struct BattlegroundEYLosingPointStruct struct BattlegroundEYCapturingPointStruct { - BattlegroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveYardId) + BattlegroundEYCapturingPointStruct(uint32 _DespawnNeutralObjectType, uint32 _SpawnObjectTypeAlliance, uint32 _MessageIdAlliance, uint32 _SpawnObjectTypeHorde, uint32 _MessageIdHorde, uint32 _GraveyardId) : DespawnNeutralObjectType(_DespawnNeutralObjectType), SpawnObjectTypeAlliance(_SpawnObjectTypeAlliance), MessageIdAlliance(_MessageIdAlliance), SpawnObjectTypeHorde(_SpawnObjectTypeHorde), MessageIdHorde(_MessageIdHorde), - GraveYardId(_GraveYardId) + GraveyardId(_GraveyardId) { } uint32 DespawnNeutralObjectType; @@ -294,7 +294,7 @@ struct BattlegroundEYCapturingPointStruct uint32 MessageIdAlliance; uint32 SpawnObjectTypeHorde; uint32 MessageIdHorde; - uint32 GraveYardId; + uint32 GraveyardId; }; const uint8 BG_EY_TickPoints[EY_POINTS_MAX] = {1, 2, 5, 10}; @@ -343,11 +343,7 @@ struct BattlegroundEYScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(1); // Objectives Count - data << uint32(FlagCaptures); - } + void BuildObjectivesBlock(WorldPacket& data) final override; uint32 GetAttr1() const final override { return FlagCaptures; } @@ -376,7 +372,7 @@ class BattlegroundEY : public Battleground void RemovePlayer(Player* player, ObjectGuid guid, uint32 team) override; void HandleAreaTrigger(Player* Source, uint32 Trigger) override; void HandleKillPlayer(Player* player, Player* killer) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override; bool SetupBattleground() override; void Reset() override; void UpdateTeamScore(uint32 Team); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index bbd4f16328a..21e20ab2752 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -16,16 +16,24 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Player.h" -#include "Battleground.h" #include "BattlegroundIC.h" -#include "Language.h" -#include "WorldPacket.h" #include "GameObject.h" +#include "Language.h" +#include "Log.h" +#include "Map.h" #include "ObjectMgr.h" -#include "Vehicle.h" -#include "Transport.h" +#include "Player.h" #include "ScriptedCreature.h" +#include "Transport.h" +#include "Vehicle.h" +#include "WorldPacket.h" + +void BattlegroundICScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(2); // Objectives Count + data << uint32(BasesAssaulted); + data << uint32(BasesDefended); +} BattlegroundIC::BattlegroundIC() { @@ -53,8 +61,8 @@ BattlegroundIC::BattlegroundIC() siegeEngineWorkshopTimer = WORKSHOP_UPDATE_TIME; - gunshipHorde = NULL; - gunshipAlliance = NULL; + gunshipHorde = nullptr; + gunshipAlliance = nullptr; } BattlegroundIC::~BattlegroundIC() { } @@ -192,7 +200,7 @@ void BattlegroundIC::PostUpdateImpl(uint32 diff) UpdateNodeWorldState(&nodePoint[i]); HandleCapturedNodes(&nodePoint[i], false); - SendMessage2ToAll(LANG_BG_IC_TEAM_HAS_TAKEN_NODE, CHAT_MSG_BG_SYSTEM_NEUTRAL, NULL, (nodePoint[i].faction == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE), nodePoint[i].string); + SendMessage2ToAll(LANG_BG_IC_TEAM_HAS_TAKEN_NODE, CHAT_MSG_BG_SYSTEM_NEUTRAL, nullptr, (nodePoint[i].faction == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE), nodePoint[i].string); nodePoint[i].needChange = false; nodePoint[i].timer = BANNER_STATE_CHANGE_TIME; @@ -416,7 +424,7 @@ void BattlegroundIC::HandleKillPlayer(Player* player, Player* killer) void BattlegroundIC::EndBattleground(uint32 winner) { - SendMessage2ToAll(LANG_BG_IC_TEAM_WINS, CHAT_MSG_BG_SYSTEM_NEUTRAL, NULL, (winner == ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE)); + SendMessage2ToAll(LANG_BG_IC_TEAM_WINS, CHAT_MSG_BG_SYSTEM_NEUTRAL, nullptr, (winner == ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE)); Battleground::EndBattleground(winner); } @@ -842,10 +850,10 @@ void BattlegroundIC::DestroyGate(Player* player, GameObject* go) TC_LOG_ERROR("bg.battleground", "Isle of Conquest: There was an error spawning creature %u", BG_IC_NpcSpawnlocs[BG_IC_NPC_HIGH_COMMANDER_HALFORD_WYRMBANE].entry); } - SendMessage2ToAll(lang_entry, CHAT_MSG_BG_SYSTEM_NEUTRAL, NULL, (player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_HORDE_KEEP : LANG_BG_IC_ALLIANCE_KEEP)); + SendMessage2ToAll(lang_entry, CHAT_MSG_BG_SYSTEM_NEUTRAL, nullptr, (player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_HORDE_KEEP : LANG_BG_IC_ALLIANCE_KEEP)); } -WorldSafeLocsEntry const* BattlegroundIC::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* BattlegroundIC::GetClosestGraveyard(Player* player) { TeamId teamIndex = GetTeamIndexByTeamId(player->GetTeam()); @@ -855,7 +863,7 @@ WorldSafeLocsEntry const* BattlegroundIC::GetClosestGraveYard(Player* player) if (nodePoint[i].faction == player->GetTeamId()) nodes.push_back(i); - WorldSafeLocsEntry const* good_entry = NULL; + WorldSafeLocsEntry const* good_entry = nullptr; // If so, select the closest node to place ghost on if (!nodes.empty()) { diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h index 0f04c60d22a..ef1724dd191 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.h @@ -903,12 +903,7 @@ struct BattlegroundICScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(2); // Objectives Count - data << uint32(BasesAssaulted); - data << uint32(BasesDefended); - } + void BuildObjectivesBlock(WorldPacket& data) final override; uint32 GetAttr1() const final override { return BasesAssaulted; } uint32 GetAttr2() const final override { return BasesDefended; } @@ -940,7 +935,7 @@ class BattlegroundIC : public Battleground void DestroyGate(Player* player, GameObject* go) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override; /* Scorekeeping */ void FillInitialWorldStates(WorldPacket& data) override; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp index d4380b043d7..e0df1d6138d 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundNA.cpp @@ -17,6 +17,7 @@ */ #include "BattlegroundNA.h" +#include "Log.h" #include "Player.h" #include "WorldPacket.h" diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp index be508ee3c9a..fd4d206385c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRL.cpp @@ -17,6 +17,7 @@ */ #include "BattlegroundRL.h" +#include "Log.h" #include "Player.h" #include "WorldPacket.h" diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp index 35fb94b3cc3..9356110a228 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundRV.cpp @@ -18,6 +18,7 @@ #include "BattlegroundRV.h" #include "GameObject.h" +#include "Log.h" #include "ObjectAccessor.h" #include "Player.h" #include "WorldPacket.h" diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index 936106052c0..b28f31cd09c 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -17,14 +17,26 @@ */ #include "BattlegroundSA.h" +#include "DBCStores.h" #include "GameObject.h" #include "GameTime.h" #include "Language.h" +#include "Log.h" +#include "Map.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" #include "ScriptedCreature.h" +#include "UpdateData.h" #include "WorldPacket.h" +void BattlegroundSAScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(2); // Objectives Count + data << uint32(DemolishersDestroyed); + data << uint32(GatesDestroyed); +} + BattlegroundSA::BattlegroundSA() { StartMessageIds[BG_STARTING_EVENT_FIRST] = LANG_BG_SA_START_TWO_MINUTES; @@ -152,8 +164,8 @@ bool BattlegroundSA::ResetObjs() } // MAD props for Kiper for discovering those values - 4 hours of his work. - GetBGObject(BG_SA_BOAT_ONE)->SetParentRotation(G3D::Quat(0.f, 0.f, 1.0f, 0.0002f)); - GetBGObject(BG_SA_BOAT_TWO)->SetParentRotation(G3D::Quat(0.f, 0.f, 1.0f, 0.00001f)); + GetBGObject(BG_SA_BOAT_ONE)->SetParentRotation(QuaternionData(0.f, 0.f, 1.0f, 0.0002f)); + GetBGObject(BG_SA_BOAT_TWO)->SetParentRotation(QuaternionData(0.f, 0.f, 1.0f, 0.00001f)); SpawnBGObject(BG_SA_BOAT_ONE, RESPAWN_IMMEDIATELY); SpawnBGObject(BG_SA_BOAT_TWO, RESPAWN_IMMEDIATELY); @@ -186,7 +198,7 @@ bool BattlegroundSA::ResetObjs() //Graveyards for (uint8 i = 0; i < BG_SA_MAX_GY; i++) { - WorldSafeLocsEntry const* sg = NULL; + WorldSafeLocsEntry const* sg = nullptr; sg = sWorldSafeLocsStore.LookupEntry(BG_SA_GYEntries[i]); if (!sg) @@ -541,7 +553,7 @@ void BattlegroundSA::TeleportToEntrancePosition(Player* player) player->TeleportTo(607, 1209.7f, -65.16f, 70.1f, 0.0f, 0); } -void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker /*= NULL*/) +void BattlegroundSA::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker /*= nullptr*/) { if (GameObject* go = obj->ToGameObject()) { @@ -686,7 +698,7 @@ void BattlegroundSA::DestroyGate(Player* /*player*/, GameObject* /*go*/) { } -WorldSafeLocsEntry const* BattlegroundSA::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* BattlegroundSA::GetClosestGraveyard(Player* player) { uint32 safeloc = 0; WorldSafeLocsEntry const* ret; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h index afbeffcd4e9..fc047b892c6 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.h @@ -531,12 +531,7 @@ struct BattlegroundSAScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(2); // Objectives Count - data << uint32(DemolishersDestroyed); - data << uint32(GatesDestroyed); - } + void BuildObjectivesBlock(WorldPacket& data) final override; uint32 GetAttr1() const final override { return DemolishersDestroyed; } uint32 GetAttr2() const final override { return GatesDestroyed; } @@ -573,9 +568,9 @@ class BattlegroundSA : public Battleground /// Called when a player kill a unit in bg void HandleKillUnit(Creature* creature, Player* killer) override; /// Return the nearest graveyard where player can respawn - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override; /// Called when someone activates an event - void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/ = NULL) override; + void ProcessEvent(WorldObject* /*obj*/, uint32 /*eventId*/, WorldObject* /*invoker*/ = nullptr) override; /// Called when a player click on flag (graveyard flag) void EventPlayerClickedOnFlag(Player* source, GameObject* go) override; /// Called when a player clicked on relic @@ -587,7 +582,7 @@ class BattlegroundSA : public Battleground for (uint8 i = 0; i < MAX_GATES; ++i) if (Gates[i].GameObjectId == entry) return &Gates[i]; - return NULL; + return nullptr; } /// Called on battleground ending @@ -600,7 +595,7 @@ class BattlegroundSA : public Battleground /* Scorekeeping */ // Achievement: Not Even a Scratch - bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = NULL, uint32 miscValue = 0) override; + bool CheckAchievementCriteriaMeet(uint32 criteriaId, Player const* source, Unit const* target = nullptr, uint32 miscValue = 0) override; // Control Phase Shift bool IsSpellAllowed(uint32 spellId, Player const* player) const override; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index 6045ee78352..0129197e9ec 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -17,13 +17,16 @@ */ #include "BattlegroundWS.h" +#include "BattlegroundMgr.h" +#include "DBCStores.h" #include "GameObject.h" #include "Language.h" +#include "Log.h" +#include "Map.h" #include "Object.h" -#include "BattlegroundMgr.h" +#include "ObjectAccessor.h" #include "Player.h" #include "WorldPacket.h" -#include "ObjectAccessor.h" // these variables aren't used outside of this file, so declare them only here enum BG_WSG_Rewards @@ -69,6 +72,13 @@ BattlegroundWS::BattlegroundWS() _minutesElapsed = 0; } +void BattlegroundWGScore::BuildObjectivesBlock(WorldPacket& data) +{ + data << uint32(2); // Objectives Count + data << uint32(FlagCaptures); + data << uint32(FlagReturns); +} + BattlegroundWS::~BattlegroundWS() { } void BattlegroundWS::PostUpdateImpl(uint32 diff) @@ -804,7 +814,7 @@ bool BattlegroundWS::UpdatePlayerScore(Player* player, uint32 type, uint32 value return true; } -WorldSafeLocsEntry const* BattlegroundWS::GetClosestGraveYard(Player* player) +WorldSafeLocsEntry const* BattlegroundWS::GetClosestGraveyard(Player* player) { //if status in progress, it returns main graveyards with spiritguides //else it will return the graveyard in the flagroom - this is especially good diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h index 6541148843c..c6ab47eb7ba 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.h @@ -170,12 +170,7 @@ struct BattlegroundWGScore final : public BattlegroundScore } } - void BuildObjectivesBlock(WorldPacket& data) final override - { - data << uint32(2); // Objectives Count - data << uint32(FlagCaptures); - data << uint32(FlagReturns); - } + void BuildObjectivesBlock(WorldPacket& data) final override; uint32 GetAttr1() const final override { return FlagCaptures; } uint32 GetAttr2() const final override { return FlagReturns; } @@ -222,7 +217,7 @@ class BattlegroundWS : public Battleground bool SetupBattleground() override; void Reset() override; void EndBattleground(uint32 winner) override; - WorldSafeLocsEntry const* GetClosestGraveYard(Player* player) override; + WorldSafeLocsEntry const* GetClosestGraveyard(Player* player) override; void UpdateFlagState(uint32 team, uint32 value); void SetLastFlagCapture(uint32 team) { _lastFlagCaptureTeam = team; } diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index 4e86fdd1775..08a406c4f15 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -17,12 +17,15 @@ #include "CalendarMgr.h" #include "CharacterCache.h" -#include "QueryResult.h" -#include "Log.h" -#include "Player.h" +#include "DatabaseEnv.h" +#include "Guild.h" #include "GuildMgr.h" +#include "Log.h" +#include "Mail.h" #include "ObjectAccessor.h" #include "Opcodes.h" +#include "Player.h" +#include "WorldPacket.h" CalendarInvite::~CalendarInvite() { @@ -297,7 +300,7 @@ CalendarEvent* CalendarMgr::GetEvent(uint64 eventId) const return *itr; TC_LOG_DEBUG("calendar", "CalendarMgr::GetEvent: [" UI64FMTD "] not found!", eventId); - return NULL; + return nullptr; } CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) const @@ -308,7 +311,7 @@ CalendarInvite* CalendarMgr::GetInvite(uint64 inviteId) const return *itr2; TC_LOG_DEBUG("calendar", "CalendarMgr::GetInvite: [" UI64FMTD "] not found!", inviteId); - return NULL; + return nullptr; } void CalendarMgr::FreeEventId(uint64 id) @@ -618,7 +621,7 @@ void CalendarMgr::SendCalendarClearPendingAction(ObjectGuid guid) } } -void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= NULL*/) +void CalendarMgr::SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param /*= nullptr*/) { if (Player* player = ObjectAccessor::FindConnectedPlayer(guid)) { diff --git a/src/server/game/Calendar/CalendarMgr.h b/src/server/game/Calendar/CalendarMgr.h index ed590378f59..ded691c241d 100644 --- a/src/server/game/Calendar/CalendarMgr.h +++ b/src/server/game/Calendar/CalendarMgr.h @@ -19,9 +19,14 @@ #define TRINITY_CALENDARMGR_H #include "Common.h" -#include "DatabaseEnv.h" -#include "WorldPacket.h" +#include "DatabaseEnvFwd.h" #include "ObjectGuid.h" +#include <deque> +#include <map> +#include <set> +#include <vector> + +class WorldPacket; enum CalendarMailAnswers { @@ -141,7 +146,7 @@ struct TC_GAME_API CalendarInvite _text = calendarInvite.GetText(); } - CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _statusTime(time(NULL)), + CalendarInvite() : _inviteId(1), _eventId(0), _invitee(), _senderGUID(), _statusTime(time(nullptr)), _status(CALENDAR_STATUS_INVITED), _rank(CALENDAR_RANK_PLAYER), _text("") { } CalendarInvite(uint64 inviteId, uint64 eventId, ObjectGuid invitee, ObjectGuid senderGUID, time_t statusTime, @@ -324,7 +329,7 @@ class TC_GAME_API CalendarMgr void SendCalendarEventRemovedAlert(CalendarEvent const& calendarEvent); void SendCalendarEventModeratorStatusAlert(CalendarEvent const& calendarEvent, CalendarInvite const& invite); void SendCalendarClearPendingAction(ObjectGuid guid); - void SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param = NULL); + void SendCalendarCommandResult(ObjectGuid guid, CalendarError err, char const* param = nullptr); void SendPacketToAllEventRelatives(WorldPacket& packet, CalendarEvent const& calendarEvent); }; diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 83f25ddf0b2..fc6b38f0e69 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -17,17 +17,20 @@ */ #include "Channel.h" +#include "AccountMgr.h" #include "ChannelAppenders.h" #include "Chat.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" -#include "ObjectMgr.h" #include "Language.h" +#include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Player.h" #include "SocialMgr.h" #include "World.h" -#include "DatabaseEnv.h" -#include "AccountMgr.h" -#include "Player.h" Channel::Channel(uint32 channelId, uint32 team /*= 0*/, AreaTableEntry const* zoneEntry /*= nullptr*/) : _announceEnabled(false), // no join/leave announces diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index 5c7460f10ec..364bec73a5f 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -20,11 +20,12 @@ #define _CHANNEL_H #include "Common.h" - -#include "WorldSession.h" -#include "WorldPacket.h" +#include "ObjectGuid.h" +#include <map> +#include <unordered_set> class Player; +struct AreaTableEntry; enum ChatNotify { diff --git a/src/server/game/Chat/Channels/ChannelAppenders.h b/src/server/game/Chat/Channels/ChannelAppenders.h index 03daf416f30..a6723ed1f8e 100644 --- a/src/server/game/Chat/Channels/ChannelAppenders.h +++ b/src/server/game/Chat/Channels/ChannelAppenders.h @@ -20,6 +20,8 @@ #include "Channel.h" #include "CharacterCache.h" +#include "World.h" +#include "WorldPacket.h" // initial packet data (notify type and channel name) template<class PacketModifier> @@ -185,10 +187,7 @@ struct ChannelOwnerAppend { explicit ChannelOwnerAppend(Channel const* channel, ObjectGuid const& ownerGuid) : _channel(channel), _ownerGuid(ownerGuid) { - CharacterCacheEntry const* cInfo = sCharacterCache->GetCharacterCacheByGuid(_ownerGuid); - if (!cInfo || cInfo->Name.empty()) - _ownerName = "PLAYER_NOT_FOUND"; - else + if (CharacterCacheEntry const* cInfo = sCharacterCache->GetCharacterCacheByGuid(_ownerGuid)) _ownerName = cInfo->Name; } diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp index 86328202737..48fd564af28 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.cpp +++ b/src/server/game/Chat/Channels/ChannelMgr.cpp @@ -18,8 +18,10 @@ #include "Channel.h" #include "ChannelMgr.h" +#include "DBCStores.h" #include "Player.h" #include "World.h" +#include "WorldSession.h" ChannelMgr::~ChannelMgr() { diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h index ff1c7d6fd31..5482c3e2e1c 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.h +++ b/src/server/game/Chat/Channels/ChannelMgr.h @@ -18,9 +18,15 @@ #ifndef __TRINITY_CHANNELMGR_H #define __TRINITY_CHANNELMGR_H -#include "Common.h" +#include "Define.h" +#include "Hash.h" +#include <string> +#include <unordered_map> class Channel; +class Player; +class WorldPacket; +struct AreaTableEntry; class TC_GAME_API ChannelMgr { diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 3926dda13f5..3e15ecc9319 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -16,22 +16,28 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "ObjectMgr.h" -#include "World.h" -#include "WorldSession.h" -#include "DatabaseEnv.h" - +#include "Chat.h" #include "AccountMgr.h" #include "CellImpl.h" #include "CharacterCache.h" -#include "Chat.h" +#include "ChatLink.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "GridNotifiersImpl.h" #include "Language.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Optional.h" #include "Player.h" +#include "Realm.h" #include "ScriptMgr.h" -#include "ChatLink.h" +#include "World.h" + +ChatCommand::ChatCommand(char const* name, uint32 permission, bool allowConsole, pHandler handler, std::string help, std::vector<ChatCommand> childCommands /*= std::vector<ChatCommand>()*/) + : Name(ASSERT_NOTNULL(name)), Permission(permission), AllowConsole(allowConsole), Handler(handler), Help(std::move(help)), ChildCommands(std::move(childCommands)) +{ +} // Lazy loading of the command table cache from commands and the // ScriptMgr should be thread safe since the player commands, @@ -80,6 +86,16 @@ bool ChatHandler::isAvailable(ChatCommand const& cmd) const return HasPermission(cmd.Permission); } +bool ChatHandler::HasPermission(uint32 permission) const +{ + return m_session->HasPermission(permission); +} + +std::string ChatHandler::GetNameLink() const +{ + return GetNameLink(m_session->GetPlayer()); +} + bool ChatHandler::HasLowerSecurity(Player* target, ObjectGuid guid, bool strong) { WorldSession* target_session = nullptr; diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 9bbe908fa0b..f2ab3772a0d 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -19,20 +19,21 @@ #ifndef TRINITYCORE_CHAT_H #define TRINITYCORE_CHAT_H +#include "Common.h" +#include "ObjectGuid.h" #include "SharedDefines.h" #include "StringFormat.h" -#include "WorldSession.h" -#include "RBAC.h" - #include <vector> class ChatHandler; class Creature; +class GameObject; class Group; class Player; class Unit; class WorldSession; class WorldObject; +class WorldPacket; struct GameTele; @@ -41,8 +42,7 @@ class TC_GAME_API ChatCommand typedef bool(*pHandler)(ChatHandler*, char const*); public: - ChatCommand(char const* name, uint32 permission, bool allowConsole, pHandler handler, std::string help, std::vector<ChatCommand> childCommands = std::vector<ChatCommand>()) - : Name(ASSERT_NOTNULL(name)), Permission(permission), AllowConsole(allowConsole), Handler(handler), Help(std::move(help)), ChildCommands(std::move(childCommands)) { } + ChatCommand(char const* name, uint32 permission, bool allowConsole, pHandler handler, std::string help, std::vector<ChatCommand> childCommands = std::vector<ChatCommand>()); char const* Name; uint32 Permission; // function pointer required correct align (use uint32) @@ -105,8 +105,8 @@ class TC_GAME_API ChatHandler // function with different implementation for chat/console virtual bool isAvailable(ChatCommand const& cmd) const; - virtual bool HasPermission(uint32 permission) const { return m_session->HasPermission(permission); } - virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); } + virtual bool HasPermission(uint32 permission) const; + virtual std::string GetNameLink() const; virtual bool needReportToTarget(Player* chr) const; virtual LocaleConstant GetSessionDbcLocale() const; virtual int GetSessionDbLocaleIndex() const; diff --git a/src/server/game/Chat/ChatLink.cpp b/src/server/game/Chat/ChatLink.cpp index 126124e2f07..db07e9e2efd 100644 --- a/src/server/game/Chat/ChatLink.cpp +++ b/src/server/game/Chat/ChatLink.cpp @@ -16,11 +16,12 @@ */ #include "ChatLink.h" -#include "SpellMgr.h" +#include "AchievementMgr.h" +#include "DBCStores.h" +#include "Log.h" #include "ObjectMgr.h" #include "SpellInfo.h" -#include "DBCStores.h" -#include "AchievementMgr.h" +#include "SpellMgr.h" // Supported shift-links (client generated and server side) // |color|Hachievement:achievement_id:player_guid:0:0:0:0:0:0:0:0|h[name]|h|r diff --git a/src/server/game/Chat/ChatLink.h b/src/server/game/Chat/ChatLink.h index c801deffe48..83864e58520 100644 --- a/src/server/game/Chat/ChatLink.h +++ b/src/server/game/Chat/ChatLink.h @@ -19,8 +19,10 @@ #define TRINITYCORE_CHATLINK_H #include "SharedDefines.h" -#include <sstream> +#include "Common.h" #include <list> +#include <sstream> +#include <vector> #include <cstring> struct ItemLocale; diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index c858314dc16..005e8fad2a8 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -44,7 +44,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float return threat; if (Player* modOwner = hatedUnit->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_THREAT>(threatSpell->Id, threat); + modOwner->ApplySpellMod(threatSpell->Id, SPELLMOD_THREAT, threat); } return hatedUnit->ApplyTotalThreatModifier(threat, schoolMask); @@ -266,7 +266,7 @@ void ThreatContainer::clearReferences() HostileReference* ThreatContainer::getReferenceByTarget(Unit* victim) const { if (!victim) - return NULL; + return nullptr; ObjectGuid guid = victim->GetGUID(); for (ThreatContainer::StorageType::const_iterator i = iThreatList.begin(); i != iThreatList.end(); ++i) @@ -276,7 +276,7 @@ HostileReference* ThreatContainer::getReferenceByTarget(Unit* victim) const return ref; } - return NULL; + return nullptr; } //============================================================ @@ -315,7 +315,7 @@ void ThreatContainer::update() HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileReference* currentVictim) const { - HostileReference* currentRef = NULL; + HostileReference* currentRef = nullptr; bool found = false; bool noPriorityTargetFound = false; @@ -380,7 +380,7 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileR ++iter; } if (!found) - currentRef = NULL; + currentRef = nullptr; return currentRef; } @@ -389,7 +389,7 @@ HostileReference* ThreatContainer::selectNextVictim(Creature* attacker, HostileR //=================== ThreatManager ========================== //============================================================ -ThreatManager::ThreatManager(Unit* owner) : iCurrentVictim(NULL), iOwner(owner), iUpdateTimer(THREAT_UPDATE_INTERVAL) { } +ThreatManager::ThreatManager(Unit* owner) : iCurrentVictim(nullptr), iOwner(owner), iUpdateTimer(THREAT_UPDATE_INTERVAL) { } //============================================================ @@ -397,7 +397,7 @@ void ThreatManager::clearReferences() { iThreatContainer.clearReferences(); iThreatOfflineContainer.clearReferences(); - iCurrentVictim = NULL; + iCurrentVictim = nullptr; iUpdateTimer = THREAT_UPDATE_INTERVAL; } @@ -465,7 +465,7 @@ Unit* ThreatManager::getHostilTarget() iThreatContainer.update(); HostileReference* nextVictim = iThreatContainer.selectNextVictim(GetOwner()->ToCreature(), getCurrentVictim()); setCurrentVictim(nextVictim); - return getCurrentVictim() != NULL ? getCurrentVictim()->getTarget() : NULL; + return getCurrentVictim() != nullptr ? getCurrentVictim()->getTarget() : nullptr; } //============================================================ @@ -535,7 +535,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat { if (hostilRef == getCurrentVictim()) { - setCurrentVictim(NULL); + setCurrentVictim(nullptr); setDirty(true); } iOwner->SendRemoveFromThreatListOpcode(hostilRef); @@ -553,7 +553,7 @@ void ThreatManager::processThreatEvent(ThreatRefStatusChangeEvent* threatRefStat case UEV_THREAT_REF_REMOVE_FROM_LIST: if (hostilRef == getCurrentVictim()) { - setCurrentVictim(NULL); + setCurrentVictim(nullptr); setDirty(true); } iOwner->SendRemoveFromThreatListOpcode(hostilRef); diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h index e17a6926ffd..c500663214e 100644 --- a/src/server/game/Combat/ThreatManager.h +++ b/src/server/game/Combat/ThreatManager.h @@ -212,7 +212,7 @@ class TC_GAME_API ThreatManager void clearReferences(); - void addThreat(Unit* victim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL); + void addThreat(Unit* victim, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr); void doAddThreat(Unit* victim, float threat); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 4d7146b1f3c..146d2cb3bde 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -18,16 +18,21 @@ #include "ConditionMgr.h" #include "AchievementMgr.h" +#include "DatabaseEnv.h" #include "GameEventMgr.h" +#include "GameObject.h" #include "InstanceScript.h" +#include "Log.h" +#include "LootMgr.h" +#include "Map.h" #include "ObjectMgr.h" #include "Player.h" #include "Pet.h" #include "ReputationMgr.h" -#include "ScriptedCreature.h" #include "ScriptMgr.h" #include "SpellAuras.h" #include "SpellMgr.h" +#include "World.h" char const* const ConditionMgr::StaticSourceTypeData[CONDITION_SOURCE_TYPE_MAX] = { @@ -289,12 +294,12 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) const } case CONDITION_NEAR_CREATURE: { - condMeets = GetClosestCreatureWithEntry(object, ConditionValue1, (float)ConditionValue2, bool(!ConditionValue3)) ? true : false; + condMeets = object->FindNearestCreature(ConditionValue1, (float)ConditionValue2, bool(!ConditionValue3)) != nullptr; break; } case CONDITION_NEAR_GAMEOBJECT: { - condMeets = GetClosestGameObjectWithEntry(object, ConditionValue1, (float)ConditionValue2) ? true : false; + condMeets = object->FindNearestGameObject(ConditionValue1, (float)ConditionValue2) != nullptr; break; } case CONDITION_OBJECT_ENTRY_GUID: @@ -1073,7 +1078,7 @@ void ConditionMgr::LoadConditions(bool isReload) } cond->ReferenceId = uint32(abs(iConditionTypeOrReference)); - const char* rowType = "reference template"; + char const* rowType = "reference template"; if (iSourceTypeOrReferenceId >= 0) rowType = "reference"; //check for useless data diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 6e9086d45f7..ff3f096abae 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -19,7 +19,11 @@ #ifndef TRINITY_CONDITIONMGR_H #define TRINITY_CONDITIONMGR_H -#include "Common.h" +#include "Define.h" +#include "Hash.h" +#include <array> +#include <unordered_map> +#include <vector> class Creature; class Player; diff --git a/src/server/game/Conditions/DisableMgr.cpp b/src/server/game/Conditions/DisableMgr.cpp index c121cb2c15e..747ea936673 100644 --- a/src/server/game/Conditions/DisableMgr.cpp +++ b/src/server/game/Conditions/DisableMgr.cpp @@ -18,10 +18,13 @@ #include "DisableMgr.h" #include "AchievementMgr.h" +#include "DatabaseEnv.h" +#include "Log.h" #include "ObjectMgr.h" #include "OutdoorPvP.h" -#include "SpellMgr.h" #include "Player.h" +#include "SpellMgr.h" +#include "VMapManager2.h" #include "World.h" namespace DisableMgr @@ -391,13 +394,13 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags bool IsVMAPDisabledFor(uint32 entry, uint8 flags) { - return IsDisabledFor(DISABLE_TYPE_VMAP, entry, NULL, flags); + return IsDisabledFor(DISABLE_TYPE_VMAP, entry, nullptr, flags); } bool IsPathfindingEnabled(uint32 mapId) { return sWorld->getBoolConfig(CONFIG_ENABLE_MMAPS) - && !IsDisabledFor(DISABLE_TYPE_MMAP, mapId, NULL, MMAP_DISABLE_PATHFINDING); + && !IsDisabledFor(DISABLE_TYPE_MMAP, mapId, nullptr, MMAP_DISABLE_PATHFINDING); } } // Namespace diff --git a/src/server/game/Conditions/DisableMgr.h b/src/server/game/Conditions/DisableMgr.h index c7172b2ec23..ea76481c977 100644 --- a/src/server/game/Conditions/DisableMgr.h +++ b/src/server/game/Conditions/DisableMgr.h @@ -19,7 +19,6 @@ #ifndef TRINITY_DISABLEMGR_H #define TRINITY_DISABLEMGR_H -#include "VMapManager2.h" #include "Define.h" class Unit; diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index b8e429c0d14..f7d3fe325dc 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -19,6 +19,9 @@ #ifndef DBCENUMS_H #define DBCENUMS_H +#include "Define.h" +#include <array> + #pragma pack(push, 1) struct DBCPosition2D @@ -115,7 +118,7 @@ enum AchievementCriteriaFlags ACHIEVEMENT_CRITERIA_FLAG_MONEY_COUNTER = 0x00000020 // Displays counter as money }; -enum AchievementCriteriaTimedTypes +enum AchievementCriteriaTimedTypes : uint8 { ACHIEVEMENT_TIMED_TYPE_EVENT = 1, // Timer is started by internal event with id in timerStartEvent ACHIEVEMENT_TIMED_TYPE_QUEST = 2, // Timer is started by accepting quest with entry in timerStartEvent @@ -127,7 +130,7 @@ enum AchievementCriteriaTimedTypes ACHIEVEMENT_TIMED_TYPE_MAX }; -enum AchievementCriteriaTypes +enum AchievementCriteriaTypes : uint8 { ACHIEVEMENT_CRITERIA_TYPE_KILL_CREATURE = 0, ACHIEVEMENT_CRITERIA_TYPE_WIN_BG = 1, @@ -273,7 +276,7 @@ enum AreaFlags AREA_FLAG_NO_FLY_ZONE = 0x20000000 // Marks zones where you cannot fly }; -enum Difficulty +enum Difficulty : uint8 { REGULAR_DIFFICULTY = 0, @@ -383,6 +386,18 @@ enum SpellCategoryFlags SPELL_CATEGORY_FLAG_COOLDOWN_STARTS_ON_EVENT = 0x04 }; +#define MAX_SPELL_EFFECTS 3 +#define MAX_EFFECT_MASK 7 +#define MAX_SPELL_REAGENTS 8 + +enum EnchantmentSlotMask +{ + ENCHANTMENT_CAN_SOULBOUND = 0x01, + ENCHANTMENT_UNK1 = 0x02, + ENCHANTMENT_UNK2 = 0x04, + ENCHANTMENT_UNK3 = 0x08 +}; + // SummonProperties.dbc, col 1 enum SummonPropGroup { @@ -415,6 +430,13 @@ enum SummonPropFlags SUMMON_PROP_FLAG_UNK16 = 0x00008000 // Light/Dark Bullet, Soul/Fiery Consumption, Twisted Visage, Twilight Whelp. Phase related? }; +#define MAX_TALENT_RANK 5 +#define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK +#define MAX_TALENT_TABS 3 + +#define TaxiMaskSize 14 +typedef std::array<uint32, TaxiMaskSize> TaxiMask; + enum TotemCategoryType { TOTEM_CATEGORY_TYPE_KNIFE = 1, diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index e4db97cce4c..ce3463c5f5c 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -17,38 +17,26 @@ */ #include "DBCStores.h" +#include "DBCFileLoader.h" +#include "DBCfmt.h" +#include "Errors.h" #include "Log.h" +#include "ObjectDefines.h" +#include "Regex.h" #include "SharedDefines.h" #include "SpellMgr.h" -#include "TransportMgr.h" -#include "DBCfmt.h" #include "Timer.h" -#include "ObjectDefines.h" -#include "Regex.h" -#include <map> +// temporary hack until includes are sorted out (don't want to pull in Windows.h) +#ifdef GetClassName +#undef GetClassName +#endif typedef std::map<uint16, uint32> AreaFlagByAreaID; typedef std::map<uint32, uint32> AreaFlagByMapID; -struct WMOAreaTableTripple -{ - WMOAreaTableTripple(int32 r, int32 a, int32 g) : groupId(g), rootId(r), adtId(a) - { - } - - bool operator <(const WMOAreaTableTripple& b) const - { - return memcmp(this, &b, sizeof(WMOAreaTableTripple))<0; - } - - // ordered by entropy; that way memcmp will have a minimal medium runtime - int32 groupId; - int32 rootId; - int32 adtId; -}; - -typedef std::map<WMOAreaTableTripple, WMOAreaTableEntry const*> WMOAreaInfoByTripple; +typedef std::tuple<int16, int8, int32> WMOAreaTableKey; +typedef std::map<WMOAreaTableKey, WMOAreaTableEntry const*> WMOAreaInfoByTripple; typedef std::multimap<uint32, CharSectionsEntry const*> CharSectionsMap; DBCStorage <AreaTableEntry> sAreaTableStore(AreaTableEntryfmt); @@ -231,18 +219,15 @@ static bool LoadDBC_assert_print(uint32 fsize, uint32 rsize, const std::string& } template<class T> -inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCStorage<T>& storage, std::string const& dbcPath, std::string const& filename, std::string const* customFormat = NULL, std::string const* customIndexName = NULL) +inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCStorage<T>& storage, std::string const& dbcPath, std::string const& filename, std::string const& customFormat = std::string(), std::string const& customIndexName = std::string()) { // compatibility format and C++ structure sizes ASSERT(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()) == sizeof(T) || LoadDBC_assert_print(DBCFileLoader::GetFormatRecordSize(storage.GetFormat()), sizeof(T), filename)); ++DBCFileCount; std::string dbcFilename = dbcPath + filename; - SqlDbc * sql = NULL; - if (customFormat) - sql = new SqlDbc(&filename, customFormat, customIndexName, storage.GetFormat()); - if (storage.Load(dbcFilename.c_str(), sql)) + if (storage.Load(dbcFilename)) { for (uint8 i = 0; i < TOTAL_LOCALES; ++i) { @@ -255,8 +240,11 @@ inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCSt localizedName.append(filename); if (!storage.LoadStringsFrom(localizedName.c_str())) - availableDbcLocales &= ~(1<<i); // mark as not available for speedup next checks + availableDbcLocales &= ~(1 << i); // mark as not available for speedup next checks } + + if (!customFormat.empty()) + storage.LoadFromDB(filename, customFormat, customIndexName); } else { @@ -272,143 +260,176 @@ inline void LoadDBC(uint32& availableDbcLocales, StoreProblemList& errors, DBCSt else errors.push_back(dbcFilename); } - - delete sql; } void LoadDBCStores(const std::string& dataPath) { uint32 oldMSTime = getMSTime(); - std::string dbcPath = dataPath+"dbc/"; + std::string dbcPath = dataPath + "dbc/"; StoreProblemList bad_dbc_files; uint32 availableDbcLocales = 0xFFFFFFFF; - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTableStore, dbcPath, "AreaTable.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementStore, dbcPath, "Achievement.dbc", &CustomAchievementfmt, &CustomAchievementIndex); - LoadDBC(availableDbcLocales, bad_dbc_files, sAchievementCriteriaStore, dbcPath, "Achievement_Criteria.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaTriggerStore, dbcPath, "AreaTrigger.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaGroupStore, dbcPath, "AreaGroup.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAreaPOIStore, dbcPath, "AreaPOI.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sAuctionHouseStore, dbcPath, "AuctionHouse.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBankBagSlotPricesStore, dbcPath, "BankBagSlotPrices.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBannedAddOnsStore, dbcPath, "BannedAddOns.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBattlemasterListStore, dbcPath, "BattlemasterList.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sBarberShopStyleStore, dbcPath, "BarberShopStyle.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCharStartOutfitStore, dbcPath, "CharStartOutfit.dbc"); - for (uint32 i = 0; i < sCharStartOutfitStore.GetNumRows(); ++i) - if (CharStartOutfitEntry const* outfit = sCharStartOutfitStore.LookupEntry(i)) - sCharStartOutfitMap[outfit->Race | (outfit->Class << 8) | (outfit->Gender << 16)] = outfit; - - LoadDBC(availableDbcLocales, bad_dbc_files, sCharSectionsStore, dbcPath, "CharSections.dbc"); - for (uint32 i = 0; i < sCharSectionsStore.GetNumRows(); ++i) - if (CharSectionsEntry const* entry = sCharSectionsStore.LookupEntry(i)) - if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) //ignore Nonplayable races - sCharSectionMap.insert({ entry->GenType | (entry->Gender << 8) | (entry->Race << 16), entry }); - - LoadDBC(availableDbcLocales, bad_dbc_files, sCharTitlesStore, dbcPath, "CharTitles.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sChatChannelsStore, dbcPath, "ChatChannels.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sChrClassesStore, dbcPath, "ChrClasses.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sChrRacesStore, dbcPath, "ChrRaces.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicCameraStore, dbcPath, "CinematicCamera.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCinematicSequencesStore, dbcPath, "CinematicSequences.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoStore, dbcPath, "CreatureDisplayInfo.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureDisplayInfoExtraStore, dbcPath, "CreatureDisplayInfoExtra.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureFamilyStore, dbcPath, "CreatureFamily.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureModelDataStore, dbcPath, "CreatureModelData.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureSpellDataStore, dbcPath, "CreatureSpellData.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCreatureTypeStore, dbcPath, "CreatureType.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sCurrencyTypesStore, dbcPath, "CurrencyTypes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDestructibleModelDataStore, dbcPath, "DestructibleModelData.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDungeonEncounterStore, dbcPath, "DungeonEncounter.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityCostsStore, dbcPath, "DurabilityCosts.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sDurabilityQualityStore, dbcPath, "DurabilityQuality.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesStore, dbcPath, "Emotes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextStore, dbcPath, "EmotesText.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sEmotesTextSoundStore, dbcPath, "EmotesTextSound.dbc"); - for (uint32 i = 0; i < sEmotesTextSoundStore.GetNumRows(); ++i) - if (EmotesTextSoundEntry const* entry = sEmotesTextSoundStore.LookupEntry(i)) - sEmotesTextSoundMap[EmotesTextSoundKey(entry->EmotesTextId, entry->RaceId, entry->SexId)] = entry; - LoadDBC(availableDbcLocales, bad_dbc_files, sFactionStore, dbcPath, "Faction.dbc"); - for (uint32 i=0; i<sFactionStore.GetNumRows(); ++i) +#define LOAD_DBC(store, file) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file) + + LOAD_DBC(sAreaTableStore, "AreaTable.dbc"); + LOAD_DBC(sAchievementCriteriaStore, "Achievement_Criteria.dbc"); + LOAD_DBC(sAreaTriggerStore, "AreaTrigger.dbc"); + LOAD_DBC(sAreaGroupStore, "AreaGroup.dbc"); + LOAD_DBC(sAreaPOIStore, "AreaPOI.dbc"); + LOAD_DBC(sAuctionHouseStore, "AuctionHouse.dbc"); + LOAD_DBC(sBankBagSlotPricesStore, "BankBagSlotPrices.dbc"); + LOAD_DBC(sBannedAddOnsStore, "BannedAddOns.dbc"); + LOAD_DBC(sBattlemasterListStore, "BattlemasterList.dbc"); + LOAD_DBC(sBarberShopStyleStore, "BarberShopStyle.dbc"); + LOAD_DBC(sCharStartOutfitStore, "CharStartOutfit.dbc"); + LOAD_DBC(sCharSectionsStore, "CharSections.dbc"); + LOAD_DBC(sCharTitlesStore, "CharTitles.dbc"); + LOAD_DBC(sChatChannelsStore, "ChatChannels.dbc"); + LOAD_DBC(sChrClassesStore, "ChrClasses.dbc"); + LOAD_DBC(sChrRacesStore, "ChrRaces.dbc"); + LOAD_DBC(sCinematicCameraStore, "CinematicCamera.dbc"); + LOAD_DBC(sCinematicSequencesStore, "CinematicSequences.dbc"); + LOAD_DBC(sCreatureDisplayInfoStore, "CreatureDisplayInfo.dbc"); + LOAD_DBC(sCreatureDisplayInfoExtraStore, "CreatureDisplayInfoExtra.dbc"); + LOAD_DBC(sCreatureFamilyStore, "CreatureFamily.dbc"); + LOAD_DBC(sCreatureModelDataStore, "CreatureModelData.dbc"); + LOAD_DBC(sCreatureSpellDataStore, "CreatureSpellData.dbc"); + LOAD_DBC(sCreatureTypeStore, "CreatureType.dbc"); + LOAD_DBC(sCurrencyTypesStore, "CurrencyTypes.dbc"); + LOAD_DBC(sDestructibleModelDataStore, "DestructibleModelData.dbc"); + LOAD_DBC(sDungeonEncounterStore, "DungeonEncounter.dbc"); + LOAD_DBC(sDurabilityCostsStore, "DurabilityCosts.dbc"); + LOAD_DBC(sDurabilityQualityStore, "DurabilityQuality.dbc"); + LOAD_DBC(sEmotesStore, "Emotes.dbc"); + LOAD_DBC(sEmotesTextStore, "EmotesText.dbc"); + LOAD_DBC(sEmotesTextSoundStore, "EmotesTextSound.dbc"); + LOAD_DBC(sFactionStore, "Faction.dbc"); + LOAD_DBC(sFactionTemplateStore, "FactionTemplate.dbc"); + LOAD_DBC(sGameObjectDisplayInfoStore, "GameObjectDisplayInfo.dbc"); + LOAD_DBC(sGemPropertiesStore, "GemProperties.dbc"); + LOAD_DBC(sGlyphPropertiesStore, "GlyphProperties.dbc"); + LOAD_DBC(sGlyphSlotStore, "GlyphSlot.dbc"); + LOAD_DBC(sGtBarberShopCostBaseStore, "gtBarberShopCostBase.dbc"); + LOAD_DBC(sGtCombatRatingsStore, "gtCombatRatings.dbc"); + LOAD_DBC(sGtChanceToMeleeCritBaseStore, "gtChanceToMeleeCritBase.dbc"); + LOAD_DBC(sGtChanceToMeleeCritStore, "gtChanceToMeleeCrit.dbc"); + LOAD_DBC(sGtChanceToSpellCritBaseStore, "gtChanceToSpellCritBase.dbc"); + LOAD_DBC(sGtChanceToSpellCritStore, "gtChanceToSpellCrit.dbc"); + LOAD_DBC(sGtNPCManaCostScalerStore, "gtNPCManaCostScaler.dbc"); + LOAD_DBC(sGtOCTClassCombatRatingScalarStore, "gtOCTClassCombatRatingScalar.dbc"); + LOAD_DBC(sGtOCTRegenHPStore, "gtOCTRegenHP.dbc"); + //LOAD_DBC(sGtOCTRegenMPStore, "gtOCTRegenMP.dbc"); -- not used currently + LOAD_DBC(sGtRegenHPPerSptStore, "gtRegenHPPerSpt.dbc"); + LOAD_DBC(sGtRegenMPPerSptStore, "gtRegenMPPerSpt.dbc"); + LOAD_DBC(sHolidaysStore, "Holidays.dbc"); + LOAD_DBC(sItemStore, "Item.dbc"); + LOAD_DBC(sItemBagFamilyStore, "ItemBagFamily.dbc"); + //LOAD_DBC(sItemDisplayInfoStore, "ItemDisplayInfo.dbc"); -- not used currently + //LOAD_DBC(sItemCondExtCostsStore, "ItemCondExtCosts.dbc"); + LOAD_DBC(sItemExtendedCostStore, "ItemExtendedCost.dbc"); + LOAD_DBC(sItemLimitCategoryStore, "ItemLimitCategory.dbc"); + LOAD_DBC(sItemRandomPropertiesStore, "ItemRandomProperties.dbc"); + LOAD_DBC(sItemRandomSuffixStore, "ItemRandomSuffix.dbc"); + LOAD_DBC(sItemSetStore, "ItemSet.dbc"); + LOAD_DBC(sLFGDungeonStore, "LFGDungeons.dbc"); + LOAD_DBC(sLightStore, "Light.dbc"); + LOAD_DBC(sLiquidTypeStore, "LiquidType.dbc"); + LOAD_DBC(sLockStore, "Lock.dbc"); + LOAD_DBC(sMailTemplateStore, "MailTemplate.dbc"); + LOAD_DBC(sMapStore, "Map.dbc"); + LOAD_DBC(sMapDifficultyStore, "MapDifficulty.dbc"); + LOAD_DBC(sMovieStore, "Movie.dbc"); + LOAD_DBC(sNamesProfanityStore, "NamesProfanity.dbc"); + LOAD_DBC(sNamesReservedStore, "NamesReserved.dbc"); + LOAD_DBC(sOverrideSpellDataStore, "OverrideSpellData.dbc"); + LOAD_DBC(sPowerDisplayStore, "PowerDisplay.dbc"); + LOAD_DBC(sPvPDifficultyStore, "PvpDifficulty.dbc"); + LOAD_DBC(sQuestXPStore, "QuestXP.dbc"); + LOAD_DBC(sQuestFactionRewardStore, "QuestFactionReward.dbc"); + LOAD_DBC(sQuestSortStore, "QuestSort.dbc"); + LOAD_DBC(sRandomPropertiesPointsStore, "RandPropPoints.dbc"); + LOAD_DBC(sScalingStatDistributionStore, "ScalingStatDistribution.dbc"); + LOAD_DBC(sScalingStatValuesStore, "ScalingStatValues.dbc"); + LOAD_DBC(sSkillLineStore, "SkillLine.dbc"); + LOAD_DBC(sSkillLineAbilityStore, "SkillLineAbility.dbc"); + LOAD_DBC(sSkillRaceClassInfoStore, "SkillRaceClassInfo.dbc"); + LOAD_DBC(sSkillTiersStore, "SkillTiers.dbc"); + LOAD_DBC(sSoundEntriesStore, "SoundEntries.dbc"); + LOAD_DBC(sSpellCastTimesStore, "SpellCastTimes.dbc"); + LOAD_DBC(sSpellCategoryStore, "SpellCategory.dbc"); + LOAD_DBC(sSpellDurationStore, "SpellDuration.dbc"); + LOAD_DBC(sSpellFocusObjectStore, "SpellFocusObject.dbc"); + LOAD_DBC(sSpellItemEnchantmentStore, "SpellItemEnchantment.dbc"); + LOAD_DBC(sSpellItemEnchantmentConditionStore, "SpellItemEnchantmentCondition.dbc"); + LOAD_DBC(sSpellRadiusStore, "SpellRadius.dbc"); + LOAD_DBC(sSpellRangeStore, "SpellRange.dbc"); + LOAD_DBC(sSpellRuneCostStore, "SpellRuneCost.dbc"); + LOAD_DBC(sSpellShapeshiftStore, "SpellShapeshiftForm.dbc"); + LOAD_DBC(sStableSlotPricesStore, "StableSlotPrices.dbc"); + LOAD_DBC(sSummonPropertiesStore, "SummonProperties.dbc"); + LOAD_DBC(sTalentStore, "Talent.dbc"); + LOAD_DBC(sTalentTabStore, "TalentTab.dbc"); + LOAD_DBC(sTaxiNodesStore, "TaxiNodes.dbc"); + LOAD_DBC(sTaxiPathStore, "TaxiPath.dbc"); + LOAD_DBC(sTaxiPathNodeStore, "TaxiPathNode.dbc"); + LOAD_DBC(sTeamContributionPointsStore, "TeamContributionPoints.dbc"); + LOAD_DBC(sTotemCategoryStore, "TotemCategory.dbc"); + LOAD_DBC(sTransportAnimationStore, "TransportAnimation.dbc"); + LOAD_DBC(sTransportRotationStore, "TransportRotation.dbc"); + LOAD_DBC(sVehicleStore, "Vehicle.dbc"); + LOAD_DBC(sVehicleSeatStore, "VehicleSeat.dbc"); + LOAD_DBC(sWMOAreaTableStore, "WMOAreaTable.dbc"); + LOAD_DBC(sWorldMapAreaStore, "WorldMapArea.dbc"); + LOAD_DBC(sWorldMapOverlayStore, "WorldMapOverlay.dbc"); + LOAD_DBC(sWorldSafeLocsStore, "WorldSafeLocs.dbc"); + +#undef LOAD_DBC + +#define LOAD_DBC_EXT(store, file, dbformat, dbpk) LoadDBC(availableDbcLocales, bad_dbc_files, store, dbcPath, file, dbformat, dbpk) + + LOAD_DBC_EXT(sAchievementStore, "Achievement.dbc", CustomAchievementfmt, CustomAchievementIndex); + LOAD_DBC_EXT(sSpellStore, "Spell.dbc", CustomSpellEntryfmt, CustomSpellEntryIndex); + LOAD_DBC_EXT(sSpellDifficultyStore, "SpellDifficulty.dbc", CustomSpellDifficultyfmt, CustomSpellDifficultyIndex); + +#undef LOAD_DBC_EXT + + for (CharStartOutfitEntry const* outfit : sCharStartOutfitStore) + sCharStartOutfitMap[outfit->Race | (outfit->Class << 8) | (outfit->Gender << 16)] = outfit; + + for (CharSectionsEntry const* entry : sCharSectionsStore) + if (entry->Race && ((1 << (entry->Race - 1)) & RACEMASK_ALL_PLAYABLE) != 0) //ignore Nonplayable races + sCharSectionMap.insert({ entry->GenType | (entry->Gender << 8) | (entry->Race << 16), entry }); + + for (EmotesTextSoundEntry const* entry : sEmotesTextSoundStore) + sEmotesTextSoundMap[EmotesTextSoundKey(entry->EmotesTextId, entry->RaceId, entry->SexId)] = entry; + + for (FactionEntry const* faction : sFactionStore) { - FactionEntry const* faction = sFactionStore.LookupEntry(i); - if (faction && faction->team) + if (faction->team) { - SimpleFactionsList &flist = sFactionTeamMap[faction->team]; - flist.push_back(i); + SimpleFactionsList& flist = sFactionTeamMap[faction->team]; + flist.push_back(faction->ID); } } - LoadDBC(availableDbcLocales, bad_dbc_files, sFactionTemplateStore, dbcPath, "FactionTemplate.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGameObjectDisplayInfoStore, dbcPath, "GameObjectDisplayInfo.dbc"); - for (uint32 i = 0; i < sGameObjectDisplayInfoStore.GetNumRows(); ++i) + for (GameObjectDisplayInfoEntry const* info : sGameObjectDisplayInfoStore) { - if (GameObjectDisplayInfoEntry const* info = sGameObjectDisplayInfoStore.LookupEntry(i)) - { - if (info->maxX < info->minX) - std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); - if (info->maxY < info->minY) - std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); - if (info->maxZ < info->minZ) - std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); - } + if (info->maxX < info->minX) + std::swap(*(float*)(&info->maxX), *(float*)(&info->minX)); + if (info->maxY < info->minY) + std::swap(*(float*)(&info->maxY), *(float*)(&info->minY)); + if (info->maxZ < info->minZ) + std::swap(*(float*)(&info->maxZ), *(float*)(&info->minZ)); } - LoadDBC(availableDbcLocales, bad_dbc_files, sGemPropertiesStore, dbcPath, "GemProperties.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphPropertiesStore, dbcPath, "GlyphProperties.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGlyphSlotStore, dbcPath, "GlyphSlot.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtBarberShopCostBaseStore, dbcPath, "gtBarberShopCostBase.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtCombatRatingsStore, dbcPath, "gtCombatRatings.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritBaseStore, dbcPath, "gtChanceToMeleeCritBase.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToMeleeCritStore, dbcPath, "gtChanceToMeleeCrit.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritBaseStore, dbcPath, "gtChanceToSpellCritBase.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtChanceToSpellCritStore, dbcPath, "gtChanceToSpellCrit.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtNPCManaCostScalerStore, dbcPath, "gtNPCManaCostScaler.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTClassCombatRatingScalarStore, dbcPath, "gtOCTClassCombatRatingScalar.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtOCTRegenHPStore, dbcPath, "gtOCTRegenHP.dbc"); - //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sGtOCTRegenMPStore, dbcPath, "gtOCTRegenMP.dbc"); -- not used currently - LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenHPPerSptStore, dbcPath, "gtRegenHPPerSpt.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sGtRegenMPPerSptStore, dbcPath, "gtRegenMPPerSpt.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sHolidaysStore, dbcPath, "Holidays.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sItemStore, dbcPath, "Item.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemBagFamilyStore, dbcPath, "ItemBagFamily.dbc"); - //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemDisplayInfoStore, dbcPath, "ItemDisplayInfo.dbc"); -- not used currently - //LoadDBC(dbcCount, availableDbcLocales, bad_dbc_files, sItemCondExtCostsStore, dbcPath, "ItemCondExtCosts.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemExtendedCostStore, dbcPath, "ItemExtendedCost.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemLimitCategoryStore, dbcPath, "ItemLimitCategory.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomPropertiesStore, dbcPath, "ItemRandomProperties.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sLFGDungeonStore, dbcPath, "LFGDungeons.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sLightStore, dbcPath, "Light.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sLiquidTypeStore, dbcPath, "LiquidType.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sLockStore, dbcPath, "Lock.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sMailTemplateStore, dbcPath, "MailTemplate.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sMapStore, dbcPath, "Map.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sMapDifficultyStore, dbcPath, "MapDifficulty.dbc"); // fill data - for (uint32 i = 1; i < sMapDifficultyStore.GetNumRows(); ++i) - if (MapDifficultyEntry const* entry = sMapDifficultyStore.LookupEntry(i)) - sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0'); - sMapDifficultyStore.Clear(); - - LoadDBC(availableDbcLocales, bad_dbc_files, sMovieStore, dbcPath, "Movie.dbc"); + for (MapDifficultyEntry const* entry : sMapDifficultyStore) + sMapDifficultyMap[MAKE_PAIR32(entry->MapId, entry->Difficulty)] = MapDifficulty(entry->resetTime, entry->maxPlayers, entry->areaTriggerText[0] != '\0'); - LoadDBC(availableDbcLocales, bad_dbc_files, sNamesProfanityStore, dbcPath, "NamesProfanity.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sNamesReservedStore, dbcPath, "NamesReserved.dbc"); - for (uint32 i = 0; i < sNamesProfanityStore.GetNumRows(); ++i) + for (NamesProfanityEntry const* namesProfanity : sNamesProfanityStore) { - NamesProfanityEntry const* namesProfanity = sNamesProfanityStore.LookupEntry(i); - if (!namesProfanity) - continue; - ASSERT(namesProfanity->Language < TOTAL_LOCALES || namesProfanity->Language == -1); std::wstring wname; ASSERT(Utf8toWStr(namesProfanity->Name, wname)); @@ -420,12 +441,8 @@ void LoadDBCStores(const std::string& dataPath) NamesProfaneValidators[i].emplace_back(wname, Trinity::regex::icase | Trinity::regex::optimize); } - for (uint32 i = 0; i < sNamesReservedStore.GetNumRows(); ++i) + for (NamesReservedEntry const* namesReserved : sNamesReservedStore) { - NamesReservedEntry const* namesReserved = sNamesReservedStore.LookupEntry(i); - if (!namesReserved) - continue; - ASSERT(namesReserved->Language < TOTAL_LOCALES || namesReserved->Language == -1); std::wstring wname; ASSERT(Utf8toWStr(namesReserved->Name, wname)); @@ -437,53 +454,21 @@ void LoadDBCStores(const std::string& dataPath) NamesReservedValidators[i].emplace_back(wname, Trinity::regex::icase | Trinity::regex::optimize); } + for (PvPDifficultyEntry const* entry : sPvPDifficultyStore) + if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) + ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); - LoadDBC(availableDbcLocales, bad_dbc_files, sOverrideSpellDataStore, dbcPath, "OverrideSpellData.dbc"); + for (SkillRaceClassInfoEntry const* entry : sSkillRaceClassInfoStore) + if (sSkillLineStore.LookupEntry(entry->SkillId)) + SkillRaceClassInfoBySkill.emplace(entry->SkillId, entry); - LoadDBC(availableDbcLocales, bad_dbc_files, sPowerDisplayStore, dbcPath, "PowerDisplay.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sPvPDifficultyStore, dbcPath, "PvpDifficulty.dbc"); - for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) - if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) - if (entry->bracketId > MAX_BATTLEGROUND_BRACKETS) - ASSERT(false && "Need update MAX_BATTLEGROUND_BRACKETS by DBC data"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sQuestXPStore, dbcPath, "QuestXP.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sQuestFactionRewardStore, dbcPath, "QuestFactionReward.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sQuestSortStore, dbcPath, "QuestSort.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sRandomPropertiesPointsStore, dbcPath, "RandPropPoints.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatDistributionStore, dbcPath, "ScalingStatDistribution.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sScalingStatValuesStore, dbcPath, "ScalingStatValues.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineStore, dbcPath, "SkillLine.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSkillLineAbilityStore, dbcPath, "SkillLineAbility.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSkillRaceClassInfoStore, dbcPath, "SkillRaceClassInfo.dbc"); - for (uint32 i = 0; i < sSkillRaceClassInfoStore.GetNumRows(); ++i) - if (SkillRaceClassInfoEntry const* entry = sSkillRaceClassInfoStore.LookupEntry(i)) - if (sSkillLineStore.LookupEntry(entry->SkillId)) - SkillRaceClassInfoBySkill.emplace(entry->SkillId, entry); - - LoadDBC(availableDbcLocales, bad_dbc_files, sSkillTiersStore, dbcPath, "SkillTiers.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSoundEntriesStore, dbcPath, "SoundEntries.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellStore, dbcPath, "Spell.dbc", &CustomSpellEntryfmt, &CustomSpellEntryIndex); - - for (uint32 j = 0; j < sSkillLineAbilityStore.GetNumRows(); ++j) + for (SkillLineAbilityEntry const* skillLine : sSkillLineAbilityStore) { - SkillLineAbilityEntry const* skillLine = sSkillLineAbilityStore.LookupEntry(j); - - if (!skillLine) - continue; - SpellEntry const* spellInfo = sSpellStore.LookupEntry(skillLine->spellId); - if (spellInfo && spellInfo->Attributes & SPELL_ATTR0_PASSIVE) { - for (uint32 i = 1; i < sCreatureFamilyStore.GetNumRows(); ++i) + for (CreatureFamilyEntry const* cFamily : sCreatureFamilyStore) { - CreatureFamilyEntry const* cFamily = sCreatureFamilyStore.LookupEntry(i); - if (!cFamily) - continue; - if (skillLine->skillId != cFamily->skillLine[0] && skillLine->skillId != cFamily->skillLine[1]) continue; if (spellInfo->spellLevel) @@ -492,37 +477,17 @@ void LoadDBCStores(const std::string& dataPath) if (skillLine->AutolearnType != SKILL_LINE_ABILITY_LEARNED_ON_SKILL_LEARN) continue; - sPetFamilySpellsStore[i].insert(spellInfo->Id); + sPetFamilySpellsStore[cFamily->ID].insert(spellInfo->Id); } } } - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastTimesStore, dbcPath, "SpellCastTimes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoryStore, dbcPath, "SpellCategory.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDifficultyStore, dbcPath, "SpellDifficulty.dbc", &CustomSpellDifficultyfmt, &CustomSpellDifficultyIndex); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellDurationStore, dbcPath, "SpellDuration.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellFocusObjectStore, dbcPath, "SpellFocusObject.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentStore, dbcPath, "SpellItemEnchantment.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellItemEnchantmentConditionStore, dbcPath, "SpellItemEnchantmentCondition.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRadiusStore, dbcPath, "SpellRadius.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRangeStore, dbcPath, "SpellRange.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellRuneCostStore, dbcPath, "SpellRuneCost.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSpellShapeshiftStore, dbcPath, "SpellShapeshiftForm.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sStableSlotPricesStore, dbcPath, "StableSlotPrices.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sSummonPropertiesStore, dbcPath, "SummonProperties.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sTalentStore, dbcPath, "Talent.dbc"); - // Create Spelldifficulty searcher - for (uint32 i = 0; i < sSpellDifficultyStore.GetNumRows(); ++i) + for (SpellDifficultyEntry const* spellDiff : sSpellDifficultyStore) { - SpellDifficultyEntry const* spellDiff = sSpellDifficultyStore.LookupEntry(i); - if (!spellDiff) - continue; - SpellDifficultyEntry newEntry; memset(newEntry.SpellID, 0, 4*sizeof(uint32)); - for (int x = 0; x < MAX_DIFFICULTY; ++x) + for (uint8 x = 0; x < MAX_DIFFICULTY; ++x) { if (spellDiff->SpellID[x] <= 0 || !sSpellStore.LookupEntry(spellDiff->SpellID[x])) { @@ -536,34 +501,25 @@ void LoadDBCStores(const std::string& dataPath) if (newEntry.SpellID[0] <= 0 || newEntry.SpellID[1] <= 0)//id0-1 must be always set! continue; - for (int x = 0; x < MAX_DIFFICULTY; ++x) + for (uint8 x = 0; x < MAX_DIFFICULTY; ++x) if (newEntry.SpellID[x]) sSpellMgr->SetSpellDifficultyId(uint32(newEntry.SpellID[x]), spellDiff->ID); } // create talent spells set - for (unsigned int i = 0; i < sTalentStore.GetNumRows(); ++i) + for (TalentEntry const* talentInfo : sTalentStore) { - TalentEntry const* talentInfo = sTalentStore.LookupEntry(i); - if (!talentInfo) - continue; - - for (int j = 0; j < MAX_TALENT_RANK; j++) + for (uint8 j = 0; j < MAX_TALENT_RANK; ++j) if (talentInfo->RankID[j]) - sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(i, j); + sTalentSpellPosMap[talentInfo->RankID[j]] = TalentSpellPos(talentInfo->TalentID, j); } - LoadDBC(availableDbcLocales, bad_dbc_files, sTalentTabStore, dbcPath, "TalentTab.dbc"); // prepare fast data access to bit pos of talent ranks for use at inspecting { // now have all max ranks (and then bit amount used for store talent ranks in inspect) - for (uint32 talentTabId = 1; talentTabId < sTalentTabStore.GetNumRows(); ++talentTabId) + for (TalentTabEntry const* talentTabInfo : sTalentTabStore) { - TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentTabId); - if (!talentTabInfo) - continue; - // prevent memory corruption; otherwise cls will become 12 below if ((talentTabInfo->ClassMask & CLASSMASK_ALL_PLAYABLE) == 0) continue; @@ -571,59 +527,48 @@ void LoadDBCStores(const std::string& dataPath) // store class talent tab pages for (uint32 cls = 1; cls < MAX_CLASSES; ++cls) if (talentTabInfo->ClassMask & (1 << (cls - 1))) - sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabId; + sTalentTabPages[cls][talentTabInfo->tabpage] = talentTabInfo->TalentTabID; } } - LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiNodesStore, dbcPath, "TaxiNodes.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathStore, dbcPath, "TaxiPath.dbc"); - for (uint32 i = 1; i < sTaxiPathStore.GetNumRows(); ++i) - if (TaxiPathEntry const* entry = sTaxiPathStore.LookupEntry(i)) - sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); - uint32 pathCount = sTaxiPathStore.GetNumRows(); + for (TaxiPathEntry const* entry : sTaxiPathStore) + sTaxiPathSetBySource[entry->from][entry->to] = TaxiPathBySourceAndDestination(entry->ID, entry->price); - //## TaxiPathNode.dbc ## Loaded only for initialization different structures - LoadDBC(availableDbcLocales, bad_dbc_files, sTaxiPathNodeStore, dbcPath, "TaxiPathNode.dbc"); + uint32 pathCount = sTaxiPathStore.GetNumRows(); // Calculate path nodes count std::vector<uint32> pathLength; pathLength.resize(pathCount); // 0 and some other indexes not used - for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) - if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) - { - if (pathLength[entry->PathID] < entry->NodeIndex + 1) - pathLength[entry->PathID] = entry->NodeIndex + 1; - } + for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore) + { + if (pathLength[entry->PathID] < entry->NodeIndex + 1) + pathLength[entry->PathID] = entry->NodeIndex + 1; + } + // Set path length sTaxiPathNodesByPath.resize(pathCount); // 0 and some other indexes not used for (uint32 i = 1; i < sTaxiPathNodesByPath.size(); ++i) sTaxiPathNodesByPath[i].resize(pathLength[i]); // fill data - for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) - if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) - sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry; + for (TaxiPathNodeEntry const* entry : sTaxiPathNodeStore) + sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry; // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path { std::set<uint32> spellPaths; - for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) - if (SpellEntry const* sInfo = sSpellStore.LookupEntry (i)) - for (int j = 0; j < MAX_SPELL_EFFECTS; ++j) - if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) - spellPaths.insert(sInfo->EffectMiscValue[j]); - - memset(sTaxiNodesMask, 0, sizeof(sTaxiNodesMask)); - memset(sOldContinentsNodesMask, 0, sizeof(sOldContinentsNodesMask)); - memset(sHordeTaxiNodesMask, 0, sizeof(sHordeTaxiNodesMask)); - memset(sAllianceTaxiNodesMask, 0, sizeof(sAllianceTaxiNodesMask)); - memset(sDeathKnightTaxiNodesMask, 0, sizeof(sDeathKnightTaxiNodesMask)); - for (uint32 i = 1; i < sTaxiNodesStore.GetNumRows(); ++i) + for (SpellEntry const* sInfo : sSpellStore) + for (uint8 j = 0; j < MAX_SPELL_EFFECTS; ++j) + if (sInfo->Effect[j] == SPELL_EFFECT_SEND_TAXI) + spellPaths.insert(sInfo->EffectMiscValue[j]); + + sTaxiNodesMask.fill(0); + sOldContinentsNodesMask.fill(0); + sHordeTaxiNodesMask.fill(0); + sAllianceTaxiNodesMask.fill(0); + sDeathKnightTaxiNodesMask.fill(0); + for (TaxiNodesEntry const* node : sTaxiNodesStore) { - TaxiNodesEntry const* node = sTaxiNodesStore.LookupEntry(i); - if (!node) - continue; - - TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(i); + TaxiPathSetBySource::const_iterator src_i = sTaxiPathSetBySource.find(node->ID); if (src_i != sTaxiPathSetBySource.end() && !src_i->second.empty()) { bool ok = false; @@ -642,8 +587,8 @@ void LoadDBCStores(const std::string& dataPath) } // valid taxi network node - uint8 field = (uint8)((i - 1) / 32); - uint32 submask = 1<<((i-1)%32); + uint8 field = (uint8)((node->ID - 1) / 32); + uint32 submask = 1 << ((node->ID - 1) % 32); sTaxiNodesMask[field] |= submask; if (node->MountCreatureID[0] && node->MountCreatureID[0] != 32981) @@ -654,47 +599,17 @@ void LoadDBCStores(const std::string& dataPath) sDeathKnightTaxiNodesMask[field] |= submask; // old continent node (+ nodes virtually at old continents, check explicitly to avoid loading map files for zone info) - if (node->map_id < 2 || i == 82 || i == 83 || i == 93 || i == 94) + if (node->map_id < 2 || node->ID == 82 || node->ID == 83 || node->ID == 93 || node->ID == 94) sOldContinentsNodesMask[field] |= submask; // fix DK node at Ebon Hold and Shadow Vault flight master - if (i == 315 || i == 333) - ((TaxiNodesEntry*)node)->MountCreatureID[1] = 32981; + if (node->ID == 315 || node->ID == 333) + const_cast<TaxiNodesEntry*>(node)->MountCreatureID[1] = 32981; } } - LoadDBC(availableDbcLocales, bad_dbc_files, sTeamContributionPointsStore, dbcPath, "TeamContributionPoints.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sTotemCategoryStore, dbcPath, "TotemCategory.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sTransportAnimationStore, dbcPath, "TransportAnimation.dbc"); - for (uint32 i = 0; i < sTransportAnimationStore.GetNumRows(); ++i) - { - TransportAnimationEntry const* anim = sTransportAnimationStore.LookupEntry(i); - if (!anim) - continue; - - sTransportMgr->AddPathNodeToTransport(anim->TransportEntry, anim->TimeSeg, anim); - } - - LoadDBC(availableDbcLocales, bad_dbc_files, sTransportRotationStore, dbcPath, "TransportRotation.dbc"); - for (uint32 i = 0; i < sTransportRotationStore.GetNumRows(); ++i) - { - TransportRotationEntry const* rot = sTransportRotationStore.LookupEntry(i); - if (!rot) - continue; - - sTransportMgr->AddPathRotationToTransport(rot->TransportEntry, rot->TimeSeg, rot); - } - - LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleStore, dbcPath, "Vehicle.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sVehicleSeatStore, dbcPath, "VehicleSeat.dbc"); - - LoadDBC(availableDbcLocales, bad_dbc_files, sWMOAreaTableStore, dbcPath, "WMOAreaTable.dbc"); - for (uint32 i = 0; i < sWMOAreaTableStore.GetNumRows(); ++i) - if (WMOAreaTableEntry const* entry = sWMOAreaTableStore.LookupEntry(i)) - sWMOAreaInfoByTripple.insert(WMOAreaInfoByTripple::value_type(WMOAreaTableTripple(entry->rootId, entry->adtId, entry->groupId), entry)); - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapAreaStore, dbcPath, "WorldMapArea.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldMapOverlayStore, dbcPath, "WorldMapOverlay.dbc"); - LoadDBC(availableDbcLocales, bad_dbc_files, sWorldSafeLocsStore, dbcPath, "WorldSafeLocs.dbc"); + for (WMOAreaTableEntry const* entry : sWMOAreaTableStore) + sWMOAreaInfoByTripple[WMOAreaTableKey(entry->rootId, entry->adtId, entry->groupId)] = entry; // error checks if (bad_dbc_files.size() >= DBCFileCount) @@ -715,11 +630,11 @@ void LoadDBCStores(const std::string& dataPath) // Check loaded DBC files proper version if (!sAreaTableStore.LookupEntry(4987) || // last area added in 3.3.5a !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.5a - !sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.5a - !sItemStore.LookupEntry(56806) || // last gem property added in 3.3.5a + !sGemPropertiesStore.LookupEntry(1629) || // last gem property added in 3.3.5a + !sItemStore.LookupEntry(56806) || // last client known item added in 3.3.5a !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.5a !sMapStore.LookupEntry(724) || // last map added in 3.3.5a - !sSpellStore.LookupEntry(80864) ) // last client known item added in 3.3.5a + !sSpellStore.LookupEntry(80864) ) // last added spell in 3.3.5a { TC_LOG_ERROR("misc", "You have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); @@ -735,24 +650,24 @@ SimpleFactionsList const* GetFactionTeamList(uint32 faction) if (itr != sFactionTeamMap.end()) return &itr->second; - return NULL; + return nullptr; } char* GetPetName(uint32 petfamily, uint32 dbclang) { if (!petfamily) - return NULL; + return nullptr; CreatureFamilyEntry const* pet_family = sCreatureFamilyStore.LookupEntry(petfamily); if (!pet_family) - return NULL; - return pet_family->Name[dbclang]?pet_family->Name[dbclang]:NULL; + return nullptr; + return pet_family->Name[dbclang]?pet_family->Name[dbclang]:nullptr; } TalentSpellPos const* GetTalentSpellPos(uint32 spellId) { TalentSpellPosMap::const_iterator itr = sTalentSpellPosMap.find(spellId); if (itr == sTalentSpellPosMap.end()) - return NULL; + return nullptr; return &itr->second; } @@ -765,25 +680,25 @@ uint32 GetTalentSpellCost(uint32 spellId) return 0; } - WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, int32 adtid, int32 groupid) { - WMOAreaInfoByTripple::iterator i = sWMOAreaInfoByTripple.find(WMOAreaTableTripple(rootid, adtid, groupid)); - if (i == sWMOAreaInfoByTripple.end()) - return NULL; - return i->second; + auto i = sWMOAreaInfoByTripple.find(WMOAreaTableKey(int16(rootid), int8(adtid), groupid)); + if (i != sWMOAreaInfoByTripple.end()) + return i->second; + + return nullptr; } char const* GetRaceName(uint8 race, uint8 locale) { ChrRacesEntry const* raceEntry = sChrRacesStore.LookupEntry(race); - return raceEntry ? raceEntry->name[locale] : NULL; + return raceEntry ? raceEntry->name[locale] : nullptr; } char const* GetClassName(uint8 class_, uint8 locale) { ChrClassesEntry const* classEntry = sChrClassesStore.LookupEntry(class_); - return classEntry ? classEntry->name[locale] : NULL; + return classEntry ? classEntry->name[locale] : nullptr; } uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId) @@ -864,7 +779,7 @@ void Map2ZoneCoordinates(float& x, float& y, uint32 zone) MapDifficulty const* GetMapDifficultyData(uint32 mapId, Difficulty difficulty) { MapDifficultyMap::const_iterator itr = sMapDifficultyMap.find(MAKE_PAIR32(mapId, difficulty)); - return itr != sMapDifficultyMap.end() ? &itr->second : NULL; + return itr != sMapDifficultyMap.end() ? &itr->second : nullptr; } MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &difficulty) @@ -893,7 +808,7 @@ MapDifficulty const* GetDownscaledMapDifficultyData(uint32 mapId, Difficulty &di PvPDifficultyEntry const* GetBattlegroundBracketByLevel(uint32 mapid, uint32 level) { - PvPDifficultyEntry const* maxEntry = NULL; // used for level > max listed level case + PvPDifficultyEntry const* maxEntry = nullptr; // used for level > max listed level case for (uint32 i = 0; i < sPvPDifficultyStore.GetNumRows(); ++i) { if (PvPDifficultyEntry const* entry = sPvPDifficultyStore.LookupEntry(i)) @@ -922,7 +837,7 @@ PvPDifficultyEntry const* GetBattlegroundBracketById(uint32 mapid, BattlegroundB if (entry->mapId == mapid && entry->GetBracketId() == id) return entry; - return NULL; + return nullptr; } uint32 const* GetTalentTabPages(uint8 cls) @@ -942,7 +857,7 @@ CharStartOutfitEntry const* GetCharStartOutfitEntry(uint8 race, uint8 class_, ui { std::map<uint32, CharStartOutfitEntry const*>::const_iterator itr = sCharStartOutfitMap.find(race | (class_ << 8) | (gender << 16)); if (itr == sCharStartOutfitMap.end()) - return NULL; + return nullptr; return itr->second; } @@ -956,7 +871,7 @@ CharSectionsEntry const* GetCharSectionEntry(uint8 race, CharSectionType genType return itr->second; } - return NULL; + return nullptr; } /// Returns LFGDungeonEntry for a specific map and difficulty. Will return first found entry if multiple dungeons use the same map (such as Scarlet Monastery) @@ -972,7 +887,7 @@ LFGDungeonEntry const* GetLFGDungeon(uint32 mapId, Difficulty difficulty) return dungeon; } - return NULL; + return nullptr; } uint32 GetDefaultMapLight(uint32 mapId) @@ -1003,7 +918,7 @@ SkillRaceClassInfoEntry const* GetSkillRaceClassInfo(uint32 skill, uint8 race, u return itr->second; } - return NULL; + return nullptr; } ResponseCodes ValidateName(std::wstring const& name, LocaleConstant locale) diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 360b0d22b76..846b2b40c1a 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -19,12 +19,19 @@ #ifndef TRINITY_DBCSTORES_H #define TRINITY_DBCSTORES_H -#include "Common.h" #include "DBCStore.h" #include "DBCStructure.h" #include "SharedDefines.h" - #include <list> +#include <map> +#include <unordered_map> + +enum LocaleConstant : uint8; + + // temporary hack until includes are sorted out (don't want to pull in Windows.h) +#ifdef GetClassName +#undef GetClassName +#endif typedef std::list<uint32> SimpleFactionsList; TC_GAME_API SimpleFactionsList const* GetFactionTeamList(uint32 faction); @@ -40,7 +47,7 @@ TC_GAME_API WMOAreaTableEntry const* GetWMOAreaTableEntryByTripple(int32 rootid, TC_GAME_API uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); -enum ContentLevels +enum ContentLevels : uint8 { CONTENT_1_60 = 0, CONTENT_61_70, @@ -186,6 +193,8 @@ TC_GAME_API extern TaxiMask sAllianceTaxiNodesM TC_GAME_API extern TaxiMask sDeathKnightTaxiNodesMask; TC_GAME_API extern TaxiPathSetBySource sTaxiPathSetBySource; TC_GAME_API extern TaxiPathNodesByPath sTaxiPathNodesByPath; +TC_GAME_API extern DBCStorage <TransportAnimationEntry> sTransportAnimationStore; +TC_GAME_API extern DBCStorage <TransportRotationEntry> sTransportRotationStore; TC_GAME_API extern DBCStorage <TeamContributionPointsEntry> sTeamContributionPointsStore; TC_GAME_API extern DBCStorage <TotemCategoryEntry> sTotemCategoryStore; TC_GAME_API extern DBCStorage <VehicleEntry> sVehicleStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 7dc8f91826c..409f1ec25f7 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -19,9 +19,12 @@ #ifndef TRINITY_DBCSTRUCTURE_H #define TRINITY_DBCSTRUCTURE_H -#include "Common.h" +#include "Define.h" #include "DBCEnums.h" +#include "SharedDefines.h" #include "Util.h" +#include <set> +#include <map> // Structures using to access raw DBC data and required packing to portability #pragma pack(push, 1) @@ -501,8 +504,6 @@ struct CreatureModelDataEntry //float Unks[11] }; -#define MAX_CREATURE_SPELL_DATA_SLOT 4 - struct CreatureSpellDataEntry { uint32 ID; // 0 m_ID @@ -1316,10 +1317,6 @@ struct SoundEntriesEntry // 29 new in 3.1 }; -#define MAX_SPELL_EFFECTS 3 -#define MAX_EFFECT_MASK 7 -#define MAX_SPELL_REAGENTS 8 - struct SpellEntry { uint32 Id; // 0 m_ID @@ -1432,7 +1429,7 @@ struct SpellEntry }; typedef std::set<uint32> PetFamilySpellsSet; -typedef std::map<uint32, PetFamilySpellsSet > PetFamilySpellsStore; +typedef std::map<uint32, PetFamilySpellsSet> PetFamilySpellsStore; struct SpellCastTimesEntry { @@ -1564,10 +1561,6 @@ struct SummonPropertiesEntry uint32 Flags; // 5 }; -#define MAX_TALENT_RANK 5 -#define MAX_PET_TALENT_RANK 3 // use in calculations, expected <= MAX_TALENT_RANK -#define MAX_TALENT_TABS 3 - struct TalentEntry { uint32 TalentID; // 0 @@ -1901,7 +1894,5 @@ typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource; typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList; typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; -#define TaxiMaskSize 14 -typedef uint32 TaxiMask[TaxiMaskSize]; #endif diff --git a/src/server/game/DataStores/M2Stores.cpp b/src/server/game/DataStores/M2Stores.cpp index 8594ddb5281..1b9ace510d7 100644 --- a/src/server/game/DataStores/M2Stores.cpp +++ b/src/server/game/DataStores/M2Stores.cpp @@ -16,17 +16,18 @@ */ #include "DBCStores.h" -#include "M2Structure.h" -#include "M2Stores.h" #include "Common.h" #include "Containers.h" #include "Log.h" +#include "M2Structure.h" +#include "M2Stores.h" #include "World.h" +#include <boost/filesystem/path.hpp> #include <fstream> #include <iostream> #include <iomanip> -#include <boost/filesystem/path.hpp> +typedef std::vector<FlyByCamera> FlyByCameraCollection; std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore; // Convert the geomoetry from a spline value, to an actual WoW XYZ @@ -90,10 +91,7 @@ bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, Ci // Add to vector FlyByCamera thisCam; thisCam.timeStamp = targTimestamps[i]; - thisCam.locations.x = newPos.x; - thisCam.locations.y = newPos.y; - thisCam.locations.z = newPos.z; - thisCam.locations.w = 0.0f; + thisCam.locations.Relocate(newPos.x, newPos.y, newPos.z, 0.0f); targetcam.push_back(thisCam); targPositions++; currPos += sizeof(M2SplineKey<G3D::Vector3>); @@ -127,9 +125,7 @@ bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, Ci // Add to vector FlyByCamera thisCam; thisCam.timeStamp = posTimestamps[i]; - thisCam.locations.x = newPos.x; - thisCam.locations.y = newPos.y; - thisCam.locations.z = newPos.z; + thisCam.locations.Relocate(newPos.x, newPos.y, newPos.z); if (targetcam.size() > 0) { @@ -149,28 +145,24 @@ bool readCamera(M2Camera const* cam, uint32 buffSize, M2Header const* header, Ci lastTarget = targetcam[j]; } - float x = lastTarget.locations.x; - float y = lastTarget.locations.y; - float z = lastTarget.locations.z; + float x, y, z; + lastTarget.locations.GetPosition(x, y, z); // Now, the timestamps for target cam and position can be different. So, if they differ we interpolate if (lastTarget.timeStamp != posTimestamps[i]) { uint32 timeDiffTarget = nextTarget.timeStamp - lastTarget.timeStamp; uint32 timeDiffThis = posTimestamps[i] - lastTarget.timeStamp; - float xDiff = nextTarget.locations.x - lastTarget.locations.x; - float yDiff = nextTarget.locations.y - lastTarget.locations.y; - float zDiff = nextTarget.locations.z - lastTarget.locations.z; - x = lastTarget.locations.x + (xDiff * (float(timeDiffThis) / float(timeDiffTarget))); - y = lastTarget.locations.y + (yDiff * (float(timeDiffThis) / float(timeDiffTarget))); - z = lastTarget.locations.z + (zDiff * (float(timeDiffThis) / float(timeDiffTarget))); + float xDiff = nextTarget.locations.GetPositionX() - lastTarget.locations.GetPositionX(); + float yDiff = nextTarget.locations.GetPositionY() - lastTarget.locations.GetPositionY(); + float zDiff = nextTarget.locations.GetPositionZ() - lastTarget.locations.GetPositionZ(); + x = lastTarget.locations.GetPositionX() + (xDiff * (float(timeDiffThis) / float(timeDiffTarget))); + y = lastTarget.locations.GetPositionY() + (yDiff * (float(timeDiffThis) / float(timeDiffTarget))); + z = lastTarget.locations.GetPositionZ() + (zDiff * (float(timeDiffThis) / float(timeDiffTarget))); } - float xDiff = x - thisCam.locations.x; - float yDiff = y - thisCam.locations.y; - thisCam.locations.w = std::atan2(yDiff, xDiff); - - if (thisCam.locations.w < 0) - thisCam.locations.w += 2 * float(M_PI); + float xDiff = x - thisCam.locations.GetPositionX(); + float yDiff = y - thisCam.locations.GetPositionY(); + thisCam.locations.SetOrientation(std::atan2(yDiff, xDiff)); } cameras.push_back(thisCam); @@ -189,78 +181,81 @@ void LoadM2Cameras(std::string const& dataPath) TC_LOG_INFO("server.loading", ">> Loading Cinematic Camera files"); uint32 oldMSTime = getMSTime(); - for (uint32 i = 0; i < sCinematicCameraStore.GetNumRows(); ++i) + for (CinematicCameraEntry const* dbcentry : sCinematicCameraStore) { - if (CinematicCameraEntry const* dbcentry = sCinematicCameraStore.LookupEntry(i)) - { - std::string filenameWork = dataPath; - filenameWork.append(dbcentry->Model); + std::string filenameWork = dataPath; + filenameWork.append(dbcentry->Model); - // Replace slashes (always to forward slash, because boost!) - std::replace(filenameWork.begin(), filenameWork.end(), '\\', '/'); + // Replace slashes (always to forward slash, because boost!) + std::replace(filenameWork.begin(), filenameWork.end(), '\\', '/'); - boost::filesystem::path filename = filenameWork; + boost::filesystem::path filename = filenameWork; - // Convert to native format - filename.make_preferred(); + // Convert to native format + filename.make_preferred(); - // Replace mdx to .m2 - filename.replace_extension("m2"); + // Replace mdx to .m2 + filename.replace_extension("m2"); - std::ifstream m2file(filename.string().c_str(), std::ios::in | std::ios::binary); - if (!m2file.is_open()) - continue; + std::ifstream m2file(filename.string().c_str(), std::ios::in | std::ios::binary); + if (!m2file.is_open()) + continue; - // Get file size - m2file.seekg(0, std::ios::end); - std::streamoff const fileSize = m2file.tellg(); + // Get file size + m2file.seekg(0, std::ios::end); + std::streamoff const fileSize = m2file.tellg(); - // Reject if not at least the size of the header - if (static_cast<uint32 const>(fileSize) < sizeof(M2Header)) - { - TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.string().c_str()); - m2file.close(); - continue; - } - - // Read 4 bytes (signature) - m2file.seekg(0, std::ios::beg); - char fileCheck[5]; - m2file.read(fileCheck, 4); - fileCheck[4] = 0; + // Reject if not at least the size of the header + if (static_cast<uint32 const>(fileSize) < sizeof(M2Header)) + { + TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File is smaller than header size", filename.string().c_str()); + m2file.close(); + continue; + } - // Check file has correct magic (MD20) - if (strcmp(fileCheck, "MD20")) - { - TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found", filename.string().c_str()); - m2file.close(); - continue; - } + // Read 4 bytes (signature) + m2file.seekg(0, std::ios::beg); + char fileCheck[5]; + m2file.read(fileCheck, 4); + fileCheck[4] = 0; - // Now we have a good file, read it all into a vector of char's, then close the file. - std::vector<char> buffer(fileSize); - m2file.seekg(0, std::ios::beg); - if (!m2file.read(buffer.data(), fileSize)) - { - m2file.close(); - continue; - } + // Check file has correct magic (MD20) + if (strcmp(fileCheck, "MD20")) + { + TC_LOG_ERROR("server.loading", "Camera file %s is damaged. File identifier not found", filename.string().c_str()); m2file.close(); + continue; + } - // Read header - M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data()); + // Now we have a good file, read it all into a vector of char's, then close the file. + std::vector<char> buffer(fileSize); + m2file.seekg(0, std::ios::beg); + if (!m2file.read(buffer.data(), fileSize)) + { + m2file.close(); + continue; + } + m2file.close(); - if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize)) - { - TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str()); - continue; - } + // Read header + M2Header const* header = reinterpret_cast<M2Header const*>(buffer.data()); - // Get camera(s) - Main header, then dump them. - M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras); - if (!readCamera(cam, fileSize, header, dbcentry)) - TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str()); + if (header->ofsCameras + sizeof(M2Camera) > static_cast<uint32 const>(fileSize)) + { + TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str()); + continue; } + + // Get camera(s) - Main header, then dump them. + M2Camera const* cam = reinterpret_cast<M2Camera const*>(buffer.data() + header->ofsCameras); + if (!readCamera(cam, fileSize, header, dbcentry)) + TC_LOG_ERROR("server.loading", "Camera file %s is damaged. Camera references position beyond file end", filename.string().c_str()); } + TC_LOG_INFO("server.loading", ">> Loaded %u cinematic waypoint sets in %u ms", (uint32)sFlyByCameraStore.size(), GetMSTimeDiffToNow(oldMSTime)); } + +std::vector<FlyByCamera> const* GetFlyByCameras(uint32 cinematicCameraId) +{ + return Trinity::Containers::MapGetValuePtr(sFlyByCameraStore, cinematicCameraId); +} diff --git a/src/server/game/DataStores/M2Stores.h b/src/server/game/DataStores/M2Stores.h index c76497323a5..b37bff395d5 100644 --- a/src/server/game/DataStores/M2Stores.h +++ b/src/server/game/DataStores/M2Stores.h @@ -18,19 +18,18 @@ #ifndef TRINITY_M2STORES_H #define TRINITY_M2STORES_H -#include "SharedDefines.h" -#include "Common.h" +#include "Define.h" +#include "Position.h" +#include <vector> struct FlyByCamera { uint32 timeStamp; - G3D::Vector4 locations; + Position locations; }; -typedef std::vector<FlyByCamera> FlyByCameraCollection; - -TC_GAME_API extern std::unordered_map<uint32, FlyByCameraCollection> sFlyByCameraStore; - TC_GAME_API void LoadM2Cameras(std::string const& dataPath); +TC_GAME_API std::vector<FlyByCamera> const* GetFlyByCameras(uint32 cinematicCameraId); + #endif
\ No newline at end of file diff --git a/src/server/game/DungeonFinding/LFG.cpp b/src/server/game/DungeonFinding/LFG.cpp index 497db7fd749..b39a304d548 100644 --- a/src/server/game/DungeonFinding/LFG.cpp +++ b/src/server/game/DungeonFinding/LFG.cpp @@ -18,6 +18,7 @@ #include "LFG.h" #include "Language.h" #include "ObjectMgr.h" +#include <sstream> namespace lfg { diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index 3a16c243f46..4d65ebab887 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -18,8 +18,11 @@ #ifndef _LFG_H #define _LFG_H -#include "Common.h" +#include "Define.h" #include "ObjectGuid.h" +#include <map> +#include <set> +#include <string> namespace lfg { diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index bf13095942e..39d30a28c4f 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -15,28 +15,46 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "LFGMgr.h" #include "Common.h" -#include "SharedDefines.h" +#include "DatabaseEnv.h" #include "DBCStores.h" #include "DisableMgr.h" -#include "ObjectMgr.h" -#include "SocialMgr.h" -#include "LFGMgr.h" -#include "LFGScripts.h" +#include "GameEventMgr.h" +#include "Group.h" +#include "GroupMgr.h" +#include "InstanceSaveMgr.h" #include "LFGGroupData.h" #include "LFGPlayerData.h" +#include "LFGScripts.h" #include "LFGQueue.h" -#include "Group.h" +#include "Log.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Player.h" #include "RBAC.h" -#include "GroupMgr.h" -#include "GameEventMgr.h" +#include "SharedDefines.h" +#include "SocialMgr.h" +#include "World.h" #include "WorldSession.h" -#include "InstanceSaveMgr.h" namespace lfg { +LFGDungeonData::LFGDungeonData() : id(0), name(), map(0), type(0), expansion(0), group(0), minlevel(0), + maxlevel(0), difficulty(REGULAR_DIFFICULTY), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f) +{ +} + +LFGDungeonData::LFGDungeonData(LFGDungeonEntry const* dbc) : id(dbc->ID), name(dbc->name[0]), map(dbc->map), + type(dbc->type), expansion(uint8(dbc->expansion)), group(uint8(dbc->grouptype)), + minlevel(uint8(dbc->minlevel)), maxlevel(uint8(dbc->maxlevel)), difficulty(Difficulty(dbc->difficulty)), + seasonal((dbc->flags & LFG_FLAG_SEASONAL) != 0), x(0.0f), y(0.0f), z(0.0f), o(0.0f) +{ +} + LFGMgr::LFGMgr(): m_QueueTimer(0), m_lfgProposalId(1), m_options(sWorld->getIntConfig(CONFIG_LFG_OPTIONSMASK)) { @@ -117,7 +135,7 @@ void LFGMgr::LoadRewards() uint32 count = 0; - Field* fields = NULL; + Field* fields = nullptr; do { fields = result->Fetch(); @@ -164,7 +182,7 @@ LFGDungeonData const* LFGMgr::GetLFGDungeon(uint32 id) if (itr != LfgDungeonStore.end()) return &(itr->second); - return NULL; + return nullptr; } void LFGMgr::LoadLFGDungeons(bool reload /* = false */) @@ -270,7 +288,7 @@ void LFGMgr::Update(uint32 diff) if (!isOptionEnabled(LFG_OPTION_ENABLE_DUNGEON_FINDER | LFG_OPTION_ENABLE_RAID_BROWSER)) return; - time_t currTime = time(NULL); + time_t currTime = time(nullptr); // Remove obsolete role checks for (LfgRoleCheckContainer::iterator it = RoleChecksStore.begin(); it != RoleChecksStore.end();) @@ -424,7 +442,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const else { uint8 memberCount = 0; - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL && joinData.result == LFG_JOIN_OK; itr = itr->next()) + for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr && joinData.result == LFG_JOIN_OK; itr = itr->next()) { if (Player* plrg = itr->GetSource()) { @@ -522,7 +540,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const { // Create new rolecheck LfgRoleCheck& roleCheck = RoleChecksStore[gguid]; - roleCheck.cancelTime = time_t(time(NULL)) + LFG_TIME_ROLECHECK; + roleCheck.cancelTime = time_t(time(nullptr)) + LFG_TIME_ROLECHECK; roleCheck.state = LFG_ROLECHECK_INITIALITING; roleCheck.leader = guid; roleCheck.dungeons = dungeons; @@ -537,7 +555,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const SetState(gguid, LFG_STATE_ROLECHECK); // Send update to player LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_JOIN_QUEUE, dungeons, comment); - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) { if (Player* plrg = itr->GetSource()) { @@ -560,7 +578,7 @@ void LFGMgr::JoinLfg(Player* player, uint8 roles, LfgDungeonSet& dungeons, const LfgRolesMap rolesMap; rolesMap[guid] = roles; LFGQueue& queue = GetQueue(guid); - queue.AddQueueData(guid, time(NULL), dungeons, rolesMap); + queue.AddQueueData(guid, time(nullptr), dungeons, rolesMap); if (!isContinue) { @@ -734,7 +752,7 @@ void LFGMgr::UpdateRoleCheck(ObjectGuid gguid, ObjectGuid guid /* = ObjectGuid:: { SetState(gguid, LFG_STATE_QUEUED); LFGQueue& queue = GetQueue(gguid); - queue.AddQueueData(gguid, time_t(time(NULL)), roleCheck.dungeons, roleCheck.roles); + queue.AddQueueData(gguid, time_t(time(nullptr)), roleCheck.dungeons, roleCheck.roles); RoleChecksStore.erase(itRoleCheck); } else if (roleCheck.state != LFG_ROLECHECK_INITIALITING) @@ -895,7 +913,7 @@ void LFGMgr::MakeNewGroup(LfgProposal const& proposal) LFGDungeonData const* dungeon = GetLFGDungeon(proposal.dungeonId); ASSERT(dungeon); - Group* grp = proposal.group ? sGroupMgr->GetGroupByGUID(proposal.group.GetCounter()) : NULL; + Group* grp = proposal.group ? sGroupMgr->GetGroupByGUID(proposal.group.GetCounter()) : nullptr; for (GuidList::const_iterator it = players.begin(); it != players.end(); ++it) { ObjectGuid pguid = (*it); @@ -997,7 +1015,7 @@ void LFGMgr::UpdateProposal(uint32 proposalId, ObjectGuid guid, bool accept) bool sendUpdate = proposal.state != LFG_PROPOSAL_SUCCESS; proposal.state = LFG_PROPOSAL_SUCCESS; - time_t joinTime = time(NULL); + time_t joinTime = time(nullptr); LFGQueue& queue = GetQueue(guid); LfgUpdateData updateData = LfgUpdateData(LFG_UPDATETYPE_GROUP_FOUND); @@ -1166,7 +1184,7 @@ void LFGMgr::InitBoot(ObjectGuid gguid, ObjectGuid kicker, ObjectGuid victim, st LfgPlayerBoot& boot = BootsStore[gguid]; boot.inProgress = true; - boot.cancelTime = time_t(time(NULL)) + LFG_TIME_BOOT; + boot.cancelTime = time_t(time(nullptr)) + LFG_TIME_BOOT; boot.reason = reason; boot.victim = victim; @@ -1254,7 +1272,7 @@ void LFGMgr::UpdateBoot(ObjectGuid guid, bool accept) */ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false*/) { - LFGDungeonData const* dungeon = NULL; + LFGDungeonData const* dungeon = nullptr; Group* group = player->GetGroup(); if (group && group->isLFGGroup()) @@ -1303,7 +1321,7 @@ void LFGMgr::TeleportPlayer(Player* player, bool out, bool fromOpcode /*= false* if (!fromOpcode) { // Select a player inside to be teleported to - for (GroupReference* itr = group->GetFirstMember(); itr != NULL && !mapid; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr && !mapid; itr = itr->next()) { Player* plrg = itr->GetSource(); if (plrg && plrg != player && plrg->GetMapId() == uint32(dungeon->map)) @@ -1375,7 +1393,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const* } uint32 rDungeonId = 0; - const LfgDungeonSet& dungeons = GetSelectedDungeons(guid); + LfgDungeonSet const& dungeons = GetSelectedDungeons(guid); if (!dungeons.empty()) rDungeonId = (*dungeons.begin()); @@ -1421,7 +1439,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const* // if we can take the quest, means that we haven't done this kind of "run", IE: First Heroic Random of Day. if (player->CanRewardQuest(quest, false)) - player->RewardQuest(quest, 0, NULL, false); + player->RewardQuest(quest, 0, nullptr, false); else { done = true; @@ -1429,7 +1447,7 @@ void LFGMgr::FinishDungeon(ObjectGuid gguid, const uint32 dungeonId, Map const* if (!quest) continue; // we give reward without informing client (retail does this) - player->RewardQuest(quest, 0, NULL, false); + player->RewardQuest(quest, 0, nullptr, false); } // Give rewards @@ -1465,7 +1483,7 @@ LfgDungeonSet const& LFGMgr::GetDungeonsByRandom(uint32 randomdungeon) */ LfgReward const* LFGMgr::GetRandomDungeonReward(uint32 dungeon, uint8 level) { - LfgReward const* rew = NULL; + LfgReward const* rew = nullptr; LfgRewardContainerBounds bounds = RewardMapStore.equal_range(dungeon & 0x00FFFFFF); for (LfgRewardContainer::const_iterator itr = bounds.first; itr != bounds.second; ++itr) { diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index 96f5b2373ff..a3aa15e3a85 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -18,17 +18,20 @@ #ifndef _LFGMGR_H #define _LFGMGR_H -#include "DBCStructure.h" -#include "Field.h" +#include "Common.h" +#include "DatabaseEnvFwd.h" #include "LFG.h" #include "LFGQueue.h" #include "LFGGroupData.h" #include "LFGPlayerData.h" +#include <unordered_map> class Group; class Player; class Quest; class Map; +struct LFGDungeonEntry; +enum Difficulty : uint8; namespace lfg { @@ -265,14 +268,8 @@ struct LfgPlayerBoot struct LFGDungeonData { - LFGDungeonData(): id(0), name(""), map(0), type(0), expansion(0), group(0), minlevel(0), - maxlevel(0), difficulty(REGULAR_DIFFICULTY), seasonal(false), x(0.0f), y(0.0f), z(0.0f), o(0.0f) - { } - LFGDungeonData(LFGDungeonEntry const* dbc): id(dbc->ID), name(dbc->name[0]), map(dbc->map), - type(dbc->type), expansion(dbc->expansion), group(dbc->grouptype), - minlevel(dbc->minlevel), maxlevel(dbc->maxlevel), difficulty(Difficulty(dbc->difficulty)), - seasonal((dbc->flags & LFG_FLAG_SEASONAL) != 0), x(0.0f), y(0.0f), z(0.0f), o(0.0f) - { } + LFGDungeonData(); + LFGDungeonData(LFGDungeonEntry const* dbc); uint32 id; std::string name; diff --git a/src/server/game/DungeonFinding/LFGPlayerData.h b/src/server/game/DungeonFinding/LFGPlayerData.h index 356a0bb3152..dc18c796997 100644 --- a/src/server/game/DungeonFinding/LFGPlayerData.h +++ b/src/server/game/DungeonFinding/LFGPlayerData.h @@ -41,7 +41,7 @@ class TC_GAME_API LfgPlayerData // Queue void SetRoles(uint8 roles); void SetComment(std::string const& comment); - void SetSelectedDungeons(const LfgDungeonSet& dungeons); + void SetSelectedDungeons(LfgDungeonSet const& dungeons); // General LfgState GetState() const; diff --git a/src/server/game/DungeonFinding/LFGQueue.cpp b/src/server/game/DungeonFinding/LFGQueue.cpp index 4cbff1e3307..2843275dfd1 100644 --- a/src/server/game/DungeonFinding/LFGQueue.cpp +++ b/src/server/game/DungeonFinding/LFGQueue.cpp @@ -283,7 +283,7 @@ LfgCompatibilityData* LFGQueue::GetCompatibilityData(std::string const& key) if (itr != CompatibleMapStore.end()) return &(itr->second); - return NULL; + return nullptr; } uint8 LFGQueue::FindGroups() @@ -508,7 +508,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) else { ObjectGuid gguid = *check.begin(); - const LfgQueueData &queue = QueueDataStore[gguid]; + LfgQueueData const& queue = QueueDataStore[gguid]; proposalDungeons = queue.dungeons; proposalRoles = queue.roles; LFGMgr::CheckGroupRoles(proposalRoles); // assing new roles @@ -540,7 +540,7 @@ LfgCompatibility LFGQueue::CheckCompatibility(GuidList check) } // Create a new proposal - proposal.cancelTime = time(NULL) + LFG_TIME_PROPOSAL; + proposal.cancelTime = time(nullptr) + LFG_TIME_PROPOSAL; proposal.state = LFG_PROPOSAL_INITIATING; proposal.leader.Clear(); proposal.dungeonId = Trinity::Containers::SelectRandomContainerElement(proposalDungeons); @@ -674,7 +674,7 @@ std::string LFGQueue::DumpCompatibleInfo(bool full /* = false */) const { o << " ("; bool first = true; - for (const auto& role : itr->second.roles) + for (auto const& role : itr->second.roles) { if (!first) o << "|"; diff --git a/src/server/game/DungeonFinding/LFGQueue.h b/src/server/game/DungeonFinding/LFGQueue.h index 4d5d8849751..474b7a0bbdc 100644 --- a/src/server/game/DungeonFinding/LFGQueue.h +++ b/src/server/game/DungeonFinding/LFGQueue.h @@ -51,7 +51,7 @@ struct LfgCompatibilityData /// Stores player or group queue info struct LfgQueueData { - LfgQueueData(): joinTime(time_t(time(NULL))), tanks(LFG_TANKS_NEEDED), + LfgQueueData(): joinTime(time_t(time(nullptr))), tanks(LFG_TANKS_NEEDED), healers(LFG_HEALERS_NEEDED), dps(LFG_DPS_NEEDED) { } diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 2e442a9720e..a816599e36f 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -19,14 +19,16 @@ * Interaction between core and LFGScripts */ +#include "LFGScripts.h" #include "Common.h" -#include "SharedDefines.h" -#include "Player.h" #include "Group.h" -#include "LFGScripts.h" #include "LFGMgr.h" -#include "ScriptMgr.h" +#include "Log.h" +#include "Map.h" +#include "Player.h" #include "ObjectAccessor.h" +#include "ScriptMgr.h" +#include "SharedDefines.h" #include "WorldSession.h" namespace lfg @@ -93,7 +95,7 @@ void LFGPlayerScript::OnMapChanged(Player* player) return; } - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) if (Player* member = itr->GetSource()) player->GetSession()->SendNameQueryOpcode(member->GetGUID()); diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index faac452bac0..37b29df81fa 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -19,7 +19,10 @@ #include "CharacterCache.h" #include "Common.h" #include "Corpse.h" +#include "Log.h" +#include "Map.h" #include "Player.h" +#include "UpdateData.h" #include "UpdateMask.h" #include "ObjectAccessor.h" #include "DatabaseEnv.h" @@ -34,7 +37,7 @@ Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type m_valuesCount = CORPSE_END; - m_time = time(NULL); + m_time = time(nullptr); lootRecipient = nullptr; } diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index 533a520a515..1d37cdebfff 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -20,9 +20,9 @@ #define TRINITYCORE_CORPSE_H #include "Object.h" -#include "DatabaseEnv.h" +#include "DatabaseEnvFwd.h" #include "GridDefines.h" -#include "LootMgr.h" +#include "Loot.h" enum CorpseType { @@ -67,7 +67,7 @@ class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse> ObjectGuid GetOwnerGUID() const { return GetGuidValue(CORPSE_FIELD_OWNER); } time_t const& GetGhostTime() const { return m_time; } - void ResetGhostTime() { m_time = time(NULL); } + void ResetGhostTime() { m_time = time(nullptr); } CorpseType GetType() const { return m_type; } CellCoord const& GetCellCoord() const { return _cellCoord; } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index ed98f7d70be..ef17eaa07bd 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -28,29 +28,30 @@ #include "GameEventMgr.h" #include "GameTime.h" #include "GossipDef.h" -#include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "GroupMgr.h" #include "InstanceScript.h" #include "Log.h" #include "LootMgr.h" +#include "MotionMaster.h" #include "MoveSpline.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" #include "PoolMgr.h" +#include "QueryPackets.h" #include "QuestDef.h" +#include "ScriptedGossip.h" #include "SpellAuraEffects.h" #include "SpellMgr.h" #include "TemporarySummon.h" +#include "Transport.h" #include "Util.h" #include "Vehicle.h" #include "World.h" #include "WorldPacket.h" -#include "Transport.h" -#include "ScriptedGossip.h" - -#include "Packets/QueryPackets.h" +#include <G3D/g3dmath.h> TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const { @@ -61,27 +62,28 @@ TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const return nullptr; } +bool VendorItem::IsGoldRequired(ItemTemplate const* pProto) const +{ + return (pProto->Flags2 & ITEM_FLAG2_DONT_IGNORE_BUY_PRICE) || !ExtendedCost; +} + bool VendorItemData::RemoveItem(uint32 item_id) { - bool found = false; - for (VendorItemList::iterator i = m_items.begin(); i != m_items.end();) + auto newEnd = std::remove_if(m_items.begin(), m_items.end(), [=](VendorItem const& vendorItem) { - if ((*i)->item == item_id) - { - i = m_items.erase(i++); - found = true; - } - else - ++i; - } + return vendorItem.item == item_id; + }); + + bool found = (newEnd != m_items.end()); + m_items.erase(newEnd, m_items.end()); return found; } VendorItem const* VendorItemData::FindItemCostPair(uint32 item_id, uint32 extendedCost) const { - for (VendorItemList::const_iterator i = m_items.begin(); i != m_items.end(); ++i) - if ((*i)->item == item_id && (*i)->ExtendedCost == extendedCost) - return *i; + for (VendorItem const& vendorItem : m_items) + if (vendorItem.item == item_id && vendorItem.ExtendedCost == extendedCost) + return &vendorItem; return nullptr; } @@ -192,7 +194,7 @@ WorldPacket CreatureTemplate::BuildQueryData(LocaleConstant loc) const for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) queryTemp.Stats.QuestItems[i] = 0; - if (CreatureQuestItemList const* items = sObjectMgr->GetCreatureQuestItemList(Entry)) + if (std::vector<uint32> const* items = sObjectMgr->GetCreatureQuestItemList(Entry)) for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) if (i < items->size()) queryTemp.Stats.QuestItems[i] = (*items)[i]; @@ -333,7 +335,7 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool destroyForNearbyPlayers) if (getDeathState() != CORPSE) return; - m_corpseRemoveTime = time(NULL); + m_corpseRemoveTime = time(nullptr); setDeathState(DEAD); RemoveAllAuras(); loot.clear(); @@ -346,7 +348,7 @@ void Creature::RemoveCorpse(bool setSpawnTime, bool destroyForNearbyPlayers) // Should get removed later, just keep "compatibility" with scripts if (setSpawnTime) - m_respawnTime = std::max<time_t>(time(NULL) + respawnDelay, m_respawnTime); + m_respawnTime = std::max<time_t>(time(nullptr) + respawnDelay, m_respawnTime); // if corpse was removed during falling, the falling will continue and override relocation to respawn position if (IsFalling()) @@ -583,7 +585,7 @@ void Creature::Update(uint32 diff) break; case DEAD: { - time_t now = time(NULL); + time_t now = time(nullptr); if (m_respawnTime <= now) { // First check if there are any scripts that object to us respawning @@ -636,7 +638,7 @@ void Creature::Update(uint32 diff) } else m_groupLootTimer -= diff; } - else if (m_corpseRemoveTime <= time(NULL)) + else if (m_corpseRemoveTime <= time(nullptr)) { RemoveCorpse(false); TC_LOG_DEBUG("entities.unit", "Removing corpse... %u ", GetUInt32Value(OBJECT_FIELD_ENTRY)); @@ -700,7 +702,7 @@ void Creature::Update(uint32 diff) if (m_combatPulseTime == 0) { - Map::PlayerList const &players = GetMap()->GetPlayers(); + Map::PlayerList const& players = GetMap()->GetPlayers(); if (!players.isEmpty()) for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it) { @@ -709,11 +711,11 @@ void Creature::Update(uint32 diff) if (player->IsGameMaster()) continue; - if (player->IsAlive() && this->IsHostileTo(player)) + if (player->IsAlive() && IsHostileTo(player)) { if (CanHaveThreatList()) AddThreat(player, 0.0f); - this->SetInCombatWith(player); + SetInCombatWith(player); player->SetInCombatWith(this); } } @@ -1486,7 +1488,7 @@ bool Creature::LoadCreatureFromDB(ObjectGuid::LowType spawnId, Map* map, bool ad // Is the creature script objecting to us spawning? If yes, delay by one second (then re-check in ::Update) if (!m_respawnTime && !sScriptMgr->CanSpawn(spawnId, GetEntry(), GetCreatureTemplate(), GetCreatureData(), map)) - m_respawnTime = time(NULL)+1; + m_respawnTime = time(nullptr)+1; if (m_respawnTime) // respawn on Update { @@ -1620,7 +1622,7 @@ bool Creature::IsInvisibleDueToDespawn() const if (Unit::IsInvisibleDueToDespawn()) return true; - if (IsAlive() || isDying() || m_corpseRemoveTime > time(NULL)) + if (IsAlive() || isDying() || m_corpseRemoveTime > time(nullptr)) return false; return true; @@ -1739,11 +1741,11 @@ void Creature::setDeathState(DeathState s) if (s == JUST_DIED) { - m_corpseRemoveTime = time(NULL) + m_corpseDelay; + m_corpseRemoveTime = time(nullptr) + m_corpseDelay; if (IsDungeonBoss() && !m_respawnDelay) m_respawnTime = std::numeric_limits<time_t>::max(); // never respawn in this instance else - m_respawnTime = time(NULL) + m_respawnDelay + m_corpseDelay; + m_respawnTime = time(nullptr) + m_respawnDelay + m_corpseDelay; // always save boss respawn time at death to prevent crash cheating if (sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss()) @@ -1910,7 +1912,7 @@ void Creature::ForcedDespawn(uint32 timeMSToDespawn, Seconds const& forceRespawn void Creature::DespawnOrUnsummon(uint32 msTimeToDespawn /*= 0*/, Seconds const& forceRespawnTimer /*= 0*/) { - if (TempSummon* summon = this->ToTempSummon()) + if (TempSummon* summon = ToTempSummon()) summon->UnSummon(msTimeToDespawn); else ForcedDespawn(msTimeToDespawn, forceRespawnTimer); @@ -2162,7 +2164,7 @@ void Creature::CallForHelp(float radius) Cell::VisitGridObjects(this, worker, radius); } -bool Creature::CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction /*= true*/) const +bool Creature::CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction /*= true*/) const { if (IsInEvadeMode()) return false; @@ -2426,7 +2428,7 @@ void Creature::SetInCombatWithZone() return; } - Map::PlayerList const &PlList = map->GetPlayers(); + Map::PlayerList const& PlList = map->GetPlayers(); if (PlList.isEmpty()) return; @@ -2440,7 +2442,7 @@ void Creature::SetInCombatWithZone() if (player->IsAlive()) { - this->SetInCombatWith(player); + SetInCombatWith(player); player->SetInCombatWith(this); AddThreat(player, 0.0f); } @@ -2464,7 +2466,7 @@ bool Creature::HasSpell(uint32 spellID) const time_t Creature::GetRespawnTimeEx() const { - time_t now = time(NULL); + time_t now = time(nullptr); if (m_respawnTime > now) return m_respawnTime; else @@ -2508,7 +2510,7 @@ void Creature::AllLootRemovedFromCorpse() if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId)) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE); - time_t now = time(NULL); + time_t now = time(nullptr); // Do not reset corpse remove time if corpse is already removed if (m_corpseRemoveTime <= now) return; @@ -2576,7 +2578,7 @@ uint32 Creature::GetVendorItemCurrentCount(VendorItem const* vItem) VendorItemCount* vCount = &*itr; - time_t ptime = time(NULL); + time_t ptime = time(nullptr); if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime) if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item)) @@ -2614,7 +2616,7 @@ uint32 Creature::UpdateVendorItemCurrentCount(VendorItem const* vItem, uint32 us VendorItemCount* vCount = &*itr; - time_t ptime = time(NULL); + time_t ptime = time(nullptr); if (time_t(vCount->lastIncrementTime + vItem->incrtime) <= ptime) if (ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(vItem->item)) @@ -2792,7 +2794,7 @@ float Creature::GetAggroRange(Unit const* target) const // Determines the aggro range for creatures (usually pets), used mainly for aggressive pet target selection. // Based on data from wowwiki due to lack of 3.3.5a data - if (target && this->IsPet()) + if (target && IsPet()) { uint32 targetLevel = 0; @@ -2841,7 +2843,7 @@ Unit* Creature::SelectNearestHostileUnitInAggroRange(bool useLOS) const // Selects nearest hostile target within creature's aggro range. Used primarily by // pets set to aggressive. Will not return neutral or friendly targets. - Unit* target = NULL; + Unit* target = nullptr; Trinity::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS); Trinity::UnitSearcher<Trinity::NearestHostileUnitInAggroRangeCheck> searcher(this, target, u_check); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 2e398dcb223..77f383dcfd2 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -19,15 +19,13 @@ #ifndef TRINITYCORE_CREATURE_H #define TRINITYCORE_CREATURE_H -#include "Common.h" #include "Unit.h" -#include "UpdateMask.h" -#include "ItemTemplate.h" -#include "LootMgr.h" -#include "DatabaseEnv.h" -#include "Cell.h" -#include "WorldPacket.h" - +#include "Common.h" +#include "CreatureData.h" +#include "DatabaseEnvFwd.h" +#include "Duration.h" +#include "Loot.h" +#include "MapObject.h" #include <list> class CreatureAI; @@ -37,364 +35,12 @@ class Quest; class Player; class SpellInfo; class WorldSession; - -enum CreatureFlagsExtra : uint32 -{ - CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group - CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility) - CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry - CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry - CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block - CREATURE_FLAG_EXTRA_NO_CRUSH = 0x00000020, // creature can't do crush attacks - CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP - CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature - CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and effect attack me - CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE = 0x00000200, // creature won't update movement flags - CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will be only visible for dead players - CREATURE_FLAG_EXTRA_UNUSED_11 = 0x00000800, - CREATURE_FLAG_EXTRA_UNUSED_12 = 0x00001000, - CREATURE_FLAG_EXTRA_UNUSED_13 = 0x00002000, - CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging) - CREATURE_FLAG_EXTRA_GUARD = 0x00008000, // Creature is guard - CREATURE_FLAG_EXTRA_UNUSED_16 = 0x00010000, - CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes - CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills - CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre - CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // creature is subject to all diminishing returns as player are - CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ = 0x00200000, // creature does not need to take player damage for kill credit - CREATURE_FLAG_EXTRA_UNUSED_22 = 0x00400000, - CREATURE_FLAG_EXTRA_UNUSED_23 = 0x00800000, - CREATURE_FLAG_EXTRA_UNUSED_24 = 0x01000000, - CREATURE_FLAG_EXTRA_UNUSED_25 = 0x02000000, - CREATURE_FLAG_EXTRA_UNUSED_26 = 0x04000000, - CREATURE_FLAG_EXTRA_UNUSED_27 = 0x08000000, - CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB) - CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding - CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects - CREATURE_FLAG_EXTRA_UNUSED_31 = 0x80000000, - - // Masks - CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_11 | CREATURE_FLAG_EXTRA_UNUSED_12 | CREATURE_FLAG_EXTRA_UNUSED_13 | - CREATURE_FLAG_EXTRA_UNUSED_16 | CREATURE_FLAG_EXTRA_UNUSED_22 | CREATURE_FLAG_EXTRA_UNUSED_23 | - CREATURE_FLAG_EXTRA_UNUSED_24 | CREATURE_FLAG_EXTRA_UNUSED_25 | CREATURE_FLAG_EXTRA_UNUSED_26 | - CREATURE_FLAG_EXTRA_UNUSED_27 | CREATURE_FLAG_EXTRA_UNUSED_31), - - CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) -}; - -static const uint32 CREATURE_REGEN_INTERVAL = 2 * IN_MILLISECONDS; -static const uint32 PET_FOCUS_REGEN_INTERVAL = 4 * IN_MILLISECONDS; -static const uint32 CREATURE_NOPATH_EVADE_TIME = 5 * IN_MILLISECONDS; - -static const uint8 MAX_KILL_CREDIT = 2; -static const uint32 MAX_CREATURE_MODELS = 4; -static const uint32 MAX_CREATURE_QUEST_ITEMS = 6; -static const uint32 MAX_CREATURE_SPELLS = 8; - -// from `creature_template` table -struct TC_GAME_API CreatureTemplate -{ - uint32 Entry; - uint32 DifficultyEntry[MAX_DIFFICULTY - 1]; - uint32 KillCredit[MAX_KILL_CREDIT]; - uint32 Modelid1; - uint32 Modelid2; - uint32 Modelid3; - uint32 Modelid4; - std::string Name; - std::string Title; - std::string IconName; - uint32 GossipMenuId; - uint8 minlevel; - uint8 maxlevel; - uint32 expansion; - uint32 faction; - uint32 npcflag; - float speed_walk; - float speed_run; - float scale; - uint32 rank; - uint32 dmgschool; - uint32 BaseAttackTime; - uint32 RangeAttackTime; - float BaseVariance; - float RangeVariance; - uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. - uint32 unit_flags; // enum UnitFlags mask values - uint32 unit_flags2; // enum UnitFlags2 mask values - uint32 dynamicflags; - CreatureFamily family; // enum CreatureFamily values (optional) - uint32 trainer_type; - uint32 trainer_spell; - uint32 trainer_class; - uint32 trainer_race; - uint32 type; // enum CreatureType values - uint32 type_flags; // enum CreatureTypeFlags mask values - uint32 lootid; - uint32 pickpocketLootId; - uint32 SkinLootId; - int32 resistance[MAX_SPELL_SCHOOL]; - uint32 spells[MAX_CREATURE_SPELLS]; - uint32 PetSpellDataId; - uint32 VehicleId; - uint32 mingold; - uint32 maxgold; - std::string AIName; - uint32 MovementType; - uint32 InhabitType; - float HoverHeight; - float ModHealth; - float ModMana; - float ModArmor; - float ModDamage; - float ModExperience; - bool RacialLeader; - uint32 movementId; - bool RegenHealth; - uint32 MechanicImmuneMask; - uint32 flags_extra; - uint32 ScriptID; - WorldPacket QueryData[TOTAL_LOCALES]; - uint32 GetRandomValidModelId() const; - uint32 GetFirstValidModelId() const; - uint32 GetFirstInvisibleModel() const; - uint32 GetFirstVisibleModel() const; - - // helpers - SkillType GetRequiredLootSkill() const - { - if (type_flags & CREATURE_TYPE_FLAG_HERB_SKINNING_SKILL) - return SKILL_HERBALISM; - else if (type_flags & CREATURE_TYPE_FLAG_MINING_SKINNING_SKILL) - return SKILL_MINING; - else if (type_flags & CREATURE_TYPE_FLAG_ENGINEERING_SKINNING_SKILL) - return SKILL_ENGINEERING; - else - return SKILL_SKINNING; // normal case - } - - bool IsExotic() const - { - return (type_flags & CREATURE_TYPE_FLAG_EXOTIC_PET) != 0; - } - - bool IsTameable(bool canTameExotic) const - { - if (type != CREATURE_TYPE_BEAST || family == CREATURE_FAMILY_NONE || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_PET) == 0) - return false; - - // if can tame exotic then can tame any tameable - return canTameExotic || !IsExotic(); - } - - void InitializeQueryData(); - WorldPacket BuildQueryData(LocaleConstant loc) const; -}; - -typedef std::vector<uint32> CreatureQuestItemList; -typedef std::unordered_map<uint32, CreatureQuestItemList> CreatureQuestItemMap; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer; - -#pragma pack(push, 1) - -// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). -struct TC_GAME_API CreatureBaseStats -{ - uint32 BaseHealth[MAX_EXPANSIONS]; - uint32 BaseMana; - uint32 BaseArmor; - uint32 AttackPower; - uint32 RangedAttackPower; - float BaseDamage[MAX_EXPANSIONS]; - - // Helpers - - uint32 GenerateHealth(CreatureTemplate const* info) const - { - return uint32(ceil(BaseHealth[info->expansion] * info->ModHealth)); - } - - uint32 GenerateMana(CreatureTemplate const* info) const - { - // Mana can be 0. - if (!BaseMana) - return 0; - - return uint32(ceil(BaseMana * info->ModMana)); - } - - uint32 GenerateArmor(CreatureTemplate const* info) const - { - return uint32(ceil(BaseArmor * info->ModArmor)); - } - - float GenerateBaseDamage(CreatureTemplate const* info) const - { - return BaseDamage[info->expansion]; - } - - static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass); -}; - -typedef std::unordered_map<uint16, CreatureBaseStats> CreatureBaseStatsContainer; - -struct CreatureLocale -{ - StringVector Name; - StringVector Title; -}; - -struct GossipMenuItemsLocale -{ - StringVector OptionText; - StringVector BoxText; -}; - -struct PointOfInterestLocale -{ - StringVector Name; -}; - -#define MAX_EQUIPMENT_ITEMS 3 - -struct EquipmentInfo -{ - uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]; -}; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map<uint8, EquipmentInfo> EquipmentInfoContainerInternal; -typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> EquipmentInfoContainer; - -// from `creature` table -struct CreatureData -{ - CreatureData() : id(0), mapid(0), phaseMask(0), displayid(0), equipmentId(0), - posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), - spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0), - spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), ScriptId(0), dbData(true) { } - uint32 id; // entry in creature_template - uint16 mapid; - uint32 phaseMask; - uint32 displayid; - int8 equipmentId; - float posX; - float posY; - float posZ; - float orientation; - uint32 spawntimesecs; - float spawndist; - uint32 currentwaypoint; - uint32 curhealth; - uint32 curmana; - uint8 movementType; - uint8 spawnMask; - uint32 npcflag; - uint32 unit_flags; // enum UnitFlags mask values - uint32 dynamicflags; - uint32 ScriptId; - bool dbData; -}; - -struct CreatureModelInfo -{ - float bounding_radius; - float combat_reach; - uint8 gender; - uint32 modelid_other_gender; - bool is_trigger; -}; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map<uint16, CreatureModelInfo> CreatureModelContainer; - -enum InhabitTypeValues -{ - INHABIT_GROUND = 1, - INHABIT_WATER = 2, - INHABIT_AIR = 4, - INHABIT_ROOT = 8, - INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR | INHABIT_ROOT -}; - -// Enums used by StringTextData::Type (CreatureEventAI) -enum ChatType -{ - CHAT_TYPE_SAY = 0, - CHAT_TYPE_YELL = 1, - CHAT_TYPE_TEXT_EMOTE = 2, - CHAT_TYPE_BOSS_EMOTE = 3, - CHAT_TYPE_WHISPER = 4, - CHAT_TYPE_BOSS_WHISPER = 5, - CHAT_TYPE_ZONE_YELL = 6, - CHAT_TYPE_END = 255 -}; - -#pragma pack(pop) - -// `creature_addon` table -struct CreatureAddon -{ - uint32 path_id; - uint32 mount; - uint32 bytes1; - uint32 bytes2; - uint32 emote; - std::vector<uint32> auras; -}; - -typedef std::unordered_map<ObjectGuid::LowType, CreatureAddon> CreatureAddonContainer; -typedef std::unordered_map<uint32, CreatureAddon> CreatureAddonTemplateContainer; - -// Vendors -struct VendorItem -{ - VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost) - : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) { } - - uint32 item; - uint32 maxcount; // 0 for infinity item amount - uint32 incrtime; // time for restore items amount if maxcount != 0 - uint32 ExtendedCost; - - //helpers - bool IsGoldRequired(ItemTemplate const* pProto) const { return (pProto->Flags2 & ITEM_FLAG2_DONT_IGNORE_BUY_PRICE) || !ExtendedCost; } -}; -typedef std::vector<VendorItem*> VendorItemList; - -struct VendorItemData -{ - VendorItemList m_items; - - VendorItem* GetItem(uint32 slot) const - { - if (slot >= m_items.size()) - return NULL; - - return m_items[slot]; - } - bool Empty() const { return m_items.empty(); } - uint8 GetItemCount() const { return m_items.size(); } - void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost) - { - m_items.push_back(new VendorItem(item, maxcount, ptime, ExtendedCost)); - } - bool RemoveItem(uint32 item_id); - VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const; - void Clear() - { - for (VendorItemList::const_iterator itr = m_items.begin(); itr != m_items.end(); ++itr) - delete (*itr); - m_items.clear(); - } -}; +enum MovementGeneratorType : uint8; struct VendorItemCount { - explicit VendorItemCount(uint32 _item, uint32 _count) - : itemId(_item), count(_count), lastIncrementTime(time(NULL)) { } + VendorItemCount(uint32 _item, uint32 _count) + : itemId(_item), count(_count), lastIncrementTime(time(nullptr)) { } uint32 itemId; uint32 count; @@ -403,38 +49,6 @@ struct VendorItemCount typedef std::list<VendorItemCount> VendorItemCounts; -struct TrainerSpell -{ - TrainerSpell() : SpellID(0), MoneyCost(0), ReqSkillLine(0), ReqSkillRank(0), ReqLevel(0) - { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - ReqAbility[i] = 0; - } - - uint32 SpellID; - uint32 MoneyCost; - uint32 ReqSkillLine; - uint32 ReqSkillRank; - uint32 ReqLevel; - uint32 ReqAbility[3]; - - // helpers - bool IsCastable() const { return ReqAbility[0] != SpellID; } -}; - -typedef std::unordered_map<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap; - -struct TC_GAME_API TrainerSpellData -{ - TrainerSpellData() : trainerType(0) { } - ~TrainerSpellData() { spellList.clear(); } - - TrainerSpellMap spellList; - uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value. - // req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2. - TrainerSpell const* Find(uint32 spell_id) const; -}; - // max different by z coordinate for creature aggro reaction #define CREATURE_Z_ATTACK_RANGE 3 @@ -447,7 +61,6 @@ typedef std::unordered_map<uint8, CreatureTextRepeatIds> CreatureTextRepeatGroup class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public MapObject { public: - explicit Creature(bool isWorldObject = false); virtual ~Creature(); @@ -504,7 +117,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma bool IsEvadingAttacks() const { return IsInEvadeMode() || CanNotReachTarget(); } bool AIM_Destroy(); - bool AIM_Initialize(CreatureAI* ai = NULL); + bool AIM_Initialize(CreatureAI* ai = nullptr); void Motion_Initialize(); CreatureAI* AI() const { return reinterpret_cast<CreatureAI*>(i_AI); } @@ -611,8 +224,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma void SetNoCallAssistance(bool val) { m_AlreadyCallAssistance = val; } void SetNoSearchAssistance(bool val) { m_AlreadySearchedAssistance = val; } bool HasSearchedAssistance() const { return m_AlreadySearchedAssistance; } - bool CanAssistTo(const Unit* u, const Unit* enemy, bool checkfaction = true) const; - bool _IsTargetAcceptable(const Unit* target) const; + bool CanAssistTo(Unit const* u, Unit const* enemy, bool checkfaction = true) const; + bool _IsTargetAcceptable(Unit const* target) const; MovementGeneratorType GetDefaultMovementType() const { return m_defaultMovementType; } void SetDefaultMovementType(MovementGeneratorType mgt) { m_defaultMovementType = mgt; } @@ -624,7 +237,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma time_t const& GetRespawnTime() const { return m_respawnTime; } time_t GetRespawnTimeEx() const; - void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(NULL) + respawn : 0; } + void SetRespawnTime(uint32 respawn) { m_respawnTime = respawn ? time(nullptr) + respawn : 0; } void Respawn(bool force = false); void SaveRespawnTime() override; @@ -669,12 +282,12 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma bool CanNotReachTarget() const { return m_cannotReachTarget; } void SetHomePosition(float x, float y, float z, float o) { m_homePosition.Relocate(x, y, z, o); } - void SetHomePosition(const Position &pos) { m_homePosition.Relocate(pos); } + void SetHomePosition(Position const& pos) { m_homePosition.Relocate(pos); } void GetHomePosition(float& x, float& y, float& z, float& ori) const { m_homePosition.GetPosition(x, y, z, ori); } Position const& GetHomePosition() const { return m_homePosition; } void SetTransportHomePosition(float x, float y, float z, float o) { m_transportHomePosition.Relocate(x, y, z, o); } - void SetTransportHomePosition(const Position &pos) { m_transportHomePosition.Relocate(pos); } + void SetTransportHomePosition(Position const& pos) { m_transportHomePosition.Relocate(pos); } void GetTransportHomePosition(float& x, float& y, float& z, float& ori) const { m_transportHomePosition.GetPosition(x, y, z, ori); } Position const& GetTransportHomePosition() const { return m_transportHomePosition; } diff --git a/src/server/game/Entities/Creature/CreatureData.h b/src/server/game/Entities/Creature/CreatureData.h new file mode 100644 index 00000000000..754963f9812 --- /dev/null +++ b/src/server/game/Entities/Creature/CreatureData.h @@ -0,0 +1,370 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CreatureData_h__ +#define CreatureData_h__ + +#include "DBCEnums.h" +#include "SharedDefines.h" +#include "UnitDefines.h" +#include "WorldPacket.h" +#include <string> +#include <unordered_map> +#include <vector> +#include <cmath> + +struct ItemTemplate; + +enum CreatureFlagsExtra : uint32 +{ + CREATURE_FLAG_EXTRA_INSTANCE_BIND = 0x00000001, // creature kill bind instance with killer and killer's group + CREATURE_FLAG_EXTRA_CIVILIAN = 0x00000002, // not aggro (ignore faction/reputation hostility) + CREATURE_FLAG_EXTRA_NO_PARRY = 0x00000004, // creature can't parry + CREATURE_FLAG_EXTRA_NO_PARRY_HASTEN = 0x00000008, // creature can't counter-attack at parry + CREATURE_FLAG_EXTRA_NO_BLOCK = 0x00000010, // creature can't block + CREATURE_FLAG_EXTRA_NO_CRUSH = 0x00000020, // creature can't do crush attacks + CREATURE_FLAG_EXTRA_NO_XP_AT_KILL = 0x00000040, // creature kill not provide XP + CREATURE_FLAG_EXTRA_TRIGGER = 0x00000080, // trigger creature + CREATURE_FLAG_EXTRA_NO_TAUNT = 0x00000100, // creature is immune to taunt auras and effect attack me + CREATURE_FLAG_EXTRA_NO_MOVE_FLAGS_UPDATE = 0x00000200, // creature won't update movement flags + CREATURE_FLAG_EXTRA_GHOST_VISIBILITY = 0x00000400, // creature will be only visible for dead players + CREATURE_FLAG_EXTRA_UNUSED_11 = 0x00000800, + CREATURE_FLAG_EXTRA_UNUSED_12 = 0x00001000, + CREATURE_FLAG_EXTRA_UNUSED_13 = 0x00002000, + CREATURE_FLAG_EXTRA_WORLDEVENT = 0x00004000, // custom flag for world event creatures (left room for merging) + CREATURE_FLAG_EXTRA_GUARD = 0x00008000, // Creature is guard + CREATURE_FLAG_EXTRA_UNUSED_16 = 0x00010000, + CREATURE_FLAG_EXTRA_NO_CRIT = 0x00020000, // creature can't do critical strikes + CREATURE_FLAG_EXTRA_NO_SKILLGAIN = 0x00040000, // creature won't increase weapon skills + CREATURE_FLAG_EXTRA_TAUNT_DIMINISH = 0x00080000, // Taunt is a subject to diminishing returns on this creautre + CREATURE_FLAG_EXTRA_ALL_DIMINISH = 0x00100000, // creature is subject to all diminishing returns as player are + CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ = 0x00200000, // creature does not need to take player damage for kill credit + CREATURE_FLAG_EXTRA_UNUSED_22 = 0x00400000, + CREATURE_FLAG_EXTRA_UNUSED_23 = 0x00800000, + CREATURE_FLAG_EXTRA_UNUSED_24 = 0x01000000, + CREATURE_FLAG_EXTRA_UNUSED_25 = 0x02000000, + CREATURE_FLAG_EXTRA_UNUSED_26 = 0x04000000, + CREATURE_FLAG_EXTRA_UNUSED_27 = 0x08000000, + CREATURE_FLAG_EXTRA_DUNGEON_BOSS = 0x10000000, // creature is a dungeon boss (SET DYNAMICALLY, DO NOT ADD IN DB) + CREATURE_FLAG_EXTRA_IGNORE_PATHFINDING = 0x20000000, // creature ignore pathfinding + CREATURE_FLAG_EXTRA_IMMUNITY_KNOCKBACK = 0x40000000, // creature is immune to knockback effects + CREATURE_FLAG_EXTRA_UNUSED_31 = 0x80000000, + + // Masks + CREATURE_FLAG_EXTRA_UNUSED = (CREATURE_FLAG_EXTRA_UNUSED_11 | CREATURE_FLAG_EXTRA_UNUSED_12 | CREATURE_FLAG_EXTRA_UNUSED_13 | + CREATURE_FLAG_EXTRA_UNUSED_16 | CREATURE_FLAG_EXTRA_UNUSED_22 | CREATURE_FLAG_EXTRA_UNUSED_23 | + CREATURE_FLAG_EXTRA_UNUSED_24 | CREATURE_FLAG_EXTRA_UNUSED_25 | CREATURE_FLAG_EXTRA_UNUSED_26 | + CREATURE_FLAG_EXTRA_UNUSED_27 | CREATURE_FLAG_EXTRA_UNUSED_31), + + CREATURE_FLAG_EXTRA_DB_ALLOWED = (0xFFFFFFFF & ~(CREATURE_FLAG_EXTRA_UNUSED | CREATURE_FLAG_EXTRA_DUNGEON_BOSS)) +}; + +static const uint32 CREATURE_REGEN_INTERVAL = 2 * IN_MILLISECONDS; +static const uint32 PET_FOCUS_REGEN_INTERVAL = 4 * IN_MILLISECONDS; +static const uint32 CREATURE_NOPATH_EVADE_TIME = 5 * IN_MILLISECONDS; + +static const uint8 MAX_KILL_CREDIT = 2; +static const uint32 MAX_CREATURE_MODELS = 4; +static const uint32 MAX_CREATURE_QUEST_ITEMS = 6; +static const uint32 MAX_CREATURE_SPELLS = 8; + +// from `creature_template` table +struct TC_GAME_API CreatureTemplate +{ + uint32 Entry; + uint32 DifficultyEntry[MAX_DIFFICULTY - 1]; + uint32 KillCredit[MAX_KILL_CREDIT]; + uint32 Modelid1; + uint32 Modelid2; + uint32 Modelid3; + uint32 Modelid4; + std::string Name; + std::string Title; + std::string IconName; + uint32 GossipMenuId; + uint8 minlevel; + uint8 maxlevel; + uint32 expansion; + uint32 faction; + uint32 npcflag; + float speed_walk; + float speed_run; + float scale; + uint32 rank; + uint32 dmgschool; + uint32 BaseAttackTime; + uint32 RangeAttackTime; + float BaseVariance; + float RangeVariance; + uint32 unit_class; // enum Classes. Note only 4 classes are known for creatures. + uint32 unit_flags; // enum UnitFlags mask values + uint32 unit_flags2; // enum UnitFlags2 mask values + uint32 dynamicflags; + CreatureFamily family; // enum CreatureFamily values (optional) + uint32 trainer_type; + uint32 trainer_spell; + uint32 trainer_class; + uint32 trainer_race; + uint32 type; // enum CreatureType values + uint32 type_flags; // enum CreatureTypeFlags mask values + uint32 lootid; + uint32 pickpocketLootId; + uint32 SkinLootId; + int32 resistance[MAX_SPELL_SCHOOL]; + uint32 spells[MAX_CREATURE_SPELLS]; + uint32 PetSpellDataId; + uint32 VehicleId; + uint32 mingold; + uint32 maxgold; + std::string AIName; + uint32 MovementType; + uint32 InhabitType; + float HoverHeight; + float ModHealth; + float ModMana; + float ModArmor; + float ModDamage; + float ModExperience; + bool RacialLeader; + uint32 movementId; + bool RegenHealth; + uint32 MechanicImmuneMask; + uint32 flags_extra; + uint32 ScriptID; + WorldPacket QueryData[TOTAL_LOCALES]; + uint32 GetRandomValidModelId() const; + uint32 GetFirstValidModelId() const; + uint32 GetFirstInvisibleModel() const; + uint32 GetFirstVisibleModel() const; + + // helpers + SkillType GetRequiredLootSkill() const + { + if (type_flags & CREATURE_TYPE_FLAG_HERB_SKINNING_SKILL) + return SKILL_HERBALISM; + else if (type_flags & CREATURE_TYPE_FLAG_MINING_SKINNING_SKILL) + return SKILL_MINING; + else if (type_flags & CREATURE_TYPE_FLAG_ENGINEERING_SKINNING_SKILL) + return SKILL_ENGINEERING; + else + return SKILL_SKINNING; // normal case + } + + bool IsExotic() const + { + return (type_flags & CREATURE_TYPE_FLAG_EXOTIC_PET) != 0; + } + + bool IsTameable(bool canTameExotic) const + { + if (type != CREATURE_TYPE_BEAST || family == CREATURE_FAMILY_NONE || (type_flags & CREATURE_TYPE_FLAG_TAMEABLE_PET) == 0) + return false; + + // if can tame exotic then can tame any tameable + return canTameExotic || !IsExotic(); + } + + void InitializeQueryData(); + WorldPacket BuildQueryData(LocaleConstant loc) const; +}; + +#pragma pack(push, 1) + +// Defines base stats for creatures (used to calculate HP/mana/armor/attackpower/rangedattackpower/all damage). +struct TC_GAME_API CreatureBaseStats +{ + uint32 BaseHealth[MAX_EXPANSIONS]; + uint32 BaseMana; + uint32 BaseArmor; + uint32 AttackPower; + uint32 RangedAttackPower; + float BaseDamage[MAX_EXPANSIONS]; + + // Helpers + + uint32 GenerateHealth(CreatureTemplate const* info) const + { + return uint32(ceil(BaseHealth[info->expansion] * info->ModHealth)); + } + + uint32 GenerateMana(CreatureTemplate const* info) const + { + // Mana can be 0. + if (!BaseMana) + return 0; + + return uint32(ceil(BaseMana * info->ModMana)); + } + + uint32 GenerateArmor(CreatureTemplate const* info) const + { + return uint32(ceil(BaseArmor * info->ModArmor)); + } + + float GenerateBaseDamage(CreatureTemplate const* info) const + { + return BaseDamage[info->expansion]; + } + + static CreatureBaseStats const* GetBaseStats(uint8 level, uint8 unitClass); +}; + +struct CreatureLocale +{ + std::vector<std::string> Name; + std::vector<std::string> Title; +}; + +struct EquipmentInfo +{ + uint32 ItemEntry[MAX_EQUIPMENT_ITEMS]; +}; + +// from `creature` table +struct CreatureData +{ + CreatureData() : id(0), mapid(0), phaseMask(0), displayid(0), equipmentId(0), + posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), + spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0), + spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), ScriptId(0), dbData(true) { } + uint32 id; // entry in creature_template + uint16 mapid; + uint32 phaseMask; + uint32 displayid; + int8 equipmentId; + float posX; + float posY; + float posZ; + float orientation; + uint32 spawntimesecs; + float spawndist; + uint32 currentwaypoint; + uint32 curhealth; + uint32 curmana; + uint8 movementType; + uint8 spawnMask; + uint32 npcflag; + uint32 unit_flags; // enum UnitFlags mask values + uint32 dynamicflags; + uint32 ScriptId; + bool dbData; +}; + +struct CreatureModelInfo +{ + float bounding_radius; + float combat_reach; + uint8 gender; + uint32 modelid_other_gender; + bool is_trigger; +}; + +enum InhabitTypeValues +{ + INHABIT_GROUND = 1, + INHABIT_WATER = 2, + INHABIT_AIR = 4, + INHABIT_ROOT = 8, + INHABIT_ANYWHERE = INHABIT_GROUND | INHABIT_WATER | INHABIT_AIR | INHABIT_ROOT +}; + +#pragma pack(pop) + +// `creature_addon` table +struct CreatureAddon +{ + uint32 path_id; + uint32 mount; + uint32 bytes1; + uint32 bytes2; + uint32 emote; + std::vector<uint32> auras; +}; + +// Vendors +struct VendorItem +{ + VendorItem(uint32 _item, int32 _maxcount, uint32 _incrtime, uint32 _ExtendedCost) + : item(_item), maxcount(_maxcount), incrtime(_incrtime), ExtendedCost(_ExtendedCost) { } + + uint32 item; + uint32 maxcount; // 0 for infinity item amount + uint32 incrtime; // time for restore items amount if maxcount != 0 + uint32 ExtendedCost; + + //helpers + bool IsGoldRequired(ItemTemplate const* pProto) const; +}; + +struct VendorItemData +{ + std::vector<VendorItem> m_items; + + VendorItem const* GetItem(uint32 slot) const + { + if (slot >= m_items.size()) + return nullptr; + + return &m_items[slot]; + } + bool Empty() const { return m_items.empty(); } + uint8 GetItemCount() const { return m_items.size(); } + void AddItem(uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost) + { + m_items.emplace_back(item, maxcount, ptime, ExtendedCost); + } + bool RemoveItem(uint32 item_id); + VendorItem const* FindItemCostPair(uint32 item_id, uint32 extendedCost) const; + void Clear() + { + m_items.clear(); + } +}; + +struct TrainerSpell +{ + TrainerSpell() : SpellID(0), MoneyCost(0), ReqSkillLine(0), ReqSkillRank(0), ReqLevel(0) + { + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + ReqAbility[i] = 0; + } + + uint32 SpellID; + uint32 MoneyCost; + uint32 ReqSkillLine; + uint32 ReqSkillRank; + uint32 ReqLevel; + uint32 ReqAbility[3]; + + // helpers + bool IsCastable() const { return ReqAbility[0] != SpellID; } +}; + +typedef std::unordered_map<uint32 /*spellid*/, TrainerSpell> TrainerSpellMap; + +struct TC_GAME_API TrainerSpellData +{ + TrainerSpellData() : trainerType(0) { } + ~TrainerSpellData() { spellList.clear(); } + + TrainerSpellMap spellList; + uint32 trainerType; // trainer type based at trainer spells, can be different from creature_template value. + // req. for correct show non-prof. trainers like weaponmaster, allowed values 0 and 2. + TrainerSpell const* Find(uint32 spell_id) const; +}; + +#endif // CreatureData_h__ diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index c0bdaddb767..0c19bdb502d 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -16,11 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Creature.h" #include "CreatureGroups.h" -#include "ObjectMgr.h" - +#include "Creature.h" #include "CreatureAI.h" +#include "DatabaseEnv.h" +#include "Log.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectMgr.h" #define MAX_DESYNC 5.0f @@ -164,10 +167,10 @@ void CreatureGroup::AddMember(Creature* member) void CreatureGroup::RemoveMember(Creature* member) { if (m_leader == member) - m_leader = NULL; + m_leader = nullptr; m_members.erase(member); - member->SetFormation(NULL); + member->SetFormation(nullptr); } void CreatureGroup::MemberAttackStart(Creature* member, Unit* target) @@ -217,7 +220,7 @@ void CreatureGroup::FormationReset(bool dismiss) m_Formed = !dismiss; } -void CreatureGroup::LeaderMoveTo(Position destination, uint32 id /*= 0*/, uint32 moveType /*= 0*/, bool orientation /*= false*/) +void CreatureGroup::LeaderMoveTo(Position const& destination, uint32 id /*= 0*/, uint32 moveType /*= 0*/, bool orientation /*= false*/) { //! To do: This should probably get its own movement generator or use WaypointMovementGenerator. //! If the leader's path is known, member's path can be plotted as well using formation offsets. diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index ae57d7b9152..ddb8b6876ec 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -20,11 +20,14 @@ #define _FORMATIONS_H #include "Define.h" +#include "ObjectGuid.h" #include <unordered_map> #include <map> class Creature; class CreatureGroup; +class Unit; +struct Position; struct FormationInfo { @@ -65,7 +68,7 @@ class TC_GAME_API CreatureGroup public: //Group cannot be created empty - explicit CreatureGroup(uint32 id) : m_leader(NULL), m_groupID(id), m_Formed(false) { } + explicit CreatureGroup(uint32 id) : m_leader(nullptr), m_groupID(id), m_Formed(false) { } ~CreatureGroup() { } Creature* getLeader() const { return m_leader; } @@ -77,7 +80,7 @@ class TC_GAME_API CreatureGroup void RemoveMember(Creature* member); void FormationReset(bool dismiss); - void LeaderMoveTo(Position destination, uint32 id = 0, uint32 moveType = 0, bool orientation = false); + void LeaderMoveTo(Position const& destination, uint32 id = 0, uint32 moveType = 0, bool orientation = false); void MemberAttackStart(Creature* member, Unit* target); }; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 0c395eb8cad..caa700f6672 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -16,11 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "QuestDef.h" #include "GossipDef.h" +#include "Log.h" #include "ObjectMgr.h" +#include "Player.h" +#include "QuestDef.h" +#include "World.h" #include "WorldSession.h" -#include "Formulas.h" GossipMenu::GossipMenu() { @@ -229,7 +231,7 @@ void PlayerMenu::SendGossipMenu(uint32 titleTextId, ObjectGuid objectGUID) std::string title = quest->GetTitle(); LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) ObjectMgr::GetLocaleString(localeData->Title, localeConstant, title); @@ -263,7 +265,7 @@ void PlayerMenu::SendPointOfInterest(uint32 id) const std::string name = poi->Name; LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (PointOfInterestLocale const* localeData = sObjectMgr->GetPointOfInterestLocale(id)) ObjectMgr::GetLocaleString(localeData->Name, localeConstant, name); @@ -348,7 +350,7 @@ void PlayerMenu::SendQuestGiverQuestList(QEmote const& eEmote, const std::string std::string title = quest->GetTitle(); LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(questID)) ObjectMgr::GetLocaleString(localeData->Title, localeConstant, title); @@ -387,7 +389,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU std::string questAreaDescription = quest->GetAreaDescription(); LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { @@ -506,7 +508,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* quest, ObjectGuid npcGUI std::string questOfferRewardText = quest->GetOfferRewardText(); LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { @@ -603,7 +605,7 @@ void PlayerMenu::SendQuestGiverRequestItems(Quest const* quest, ObjectGuid npcGU std::string requestItemsText = quest->GetRequestItemsText(); LocaleConstant localeConstant = _session->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) { if (QuestLocale const* localeData = sObjectMgr->GetQuestLocale(quest->GetQuestId())) { diff --git a/src/server/game/Entities/Creature/GossipDef.h b/src/server/game/Entities/Creature/GossipDef.h index 9826057361d..cd9d529605f 100644 --- a/src/server/game/Entities/Creature/GossipDef.h +++ b/src/server/game/Entities/Creature/GossipDef.h @@ -21,9 +21,10 @@ #include "Common.h" #include "ObjectGuid.h" -#include "QuestDef.h" #include "NPCHandler.h" +#include <map> +class Quest; class WorldSession; #define GOSSIP_MAX_MENU_ITEMS 32 @@ -192,7 +193,7 @@ class TC_GAME_API GossipMenu if (itr != _menuItems.end()) return &itr->second; - return NULL; + return nullptr; } GossipMenuItemData const* GetItemData(uint32 indexId) const @@ -201,7 +202,7 @@ class TC_GAME_API GossipMenu if (itr != _menuItemData.end()) return &itr->second; - return NULL; + return nullptr; } uint32 GetMenuItemSender(uint32 menuItemId) const; diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index bc433ed2d69..7e9cf6bf7a3 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -16,10 +16,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "TemporarySummon.h" +#include "CreatureAI.h" +#include "DBCStructure.h" #include "Log.h" +#include "Map.h" #include "ObjectAccessor.h" -#include "CreatureAI.h" -#include "TemporarySummon.h" #include "Pet.h" #include "Player.h" @@ -35,12 +37,12 @@ m_timer(0), m_lifetime(0) Unit* TempSummon::GetSummoner() const { - return m_summonerGUID ? ObjectAccessor::GetUnit(*this, m_summonerGUID) : NULL; + return m_summonerGUID ? ObjectAccessor::GetUnit(*this, m_summonerGUID) : nullptr; } Creature* TempSummon::GetSummonerCreatureBase() const { - return m_summonerGUID ? ObjectAccessor::GetCreature(*this, m_summonerGUID) : NULL; + return m_summonerGUID ? ObjectAccessor::GetCreature(*this, m_summonerGUID) : nullptr; } void TempSummon::Update(uint32 diff) @@ -250,7 +252,7 @@ void TempSummon::UnSummon(uint32 msTime) //ASSERT(!IsPet()); if (IsPet()) { - ((Pet*)this)->Remove(PET_SAVE_NOT_IN_SLOT); + ToPet()->Remove(PET_SAVE_NOT_IN_SLOT); ASSERT(!IsInWorld()); return; } @@ -395,6 +397,6 @@ void Puppet::RemoveFromWorld() if (!IsInWorld()) return; - RemoveCharmedBy(NULL); + RemoveCharmedBy(nullptr); Minion::RemoveFromWorld(); } diff --git a/src/server/game/Entities/Creature/TemporarySummon.h b/src/server/game/Entities/Creature/TemporarySummon.h index 50f6c592b9e..50d7f9f712f 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.h +++ b/src/server/game/Entities/Creature/TemporarySummon.h @@ -21,21 +21,7 @@ #include "Creature.h" -enum SummonerType -{ - SUMMONER_TYPE_CREATURE = 0, - SUMMONER_TYPE_GAMEOBJECT = 1, - SUMMONER_TYPE_MAP = 2 -}; - -/// Stores data for temp summons -struct TempSummonData -{ - uint32 entry; ///< Entry of summoned creature - Position pos; ///< Position, where should be creature spawned - TempSummonType type; ///< Summon type, see TempSummonType for available types - uint32 time; ///< Despawn time, usable only with certain temp summon types -}; +struct SummonPropertiesEntry; class TC_GAME_API TempSummon : public Creature { @@ -56,7 +42,7 @@ class TC_GAME_API TempSummon : public Creature TempSummonType const& GetSummonType() { return m_type; } uint32 GetTimer() const { return m_timer; } - const SummonPropertiesEntry* const m_Properties; + SummonPropertiesEntry const* const m_Properties; private: TempSummonType m_type; uint32 m_timer; diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index b9be22478f6..87603080ada 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -16,19 +16,22 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "DynamicObject.h" #include "Common.h" -#include "UpdateMask.h" -#include "World.h" -#include "ObjectAccessor.h" -#include "DatabaseEnv.h" #include "GameTime.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" +#include "Log.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "SpellAuras.h" +#include "SpellMgr.h" #include "ScriptMgr.h" #include "Transport.h" +#include "Unit.h" +#include "UpdateData.h" DynamicObject::DynamicObject(bool isWorldObject) : WorldObject(isWorldObject), - _aura(NULL), _removedAura(NULL), _caster(NULL), _duration(0), _isViewpoint(false) + _aura(nullptr), _removedAura(nullptr), _caster(nullptr), _duration(0), _isViewpoint(false) { m_objectType |= TYPEMASK_DYNAMICOBJECT; m_objectTypeId = TYPEID_DYNAMICOBJECT; @@ -204,7 +207,7 @@ void DynamicObject::RemoveAura() { ASSERT(_aura && !_removedAura); _removedAura = _aura; - _aura = NULL; + _aura = nullptr; if (!_removedAura->IsRemoved()) _removedAura->_Remove(AURA_REMOVE_BY_DEFAULT); } @@ -240,5 +243,10 @@ void DynamicObject::UnbindFromCaster() { ASSERT(_caster); _caster->_UnregisterDynObject(this); - _caster = NULL; + _caster = nullptr; +} + +SpellInfo const* DynamicObject::GetSpellInfo() const +{ + return sSpellMgr->GetSpellInfo(GetSpellId()); } diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.h b/src/server/game/Entities/DynamicObject/DynamicObject.h index 4eb6cb0dcca..94bb0d8bc8d 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.h +++ b/src/server/game/Entities/DynamicObject/DynamicObject.h @@ -20,6 +20,7 @@ #define TRINITYCORE_DYNAMICOBJECT_H #include "Object.h" +#include "MapObject.h" class Unit; class Aura; @@ -54,7 +55,8 @@ class TC_GAME_API DynamicObject : public WorldObject, public GridObject<DynamicO Unit* GetCaster() const { return _caster; } void BindToCaster(); void UnbindFromCaster(); - uint32 GetSpellId() const { return GetUInt32Value(DYNAMICOBJECT_SPELLID); } + uint32 GetSpellId() const { return GetUInt32Value(DYNAMICOBJECT_SPELLID); } + SpellInfo const* GetSpellInfo() const; ObjectGuid GetCasterGUID() const { return GetGuidValue(DYNAMICOBJECT_CASTER); } float GetRadius() const { return GetFloatValue(DYNAMICOBJECT_RADIUS); } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 58d2ce513c6..93a2d43b4f2 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -16,26 +16,31 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "GameObjectAI.h" +#include "GameObject.h" #include "Battleground.h" #include "CellImpl.h" #include "CreatureAISelector.h" +#include "DatabaseEnv.h" +#include "GameObjectAI.h" #include "GameObjectModel.h" #include "GameTime.h" +#include "GossipDef.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "GroupMgr.h" +#include "Log.h" +#include "LootMgr.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" #include "PoolMgr.h" +#include "QueryPackets.h" #include "ScriptMgr.h" #include "SpellMgr.h" +#include "Transport.h" #include "UpdateFieldFlags.h" #include "World.h" -#include "Transport.h" -#include "GossipDef.h" - -#include "Packets/QueryPackets.h" +#include <G3D/Quat.h> void GameObjectTemplate::InitializeQueryData() { @@ -76,7 +81,7 @@ WorldPacket GameObjectTemplate::BuildQueryData(LocaleConstant loc) const for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) queryTemp.Stats.QuestItems[i] = 0; - if (GameObjectQuestItemList const* items = sObjectMgr->GetGameObjectQuestItemList(entry)) + if (std::vector<uint32> const* items = sObjectMgr->GetGameObjectQuestItemList(entry)) for (uint32 i = 0; i < MAX_GAMEOBJECT_QUEST_ITEMS; ++i) if (i < items->size()) queryTemp.Stats.QuestItems[i] = (*items)[i]; @@ -84,6 +89,17 @@ WorldPacket GameObjectTemplate::BuildQueryData(LocaleConstant loc) const return *queryTemp.Write(); } +bool QuaternionData::isUnit() const +{ + return fabs(x * x + y * y + z * z + w * w - 1.0f) < 1e-5f; +} + +QuaternionData QuaternionData::fromEulerAnglesZYX(float Z, float Y, float X) +{ + G3D::Quat quat(G3D::Matrix3::fromEulerAnglesZYX(Z, Y, X)); + return QuaternionData(quat.x, quat.y, quat.z, quat.w); +} + GameObject::GameObject() : WorldObject(false), MapObject(), m_model(nullptr), m_goValue(), m_AI(nullptr) { @@ -224,7 +240,7 @@ void GameObject::RemoveFromWorld() } } -bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, Position const& pos, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit /*= 0*/) +bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit /*= 0*/) { ASSERT(map); SetMap(map); @@ -274,11 +290,11 @@ bool GameObject::Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, u return false; } - SetWorldRotation(rotation); + SetWorldRotation(rotation.x, rotation.y, rotation.z, rotation.w); GameObjectAddon const* gameObjectAddon = sObjectMgr->GetGameObjectAddon(GetSpawnId()); // For most of gameobjects is (0, 0, 0, 1) quaternion, there are only some transports with not standard rotation - G3D::Quat parentRotation; + QuaternionData parentRotation; if (gameObjectAddon) parentRotation = gameObjectAddon->ParentRotation; @@ -417,7 +433,10 @@ void GameObject::Update(uint32 diff) { m_goValue.Transport.CurrentSeg = node->TimeSeg; - G3D::Quat rotation = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer); + G3D::Quat rotation; + if (TransportRotationEntry const* rot = m_goValue.Transport.AnimationInfo->GetAnimRotation(timer)) + rotation = G3D::Quat(rot->X, rot->Y, rot->Z, rot->W); + G3D::Vector3 pos = rotation.toRotationMatrix() * G3D::Matrix3::fromEulerAnglesZYX(GetOrientation(), 0.0f, 0.0f) * G3D::Vector3(node->X, node->Y, node->Z); @@ -437,7 +456,7 @@ void GameObject::Update(uint32 diff) case GAMEOBJECT_TYPE_FISHINGNODE: { // fishing code (bobber ready) - if (time(NULL) > m_respawnTime - FISHING_BOBBER_READY_TIME) + if (time(nullptr) > m_respawnTime - FISHING_BOBBER_READY_TIME) { // splash bobber (bobber ready now) Unit* caster = GetOwner(); @@ -469,7 +488,7 @@ void GameObject::Update(uint32 diff) { if (m_respawnTime > 0) // timer on { - time_t now = time(NULL); + time_t now = time(nullptr); if (m_respawnTime <= now) // timer expired { ObjectGuid dbtableHighGuid(HighGuid::GameObject, GetEntry(), m_spawnId); @@ -738,7 +757,7 @@ void GameObject::Update(uint32 diff) return; } - m_respawnTime = time(NULL) + m_respawnDelayTime; + m_respawnTime = time(nullptr) + m_respawnDelayTime; // if option not set then object will be saved at grid unload if (sWorld->getBoolConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY)) @@ -841,8 +860,7 @@ void GameObject::SaveToDB() void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) { - const GameObjectTemplate* goI = GetGOInfo(); - + GameObjectTemplate const* goI = GetGOInfo(); if (!goI) return; @@ -1039,7 +1057,7 @@ Unit* GameObject::GetOwner() const void GameObject::SaveRespawnTime() { - if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault) + if (m_goData && m_goData->dbData && m_respawnTime > time(nullptr) && m_spawnedByDefault) GetMap()->SaveGORespawnTime(m_spawnId, m_respawnTime); } @@ -1092,11 +1110,19 @@ bool GameObject::IsInvisibleDueToDespawn() const return false; } +uint8 GameObject::getLevelForTarget(WorldObject const* target) const +{ + if (Unit* owner = GetOwner()) + return owner->getLevelForTarget(target); + + return 1; +} + void GameObject::Respawn() { if (m_spawnedByDefault && m_respawnTime > 0) { - m_respawnTime = time(NULL); + m_respawnTime = time(nullptr); GetMap()->RemoveGORespawnTime(m_spawnId); } } @@ -1208,7 +1234,7 @@ void GameObject::SetGoArtKit(uint8 kit) void GameObject::SetGoArtKit(uint8 artkit, GameObject* go, ObjectGuid::LowType lowguid) { - const GameObjectData* data = nullptr; + GameObjectData const* data = nullptr; if (go) { go->SetGoArtKit(artkit); @@ -1981,13 +2007,18 @@ void GameObject::UpdatePackedRotation() m_packedRotation = z | (y << 21) | (x << 42); } -void GameObject::SetWorldRotation(G3D::Quat const& rot) +void GameObject::SetWorldRotation(float qx, float qy, float qz, float qw) { - m_worldRotation = rot.toUnit(); + G3D::Quat rotation(qx, qy, qz, qw); + rotation.unitize(); + m_worldRotation.x = rotation.x; + m_worldRotation.y = rotation.y; + m_worldRotation.z = rotation.z; + m_worldRotation.w = rotation.w; UpdatePackedRotation(); } -void GameObject::SetParentRotation(G3D::Quat const& rotation) +void GameObject::SetParentRotation(QuaternionData const& rotation) { SetFloatValue(GAMEOBJECT_PARENTROTATION + 0, rotation.x); SetFloatValue(GAMEOBJECT_PARENTROTATION + 1, rotation.y); @@ -1997,7 +2028,8 @@ void GameObject::SetParentRotation(G3D::Quat const& rotation) void GameObject::SetWorldRotationAngles(float z_rot, float y_rot, float x_rot) { - SetWorldRotation(G3D::Quat(G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot))); + G3D::Quat quat(G3D::Matrix3::fromEulerAnglesZYX(z_rot, y_rot, x_rot)); + SetWorldRotation(quat.x, quat.y, quat.z, quat.w); } void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/, uint32 spellId /*= 0*/) diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 371728c7196..3080bd94860 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -19,569 +19,21 @@ #ifndef TRINITYCORE_GAMEOBJECT_H #define TRINITYCORE_GAMEOBJECT_H -#include "Common.h" -#include "SharedDefines.h" -#include "Unit.h" #include "Object.h" -#include "LootMgr.h" -#include "DatabaseEnv.h" -#include "WorldPacket.h" -#include <G3D/Quat.h> +#include "DatabaseEnvFwd.h" +#include "GameObjectData.h" +#include "Loot.h" +#include "MapObject.h" +#include "SharedDefines.h" class GameObjectAI; +class GameObjectModel; class Group; -class Transport; - -#define MAX_GAMEOBJECT_QUEST_ITEMS 6 - -// from `gameobject_template` -struct GameObjectTemplate -{ - uint32 entry; - uint32 type; - uint32 displayId; - std::string name; - std::string IconName; - std::string castBarCaption; - std::string unk1; - float size; - union // different GO types have different data field - { - //0 GAMEOBJECT_TYPE_DOOR - struct - { - uint32 startOpen; //0 used client side to determine GO_ACTIVATED means open/closed - uint32 lockId; //1 -> Lock.dbc - uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 - uint32 noDamageImmune; //3 break opening whenever you recieve damage? - uint32 openTextID; //4 can be used to replace castBarCaption? - uint32 closeTextID; //5 - uint32 ignoredByPathing; //6 - uint32 conditionID1; //7 - } door; - //1 GAMEOBJECT_TYPE_BUTTON - struct - { - uint32 startOpen; //0 - uint32 lockId; //1 -> Lock.dbc - uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 - uint32 linkedTrap; //3 - uint32 noDamageImmune; //4 isBattlegroundObject - uint32 large; //5 - uint32 openTextID; //6 can be used to replace castBarCaption? - uint32 closeTextID; //7 - uint32 losOK; //8 - uint32 conditionID1; //9 - } button; - //2 GAMEOBJECT_TYPE_QUESTGIVER - struct - { - uint32 lockId; //0 -> Lock.dbc - uint32 questList; //1 - uint32 pageMaterial; //2 - uint32 gossipID; //3 - uint32 customAnim; //4 - uint32 noDamageImmune; //5 - uint32 openTextID; //6 can be used to replace castBarCaption? - uint32 losOK; //7 - uint32 allowMounted; //8 Is usable while on mount/vehicle. (0/1) - uint32 large; //9 - uint32 conditionID1; //10 - } questgiver; - //3 GAMEOBJECT_TYPE_CHEST - struct - { - uint32 lockId; //0 -> Lock.dbc - uint32 lootId; //1 - uint32 chestRestockTime; //2 - uint32 consumable; //3 - uint32 minSuccessOpens; //4 Deprecated, pre 3.0 was used for mining nodes but since WotLK all mining nodes are usable once and grant all loot with a single use - uint32 maxSuccessOpens; //5 Deprecated, pre 3.0 was used for mining nodes but since WotLK all mining nodes are usable once and grant all loot with a single use - uint32 eventId; //6 lootedEvent - uint32 linkedTrapId; //7 - uint32 questId; //8 not used currently but store quest required for GO activation for player - uint32 level; //9 - uint32 losOK; //10 - uint32 leaveLoot; //11 - uint32 notInCombat; //12 - uint32 logLoot; //13 - uint32 openTextID; //14 can be used to replace castBarCaption? - uint32 groupLootRules; //15 - uint32 floatingTooltip; //16 - uint32 conditionID1; //17 - } chest; - //4 GAMEOBJECT_TYPE_BINDER - empty - //5 GAMEOBJECT_TYPE_GENERIC - struct - { - uint32 floatingTooltip; //0 - uint32 highlight; //1 - uint32 serverOnly; //2 - uint32 large; //3 - uint32 floatOnWater; //4 - int32 questID; //5 - uint32 conditionID1; //6 - } _generic; - //6 GAMEOBJECT_TYPE_TRAP - struct - { - uint32 lockId; //0 -> Lock.dbc - uint32 level; //1 - uint32 diameter; //2 diameter for trap activation - uint32 spellId; //3 - uint32 type; //4 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn. - uint32 cooldown; //5 time in secs - int32 autoCloseTime; //6 - uint32 startDelay; //7 - uint32 serverOnly; //8 - uint32 stealthed; //9 - uint32 large; //10 - uint32 invisible; //11 - uint32 openTextID; //12 can be used to replace castBarCaption? - uint32 closeTextID; //13 - uint32 ignoreTotems; //14 - uint32 conditionID1; //15 - } trap; - //7 GAMEOBJECT_TYPE_CHAIR - struct - { - uint32 slots; //0 - uint32 height; //1 - uint32 onlyCreatorUse; //2 - uint32 triggeredEvent; //3 - uint32 conditionID1; //4 - } chair; - //8 GAMEOBJECT_TYPE_SPELL_FOCUS - struct - { - uint32 focusId; //0 - uint32 dist; //1 - uint32 linkedTrapId; //2 - uint32 serverOnly; //3 - uint32 questID; //4 - uint32 large; //5 - uint32 floatingTooltip; //6 - uint32 floatOnWater; //7 - uint32 conditionID1; //8 - } spellFocus; - //9 GAMEOBJECT_TYPE_TEXT - struct - { - uint32 pageID; //0 - uint32 language; //1 - uint32 pageMaterial; //2 - uint32 allowMounted; //3 Is usable while on mount/vehicle. (0/1) - uint32 conditionID1; //4 - } text; - //10 GAMEOBJECT_TYPE_GOOBER - struct - { - uint32 lockId; //0 -> Lock.dbc - int32 questId; //1 - uint32 eventId; //2 - uint32 autoCloseTime; //3 - uint32 customAnim; //4 - uint32 consumable; //5 - uint32 cooldown; //6 - uint32 pageId; //7 - uint32 language; //8 - uint32 pageMaterial; //9 - uint32 spellId; //10 - uint32 noDamageImmune; //11 - uint32 linkedTrapId; //12 - uint32 large; //13 - uint32 openTextID; //14 can be used to replace castBarCaption? - uint32 closeTextID; //15 - uint32 losOK; //16 isBattlegroundObject - uint32 allowMounted; //17 Is usable while on mount/vehicle. (0/1) - uint32 floatingTooltip; //18 - uint32 gossipID; //19 - uint32 WorldStateSetsState; //20 - uint32 floatOnWater; //21 - uint32 conditionID1; //22 - } goober; - //11 GAMEOBJECT_TYPE_TRANSPORT - struct - { - uint32 pause; //0 - uint32 startOpen; //1 - uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 - uint32 pause1EventID; //3 - uint32 pause2EventID; //4 - uint32 mapID; //5 - } transport; - //12 GAMEOBJECT_TYPE_AREADAMAGE - struct - { - uint32 lockId; //0 - uint32 radius; //1 - uint32 damageMin; //2 - uint32 damageMax; //3 - uint32 damageSchool; //4 - uint32 autoCloseTime; //5 secs till autoclose = autoCloseTime / 0x10000 - uint32 openTextID; //6 - uint32 closeTextID; //7 - } areadamage; - //13 GAMEOBJECT_TYPE_CAMERA - struct - { - uint32 lockId; //0 -> Lock.dbc - uint32 cinematicId; //1 - uint32 eventID; //2 - uint32 openTextID; //3 can be used to replace castBarCaption? - uint32 conditionID1; //4 - } camera; - //14 GAMEOBJECT_TYPE_MAPOBJECT - empty - //15 GAMEOBJECT_TYPE_MO_TRANSPORT - struct - { - uint32 taxiPathId; //0 - uint32 moveSpeed; //1 - uint32 accelRate; //2 - uint32 startEventID; //3 - uint32 stopEventID; //4 - uint32 transportPhysics; //5 - uint32 mapID; //6 - uint32 worldState1; //7 - uint32 canBeStopped; //8 - } moTransport; - //16 GAMEOBJECT_TYPE_DUELFLAG - empty - //17 GAMEOBJECT_TYPE_FISHINGNODE - empty - //18 GAMEOBJECT_TYPE_SUMMONING_RITUAL - struct - { - uint32 reqParticipants; //0 - uint32 spellId; //1 - uint32 animSpell; //2 - uint32 ritualPersistent; //3 - uint32 casterTargetSpell; //4 - uint32 casterTargetSpellTargets; //5 - uint32 castersGrouped; //6 - uint32 ritualNoTargetCheck; //7 - uint32 conditionID1; //8 - } summoningRitual; - //19 GAMEOBJECT_TYPE_MAILBOX - struct - { - uint32 conditionID1; //0 - } mailbox; - //20 GAMEOBJECT_TYPE_DO_NOT_USE - empty - //21 GAMEOBJECT_TYPE_GUARDPOST - struct - { - uint32 creatureID; //0 - uint32 charges; //1 - } guardpost; - //22 GAMEOBJECT_TYPE_SPELLCASTER - struct - { - uint32 spellId; //0 - uint32 charges; //1 - uint32 partyOnly; //2 - uint32 allowMounted; //3 Is usable while on mount/vehicle. (0/1) - uint32 large; //4 - uint32 conditionID1; //5 - } spellcaster; - //23 GAMEOBJECT_TYPE_MEETINGSTONE - struct - { - uint32 minLevel; //0 - uint32 maxLevel; //1 - uint32 areaID; //2 - } meetingstone; - //24 GAMEOBJECT_TYPE_FLAGSTAND - struct - { - uint32 lockId; //0 - uint32 pickupSpell; //1 - uint32 radius; //2 - uint32 returnAura; //3 - uint32 returnSpell; //4 - uint32 noDamageImmune; //5 - uint32 openTextID; //6 - uint32 losOK; //7 - uint32 conditionID1; //8 - } flagstand; - //25 GAMEOBJECT_TYPE_FISHINGHOLE - struct - { - uint32 radius; //0 how close bobber must land for sending loot - uint32 lootId; //1 - uint32 minSuccessOpens; //2 - uint32 maxSuccessOpens; //3 - uint32 lockId; //4 -> Lock.dbc; possibly 1628 for all? - } fishinghole; - //26 GAMEOBJECT_TYPE_FLAGDROP - struct - { - uint32 lockId; //0 - uint32 eventID; //1 - uint32 pickupSpell; //2 - uint32 noDamageImmune; //3 - uint32 openTextID; //4 - } flagdrop; - //27 GAMEOBJECT_TYPE_MINI_GAME - struct - { - uint32 gameType; //0 - } miniGame; - //29 GAMEOBJECT_TYPE_CAPTURE_POINT - struct - { - uint32 radius; //0 - uint32 spell; //1 - uint32 worldState1; //2 - uint32 worldstate2; //3 - uint32 winEventID1; //4 - uint32 winEventID2; //5 - uint32 contestedEventID1; //6 - uint32 contestedEventID2; //7 - uint32 progressEventID1; //8 - uint32 progressEventID2; //9 - uint32 neutralEventID1; //10 - uint32 neutralEventID2; //11 - uint32 neutralPercent; //12 - uint32 worldstate3; //13 - uint32 minSuperiority; //14 - uint32 maxSuperiority; //15 - uint32 minTime; //16 - uint32 maxTime; //17 - uint32 large; //18 - uint32 highlight; //19 - uint32 startingValue; //20 - uint32 unidirectional; //21 - } capturePoint; - //30 GAMEOBJECT_TYPE_AURA_GENERATOR - struct - { - uint32 startOpen; //0 - uint32 radius; //1 - uint32 auraID1; //2 - uint32 conditionID1; //3 - uint32 auraID2; //4 - uint32 conditionID2; //5 - uint32 serverOnly; //6 - } auraGenerator; - //31 GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY - struct - { - uint32 mapID; //0 - uint32 difficulty; //1 - } dungeonDifficulty; - //32 GAMEOBJECT_TYPE_BARBER_CHAIR - struct - { - uint32 chairheight; //0 - uint32 heightOffset; //1 - } barberChair; - //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING - struct - { - uint32 intactNumHits; //0 - uint32 creditProxyCreature; //1 - uint32 empty1; //2 - uint32 intactEvent; //3 - uint32 empty2; //4 - uint32 damagedNumHits; //5 - uint32 empty3; //6 - uint32 empty4; //7 - uint32 empty5; //8 - uint32 damagedEvent; //9 - uint32 empty6; //10 - uint32 empty7; //11 - uint32 empty8; //12 - uint32 empty9; //13 - uint32 destroyedEvent; //14 - uint32 empty10; //15 - uint32 rebuildingTimeSecs; //16 - uint32 empty11; //17 - uint32 destructibleData; //18 - uint32 rebuildingEvent; //19 - uint32 empty12; //20 - uint32 empty13; //21 - uint32 damageEvent; //22 - uint32 empty14; //23 - } building; - //34 GAMEOBJECT_TYPE_GUILDBANK - struct - { - uint32 conditionID1; //0 - } guildbank; - //35 GAMEOBJECT_TYPE_TRAPDOOR - struct - { - uint32 whenToPause; // 0 - uint32 startOpen; // 1 - uint32 autoClose; // 2 - } trapDoor; - - // not use for specific field access (only for output with loop by all filed), also this determinate max union size - struct - { - uint32 data[MAX_GAMEOBJECT_DATA]; - } raw; - }; - - std::string AIName; - uint32 ScriptId; - WorldPacket QueryData[TOTAL_LOCALES]; - - // helpers - bool IsDespawnAtAction() const - { - switch (type) - { - case GAMEOBJECT_TYPE_CHEST: return chest.consumable != 0; - case GAMEOBJECT_TYPE_GOOBER: return goober.consumable != 0; - default: return false; - } - } - - bool IsUsableMounted() const - { - switch (type) - { - case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.allowMounted != 0; - case GAMEOBJECT_TYPE_TEXT: return text.allowMounted != 0; - case GAMEOBJECT_TYPE_GOOBER: return goober.allowMounted != 0; - case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.allowMounted != 0; - default: return false; - } - } - - uint32 GetLockId() const - { - switch (type) - { - case GAMEOBJECT_TYPE_DOOR: return door.lockId; - case GAMEOBJECT_TYPE_BUTTON: return button.lockId; - case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.lockId; - case GAMEOBJECT_TYPE_CHEST: return chest.lockId; - case GAMEOBJECT_TYPE_TRAP: return trap.lockId; - case GAMEOBJECT_TYPE_GOOBER: return goober.lockId; - case GAMEOBJECT_TYPE_AREADAMAGE: return areadamage.lockId; - case GAMEOBJECT_TYPE_CAMERA: return camera.lockId; - case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.lockId; - case GAMEOBJECT_TYPE_FISHINGHOLE:return fishinghole.lockId; - case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.lockId; - default: return 0; - } - } - - bool GetDespawnPossibility() const // despawn at targeting of cast? - { - switch (type) - { - case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune != 0; - case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune != 0; - case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune != 0; - case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune != 0; - case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune != 0; - case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune != 0; - default: return true; - } - } - - uint32 GetCharges() const // despawn at uses amount - { - switch (type) - { - //case GAMEOBJECT_TYPE_TRAP: return trap.charges; - case GAMEOBJECT_TYPE_GUARDPOST: return guardpost.charges; - case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.charges; - default: return 0; - } - } - - uint32 GetLinkedGameObjectEntry() const - { - switch (type) - { - case GAMEOBJECT_TYPE_BUTTON: return button.linkedTrap; - case GAMEOBJECT_TYPE_CHEST: return chest.linkedTrapId; - case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.linkedTrapId; - case GAMEOBJECT_TYPE_GOOBER: return goober.linkedTrapId; - default: return 0; - } - } - - uint32 GetAutoCloseTime() const - { - uint32 autoCloseTime = 0; - switch (type) - { - case GAMEOBJECT_TYPE_DOOR: autoCloseTime = door.autoCloseTime; break; - case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = button.autoCloseTime; break; - case GAMEOBJECT_TYPE_TRAP: autoCloseTime = trap.autoCloseTime; break; - case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = goober.autoCloseTime; break; - case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = transport.autoCloseTime; break; - case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = areadamage.autoCloseTime; break; - default: break; - } - return autoCloseTime; // prior to 3.0.3, conversion was / 0x10000; - } - - uint32 GetLootId() const - { - switch (type) - { - case GAMEOBJECT_TYPE_CHEST: return chest.lootId; - case GAMEOBJECT_TYPE_FISHINGHOLE: return fishinghole.lootId; - default: return 0; - } - } - - uint32 GetGossipMenuId() const - { - switch (type) - { - case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.gossipID; - case GAMEOBJECT_TYPE_GOOBER: return goober.gossipID; - default: return 0; - } - } - - uint32 GetEventScriptId() const - { - switch (type) - { - case GAMEOBJECT_TYPE_GOOBER: return goober.eventId; - case GAMEOBJECT_TYPE_CHEST: return chest.eventId; - case GAMEOBJECT_TYPE_CAMERA: return camera.eventID; - default: return 0; - } - } - - uint32 GetCooldown() const // Cooldown preventing goober and traps to cast spell - { - switch (type) - { - case GAMEOBJECT_TYPE_TRAP: return trap.cooldown; - case GAMEOBJECT_TYPE_GOOBER: return goober.cooldown; - default: return 0; - } - } - - void InitializeQueryData(); - WorldPacket BuildQueryData(LocaleConstant loc) const; -}; - -// From `gameobject_template_addon` -struct GameObjectTemplateAddon -{ - uint32 entry; - uint32 faction; - uint32 flags; - uint32 mingold; - uint32 maxgold; -}; - -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map<uint32, GameObjectTemplate> GameObjectTemplateContainer; -typedef std::unordered_map<uint32, GameObjectTemplateAddon> GameObjectTemplateAddonContainer; - class OPvPCapturePoint; +class Transport; +class Unit; struct TransportAnimation; +enum TriggerCastFlags : uint32; union GameObjectValue { @@ -610,57 +62,6 @@ union GameObjectValue } Building; }; -struct GameObjectLocale -{ - StringVector Name; - StringVector CastBarCaption; -}; - -// `gameobject_addon` table -struct GameObjectAddon -{ - G3D::Quat ParentRotation; - InvisibilityType invisibilityType; - uint32 InvisibilityValue; -}; - -typedef std::unordered_map<ObjectGuid::LowType, GameObjectAddon> GameObjectAddonContainer; - -// client side GO show states -enum GOState -{ - GO_STATE_ACTIVE = 0, // show in world as used and not reset (closed door open) - GO_STATE_READY = 1, // show in world as ready (closed door close) - GO_STATE_ACTIVE_ALTERNATIVE = 2 // show in world as used in alt way and not reset (closed door open by cannon fire) -}; - -#define MAX_GO_STATE 3 - -// from `gameobject` -struct GameObjectData -{ - explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), - animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), ScriptId(0), dbData(true) { } - uint32 id; // entry in gamobject_template - uint16 mapid; - uint32 phaseMask; - float posX; - float posY; - float posZ; - float orientation; - G3D::Quat rotation; - int32 spawntimesecs; - uint32 animprogress; - GOState go_state; - uint8 spawnMask; - uint8 artKit; - uint32 ScriptId; - bool dbData; -}; - -typedef std::vector<uint32> GameObjectQuestItemList; -typedef std::unordered_map<uint32, GameObjectQuestItemList> GameObjectQuestItemMap; - // For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ... // For bobber: GO_NOT_READY ->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED-><deleted> // For door(closed):[GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY(close) -> ... @@ -673,9 +74,6 @@ enum LootState GO_JUST_DEACTIVATED }; -class Unit; -class GameObjectModel; - // 5 sec for bobber catch #define FISHING_BOBBER_READY_TIME 5 @@ -691,7 +89,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void RemoveFromWorld() override; void CleanupsBeforeDelete(bool finalCleanup = true) override; - bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, Position const& pos, G3D::Quat const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0); + bool Create(ObjectGuid::LowType guidlow, uint32 name_id, Map* map, uint32 phaseMask, Position const& pos, QuaternionData const& rotation, uint32 animprogress, GOState go_state, uint32 artKit = 0); void Update(uint32 p_time) override; GameObjectTemplate const* GetGOInfo() const { return m_goInfo; } GameObjectTemplateAddon const* GetTemplateAddon() const { return m_goTemplateAddon; } @@ -706,9 +104,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> // z_rot, y_rot, x_rot - rotation angles around z, y and x axes void SetWorldRotationAngles(float z_rot, float y_rot, float x_rot); - void SetWorldRotation(G3D::Quat const& rot); - G3D::Quat const& GetWorldRotation() const { return m_worldRotation; } - void SetParentRotation(G3D::Quat const& rotation); // transforms(rotates) transport's path + void SetWorldRotation(float qx, float qy, float qz, float qw); + void SetParentRotation(QuaternionData const& rotation); // transforms(rotates) transport's path int64 GetPackedWorldRotation() const { return m_packedRotation; } // overwrite WorldObject function for proper name localization @@ -743,7 +140,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> time_t GetRespawnTime() const { return m_respawnTime; } time_t GetRespawnTimeEx() const { - time_t now = time(NULL); + time_t now = time(nullptr); if (m_respawnTime > now) return m_respawnTime; else @@ -752,7 +149,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SetRespawnTime(int32 respawn) { - m_respawnTime = respawn > 0 ? time(NULL) + respawn : 0; + m_respawnTime = respawn > 0 ? time(nullptr) + respawn : 0; m_respawnDelayTime = respawn > 0 ? respawn : 0; } void Respawn(); @@ -787,7 +184,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> LootState getLootState() const { return m_lootState; } // Note: unit is only used when s = GO_ACTIVATED - void SetLootState(LootState s, Unit* unit = NULL); + void SetLootState(LootState s, Unit* unit = nullptr); uint16 GetLootMode() const { return m_LootMode; } bool HasLootMode(uint16 lootMode) const { return (m_LootMode & lootMode) != 0; } @@ -833,7 +230,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; - void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = NULL); + void UseDoorOrButton(uint32 time_to_restore = 0, bool alternative = false, Unit* user = nullptr); // 0 = use `gameobject`.`spawntimesecs` void ResetDoorOrButton(); @@ -844,13 +241,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> bool IsAlwaysVisibleFor(WorldObject const* seer) const override; bool IsInvisibleDueToDespawn() const override; - uint8 getLevelForTarget(WorldObject const* target) const override - { - if (Unit* owner = GetOwner()) - return owner->getLevelForTarget(target); - - return 1; - } + uint8 getLevelForTarget(WorldObject const* target) const override; GameObject* LookupFishingHoleAround(float range); @@ -859,9 +250,9 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SendCustomAnim(uint32 anim); bool IsInRange(float x, float y, float z, float radius) const; - void ModifyHealth(int32 change, Unit* attackerOrHealer = NULL, uint32 spellId = 0); + void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0); // sets GameObject type 33 destruction flags and optionally default health for that state - void SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker = NULL, bool setHealth = false); + void SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker = nullptr, bool setHealth = false); GameObjectDestructibleState GetDestructibleState() const { if (HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED)) @@ -871,7 +262,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> return GO_DESTRUCTIBLE_INTACT; } - void EventInform(uint32 eventId, WorldObject* invoker = NULL); + void EventInform(uint32 eventId, WorldObject* invoker = nullptr); uint32 GetScriptId() const; GameObjectAI* AI() const { return m_AI; } @@ -884,10 +275,10 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> void SetFaction(uint32 faction) { SetUInt32Value(GAMEOBJECT_FACTION, faction); } GameObjectModel* m_model; - void GetRespawnPosition(float &x, float &y, float &z, float* ori = NULL) const; + void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr) const; - Transport* ToTransport() { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport*>(this); else return NULL; } - Transport const* ToTransport() const { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport const*>(this); else return NULL; } + Transport* ToTransport() { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport*>(this); else return nullptr; } + Transport const* ToTransport() const { if (GetGOInfo()->type == GAMEOBJECT_TYPE_MO_TRANSPORT) return reinterpret_cast<Transport const*>(this); else return nullptr; } float GetStationaryX() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionX(); return GetPositionX(); } float GetStationaryY() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionY(); return GetPositionY(); } @@ -931,7 +322,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject> GameObjectValue m_goValue; int64 m_packedRotation; - G3D::Quat m_worldRotation; + QuaternionData m_worldRotation; Position m_stationaryPosition; ObjectGuid m_lootRecipient; diff --git a/src/server/game/Entities/GameObject/GameObjectData.h b/src/server/game/Entities/GameObject/GameObjectData.h new file mode 100644 index 00000000000..e2d2f27e5b5 --- /dev/null +++ b/src/server/game/Entities/GameObject/GameObjectData.h @@ -0,0 +1,618 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef GameObjectData_h__ +#define GameObjectData_h__ + +#include "Common.h" +#include "SharedDefines.h" +#include "WorldPacket.h" +#include <string> +#include <vector> + +#define MAX_GAMEOBJECT_QUEST_ITEMS 6 + +// from `gameobject_template` +struct GameObjectTemplate +{ + uint32 entry; + uint32 type; + uint32 displayId; + std::string name; + std::string IconName; + std::string castBarCaption; + std::string unk1; + float size; + union // different GO types have different data field + { + //0 GAMEOBJECT_TYPE_DOOR + struct + { + uint32 startOpen; //0 used client side to determine GO_ACTIVATED means open/closed + uint32 lockId; //1 -> Lock.dbc + uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 + uint32 noDamageImmune; //3 break opening whenever you recieve damage? + uint32 openTextID; //4 can be used to replace castBarCaption? + uint32 closeTextID; //5 + uint32 ignoredByPathing; //6 + uint32 conditionID1; //7 + } door; + //1 GAMEOBJECT_TYPE_BUTTON + struct + { + uint32 startOpen; //0 + uint32 lockId; //1 -> Lock.dbc + uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 + uint32 linkedTrap; //3 + uint32 noDamageImmune; //4 isBattlegroundObject + uint32 large; //5 + uint32 openTextID; //6 can be used to replace castBarCaption? + uint32 closeTextID; //7 + uint32 losOK; //8 + uint32 conditionID1; //9 + } button; + //2 GAMEOBJECT_TYPE_QUESTGIVER + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 questList; //1 + uint32 pageMaterial; //2 + uint32 gossipID; //3 + uint32 customAnim; //4 + uint32 noDamageImmune; //5 + uint32 openTextID; //6 can be used to replace castBarCaption? + uint32 losOK; //7 + uint32 allowMounted; //8 Is usable while on mount/vehicle. (0/1) + uint32 large; //9 + uint32 conditionID1; //10 + } questgiver; + //3 GAMEOBJECT_TYPE_CHEST + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 lootId; //1 + uint32 chestRestockTime; //2 + uint32 consumable; //3 + uint32 minSuccessOpens; //4 Deprecated, pre 3.0 was used for mining nodes but since WotLK all mining nodes are usable once and grant all loot with a single use + uint32 maxSuccessOpens; //5 Deprecated, pre 3.0 was used for mining nodes but since WotLK all mining nodes are usable once and grant all loot with a single use + uint32 eventId; //6 lootedEvent + uint32 linkedTrapId; //7 + uint32 questId; //8 not used currently but store quest required for GO activation for player + uint32 level; //9 + uint32 losOK; //10 + uint32 leaveLoot; //11 + uint32 notInCombat; //12 + uint32 logLoot; //13 + uint32 openTextID; //14 can be used to replace castBarCaption? + uint32 groupLootRules; //15 + uint32 floatingTooltip; //16 + uint32 conditionID1; //17 + } chest; + //4 GAMEOBJECT_TYPE_BINDER - empty + //5 GAMEOBJECT_TYPE_GENERIC + struct + { + uint32 floatingTooltip; //0 + uint32 highlight; //1 + uint32 serverOnly; //2 + uint32 large; //3 + uint32 floatOnWater; //4 + int32 questID; //5 + uint32 conditionID1; //6 + } _generic; + //6 GAMEOBJECT_TYPE_TRAP + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 level; //1 + uint32 diameter; //2 diameter for trap activation + uint32 spellId; //3 + uint32 type; //4 0 trap with no despawn after cast. 1 trap despawns after cast. 2 bomb casts on spawn. + uint32 cooldown; //5 time in secs + int32 autoCloseTime; //6 + uint32 startDelay; //7 + uint32 serverOnly; //8 + uint32 stealthed; //9 + uint32 large; //10 + uint32 invisible; //11 + uint32 openTextID; //12 can be used to replace castBarCaption? + uint32 closeTextID; //13 + uint32 ignoreTotems; //14 + uint32 conditionID1; //15 + } trap; + //7 GAMEOBJECT_TYPE_CHAIR + struct + { + uint32 slots; //0 + uint32 height; //1 + uint32 onlyCreatorUse; //2 + uint32 triggeredEvent; //3 + uint32 conditionID1; //4 + } chair; + //8 GAMEOBJECT_TYPE_SPELL_FOCUS + struct + { + uint32 focusId; //0 + uint32 dist; //1 + uint32 linkedTrapId; //2 + uint32 serverOnly; //3 + uint32 questID; //4 + uint32 large; //5 + uint32 floatingTooltip; //6 + uint32 floatOnWater; //7 + uint32 conditionID1; //8 + } spellFocus; + //9 GAMEOBJECT_TYPE_TEXT + struct + { + uint32 pageID; //0 + uint32 language; //1 + uint32 pageMaterial; //2 + uint32 allowMounted; //3 Is usable while on mount/vehicle. (0/1) + uint32 conditionID1; //4 + } text; + //10 GAMEOBJECT_TYPE_GOOBER + struct + { + uint32 lockId; //0 -> Lock.dbc + int32 questId; //1 + uint32 eventId; //2 + uint32 autoCloseTime; //3 + uint32 customAnim; //4 + uint32 consumable; //5 + uint32 cooldown; //6 + uint32 pageId; //7 + uint32 language; //8 + uint32 pageMaterial; //9 + uint32 spellId; //10 + uint32 noDamageImmune; //11 + uint32 linkedTrapId; //12 + uint32 large; //13 + uint32 openTextID; //14 can be used to replace castBarCaption? + uint32 closeTextID; //15 + uint32 losOK; //16 isBattlegroundObject + uint32 allowMounted; //17 Is usable while on mount/vehicle. (0/1) + uint32 floatingTooltip; //18 + uint32 gossipID; //19 + uint32 WorldStateSetsState; //20 + uint32 floatOnWater; //21 + uint32 conditionID1; //22 + } goober; + //11 GAMEOBJECT_TYPE_TRANSPORT + struct + { + uint32 pause; //0 + uint32 startOpen; //1 + uint32 autoCloseTime; //2 secs till autoclose = autoCloseTime / 0x10000 + uint32 pause1EventID; //3 + uint32 pause2EventID; //4 + uint32 mapID; //5 + } transport; + //12 GAMEOBJECT_TYPE_AREADAMAGE + struct + { + uint32 lockId; //0 + uint32 radius; //1 + uint32 damageMin; //2 + uint32 damageMax; //3 + uint32 damageSchool; //4 + uint32 autoCloseTime; //5 secs till autoclose = autoCloseTime / 0x10000 + uint32 openTextID; //6 + uint32 closeTextID; //7 + } areadamage; + //13 GAMEOBJECT_TYPE_CAMERA + struct + { + uint32 lockId; //0 -> Lock.dbc + uint32 cinematicId; //1 + uint32 eventID; //2 + uint32 openTextID; //3 can be used to replace castBarCaption? + uint32 conditionID1; //4 + } camera; + //14 GAMEOBJECT_TYPE_MAPOBJECT - empty + //15 GAMEOBJECT_TYPE_MO_TRANSPORT + struct + { + uint32 taxiPathId; //0 + uint32 moveSpeed; //1 + uint32 accelRate; //2 + uint32 startEventID; //3 + uint32 stopEventID; //4 + uint32 transportPhysics; //5 + uint32 mapID; //6 + uint32 worldState1; //7 + uint32 canBeStopped; //8 + } moTransport; + //16 GAMEOBJECT_TYPE_DUELFLAG - empty + //17 GAMEOBJECT_TYPE_FISHINGNODE - empty + //18 GAMEOBJECT_TYPE_SUMMONING_RITUAL + struct + { + uint32 reqParticipants; //0 + uint32 spellId; //1 + uint32 animSpell; //2 + uint32 ritualPersistent; //3 + uint32 casterTargetSpell; //4 + uint32 casterTargetSpellTargets; //5 + uint32 castersGrouped; //6 + uint32 ritualNoTargetCheck; //7 + uint32 conditionID1; //8 + } summoningRitual; + //19 GAMEOBJECT_TYPE_MAILBOX + struct + { + uint32 conditionID1; //0 + } mailbox; + //20 GAMEOBJECT_TYPE_DO_NOT_USE - empty + //21 GAMEOBJECT_TYPE_GUARDPOST + struct + { + uint32 creatureID; //0 + uint32 charges; //1 + } guardpost; + //22 GAMEOBJECT_TYPE_SPELLCASTER + struct + { + uint32 spellId; //0 + uint32 charges; //1 + uint32 partyOnly; //2 + uint32 allowMounted; //3 Is usable while on mount/vehicle. (0/1) + uint32 large; //4 + uint32 conditionID1; //5 + } spellcaster; + //23 GAMEOBJECT_TYPE_MEETINGSTONE + struct + { + uint32 minLevel; //0 + uint32 maxLevel; //1 + uint32 areaID; //2 + } meetingstone; + //24 GAMEOBJECT_TYPE_FLAGSTAND + struct + { + uint32 lockId; //0 + uint32 pickupSpell; //1 + uint32 radius; //2 + uint32 returnAura; //3 + uint32 returnSpell; //4 + uint32 noDamageImmune; //5 + uint32 openTextID; //6 + uint32 losOK; //7 + uint32 conditionID1; //8 + } flagstand; + //25 GAMEOBJECT_TYPE_FISHINGHOLE + struct + { + uint32 radius; //0 how close bobber must land for sending loot + uint32 lootId; //1 + uint32 minSuccessOpens; //2 + uint32 maxSuccessOpens; //3 + uint32 lockId; //4 -> Lock.dbc; possibly 1628 for all? + } fishinghole; + //26 GAMEOBJECT_TYPE_FLAGDROP + struct + { + uint32 lockId; //0 + uint32 eventID; //1 + uint32 pickupSpell; //2 + uint32 noDamageImmune; //3 + uint32 openTextID; //4 + } flagdrop; + //27 GAMEOBJECT_TYPE_MINI_GAME + struct + { + uint32 gameType; //0 + } miniGame; + //29 GAMEOBJECT_TYPE_CAPTURE_POINT + struct + { + uint32 radius; //0 + uint32 spell; //1 + uint32 worldState1; //2 + uint32 worldstate2; //3 + uint32 winEventID1; //4 + uint32 winEventID2; //5 + uint32 contestedEventID1; //6 + uint32 contestedEventID2; //7 + uint32 progressEventID1; //8 + uint32 progressEventID2; //9 + uint32 neutralEventID1; //10 + uint32 neutralEventID2; //11 + uint32 neutralPercent; //12 + uint32 worldstate3; //13 + uint32 minSuperiority; //14 + uint32 maxSuperiority; //15 + uint32 minTime; //16 + uint32 maxTime; //17 + uint32 large; //18 + uint32 highlight; //19 + uint32 startingValue; //20 + uint32 unidirectional; //21 + } capturePoint; + //30 GAMEOBJECT_TYPE_AURA_GENERATOR + struct + { + uint32 startOpen; //0 + uint32 radius; //1 + uint32 auraID1; //2 + uint32 conditionID1; //3 + uint32 auraID2; //4 + uint32 conditionID2; //5 + uint32 serverOnly; //6 + } auraGenerator; + //31 GAMEOBJECT_TYPE_DUNGEON_DIFFICULTY + struct + { + uint32 mapID; //0 + uint32 difficulty; //1 + } dungeonDifficulty; + //32 GAMEOBJECT_TYPE_BARBER_CHAIR + struct + { + uint32 chairheight; //0 + uint32 heightOffset; //1 + } barberChair; + //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING + struct + { + uint32 intactNumHits; //0 + uint32 creditProxyCreature; //1 + uint32 empty1; //2 + uint32 intactEvent; //3 + uint32 empty2; //4 + uint32 damagedNumHits; //5 + uint32 empty3; //6 + uint32 empty4; //7 + uint32 empty5; //8 + uint32 damagedEvent; //9 + uint32 empty6; //10 + uint32 empty7; //11 + uint32 empty8; //12 + uint32 empty9; //13 + uint32 destroyedEvent; //14 + uint32 empty10; //15 + uint32 rebuildingTimeSecs; //16 + uint32 empty11; //17 + uint32 destructibleData; //18 + uint32 rebuildingEvent; //19 + uint32 empty12; //20 + uint32 empty13; //21 + uint32 damageEvent; //22 + uint32 empty14; //23 + } building; + //34 GAMEOBJECT_TYPE_GUILDBANK + struct + { + uint32 conditionID1; //0 + } guildbank; + //35 GAMEOBJECT_TYPE_TRAPDOOR + struct + { + uint32 whenToPause; // 0 + uint32 startOpen; // 1 + uint32 autoClose; // 2 + } trapDoor; + + // not use for specific field access (only for output with loop by all filed), also this determinate max union size + struct + { + uint32 data[MAX_GAMEOBJECT_DATA]; + } raw; + }; + + std::string AIName; + uint32 ScriptId; + WorldPacket QueryData[TOTAL_LOCALES]; + + // helpers + bool IsDespawnAtAction() const + { + switch (type) + { + case GAMEOBJECT_TYPE_CHEST: return chest.consumable != 0; + case GAMEOBJECT_TYPE_GOOBER: return goober.consumable != 0; + default: return false; + } + } + + bool IsUsableMounted() const + { + switch (type) + { + case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.allowMounted != 0; + case GAMEOBJECT_TYPE_TEXT: return text.allowMounted != 0; + case GAMEOBJECT_TYPE_GOOBER: return goober.allowMounted != 0; + case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.allowMounted != 0; + default: return false; + } + } + + uint32 GetLockId() const + { + switch (type) + { + case GAMEOBJECT_TYPE_DOOR: return door.lockId; + case GAMEOBJECT_TYPE_BUTTON: return button.lockId; + case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.lockId; + case GAMEOBJECT_TYPE_CHEST: return chest.lockId; + case GAMEOBJECT_TYPE_TRAP: return trap.lockId; + case GAMEOBJECT_TYPE_GOOBER: return goober.lockId; + case GAMEOBJECT_TYPE_AREADAMAGE: return areadamage.lockId; + case GAMEOBJECT_TYPE_CAMERA: return camera.lockId; + case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.lockId; + case GAMEOBJECT_TYPE_FISHINGHOLE:return fishinghole.lockId; + case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.lockId; + default: return 0; + } + } + + bool GetDespawnPossibility() const // despawn at targeting of cast? + { + switch (type) + { + case GAMEOBJECT_TYPE_DOOR: return door.noDamageImmune != 0; + case GAMEOBJECT_TYPE_BUTTON: return button.noDamageImmune != 0; + case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.noDamageImmune != 0; + case GAMEOBJECT_TYPE_GOOBER: return goober.noDamageImmune != 0; + case GAMEOBJECT_TYPE_FLAGSTAND: return flagstand.noDamageImmune != 0; + case GAMEOBJECT_TYPE_FLAGDROP: return flagdrop.noDamageImmune != 0; + default: return true; + } + } + + uint32 GetCharges() const // despawn at uses amount + { + switch (type) + { + //case GAMEOBJECT_TYPE_TRAP: return trap.charges; + case GAMEOBJECT_TYPE_GUARDPOST: return guardpost.charges; + case GAMEOBJECT_TYPE_SPELLCASTER: return spellcaster.charges; + default: return 0; + } + } + + uint32 GetLinkedGameObjectEntry() const + { + switch (type) + { + case GAMEOBJECT_TYPE_BUTTON: return button.linkedTrap; + case GAMEOBJECT_TYPE_CHEST: return chest.linkedTrapId; + case GAMEOBJECT_TYPE_SPELL_FOCUS: return spellFocus.linkedTrapId; + case GAMEOBJECT_TYPE_GOOBER: return goober.linkedTrapId; + default: return 0; + } + } + + uint32 GetAutoCloseTime() const + { + uint32 autoCloseTime = 0; + switch (type) + { + case GAMEOBJECT_TYPE_DOOR: autoCloseTime = door.autoCloseTime; break; + case GAMEOBJECT_TYPE_BUTTON: autoCloseTime = button.autoCloseTime; break; + case GAMEOBJECT_TYPE_TRAP: autoCloseTime = trap.autoCloseTime; break; + case GAMEOBJECT_TYPE_GOOBER: autoCloseTime = goober.autoCloseTime; break; + case GAMEOBJECT_TYPE_TRANSPORT: autoCloseTime = transport.autoCloseTime; break; + case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = areadamage.autoCloseTime; break; + default: break; + } + return autoCloseTime; // prior to 3.0.3, conversion was / 0x10000; + } + + uint32 GetLootId() const + { + switch (type) + { + case GAMEOBJECT_TYPE_CHEST: return chest.lootId; + case GAMEOBJECT_TYPE_FISHINGHOLE: return fishinghole.lootId; + default: return 0; + } + } + + uint32 GetGossipMenuId() const + { + switch (type) + { + case GAMEOBJECT_TYPE_QUESTGIVER: return questgiver.gossipID; + case GAMEOBJECT_TYPE_GOOBER: return goober.gossipID; + default: return 0; + } + } + + uint32 GetEventScriptId() const + { + switch (type) + { + case GAMEOBJECT_TYPE_GOOBER: return goober.eventId; + case GAMEOBJECT_TYPE_CHEST: return chest.eventId; + case GAMEOBJECT_TYPE_CAMERA: return camera.eventID; + default: return 0; + } + } + + uint32 GetCooldown() const // Cooldown preventing goober and traps to cast spell + { + switch (type) + { + case GAMEOBJECT_TYPE_TRAP: return trap.cooldown; + case GAMEOBJECT_TYPE_GOOBER: return goober.cooldown; + default: return 0; + } + } + + void InitializeQueryData(); + WorldPacket BuildQueryData(LocaleConstant loc) const; +}; + +// From `gameobject_template_addon` +struct GameObjectTemplateAddon +{ + uint32 entry; + uint32 faction; + uint32 flags; + uint32 mingold; + uint32 maxgold; +}; + +struct GameObjectLocale +{ + std::vector<std::string> Name; + std::vector<std::string> CastBarCaption; +}; + +struct TC_GAME_API QuaternionData +{ + float x, y, z, w; + + QuaternionData() : x(0.0f), y(0.0f), z(0.0f), w(1.0f) { } + QuaternionData(float X, float Y, float Z, float W) : x(X), y(Y), z(Z), w(W) { } + + bool isUnit() const; + static QuaternionData fromEulerAnglesZYX(float Z, float Y, float X); +}; + +// `gameobject_addon` table +struct GameObjectAddon +{ + QuaternionData ParentRotation; + InvisibilityType invisibilityType; + uint32 InvisibilityValue; +}; + +// from `gameobject` +struct GameObjectData +{ + explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), + animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), ScriptId(0), dbData(true) { } + uint32 id; // entry in gamobject_template + uint16 mapid; + uint32 phaseMask; + float posX; + float posY; + float posZ; + float orientation; + QuaternionData rotation; + int32 spawntimesecs; + uint32 animprogress; + GOState go_state; + uint8 spawnMask; + uint8 artKit; + uint32 ScriptId; + bool dbData; +}; + +#endif // GameObjectData_h__ diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index 523b2e440a7..847142f2ad4 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -98,7 +98,7 @@ bool Bag::Create(ObjectGuid::LowType guidlow, uint32 itemid, Player const* owner for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) { SetGuidValue(CONTAINER_FIELD_SLOT_1 + (i*2), ObjectGuid::Empty); - m_bagslot[i] = NULL; + m_bagslot[i] = nullptr; } return true; @@ -121,7 +121,7 @@ bool Bag::LoadFromDB(ObjectGuid::LowType guid, ObjectGuid owner_guid, Field* fie { SetGuidValue(CONTAINER_FIELD_SLOT_1 + (i * 2), ObjectGuid::Empty); delete m_bagslot[i]; - m_bagslot[i] = NULL; + m_bagslot[i] = nullptr; } return true; @@ -151,9 +151,9 @@ void Bag::RemoveItem(uint8 slot, bool /*update*/) ASSERT(slot < MAX_BAG_SIZE); if (m_bagslot[slot]) - m_bagslot[slot]->SetContainer(NULL); + m_bagslot[slot]->SetContainer(nullptr); - m_bagslot[slot] = NULL; + m_bagslot[slot] = nullptr; SetGuidValue(CONTAINER_FIELD_SLOT_1 + (slot * 2), ObjectGuid::Empty); } @@ -161,7 +161,7 @@ void Bag::StoreItem(uint8 slot, Item* pItem, bool /*update*/) { ASSERT(slot < MAX_BAG_SIZE); - if (pItem && pItem->GetGUID() != this->GetGUID()) + if (pItem && pItem->GetGUID() != GetGUID()) { m_bagslot[slot] = pItem; SetGuidValue(CONTAINER_FIELD_SLOT_1 + (slot * 2), pItem->GetGUID()); @@ -243,6 +243,6 @@ Item* Bag::GetItemByPos(uint8 slot) const if (slot < GetBagSize()) return m_bagslot[slot]; - return NULL; + return nullptr; } diff --git a/src/server/game/Entities/Item/Container/Bag.h b/src/server/game/Entities/Item/Container/Bag.h index 7f5e5aff2d3..e39a7ed6b66 100644 --- a/src/server/game/Entities/Item/Container/Bag.h +++ b/src/server/game/Entities/Item/Container/Bag.h @@ -23,7 +23,6 @@ #define MAX_BAG_SIZE 36 // 2.0.12 #include "Item.h" -#include "ItemTemplate.h" class TC_GAME_API Bag : public Item { @@ -42,8 +41,8 @@ class TC_GAME_API Bag : public Item void RemoveItem(uint8 slot, bool update); Item* GetItemByPos(uint8 slot) const; - uint32 GetItemCount(uint32 item, Item* eItem = NULL) const; - uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = NULL) const; + uint32 GetItemCount(uint32 item, Item* eItem = nullptr) const; + uint32 GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem = nullptr) const; uint8 GetSlotByItemGUID(ObjectGuid guid) const; bool IsEmpty() const; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 6ea1665ce35..7556c7d007c 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -16,20 +16,26 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" #include "Item.h" -#include "ObjectMgr.h" -#include "WorldPacket.h" +#include "Bag.h" +#include "Common.h" +#include "ConditionMgr.h" #include "DatabaseEnv.h" +#include "DBCStores.h" #include "ItemEnchantmentMgr.h" +#include "Log.h" #include "LootItemStorage.h" -#include "SpellMgr.h" -#include "SpellInfo.h" +#include "Map.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "ScriptMgr.h" -#include "ConditionMgr.h" +#include "SpellInfo.h" +#include "SpellMgr.h" #include "Player.h" -#include "WorldSession.h" #include "TradeData.h" +#include "UpdateData.h" +#include "WorldPacket.h" +#include "WorldSession.h" void AddItemsSetItem(Player* player, Item* item) { @@ -47,7 +53,7 @@ void AddItemsSetItem(Player* player, Item* item) if (set->required_skill_id && player->GetSkillValue(set->required_skill_id) < set->required_skill_value) return; - ItemSetEffect* eff = NULL; + ItemSetEffect* eff = nullptr; for (size_t x = 0; x < player->ItemSetEff.size(); ++x) { @@ -105,7 +111,7 @@ void AddItemsSetItem(Player* player, Item* item) } // spell cast only if fit form requirement, in other case will cast at form change - player->ApplyEquipSpell(spellInfo, NULL, true); + player->ApplyEquipSpell(spellInfo, nullptr, true); eff->spells[y] = spellInfo; break; } @@ -125,7 +131,7 @@ void RemoveItemsSetItem(Player*player, ItemTemplate const* proto) return; } - ItemSetEffect* eff = NULL; + ItemSetEffect* eff = nullptr; size_t setindex = 0; for (; setindex < player->ItemSetEff.size(); setindex++) { @@ -156,8 +162,8 @@ void RemoveItemsSetItem(Player*player, ItemTemplate const* proto) if (eff->spells[z] && eff->spells[z]->Id == set->spells[x]) { // spell can be not active if not fit form requirement - player->ApplyEquipSpell(eff->spells[z], NULL, false); - eff->spells[z]=NULL; + player->ApplyEquipSpell(eff->spells[z], nullptr, false); + eff->spells[z]=nullptr; break; } } @@ -167,7 +173,7 @@ void RemoveItemsSetItem(Player*player, ItemTemplate const* proto) { ASSERT(eff == player->ItemSetEff[setindex]); delete eff; - player->ItemSetEff[setindex] = NULL; + player->ItemSetEff[setindex] = nullptr; } } @@ -247,10 +253,10 @@ Item::Item() m_slot = 0; uState = ITEM_NEW; uQueuePos = -1; - m_container = NULL; + m_container = nullptr; m_lootGenerated = false; mb_in_trade = false; - m_lastPlayedTimeUpdate = time(NULL); + m_lastPlayedTimeUpdate = time(nullptr); m_refundRecipient = 0; m_paidMoney = 0; @@ -569,52 +575,6 @@ uint32 Item::GetSpell() return 0; } -int32 Item::GenerateItemRandomPropertyId(uint32 item_id) -{ - ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id); - - if (!itemProto) - return 0; - - // item must have one from this field values not null if it can have random enchantments - if ((!itemProto->RandomProperty) && (!itemProto->RandomSuffix)) - return 0; - - // item can have not null only one from field values - if ((itemProto->RandomProperty) && (itemProto->RandomSuffix)) - { - TC_LOG_ERROR("sql.sql", "Item template %u have RandomProperty == %u and RandomSuffix == %u, but must have one from field =0", itemProto->ItemId, itemProto->RandomProperty, itemProto->RandomSuffix); - return 0; - } - - // RandomProperty case - if (itemProto->RandomProperty) - { - uint32 randomPropId = GetItemEnchantMod(itemProto->RandomProperty); - ItemRandomPropertiesEntry const* random_id = sItemRandomPropertiesStore.LookupEntry(randomPropId); - if (!random_id) - { - TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in 'ItemRandomProperties.dbc'", randomPropId); - return 0; - } - - return random_id->ID; - } - // RandomSuffix case - else - { - uint32 randomPropId = GetItemEnchantMod(itemProto->RandomSuffix); - ItemRandomSuffixEntry const* random_id = sItemRandomSuffixStore.LookupEntry(randomPropId); - if (!random_id) - { - TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in sItemRandomSuffixStore.", randomPropId); - return 0; - } - - return -int32(random_id->ID); - } -} - void Item::SetItemRandomProperties(int32 randomPropId) { if (!randomPropId) @@ -668,7 +628,7 @@ void Item::SetState(ItemUpdateState state, Player* forplayer) // pretend the item never existed if (forplayer) { - RemoveFromUpdateQueueOf(forplayer); + RemoveItemFromUpdateQueueOf(this, forplayer); forplayer->DeleteRefundReference(GetGUID()); } delete this; @@ -681,7 +641,7 @@ void Item::SetState(ItemUpdateState state, Player* forplayer) uState = state; if (forplayer) - AddToUpdateQueueOf(forplayer); + AddItemToUpdateQueueOf(this, forplayer); } else { @@ -692,46 +652,46 @@ void Item::SetState(ItemUpdateState state, Player* forplayer) } } -void Item::AddToUpdateQueueOf(Player* player) +void AddItemToUpdateQueueOf(Item* item, Player* player) { - if (IsInUpdateQueue()) + if (item->IsInUpdateQueue()) return; - ASSERT(player != NULL); + ASSERT(player != nullptr); - if (player->GetGUID() != GetOwnerGUID()) + if (player->GetGUID() != item->GetOwnerGUID()) { - TC_LOG_DEBUG("entities.player.items", "Item::AddToUpdateQueueOf - Owner's guid (%s) and player's guid (%s) don't match!", - GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("entities.player.items", "AddItemToUpdateQueueOf - Owner's guid (%s) and player's guid (%s) don't match!", + item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); return; } if (player->m_itemUpdateQueueBlocked) return; - player->m_itemUpdateQueue.push_back(this); - uQueuePos = player->m_itemUpdateQueue.size()-1; + player->m_itemUpdateQueue.push_back(item); + item->uQueuePos = player->m_itemUpdateQueue.size() - 1; } -void Item::RemoveFromUpdateQueueOf(Player* player) +void RemoveItemFromUpdateQueueOf(Item* item, Player* player) { - if (!IsInUpdateQueue()) + if (!item->IsInUpdateQueue()) return; - ASSERT(player != NULL); + ASSERT(player != nullptr); - if (player->GetGUID() != GetOwnerGUID()) + if (player->GetGUID() != item->GetOwnerGUID()) { - TC_LOG_DEBUG("entities.player.items", "Item::RemoveFromUpdateQueueOf - Owner's guid (%s) and player's guid (%s) don't match!", - GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); + TC_LOG_DEBUG("entities.player.items", "RemoveItemFromUpdateQueueOf - Owner's guid (%s) and player's guid (%s) don't match!", + item->GetOwnerGUID().ToString().c_str(), player->GetGUID().ToString().c_str()); return; } if (player->m_itemUpdateQueueBlocked) return; - player->m_itemUpdateQueue[uQueuePos] = NULL; - uQueuePos = -1; + player->m_itemUpdateQueue[item->uQueuePos] = nullptr; + item->uQueuePos = -1; } uint8 Item::GetBagSlot() const @@ -752,7 +712,7 @@ bool Item::CanBeTraded(bool mail, bool trade) const if ((!mail || !IsBoundAccountWide()) && (IsSoulBound() && (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE) || !trade))) return false; - if (IsBag() && (Player::IsBagPos(GetPos()) || !((Bag const*)this)->IsEmpty())) + if (IsBag() && (Player::IsBagPos(GetPos()) || !ToBag()->IsEmpty())) return false; if (Player* owner = GetOwner()) @@ -769,7 +729,7 @@ bool Item::CanBeTraded(bool mail, bool trade) const return true; } -bool Item::HasEnchantRequiredSkill(const Player* player) const +bool Item::HasEnchantRequiredSkill(Player const* player) const { // Check all enchants for required skill for (uint32 enchant_slot = PERM_ENCHANTMENT_SLOT; enchant_slot < MAX_ENCHANTMENT_SLOT; ++enchant_slot) @@ -1002,7 +962,7 @@ void Item::SendUpdateSockets() for (uint32 i = SOCK_ENCHANTMENT_SLOT; i <= BONUS_ENCHANTMENT_SLOT; ++i) data << uint32(GetEnchantmentId(EnchantmentSlot(i))); - GetOwner()->GetSession()->SendPacket(&data); + GetOwner()->SendDirectMessage(&data); } // Though the client has the information in the item's data field, @@ -1017,7 +977,7 @@ void Item::SendTimeUpdate(Player* owner) WorldPacket data(SMSG_ITEM_TIME_UPDATE, (8+4)); data << uint64(GetGUID()); data << uint32(duration); - owner->GetSession()->SendPacket(&data); + owner->SendDirectMessage(&data); } Item* Item::CreateItem(uint32 itemEntry, uint32 count, Player const* player /*= nullptr*/) @@ -1074,7 +1034,7 @@ bool Item::IsBindedNotWith(Player const* player) const return false; if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE)) - if (allowedGUIDs.find(player->GetGUID().GetCounter()) != allowedGUIDs.end()) + if (allowedGUIDs.find(player->GetGUID()) != allowedGUIDs.end()) return false; // BOA item case @@ -1132,7 +1092,7 @@ void Item::DeleteRefundDataFromDB(SQLTransaction* trans) } } -void Item::SetNotRefundable(Player* owner, bool changestate /*=true*/, SQLTransaction* trans /*=NULL*/) +void Item::SetNotRefundable(Player* owner, bool changestate /*=true*/, SQLTransaction* trans /*=nullptr*/) { if (!HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_REFUNDABLE)) return; @@ -1159,7 +1119,7 @@ void Item::UpdatePlayedTime(Player* owner) // Get current played time uint32 current_playtime = GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME); // Calculate time elapsed since last played time update - time_t curtime = time(NULL); + time_t curtime = time(nullptr); uint32 elapsed = uint32(curtime - m_lastPlayedTimeUpdate); uint32 new_playtime = current_playtime + elapsed; // Check if the refund timer has expired yet @@ -1180,7 +1140,7 @@ void Item::UpdatePlayedTime(Player* owner) uint32 Item::GetPlayedTime() { - time_t curtime = time(NULL); + time_t curtime = time(nullptr); uint32 elapsed = uint32(curtime - m_lastPlayedTimeUpdate); return GetUInt32Value(ITEM_FIELD_CREATE_PLAYED_TIME) + elapsed; } @@ -1190,7 +1150,7 @@ bool Item::IsRefundExpired() return (GetPlayedTime() > 2*HOUR); } -void Item::SetSoulboundTradeable(AllowedLooterSet const& allowedLooters) +void Item::SetSoulboundTradeable(GuidSet const& allowedLooters) { SetFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_BOP_TRADEABLE); allowedGUIDs = allowedLooters; diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 421d13b9aa1..a34ff9124ff 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -19,11 +19,13 @@ #ifndef TRINITYCORE_ITEM_H #define TRINITYCORE_ITEM_H -#include "Common.h" #include "Object.h" -#include "LootMgr.h" +#include "Common.h" +#include "DatabaseEnvFwd.h" +#include "ItemDefines.h" +#include "ItemEnchantmentMgr.h" #include "ItemTemplate.h" -#include "DatabaseEnv.h" +#include "Loot.h" class SpellInfo; class Bag; @@ -36,144 +38,6 @@ struct ItemSetEffect SpellInfo const* spells[8]; }; -enum InventoryResult -{ - EQUIP_ERR_OK = 0, - EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1, - EQUIP_ERR_CANT_EQUIP_SKILL = 2, - EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT = 3, - EQUIP_ERR_BAG_FULL = 4, - EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG = 5, - EQUIP_ERR_CANT_TRADE_EQUIP_BAGS = 6, - EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE = 7, - EQUIP_ERR_NO_REQUIRED_PROFICIENCY = 8, - EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE = 9, - EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM = 10, - EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2 = 11, - EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2 = 12, - EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED = 13, - EQUIP_ERR_CANT_DUAL_WIELD = 14, - EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG = 15, - EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 = 16, - EQUIP_ERR_CANT_CARRY_MORE_OF_THIS = 17, - EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3 = 18, - EQUIP_ERR_ITEM_CANT_STACK = 19, - EQUIP_ERR_ITEM_CANT_BE_EQUIPPED = 20, - EQUIP_ERR_ITEMS_CANT_BE_SWAPPED = 21, - EQUIP_ERR_SLOT_IS_EMPTY = 22, - EQUIP_ERR_ITEM_NOT_FOUND = 23, - EQUIP_ERR_CANT_DROP_SOULBOUND = 24, - EQUIP_ERR_OUT_OF_RANGE = 25, - EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT = 26, - EQUIP_ERR_COULDNT_SPLIT_ITEMS = 27, - EQUIP_ERR_MISSING_REAGENT = 28, - EQUIP_ERR_NOT_ENOUGH_MONEY = 29, - EQUIP_ERR_NOT_A_BAG = 30, - EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS = 31, - EQUIP_ERR_DONT_OWN_THAT_ITEM = 32, - EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER = 33, - EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT = 34, - EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK = 35, - EQUIP_ERR_ITEM_LOCKED = 36, - EQUIP_ERR_YOU_ARE_STUNNED = 37, - EQUIP_ERR_YOU_ARE_DEAD = 38, - EQUIP_ERR_CANT_DO_RIGHT_NOW = 39, - EQUIP_ERR_INT_BAG_ERROR = 40, - EQUIP_ERR_CAN_EQUIP_ONLY1_BOLT = 41, - EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH = 42, - EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED = 43, - EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED = 44, - EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED = 45, - EQUIP_ERR_BOUND_CANT_BE_WRAPPED = 46, - EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED = 47, - EQUIP_ERR_BAGS_CANT_BE_WRAPPED = 48, - EQUIP_ERR_ALREADY_LOOTED = 49, - EQUIP_ERR_INVENTORY_FULL = 50, - EQUIP_ERR_BANK_FULL = 51, - EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT = 52, - EQUIP_ERR_BAG_FULL3 = 53, - EQUIP_ERR_ITEM_NOT_FOUND2 = 54, - EQUIP_ERR_ITEM_CANT_STACK2 = 55, - EQUIP_ERR_BAG_FULL4 = 56, - EQUIP_ERR_ITEM_SOLD_OUT = 57, - EQUIP_ERR_OBJECT_IS_BUSY = 58, - EQUIP_ERR_NONE = 59, - EQUIP_ERR_NOT_IN_COMBAT = 60, - EQUIP_ERR_NOT_WHILE_DISARMED = 61, - EQUIP_ERR_BAG_FULL6 = 62, - EQUIP_ERR_CANT_EQUIP_RANK = 63, - EQUIP_ERR_CANT_EQUIP_REPUTATION = 64, - EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65, - EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66, - EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE = 67, - EQUIP_ERR_VENDOR_MISSING_TURNINS = 68, - EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69, - EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70, - EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71, - EQUIP_ERR_MAIL_BOUND_ITEM = 72, - EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING = 73, - EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75, - EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76, - EQUIP_ERR_TOO_MUCH_GOLD = 77, - EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78, - EQUIP_ERR_CANNOT_TRADE_THAT = 79, - EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80, - EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM = 81, - EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82, - // no output = 83, - EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED = 84, - EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED = 85, - EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED = 86, - EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW = 87, - EQUIP_ERR_CANT_EQUIP_NEED_TALENT = 88, - EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED = 89 -}; - -enum BuyResult -{ - BUY_ERR_CANT_FIND_ITEM = 0, - BUY_ERR_ITEM_ALREADY_SOLD = 1, - BUY_ERR_NOT_ENOUGHT_MONEY = 2, - BUY_ERR_SELLER_DONT_LIKE_YOU = 4, - BUY_ERR_DISTANCE_TOO_FAR = 5, - BUY_ERR_ITEM_SOLD_OUT = 7, - BUY_ERR_CANT_CARRY_MORE = 8, - BUY_ERR_RANK_REQUIRE = 11, - BUY_ERR_REPUTATION_REQUIRE = 12 -}; - -enum SellResult -{ - SELL_ERR_CANT_FIND_ITEM = 1, - SELL_ERR_CANT_SELL_ITEM = 2, // merchant doesn't like that item - SELL_ERR_CANT_FIND_VENDOR = 3, // merchant doesn't like you - SELL_ERR_YOU_DONT_OWN_THAT_ITEM = 4, // you don't own that item - SELL_ERR_UNK = 5, // nothing appears... - SELL_ERR_ONLY_EMPTY_BAG = 6 // can only do with empty bags -}; - -// -1 from client enchantment slot number -enum EnchantmentSlot -{ - PERM_ENCHANTMENT_SLOT = 0, - TEMP_ENCHANTMENT_SLOT = 1, - SOCK_ENCHANTMENT_SLOT = 2, - SOCK_ENCHANTMENT_SLOT_2 = 3, - SOCK_ENCHANTMENT_SLOT_3 = 4, - BONUS_ENCHANTMENT_SLOT = 5, - PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment - MAX_INSPECTED_ENCHANTMENT_SLOT = 7, - - PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix - PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix - PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty - PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty - PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty - MAX_ENCHANTMENT_SLOT = 12 -}; - -#define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment) - #define MAX_GEM_SOCKETS MAX_ITEM_PROTO_SOCKETS// (BONUS_ENCHANTMENT_SLOT-SOCK_ENCHANTMENT_SLOT) and item proto size, equal value expected enum EnchantmentOffset @@ -185,14 +49,6 @@ enum EnchantmentOffset #define MAX_ENCHANTMENT_OFFSET 3 -enum EnchantmentSlotMask -{ - ENCHANTMENT_CAN_SOULBOUND = 0x01, - ENCHANTMENT_UNK1 = 0x02, - ENCHANTMENT_UNK2 = 0x04, - ENCHANTMENT_UNK3 = 0x08 -}; - enum ItemUpdateState { ITEM_UNCHANGED = 0, @@ -205,6 +61,9 @@ bool ItemCanGoIntoBag(ItemTemplate const* proto, ItemTemplate const* pBagProto); class TC_GAME_API Item : public Object { + friend void AddItemToUpdateQueueOf(Item* item, Player* player); + friend void RemoveItemFromUpdateQueueOf(Item* item, Player* player); + public: static Item* CreateItem(uint32 itemEntry, uint32 count, Player const* player = nullptr); Item* CloneItem(uint32 count, Player const* player = nullptr) const; @@ -234,8 +93,8 @@ class TC_GAME_API Item : public Object void SaveRefundDataToDB(); void DeleteRefundDataFromDB(SQLTransaction* trans); - Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return NULL; } - const Bag* ToBag() const { if (IsBag()) return reinterpret_cast<const Bag*>(this); else return NULL; } + Bag* ToBag() { if (IsBag()) return reinterpret_cast<Bag*>(this); else return nullptr; } + Bag const* ToBag() const { if (IsBag()) return reinterpret_cast<Bag const*>(this); else return nullptr; } bool IsLocked() const { return !HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_UNLOCKED); } bool IsBag() const { return GetTemplate()->InventoryType == INVTYPE_BAG; } @@ -246,7 +105,7 @@ class TC_GAME_API Item : public Object void SetInTrade(bool b = true) { mb_in_trade = b; } bool IsInTrade() const { return mb_in_trade; } - bool HasEnchantRequiredSkill(const Player* player) const; + bool HasEnchantRequiredSkill(Player const* player) const; uint32 GetEnchantRequiredLevel() const; bool IsFitToSpellRequirements(SpellInfo const* spellInfo) const; @@ -267,7 +126,7 @@ class TC_GAME_API Item : public Object uint16 GetPos() const { return uint16(GetBagSlot()) << 8 | GetSlot(); } void SetContainer(Bag* container) { m_container = container; } - bool IsInBag() const { return m_container != NULL; } + bool IsInBag() const { return m_container != nullptr; } bool IsEquipped() const; uint32 GetSkill(); @@ -278,7 +137,6 @@ class TC_GAME_API Item : public Object uint32 GetItemSuffixFactor() const { return GetUInt32Value(ITEM_FIELD_PROPERTY_SEED); } void SetItemRandomProperties(int32 randomPropId); void UpdateItemSuffixFactor(); - static int32 GenerateItemRandomPropertyId(uint32 item_id); void SetEnchantment(EnchantmentSlot slot, uint32 id, uint32 duration, uint32 charges, ObjectGuid caster = ObjectGuid::Empty); void SetEnchantmentDuration(EnchantmentSlot slot, uint32 duration, Player* owner); void SetEnchantmentCharges(EnchantmentSlot slot, uint32 charges); @@ -304,9 +162,7 @@ class TC_GAME_API Item : public Object // Update States ItemUpdateState GetState() const { return uState; } - void SetState(ItemUpdateState state, Player* forplayer = NULL); - void AddToUpdateQueueOf(Player* player); - void RemoveFromUpdateQueueOf(Player* player); + void SetState(ItemUpdateState state, Player* forplayer = nullptr); bool IsInUpdateQueue() const { return uQueuePos != -1; } uint16 GetQueuePos() const { return uQueuePos; } void FSetState(ItemUpdateState state) // forced @@ -322,7 +178,7 @@ class TC_GAME_API Item : public Object bool IsConjuredConsumable() const { return GetTemplate()->IsConjuredConsumable(); } // Item Refund system - void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = NULL); + void SetNotRefundable(Player* owner, bool changestate = true, SQLTransaction* trans = nullptr); void SetRefundRecipient(ObjectGuid::LowType pGuidLow) { m_refundRecipient = pGuidLow; } void SetPaidMoney(uint32 money) { m_paidMoney = money; } void SetPaidExtendedCost(uint32 iece) { m_paidExtendedCost = iece; } @@ -336,7 +192,7 @@ class TC_GAME_API Item : public Object bool IsRefundExpired(); // Soulbound trade system - void SetSoulboundTradeable(AllowedLooterSet const& allowedLooters); + void SetSoulboundTradeable(GuidSet const& allowedLooters); void ClearSoulboundTradeable(Player* currentOwner); bool CheckSoulboundTradeExpire(); @@ -357,6 +213,6 @@ class TC_GAME_API Item : public Object ObjectGuid::LowType m_refundRecipient; uint32 m_paidMoney; uint32 m_paidExtendedCost; - AllowedLooterSet allowedGUIDs; + GuidSet allowedGUIDs; }; #endif diff --git a/src/server/game/Entities/Item/ItemDefines.h b/src/server/game/Entities/Item/ItemDefines.h new file mode 100644 index 00000000000..a4e59526a91 --- /dev/null +++ b/src/server/game/Entities/Item/ItemDefines.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef ItemDefines_h__ +#define ItemDefines_h__ + +#include "Define.h" + +enum InventoryResult : uint8 +{ + EQUIP_ERR_OK = 0, + EQUIP_ERR_CANT_EQUIP_LEVEL_I = 1, + EQUIP_ERR_CANT_EQUIP_SKILL = 2, + EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT = 3, + EQUIP_ERR_BAG_FULL = 4, + EQUIP_ERR_NONEMPTY_BAG_OVER_OTHER_BAG = 5, + EQUIP_ERR_CANT_TRADE_EQUIP_BAGS = 6, + EQUIP_ERR_ONLY_AMMO_CAN_GO_HERE = 7, + EQUIP_ERR_NO_REQUIRED_PROFICIENCY = 8, + EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE = 9, + EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM = 10, + EQUIP_ERR_YOU_CAN_NEVER_USE_THAT_ITEM2 = 11, + EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE2 = 12, + EQUIP_ERR_CANT_EQUIP_WITH_TWOHANDED = 13, + EQUIP_ERR_CANT_DUAL_WIELD = 14, + EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG = 15, + EQUIP_ERR_ITEM_DOESNT_GO_INTO_BAG2 = 16, + EQUIP_ERR_CANT_CARRY_MORE_OF_THIS = 17, + EQUIP_ERR_NO_EQUIPMENT_SLOT_AVAILABLE3 = 18, + EQUIP_ERR_ITEM_CANT_STACK = 19, + EQUIP_ERR_ITEM_CANT_BE_EQUIPPED = 20, + EQUIP_ERR_ITEMS_CANT_BE_SWAPPED = 21, + EQUIP_ERR_SLOT_IS_EMPTY = 22, + EQUIP_ERR_ITEM_NOT_FOUND = 23, + EQUIP_ERR_CANT_DROP_SOULBOUND = 24, + EQUIP_ERR_OUT_OF_RANGE = 25, + EQUIP_ERR_TRIED_TO_SPLIT_MORE_THAN_COUNT = 26, + EQUIP_ERR_COULDNT_SPLIT_ITEMS = 27, + EQUIP_ERR_MISSING_REAGENT = 28, + EQUIP_ERR_NOT_ENOUGH_MONEY = 29, + EQUIP_ERR_NOT_A_BAG = 30, + EQUIP_ERR_CAN_ONLY_DO_WITH_EMPTY_BAGS = 31, + EQUIP_ERR_DONT_OWN_THAT_ITEM = 32, + EQUIP_ERR_CAN_EQUIP_ONLY1_QUIVER = 33, + EQUIP_ERR_MUST_PURCHASE_THAT_BAG_SLOT = 34, + EQUIP_ERR_TOO_FAR_AWAY_FROM_BANK = 35, + EQUIP_ERR_ITEM_LOCKED = 36, + EQUIP_ERR_YOU_ARE_STUNNED = 37, + EQUIP_ERR_YOU_ARE_DEAD = 38, + EQUIP_ERR_CANT_DO_RIGHT_NOW = 39, + EQUIP_ERR_INT_BAG_ERROR = 40, + EQUIP_ERR_CAN_EQUIP_ONLY1_BOLT = 41, + EQUIP_ERR_CAN_EQUIP_ONLY1_AMMOPOUCH = 42, + EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED = 43, + EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED = 44, + EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED = 45, + EQUIP_ERR_BOUND_CANT_BE_WRAPPED = 46, + EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED = 47, + EQUIP_ERR_BAGS_CANT_BE_WRAPPED = 48, + EQUIP_ERR_ALREADY_LOOTED = 49, + EQUIP_ERR_INVENTORY_FULL = 50, + EQUIP_ERR_BANK_FULL = 51, + EQUIP_ERR_ITEM_IS_CURRENTLY_SOLD_OUT = 52, + EQUIP_ERR_BAG_FULL3 = 53, + EQUIP_ERR_ITEM_NOT_FOUND2 = 54, + EQUIP_ERR_ITEM_CANT_STACK2 = 55, + EQUIP_ERR_BAG_FULL4 = 56, + EQUIP_ERR_ITEM_SOLD_OUT = 57, + EQUIP_ERR_OBJECT_IS_BUSY = 58, + EQUIP_ERR_NONE = 59, + EQUIP_ERR_NOT_IN_COMBAT = 60, + EQUIP_ERR_NOT_WHILE_DISARMED = 61, + EQUIP_ERR_BAG_FULL6 = 62, + EQUIP_ERR_CANT_EQUIP_RANK = 63, + EQUIP_ERR_CANT_EQUIP_REPUTATION = 64, + EQUIP_ERR_TOO_MANY_SPECIAL_BAGS = 65, + EQUIP_ERR_LOOT_CANT_LOOT_THAT_NOW = 66, + EQUIP_ERR_ITEM_UNIQUE_EQUIPABLE = 67, + EQUIP_ERR_VENDOR_MISSING_TURNINS = 68, + EQUIP_ERR_NOT_ENOUGH_HONOR_POINTS = 69, + EQUIP_ERR_NOT_ENOUGH_ARENA_POINTS = 70, + EQUIP_ERR_ITEM_MAX_COUNT_SOCKETED = 71, + EQUIP_ERR_MAIL_BOUND_ITEM = 72, + EQUIP_ERR_NO_SPLIT_WHILE_PROSPECTING = 73, + EQUIP_ERR_ITEM_MAX_COUNT_EQUIPPED_SOCKETED = 75, + EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED = 76, + EQUIP_ERR_TOO_MUCH_GOLD = 77, + EQUIP_ERR_NOT_DURING_ARENA_MATCH = 78, + EQUIP_ERR_CANNOT_TRADE_THAT = 79, + EQUIP_ERR_PERSONAL_ARENA_RATING_TOO_LOW = 80, + EQUIP_ERR_EVENT_AUTOEQUIP_BIND_CONFIRM = 81, + EQUIP_ERR_ARTEFACTS_ONLY_FOR_OWN_CHARACTERS = 82, + // no output = 83, + EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_COUNT_EXCEEDED = 84, + EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_SOCKETED_EXCEEDED = 85, + EQUIP_ERR_SCALING_STAT_ITEM_LEVEL_EXCEEDED = 86, + EQUIP_ERR_PURCHASE_LEVEL_TOO_LOW = 87, + EQUIP_ERR_CANT_EQUIP_NEED_TALENT = 88, + EQUIP_ERR_ITEM_MAX_LIMIT_CATEGORY_EQUIPPED_EXCEEDED = 89 +}; + +enum BuyResult +{ + BUY_ERR_CANT_FIND_ITEM = 0, + BUY_ERR_ITEM_ALREADY_SOLD = 1, + BUY_ERR_NOT_ENOUGHT_MONEY = 2, + BUY_ERR_SELLER_DONT_LIKE_YOU = 4, + BUY_ERR_DISTANCE_TOO_FAR = 5, + BUY_ERR_ITEM_SOLD_OUT = 7, + BUY_ERR_CANT_CARRY_MORE = 8, + BUY_ERR_RANK_REQUIRE = 11, + BUY_ERR_REPUTATION_REQUIRE = 12 +}; + +enum SellResult +{ + SELL_ERR_CANT_FIND_ITEM = 1, + SELL_ERR_CANT_SELL_ITEM = 2, // merchant doesn't like that item + SELL_ERR_CANT_FIND_VENDOR = 3, // merchant doesn't like you + SELL_ERR_YOU_DONT_OWN_THAT_ITEM = 4, // you don't own that item + SELL_ERR_UNK = 5, // nothing appears... + SELL_ERR_ONLY_EMPTY_BAG = 6 // can only do with empty bags +}; + +// -1 from client enchantment slot number +enum EnchantmentSlot : uint16 +{ + PERM_ENCHANTMENT_SLOT = 0, + TEMP_ENCHANTMENT_SLOT = 1, + SOCK_ENCHANTMENT_SLOT = 2, + SOCK_ENCHANTMENT_SLOT_2 = 3, + SOCK_ENCHANTMENT_SLOT_3 = 4, + BONUS_ENCHANTMENT_SLOT = 5, + PRISMATIC_ENCHANTMENT_SLOT = 6, // added at apply special permanent enchantment + MAX_INSPECTED_ENCHANTMENT_SLOT = 7, + + PROP_ENCHANTMENT_SLOT_0 = 7, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_1 = 8, // used with RandomSuffix + PROP_ENCHANTMENT_SLOT_2 = 9, // used with RandomSuffix and RandomProperty + PROP_ENCHANTMENT_SLOT_3 = 10, // used with RandomProperty + PROP_ENCHANTMENT_SLOT_4 = 11, // used with RandomProperty + MAX_ENCHANTMENT_SLOT = 12 +}; + +#define MAX_VISIBLE_ITEM_OFFSET 2 // 2 fields per visible item (entry+enchantment) + +#endif // ItemDefines_h__ diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index f316ee84e83..50e0805797c 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -22,6 +22,8 @@ #include "ObjectMgr.h" #include "Util.h" #include "DBCStores.h" +#include "Random.h" +#include "Timer.h" #include <list> #include <vector> @@ -118,6 +120,52 @@ uint32 GetItemEnchantMod(int32 entry) return 0; } +int32 GenerateItemRandomPropertyId(uint32 item_id) +{ + ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id); + + if (!itemProto) + return 0; + + // item must have one from this field values not null if it can have random enchantments + if ((!itemProto->RandomProperty) && (!itemProto->RandomSuffix)) + return 0; + + // item can have not null only one from field values + if ((itemProto->RandomProperty) && (itemProto->RandomSuffix)) + { + TC_LOG_ERROR("sql.sql", "Item template %u have RandomProperty == %u and RandomSuffix == %u, but must have one from field =0", itemProto->ItemId, itemProto->RandomProperty, itemProto->RandomSuffix); + return 0; + } + + // RandomProperty case + if (itemProto->RandomProperty) + { + uint32 randomPropId = GetItemEnchantMod(itemProto->RandomProperty); + ItemRandomPropertiesEntry const* random_id = sItemRandomPropertiesStore.LookupEntry(randomPropId); + if (!random_id) + { + TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in 'ItemRandomProperties.dbc'", randomPropId); + return 0; + } + + return random_id->ID; + } + // RandomSuffix case + else + { + uint32 randomPropId = GetItemEnchantMod(itemProto->RandomSuffix); + ItemRandomSuffixEntry const* random_id = sItemRandomSuffixStore.LookupEntry(randomPropId); + if (!random_id) + { + TC_LOG_ERROR("sql.sql", "Enchantment id #%u used but it doesn't have records in sItemRandomSuffixStore.", randomPropId); + return 0; + } + + return -int32(random_id->ID); + } +} + uint32 GenerateEnchSuffixFactor(uint32 item_id) { ItemTemplate const* itemProto = sObjectMgr->GetItemTemplate(item_id); diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.h b/src/server/game/Entities/Item/ItemEnchantmentMgr.h index a9d8cf52f91..9692a491c89 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.h +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.h @@ -22,6 +22,7 @@ #include "Common.h" TC_GAME_API void LoadRandomEnchantmentsTable(); +TC_GAME_API int32 GenerateItemRandomPropertyId(uint32 item_id); TC_GAME_API uint32 GetItemEnchantMod(int32 entry); TC_GAME_API uint32 GenerateEnchSuffixFactor(uint32 item_id); diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 5ea34aedb01..0f43a6bb8c2 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -22,6 +22,7 @@ #include "Common.h" #include "SharedDefines.h" #include "WorldPacket.h" +#include <vector> class ObjectMgr; @@ -256,7 +257,7 @@ enum SocketColor #define SOCKET_COLOR_ALL (SOCKET_COLOR_META | SOCKET_COLOR_RED | SOCKET_COLOR_YELLOW | SOCKET_COLOR_BLUE) -enum InventoryType +enum InventoryType : uint8 { INVTYPE_NON_EQUIP = 0, INVTYPE_HEAD = 1, @@ -291,7 +292,7 @@ enum InventoryType #define MAX_INVTYPE 29 -enum ItemClass +enum ItemClass : uint8 { ITEM_CLASS_CONSUMABLE = 0, ITEM_CLASS_CONTAINER = 1, @@ -723,13 +724,10 @@ private: void _LoadTotalAP(); }; -// Benchmarked: Faster than std::map (insert/find) -typedef std::unordered_map<uint32, ItemTemplate> ItemTemplateContainer; - struct ItemLocale { - StringVector Name; - StringVector Description; + std::vector<std::string> Name; + std::vector<std::string> Description; }; struct ItemSetNameEntry @@ -740,7 +738,7 @@ struct ItemSetNameEntry struct ItemSetNameLocale { - StringVector Name; + std::vector<std::string> Name; }; #endif diff --git a/src/server/game/Entities/Object/MovementInfo.h b/src/server/game/Entities/Object/MovementInfo.h new file mode 100644 index 00000000000..f8262f44d51 --- /dev/null +++ b/src/server/game/Entities/Object/MovementInfo.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MovementInfo_h__ +#define MovementInfo_h__ + +#include "ObjectGuid.h" +#include "Position.h" + +struct MovementInfo +{ + // common + ObjectGuid guid; + uint32 flags; + uint16 flags2; + Position pos; + uint32 time; + + // transport + struct TransportInfo + { + void Reset() + { + guid.Clear(); + pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); + seat = -1; + time = 0; + time2 = 0; + } + + ObjectGuid guid; + Position pos; + int8 seat; + uint32 time; + uint32 time2; + } transport; + + // swimming/flying + float pitch; + + // falling + uint32 fallTime; + + // jumping + struct JumpInfo + { + void Reset() + { + zspeed = sinAngle = cosAngle = xyspeed = 0.0f; + } + + float zspeed, sinAngle, cosAngle, xyspeed; + + } jump; + + // spline + float splineElevation; + + MovementInfo() : + guid(), flags(0), flags2(0), time(0), pitch(0.0f), fallTime(0), splineElevation(0.0f) + { + pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); + transport.Reset(); + jump.Reset(); + } + + uint32 GetMovementFlags() const { return flags; } + void SetMovementFlags(uint32 flag) { flags = flag; } + void AddMovementFlag(uint32 flag) { flags |= flag; } + void RemoveMovementFlag(uint32 flag) { flags &= ~flag; } + bool HasMovementFlag(uint32 flag) const { return (flags & flag) != 0; } + + uint16 GetExtraMovementFlags() const { return flags2; } + void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; } + bool HasExtraMovementFlag(uint16 flag) const { return (flags2 & flag) != 0; } + + void SetFallTime(uint32 val) { fallTime = val; } + + void OutDebug(); +}; + +#endif // MovementInfo_h__ diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 6f3a96102cd..ba48a64d719 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -17,33 +17,32 @@ */ #include "Object.h" +#include "BattlefieldMgr.h" +#include "Battleground.h" +#include "CellImpl.h" +#include "CinematicMgr.h" #include "Common.h" -#include "SharedDefines.h" -#include "WorldPacket.h" -#include "Opcodes.h" -#include "Log.h" -#include "World.h" #include "Creature.h" -#include "Player.h" -#include "Vehicle.h" -#include "ObjectMgr.h" -#include "UpdateData.h" -#include "UpdateMask.h" -#include "Util.h" -#include "ObjectAccessor.h" -#include "Transport.h" -#include "VMapFactory.h" -#include "CellImpl.h" -#include "GridNotifiers.h" +#include "GameTime.h" #include "GridNotifiersImpl.h" -#include "UpdateFieldFlags.h" +#include "Item.h" +#include "Log.h" +#include "Map.h" +#include "MovementInfo.h" +#include "MovementPacketBuilder.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "OutdoorPvPMgr.h" +#include "Player.h" #include "TemporarySummon.h" #include "Totem.h" -#include "OutdoorPvPMgr.h" -#include "MovementPacketBuilder.h" -#include "BattlefieldMgr.h" -#include "Battleground.h" -#include "GameTime.h" +#include "Transport.h" +#include "Unit.h" +#include "UpdateFieldFlags.h" +#include "Vehicle.h" +#include "VMapFactory.h" +#include "World.h" +#include <G3D/Vector3.h> Object::Object() : m_PackGUID(sizeof(uint64)+1) { @@ -51,7 +50,7 @@ Object::Object() : m_PackGUID(sizeof(uint64)+1) m_objectType = TYPEMASK_OBJECT; m_updateFlag = UPDATEFLAG_NONE; - m_uint32Values = NULL; + m_uint32Values = nullptr; m_valuesCount = 0; _fieldNotifyFlags = UF_FLAG_DYNAMIC; @@ -227,7 +226,7 @@ void Object::SendUpdateToPlayer(Player* player) else BuildCreateUpdateBlockForPlayer(&upd, player); upd.BuildPacket(&packet); - player->GetSession()->SendPacket(&packet); + player->SendDirectMessage(&packet); } void Object::BuildValuesUpdateBlockForPlayer(UpdateData* data, Player* target) const @@ -259,7 +258,7 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const { WorldPacket data(SMSG_ARENA_UNIT_DESTROYED, 8); data << uint64(GetGUID()); - target->GetSession()->SendPacket(&data); + target->SendDirectMessage(&data); } } } @@ -269,7 +268,7 @@ void Object::DestroyForPlayer(Player* target, bool onDeath) const //! If the following bool is true, the client will call "void CGUnit_C::OnDeath()" for this object. //! OnDeath() does for eg trigger death animation and interrupts certain spells/missiles/auras/sounds... data << uint8(onDeath ? 1 : 0); - target->GetSession()->SendPacket(&data); + target->SendDirectMessage(&data); } int32 Object::GetInt32Value(uint16 index) const @@ -318,8 +317,8 @@ ObjectGuid Object::GetGuidValue(uint16 index) const void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const { - Unit const* unit = NULL; - WorldObject const* object = NULL; + Unit const* unit = nullptr; + WorldObject const* object = nullptr; if (isType(TYPEMASK_UNIT)) unit = ToUnit(); @@ -493,7 +492,7 @@ void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* targe UpdateMask updateMask; updateMask.SetCount(m_valuesCount); - uint32* flags = NULL; + uint32* flags = nullptr; uint32 visibleFlag = GetUpdateFieldData(target, flags); ASSERT(flags); @@ -974,7 +973,7 @@ void MovementInfo::OutDebug() TC_LOG_DEBUG("misc", "%s", guid.ToString().c_str()); TC_LOG_DEBUG("misc", "flags %u", flags); TC_LOG_DEBUG("misc", "flags2 %u", flags2); - TC_LOG_DEBUG("misc", "time %u current time " UI64FMTD "", flags2, uint64(::time(NULL))); + TC_LOG_DEBUG("misc", "time %u current time " UI64FMTD "", flags2, uint64(::time(nullptr))); TC_LOG_DEBUG("misc", "position: `%s`", pos.ToString().c_str()); if (flags & MOVEMENTFLAG_ONTRANSPORT) { @@ -999,8 +998,8 @@ void MovementInfo::OutDebug() } WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0), -m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL), -m_transport(NULL), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_currMap(NULL), m_InstanceId(0), +m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(nullptr), +m_transport(nullptr), m_zoneId(0), m_areaId(0), m_staticFloorZ(VMAP_INVALID_HEIGHT), m_currMap(nullptr), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0) { m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST); @@ -1046,14 +1045,14 @@ void WorldObject::setActive(bool on) if (on) { if (GetTypeId() == TYPEID_UNIT) - map->AddToActive(this->ToCreature()); + map->AddToActive(ToCreature()); else if (GetTypeId() == TYPEID_DYNAMICOBJECT) map->AddToActive((DynamicObject*)this); } else { if (GetTypeId() == TYPEID_UNIT) - map->RemoveFromActive(this->ToCreature()); + map->RemoveFromActive(ToCreature()); else if (GetTypeId() == TYPEID_DYNAMICOBJECT) map->RemoveFromActive((DynamicObject*)this); } @@ -1109,10 +1108,10 @@ void WorldObject::RemoveFromWorld() InstanceScript* WorldObject::GetInstanceScript() { Map* map = GetMap(); - return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceScript() : NULL; + return map->IsDungeon() ? ((InstanceMap*)map)->GetInstanceScript() : nullptr; } -float WorldObject::GetDistanceZ(const WorldObject* obj) const +float WorldObject::GetDistanceZ(WorldObject const* obj) const { float dz = std::fabs(GetPositionZ() - obj->GetPositionZ()); float sizefactor = GetCombatReach() + obj->GetCombatReach(); @@ -1142,13 +1141,13 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool return thisOrTransport->IsInDist2d(objOrObjTransport, maxdist); } -float WorldObject::GetDistance(const WorldObject* obj) const +float WorldObject::GetDistance(WorldObject const* obj) const { float d = GetExactDist(obj) - GetCombatReach() - obj->GetCombatReach(); return d > 0.0f ? d : 0.0f; } -float WorldObject::GetDistance(const Position &pos) const +float WorldObject::GetDistance(Position const& pos) const { float d = GetExactDist(&pos) - GetCombatReach(); return d > 0.0f ? d : 0.0f; @@ -1160,7 +1159,7 @@ float WorldObject::GetDistance(float x, float y, float z) const return d > 0.0f ? d : 0.0f; } -float WorldObject::GetDistance2d(const WorldObject* obj) const +float WorldObject::GetDistance2d(WorldObject const* obj) const { float d = GetExactDist2d(obj) - GetCombatReach() - obj->GetCombatReach(); return d > 0.0f ? d : 0.0f; @@ -1172,14 +1171,14 @@ float WorldObject::GetDistance2d(float x, float y) const return d > 0.0f ? d : 0.0f; } -bool WorldObject::IsSelfOrInSameMap(const WorldObject* obj) const +bool WorldObject::IsSelfOrInSameMap(WorldObject const* obj) const { if (this == obj) return true; return IsInMap(obj); } -bool WorldObject::IsInMap(const WorldObject* obj) const +bool WorldObject::IsInMap(WorldObject const* obj) const { if (obj) return IsInWorld() && obj->IsInWorld() && (GetMap() == obj->GetMap()); @@ -1191,7 +1190,7 @@ bool WorldObject::IsWithinDist3d(float x, float y, float z, float dist) const return IsInDist(x, y, z, dist + GetCombatReach()); } -bool WorldObject::IsWithinDist3d(const Position* pos, float dist) const +bool WorldObject::IsWithinDist3d(Position const* pos, float dist) const { return IsInDist(pos, dist + GetCombatReach()); } @@ -1201,7 +1200,7 @@ bool WorldObject::IsWithinDist2d(float x, float y, float dist) const return IsInDist2d(x, y, dist + GetCombatReach()); } -bool WorldObject::IsWithinDist2d(const Position* pos, float dist) const +bool WorldObject::IsWithinDist2d(Position const* pos, float dist) const { return IsInDist2d(pos, dist + GetCombatReach()); } @@ -1241,7 +1240,7 @@ bool WorldObject::IsWithinLOS(float ox, float oy, float oz, LineOfSightChecks ch return true; } -bool WorldObject::IsWithinLOSInMap(const WorldObject* obj, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const +bool WorldObject::IsWithinLOSInMap(WorldObject const* obj, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const { if (!IsInMap(obj)) return false; @@ -1379,7 +1378,7 @@ bool WorldObject::isInBack(WorldObject const* target, float arc) const return !HasInArc(2 * float(M_PI) - arc, target); } -void WorldObject::GetRandomPoint(const Position &pos, float distance, float &rand_x, float &rand_y, float &rand_z) const +void WorldObject::GetRandomPoint(Position const& pos, float distance, float& rand_x, float& rand_y, float& rand_z) const { if (!distance) { @@ -1401,7 +1400,7 @@ void WorldObject::GetRandomPoint(const Position &pos, float distance, float &ran UpdateGroundPositionZ(rand_x, rand_y, rand_z); // update to LOS height if available } -Position WorldObject::GetRandomPoint(const Position &srcPos, float distance) const +Position WorldObject::GetRandomPoint(Position const& srcPos, float distance) const { float x, y, z; GetRandomPoint(srcPos, distance, x, y, z); @@ -1507,7 +1506,7 @@ float WorldObject::GetVisibilityRange() const return GetMap()->GetVisibilityRange(); } -float WorldObject::GetSightRange(const WorldObject* target) const +float WorldObject::GetSightRange(WorldObject const* target) const { if (ToUnit()) { @@ -1573,7 +1572,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo } WorldObject const* viewpoint = this; - if (Player const* player = this->ToPlayer()) + if (Player const* player = ToPlayer()) viewpoint = player->GetViewpoint(); if (!viewpoint) @@ -1627,7 +1626,7 @@ bool WorldObject::CanNeverSee(WorldObject const* obj) const bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth, bool checkAlert) const { - const WorldObject* seer = this; + WorldObject const* seer = this; // Pets don't have detection, they use the detection of their masters if (Unit const* thisUnit = ToUnit()) @@ -1809,7 +1808,7 @@ void WorldObject::ResetMap() ASSERT(!IsInWorld()); if (IsWorldObject()) m_currMap->RemoveWorldObject(this); - m_currMap = NULL; + m_currMap = nullptr; //maybe not for corpse //m_mapId = 0; //m_InstanceId = 0; @@ -1881,7 +1880,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert break; } default: - return NULL; + return nullptr; } } @@ -1889,7 +1888,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert if (summoner) phase = summoner->GetPhaseMask(); - TempSummon* summon = NULL; + TempSummon* summon = nullptr; switch (mask) { case UNIT_MASK_SUMMON: @@ -1912,7 +1911,7 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, phase, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) { delete summon; - return NULL; + return nullptr; } summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); @@ -1937,14 +1936,14 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert * @param list List to store pointers to summoned creatures. */ -void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= NULL*/) +void Map::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= nullptr*/) { std::vector<TempSummonData> const* data = sObjectMgr->GetSummonGroup(GetId(), SUMMONER_TYPE_MAP, group); if (!data) return; for (std::vector<TempSummonData>::const_iterator itr = data->begin(); itr != data->end(); ++itr) - if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, NULL, itr->time)) + if (TempSummon* summon = SummonCreature(itr->entry, itr->pos, nullptr, itr->time)) if (list) list->push_back(summon); } @@ -1967,14 +1966,14 @@ void WorldObject::SetZoneScript() void WorldObject::ClearZoneScript() { - m_zoneScript = NULL; + m_zoneScript = nullptr; } TempSummon* WorldObject::SummonCreature(uint32 entry, Position const& pos, TempSummonType spwtype /*= TEMPSUMMON_MANUAL_DESPAWN*/, uint32 duration /*= 0*/, uint32 /*vehId = 0*/) const { if (Map* map = FindMap()) { - if (TempSummon* summon = map->SummonCreature(entry, pos, NULL, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : NULL)) + if (TempSummon* summon = map->SummonCreature(entry, pos, nullptr, duration, isType(TYPEMASK_UNIT) ? (Unit*)this : nullptr)) { summon->SetTempSummonType(spwtype); return summon; @@ -1997,7 +1996,7 @@ TempSummon* WorldObject::SummonCreature(uint32 id, float x, float y, float z, fl return SummonCreature(id, pos, spwtype, despwtime, 0); } -GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, G3D::Quat const& rot, uint32 respawnTime) +GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, QuaternionData const& rot, uint32 respawnTime) { if (!IsInWorld()) return nullptr; @@ -2027,7 +2026,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, Position const& pos, G3D return go; } -GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, G3D::Quat const& rot, uint32 respawnTime) +GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float z, float ang, QuaternionData const& rot, uint32 respawnTime) { if (!x && !y && !z) { @@ -2064,7 +2063,7 @@ Creature* WorldObject::SummonTrigger(float x, float y, float z, float ang, uint3 * @param group Id of group to summon. * @param list List to store pointers to summoned creatures. */ -void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= NULL*/) +void WorldObject::SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list /*= nullptr*/) { ASSERT((GetTypeId() == TYPEID_GAMEOBJECT || GetTypeId() == TYPEID_UNIT) && "Only GOs and creatures can summon npc groups!"); @@ -2215,7 +2214,7 @@ Position WorldObject::GetRandomNearPosition(float radius) return pos; } -void WorldObject::GetContactPoint(const WorldObject* obj, float &x, float &y, float &z, float distance2d /*= CONTACT_DISTANCE*/) const +void WorldObject::GetContactPoint(WorldObject const* obj, float& x, float& y, float& z, float distance2d /*= CONTACT_DISTANCE*/) const { // angle to face `obj` to `this` using distance includes size of `obj` GetNearPoint(obj, x, y, z, obj->GetCombatReach(), distance2d, GetAngle(obj)); @@ -2368,7 +2367,7 @@ bool WorldObject::InSamePhase(WorldObject const* obj) const return InSamePhase(obj->GetPhaseMask()); } -void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/) +void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= nullptr*/) { WorldPacket data(SMSG_PLAY_OBJECT_SOUND, 4+8); data << uint32(sound_id); @@ -2379,7 +2378,7 @@ void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/) SendMessageToSet(&data, true); } -void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/) +void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= nullptr*/) { WorldPacket data(SMSG_PLAY_SOUND, 4); data << uint32(sound_id); @@ -2389,7 +2388,7 @@ void WorldObject::PlayDirectSound(uint32 sound_id, Player* target /*= NULL*/) SendMessageToSet(&data, true); } -void WorldObject::PlayDirectMusic(uint32 music_id, Player* target /*= NULL*/) +void WorldObject::PlayDirectMusic(uint32 music_id, Player* target /*= nullptr*/) { WorldPacket data(SMSG_PLAY_MUSIC, 4); data << uint32(music_id); @@ -2445,7 +2444,7 @@ struct WorldObjectChangeAccumulator WorldObjectChangeAccumulator(WorldObject &obj, UpdateDataMapType &d) : i_updateDatas(d), i_object(obj) { } void Visit(PlayerMapType &m) { - Player* source = NULL; + Player* source = nullptr; for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { source = iter->GetSource(); @@ -2463,7 +2462,7 @@ struct WorldObjectChangeAccumulator void Visit(CreatureMapType &m) { - Creature* source = NULL; + Creature* source = nullptr; for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { source = iter->GetSource(); @@ -2478,7 +2477,7 @@ struct WorldObjectChangeAccumulator void Visit(DynamicObjectMapType &m) { - DynamicObject* source = NULL; + DynamicObject* source = nullptr; for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { source = iter->GetSource(); @@ -2486,7 +2485,7 @@ struct WorldObjectChangeAccumulator if (guid.IsPlayer()) { - //Caster may be NULL if DynObj is in removelist + //Caster may be nullptr if DynObj is in removelist if (Player* caster = ObjectAccessor::FindPlayer(guid)) if (caster->GetGuidValue(PLAYER_FARSIGHT) == source->GetGUID()) BuildPacket(caster); diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 3438e428a75..f5ff5100b78 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -20,59 +20,19 @@ #define _OBJECT_H #include "Common.h" -#include "Position.h" -#include "UpdateMask.h" #include "GridReference.h" -#include "ObjectDefines.h" -#include "Map.h" +#include "GridRefManager.h" #include "ModelIgnoreFlags.h" - +#include "MovementInfo.h" +#include "ObjectDefines.h" +#include "ObjectGuid.h" +#include "Position.h" +#include "SharedDefines.h" +#include "UpdateFields.h" +#include "UpdateMask.h" +#include <list> #include <set> -#include <string> -#include <sstream> - -#define CONTACT_DISTANCE 0.5f -#define INTERACTION_DISTANCE 5.0f -#define ATTACK_DISTANCE 5.0f -#define INSPECT_DISTANCE 28.0f -#define TRADE_DISTANCE 11.11f -#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects -#define SIGHT_RANGE_UNIT 50.0f -#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents -#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards -#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards - -#define DEFAULT_PLAYER_BOUNDING_RADIUS 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects -#define DEFAULT_PLAYER_COMBAT_REACH 1.5f -#define MIN_MELEE_REACH 2.0f -#define NOMINAL_MELEE_RANGE 5.0f -#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players - -enum TempSummonType -{ - TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears - TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies - TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time - TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat - TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death - TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death - TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears - TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called -}; - -enum PhaseMasks -{ - PHASEMASK_NORMAL = 0x00000001, - PHASEMASK_ANYWHERE = 0xFFFFFFFF -}; - -enum NotifyFlags -{ - NOTIFY_NONE = 0x00, - NOTIFY_AI_RELOCATION = 0x01, - NOTIFY_VISIBILITY_CHANGED = 0x02, - NOTIFY_ALL = 0xFF -}; +#include <unordered_map> class Corpse; class Creature; @@ -80,6 +40,7 @@ class CreatureAI; class DynamicObject; class GameObject; class InstanceScript; +class Map; class Player; class TempSummon; class Transport; @@ -88,6 +49,8 @@ class UpdateData; class WorldObject; class WorldPacket; class ZoneScript; +struct PositionFullTerrainStatus; +struct QuaternionData; typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType; @@ -183,23 +146,23 @@ class TC_GAME_API Object // FG: some hacky helpers void ForceValuesUpdateAtIndex(uint32); - Player* ToPlayer() { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return NULL; } - Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player const*>(this); else return NULL; } + Player* ToPlayer() { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player*>(this); else return nullptr; } + Player const* ToPlayer() const { if (GetTypeId() == TYPEID_PLAYER) return reinterpret_cast<Player const*>(this); else return nullptr; } - Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return NULL; } - Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature const*>(this); else return NULL; } + Creature* ToCreature() { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature*>(this); else return nullptr; } + Creature const* ToCreature() const { if (GetTypeId() == TYPEID_UNIT) return reinterpret_cast<Creature const*>(this); else return nullptr; } - Unit* ToUnit() { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit*>(this); else return NULL; } - Unit const* ToUnit() const { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit const*>(this); else return NULL; } + Unit* ToUnit() { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit*>(this); else return nullptr; } + Unit const* ToUnit() const { if (isType(TYPEMASK_UNIT)) return reinterpret_cast<Unit const*>(this); else return nullptr; } - GameObject* ToGameObject() { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(this); else return NULL; } - GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject const*>(this); else return NULL; } + GameObject* ToGameObject() { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject*>(this); else return nullptr; } + GameObject const* ToGameObject() const { if (GetTypeId() == TYPEID_GAMEOBJECT) return reinterpret_cast<GameObject const*>(this); else return nullptr; } - Corpse* ToCorpse() { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(this); else return NULL; } - Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse const*>(this); else return NULL; } + Corpse* ToCorpse() { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse*>(this); else return nullptr; } + Corpse const* ToCorpse() const { if (GetTypeId() == TYPEID_CORPSE) return reinterpret_cast<Corpse const*>(this); else return nullptr; } - DynamicObject* ToDynObject() { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject*>(this); else return NULL; } - DynamicObject const* ToDynObject() const { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject const*>(this); else return NULL; } + DynamicObject* ToDynObject() { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject*>(this); else return nullptr; } + DynamicObject const* ToDynObject() const { if (GetTypeId() == TYPEID_DYNAMICOBJECT) return reinterpret_cast<DynamicObject const*>(this); else return nullptr; } protected: Object(); @@ -249,114 +212,6 @@ class TC_GAME_API Object Object& operator=(Object const& right) = delete; }; -struct MovementInfo -{ - // common - ObjectGuid guid; - uint32 flags; - uint16 flags2; - Position pos; - uint32 time; - - // transport - struct TransportInfo - { - void Reset() - { - guid.Clear(); - pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - seat = -1; - time = 0; - time2 = 0; - } - - ObjectGuid guid; - Position pos; - int8 seat; - uint32 time; - uint32 time2; - } transport; - - // swimming/flying - float pitch; - - // falling - uint32 fallTime; - - // jumping - struct JumpInfo - { - void Reset() - { - zspeed = sinAngle = cosAngle = xyspeed = 0.0f; - } - - float zspeed, sinAngle, cosAngle, xyspeed; - - } jump; - - // spline - float splineElevation; - - MovementInfo() : - guid(), flags(0), flags2(0), time(0), pitch(0.0f), fallTime(0), splineElevation(0.0f) - { - pos.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - transport.Reset(); - jump.Reset(); - } - - uint32 GetMovementFlags() const { return flags; } - void SetMovementFlags(uint32 flag) { flags = flag; } - void AddMovementFlag(uint32 flag) { flags |= flag; } - void RemoveMovementFlag(uint32 flag) { flags &= ~flag; } - bool HasMovementFlag(uint32 flag) const { return (flags & flag) != 0; } - - uint16 GetExtraMovementFlags() const { return flags2; } - void AddExtraMovementFlag(uint16 flag) { flags2 |= flag; } - bool HasExtraMovementFlag(uint16 flag) const { return (flags2 & flag) != 0; } - - void SetFallTime(uint32 val) { fallTime = val; } - - void OutDebug(); -}; - -#define MAPID_INVALID 0xFFFFFFFF - -class WorldLocation : public Position -{ - public: - explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f) - : Position(_x, _y, _z, _o), m_mapId(_mapId) { } - - WorldLocation(uint32 mapId, Position const& position) - : Position(position), m_mapId(mapId) { } - - WorldLocation(WorldLocation const& loc) - : Position(loc), m_mapId(loc.GetMapId()) { } - - void WorldRelocate(WorldLocation const& loc) - { - m_mapId = loc.GetMapId(); - Relocate(loc); - } - - void WorldRelocate(uint32 _mapId = MAPID_INVALID, float _x = 0.f, float _y = 0.f, float _z = 0.f, float _o = 0.f) - { - m_mapId = _mapId; - Relocate(_x, _y, _z, _o); - } - - WorldLocation GetWorldLocation() const - { - return *this; - } - - uint32 GetMapId() const { return m_mapId; } - - uint32 m_mapId; -}; - template<class T> class GridObject { @@ -376,7 +231,8 @@ class FlaggedValuesArray32 public: FlaggedValuesArray32() { - memset(&m_values, 0x00, sizeof(T_VALUES) * ARRAY_SIZE); + for (uint32 i = 0; i < ARRAY_SIZE; ++i) + m_values[i] = T_VALUES(0); m_flags = 0; } @@ -394,38 +250,6 @@ class FlaggedValuesArray32 T_FLAGS m_flags; }; -enum MapObjectCellMoveState -{ - MAP_OBJECT_CELL_MOVE_NONE, //not in move list - MAP_OBJECT_CELL_MOVE_ACTIVE, //in move list - MAP_OBJECT_CELL_MOVE_INACTIVE, //in move list but should not move -}; - -class TC_GAME_API MapObject -{ - friend class Map; //map for moving creatures - friend class ObjectGridLoader; //grid loader for loading creatures - - protected: - MapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE) - { - _newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f); - } - - private: - Cell _currentCell; - Cell const& GetCurrentCell() const { return _currentCell; } - void SetCurrentCell(Cell const& cell) { _currentCell = cell; } - - MapObjectCellMoveState _moveState; - Position _newPosition; - void SetNewCellPosition(float x, float y, float z, float o) - { - _moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; - _newPosition.Relocate(x, y, z, o); - } -}; - class TC_GAME_API WorldObject : public Object, public WorldLocation { protected: @@ -453,8 +277,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation void UpdateGroundPositionZ(float x, float y, float &z) const; void UpdateAllowedPositionZ(float x, float y, float &z) const; - void GetRandomPoint(Position const &srcPos, float distance, float &rand_x, float &rand_y, float &rand_z) const; - Position GetRandomPoint(Position const &srcPos, float distance) const; + void GetRandomPoint(Position const& srcPos, float distance, float& rand_x, float& rand_y, float& rand_z) const; + Position GetRandomPoint(Position const& srcPos, float distance) const; uint32 GetInstanceId() const { return m_InstanceId; } @@ -470,12 +294,12 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation InstanceScript* GetInstanceScript(); std::string const& GetName() const { return m_name; } - void SetName(std::string const& newname) { m_name=newname; } + void SetName(std::string const& newname) { m_name = newname; } virtual std::string const& GetNameForLocaleIdx(LocaleConstant /*locale_idx*/) const { return m_name; } float GetDistance(WorldObject const* obj) const; - float GetDistance(Position const &pos) const; + float GetDistance(Position const& pos) const; float GetDistance(float x, float y, float z) const; float GetDistance2d(WorldObject const* obj) const; float GetDistance2d(float x, float y) const; @@ -512,9 +336,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation virtual uint8 getLevelForTarget(WorldObject const* /*target*/) const { return 1; } - void PlayDistanceSound(uint32 sound_id, Player* target = NULL); - void PlayDirectSound(uint32 sound_id, Player* target = NULL); - void PlayDirectMusic(uint32 music_id, Player* target = NULL); + void PlayDistanceSound(uint32 sound_id, Player* target = nullptr); + void PlayDirectSound(uint32 sound_id, Player* target = nullptr); + void PlayDirectMusic(uint32 music_id, Player* target = nullptr); void SendObjectDeSpawnAnim(ObjectGuid guid); @@ -523,7 +347,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation float GetGridActivationRange() const; float GetVisibilityRange() const; - float GetSightRange(WorldObject const* target = NULL) const; + float GetSightRange(WorldObject const* target = nullptr) const; bool CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth = false, bool distanceCheck = false, bool checkAlert = false) const; FlaggedValuesArray32<int32, uint32, StealthType, TOTAL_STEALTH_TYPES> m_stealth; @@ -550,10 +374,10 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation TempSummon* SummonCreature(uint32 id, Position const& pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0) const; TempSummon* SummonCreature(uint32 id, float x, float y, float z, float ang = 0, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0) const; - GameObject* SummonGameObject(uint32 entry, Position const& pos, G3D::Quat const& rot, uint32 respawnTime /* s */); - GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, G3D::Quat const& rot, uint32 respawnTime /* s */); - Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = NULL); - void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL); + GameObject* SummonGameObject(uint32 entry, Position const& pos, QuaternionData const& rot, uint32 respawnTime /* s */); + GameObject* SummonGameObject(uint32 entry, float x, float y, float z, float ang, QuaternionData const& rot, uint32 respawnTime /* s */); + Creature* SummonTrigger(float x, float y, float z, float ang, uint32 dur, CreatureAI* (*GetAI)(Creature*) = nullptr); + void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = nullptr); Creature* FindNearestCreature(uint32 entry, float range, bool alive = true) const; GameObject* FindNearestGameObject(uint32 entry, float range) const; @@ -604,6 +428,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation float GetTransOffsetY() const { return m_movementInfo.transport.pos.GetPositionY(); } float GetTransOffsetZ() const { return m_movementInfo.transport.pos.GetPositionZ(); } float GetTransOffsetO() const { return m_movementInfo.transport.pos.GetOrientation(); } + Position const& GetTransOffset() const { return m_movementInfo.transport.pos; } uint32 GetTransTime() const { return m_movementInfo.transport.time; } int8 GetTransSeat() const { return m_movementInfo.transport.seat; } virtual ObjectGuid GetTransGUID() const; diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index 8c2735502b4..fb3b8191af4 100644 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -20,48 +20,81 @@ #define TRINITY_OBJECTDEFINES_H #include "Define.h" -#include "ObjectGuid.h" -// used for creating values for respawn for example -inline uint64 MAKE_PAIR64(uint32 l, uint32 h); -inline uint32 PAIR64_HIPART(uint64 x); -inline uint32 PAIR64_LOPART(uint64 x); -inline uint16 MAKE_PAIR16(uint8 l, uint8 h); -inline uint32 MAKE_PAIR32(uint16 l, uint16 h); -inline uint16 PAIR32_HIPART(uint32 x); -inline uint16 PAIR32_LOPART(uint32 x); +#define CONTACT_DISTANCE 0.5f +#define INTERACTION_DISTANCE 5.0f +#define ATTACK_DISTANCE 5.0f +#define INSPECT_DISTANCE 28.0f +#define TRADE_DISTANCE 11.11f +#define MAX_VISIBILITY_DISTANCE SIZE_OF_GRIDS // max distance for visible objects +#define SIGHT_RANGE_UNIT 50.0f +#define DEFAULT_VISIBILITY_DISTANCE 90.0f // default visible distance, 90 yards on continents +#define DEFAULT_VISIBILITY_INSTANCE 170.0f // default visible distance in instances, 170 yards +#define DEFAULT_VISIBILITY_BGARENAS 533.0f // default visible distance in BG/Arenas, roughly 533 yards -uint64 MAKE_PAIR64(uint32 l, uint32 h) +#define DEFAULT_PLAYER_BOUNDING_RADIUS 0.388999998569489f // player size, also currently used (correctly?) for any non Unit world objects +#define DEFAULT_PLAYER_COMBAT_REACH 1.5f +#define MIN_MELEE_REACH 2.0f +#define NOMINAL_MELEE_RANGE 5.0f +#define MELEE_RANGE (NOMINAL_MELEE_RANGE - MIN_MELEE_REACH * 2) //center to center for players + +enum TempSummonType +{ + TEMPSUMMON_TIMED_OR_DEAD_DESPAWN = 1, // despawns after a specified time OR when the creature disappears + TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN = 2, // despawns after a specified time OR when the creature dies + TEMPSUMMON_TIMED_DESPAWN = 3, // despawns after a specified time + TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT = 4, // despawns after a specified time after the creature is out of combat + TEMPSUMMON_CORPSE_DESPAWN = 5, // despawns instantly after death + TEMPSUMMON_CORPSE_TIMED_DESPAWN = 6, // despawns after a specified time after death + TEMPSUMMON_DEAD_DESPAWN = 7, // despawns when the creature disappears + TEMPSUMMON_MANUAL_DESPAWN = 8 // despawns when UnSummon() is called +}; + +enum PhaseMasks +{ + PHASEMASK_NORMAL = 0x00000001, + PHASEMASK_ANYWHERE = 0xFFFFFFFF +}; + +enum NotifyFlags +{ + NOTIFY_NONE = 0x00, + NOTIFY_AI_RELOCATION = 0x01, + NOTIFY_VISIBILITY_CHANGED = 0x02, + NOTIFY_ALL = 0xFF +}; + +inline uint64 MAKE_PAIR64(uint32 l, uint32 h) { return uint64(l | (uint64(h) << 32)); } -uint32 PAIR64_HIPART(uint64 x) +inline uint32 PAIR64_HIPART(uint64 x) { return (uint32)((x >> 32) & UI64LIT(0x00000000FFFFFFFF)); } -uint32 PAIR64_LOPART(uint64 x) +inline uint32 PAIR64_LOPART(uint64 x) { return (uint32)(x & UI64LIT(0x00000000FFFFFFFF)); } -uint16 MAKE_PAIR16(uint8 l, uint8 h) +inline uint16 MAKE_PAIR16(uint8 l, uint8 h) { return uint16(l | (uint16(h) << 8)); } -uint32 MAKE_PAIR32(uint16 l, uint16 h) +inline uint32 MAKE_PAIR32(uint16 l, uint16 h) { return uint32(l | (uint32(h) << 16)); } -uint16 PAIR32_HIPART(uint32 x) +inline uint16 PAIR32_HIPART(uint32 x) { return (uint16)((x >> 16) & 0x0000FFFF); } -uint16 PAIR32_LOPART(uint32 x) +inline uint16 PAIR32_LOPART(uint32 x) { return (uint16)(x & 0x0000FFFF); } diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index ef93a499fc0..3a26dfd0d7f 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -17,8 +17,9 @@ */ #include "ObjectGuid.h" +#include "Hash.h" +#include "Log.h" #include "World.h" -#include "ObjectMgr.h" #include <sstream> #include <iomanip> @@ -87,7 +88,7 @@ ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid) ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid) { - buf.readPackGUID(*reinterpret_cast<uint64*>(guid.GuidPtr)); + buf.readPackGUID(reinterpret_cast<uint64&>(guid.Guid)); return buf; } diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index 1bf5c15c2b6..75410aa4f28 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -19,10 +19,16 @@ #ifndef ObjectGuid_h__ #define ObjectGuid_h__ -#include "Common.h" #include "ByteBuffer.h" -#include <type_traits> +#include "Define.h" +#include <deque> #include <functional> +#include <list> +#include <memory> +#include <set> +#include <type_traits> +#include <vector> +#include <unordered_set> enum TypeID { @@ -107,8 +113,8 @@ class PackedGuid; struct PackedGuidReader { - explicit PackedGuidReader(ObjectGuid& guid) : GuidPtr(&guid) { } - ObjectGuid* GuidPtr; + explicit PackedGuidReader(ObjectGuid& guid) : Guid(guid) { } + ObjectGuid& Guid; }; class TC_GAME_API ObjectGuid @@ -180,7 +186,7 @@ class TC_GAME_API ObjectGuid switch (high) { case HighGuid::Item: return TYPEID_ITEM; - //case HighGuid::Container: return TYPEID_CONTAINER; HighGuid::Container==HighGuid::Item currently + //case HighGuid::Container: return TYPEID_CONTAINER; HighGuid::Container == HighGuid::Item currently case HighGuid::Unit: return TYPEID_UNIT; case HighGuid::Pet: return TYPEID_UNIT; case HighGuid::Player: return TYPEID_PLAYER; @@ -199,8 +205,8 @@ class TC_GAME_API ObjectGuid TypeID GetTypeId() const { return GetTypeId(GetHigh()); } bool operator!() const { return IsEmpty(); } - bool operator== (ObjectGuid const& guid) const { return GetRawValue() == guid.GetRawValue(); } - bool operator!= (ObjectGuid const& guid) const { return GetRawValue() != guid.GetRawValue(); } + bool operator==(ObjectGuid const& guid) const { return GetRawValue() == guid.GetRawValue(); } + bool operator!=(ObjectGuid const& guid) const { return GetRawValue() != guid.GetRawValue(); } bool operator< (ObjectGuid const& guid) const { return GetRawValue() < guid.GetRawValue(); } static char const* GetTypeName(HighGuid high); @@ -254,7 +260,7 @@ typedef std::unordered_set<ObjectGuid> GuidUnorderedSet; class TC_GAME_API PackedGuid { - friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid); + friend TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, PackedGuid const& guid); public: explicit PackedGuid() : _packedGuid(PACKED_GUID_MIN_BUFFER_SIZE) { _packedGuid.appendPackGUID(0); } @@ -264,7 +270,7 @@ class TC_GAME_API PackedGuid void Set(uint64 guid) { _packedGuid.wpos(0); _packedGuid.appendPackGUID(guid); } void Set(ObjectGuid guid) { _packedGuid.wpos(0); _packedGuid.appendPackGUID(guid.GetRawValue()); } - size_t size() const { return _packedGuid.size(); } + std::size_t size() const { return _packedGuid.size(); } private: ByteBuffer _packedGuid; @@ -314,7 +320,7 @@ namespace std public: size_t operator()(ObjectGuid const& key) const { - return hash<uint64>()(key.GetRawValue()); + return std::hash<uint64>()(key.GetRawValue()); } }; } diff --git a/src/server/game/Entities/Object/ObjectPosSelector.cpp b/src/server/game/Entities/Object/ObjectPosSelector.cpp index bfb3022a2b7..e9acd8099ec 100644 --- a/src/server/game/Entities/Object/ObjectPosSelector.cpp +++ b/src/server/game/Entities/Object/ObjectPosSelector.cpp @@ -32,8 +32,8 @@ ObjectPosSelector::ObjectPosSelector(float x, float y, float size, float dist) m_smallStepOk[USED_POS_PLUS] = false; m_smallStepOk[USED_POS_MINUS] = false; - m_smallStepNextUsedPos[USED_POS_PLUS] = NULL; - m_smallStepNextUsedPos[USED_POS_MINUS] = NULL; + m_smallStepNextUsedPos[USED_POS_PLUS] = nullptr; + m_smallStepNextUsedPos[USED_POS_MINUS] = nullptr; } ObjectPosSelector::UsedPosList::value_type const* ObjectPosSelector::nextUsedPos(UsedPosType uptype) @@ -42,12 +42,12 @@ ObjectPosSelector::UsedPosList::value_type const* ObjectPosSelector::nextUsedPos if (itr!=m_UsedPosLists[uptype].end()) ++itr; - if (itr==m_UsedPosLists[uptype].end()) + if (itr == m_UsedPosLists[uptype].end()) { if (!m_UsedPosLists[~uptype].empty()) return &*m_UsedPosLists[~uptype].rbegin(); else - return NULL; + return nullptr; } else return &*itr; diff --git a/src/server/game/Entities/Object/ObjectPosSelector.h b/src/server/game/Entities/Object/ObjectPosSelector.h index d5414e0e245..8185a2a0c21 100644 --- a/src/server/game/Entities/Object/ObjectPosSelector.h +++ b/src/server/game/Entities/Object/ObjectPosSelector.h @@ -19,15 +19,15 @@ #ifndef _OBJECT_POS_SELECTOR_H #define _OBJECT_POS_SELECTOR_H -#include<Common.h> - -#include<map> +#include "Common.h" +#include <map> +#include <cmath> enum UsedPosType { USED_POS_PLUS, USED_POS_MINUS }; -inline UsedPosType operator ~(UsedPosType uptype) +inline UsedPosType operator~(UsedPosType uptype) { - return uptype==USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS; + return uptype == USED_POS_PLUS ? USED_POS_MINUS : USED_POS_PLUS; } struct TC_GAME_API ObjectPosSelector diff --git a/src/server/game/Entities/Object/Position.cpp b/src/server/game/Entities/Object/Position.cpp index a8cb363e272..99bc433ff91 100644 --- a/src/server/game/Entities/Object/Position.cpp +++ b/src/server/game/Entities/Object/Position.cpp @@ -18,21 +18,12 @@ #include "Position.h" #include "ByteBuffer.h" #include "GridDefines.h" +#include "Random.h" #include <G3D/g3dmath.h> -#include <G3D/Vector3.h> +#include <sstream> -Position::Position(G3D::Vector3 const& vect) -{ - Relocate(vect.x, vect.y, vect.z, 0.f); -} - -Position::operator G3D::Vector3() const -{ - return { m_positionX, m_positionY, m_positionZ }; -} - -bool Position::operator==(Position const &a) +bool Position::operator==(Position const& a) { return (G3D::fuzzyEq(a.m_positionX, m_positionX) && G3D::fuzzyEq(a.m_positionY, m_positionY) && @@ -40,7 +31,7 @@ bool Position::operator==(Position const &a) G3D::fuzzyEq(a.m_orientation, m_orientation)); } -void Position::RelocateOffset(const Position & offset) +void Position::RelocateOffset(Position const& offset) { m_positionX = GetPositionX() + (offset.GetPositionX() * std::cos(GetOrientation()) + offset.GetPositionY() * std::sin(GetOrientation() + float(M_PI))); m_positionY = GetPositionY() + (offset.GetPositionY() * std::cos(GetOrientation()) + offset.GetPositionX() * std::sin(GetOrientation())); @@ -53,7 +44,27 @@ bool Position::IsPositionValid() const return Trinity::IsValidMapCoord(m_positionX, m_positionY, m_positionZ, m_orientation); } -void Position::GetPositionOffsetTo(const Position & endPos, Position & retOffset) const +float Position::GetExactDist2d(const float x, const float y) const +{ + return std::sqrt(GetExactDist2dSq(x, y)); +} + +float Position::GetExactDist2d(Position const* pos) const +{ + return std::sqrt(GetExactDist2dSq(pos)); +} + +float Position::GetExactDist(float x, float y, float z) const +{ + return std::sqrt(GetExactDistSq(x, y, z)); +} + +float Position::GetExactDist(Position const* pos) const +{ + return std::sqrt(GetExactDistSq(pos)); +} + +void Position::GetPositionOffsetTo(Position const& endPos, Position& retOffset) const { float dx = endPos.GetPositionX() - GetPositionX(); float dy = endPos.GetPositionY() - GetPositionY(); @@ -109,7 +120,7 @@ void Position::GetSinCos(const float x, const float y, float &vsin, float &vcos) } } -bool Position::IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const +bool Position::IsWithinBox(Position const& center, float xradius, float yradius, float zradius) const { // rotate the WorldObject position instead of rotating the whole cube, that way we can make a simplified // is-in-cube check and we have to calculate only one point instead of 4 @@ -143,7 +154,7 @@ bool Position::IsWithinDoubleVerticalCylinder(Position const* center, float radi return IsInDist2d(center, radius) && std::abs(verticalDelta) <= height; } -bool Position::HasInArc(float arc, const Position* obj, float border) const +bool Position::HasInArc(float arc, Position const* obj, float border) const { // always have self in arc if (obj == this) @@ -182,14 +193,28 @@ std::string Position::ToString() const return sstr.str(); } -ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer) +float Position::NormalizeOrientation(float o) +{ + // fmod only supports positive numbers. Thus we have + // to emulate negative numbers + if (o < 0) + { + float mod = o *-1; + mod = std::fmod(mod, 2.0f * static_cast<float>(M_PI)); + mod = -mod + 2.0f * static_cast<float>(M_PI); + return mod; + } + return std::fmod(o, 2.0f * static_cast<float>(M_PI)); +} + +ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XY> const& streamer) { buf << streamer.Pos->GetPositionX(); buf << streamer.Pos->GetPositionY(); return buf; } -ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& streamer) +ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer<Position::XY> const& streamer) { float x, y; buf >> x >> y; @@ -197,7 +222,7 @@ ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& stre return buf; } -ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer) +ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XYZ> const& streamer) { buf << streamer.Pos->GetPositionX(); buf << streamer.Pos->GetPositionY(); @@ -205,7 +230,7 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& str return buf; } -ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer) +ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer<Position::XYZ> const& streamer) { float x, y, z; buf >> x >> y >> z; @@ -213,7 +238,7 @@ ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& str return buf; } -ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer) +ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XYZO> const& streamer) { buf << streamer.Pos->GetPositionX(); buf << streamer.Pos->GetPositionY(); @@ -222,10 +247,16 @@ ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& st return buf; } -ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer) +ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer<Position::XYZO> const& streamer) { float x, y, z, o; buf >> x >> y >> z >> o; streamer.Pos->Relocate(x, y, z, o); return buf; } + +ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::PackedXYZ> const& streamer) +{ + buf.appendPackXYZ(streamer.Pos->GetPositionX(), streamer.Pos->GetPositionY(), streamer.Pos->GetPositionZ()); + return buf; +} diff --git a/src/server/game/Entities/Object/Position.h b/src/server/game/Entities/Object/Position.h index 4dba3d1f330..98cb82df2e1 100644 --- a/src/server/game/Entities/Object/Position.h +++ b/src/server/game/Entities/Object/Position.h @@ -18,12 +18,9 @@ #ifndef Trinity_game_Position_h__ #define Trinity_game_Position_h__ -#include "Common.h" - -namespace G3D -{ - class Vector3; -} +#include "Define.h" +#include <string> +#include <cmath> class ByteBuffer; @@ -34,25 +31,24 @@ struct TC_GAME_API Position Position(Position const& loc) { Relocate(loc); } - Position(G3D::Vector3 const& vect); - - operator G3D::Vector3() const; + // streamer tags + struct XY; + struct XYZ; + struct XYZO; + struct PackedXYZ; - struct PositionXYStreamer + template <class Tag> + struct ConstStreamer { - explicit PositionXYStreamer(Position& pos) : Pos(&pos) { } - Position* Pos; + explicit ConstStreamer(Position const& pos) : Pos(&pos) { } + Position const* Pos; }; - struct PositionXYZStreamer + template <class Tag> + struct Streamer { - explicit PositionXYZStreamer(Position& pos) : Pos(&pos) { } - Position* Pos; - }; - - struct PositionXYZOStreamer - { - explicit PositionXYZOStreamer(Position& pos) : Pos(&pos) { } + explicit Streamer(Position& pos) : Pos(&pos) { } + operator ConstStreamer<Tag>() const { return ConstStreamer<Tag>(*Pos); } Position* Pos; }; @@ -64,9 +60,9 @@ private: float m_orientation; public: - bool operator==(Position const &a); + bool operator==(Position const& a); - inline bool operator!=(Position const &a) + inline bool operator!=(Position const& a) { return !(operator==(a)); } @@ -86,7 +82,7 @@ public: m_positionX = x; m_positionY = y; m_positionZ = z; SetOrientation(orientation); } - void Relocate(Position const &pos) + void Relocate(Position const& pos) { m_positionX = pos.m_positionX; m_positionY = pos.m_positionY; m_positionZ = pos.m_positionZ; SetOrientation(pos.m_orientation); } @@ -96,7 +92,7 @@ public: m_positionX = pos->m_positionX; m_positionY = pos->m_positionY; m_positionZ = pos->m_positionZ; SetOrientation(pos->m_orientation); } - void RelocateOffset(Position const &offset); + void RelocateOffset(Position const& offset); void SetOrientation(float orientation) { @@ -125,9 +121,14 @@ public: Position GetPosition() const { return *this; } - Position::PositionXYStreamer PositionXYStream() { return PositionXYStreamer(*this); } - Position::PositionXYZStreamer PositionXYZStream() { return PositionXYZStreamer(*this); } - Position::PositionXYZOStreamer PositionXYZOStream() { return PositionXYZOStreamer(*this); } + Streamer<XY> PositionXYStream() { return Streamer<XY>(*this); } + ConstStreamer<XY> PositionXYStream() const { return ConstStreamer<XY>(*this); } + Streamer<XYZ> PositionXYZStream() { return Streamer<XYZ>(*this); } + ConstStreamer<XYZ> PositionXYZStream() const { return ConstStreamer<XYZ>(*this); } + Streamer<XYZO> PositionXYZOStream() { return Streamer<XYZO>(*this); } + ConstStreamer<XYZO> PositionXYZOStream() const { return ConstStreamer<XYZO>(*this); } + Streamer<PackedXYZ> PositionPackedXYZStream() { return Streamer<PackedXYZ>(*this); } + ConstStreamer<PackedXYZ> PositionPackedXYZStream() const { return ConstStreamer<PackedXYZ>(*this); } bool IsPositionValid() const; @@ -136,10 +137,7 @@ public: float dx = m_positionX - x; float dy = m_positionY - y; return dx*dx + dy*dy; } - float GetExactDist2d(const float x, const float y) const - { - return std::sqrt(GetExactDist2dSq(x, y)); - } + float GetExactDist2d(const float x, const float y) const; float GetExactDist2dSq(Position const& pos) const { @@ -156,20 +154,14 @@ public: float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; return dx*dx + dy*dy; } - float GetExactDist2d(Position const* pos) const - { - return std::sqrt(GetExactDist2dSq(pos)); - } + float GetExactDist2d(Position const* pos) const; float GetExactDistSq(float x, float y, float z) const { float dz = m_positionZ - z; return GetExactDist2dSq(x, y) + dz*dz; } - float GetExactDist(float x, float y, float z) const - { - return std::sqrt(GetExactDistSq(x, y, z)); - } + float GetExactDist(float x, float y, float z) const; float GetExactDistSq(Position const& pos) const { @@ -186,10 +178,7 @@ public: float dx = m_positionX - pos->m_positionX; float dy = m_positionY - pos->m_positionY; float dz = m_positionZ - pos->m_positionZ; return dx*dx + dy*dy + dz*dz; } - float GetExactDist(Position const* pos) const - { - return std::sqrt(GetExactDistSq(pos)); - } + float GetExactDist(Position const* pos) const; void GetPositionOffsetTo(Position const & endPos, Position & retOffset) const; Position GetPositionWithOffset(Position const& offset) const; @@ -228,7 +217,7 @@ public: return GetExactDistSq(pos) < dist * dist; } - bool IsWithinBox(const Position& center, float xradius, float yradius, float zradius) const; + bool IsWithinBox(Position const& center, float xradius, float yradius, float zradius) const; /* search using this relation: dist2d < radius && abs(dz) < height @@ -239,26 +228,71 @@ public: std::string ToString() const; // modulos a radian orientation to the range of 0..2PI - static float NormalizeOrientation(float o) - { - // fmod only supports positive numbers. Thus we have - // to emulate negative numbers - if (o < 0) + static float NormalizeOrientation(float o); +}; + +#define MAPID_INVALID 0xFFFFFFFF + +class WorldLocation : public Position +{ + public: + explicit WorldLocation(uint32 _mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f) + : Position(x, y, z, o), m_mapId(_mapId) { } + + WorldLocation(uint32 mapId, Position const& position) + : Position(position), m_mapId(mapId) { } + + WorldLocation(WorldLocation const& loc) + : Position(loc), m_mapId(loc.GetMapId()) { } + + void WorldRelocate(WorldLocation const& loc) { - float mod = o *-1; - mod = std::fmod(mod, 2.0f * static_cast<float>(M_PI)); - mod = -mod + 2.0f * static_cast<float>(M_PI); - return mod; + m_mapId = loc.GetMapId(); + Relocate(loc); } - return std::fmod(o, 2.0f * static_cast<float>(M_PI)); - } + + void WorldRelocate(uint32 _mapId = MAPID_INVALID, float x = 0.f, float y = 0.f, float z = 0.f, float o = 0.f) + { + m_mapId = _mapId; + Relocate(x, y, z, o); + } + + WorldLocation GetWorldLocation() const + { + return *this; + } + + uint32 GetMapId() const { return m_mapId; } + + uint32 m_mapId; }; -TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYStreamer const& streamer); -TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYStreamer const& streamer); -TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer); -TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZStreamer const& streamer); -TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); -TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::PositionXYZOStreamer const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XY> const& streamer); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer<Position::XY> const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XYZ> const& streamer); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer<Position::XYZ> const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::XYZO> const& streamer); +TC_GAME_API ByteBuffer& operator>>(ByteBuffer& buf, Position::Streamer<Position::XYZO> const& streamer); +TC_GAME_API ByteBuffer& operator<<(ByteBuffer& buf, Position::ConstStreamer<Position::PackedXYZ> const& streamer); + +template <class Tag> +struct TaggedPosition +{ + TaggedPosition(float x = 0.0f, float y = 0.0f, float z = 0.0f, float o = 0.0f) : Pos(x, y, z, o) { } + TaggedPosition(Position const& pos) : Pos(pos) { } + + TaggedPosition& operator=(Position const& pos) + { + Pos.Relocate(pos); + return *this; + } + + operator Position() const { return Pos; } + + friend ByteBuffer& operator<<(ByteBuffer& buf, TaggedPosition const& tagged) { return buf << Position::ConstStreamer<Tag>(tagged.Pos); } + friend ByteBuffer& operator>>(ByteBuffer& buf, TaggedPosition& tagged) { return buf >> Position::Streamer<Tag>(tagged.Pos); } + + Position Pos; +}; #endif // Trinity_game_Position_h__ diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp index 0674fc4579c..cb8ecf45e2f 100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp @@ -16,13 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "ByteBuffer.h" -#include "WorldPacket.h" #include "UpdateData.h" +#include "Errors.h" +#include "Log.h" #include "Opcodes.h" #include "World.h" -#include "zlib.h" +#include "WorldPacket.h" +#include <zlib.h> UpdateData::UpdateData() : m_blockCount(0) { } @@ -36,7 +36,7 @@ void UpdateData::AddOutOfRangeGUID(ObjectGuid guid) m_outOfRangeGUIDs.insert(guid); } -void UpdateData::AddUpdateBlock(const ByteBuffer &block) +void UpdateData::AddUpdateBlock(ByteBuffer const& block) { m_data.append(block); ++m_blockCount; diff --git a/src/server/game/Entities/Object/Updates/UpdateData.h b/src/server/game/Entities/Object/Updates/UpdateData.h index 308d8662d40..e3437595c0b 100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.h +++ b/src/server/game/Entities/Object/Updates/UpdateData.h @@ -19,6 +19,7 @@ #ifndef __UPDATEDATA_H #define __UPDATEDATA_H +#include "Define.h" #include "ByteBuffer.h" #include "ObjectGuid.h" #include <set> @@ -62,7 +63,7 @@ class UpdateData void AddOutOfRangeGUID(GuidSet& guids); void AddOutOfRangeGUID(ObjectGuid guid); - void AddUpdateBlock(const ByteBuffer &block); + void AddUpdateBlock(ByteBuffer const& block); bool BuildPacket(WorldPacket* packet); bool HasData() const { return m_blockCount > 0 || !m_outOfRangeGUIDs.empty(); } void Clear(); diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h index 5550a50b314..21fe8d700f7 100644 --- a/src/server/game/Entities/Object/Updates/UpdateMask.h +++ b/src/server/game/Entities/Object/Updates/UpdateMask.h @@ -20,7 +20,6 @@ #define __UPDATEMASK_H #include "UpdateFields.h" -#include "Errors.h" #include "ByteBuffer.h" class UpdateMask @@ -34,9 +33,9 @@ class UpdateMask CLIENT_UPDATE_MASK_BITS = sizeof(ClientUpdateMaskType) * 8, }; - UpdateMask() : _fieldCount(0), _blockCount(0), _bits(NULL) { } + UpdateMask() : _fieldCount(0), _blockCount(0), _bits(nullptr) { } - UpdateMask(UpdateMask const& right) : _bits(NULL) + UpdateMask(UpdateMask const& right) : _bits(nullptr) { SetCount(right.GetCount()); memcpy(_bits, right._bits, sizeof(uint8) * _blockCount * 32); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index a1a0a44f822..20f9e57b666 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -16,28 +16,30 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Pet.h" #include "Common.h" #include "DatabaseEnv.h" +#include "Formulas.h" +#include "Group.h" #include "Log.h" -#include "WorldPacket.h" #include "ObjectMgr.h" -#include "SpellMgr.h" -#include "Pet.h" -#include "Formulas.h" -#include "SpellHistory.h" -#include "SpellAuras.h" +#include "Player.h" +#include "Spell.h" #include "SpellAuraEffects.h" +#include "SpellAuras.h" +#include "SpellHistory.h" +#include "SpellMgr.h" #include "Unit.h" #include "Util.h" -#include "Group.h" +#include "WorldPacket.h" #include "WorldSession.h" #define PET_XP_FACTOR 0.05f Pet::Pet(Player* owner, PetType type) : - Guardian(NULL, owner, true), m_usedTalentCount(0), m_removed(false), + Guardian(nullptr, owner, true), m_usedTalentCount(0), m_removed(false), m_happinessTimer(7500), m_petType(type), m_duration(0), m_auraRaidUpdateMask(0), m_loading(false), - m_declinedname(NULL) + m_declinedname(nullptr) { ASSERT(GetOwner()); @@ -196,7 +198,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c return false; } - map->AddToMap(this->ToCreature()); + map->AddToMap(ToCreature()); return true; } @@ -235,7 +237,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c break; } - SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped here + SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped here SetCreatorGUID(owner->GetGUID()); InitStatsForLevel(petlevel); @@ -312,11 +314,11 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c } owner->SetMinion(this, true); - map->AddToMap(this->ToCreature()); + map->AddToMap(ToCreature()); InitTalentForLevel(); // set original talents points before spell loading - uint32 timediff = uint32(time(NULL) - fields[14].GetUInt32()); + uint32 timediff = uint32(time(nullptr) - fields[14].GetUInt32()); _LoadAuras(timediff); // load action bar, if data broken will fill later by default spells. @@ -544,7 +546,7 @@ void Pet::Update(uint32 diff) { case CORPSE: { - if (getPetType() != HUNTER_PET || m_corpseRemoveTime <= time(NULL)) + if (getPetType() != HUNTER_PET || m_corpseRemoveTime <= time(nullptr)) { Remove(PET_SAVE_NOT_IN_SLOT); //hunters' pets never get removed because of death, NEVER! return; @@ -764,7 +766,7 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner) bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask) { TC_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed"); - ObjectGuid::LowType guid=map->GenerateLowGuid<HighGuid::Pet>(); + ObjectGuid::LowType guid = map->GenerateLowGuid<HighGuid::Pet>(); uint32 petId = sObjectMgr->GeneratePetNumber(); if (!Create(guid, map, phaseMask, cinfo->Entry, petId)) return false; @@ -1201,7 +1203,7 @@ void Pet::_LoadAuras(uint32 timediff) else remaincharges = 0; - if (Aura* aura = Aura::TryCreate(spellInfo, effmask, this, NULL, &baseDamage[0], NULL, caster_guid)) + if (Aura* aura = Aura::TryCreate(spellInfo, effmask, this, nullptr, &baseDamage[0], nullptr, caster_guid)) { if (!aura->CanBeSaved()) { @@ -1405,7 +1407,7 @@ bool Pet::addSpell(uint32 spellId, ActiveStates active /*= ACT_DECIDE*/, PetSpel int32 free_points = GetMaxTalentPointsForLevel(getLevel()); m_usedTalentCount += talentCost; // update free talent points - free_points-=m_usedTalentCount; + free_points -= m_usedTalentCount; SetFreeTalentPoints(free_points > 0 ? free_points : 0); } return true; @@ -1421,7 +1423,7 @@ bool Pet::learnSpell(uint32 spell_id) { WorldPacket data(SMSG_PET_LEARNED_SPELL, 4); data << uint32(spell_id); - GetOwner()->GetSession()->SendPacket(&data); + GetOwner()->SendDirectMessage(&data); GetOwner()->PetSpellInitialize(); } return true; @@ -1431,7 +1433,7 @@ void Pet::InitLevelupSpellsForLevel() { uint8 level = getLevel(); - if (PetLevelupSpellSet const* levelupSpells = GetCreatureTemplate()->family ? sSpellMgr->GetPetLevelupSpellList(GetCreatureTemplate()->family) : NULL) + if (PetLevelupSpellSet const* levelupSpells = GetCreatureTemplate()->family ? sSpellMgr->GetPetLevelupSpellList(GetCreatureTemplate()->family) : nullptr) { // PetLevelupSpellSet ordered by levels, process in reversed order for (PetLevelupSpellSet::const_reverse_iterator itr = levelupSpells->rbegin(); itr != levelupSpells->rend(); ++itr) @@ -1474,7 +1476,7 @@ bool Pet::unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab) { WorldPacket data(SMSG_PET_REMOVED_SPELL, 4); data << uint32(spell_id); - GetOwner()->GetSession()->SendPacket(&data); + GetOwner()->SendDirectMessage(&data); } return true; } @@ -1627,7 +1629,7 @@ bool Pet::resetTalents() return true; } -void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/) +void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= nullptr*/) { // not need after this call if (owner->HasAtLoginFlag(AT_LOGIN_RESET_PET_TALENTS)) @@ -1873,7 +1875,7 @@ void Pet::CastPetAura(PetAura const* aura) if (auraId == 35696) // Demonic Knowledge { int32 basePoints = CalculatePct(aura->GetDamage(), GetStat(STAT_STAMINA) + GetStat(STAT_INTELLECT)); - CastCustomSpell(this, auraId, &basePoints, NULL, NULL, true); + CastCustomSpell(this, auraId, &basePoints, nullptr, nullptr, true); } else CastSpell(this, auraId, true); diff --git a/src/server/game/Entities/Player/CinematicMgr.cpp b/src/server/game/Entities/Player/CinematicMgr.cpp index 4ea1413055d..56a017d1e79 100644 --- a/src/server/game/Entities/Player/CinematicMgr.cpp +++ b/src/server/game/Entities/Player/CinematicMgr.cpp @@ -17,7 +17,9 @@ */ #include "CinematicMgr.h" -#include "Creature.h" +#include "Map.h" +#include "M2Stores.h" +#include "MotionMaster.h" #include "Player.h" #include "TemporarySummon.h" @@ -45,21 +47,20 @@ void CinematicMgr::BeginCinematic() if (m_activeCinematicCameraId == 0) return; - auto itr = sFlyByCameraStore.find(m_activeCinematicCameraId); - if (itr != sFlyByCameraStore.end()) + if (std::vector<FlyByCamera> const* flyByCameras = GetFlyByCameras(m_activeCinematicCameraId)) { // Initialize diff, and set camera m_cinematicDiff = 0; - m_cinematicCamera = &itr->second; + m_cinematicCamera = flyByCameras; auto camitr = m_cinematicCamera->begin(); if (camitr != m_cinematicCamera->end()) { - Position pos(camitr->locations.x, camitr->locations.y, camitr->locations.z, camitr->locations.w); + Position const& pos = camitr->locations; if (!pos.IsPositionValid()) return; - player->GetMap()->LoadGrid(camitr->locations.x, camitr->locations.y); + player->GetMap()->LoadGrid(pos.GetPositionX(), pos.GetPositionY()); m_CinematicObject = player->SummonCreature(VISUAL_WAYPOINT, pos.m_positionX, pos.m_positionY, pos.m_positionZ, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 5 * MINUTE * IN_MILLISECONDS); if (m_CinematicObject) { @@ -68,11 +69,7 @@ void CinematicMgr::BeginCinematic() } // Get cinematic length - FlyByCameraCollection::const_reverse_iterator camrevitr = m_cinematicCamera->rbegin(); - if (camrevitr != m_cinematicCamera->rend()) - m_cinematicLength = camrevitr->timeStamp; - else - m_cinematicLength = 0; + m_cinematicLength = flyByCameras->back().timeStamp; } } } @@ -110,11 +107,11 @@ void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) { if (cam.timeStamp > m_cinematicDiff) { - nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + nextPosition.Relocate(cam.locations); nextTimestamp = cam.timeStamp; break; } - lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + lastPosition.Relocate(cam.locations); lastTimestamp = cam.timeStamp; } float angle = lastPosition.GetAngle(&nextPosition); @@ -129,7 +126,7 @@ void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) workDiff += static_cast<int32>(float(CINEMATIC_LOOKAHEAD) * cos(angle)); // Get an iterator to the last entry in the cameras, to make sure we don't go beyond the end - FlyByCameraCollection::const_reverse_iterator endItr = m_cinematicCamera->rbegin(); + auto endItr = m_cinematicCamera->rbegin(); if (endItr != m_cinematicCamera->rend() && workDiff > static_cast<int32>(endItr->timeStamp)) workDiff = endItr->timeStamp; @@ -142,11 +139,11 @@ void CinematicMgr::UpdateCinematicLocation(uint32 /*diff*/) { if (static_cast<int32>(cam.timeStamp) >= workDiff) { - nextPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + nextPosition.Relocate(cam.locations); nextTimestamp = cam.timeStamp; break; } - lastPosition = Position(cam.locations.x, cam.locations.y, cam.locations.z, cam.locations.w); + lastPosition.Relocate(cam.locations); lastTimestamp = cam.timeStamp; } diff --git a/src/server/game/Entities/Player/CinematicMgr.h b/src/server/game/Entities/Player/CinematicMgr.h index 96d6e04b949..f2c0970fb81 100644 --- a/src/server/game/Entities/Player/CinematicMgr.h +++ b/src/server/game/Entities/Player/CinematicMgr.h @@ -21,12 +21,12 @@ #include "Define.h" #include "Object.h" -#include "M2Stores.h" #define CINEMATIC_LOOKAHEAD (2 * IN_MILLISECONDS) #define CINEMATIC_UPDATEDIFF 500 class Player; +struct FlyByCamera; class TC_GAME_API CinematicMgr { @@ -52,7 +52,7 @@ protected: uint32 m_lastCinematicCheck; uint32 m_activeCinematicCameraId; uint32 m_cinematicLength; - FlyByCameraCollection* m_cinematicCamera; + std::vector<FlyByCamera> const* m_cinematicCamera; Position m_remoteSightPosition; TempSummon* m_CinematicObject; }; diff --git a/src/server/game/Entities/Player/EquipmentSet.h b/src/server/game/Entities/Player/EquipmentSet.h new file mode 100644 index 00000000000..779025fbec3 --- /dev/null +++ b/src/server/game/Entities/Player/EquipmentSet.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EquipmentSet_h__ +#define EquipmentSet_h__ + +#include "Define.h" +#include "ObjectGuid.h" +#include <array> +#include <map> + +enum EquipmentSetUpdateState +{ + EQUIPMENT_SET_UNCHANGED = 0, + EQUIPMENT_SET_CHANGED = 1, + EQUIPMENT_SET_NEW = 2, + EQUIPMENT_SET_DELETED = 3 +}; + +#define EQUIPMENT_SET_SLOTS 19 + +struct EquipmentSetInfo +{ + /// Data sent in EquipmentSet related packets + struct EquipmentSetData + { + uint64 Guid = 0; ///< Set Identifier + uint32 SetID = 0; ///< Index + std::string SetName; + std::string SetIcon; + uint32 IgnoreMask = 0; ///< Mask of EquipmentSlot + std::array<ObjectGuid, EQUIPMENT_SET_SLOTS> Pieces; + } Data; + + /// Server-side data + EquipmentSetUpdateState State = EQUIPMENT_SET_NEW; +}; + +#define MAX_EQUIPMENT_SET_INDEX 10 // client limit + +typedef std::map<uint64, EquipmentSetInfo> EquipmentSetContainer; + + +#endif // EquipmentSet_h__ diff --git a/src/server/game/Entities/Player/KillRewarder.cpp b/src/server/game/Entities/Player/KillRewarder.cpp index 61a6277e6cd..b7d714ed5ad 100644 --- a/src/server/game/Entities/Player/KillRewarder.cpp +++ b/src/server/game/Entities/Player/KillRewarder.cpp @@ -270,5 +270,5 @@ void KillRewarder::Reward() if (Creature* victim = _victim->ToCreature()) if (victim->IsDungeonBoss()) if (InstanceScript* instance = _victim->GetInstanceScript()) - instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim); + instance->UpdateEncounterStateForKilledCreature(_victim->GetEntry(), _victim); } diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2394e822efc..f7766a7fcc0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -21,6 +21,7 @@ #include "AchievementMgr.h" #include "ArenaTeam.h" #include "ArenaTeamMgr.h" +#include "Bag.h" #include "Battlefield.h" #include "BattlefieldMgr.h" #include "BattlefieldWG.h" @@ -33,6 +34,7 @@ #include "CharacterCache.h" #include "CharacterDatabaseCleaner.h" #include "Chat.h" +#include "CinematicMgr.h" #include "Common.h" #include "ConditionMgr.h" #include "CreatureAI.h" @@ -40,7 +42,9 @@ #include "DisableMgr.h" #include "Formulas.h" #include "GameEventMgr.h" +#include "GameObjectAI.h" #include "GameTime.h" +#include "GitRevision.h" #include "GossipDef.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" @@ -50,33 +54,38 @@ #include "GuildMgr.h" #include "InstanceSaveMgr.h" #include "InstanceScript.h" +#include "Item.h" #include "KillRewarder.h" -#include "LFGMgr.h" #include "Language.h" +#include "LFGMgr.h" #include "Log.h" #include "LootItemStorage.h" +#include "LootMgr.h" +#include "Mail.h" #include "MapManager.h" +#include "MotionMaster.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "OutdoorPvP.h" #include "OutdoorPvPMgr.h" #include "Pet.h" -#include "PoolMgr.h" #include "PetitionMgr.h" -#include "QueryCallback.h" +#include "PoolMgr.h" +#include "QueryHolder.h" #include "QuestDef.h" +#include "Realm.h" #include "ReputationMgr.h" -#include "GitRevision.h" #include "SkillDiscovery.h" #include "SocialMgr.h" #include "Spell.h" #include "SpellAuraEffects.h" #include "SpellAuras.h" -#include "SpellMgr.h" #include "SpellHistory.h" -#include "Transport.h" +#include "SpellMgr.h" #include "TicketMgr.h" +#include "TradeData.h" +#include "Transport.h" #include "UpdateData.h" #include "UpdateFieldFlags.h" #include "UpdateMask.h" @@ -86,7 +95,6 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "GameObjectAI.h" #define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) @@ -155,147 +163,6 @@ static uint32 copseReclaimDelay[MAX_DEATH_COUNT] = { 30, 60, 120 }; uint32 const MAX_MONEY_AMOUNT = static_cast<uint32>(std::numeric_limits<int32>::max()); -// == PlayerTaxi ================================================ - -PlayerTaxi::PlayerTaxi() -{ - memset(m_taximask, 0, sizeof(m_taximask)); -} - -void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level) -{ - // class specific initial known nodes - switch (chrClass) - { - case CLASS_DEATH_KNIGHT: - { - for (uint8 i = 0; i < TaxiMaskSize; ++i) - m_taximask[i] |= sOldContinentsNodesMask[i]; - break; - } - } - - // race specific initial known nodes: capital and taxi hub masks - switch (race) - { - case RACE_HUMAN: SetTaximaskNode(2); break; // Human - case RACE_ORC: SetTaximaskNode(23); break; // Orc - case RACE_DWARF: SetTaximaskNode(6); break; // Dwarf - case RACE_NIGHTELF: SetTaximaskNode(26); - SetTaximaskNode(27); break; // Night Elf - case RACE_UNDEAD_PLAYER: SetTaximaskNode(11); break;// Undead - case RACE_TAUREN: SetTaximaskNode(22); break; // Tauren - case RACE_GNOME: SetTaximaskNode(6); break; // Gnome - case RACE_TROLL: SetTaximaskNode(23); break; // Troll - case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf - case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei - } - - // new continent starting masks (It will be accessible only at new map) - switch (Player::TeamForRace(race)) - { - case ALLIANCE: SetTaximaskNode(100); break; - case HORDE: SetTaximaskNode(99); break; - } - // level dependent taxi hubs - if (level >= 68) - SetTaximaskNode(213); //Shattered Sun Staging Area -} - -void PlayerTaxi::LoadTaxiMask(std::string const &data) -{ - Tokenizer tokens(data, ' '); - - uint8 index = 0; - for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index) - { - // load and set bits only for existing taxi nodes - m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter); - } -} - -void PlayerTaxi::AppendTaximaskTo(ByteBuffer& data, bool all) -{ - if (all) - { - for (uint8 i = 0; i < TaxiMaskSize; ++i) - data << uint32(sTaxiNodesMask[i]); // all existing nodes - } - else - { - for (uint8 i = 0; i < TaxiMaskSize; ++i) - data << uint32(m_taximask[i]); // known nodes - } -} - -bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint32 team) -{ - ClearTaxiDestinations(); - - Tokenizer Tokenizer(values, ' '); - - for (Tokenizer::const_iterator iter = Tokenizer.begin(); iter != Tokenizer.end(); ++iter) - { - uint32 node = atoul(*iter); - AddTaxiDestination(node); - } - - if (m_TaxiDestinations.empty()) - return true; - - // Check integrity - if (m_TaxiDestinations.size() < 2) - return false; - - for (size_t i = 1; i < m_TaxiDestinations.size(); ++i) - { - uint32 cost; - uint32 path; - sObjectMgr->GetTaxiPath(m_TaxiDestinations[i-1], m_TaxiDestinations[i], path, cost); - if (!path) - return false; - } - - // can't load taxi path without mount set (quest taxi path?) - if (!sObjectMgr->GetTaxiMountDisplayId(GetTaxiSource(), team, true)) - return false; - - return true; -} - -std::string PlayerTaxi::SaveTaxiDestinationsToString() -{ - if (m_TaxiDestinations.empty()) - return ""; - - std::ostringstream ss; - - for (size_t i=0; i < m_TaxiDestinations.size(); ++i) - ss << m_TaxiDestinations[i] << ' '; - - return ss.str(); -} - -uint32 PlayerTaxi::GetCurrentTaxiPath() const -{ - if (m_TaxiDestinations.size() < 2) - return 0; - - uint32 path; - uint32 cost; - - sObjectMgr->GetTaxiPath(m_TaxiDestinations[0], m_TaxiDestinations[1], path, cost); - - return path; -} - -std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi) -{ - for (uint8 i = 0; i < TaxiMaskSize; ++i) - ss << taxi.m_taximask[i] << ' '; - return ss; -} - Player::Player(WorldSession* session): Unit(true) { m_speakTime = 0; @@ -544,7 +411,7 @@ Player::Player(WorldSession* session): Unit(true) Player::~Player() { // it must be unloaded already in PlayerLogout and accessed only for logged in player - //m_social = NULL; + //m_social = nullptr; // Note: buy back item already deleted from DB when player was saved for (uint8 i = 0; i < PLAYER_SLOTS_COUNT; ++i) @@ -846,7 +713,7 @@ bool Player::StoreNewItemInBestSlots(uint32 titem_id, uint32 titem_amount) InventoryResult msg = CanStoreNewItem(INVENTORY_SLOT_BAG_0, NULL_SLOT, sDest, titem_id, titem_amount); if (msg == EQUIP_ERR_OK) { - StoreNewItem(sDest, titem_id, true, Item::GenerateItemRandomPropertyId(titem_id)); + StoreNewItem(sDest, titem_id, true, GenerateItemRandomPropertyId(titem_id)); return true; // stored } @@ -871,7 +738,7 @@ void Player::SendMirrorTimer(MirrorTimerType Type, uint32 MaxValue, uint32 Curre data << Regen; data << (uint8)0; data << (uint32)0; // spell id - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::StopMirrorTimer(MirrorTimerType Type) @@ -879,7 +746,7 @@ void Player::StopMirrorTimer(MirrorTimerType Type) m_MirrorTimer[Type] = DISABLED_MIRROR_TIMER; WorldPacket data(SMSG_STOP_MIRROR_TIMER, 4); data << (uint32)Type; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } bool Player::IsImmuneToEnvironmentalDamage() const @@ -933,7 +800,7 @@ uint32 Player::EnvironmentalDamage(EnviromentalDamage type, uint32 damage) DurabilityLossAll(0.10f, false); // durability lost message WorldPacket data2(SMSG_DURABILITY_DAMAGE_DEATH, 0); - GetSession()->SendPacket(&data2); + SendDirectMessage(&data2); } UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_DEATHS_FROM, 1, type); @@ -1003,14 +870,14 @@ void Player::HandleDrowning(uint32 time_diff) } else // If activated - do tick { - m_MirrorTimer[BREATH_TIMER]-=time_diff; + m_MirrorTimer[BREATH_TIMER] -= time_diff; // Timer limit - need deal damage if (m_MirrorTimer[BREATH_TIMER] < 0) { - m_MirrorTimer[BREATH_TIMER]+= 1*IN_MILLISECONDS; + m_MirrorTimer[BREATH_TIMER] += 1 * IN_MILLISECONDS; // Calculate and deal damage /// @todo Check this formula - uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1); + uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel() - 1); EnvironmentalDamage(DAMAGE_DROWNING, damage); } else if (!(m_MirrorTimerFlagsLast & UNDERWATER_INWATER)) // Update time in client if need @@ -1021,7 +888,7 @@ void Player::HandleDrowning(uint32 time_diff) { int32 UnderWaterTime = getMaxTimer(BREATH_TIMER); // Need breath regen - m_MirrorTimer[BREATH_TIMER]+=10*time_diff; + m_MirrorTimer[BREATH_TIMER] += 10 * time_diff; if (m_MirrorTimer[BREATH_TIMER] >= UnderWaterTime || !IsAlive()) StopMirrorTimer(BREATH_TIMER); else if (m_MirrorTimerFlagsLast & UNDERWATER_INWATER) @@ -1039,14 +906,14 @@ void Player::HandleDrowning(uint32 time_diff) } else { - m_MirrorTimer[FATIGUE_TIMER]-=time_diff; + m_MirrorTimer[FATIGUE_TIMER] -= time_diff; // Timer limit - need deal damage or teleport ghost to graveyard if (m_MirrorTimer[FATIGUE_TIMER] < 0) { - m_MirrorTimer[FATIGUE_TIMER]+= 1*IN_MILLISECONDS; + m_MirrorTimer[FATIGUE_TIMER] += 1 * IN_MILLISECONDS; if (IsAlive()) // Calculate and deal damage { - uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1); + uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel() - 1); EnvironmentalDamage(DAMAGE_EXHAUSTED, damage); } else if (HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) // Teleport ghost to graveyard @@ -1059,7 +926,7 @@ void Player::HandleDrowning(uint32 time_diff) else if (m_MirrorTimer[FATIGUE_TIMER] != DISABLED_MIRROR_TIMER) // Regen timer { int32 DarkWaterTime = getMaxTimer(FATIGUE_TIMER); - m_MirrorTimer[FATIGUE_TIMER]+=10*time_diff; + m_MirrorTimer[FATIGUE_TIMER] += 10 * time_diff; if (m_MirrorTimer[FATIGUE_TIMER] >= DarkWaterTime || !IsAlive()) StopMirrorTimer(FATIGUE_TIMER); else if (m_MirrorTimerFlagsLast & UNDERWATER_INDARKWATER) @@ -1076,7 +943,7 @@ void Player::HandleDrowning(uint32 time_diff) m_MirrorTimer[FIRE_TIMER] -= time_diff; if (m_MirrorTimer[FIRE_TIMER] < 0) { - m_MirrorTimer[FIRE_TIMER]+= 1*IN_MILLISECONDS; + m_MirrorTimer[FIRE_TIMER] += 1 * IN_MILLISECONDS; // Calculate and deal damage /// @todo Check this formula uint32 damage = urand(600, 700); @@ -1093,13 +960,15 @@ void Player::HandleDrowning(uint32 time_diff) m_MirrorTimer[FIRE_TIMER] = DISABLED_MIRROR_TIMER; // Recheck timers flag - m_MirrorTimerFlags&=~UNDERWATER_EXIST_TIMERS; - for (uint8 i = 0; i< MAX_TIMERS; ++i) + m_MirrorTimerFlags &= ~UNDERWATER_EXIST_TIMERS; + for (uint8 i = 0; i < MAX_TIMERS; ++i) + { if (m_MirrorTimer[i] != DISABLED_MIRROR_TIMER) { - m_MirrorTimerFlags|=UNDERWATER_EXIST_TIMERS; + m_MirrorTimerFlags |= UNDERWATER_EXIST_TIMERS; break; } + } m_MirrorTimerFlagsLast = m_MirrorTimerFlags; } @@ -1714,7 +1583,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) continue; } - SpellItemEnchantmentEntry const* enchant = NULL; + SpellItemEnchantmentEntry const* enchant = nullptr; uint32 enchants = GetUInt32ValueFromArray(equipment, visualBase + 1); for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot) @@ -1877,7 +1746,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return false; // far teleport to another map - Map* oldmap = IsInWorld() ? GetMap() : NULL; + Map* oldmap = IsInWorld() ? GetMap() : nullptr; // check if we can enter before stopping combat / removing pet / totems / interrupting spells // Check enter rights before map getting to avoid creating instance copy for player @@ -1955,7 +1824,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (Transport* transport = GetTransport()) data << transport->GetEntry() << GetMapId(); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } // remove from old map now @@ -1976,7 +1845,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati else data << m_teleport_dest.PositionXYZOStream(); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); SendSavedInstances(); } @@ -1990,7 +1859,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati return true; } -bool Player::TeleportTo(WorldLocation const &loc, uint32 options /*= 0*/) +bool Player::TeleportTo(WorldLocation const& loc, uint32 options /*= 0*/) { return TeleportTo(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation(), options); } @@ -2107,6 +1976,13 @@ void Player::RemoveFromWorld() } } +void Player::SetObjectScale(float scale) +{ + Unit::SetObjectScale(scale); + SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_PLAYER_BOUNDING_RADIUS); + SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_PLAYER_COMBAT_REACH); +} + bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const { // players are immune to taunt (the aura and the spell effect) @@ -2457,7 +2333,7 @@ void Player::SetInWater(bool apply) getHostileRefManager().updateThreatTables(); } -bool Player::IsInAreaTriggerRadius(const AreaTriggerEntry* trigger) const +bool Player::IsInAreaTriggerRadius(AreaTriggerEntry const* trigger) const { if (!trigger || GetMapId() != trigger->mapid) return false; @@ -2615,7 +2491,7 @@ void Player::UninviteFromGroup() } } -void Player::RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method /* = GROUP_REMOVEMETHOD_DEFAULT*/, ObjectGuid kicker /* = ObjectGuid::Empty */, const char* reason /* = NULL */) +void Player::RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method /*= GROUP_REMOVEMETHOD_DEFAULT*/, ObjectGuid kicker /*= ObjectGuid::Empty*/, char const* reason /*= nullptr*/) { if (!group) return; @@ -2639,7 +2515,7 @@ void Player::SendLogXPGain(uint32 GivenXP, Unit* victim, uint32 BonusXP, bool re } data << uint8(recruitAFriend ? 1 : 0); // does the GivenXP include a RaF bonus? - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::GiveXP(uint32 xp, Unit* victim, float group_rate) @@ -2726,7 +2602,7 @@ void Player::GiveLevel(uint8 level) for (uint8 i = STAT_STRENGTH; i < MAX_STATS; ++i) // Stats loop (0-4) data << uint32(int32(info.stats[i]) - GetCreateStat(Stats(i))); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); SetUInt32Value(PLAYER_NEXT_LEVEL_XP, sObjectMgr->GetXPForLevel(level)); @@ -3023,7 +2899,7 @@ void Player::SendInitialSpells() GetSpellHistory()->WritePacket<Player>(data); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::RemoveMail(uint32 id) @@ -3052,7 +2928,7 @@ void Player::SendMailResult(uint32 mailId, MailResponseType mailAction, MailResp data << (uint32) item_guid; // item guid low? data << (uint32) item_count; // item count? } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendNewMail() const @@ -3060,7 +2936,7 @@ void Player::SendNewMail() const // deliver undelivered mail WorldPacket data(SMSG_RECEIVED_MAIL, 4); data << (uint32) 0; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::UpdateNextMailTimeAndUnreads() @@ -3276,7 +3152,7 @@ bool Player::AddSpell(uint32 spellId, bool active, bool learning, bool dependent { WorldPacket data(SMSG_REMOVED_SPELL, 4); data << uint32(spellId); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } @@ -3577,7 +3453,7 @@ void Player::LearnSpell(uint32 spell_id, bool dependent, uint32 fromSkill /*= 0* WorldPacket data(SMSG_LEARNED_SPELL, 6); data << uint32(spell_id); data << uint16(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } // learn all disabled higher ranks and required spells (recursive) @@ -3758,7 +3634,7 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank) // learnSpell(prev_id, false); } // if ranked non-stackable spell: need activate lesser rank and update dendence state - /// No need to check for spellInfo != NULL here because if cur_active is true, then that means that the spell was already in m_spells, and only valid spells can be pushed there. + /// No need to check for spellInfo != nullptr here because if cur_active is true, then that means that the spell was already in m_spells, and only valid spells can be pushed there. else if (cur_active && !spellInfo->IsStackableWithRanks() && spellInfo->IsRanked()) { // need manually update dependence state (learn spell ignore like attempts) @@ -3803,7 +3679,7 @@ void Player::RemoveSpell(uint32 spell_id, bool disabled, bool learn_low_rank) { WorldPacket data(SMSG_REMOVED_SPELL, 4); data << uint32(spell_id); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } @@ -3943,7 +3819,7 @@ bool Player::ResetTalents(bool no_cost) // skip non-existing talent ranks if (talentInfo->RankID[rank] == 0) continue; - const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank]); + SpellInfo const* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank]); if (!_spellEntry) continue; RemoveSpell(talentInfo->RankID[rank], true); @@ -3972,14 +3848,14 @@ bool Player::ResetTalents(bool no_cost) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_NUMBER_OF_TALENT_RESETS, 1); m_resetTalentsCost = cost; - m_resetTalentsTime = time(NULL); + m_resetTalentsTime = time(nullptr); } /* when prev line will dropped use next line if (Pet* pet = GetPet()) { if (pet->getPetType() == HUNTER_PET && !pet->GetCreatureTemplate()->IsTameable(CanTameExoticPets())) - RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true); } */ @@ -4022,7 +3898,7 @@ void Player::BuildCreateUpdateBlockForPlayer(UpdateData* data, Player* target) c } for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) { - if (m_items[i] == NULL) + if (m_items[i] == nullptr) continue; m_items[i]->BuildCreateUpdateBlockForPlayer(data, target); @@ -4055,7 +3931,7 @@ void Player::DestroyForPlayer(Player* target, bool onDeath) const } for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) { - if (m_items[i] == NULL) + if (m_items[i] == nullptr) continue; m_items[i]->DestroyForPlayer(target); @@ -4590,7 +4466,7 @@ void Player::SetMovement(PlayerMovementType pType) } data << GetPackGUID(); data << uint32(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } /* Preconditions: @@ -4601,7 +4477,7 @@ void Player::BuildPlayerRepop() { WorldPacket data(SMSG_PRE_RESURRECT, GetPackGUID().size()); data << GetPackGUID(); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (getRace() == RACE_NIGHTELF) CastSpell(this, 20584, true); @@ -4661,7 +4537,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) data << float(0); data << float(0); data << float(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); // speed change, land walk @@ -5087,13 +4963,13 @@ void Player::RepopAtGraveyard() // Special handle for battleground maps if (Battleground* bg = GetBattleground()) - ClosestGrave = bg->GetClosestGraveYard(this); + ClosestGrave = bg->GetClosestGraveyard(this); else { if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) - ClosestGrave = bf->GetClosestGraveYard(this); + ClosestGrave = bf->GetClosestGraveyard(this); else - ClosestGrave = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); + ClosestGrave = sObjectMgr->GetClosestGraveyard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); } // stop countdown until repop @@ -5108,10 +4984,8 @@ void Player::RepopAtGraveyard() { WorldPacket data(SMSG_DEATH_RELEASE_LOC, 4*4); // show spirit healer position on minimap data << ClosestGrave->map_id; - data << ClosestGrave->x; - data << ClosestGrave->y; - data << ClosestGrave->z; - GetSession()->SendPacket(&data); + data << TaggedPosition<Position::XYZ>(ClosestGrave->x, ClosestGrave->y, ClosestGrave->z); + SendDirectMessage(&data); } } else if (GetPositionZ() < GetMap()->GetMinHeight(GetPositionX(), GetPositionY())) @@ -5477,8 +5351,8 @@ float Player::GetSpellCritFromIntellect() const if (critBase == nullptr || critRatio == nullptr) return 0.0f; - float crit=critBase->base + GetStat(STAT_INTELLECT)*critRatio->ratio; - return crit*100.0f; + float crit = critBase->base + GetStat(STAT_INTELLECT) * critRatio->ratio; + return crit * 100.0f; } float Player::GetRatingMultiplier(CombatRating cr) const @@ -5526,7 +5400,7 @@ float Player::OCTRegenHPPerSpirit() const GtOCTRegenHPEntry const* baseRatio = sGtOCTRegenHPStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); GtRegenHPPerSptEntry const* moreRatio = sGtRegenHPPerSptStore.LookupEntry((pclass-1)*GT_MAX_LEVEL + level-1); - if (baseRatio == NULL || moreRatio == NULL) + if (baseRatio == nullptr || moreRatio == nullptr) return 0.0f; // Formula from PaperDollFrame script @@ -5699,6 +5573,11 @@ void Player::SetRegularAttackTime() } } +void Player::StoreRaidMapDifficulty() +{ + m_raidMapDifficulty = GetMap()->GetDifficulty(); +} + //skill+step, checking for max value bool Player::UpdateSkill(uint32 skill_id, uint32 step) { @@ -6320,7 +6199,7 @@ void Player::SendActionButtons(uint32 state) const } } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } @@ -6450,7 +6329,7 @@ bool Player::UpdatePosition(float x, float y, float z, float orientation, bool t void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) { if (self) - GetSession()->SendPacket(data); + SendDirectMessage(data); Trinity::MessageDistDeliverer notifier(this, data, dist); Cell::VisitWorldObjects(this, notifier, dist); @@ -6459,7 +6338,7 @@ void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool s void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool self, bool own_team_only) { if (self) - GetSession()->SendPacket(data); + SendDirectMessage(data); Trinity::MessageDistDeliverer notifier(this, data, dist, own_team_only); Cell::VisitWorldObjects(this, notifier, dist); @@ -6468,7 +6347,7 @@ void Player::SendMessageToSetInRange(WorldPacket const* data, float dist, bool s void Player::SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) { if (skipped_rcvr != this) - GetSession()->SendPacket(data); + SendDirectMessage(data); // we use World::GetMaxVisibleDistance() because i cannot see why not use a distance // update: replaced by GetMap()->GetVisibilityDistance() @@ -6931,7 +6810,7 @@ bool Player::RewardHonor(Unit* victim, uint32 groupsize, int32 honor, bool pvpto data << uint64(victim_guid); data << uint32(victim_rank); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); // add honor points ModifyHonorPoints(honor); @@ -7218,7 +7097,7 @@ void Player::CheckDuelDistance(time_t currTime) duel->outOfBound = currTime; WorldPacket data(SMSG_DUEL_OUTOFBOUNDS, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } else @@ -7228,7 +7107,7 @@ void Player::CheckDuelDistance(time_t currTime) duel->outOfBound = 0; WorldPacket data(SMSG_DUEL_INBOUNDS, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } else if (currTime >= (duel->outOfBound+10)) DuelComplete(DUEL_FLED); @@ -7258,10 +7137,10 @@ void Player::DuelComplete(DuelCompleteType type) WorldPacket data(SMSG_DUEL_COMPLETE, (1)); data << (uint8)((type != DUEL_INTERRUPTED) ? 1 : 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (duel->opponent->GetSession()) - duel->opponent->GetSession()->SendPacket(&data); + duel->opponent->SendDirectMessage(&data); if (type != DUEL_INTERRUPTED) { @@ -7408,7 +7287,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (slot >= INVENTORY_SLOT_BAG_END || !proto) return; - ScalingStatDistributionEntry const* ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : NULL; + ScalingStatDistributionEntry const* ssd = proto->ScalingStatDistribution ? sScalingStatDistributionStore.LookupEntry(proto->ScalingStatDistribution) : nullptr; if (only_level_scale && !ssd) return; @@ -7417,7 +7296,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (ssd && ssd_level > ssd->MaxLevel) ssd_level = ssd->MaxLevel; - ScalingStatValuesEntry const* ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL; + ScalingStatValuesEntry const* ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : nullptr; if (only_level_scale && !ssv) return; @@ -7960,8 +7839,8 @@ void Player::UpdateEquipSpellsAtFormChange() if (!spellInfo) continue; - ApplyEquipSpell(spellInfo, NULL, false, true); // remove spells that not fit to form - ApplyEquipSpell(spellInfo, NULL, true, true); // add spells that fit form but not active + ApplyEquipSpell(spellInfo, nullptr, false, true); // remove spells that not fit to form + ApplyEquipSpell(spellInfo, nullptr, true, true); // add spells that fit form but not active } } } @@ -8112,7 +7991,7 @@ void Player::CastItemCombatSpell(DamageInfo const& damageInfo, Item* item, ItemT } // Apply spell mods - ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(pEnchant->spellid[s], chance); + ApplySpellMod(pEnchant->spellid[s], SPELLMOD_CHANCE_OF_SUCCESS, chance); // Shiv has 100% chance to apply the poison if (FindCurrentSpellBySpellId(5938) && e_slot == TEMP_ENCHANTMENT_SLOT) @@ -8157,7 +8036,7 @@ void Player::CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 if (!spellInfo) { TC_LOG_ERROR("entities.player", "Player::CastItemUseSpell: Item (Entry: %u) has wrong spell id %u, ignoring.", proto->ItemId, learn_spell_id); - SendEquipError(EQUIP_ERR_NONE, item, NULL); + SendEquipError(EQUIP_ERR_NONE, item, nullptr); return; } @@ -8363,7 +8242,7 @@ void Player::_ApplyAmmoBonuses() UpdateDamagePhysical(RANGED_ATTACK); } -bool Player::CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const +bool Player::CheckAmmoCompatibility(ItemTemplate const* ammo_proto) const { if (!ammo_proto) return false; @@ -8817,14 +8696,14 @@ void Player::SendLootError(ObjectGuid guid, LootError error) const void Player::SendNotifyLootMoneyRemoved() const { WorldPacket data(SMSG_LOOT_CLEAR_MONEY, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendNotifyLootItemRemoved(uint8 lootSlot) const { WorldPacket data(SMSG_LOOT_REMOVED, 1); data << uint8(lootSlot); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendUpdateWorldState(uint32 Field, uint32 Value) const @@ -8832,7 +8711,7 @@ void Player::SendUpdateWorldState(uint32 Field, uint32 Value) const WorldPacket data(SMSG_UPDATE_WORLD_STATE, 8); data << Field; data << Value; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) @@ -9457,7 +9336,7 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) uint16 length = (data.wpos() - countPos) / 8; data.put<uint16>(countPos, length); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); SendBGWeekendWorldStates(); SendBattlefieldWorldStates(); } @@ -9508,7 +9387,7 @@ void Player::SetBindPoint(ObjectGuid guid) const { WorldPacket data(SMSG_BINDER_CONFIRM, 8); data << uint64(guid); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendTalentWipeConfirm(ObjectGuid guid) const @@ -9517,7 +9396,7 @@ void Player::SendTalentWipeConfirm(ObjectGuid guid) const data << uint64(guid); uint32 cost = sWorld->getBoolConfig(CONFIG_NO_RESET_TALENT_COST) ? 0 : ResetTalentsCost(); data << cost; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::ResetPetTalents() @@ -9956,7 +9835,7 @@ Item* Player::GetItemByPos(uint8 bag, uint8 slot) const Item* Player::GetUseableItemByPos(uint8 bag, uint8 slot) const { if (!CanUseAttackType(GetAttackBySlot(slot))) - return NULL; + return nullptr; return GetItemByPos(bag, slot); } @@ -10290,7 +10169,7 @@ bool Player::HasGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, return false; } -InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count /*= NULL*/, uint32* itemLimitCategory /*= NULL*/) const +InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count /*= nullptr*/, uint32* itemLimitCategory /*= nullptr*/) const { ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(entry); if (!pProto) @@ -10346,7 +10225,12 @@ InventoryResult Player::CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item return EQUIP_ERR_OK; } -InventoryResult Player::CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count /*= NULL*/) const +InventoryResult Player::CanTakeMoreSimilarItems(Item* pItem, uint32* itemLimitCategory /*= nullptr*/) const +{ + return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem, nullptr, itemLimitCategory); +} + +InventoryResult Player::CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count /*= nullptr*/) const { return CanStoreItem(bag, slot, dest, item, count, nullptr, false, no_space_count); } @@ -11898,7 +11782,7 @@ void Player::SetAmmo(uint32 item) InventoryResult msg = CanUseAmmo(item); if (msg != EQUIP_ERR_OK) { - SendEquipError(msg, NULL, NULL, item); + SendEquipError(msg, nullptr, nullptr, item); return; } } @@ -11919,7 +11803,7 @@ void Player::RemoveAmmo() } // Return stored item (if stored to stack, it can diff. from pItem). And pItem ca be deleted in this case. -Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update, int32 randomPropertyId, AllowedLooterSet const& allowedLooters) +Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update, int32 randomPropertyId, GuidSet const& allowedLooters) { uint32 count = 0; for (ItemPosCountVec::const_iterator itr = dest.begin(); itr != dest.end(); ++itr) @@ -11943,10 +11827,10 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update // save data std::ostringstream ss; - AllowedLooterSet::const_iterator itr = allowedLooters.begin(); + GuidSet::const_iterator itr = allowedLooters.begin(); ss << *itr; for (++itr; itr != allowedLooters.end(); ++itr) - ss << ' ' << *itr; + ss << ' ' << itr->GetCounter(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_BOP_TRADE); stmt->setUInt32(0, pItem->GetGUID().GetCounter()); @@ -12010,7 +11894,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool (pItem->GetTemplate()->Bonding == BIND_WHEN_EQUIPED && IsBagPos(pos))) pItem->SetBinding(true); - Bag* pBag = (bag == INVENTORY_SLOT_BAG_0) ? NULL : GetBagByPos(bag); + Bag* pBag = (bag == INVENTORY_SLOT_BAG_0) ? nullptr : GetBagByPos(bag); if (!pBag) { m_items[slot] = pItem; @@ -12138,7 +12022,7 @@ Item* Player::EquipItem(uint16 pos, Item* pItem, bool update) GetSpellHistory()->AddGlobalCooldown(spellProto, m_weaponChangeTimer); WorldPacket data; GetSpellHistory()->BuildCooldownPacket(data, SPELL_COOLDOWN_FLAG_INCLUDE_GCD, cooldownSpell, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } } @@ -12369,7 +12253,7 @@ void Player::MoveItemFromInventory(uint8 bag, uint8 slot, bool update) ItemRemovedQuestCheck(it->GetEntry(), it->GetCount()); RemoveItem(bag, slot, update); it->SetNotRefundable(this, false); - it->RemoveFromUpdateQueueOf(this); + RemoveItemFromUpdateQueueOf(it, this); if (it->IsInWorld()) { it->RemoveFromWorld(); @@ -13403,7 +13287,7 @@ void Player::SendEquipError(InventoryResult msg, Item* pItem, Item* pItem2, uint break; } } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 param) const @@ -13414,7 +13298,7 @@ void Player::SendBuyError(BuyResult msg, Creature* creature, uint32 item, uint32 if (param > 0) data << uint32(param); data << uint8(msg); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendSellError(SellResult msg, Creature* creature, ObjectGuid guid, uint32 param) const @@ -13425,7 +13309,7 @@ void Player::SendSellError(SellResult msg, Creature* creature, ObjectGuid guid, if (param > 0) data << uint32(param); data << uint8(msg); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } bool Player::IsUseEquipedWeapon(bool mainhand) const @@ -13543,7 +13427,7 @@ void Player::UpdateItemDuration(uint32 time, bool realtimeonly) void Player::UpdateEnchantTime(uint32 time) { - for (EnchantDurationList::iterator itr = m_enchantDuration.begin(), next; itr != m_enchantDuration.end(); itr=next) + for (EnchantDurationList::iterator itr = m_enchantDuration.begin(), next; itr != m_enchantDuration.end(); itr = next) { ASSERT(itr->item); next = itr; @@ -14125,7 +14009,7 @@ void Player::SendNewItem(Item* item, uint32 count, bool received, bool created, if (broadcast && GetGroup()) GetGroup()->BroadcastPacket(&data, true); else - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } /*********************************************************/ @@ -14640,7 +14524,7 @@ void Player::SendPreparedQuest(ObjectGuid guid) title = gossiptext->Options[0].Text_0; LocaleConstant localeConstant = GetSession()->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) ObjectMgr::GetLocaleString(nl->Text_0[0], localeConstant, title); } @@ -14649,7 +14533,7 @@ void Player::SendPreparedQuest(ObjectGuid guid) title = gossiptext->Options[0].Text_1; LocaleConstant localeConstant = GetSession()->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (NpcTextLocale const* nl = sObjectMgr->GetNpcTextLocale(textid)) ObjectMgr::GetLocaleString(nl->Text_1[0], localeConstant, title); } @@ -15124,7 +15008,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, ItemPosCountVec dest; if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, quest->RewardChoiceItemCount[reward]) == EQUIP_ERR_OK) { - Item* item = StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomPropertyId(itemId)); SendNewItem(item, quest->RewardChoiceItemCount[reward], true, false); } } @@ -15139,7 +15023,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, ItemPosCountVec dest; if (CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemId, quest->RewardItemIdCount[i]) == EQUIP_ERR_OK) { - Item* item = StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomPropertyId(itemId)); SendNewItem(item, quest->RewardItemIdCount[i], true, false); } else if (quest->IsDFQuest()) @@ -15193,7 +15077,7 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, if (quest->GetBonusTalents()) { - m_questRewardTalentCount+=quest->GetBonusTalents(); + m_questRewardTalentCount += quest->GetBonusTalents(); InitTalentForLevel(); } @@ -15414,7 +15298,7 @@ bool Player::SatisfyQuestLog(bool msg) const if (msg) { WorldPacket data(SMSG_QUESTLOG_FULL, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } return false; } @@ -16656,7 +16540,7 @@ void Player::SendQuestComplete(uint32 quest_id) const { WorldPacket data(SMSG_QUESTUPDATE_COMPLETE, 4); data << uint32(quest_id); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } @@ -16681,7 +16565,7 @@ void Player::SendQuestReward(Quest const* quest, uint32 XP) const data << uint32(10 * quest->CalculateHonorGain(GetQuestLevel(quest))); data << uint32(quest->GetBonusTalents()); // bonus talents data << uint32(quest->GetRewArenaPoints()); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendQuestFailed(uint32 questId, InventoryResult reason) const @@ -16691,7 +16575,7 @@ void Player::SendQuestFailed(uint32 questId, InventoryResult reason) const WorldPacket data(SMSG_QUESTGIVER_QUEST_FAILED, 4 + 4); data << uint32(questId); data << uint32(reason); // failed reason (valid reasons: 4, 16, 50, 17, 74, other values show default message) - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } @@ -16701,7 +16585,7 @@ void Player::SendQuestTimerFailed(uint32 quest_id) const { WorldPacket data(SMSG_QUESTUPDATE_FAILEDTIMER, 4); data << uint32(quest_id); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_FAILEDTIMER"); } } @@ -16710,26 +16594,26 @@ void Player::SendCanTakeQuestResponse(QuestFailedReason msg) const { WorldPacket data(SMSG_QUESTGIVER_QUEST_INVALID, 4); data << uint32(msg); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTGIVER_QUEST_INVALID"); } -void Player::SendQuestConfirmAccept(const Quest* quest, Player* pReceiver) const +void Player::SendQuestConfirmAccept(Quest const* quest, Player* pReceiver) const { if (pReceiver) { std::string strTitle = quest->GetTitle(); LocaleConstant localeConstant = pReceiver->GetSession()->GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) - if (const QuestLocale* pLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) + if (localeConstant != LOCALE_enUS) + if (QuestLocale const* pLocale = sObjectMgr->GetQuestLocale(quest->GetQuestId())) ObjectMgr::GetLocaleString(pLocale->Title, localeConstant, strTitle); WorldPacket data(SMSG_QUEST_CONFIRM_ACCEPT, (4 + strTitle.size() + 8)); data << uint32(quest->GetQuestId()); data << strTitle; data << uint64(GetGUID()); - pReceiver->GetSession()->SendPacket(&data); + pReceiver->SendDirectMessage(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUEST_CONFIRM_ACCEPT"); } @@ -16753,7 +16637,7 @@ void Player::SendQuestUpdateAddItem(Quest const* /*quest*/, uint32 /*item_idx*/, TC_LOG_DEBUG("network", "WORLD: Sent SMSG_QUESTUPDATE_ADD_ITEM"); //data << quest->RequiredItemId[item_idx]; //data << count; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendQuestUpdateAddCreatureOrGo(Quest const* quest, ObjectGuid guid, uint32 creatureOrGO_idx, uint16 old_count, uint16 add_count) @@ -16772,7 +16656,7 @@ void Player::SendQuestUpdateAddCreatureOrGo(Quest const* quest, ObjectGuid guid, data << uint32(old_count + add_count); data << uint32(quest->RequiredNpcOrGoCount[ creatureOrGO_idx ]); data << uint64(guid); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); uint16 log_slot = FindQuestSlot(quest->GetQuestId()); if (log_slot < MAX_QUEST_LOG_SIZE) @@ -16787,7 +16671,7 @@ void Player::SendQuestUpdateAddPlayer(Quest const* quest, uint16 old_count, uint data << uint32(quest->GetQuestId()); data << uint32(old_count + add_count); data << uint32(quest->GetPlayersSlain()); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); uint16 log_slot = FindQuestSlot(quest->GetQuestId()); if (log_slot < MAX_QUEST_LOG_SIZE) @@ -16835,7 +16719,7 @@ void Player::SendQuestGiverStatusMultiple() } data.put<uint32>(0, count); // write real count - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } bool Player::HasPvPForcingQuest() const @@ -16925,30 +16809,27 @@ void Player::_LoadEquipmentSets(PreparedQueryResult result) if (!result) return; - uint32 count = 0; do { Field* fields = result->Fetch(); - EquipmentSet eqSet; + EquipmentSetInfo eqSet; - eqSet.Guid = fields[0].GetUInt64(); - uint8 index = fields[1].GetUInt8(); - eqSet.Name = fields[2].GetString(); - eqSet.IconName = fields[3].GetString(); - eqSet.IgnoreMask = fields[4].GetUInt32(); - eqSet.state = EQUIPMENT_SET_UNCHANGED; + eqSet.Data.Guid = fields[0].GetUInt64(); + eqSet.Data.SetID = fields[1].GetUInt8(); + eqSet.Data.SetName = fields[2].GetString(); + eqSet.Data.SetIcon = fields[3].GetString(); + eqSet.Data.IgnoreMask = fields[4].GetUInt32(); + eqSet.State = EQUIPMENT_SET_UNCHANGED; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) - eqSet.Items[i] = fields[5+i].GetUInt32(); + if (ObjectGuid::LowType guid = fields[5 + i].GetUInt32()) + eqSet.Data.Pieces[i] = ObjectGuid::Create<HighGuid::Item>(guid); - m_EquipmentSets[index] = eqSet; - - ++count; + if (eqSet.Data.SetID >= MAX_EQUIPMENT_SET_INDEX) // client limit + continue; - if (count >= MAX_EQUIPMENT_SET_INDEX) // client limit - break; - } - while (result->NextRow()); + _equipmentSets[eqSet.Data.Guid] = eqSet; + } while (result->NextRow()); } void Player::_LoadBGData(PreparedQueryResult result) @@ -17766,7 +17647,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) return true; } -bool Player::isAllowedToLoot(const Creature* creature) +bool Player::isAllowedToLoot(Creature const* creature) { if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward()) return false; @@ -17774,7 +17655,7 @@ bool Player::isAllowedToLoot(const Creature* creature) if (HasPendingBind()) return false; - const Loot* loot = &creature->loot; + Loot const* loot = &creature->loot; if (loot->isLooted()) // nothing to loot or everything looted. return false; if (!loot->hasItemForAll() && !loot->hasItemFor(this)) // no loot in creature for this player @@ -18172,9 +18053,9 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F { std::string strGUID = (*result)[0].GetString(); Tokenizer GUIDlist(strGUID, ' '); - AllowedLooterSet looters; + GuidSet looters; for (Tokenizer::const_iterator itr = GUIDlist.begin(); itr != GUIDlist.end(); ++itr) - looters.insert(atol(*itr)); + looters.insert(ObjectGuid::Create<HighGuid::Player>(uint32(strtoul(*itr, nullptr, 10)))); if (looters.size() > 1 && item->GetTemplate()->GetMaxStackSize() == 1 && item->IsSoulBound()) { @@ -18750,7 +18631,7 @@ InstancePlayerBind* Player::GetBoundInstance(uint32 mapid, Difficulty difficulty InstanceSave* Player::GetInstanceSave(uint32 mapid, bool raid) { InstancePlayerBind* pBind = GetBoundInstance(mapid, GetDifficulty(raid)); - InstanceSave* pSave = pBind ? pBind->save : NULL; + InstanceSave* pSave = pBind ? pBind->save : nullptr; if (!pBind || !pBind->perm) if (Group* group = GetGroup()) if (InstanceGroupBind* groupBind = group->GetBoundInstance(GetDifficulty(raid), mapid)) @@ -18856,12 +18737,12 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, B void Player::BindToInstance() { InstanceSave* mapSave = sInstanceSaveMgr->GetInstanceSave(_pendingBindId); - if (!mapSave) //it seems sometimes mapSave is NULL, but I did not check why + if (!mapSave) //it seems sometimes mapSave is nullptr, but I did not check why return; WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); data << uint32(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (!IsGameMaster()) { BindToInstance(mapSave, true, EXTEND_STATE_KEEP); @@ -18908,7 +18789,7 @@ void Player::SendRaidInfo() } } data.put<uint32>(p_counter, counter); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } /* @@ -18934,7 +18815,7 @@ void Player::SendSavedInstances() //Send opcode 811. true or false means, whether you have current raid/heroic instances data.Initialize(SMSG_UPDATE_INSTANCE_OWNERSHIP); data << uint32(hasBeenSaved); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (!hasBeenSaved) return; @@ -18947,7 +18828,7 @@ void Player::SendSavedInstances() { data.Initialize(SMSG_UPDATE_LAST_INSTANCE); data << uint32(itr->second.save->GetMapId()); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } } @@ -19195,6 +19076,8 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); + auto finiteAlways = [](float f) { return std::isfinite(f) ? f : 0.0f; }; + if (create) { //! Insert query @@ -20211,7 +20094,7 @@ bool Player::CanSpeak() const void Player::SendAttackSwingNotInRange() const { WorldPacket data(SMSG_ATTACKSWING_NOTINRANGE, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SavePositionInDB(WorldLocation const& loc, uint16 zoneId, ObjectGuid guid, SQLTransaction& trans) @@ -20258,25 +20141,25 @@ void Player::Customize(CharacterCustomizeInfo const* customizeInfo, SQLTransacti void Player::SendAttackSwingDeadTarget() const { WorldPacket data(SMSG_ATTACKSWING_DEADTARGET, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendAttackSwingCantAttack() const { WorldPacket data(SMSG_ATTACKSWING_CANT_ATTACK, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendAttackSwingCancelAttack() const { WorldPacket data(SMSG_CANCEL_COMBAT, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendAttackSwingBadFacingAttack() const { WorldPacket data(SMSG_ATTACKSWING_BADFACING, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendAutoRepeatCancel(Unit* target) @@ -20291,7 +20174,7 @@ void Player::SendExplorationExperience(uint32 Area, uint32 Experience) const WorldPacket data(SMSG_EXPLORATION_EXPERIENCE, 8); data << uint32(Area); data << uint32(Experience); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendDungeonDifficulty(bool IsInGroup) const @@ -20301,7 +20184,7 @@ void Player::SendDungeonDifficulty(bool IsInGroup) const data << (uint32)GetDungeonDifficulty(); data << uint32(val); data << uint32(IsInGroup); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty) const @@ -20311,14 +20194,14 @@ void Player::SendRaidDifficulty(bool IsInGroup, int32 forcedDifficulty) const data << uint32(forcedDifficulty == -1 ? GetRaidDifficulty() : forcedDifficulty); data << uint32(val); data << uint32(IsInGroup); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendResetFailedNotify(uint32 mapid) const { WorldPacket data(SMSG_RESET_FAILED_NOTIFY, 4); data << uint32(mapid); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } /// Reset all solo instances and optionally send a message on success for each @@ -20332,7 +20215,7 @@ void Player::ResetInstances(uint8 method, bool isRaid) for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) { InstanceSave* p = itr->second.save; - const MapEntry* entry = sMapStore.LookupEntry(itr->first); + MapEntry const* entry = sMapStore.LookupEntry(itr->first); if (!entry || entry->IsRaid() != isRaid || !p->CanReset()) { ++itr; @@ -20374,7 +20257,7 @@ void Player::SendResetInstanceSuccess(uint32 MapId) const { WorldPacket data(SMSG_INSTANCE_RESET, 4); data << uint32(MapId); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) const @@ -20387,7 +20270,7 @@ void Player::SendResetInstanceFailed(uint32 reason, uint32 MapId) const WorldPacket data(SMSG_INSTANCE_RESET_FAILED, 4); data << uint32(reason); data << uint32(MapId); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } /*********************************************************/ @@ -20544,7 +20427,7 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent) { WorldPacket data(SMSG_PET_SPELLS, 8); data << uint64(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (GetGroup()) SetGroupUpdateFlag(GROUP_UPDATE_PET); @@ -20659,14 +20542,14 @@ void Player::Whisper(std::string const& text, Language language, Player* target, WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER, Language(language), this, this, _text); - target->GetSession()->SendPacket(&data); + target->SendDirectMessage(&data); // rest stuff shouldn't happen in case of addon message if (isAddonMessage) return; ChatHandler::BuildChatPacket(data, CHAT_MSG_WHISPER_INFORM, Language(language), target, target, _text); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (!isAcceptWhispers() && !IsGameMaster() && !target->IsGameMaster()) { @@ -20702,7 +20585,7 @@ void Player::Whisper(uint32 textId, Player* target, bool /*isBossWhisper = false Item* Player::GetMItem(uint32 id) { ItemMap::const_iterator itr = mMitems.find(id); - return itr != mMitems.end() ? itr->second : NULL; + return itr != mMitems.end() ? itr->second : nullptr; } void Player::AddMItem(Item* it) @@ -20720,7 +20603,7 @@ bool Player::RemoveMItem(uint32 id) void Player::SendOnCancelExpectedVehicleRideAura() const { WorldPacket data(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::PetSpellInitialize() @@ -20769,7 +20652,7 @@ void Player::PetSpellInitialize() //Cooldowns pet->GetSpellHistory()->WritePacket<Pet>(data); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::PossessSpellInitialize() @@ -20797,7 +20680,7 @@ void Player::PossessSpellInitialize() data << uint8(0); // spells count data << uint8(0); // cooldowns count - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::VehicleSpellInitialize() @@ -20848,7 +20731,7 @@ void Player::VehicleSpellInitialize() // Cooldowns vehicle->GetSpellHistory()->WritePacket<Pet>(data); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::CharmSpellInitialize() @@ -20903,14 +20786,14 @@ void Player::CharmSpellInitialize() data << uint8(0); // cooldowns count - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendRemoveControlBar() const { WorldPacket data(SMSG_PET_SPELLS, 8); data << uint64(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell) @@ -20929,6 +20812,120 @@ bool Player::IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod return spellInfo->IsAffectedBySpellMod(mod); } +template <class T> +void Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell /*= nullptr*/) const +{ + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); + if (!spellInfo) + return; + + float totalmul = 1.0f; + int32 totalflat = 0; + + // Drop charges for triggering spells instead of triggered ones + if (m_spellModTakingSpell) + spell = m_spellModTakingSpell; + + switch (op) + { + // special case, if a mod makes spell instant, only consume that mod + case SPELLMOD_CASTING_TIME: + { + SpellModifier* modInstantSpell = nullptr; + for (SpellModifier* mod : m_spellMods[op]) + { + if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + continue; + + if (mod->type == SPELLMOD_PCT && basevalue < T(10000) && mod->value <= -100) + { + modInstantSpell = mod; + break; + } + } + + if (modInstantSpell) + { + Player::ApplyModToSpell(modInstantSpell, spell); + basevalue = T(0); + return; + } + break; + } + // special case if two mods apply 100% critical chance, only consume one + case SPELLMOD_CRITICAL_CHANCE: + { + SpellModifier* modCritical = nullptr; + for (SpellModifier* mod : m_spellMods[op]) + { + if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + continue; + + if (mod->type == SPELLMOD_FLAT && mod->value >= 100) + { + modCritical = mod; + break; + } + } + + if (modCritical) + { + Player::ApplyModToSpell(modCritical, spell); + basevalue = T(100); + return; + } + break; + } + default: + break; + } + + for (SpellModifier* mod : m_spellMods[op]) + { + if (!IsAffectedBySpellmod(spellInfo, mod, spell)) + continue; + + switch (mod->type) + { + case SPELLMOD_FLAT: + totalflat += mod->value; + break; + case SPELLMOD_PCT: + { + // skip percent mods with null basevalue (most important for spell mods with charges) + if (basevalue == T(0)) + continue; + + // special case (skip > 10sec spell casts for instant cast setting) + if (op == SPELLMOD_CASTING_TIME && mod->value <= -100 && basevalue >= T(10000)) + continue; + else if (!Player::HasSpellModApplied(mod, spell)) + { + // special case for Surge of Light, don't apply critical chance reduction if other mods not applied (ie procs while casting another spell) + // (Surge of Light is the only PCT_MOD on critical chance) + if (op == SPELLMOD_CRITICAL_CHANCE) + continue; + // special case for Backdraft, dont' apply GCD reduction if cast time reduction wasn't applied (ie when Backlash is consumed first) + // (Backdraft is the only PCT_MOD on global cooldown) + else if (op == SPELLMOD_GLOBAL_COOLDOWN) + continue; + } + + totalmul += CalculatePct(1.0f, mod->value); + break; + } + } + + Player::ApplyModToSpell(mod, spell); + } + + basevalue = T(float(basevalue + totalflat) * totalmul); +} + +template TC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, int32& basevalue, Spell* spell) const; +template TC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, uint32& basevalue, Spell* spell) const; +template TC_GAME_API void Player::ApplySpellMod(uint32 spellId, SpellModOp op, float& basevalue, Spell* spell) const; + void Player::AddSpellMod(SpellModifier* mod, bool apply) { TC_LOG_DEBUG("spells", "Player::AddSpellMod: Player '%s' (%s), SpellID: %d", GetName().c_str(), GetGUID().ToString().c_str(), mod->spellId); @@ -21003,7 +21000,7 @@ void Player::SendProficiency(ItemClass itemClass, uint32 itemSubclassMask) const { WorldPacket data(SMSG_SET_PROFICIENCY, 1 + 4); data << uint8(itemClass) << uint32(itemSubclassMask); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::RemovePetitionsAndSigns(ObjectGuid guid, CharterTypes type) @@ -21422,7 +21419,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c data << uint32(vendorslot + 1); // numbered from 1 at client data << int32(crItem->maxcount > 0 ? new_count : 0xFFFFFFFF); data << uint32(count); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); SendNewItem(it, pProto->BuyCount * count, true, false, false); if (!bStore) @@ -21643,7 +21640,7 @@ void Player::UpdateHomebindTime(uint32 time) WorldPacket data(SMSG_RAID_GROUP_ONLY, 4+4); data << uint32(0); data << uint32(0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } // instance is valid, reset homebind timer m_HomebindTimer = 0; @@ -21666,7 +21663,7 @@ void Player::UpdateHomebindTime(uint32 time) WorldPacket data(SMSG_RAID_GROUP_ONLY, 4+4); data << uint32(m_HomebindTimer); data << uint32(1); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); TC_LOG_DEBUG("maps", "Player::UpdateHomebindTime: Player '%s' (%s) will be teleported to homebind in 60 seconds", GetName().c_str(), GetGUID().ToString().c_str()); } @@ -21958,7 +21955,7 @@ void Player::SetBattlegroundEntryPoint() // If map is dungeon find linked graveyard if (GetMap()->IsDungeon()) { - if (const WorldSafeLocsEntry* entry = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam())) + if (WorldSafeLocsEntry const* entry = sObjectMgr->GetClosestGraveyard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam())) m_bgData.joinPos = WorldLocation(entry->map_id, entry->x, entry->y, entry->z, 0.0f); else TC_LOG_ERROR("entities.player", "Player::SetBattlegroundEntryPoint: Dungeon (MapID: %u) has no linked graveyard, setting home location as entry point.", GetMapId()); @@ -22109,7 +22106,7 @@ bool Player::IsAlwaysDetectableFor(WorldObject const* seer) const if (Unit::IsAlwaysDetectableFor(seer)) return true; - if (const Player* seerPlayer = seer->ToPlayer()) + if (Player const* seerPlayer = seer->ToPlayer()) if (IsGroupVisibleFor(seerPlayer)) return !(seerPlayer->duel && seerPlayer->duel->startTime != 0 && seerPlayer->duel->opponent == this); @@ -22250,7 +22247,7 @@ void Player::UpdateTriggerVisibility() return; udata.BuildPacket(&packet); - GetSession()->SendPacket(&packet); + SendDirectMessage(&packet); } void Player::SendInitialVisiblePackets(Unit* target) const @@ -22398,7 +22395,7 @@ void Player::SendComboPoints() data.Initialize(SMSG_UPDATE_COMBO_POINTS, combotarget->GetPackGUID().size()+1); data << combotarget->GetPackGUID(); data << uint8(m_comboPoints); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } @@ -22496,7 +22493,7 @@ void Player::SendInitialPacketsBeforeAddToMap() data << m_homebindX << m_homebindY << m_homebindZ; data << (uint32) m_homebindMapId; data << (uint32) m_homebindAreaId; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); // SMSG_SET_PROFICIENCY // SMSG_SET_PCT_SPELL_MODIFIER @@ -22509,13 +22506,13 @@ void Player::SendInitialPacketsBeforeAddToMap() data.Initialize(SMSG_INSTANCE_DIFFICULTY, 4+4); data << uint32(GetMap()->GetDifficulty()); data << uint32(GetMap()->GetEntry()->IsDynamicDifficultyMap() && GetMap()->IsHeroic()); // Raid dynamic difficulty - GetSession()->SendPacket(&data); + SendDirectMessage(&data); SendInitialSpells(); data.Initialize(SMSG_SEND_UNLEARN_SPELLS, 4); data << uint32(0); // count, for (count) uint32; - GetSession()->SendPacket(&data); + SendDirectMessage(&data); SendInitialActionButtons(); m_reputationMgr->SendInitialReputations(); @@ -22527,7 +22524,7 @@ void Player::SendInitialPacketsBeforeAddToMap() data.AppendPackedTime(GameTime::GetGameTime()); data << float(0.01666667f); // game speed data << uint32(0); // added in 3.1.2 - GetSession()->SendPacket(&data); + SendDirectMessage(&data); GetReputationMgr().SendForceReactions(); // SMSG_SET_FORCED_REACTIONS @@ -22591,11 +22588,11 @@ void Player::SendInitialPacketsAfterAddToMap() if (GetMap()->GetDifficulty() != GetRaidDifficulty()) { StoreRaidMapDifficulty(); - SendRaidDifficulty(GetGroup() != NULL, GetStoredRaidDifficulty()); + SendRaidDifficulty(GetGroup() != nullptr, GetStoredRaidDifficulty()); } } else if (GetRaidDifficulty() != GetStoredRaidDifficulty()) - SendRaidDifficulty(GetGroup() != NULL); + SendRaidDifficulty(GetGroup() != nullptr); if (GetPlayerSharingQuest()) { @@ -22635,7 +22632,7 @@ void Player::SendTransferAborted(uint32 mapid, TransferAbortReason reason, uint8 default: break; } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint32 time, bool welcome) const @@ -22663,7 +22660,7 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3 data << uint8(0); // is locked data << uint8(0); // is extended, ignored if prev field is 0 } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::ApplyEquipCooldown(Item* pItem) @@ -22705,7 +22702,7 @@ void Player::ApplyEquipCooldown(Item* pItem) WorldPacket data(SMSG_ITEM_COOLDOWN, 8 + 4); data << uint64(pItem->GetGUID()); data << uint32(spellData.SpellId); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } } @@ -22998,7 +22995,7 @@ void Player::SendAurasForTarget(Unit* target) const auraApp->BuildUpdatePacket(data, false); } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SetDailyQuestStatus(uint32 quest_id) @@ -23246,6 +23243,11 @@ float Player::GetReputationPriceDiscount(Creature const* creature) const return 1.0f - 0.05f* (rank - REP_NEUTRAL); } +Player* Player::GetTrader() const +{ + return m_trade ? m_trade->GetTrader() : nullptr; +} + bool Player::IsSpellFitByClassAndRace(uint32 spell_id) const { uint32 racemask = getRaceMask(); @@ -23353,7 +23355,7 @@ void Player::UpdateForQuestWorldObjects() } } udata.BuildPacket(&packet); - GetSession()->SendPacket(&packet); + SendDirectMessage(&packet); } bool Player::HasSummonPending() const @@ -23381,7 +23383,7 @@ void Player::SendSummonRequestFrom(Unit* summoner) data << uint64(summoner->GetGUID()); // summoner guid data << uint32(summoner->GetZoneId()); // summoner zone data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILLISECONDS); // auto decline after msecs - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::SummonIfPossible(bool agree) @@ -23635,7 +23637,7 @@ bool Player::GetsRecruitAFriendBonus(bool forXP) bool recruitAFriend = false; if (getLevel() <= sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL) || !forXP) { - if (Group* group = this->GetGroup()) + if (Group* group = GetGroup()) { for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { @@ -23709,7 +23711,7 @@ bool Player::IsAtGroupRewardDistance(WorldObject const* pRewardSource) const if (!pRewardSource || !IsInMap(pRewardSource)) return false; - const WorldObject* player = GetCorpse(); + WorldObject const* player = GetCorpse(); if (!player || IsAlive()) player = this; @@ -23724,7 +23726,7 @@ bool Player::IsAtRecruitAFriendDistance(WorldObject const* pOther) const if (!pOther || !IsInMap(pOther)) return false; - const WorldObject* player = GetCorpse(); + WorldObject const* player = GetCorpse(); if (!player || IsAlive()) player = this; @@ -23796,7 +23798,7 @@ void Player::SetClientControl(Unit* target, bool allowMove) WorldPacket data(SMSG_CLIENT_CONTROL_UPDATE, target->GetPackGUID().size()+1); data << target->GetPackGUID(); data << uint8(allowMove ? 1 : 0); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); if (this != target) SetViewpoint(target, allowMove); @@ -23928,7 +23930,7 @@ void Player::SendCorpseReclaimDelay(uint32 delay) const { WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4); data << uint32(delay); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } Player* Player::GetNextRandomRaidMember(float radius) @@ -24182,7 +24184,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply) SetSeer(this); //WorldPacket data(SMSG_CLEAR_FAR_SIGHT_IMMEDIATE, 0); - //GetSession()->SendPacket(&data); + //SendDirectMessage(&data); } // HACK: Make sure update for PLAYER_FARSIGHT is received before SMSG_PET_SPELLS to properly hide "Release spirit" dialog @@ -24196,7 +24198,7 @@ void Player::SetViewpoint(WorldObject* target, bool apply) for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) { iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); + iter->first->SendDirectMessage(&packet); packet.clear(); } } @@ -24336,6 +24338,11 @@ bool Player::HasTitle(uint32 bitIndex) const return HasFlag(PLAYER__FIELD_KNOWN_TITLES + fieldIndexOffset, flag); } +bool Player::HasTitle(CharTitlesEntry const* title) const +{ + return HasTitle(title->bit_index); +} + void Player::SetTitle(CharTitlesEntry const* title, bool lost) { uint32 fieldIndexOffset = title->bit_index / 32; @@ -24359,7 +24366,7 @@ void Player::SetTitle(CharTitlesEntry const* title, bool lost) WorldPacket data(SMSG_TITLE_EARNED, 4 + 4); data << uint32(title->bit_index); data << uint32(lost ? 0 : 1); // 1 - earned, 0 - lost - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } uint32 Player::GetRuneBaseCooldown(uint8 index) @@ -24445,7 +24452,7 @@ void Player::ConvertRune(uint8 index, RuneType newType) WorldPacket data(SMSG_CONVERT_RUNE, 2); data << uint8(index); data << uint8(newType); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::ResyncRunes(uint8 count) const @@ -24457,14 +24464,14 @@ void Player::ResyncRunes(uint8 count) const data << uint8(GetCurrentRune(i)); // rune type data << uint8(255 - (GetRuneCooldown(i) * 51)); // passed cooldown time (0-255) } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::AddRunePower(uint8 index) const { WorldPacket data(SMSG_ADD_RUNE_POWER, 4); data << uint32(1 << index); // mask (0x00-0x3F probably) - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } static RuneType runeSlotTypes[MAX_RUNES] = @@ -24576,7 +24583,7 @@ void Player::StoreLootItem(uint8 lootSlot, Loot* loot) InventoryResult msg = CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, item->itemid, item->count); if (msg == EQUIP_ERR_OK) { - AllowedLooterSet looters = item->GetAllowedLooters(); + GuidSet looters = item->GetAllowedLooters(); Item* newitem = StoreNewItem(dest, item->itemid, true, item->randomPropertyId, looters); if (qitem) @@ -24935,7 +24942,7 @@ void Player::ResetAchievementCriteria(AchievementCriteriaCondition condition, ui m_achievementMgr->ResetAchievementCriteria(condition, value, evenIfCriteriaComplete); } -void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) +void Player::UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= nullptr*/) { m_achievementMgr->UpdateAchievementCriteria(type, miscValue1, miscValue2, unit); } @@ -25011,7 +25018,7 @@ void Player::LearnTalent(uint32 talentId, uint32 talentRank) uint32 tTab = talentInfo->TalentTab; if (talentInfo->Row > 0) for (uint32 i = 0; i < sTalentStore.GetNumRows(); i++) // Loop through all talents. - if (const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i)) // the way talents are tracked + if (TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i)) // the way talents are tracked if (tmpTalent->TalentTab == tTab) for (uint8 rank = 0; rank < MAX_TALENT_RANK; rank++) if (tmpTalent->RankID[rank] != 0) @@ -25135,7 +25142,7 @@ void Player::LearnPetTalent(ObjectGuid petGuid, uint32 talentId, uint32 talentRa for (uint32 i = 0; i < numRows; ++i) // Loop through all talents. { // Someday, someone needs to revamp - const TalentEntry* tmpTalent = sTalentStore.LookupEntry(i); + TalentEntry const* tmpTalent = sTalentStore.LookupEntry(i); if (tmpTalent) // the way talents are tracked { if (tmpTalent->TalentTab == tTab) @@ -25398,7 +25405,7 @@ void Player::SendTalentsInfoData(bool pet) BuildPetTalentsInfoData(&data); else BuildPlayerTalentsInfoData(&data); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::BuildEnchantmentsInfoData(WorldPacket* data) @@ -25447,123 +25454,112 @@ void Player::BuildEnchantmentsInfoData(WorldPacket* data) void Player::SendEquipmentSetList() { uint32 count = 0; - WorldPacket data(SMSG_EQUIPMENT_SET_LIST, 4); + WorldPacket data(SMSG_EQUIPMENT_SET_LIST, 1000); // guess size size_t count_pos = data.wpos(); data << uint32(count); // count placeholder - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr) + + for (EquipmentSetContainer::value_type const& eqSet : _equipmentSets) { - if (itr->second.state == EQUIPMENT_SET_DELETED) + if (eqSet.second.State == EQUIPMENT_SET_DELETED) continue; - data.appendPackGUID(itr->second.Guid); - data << uint32(itr->first); - data << itr->second.Name; - data << itr->second.IconName; + data.appendPackGUID(eqSet.first); + data << uint32(eqSet.second.Data.SetID); + data << eqSet.second.Data.SetName; + data << eqSet.second.Data.SetIcon; + for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { // ignored slots stored in IgnoreMask, client wants "1" as raw GUID, so no HighGuid::Item - if (itr->second.IgnoreMask & (1 << i)) + if (eqSet.second.Data.IgnoreMask & (1 << i)) data.appendPackGUID(uint64(1)); - else if (itr->second.Items[i] > 0) // send proper data (do not append 0 with high guid) - data << ObjectGuid(HighGuid::Item, 0, itr->second.Items[i]).WriteAsPacked(); else - data.appendPackGUID(uint64(0)); + data.appendPackGUID(eqSet.second.Data.Pieces[i]); } ++count; // client have limit but it checked at loading and set } data.put<uint32>(count_pos, count); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } -void Player::SetEquipmentSet(uint32 index, EquipmentSet eqset) +void Player::SetEquipmentSet(EquipmentSetInfo::EquipmentSetData const& eqSet) { - if (eqset.Guid != 0) + if (eqSet.Guid != 0) { - bool found = false; - - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr) - { - if ((itr->second.Guid == eqset.Guid) && (itr->first == index)) - { - found = true; - break; - } - } - - if (!found) // something wrong... + // something wrong... + auto itr = _equipmentSets.find(eqSet.Guid); + if (itr == _equipmentSets.end() || itr->second.Data.Guid != eqSet.Guid) { TC_LOG_ERROR("entities.player", "Player::SetEquipmentSet: Player '%s' (%s) tried to save nonexistent equipment set " UI64FMTD " (index: %u)", - GetName().c_str(), GetGUID().ToString().c_str(), eqset.Guid, index); + GetName().c_str(), GetGUID().ToString().c_str(), eqSet.Guid, eqSet.SetID); return; } } - EquipmentSet& eqslot = m_EquipmentSets[index]; - - EquipmentSetUpdateState old_state = eqslot.state; + EquipmentSetInfo& eqSlot = _equipmentSets[eqSet.Guid]; - eqslot = eqset; + EquipmentSetUpdateState oldState = eqSlot.State; + eqSlot.Data = eqSet; - if (eqset.Guid == 0) + if (eqSet.Guid == 0) { - eqslot.Guid = sObjectMgr->GenerateEquipmentSetGuid(); + eqSlot.Data.Guid = sObjectMgr->GenerateEquipmentSetGuid(); WorldPacket data(SMSG_EQUIPMENT_SET_SAVED, 4 + 1); - data << uint32(index); - data.appendPackGUID(eqslot.Guid); - GetSession()->SendPacket(&data); + data << uint32(eqSlot.Data.SetID); + data.appendPackGUID(eqSlot.Data.Guid); + SendDirectMessage(&data); } - eqslot.state = old_state == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED; + eqSlot.State = (oldState == EQUIPMENT_SET_NEW ? EQUIPMENT_SET_NEW : EQUIPMENT_SET_CHANGED); } void Player::_SaveEquipmentSets(SQLTransaction& trans) { - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end();) + for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();) { - uint32 index = itr->first; - EquipmentSet& eqset = itr->second; - PreparedStatement* stmt = nullptr; + EquipmentSetInfo& eqSet = itr->second; + PreparedStatement* stmt; uint8 j = 0; - switch (eqset.state) + switch (eqSet.State) { case EQUIPMENT_SET_UNCHANGED: ++itr; break; // nothing do case EQUIPMENT_SET_CHANGED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_EQUIP_SET); - stmt->setString(j++, eqset.Name.c_str()); - stmt->setString(j++, eqset.IconName.c_str()); - stmt->setUInt32(j++, eqset.IgnoreMask); - for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i) - stmt->setUInt32(j++, eqset.Items[i]); + stmt->setString(j++, eqSet.Data.SetName); + stmt->setString(j++, eqSet.Data.SetIcon); + stmt->setUInt32(j++, eqSet.Data.IgnoreMask); + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + stmt->setUInt32(j++, eqSet.Data.Pieces[i].GetCounter()); stmt->setUInt32(j++, GetGUID().GetCounter()); - stmt->setUInt64(j++, eqset.Guid); - stmt->setUInt32(j, index); + stmt->setUInt64(j++, eqSet.Data.Guid); + stmt->setUInt32(j, eqSet.Data.SetID); trans->Append(stmt); - eqset.state = EQUIPMENT_SET_UNCHANGED; + eqSet.State = EQUIPMENT_SET_UNCHANGED; ++itr; break; case EQUIPMENT_SET_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_EQUIP_SET); stmt->setUInt32(j++, GetGUID().GetCounter()); - stmt->setUInt64(j++, eqset.Guid); - stmt->setUInt32(j++, index); - stmt->setString(j++, eqset.Name.c_str()); - stmt->setString(j++, eqset.IconName.c_str()); - stmt->setUInt32(j++, eqset.IgnoreMask); - for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i) - stmt->setUInt32(j++, eqset.Items[i]); + stmt->setUInt64(j++, eqSet.Data.Guid); + stmt->setUInt32(j++, eqSet.Data.SetID); + stmt->setString(j++, eqSet.Data.SetName); + stmt->setString(j++, eqSet.Data.SetIcon); + stmt->setUInt32(j++, eqSet.Data.IgnoreMask); + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + stmt->setUInt32(j++, eqSet.Data.Pieces[i].GetCounter()); trans->Append(stmt); - eqset.state = EQUIPMENT_SET_UNCHANGED; + eqSet.State = EQUIPMENT_SET_UNCHANGED; ++itr; break; case EQUIPMENT_SET_DELETED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_EQUIP_SET); - stmt->setUInt64(0, eqset.Guid); + stmt->setUInt64(0, eqSet.Data.Guid); trans->Append(stmt); - m_EquipmentSets.erase(itr++); + itr = _equipmentSets.erase(itr); break; } } @@ -25592,16 +25588,17 @@ void Player::_SaveBGData(SQLTransaction& trans) void Player::DeleteEquipmentSet(uint64 setGuid) { - for (EquipmentSets::iterator itr = m_EquipmentSets.begin(); itr != m_EquipmentSets.end(); ++itr) + for (EquipmentSetContainer::iterator itr = _equipmentSets.begin(); itr != _equipmentSets.end();) { - if (itr->second.Guid == setGuid) + if (itr->second.Data.Guid == setGuid) { - if (itr->second.state == EQUIPMENT_SET_NEW) - m_EquipmentSets.erase(itr); + if (itr->second.State == EQUIPMENT_SET_NEW) + itr = _equipmentSets.erase(itr); else - itr->second.state = EQUIPMENT_SET_DELETED; + itr->second.State = EQUIPMENT_SET_DELETED; break; } + ++itr; } } @@ -25626,7 +25623,7 @@ void Player::ResetMap() // after decrement+unlink, ++m_mapRefIter will continue correctly // when the first element of the list is being removed // nocheck_prev will return the padding element of the RefManager - // instead of NULL in the case of prev + // instead of nullptr in the case of prev GetMap()->UpdateIteratorBack(this); Unit::ResetMap(); GetMapRef().unlink(); @@ -25698,7 +25695,7 @@ void Player::_LoadTalents(PreparedQueryResult result) void Player::_SaveTalents(SQLTransaction& trans) { - PreparedStatement* stmt = NULL; + PreparedStatement* stmt = nullptr; for (uint8 i = 0; i < MAX_TALENT_SPECS; ++i) { @@ -25824,7 +25821,7 @@ void Player::ActivateSpec(uint8 spec) if (GetPet()) GetPet()->RemoveAllAurasOnDeath();*/ - //RemoveAllAuras(GetGUID(), NULL, false, true); // removes too many auras + //RemoveAllAuras(GetGUID(), nullptr, false, true); // removes too many auras //ExitVehicle(); // should be impossible to switch specs from inside a vehicle.. // Let client clear his current Actions @@ -25854,7 +25851,7 @@ void Player::ActivateSpec(uint8 spec) if (talentInfo->RankID[rank] == 0) continue; RemoveSpell(talentInfo->RankID[rank], true); // removes the talent, and all dependant, learned, and chained spells.. - if (const SpellInfo* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank])) + if (SpellInfo const* _spellEntry = sSpellMgr->GetSpellInfo(talentInfo->RankID[rank])) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) // search through the SpellInfo for valid trigger spells if (_spellEntry->Effects[i].TriggerSpell > 0 && _spellEntry->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL) RemoveSpell(_spellEntry->Effects[i].TriggerSpell, true); // and remove any spells that the talent teaches @@ -25973,7 +25970,7 @@ void Player::SendTimeSync() { WorldPacket data(SMSG_TIME_SYNC_REQ, 4); data << uint32(m_timeSyncCounter++); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); // Schedule next sync in 10 sec m_timeSyncTimer = 10000; @@ -25998,7 +25995,7 @@ void Player::SendDuelCountdown(uint32 counter) { WorldPacket data(SMSG_DUEL_COUNTDOWN, 4); data << uint32(counter); // seconds - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } void Player::AddRefundReference(ObjectGuid it) @@ -26050,7 +26047,7 @@ void Player::SendRefundInfo(Item* item) } data << uint32(0); data << uint32(GetTotalPlayedTime() - item->GetPlayedTime()); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } bool Player::AddItem(uint32 itemId, uint32 count) @@ -26068,7 +26065,7 @@ bool Player::AddItem(uint32 itemId, uint32 count) return false; } - Item* item = StoreNewItem(dest, itemId, true, Item::GenerateItemRandomPropertyId(itemId)); + Item* item = StoreNewItem(dest, itemId, true, GenerateItemRandomPropertyId(itemId)); if (item) SendNewItem(item, count, true, false); else @@ -26090,7 +26087,7 @@ void Player::RefundItem(Item* item) WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4); data << uint64(item->GetGUID()); // Guid data << uint32(10); // Error! - GetSession()->SendPacket(&data); + SendDirectMessage(&data); return; } @@ -26131,7 +26128,7 @@ void Player::RefundItem(Item* item) WorldPacket data(SMSG_ITEM_REFUND_RESULT, 8+4); data << uint64(item->GetGUID()); // Guid data << uint32(10); // Error! - GetSession()->SendPacket(&data); + SendDirectMessage(&data); return; } @@ -26146,7 +26143,7 @@ void Player::RefundItem(Item* item) data << uint32(iece->reqitem[i]); data << uint32(iece->reqitemcount[i]); } - GetSession()->SendPacket(&data); + SendDirectMessage(&data); uint32 moneyRefund = item->GetPaidMoney(); // item-> will be invalidated in DestroyItem @@ -26443,7 +26440,7 @@ void Player::SetInGuild(uint32 guildId) Guild* Player::GetGuild() { uint32 guildId = GetGuildId(); - return guildId ? sGuildMgr->GetGuildById(guildId) : NULL; + return guildId ? sGuildMgr->GetGuildById(guildId) : nullptr; } Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 duration) @@ -26563,7 +26560,7 @@ void Player::SendSupercededSpell(uint32 oldSpell, uint32 newSpell) const { WorldPacket data(SMSG_SUPERCEDED_SPELL, 8); data << uint32(oldSpell) << uint32(newSpell); - GetSession()->SendPacket(&data); + SendDirectMessage(&data); } bool Player::ValidateAppearance(uint8 race, uint8 class_, uint8 gender, uint8 hairID, uint8 hairColor, uint8 faceID, uint8 facialHair, uint8 skinColor, bool create /*=false*/) diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 99e5f37ee7b..8120c4bc531 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -19,46 +19,63 @@ #ifndef _PLAYER_H #define _PLAYER_H -#include "DBCStores.h" +#include "Unit.h" +#include "DatabaseEnvFwd.h" +#include "DBCEnums.h" +#include "EquipmentSet.h" #include "GroupReference.h" +#include "ItemDefines.h" +#include "ItemEnchantmentMgr.h" #include "MapReference.h" - -#include "Item.h" #include "PetDefines.h" +#include "PlayerTaxi.h" #include "QuestDef.h" -#include "SpellMgr.h" -#include "SpellHistory.h" -#include "Unit.h" -#include "TradeData.h" -#include "CinematicMgr.h" - -#include <limits> -#include <string> -#include <vector> +#include <queue> +struct AccessRequirement; +struct AchievementEntry; +struct AreaTableEntry; +struct AreaTriggerEntry; +struct BarberShopStyleEntry; +struct CharacterCustomizeInfo; +struct CharTitlesEntry; +struct ChatChannelsEntry; struct CreatureTemplate; +struct FactionEntry; +struct ItemSetEffect; +struct ItemTemplate; +struct Loot; struct Mail; +struct ScalingStatValuesEntry; struct TrainerSpell; struct VendorItem; class AchievementMgr; -class ReputationMgr; +class Bag; +class Battleground; +class CinematicMgr; class Channel; class CharacterCreateInfo; class Creature; class DynamicObject; class Group; class Guild; +class Item; +class LootStore; class OutdoorPvP; class Pet; class PetAura; +class PlayerAI; class PlayerMenu; class PlayerSocial; +class ReputationMgr; class SpellCastTargets; -class UpdateMask; -class PlayerAI; +class TradeData; -struct CharacterCustomizeInfo; +enum InventoryType : uint8; +enum ItemClass : uint8; +enum LootError : uint8; +enum LootType : uint8; typedef std::deque<Mail*> PlayerMails; @@ -203,81 +220,6 @@ struct ActionButton typedef std::map<uint8, ActionButton> ActionButtonList; -struct PlayerCreateInfoItem -{ - PlayerCreateInfoItem(uint32 id, uint32 amount) : item_id(id), item_amount(amount) { } - - uint32 item_id; - uint32 item_amount; -}; - -typedef std::list<PlayerCreateInfoItem> PlayerCreateInfoItems; - -struct PlayerClassLevelInfo -{ - PlayerClassLevelInfo() : basehealth(0), basemana(0) { } - uint16 basehealth; - uint16 basemana; -}; - -struct PlayerClassInfo -{ - PlayerClassInfo() : levelInfo(NULL) { } - - PlayerClassLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1 -}; - -struct PlayerLevelInfo -{ - PlayerLevelInfo() { for (uint8 i=0; i < MAX_STATS; ++i) stats[i] = 0; } - - uint8 stats[MAX_STATS]; -}; - -typedef std::list<uint32> PlayerCreateInfoSpells; - -struct PlayerCreateInfoAction -{ - PlayerCreateInfoAction() : button(0), type(0), action(0) { } - PlayerCreateInfoAction(uint8 _button, uint32 _action, uint8 _type) : button(_button), type(_type), action(_action) { } - - uint8 button; - uint8 type; - uint32 action; -}; - -typedef std::list<PlayerCreateInfoAction> PlayerCreateInfoActions; - -struct PlayerCreateInfoSkill -{ - uint16 SkillId; - uint16 Rank; -}; - -typedef std::list<PlayerCreateInfoSkill> PlayerCreateInfoSkills; - -struct PlayerInfo -{ - // existence checked by displayId != 0 - PlayerInfo() : mapId(0), areaId(0), positionX(0.0f), positionY(0.0f), positionZ(0.0f), orientation(0.0f), displayId_m(0), displayId_f(0), levelInfo(nullptr) { } - - uint32 mapId; - uint32 areaId; - float positionX; - float positionY; - float positionZ; - float orientation; - uint16 displayId_m; - uint16 displayId_f; - PlayerCreateInfoItems item; - PlayerCreateInfoSpells customSpells; - PlayerCreateInfoSpells castSpells; - PlayerCreateInfoActions action; - PlayerCreateInfoSkills skills; - - PlayerLevelInfo* levelInfo; //[level-1] 0..MaxPlayerLevel-1 -}; - struct PvPInfo { PvPInfo() : IsHostile(false), IsInHostileArea(false), IsInNoPvPArea(false), IsInFFAPvPArea(false), EndTimer(0) { } @@ -655,34 +597,6 @@ enum CurrencyTokenSlots // 32 slots CURRENCYTOKEN_SLOT_END = 150 }; -enum EquipmentSetUpdateState -{ - EQUIPMENT_SET_UNCHANGED = 0, - EQUIPMENT_SET_CHANGED = 1, - EQUIPMENT_SET_NEW = 2, - EQUIPMENT_SET_DELETED = 3 -}; - -struct EquipmentSet -{ - EquipmentSet() : Guid(0), IgnoreMask(0), state(EQUIPMENT_SET_NEW) - { - for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) - Items[i] = 0; - } - - uint64 Guid; - std::string Name; - std::string IconName; - uint32 IgnoreMask; - uint32 Items[EQUIPMENT_SLOT_END]; - EquipmentSetUpdateState state; -}; - -#define MAX_EQUIPMENT_SET_INDEX 10 // client limit - -typedef std::map<uint32, EquipmentSet> EquipmentSets; - struct ItemPosCount { ItemPosCount(uint16 _pos, uint32 _count) : pos(_pos), count(_count) { } @@ -862,19 +776,6 @@ struct InstancePlayerBind InstancePlayerBind() : save(nullptr), perm(false), extendState(EXTEND_STATE_NORMAL) { } }; -struct AccessRequirement -{ - uint8 levelMin; - uint8 levelMax; - uint16 item_level; - uint32 item; - uint32 item2; - uint32 quest_A; - uint32 quest_H; - uint32 achievement; - std::string questFailedText; -}; - enum CharDeleteMethod { CHAR_DELETE_REMOVE = 0, // Completely remove from the database @@ -923,61 +824,6 @@ enum PlayerCommandStates CHEAT_WATERWALK = 0x10 }; -class TC_GAME_API PlayerTaxi -{ - public: - PlayerTaxi(); - ~PlayerTaxi() { } - // Nodes - void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level); - void LoadTaxiMask(std::string const& data); - - bool IsTaximaskNodeKnown(uint32 nodeidx) const - { - uint8 field = uint8((nodeidx - 1) / 32); - uint32 submask = 1 << ((nodeidx-1) % 32); - return (m_taximask[field] & submask) == submask; - } - bool SetTaximaskNode(uint32 nodeidx) - { - uint8 field = uint8((nodeidx - 1) / 32); - uint32 submask = 1 << ((nodeidx - 1) % 32); - if ((m_taximask[field] & submask) != submask) - { - m_taximask[field] |= submask; - return true; - } - else - return false; - } - void AppendTaximaskTo(ByteBuffer& data, bool all); - - // Destinations - bool LoadTaxiDestinationsFromString(std::string const& values, uint32 team); - std::string SaveTaxiDestinationsToString(); - - void ClearTaxiDestinations() { m_TaxiDestinations.clear(); } - void AddTaxiDestination(uint32 dest) { m_TaxiDestinations.push_back(dest); } - uint32 GetTaxiSource() const { return m_TaxiDestinations.empty() ? 0 : m_TaxiDestinations.front(); } - uint32 GetTaxiDestination() const { return m_TaxiDestinations.size() < 2 ? 0 : m_TaxiDestinations[1]; } - uint32 GetCurrentTaxiPath() const; - uint32 NextTaxiDestination() - { - m_TaxiDestinations.pop_front(); - return GetTaxiDestination(); - } - - std::deque<uint32> const& GetPath() const { return m_TaxiDestinations; } - bool empty() const { return m_TaxiDestinations.empty(); } - - friend std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi); - private: - TaxiMask m_taximask; - std::deque<uint32> m_TaxiDestinations; -}; - -std::ostringstream& operator << (std::ostringstream& ss, PlayerTaxi const& taxi); - class Player; /// Holder for Battleground data @@ -1033,8 +879,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> { friend class WorldSession; friend class CinematicMgr; - friend void Item::AddToUpdateQueueOf(Player* player); - friend void Item::RemoveFromUpdateQueueOf(Player* player); + friend void AddItemToUpdateQueueOf(Item* item, Player* player); + friend void RemoveItemFromUpdateQueueOf(Item* item, Player* player); public: explicit Player(WorldSession* session); ~Player(); @@ -1046,15 +892,10 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void AddToWorld() override; void RemoveFromWorld() override; - void SetObjectScale(float scale) override - { - Unit::SetObjectScale(scale); - SetFloatValue(UNIT_FIELD_BOUNDINGRADIUS, scale * DEFAULT_PLAYER_BOUNDING_RADIUS); - SetFloatValue(UNIT_FIELD_COMBATREACH, scale * DEFAULT_PLAYER_COMBAT_REACH); - } + void SetObjectScale(float scale) override; bool TeleportTo(uint32 mapid, float x, float y, float z, float orientation, uint32 options = 0); - bool TeleportTo(WorldLocation const &loc, uint32 options = 0); + bool TeleportTo(WorldLocation const& loc, uint32 options = 0); bool TeleportToBGEntryPoint(); bool HasSummonPending() const; @@ -1074,7 +915,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool IsInWater() const override { return m_isInWater; } bool IsUnderWater() const override; bool IsFalling() { return GetPositionZ() < m_lastFallZ; } - bool IsInAreaTriggerRadius(const AreaTriggerEntry* trigger) const; + bool IsInAreaTriggerRadius(AreaTriggerEntry const* trigger) const; void SendInitialPacketsBeforeAddToMap(); void SendInitialPacketsAfterAddToMap(); @@ -1209,8 +1050,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool HasItemOrGemWithIdEquipped(uint32 item, uint32 count, uint8 except_slot = NULL_SLOT) const; bool HasItemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const; bool HasGemWithLimitCategoryEquipped(uint32 limitCategory, uint32 count, uint8 except_slot = NULL_SLOT) const; - InventoryResult CanTakeMoreSimilarItems(Item* pItem, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(pItem->GetEntry(), pItem->GetCount(), pItem, NULL, itemLimitCategory); } - InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitCategory = NULL) const { return CanTakeMoreSimilarItems(entry, count, NULL, NULL, itemLimitCategory); } + InventoryResult CanTakeMoreSimilarItems(Item* pItem, uint32* itemLimitCategory = nullptr) const; + InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, uint32* itemLimitCategory = nullptr) const { return CanTakeMoreSimilarItems(entry, count, nullptr, nullptr, itemLimitCategory); } InventoryResult CanStoreNewItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 item, uint32 count, uint32* no_space_count = nullptr) const; InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, Item* pItem, bool swap = false) const; InventoryResult CanStoreItems(Item** items, int count, uint32* itemLimitCategory) const; @@ -1227,7 +1068,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> InventoryResult CanUseItem(ItemTemplate const* pItem) const; InventoryResult CanUseAmmo(uint32 item) const; InventoryResult CanRollForItemInLFG(ItemTemplate const* item, WorldObject const* lootedObject) const; - Item* StoreNewItem(ItemPosCountVec const& pos, uint32 item, bool update, int32 randomPropertyId = 0, AllowedLooterSet const& allowedLooters = AllowedLooterSet()); + Item* StoreNewItem(ItemPosCountVec const& pos, uint32 item, bool update, int32 randomPropertyId = 0, GuidSet const& allowedLooters = GuidSet()); Item* StoreItem(ItemPosCountVec const& pos, Item* pItem, bool update); Item* EquipNewItem(uint16 pos, uint32 item, bool update); Item* EquipItem(uint16 pos, Item* pItem, bool update); @@ -1237,7 +1078,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void AutoStoreLoot(uint32 loot_id, LootStore const& store, bool broadcast = false) { AutoStoreLoot(NULL_BAG, NULL_SLOT, loot_id, store, broadcast); } void StoreLootItem(uint8 lootSlot, Loot* loot); - InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL, uint32* itemLimitCategory = NULL) const; + InventoryResult CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = nullptr, uint32* itemLimitCategory = nullptr) const; InventoryResult CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item* pItem = nullptr, bool swap = false, uint32* no_space_count = nullptr) const; void AddRefundReference(ObjectGuid it); @@ -1247,7 +1088,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetAmmo(uint32 item); void RemoveAmmo(); float GetAmmoDPS() const { return m_ammoDPS; } - bool CheckAmmoCompatibility(const ItemTemplate* ammo_proto) const; + bool CheckAmmoCompatibility(ItemTemplate const* ammo_proto) const; void QuickEquipItem(uint16 pos, Item* pItem); void VisualizeItem(uint8 slot, Item* pItem); void SetVisibleItemSlot(uint8 slot, Item* pItem); @@ -1285,7 +1126,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> float GetReputationPriceDiscount(Creature const* creature) const; - Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : nullptr; } + Player* GetTrader() const; TradeData* GetTradeData() const { return m_trade; } void TradeCancel(bool sendback); @@ -1616,8 +1457,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void AddSpellMod(SpellModifier* mod, bool apply); static bool IsAffectedBySpellmod(SpellInfo const* spellInfo, SpellModifier* mod, Spell* spell = nullptr); - template <SpellModOp op, class T> - void ApplySpellMod(uint32 spellId, T& basevalue, Spell* spell = nullptr) const; + template <class T> + void ApplySpellMod(uint32 spellId, SpellModOp op, T& basevalue, Spell* spell = nullptr) const; static void ApplyModToSpell(SpellModifier* mod, Spell* spell); static bool HasSpellModApplied(SpellModifier* mod, Spell* spell); void SetSpellModTakingSpell(Spell* spell, bool apply); @@ -1659,7 +1500,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> PvPInfo pvpInfo; void UpdatePvPState(bool onlyFFA = false); void SetPvP(bool state) override; - void UpdatePvP(bool state, bool override=false); + void UpdatePvP(bool state, bool override = false); void UpdateZone(uint32 newZone, uint32 newArea); void UpdateArea(uint32 newArea); void SetNeedsZoneUpdate(bool needsUpdate) { m_needsZoneUpdate = needsUpdate; } @@ -1684,7 +1525,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool IsInSameGroupWith(Player const* p) const; bool IsInSameRaidWith(Player const* p) const; void UninviteFromGroup(); - static void RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = nullptr); + static void RemoveFromGroup(Group* group, ObjectGuid guid, RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, char const* reason = nullptr); void RemoveFromGroup(RemoveMethod method = GROUP_REMOVEMETHOD_DEFAULT) { RemoveFromGroup(GetGroup(), GetGUID(), method); } void SendUpdateToOutOfRangeGroupMembers(); @@ -1712,7 +1553,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> Difficulty GetStoredRaidDifficulty() const { return m_raidMapDifficulty; } // only for use in difficulty packet after exiting to raid map void SetDungeonDifficulty(Difficulty dungeon_difficulty) { m_dungeonDifficulty = dungeon_difficulty; } void SetRaidDifficulty(Difficulty raid_difficulty) { m_raidDifficulty = raid_difficulty; } - void StoreRaidMapDifficulty() { m_raidMapDifficulty = GetMap()->GetDifficulty(); } + void StoreRaidMapDifficulty(); bool UpdateSkill(uint32 skill_id, uint32 step); bool UpdateSkillPro(uint16 SkillId, int32 Chance, uint32 step); @@ -1809,7 +1650,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SendResetFailedNotify(uint32 mapid) const; bool UpdatePosition(float x, float y, float z, float orientation, bool teleport = false) override; - bool UpdatePosition(const Position &pos, bool teleport = false) override { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } + bool UpdatePosition(Position const& pos, bool teleport = false) override { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } void ProcessTerrainStatusUpdate(ZLiquidStatus status, Optional<LiquidData> const& liquidData) override; void SendMessageToSet(WorldPacket const* data, bool self) override { SendMessageToSetInRange(data, GetVisibilityRange(), self); } @@ -2002,7 +1843,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void CastItemUseSpell(Item* item, SpellCastTargets const& targets, uint8 cast_count, uint32 glyphIndex); void SendEquipmentSetList(); - void SetEquipmentSet(uint32 index, EquipmentSet eqset); + void SetEquipmentSet(EquipmentSetInfo::EquipmentSetData const& eqset); void DeleteEquipmentSet(uint64 setGuid); void SendInitWorldStates(uint32 zone, uint32 area); @@ -2236,7 +2077,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void SetMap(Map* map) override; void ResetMap() override; - bool isAllowedToLoot(const Creature* creature); + bool isAllowedToLoot(Creature const* creature); DeclinedName const* GetDeclinedNames() const { return m_declinedname; } uint8 GetRunesState() const { return m_runes->runeState; } @@ -2263,13 +2104,13 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> bool HasAchieved(uint32 achievementId) const; void ResetAchievements(); void ResetAchievementCriteria(AchievementCriteriaCondition condition, uint32 value, bool evenIfCriteriaComplete = false); - void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); + void UpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = nullptr); void StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry, uint32 timeLost = 0); void RemoveTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); void CompletedAchievement(AchievementEntry const* entry); bool HasTitle(uint32 bitIndex) const; - bool HasTitle(CharTitlesEntry const* title) const { return HasTitle(title->bit_index); } + bool HasTitle(CharTitlesEntry const* title) const; void SetTitle(CharTitlesEntry const* title, bool lost = false); //bool isActiveObject() const { return true; } @@ -2545,7 +2386,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> DeclinedName *m_declinedname; Runes *m_runes; - EquipmentSets m_EquipmentSets; + EquipmentSetContainer _equipmentSets; bool CanAlwaysSee(WorldObject const* obj) const override; @@ -2638,115 +2479,4 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> TC_GAME_API void AddItemsSetItem(Player* player, Item* item); TC_GAME_API void RemoveItemsSetItem(Player* player, ItemTemplate const* proto); -// "the bodies of template functions must be made available in a header file" -template <SpellModOp op, class T> -void Player::ApplySpellMod(uint32 spellId, T& basevalue, Spell* spell /*= nullptr*/) const -{ - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); - if (!spellInfo) - return; - - float totalmul = 1.0f; - int32 totalflat = 0; - - // Drop charges for triggering spells instead of triggered ones - if (m_spellModTakingSpell) - spell = m_spellModTakingSpell; - - switch (op) - { - // special case, if a mod makes spell instant, only consume that mod - case SPELLMOD_CASTING_TIME: - { - SpellModifier* modInstantSpell = nullptr; - for (SpellModifier* mod : m_spellMods[op]) - { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - continue; - - if (mod->type == SPELLMOD_PCT && basevalue < T(10000) && mod->value <= -100) - { - modInstantSpell = mod; - break; - } - } - - if (modInstantSpell) - { - Player::ApplyModToSpell(modInstantSpell, spell); - basevalue = T(0); - return; - } - break; - } - // special case if two mods apply 100% critical chance, only consume one - case SPELLMOD_CRITICAL_CHANCE: - { - SpellModifier* modCritical = nullptr; - for (SpellModifier* mod : m_spellMods[op]) - { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - continue; - - if (mod->type == SPELLMOD_FLAT && mod->value >= 100) - { - modCritical = mod; - break; - } - } - - if (modCritical) - { - Player::ApplyModToSpell(modCritical, spell); - basevalue = T(100); - return; - } - break; - } - default: - break; - } - - for (SpellModifier* mod : m_spellMods[op]) - { - if (!IsAffectedBySpellmod(spellInfo, mod, spell)) - continue; - - switch (mod->type) - { - case SPELLMOD_FLAT: - totalflat += mod->value; - break; - case SPELLMOD_PCT: - { - // skip percent mods with null basevalue (most important for spell mods with charges) - if (basevalue == T(0)) - continue; - - // special case (skip > 10sec spell casts for instant cast setting) - if (op == SPELLMOD_CASTING_TIME && mod->value <= -100 && basevalue >= T(10000)) - continue; - else if (!Player::HasSpellModApplied(mod, spell)) - { - // special case for Surge of Light, don't apply critical chance reduction if other mods not applied (ie procs while casting another spell) - // (Surge of Light is the only PCT_MOD on critical chance) - if (op == SPELLMOD_CRITICAL_CHANCE) - continue; - // special case for Backdraft, dont' apply GCD reduction if cast time reduction wasn't applied (ie when Backlash is consumed first) - // (Backdraft is the only PCT_MOD on global cooldown) - else if (op == SPELLMOD_GLOBAL_COOLDOWN) - continue; - } - - totalmul += CalculatePct(1.0f, mod->value); - break; - } - } - - Player::ApplyModToSpell(mod, spell); - } - - basevalue = T(float(basevalue + totalflat) * totalmul); -} - #endif diff --git a/src/server/game/Entities/Player/PlayerTaxi.cpp b/src/server/game/Entities/Player/PlayerTaxi.cpp new file mode 100644 index 00000000000..9a53838e4a9 --- /dev/null +++ b/src/server/game/Entities/Player/PlayerTaxi.cpp @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "PlayerTaxi.h" +#include "DBCStores.h" +#include "ObjectMgr.h" +#include "Player.h" +#include <sstream> + +void PlayerTaxi::InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level) +{ + // class specific initial known nodes + switch (chrClass) + { + case CLASS_DEATH_KNIGHT: + { + for (uint8 i = 0; i < TaxiMaskSize; ++i) + m_taximask[i] |= sOldContinentsNodesMask[i]; + break; + } + } + + // race specific initial known nodes: capital and taxi hub masks + switch (race) + { + case RACE_HUMAN: SetTaximaskNode(2); break; // Human + case RACE_ORC: SetTaximaskNode(23); break; // Orc + case RACE_DWARF: SetTaximaskNode(6); break; // Dwarf + case RACE_NIGHTELF: SetTaximaskNode(26); + SetTaximaskNode(27); break; // Night Elf + case RACE_UNDEAD_PLAYER: SetTaximaskNode(11); break;// Undead + case RACE_TAUREN: SetTaximaskNode(22); break; // Tauren + case RACE_GNOME: SetTaximaskNode(6); break; // Gnome + case RACE_TROLL: SetTaximaskNode(23); break; // Troll + case RACE_BLOODELF: SetTaximaskNode(82); break; // Blood Elf + case RACE_DRAENEI: SetTaximaskNode(94); break; // Draenei + } + + // new continent starting masks (It will be accessible only at new map) + switch (Player::TeamForRace(race)) + { + case ALLIANCE: SetTaximaskNode(100); break; + case HORDE: SetTaximaskNode(99); break; + } + // level dependent taxi hubs + if (level >= 68) + SetTaximaskNode(213); //Shattered Sun Staging Area +} + +void PlayerTaxi::LoadTaxiMask(std::string const& data) +{ + Tokenizer tokens(data, ' '); + + uint8 index = 0; + for (Tokenizer::const_iterator iter = tokens.begin(); index < TaxiMaskSize && iter != tokens.end(); ++iter, ++index) + { + // load and set bits only for existing taxi nodes + m_taximask[index] = sTaxiNodesMask[index] & atoul(*iter); + } +} + +void PlayerTaxi::AppendTaximaskTo(ByteBuffer& data, bool all) +{ + if (all) + { + for (uint8 i = 0; i < TaxiMaskSize; ++i) + data << uint32(sTaxiNodesMask[i]); // all existing nodes + } + else + { + for (uint8 i = 0; i < TaxiMaskSize; ++i) + data << uint32(m_taximask[i]); // known nodes + } +} + +bool PlayerTaxi::LoadTaxiDestinationsFromString(const std::string& values, uint32 team) +{ + ClearTaxiDestinations(); + + Tokenizer Tokenizer(values, ' '); + + for (Tokenizer::const_iterator iter = Tokenizer.begin(); iter != Tokenizer.end(); ++iter) + { + uint32 node = atoul(*iter); + AddTaxiDestination(node); + } + + if (m_TaxiDestinations.empty()) + return true; + + // Check integrity + if (m_TaxiDestinations.size() < 2) + return false; + + for (size_t i = 1; i < m_TaxiDestinations.size(); ++i) + { + uint32 cost; + uint32 path; + sObjectMgr->GetTaxiPath(m_TaxiDestinations[i - 1], m_TaxiDestinations[i], path, cost); + if (!path) + return false; + } + + // can't load taxi path without mount set (quest taxi path?) + if (!sObjectMgr->GetTaxiMountDisplayId(GetTaxiSource(), team, true)) + return false; + + return true; +} + +std::string PlayerTaxi::SaveTaxiDestinationsToString() +{ + if (m_TaxiDestinations.empty()) + return ""; + + std::ostringstream ss; + + for (size_t i = 0; i < m_TaxiDestinations.size(); ++i) + ss << m_TaxiDestinations[i] << ' '; + + return ss.str(); +} + +uint32 PlayerTaxi::GetCurrentTaxiPath() const +{ + if (m_TaxiDestinations.size() < 2) + return 0; + + uint32 path; + uint32 cost; + + sObjectMgr->GetTaxiPath(m_TaxiDestinations[0], m_TaxiDestinations[1], path, cost); + + return path; +} + +std::ostringstream& operator<<(std::ostringstream& ss, PlayerTaxi const& taxi) +{ + for (uint8 i = 0; i < TaxiMaskSize; ++i) + ss << taxi.m_taximask[i] << ' '; + return ss; +} diff --git a/src/server/game/Entities/Player/PlayerTaxi.h b/src/server/game/Entities/Player/PlayerTaxi.h new file mode 100644 index 00000000000..ae5052b3e7a --- /dev/null +++ b/src/server/game/Entities/Player/PlayerTaxi.h @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef PlayerTaxi_h__ +#define PlayerTaxi_h__ + +#include "DBCEnums.h" +#include "Define.h" +#include <deque> +#include <iosfwd> + +class ByteBuffer; + +class TC_GAME_API PlayerTaxi +{ + public: + PlayerTaxi() { m_taximask.fill(0); } + ~PlayerTaxi() { } + // Nodes + void InitTaxiNodesForLevel(uint32 race, uint32 chrClass, uint8 level); + void LoadTaxiMask(std::string const& data); + + bool IsTaximaskNodeKnown(uint32 nodeidx) const + { + uint8 field = uint8((nodeidx - 1) / 32); + uint32 submask = 1 << ((nodeidx-1) % 32); + return (m_taximask[field] & submask) == submask; + } + bool SetTaximaskNode(uint32 nodeidx) + { + uint8 field = uint8((nodeidx - 1) / 32); + uint32 submask = 1 << ((nodeidx - 1) % 32); + if ((m_taximask[field] & submask) != submask) + { + m_taximask[field] |= submask; + return true; + } + else + return false; + } + void AppendTaximaskTo(ByteBuffer& data, bool all); + + // Destinations + bool LoadTaxiDestinationsFromString(std::string const& values, uint32 team); + std::string SaveTaxiDestinationsToString(); + + void ClearTaxiDestinations() { m_TaxiDestinations.clear(); } + void AddTaxiDestination(uint32 dest) { m_TaxiDestinations.push_back(dest); } + uint32 GetTaxiSource() const { return m_TaxiDestinations.empty() ? 0 : m_TaxiDestinations.front(); } + uint32 GetTaxiDestination() const { return m_TaxiDestinations.size() < 2 ? 0 : m_TaxiDestinations[1]; } + uint32 GetCurrentTaxiPath() const; + uint32 NextTaxiDestination() + { + m_TaxiDestinations.pop_front(); + return GetTaxiDestination(); + } + + std::deque<uint32> const& GetPath() const { return m_TaxiDestinations; } + bool empty() const { return m_TaxiDestinations.empty(); } + + friend std::ostringstream& operator<<(std::ostringstream& ss, PlayerTaxi const& taxi); + private: + TaxiMask m_taximask; + std::deque<uint32> m_TaxiDestinations; +}; + +std::ostringstream& operator<<(std::ostringstream& ss, PlayerTaxi const& taxi); + +#endif // PlayerTaxi_h__ diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index d3638c36029..6c9cdd67287 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -17,12 +17,13 @@ */ #include "SocialMgr.h" -#include "WorldSession.h" -#include "WorldPacket.h" #include "DatabaseEnv.h" #include "ObjectAccessor.h" #include "Player.h" +#include "RBAC.h" #include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" PlayerSocial::PlayerSocial(): _playerGUID() { } diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index b8482ecc9f0..343675eae9d 100644 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -19,9 +19,10 @@ #ifndef __TRINITY_SOCIALMGR_H #define __TRINITY_SOCIALMGR_H -#include "DatabaseEnv.h" +#include "DatabaseEnvFwd.h" #include "Common.h" #include "ObjectGuid.h" +#include <map> class Player; class WorldPacket; diff --git a/src/server/game/Entities/Player/TradeData.cpp b/src/server/game/Entities/Player/TradeData.cpp index c36173a6b41..83f33b3537e 100644 --- a/src/server/game/Entities/Player/TradeData.cpp +++ b/src/server/game/Entities/Player/TradeData.cpp @@ -16,6 +16,7 @@ */ #include "TradeData.h" +#include "Item.h" #include "Player.h" #include "WorldSession.h" diff --git a/src/server/game/Entities/Totem/Totem.cpp b/src/server/game/Entities/Totem/Totem.cpp index 74acba5c0a9..7d956ebd8af 100644 --- a/src/server/game/Entities/Totem/Totem.cpp +++ b/src/server/game/Entities/Totem/Totem.cpp @@ -133,7 +133,7 @@ void Totem::UnSummon(uint32 msTime) if (Group* group = owner->GetGroup()) { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* target = itr->GetSource(); if (target && target->IsInMap(owner) && group->SameSubGroup(owner, target)) diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index a7e89f9aac0..6d36095ee7d 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -16,21 +16,25 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" #include "Transport.h" +#include "Cell.h" +#include "CellImpl.h" +#include "Common.h" +#include "DBCStores.h" +#include "GameObjectAI.h" +#include "Log.h" #include "MapManager.h" #include "ObjectMgr.h" #include "ScriptMgr.h" -#include "DBCStores.h" -#include "GameObjectAI.h" -#include "Vehicle.h" +#include "Spline.h" #include "Player.h" -#include "Cell.h" -#include "CellImpl.h" #include "Totem.h" +#include "UpdateData.h" +#include "Vehicle.h" +#include <G3D/Vector3.h> Transport::Transport() : GameObject(), - _transportInfo(NULL), _isMoving(true), _pendingStop(false), + _transportInfo(nullptr), _isMoving(true), _pendingStop(false), _triggeredArrivalEvent(false), _triggeredDepartureEvent(false), _passengerTeleportItr(_passengers.begin()), _delayedAddModel(false), _delayedTeleport(false) { @@ -96,8 +100,8 @@ bool Transport::Create(ObjectGuid::LowType guidlow, uint32 entry, uint32 mapid, SetGoType(GAMEOBJECT_TYPE_MO_TRANSPORT); SetGoAnimProgress(animprogress); SetName(goinfo->name); - SetWorldRotation(G3D::Quat()); - SetParentRotation(G3D::Quat()); + SetWorldRotation(0.0f, 0.0f, 0.0f, 1.0f); + SetParentRotation(QuaternionData()); m_model = CreateModel(); return true; @@ -280,7 +284,7 @@ void Transport::RemovePassenger(WorldObject* passenger) if (erased || _staticPassengers.erase(passenger)) // static passenger can remove itself in case of grid unload { - passenger->SetTransport(NULL); + passenger->SetTransport(nullptr); passenger->m_movementInfo.RemoveMovementFlag(MOVEMENTFLAG_ONTRANSPORT); passenger->m_movementInfo.transport.Reset(); TC_LOG_DEBUG("entities.transport", "Object %s removed from transport %s.", passenger->GetName().c_str(), GetName().c_str()); @@ -301,7 +305,7 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c if (!creature->LoadCreatureFromDB(guid, map, false)) { delete creature; - return NULL; + return nullptr; } float x = data->posX; @@ -326,13 +330,13 @@ Creature* Transport::CreateNPCPassenger(ObjectGuid::LowType guid, CreatureData c { TC_LOG_ERROR("entities.transport", "Creature (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)",creature->GetGUID().GetCounter(),creature->GetEntry(),creature->GetPositionX(),creature->GetPositionY()); delete creature; - return NULL; + return nullptr; } if (!map->AddToMap(creature)) { delete creature; - return NULL; + return nullptr; } _staticPassengers.insert(creature); @@ -348,7 +352,7 @@ GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectDat if (!go->LoadGameObjectFromDB(guid, map, false)) { delete go; - return NULL; + return nullptr; } ASSERT(data); @@ -369,24 +373,24 @@ GameObject* Transport::CreateGOPassenger(ObjectGuid::LowType guid, GameObjectDat { TC_LOG_ERROR("entities.transport", "GameObject (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUID().GetCounter(), go->GetEntry(), go->GetPositionX(), go->GetPositionY()); delete go; - return NULL; + return nullptr; } if (!map->AddToMap(go)) { delete go; - return NULL; + return nullptr; } _staticPassengers.insert(go); return go; } -TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= NULL*/, uint32 duration /*= 0*/, Unit* summoner /*= NULL*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) +TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties /*= nullptr*/, uint32 duration /*= 0*/, Unit* summoner /*= nullptr*/, uint32 spellId /*= 0*/, uint32 vehId /*= 0*/) { Map* map = FindMap(); if (!map) - return NULL; + return nullptr; uint32 mask = UNIT_MASK_SUMMON; if (properties) @@ -432,7 +436,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu break; } default: - return NULL; + return nullptr; } } @@ -440,7 +444,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu if (summoner) phase = summoner->GetPhaseMask(); - TempSummon* summon = NULL; + TempSummon* summon = nullptr; switch (mask) { case UNIT_MASK_SUMMON: @@ -467,7 +471,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu if (!summon->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, phase, entry, x, y, z, o, nullptr, vehId)) { delete summon; - return NULL; + return nullptr; } summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); @@ -489,7 +493,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu if (!map->AddToMap<Creature>(summon)) { delete summon; - return NULL; + return nullptr; } _staticPassengers.insert(summon); diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 5dd77f3df90..757a493f673 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -66,16 +66,16 @@ class TC_GAME_API Transport : public GameObject, public TransportBase * * @return Summoned creature. */ - TempSummon* SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); + TempSummon* SummonPassenger(uint32 entry, Position const& pos, TempSummonType summonType, SummonPropertiesEntry const* properties = nullptr, uint32 duration = 0, Unit* summoner = nullptr, uint32 spellId = 0, uint32 vehId = 0); /// This method transforms supplied transport offsets into global coordinates - void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const override + void CalculatePassengerPosition(float& x, float& y, float& z, float* o = nullptr) const override { TransportBase::CalculatePassengerPosition(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); } /// This method transforms supplied global coordinates into local offsets - void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const override + void CalculatePassengerOffset(float& x, float& y, float& z, float* o = nullptr) const override { TransportBase::CalculatePassengerOffset(x, y, z, o, GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); } diff --git a/src/server/game/Entities/Unit/StatSystem.cpp b/src/server/game/Entities/Unit/StatSystem.cpp index 436740c6fe1..cf61198ddd9 100644 --- a/src/server/game/Entities/Unit/StatSystem.cpp +++ b/src/server/game/Entities/Unit/StatSystem.cpp @@ -17,13 +17,16 @@ */ #include "Unit.h" -#include "Player.h" -#include "Pet.h" #include "Creature.h" +#include "Item.h" +#include "Pet.h" +#include "Player.h" #include "SharedDefines.h" #include "SpellAuras.h" #include "SpellAuraEffects.h" +#include "SpellMgr.h" #include "World.h" +#include <numeric> inline bool _ModifyUInt32(bool apply, uint32& baseValue, int32& amount) { diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index bb08b9bc862..941ad019396 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -17,26 +17,29 @@ */ #include "Unit.h" -#include "CharacterCache.h" -#include "Common.h" #include "Battlefield.h" #include "BattlefieldMgr.h" #include "Battleground.h" #include "BattlegroundScore.h" #include "CellImpl.h" +#include "CharacterCache.h" +#include "Chat.h" #include "ChatTextBuilder.h" +#include "Common.h" #include "ConditionMgr.h" #include "CreatureAI.h" #include "CreatureAIImpl.h" #include "CreatureGroups.h" -#include "Creature.h" #include "Formulas.h" #include "GameTime.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "InstanceSaveMgr.h" #include "InstanceScript.h" +#include "Item.h" #include "Log.h" +#include "LootMgr.h" +#include "MotionMaster.h" #include "MoveSpline.h" #include "MoveSplineInit.h" #include "ObjectAccessor.h" @@ -65,7 +68,6 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" - #include <cmath> float baseMoveSpeed[MAX_MOVE_TYPE] = @@ -262,13 +264,25 @@ SpellSchoolMask ProcEventInfo::GetSchoolMask() const return SPELL_SCHOOL_MASK_NONE; } +DispelableAura::DispelableAura(Aura* aura, int32 dispelChance, uint8 dispelCharges) : + _aura(aura), _chance(dispelChance), _charges(dispelCharges) +{ +} + +DispelableAura::~DispelableAura() = default; + +bool DispelableAura::RollDispel() const +{ + return roll_chance_i(_chance); +} + Unit::Unit(bool isWorldObject) : WorldObject(isWorldObject), m_playerMovingMe(nullptr), m_lastSanctuaryTime(0), IsAIEnabled(false), NeedChangeAI(false), LastCharmerGUID(), m_ControlledByPlayer(false), movespline(new Movement::MoveSpline()), i_AI(nullptr), i_disabledAI(nullptr), m_AutoRepeatFirstCast(false), m_procDeep(0), m_removedAurasCount(0), i_motionMaster(new MotionMaster(this)), m_regenTimer(0), m_ThreatManager(this), - m_vehicle(nullptr), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), + m_vehicle(nullptr), m_vehicleKit(nullptr), m_unitTypeMask(UNIT_MASK_NONE), m_Diminishing(), m_HostileRefManager(this), m_spellHistory(new SpellHistory(this)) { m_objectType |= TYPEMASK_UNIT; @@ -292,7 +306,7 @@ Unit::Unit(bool isWorldObject) : m_deathState = ALIVE; for (uint8 i = 0; i < CURRENT_MAX_SPELL; ++i) - m_currentSpells[i] = NULL; + m_currentSpells[i] = nullptr; for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i) m_SummonSlot[i].Clear(); @@ -540,7 +554,7 @@ void Unit::resetAttackTimer(WeaponAttackType type) m_attackTimer[type] = uint32(GetAttackTime(type) * m_modAttackSpeedPct[type]); } -bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const +bool Unit::IsWithinCombatRange(Unit const* obj, float dist2compare) const { if (!obj || !IsInMap(obj) || !InSamePhase(obj)) return false; @@ -577,7 +591,7 @@ float Unit::GetMeleeRange(Unit const* target) const return std::max(range, NOMINAL_MELEE_RANGE); } -void Unit::GetRandomContactPoint(const Unit* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const +void Unit::GetRandomContactPoint(Unit const* obj, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const { float combat_reach = GetCombatReach(); if (combat_reach < 0.1f) // sometimes bugged for players @@ -646,7 +660,7 @@ bool Unit::HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura) const bool Unit::HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel) const { uint32 excludeAura = 0; - if (Spell* currentChanneledSpell = excludeCasterChannel ? excludeCasterChannel->GetCurrentSpell(CURRENT_CHANNELED_SPELL) : NULL) + if (Spell* currentChanneledSpell = excludeCasterChannel ? excludeCasterChannel->GetCurrentSpell(CURRENT_CHANNELED_SPELL) : nullptr) excludeAura = currentChanneledSpell->GetSpellInfo()->Id; //Avoid self interrupt of channeled Crowd Control spells like Seduction return ( HasBreakableByDamageAuraType(SPELL_AURA_MOD_CONFUSE, excludeAura) @@ -735,8 +749,8 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam uint32 share = CalculatePct(damage, (*i)->GetAmount()); /// @todo check packets if damage is done by victim, or by attacker of victim - DealDamageMods(shareDamageTarget, share, NULL); - DealDamage(shareDamageTarget, share, NULL, NODAMAGE, spell->GetSchoolMask(), spell, false); + DealDamageMods(shareDamageTarget, share, nullptr); + DealDamage(shareDamageTarget, share, nullptr, NODAMAGE, spell->GetSchoolMask(), spell, false); } } @@ -928,7 +942,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam ASSERT(he && he->duel); - if (duel_wasMounted) // In this case victim==mount + if (duel_wasMounted) // In this case victim == mount victim->SetHealth(1); else he->SetHealth(1); @@ -1127,7 +1141,7 @@ void Unit::CalculateSpellDamageTaken(SpellNonMeleeDamage* damageInfo, int32 dama uint32 crit_bonus = damage; // Apply crit_damage bonus for melee spells if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRIT_DAMAGE_BONUS>(spellInfo->Id, crit_bonus); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); damage += crit_bonus; // Apply SPELL_AURA_MOD_ATTACKER_RANGED_CRIT_DAMAGE or SPELL_AURA_MOD_ATTACKER_MELEE_CRIT_DAMAGE @@ -1222,7 +1236,7 @@ void Unit::DealSpellDamage(SpellNonMeleeDamage* damageInfo, bool durabilityLoss) return; SpellInfo const* spellProto = sSpellMgr->GetSpellInfo(damageInfo->SpellID); - if (spellProto == NULL) + if (spellProto == nullptr) { TC_LOG_DEBUG("entities.unit", "Unit::DealSpellDamage has wrong damageInfo->SpellID: %u", damageInfo->SpellID); return; @@ -1296,7 +1310,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam // Calculate armor reduction if (IsDamageReducedByArmor((SpellSchoolMask)(damageInfo->damageSchoolMask))) { - damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage, NULL, damageInfo->attackType); + damageInfo->damage = CalcArmorReducedDamage(damageInfo->target, damage, nullptr, damageInfo->attackType); damageInfo->cleanDamage += damage - damageInfo->damage; } else @@ -1405,7 +1419,7 @@ void Unit::CalculateMeleeDamage(Unit* victim, uint32 damage, CalcDamageInfo* dam int32 resilienceReduction = damageInfo->damage; // attackType is checked already for BASE_ATTACK or OFF_ATTACK so it can't be RANGED_ATTACK here - ApplyResilience(victim, NULL, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE); + ApplyResilience(victim, nullptr, &resilienceReduction, (damageInfo->hitOutCome == MELEE_HIT_CRIT), CR_CRIT_TAKEN_MELEE); resilienceReduction = damageInfo->damage - resilienceReduction; damageInfo->damage -= resilienceReduction; damageInfo->cleanDamage += resilienceReduction; @@ -1480,7 +1494,7 @@ void Unit::DealMeleeDamage(CalcDamageInfo* damageInfo, bool durabilityLoss) // Call default DealDamage CleanDamage cleanDamage(damageInfo->cleanDamage, damageInfo->absorb, damageInfo->attackType, damageInfo->hitOutCome); - DealDamage(victim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), NULL, durabilityLoss); + DealDamage(victim, damageInfo->damage, &cleanDamage, DIRECT_DAMAGE, SpellSchoolMask(damageInfo->damageSchoolMask), nullptr, durabilityLoss); // If this is a creature and it attacks from behind it has a probability to daze it's victim if ((damageInfo->hitOutCome == MELEE_HIT_CRIT || damageInfo->hitOutCome == MELEE_HIT_CRUSHING || damageInfo->hitOutCome == MELEE_HIT_NORMAL || damageInfo->hitOutCome == MELEE_HIT_GLANCING) && @@ -1570,7 +1584,7 @@ void Unit::HandleEmoteCommand(uint32 anim_id) SendMessageToSet(&data, true); } -bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* spellInfo, uint8 effIndex) +bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* spellInfo /*= nullptr*/, int8 effIndex /*= -1*/) { // only physical spells damage gets reduced by armor if ((schoolMask & SPELL_SCHOOL_MASK_NORMAL) == 0) @@ -1582,7 +1596,7 @@ bool Unit::IsDamageReducedByArmor(SpellSchoolMask schoolMask, SpellInfo const* s return false; // bleeding effects are not reduced by armor - if (effIndex != MAX_SPELL_EFFECTS) + if (effIndex != -1) { if (spellInfo->Effects[effIndex].ApplyAuraName == SPELL_AURA_PERIODIC_DAMAGE || spellInfo->Effects[effIndex].Effect == SPELL_EFFECT_SCHOOL_DAMAGE) @@ -1602,7 +1616,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo if (spellInfo) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_IGNORE_ARMOR>(spellInfo->Id, armor); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_IGNORE_ARMOR, armor); AuraEffectList const& resIgnoreAurasAb = GetAuraEffectsByType(SPELL_AURA_MOD_ABILITY_IGNORE_TARGET_RESIST); for (AuraEffectList::const_iterator j = resIgnoreAurasAb.begin(); j != resIgnoreAurasAb.end(); ++j) @@ -2613,7 +2627,7 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo // Spellmod from SPELLMOD_RESIST_MISS_CHANCE if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RESIST_MISS_CHANCE>(spellInfo->Id, modHitChance); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_RESIST_MISS_CHANCE, modHitChance); // Increase from attacker SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT auras modHitChance += GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_INCREASES_SPELL_PCT_TO_HIT, schoolMask); @@ -3045,7 +3059,7 @@ void Unit::_UpdateSpells(uint32 time) if (m_currentSpells[i] && m_currentSpells[i]->getState() == SPELL_STATE_FINISHED) { m_currentSpells[i]->SetReferencedFromCurrent(false); - m_currentSpells[i] = NULL; // remove pointer + m_currentSpells[i] = nullptr; // remove pointer } } @@ -3094,7 +3108,7 @@ void Unit::_UpdateSpells(uint32 time) void Unit::_UpdateAutoRepeatSpell() { - const SpellInfo* autoRepeatSpellInfo = m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo; + SpellInfo const* autoRepeatSpellInfo = m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo; // check "realtime" interrupts if ((GetTypeId() == TYPEID_PLAYER && ToPlayer()->isMoving()) || IsNonMeleeSpellCast(false, false, true, autoRepeatSpellInfo->Id == 75)) @@ -3231,7 +3245,7 @@ void Unit::InterruptSpell(CurrentSpellTypes spellType, bool withDelayed, bool wi if (spell->getState() != SPELL_STATE_FINISHED) spell->cancel(); - m_currentSpells[spellType] = NULL; + m_currentSpells[spellType] = nullptr; spell->SetReferencedFromCurrent(false); } } @@ -3298,7 +3312,7 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const for (uint32 i = 0; i < CURRENT_MAX_SPELL; i++) if (m_currentSpells[i] && m_currentSpells[i]->m_spellInfo->Id == spell_id) return m_currentSpells[i]; - return NULL; + return nullptr; } int32 Unit::GetCurrentSpellCastTime(uint32 spell_id) const @@ -3501,7 +3515,7 @@ AuraApplication * Unit::_CreateAuraApplication(Aura* aura, uint8 effMask) // ghost spell check, allow apply any auras at player loading in ghost mode (will be cleanup after load) if (!IsAlive() && !aurSpellInfo->IsDeathPersistent() && (GetTypeId() != TYPEID_PLAYER || !ToPlayer()->GetSession()->PlayerLoading())) - return NULL; + return nullptr; Unit* caster = aura->GetCaster(); @@ -3811,7 +3825,7 @@ Aura* Unit::GetOwnedAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemC return itr->second; } } - return NULL; + return nullptr; } void Unit::RemoveAura(AuraApplicationMap::iterator &i, AuraRemoveMode mode) @@ -4506,7 +4520,7 @@ AuraEffect* Unit::GetAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caste return itr->second->GetBase()->GetEffect(effIndex); } } - return NULL; + return nullptr; } AuraEffect* Unit::GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, ObjectGuid caster) const @@ -4518,7 +4532,7 @@ AuraEffect* Unit::GetAuraEffectOfRankedSpell(uint32 spellId, uint8 effIndex, Obj return aurEff; rankSpell = sSpellMgr->GetNextSpellInChain(rankSpell); } - return NULL; + return nullptr; } AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 iconId, uint8 effIndex) const @@ -4532,7 +4546,7 @@ AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames name, uint32 ico if (spell->SpellIconID == iconId && spell->SpellFamilyName == uint32(name) && !spell->SpellFamilyFlags) return *itr; } - return NULL; + return nullptr; } AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID) const @@ -4548,7 +4562,7 @@ AuraEffect* Unit::GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 f return (*i); } } - return NULL; + return nullptr; } AuraEffect* Unit::GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const @@ -4572,13 +4586,13 @@ AuraApplication * Unit::GetAuraApplication(uint32 spellId, ObjectGuid casterGUID return app; } } - return NULL; + return nullptr; } Aura* Unit::GetAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask) const { AuraApplication * aurApp = GetAuraApplication(spellId, casterGUID, itemCasterGUID, reqEffMask); - return aurApp ? aurApp->GetBase() : NULL; + return aurApp ? aurApp->GetBase() : nullptr; } AuraApplication * Unit::GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask, AuraApplication* except) const @@ -4590,13 +4604,13 @@ AuraApplication * Unit::GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGu return aurApp; rankSpell = sSpellMgr->GetNextSpellInChain(rankSpell); } - return NULL; + return nullptr; } Aura* Unit::GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask) const { AuraApplication * aurApp = GetAuraApplicationOfRankedSpell(spellId, casterGUID, itemCasterGUID, reqEffMask); - return aurApp ? aurApp->GetBase() : NULL; + return aurApp ? aurApp->GetBase() : nullptr; } void Unit::GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, bool isReflect /*= false*/) const @@ -4768,7 +4782,7 @@ AuraEffect* Unit::IsScriptOverriden(SpellInfo const* spell, int32 script) const if ((*i)->IsAffectedOnSpell(spell)) return (*i); } - return NULL; + return nullptr; } uint32 Unit::GetDiseasesByCaster(ObjectGuid casterGUID, bool remove) @@ -5162,14 +5176,14 @@ void Unit::_UnregisterDynObject(DynamicObject* dynObj) DynamicObject* Unit::GetDynObject(uint32 spellId) { if (m_dynObj.empty()) - return NULL; + return nullptr; for (DynObjectList::const_iterator i = m_dynObj.begin(); i != m_dynObj.end();++i) { DynamicObject* dynObj = *i; if (dynObj->GetSpellId() == spellId) return dynObj; } - return NULL; + return nullptr; } void Unit::RemoveDynObject(uint32 spellId) @@ -5201,7 +5215,7 @@ GameObject* Unit::GetGameObject(uint32 spellId) const if ((*i)->GetSpellId() == spellId) return *i; - return NULL; + return nullptr; } void Unit::AddGameObject(GameObject* gameObj) @@ -6017,7 +6031,7 @@ void Unit::ModifyAuraState(AuraStateType flag, bool apply) if (!spellInfo || !spellInfo->IsPassive()) continue; if (spellInfo->CasterAuraState == uint32(flag)) - CastSpell(this, itr->first, true, NULL); + CastSpell(this, itr->first, true, nullptr); } } else if (Pet* pet = ToCreature()->ToPet()) @@ -6030,7 +6044,7 @@ void Unit::ModifyAuraState(AuraStateType flag, bool apply) if (!spellInfo || !spellInfo->IsPassive()) continue; if (spellInfo->CasterAuraState == uint32(flag)) - CastSpell(this, itr->first, true, NULL); + CastSpell(this, itr->first, true, nullptr); } } } @@ -6120,7 +6134,7 @@ Unit* Unit::GetOwner() const if (ObjectGuid ownerGUID = GetOwnerGUID()) return ObjectAccessor::GetUnit(*this, ownerGUID); - return NULL; + return nullptr; } Unit* Unit::GetCharmer() const @@ -6148,7 +6162,7 @@ Player* Unit::GetAffectingPlayer() const if (Unit* owner = GetCharmerOrOwner()) return owner->GetCharmerOrOwnerPlayerOrPlayerItself(); - return NULL; + return nullptr; } Minion *Unit::GetFirstMinion() const @@ -6163,7 +6177,7 @@ Minion *Unit::GetFirstMinion() const const_cast<Unit*>(this)->SetMinionGUID(ObjectGuid::Empty); } - return NULL; + return nullptr; } Guardian* Unit::GetGuardianPet() const @@ -6178,7 +6192,7 @@ Guardian* Unit::GetGuardianPet() const const_cast<Unit*>(this)->SetPetGUID(ObjectGuid::Empty); } - return NULL; + return nullptr; } Unit* Unit::GetCharm() const @@ -6192,7 +6206,7 @@ Unit* Unit::GetCharm() const const_cast<Unit*>(this)->SetGuidValue(UNIT_FIELD_CHARM, ObjectGuid::Empty); } - return NULL; + return nullptr; } Unit* Unit::GetCharmerOrOwner() const @@ -6619,7 +6633,7 @@ bool Unit::isPossessing() const Unit* Unit::GetNextRandomRaidMemberOrPet(float radius) { - Player* player = NULL; + Player* player = nullptr; if (GetTypeId() == TYPEID_PLAYER) player = ToPlayer(); // Should we enable this also for charmed units? @@ -6627,27 +6641,27 @@ Unit* Unit::GetNextRandomRaidMemberOrPet(float radius) player = GetOwner()->ToPlayer(); if (!player) - return NULL; + return nullptr; Group* group = player->GetGroup(); // When there is no group check pet presence if (!group) { // We are pet now, return owner if (player != this) - return IsWithinDistInMap(player, radius) ? player : NULL; + return IsWithinDistInMap(player, radius) ? player : nullptr; Unit* pet = GetGuardianPet(); // No pet, no group, nothing to return if (!pet) - return NULL; + return nullptr; // We are owner now, return pet - return IsWithinDistInMap(pet, radius) ? pet : NULL; + return IsWithinDistInMap(pet, radius) ? pet : nullptr; } std::vector<Unit*> nearMembers; // reserve place for players and pets because resizing vector every unit push is unefficient (vector is reallocated then) nearMembers.reserve(group->GetMembersCount() * 2); - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) if (Player* Target = itr->GetSource()) { // IsHostileTo check duel and controlled by enemy @@ -6661,7 +6675,7 @@ Unit* Unit::GetNextRandomRaidMemberOrPet(float radius) } if (nearMembers.empty()) - return NULL; + return nullptr; uint32 randTarget = urand(0, nearMembers.size()-1); return nearMembers[randTarget]; @@ -6874,7 +6888,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } DoneTotal += int32(DoneAdvertisedBenefit * coeff * factorMod); @@ -6890,7 +6904,7 @@ uint32 Unit::SpellDamageBonusDone(Unit* victim, SpellInfo const* spellProto, uin // apply spellmod to Done damage (flat and pct) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DAMAGE>(spellProto->Id, tmpDamage); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); } return uint32(std::max(tmpDamage, 0.0f)); @@ -7276,7 +7290,7 @@ uint32 Unit::SpellDamageBonusTaken(Unit* caster, SpellInfo const* spellProto, ui if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } TakenTotal += int32(TakenAdvertisedBenefit * coeff * factorMod); @@ -7569,7 +7583,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto // percent done // only players use intelligence for critical chance computations if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRITICAL_CHANCE>(spellProto->Id, crit_chance); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRITICAL_CHANCE, crit_chance); // for this types the bonus was already added in GetUnitCriticalChance, do not add twice if (spellProto->DmgClass != SPELL_DAMAGE_CLASS_MELEE && spellProto->DmgClass != SPELL_DAMAGE_CLASS_RANGED) @@ -7617,7 +7631,7 @@ uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage { // adds additional damage to critBonus (from talents) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CRIT_DAMAGE_BONUS>(spellProto->Id, crit_bonus); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus); } crit_bonus += damage; @@ -7759,7 +7773,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } @@ -7794,7 +7808,7 @@ uint32 Unit::SpellHealingBonusDone(Unit* victim, SpellInfo const* spellProto, ui // apply spellmod to Done amount if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DAMAGE>(spellProto->Id, heal); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, heal); } return uint32(std::max(heal, 0.0f)); @@ -7939,7 +7953,7 @@ uint32 Unit::SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, u if (Player* modOwner = GetSpellModOwner()) { coeff *= 100.0f; - modOwner->ApplySpellMod<SPELLMOD_BONUS_MULTIPLIER>(spellProto->Id, coeff); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_BONUS_MULTIPLIER, coeff); coeff /= 100.0f; } @@ -8363,7 +8377,7 @@ uint32 Unit::MeleeDamageBonusDone(Unit* victim, uint32 pdamage, WeaponAttackType // apply spellmod to Done damage if (spellProto) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DAMAGE>(spellProto->Id, tmpDamage); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_DAMAGE, tmpDamage); // bonus result can be negative return uint32(std::max(tmpDamage, 0.0f)); @@ -8507,7 +8521,7 @@ float Unit::GetWeaponProcChance() const return 0; } -float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spellProto) const +float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spellProto) const { // proc per minute chance calculation if (PPM <= 0) @@ -8516,7 +8530,7 @@ float Unit::GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spe // Apply chance modifer aura if (spellProto) if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_PROC_PER_MINUTE>(spellProto->Id, PPM); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_PROC_PER_MINUTE, PPM); return std::floor((WeaponSpeed * PPM) / 600.0f); // result is chance in percents (probability = Speed_in_sec * (PPM / 60)) } @@ -8542,7 +8556,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) SendMessageToSet(&data, true); data.Initialize(SMSG_ON_CANCEL_EXPECTED_RIDE_VEHICLE_AURA, 0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); // mounts can also have accessories GetVehicleKit()->InstallAllAccessories(false); @@ -8570,7 +8584,7 @@ void Unit::Mount(uint32 mount, uint32 VehicleId, uint32 creatureEntry) data << GetPackGUID(); data << uint32(GameTime::GetGameTime()); // Packet counter data << player->GetCollisionHeight(true); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_MOUNT); @@ -8590,7 +8604,7 @@ void Unit::Dismount() data << GetPackGUID(); data << uint32(GameTime::GetGameTime()); // Packet counter data << thisPlayer->GetCollisionHeight(false); - thisPlayer->GetSession()->SendPacket(&data); + thisPlayer->SendDirectMessage(&data); } WorldPacket data(SMSG_DISMOUNT, 8); @@ -8803,7 +8817,7 @@ bool Unit::isTargetableForAttack(bool checkFakeDeath) const bool Unit::IsValidAttackTarget(Unit const* target) const { - return _IsValidAttackTarget(target, NULL); + return _IsValidAttackTarget(target, nullptr); } // function based on function Unit::CanAttack from 13850 client @@ -8926,7 +8940,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, Wo bool Unit::IsValidAssistTarget(Unit const* target) const { - return _IsValidAssistTarget(target, NULL); + return _IsValidAssistTarget(target, nullptr); } // function based on function Unit::CanAssist from 13850 client @@ -9371,7 +9385,7 @@ void Unit::SetSpeedRate(UnitMoveType mtype, float rate) if (mtype == MOVE_RUN) self << uint8(1); // unknown byte added in 2.1.0 self << float(GetSpeed(mtype)); - playerMover->GetSession()->SendPacket(&self); + playerMover->SendDirectMessage(&self); // Send notification to other players. sent to every clients (if in range) except one: the client of the player concerned by the change. WorldPacket data; @@ -9712,17 +9726,17 @@ float Unit::ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index { if (Player* modOwner = GetSpellModOwner()) { - modOwner->ApplySpellMod<SPELLMOD_ALL_EFFECTS>(spellProto->Id, value); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_ALL_EFFECTS, value); switch (effect_index) { case EFFECT_0: - modOwner->ApplySpellMod<SPELLMOD_EFFECT1>(spellProto->Id, value); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT1, value); break; case EFFECT_1: - modOwner->ApplySpellMod<SPELLMOD_EFFECT2>(spellProto->Id, value); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT2, value); break; case EFFECT_2: - modOwner->ApplySpellMod<SPELLMOD_EFFECT3>(spellProto->Id, value); + modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_EFFECT3, value); break; } } @@ -9865,7 +9879,7 @@ void Unit::ModSpellCastTime(SpellInfo const* spellInfo, int32 & castTime, Spell* // called from caster if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CASTING_TIME>(spellInfo->Id, castTime, spell); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, castTime, spell); if (!(spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL) || spellInfo->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS)) && ((GetTypeId() == TYPEID_PLAYER && spellInfo->SpellFamilyName) || GetTypeId() == TYPEID_UNIT)) @@ -9886,7 +9900,7 @@ void Unit::ModSpellDurationTime(SpellInfo const* spellInfo, int32 & duration, Sp // called from caster if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CASTING_TIME>(spellInfo->Id, duration, spell); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_CASTING_TIME, duration, spell); if (!(spellInfo->HasAttribute(SPELL_ATTR0_ABILITY) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL) || spellInfo->HasAttribute(SPELL_ATTR3_NO_DONE_BONUS)) && ((GetTypeId() == TYPEID_PLAYER && spellInfo->SpellFamilyName) || GetTypeId() == TYPEID_UNIT)) @@ -10003,8 +10017,8 @@ void Unit::ApplyDiminishingAura(DiminishingGroup group, bool apply) void Unit::ClearDiminishings() { - for (uint32 i = 0; i < DIMINISHING_MAX; ++i) - m_Diminishing[i].Clear(); + for (DiminishingReturn& dim : m_Diminishing) + dim.Clear(); } float Unit::GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const @@ -10768,7 +10782,7 @@ void Unit::DeleteCharmInfo() m_charmInfo->RestoreState(); delete m_charmInfo; - m_charmInfo = NULL; + m_charmInfo = nullptr; } CharmInfo::CharmInfo(Unit* unit) @@ -11333,7 +11347,7 @@ void Unit::SendPetActionFeedback(uint8 msg) WorldPacket data(SMSG_PET_ACTION_FEEDBACK, 1); data << uint8(msg); - owner->ToPlayer()->GetSession()->SendPacket(&data); + owner->ToPlayer()->SendDirectMessage(&data); } void Unit::SendPetTalk(uint32 pettalk) @@ -11345,7 +11359,7 @@ void Unit::SendPetTalk(uint32 pettalk) WorldPacket data(SMSG_PET_ACTION_SOUND, 8 + 4); data << uint64(GetGUID()); data << uint32(pettalk); - owner->ToPlayer()->GetSession()->SendPacket(&data); + owner->ToPlayer()->SendDirectMessage(&data); } void Unit::SendPetAIReaction(ObjectGuid guid) @@ -11357,11 +11371,16 @@ void Unit::SendPetAIReaction(ObjectGuid guid) WorldPacket data(SMSG_AI_REACTION, 8 + 4); data << uint64(guid); data << uint32(AI_REACTION_HOSTILE); - owner->ToPlayer()->GetSession()->SendPacket(&data); + owner->ToPlayer()->SendDirectMessage(&data); } ///----------End of Pet responses methods---------- +void Unit::PropagateSpeedChange() +{ + GetMotionMaster()->PropagateSpeedChange(); +} + void Unit::StopMoving() { ClearUnitState(UNIT_STATE_MOVING); @@ -11409,7 +11428,7 @@ void Unit::SetStandState(uint8 state) { WorldPacket data(SMSG_STANDSTATE_UPDATE, 1); data << (uint8)state; - ToPlayer()->GetSession()->SendPacket(&data); + ToPlayer()->SendDirectMessage(&data); } } @@ -11568,7 +11587,7 @@ Unit* Unit::SelectNearbyTarget(Unit* exclude, float dist) const // no appropriate targets if (targets.empty()) - return NULL; + return nullptr; // select random return Trinity::Containers::SelectRandomContainerElement(targets); @@ -11834,14 +11853,14 @@ void Unit::SetContestedPvP(Player* attackedPlayer) Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget, uint32 spell_id) { if (GetTypeId() != TYPEID_PLAYER) - return NULL; + return nullptr; Pet* pet = new Pet(ToPlayer(), HUNTER_PET); if (!pet->CreateBaseAtCreature(creatureTarget)) { delete pet; - return NULL; + return nullptr; } uint8 level = creatureTarget->getLevel() + 5 < getLevel() ? (getLevel() - 5) : creatureTarget->getLevel(); @@ -11854,18 +11873,18 @@ Pet* Unit::CreateTamedPetFrom(Creature* creatureTarget, uint32 spell_id) Pet* Unit::CreateTamedPetFrom(uint32 creatureEntry, uint32 spell_id) { if (GetTypeId() != TYPEID_PLAYER) - return NULL; + return nullptr; CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(creatureEntry); if (!creatureInfo) - return NULL; + return nullptr; Pet* pet = new Pet(ToPlayer(), HUNTER_PET); if (!pet->CreateBaseAtCreatureInfo(creatureInfo, this) || !InitTamedPet(pet, getLevel(), spell_id)) { delete pet; - return NULL; + return nullptr; } return pet; @@ -11909,7 +11928,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) { isRewardAllowed = creature->IsDamageEnoughForLootingAndReward(); if (!isRewardAllowed) - creature->SetLootRecipient(NULL); + creature->SetLootRecipient(nullptr); } if (isRewardAllowed && creature && creature->GetLootRecipient()) @@ -11980,7 +11999,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (hasLooterGuid) group->SendLooter(creature, looter); else - group->SendLooter(creature, NULL); + group->SendLooter(creature, nullptr); // Update round robin looter only if the creature had loot if (!loot->empty()) @@ -12030,7 +12049,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) victim->SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId); // FORM_SPIRITOFREDEMPTION and related auras - victim->CastSpell(victim, 27827, true, NULL, aurEff); + victim->CastSpell(victim, 27827, true, nullptr, aurEff); spiritOfRedemption = true; break; } @@ -12059,7 +12078,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) { // remember victim PvP death for corpse type and corpse reclaim delay // at original death (not at SpiritOfRedemtionTalent timeout) - plrVictim->SetPvPDeath(player != NULL); + plrVictim->SetPvPDeath(player != nullptr); // only if not player and not controlled by player pet. And not at BG if ((durabilityLoss && !player && !victim->ToPlayer()->InBattleground()) || (player && sWorld->getBoolConfig(CONFIG_DURABILITY_LOSS_IN_PVP))) @@ -12068,7 +12087,7 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) plrVictim->DurabilityLossAll(sWorld->getRate(RATE_DURABILITY_LOSS_ON_DEATH), false); // durability lost message WorldPacket data(SMSG_DURABILITY_DAMAGE_DEATH, 0); - plrVictim->GetSession()->SendPacket(&data); + plrVictim->SendDirectMessage(&data); } // Call KilledUnit for creatures if (GetTypeId() == TYPEID_UNIT && IsAIEnabled) @@ -12392,7 +12411,7 @@ void Unit::SetFeared(bool apply) { SetTarget(ObjectGuid::Empty); - Unit* caster = NULL; + Unit* caster = nullptr; Unit::AuraEffectList const& fearAuras = GetAuraEffectsByType(SPELL_AURA_MOD_FEAR); if (!fearAuras.empty()) caster = ObjectAccessor::GetUnit(*this, fearAuras.front()->GetCasterGUID()); @@ -12584,7 +12603,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au GetCharmInfo()->SetPetNumber(sObjectMgr->GeneratePetNumber(), true); // if charmed two demons the same session, the 2nd gets the 1st one's name - SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped + SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped } } playerCharmer->CharmSpellInitialize(); @@ -12731,7 +12750,7 @@ void Unit::RestoreFaction() Unit* Unit::GetRedirectThreatTarget() { - return _redirectThreadInfo.GetTargetGUID() ? ObjectAccessor::GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : NULL; + return _redirectThreadInfo.GetTargetGUID() ? ObjectAccessor::GetUnit(*this, _redirectThreadInfo.GetTargetGUID()) : nullptr; } bool Unit::CreateVehicleKit(uint32 id, uint32 creatureEntry) @@ -12754,21 +12773,21 @@ void Unit::RemoveVehicleKit() m_vehicleKit->Uninstall(); delete m_vehicleKit; - m_vehicleKit = NULL; + m_vehicleKit = nullptr; m_updateFlag &= ~UPDATEFLAG_VEHICLE; m_unitTypeMask &= ~UNIT_MASK_VEHICLE; RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK | UNIT_NPC_FLAG_PLAYER_VEHICLE); } -bool Unit::IsOnVehicle(const Unit* vehicle) const +bool Unit::IsOnVehicle(Unit const* vehicle) const { return m_vehicle && m_vehicle == vehicle->GetVehicleKit(); } Unit* Unit::GetVehicleBase() const { - return m_vehicle ? m_vehicle->GetBase() : NULL; + return m_vehicle ? m_vehicle->GetBase() : nullptr; } Creature* Unit::GetVehicleCreatureBase() const @@ -12777,7 +12796,7 @@ Creature* Unit::GetVehicleCreatureBase() const if (Creature* c = veh->ToCreature()) return c; - return NULL; + return nullptr; } ObjectGuid Unit::GetTransGUID() const @@ -12838,7 +12857,7 @@ bool Unit::IsInRaidWith(Unit const* unit) const void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap) { Unit* owner = GetCharmerOrOwnerOrSelf(); - Group* group = NULL; + Group* group = nullptr; if (owner->GetTypeId() == TYPEID_PLAYER) group = owner->ToPlayer()->GetGroup(); @@ -12846,7 +12865,7 @@ void Unit::GetPartyMembers(std::list<Unit*> &TagUnitMap) { uint8 subgroup = owner->ToPlayer()->GetSubGroup(); - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* Target = itr->GetSource(); @@ -12891,14 +12910,14 @@ void Unit::SetPvP(bool state) Aura* Unit::AddAura(uint32 spellId, Unit* target) { if (!target) - return NULL; + return nullptr; SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) - return NULL; + return nullptr; if (!target->IsAlive() && !spellInfo->IsPassive() && !spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_DEAD)) - return NULL; + return nullptr; return AddAura(spellInfo, MAX_EFFECT_MASK, target); } @@ -12906,10 +12925,10 @@ Aura* Unit::AddAura(uint32 spellId, Unit* target) Aura* Unit::AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target) { if (!spellInfo) - return NULL; + return nullptr; if (target->IsImmunedToSpell(spellInfo, this)) - return NULL; + return nullptr; for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) { @@ -12924,7 +12943,7 @@ Aura* Unit::AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target) aura->ApplyForTargets(); return aura; } - return NULL; + return nullptr; } void Unit::SetAuraStack(uint32 spellId, Unit* target, uint32 stack) @@ -12958,13 +12977,13 @@ void Unit::ApplyResilience(Unit const* victim, float* crit, int32* damage, bool if (IsVehicle() || (victim->IsVehicle() && victim->GetTypeId() != TYPEID_PLAYER)) return; - Unit const* source = NULL; + Unit const* source = nullptr; if (GetTypeId() == TYPEID_PLAYER) source = this; else if (GetTypeId() == TYPEID_UNIT && GetOwner() && GetOwner()->GetTypeId() == TYPEID_PLAYER) source = GetOwner(); - Unit const* target = NULL; + Unit const* target = nullptr; if (victim->GetTypeId() == TYPEID_PLAYER) target = victim; else if (victim->GetTypeId() == TYPEID_UNIT && victim->GetOwner() && victim->GetOwner()->GetTypeId() == TYPEID_PLAYER) @@ -13042,7 +13061,7 @@ float Unit::MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, i if (spellId) { if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RESIST_MISS_CHANCE>(spellId, resistMissChance); + modOwner->ApplySpellMod(spellId, SPELLMOD_RESIST_MISS_CHANCE, resistMissChance); } missChance -= resistMissChance - 100.0f; @@ -13141,7 +13160,7 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) { player = charmer->ToPlayer(); if (player && player->m_unitMovedByMe != this) - player = NULL; + player = nullptr; } } @@ -13157,12 +13176,11 @@ void Unit::KnockbackFrom(float x, float y, float speedXY, float speedZ) WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8 + 4 + 4 + 4 + 4 + 4)); data << GetPackGUID(); data << uint32(0); // counter - data << float(vcos); // x direction - data << float(vsin); // y direction + data << TaggedPosition<Position::XY>(vcos, vsin); data << float(speedXY); // Horizontal speed data << float(-speedZ); // Z Movement speed (vertical) - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); if (player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) || player->HasAuraType(SPELL_AURA_FLY)) player->SetCanFly(true, true); @@ -13494,12 +13512,11 @@ void Unit::JumpTo(float speedXY, float speedZ, bool forward) WorldPacket data(SMSG_MOVE_KNOCK_BACK, (8+4+4+4+4+4)); data << GetPackGUID(); data << uint32(0); // Sequence - data << float(vcos); // x direction - data << float(vsin); // y direction + data << TaggedPosition<Position::XY>(vcos, vsin); data << float(speedXY); // Horizontal speed data << float(-speedZ); // Z Movement speed (vertical) - ToPlayer()->GetSession()->SendPacket(&data); + ToPlayer()->SendDirectMessage(&data); } } @@ -13556,7 +13573,7 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) } if (IsInMap(caster)) - caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId + 1, target, flags, NULL, NULL, origCasterGUID); + caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId + 1, target, flags, nullptr, nullptr, origCasterGUID); else // This can happen during Player::_LoadAuras { int32 bp0[MAX_SPELL_EFFECTS]; @@ -13564,15 +13581,15 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId) bp0[j] = spellEntry->Effects[j].BasePoints; bp0[i] = seatId; - Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, NULL, origCasterGUID); + Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, bp0, nullptr, origCasterGUID); } } else { if (IsInMap(caster)) - caster->CastSpell(target, spellEntry, flags, NULL, NULL, origCasterGUID); + caster->CastSpell(target, spellEntry, flags, nullptr, nullptr, origCasterGUID); else - Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID); + Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, nullptr, nullptr, origCasterGUID); } result = true; @@ -13645,7 +13662,7 @@ void Unit::ChangeSeat(int8 seatId, bool next) if (seat == m_vehicle->Seats.end() || !seat->second.IsEmpty()) return; - AuraEffect* rideVehicleEffect = NULL; + AuraEffect* rideVehicleEffect = nullptr; AuraEffectList const& vehicleAuras = m_vehicle->GetBase()->GetAuraEffectsByType(SPELL_AURA_CONTROL_VEHICLE); for (AuraEffectList::const_iterator itr = vehicleAuras.begin(); itr != vehicleAuras.end(); ++itr) { @@ -13760,19 +13777,13 @@ void Unit::BuildMovementPacket(Position const& pos, Position const& transportPos *data << uint32(movementInfo.GetMovementFlags()); *data << uint16(movementInfo.GetExtraMovementFlags()); *data << uint32(GameTime::GetGameTimeMS()); // time / counter - *data << float(pos.GetPositionX()); - *data << float(pos.GetPositionY()); - *data << float(pos.GetPositionZ()); - *data << float(pos.GetOrientation()); + *data << TaggedPosition<Position::XYZO>(pos); // 0x00000200 if (movementInfo.HasMovementFlag(MOVEMENTFLAG_ONTRANSPORT)) { *data << movementInfo.transport.guid.WriteAsPacked(); - *data << float(transportPos.GetPositionX()); - *data << float(transportPos.GetPositionY()); - *data << float(transportPos.GetPositionZ()); - *data << float(transportPos.GetOrientation()); + *data << TaggedPosition<Position::XYZO>(transportPos); *data << uint32(movementInfo.transport.time); *data << int8(movementInfo.transport.seat); @@ -13904,7 +13915,7 @@ bool Unit::UpdatePosition(float x, float y, float z, float orientation, bool tel return (relocated || turn); } -bool Unit::UpdatePosition(const Position &pos, bool teleport) +bool Unit::UpdatePosition(Position const& pos, bool teleport) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } @@ -13935,7 +13946,7 @@ void Unit::SendThreatListUpdate() WorldPacket data(SMSG_THREAT_UPDATE, 8 + count * 8); data << GetPackGUID(); data << uint32(count); - ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList(); + ThreatContainer::StorageType const& tlist = getThreatManager().getThreatList(); for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { data << (*itr)->getUnitGuid().WriteAsPacked(); @@ -13956,7 +13967,7 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference) data << GetPackGUID(); data << pHostileReference->getUnitGuid().WriteAsPacked(); data << uint32(count); - ThreatContainer::StorageType const &tlist = getThreatManager().getThreatList(); + ThreatContainer::StorageType const& tlist = getThreatManager().getThreatList(); for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { data << (*itr)->getUnitGuid().WriteAsPacked(); diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 61e1ad86c3e..5ed2e57cc3f 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -19,15 +19,18 @@ #ifndef __UNIT_H #define __UNIT_H -#include "DBCStructure.h" +#include "Object.h" #include "EventProcessor.h" #include "FollowerReference.h" #include "FollowerRefManager.h" #include "HostileRefManager.h" -#include "MotionMaster.h" -#include "Object.h" +#include "OptionalFwd.h" #include "SpellAuraDefines.h" #include "ThreatManager.h" +#include "Timer.h" +#include "UnitDefines.h" +#include "Util.h" +#include <map> #define WORLD_TRIGGER 12999 @@ -118,7 +121,7 @@ enum SpellModOp : uint8 MAX_SPELLMOD }; -enum SpellValueMod +enum SpellValueMod : uint8 { SPELLVALUE_BASE_POINT0, SPELLVALUE_BASE_POINT1, @@ -161,69 +164,6 @@ enum SpellFacingFlags SPELL_FACING_FLAG_INFRONT = 0x0001 }; -#define BASE_MINDAMAGE 1.0f -#define BASE_MAXDAMAGE 2.0f -#define BASE_ATTACK_TIME 2000 - -// byte value (UNIT_FIELD_BYTES_1, 0) -enum UnitStandStateType -{ - UNIT_STAND_STATE_STAND = 0, - UNIT_STAND_STATE_SIT = 1, - UNIT_STAND_STATE_SIT_CHAIR = 2, - UNIT_STAND_STATE_SLEEP = 3, - UNIT_STAND_STATE_SIT_LOW_CHAIR = 4, - UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5, - UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6, - UNIT_STAND_STATE_DEAD = 7, - UNIT_STAND_STATE_KNEEL = 8, - UNIT_STAND_STATE_SUBMERGED = 9 -}; - -// byte flag value (UNIT_FIELD_BYTES_1, 2) -enum UnitStandFlags -{ - UNIT_STAND_FLAGS_UNK1 = 0x01, - UNIT_STAND_FLAGS_CREEP = 0x02, - UNIT_STAND_FLAGS_UNTRACKABLE = 0x04, - UNIT_STAND_FLAGS_UNK4 = 0x08, - UNIT_STAND_FLAGS_UNK5 = 0x10, - UNIT_STAND_FLAGS_ALL = 0xFF -}; - -enum UnitBytes0Offsets -{ - UNIT_BYTES_0_OFFSET_RACE = 0, - UNIT_BYTES_0_OFFSET_CLASS = 1, - UNIT_BYTES_0_OFFSET_GENDER = 2, - UNIT_BYTES_0_OFFSET_POWER_TYPE = 3, -}; - -enum UnitBytes1Offsets -{ - UNIT_BYTES_1_OFFSET_STAND_STATE = 0, - UNIT_BYTES_1_OFFSET_PET_TALENTS = 1, - UNIT_BYTES_1_OFFSET_VIS_FLAG = 2, - UNIT_BYTES_1_OFFSET_ANIM_TIER = 3 -}; - -enum UnitBytes2Offsets -{ - UNIT_BYTES_2_OFFSET_SHEATH_STATE = 0, - UNIT_BYTES_2_OFFSET_PVP_FLAG = 1, - UNIT_BYTES_2_OFFSET_PET_FLAGS = 2, - UNIT_BYTES_2_OFFSET_SHAPESHIFT_FORM = 3 -}; - -// byte flags value (UNIT_FIELD_BYTES_1, 3) -enum UnitBytes1_Flags -{ - UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, - UNIT_BYTE1_FLAG_HOVER = 0x02, - UNIT_BYTE1_FLAG_UNK_3 = 0x04, - UNIT_BYTE1_FLAG_ALL = 0xFF -}; - // high byte (3 from 0..3) of UNIT_FIELD_BYTES_2 enum ShapeshiftForm { @@ -260,36 +200,6 @@ enum ShapeshiftForm FORM_SPIRITOFREDEMPTION = 0x20 }; -// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2 -enum SheathState -{ - SHEATH_STATE_UNARMED = 0, // non prepared weapon - SHEATH_STATE_MELEE = 1, // prepared melee weapon - SHEATH_STATE_RANGED = 2 // prepared ranged weapon -}; - -#define MAX_SHEATH_STATE 3 - -// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitPVPStateFlags -{ - UNIT_BYTE2_FLAG_PVP = 0x01, - UNIT_BYTE2_FLAG_UNK1 = 0x02, - UNIT_BYTE2_FLAG_FFA_PVP = 0x04, - UNIT_BYTE2_FLAG_SANCTUARY = 0x08, - UNIT_BYTE2_FLAG_UNK4 = 0x10, - UNIT_BYTE2_FLAG_UNK5 = 0x20, - UNIT_BYTE2_FLAG_UNK6 = 0x40, - UNIT_BYTE2_FLAG_UNK7 = 0x80 -}; - -// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 -enum UnitRename -{ - UNIT_CAN_BE_RENAMED = 0x01, - UNIT_CAN_BE_ABANDONED = 0x02 -}; - #define MAX_SPELL_CHARM 4 #define MAX_SPELL_VEHICLE 6 #define MAX_SPELL_POSSESS 8 @@ -311,36 +221,6 @@ enum VictimState VICTIMSTATE_DEFLECTS = 8 }; -enum HitInfo -{ - HITINFO_NORMALSWING = 0x00000000, - HITINFO_UNK1 = 0x00000001, // req correct packet structure - HITINFO_AFFECTS_VICTIM = 0x00000002, - HITINFO_OFFHAND = 0x00000004, - HITINFO_UNK2 = 0x00000008, - HITINFO_MISS = 0x00000010, - HITINFO_FULL_ABSORB = 0x00000020, - HITINFO_PARTIAL_ABSORB = 0x00000040, - HITINFO_FULL_RESIST = 0x00000080, - HITINFO_PARTIAL_RESIST = 0x00000100, - HITINFO_CRITICALHIT = 0x00000200, // critical hit - HITINFO_UNK10 = 0x00000400, - HITINFO_UNK11 = 0x00000800, - HITINFO_UNK12 = 0x00001000, - HITINFO_BLOCK = 0x00002000, // blocked damage - HITINFO_UNK14 = 0x00004000, // set only if meleespellid is present// no world text when victim is hit for 0 dmg(HideWorldTextForNoDamage?) - HITINFO_UNK15 = 0x00008000, // player victim?// something related to blod sprut visual (BloodSpurtInBack?) - HITINFO_GLANCING = 0x00010000, - HITINFO_CRUSHING = 0x00020000, - HITINFO_NO_ANIMATION = 0x00040000, - HITINFO_UNK19 = 0x00080000, - HITINFO_UNK20 = 0x00100000, - HITINFO_SWINGNOHITSOUND = 0x00200000, // unused? - HITINFO_UNK22 = 0x00400000, - HITINFO_RAGE_GAIN = 0x00800000, - HITINFO_FAKE_DAMAGE = 0x01000000 // enables damage animation even if no damage done, set only if no damage -}; - //i would like to remove this: (it is defined in item.h enum InventorySlot { @@ -349,40 +229,46 @@ enum InventorySlot }; struct FactionTemplateEntry; +struct LiquidData; +struct LiquidTypeEntry; struct SpellValue; -class AuraApplication; class Aura; -class UnitAura; +class AuraApplication; class AuraEffect; class Creature; -class Spell; -class SpellInfo; -class SpellHistory; class DynamicObject; class GameObject; +class Guardian; class Item; -class Pet; class Minion; -class Guardian; -class UnitAI; +class MotionMaster; +class Pet; +class PetAura; +class Spell; +class SpellCastTargets; +class SpellHistory; +class SpellInfo; class Totem; class Transport; +class TransportBase; +class UnitAI; +class UnitAura; class Vehicle; class VehicleJoinEvent; -class TransportBase; -class SpellCastTargets; + +enum ZLiquidStatus : uint32; typedef std::list<Unit*> UnitList; class DispelableAura { public: - DispelableAura(Aura* aura, int32 dispelChance, uint8 dispelCharges) : - _aura(aura), _chance(dispelChance), _charges(dispelCharges) { } + DispelableAura(Aura* aura, int32 dispelChance, uint8 dispelCharges); + ~DispelableAura(); Aura* GetAura() const { return _aura; } - bool RollDispel() const { return roll_chance_i(_chance); } + bool RollDispel() const; uint8 GetDispelCharges() const { return _charges; } void IncrementCharges() { ++_charges; } @@ -424,17 +310,7 @@ enum WeaponDamageRange MAXDAMAGE }; -enum AuraRemoveMode -{ - AURA_REMOVE_NONE = 0, - AURA_REMOVE_BY_DEFAULT = 1, // scripted remove, remove by stack with aura with different ids and sc aura remove - AURA_REMOVE_BY_CANCEL, - AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy - AURA_REMOVE_BY_EXPIRE, // aura duration has ended - AURA_REMOVE_BY_DEATH -}; - -enum TriggerCastFlags +enum TriggerCastFlags : uint32 { TRIGGERED_NONE = 0x00000000, //! Not triggered TRIGGERED_IGNORE_GCD = 0x00000001, //! Will ignore GCD @@ -625,7 +501,7 @@ enum CombatRating #define MAX_COMBAT_RATING 25 -enum DamageEffectType +enum DamageEffectType : uint8 { DIRECT_DAMAGE = 0, // used for normal weapon damage (not for class abilities or spells) SPELL_DIRECT_DAMAGE = 1, // spell/class abilities damage @@ -635,176 +511,6 @@ enum DamageEffectType SELF_DAMAGE = 5 }; -// Value masks for UNIT_FIELD_FLAGS -enum UnitFlags : uint32 -{ - UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner - UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable - UNIT_FLAG_REMOVE_CLIENT_CONTROL = 0x00000004, // This is a legacy flag used to disable movement player's movement while controlling other units, SMSG_CLIENT_CONTROL replaces this functionality clientside now. CONFUSED and FLEEING flags have the same effect on client movement asDISABLE_MOVE_CONTROL in addition to preventing spell casts/autoattack (they all allow climbing steeper hills and emotes while moving) - UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state - UNIT_FLAG_RENAME = 0x00000010, - UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_WHILE_PREP - UNIT_FLAG_UNK_6 = 0x00000040, - UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE - UNIT_FLAG_IMMUNE_TO_PC = 0x00000100, // disables combat/assistance with PlayerCharacters (PC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget - UNIT_FLAG_IMMUNE_TO_NPC = 0x00000200, // disables combat/assistance with NonPlayerCharacters (NPC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget - UNIT_FLAG_LOOTING = 0x00000400, // loot animation - UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 - UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 - UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 - UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8 - UNIT_FLAG_UNK_15 = 0x00008000, - UNIT_FLAG_UNK_16 = 0x00010000, - UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok - UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok - UNIT_FLAG_IN_COMBAT = 0x00080000, - UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag - UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. - UNIT_FLAG_CONFUSED = 0x00400000, - UNIT_FLAG_FLEEING = 0x00800000, - UNIT_FLAG_PLAYER_CONTROLLED = 0x01000000, // used in spell Eyes of the Beast for pet... let attack by controlled creature - UNIT_FLAG_NOT_SELECTABLE = 0x02000000, - UNIT_FLAG_SKINNABLE = 0x04000000, - UNIT_FLAG_MOUNT = 0x08000000, - UNIT_FLAG_UNK_28 = 0x10000000, - UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell - UNIT_FLAG_SHEATHE = 0x40000000, - UNIT_FLAG_UNK_31 = 0x80000000, - MAX_UNIT_FLAGS = 33 -}; - -// Value masks for UNIT_FIELD_FLAGS_2 -enum UnitFlags2 -{ - UNIT_FLAG2_FEIGN_DEATH = 0x00000001, - UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) - UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, - UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, - UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, - UNIT_FLAG2_INSTANTLY_APPEAR_MODEL = 0x00000020, // Unit model instantly appears when summoned (does not fade in) - UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040, - UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, - UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames) - UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) - UNIT_FLAG2_REGENERATE_POWER = 0x00000800, - UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid - UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick - UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, - UNIT_FLAG2_DISABLE_TURN = 0x00008000, - UNIT_FLAG2_UNK2 = 0x00010000, - UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death - UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000 // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL -}; - -/// Non Player Character flags -enum NPCFlags -{ - UNIT_NPC_FLAG_NONE = 0x00000000, - UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100% - UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok - UNIT_NPC_FLAG_UNK1 = 0x00000004, - UNIT_NPC_FLAG_UNK2 = 0x00000008, - UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100% - UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // 100% - UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // 100% - UNIT_NPC_FLAG_VENDOR = 0x00000080, // 100% - UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // 100%, general goods vendor - UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // 100% - UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // guessed - UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // 100% - UNIT_NPC_FLAG_REPAIR = 0x00001000, // 100% - UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // 100% - UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // guessed - UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // guessed - UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // 100% - UNIT_NPC_FLAG_BANKER = 0x00020000, // 100% - UNIT_NPC_FLAG_PETITIONER = 0x00040000, // 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions - UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // 100% - UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // 100% - UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // 100% - UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% - UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode - UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) - UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set - UNIT_NPC_FLAG_MAILBOX = 0x04000000 // -}; - -enum MovementFlags -{ - MOVEMENTFLAG_NONE = 0x00000000, - MOVEMENTFLAG_FORWARD = 0x00000001, - MOVEMENTFLAG_BACKWARD = 0x00000002, - MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, - MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, - MOVEMENTFLAG_LEFT = 0x00000010, - MOVEMENTFLAG_RIGHT = 0x00000020, - MOVEMENTFLAG_PITCH_UP = 0x00000040, - MOVEMENTFLAG_PITCH_DOWN = 0x00000080, - MOVEMENTFLAG_WALKING = 0x00000100, // Walking - MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures - MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible. - MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING - MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling - MOVEMENTFLAG_FALLING_FAR = 0x00002000, - MOVEMENTFLAG_PENDING_STOP = 0x00004000, - MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000, - MOVEMENTFLAG_PENDING_FORWARD = 0x00010000, - MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000, - MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000, - MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000, - MOVEMENTFLAG_PENDING_ROOT = 0x00100000, - MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also - MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying - MOVEMENTFLAG_DESCENDING = 0x00800000, - MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk - MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity - MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths - MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths - MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water - MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive) - MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump - - MOVEMENTFLAG_MASK_MOVING = - MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | - MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING | - MOVEMENTFLAG_SPLINE_ELEVATION, - - MOVEMENTFLAG_MASK_TURNING = - MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT | MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN, - - MOVEMENTFLAG_MASK_MOVING_FLY = - MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING, - - /// @todo if needed: add more flags to this masks that are exclusive to players - MOVEMENTFLAG_MASK_PLAYER_ONLY = - MOVEMENTFLAG_FLYING, - - /// Movement flags that have change status opcodes associated for players - MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT | - MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER -}; - -enum MovementFlags2 -{ - MOVEMENTFLAG2_NONE = 0x00000000, - MOVEMENTFLAG2_NO_STRAFE = 0x00000001, - MOVEMENTFLAG2_NO_JUMPING = 0x00000002, - MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks - MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008, - MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010, - MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020, - MOVEMENTFLAG2_UNK7 = 0x00000040, - MOVEMENTFLAG2_UNK8 = 0x00000080, - MOVEMENTFLAG2_UNK9 = 0x00000100, - MOVEMENTFLAG2_UNK10 = 0x00000200, - MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400, - MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800, - MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000, - MOVEMENTFLAG2_UNK14 = 0x00002000, - MOVEMENTFLAG2_UNK15 = 0x00004000, - MOVEMENTFLAG2_UNK16 = 0x00008000 -}; - enum UnitTypeMask { UNIT_MASK_NONE = 0x00000000, @@ -1065,14 +771,7 @@ struct RedirectThreatInfo } }; -#define MAX_DECLINED_NAME_CASES 5 - -struct DeclinedName -{ - std::string name[MAX_DECLINED_NAME_CASES]; -}; - -enum CurrentSpellTypes +enum CurrentSpellTypes : uint8 { CURRENT_MELEE_SPELL = 0, CURRENT_GENERIC_SPELL = 1, @@ -1083,31 +782,6 @@ enum CurrentSpellTypes #define CURRENT_FIRST_NON_MELEE_SPELL 1 #define CURRENT_MAX_SPELL 4 -enum ActiveStates -{ - ACT_PASSIVE = 0x01, // 0x01 - passive - ACT_DISABLED = 0x81, // 0x80 - castable - ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable - ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04 - ACT_REACTION = 0x06, // 0x02 | 0x04 - ACT_DECIDE = 0x00 // custom -}; - -enum ReactStates -{ - REACT_PASSIVE = 0, - REACT_DEFENSIVE = 1, - REACT_AGGRESSIVE = 2 -}; - -enum CommandStates : uint8 -{ - COMMAND_STAY = 0, - COMMAND_FOLLOW = 1, - COMMAND_ATTACK = 2, - COMMAND_ABANDON = 3 -}; - #define UNIT_ACTION_BUTTON_ACTION(X) (uint32(X) & 0x00FFFFFF) #define UNIT_ACTION_BUTTON_TYPE(X) ((uint32(X) & 0xFF000000) >> 24) #define MAKE_UNIT_ACTION_BUTTON(A, T) (uint32(A) | (uint32(T) << 24)) @@ -1286,7 +960,6 @@ class TC_GAME_API Unit : public WorldObject typedef std::list<AuraEffect*> AuraEffectList; typedef std::list<Aura*> AuraList; typedef std::list<AuraApplication *> AuraApplicationList; - typedef std::array<DiminishingReturn, DIMINISHING_MAX> Diminishing; typedef std::vector<std::pair<uint8 /*procEffectMask*/, AuraApplication*>> AuraApplicationProcContainer; @@ -1323,10 +996,10 @@ class TC_GAME_API Unit : public WorldObject bool CanDualWield() const { return m_canDualWield; } virtual void SetCanDualWield(bool value) { m_canDualWield = value; } float GetCombatReach() const override { return m_floatValues[UNIT_FIELD_COMBATREACH]; } - bool IsWithinCombatRange(const Unit* obj, float dist2compare) const; + bool IsWithinCombatRange(Unit const* obj, float dist2compare) const; bool IsWithinMeleeRange(Unit const* obj) const; float GetMeleeRange(Unit const* target) const; - void GetRandomContactPoint(const Unit* target, float &x, float &y, float &z, float distance2dMin, float distance2dMax) const; + void GetRandomContactPoint(Unit const* target, float& x, float& y, float& z, float distance2dMin, float distance2dMax) const; uint32 m_extraAttacks; bool m_canDualWield; @@ -1351,8 +1024,8 @@ class TC_GAME_API Unit : public WorldObject void CombatStop(bool includingCast = false); void CombatStopWithPets(bool includingCast = false); void StopAttackFaction(uint32 faction_id); - Unit* SelectNearbyTarget(Unit* exclude = NULL, float dist = NOMINAL_MELEE_RANGE) const; - void SendMeleeAttackStop(Unit* victim = NULL); + Unit* SelectNearbyTarget(Unit* exclude = nullptr, float dist = NOMINAL_MELEE_RANGE) const; + void SendMeleeAttackStop(Unit* victim = nullptr); void SendMeleeAttackStart(Unit* victim); void AddUnitState(uint32 f) { m_state |= f; } @@ -1462,7 +1135,7 @@ class TC_GAME_API Unit : public WorldObject uint32 GetMaxSkillValueForLevel(Unit const* target = nullptr) const { return (target ? getLevelForTarget(target) : getLevel()) * 5; } void DealDamageMods(Unit const* victim, uint32 &damage, uint32* absorb) const; - uint32 DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage = NULL, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = NULL, bool durabilityLoss = true); + uint32 DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDamage = nullptr, DamageEffectType damagetype = DIRECT_DAMAGE, SpellSchoolMask damageSchoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* spellProto = nullptr, bool durabilityLoss = true); void Kill(Unit* victim, bool durabilityLoss = true); void KillSelf(bool durabilityLoss = true) { Kill(this, durabilityLoss); } void DealHeal(HealInfo& healInfo); @@ -1524,7 +1197,7 @@ class TC_GAME_API Unit : public WorldObject uint32 GetDefenseSkillValue(Unit const* target = nullptr) const; uint32 GetWeaponSkillValue(WeaponAttackType attType, Unit const* target = nullptr) const; float GetWeaponProcChance() const; - float GetPPMProcChance(uint32 WeaponSpeed, float PPM, const SpellInfo* spellProto) const; + float GetPPMProcChance(uint32 WeaponSpeed, float PPM, SpellInfo const* spellProto) const; MeleeHitOutcome RollMeleeOutcomeAgainst(Unit const* victim, WeaponAttackType attType) const; @@ -1552,7 +1225,7 @@ class TC_GAME_API Unit : public WorldObject bool IsPetInCombat() const { return HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PET_IN_COMBAT); } bool IsInCombatWith(Unit const* who) const; void CombatStart(Unit* target, bool initialAggro = true); - void SetInCombatState(bool PvP, Unit* enemy = NULL); + void SetInCombatState(bool PvP, Unit* enemy = nullptr); void SetInCombatWith(Unit* enemy); void ClearInCombat(); void ClearInPetCombat(); @@ -1561,7 +1234,7 @@ class TC_GAME_API Unit : public WorldObject bool HasAuraTypeWithFamilyFlags(AuraType auraType, uint32 familyName, uint32 familyFlags) const; bool virtual HasSpell(uint32 /*spellID*/) const { return false; } bool HasBreakableByDamageAuraType(AuraType type, uint32 excludeAura = 0) const; - bool HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel = NULL) const; + bool HasBreakableByDamageCrowdControlAura(Unit* excludeCasterChannel = nullptr) const; bool HasStealthAura() const { return HasAuraType(SPELL_AURA_MOD_STEALTH); } bool HasInvisibilityAura() const { return HasAuraType(SPELL_AURA_MOD_INVISIBILITY); } @@ -1574,7 +1247,7 @@ class TC_GAME_API Unit : public WorldObject bool isTargetableForAttack(bool checkFakeDeath = true) const; bool IsValidAttackTarget(Unit const* target) const; - bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj = NULL) const; + bool _IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj = nullptr) const; bool IsValidAssistTarget(Unit const* target) const; bool _IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell) const; @@ -1599,7 +1272,7 @@ class TC_GAME_API Unit : public WorldObject void CastCustomSpell(Unit* victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim, bool triggered, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim = nullptr, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); - void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* victim = nullptr, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); + void CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim = nullptr, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = nullptr, AuraEffect const* triggeredByAura = nullptr, ObjectGuid originalCaster = ObjectGuid::Empty); Aura* AddAura(uint32 spellId, Unit* target); Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target); void SetAuraStack(uint32 spellId, Unit* target, uint32 stack); @@ -1622,7 +1295,7 @@ class TC_GAME_API Unit : public WorldObject void SendTeleportPacket(Position const& pos, bool teleportingTransport = false); virtual bool UpdatePosition(float x, float y, float z, float ang, bool teleport = false); // returns true if unit's position really changed - virtual bool UpdatePosition(const Position &pos, bool teleport = false); + virtual bool UpdatePosition(Position const& pos, bool teleport = false); void UpdateOrientation(float orientation); void UpdateHeight(float newZ); @@ -1631,8 +1304,8 @@ class TC_GAME_API Unit : public WorldObject void JumpTo(WorldObject* obj, float speedZ, bool withOrientation = false); void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false); - //void SetFacing(float ori, WorldObject* obj = NULL); - //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); + //void SetFacing(float ori, WorldObject* obj = nullptr); + //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = nullptr); void SendMovementFlagUpdate(bool self = false); bool IsLevitating() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_DISABLE_GRAVITY); } @@ -1702,7 +1375,7 @@ class TC_GAME_API Unit : public WorldObject void RemoveAllMinionsByEntry(uint32 entry); void SetCharm(Unit* target, bool apply); Unit* GetNextRandomRaidMemberOrPet(float radius); - bool SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* aurApp = NULL); + bool SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* aurApp = nullptr); void RemoveCharmedBy(Unit* charmer); void RestoreFaction(); @@ -1758,7 +1431,7 @@ class TC_GAME_API Unit : public WorldObject void RemoveOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); void RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT); - Aura* GetOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, Aura* except = NULL) const; + Aura* GetOwnedAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, Aura* except = nullptr) const; // m_appliedAuras container management AuraApplicationMap & GetAppliedAuras() { return m_appliedAuras; } @@ -1784,7 +1457,7 @@ class TC_GAME_API Unit : public WorldObject void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit* dispeller, uint8 chargesRemoved = 1); void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit* stealer); void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid); - void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = NULL, bool negative = true, bool positive = true); + void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = nullptr, bool negative = true, bool positive = true); void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = 0); void RemoveAurasWithAttribute(uint32 flags); @@ -1817,10 +1490,10 @@ class TC_GAME_API Unit : public WorldObject AuraEffect* GetAuraEffect(AuraType type, SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, ObjectGuid casterGUID = ObjectGuid::Empty) const; AuraEffect* GetDummyAuraEffect(SpellFamilyNames name, uint32 iconId, uint8 effIndex) const; - AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication * except = NULL) const; + AuraApplication * GetAuraApplication(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication * except = nullptr) const; Aura* GetAura(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const; - AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication * except = NULL) const; + AuraApplication * GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0, AuraApplication * except = nullptr) const; Aura* GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint8 reqEffMask = 0) const; void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, bool isReflect = false) const; @@ -1987,7 +1660,7 @@ class TC_GAME_API Unit : public WorldObject // Threat related methods bool CanHaveThreatList(bool skipAliveCheck = false) const; - void AddThreat(Unit* victim, float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL); + void AddThreat(Unit* victim, float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr); float ApplyTotalThreatModifier(float fThreat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL); void DeleteThreatList(); void TauntApply(Unit* victim); @@ -2029,11 +1702,11 @@ class TC_GAME_API Unit : public WorldObject void ModifyAuraState(AuraStateType flag, bool apply); uint32 BuildAuraStateUpdateForTarget(Unit* target) const; - bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = NULL, Unit const* Caster = NULL) const; + bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = nullptr, Unit const* Caster = nullptr) const; void UnsummonAllTotems(); bool IsMagnet() const; Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo); - Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = NULL); + Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = nullptr); int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const; int32 SpellBaseDamageBonusTaken(SpellSchoolMask schoolMask) const; @@ -2046,8 +1719,8 @@ class TC_GAME_API Unit : public WorldObject float SpellHealingPctDone(Unit* victim, SpellInfo const* spellProto) const; uint32 SpellHealingBonusTaken(Unit* caster, SpellInfo const* spellProto, uint32 healamount, DamageEffectType damagetype, uint32 stack = 1) const; - uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = NULL); - uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = NULL); + uint32 MeleeDamageBonusDone(Unit* pVictim, uint32 damage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr); + uint32 MeleeDamageBonusTaken(Unit* attacker, uint32 pdamage, WeaponAttackType attType, SpellInfo const* spellProto = nullptr); bool isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType = BASE_ATTACK); bool isBlockCritical(); @@ -2059,7 +1732,7 @@ class TC_GAME_API Unit : public WorldObject void SetLastManaUse(uint32 spellCastTime) { m_lastManaUse = spellCastTime; } bool IsUnderLastManaUseEffect() const; - void SetContestedPvP(Player* attackedPlayer = NULL); + void SetContestedPvP(Player* attackedPlayer = nullptr); uint32 GetCastingTimeForBonus(SpellInfo const* spellProto, DamageEffectType damagetype, uint32 CastingTime) const; float CalculateDefaultCoefficient(SpellInfo const* spellInfo, DamageEffectType damagetype) const; @@ -2076,7 +1749,7 @@ class TC_GAME_API Unit : public WorldObject bool IsImmunedToDamage(SpellInfo const* spellInfo) const; virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const; // redefined in Creature - static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = NULL, uint8 effIndex = MAX_SPELL_EFFECTS); + static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr, int8 effIndex = -1); uint32 CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK) const; uint32 CalcSpellResistedDamage(Unit* victim, uint32 damage, SpellSchoolMask schoolMask, SpellInfo const* spellInfo) const; void CalcAbsorbResist(DamageInfo& damageInfo); @@ -2089,18 +1762,18 @@ class TC_GAME_API Unit : public WorldObject void SetSpeedRate(UnitMoveType mtype, float rate); float ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index, float value) const; - int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = NULL) const; + int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = nullptr) const; int32 CalcSpellDuration(SpellInfo const* spellProto); int32 ModSpellDuration(SpellInfo const* spellProto, Unit const* target, int32 duration, bool positive, uint32 effectMask); - void ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = NULL); - void ModSpellDurationTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = NULL); + void ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = nullptr); + void ModSpellDurationTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = nullptr); float CalculateLevelPenalty(SpellInfo const* spellProto) const; void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); } void removeFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ } MotionMaster* GetMotionMaster() { return i_motionMaster; } - const MotionMaster* GetMotionMaster() const { return i_motionMaster; } + MotionMaster const* GetMotionMaster() const { return i_motionMaster; } bool IsStopped() const { return !(HasUnitState(UNIT_STATE_MOVING)); } void StopMoving(); @@ -2131,7 +1804,7 @@ class TC_GAME_API Unit : public WorldObject void SendPetAIReaction(ObjectGuid guid); ///----------End of Pet responses methods---------- - void PropagateSpeedChange() { GetMotionMaster()->PropagateSpeedChange(); } + void PropagateSpeedChange(); // reactive attacks void ClearAllReactives(); @@ -2163,7 +1836,7 @@ class TC_GAME_API Unit : public WorldObject Vehicle* GetVehicleKit()const { return m_vehicleKit; } Vehicle* GetVehicle() const { return m_vehicle; } void SetVehicle(Vehicle* vehicle) { m_vehicle = vehicle; } - bool IsOnVehicle(const Unit* vehicle) const; + bool IsOnVehicle(Unit const* vehicle) const; Unit* GetVehicleBase() const; Creature* GetVehicleCreatureBase() const; ObjectGuid GetTransGUID() const override; @@ -2174,12 +1847,12 @@ class TC_GAME_API Unit : public WorldObject bool HandleSpellClick(Unit* clicker, int8 seatId = -1); void EnterVehicle(Unit* base, int8 seatId = -1); - void ExitVehicle(Position const* exitPosition = NULL); + void ExitVehicle(Position const* exitPosition = nullptr); void ChangeSeat(int8 seatId, bool next = true); // Should only be called by AuraEffect::HandleAuraControlVehicle(AuraApplication const* auraApp, uint8 mode, bool apply) const; - void _ExitVehicle(Position const* exitPosition = NULL); - void _EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp = NULL); + void _ExitVehicle(Position const* exitPosition = nullptr); + void _EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp = nullptr); void BuildMovementPacket(ByteBuffer* data) const; static void BuildMovementPacket(Position const& pos, Position const& transportPos, MovementInfo const& movementInfo, ByteBuffer* data); @@ -2198,14 +1871,14 @@ class TC_GAME_API Unit : public WorldObject virtual bool IsLoading() const { return false; } bool IsDuringRemoveFromWorld() const {return m_duringRemoveFromWorld;} - Pet* ToPet() { if (IsPet()) return reinterpret_cast<Pet*>(this); else return NULL; } - Pet const* ToPet() const { if (IsPet()) return reinterpret_cast<Pet const*>(this); else return NULL; } + Pet* ToPet() { if (IsPet()) return reinterpret_cast<Pet*>(this); else return nullptr; } + Pet const* ToPet() const { if (IsPet()) return reinterpret_cast<Pet const*>(this); else return nullptr; } - Totem* ToTotem() { if (IsTotem()) return reinterpret_cast<Totem*>(this); else return NULL; } - Totem const* ToTotem() const { if (IsTotem()) return reinterpret_cast<Totem const*>(this); else return NULL; } + Totem* ToTotem() { if (IsTotem()) return reinterpret_cast<Totem*>(this); else return nullptr; } + Totem const* ToTotem() const { if (IsTotem()) return reinterpret_cast<Totem const*>(this); else return nullptr; } - TempSummon* ToTempSummon() { if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return NULL; } - TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return NULL; } + TempSummon* ToTempSummon() { if (IsSummon()) return reinterpret_cast<TempSummon*>(this); else return nullptr; } + TempSummon const* ToTempSummon() const { if (IsSummon()) return reinterpret_cast<TempSummon const*>(this); else return nullptr; } ObjectGuid GetTarget() const { return GetGuidValue(UNIT_FIELD_TARGET); } virtual void SetTarget(ObjectGuid /*guid*/) = 0; @@ -2334,7 +2007,7 @@ class TC_GAME_API Unit : public WorldObject uint32 m_lastManaUse; // msecs TimeTrackerSmall m_movesplineTimer; - Diminishing m_Diminishing; + DiminishingReturn m_Diminishing[DIMINISHING_MAX]; // Manage all Units that are threatened by us HostileRefManager m_HostileRefManager; @@ -2409,4 +2082,5 @@ namespace Trinity bool const _ascending; }; } + #endif diff --git a/src/server/game/Entities/Unit/UnitDefines.h b/src/server/game/Entities/Unit/UnitDefines.h new file mode 100644 index 00000000000..47f0ed28923 --- /dev/null +++ b/src/server/game/Entities/Unit/UnitDefines.h @@ -0,0 +1,352 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef UnitDefines_h__ +#define UnitDefines_h__ + +#include "Define.h" +#include <string> + +#define BASE_MINDAMAGE 1.0f +#define BASE_MAXDAMAGE 2.0f +#define BASE_ATTACK_TIME 2000 + +#define MAX_EQUIPMENT_ITEMS 3 + +// byte value (UNIT_FIELD_BYTES_1, 0) +enum UnitStandStateType : uint8 +{ + UNIT_STAND_STATE_STAND = 0, + UNIT_STAND_STATE_SIT = 1, + UNIT_STAND_STATE_SIT_CHAIR = 2, + UNIT_STAND_STATE_SLEEP = 3, + UNIT_STAND_STATE_SIT_LOW_CHAIR = 4, + UNIT_STAND_STATE_SIT_MEDIUM_CHAIR = 5, + UNIT_STAND_STATE_SIT_HIGH_CHAIR = 6, + UNIT_STAND_STATE_DEAD = 7, + UNIT_STAND_STATE_KNEEL = 8, + UNIT_STAND_STATE_SUBMERGED = 9 +}; + +// byte flag value (UNIT_FIELD_BYTES_1, 2) +enum UnitStandFlags : uint8 +{ + UNIT_STAND_FLAGS_UNK1 = 0x01, + UNIT_STAND_FLAGS_CREEP = 0x02, + UNIT_STAND_FLAGS_UNTRACKABLE = 0x04, + UNIT_STAND_FLAGS_UNK4 = 0x08, + UNIT_STAND_FLAGS_UNK5 = 0x10, + UNIT_STAND_FLAGS_ALL = 0xFF +}; + +enum UnitBytes0Offsets : uint8 +{ + UNIT_BYTES_0_OFFSET_RACE = 0, + UNIT_BYTES_0_OFFSET_CLASS = 1, + UNIT_BYTES_0_OFFSET_GENDER = 2, + UNIT_BYTES_0_OFFSET_POWER_TYPE = 3, +}; + +enum UnitBytes1Offsets : uint8 +{ + UNIT_BYTES_1_OFFSET_STAND_STATE = 0, + UNIT_BYTES_1_OFFSET_PET_TALENTS = 1, + UNIT_BYTES_1_OFFSET_VIS_FLAG = 2, + UNIT_BYTES_1_OFFSET_ANIM_TIER = 3 +}; + +enum UnitBytes2Offsets : uint8 +{ + UNIT_BYTES_2_OFFSET_SHEATH_STATE = 0, + UNIT_BYTES_2_OFFSET_PVP_FLAG = 1, + UNIT_BYTES_2_OFFSET_PET_FLAGS = 2, + UNIT_BYTES_2_OFFSET_SHAPESHIFT_FORM = 3 +}; + +// byte flags value (UNIT_FIELD_BYTES_1, 3) +enum UnitBytes1_Flags : uint8 +{ + UNIT_BYTE1_FLAG_ALWAYS_STAND = 0x01, + UNIT_BYTE1_FLAG_HOVER = 0x02, + UNIT_BYTE1_FLAG_UNK_3 = 0x04, + UNIT_BYTE1_FLAG_ALL = 0xFF +}; + +// low byte (0 from 0..3) of UNIT_FIELD_BYTES_2 +enum SheathState : uint8 +{ + SHEATH_STATE_UNARMED = 0, // non prepared weapon + SHEATH_STATE_MELEE = 1, // prepared melee weapon + SHEATH_STATE_RANGED = 2 // prepared ranged weapon +}; + +#define MAX_SHEATH_STATE 3 + +// byte (1 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitPVPStateFlags : uint8 +{ + UNIT_BYTE2_FLAG_PVP = 0x01, + UNIT_BYTE2_FLAG_UNK1 = 0x02, + UNIT_BYTE2_FLAG_FFA_PVP = 0x04, + UNIT_BYTE2_FLAG_SANCTUARY = 0x08, + UNIT_BYTE2_FLAG_UNK4 = 0x10, + UNIT_BYTE2_FLAG_UNK5 = 0x20, + UNIT_BYTE2_FLAG_UNK6 = 0x40, + UNIT_BYTE2_FLAG_UNK7 = 0x80 +}; + +// byte (2 from 0..3) of UNIT_FIELD_BYTES_2 +enum UnitRename : uint8 +{ + UNIT_CAN_BE_RENAMED = 0x01, + UNIT_CAN_BE_ABANDONED = 0x02 +}; + +// Value masks for UNIT_FIELD_FLAGS +enum UnitFlags : uint32 +{ + UNIT_FLAG_SERVER_CONTROLLED = 0x00000001, // set only when unit movement is controlled by server - by SPLINE/MONSTER_MOVE packets, together with UNIT_FLAG_STUNNED; only set to units controlled by client; client function CGUnit_C::IsClientControlled returns false when set for owner + UNIT_FLAG_NON_ATTACKABLE = 0x00000002, // not attackable + UNIT_FLAG_REMOVE_CLIENT_CONTROL = 0x00000004, // This is a legacy flag used to disable movement player's movement while controlling other units, SMSG_CLIENT_CONTROL replaces this functionality clientside now. CONFUSED and FLEEING flags have the same effect on client movement asDISABLE_MOVE_CONTROL in addition to preventing spell casts/autoattack (they all allow climbing steeper hills and emotes while moving) + UNIT_FLAG_PVP_ATTACKABLE = 0x00000008, // allow apply pvp rules to attackable state in addition to faction dependent state + UNIT_FLAG_RENAME = 0x00000010, + UNIT_FLAG_PREPARATION = 0x00000020, // don't take reagents for spells with SPELL_ATTR5_NO_REAGENT_WHILE_PREP + UNIT_FLAG_UNK_6 = 0x00000040, + UNIT_FLAG_NOT_ATTACKABLE_1 = 0x00000080, // ?? (UNIT_FLAG_PVP_ATTACKABLE | UNIT_FLAG_NOT_ATTACKABLE_1) is NON_PVP_ATTACKABLE + UNIT_FLAG_IMMUNE_TO_PC = 0x00000100, // disables combat/assistance with PlayerCharacters (PC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget + UNIT_FLAG_IMMUNE_TO_NPC = 0x00000200, // disables combat/assistance with NonPlayerCharacters (NPC) - see Unit::_IsValidAttackTarget, Unit::_IsValidAssistTarget + UNIT_FLAG_LOOTING = 0x00000400, // loot animation + UNIT_FLAG_PET_IN_COMBAT = 0x00000800, // in combat?, 2.0.8 + UNIT_FLAG_PVP = 0x00001000, // changed in 3.0.3 + UNIT_FLAG_SILENCED = 0x00002000, // silenced, 2.1.1 + UNIT_FLAG_CANNOT_SWIM = 0x00004000, // 2.0.8 + UNIT_FLAG_UNK_15 = 0x00008000, + UNIT_FLAG_UNK_16 = 0x00010000, + UNIT_FLAG_PACIFIED = 0x00020000, // 3.0.3 ok + UNIT_FLAG_STUNNED = 0x00040000, // 3.0.3 ok + UNIT_FLAG_IN_COMBAT = 0x00080000, + UNIT_FLAG_TAXI_FLIGHT = 0x00100000, // disable casting at client side spell not allowed by taxi flight (mounted?), probably used with 0x4 flag + UNIT_FLAG_DISARMED = 0x00200000, // 3.0.3, disable melee spells casting..., "Required melee weapon" added to melee spells tooltip. + UNIT_FLAG_CONFUSED = 0x00400000, + UNIT_FLAG_FLEEING = 0x00800000, + UNIT_FLAG_PLAYER_CONTROLLED = 0x01000000, // used in spell Eyes of the Beast for pet... let attack by controlled creature + UNIT_FLAG_NOT_SELECTABLE = 0x02000000, + UNIT_FLAG_SKINNABLE = 0x04000000, + UNIT_FLAG_MOUNT = 0x08000000, + UNIT_FLAG_UNK_28 = 0x10000000, + UNIT_FLAG_UNK_29 = 0x20000000, // used in Feing Death spell + UNIT_FLAG_SHEATHE = 0x40000000, + UNIT_FLAG_UNK_31 = 0x80000000, + MAX_UNIT_FLAGS = 33 +}; + +// Value masks for UNIT_FIELD_FLAGS_2 +enum UnitFlags2 : uint32 +{ + UNIT_FLAG2_FEIGN_DEATH = 0x00000001, + UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip) + UNIT_FLAG2_IGNORE_REPUTATION = 0x00000004, + UNIT_FLAG2_COMPREHEND_LANG = 0x00000008, + UNIT_FLAG2_MIRROR_IMAGE = 0x00000010, + UNIT_FLAG2_INSTANTLY_APPEAR_MODEL = 0x00000020, // Unit model instantly appears when summoned (does not fade in) + UNIT_FLAG2_FORCE_MOVEMENT = 0x00000040, + UNIT_FLAG2_DISARM_OFFHAND = 0x00000080, + UNIT_FLAG2_DISABLE_PRED_STATS = 0x00000100, // Player has disabled predicted stats (Used by raid frames) + UNIT_FLAG2_DISARM_RANGED = 0x00000400, // this does not disable ranged weapon display (maybe additional flag needed?) + UNIT_FLAG2_REGENERATE_POWER = 0x00000800, + UNIT_FLAG2_RESTRICT_PARTY_INTERACTION = 0x00001000, // Restrict interaction to party or raid + UNIT_FLAG2_PREVENT_SPELL_CLICK = 0x00002000, // Prevent spellclick + UNIT_FLAG2_ALLOW_ENEMY_INTERACT = 0x00004000, + UNIT_FLAG2_DISABLE_TURN = 0x00008000, + UNIT_FLAG2_UNK2 = 0x00010000, + UNIT_FLAG2_PLAY_DEATH_ANIM = 0x00020000, // Plays special death animation upon death + UNIT_FLAG2_ALLOW_CHEAT_SPELLS = 0x00040000 // Allows casting spells with AttributesEx7 & SPELL_ATTR7_IS_CHEAT_SPELL +}; + +/// Non Player Character flags +enum NPCFlags : uint32 +{ + UNIT_NPC_FLAG_NONE = 0x00000000, + UNIT_NPC_FLAG_GOSSIP = 0x00000001, // 100% + UNIT_NPC_FLAG_QUESTGIVER = 0x00000002, // guessed, probably ok + UNIT_NPC_FLAG_UNK1 = 0x00000004, + UNIT_NPC_FLAG_UNK2 = 0x00000008, + UNIT_NPC_FLAG_TRAINER = 0x00000010, // 100% + UNIT_NPC_FLAG_TRAINER_CLASS = 0x00000020, // 100% + UNIT_NPC_FLAG_TRAINER_PROFESSION = 0x00000040, // 100% + UNIT_NPC_FLAG_VENDOR = 0x00000080, // 100% + UNIT_NPC_FLAG_VENDOR_AMMO = 0x00000100, // 100%, general goods vendor + UNIT_NPC_FLAG_VENDOR_FOOD = 0x00000200, // 100% + UNIT_NPC_FLAG_VENDOR_POISON = 0x00000400, // guessed + UNIT_NPC_FLAG_VENDOR_REAGENT = 0x00000800, // 100% + UNIT_NPC_FLAG_REPAIR = 0x00001000, // 100% + UNIT_NPC_FLAG_FLIGHTMASTER = 0x00002000, // 100% + UNIT_NPC_FLAG_SPIRITHEALER = 0x00004000, // guessed + UNIT_NPC_FLAG_SPIRITGUIDE = 0x00008000, // guessed + UNIT_NPC_FLAG_INNKEEPER = 0x00010000, // 100% + UNIT_NPC_FLAG_BANKER = 0x00020000, // 100% + UNIT_NPC_FLAG_PETITIONER = 0x00040000, // 100% 0xC0000 = guild petitions, 0x40000 = arena team petitions + UNIT_NPC_FLAG_TABARDDESIGNER = 0x00080000, // 100% + UNIT_NPC_FLAG_BATTLEMASTER = 0x00100000, // 100% + UNIT_NPC_FLAG_AUCTIONEER = 0x00200000, // 100% + UNIT_NPC_FLAG_STABLEMASTER = 0x00400000, // 100% + UNIT_NPC_FLAG_GUILD_BANKER = 0x00800000, // cause client to send 997 opcode + UNIT_NPC_FLAG_SPELLCLICK = 0x01000000, // cause client to send 1015 opcode (spell click) + UNIT_NPC_FLAG_PLAYER_VEHICLE = 0x02000000, // players with mounts that have vehicle data should have it set + UNIT_NPC_FLAG_MAILBOX = 0x04000000 // +}; + +enum MovementFlags : uint32 +{ + MOVEMENTFLAG_NONE = 0x00000000, + MOVEMENTFLAG_FORWARD = 0x00000001, + MOVEMENTFLAG_BACKWARD = 0x00000002, + MOVEMENTFLAG_STRAFE_LEFT = 0x00000004, + MOVEMENTFLAG_STRAFE_RIGHT = 0x00000008, + MOVEMENTFLAG_LEFT = 0x00000010, + MOVEMENTFLAG_RIGHT = 0x00000020, + MOVEMENTFLAG_PITCH_UP = 0x00000040, + MOVEMENTFLAG_PITCH_DOWN = 0x00000080, + MOVEMENTFLAG_WALKING = 0x00000100, // Walking + MOVEMENTFLAG_ONTRANSPORT = 0x00000200, // Used for flying on some creatures + MOVEMENTFLAG_DISABLE_GRAVITY = 0x00000400, // Former MOVEMENTFLAG_LEVITATING. This is used when walking is not possible. + MOVEMENTFLAG_ROOT = 0x00000800, // Must not be set along with MOVEMENTFLAG_MASK_MOVING + MOVEMENTFLAG_FALLING = 0x00001000, // damage dealt on that type of falling + MOVEMENTFLAG_FALLING_FAR = 0x00002000, + MOVEMENTFLAG_PENDING_STOP = 0x00004000, + MOVEMENTFLAG_PENDING_STRAFE_STOP = 0x00008000, + MOVEMENTFLAG_PENDING_FORWARD = 0x00010000, + MOVEMENTFLAG_PENDING_BACKWARD = 0x00020000, + MOVEMENTFLAG_PENDING_STRAFE_LEFT = 0x00040000, + MOVEMENTFLAG_PENDING_STRAFE_RIGHT = 0x00080000, + MOVEMENTFLAG_PENDING_ROOT = 0x00100000, + MOVEMENTFLAG_SWIMMING = 0x00200000, // appears with fly flag also + MOVEMENTFLAG_ASCENDING = 0x00400000, // press "space" when flying + MOVEMENTFLAG_DESCENDING = 0x00800000, + MOVEMENTFLAG_CAN_FLY = 0x01000000, // Appears when unit can fly AND also walk + MOVEMENTFLAG_FLYING = 0x02000000, // unit is actually flying. pretty sure this is only used for players. creatures use disable_gravity + MOVEMENTFLAG_SPLINE_ELEVATION = 0x04000000, // used for flight paths + MOVEMENTFLAG_SPLINE_ENABLED = 0x08000000, // used for flight paths + MOVEMENTFLAG_WATERWALKING = 0x10000000, // prevent unit from falling through water + MOVEMENTFLAG_FALLING_SLOW = 0x20000000, // active rogue safe fall spell (passive) + MOVEMENTFLAG_HOVER = 0x40000000, // hover, cannot jump + + MOVEMENTFLAG_MASK_MOVING = + MOVEMENTFLAG_FORWARD | MOVEMENTFLAG_BACKWARD | MOVEMENTFLAG_STRAFE_LEFT | MOVEMENTFLAG_STRAFE_RIGHT | + MOVEMENTFLAG_FALLING | MOVEMENTFLAG_FALLING_FAR | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING | + MOVEMENTFLAG_SPLINE_ELEVATION, + + MOVEMENTFLAG_MASK_TURNING = + MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT | MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN, + + MOVEMENTFLAG_MASK_MOVING_FLY = + MOVEMENTFLAG_FLYING | MOVEMENTFLAG_ASCENDING | MOVEMENTFLAG_DESCENDING, + + /// @todo if needed: add more flags to this masks that are exclusive to players + MOVEMENTFLAG_MASK_PLAYER_ONLY = + MOVEMENTFLAG_FLYING, + + /// Movement flags that have change status opcodes associated for players + MOVEMENTFLAG_MASK_HAS_PLAYER_STATUS_OPCODE = MOVEMENTFLAG_DISABLE_GRAVITY | MOVEMENTFLAG_ROOT | + MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_WATERWALKING | MOVEMENTFLAG_FALLING_SLOW | MOVEMENTFLAG_HOVER +}; + +enum MovementFlags2 : uint32 +{ + MOVEMENTFLAG2_NONE = 0x00000000, + MOVEMENTFLAG2_NO_STRAFE = 0x00000001, + MOVEMENTFLAG2_NO_JUMPING = 0x00000002, + MOVEMENTFLAG2_UNK3 = 0x00000004, // Overrides various clientside checks + MOVEMENTFLAG2_FULL_SPEED_TURNING = 0x00000008, + MOVEMENTFLAG2_FULL_SPEED_PITCHING = 0x00000010, + MOVEMENTFLAG2_ALWAYS_ALLOW_PITCHING = 0x00000020, + MOVEMENTFLAG2_UNK7 = 0x00000040, + MOVEMENTFLAG2_UNK8 = 0x00000080, + MOVEMENTFLAG2_UNK9 = 0x00000100, + MOVEMENTFLAG2_UNK10 = 0x00000200, + MOVEMENTFLAG2_INTERPOLATED_MOVEMENT = 0x00000400, + MOVEMENTFLAG2_INTERPOLATED_TURNING = 0x00000800, + MOVEMENTFLAG2_INTERPOLATED_PITCHING = 0x00001000, + MOVEMENTFLAG2_UNK14 = 0x00002000, + MOVEMENTFLAG2_UNK15 = 0x00004000, + MOVEMENTFLAG2_UNK16 = 0x00008000 +}; + +enum HitInfo +{ + HITINFO_NORMALSWING = 0x00000000, + HITINFO_UNK1 = 0x00000001, // req correct packet structure + HITINFO_AFFECTS_VICTIM = 0x00000002, + HITINFO_OFFHAND = 0x00000004, + HITINFO_UNK2 = 0x00000008, + HITINFO_MISS = 0x00000010, + HITINFO_FULL_ABSORB = 0x00000020, + HITINFO_PARTIAL_ABSORB = 0x00000040, + HITINFO_FULL_RESIST = 0x00000080, + HITINFO_PARTIAL_RESIST = 0x00000100, + HITINFO_CRITICALHIT = 0x00000200, // critical hit + HITINFO_UNK10 = 0x00000400, + HITINFO_UNK11 = 0x00000800, + HITINFO_UNK12 = 0x00001000, + HITINFO_BLOCK = 0x00002000, // blocked damage + HITINFO_UNK14 = 0x00004000, // set only if meleespellid is present// no world text when victim is hit for 0 dmg(HideWorldTextForNoDamage?) + HITINFO_UNK15 = 0x00008000, // player victim?// something related to blod sprut visual (BloodSpurtInBack?) + HITINFO_GLANCING = 0x00010000, + HITINFO_CRUSHING = 0x00020000, + HITINFO_NO_ANIMATION = 0x00040000, + HITINFO_UNK19 = 0x00080000, + HITINFO_UNK20 = 0x00100000, + HITINFO_SWINGNOHITSOUND = 0x00200000, // unused? + HITINFO_UNK22 = 0x00400000, + HITINFO_RAGE_GAIN = 0x00800000, + HITINFO_FAKE_DAMAGE = 0x01000000 // enables damage animation even if no damage done, set only if no damage +}; + +#define MAX_DECLINED_NAME_CASES 5 + +struct DeclinedName +{ + std::string name[MAX_DECLINED_NAME_CASES]; +}; + +enum ActiveStates +{ + ACT_PASSIVE = 0x01, // 0x01 - passive + ACT_DISABLED = 0x81, // 0x80 - castable + ACT_ENABLED = 0xC1, // 0x40 | 0x80 - auto cast + castable + ACT_COMMAND = 0x07, // 0x01 | 0x02 | 0x04 + ACT_REACTION = 0x06, // 0x02 | 0x04 + ACT_DECIDE = 0x00 // custom +}; + +enum ReactStates +{ + REACT_PASSIVE = 0, + REACT_DEFENSIVE = 1, + REACT_AGGRESSIVE = 2 +}; + +enum CommandStates : uint8 +{ + COMMAND_STAY = 0, + COMMAND_FOLLOW = 1, + COMMAND_ATTACK = 2, + COMMAND_ABANDON = 3 +}; + +#endif // UnitDefines_h__ diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index 8c71df670ad..357cceb99b6 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -16,19 +16,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Vehicle.h" +#include "Battleground.h" #include "Common.h" +#include "CreatureAI.h" +#include "DBCStores.h" +#include "EventProcessor.h" #include "Log.h" +#include "MoveSplineInit.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "Vehicle.h" -#include "Unit.h" -#include "Util.h" +#include "Player.h" #include "ScriptMgr.h" -#include "CreatureAI.h" -#include "MoveSplineInit.h" #include "TemporarySummon.h" -#include "EventProcessor.h" -#include "Player.h" -#include "Battleground.h" +#include "Unit.h" +#include "Util.h" Vehicle::Vehicle(Unit* unit, VehicleEntry const* vehInfo, uint32 creatureEntry) : UsableSeatNum(0), _me(unit), _vehicleInfo(vehInfo), _creatureEntry(creatureEntry), _status(STATUS_NONE), _lastShootPos() @@ -239,7 +241,7 @@ void Vehicle::RemoveAllPassengers() /// This will properly "reset" the pending join process for the passenger. { /// Update vehicle pointer in every pending join event - Abort may be called after vehicle is deleted - Vehicle* eventVehicle = _status != STATUS_UNINSTALLING ? this : NULL; + Vehicle* eventVehicle = _status != STATUS_UNINSTALLING ? this : nullptr; while (!_pendingJoinEvents.empty()) { @@ -300,7 +302,7 @@ Unit* Vehicle::GetPassenger(int8 seatId) const { SeatMap::const_iterator seat = Seats.find(seatId); if (seat == Seats.end()) - return NULL; + return nullptr; return ObjectAccessor::GetUnit(*GetBase(), seat->second.Passenger.Guid); } @@ -480,7 +482,7 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) Vehicle* Vehicle::RemovePassenger(Unit* unit) { if (unit->GetVehicle() != this) - return NULL; + return nullptr; SeatMap::iterator seat = GetSeatIteratorForPassenger(unit); ASSERT(seat != Seats.end()); @@ -521,7 +523,7 @@ Vehicle* Vehicle::RemovePassenger(Unit* unit) if (GetBase()->GetTypeId() == TYPEID_UNIT) sScriptMgr->OnRemovePassenger(this, unit); - unit->SetVehicle(NULL); + unit->SetVehicle(nullptr); return this; } @@ -623,7 +625,7 @@ VehicleSeatEntry const* Vehicle::GetSeatForPassenger(Unit const* passenger) cons if (itr->second.Passenger.Guid == passenger->GetGUID()) return itr->second.SeatInfo; - return NULL; + return nullptr; } /** diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index 08f3e7f8f1a..d022174bd08 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -87,7 +87,7 @@ class TC_GAME_API Vehicle : public TransportBase void InitMovementInfoForBase(); /// This method transforms supplied transport offsets into global coordinates - void CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= NULL*/) const override + void CalculatePassengerPosition(float& x, float& y, float& z, float* o /*= nullptr*/) const override { TransportBase::CalculatePassengerPosition(x, y, z, o, GetBase()->GetPositionX(), GetBase()->GetPositionY(), @@ -95,7 +95,7 @@ class TC_GAME_API Vehicle : public TransportBase } /// This method transforms supplied global coordinates into local offsets - void CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= NULL*/) const override + void CalculatePassengerOffset(float& x, float& y, float& z, float* o /*= nullptr*/) const override { TransportBase::CalculatePassengerOffset(x, y, z, o, GetBase()->GetPositionX(), GetBase()->GetPositionY(), diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index 0b53465bba6..e4d41276d64 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -102,10 +102,10 @@ protected: public: /// This method transforms supplied transport offsets into global coordinates - virtual void CalculatePassengerPosition(float& x, float& y, float& z, float* o = NULL) const = 0; + virtual void CalculatePassengerPosition(float& x, float& y, float& z, float* o = nullptr) const = 0; /// This method transforms supplied global coordinates into local offsets - virtual void CalculatePassengerOffset(float& x, float& y, float& z, float* o = NULL) const = 0; + virtual void CalculatePassengerOffset(float& x, float& y, float& z, float* o = nullptr) const = 0; protected: static void CalculatePassengerPosition(float& x, float& y, float& z, float* o, float transX, float transY, float transZ, float transO) diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index b126eb9c644..fc00ce5ee9e 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -17,17 +17,19 @@ */ #include "GameEventMgr.h" -#include "World.h" -#include "ObjectMgr.h" -#include "WorldPacket.h" -#include "PoolMgr.h" +#include "BattlegroundMgr.h" +#include "CreatureAI.h" +#include "DBCStores.h" +#include "DatabaseEnv.h" +#include "GameObjectAI.h" #include "Language.h" #include "Log.h" #include "MapManager.h" +#include "ObjectMgr.h" +#include "PoolMgr.h" #include "Player.h" -#include "BattlegroundMgr.h" -#include "UnitAI.h" -#include "GameObjectAI.h" +#include "World.h" +#include "WorldPacket.h" GameEventMgr* GameEventMgr::instance() { @@ -42,7 +44,7 @@ bool GameEventMgr::CheckOneGameEvent(uint16 entry) const default: case GAMEEVENT_NORMAL: { - time_t currenttime = time(NULL); + time_t currenttime = time(nullptr); // Get the event information return mGameEvent[entry].start < currenttime && currenttime < mGameEvent[entry].end @@ -59,7 +61,7 @@ bool GameEventMgr::CheckOneGameEvent(uint16 entry) const // if inactive world event, check the prerequisite events case GAMEEVENT_WORLD_INACTIVE: { - time_t currenttime = time(NULL); + time_t currenttime = time(nullptr); for (std::set<uint16>::const_iterator itr = mGameEvent[entry].prerequisite_events.begin(); itr != mGameEvent[entry].prerequisite_events.end(); ++itr) { if ((mGameEvent[*itr].state != GAMEEVENT_WORLD_NEXTPHASE && mGameEvent[*itr].state != GAMEEVENT_WORLD_FINISHED) || // if prereq not in nextphase or finished state, then can't start this one @@ -75,7 +77,7 @@ bool GameEventMgr::CheckOneGameEvent(uint16 entry) const uint32 GameEventMgr::NextCheck(uint16 entry) const { - time_t currenttime = time(NULL); + time_t currenttime = time(nullptr); // for NEXTPHASE state world events, return the delay to start the next event, so the followup event will be checked correctly if ((mGameEvent[entry].state == GAMEEVENT_WORLD_NEXTPHASE || mGameEvent[entry].state == GAMEEVENT_WORLD_FINISHED) && mGameEvent[entry].nextstart >= currenttime) @@ -135,13 +137,13 @@ bool GameEventMgr::StartEvent(uint16 event_id, bool overwrite) ApplyNewEvent(event_id); if (overwrite) { - mGameEvent[event_id].start = time(NULL); + mGameEvent[event_id].start = time(nullptr); if (data.end <= data.start) data.end = data.start + data.length; } // When event is started, set its worldstate to current time - sWorld->setWorldState(event_id, time(NULL)); + sWorld->setWorldState(event_id, time(nullptr)); return false; } else @@ -182,7 +184,7 @@ void GameEventMgr::StopEvent(uint16 event_id, bool overwrite) if (overwrite && !serverwide_evt) { - data.start = time(NULL) - data.length * MINUTE; + data.start = time(nullptr) - data.length * MINUTE; if (data.end <= data.start) data.end = data.start + data.length; } @@ -464,7 +466,7 @@ void GameEventMgr::LoadFromDB() // 0 1 2 3 4 QueryResult result = WorldDatabase.Query("SELECT creature.guid, creature.id, game_event_model_equip.eventEntry, game_event_model_equip.modelid, game_event_model_equip.equipment_id " - "FROM creature JOIN game_event_model_equip ON creature.guid=game_event_model_equip.guid"); + "FROM creature JOIN game_event_model_equip ON creature.guid = game_event_model_equip.guid"); if (!result) TC_LOG_INFO("server.loading", ">> Loaded 0 model/equipment changes in game events. DB table `game_event_model_equip` is empty."); @@ -834,7 +836,7 @@ void GameEventMgr::LoadFromDB() newEntry.entry = data->id; // check validity with event's npcflag - if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, NULL, NULL, event_npc_flag)) + if (!sObjectMgr->IsVendorItemValid(newEntry.entry, newEntry.item, newEntry.maxcount, newEntry.incrtime, newEntry.ExtendedCost, nullptr, nullptr, event_npc_flag)) continue; vendors.push_back(newEntry); @@ -1004,7 +1006,7 @@ void GameEventMgr::StartArenaSeason() uint32 GameEventMgr::Update() // return the next event delay in ms { - time_t currenttime = time(NULL); + time_t currenttime = time(nullptr); uint32 nextEventDelay = max_ge_check_delay; // 1 day uint32 calcDelay; std::set<uint16> activate, deactivate; @@ -1592,7 +1594,7 @@ bool GameEventMgr::CheckOneGameEventConditions(uint16 event_id) // set the followup events' start time if (!mGameEvent[event_id].nextstart) { - time_t currenttime = time(NULL); + time_t currenttime = time(nullptr); mGameEvent[event_id].nextstart = currenttime + mGameEvent[event_id].length * 60; } return true; diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index 05737b23426..bee6dfc8fb3 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -23,6 +23,11 @@ #include "ObjectGuid.h" #include "SharedDefines.h" #include "Define.h" +#include <list> +#include <map> +#include <set> +#include <unordered_map> +#include <vector> #define max_ge_check_delay DAY // 1 day in seconds diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 71da19b1bc6..d4dfb96485e 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -37,6 +37,10 @@ template<class T> void HashMapHolder<T>::Insert(T* o) { + static_assert(std::is_same<Player, T>::value + || std::is_same<Transport, T>::value, + "Only Player and Transport can be registered in global HashMapHolder"); + boost::unique_lock<boost::shared_mutex> lock(*GetLock()); GetContainer()[o->GetGUID()] = o; @@ -56,7 +60,7 @@ T* HashMapHolder<T>::Find(ObjectGuid guid) boost::shared_lock<boost::shared_mutex> lock(*GetLock()); typename MapType::iterator itr = GetContainer().find(guid); - return (itr != GetContainer().end()) ? itr->second : NULL; + return (itr != GetContainer().end()) ? itr->second : nullptr; } template<class T> @@ -120,7 +124,7 @@ WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid con case HighGuid::Pet: return GetPet(p, guid); case HighGuid::DynamicObject: return GetDynamicObject(p, guid); case HighGuid::Corpse: return GetCorpse(p, guid); - default: return NULL; + default: return nullptr; } } @@ -161,7 +165,7 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid con break; } - return NULL; + return nullptr; } Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, ObjectGuid const& guid) @@ -227,7 +231,7 @@ Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, Object if (guid.IsCreatureOrVehicle()) return GetCreature(u, guid); - return NULL; + return nullptr; } Player* ObjectAccessor::FindPlayer(ObjectGuid const& guid) diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index b86ccccd5da..bc4062eed77 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -19,27 +19,25 @@ #ifndef TRINITY_OBJECTACCESSOR_H #define TRINITY_OBJECTACCESSOR_H -#include <mutex> -#include <set> +#include "ObjectGuid.h" #include <unordered_map> -#include <boost/thread/locks.hpp> -#include <boost/thread/shared_mutex.hpp> -#include "Define.h" -#include "GridDefines.h" -#include "UpdateData.h" -#include "Object.h" - -class Creature; class Corpse; -class Unit; -class GameObject; +class Creature; class DynamicObject; -class WorldObject; -class Vehicle; +class GameObject; class Map; -class WorldRunnable; +class Object; +class Pet; +class Player; class Transport; +class Unit; +class WorldObject; + +namespace boost +{ + class shared_mutex; +} template <class T> class TC_GAME_API HashMapHolder @@ -48,9 +46,6 @@ class TC_GAME_API HashMapHolder HashMapHolder() { } public: - static_assert(std::is_same<Player, T>::value - || std::is_same<Transport, T>::value, - "Only Player and Transport can be registered in global HashMapHolder"); typedef std::unordered_map<ObjectGuid, T*> MapType; diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 048eff35504..1b7713ab363 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -16,16 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "AccountMgr.h" +#include "ObjectMgr.h" #include "AchievementMgr.h" -#include "ArenaTeam.h" #include "ArenaTeamMgr.h" -#include "BattlegroundMgr.h" +#include "Bag.h" #include "Chat.h" -#include "Common.h" #include "CreatureAIFactory.h" #include "DatabaseEnv.h" #include "DisableMgr.h" +#include "GameObject.h" #include "GameObjectAIFactory.h" #include "GossipDef.h" #include "GroupMgr.h" @@ -34,22 +33,26 @@ #include "Language.h" #include "LFGMgr.h" #include "Log.h" +#include "LootMgr.h" +#include "Mail.h" #include "MapManager.h" -#include "Object.h" -#include "ObjectMgr.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" +#include "Player.h" #include "PoolMgr.h" +#include "QueryPackets.h" +#include "Random.h" #include "ReputationMgr.h" #include "ScriptMgr.h" #include "SpellAuras.h" #include "SpellMgr.h" #include "SpellScript.h" +#include "TemporarySummon.h" #include "UpdateMask.h" #include "Util.h" #include "Vehicle.h" #include "World.h" -#include "Packets/QueryPackets.h" - ScriptMapMap sSpellScripts; ScriptMapMap sEventScripts; ScriptMapMap sWaypointScripts; @@ -284,7 +287,7 @@ ObjectMgr::~ObjectMgr() delete itr->second; } -void ObjectMgr::AddLocaleString(std::string const& value, LocaleConstant localeConstant, StringVector& data) +void ObjectMgr::AddLocaleString(std::string const& value, LocaleConstant localeConstant, std::vector<std::string>& data) { if (!value.empty()) { @@ -1128,7 +1131,7 @@ void ObjectMgr::LoadGameObjectAddons() } GameObjectAddon& gameObjectAddon = _gameObjectAddonStore[guid]; - gameObjectAddon.ParentRotation = G3D::Quat(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); + gameObjectAddon.ParentRotation = QuaternionData(fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); gameObjectAddon.invisibilityType = InvisibilityType(fields[5].GetUInt8()); gameObjectAddon.InvisibilityValue = fields[6].GetUInt32(); @@ -1148,7 +1151,7 @@ void ObjectMgr::LoadGameObjectAddons() if (!gameObjectAddon.ParentRotation.isUnit()) { TC_LOG_ERROR("sql.sql", "GameObject (GUID: %u) has invalid parent rotation in `gameobject_addon`, set to default", guid); - gameObjectAddon.ParentRotation = G3D::Quat(); + gameObjectAddon.ParentRotation = QuaternionData(); } ++count; @@ -1310,7 +1313,7 @@ uint32 ObjectMgr::ChooseDisplayId(CreatureTemplate const* cinfo, CreatureData co return cinfo->GetFirstInvisibleModel(); } -void ObjectMgr::ChooseCreatureFlags(const CreatureTemplate* cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, const CreatureData* data /*= nullptr*/) +void ObjectMgr::ChooseCreatureFlags(CreatureTemplate const* cinfo, uint32& npcflag, uint32& unit_flags, uint32& dynamicflags, CreatureData const* data /*= nullptr*/) { npcflag = cinfo->npcflag; unit_flags = cinfo->unit_flags; @@ -1442,7 +1445,7 @@ void ObjectMgr::LoadLinkedRespawn() { case CREATURE_TO_CREATURE: { - const CreatureData* slave = GetCreatureData(guidLow); + CreatureData const* slave = GetCreatureData(guidLow); if (!slave) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) '%u' not found in creature table", guidLow); @@ -1450,7 +1453,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const CreatureData* master = GetCreatureData(linkedGuidLow); + CreatureData const* master = GetCreatureData(linkedGuidLow); if (!master) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) '%u' not found in creature table", linkedGuidLow); @@ -1458,7 +1461,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const MapEntry* const map = sMapStore.LookupEntry(master->mapid); + MapEntry const* const map = sMapStore.LookupEntry(master->mapid); if (!map || !map->Instanceable() || (master->mapid != slave->mapid)) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '%u' linking to Creature '%u' on an unpermitted map.", guidLow, linkedGuidLow); @@ -1479,7 +1482,7 @@ void ObjectMgr::LoadLinkedRespawn() } case CREATURE_TO_GO: { - const CreatureData* slave = GetCreatureData(guidLow); + CreatureData const* slave = GetCreatureData(guidLow); if (!slave) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature (guid) '%u' not found in creature table", guidLow); @@ -1487,7 +1490,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const GameObjectData* master = GetGOData(linkedGuidLow); + GameObjectData const* master = GetGOData(linkedGuidLow); if (!master) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) '%u' not found in gameobject table", linkedGuidLow); @@ -1495,7 +1498,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const MapEntry* const map = sMapStore.LookupEntry(master->mapid); + MapEntry const* const map = sMapStore.LookupEntry(master->mapid); if (!map || !map->Instanceable() || (master->mapid != slave->mapid)) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature '%u' linking to Gameobject '%u' on an unpermitted map.", guidLow, linkedGuidLow); @@ -1516,7 +1519,7 @@ void ObjectMgr::LoadLinkedRespawn() } case GO_TO_GO: { - const GameObjectData* slave = GetGOData(guidLow); + GameObjectData const* slave = GetGOData(guidLow); if (!slave) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) '%u' not found in gameobject table", guidLow); @@ -1524,7 +1527,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const GameObjectData* master = GetGOData(linkedGuidLow); + GameObjectData const* master = GetGOData(linkedGuidLow); if (!master) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (linkedGuid) '%u' not found in gameobject table", linkedGuidLow); @@ -1532,7 +1535,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const MapEntry* const map = sMapStore.LookupEntry(master->mapid); + MapEntry const* const map = sMapStore.LookupEntry(master->mapid); if (!map || !map->Instanceable() || (master->mapid != slave->mapid)) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '%u' linking to Gameobject '%u' on an unpermitted map.", guidLow, linkedGuidLow); @@ -1553,7 +1556,7 @@ void ObjectMgr::LoadLinkedRespawn() } case GO_TO_CREATURE: { - const GameObjectData* slave = GetGOData(guidLow); + GameObjectData const* slave = GetGOData(guidLow); if (!slave) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject (guid) '%u' not found in gameobject table", guidLow); @@ -1561,7 +1564,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const CreatureData* master = GetCreatureData(linkedGuidLow); + CreatureData const* master = GetCreatureData(linkedGuidLow); if (!master) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Creature (linkedGuid) '%u' not found in creature table", linkedGuidLow); @@ -1569,7 +1572,7 @@ void ObjectMgr::LoadLinkedRespawn() break; } - const MapEntry* const map = sMapStore.LookupEntry(master->mapid); + MapEntry const* const map = sMapStore.LookupEntry(master->mapid); if (!map || !map->Instanceable() || (master->mapid != slave->mapid)) { TC_LOG_ERROR("sql.sql", "LinkedRespawn: Gameobject '%u' linking to Creature '%u' on an unpermitted map.", guidLow, linkedGuidLow); @@ -1838,7 +1841,7 @@ void ObjectMgr::LoadCreatures() if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_INSTANCE_BIND) { - if (!mapEntry || !mapEntry->IsDungeon()) + if (!mapEntry->IsDungeon()) TC_LOG_ERROR("sql.sql", "Table `creature` has creature (GUID: %u Entry: %u) with `creature_template`.`flags_extra` including CREATURE_FLAG_EXTRA_INSTANCE_BIND but creature is not in instance.", guid, data.id); } @@ -1934,7 +1937,7 @@ void ObjectMgr::RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData co } } -ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, Position const& pos, G3D::Quat const& rot, uint32 spawntimedelay /*= 0*/) +ObjectGuid::LowType ObjectMgr::AddGOData(uint32 entry, uint32 mapId, Position const& pos, QuaternionData const& rot, uint32 spawntimedelay /*= 0*/) { GameObjectTemplate const* goinfo = GetGameObjectTemplate(entry); if (!goinfo) @@ -4670,6 +4673,18 @@ void ObjectMgr::LoadQuests() TC_LOG_INFO("server.loading", ">> Loaded %lu quests definitions in %u ms", (unsigned long)_questTemplates.size(), GetMSTimeDiffToNow(oldMSTime)); } +void ObjectMgr::LoadQuestStartersAndEnders() +{ + TC_LOG_INFO("server.loading", "Loading GO Start Quest Data..."); + LoadGameobjectQuestStarters(); + TC_LOG_INFO("server.loading", "Loading GO End Quest Data..."); + LoadGameobjectQuestEnders(); + TC_LOG_INFO("server.loading", "Loading Creature Start Quest Data..."); + LoadCreatureQuestStarters(); + TC_LOG_INFO("server.loading", "Loading Creature End Quest Data..."); + LoadCreatureQuestEnders(); +} + void ObjectMgr::LoadQuestLocales() { uint32 oldMSTime = getMSTime(); @@ -5957,7 +5972,7 @@ void ObjectMgr::LoadGraveyardZones() { uint32 oldMSTime = getMSTime(); - GraveYardStore.clear(); // need for reload case + GraveyardStore.clear(); // need for reload case // 0 1 2 QueryResult result = WorldDatabase.Query("SELECT ID, GhostZone, Faction FROM graveyard_zone"); @@ -6006,14 +6021,14 @@ void ObjectMgr::LoadGraveyardZones() continue; } - if (!AddGraveYardLink(safeLocId, zoneId, team, false)) + if (!AddGraveyardLink(safeLocId, zoneId, team, false)) TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` has a duplicate record for Graveyard (ID: %u) and Zone (ID: %u), skipped.", safeLocId, zoneId); } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u graveyard-zone links in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } -WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveYard(uint32 team) const +WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveyard(uint32 team) const { enum DefaultGraveyard { @@ -6028,7 +6043,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveYard(uint32 team) const else return nullptr; } -WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) const +WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveyard(float x, float y, float z, uint32 MapId, uint32 team) const { // search for zone associated closest graveyard uint32 zoneId = sMapMgr->GetZoneId(MapId, x, y, z); @@ -6038,7 +6053,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float if (z > -500) { TC_LOG_ERROR("misc", "ZoneId not found for map %u coords (%f, %f, %f)", MapId, x, y, z); - return GetDefaultGraveYard(team); + return GetDefaultGraveyard(team); } } @@ -6049,7 +6064,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float // then check faction // if mapId != graveyard.mapId (ghost in instance) and search any graveyard associated // then check faction - GraveYardMapBounds range = GraveYardStore.equal_range(zoneId); + GraveyardMapBounds range = GraveyardStore.equal_range(zoneId); MapEntry const* map = sMapStore.LookupEntry(MapId); // not need to check validity of map object; MapId _MUST_ be valid here @@ -6057,7 +6072,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float { if (zoneId != 0) // zone == 0 can't be fixed, used by bliz for bugged zones TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.", zoneId, team); - return GetDefaultGraveYard(team); + return GetDefaultGraveyard(team); } // at corpse map @@ -6077,7 +6092,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float for (; range.first != range.second; ++range.first) { - GraveYardData const& data = range.first->second; + GraveyardData const& data = range.first->second; WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(data.safeLocId); if (!entry) @@ -6153,29 +6168,45 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float return entryFar; } -GraveYardData const* ObjectMgr::FindGraveYardData(uint32 id, uint32 zoneId) const +GraveyardData const* ObjectMgr::FindGraveyardData(uint32 id, uint32 zoneId) const { - GraveYardMapBounds range = GraveYardStore.equal_range(zoneId); + GraveyardMapBounds range = GraveyardStore.equal_range(zoneId); for (; range.first != range.second; ++range.first) { - GraveYardData const& data = range.first->second; + GraveyardData const& data = range.first->second; if (data.safeLocId == id) return &data; } return nullptr; } -bool ObjectMgr::AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist /*= true*/) +AreaTrigger const* ObjectMgr::GetAreaTrigger(uint32 trigger) const +{ + AreaTriggerContainer::const_iterator itr = _areaTriggerStore.find(trigger); + if (itr != _areaTriggerStore.end()) + return &itr->second; + return nullptr; +} + +AccessRequirement const* ObjectMgr::GetAccessRequirement(uint32 mapid, Difficulty difficulty) const +{ + AccessRequirementContainer::const_iterator itr = _accessRequirementStore.find(MAKE_PAIR32(mapid, difficulty)); + if (itr != _accessRequirementStore.end()) + return itr->second; + return nullptr; +} + +bool ObjectMgr::AddGraveyardLink(uint32 id, uint32 zoneId, uint32 team, bool persist /*= true*/) { - if (FindGraveYardData(id, zoneId)) + if (FindGraveyardData(id, zoneId)) return false; // add link to loaded data - GraveYardData data; + GraveyardData data; data.safeLocId = id; data.team = team; - GraveYardStore.insert(GraveYardContainer::value_type(zoneId, data)); + GraveyardStore.insert(GraveyardContainer::value_type(zoneId, data)); // add link to DB if (persist) @@ -6192,9 +6223,9 @@ bool ObjectMgr::AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool per return true; } -void ObjectMgr::RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist /*= false*/) +void ObjectMgr::RemoveGraveyardLink(uint32 id, uint32 zoneId, uint32 team, bool persist /*= false*/) { - GraveYardMapBoundsNonConst range = GraveYardStore.equal_range(zoneId); + GraveyardMapBoundsNonConst range = GraveyardStore.equal_range(zoneId); if (range.first == range.second) { //TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.", zoneId, team); @@ -6206,7 +6237,7 @@ void ObjectMgr::RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool for (; range.first != range.second; ++range.first) { - GraveYardData & data = range.first->second; + GraveyardData & data = range.first->second; // skip not matching safezone id if (data.safeLocId != id) @@ -6226,7 +6257,7 @@ void ObjectMgr::RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool return; // remove from links - GraveYardStore.erase(range.first); + GraveyardStore.erase(range.first); // remove link from DB if (persist) @@ -6405,13 +6436,13 @@ AreaTrigger const* ObjectMgr::GetGoBackTrigger(uint32 Map) const { bool useParentDbValue = false; uint32 parentId = 0; - const MapEntry* mapEntry = sMapStore.LookupEntry(Map); + MapEntry const* mapEntry = sMapStore.LookupEntry(Map); if (!mapEntry || mapEntry->entrance_map < 0) return nullptr; if (mapEntry->IsDungeon()) { - const InstanceTemplate* iTemplate = sObjectMgr->GetInstanceTemplate(Map); + InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(Map); if (!iTemplate) return nullptr; @@ -6984,8 +7015,8 @@ void ObjectMgr::LoadPetNumber() std::string ObjectMgr::GeneratePetName(uint32 entry) { - StringVector& list0 = _petHalfName0[entry]; - StringVector& list1 = _petHalfName1[entry]; + std::vector<std::string>& list0 = _petHalfName0[entry]; + std::vector<std::string>& list1 = _petHalfName1[entry]; if (list0.empty() || list1.empty()) { @@ -9217,6 +9248,14 @@ VehicleAccessoryList const* ObjectMgr::GetVehicleAccessoryList(Vehicle* veh) con return nullptr; } +DungeonEncounterList const* ObjectMgr::GetDungeonEncounterList(uint32 mapId, Difficulty difficulty) const +{ + std::unordered_map<uint32, DungeonEncounterList>::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR32(mapId, difficulty)); + if (itr != _dungeonEncounterStore.end()) + return &itr->second; + return nullptr; +} + PlayerInfo const* ObjectMgr::GetPlayerInfo(uint32 race, uint32 class_) const { if (race >= MAX_RACES) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index d88dbc10167..95e7019dacf 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -19,40 +19,35 @@ #ifndef _OBJECTMGR_H #define _OBJECTMGR_H -#include "Log.h" -#include "Object.h" -#include "Bag.h" -#include "Creature.h" -#include "DynamicObject.h" -#include "GameObject.h" -#include "TemporarySummon.h" -#include "Corpse.h" -#include "QuestDef.h" +#include "Common.h" +#include "ConditionMgr.h" +#include "CreatureData.h" +#include "DatabaseEnvFwd.h" +#include "GameObjectData.h" #include "ItemTemplate.h" #include "NPCHandler.h" -#include "DatabaseEnv.h" -#include "Mail.h" -#include "Map.h" -#include "ObjectAccessor.h" #include "ObjectDefines.h" +#include "ObjectGuid.h" +#include "Position.h" +#include "QuestDef.h" +#include "SharedDefines.h" #include "VehicleDefines.h" -#include "ConditionMgr.h" -#include "DBCStores.h" -#include <string> -#include <tuple> #include <map> -#include <limits> -#include <functional> -#include <memory> +#include <unordered_map> class Item; +class Unit; +class Vehicle; struct AccessRequirement; +struct DeclinedName; +struct DungeonEncounterEntry; +struct FactionEntry; struct PlayerClassInfo; struct PlayerClassLevelInfo; struct PlayerInfo; struct PlayerLevelInfo; - -#pragma pack(push, 1) +struct SkillRaceClassInfoEntry; +struct WorldSafeLocsEntry; struct PageText { @@ -60,6 +55,15 @@ struct PageText uint32 NextPageID; }; +enum SummonerType +{ + SUMMONER_TYPE_CREATURE = 0, + SUMMONER_TYPE_GAMEOBJECT = 1, + SUMMONER_TYPE_MAP = 2 +}; + +#pragma pack(push, 1) + /// Key for storing temp summon data in TempSummonDataContainer struct TempSummonGroupKey { @@ -80,6 +84,15 @@ private: uint8 _summonGroup; ///< Summon's group id }; +/// Stores data for temp summons +struct TempSummonData +{ + uint32 entry; ///< Entry of summoned creature + Position pos; ///< Position, where should be creature spawned + TempSummonType type; ///< Summon type, see TempSummonType for available types + uint32 time; ///< Despawn time, usable only with certain temp summon types +}; + #pragma pack(pop) // DB scripting commands @@ -119,10 +132,27 @@ enum ScriptCommands SCRIPT_COMMAND_PLAY_ANIMKIT = 36 // source = Creature, datalong = AnimKit id (NOT ON 3.3.5A, DON'T REUSE) }; -// Benchmarked: Faster than std::unordered_map (insert/find) +enum ChatType +{ + CHAT_TYPE_SAY = 0, + CHAT_TYPE_YELL = 1, + CHAT_TYPE_TEXT_EMOTE = 2, + CHAT_TYPE_BOSS_EMOTE = 3, + CHAT_TYPE_WHISPER = 4, + CHAT_TYPE_BOSS_WHISPER = 5, + CHAT_TYPE_ZONE_YELL = 6, + CHAT_TYPE_END = 255 +}; + typedef std::map<uint32, PageText> PageTextContainer; -// Benchmarked: Faster than std::map (insert/find) +struct InstanceTemplate +{ + uint32 Parent; + uint32 ScriptId; + bool AllowMount; +}; + typedef std::unordered_map<uint16, InstanceTemplate> InstanceTemplateContainer; struct GameTele @@ -411,6 +441,19 @@ struct AreaTrigger float target_Orientation; }; +struct AccessRequirement +{ + uint8 levelMin; + uint8 levelMax; + uint16 item_level; + uint32 item; + uint32 item2; + uint32 quest_A; + uint32 quest_H; + uint32 achievement; + std::string questFailedText; +}; + struct BroadcastText { BroadcastText() : Id(0), Language(0), EmoteId0(0), EmoteId1(0), EmoteId2(0), @@ -422,8 +465,8 @@ struct BroadcastText uint32 Id; uint32 Language; - StringVector MaleText; - StringVector FemaleText; + std::vector<std::string> MaleText; + std::vector<std::string> FemaleText; uint32 EmoteId0; uint32 EmoteId1; uint32 EmoteId2; @@ -468,21 +511,47 @@ typedef std::unordered_map<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap struct TrinityString { - StringVector Content; + std::vector<std::string> Content; }; typedef std::map<ObjectGuid, ObjectGuid> LinkedRespawnContainer; +typedef std::unordered_map<uint32, CreatureTemplate> CreatureTemplateContainer; +typedef std::unordered_map<uint32, CreatureAddon> CreatureTemplateAddonContainer; typedef std::unordered_map<ObjectGuid::LowType, CreatureData> CreatureDataContainer; +typedef std::unordered_map<ObjectGuid::LowType, CreatureAddon> CreatureAddonContainer; +typedef std::unordered_map<uint16, CreatureBaseStats> CreatureBaseStatsContainer; +typedef std::unordered_map<uint8, EquipmentInfo> EquipmentInfoContainerInternal; +typedef std::unordered_map<uint32, EquipmentInfoContainerInternal> EquipmentInfoContainer; +typedef std::unordered_map<uint32, CreatureModelInfo> CreatureModelContainer; +typedef std::unordered_map<uint32, std::vector<uint32>> CreatureQuestItemMap; +typedef std::unordered_map<uint32, GameObjectTemplate> GameObjectTemplateContainer; +typedef std::unordered_map<uint32, GameObjectTemplateAddon> GameObjectTemplateAddonContainer; typedef std::unordered_map<ObjectGuid::LowType, GameObjectData> GameObjectDataContainer; -typedef std::map<TempSummonGroupKey, std::vector<TempSummonData> > TempSummonDataContainer; +typedef std::unordered_map<ObjectGuid::LowType, GameObjectAddon> GameObjectAddonContainer; +typedef std::unordered_map<uint32, std::vector<uint32>> GameObjectQuestItemMap; +typedef std::map<TempSummonGroupKey, std::vector<TempSummonData>> TempSummonDataContainer; typedef std::unordered_map<uint32, CreatureLocale> CreatureLocaleContainer; typedef std::unordered_map<uint32, GameObjectLocale> GameObjectLocaleContainer; +typedef std::unordered_map<uint32, ItemTemplate> ItemTemplateContainer; typedef std::unordered_map<uint32, ItemLocale> ItemLocaleContainer; typedef std::unordered_map<uint32, ItemSetNameLocale> ItemSetNameLocaleContainer; typedef std::unordered_map<uint32, QuestLocale> QuestLocaleContainer; typedef std::unordered_map<uint32, NpcTextLocale> NpcTextLocaleContainer; typedef std::unordered_map<uint32, PageTextLocale> PageTextLocaleContainer; + +struct GossipMenuItemsLocale +{ + std::vector<std::string> OptionText; + std::vector<std::string> BoxText; +}; + typedef std::unordered_map<uint32, GossipMenuItemsLocale> GossipMenuItemsLocaleContainer; + +struct PointOfInterestLocale +{ + std::vector<std::string> Name; +}; + typedef std::unordered_map<uint32, PointOfInterestLocale> PointOfInterestLocaleContainer; typedef std::unordered_map<uint32, TrinityString> TrinityStringContainer; @@ -492,12 +561,86 @@ typedef std::multimap<uint32, uint32> QuestRelationsReverse; // quest -> unit/go typedef std::pair<QuestRelations::const_iterator, QuestRelations::const_iterator> QuestRelationBounds; typedef std::pair<QuestRelationsReverse::const_iterator, QuestRelationsReverse::const_iterator> QuestRelationReverseBounds; +struct PlayerCreateInfoItem +{ + PlayerCreateInfoItem(uint32 id, uint32 amount) : item_id(id), item_amount(amount) { } + + uint32 item_id = 0; + uint32 item_amount = 0; +}; + +typedef std::vector<PlayerCreateInfoItem> PlayerCreateInfoItems; + +struct PlayerClassLevelInfo +{ + uint16 basehealth = 0; + uint16 basemana = 0; +}; + +struct PlayerClassInfo +{ + //[level-1] 0..MaxPlayerLevel-1 + PlayerClassLevelInfo* levelInfo = nullptr; +}; + +struct PlayerLevelInfo +{ + uint8 stats[MAX_STATS] = { }; +}; + +typedef std::vector<uint32> PlayerCreateInfoSpells; + +struct PlayerCreateInfoAction +{ + PlayerCreateInfoAction(uint8 _button, uint32 _action, uint8 _type) : button(_button), type(_type), action(_action) { } + + uint8 button = 0; + uint8 type = 0; + uint32 action = 0; +}; + +typedef std::vector<PlayerCreateInfoAction> PlayerCreateInfoActions; + +struct PlayerCreateInfoSkill +{ + uint16 SkillId; + uint16 Rank; +}; + +typedef std::vector<PlayerCreateInfoSkill> PlayerCreateInfoSkills; + +// existence checked by displayId != 0 +struct PlayerInfo +{ + uint32 mapId = 0; + uint32 areaId = 0; + float positionX = 0.0f; + float positionY = 0.0f; + float positionZ = 0.0f; + float orientation = 0.0f; + uint16 displayId_m = 0; + uint16 displayId_f = 0; + PlayerCreateInfoItems item; + PlayerCreateInfoSpells customSpells; + PlayerCreateInfoSpells castSpells; + PlayerCreateInfoActions action; + PlayerCreateInfoSkills skills; + + //[level-1] 0..MaxPlayerLevel-1 + PlayerLevelInfo* levelInfo = nullptr; +}; + + typedef std::multimap<int32, uint32> ExclusiveQuestGroups; // exclusiveGroupId -> quest typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ExclusiveQuestGroupsBounds; struct PetLevelInfo { - PetLevelInfo() : health(0), mana(0), armor(0) { for (uint8 i=0; i < MAX_STATS; ++i) stats[i] = 0; } + PetLevelInfo() : health(0), mana(0), armor(0) + { + for (uint16& stat : stats) + stat = 0; + } uint16 stats[MAX_STATS]; uint16 health; @@ -630,15 +773,15 @@ struct QuestPOIWrapper typedef std::unordered_map<uint32, QuestPOIWrapper> QuestPOIContainer; -struct GraveYardData +struct GraveyardData { uint32 safeLocId; uint32 team; }; -typedef std::multimap<uint32, GraveYardData> GraveYardContainer; -typedef std::pair<GraveYardContainer::const_iterator, GraveYardContainer::const_iterator> GraveYardMapBounds; -typedef std::pair<GraveYardContainer::iterator, GraveYardContainer::iterator> GraveYardMapBoundsNonConst; +typedef std::multimap<uint32, GraveyardData> GraveyardContainer; +typedef std::pair<GraveyardContainer::const_iterator, GraveyardContainer::const_iterator> GraveyardMapBounds; +typedef std::pair<GraveyardContainer::iterator, GraveyardContainer::iterator> GraveyardMapBoundsNonConst; typedef std::unordered_map<uint32, VendorItemData> CacheVendorItemContainer; typedef std::unordered_map<uint32, TrainerSpellData> CacheTrainerSpellContainer; @@ -671,7 +814,7 @@ struct LanguageDesc TC_GAME_API extern LanguageDesc lang_description[LANGUAGES_COUNT]; LanguageDesc const* GetLanguageDescByID(uint32 lang); -enum EncounterCreditType +enum EncounterCreditType : uint8 { ENCOUNTER_CREDIT_KILL_CREATURE = 0, ENCOUNTER_CREDIT_CAST_SPELL = 1 @@ -721,8 +864,6 @@ class TC_GAME_API ObjectMgr static ObjectMgr* instance(); - typedef std::unordered_map<uint32, Item*> ItemMap; - typedef std::unordered_map<uint32, Quest*> QuestMap; typedef std::unordered_map<uint32, AreaTrigger> AreaTriggerContainer; @@ -786,7 +927,7 @@ class TC_GAME_API ObjectMgr void GetPlayerLevelInfo(uint32 race, uint32 class_, uint8 level, PlayerLevelInfo* info) const; - GameObjectQuestItemList const* GetGameObjectQuestItemList(uint32 id) const + std::vector<uint32> const* GetGameObjectQuestItemList(uint32 id) const { GameObjectQuestItemMap::const_iterator itr = _gameObjectQuestItemStore.find(id); if (itr != _gameObjectQuestItemStore.end()) @@ -795,7 +936,7 @@ class TC_GAME_API ObjectMgr } GameObjectQuestItemMap const* GetGameObjectQuestItemMap() const { return &_gameObjectQuestItemStore; } - CreatureQuestItemList const* GetCreatureQuestItemList(uint32 id) const + std::vector<uint32> const* GetCreatureQuestItemList(uint32 id) const { CreatureQuestItemMap::const_iterator itr = _creatureQuestItemStore.find(id); if (itr != _creatureQuestItemStore.end()) @@ -836,29 +977,15 @@ class TC_GAME_API ObjectMgr GossipText const* GetGossipText(uint32 Text_ID) const; - WorldSafeLocsEntry const* GetDefaultGraveYard(uint32 team) const; - WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) const; - bool AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = true); - void RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = false); + WorldSafeLocsEntry const* GetDefaultGraveyard(uint32 team) const; + WorldSafeLocsEntry const* GetClosestGraveyard(float x, float y, float z, uint32 MapId, uint32 team) const; + bool AddGraveyardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = true); + void RemoveGraveyardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = false); void LoadGraveyardZones(); - GraveYardData const* FindGraveYardData(uint32 id, uint32 zone) const; - - AreaTrigger const* GetAreaTrigger(uint32 trigger) const - { - AreaTriggerContainer::const_iterator itr = _areaTriggerStore.find(trigger); - if (itr != _areaTriggerStore.end()) - return &itr->second; - return nullptr; - } - - AccessRequirement const* GetAccessRequirement(uint32 mapid, Difficulty difficulty) const - { - AccessRequirementContainer::const_iterator itr = _accessRequirementStore.find(MAKE_PAIR32(mapid, difficulty)); - if (itr != _accessRequirementStore.end()) - return itr->second; - return nullptr; - } + GraveyardData const* FindGraveyardData(uint32 id, uint32 zone) const; + AreaTrigger const* GetAreaTrigger(uint32 trigger) const; + AccessRequirement const* GetAccessRequirement(uint32 mapid, Difficulty difficulty) const; AreaTrigger const* GetGoBackTrigger(uint32 Map) const; AreaTrigger const* GetMapEntranceTrigger(uint32 Map) const; @@ -911,26 +1038,10 @@ class TC_GAME_API ObjectMgr VehicleAccessoryList const* GetVehicleAccessoryList(Vehicle* veh) const; - DungeonEncounterList const* GetDungeonEncounterList(uint32 mapId, Difficulty difficulty) const - { - std::unordered_map<uint32, DungeonEncounterList>::const_iterator itr = _dungeonEncounterStore.find(MAKE_PAIR32(mapId, difficulty)); - if (itr != _dungeonEncounterStore.end()) - return &itr->second; - return nullptr; - } + DungeonEncounterList const* GetDungeonEncounterList(uint32 mapId, Difficulty difficulty) const; void LoadQuests(); - void LoadQuestStartersAndEnders() - { - TC_LOG_INFO("server.loading", "Loading GO Start Quest Data..."); - LoadGameobjectQuestStarters(); - TC_LOG_INFO("server.loading", "Loading GO End Quest Data..."); - LoadGameobjectQuestEnders(); - TC_LOG_INFO("server.loading", "Loading Creature Start Quest Data..."); - LoadCreatureQuestStarters(); - TC_LOG_INFO("server.loading", "Loading Creature End Quest Data..."); - LoadCreatureQuestEnders(); - } + void LoadQuestStartersAndEnders(); void LoadGameobjectQuestStarters(); void LoadGameobjectQuestEnders(); void LoadCreatureQuestStarters(); @@ -1238,7 +1349,7 @@ class TC_GAME_API ObjectMgr void RemoveCreatureFromGrid(ObjectGuid::LowType guid, CreatureData const* data); void AddGameobjectToGrid(ObjectGuid::LowType guid, GameObjectData const* data); void RemoveGameobjectFromGrid(ObjectGuid::LowType guid, GameObjectData const* data); - ObjectGuid::LowType AddGOData(uint32 entry, uint32 map, Position const& pos, G3D::Quat const& rot, uint32 spawntimedelay = 0); + ObjectGuid::LowType AddGOData(uint32 entry, uint32 map, Position const& pos, QuaternionData const& rot, uint32 spawntimedelay = 0); ObjectGuid::LowType AddCreatureData(uint32 entry, uint32 map, Position const& pos, uint32 spawntimedelay = 0); // reserved names @@ -1315,10 +1426,10 @@ class TC_GAME_API ObjectMgr } // for wintergrasp only - GraveYardContainer GraveYardStore; + GraveyardContainer GraveyardStore; - static void AddLocaleString(std::string const& value, LocaleConstant localeConstant, StringVector& data); - static inline void GetLocaleString(StringVector const& data, LocaleConstant localeConstant, std::string& value) + static void AddLocaleString(std::string const& value, LocaleConstant localeConstant, std::vector<std::string>& data); + static inline void GetLocaleString(std::vector<std::string> const& data, LocaleConstant localeConstant, std::string& value) { if (data.size() > size_t(localeConstant) && !data[localeConstant].empty()) value = data[localeConstant]; @@ -1445,7 +1556,7 @@ class TC_GAME_API ObjectMgr typedef std::map<uint32, int32> FishingBaseSkillContainer; // [areaId][base skill level] FishingBaseSkillContainer _fishingBaseForAreaStore; - typedef std::map<uint32, StringVector> HalfNameContainer; + typedef std::map<uint32, std::vector<std::string>> HalfNameContainer; HalfNameContainer _petHalfName0; HalfNameContainer _petHalfName1; @@ -1457,7 +1568,7 @@ class TC_GAME_API ObjectMgr CreatureTemplateContainer _creatureTemplateStore; CreatureModelContainer _creatureModelStore; CreatureAddonContainer _creatureAddonStore; - CreatureAddonTemplateContainer _creatureTemplateAddonStore; + CreatureTemplateAddonContainer _creatureTemplateAddonStore; GameObjectAddonContainer _gameObjectAddonStore; GameObjectQuestItemMap _gameObjectQuestItemStore; CreatureQuestItemMap _creatureQuestItemStore; diff --git a/src/server/game/Grids/Cells/Cell.h b/src/server/game/Grids/Cells/Cell.h index d4169dff855..56aa7f794af 100644 --- a/src/server/game/Grids/Cells/Cell.h +++ b/src/server/game/Grids/Cells/Cell.h @@ -59,13 +59,13 @@ struct Cell y = data.Part.grid_y * MAX_NUMBER_OF_CELLS + data.Part.cell_y; } - bool DiffCell(const Cell &cell) const + bool DiffCell(Cell const& cell) const { return(data.Part.cell_x != cell.data.Part.cell_x || data.Part.cell_y != cell.data.Part.cell_y); } - bool DiffGrid(const Cell &cell) const + bool DiffGrid(Cell const& cell) const { return(data.Part.grid_x != cell.data.Part.grid_x || data.Part.grid_y != cell.data.Part.grid_y); diff --git a/src/server/game/Grids/Dynamic/TypeContainer.h b/src/server/game/Grids/Dynamic/TypeContainer.h new file mode 100644 index 00000000000..d095baf059d --- /dev/null +++ b/src/server/game/Grids/Dynamic/TypeContainer.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_TYPECONTAINER_H +#define TRINITY_TYPECONTAINER_H + +/* + * Here, you'll find a series of containers that allow you to hold multiple + * types of object at the same time. + */ + +#include <map> +#include <unordered_map> +#include <vector> +#include "Define.h" +#include "Dynamic/TypeList.h" +#include "GridRefManager.h" + +/* + * @class ContainerMapList is a mulit-type container for map elements + * By itself its meaningless but collaborate along with TypeContainers, + * it become the most powerfully container in the whole system. + */ +template<class OBJECT> +struct ContainerMapList +{ + //std::map<OBJECT_HANDLE, OBJECT *> _element; + GridRefManager<OBJECT> _element; +}; + +template<> +struct ContainerMapList<TypeNull> /* nothing is in type null */ +{ +}; + +template<class H, class T> +struct ContainerMapList<TypeList<H, T> > +{ + ContainerMapList<H> _elements; + ContainerMapList<T> _TailElements; +}; + +template<class OBJECT, class KEY_TYPE> +struct ContainerUnorderedMap +{ + std::unordered_map<KEY_TYPE, OBJECT*> _element; +}; + +template<class KEY_TYPE> +struct ContainerUnorderedMap<TypeNull, KEY_TYPE> +{ +}; + +template<class H, class T, class KEY_TYPE> +struct ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> +{ + ContainerUnorderedMap<H, KEY_TYPE> _elements; + ContainerUnorderedMap<T, KEY_TYPE> _TailElements; +}; + +#include "TypeContainerFunctions.h" + +/* + * @class TypeMapContainer contains a fixed number of types and is + * determined at compile time. This is probably the most complicated + * class and do its simplest thing, that is, holds objects + * of different types. + */ + +template<class OBJECT_TYPES> +class TypeMapContainer +{ + public: + template<class SPECIFIC_TYPE> size_t Count() const { return Trinity::Count(i_elements, (SPECIFIC_TYPE*)nullptr); } + + /// inserts a specific object into the container + template<class SPECIFIC_TYPE> + bool insert(SPECIFIC_TYPE *obj) + { + SPECIFIC_TYPE* t = Trinity::Insert(i_elements, obj); + return (t != nullptr); + } + + /// Removes the object from the container, and returns the removed object + //template<class SPECIFIC_TYPE> + //bool remove(SPECIFIC_TYPE* obj) + //{ + // SPECIFIC_TYPE* t = Trinity::Remove(i_elements, obj); + // return (t != nullptr); + //} + + ContainerMapList<OBJECT_TYPES> & GetElements(void) { return i_elements; } + const ContainerMapList<OBJECT_TYPES> & GetElements(void) const { return i_elements;} + + private: + ContainerMapList<OBJECT_TYPES> i_elements; +}; + +template<class OBJECT_TYPES, class KEY_TYPE> +class TypeUnorderedMapContainer +{ +public: + template<class SPECIFIC_TYPE> + bool Insert(KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + return Trinity::Insert(_elements, handle, obj); + } + + template<class SPECIFIC_TYPE> + bool Remove(KEY_TYPE const& handle) + { + return Trinity::Remove(_elements, handle, (SPECIFIC_TYPE*)nullptr); + } + + template<class SPECIFIC_TYPE> + SPECIFIC_TYPE* Find(KEY_TYPE const& handle) + { + return Trinity::Find(_elements, handle, (SPECIFIC_TYPE*)nullptr); + } + + ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE>& GetElements() { return _elements; } + ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> const& GetElements() const { return _elements; } + +private: + ContainerUnorderedMap<OBJECT_TYPES, KEY_TYPE> _elements; +}; + +#endif diff --git a/src/server/game/Grids/Dynamic/TypeContainerFunctions.h b/src/server/game/Grids/Dynamic/TypeContainerFunctions.h new file mode 100644 index 00000000000..97d20922a05 --- /dev/null +++ b/src/server/game/Grids/Dynamic/TypeContainerFunctions.h @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TYPECONTAINER_FUNCTIONS_H +#define TYPECONTAINER_FUNCTIONS_H + +/* + * Here you'll find a list of helper functions to make + * the TypeContainer usefull. Without it, its hard + * to access or mutate the container. + */ + +#include "Define.h" +#include "Dynamic/TypeList.h" +#include <map> +#include <unordered_map> + +namespace Trinity +{ + // Helpers + // Insert helpers + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Insert(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + auto i = elements._element.find(handle); + if (i == elements._element.end()) + { + elements._element[handle] = obj; + return true; + } + else + { + ASSERT(i->second == obj, "Object with certain key already in but objects are different!"); + return false; + } + } + + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Insert(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class T> + bool Insert(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T> + bool Insert(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* obj) + { + bool ret = Insert(elements._elements, handle, obj); + return ret ? ret : Insert(elements._TailElements, handle, obj); + } + + // Find helpers + template<class SPECIFIC_TYPE, class KEY_TYPE> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + auto i = elements._element.find(handle); + if (i == elements._element.end()) + return nullptr; + else + return i->second; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeNull, KEY_TYPE> const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class T> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<T, KEY_TYPE> const& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T> + SPECIFIC_TYPE* Find(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE> const& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + SPECIFIC_TYPE* ret = Find(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); + return ret ? ret : Find(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + } + + // Erase helpers + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Remove(ContainerUnorderedMap<SPECIFIC_TYPE, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + elements._element.erase(handle); + return true; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE> + bool Remove(ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class T> + bool Remove(ContainerUnorderedMap<T, KEY_TYPE>& /*elements*/, KEY_TYPE const& /*handle*/, SPECIFIC_TYPE* /*obj*/) + { + return false; + } + + template<class SPECIFIC_TYPE, class KEY_TYPE, class H, class T> + bool Remove(ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& elements, KEY_TYPE const& handle, SPECIFIC_TYPE* /*obj*/) + { + bool ret = Remove(elements._elements, handle, (SPECIFIC_TYPE*)nullptr); + return ret ? ret : Remove(elements._TailElements, handle, (SPECIFIC_TYPE*)nullptr); + } + + /* ContainerMapList Helpers */ + // count functions + template<class SPECIFIC_TYPE> + size_t Count(ContainerMapList<SPECIFIC_TYPE> const& elements, SPECIFIC_TYPE* /*fake*/) + { + return elements._element.getSize(); + } + + template<class SPECIFIC_TYPE> + size_t Count(ContainerMapList<TypeNull> const& /*elements*/, SPECIFIC_TYPE* /*fake*/) + { + return 0; + } + + template<class SPECIFIC_TYPE, class T> + size_t Count(ContainerMapList<T> const& /*elements*/, SPECIFIC_TYPE* /*fake*/) + { + return 0; + } + + template<class SPECIFIC_TYPE, class T> + size_t Count(ContainerMapList<TypeList<SPECIFIC_TYPE, T>> const& elements, SPECIFIC_TYPE* fake) + { + return Count(elements._elements, fake); + } + + template<class SPECIFIC_TYPE, class H, class T> + size_t Count(ContainerMapList<TypeList<H, T>> const& elements, SPECIFIC_TYPE* fake) + { + return Count(elements._TailElements, fake); + } + + // non-const insert functions + template<class SPECIFIC_TYPE> + SPECIFIC_TYPE* Insert(ContainerMapList<SPECIFIC_TYPE>& elements, SPECIFIC_TYPE* obj) + { + //elements._element[hdl] = obj; + obj->AddToGrid(elements._element); + return obj; + } + + template<class SPECIFIC_TYPE> + SPECIFIC_TYPE* Insert(ContainerMapList<TypeNull>& /*elements*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; + } + + // this is a missed + template<class SPECIFIC_TYPE, class T> + SPECIFIC_TYPE* Insert(ContainerMapList<T>& /*elements*/, SPECIFIC_TYPE* /*obj*/) + { + return nullptr; // a missed + } + + // Recursion + template<class SPECIFIC_TYPE, class H, class T> + SPECIFIC_TYPE* Insert(ContainerMapList<TypeList<H, T>>& elements, SPECIFIC_TYPE* obj) + { + SPECIFIC_TYPE* t = Insert(elements._elements, obj); + return (t != nullptr ? t : Insert(elements._TailElements, obj)); + } + + //// non-const remove method + //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<SPECIFIC_TYPE> & /*elements*/, SPECIFIC_TYPE *obj) + //{ + // obj->GetGridRef().unlink(); + // return obj; + //} + + //template<class SPECIFIC_TYPE> SPECIFIC_TYPE* Remove(ContainerMapList<TypeNull> &/*elements*/, SPECIFIC_TYPE * /*obj*/) + //{ + // return nullptr; + //} + + //// this is a missed + //template<class SPECIFIC_TYPE, class T> SPECIFIC_TYPE* Remove(ContainerMapList<T> &/*elements*/, SPECIFIC_TYPE * /*obj*/) + //{ + // return nullptr; // a missed + //} + + //template<class SPECIFIC_TYPE, class T, class H> SPECIFIC_TYPE* Remove(ContainerMapList<TypeList<H, T> > &elements, SPECIFIC_TYPE *obj) + //{ + // // The head element is bad + // SPECIFIC_TYPE* t = Remove(elements._elements, obj); + // return (t != nullptr ? t : Remove(elements._TailElements, obj)); + //} +} +#endif + diff --git a/src/server/game/Grids/Dynamic/TypeContainerVisitor.h b/src/server/game/Grids/Dynamic/TypeContainerVisitor.h new file mode 100644 index 00000000000..2d08da778e9 --- /dev/null +++ b/src/server/game/Grids/Dynamic/TypeContainerVisitor.h @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef TRINITY_TYPECONTAINERVISITOR_H +#define TRINITY_TYPECONTAINERVISITOR_H + +/* + * @class TypeContainerVisitor is implemented as a visitor pattern. It is + * a visitor to the TypeContainerList or TypeContainerMapList. The visitor has + * to overload its types as a visit method is called. + */ + +#include "Define.h" +#include "Dynamic/TypeContainer.h" + +// forward declaration +template<class T, class Y> class TypeContainerVisitor; + +// visitor helper +template<class VISITOR, class TYPE_CONTAINER> void VisitorHelper(VISITOR &v, TYPE_CONTAINER &c) +{ + v.Visit(c); +} + +// terminate condition container map list +template<class VISITOR> void VisitorHelper(VISITOR &/*v*/, ContainerMapList<TypeNull> &/*c*/) { } + +template<class VISITOR, class T> void VisitorHelper(VISITOR &v, ContainerMapList<T> &c) +{ + v.Visit(c._element); +} + +// recursion container map list +template<class VISITOR, class H, class T> void VisitorHelper(VISITOR &v, ContainerMapList<TypeList<H, T> > &c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +// for TypeMapContainer +template<class VISITOR, class OBJECT_TYPES> void VisitorHelper(VISITOR &v, TypeMapContainer<OBJECT_TYPES> &c) +{ + VisitorHelper(v, c.GetElements()); +} + +// TypeUnorderedMapContainer +template<class VISITOR, class KEY_TYPE> +void VisitorHelper(VISITOR& /*v*/, ContainerUnorderedMap<TypeNull, KEY_TYPE>& /*c*/) { } + +template<class VISITOR, class KEY_TYPE, class T> +void VisitorHelper(VISITOR& v, ContainerUnorderedMap<T, KEY_TYPE>& c) +{ + v.Visit(c._element); +} + +template<class VISITOR, class KEY_TYPE, class H, class T> +void VisitorHelper(VISITOR& v, ContainerUnorderedMap<TypeList<H, T>, KEY_TYPE>& c) +{ + VisitorHelper(v, c._elements); + VisitorHelper(v, c._TailElements); +} + +template<class VISITOR, class OBJECT_TYPES, class KEY_TYPE> +void VisitorHelper(VISITOR& v, TypeUnorderedMapContainer<OBJECT_TYPES, KEY_TYPE>& c) +{ + VisitorHelper(v, c.GetElements()); +} + +template<class VISITOR, class TYPE_CONTAINER> +class TypeContainerVisitor +{ + public: + TypeContainerVisitor(VISITOR &v) : i_visitor(v) { } + + void Visit(TYPE_CONTAINER& c) + { + VisitorHelper(i_visitor, c); + } + + void Visit(TYPE_CONTAINER const& c) const + { + VisitorHelper(i_visitor, c); + } + + private: + VISITOR &i_visitor; +}; +#endif + diff --git a/src/server/game/Grids/GridRefManager.h b/src/server/game/Grids/GridRefManager.h index 4d21a8d3446..89d6cc9e7e6 100644 --- a/src/server/game/Grids/GridRefManager.h +++ b/src/server/game/Grids/GridRefManager.h @@ -34,7 +34,7 @@ class GridRefManager : public RefManager<GridRefManager<OBJECT>, OBJECT> GridReference<OBJECT>* getLast() { return (GridReference<OBJECT>*)RefManager<GridRefManager<OBJECT>, OBJECT>::getLast(); } iterator begin() { return iterator(getFirst()); } - iterator end() { return iterator(NULL); } + iterator end() { return iterator(nullptr); } }; #endif diff --git a/src/server/game/Grids/GridStates.cpp b/src/server/game/Grids/GridStates.cpp index 98f9006235b..4e3b11154af 100644 --- a/src/server/game/Grids/GridStates.cpp +++ b/src/server/game/Grids/GridStates.cpp @@ -19,9 +19,12 @@ #include "GridStates.h" #include "GridNotifiers.h" #include "Log.h" +#include "Map.h" +#include "ObjectGridLoader.h" void InvalidState::Update(Map&, NGridType&, GridInfo&, uint32) const -{ } +{ +} void ActiveState::Update(Map& map, NGridType& grid, GridInfo& info, uint32 diff) const { diff --git a/src/server/game/Grids/NGrid.cpp b/src/server/game/Grids/NGrid.cpp new file mode 100644 index 00000000000..e5d69dae44a --- /dev/null +++ b/src/server/game/Grids/NGrid.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "NGrid.h" +#include "Random.h" + +GridInfo::GridInfo() : i_timer(0), vis_Update(0, irand(0, DEFAULT_VISIBILITY_NOTIFY_PERIOD)), + i_unloadActiveLockCount(0), i_unloadExplicitLock(false), i_unloadReferenceLock(false) +{ +} + +GridInfo::GridInfo(time_t expiry, bool unload /*= true */) : i_timer(expiry), vis_Update(0, irand(0, DEFAULT_VISIBILITY_NOTIFY_PERIOD)), + i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload), i_unloadReferenceLock(false) +{ +} diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h index 69ab43106a9..dc6f2561e4f 100644 --- a/src/server/game/Grids/NGrid.h +++ b/src/server/game/Grids/NGrid.h @@ -29,23 +29,19 @@ #define DEFAULT_VISIBILITY_NOTIFY_PERIOD 1000 -class GridInfo +class TC_GAME_API GridInfo { public: - GridInfo() - : i_timer(0), vis_Update(0, irand(0, DEFAULT_VISIBILITY_NOTIFY_PERIOD)), - i_unloadActiveLockCount(0), i_unloadExplicitLock(false), i_unloadReferenceLock(false) { } - GridInfo(time_t expiry, bool unload = true ) - : i_timer(expiry), vis_Update(0, irand(0, DEFAULT_VISIBILITY_NOTIFY_PERIOD)), - i_unloadActiveLockCount(0), i_unloadExplicitLock(!unload), i_unloadReferenceLock(false) { } - const TimeTracker& getTimeTracker() const { return i_timer; } + GridInfo(); + GridInfo(time_t expiry, bool unload = true); + TimeTracker const& getTimeTracker() const { return i_timer; } bool getUnloadLock() const { return i_unloadActiveLockCount || i_unloadExplicitLock || i_unloadReferenceLock; } void setUnloadExplicitLock(bool on) { i_unloadExplicitLock = on; } void setUnloadReferenceLock(bool on) { i_unloadReferenceLock = on; } void incUnloadActiveLock() { ++i_unloadActiveLockCount; } void decUnloadActiveLock() { if (i_unloadActiveLockCount) --i_unloadActiveLockCount; } - void setTimer(const TimeTracker& pTimer) { i_timer = pTimer; } + void setTimer(TimeTracker const& pTimer) { i_timer = pTimer; } void ResetTimeTracker(time_t interval) { i_timer.Reset(interval); } void UpdateTimeTracker(time_t diff) { i_timer.Update(diff); } PeriodicTimer& getRelocationTimer() { return vis_Update; } @@ -110,7 +106,7 @@ class NGrid void setGridObjectDataLoaded(bool pLoaded) { i_GridObjectDataLoaded = pLoaded; } GridInfo* getGridInfoRef() { return &i_GridInfo; } - const TimeTracker& getTimeTracker() const { return i_GridInfo.getTimeTracker(); } + TimeTracker const& getTimeTracker() const { return i_GridInfo.getTimeTracker(); } bool getUnloadLock() const { return i_GridInfo.getUnloadLock(); } void setUnloadExplicitLock(bool on) { i_GridInfo.setUnloadExplicitLock(on); } void setUnloadReferenceLock(bool on) { i_GridInfo.setUnloadReferenceLock(on); } diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 70d472604e2..623010310ea 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -80,7 +80,7 @@ void VisibleNotifier::SendToSelf() WorldPacket packet; i_data.BuildPacket(&packet); - i_player.GetSession()->SendPacket(&packet); + i_player.SendDirectMessage(&packet); for (std::set<Unit*>::const_iterator it = i_visibleNow.begin(); it != i_visibleNow.end(); ++it) i_player.SendInitialVisiblePackets(*it); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 1378b4a5778..897e43d5e03 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -19,22 +19,16 @@ #ifndef TRINITY_GRIDNOTIFIERS_H #define TRINITY_GRIDNOTIFIERS_H -#include "ObjectGridLoader.h" -#include "UpdateData.h" -#include <iostream> - +#include "Creature.h" #include "Corpse.h" -#include "Object.h" +#include "CreatureAI.h" #include "DynamicObject.h" #include "GameObject.h" #include "Player.h" -#include "Unit.h" -#include "CreatureAI.h" #include "Spell.h" -#include "WorldSession.h" - -class Player; -//class Map; +#include "SpellInfo.h" +#include "UnitAI.h" +#include "UpdateData.h" namespace Trinity { @@ -128,7 +122,7 @@ namespace Trinity float i_distSq; uint32 team; Player const* skipped_receiver; - MessageDistDeliverer(WorldObject* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) + MessageDistDeliverer(WorldObject* src, WorldPacket const* msg, float dist, bool own_team_only = false, Player const* skipped = nullptr) : i_source(src), i_message(msg), i_phaseMask(src->GetPhaseMask()), i_distSq(dist * dist) , team(0) , skipped_receiver(skipped) @@ -152,8 +146,7 @@ namespace Trinity if (!player->HaveAtClient(i_source)) return; - if (WorldSession* session = player->GetSession()) - session->SendPacket(i_message); + player->SendDirectMessage(i_message); } }; @@ -180,8 +173,7 @@ namespace Trinity if (player == i_source || !player->HaveAtClient(i_source) || player->IsFriendlyTo(i_source)) return; - if (WorldSession* session = player->GetSession()) - session->SendPacket(i_message); + player->SendDirectMessage(i_message); } }; @@ -641,7 +633,7 @@ namespace Trinity { public: AnyDeadUnitSpellTargetInRangeCheck(Unit* searchObj, float range, SpellInfo const* spellInfo, SpellTargetCheckTypes check) - : AnyDeadUnitObjectInRangeCheck(searchObj, range), i_spellInfo(spellInfo), i_check(searchObj, searchObj, spellInfo, check, NULL) + : AnyDeadUnitObjectInRangeCheck(searchObj, range), i_spellInfo(spellInfo), i_check(searchObj, searchObj, spellInfo, check, nullptr) { } bool operator()(Player* u); bool operator()(Corpse* u); @@ -967,9 +959,6 @@ namespace Trinity bool operator()(Unit* u) const { - if (G3D::fuzzyEq(_range, 0.0f)) - return false; - if (_playerOnly && u->GetTypeId() != TYPEID_PLAYER) return false; @@ -1059,7 +1048,7 @@ namespace Trinity { if (!_spellInfo) if (DynamicObject const* dynObj = i_obj->ToDynObject()) - _spellInfo = sSpellMgr->GetSpellInfo(dynObj->GetSpellId()); + _spellInfo = dynObj->GetSpellInfo(); } bool operator()(Unit* u) const @@ -1115,8 +1104,8 @@ namespace Trinity if (!u->IsWithinLOSInMap(i_enemy)) return; - if (u->AI()) - u->AI()->AttackStart(i_enemy); + if (u->GetAI() && u->IsAIEnabled) + u->GetAI()->AttackStart(i_enemy); } private: Unit* const i_funit; @@ -1374,7 +1363,7 @@ namespace Trinity class AllGameObjectsWithEntryInRange { public: - AllGameObjectsWithEntryInRange(const WorldObject* object, uint32 entry, float maxRange) : m_pObject(object), m_uiEntry(entry), m_fRange(maxRange) { } + AllGameObjectsWithEntryInRange(WorldObject const* object, uint32 entry, float maxRange) : m_pObject(object), m_uiEntry(entry), m_fRange(maxRange) { } bool operator()(GameObject* go) const { @@ -1393,7 +1382,7 @@ namespace Trinity class AllCreaturesOfEntryInRange { public: - AllCreaturesOfEntryInRange(const WorldObject* object, uint32 entry, float maxRange) : m_pObject(object), m_uiEntry(entry), m_fRange(maxRange) { } + AllCreaturesOfEntryInRange(WorldObject const* object, uint32 entry, float maxRange) : m_pObject(object), m_uiEntry(entry), m_fRange(maxRange) { } bool operator()(Unit* unit) const { @@ -1449,7 +1438,7 @@ namespace Trinity class AllWorldObjectsInRange { public: - AllWorldObjectsInRange(const WorldObject* object, float maxRange) : m_pObject(object), m_fRange(maxRange) { } + AllWorldObjectsInRange(WorldObject const* object, float maxRange) : m_pObject(object), m_fRange(maxRange) { } bool operator()(WorldObject* go) const { diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index dc6a8f59d61..26e74839496 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -20,13 +20,13 @@ #define TRINITY_GRIDNOTIFIERSIMPL_H #include "GridNotifiers.h" -#include "WorldPacket.h" #include "Corpse.h" -#include "Player.h" -#include "UpdateData.h" #include "CreatureAI.h" +#include "Player.h" #include "SpellAuras.h" -#include "Opcodes.h" +#include "UpdateData.h" +#include "WorldPacket.h" +#include "WorldSession.h" template<class T> inline void Trinity::VisibleNotifier::Visit(GridRefManager<T> &m) diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index 1cdedf34ec5..848df6f60dc 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -17,15 +17,16 @@ */ #include "ObjectGridLoader.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" +#include "CellImpl.h" +#include "Corpse.h" #include "Creature.h" -#include "GameObject.h" +#include "CreatureAI.h" #include "DynamicObject.h" -#include "Corpse.h" +#include "Log.h" +#include "GameObject.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "World.h" -#include "CellImpl.h" -#include "CreatureAI.h" void ObjectGridEvacuator::Visit(CreatureMapType &m) { diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h index 32d27ebe502..b823044347f 100644 --- a/src/server/game/Grids/ObjectGridLoader.h +++ b/src/server/game/Grids/ObjectGridLoader.h @@ -32,7 +32,7 @@ class TC_GAME_API ObjectGridLoader friend class ObjectWorldLoader; public: - ObjectGridLoader(NGridType &grid, Map* map, const Cell &cell) + ObjectGridLoader(NGridType& grid, Map* map, Cell const& cell) : i_cell(cell), i_grid(grid), i_map(map), i_gameObjects(0), i_creatures(0), i_corpses (0) { } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index dffe6250444..76b7de68ea9 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -16,26 +16,32 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "CharacterCache.h" -#include "Common.h" -#include "Opcodes.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Player.h" -#include "World.h" -#include "ObjectMgr.h" -#include "GroupMgr.h" #include "Group.h" -#include "Formulas.h" -#include "ObjectAccessor.h" #include "Battleground.h" #include "BattlegroundMgr.h" -#include "MapManager.h" +#include "Common.h" +#include "CharacterCache.h" +#include "DatabaseEnv.h" +#include "Formulas.h" +#include "GameObject.h" +#include "GroupMgr.h" #include "InstanceSaveMgr.h" -#include "Util.h" +#include "LootMgr.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "Player.h" +#include "MapManager.h" +#include "Log.h" #include "LFGMgr.h" -#include "UpdateFieldFlags.h" +#include "Random.h" #include "SpellAuras.h" +#include "UpdateData.h" +#include "UpdateFieldFlags.h" +#include "Util.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" Roll::Roll(ObjectGuid _guid, LootItem const& li) : itemGUID(_guid), itemid(li.itemid), itemRandomPropId(li.randomPropertyId), itemRandomSuffix(li.randomSuffix), itemCount(li.count), @@ -56,8 +62,8 @@ Loot* Roll::getLoot() Group::Group() : m_leaderGuid(), m_leaderName(""), m_groupType(GROUPTYPE_NORMAL), m_dungeonDifficulty(DUNGEON_DIFFICULTY_NORMAL), m_raidDifficulty(RAID_DIFFICULTY_10MAN_NORMAL), -m_bgGroup(NULL), m_bfGroup(NULL), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), -m_masterLooterGuid(), m_subGroupsCounts(NULL), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0) +m_bgGroup(nullptr), m_bfGroup(nullptr), m_lootMethod(FREE_FOR_ALL), m_lootThreshold(ITEM_QUALITY_UNCOMMON), m_looterGuid(), +m_masterLooterGuid(), m_subGroupsCounts(nullptr), m_guid(), m_counter(0), m_maxEnchantingLevel(0), m_dbStoreId(0) { for (uint8 i = 0; i < TARGETICONCOUNT; ++i) m_targetIcons[i].Clear(); @@ -68,9 +74,12 @@ Group::~Group() if (m_bgGroup) { TC_LOG_DEBUG("bg.battleground", "Group::~Group: battleground group being deleted."); - if (m_bgGroup->GetBgRaid(ALLIANCE) == this) m_bgGroup->SetBgRaid(ALLIANCE, NULL); - else if (m_bgGroup->GetBgRaid(HORDE) == this) m_bgGroup->SetBgRaid(HORDE, NULL); - else TC_LOG_ERROR("misc", "Group::~Group: battleground group is not linked to the correct battleground."); + if (m_bgGroup->GetBgRaid(ALLIANCE) == this) + m_bgGroup->SetBgRaid(ALLIANCE, nullptr); + else if (m_bgGroup->GetBgRaid(HORDE) == this) + m_bgGroup->SetBgRaid(HORDE, nullptr); + else + TC_LOG_ERROR("misc", "Group::~Group: battleground group is not linked to the correct battleground."); } Rolls::iterator itr; while (!RollId.empty()) @@ -301,15 +310,15 @@ void Group::RemoveInvite(Player* player) if (player) { m_invitees.erase(player); - player->SetGroupInvite(NULL); + player->SetGroupInvite(nullptr); } } void Group::RemoveAllInvites() { - for (InvitesList::iterator itr=m_invitees.begin(); itr != m_invitees.end(); ++itr) + for (InvitesList::iterator itr = m_invitees.begin(); itr != m_invitees.end(); ++itr) if (*itr) - (*itr)->SetGroupInvite(NULL); + (*itr)->SetGroupInvite(nullptr); m_invitees.clear(); } @@ -321,7 +330,7 @@ Player* Group::GetInvited(ObjectGuid guid) const if ((*itr) && (*itr)->GetGUID() == guid) return (*itr); } - return NULL; + return nullptr; } Player* Group::GetInvited(const std::string& name) const @@ -331,7 +340,7 @@ Player* Group::GetInvited(const std::string& name) const if ((*itr) && (*itr)->GetName() == name) return (*itr); } - return NULL; + return nullptr; } bool Group::AddMember(Player* player) @@ -364,7 +373,7 @@ bool Group::AddMember(Player* player) SubGroupCounterIncrease(subGroup); - player->SetGroupInvite(NULL); + player->SetGroupInvite(nullptr); if (player->GetGroup()) { if (isBGGroup() || isBFGroup()) // if player is in group and he is being added to BG raid group, then call SetBattlegroundRaid() @@ -437,7 +446,7 @@ bool Group::AddMember(Player* player) WorldPacket groupDataPacket; // Broadcast group members' fields to player - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { if (itr->GetSource() == player) continue; @@ -480,7 +489,7 @@ bool Group::AddMember(Player* player) return true; } -bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_REMOVEMETHOD_DEFAULT*/, ObjectGuid kicker /*= 0*/, const char* reason /*= NULL*/) +bool Group::RemoveMember(ObjectGuid guid, RemoveMethod const& method /*= GROUP_REMOVEMETHOD_DEFAULT*/, ObjectGuid kicker /*= ObjectGuid::Empty*/, char const* reason /*= nullptr*/) { BroadcastGroupUpdate(); @@ -518,9 +527,9 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R // Regular group { if (player->GetOriginalGroup() == this) - player->SetOriginalGroup(NULL); + player->SetOriginalGroup(nullptr); else - player->SetGroup(NULL); + player->SetGroup(nullptr); // quest related GO state dependent from raid membership player->UpdateForQuestWorldObjects(); @@ -531,14 +540,14 @@ bool Group::RemoveMember(ObjectGuid guid, const RemoveMethod& method /*= GROUP_R if (method == GROUP_REMOVEMETHOD_KICK || method == GROUP_REMOVEMETHOD_KICK_LFG) { data.Initialize(SMSG_GROUP_UNINVITE, 0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } // Do we really need to send this opcode? data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8); data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0); data << uint64(m_guid) << uint32(m_counter) << uint32(0) << uint64(0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); _homebindIfInstance(player); } @@ -750,9 +759,9 @@ void Group::Disband(bool hideDestroy /* = false */) { //we can remove player who is in battleground from his original group if (player->GetOriginalGroup() == this) - player->SetOriginalGroup(NULL); + player->SetOriginalGroup(nullptr); else - player->SetGroup(NULL); + player->SetGroup(nullptr); } // quest related GO state dependent from raid membership @@ -766,7 +775,7 @@ void Group::Disband(bool hideDestroy /* = false */) if (!hideDestroy) { data.Initialize(SMSG_GROUP_DESTROYED, 0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } //we already removed player from group and in player->GetGroup() is his original group, send update @@ -779,7 +788,7 @@ void Group::Disband(bool hideDestroy /* = false */) data.Initialize(SMSG_GROUP_LIST, 1+1+1+1+8+4+4+8); data << uint8(0x10) << uint8(0) << uint8(0) << uint8(0); data << uint64(m_guid) << uint32(m_counter) << uint32(0) << uint64(0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } _homebindIfInstance(player); @@ -803,8 +812,8 @@ void Group::Disband(bool hideDestroy /* = false */) CharacterDatabase.CommitTransaction(trans); - ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); - ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); + ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, nullptr); + ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, nullptr); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_LFG_DATA); stmt->setUInt32(0, m_dbStoreId); @@ -821,7 +830,7 @@ void Group::Disband(bool hideDestroy /* = false */) /*** LOOT SYSTEM ***/ /*********************************************************/ -void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r) +void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, Roll const& r) { WorldPacket data(SMSG_LOOT_START_ROLL, (8+4+4+4+4+4+4+1)); data << uint64(r.itemGUID); // guid of rolled item @@ -841,7 +850,7 @@ void Group::SendLootStartRoll(uint32 countDown, uint32 mapid, const Roll &r) continue; if (itr->second == NOT_EMITED_YET) - p->GetSession()->SendPacket(&data); + p->SendDirectMessage(&data); } } @@ -864,7 +873,7 @@ void Group::SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, voteMask &= ~ROLL_FLAG_TYPE_NEED; data << uint8(voteMask); // roll type mask - p->GetSession()->SendPacket(&data); + p->SendDirectMessage(&data); } void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rollNumber, uint8 rollType, Roll const& roll) @@ -887,7 +896,7 @@ void Group::SendLootRoll(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 rol continue; if (itr->second != NOT_VALID) - p->GetSession()->SendPacket(&data); + p->SendDirectMessage(&data); } } @@ -910,7 +919,7 @@ void Group::SendLootRollWon(ObjectGuid sourceGuid, ObjectGuid targetGuid, uint8 continue; if (itr->second != NOT_VALID) - p->GetSession()->SendPacket(&data); + p->SendDirectMessage(&data); } } @@ -930,7 +939,7 @@ void Group::SendLootAllPassed(Roll const& roll) continue; if (itr->second != NOT_VALID) - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } } @@ -981,7 +990,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) Roll* r = new Roll(newitemGUID, *i); //a vector is filled with only near party members - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member || !member->GetSession()) @@ -1063,7 +1072,7 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) Roll* r = new Roll(newitemGUID, *i); //a vector is filled with only near party members - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member || !member->GetSession()) @@ -1121,7 +1130,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) Roll* r = new Roll(newitemGUID, *i); - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* playerToRoll = itr->GetSource(); if (!playerToRoll || !playerToRoll->GetSession()) @@ -1196,7 +1205,7 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) Roll* r = new Roll(newitemGUID, *i); - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* playerToRoll = itr->GetSource(); if (!playerToRoll || !playerToRoll->GetSession()) @@ -1272,7 +1281,7 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject) WorldPacket data(SMSG_LOOT_MASTER_LIST, 1 + GetMembersCount() * 8); data << uint8(GetMembersCount()); - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* looter = itr->GetSource(); if (!looter->IsInWorld()) @@ -1287,11 +1296,11 @@ void Group::MasterLoot(Loot* loot, WorldObject* pLootedObject) data.put<uint8>(0, real_count); - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* looter = itr->GetSource(); if (looter->IsAtGroupRewardDistance(pLootedObject)) - looter->GetSession()->SendPacket(&data); + looter->SendDirectMessage(&data); } } @@ -1372,7 +1381,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap) ObjectGuid maxguid = ObjectGuid::Empty; Player* player = nullptr; - for (Roll::PlayerVote::const_iterator itr=roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr) + for (Roll::PlayerVote::const_iterator itr = roll->playerVote.begin(); itr != roll->playerVote.end(); ++itr) { if (itr->second != NEED) continue; @@ -1416,7 +1425,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap) { item->is_blocked = false; item->rollWinnerGUID = player->GetGUID(); - player->SendEquipError(msg, NULL, NULL, roll->itemid); + player->SendEquipError(msg, nullptr, nullptr, roll->itemid); } } } @@ -1441,7 +1450,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap) continue; player = ObjectAccessor::FindPlayer(itr->first); - if (!player || (allowedMap != NULL && player->FindMap() != allowedMap)) + if (!player || (allowedMap != nullptr && player->FindMap() != allowedMap)) { --roll->totalGreed; continue; @@ -1483,7 +1492,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap) { item->is_blocked = false; item->rollWinnerGUID = player->GetGUID(); - player->SendEquipError(msg, NULL, NULL, roll->itemid); + player->SendEquipError(msg, nullptr, nullptr, roll->itemid); } } else if (rollvote == DISENCHANT) @@ -1507,7 +1516,7 @@ void Group::CountTheRoll(Rolls::iterator rollI, Map* allowedMap) for (uint32 i = 0; i < max_slot; ++i) { LootItem* lootItem = loot.LootItemInSlot(i, player); - player->SendEquipError(msg, NULL, NULL, lootItem->itemid); + player->SendEquipError(msg, nullptr, nullptr, lootItem->itemid); player->SendItemRetrievalMail(lootItem->itemid, lootItem->count); } } @@ -1647,7 +1656,7 @@ void Group::SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot) data << uint8(m_raidDifficulty >= RAID_DIFFICULTY_10MAN_HEROIC); // 3.3 Dynamic Raid Difficulty - 0 normal/1 heroic } - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } void Group::UpdatePlayerOutOfRange(Player* player) @@ -1659,35 +1668,35 @@ void Group::UpdatePlayerOutOfRange(Player* player) player->GetSession()->BuildPartyMemberStatsChangedPacket(player, &data); Player* member; - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { member = itr->GetSource(); if (member && member != player && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(), false))) - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); } } void Group::BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group /*= -1*/, ObjectGuid ignoredPlayer /*= ObjectGuid::Empty*/) { - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* player = itr->GetSource(); if (!player || (!ignoredPlayer.IsEmpty() && player->GetGUID() == ignoredPlayer) || (ignorePlayersInBGRaid && player->GetGroup() != this)) continue; if (player->GetSession() && (group == -1 || itr->getSubGroup() == group)) - player->GetSession()->SendPacket(packet); + player->SendDirectMessage(packet); } } void Group::BroadcastReadyCheck(WorldPacket* packet) { - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* player = itr->GetSource(); if (player && player->GetSession()) if (IsLeader(player->GetGUID()) || IsAssistant(player->GetGUID())) - player->GetSession()->SendPacket(packet); + player->SendDirectMessage(packet); } } @@ -1827,7 +1836,7 @@ void Group::UpdateLooterGuid(WorldObject* pLootedObject, bool ifneed) } // search next after current - Player* pNewLooter = NULL; + Player* pNewLooter = nullptr; for (member_citerator itr = guid_itr; itr != m_memberSlots.end(); ++itr) { if (Player* player = ObjectAccessor::FindPlayer(itr->guid)) @@ -1900,7 +1909,7 @@ GroupJoinBattlegroundResult Group::CanJoinBattlegroundQueue(Battleground const* // check every member of the group to be able to join memberscount = 0; - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next(), ++memberscount) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next(), ++memberscount) { Player* member = itr->GetSource(); // offline member? don't let join @@ -1969,7 +1978,7 @@ void Group::SetDungeonDifficulty(Difficulty difficulty) CharacterDatabase.Execute(stmt); } - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* player = itr->GetSource(); if (!player->GetSession()) @@ -1993,7 +2002,7 @@ void Group::SetRaidDifficulty(Difficulty difficulty) CharacterDatabase.Execute(stmt); } - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* player = itr->GetSource(); if (!player->GetSession()) @@ -2006,7 +2015,7 @@ void Group::SetRaidDifficulty(Difficulty difficulty) bool Group::InCombatToInstance(uint32 instanceId) { - for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* player = itr->GetSource(); if (player && player->GetInstanceId() == instanceId && !player->getAttackers().empty() && (player->GetMap()->IsRaidOrHeroicDungeon())) @@ -2030,7 +2039,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) for (BoundInstancesMap::iterator itr = m_boundInstances[diff].begin(); itr != m_boundInstances[diff].end();) { InstanceSave* instanceSave = itr->second.save; - const MapEntry* entry = sMapStore.LookupEntry(itr->first); + MapEntry const* entry = sMapStore.LookupEntry(itr->first); if (!entry || entry->IsRaid() != isRaid || (!instanceSave->CanReset() && method != INSTANCE_RESET_GROUP_DISBAND)) { ++itr; @@ -2066,7 +2075,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) { if (Group* group = SendMsgTo->GetGroup()) { - for (GroupReference* groupRef = group->GetFirstMember(); groupRef != NULL; groupRef = groupRef->next()) + for (GroupReference* groupRef = group->GetFirstMember(); groupRef != nullptr; groupRef = groupRef->next()) if (Player* player = groupRef->GetSource()) player->SendResetInstanceSuccess(instanceSave->GetMapId()); } @@ -2122,7 +2131,7 @@ InstanceGroupBind* Group::GetBoundInstance(Map* aMap) InstanceGroupBind* Group::GetBoundInstance(MapEntry const* mapEntry) { if (!mapEntry || !mapEntry->IsDungeon()) - return NULL; + return nullptr; Difficulty difficulty = GetDifficulty(mapEntry->IsRaid()); return GetBoundInstance(difficulty, mapEntry->MapID); @@ -2137,13 +2146,13 @@ InstanceGroupBind* Group::GetBoundInstance(Difficulty difficulty, uint32 mapId) if (itr != m_boundInstances[difficulty].end()) return &itr->second; else - return NULL; + return nullptr; } InstanceGroupBind* Group::BindToInstance(InstanceSave* save, bool permanent, bool load) { if (!save || isBGGroup() || isBFGroup()) - return NULL; + return nullptr; InstanceGroupBind& bind = m_boundInstances[save->GetDifficulty()][save->GetMapId()]; if (!load && (!bind.save || permanent != bind.perm || save != bind.save)) @@ -2218,7 +2227,7 @@ void Group::BroadcastGroupUpdate(void) void Group::ResetMaxEnchantingLevel() { m_maxEnchantingLevel = 0; - Player* member = NULL; + Player* member = nullptr; for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) { member = ObjectAccessor::FindPlayer(citr->guid); @@ -2274,12 +2283,12 @@ bool Group::isRaidGroup() const bool Group::isBGGroup() const { - return m_bgGroup != NULL; + return m_bgGroup != nullptr; } bool Group::isBFGroup() const { - return m_bfGroup != NULL; + return m_bfGroup != nullptr; } bool Group::IsCreated() const @@ -2459,7 +2468,7 @@ bool Group::isRollLootActive() const Group::Rolls::iterator Group::GetRoll(ObjectGuid Guid) { Rolls::iterator iter; - for (iter=RollId.begin(); iter != RollId.end(); ++iter) + for (iter = RollId.begin(); iter != RollId.end(); ++iter) if ((*iter)->itemGUID == Guid && (*iter)->isValid()) return iter; return RollId.end(); diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index bee3f95350a..1aa498842cf 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -20,10 +20,11 @@ #define TRINITYCORE_GROUP_H #include "DBCEnums.h" +#include "DatabaseEnvFwd.h" #include "GroupRefManager.h" -#include "LootMgr.h" -#include "QueryResult.h" +#include "Loot.h" #include "SharedDefines.h" +#include <map> class Battlefield; class Battleground; @@ -153,7 +154,7 @@ struct InstanceGroupBind bool perm; /* permanent InstanceGroupBinds exist if the leader has a permanent PlayerInstanceBind for the same instance. */ - InstanceGroupBind() : save(NULL), perm(false) { } + InstanceGroupBind() : save(nullptr), perm(false) { } }; /** request member stats checken **/ @@ -192,7 +193,7 @@ class TC_GAME_API Group void RemoveAllInvites(); bool AddLeaderInvite(Player* player); bool AddMember(Player* player); - bool RemoveMember(ObjectGuid guid, const RemoveMethod &method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, const char* reason = NULL); + bool RemoveMember(ObjectGuid guid, RemoveMethod const& method = GROUP_REMOVEMETHOD_DEFAULT, ObjectGuid kicker = ObjectGuid::Empty, char const* reason = nullptr); void ChangeLeader(ObjectGuid guid); static void ConvertLeaderInstancesToGroup(Player* player, Group* group, bool switchLeader); void SetLootMethod(LootMethod method); @@ -272,7 +273,7 @@ class TC_GAME_API Group //void SendInit(WorldSession* session); void SendTargetIconList(WorldSession* session); void SendUpdate(); - void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = NULL); + void SendUpdateToPlayer(ObjectGuid playerGUID, MemberSlot* slot = nullptr); void UpdatePlayerOutOfRange(Player* player); template<class Worker> @@ -298,10 +299,10 @@ class TC_GAME_API Group /*********************************************************/ bool isRollLootActive() const; - void SendLootStartRoll(uint32 CountDown, uint32 mapid, const Roll &r); + void SendLootStartRoll(uint32 CountDown, uint32 mapid, Roll const& r); void SendLootStartRollToPlayer(uint32 countDown, uint32 mapId, Player* p, bool canNeed, Roll const& r); - void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); - void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, const Roll &r); + void SendLootRoll(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const& r); + void SendLootRollWon(ObjectGuid SourceGuid, ObjectGuid TargetGuid, uint8 RollNumber, uint8 RollType, Roll const& r); void SendLootAllPassed(Roll const& roll); void SendLooter(Creature* creature, Player* pLooter); void GroupLoot(Loot* loot, WorldObject* pLootedObject); diff --git a/src/server/game/Groups/GroupMgr.cpp b/src/server/game/Groups/GroupMgr.cpp index 1d0714bdf3e..13a017c4443 100644 --- a/src/server/game/Groups/GroupMgr.cpp +++ b/src/server/game/Groups/GroupMgr.cpp @@ -15,11 +15,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" #include "GroupMgr.h" +#include "Common.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "InstanceSaveMgr.h" +#include "Log.h" #include "World.h" -#include "DBCStores.h" GroupMgr::GroupMgr() { @@ -39,7 +41,7 @@ uint32 GroupMgr::GenerateNewGroupDbStoreId() for (uint32 i = ++NextGroupDbStoreId; i < 0xFFFFFFFF; ++i) { - if ((i < GroupDbStore.size() && GroupDbStore[i] == NULL) || i >= GroupDbStore.size()) + if ((i < GroupDbStore.size() && GroupDbStore[i] == nullptr) || i >= GroupDbStore.size()) { NextGroupDbStoreId = i; break; @@ -71,7 +73,7 @@ void GroupMgr::FreeGroupDbStoreId(Group* group) if (storageId < NextGroupDbStoreId) NextGroupDbStoreId = storageId; - GroupDbStore[storageId] = NULL; + GroupDbStore[storageId] = nullptr; } Group* GroupMgr::GetGroupByDbStoreId(uint32 storageId) const @@ -79,7 +81,7 @@ Group* GroupMgr::GetGroupByDbStoreId(uint32 storageId) const if (storageId < GroupDbStore.size()) return GroupDbStore[storageId]; - return NULL; + return nullptr; } ObjectGuid::LowType GroupMgr::GenerateGroupId() @@ -104,7 +106,7 @@ Group* GroupMgr::GetGroupByGUID(ObjectGuid::LowType groupId) const if (itr != GroupStore.end()) return itr->second; - return NULL; + return nullptr; } void GroupMgr::AddGroup(Group* group) diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 488601d9536..54d802ef546 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -16,20 +16,25 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Guild.h" #include "AccountMgr.h" +#include "Bag.h" #include "CalendarMgr.h" #include "CharacterCache.h" #include "Chat.h" #include "Config.h" #include "DatabaseEnv.h" -#include "Guild.h" #include "GuildMgr.h" #include "Language.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "Player.h" #include "ScriptMgr.h" #include "SocialMgr.h" -#include "Opcodes.h" - +#include "World.h" +#include "WorldSession.h" size_t const MAX_GUILD_BANK_TAB_TEXT_LEN = 500; @@ -384,6 +389,11 @@ void Guild::RankInfo::SetBankTabSlotsAndRights(GuildBankRightsAndSlots rightsAnd } // BankTab +Guild::BankTab::BankTab(ObjectGuid::LowType guildId, uint8 tabId) : m_guildId(guildId), m_tabId(tabId) +{ + memset(m_items, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); +} + void Guild::BankTab::LoadFromDB(Field* fields) { m_name = fields[2].GetString(); @@ -505,6 +515,12 @@ bool Guild::BankTab::WriteSlotPacket(WorldPacket& data, uint8 slotId, bool ignor return true; } +void Guild::BankTab::WriteInfoPacket(WorldPacket& data) const +{ + data << m_name; + data << m_icon; +} + void Guild::BankTab::SetInfo(std::string const& name, std::string const& icon) { if (m_name == name && m_icon == icon) @@ -589,6 +605,20 @@ void Guild::BankTab::SendText(Guild const* guild, WorldSession* session) const } // Member +Guild::Member::Member(ObjectGuid::LowType guildId, ObjectGuid guid, uint8 rankId) : + m_guildId(guildId), + m_guid(guid), + m_zoneId(0), + m_level(0), + m_class(0), + m_flags(GUILDMEMBER_STATUS_NONE), + m_logoutTime(::time(nullptr)), + m_accountId(0), + m_rankId(rankId) +{ + memset(m_bankWithdraw, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(int32)); +} + void Guild::Member::SetStats(Player* player) { m_name = player->GetName(); @@ -728,6 +758,16 @@ void Guild::Member::WritePacket(WorldPacket& data, bool sendOfficerNote) const data << ""; } +Player* Guild::Member::FindPlayer() const +{ + return ObjectAccessor::FindPlayer(m_guid); +} + +Player* Guild::Member::FindConnectedPlayer() const +{ + return ObjectAccessor::FindConnectedPlayer(m_guid); +} + // Decreases amount of money/slots left for today. // If (tabId == GUILD_BANK_MAX_TABS) decrease money amount. // Otherwise decrease remaining items amount for specified tab. @@ -801,6 +841,15 @@ void EmblemInfo::SaveToDB(ObjectGuid::LowType guildId) const } // MoveItemData +Guild::MoveItemData::MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : m_pGuild(guild), m_pPlayer(player), +m_container(container), m_slotId(slotId), m_pItem(nullptr), m_pClonedItem(nullptr) +{ +} + +Guild::MoveItemData::~MoveItemData() +{ +} + bool Guild::MoveItemData::CheckItem(uint32& splitedAmount) { ASSERT(m_pItem); @@ -1392,7 +1441,7 @@ void Guild::HandleSetInfo(WorldSession* session, std::string const& info) } } -void Guild::HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo) +void Guild::HandleSetEmblem(WorldSession* session, EmblemInfo const& emblemInfo) { Player* player = session->GetPlayer(); if (!_IsLeader(player)) @@ -1463,7 +1512,7 @@ void Guild::HandleSetMemberNote(WorldSession* session, std::string const& name, } } -void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, const GuildBankRightsAndSlotsVec& rightsAndSlots) +void Guild::HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots) { // Only leader can modify ranks if (!_IsLeader(session->GetPlayer())) @@ -1561,7 +1610,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) WorldPacket data(SMSG_GUILD_INVITE, 8 + 10); // Guess size data << player->GetName(); data << m_name; - pInvitee->GetSession()->SendPacket(&data); + pInvitee->SendDirectMessage(&data); TC_LOG_DEBUG("guild", "SMSG_GUILD_INVITE [%s]", pInvitee->GetName().c_str()); } @@ -1857,7 +1906,7 @@ void Guild::SendBankLog(WorldSession* session, uint8 tabId) const // GUILD_BANK_MAX_TABS send by client for money log if (tabId < _GetPurchasedTabsSize() || tabId == GUILD_BANK_MAX_TABS) { - const LogHolder* pLog = m_bankEventLog[tabId]; + LogHolder const* pLog = m_bankEventLog[tabId]; WorldPacket data(MSG_GUILD_BANK_LOG_QUERY, pLog->GetSize() * (4 * 4 + 1) + 1 + 1); data << uint8(tabId); pLog->WritePacket(data); @@ -2164,7 +2213,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin if (Player* player = itr->second->FindConnectedPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID())) - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } } @@ -2173,14 +2222,14 @@ void Guild::BroadcastPacketToRank(WorldPacket* packet, uint8 rankId) const for (auto itr = m_members.begin(); itr != m_members.end(); ++itr) if (itr->second->IsRank(rankId)) if (Player* player = itr->second->FindConnectedPlayer()) - player->GetSession()->SendPacket(packet); + player->SendDirectMessage(packet); } void Guild::BroadcastPacket(WorldPacket* packet) const { for (auto itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindPlayer()) - player->GetSession()->SendPacket(packet); + player->SendDirectMessage(packet); } void Guild::MassInviteToEvent(WorldSession* session, uint32 minLevel, uint32 maxLevel, uint32 minRank) @@ -2406,6 +2455,21 @@ void Guild::SetBankTabText(uint8 tabId, std::string const& text) } } +bool Guild::_HasRankRight(Player* player, uint32 right) const +{ + if (player) + if (Member const* member = GetMember(player->GetGUID())) + return (_GetRankRights(member->GetRankId()) & right) != GR_RIGHT_EMPTY; + return false; +} + +void Guild::_DeleteMemberFromDB(SQLTransaction& trans, ObjectGuid::LowType lowguid) +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER); + stmt->setUInt32(0, lowguid); + CharacterDatabase.ExecuteOrAppend(trans, stmt); +} + // Private methods void Guild::_CreateLogHolders() { @@ -2499,7 +2563,7 @@ bool Guild::_IsLeader(Player* player) const { if (player->GetGUID() == m_leaderGuid) return true; - if (const Member* member = GetMember(player->GetGUID())) + if (Member const* member = GetMember(player->GetGUID())) return member->IsRank(GR_GUILDMASTER); return false; } @@ -2568,21 +2632,21 @@ void Guild::_SetRankBankTabRightsAndSlots(uint8 rankId, GuildBankRightsAndSlots inline std::string Guild::_GetRankName(uint8 rankId) const { - if (const RankInfo* rankInfo = GetRankInfo(rankId)) + if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetName(); return "<unknown>"; } inline uint32 Guild::_GetRankRights(uint8 rankId) const { - if (const RankInfo* rankInfo = GetRankInfo(rankId)) + if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetRights(); return 0; } inline int32 Guild::_GetRankBankMoneyPerDay(uint8 rankId) const { - if (const RankInfo* rankInfo = GetRankInfo(rankId)) + if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankMoneyPerDay(); return 0; } @@ -2590,14 +2654,14 @@ inline int32 Guild::_GetRankBankMoneyPerDay(uint8 rankId) const inline int32 Guild::_GetRankBankTabSlotsPerDay(uint8 rankId, uint8 tabId) const { if (tabId < _GetPurchasedTabsSize()) - if (const RankInfo* rankInfo = GetRankInfo(rankId)) + if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankTabSlotsPerDay(tabId); return 0; } inline int8 Guild::_GetRankBankTabRights(uint8 rankId, uint8 tabId) const { - if (const RankInfo* rankInfo = GetRankInfo(rankId)) + if (RankInfo const* rankInfo = GetRankInfo(rankId)) return rankInfo->GetBankTabRights(tabId); return 0; } @@ -2650,7 +2714,7 @@ inline void Guild::_UpdateMemberWithdrawSlots(SQLTransaction& trans, ObjectGuid inline bool Guild::_MemberHasTabRights(ObjectGuid guid, uint8 tabId, uint32 rights) const { - if (const Member* member = GetMember(guid)) + if (Member const* member = GetMember(guid)) { // Leader always has full rights if (member->IsRank(GR_GUILDMASTER) || m_leaderGuid == guid) @@ -2694,7 +2758,7 @@ void Guild::_LogBankEvent(SQLTransaction& trans, GuildBankEventLogTypes eventTyp inline Item* Guild::_GetItem(uint8 tabId, uint8 slotId) const { - if (const BankTab* tab = GetBankTab(tabId)) + if (BankTab const* tab = GetBankTab(tabId)) return tab->GetItem(slotId); return nullptr; } @@ -2861,7 +2925,7 @@ void Guild::_SendBankContentUpdate(uint8 tabId, SlotIds slots) const _SendBankList(nullptr, tabId, false, &slots); } -void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, const char* param1, const char* param2, const char* param3) const +void Guild::_BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, char const* param1, char const* param2, char const* param3) const { uint8 count = !param3 ? (!param2 ? (!param1 ? 0 : 1) : 2) : 3; @@ -2936,7 +3000,7 @@ void Guild::_SendBankList(WorldSession* session /* = nullptr*/, uint8 tabId /*= uint32 numSlots = _GetMemberRemainingSlots(itr->second, tabId); data.put<uint32>(rempos, numSlots); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); TC_LOG_DEBUG("guild", "SMSG_GUILD_BANK_LIST [%s]: TabId: %u, FullSlots: %u, slots: %u" , player->GetName().c_str(), tabId, sendAllSlots, numSlots); } diff --git a/src/server/game/Guilds/Guild.h b/src/server/game/Guilds/Guild.h index 38510d8c06b..4c904dd8e37 100644 --- a/src/server/game/Guilds/Guild.h +++ b/src/server/game/Guilds/Guild.h @@ -19,13 +19,18 @@ #ifndef TRINITYCORE_GUILD_H #define TRINITYCORE_GUILD_H -#include "World.h" -#include "Item.h" -#include "WorldPacket.h" -#include "ObjectMgr.h" -#include "Player.h" +#include "DatabaseEnvFwd.h" +#include "ObjectGuid.h" +#include "SharedDefines.h" +#include <unordered_map> class Item; +class Player; +class WorldPacket; +class WorldSession; +struct ItemPosCount; +enum InventoryResult : uint8; +enum LocaleConstant : uint8; enum GuildMisc { @@ -270,19 +275,7 @@ class TC_GAME_API Guild class Member { public: - Member(ObjectGuid::LowType guildId, ObjectGuid guid, uint8 rankId) : - m_guildId(guildId), - m_guid(guid), - m_zoneId(0), - m_level(0), - m_class(0), - m_flags(GUILDMEMBER_STATUS_NONE), - m_logoutTime(::time(nullptr)), - m_accountId(0), - m_rankId(rankId) - { - memset(m_bankWithdraw, 0, (GUILD_BANK_MAX_TABS + 1) * sizeof(int32)); - } + Member(ObjectGuid::LowType guildId, ObjectGuid guid, uint8 rankId); void SetStats(Player* player); void SetStats(std::string const& name, uint8 level, uint8 _class, uint32 zoneId, uint32 accountId); @@ -325,8 +318,8 @@ class TC_GAME_API Guild int32 GetBankWithdrawValue(uint8 tabId) const; void ResetValues(); - inline Player* FindPlayer() const { return ObjectAccessor::FindPlayer(m_guid); } - inline Player* FindConnectedPlayer() const { return ObjectAccessor::FindConnectedPlayer(m_guid); } + Player* FindPlayer() const; + Player* FindConnectedPlayer() const; private: ObjectGuid::LowType m_guildId; @@ -501,10 +494,7 @@ class TC_GAME_API Guild class BankTab { public: - BankTab(ObjectGuid::LowType guildId, uint8 tabId) : m_guildId(guildId), m_tabId(tabId) - { - memset(m_items, 0, GUILD_BANK_MAX_SLOTS * sizeof(Item*)); - } + BankTab(ObjectGuid::LowType guildId, uint8 tabId); void LoadFromDB(Field* fields); bool LoadItemFromDB(Field* fields); @@ -512,17 +502,13 @@ class TC_GAME_API Guild void WritePacket(WorldPacket& data) const; bool WriteSlotPacket(WorldPacket& data, uint8 slotId, bool ignoreEmpty = true) const; - void WriteInfoPacket(WorldPacket& data) const - { - data << m_name; - data << m_icon; - } + void WriteInfoPacket(WorldPacket& data) const; void SetInfo(std::string const& name, std::string const& icon); void SetText(std::string const& text); - void SendText(const Guild* guild, WorldSession* session) const; + void SendText(Guild const* guild, WorldSession* session) const; - inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : NULL; } + inline Item* GetItem(uint8 slotId) const { return slotId < GUILD_BANK_MAX_SLOTS ? m_items[slotId] : nullptr; } bool SetItem(SQLTransaction& trans, uint8 slotId, Item* pItem); private: @@ -539,9 +525,8 @@ class TC_GAME_API Guild class MoveItemData { public: - MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId) : m_pGuild(guild), m_pPlayer(player), - m_container(container), m_slotId(slotId), m_pItem(NULL), m_pClonedItem(NULL) { } - virtual ~MoveItemData() { } + MoveItemData(Guild* guild, Player* player, uint8 container, uint8 slotId); + virtual ~MoveItemData(); virtual bool IsBank() const = 0; // Initializes item pointer. Returns true, if item exists, false otherwise. @@ -580,7 +565,7 @@ class TC_GAME_API Guild uint8 m_slotId; Item* m_pItem; Item* m_pClonedItem; - ItemPosCountVec m_vec; + std::vector<ItemPosCount> m_vec; }; class PlayerMoveItemData : public MoveItemData @@ -653,11 +638,11 @@ class TC_GAME_API Guild void HandleQuery(WorldSession* session); void HandleSetMOTD(WorldSession* session, std::string const& motd); void HandleSetInfo(WorldSession* session, std::string const& info); - void HandleSetEmblem(WorldSession* session, const EmblemInfo& emblemInfo); + void HandleSetEmblem(WorldSession* session, EmblemInfo const& emblemInfo); void HandleSetLeader(WorldSession* session, std::string const& name); void HandleSetBankTabInfo(WorldSession* session, uint8 tabId, std::string const& name, std::string const& icon); void HandleSetMemberNote(WorldSession* session, std::string const& name, std::string const& note, bool officer); - void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, const GuildBankRightsAndSlotsVec& rightsAndSlots); + void HandleSetRankInfo(WorldSession* session, uint8 rankId, std::string const& name, uint32 rights, uint32 moneyPerDay, GuildBankRightsAndSlotsVec const& rightsAndSlots); void HandleBuyBankTab(WorldSession* session, uint8 tabId); void HandleInviteMember(WorldSession* session, std::string const& name); void HandleAcceptMember(WorldSession* session); @@ -752,13 +737,7 @@ class TC_GAME_API Guild inline uint8 _GetRanksSize() const { return uint8(m_ranks.size()); } inline RankInfo const* GetRankInfo(uint8 rankId) const { return rankId < _GetRanksSize() ? &m_ranks[rankId] : nullptr; } inline RankInfo* GetRankInfo(uint8 rankId) { return rankId < _GetRanksSize() ? &m_ranks[rankId] : nullptr; } - inline bool _HasRankRight(Player* player, uint32 right) const - { - if (player) - if (Member const* member = GetMember(player->GetGUID())) - return (_GetRankRights(member->GetRankId()) & right) != GR_RIGHT_EMPTY; - return false; - } + bool _HasRankRight(Player* player, uint32 right) const; inline uint8 _GetLowestRankId() const { return uint8(m_ranks.size() - 1); } @@ -787,12 +766,7 @@ class TC_GAME_API Guild return nullptr; } - inline void _DeleteMemberFromDB(SQLTransaction& trans, ObjectGuid::LowType lowguid) const - { - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GUILD_MEMBER); - stmt->setUInt32(0, lowguid); - CharacterDatabase.ExecuteOrAppend(trans, stmt); - } + static void _DeleteMemberFromDB(SQLTransaction& trans, ObjectGuid::LowType lowguid); // Creates log holders (either when loading or when creating guild) void _CreateLogHolders(); @@ -834,8 +808,8 @@ class TC_GAME_API Guild void _SendBankMoneyUpdate(WorldSession* session) const; void _SendBankContentUpdate(MoveItemData* pSrc, MoveItemData* pDest) const; void _SendBankContentUpdate(uint8 tabId, SlotIds slots) const; - void _SendBankList(WorldSession* session = NULL, uint8 tabId = 0, bool sendFullSlots = false, SlotIds *slots = NULL) const; + void _SendBankList(WorldSession* session = nullptr, uint8 tabId = 0, bool sendFullSlots = false, SlotIds* slots = nullptr) const; - void _BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, const char* param1 = NULL, const char* param2 = NULL, const char* param3 = NULL) const; + void _BroadcastEvent(GuildEvents guildEvent, ObjectGuid guid, char const* param1 = nullptr, char const* param2 = nullptr, char const* param3 = nullptr) const; }; #endif diff --git a/src/server/game/Guilds/GuildMgr.cpp b/src/server/game/Guilds/GuildMgr.cpp index ca89fae95c1..e49e3dd624e 100644 --- a/src/server/game/Guilds/GuildMgr.cpp +++ b/src/server/game/Guilds/GuildMgr.cpp @@ -15,8 +15,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" #include "GuildMgr.h" +#include "DatabaseEnv.h" +#include "Guild.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "World.h" GuildMgr::GuildMgr() : NextGuildId(1) { } @@ -54,7 +58,7 @@ Guild* GuildMgr::GetGuildById(ObjectGuid::LowType guildId) const if (itr != GuildStore.end()) return itr->second; - return NULL; + return nullptr; } Guild* GuildMgr::GetGuildByName(const std::string& guildName) const @@ -68,7 +72,7 @@ Guild* GuildMgr::GetGuildByName(const std::string& guildName) const if (search == gname) return itr->second; } - return NULL; + return nullptr; } std::string GuildMgr::GetGuildNameById(ObjectGuid::LowType guildId) const @@ -91,7 +95,7 @@ Guild* GuildMgr::GetGuildByLeader(ObjectGuid guid) const if (itr->second->GetLeaderGUID() == guid) return itr->second; - return NULL; + return nullptr; } void GuildMgr::LoadGuilds() diff --git a/src/server/game/Guilds/GuildMgr.h b/src/server/game/Guilds/GuildMgr.h index 75ff0648090..b1fa01f28a0 100644 --- a/src/server/game/Guilds/GuildMgr.h +++ b/src/server/game/Guilds/GuildMgr.h @@ -18,13 +18,20 @@ #ifndef _GUILDMGR_H #define _GUILDMGR_H -#include "Guild.h" +#include "Define.h" +#include "ObjectGuid.h" +#include <unordered_map> +#include <vector> + +class Guild; class TC_GAME_API GuildMgr { private: GuildMgr(); ~GuildMgr(); + GuildMgr(GuildMgr const&) = delete; + GuildMgr& operator=(GuildMgr const&) = delete; public: static GuildMgr* instance(); diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index 63c766433fa..9c7efa1ee05 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -16,16 +16,18 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Player.h" -#include "WorldPacket.h" #include "WorldSession.h" #include "ArenaTeam.h" -#include "SocialMgr.h" #include "ArenaTeamMgr.h" -#include "Opcodes.h" +#include "CharacterCache.h" +#include "Log.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "CharacterCache.h" +#include "Opcodes.h" +#include "Player.h" +#include "SocialMgr.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleInspectArenaTeamsOpcode(WorldPacket& recvData) { @@ -88,7 +90,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData) uint32 arenaTeamId; // arena team id std::string invitedName; - Player* player = NULL; + Player* player = nullptr; recvData >> arenaTeamId >> invitedName; @@ -160,7 +162,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData) WorldPacket data(SMSG_ARENA_TEAM_INVITE, (8+10)); data << GetPlayer()->GetName(); data << arenaTeam->GetName(); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); TC_LOG_DEBUG("network", "WORLD: Sent SMSG_ARENA_TEAM_INVITE"); } diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 49373d97036..a0d6ae3bdd2 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -16,19 +16,24 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ObjectMgr.h" -#include "Player.h" -#include "World.h" -#include "WorldPacket.h" #include "WorldSession.h" - +#include "AccountMgr.h" #include "AuctionHouseMgr.h" #include "CharacterCache.h" -#include "Log.h" +#include "Creature.h" +#include "DatabaseEnv.h" +#include "DBCStructure.h" +#include "Item.h" #include "Language.h" +#include "Log.h" +#include "Mail.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Player.h" #include "UpdateMask.h" #include "Util.h" -#include "AccountMgr.h" +#include "World.h" +#include "WorldPacket.h" //void called when player click on auctioneer npc void WorldSession::HandleAuctionHelloOpcode(WorldPacket& recvData) @@ -280,7 +285,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) return; } - const AuctionHouseEntry* AHEntry = sAuctionMgr->GetAuctionHouseEntry(auctioneerInfo->faction); + AuctionHouseEntry const* AHEntry = sAuctionMgr->GetAuctionHouseEntry(auctioneerInfo->faction); AH->houseId = AHEntry->houseId; } @@ -302,7 +307,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; - AH->expire_time = time(NULL) + auctionTime; + AH->expire_time = time(nullptr) + auctionTime; AH->deposit = deposit; AH->etime = etime; AH->auctionHouseEntry = auctionHouseEntry; @@ -359,7 +364,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->bidder = 0; AH->bid = 0; AH->buyout = buyout; - AH->expire_time = time(NULL) + auctionTime; + AH->expire_time = time(nullptr) + auctionTime; AH->deposit = deposit; AH->etime = etime; AH->auctionHouseEntry = auctionHouseEntry; diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index ba5cb325098..8b03ff91240 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -16,25 +16,29 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" -#include "ArenaTeamMgr.h" -#include "WorldPacket.h" #include "WorldSession.h" - #include "ArenaTeam.h" -#include "BattlegroundMgr.h" +#include "ArenaTeamMgr.h" #include "Battleground.h" +#include "BattlegroundMgr.h" #include "Chat.h" +#include "Common.h" +#include "Creature.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "DisableMgr.h" #include "GameTime.h" +#include "Group.h" #include "Language.h" #include "Log.h" -#include "Player.h" +#include "MotionMaster.h" #include "Object.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Opcodes.h" -#include "DisableMgr.h" -#include "Group.h" +#include "Player.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) { @@ -42,13 +46,10 @@ void WorldSession::HandleBattlemasterHelloOpcode(WorldPacket& recvData) recvData >> guid; TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_BATTLEMASTER_HELLO Message from %s", guid.ToString().c_str()); - Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BATTLEMASTER); if (!unit) return; - if (!unit->IsBattleMaster()) // it's not battlemaster - return; - // Stop the npc if moving unit->StopMoving(); @@ -78,7 +79,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) uint32 instanceId; uint8 joinAsGroup; bool isPremade = false; - Group* grp = NULL; + Group* grp = nullptr; recvData >> guid; // battlemaster guid recvData >> bgTypeId_; // battleground type id (DBC id) @@ -91,7 +92,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) return; } - if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, NULL)) + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, bgTypeId_, nullptr)) { ChatHandler(this).PSendSysMessage(LANG_BG_DISABLED); return; @@ -110,7 +111,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) return; // get bg instance or bg template if instance not found - Battleground* bg = NULL; + Battleground* bg = nullptr; if (instanceId) bg = sBattlegroundMgr->GetBattlegroundThroughClientInstance(instanceId, bgTypeId); @@ -134,7 +135,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) // player is using dungeon finder or raid finder WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_LFG_CANT_USE_BATTLEGROUND); - GetPlayer()->GetSession()->SendPacket(&data); + GetPlayer()->SendDirectMessage(&data); return; } @@ -143,7 +144,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); return; } @@ -152,7 +153,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) // player is already in random queue WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_RANDOM_BG); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); return; } @@ -161,7 +162,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) // player is already in queue, can't start random queue WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_IN_NON_RANDOM_BG); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); return; } @@ -175,7 +176,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) { WorldPacket data; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, ERR_BATTLEGROUND_TOO_MANY_QUEUES); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); return; } @@ -185,7 +186,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); + GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, 0, false, isPremade, 0, 0); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); // already checked if queueSlot is valid, now just get it uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); @@ -209,7 +210,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) isPremade = (grp->GetMembersCount() >= bg->GetMinPlayersPerTeam()); BattlegroundQueue& bgQueue = sBattlegroundMgr->GetBattlegroundQueue(bgQueueTypeId); - GroupQueueInfo* ginfo = NULL; + GroupQueueInfo* ginfo = nullptr; uint32 avgTime = 0; if (err > 0) @@ -219,7 +220,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) @@ -230,7 +231,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (err <= 0) { sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); continue; } @@ -239,9 +240,9 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUID().GetCounter(), member->GetName().c_str()); } @@ -259,8 +260,8 @@ void WorldSession::HandleBattlegroundPlayerPositionsOpcode(WorldPacket& /*recvDa return; uint32 flagCarrierCount = 0; - Player* allianceFlagCarrier = NULL; - Player* hordeFlagCarrier = NULL; + Player* allianceFlagCarrier = nullptr; + Player* hordeFlagCarrier = nullptr; if (ObjectGuid guid = bg->GetFlagPickerGUID(TEAM_ALLIANCE)) { @@ -423,7 +424,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) //send bg command result to show nice message WorldPacket data2; sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); - _player->GetSession()->SendPacket(&data2); + _player->SendDirectMessage(&data2); action = 0; TC_LOG_DEBUG("bg.battleground", "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUID().GetCounter()); } @@ -463,7 +464,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) } sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_IN_PROGRESS, 0, bg->GetStartTime(), bg->GetArenaType(), ginfo.Team); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); // remove battleground queue status from BGmgr bgQueue.RemovePlayer(_player->GetGUID(), false); @@ -545,7 +546,7 @@ void WorldSession::HandleBattlefieldStatusOpcode(WorldPacket & /*recvData*/) WorldPacket data; // we must update all queues here - Battleground* bg = NULL; + Battleground* bg = nullptr; for (uint8 i = 0; i < PLAYER_MAX_BATTLEGROUND_QUEUES; ++i) { BattlegroundQueueTypeId bgQueueTypeId = _player->GetBattlegroundQueueTypeId(i); @@ -610,7 +611,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) uint8 arenaslot; // 2v2, 3v3 or 5v5 uint8 asGroup; // asGroup uint8 isRated; // isRated - Group* grp = NULL; + Group* grp = nullptr; recvData >> guid >> arenaslot >> asGroup >> isRated; @@ -618,13 +619,10 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) if (_player->InBattleground()) return; - Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_BATTLEMASTER); if (!unit) return; - if (!unit->IsBattleMaster()) // it's not battle master - return; - uint8 arenatype = 0; uint32 arenaRating = 0; uint32 matchmakerRating = 0; @@ -653,7 +651,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) return; } - if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, NULL)) + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_BATTLEGROUND, BATTLEGROUND_AA, nullptr)) { ChatHandler(this).PSendSysMessage(LANG_ARENA_DISABLED); return; @@ -729,7 +727,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); } - for (GroupReference* itr = grp->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = grp->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) @@ -740,7 +738,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) if (err <= 0) { sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); continue; } @@ -749,15 +747,15 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0); - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); - member->GetSession()->SendPacket(&data); + member->SendDirectMessage(&data); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUID().GetCounter(), member->GetName().c_str()); } } else { - GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, NULL, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId); + GroupQueueInfo* ginfo = bgQueue.AddGroup(_player, nullptr, bgTypeId, bracketEntry, arenatype, isRated != 0, false, arenaRating, matchmakerRating, ateamId); uint32 avgTime = bgQueue.GetAverageQueueWaitTime(ginfo, bracketEntry->GetBracketId()); uint32 queueSlot = _player->AddBattlegroundQueueId(bgQueueTypeId); diff --git a/src/server/game/Handlers/BattlefieldHandler.cpp b/src/server/game/Handlers/BattlefieldHandler.cpp index a1107702ae6..cbf6b0b87a9 100644 --- a/src/server/game/Handlers/BattlefieldHandler.cpp +++ b/src/server/game/Handlers/BattlefieldHandler.cpp @@ -15,13 +15,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Opcodes.h" -#include "Player.h" -#include "WorldPacket.h" #include "WorldSession.h" - #include "Battlefield.h" #include "BattlefieldMgr.h" +#include "Log.h" +#include "Opcodes.h" +#include "Player.h" +#include "WorldPacket.h" /** * @fn void WorldSession::SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint32 acceptTime) @@ -37,7 +37,7 @@ void WorldSession::SendBfInvitePlayerToWar(uint32 battleId, uint32 zoneId, uint3 WorldPacket data(SMSG_BATTLEFIELD_MGR_ENTRY_INVITE, 12); data << uint32(battleId); data << uint32(zoneId); - data << uint32(time(NULL) + acceptTime); + data << uint32(time(nullptr) + acceptTime); SendPacket(&data); } diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 8b314838cf1..6d884ca2ee9 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -35,25 +35,29 @@ Copied events should probably have a new owner */ +#include "WorldSession.h" +#include "ArenaTeamMgr.h" +#include "CalendarMgr.h" #include "CharacterCache.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "Guild.h" +#include "GuildMgr.h" #include "InstanceSaveMgr.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" #include "SocialMgr.h" -#include "CalendarMgr.h" -#include "ObjectAccessor.h" -#include "DatabaseEnv.h" -#include "GuildMgr.h" -#include "ArenaTeamMgr.h" -#include "WorldSession.h" +#include "World.h" void WorldSession::HandleCalendarGetCalendar(WorldPacket& /*recvData*/) { ObjectGuid guid = _player->GetGUID(); TC_LOG_DEBUG("network", "CMSG_CALENDAR_GET_CALENDAR [%s]", guid.ToString().c_str()); - time_t currTime = time(NULL); + time_t currTime = time(nullptr); WorldPacket data(SMSG_CALENDAR_SEND_CALENDAR, 1000); // Average size if no instance @@ -236,7 +240,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) // prevent events in the past // To Do: properly handle timezones and remove the "- time_t(86400L)" hack - if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L))) + if (time_t(eventPackedTime) < (time(nullptr) - time_t(86400L))) { recvData.rfinish(); return; @@ -283,7 +287,7 @@ void WorldSession::HandleCalendarAddEvent(WorldPacket& recvData) catch (ByteBufferException const&) { delete calendarEvent; - calendarEvent = NULL; + calendarEvent = nullptr; throw; } @@ -329,7 +333,7 @@ void WorldSession::HandleCalendarUpdateEvent(WorldPacket& recvData) // prevent events in the past // To Do: properly handle timezones and remove the "- time_t(86400L)" hack - if (time_t(eventPackedTime) < (time(NULL) - time_t(86400L))) + if (time_t(eventPackedTime) < (time(nullptr) - time_t(86400L))) { recvData.rfinish(); return; @@ -386,7 +390,7 @@ void WorldSession::HandleCalendarCopyEvent(WorldPacket& recvData) // prevent events in the past // To Do: properly handle timezones and remove the "- time_t(86400L)" hack - if (time_t(eventTime) < (time(NULL) - time_t(86400L))) + if (time_t(eventTime) < (time(nullptr) - time_t(86400L))) { recvData.rfinish(); return; @@ -529,7 +533,7 @@ void WorldSession::HandleCalendarEventSignup(WorldPacket& recvData) } CalendarInviteStatus status = tentative ? CALENDAR_STATUS_TENTATIVE : CALENDAR_STATUS_SIGNED_UP; - CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, time(NULL), status, CALENDAR_RANK_PLAYER, ""); + CalendarInvite* invite = new CalendarInvite(sCalendarMgr->GetFreeInviteId(), eventId, guid, guid, time(nullptr), status, CALENDAR_RANK_PLAYER, ""); sCalendarMgr->AddInvite(calendarEvent, invite); sCalendarMgr->SendCalendarClearPendingAction(guid); } @@ -561,7 +565,7 @@ void WorldSession::HandleCalendarEventRsvp(WorldPacket& recvData) if (CalendarInvite* invite = sCalendarMgr->GetInvite(inviteId)) { invite->SetStatus(CalendarInviteStatus(status)); - invite->SetStatusTime(time(NULL)); + invite->SetStatusTime(time(nullptr)); sCalendarMgr->UpdateInvite(invite); sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite); @@ -624,7 +628,7 @@ void WorldSession::HandleCalendarEventStatus(WorldPacket& recvData) { invite->SetStatus((CalendarInviteStatus)status); // not sure if we should set response time when moderator changes invite status - //invite->SetStatusTime(time(NULL)); + //invite->SetStatusTime(time(nullptr)); sCalendarMgr->UpdateInvite(invite); sCalendarMgr->SendCalendarEventStatus(*calendarEvent, *invite); @@ -730,7 +734,7 @@ void WorldSession::HandleSetSavedInstanceExtend(WorldPacket& recvData) void WorldSession::SendCalendarRaidLockout(InstanceSave const* save, bool add) { TC_LOG_DEBUG("network", "%s", add ? "SMSG_CALENDAR_RAID_LOCKOUT_ADDED" : "SMSG_CALENDAR_RAID_LOCKOUT_REMOVED"); - time_t currTime = time(NULL); + time_t currTime = time(nullptr); WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_REMOVED, (add ? 4 : 0) + 4 + 4 + 4 + 8); if (add) @@ -755,7 +759,7 @@ void WorldSession::SendCalendarRaidLockoutUpdated(InstanceSave const* save) TC_LOG_DEBUG("network", "SMSG_CALENDAR_RAID_LOCKOUT_UPDATED [%s] Map: %u, Difficulty %u", guid.ToString().c_str(), save->GetMapId(), save->GetDifficulty()); - time_t currTime = time(NULL); + time_t currTime = time(nullptr); WorldPacket data(SMSG_CALENDAR_RAID_LOCKOUT_UPDATED, 4 + 4 + 4 + 4 + 8); data.AppendPackedTime(currTime); diff --git a/src/server/game/Handlers/ChannelHandler.cpp b/src/server/game/Handlers/ChannelHandler.cpp index 009691838c9..75ec79819a0 100644 --- a/src/server/game/Handlers/ChannelHandler.cpp +++ b/src/server/game/Handlers/ChannelHandler.cpp @@ -16,12 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "ObjectMgr.h" // for normalizePlayerName +#include "WorldSession.h" #include "Channel.h" #include "ChannelMgr.h" +#include "DBCStores.h" +#include "Log.h" +#include "ObjectMgr.h" // for normalizePlayerName #include "Player.h" -#include "WorldSession.h" - #include <cctype> static size_t const MAX_CHANNEL_PASS_STR = 31; diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index a8a1bb3e329..9bdf294c9b3 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -16,41 +16,40 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "AccountMgr.h" -#include "ArenaTeam.h" +#include "WorldSession.h" #include "ArenaTeamMgr.h" -#include "Battleground.h" #include "CalendarMgr.h" #include "CharacterCache.h" #include "Chat.h" -#include "Common.h" #include "DatabaseEnv.h" +#include "DBCStores.h" +#include "GameObject.h" #include "GameTime.h" +#include "GitRevision.h" #include "Group.h" #include "Guild.h" #include "GuildMgr.h" +#include "InstanceSaveMgr.h" +#include "Item.h" #include "Language.h" #include "Log.h" +#include "Map.h" +#include "Metric.h" +#include "MotionMaster.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "Pet.h" -#include "PlayerDump.h" #include "Player.h" -#include "QueryCallback.h" +#include "PlayerDump.h" +#include "RBAC.h" +#include "Realm.h" #include "ReputationMgr.h" -#include "GitRevision.h" #include "ScriptMgr.h" #include "ServerMotd.h" -#include "SharedDefines.h" #include "SocialMgr.h" -#include "UpdateMask.h" -#include "Util.h" +#include "QueryHolder.h" #include "World.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Metric.h" - class LoginQueryHolder : public SQLQueryHolder { @@ -126,7 +125,7 @@ bool LoginQueryHolder::Initialize() stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILCOUNT); stmt->setUInt32(0, lowGuid); - stmt->setUInt64(1, uint64(time(NULL))); + stmt->setUInt64(1, uint64(time(nullptr))); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT, stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_MAILDATE); @@ -680,7 +679,7 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData) void WorldSession::HandlePlayerLoginOpcode(WorldPacket& recvData) { - if (PlayerLoading() || GetPlayer() != NULL) + if (PlayerLoading() || GetPlayer() != nullptr) { TC_LOG_ERROR("network", "Player tries to login again, AccountId = %d", GetAccountId()); KickPlayer(); @@ -721,7 +720,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) // "GetAccountId() == db stored account id" checked in LoadFromDB (prevent login not own character using cheating tools) if (!pCurrChar->LoadFromDB(playerGuid, holder)) { - SetPlayer(NULL); + SetPlayer(nullptr); KickPlayer(); // disconnect client, player no set to session and it will not deleted or saved at kick delete pCurrChar; // delete it manually delete holder; // delete all unprocessed queries @@ -1481,12 +1480,11 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData) std::string iconName; recvData >> iconName; - EquipmentSet eqSet; - - eqSet.Guid = setGuid; - eqSet.Name = name; - eqSet.IconName = iconName; - eqSet.state = EQUIPMENT_SET_NEW; + EquipmentSetInfo::EquipmentSetData eqData; + eqData.Guid = setGuid; + eqData.SetID = index; + eqData.SetName = name; + eqData.SetIcon = iconName; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { @@ -1495,31 +1493,25 @@ void WorldSession::HandleEquipmentSetSave(WorldPacket& recvData) // if client sends 0, it means empty slot if (itemGuid.IsEmpty()) - { - eqSet.Items[i] = 0; continue; - } // equipment manager sends "1" (as raw GUID) for slots set to "ignore" (don't touch slot at equip set) if (itemGuid.GetRawValue() == 1) { // ignored slots saved as bit mask because we have no free special values for Items[i] - eqSet.IgnoreMask |= 1 << i; + eqData.IgnoreMask |= 1 << i; continue; } // some cheating checks Item* item = _player->GetItemByPos(INVENTORY_SLOT_BAG_0, i); if (!item || item->GetGUID() != itemGuid) - { - eqSet.Items[i] = 0; continue; - } - eqSet.Items[i] = itemGuid.GetCounter(); + eqData.Pieces[i] = itemGuid; } - _player->SetEquipmentSet(index, eqSet); + _player->SetEquipmentSet(eqData); } void WorldSession::HandleEquipmentSetDelete(WorldPacket& recvData) @@ -1572,7 +1564,7 @@ void WorldSession::HandleEquipmentSetUse(WorldPacket& recvData) _player->StoreItem(sDest, uItem, true); } else - _player->SendEquipError(msg, uItem, NULL); + _player->SendEquipError(msg, uItem, nullptr); continue; } diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 3cfa2293067..eb3200ea87d 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -16,29 +16,30 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "ObjectAccessor.h" -#include "ObjectMgr.h" -#include "GuildMgr.h" -#include "World.h" -#include "WorldPacket.h" #include "WorldSession.h" -#include "DatabaseEnv.h" +#include "AccountMgr.h" #include "CellImpl.h" -#include "Chat.h" +#include "Common.h" #include "Channel.h" #include "ChannelMgr.h" +#include "Chat.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "GridNotifiersImpl.h" #include "Group.h" #include "Guild.h" +#include "GuildMgr.h" #include "Language.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" +#include "ScriptMgr.h" #include "SpellAuraEffects.h" #include "Util.h" -#include "ScriptMgr.h" -#include "AccountMgr.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) { @@ -160,7 +161,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (!sender->CanSpeak()) { - std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + std::string timeStr = secsToTimeString(m_muteTime - time(nullptr)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); recvData.rfinish(); // Prevent warnings return; @@ -343,7 +344,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, NULL, msg); + ChatHandler::BuildChatPacket(data, ChatMsg(type), Language(lang), sender, nullptr, msg); group->BroadcastPacket(&data, false, group->GetMemberGroup(GetPlayer()->GetGUID())); break; } @@ -387,7 +388,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID, Language(lang), sender, nullptr, msg); group->BroadcastPacket(&data, false); break; } @@ -405,7 +406,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_LEADER, Language(lang), sender, nullptr, msg); group->BroadcastPacket(&data, false); break; } @@ -419,7 +420,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) WorldPacket data; //in battleground, raid warning is sent only to players in battleground - code is ok - ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_RAID_WARNING, Language(lang), sender, nullptr, msg); group->BroadcastPacket(&data, false); break; } @@ -433,7 +434,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, NULL, msg); + ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND, Language(lang), sender, nullptr, msg); group->BroadcastPacket(&data, false); break; } @@ -447,7 +448,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) sScriptMgr->OnPlayerChat(GetPlayer(), type, lang, msg, group); WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, NULL, msg);; + ChatHandler::BuildChatPacket(data, CHAT_MSG_BATTLEGROUND_LEADER, Language(lang), sender, nullptr, msg);; group->BroadcastPacket(&data, false); break; } @@ -572,7 +573,7 @@ void WorldSession::HandleTextEmoteOpcode(WorldPacket& recvData) if (!GetPlayer()->CanSpeak()) { - std::string timeStr = secsToTimeString(m_muteTime - time(NULL)); + std::string timeStr = secsToTimeString(m_muteTime - time(nullptr)); SendNotification(GetTrinityString(LANG_WAIT_BEFORE_SPEAKING), timeStr.c_str()); return; } @@ -642,7 +643,7 @@ void WorldSession::HandleChatIgnoredOpcode(WorldPacket& recvData) WorldPacket data; ChatHandler::BuildChatPacket(data, CHAT_MSG_IGNORED, LANG_UNIVERSAL, _player, _player, GetPlayer()->GetName()); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } void WorldSession::HandleChannelDeclineInvite(WorldPacket &recvPacket) diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index 894f6233c6b..07cadd837fa 100644 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -16,14 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" #include "Common.h" +#include "CreatureAI.h" +#include "DBCStructure.h" #include "Log.h" -#include "WorldPacket.h" -#include "WorldSession.h" #include "ObjectAccessor.h" -#include "CreatureAI.h" -#include "Vehicle.h" #include "Player.h" +#include "Vehicle.h" +#include "WorldPacket.h" void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) { @@ -37,7 +38,7 @@ void WorldSession::HandleAttackSwingOpcode(WorldPacket& recvData) if (!pEnemy) { // stop attack state at client - SendAttackStop(NULL); + SendAttackStop(nullptr); return; } diff --git a/src/server/game/Handlers/DuelHandler.cpp b/src/server/game/Handlers/DuelHandler.cpp index 52513106e77..c520100b470 100644 --- a/src/server/game/Handlers/DuelHandler.cpp +++ b/src/server/game/Handlers/DuelHandler.cpp @@ -43,7 +43,7 @@ void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket) TC_LOG_DEBUG("network", "Player 1 is: %u (%s)", player->GetGUID().GetCounter(), player->GetName().c_str()); TC_LOG_DEBUG("network", "Player 2 is: %u (%s)", plTarget->GetGUID().GetCounter(), plTarget->GetName().c_str()); - time_t now = time(NULL); + time_t now = time(nullptr); player->duel->startTimer = now; plTarget->duel->startTimer = now; diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 857c3a33d49..c3a6362ad8c 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -16,12 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" #include "CharacterCache.h" #include "Common.h" #include "DatabaseEnv.h" #include "Group.h" #include "GroupMgr.h" #include "Log.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Pet.h" #include "Player.h" @@ -31,7 +33,6 @@ #include "Vehicle.h" #include "World.h" #include "WorldPacket.h" -#include "WorldSession.h" class Aura; @@ -151,7 +152,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk - invitedPlayer->GetSession()->SendPacket(&data); + invitedPlayer->SendDirectMessage(&data); } return; @@ -209,7 +210,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) data << uint32(0); // unk data << uint8(0); // count data << uint32(0); // unk - invitedPlayer->GetSession()->SendPacket(&data); + invitedPlayer->SendDirectMessage(&data); SendPartyResult(PARTY_OP_INVITE, membername, ERR_PARTY_RESULT_OK); } @@ -286,7 +287,7 @@ void WorldSession::HandleGroupDeclineOpcode(WorldPacket & /*recvData*/) // report WorldPacket data(SMSG_GROUP_DECLINE, GetPlayer()->GetName().length()); data << GetPlayer()->GetName(); - leader->GetSession()->SendPacket(&data); + leader->SendDirectMessage(&data); } void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData) diff --git a/src/server/game/Handlers/GuildHandler.cpp b/src/server/game/Handlers/GuildHandler.cpp index 0476cbf3afb..b34b84adf67 100644 --- a/src/server/game/Handlers/GuildHandler.cpp +++ b/src/server/game/Handlers/GuildHandler.cpp @@ -16,14 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "WorldPacket.h" #include "WorldSession.h" -#include "World.h" -#include "ObjectMgr.h" +#include "Common.h" +#include "Guild.h" #include "GuildMgr.h" #include "Log.h" -#include "Guild.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "WorldPacket.h" void WorldSession::HandleGuildQueryOpcode(WorldPacket& recvPacket) { @@ -457,7 +457,7 @@ void WorldSession::HandleGuildBankSwapItems(WorldPacket& recvData) // Player <-> Bank // Allow to work with inventory only if (!Player::IsInventoryPos(playerBag, playerSlotId) && !(playerBag == NULL_BAG && playerSlotId == NULL_SLOT)) - GetPlayer()->SendEquipError(EQUIP_ERR_NONE, NULL); + GetPlayer()->SendEquipError(EQUIP_ERR_NONE, nullptr); else guild->SwapItemsWithInventory(GetPlayer(), toChar != 0, tabId, slotId, playerBag, playerSlotId, splitedAmount); } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 9159cf7f329..9f3e2a52efe 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -16,17 +16,20 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "WorldPacket.h" #include "WorldSession.h" +#include "Bag.h" +#include "Common.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "Opcodes.h" +#include "Item.h" #include "Log.h" #include "ObjectMgr.h" #include "Player.h" -#include "Item.h" #include "SpellInfo.h" - -#include "Packets/QueryPackets.h" +#include "QueryPackets.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData) { @@ -48,13 +51,13 @@ void WorldSession::HandleSplitItemOpcode(WorldPacket& recvData) if (!_player->IsValidPos(srcbag, srcslot, true)) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } if (!_player->IsValidPos(dstbag, dstslot, false)) // can be autostore pos { - _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, nullptr, nullptr); return; } @@ -75,13 +78,13 @@ void WorldSession::HandleSwapInvItemOpcode(WorldPacket& recvData) if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, srcslot, true)) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } if (!_player->IsValidPos(INVENTORY_SLOT_BAG_0, dstslot, true)) { - _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, nullptr, nullptr); return; } @@ -139,13 +142,13 @@ void WorldSession::HandleSwapItem(WorldPacket& recvData) if (!_player->IsValidPos(srcbag, srcslot, true)) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } if (!_player->IsValidPos(dstbag, dstslot, true)) { - _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, nullptr, nullptr); return; } @@ -180,7 +183,7 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPacket& recvData) InventoryResult msg = _player->CanEquipItem(NULL_SLOT, dest, pSrcItem, !pSrcItem->IsBag()); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pSrcItem, NULL); + _player->SendEquipError(msg, pSrcItem, nullptr); return; } @@ -203,7 +206,7 @@ void WorldSession::HandleAutoEquipItemOpcode(WorldPacket& recvData) msg = _player->CanUnequipItem(dest, !pSrcItem->IsBag()); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pDstItem, NULL); + _player->SendEquipError(msg, pDstItem, nullptr); return; } @@ -279,7 +282,7 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData) InventoryResult msg = _player->CanUnequipItem(pos, false); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, _player->GetItemByPos(pos), NULL); + _player->SendEquipError(msg, _player->GetItemByPos(pos), nullptr); return; } } @@ -287,13 +290,13 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket& recvData) Item* pItem = _player->GetItemByPos(bag, slot); if (!pItem) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } if (pItem->GetTemplate()->Flags & ITEM_FLAG_NO_USER_DESTROY) { - _player->SendEquipError(EQUIP_ERR_CANT_DROP_SOULBOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_CANT_DROP_SOULBOUND, nullptr, nullptr); return; } @@ -354,13 +357,13 @@ void WorldSession::HandleReadItem(WorldPacket& recvData) { data.Initialize(SMSG_READ_ITEM_FAILED, 8); TC_LOG_INFO("network", "STORAGE: Unable to read item"); - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); } data << pItem->GetGUID(); SendPacket(&data); } else - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); } void WorldSession::HandleSellItemOpcode(WorldPacket& recvData) @@ -378,7 +381,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData) if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleSellItemOpcode - %s not found or you can not interact with him.", vendorguid.ToString().c_str()); - _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, itemguid, 0); + _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, itemguid, 0); return; } @@ -458,7 +461,7 @@ void WorldSession::HandleSellItemOpcode(WorldPacket& recvData) { _player->ItemRemovedQuestCheck(pItem->GetEntry(), pItem->GetCount()); _player->RemoveItem(pItem->GetBagSlot(), pItem->GetSlot(), true); - pItem->RemoveFromUpdateQueueOf(_player); + RemoveItemFromUpdateQueueOf(pItem, _player); _player->AddItemToBuyBackSlot(pItem); } @@ -487,7 +490,7 @@ void WorldSession::HandleBuybackItem(WorldPacket& recvData) if (!creature) { TC_LOG_DEBUG("network", "WORLD: HandleBuybackItem - Unit (%s) not found or you can not interact with him.", vendorguid.ToString().c_str()); - _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid::Empty, 0); + _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, ObjectGuid::Empty, 0); return; } @@ -516,7 +519,7 @@ void WorldSession::HandleBuybackItem(WorldPacket& recvData) _player->StoreItem(dest, pItem, true); } else - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); return; } else @@ -603,7 +606,7 @@ void WorldSession::SendListInventory(ObjectGuid vendorGuid) if (!vendor) { TC_LOG_DEBUG("network", "WORLD: SendListInventory - %s not found or you can not interact with him.", vendorGuid.ToString().c_str()); - _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, NULL, ObjectGuid::Empty, 0); + _player->SendSellError(SELL_ERR_CANT_FIND_VENDOR, nullptr, ObjectGuid::Empty, 0); return; } @@ -704,7 +707,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) if (!_player->IsValidPos(dstbag, NULL_SLOT, false)) // can be autostore pos { - _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_DOESNT_GO_TO_SLOT, nullptr, nullptr); return; } @@ -716,7 +719,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) InventoryResult msg = _player->CanUnequipItem(src, !_player->IsBagPos (src)); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); return; } } @@ -725,7 +728,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) InventoryResult msg = _player->CanStoreItem(dstbag, NULL_SLOT, dest, pItem, false); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); return; } @@ -733,7 +736,7 @@ void WorldSession::HandleAutoStoreBagItemOpcode(WorldPacket& recvData) if (dest.size() == 1 && dest[0].pos == src) { // just remove grey item state - _player->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); + _player->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr); return; } @@ -812,13 +815,13 @@ void WorldSession::HandleAutoBankItemOpcode(WorldPacket& recvPacket) InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); return; } if (dest.size() == 1 && dest[0].pos == pItem->GetPos()) { - _player->SendEquipError(EQUIP_ERR_NONE, pItem, NULL); + _player->SendEquipError(EQUIP_ERR_NONE, pItem, nullptr); return; } @@ -851,7 +854,7 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket) InventoryResult msg = _player->CanStoreItem(NULL_BAG, NULL_SLOT, dest, pItem, false); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); return; } @@ -865,7 +868,7 @@ void WorldSession::HandleAutoStoreBankItemOpcode(WorldPacket& recvPacket) InventoryResult msg = _player->CanBankItem(NULL_BAG, NULL_SLOT, dest, pItem, false); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, pItem, NULL); + _player->SendEquipError(msg, pItem, nullptr); return; } @@ -878,7 +881,7 @@ void WorldSession::HandleSetAmmoOpcode(WorldPacket& recvData) { if (!_player->IsAlive()) { - _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_YOU_ARE_DEAD, nullptr, nullptr); return; } @@ -891,7 +894,7 @@ void WorldSession::HandleSetAmmoOpcode(WorldPacket& recvData) { if (!_player->GetItemCount(item)) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } @@ -934,7 +937,7 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket& recvData) { std::string Name = pName->name; LocaleConstant localeConstant = GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (ItemSetNameLocale const* isnl = sObjectMgr->GetItemSetNameLocale(itemid)) ObjectMgr::GetLocaleString(isnl->Name, localeConstant, Name); @@ -960,13 +963,13 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData) Item* gift = _player->GetItemByPos(gift_bag, gift_slot); if (!gift) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, nullptr); return; } if (!(gift->GetTemplate()->Flags & ITEM_FLAG_IS_WRAPPER)) // cheating: non-wrapper wrapper { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, gift, nullptr); return; } @@ -974,50 +977,50 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData) if (!item) { - _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, item, nullptr); return; } if (item == gift) // not possable with pacjket from real client { - _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, nullptr); return; } if (item->IsEquipped()) { - _player->SendEquipError(EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_EQUIPPED_CANT_BE_WRAPPED, item, nullptr); return; } if (!item->GetGuidValue(ITEM_FIELD_GIFTCREATOR).IsEmpty()) // HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED); { - _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_WRAPPED_CANT_BE_WRAPPED, item, nullptr); return; } if (item->IsBag()) { - _player->SendEquipError(EQUIP_ERR_BAGS_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_BAGS_CANT_BE_WRAPPED, item, nullptr); return; } if (item->IsSoulBound()) { - _player->SendEquipError(EQUIP_ERR_BOUND_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_BOUND_CANT_BE_WRAPPED, item, nullptr); return; } if (item->GetMaxStackCount() != 1) { - _player->SendEquipError(EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_STACKABLE_CANT_BE_WRAPPED, item, nullptr); return; } // maybe not correct check (it is better than nothing) if (item->GetTemplate()->MaxCount>0) { - _player->SendEquipError(EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, NULL); + _player->SendEquipError(EQUIP_ERR_UNIQUE_CANT_BE_WRAPPED, item, nullptr); return; } @@ -1048,7 +1051,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData) if (item->GetState() == ITEM_NEW) // save new item, to have alway for `character_gifts` record in `item_instance` { // after save it will be impossible to remove the item from the queue - item->RemoveFromUpdateQueueOf(_player); + RemoveItemFromUpdateQueueOf(item, _player); item->SaveToDB(trans); // item gave inventory record unchanged and can be save standalone } CharacterDatabase.CommitTransaction(trans); @@ -1089,11 +1092,11 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData) Item* Gems[MAX_GEM_SOCKETS]; for (int i = 0; i < MAX_GEM_SOCKETS; ++i) - Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : NULL; + Gems[i] = gem_guids[i] ? _player->GetItemByGuid(gem_guids[i]) : nullptr; GemPropertiesEntry const* GemProps[MAX_GEM_SOCKETS]; for (int i = 0; i < MAX_GEM_SOCKETS; ++i) //get geminfo from dbc storage - GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : NULL; + GemProps[i] = (Gems[i]) ? sGemPropertiesStore.LookupEntry(Gems[i]->GetTemplate()->GemProperties) : nullptr; // Find first prismatic socket int32 firstPrismatic = 0; @@ -1154,7 +1157,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData) { if (iGemProto->ItemId == Gems[j]->GetEntry()) { - _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, nullptr); return; } } @@ -1164,7 +1167,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData) { if (iGemProto->ItemId == enchantEntry->GemID) { - _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, nullptr); return; } } @@ -1199,7 +1202,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData) if (limit_newcount > 0 && uint32(limit_newcount) > limitEntry->maxCount) { - _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, NULL); + _player->SendEquipError(EQUIP_ERR_ITEM_UNIQUE_EQUIPPABLE_SOCKETED, itemTarget, nullptr); return; } } @@ -1210,7 +1213,7 @@ void WorldSession::HandleSocketOpcode(WorldPacket& recvData) { if (InventoryResult res = _player->CanEquipUniqueItem(Gems[i], slot, std::max(limit_newcount, 0))) { - _player->SendEquipError(res, itemTarget, NULL); + _player->SendEquipError(res, itemTarget, nullptr); return; } } diff --git a/src/server/game/Handlers/LFGHandler.cpp b/src/server/game/Handlers/LFGHandler.cpp index e3cbbe512d3..499d51f21ec 100644 --- a/src/server/game/Handlers/LFGHandler.cpp +++ b/src/server/game/Handlers/LFGHandler.cpp @@ -16,10 +16,12 @@ */ #include "LFGMgr.h" -#include "ObjectMgr.h" +#include "Log.h" #include "Group.h" -#include "Player.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Opcodes.h" +#include "Player.h" #include "WorldPacket.h" #include "WorldSession.h" @@ -186,7 +188,7 @@ void WorldSession::HandleLfgPlayerLockInfoRequestOpcode(WorldPacket& /*recvData* { data << uint32(*it); // Dungeon Entry (id + type) lfg::LfgReward const* reward = sLFGMgr->GetRandomDungeonReward(*it, level); - Quest const* quest = NULL; + Quest const* quest = nullptr; bool done = false; if (reward) { @@ -244,7 +246,7 @@ void WorldSession::HandleLfgPartyLockInfoRequestOpcode(WorldPacket& /*recvData* // Get the locked dungeons of the other party members lfg::LfgLockPartyMap lockMap; - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* plrg = itr->GetSource(); if (!plrg) @@ -526,7 +528,7 @@ void WorldSession::SendLfgBootProposalUpdate(lfg::LfgPlayerBoot const& boot) lfg::LfgAnswer playerVote = boot.votes.find(guid)->second; uint8 votesNum = 0; uint8 agreeNum = 0; - uint32 secsleft = uint8((boot.cancelTime - time(NULL)) / 1000); + uint32 secsleft = uint8((boot.cancelTime - time(nullptr)) / 1000); for (lfg::LfgAnswerContainer::const_iterator it = boot.votes.begin(); it != boot.votes.end(); ++it) { if (it->second != lfg::LFG_ANSWER_PENDING) diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 4a0013b71c1..949e858095d 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -16,26 +16,28 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" #include "Common.h" -#include "Log.h" #include "Corpse.h" #include "Creature.h" #include "GameObject.h" #include "Group.h" +#include "Item.h" +#include "Log.h" #include "LootItemStorage.h" #include "LootMgr.h" -#include "ObjectAccessor.h" +#include "Map.h" #include "Object.h" +#include "ObjectAccessor.h" #include "Player.h" #include "WorldPacket.h" -#include "WorldSession.h" void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData) { TC_LOG_DEBUG("network", "WORLD: CMSG_AUTOSTORE_LOOT_ITEM"); Player* player = GetPlayer(); ObjectGuid lguid = player->GetLootGUID(); - Loot* loot = NULL; + Loot* loot = nullptr; uint8 lootSlot = 0; recvData >> lootSlot; @@ -106,7 +108,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) if (!guid) return; - Loot* loot = NULL; + Loot* loot = nullptr; bool shareMoney = true; switch (guid.GetHigh()) @@ -169,7 +171,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) Group* group = player->GetGroup(); std::vector<Player*> playersNear; - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* member = itr->GetSource(); if (!member) @@ -189,7 +191,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) WorldPacket data(SMSG_LOOT_MONEY_NOTIFY, 4 + 1); data << uint32(goldPerPlayer); data << uint8(playersNear.size() <= 1); // Controls the text displayed in chat. 0 is "Your share is..." and 1 is "You loot..." - (*i)->GetSession()->SendPacket(&data); + (*i)->SendDirectMessage(&data); } } else @@ -371,7 +373,7 @@ void WorldSession::DoLootRelease(ObjectGuid lguid) loot->roundRobinPlayer.Clear(); if (Group* group = player->GetGroup()) - group->SendLooter(creature, NULL); + group->SendLooter(creature, nullptr); } // force dynflag update to update looter and lootable info creature->ForceValuesUpdateAtIndex(UNIT_DYNAMIC_FLAGS); @@ -418,7 +420,7 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) return; } - Loot* loot = NULL; + Loot* loot = nullptr; if (GetPlayer()->GetLootGUID().IsCreatureOrVehicle()) { @@ -462,12 +464,12 @@ void WorldSession::HandleLootMasterGiveOpcode(WorldPacket& recvData) else _player->SendLootError(lootguid, LOOT_ERROR_MASTER_OTHER); - target->SendEquipError(msg, NULL, NULL, item.itemid); + target->SendEquipError(msg, nullptr, nullptr, item.itemid); return; } // list of players allowed to receive this item in trade - AllowedLooterSet looters = item.GetAllowedLooters(); + GuidSet looters = item.GetAllowedLooters(); // now move item from loot to target inventory Item* newitem = target->StoreNewItem(dest, item.itemid, true, item.randomPropertyId, looters); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index 1b186ae6c0a..fc283e1d3df 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -15,20 +15,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "DatabaseEnv.h" -#include "Mail.h" -#include "WorldPacket.h" #include "WorldSession.h" -#include "Opcodes.h" +#include "AccountMgr.h" +#include "CharacterCache.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "Item.h" +#include "Language.h" #include "Log.h" -#include "World.h" +#include "Mail.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" +#include "Opcodes.h" #include "Player.h" -#include "Language.h" -#include "DBCStores.h" -#include "Item.h" -#include "AccountMgr.h" -#include "CharacterCache.h" +#include "World.h" +#include "WorldPacket.h" bool WorldSession::CanOpenMailBox(ObjectGuid guid) { @@ -395,7 +396,7 @@ void WorldSession::HandleMailReturnToSender(WorldPacket& recvData) Player* player = _player; Mail* m = player->GetMail(mailId); - if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(nullptr)) { player->SendMailResult(mailId, MAIL_RETURNED_TO_SENDER, MAIL_ERR_INTERNAL_ERROR); return; @@ -461,7 +462,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) Player* player = _player; Mail* m = player->GetMail(mailId); - if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(nullptr)) { player->SendMailResult(mailId, MAIL_ITEM_TAKEN, MAIL_ERR_INTERNAL_ERROR); return; @@ -562,7 +563,7 @@ void WorldSession::HandleMailTakeMoney(WorldPacket& recvData) Player* player = _player; Mail* m = player->GetMail(mailId); - if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL)) + if (!m || m->state == MAIL_STATE_DELETED || m->deliver_time > time(nullptr)) { player->SendMailResult(mailId, MAIL_MONEY_TAKEN, MAIL_ERR_INTERNAL_ERROR); return; @@ -611,7 +612,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData) WorldPacket data(SMSG_MAIL_LIST_RESULT, (200)); // guess size data << uint32(0); // real mail's count data << uint8(0); // mail's count - time_t cur_time = time(NULL); + time_t cur_time = time(nullptr); for (PlayerMails::iterator itr = player->GetMailBegin(); itr != player->GetMailEnd(); ++itr) { @@ -658,7 +659,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData) data << uint32((*itr)->stationery); // stationery (Stationery.dbc) data << uint32((*itr)->money); // Gold data << uint32((*itr)->checked); // flags - data << float(float((*itr)->expire_time-time(NULL))/DAY); // Time + data << float(float((*itr)->expire_time-time(nullptr))/DAY); // Time data << uint32((*itr)->mailTemplateId); // mail template (MailTemplate.dbc) data << (*itr)->subject; // Subject string - once 00, when mail type = 3, max 256 data << (*itr)->body; // message? max 8000 @@ -722,7 +723,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) Player* player = _player; Mail* m = player->GetMail(mailId); - if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > time(NULL) || (m->checked & MAIL_CHECK_MASK_COPIED)) + if (!m || (m->body.empty() && !m->mailTemplateId) || m->state == MAIL_STATE_DELETED || m->deliver_time > time(nullptr) || (m->checked & MAIL_CHECK_MASK_COPIED)) { player->SendMailResult(mailId, MAIL_MADE_PERMANENT, MAIL_ERR_INTERNAL_ERROR); return; @@ -784,7 +785,7 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recvData*/) data << uint32(0); // count uint32 count = 0; - time_t now = time(NULL); + time_t now = time(nullptr); std::set<uint32> sentSenders; for (PlayerMails::iterator itr = _player->GetMailBegin(); itr != _player->GetMailEnd(); ++itr) { diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 2e18f843a8d..a632bf1979c 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -16,36 +16,42 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" +#include "AccountMgr.h" +#include "Battlefield.h" +#include "BattlefieldMgr.h" +#include "Battleground.h" +#include "BattlegroundMgr.h" +#include "Chat.h" +#include "CinematicMgr.h" #include "Common.h" -#include "Language.h" +#include "Corpse.h" +#include "Creature.h" +#include "CreatureAI.h" #include "DatabaseEnv.h" -#include "WorldPacket.h" -#include "Opcodes.h" -#include "Log.h" -#include "Player.h" +#include "DBCStores.h" +#include "GameObject.h" +#include "GameObjectAI.h" #include "GameTime.h" #include "GossipDef.h" -#include "World.h" -#include "ObjectMgr.h" +#include "Group.h" #include "GuildMgr.h" -#include "WorldSession.h" -#include "Chat.h" -#include "zlib.h" -#include "ObjectAccessor.h" +#include "Language.h" +#include "Log.h" +#include "MapManager.h" #include "Object.h" -#include "Battleground.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Opcodes.h" #include "OutdoorPvP.h" -#include "AccountMgr.h" -#include "DBCEnums.h" +#include "Player.h" #include "ScriptMgr.h" -#include "MapManager.h" -#include "GameObjectAI.h" -#include "Group.h" #include "Spell.h" -#include "BattlegroundMgr.h" -#include "Battlefield.h" -#include "BattlefieldMgr.h" +#include "SpellInfo.h" #include "WhoListStorage.h" +#include "World.h" +#include "WorldPacket.h" +#include <zlib.h> void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData) { @@ -73,7 +79,7 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData) //this is spirit release confirm? GetPlayer()->RemoveGhoul(); - GetPlayer()->RemovePet(NULL, PET_SAVE_NOT_IN_SLOT, true); + GetPlayer()->RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true); GetPlayer()->BuildPlayerRepop(); GetPlayer()->RepopAtGraveyard(); } @@ -102,8 +108,8 @@ void WorldSession::HandleGossipSelectOptionOpcode(WorldPacket& recvData) if (_player->PlayerTalkClass->GetGossipMenu().GetSenderGUID() != guid) return; - Creature* unit = NULL; - GameObject* go = NULL; + Creature* unit = nullptr; + GameObject* go = nullptr; if (guid.IsCreatureOrVehicle()) { unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_GOSSIP); @@ -397,7 +403,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket& /*recvData*/) GetPlayer()->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); } - LogoutRequest(time(NULL)); + LogoutRequest(time(nullptr)); } void WorldSession::HandlePlayerLogoutOpcode(WorldPacket& /*recvData*/) @@ -459,7 +465,7 @@ void WorldSession::HandleTogglePvP(WorldPacket& recvData) else { if (!GetPlayer()->pvpInfo.IsHostile && GetPlayer()->IsPvP()) - GetPlayer()->pvpInfo.EndTimer = time(NULL); // start toggle-off + GetPlayer()->pvpInfo.EndTimer = time(nullptr); // start toggle-off } //if (OutdoorPvP* pvp = _player->GetOutdoorPvP()) @@ -544,7 +550,7 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recvData) return; // prevent resurrect before 30-sec delay after body release not finished - if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(NULL))) + if (time_t(corpse->GetGhostTime() + _player->GetCorpseReclaimDelay(corpse->GetType() == CORPSE_RESURRECTABLE_PVP)) > time_t(time(nullptr))) return; if (!corpse->IsWithinDistInMap(_player, CORPSE_RECLAIM_RADIUS, true)) @@ -581,7 +587,7 @@ void WorldSession::HandleResurrectResponseOpcode(WorldPacket& recvData) GetPlayer()->ResurrectUsingRequestData(); } -void WorldSession::SendAreaTriggerMessage(const char* Text, ...) +void WorldSession::SendAreaTriggerMessage(char const* Text, ...) { va_list ap; char szStr [1024]; @@ -686,7 +692,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) WorldPacket data(SMSG_RAID_GROUP_ONLY, 4 + 4); data << uint32(0); data << uint32(2); // You must be in a raid group to enter this instance. - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); TC_LOG_DEBUG("maps", "MAP: Player '%s' must be in a raid group to enter instance map %d", player->GetName().c_str(), at->target_mapId); reviveAtTrigger = true; break; @@ -694,7 +700,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) case Map::CANNOT_ENTER_CORPSE_IN_DIFFERENT_INSTANCE: { WorldPacket data(SMSG_CORPSE_NOT_IN_INSTANCE); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); TC_LOG_DEBUG("maps", "MAP: Player '%s' does not have a corpse in instance map %d and cannot enter", player->GetName().c_str(), at->target_mapId); break; } @@ -1301,7 +1307,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData) { if (group->IsLeader(_player->GetGUID())) { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* groupGuy = itr->GetSource(); if (!groupGuy) @@ -1359,7 +1365,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData) { if (group->IsLeader(_player->GetGUID())) { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* groupGuy = itr->GetSource(); if (!groupGuy) @@ -1471,7 +1477,7 @@ void WorldSession::HandleWorldStateUITimerUpdate(WorldPacket& /*recvData*/) TC_LOG_DEBUG("network", "WORLD: CMSG_WORLD_STATE_UI_TIMER_UPDATE"); WorldPacket data(SMSG_WORLD_STATE_UI_TIMER_UPDATE, 4); - data << uint32(time(NULL)); + data << uint32(time(nullptr)); SendPacket(&data); } @@ -1583,30 +1589,25 @@ void WorldSession::HandleUpdateMissileTrajectory(WorldPacket& recvPacket) ObjectGuid guid; uint32 spellId; float elevation, speed; - float curX, curY, curZ; - float targetX, targetY, targetZ; + TaggedPosition<Position::XYZ> firePos; + TaggedPosition<Position::XYZ> impactPos; uint8 moveStop; recvPacket >> guid >> spellId >> elevation >> speed; - recvPacket >> curX >> curY >> curZ; - recvPacket >> targetX >> targetY >> targetZ; + recvPacket >> firePos; + recvPacket >> impactPos; recvPacket >> moveStop; Unit* caster = ObjectAccessor::GetUnit(*_player, guid); - Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : NULL; + Spell* spell = caster ? caster->GetCurrentSpell(CURRENT_GENERIC_SPELL) : nullptr; if (!spell || spell->m_spellInfo->Id != spellId || !spell->m_targets.HasDst() || !spell->m_targets.HasSrc()) { recvPacket.rfinish(); return; } - Position pos = *spell->m_targets.GetSrcPos(); - pos.Relocate(curX, curY, curZ); - spell->m_targets.ModSrc(pos); - - pos = *spell->m_targets.GetDstPos(); - pos.Relocate(targetX, targetY, targetZ); - spell->m_targets.ModDst(pos); + spell->m_targets.ModSrc(firePos); + spell->m_targets.ModDst(impactPos); spell->m_targets.SetElevation(elevation); spell->m_targets.SetSpeed(speed); diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index 871031025e5..8b64e0e08bb 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -163,7 +163,7 @@ void WorldSession::HandleMoveWorldportAck() { if (time_t timeReset = sInstanceSaveMgr->GetResetTimeFor(mEntry->MapID, diff)) { - uint32 timeleft = uint32(timeReset - time(NULL)); + uint32 timeleft = uint32(timeReset - time(nullptr)); GetPlayer()->SendInstanceResetWarning(mEntry->MapID, diff, timeleft, true); } } @@ -257,7 +257,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket& recvData) Unit* mover = _player->m_unitMovedByMe; - ASSERT(mover != NULL); // there must always be a mover + ASSERT(mover != nullptr); // there must always be a mover Player* plrMover = mover->ToPlayer(); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index beca093a6a9..ddde13ae860 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -16,26 +16,29 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" +#include "Battleground.h" +#include "BattlegroundMgr.h" #include "Common.h" -#include "Language.h" +#include "Creature.h" +#include "CreatureAI.h" #include "DatabaseEnv.h" -#include "QueryCallback.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Opcodes.h" +#include "DBCStores.h" +#include "GossipDef.h" +#include "Item.h" +#include "Language.h" #include "Log.h" +#include "Map.h" +#include "Opcodes.h" #include "ObjectMgr.h" -#include "SpellMgr.h" -#include "Player.h" -#include "GossipDef.h" -#include "Creature.h" #include "Pet.h" +#include "Player.h" +#include "QueryCallback.h" #include "ReputationMgr.h" -#include "BattlegroundMgr.h" -#include "Battleground.h" #include "ScriptMgr.h" -#include "CreatureAI.h" #include "SpellInfo.h" +#include "SpellMgr.h" +#include "WorldPacket.h" enum StableResultCode { @@ -373,11 +376,11 @@ void WorldSession::SendSpiritResurrect() _player->DurabilityLossAll(0.25f, true); // get corpse nearest graveyard - WorldSafeLocsEntry const* corpseGrave = NULL; + WorldSafeLocsEntry const* corpseGrave = nullptr; WorldLocation corpseLocation = _player->GetCorpseLocation(); if (_player->HasCorpse()) { - corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(), + corpseGrave = sObjectMgr->GetClosestGraveyard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(), corpseLocation.GetPositionZ(), corpseLocation.GetMapId(), _player->GetTeam()); } @@ -387,7 +390,7 @@ void WorldSession::SendSpiritResurrect() // teleport to nearest from corpse graveyard, if different from nearest to player ghost if (corpseGrave) { - WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveYard( + WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveyard( _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeam()); if (corpseGrave != ghostGrave) @@ -675,7 +678,7 @@ void WorldSession::HandleUnstablePetCallback(uint32 petId, PreparedQueryResult r if (!newPet->LoadPetFromDB(_player, petEntry, petId)) { delete newPet; - newPet = NULL; + newPet = nullptr; SendStableResult(STABLE_ERR_STABLE); return; } diff --git a/src/server/game/Handlers/NPCHandler.h b/src/server/game/Handlers/NPCHandler.h index fb7006b1712..61db8bfb04c 100644 --- a/src/server/game/Handlers/NPCHandler.h +++ b/src/server/game/Handlers/NPCHandler.h @@ -46,15 +46,15 @@ struct GossipText struct PageTextLocale { - StringVector Text; + std::vector<std::string> Text; }; struct NpcTextLocale { NpcTextLocale() { } - StringVector Text_0[MAX_GOSSIP_TEXT_OPTIONS]; - StringVector Text_1[MAX_GOSSIP_TEXT_OPTIONS]; + std::vector<std::string> Text_0[MAX_GOSSIP_TEXT_OPTIONS]; + std::vector<std::string> Text_1[MAX_GOSSIP_TEXT_OPTIONS]; }; #endif diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 53dc69ffd94..296e444f939 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -16,24 +16,26 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "WorldPacket.h" #include "WorldSession.h" -#include "ObjectMgr.h" -#include "SpellMgr.h" +#include "Common.h" +#include "CreatureAI.h" +#include "DatabaseEnv.h" +#include "Group.h" #include "Log.h" -#include "Opcodes.h" -#include "Spell.h" +#include "MotionMaster.h" #include "ObjectAccessor.h" -#include "CreatureAI.h" -#include "PetAI.h" -#include "Util.h" +#include "ObjectMgr.h" +#include "Opcodes.h" #include "Pet.h" -#include "World.h" -#include "Group.h" +#include "PetAI.h" +#include "Player.h" +#include "Spell.h" #include "SpellHistory.h" #include "SpellInfo.h" -#include "Player.h" +#include "SpellMgr.h" +#include "Util.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleDismissCritter(WorldPacket& recvData) { @@ -88,7 +90,7 @@ void WorldSession::HandlePetAction(WorldPacket& recvData) if (!pet->IsAlive()) { - SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellid) : NULL; + SpellInfo const* spell = (flag == ACT_ENABLED || flag == ACT_PASSIVE) ? sSpellMgr->GetSpellInfo(spellid) : nullptr; if (!spell) return; if (!spell->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_DEAD)) @@ -288,7 +290,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe case ACT_PASSIVE: // 0x01 case ACT_ENABLED: // 0xC1 spell { - Unit* unit_target = NULL; + Unit* unit_target = nullptr; if (guid2) unit_target = ObjectAccessor::GetUnit(*_player, guid2); @@ -429,7 +431,7 @@ void WorldSession::SendPetNameQuery(ObjectGuid petguid, uint32 petnumber) data << uint8(0); data << uint32(0); data << uint8(0); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); return; } @@ -447,7 +449,7 @@ void WorldSession::SendPetNameQuery(ObjectGuid petguid, uint32 petnumber) else data << uint8(0); - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); } bool WorldSession::CheckStableMaster(ObjectGuid guid) @@ -614,13 +616,13 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) PetNameInvalidReason res = ObjectMgr::CheckPetName(name, GetSessionDbcLocale()); if (res != PET_NAME_SUCCESS) { - SendPetNameInvalid(res, name, NULL); + SendPetNameInvalid(res, name, nullptr); return; } if (sObjectMgr->IsReservedName(name)) { - SendPetNameInvalid(PET_NAME_RESERVED, name, NULL); + SendPetNameInvalid(PET_NAME_RESERVED, name, nullptr); return; } @@ -673,7 +675,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) CharacterDatabase.CommitTransaction(trans); - pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(NULL))); // cast can't be helped + pet->SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, uint32(time(nullptr))); // cast can't be helped } void WorldSession::HandlePetAbandon(WorldPacket& recvData) @@ -713,7 +715,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) if (guid.IsPlayer()) return; - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if (!pet || (pet != _player->GetGuardianPet() && pet != _player->GetCharm())) { @@ -793,7 +795,7 @@ void WorldSession::HandlePetCastSpellOpcode(WorldPacket& recvPacket) spell->m_cast_count = castCount; // probably pending spell cast spell->m_targets = targets; - SpellCastResult result = spell->CheckPetCast(NULL); + SpellCastResult result = spell->CheckPetCast(nullptr); if (result == SPELL_CAST_OK) { diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 809237b72fd..4e47f260fff 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -16,20 +16,25 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "Language.h" -#include "WorldPacket.h" #include "WorldSession.h" -#include "World.h" -#include "ObjectMgr.h" +#include "ArenaTeam.h" #include "ArenaTeamMgr.h" +#include "CharacterCache.h" +#include "Common.h" +#include "Creature.h" +#include "DatabaseEnv.h" +#include "Guild.h" #include "GuildMgr.h" +#include "Item.h" +#include "Language.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Opcodes.h" -#include "Guild.h" -#include "ArenaTeam.h" -#include "CharacterCache.h" +#include "Player.h" #include "PetitionMgr.h" +#include "WorldPacket.h" +#include "World.h" #define CHARTER_DISPLAY_ID 16161 @@ -170,7 +175,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(charterid); if (!pProto) { - _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, NULL, charterid, 0); + _player->SendBuyError(BUY_ERR_CANT_FIND_ITEM, nullptr, charterid, 0); return; } @@ -184,7 +189,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) InventoryResult msg = _player->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, charterid, pProto->BuyCount); if (msg != EQUIP_ERR_OK) { - _player->SendEquipError(msg, NULL, NULL, charterid); + _player->SendEquipError(msg, nullptr, nullptr, charterid); return; } @@ -252,7 +257,7 @@ void WorldSession::SendPetitionSigns(Petition const* petition, Player* sendTo) data << uint32(0); // there 0 ... } - sendTo->GetSession()->SendPacket(&data); + sendTo->SendDirectMessage(&data); } void WorldSession::HandlePetitionQueryOpcode(WorldPacket& recvData) @@ -467,7 +472,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) // update for owner if online if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid)) - owner->GetSession()->SendPacket(&data); + owner->SendDirectMessage(&data); return; } @@ -484,7 +489,7 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) // update for owner if online if (Player* owner = ObjectAccessor::FindConnectedPlayer(ownerGuid)) - owner->GetSession()->SendPacket(&data); + owner->SendDirectMessage(&data); } void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData) @@ -504,7 +509,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData) { WorldPacket data(MSG_PETITION_DECLINE, 8); data << uint64(_player->GetGUID()); - owner->GetSession()->SendPacket(&data); + owner->SendDirectMessage(&data); } } @@ -622,7 +627,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData) { data.Initialize(SMSG_TURN_IN_PETITION_RESULTS, 4); data << (uint32)PETITION_TURN_ALREADY_IN_GUILD; - _player->GetSession()->SendPacket(&data); + _player->SendDirectMessage(&data); return; } diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index aec8553cb53..a2566c9a7f0 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -16,20 +16,20 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" +#include "CharacterCache.h" #include "Common.h" #include "DatabaseEnv.h" -#include "WorldPacket.h" -#include "WorldSession.h" +#include "DBCStores.h" #include "Log.h" -#include "World.h" +#include "MapManager.h" +#include "NPCHandler.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" +#include "QueryPackets.h" #include "UpdateMask.h" -#include "NPCHandler.h" -#include "MapManager.h" -#include "CharacterCache.h" - -#include "Packets/QueryPackets.h" +#include "World.h" void WorldSession::SendNameQueryOpcode(ObjectGuid guid) { @@ -52,7 +52,7 @@ void WorldSession::SendNameQueryOpcode(ObjectGuid guid) data << uint8(nameData->Sex); data << uint8(nameData->Class); - if (DeclinedName const* names = (player ? player->GetDeclinedNames() : NULL)) + if (DeclinedName const* names = (player ? player->GetDeclinedNames() : nullptr)) { data << uint8(1); // Name is declined for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) @@ -83,8 +83,8 @@ void WorldSession::HandleQueryTimeOpcode(WorldPacket & /*recvData*/) void WorldSession::SendQueryTimeResponse() { WorldPacket data(SMSG_QUERY_TIME_RESPONSE, 4+4); - data << uint32(time(NULL)); - data << uint32(sWorld->GetNextDailyQuestsResetTime() - time(NULL)); + data << uint32(time(nullptr)); + data << uint32(sWorld->GetNextDailyQuestsResetTime() - time(nullptr)); SendPacket(&data); } @@ -300,7 +300,7 @@ void WorldSession::HandlePageTextQueryOpcode(WorldPacket& recvData) std::string Text = pageText->Text; LocaleConstant localeConstant = GetSessionDbLocaleIndex(); - if (localeConstant >= LOCALE_enUS) + if (localeConstant != LOCALE_enUS) if (PageTextLocale const* pageTextLocale = sObjectMgr->GetPageTextLocale(pageID)) ObjectMgr::GetLocaleString(pageTextLocale->Text, localeConstant, Text); diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index 1cff4d27279..f95fb01ed36 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -16,22 +16,25 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" +#include "Battleground.h" #include "Common.h" +#include "Creature.h" +#include "CreatureAI.h" +#include "DatabaseEnv.h" +#include "GameObject.h" +#include "GameObjectAI.h" +#include "GossipDef.h" +#include "Group.h" #include "Log.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "World.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" -#include "GossipDef.h" #include "QuestDef.h" -#include "ObjectAccessor.h" -#include "Group.h" -#include "Battleground.h" +#include "QuestPackets.h" #include "ScriptMgr.h" -#include "GameObjectAI.h" - -#include "Packets/QuestPackets.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) { @@ -183,7 +186,7 @@ void WorldSession::HandleQuestgiverAcceptQuestOpcode(WorldPacket& recvData) { if (Group* group = _player->GetGroup()) { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* player = itr->GetSource(); @@ -253,9 +256,6 @@ void WorldSession::HandleQuestgiverQueryQuestOpcode(WorldPacket& recvData) void WorldSession::HandleQuestQueryOpcode(WorldPackets::Quest::QueryQuestInfo& query) { - if (!_player) - return; - TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUEST_QUERY quest = %u", query.QuestID); if (Quest const* quest = sObjectMgr->GetQuestTemplate(query.QuestID)) @@ -474,7 +474,7 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recvData) if (_player->CanAddQuest(quest, true)) { - _player->AddQuestAndCheckCompletion(quest, NULL); // NULL, this prevent DB script from duplicate running + _player->AddQuestAndCheckCompletion(quest, nullptr); // NULL, this prevent DB script from duplicate running if (quest->GetSrcSpell() > 0) _player->CastSpell(_player, quest->GetSrcSpell(), true); @@ -559,7 +559,7 @@ void WorldSession::HandlePushQuestToParty(WorldPacket& recvPacket) return; } - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* receiver = itr->GetSource(); @@ -653,7 +653,7 @@ void WorldSession::HandleQueryQuestsCompleted(WorldPacket & /*recvData*/) WorldPacket data(SMSG_QUERY_QUESTS_COMPLETED_RESPONSE, 4 + 4 * rew_count); data << uint32(rew_count); - const RewardedQuestSet &rewQuests = _player->getRewardedQuests(); + RewardedQuestSet const& rewQuests = _player->getRewardedQuests(); for (RewardedQuestSet::const_iterator itr = rewQuests.begin(); itr != rewQuests.end(); ++itr) data << uint32(*itr); diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index a10744929dd..b415f2c75c1 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -16,9 +16,10 @@ */ #include "WorldSession.h" -#include "Player.h" -#include "ObjectMgr.h" #include "Log.h" +#include "ObjectAccessor.h" +#include "Player.h" +#include "World.h" void WorldSession::HandleGrantLevel(WorldPacket& recvData) { @@ -60,7 +61,7 @@ void WorldSession::HandleGrantLevel(WorldPacket& recvData) WorldPacket data2(SMSG_PROPOSE_LEVEL_GRANT, 8); data2 << _player->GetPackGUID(); - target->GetSession()->SendPacket(&data2); + target->SendDirectMessage(&data2); } void WorldSession::HandleAcceptGrantLevel(WorldPacket& recvData) diff --git a/src/server/game/Handlers/SkillHandler.cpp b/src/server/game/Handlers/SkillHandler.cpp index e16b19bbf51..ecfb793cd06 100644 --- a/src/server/game/Handlers/SkillHandler.cpp +++ b/src/server/game/Handlers/SkillHandler.cpp @@ -16,13 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" #include "Common.h" +#include "DBCStores.h" #include "Log.h" #include "ObjectAccessor.h" -#include "Player.h" #include "Pet.h" +#include "Player.h" #include "WorldPacket.h" -#include "WorldSession.h" void WorldSession::HandleLearnTalentOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/SocialHandler.cpp b/src/server/game/Handlers/SocialHandler.cpp index 752ac0dace5..d1c1233c188 100644 --- a/src/server/game/Handlers/SocialHandler.cpp +++ b/src/server/game/Handlers/SocialHandler.cpp @@ -15,12 +15,17 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "CharacterCache.h" #include "WorldSession.h" +#include "AccountMgr.h" +#include "CharacterCache.h" +#include "Log.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "Player.h" -#include "QueryCallback.h" +#include "RBAC.h" +#include "Realm.h" #include "SocialMgr.h" -#include "ObjectMgr.h" +#include "World.h" void WorldSession::HandleContactListOpcode(WorldPacket& recvData) { diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index bea6cb7bbe5..e5336d4af21 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -16,22 +16,26 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" #include "Common.h" +#include "Config.h" +#include "DatabaseEnv.h" +#include "Log.h" #include "DBCStores.h" -#include "WorldPacket.h" -#include "WorldSession.h" +#include "GameObject.h" +#include "GameObjectAI.h" +#include "Item.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "SpellMgr.h" -#include "Log.h" #include "Opcodes.h" -#include "Spell.h" -#include "Totem.h" +#include "Player.h" #include "ScriptMgr.h" -#include "GameObjectAI.h" +#include "Spell.h" #include "SpellAuraEffects.h" -#include "Player.h" -#include "Config.h" -#include "QueryCallback.h" +#include "SpellMgr.h" +#include "Totem.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::HandleClientCastFlags(WorldPacket& recvPacket, uint8 castFlags, SpellCastTargets& targets) { @@ -75,20 +79,20 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) if (glyphIndex >= MAX_GLYPH_SLOT_INDEX) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } Item* pItem = pUser->GetUseableItemByPos(bagIndex, slot); if (!pItem) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } if (pItem->GetGUID() != itemGUID) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } @@ -97,35 +101,35 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) ItemTemplate const* proto = pItem->GetTemplate(); if (!proto) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL); + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr); return; } // some item classes can be used only in equipped state if (proto->InventoryType != INVTYPE_NON_EQUIP && !pItem->IsEquipped()) { - pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, NULL); + pUser->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, pItem, nullptr); return; } InventoryResult msg = pUser->CanUseItem(pItem); if (msg != EQUIP_ERR_OK) { - pUser->SendEquipError(msg, pItem, NULL); + pUser->SendEquipError(msg, pItem, nullptr); return; } // only allow conjured consumable, bandage, poisons (all should have the 2^21 item flag set in DB) if (proto->Class == ITEM_CLASS_CONSUMABLE && !(proto->Flags & ITEM_FLAG_IGNORE_DEFAULT_ARENA_RESTRICTIONS) && pUser->InArena()) { - pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL); + pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr); return; } // don't allow items banned in arena if ((proto->Flags & ITEM_FLAG_NOT_USEABLE_IN_ARENA) && pUser->InArena()) { - pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, NULL); + pUser->SendEquipError(EQUIP_ERR_NOT_DURING_ARENA_MATCH, pItem, nullptr); return; } @@ -137,7 +141,7 @@ void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket) { if (!spellInfo->CanBeUsedInCombat()) { - pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, NULL); + pUser->SendEquipError(EQUIP_ERR_NOT_IN_COMBAT, pItem, nullptr); return; } } @@ -205,7 +209,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) // Verify that the bag is an actual bag or wrapped item that can be used "normally" if (!(proto->Flags & ITEM_FLAG_HAS_LOOT) && !item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FIELD_FLAG_WRAPPED)) { - player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); + player->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, nullptr); TC_LOG_ERROR("entities.player.cheat", "Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!", player->GetName().c_str(), player->GetGUID().GetCounter(), item->GetGUID().GetCounter(), proto->ItemId); return; @@ -485,7 +489,7 @@ void WorldSession::HandlePetCancelAuraOpcode(WorldPacket& recvPacket) return; } - Creature* pet=ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); + Creature* pet = ObjectAccessor::GetCreatureOrPetOrVehicle(*_player, guid); if (!pet) { @@ -546,8 +550,7 @@ void WorldSession::HandleTotemDestroyed(WorldPacket& recvPacket) if (!_player->m_SummonSlot[slotId]) return; - Creature* totem = GetPlayer()->GetMap()->GetCreature(_player->m_SummonSlot[slotId]); - + Creature* totem = ObjectAccessor::GetCreature(*_player, _player->m_SummonSlot[slotId]); if (totem && totem->IsTotem()) totem->ToTotem()->UnSummon(); } diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index de1a3748b6c..3912707ea25 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -16,15 +16,16 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "WorldSession.h" #include "Common.h" #include "DatabaseEnv.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Opcodes.h" +#include "DBCStores.h" #include "Log.h" #include "ObjectMgr.h" +#include "Opcodes.h" #include "Player.h" #include "WaypointMovementGenerator.h" +#include "WorldPacket.h" void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvData) { @@ -39,10 +40,10 @@ void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvData) void WorldSession::SendTaxiStatus(ObjectGuid guid) { // cheating checks - Creature* unit = GetPlayer()->GetMap()->GetCreature(guid); + Creature* unit = GetPlayer()->GetNPCIfCanInteractWith(guid, UNIT_NPC_FLAG_FLIGHTMASTER); if (!unit) { - TC_LOG_DEBUG("network", "WorldSession::SendTaxiStatus - %s not found.", guid.ToString().c_str()); + TC_LOG_DEBUG("network", "WorldSession::SendTaxiStatus - %s not found or you can't interact with him.", guid.ToString().c_str()); return; } diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index ad1114e10bb..6510875ed7a 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -16,16 +16,20 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "zlib.h" +#include "WorldSession.h" #include "Common.h" +#include "DatabaseEnv.h" #include "Language.h" +#include "Log.h" #include "ObjectMgr.h" #include "Opcodes.h" #include "Player.h" +#include "Random.h" #include "TicketMgr.h" #include "Util.h" +#include "World.h" #include "WorldPacket.h" -#include "WorldSession.h" +#include <zlib.h> void WorldSession::HandleGMTicketCreateOpcode(WorldPacket& recvData) { @@ -126,7 +130,7 @@ void WorldSession::HandleGMTicketUpdateOpcode(WorldPacket& recvData) GMTicketResponse response = GMTICKET_RESPONSE_UPDATE_ERROR; if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) { - SQLTransaction trans = SQLTransaction(NULL); + SQLTransaction trans = SQLTransaction(nullptr); ticket->SetMessage(message); ticket->SaveToDB(trans); @@ -151,7 +155,7 @@ void WorldSession::HandleGMTicketDeleteOpcode(WorldPacket & /*recvData*/) sWorld->SendGMText(LANG_COMMAND_TICKETPLAYERABANDON, GetPlayer()->GetName().c_str(), ticket->GetId()); sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID()); - sTicketMgr->SendTicket(this, NULL); + sTicketMgr->SendTicket(this, nullptr); } } @@ -167,7 +171,7 @@ void WorldSession::HandleGMTicketGetTicketOpcode(WorldPacket & /*recvData*/) sTicketMgr->SendTicket(this, ticket); } else - sTicketMgr->SendTicket(this, NULL); + sTicketMgr->SendTicket(this, nullptr); } void WorldSession::HandleGMTicketSystemStatusOpcode(WorldPacket & /*recvData*/) @@ -247,7 +251,7 @@ void WorldSession::HandleReportLag(WorldPacket& recvData) stmt->setFloat (4, y); stmt->setFloat (5, z); stmt->setUInt32(6, GetLatency()); - stmt->setUInt32(7, time(NULL)); + stmt->setUInt32(7, time(nullptr)); CharacterDatabase.Execute(stmt); } @@ -257,7 +261,7 @@ void WorldSession::HandleGMResponseResolve(WorldPacket& /*recvPacket*/) if (GmTicket* ticket = sTicketMgr->GetTicketByPlayer(GetPlayer()->GetGUID())) { uint8 getSurvey = 0; - if (float(rand_chance()) < sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY)) + if (roll_chance_f(sWorld->getFloatConfig(CONFIG_CHANCE_OF_GM_SURVEY))) getSurvey = 1; WorldPacket data(SMSG_GMRESPONSE_STATUS_UPDATE, 4); @@ -269,6 +273,6 @@ void WorldSession::HandleGMResponseResolve(WorldPacket& /*recvPacket*/) SendPacket(&data2); sTicketMgr->CloseTicket(ticket->GetId(), GetPlayer()->GetGUID()); - sTicketMgr->SendTicket(this, NULL); + sTicketMgr->SendTicket(this, nullptr); } } diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index dc992ebb537..3490e6da98d 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -16,19 +16,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "WorldPacket.h" #include "WorldSession.h" -#include "World.h" -#include "ObjectAccessor.h" +#include "AccountMgr.h" +#include "Common.h" +#include "DatabaseEnv.h" +#include "Item.h" +#include "Language.h" #include "Log.h" +#include "ObjectAccessor.h" #include "Player.h" -#include "Item.h" #include "Spell.h" +#include "SpellMgr.h" #include "SocialMgr.h" -#include "Language.h" -#include "AccountMgr.h" #include "TradeData.h" +#include "World.h" +#include "WorldPacket.h" void WorldSession::SendTradeStatus(TradeStatusInfo const& info) { @@ -132,8 +134,8 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { ItemPosCountVec traderDst; ItemPosCountVec playerDst; - bool traderCanTrade = (myItems[i] == NULL || trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK); - bool playerCanTrade = (hisItems[i] == NULL || _player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK); + bool traderCanTrade = (myItems[i] == nullptr || trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK); + bool playerCanTrade = (hisItems[i] == nullptr || _player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, hisItems[i], false) == EQUIP_ERR_OK); if (traderCanTrade && playerCanTrade) { // Ok, if trade item exists and can be stored @@ -216,7 +218,7 @@ static void setAcceptTradeMode(TradeData* myTrade, TradeData* hisTrade, Item* *m if (Item* item = myTrade->GetItem(TradeSlots(i))) { TC_LOG_DEBUG("network", "player trade item %u bag: %u slot: %u", item->GetGUID().GetCounter(), item->GetBagSlot(), item->GetSlot()); - //Can return NULL + //Can return nullptr myItems[i] = item; myItems[i]->SetInTrade(); } @@ -260,8 +262,8 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) if (!his_trade) return; - Item* myItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; - Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { NULL, NULL, NULL, NULL, NULL, NULL }; + Item* myItems[TRADE_SLOT_TRADED_COUNT] = { }; + Item* hisItems[TRADE_SLOT_TRADED_COUNT] = { }; // set before checks for propertly undo at problems (it already set in to client) my_trade->SetAccepted(true); @@ -355,10 +357,10 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { setAcceptTradeMode(my_trade, his_trade, myItems, hisItems); - Spell* my_spell = NULL; + Spell* my_spell = nullptr; SpellCastTargets my_targets; - Spell* his_spell = NULL; + Spell* his_spell = nullptr; SpellCastTargets his_targets; // not accept if spell can't be cast now (cheating) @@ -527,9 +529,9 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // cleanup clearAcceptTradeMode(my_trade, his_trade); delete _player->m_trade; - _player->m_trade = NULL; + _player->m_trade = nullptr; delete trader->m_trade; - trader->m_trade = NULL; + trader->m_trade = nullptr; // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards) SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -791,5 +793,5 @@ void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket) if (tradeSlot >= TRADE_SLOT_COUNT) return; - my_trade->SetItem(TradeSlots(tradeSlot), NULL); + my_trade->SetItem(TradeSlots(tradeSlot), nullptr); } diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp index 17af33cb270..8e80fbe2063 100644 --- a/src/server/game/Handlers/VehicleHandler.cpp +++ b/src/server/game/Handlers/VehicleHandler.cpp @@ -15,12 +15,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "WorldPacket.h" #include "WorldSession.h" -#include "Vehicle.h" -#include "Player.h" +#include "DBCStructure.h" #include "Log.h" +#include "Map.h" #include "ObjectAccessor.h" +#include "Player.h" +#include "Vehicle.h" +#include "WorldPacket.h" void WorldSession::HandleDismissControlledVehicle(WorldPacket &recvData) { diff --git a/src/server/game/Handlers/VoiceChatHandler.cpp b/src/server/game/Handlers/VoiceChatHandler.cpp index 25724c80f40..e67124b0316 100644 --- a/src/server/game/Handlers/VoiceChatHandler.cpp +++ b/src/server/game/Handlers/VoiceChatHandler.cpp @@ -17,6 +17,7 @@ */ #include "Common.h" +#include "Log.h" #include "WorldPacket.h" #include "WorldSession.h" diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index bce01828896..a4b53c3ab78 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -16,21 +16,23 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "InstanceSaveMgr.h" #include "Common.h" -#include "Player.h" +#include "Config.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "GridNotifiers.h" -#include "Log.h" #include "GridStates.h" +#include "Group.h" +#include "InstanceScript.h" +#include "Log.h" #include "Map.h" -#include "MapManager.h" #include "MapInstanced.h" -#include "InstanceSaveMgr.h" -#include "Timer.h" -#include "Config.h" +#include "MapManager.h" #include "ObjectMgr.h" +#include "Player.h" +#include "Timer.h" #include "World.h" -#include "Group.h" -#include "InstanceScript.h" uint16 InstanceSaveManager::ResetTimeDelay[] = {3600, 900, 300, 60}; @@ -76,23 +78,23 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance if (InstanceSave* old_save = GetInstanceSave(instanceId)) return old_save; - const MapEntry* entry = sMapStore.LookupEntry(mapId); + MapEntry const* entry = sMapStore.LookupEntry(mapId); if (!entry) { TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: wrong mapid = %d, instanceid = %d!", mapId, instanceId); - return NULL; + return nullptr; } if (instanceId == 0) { TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: mapid = %d, wrong instanceid = %d!", mapId, instanceId); - return NULL; + return nullptr; } if (difficulty >= (entry->IsRaid() ? MAX_RAID_DIFFICULTY : MAX_DUNGEON_DIFFICULTY)) { TC_LOG_ERROR("misc", "InstanceSaveManager::AddInstanceSave: mapid = %d, instanceid = %d, wrong dificalty %u!", mapId, instanceId, difficulty); - return NULL; + return nullptr; } if (!resetTime) @@ -103,7 +105,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance resetTime = GetResetTimeFor(mapId, difficulty); else { - resetTime = time(NULL) + 2 * HOUR; + resetTime = time(nullptr) + 2 * HOUR; // normally this will be removed soon after in InstanceMap::Add, prevent error ScheduleReset(true, resetTime, InstResetEvent(0, mapId, difficulty, instanceId)); } @@ -122,7 +124,7 @@ InstanceSave* InstanceSaveManager::AddInstanceSave(uint32 mapId, uint32 instance InstanceSave* InstanceSaveManager::GetInstanceSave(uint32 InstanceId) { InstanceSaveHashMap::iterator itr = m_instanceSaveById.find(InstanceId); - return itr != m_instanceSaveById.end() ? itr->second : NULL; + return itr != m_instanceSaveById.end() ? itr->second : nullptr; } void InstanceSaveManager::DeleteInstanceFromDB(uint32 instanceid) @@ -219,7 +221,7 @@ void InstanceSave::SaveToDB() time_t InstanceSave::GetResetTimeForDB() { // only save the reset time for normal instances - const MapEntry* entry = sMapStore.LookupEntry(GetMapId()); + MapEntry const* entry = sMapStore.LookupEntry(GetMapId()); if (!entry || entry->map_type == MAP_RAID || GetDifficulty() == DUNGEON_DIFFICULTY_HEROIC) return 0; else @@ -298,7 +300,7 @@ void InstanceSaveManager::LoadInstances() void InstanceSaveManager::LoadResetTimes() { - time_t now = time(NULL); + time_t now = time(nullptr); time_t today = (now / DAY) * DAY; // NOTE: Use DirectPExecute for tables that will be queried later @@ -457,6 +459,13 @@ time_t InstanceSaveManager::GetSubsequentResetTime(uint32 mapid, Difficulty diff return ((resetTime + MINUTE) / DAY * DAY) + period + diff; } +void InstanceSaveManager::SetResetTimeFor(uint32 mapid, Difficulty d, time_t t) +{ + ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d)); + ASSERT(itr != m_resetTimeByMapDifficulty.end()); + itr->second = t; +} + void InstanceSaveManager::ScheduleReset(bool add, time_t time, InstResetEvent event) { if (!add) @@ -507,7 +516,7 @@ void InstanceSaveManager::ForceGlobalReset(uint32 mapId, Difficulty difficulty) void InstanceSaveManager::Update() { - time_t now = time(NULL); + time_t now = time(nullptr); time_t t; while (!m_resetTimeQueue.empty()) @@ -624,7 +633,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b return; TC_LOG_DEBUG("misc", "InstanceSaveManager::ResetOrWarnAll: Processing map %s (%u) on difficulty %u (warn? %u)", mapEntry->name[0], mapid, uint8(difficulty), warn); - time_t now = time(NULL); + time_t now = time(nullptr); if (!warn) { diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 6d3728e4fc5..81c10ac83cc 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -25,7 +25,7 @@ #include <unordered_map> #include "Define.h" -#include "DatabaseEnv.h" +#include "DatabaseEnvFwd.h" #include "DBCEnums.h" #include "ObjectDefines.h" @@ -174,7 +174,7 @@ class TC_GAME_API InstanceSaveManager InstResetEvent() : type(0), difficulty(DUNGEON_DIFFICULTY_NORMAL), mapid(0), instanceId(0) { } InstResetEvent(uint8 t, uint32 _mapid, Difficulty d, uint16 _instanceid) : type(t), difficulty(d), mapid(_mapid), instanceId(_instanceid) { } - bool operator == (const InstResetEvent& e) const { return e.instanceId == instanceId; } + bool operator==(InstResetEvent const& e) const { return e.instanceId == instanceId; } }; typedef std::multimap<time_t /*resetTime*/, InstResetEvent> ResetTimeQueue; @@ -195,12 +195,7 @@ class TC_GAME_API InstanceSaveManager } // Use this only when updating existing reset times - void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t) - { - ResetTimeByMapDifficultyMap::iterator itr = m_resetTimeByMapDifficulty.find(MAKE_PAIR32(mapid, d)); - ASSERT(itr != m_resetTimeByMapDifficulty.end()); - itr->second = t; - } + void SetResetTimeFor(uint32 mapid, Difficulty d, time_t t); ResetTimeByMapDifficultyMap const& GetResetTimeMap() const { diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index c66e1b3d5e8..3fa7eb52d6e 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -16,21 +16,29 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "InstanceScript.h" +#include "AreaBoundary.h" #include "Creature.h" #include "CreatureAI.h" +#include "CreatureAIImpl.h" #include "DatabaseEnv.h" +#include "DBCStructure.h" #include "GameObject.h" #include "Group.h" -#include "InstanceScript.h" #include "LFGMgr.h" #include "Log.h" #include "Map.h" -#include "Player.h" -#include "Pet.h" -#include "WorldSession.h" +#include "ObjectMgr.h" #include "Opcodes.h" -#include "ScriptReloadMgr.h" +#include "Pet.h" +#include "Player.h" +#include "RBAC.h" #include "ScriptMgr.h" +#include "ScriptReloadMgr.h" +#include "World.h" +#include "WorldSession.h" +#include <cstdarg> +#include <sstream> BossBoundaryData::~BossBoundaryData() { @@ -109,6 +117,16 @@ ObjectGuid InstanceScript::GetGuidData(uint32 type) const return GetObjectGuid(type); } +Creature* InstanceScript::GetCreature(uint32 type) +{ + return instance->GetCreature(GetObjectGuid(type)); +} + +GameObject* InstanceScript::GetGameObject(uint32 type) +{ + return instance->GetGameObject(GetObjectGuid(type)); +} + void InstanceScript::SetHeaders(std::string const& dataHeaders) { for (char header : dataHeaders) @@ -116,14 +134,14 @@ void InstanceScript::SetHeaders(std::string const& dataHeaders) headers.push_back(header); } -void InstanceScript::LoadBossBoundaries(const BossBoundaryData& data) +void InstanceScript::LoadBossBoundaries(BossBoundaryData const& data) { for (BossBoundaryEntry const& entry : data) if (entry.BossId < bosses.size()) bosses[entry.BossId].boundary.push_back(entry.Boundary); } -void InstanceScript::LoadMinionData(const MinionData* data) +void InstanceScript::LoadMinionData(MinionData const* data) { while (data->entry) { @@ -135,7 +153,7 @@ void InstanceScript::LoadMinionData(const MinionData* data) TC_LOG_DEBUG("scripts", "InstanceScript::LoadMinionData: " UI64FMTD " minions loaded.", uint64(minions.size())); } -void InstanceScript::LoadDoorData(const DoorData* data) +void InstanceScript::LoadDoorData(DoorData const* data) { while (data->entry) { @@ -518,9 +536,9 @@ void InstanceScript::DoSendNotifyToInstance(char const* format, ...) } // Update Achievement Criteria for all players in instance -void InstanceScript::DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= NULL*/) +void InstanceScript::DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/, Unit* unit /*= nullptr*/) { - Map::PlayerList const &PlayerList = instance->GetPlayers(); + Map::PlayerList const& PlayerList = instance->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) @@ -531,7 +549,7 @@ void InstanceScript::DoUpdateAchievementCriteria(AchievementCriteriaTypes type, // Start timed achievement for all players in instance void InstanceScript::DoStartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) { - Map::PlayerList const &PlayerList = instance->GetPlayers(); + Map::PlayerList const& PlayerList = instance->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) @@ -542,7 +560,7 @@ void InstanceScript::DoStartTimedAchievement(AchievementCriteriaTimedTypes type, // Stop timed achievement for all players in instance void InstanceScript::DoStopTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) { - Map::PlayerList const &PlayerList = instance->GetPlayers(); + Map::PlayerList const& PlayerList = instance->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) @@ -571,7 +589,7 @@ void InstanceScript::DoRemoveAurasDueToSpellOnPlayers(uint32 spell) // Cast spell on all players in instance void InstanceScript::DoCastSpellOnPlayers(uint32 spell) { - Map::PlayerList const &PlayerList = instance->GetPlayers(); + Map::PlayerList const& PlayerList = instance->GetPlayers(); if (!PlayerList.isEmpty()) for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) @@ -579,14 +597,19 @@ void InstanceScript::DoCastSpellOnPlayers(uint32 spell) player->CastSpell(player, spell, true); } -bool InstanceScript::CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/ /*= NULL*/, uint32 /*miscvalue1*/ /*= 0*/) +bool InstanceScript::ServerAllowsTwoSideGroups() +{ + return sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP); +} + +bool InstanceScript::CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/ /*= nullptr*/, uint32 /*miscvalue1*/ /*= 0*/) { TC_LOG_ERROR("misc", "Achievement system call InstanceScript::CheckAchievementCriteriaMeet but instance script for map %u not have implementation for achievement criteria %u", instance->GetId(), criteria_id); return false; } -void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= NULL*/, uint8 param1 /*= 0*/, uint8 param2 /*= 0*/) +void InstanceScript::SendEncounterUnit(uint32 type, Unit* unit /*= nullptr*/, uint8 param1 /*= 0*/, uint8 param2 /*= 0*/) { // size of this packet is at most 15 (usually less) WorldPacket data(SMSG_UPDATE_INSTANCE_ENCOUNTER_UNIT, 15); @@ -658,6 +681,16 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi } } +void InstanceScript::UpdateEncounterStateForKilledCreature(uint32 creatureId, Unit* source) +{ + UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, creatureId, source); +} + +void InstanceScript::UpdateEncounterStateForSpellCast(uint32 spellId, Unit* source) +{ + UpdateEncounterState(ENCOUNTER_CREDIT_CAST_SPELL, spellId, source); +} + std::string InstanceScript::GetBossStateName(uint8 state) { // See enum EncounterState in InstanceScript.h @@ -679,3 +712,11 @@ std::string InstanceScript::GetBossStateName(uint8 state) return "INVALID"; } } + +bool InstanceHasScript(WorldObject const* obj, char const* scriptName) +{ + if (InstanceMap* instance = obj->GetMap()->ToInstanceMap()) + return instance->GetScriptName() == scriptName; + + return false; +} diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 864ee007a5e..55452ebf3c1 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -19,11 +19,11 @@ #ifndef TRINITY_INSTANCE_DATA_H #define TRINITY_INSTANCE_DATA_H -#include <set> #include "ZoneScript.h" -#include "World.h" -#include "ObjectMgr.h" -#include "CreatureAI.h" +#include "Common.h" +#include <map> +#include <memory> +#include <set> #define OUT_SAVE_INST_DATA TC_LOG_DEBUG("scripts", "Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) #define OUT_SAVE_INST_DATA_COMPLETE TC_LOG_DEBUG("scripts", "Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) @@ -31,12 +31,17 @@ #define OUT_LOAD_INST_DATA_COMPLETE TC_LOG_DEBUG("scripts", "Instance Data Load for Instance %s (Map %d, Instance Id: %d) is complete.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) #define OUT_LOAD_INST_DATA_FAIL TC_LOG_ERROR("scripts", "Unable to load Instance Data for Instance %s (Map %d, Instance Id: %d).", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) -class Map; -class Unit; -class Player; -class GameObject; +class AreaBoundary; class Creature; +class GameObject; +class Map; class ModuleReference; +class Player; +class Unit; +class WorldPacket; +enum AchievementCriteriaTypes : uint8; +enum AchievementCriteriaTimedTypes : uint8; +enum EncounterCreditType : uint8; enum EncounterFrameType { @@ -105,6 +110,8 @@ struct ObjectData uint32 type; }; +typedef std::vector<AreaBoundary const*> CreatureBoundary; + struct BossInfo { BossInfo() : state(TO_BE_DECIDED) { } @@ -174,21 +181,15 @@ class TC_GAME_API InstanceScript : public ZoneScript ObjectGuid GetObjectGuid(uint32 type) const; virtual ObjectGuid GetGuidData(uint32 type) const override; - inline Creature* GetCreature(uint32 type) - { - return instance->GetCreature(GetObjectGuid(type)); - } - inline GameObject* GetGameObject(uint32 type) - { - return instance->GetGameObject(GetObjectGuid(type)); - } + Creature* GetCreature(uint32 type); + GameObject* GetGameObject(uint32 type); // Called when a player successfully enters the instance. virtual void OnPlayerEnter(Player* /*player*/) { } // Handle open / close objects // * use HandleGameObject(0, boolen, GO); in OnObjectCreate in instance scripts - // * use HandleGameObject(GUID, boolen, NULL); in any other script + // * use HandleGameObject(GUID, boolen, nullptr); in any other script void HandleGameObject(ObjectGuid guid, bool open, GameObject* go = nullptr); // Change active state of doors or buttons @@ -205,7 +206,7 @@ class TC_GAME_API InstanceScript : public ZoneScript void DoSendNotifyToInstance(char const* format, ...); // Update Achievement Criteria for all players in instance - void DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = NULL); + void DoUpdateAchievementCriteria(AchievementCriteriaTypes type, uint32 miscValue1 = 0, uint32 miscValue2 = 0, Unit* unit = nullptr); // Start/Stop Timed Achievement Criteria for all players in instance void DoStartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry); @@ -218,22 +219,23 @@ class TC_GAME_API InstanceScript : public ZoneScript void DoCastSpellOnPlayers(uint32 spell); // Return wether server allow two side groups or not - bool ServerAllowsTwoSideGroups() { return sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GROUP); } + static bool ServerAllowsTwoSideGroups(); virtual bool SetBossState(uint32 id, EncounterState state); EncounterState GetBossState(uint32 id) const { return id < bosses.size() ? bosses[id].state : TO_BE_DECIDED; } static std::string GetBossStateName(uint8 state); - CreatureBoundary const* GetBossBoundary(uint32 id) const { return id < bosses.size() ? &bosses[id].boundary : NULL; } + CreatureBoundary const* GetBossBoundary(uint32 id) const { return id < bosses.size() ? &bosses[id].boundary : nullptr; } // Achievement criteria additional requirements check // NOTE: not use this if same can be checked existed requirement types from AchievementCriteriaRequirementType - virtual bool CheckAchievementCriteriaMeet(uint32 /*criteria_id*/, Player const* /*source*/, Unit const* /*target*/ = NULL, uint32 /*miscvalue1*/ = 0); + virtual bool CheckAchievementCriteriaMeet(uint32 /*criteria_id*/, Player const* /*source*/, Unit const* /*target*/ = nullptr, uint32 /*miscvalue1*/ = 0); // Checks boss requirements (one boss required to kill other) virtual bool CheckRequiredBosses(uint32 /*bossId*/, Player const* /*player*/ = nullptr) const { return true; } // Checks encounter state at kill/spellcast - void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* source); + void UpdateEncounterStateForKilledCreature(uint32 creatureId, Unit* source); + void UpdateEncounterStateForSpellCast(uint32 spellId, Unit* source); // Used only during loading void SetCompletedEncountersMask(uint32 newMask) { completedEncounters = newMask; } @@ -241,7 +243,7 @@ class TC_GAME_API InstanceScript : public ZoneScript // Returns completed encounters mask for packets uint32 GetCompletedEncounterMask() const { return completedEncounters; } - void SendEncounterUnit(uint32 type, Unit* unit = NULL, uint8 param1 = 0, uint8 param2 = 0); + void SendEncounterUnit(uint32 type, Unit* unit = nullptr, uint8 param1 = 0, uint8 param2 = 0); virtual void FillInitialWorldStates(WorldPacket& /*data*/) { } @@ -281,6 +283,7 @@ class TC_GAME_API InstanceScript : public ZoneScript private: static void LoadObjectData(ObjectData const* creatureData, ObjectInfoMap& objectInfo); + void UpdateEncounterState(EncounterCreditType type, uint32 creditEntry, Unit* source); std::vector<char> headers; std::vector<BossInfo> bosses; @@ -297,25 +300,4 @@ class TC_GAME_API InstanceScript : public ZoneScript #endif // #ifndef TRINITY_API_USE_DYNAMIC_LINKING }; -template<class AI, class T> -AI* GetInstanceAI(T* obj, char const* scriptName) -{ - if (InstanceMap* instance = obj->GetMap()->ToInstanceMap()) - if (instance->GetInstanceScript()) - if (instance->GetScriptId() == sObjectMgr->GetScriptId(scriptName)) - return new AI(obj); - - return NULL; -} - -template<class AI, class T> -AI* GetInstanceAI(T* obj) -{ - if (InstanceMap* instance = obj->GetMap()->ToInstanceMap()) - if (instance->GetInstanceScript()) - return new AI(obj); - - return NULL; -} - #endif // TRINITY_INSTANCE_DATA_H diff --git a/src/server/game/Loot/Loot.cpp b/src/server/game/Loot/Loot.cpp new file mode 100644 index 00000000000..7f6aaf24169 --- /dev/null +++ b/src/server/game/Loot/Loot.cpp @@ -0,0 +1,777 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Loot.h" +#include "Group.h" +#include "ItemEnchantmentMgr.h" +#include "ItemTemplate.h" +#include "Log.h" +#include "LootMgr.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "Random.h" +#include "World.h" + + // + // --------- LootItem --------- + // + + // Constructor, copies most fields from LootStoreItem and generates random count +LootItem::LootItem(LootStoreItem const& li) +{ + itemid = li.itemid; + conditions = li.conditions; + + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemid); + freeforall = proto && (proto->Flags & ITEM_FLAG_MULTI_DROP); + follow_loot_rules = proto && (proto->FlagsCu & ITEM_FLAGS_CU_FOLLOW_LOOT_RULES); + + needs_quest = li.needs_quest; + + randomSuffix = GenerateEnchSuffixFactor(itemid); + randomPropertyId = GenerateItemRandomPropertyId(itemid); + count = 0; + is_looted = 0; + is_blocked = 0; + is_underthreshold = 0; + is_counted = 0; + rollWinnerGUID = ObjectGuid::Empty; +} + +// Basic checks for player/item compatibility - if false no chance to see the item in the loot +bool LootItem::AllowedForPlayer(Player const* player) const +{ + // DB conditions check + if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(player), conditions)) + return false; + + ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid); + if (!pProto) + return false; + + // not show loot for players without profession or those who already know the recipe + if ((pProto->Flags & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId))) + return false; + + // not show loot for not own team + if ((pProto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && player->GetTeam() != HORDE) + return false; + + if ((pProto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && player->GetTeam() != ALLIANCE) + return false; + + // check quest requirements + if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid))) + return false; + + return true; +} + +void LootItem::AddAllowedLooter(Player const* player) +{ + allowedGUIDs.insert(player->GetGUID()); +} + +// +// --------- Loot --------- +// + +Loot::Loot(uint32 _gold /*= 0*/) : gold(_gold), unlootedCount(0), roundRobinPlayer(), loot_type(LOOT_NONE), maxDuplicates(1), containerID(0) +{ +} + +Loot::~Loot() +{ + clear(); +} + +void Loot::clear() +{ + for (NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr) + delete itr->second; + PlayerQuestItems.clear(); + + for (NotNormalLootItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr) + delete itr->second; + PlayerFFAItems.clear(); + + for (NotNormalLootItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr) + delete itr->second; + PlayerNonQuestNonFFAConditionalItems.clear(); + + PlayersLooting.clear(); + items.clear(); + quest_items.clear(); + gold = 0; + unlootedCount = 0; + roundRobinPlayer.Clear(); + loot_type = LOOT_NONE; + i_LootValidatorRefManager.clearReferences(); +} + +// Inserts the item into the loot (called by LootTemplate processors) +void Loot::AddItem(LootStoreItem const& item) +{ + ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); + if (!proto) + return; + + uint32 count = urand(item.mincount, item.maxcount); + uint32 stacks = count / proto->GetMaxStackSize() + ((count % proto->GetMaxStackSize()) ? 1 : 0); + + std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items; + uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS; + + for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i) + { + LootItem generatedLoot(item); + generatedLoot.count = std::min(count, proto->GetMaxStackSize()); + lootItems.push_back(generatedLoot); + count -= proto->GetMaxStackSize(); + + // non-conditional one-player only items are counted here, + // free for all items are counted in FillFFALoot(), + // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() + if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_FLAG_MULTI_DROP)) + ++unlootedCount; + } +} + +// Calls processor of corresponding LootTemplate (which handles everything including references) +bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError, uint16 lootMode /*= LOOT_MODE_DEFAULT*/) +{ + // Must be provided + if (!lootOwner) + return false; + + LootTemplate const* tab = store.GetLootFor(lootId); + + if (!tab) + { + if (!noEmptyError) + TC_LOG_ERROR("sql.sql", "Table '%s' loot id #%u used but it doesn't have records.", store.GetName(), lootId); + return false; + } + + items.reserve(MAX_NR_LOOT_ITEMS); + quest_items.reserve(MAX_NR_QUEST_ITEMS); + + tab->Process(*this, store.IsRatesAllowed(), lootMode); // Processing is done there, callback via Loot::AddItem() + + // Setting access rights for group loot case + Group* group = lootOwner->GetGroup(); + if (!personal && group) + { + roundRobinPlayer = lootOwner->GetGUID(); + + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) + if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter + if (player->IsInMap(lootOwner)) + FillNotNormalLootFor(player, player->IsAtGroupRewardDistance(lootOwner)); + + for (uint8 i = 0; i < items.size(); ++i) + { + if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid)) + if (proto->Quality < uint32(group->GetLootThreshold())) + items[i].is_underthreshold = true; + } + } + // ... for personal loot + else + FillNotNormalLootFor(lootOwner, true); + + return true; +} + +void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting) +{ + ObjectGuid plguid = player->GetGUID(); + + NotNormalLootItemMap::const_iterator qmapitr = PlayerQuestItems.find(plguid); + if (qmapitr == PlayerQuestItems.end()) + FillQuestLoot(player); + + qmapitr = PlayerFFAItems.find(plguid); + if (qmapitr == PlayerFFAItems.end()) + FillFFALoot(player); + + qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid); + if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end()) + FillNonQuestNonFFAConditionalLoot(player, presentAtLooting); + + // if not auto-processed player will have to come and pick it up manually + if (!presentAtLooting) + return; + + // Process currency items + uint32 max_slot = GetMaxSlotInLootFor(player); + LootItem const* item = nullptr; + uint32 itemsSize = uint32(items.size()); + for (uint32 i = 0; i < max_slot; ++i) + { + if (i < items.size()) + item = &items[i]; + else + item = &quest_items[i - itemsSize]; + + if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player)) + if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid)) + if (proto->IsCurrencyToken()) + player->StoreLootItem(i, this); + } +} + +NotNormalLootItemList* Loot::FillFFALoot(Player* player) +{ + NotNormalLootItemList* ql = new NotNormalLootItemList(); + + for (uint8 i = 0; i < items.size(); ++i) + { + LootItem &item = items[i]; + if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player)) + { + ql->push_back(NotNormalLootItem(i)); + ++unlootedCount; + } + } + if (ql->empty()) + { + delete ql; + return nullptr; + } + + PlayerFFAItems[player->GetGUID()] = ql; + return ql; +} + +NotNormalLootItemList* Loot::FillQuestLoot(Player* player) +{ + if (items.size() == MAX_NR_LOOT_ITEMS) + return nullptr; + + NotNormalLootItemList* ql = new NotNormalLootItemList(); + + for (uint8 i = 0; i < quest_items.size(); ++i) + { + LootItem &item = quest_items[i]; + + if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT)))) + { + ql->push_back(NotNormalLootItem(i)); + + // quest items get blocked when they first appear in a + // player's quest vector + // + // increase once if one looter only, looter-times if free for all + if (item.freeforall || !item.is_blocked) + ++unlootedCount; + if (!player->GetGroup() || (player->GetGroup()->GetLootMethod() != GROUP_LOOT && player->GetGroup()->GetLootMethod() != ROUND_ROBIN)) + item.is_blocked = true; + + if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS) + break; + } + } + if (ql->empty()) + { + delete ql; + return nullptr; + } + + PlayerQuestItems[player->GetGUID()] = ql; + return ql; +} + +NotNormalLootItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting) +{ + NotNormalLootItemList* ql = new NotNormalLootItemList(); + + for (uint8 i = 0; i < items.size(); ++i) + { + LootItem &item = items[i]; + if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player))) + { + if (presentAtLooting) + item.AddAllowedLooter(player); + if (!item.conditions.empty()) + { + ql->push_back(NotNormalLootItem(i)); + if (!item.is_counted) + { + ++unlootedCount; + item.is_counted = true; + } + } + } + } + if (ql->empty()) + { + delete ql; + return nullptr; + } + + PlayerNonQuestNonFFAConditionalItems[player->GetGUID()] = ql; + return ql; +} + +//=================================================== + +void Loot::NotifyItemRemoved(uint8 lootIndex) +{ + // notify all players that are looting this that the item was removed + // convert the index to the slot the player sees + GuidSet::iterator i_next; + for (GuidSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) + { + i_next = i; + ++i_next; + if (Player* player = ObjectAccessor::FindPlayer(*i)) + player->SendNotifyLootItemRemoved(lootIndex); + else + PlayersLooting.erase(i); + } +} + +void Loot::NotifyMoneyRemoved() +{ + // notify all players that are looting this that the money was removed + GuidSet::iterator i_next; + for (GuidSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) + { + i_next = i; + ++i_next; + if (Player* player = ObjectAccessor::FindPlayer(*i)) + player->SendNotifyLootMoneyRemoved(); + else + PlayersLooting.erase(i); + } +} + +void Loot::NotifyQuestItemRemoved(uint8 questIndex) +{ + // when a free for all questitem is looted + // all players will get notified of it being removed + // (other questitems can be looted by each group member) + // bit inefficient but isn't called often + + GuidSet::iterator i_next; + for (GuidSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) + { + i_next = i; + ++i_next; + if (Player* player = ObjectAccessor::FindPlayer(*i)) + { + NotNormalLootItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID()); + if (pq != PlayerQuestItems.end() && pq->second) + { + // find where/if the player has the given item in it's vector + NotNormalLootItemList& pql = *pq->second; + + uint8 j; + for (j = 0; j < pql.size(); ++j) + if (pql[j].index == questIndex) + break; + + if (j < pql.size()) + player->SendNotifyLootItemRemoved(items.size() + j); + } + } + else + PlayersLooting.erase(i); + } +} + +void Loot::generateMoneyLoot(uint32 minAmount, uint32 maxAmount) +{ + if (maxAmount > 0) + { + if (maxAmount <= minAmount) + gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY)); + else if ((maxAmount - minAmount) < 32700) + gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY)); + else + gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8; + } +} + +LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, NotNormalLootItem* *qitem, NotNormalLootItem* *ffaitem, NotNormalLootItem* *conditem) +{ + LootItem* item = nullptr; + bool is_looted = true; + if (lootSlot >= items.size()) + { + uint32 questSlot = lootSlot - items.size(); + NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID()); + if (itr != PlayerQuestItems.end() && questSlot < itr->second->size()) + { + NotNormalLootItem* qitem2 = &itr->second->at(questSlot); + if (qitem) + *qitem = qitem2; + item = &quest_items[qitem2->index]; + is_looted = qitem2->is_looted; + } + } + else + { + item = &items[lootSlot]; + is_looted = item->is_looted; + if (item->freeforall) + { + NotNormalLootItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID()); + if (itr != PlayerFFAItems.end()) + { + for (NotNormalLootItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter) + if (iter->index == lootSlot) + { + NotNormalLootItem* ffaitem2 = (NotNormalLootItem*)&(*iter); + if (ffaitem) + *ffaitem = ffaitem2; + is_looted = ffaitem2->is_looted; + break; + } + } + } + else if (!item->conditions.empty()) + { + NotNormalLootItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID()); + if (itr != PlayerNonQuestNonFFAConditionalItems.end()) + { + for (NotNormalLootItemList::const_iterator iter = itr->second->begin(); iter != itr->second->end(); ++iter) + { + if (iter->index == lootSlot) + { + NotNormalLootItem* conditem2 = (NotNormalLootItem*)&(*iter); + if (conditem) + *conditem = conditem2; + is_looted = conditem2->is_looted; + break; + } + } + } + } + } + + if (is_looted) + return nullptr; + + return item; +} + +uint32 Loot::GetMaxSlotInLootFor(Player* player) const +{ + NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID()); + return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0); +} + +// return true if there is any item that is lootable for any player (not quest item, FFA or conditional) +bool Loot::hasItemForAll() const +{ + // Gold is always lootable + if (gold) + return true; + + for (LootItem const& item : items) + if (!item.is_looted && !item.freeforall && item.conditions.empty()) + return true; + return false; +} + +// return true if there is any FFA, quest or conditional item for the player. +bool Loot::hasItemFor(Player* player) const +{ + NotNormalLootItemMap const& lootPlayerQuestItems = GetPlayerQuestItems(); + NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID()); + if (q_itr != lootPlayerQuestItems.end()) + { + NotNormalLootItemList* q_list = q_itr->second; + for (NotNormalLootItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) + { + LootItem const& item = quest_items[qi->index]; + if (!qi->is_looted && !item.is_looted) + return true; + } + } + + NotNormalLootItemMap const& lootPlayerFFAItems = GetPlayerFFAItems(); + NotNormalLootItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID()); + if (ffa_itr != lootPlayerFFAItems.end()) + { + NotNormalLootItemList* ffa_list = ffa_itr->second; + for (NotNormalLootItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) + { + LootItem const& item = items[fi->index]; + if (!fi->is_looted && !item.is_looted) + return true; + } + } + + NotNormalLootItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems(); + NotNormalLootItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID()); + if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) + { + NotNormalLootItemList* conditional_list = nn_itr->second; + for (NotNormalLootItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) + { + LootItem const& item = items[ci->index]; + if (!ci->is_looted && !item.is_looted) + return true; + } + } + + return false; +} + +// return true if there is any item over the group threshold (i.e. not underthreshold). +bool Loot::hasOverThresholdItem() const +{ + for (uint8 i = 0; i < items.size(); ++i) + { + if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall) + return true; + } + + return false; +} + +ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li) +{ + b << uint32(li.itemid); + b << uint32(li.count); // nr of items of this type + b << uint32(ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(li.itemid))->DisplayInfoID); + b << uint32(li.randomSuffix); + b << uint32(li.randomPropertyId); + //b << uint8(0); // slot type - will send after this function call + return b; +} + +ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) +{ + if (lv.permission == NONE_PERMISSION) + { + b << uint32(0); // gold + b << uint8(0); // item count + return b; + } + + Loot &l = lv.loot; + + uint8 itemsShown = 0; + + b << uint32(l.gold); //gold + + size_t count_pos = b.wpos(); // pos of item count byte + b << uint8(0); // item count placeholder + + switch (lv.permission) + { + case GROUP_PERMISSION: + case MASTER_PERMISSION: + case RESTRICTED_PERMISSION: + { + // if you are not the round-robin group looter, you can only see + // blocked rolled items and quest items, and !ffa items + for (uint8 i = 0; i < l.items.size(); ++i) + { + if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer)) + { + uint8 slot_type; + + if (l.items[i].is_blocked) // for ML & restricted is_blocked = !is_underthreshold + { + switch (lv.permission) + { + case GROUP_PERMISSION: + slot_type = LOOT_SLOT_TYPE_ROLL_ONGOING; + break; + case MASTER_PERMISSION: + { + if (lv.viewer->GetGroup() && lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID()) + slot_type = LOOT_SLOT_TYPE_MASTER; + else + slot_type = LOOT_SLOT_TYPE_LOCKED; + break; + } + case RESTRICTED_PERMISSION: + slot_type = LOOT_SLOT_TYPE_LOCKED; + break; + default: + continue; + } + } + else if (!l.items[i].rollWinnerGUID.IsEmpty()) + { + if (l.items[i].rollWinnerGUID == lv.viewer->GetGUID()) + slot_type = LOOT_SLOT_TYPE_OWNER; + else + continue; + } + else if (l.roundRobinPlayer.IsEmpty() || lv.viewer->GetGUID() == l.roundRobinPlayer || !l.items[i].is_underthreshold) + { + // no round robin owner or he has released the loot + // or it IS the round robin group owner + // => item is lootable + slot_type = LOOT_SLOT_TYPE_ALLOW_LOOT; + } + else + // item shall not be displayed. + continue; + + b << uint8(i) << l.items[i]; + b << uint8(slot_type); + ++itemsShown; + } + } + break; + } + case ROUND_ROBIN_PERMISSION: + { + for (uint8 i = 0; i < l.items.size(); ++i) + { + if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer)) + { + if (!l.roundRobinPlayer.IsEmpty() && lv.viewer->GetGUID() != l.roundRobinPlayer) + // item shall not be displayed. + continue; + + b << uint8(i) << l.items[i]; + b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); + ++itemsShown; + } + } + break; + } + case ALL_PERMISSION: + case OWNER_PERMISSION: + { + uint8 slot_type = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; + for (uint8 i = 0; i < l.items.size(); ++i) + { + if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer)) + { + b << uint8(i) << l.items[i]; + b << uint8(slot_type); + ++itemsShown; + } + } + break; + } + default: + return b; + } + + LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; + NotNormalLootItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems(); + NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID()); + if (q_itr != lootPlayerQuestItems.end()) + { + NotNormalLootItemList* q_list = q_itr->second; + for (NotNormalLootItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) + { + LootItem &item = l.quest_items[qi->index]; + if (!qi->is_looted && !item.is_looted) + { + b << uint8(l.items.size() + (qi - q_list->begin())); + b << item; + if (item.follow_loot_rules) + { + switch (lv.permission) + { + case MASTER_PERMISSION: + b << uint8(LOOT_SLOT_TYPE_MASTER); + break; + case RESTRICTED_PERMISSION: + b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); + break; + case GROUP_PERMISSION: + case ROUND_ROBIN_PERMISSION: + if (!item.is_blocked) + b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); + else + b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING); + break; + default: + b << uint8(slotType); + break; + } + } + else + b << uint8(slotType); + ++itemsShown; + } + } + } + + NotNormalLootItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems(); + NotNormalLootItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID()); + if (ffa_itr != lootPlayerFFAItems.end()) + { + NotNormalLootItemList* ffa_list = ffa_itr->second; + for (NotNormalLootItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) + { + LootItem &item = l.items[fi->index]; + if (!fi->is_looted && !item.is_looted) + { + b << uint8(fi->index); + b << item; + b << uint8(slotType); + ++itemsShown; + } + } + } + + NotNormalLootItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems(); + NotNormalLootItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID()); + if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) + { + NotNormalLootItemList* conditional_list = nn_itr->second; + for (NotNormalLootItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) + { + LootItem &item = l.items[ci->index]; + if (!ci->is_looted && !item.is_looted) + { + b << uint8(ci->index); + b << item; + switch (lv.permission) + { + case MASTER_PERMISSION: + b << uint8(LOOT_SLOT_TYPE_MASTER); + break; + case RESTRICTED_PERMISSION: + b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); + break; + case GROUP_PERMISSION: + case ROUND_ROBIN_PERMISSION: + if (!item.is_blocked) + b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); + else + b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING); + break; + default: + b << uint8(slotType); + break; + } + ++itemsShown; + } + } + } + + //update number of items shown + b.put<uint8>(count_pos, itemsShown); + + return b; +} diff --git a/src/server/game/Loot/Loot.h b/src/server/game/Loot/Loot.h new file mode 100644 index 00000000000..33477c4e853 --- /dev/null +++ b/src/server/game/Loot/Loot.h @@ -0,0 +1,279 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef Loot_h__ +#define Loot_h__ + +#include "Define.h" +#include "ConditionMgr.h" +#include "ObjectGuid.h" +#include "RefManager.h" +#include "SharedDefines.h" +#include <unordered_map> +#include <vector> + +class Item; +class LootStore; +class Player; +struct Loot; +struct LootStoreItem; + +enum RollType +{ + ROLL_PASS = 0, + ROLL_NEED = 1, + ROLL_GREED = 2, + ROLL_DISENCHANT = 3, + MAX_ROLL_TYPE = 4 +}; + +enum RollMask +{ + ROLL_FLAG_TYPE_PASS = 0x01, + ROLL_FLAG_TYPE_NEED = 0x02, + ROLL_FLAG_TYPE_GREED = 0x04, + ROLL_FLAG_TYPE_DISENCHANT = 0x08, + + ROLL_ALL_TYPE_NO_DISENCHANT = 0x07, + ROLL_ALL_TYPE_MASK = 0x0F +}; + +#define MAX_NR_LOOT_ITEMS 16 +// note: the client cannot show more than 16 items total +#define MAX_NR_QUEST_ITEMS 32 +// unrelated to the number of quest items shown, just for reserve + +enum LootMethod : uint8 +{ + FREE_FOR_ALL = 0, + ROUND_ROBIN = 1, + MASTER_LOOT = 2, + GROUP_LOOT = 3, + NEED_BEFORE_GREED = 4 +}; + +enum PermissionTypes +{ + ALL_PERMISSION = 0, + GROUP_PERMISSION = 1, + MASTER_PERMISSION = 2, + RESTRICTED_PERMISSION = 3, + ROUND_ROBIN_PERMISSION = 4, + OWNER_PERMISSION = 5, + NONE_PERMISSION = 6 +}; + +enum LootType : uint8 +{ + LOOT_NONE = 0, + + LOOT_CORPSE = 1, + LOOT_PICKPOCKETING = 2, + LOOT_FISHING = 3, + LOOT_DISENCHANTING = 4, + // ignored always by client + LOOT_SKINNING = 6, + LOOT_PROSPECTING = 7, + LOOT_MILLING = 8, + + LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead + LOOT_INSIGNIA = 21, // unsupported by client, sending LOOT_CORPSE instead + LOOT_FISHING_JUNK = 22 // unsupported by client, sending LOOT_FISHING instead +}; + +enum LootError : uint8 +{ + LOOT_ERROR_DIDNT_KILL = 0, // You don't have permission to loot that corpse. + LOOT_ERROR_TOO_FAR = 4, // You are too far away to loot that corpse. + LOOT_ERROR_BAD_FACING = 5, // You must be facing the corpse to loot it. + LOOT_ERROR_LOCKED = 6, // Someone is already looting that corpse. + LOOT_ERROR_NOTSTANDING = 8, // You need to be standing up to loot something! + LOOT_ERROR_STUNNED = 9, // You can't loot anything while stunned! + LOOT_ERROR_PLAYER_NOT_FOUND = 10, // Player not found + LOOT_ERROR_PLAY_TIME_EXCEEDED = 11, // Maximum play time exceeded + LOOT_ERROR_MASTER_INV_FULL = 12, // That player's inventory is full + LOOT_ERROR_MASTER_UNIQUE_ITEM = 13, // Player has too many of that item already + LOOT_ERROR_MASTER_OTHER = 14, // Can't assign item to that player + LOOT_ERROR_ALREADY_PICKPOCKETED = 15, // Your target has already had its pockets picked + LOOT_ERROR_NOT_WHILE_SHAPESHIFTED = 16 // You can't do that while shapeshifted. +}; + +// type of Loot Item in Loot View +enum LootSlotType +{ + LOOT_SLOT_TYPE_ALLOW_LOOT = 0, // player can loot the item. + LOOT_SLOT_TYPE_ROLL_ONGOING = 1, // roll is ongoing. player cannot loot. + LOOT_SLOT_TYPE_MASTER = 2, // item can only be distributed by group loot master. + LOOT_SLOT_TYPE_LOCKED = 3, // item is shown in red. player cannot loot. + LOOT_SLOT_TYPE_OWNER = 4 // ignore binding confirmation and etc, for single player looting +}; + +struct TC_GAME_API LootItem +{ + uint32 itemid; + uint32 randomSuffix; + int32 randomPropertyId; + ConditionContainer conditions; // additional loot condition + GuidSet allowedGUIDs; + ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list! + uint8 count : 8; + bool is_looted : 1; + bool is_blocked : 1; + bool freeforall : 1; // free for all + bool is_underthreshold : 1; + bool is_counted : 1; + bool needs_quest : 1; // quest drop + bool follow_loot_rules : 1; + + // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties + // Should be called for non-reference LootStoreItem entries only (reference = 0) + explicit LootItem(LootStoreItem const& li); + + // Empty constructor for creating an empty LootItem to be filled in with DB data + LootItem() : itemid(0), randomSuffix(0), randomPropertyId(0), count(0), is_looted(false), is_blocked(false), + freeforall(false), is_underthreshold(false), is_counted(false), needs_quest(false), follow_loot_rules(false) + { }; + + // Basic checks for player/item compatibility - if false no chance to see the item in the loot + bool AllowedForPlayer(Player const* player) const; + void AddAllowedLooter(Player const* player); + GuidSet const& GetAllowedLooters() const { return allowedGUIDs; } +}; + +struct NotNormalLootItem +{ + uint8 index; // position in quest_items or items; + bool is_looted; + + NotNormalLootItem() + : index(0), is_looted(false) { } + + NotNormalLootItem(uint8 _index, bool _islooted = false) + : index(_index), is_looted(_islooted) { } +}; + +struct Loot; +class LootTemplate; + +typedef std::vector<NotNormalLootItem> NotNormalLootItemList; +typedef std::vector<LootItem> LootItemList; +typedef std::unordered_map<ObjectGuid, NotNormalLootItemList*> NotNormalLootItemMap; + +class LootValidatorRef : public Reference<Loot, LootValidatorRef> +{ + public: + LootValidatorRef() { } + void targetObjectDestroyLink() override { } + void sourceObjectDestroyLink() override { } +}; + +//===================================================== + +class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef> +{ + public: + typedef LinkedListHead::Iterator< LootValidatorRef > iterator; + + LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); } + + iterator begin() { return iterator(getFirst()); } + iterator end() { return iterator(nullptr); } +}; + +//===================================================== +struct LootView; + +ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li); +ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); + +struct TC_GAME_API Loot +{ + friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); + + NotNormalLootItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; } + NotNormalLootItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; } + NotNormalLootItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; } + + std::vector<LootItem> items; + std::vector<LootItem> quest_items; + uint32 gold; + uint8 unlootedCount; + ObjectGuid roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released. + LootType loot_type; // required for achievement system + uint8 maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3) + + // GUIDLow of container that holds this loot (item_instance.entry) + // Only set for inventory items that can be right-click looted + uint32 containerID; + + Loot(uint32 _gold = 0); + ~Loot(); + + // if loot becomes invalid this reference is used to inform the listener + void addLootValidatorRef(LootValidatorRef* pLootValidatorRef) + { + i_LootValidatorRefManager.insertFirst(pLootValidatorRef); + } + + void clear(); + + bool empty() const { return items.empty() && gold == 0; } + bool isLooted() const { return gold == 0 && unlootedCount == 0; } + + void NotifyItemRemoved(uint8 lootIndex); + void NotifyQuestItemRemoved(uint8 questIndex); + void NotifyMoneyRemoved(); + void AddLooter(ObjectGuid GUID) { PlayersLooting.insert(GUID); } + void RemoveLooter(ObjectGuid GUID) { PlayersLooting.erase(GUID); } + + void generateMoneyLoot(uint32 minAmount, uint32 maxAmount); + bool FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError = false, uint16 lootMode = LOOT_MODE_DEFAULT); + + // Inserts the item into the loot (called by LootTemplate processors) + void AddItem(LootStoreItem const & item); + + 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 hasOverThresholdItem() const; + + private: + void FillNotNormalLootFor(Player* player, bool presentAtLooting); + NotNormalLootItemList* FillFFALoot(Player* player); + NotNormalLootItemList* FillQuestLoot(Player* player); + NotNormalLootItemList* FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting); + + GuidSet PlayersLooting; + NotNormalLootItemMap PlayerQuestItems; + NotNormalLootItemMap PlayerFFAItems; + NotNormalLootItemMap PlayerNonQuestNonFFAConditionalItems; + + // All rolls are registered here. They need to know, when the loot is not valid anymore + LootValidatorRefManager i_LootValidatorRefManager; +}; + +struct LootView +{ + Loot &loot; + Player* viewer; + PermissionTypes permission; + LootView(Loot &_loot, Player* _viewer, PermissionTypes _permission = ALL_PERMISSION) + : loot(_loot), viewer(_viewer), permission(_permission) { } +}; + +#endif // Loot_h__ diff --git a/src/server/game/Loot/LootItemStorage.cpp b/src/server/game/Loot/LootItemStorage.cpp index 45f1027932b..07b01379904 100644 --- a/src/server/game/Loot/LootItemStorage.cpp +++ b/src/server/game/Loot/LootItemStorage.cpp @@ -16,8 +16,11 @@ */ #include "LootItemStorage.h" +#include "DatabaseEnv.h" +#include "Item.h" #include "ItemTemplate.h" #include "Log.h" +#include "Loot.h" #include "LootMgr.h" #include "ObjectMgr.h" #include "Player.h" diff --git a/src/server/game/Loot/LootItemStorage.h b/src/server/game/Loot/LootItemStorage.h index e98831a5ecf..aeda684d705 100644 --- a/src/server/game/Loot/LootItemStorage.h +++ b/src/server/game/Loot/LootItemStorage.h @@ -19,7 +19,7 @@ #define __LOOTITEMSTORAGE_H #include "Define.h" -#include "Transaction.h" +#include "DatabaseEnvFwd.h" #include <unordered_map> diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 34712308070..7c6cc28fb48 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -17,16 +17,19 @@ */ #include "LootMgr.h" +#include "Containers.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "Group.h" #include "Log.h" +#include "Loot.h" #include "ObjectMgr.h" -#include "World.h" -#include "Util.h" +#include "Player.h" #include "SharedDefines.h" -#include "SpellMgr.h" #include "SpellInfo.h" -#include "Group.h" -#include "Player.h" -#include "Containers.h" +#include "SpellMgr.h" +#include "Util.h" +#include "World.h" static Rates const qualityToRate[MAX_ITEM_QUALITY] = { @@ -91,7 +94,6 @@ class LootTemplate::LootGroup // A set of loot def float TotalChance() const; // Overall chance for the group void Verify(LootStore const& lootstore, uint32 id, uint8 group_id) const; - void CollectLootIds(LootIdSet& set) const; void CheckLootRefs(LootTemplateMap const& store, LootIdSet* ref_set) const; LootStoreItemList* GetExplicitlyChancedItemList() { return &ExplicitlyChanced; } LootStoreItemList* GetEqualChancedItemList() { return &EqualChanced; } @@ -103,14 +105,14 @@ class LootTemplate::LootGroup // A set of loot def LootStoreItem const* Roll(Loot& loot, uint16 lootMode) const; // Rolls an item from the group, returns NULL if all miss their chances // This class must never be copied - storing pointers - LootGroup(LootGroup const&); - LootGroup& operator=(LootGroup const&); + LootGroup(LootGroup const&) = delete; + LootGroup& operator=(LootGroup const&) = delete; }; //Remove all data and free all memory void LootStore::Clear() { - for (LootTemplateMap::const_iterator itr=m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr) + for (LootTemplateMap::const_iterator itr = m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr) delete itr->second; m_LootTemplates.clear(); } @@ -228,7 +230,7 @@ LootTemplate const* LootStore::GetLootFor(uint32 loot_id) const LootTemplateMap::const_iterator tab = m_LootTemplates.find(loot_id); if (tab == m_LootTemplates.end()) - return NULL; + return nullptr; return tab->second; } @@ -238,7 +240,7 @@ LootTemplate* LootStore::GetLootForConditionFill(uint32 loot_id) LootTemplateMap::iterator tab = m_LootTemplates.find(loot_id); if (tab == m_LootTemplates.end()) - return NULL; + return nullptr; return tab->second; } @@ -266,7 +268,7 @@ void LootStore::ReportUnusedIds(LootIdSet const& lootIdSet) const TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d isn't %s and not referenced from loot, and thus useless.", GetName(), *itr, GetEntryName()); } -void LootStore::ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const +void LootStore::ReportNonExistingId(uint32 lootId, char const* ownerType, uint32 ownerId) const { TC_LOG_ERROR("sql.sql", "Table '%s' Entry %d does not exist but it is used by %s %d", GetName(), lootId, ownerType, ownerId); } @@ -343,722 +345,6 @@ bool LootStoreItem::IsValid(LootStore const& store, uint32 entry) const } // -// --------- LootItem --------- -// - -// Constructor, copies most fields from LootStoreItem and generates random count -LootItem::LootItem(LootStoreItem const& li) -{ - itemid = li.itemid; - conditions = li.conditions; - - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemid); - freeforall = proto && (proto->Flags & ITEM_FLAG_MULTI_DROP); - follow_loot_rules = proto && (proto->FlagsCu & ITEM_FLAGS_CU_FOLLOW_LOOT_RULES); - - needs_quest = li.needs_quest; - - randomSuffix = GenerateEnchSuffixFactor(itemid); - randomPropertyId = Item::GenerateItemRandomPropertyId(itemid); - count = 0; - is_looted = 0; - is_blocked = 0; - is_underthreshold = 0; - is_counted = 0; - rollWinnerGUID = ObjectGuid::Empty; -} - -// Basic checks for player/item compatibility - if false no chance to see the item in the loot -bool LootItem::AllowedForPlayer(Player const* player) const -{ - // DB conditions check - if (!sConditionMgr->IsObjectMeetToConditions(const_cast<Player*>(player), conditions)) - return false; - - ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid); - if (!pProto) - return false; - - // not show loot for players without profession or those who already know the recipe - if ((pProto->Flags & ITEM_FLAG_HIDE_UNUSABLE_RECIPE) && (!player->HasSkill(pProto->RequiredSkill) || player->HasSpell(pProto->Spells[1].SpellId))) - return false; - - // not show loot for not own team - if ((pProto->Flags2 & ITEM_FLAG2_FACTION_HORDE) && player->GetTeam() != HORDE) - return false; - - if ((pProto->Flags2 & ITEM_FLAG2_FACTION_ALLIANCE) && player->GetTeam() != ALLIANCE) - return false; - - // check quest requirements - if (!(pProto->FlagsCu & ITEM_FLAGS_CU_IGNORE_QUEST_STATUS) && ((needs_quest || (pProto->StartQuest && player->GetQuestStatus(pProto->StartQuest) != QUEST_STATUS_NONE)) && !player->HasQuestForItem(itemid))) - return false; - - return true; -} - -void LootItem::AddAllowedLooter(const Player* player) -{ - allowedGUIDs.insert(player->GetGUID().GetCounter()); -} - -// -// --------- Loot --------- -// - -// Inserts the item into the loot (called by LootTemplate processors) -void Loot::AddItem(LootStoreItem const& item) -{ - ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item.itemid); - if (!proto) - return; - - uint32 count = urand(item.mincount, item.maxcount); - uint32 stacks = count / proto->GetMaxStackSize() + ((count % proto->GetMaxStackSize()) ? 1 : 0); - - std::vector<LootItem>& lootItems = item.needs_quest ? quest_items : items; - uint32 limit = item.needs_quest ? MAX_NR_QUEST_ITEMS : MAX_NR_LOOT_ITEMS; - - for (uint32 i = 0; i < stacks && lootItems.size() < limit; ++i) - { - LootItem generatedLoot(item); - generatedLoot.count = std::min(count, proto->GetMaxStackSize()); - lootItems.push_back(generatedLoot); - count -= proto->GetMaxStackSize(); - - // non-conditional one-player only items are counted here, - // free for all items are counted in FillFFALoot(), - // non-ffa conditionals are counted in FillNonQuestNonFFAConditionalLoot() - if (!item.needs_quest && item.conditions.empty() && !(proto->Flags & ITEM_FLAG_MULTI_DROP)) - ++unlootedCount; - } -} - -// Calls processor of corresponding LootTemplate (which handles everything including references) -bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError, uint16 lootMode /*= LOOT_MODE_DEFAULT*/) -{ - // Must be provided - if (!lootOwner) - return false; - - LootTemplate const* tab = store.GetLootFor(lootId); - - if (!tab) - { - if (!noEmptyError) - TC_LOG_ERROR("sql.sql", "Table '%s' loot id #%u used but it doesn't have records.", store.GetName(), lootId); - return false; - } - - items.reserve(MAX_NR_LOOT_ITEMS); - quest_items.reserve(MAX_NR_QUEST_ITEMS); - - tab->Process(*this, store.IsRatesAllowed(), lootMode); // Processing is done there, callback via Loot::AddItem() - - // Setting access rights for group loot case - Group* group = lootOwner->GetGroup(); - if (!personal && group) - { - roundRobinPlayer = lootOwner->GetGUID(); - - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) - if (Player* player = itr->GetSource()) // should actually be looted object instead of lootOwner but looter has to be really close so doesnt really matter - if (player->IsInMap(lootOwner)) - FillNotNormalLootFor(player, player->IsAtGroupRewardDistance(lootOwner)); - - for (uint8 i = 0; i < items.size(); ++i) - { - if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(items[i].itemid)) - if (proto->Quality < uint32(group->GetLootThreshold())) - items[i].is_underthreshold = true; - } - } - // ... for personal loot - else - FillNotNormalLootFor(lootOwner, true); - - return true; -} - -void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting) -{ - ObjectGuid::LowType plguid = player->GetGUID().GetCounter(); - - NotNormalLootItemMap::const_iterator qmapitr = PlayerQuestItems.find(plguid); - if (qmapitr == PlayerQuestItems.end()) - FillQuestLoot(player); - - qmapitr = PlayerFFAItems.find(plguid); - if (qmapitr == PlayerFFAItems.end()) - FillFFALoot(player); - - qmapitr = PlayerNonQuestNonFFAConditionalItems.find(plguid); - if (qmapitr == PlayerNonQuestNonFFAConditionalItems.end()) - FillNonQuestNonFFAConditionalLoot(player, presentAtLooting); - - // if not auto-processed player will have to come and pick it up manually - if (!presentAtLooting) - return; - - // Process currency items - uint32 max_slot = GetMaxSlotInLootFor(player); - LootItem const* item = NULL; - uint32 itemsSize = uint32(items.size()); - for (uint32 i = 0; i < max_slot; ++i) - { - if (i < items.size()) - item = &items[i]; - else - item = &quest_items[i-itemsSize]; - - if (!item->is_looted && item->freeforall && item->AllowedForPlayer(player)) - if (ItemTemplate const* proto = sObjectMgr->GetItemTemplate(item->itemid)) - if (proto->IsCurrencyToken()) - player->StoreLootItem(i, this); - } -} - -NotNormalLootItemList* Loot::FillFFALoot(Player* player) -{ - NotNormalLootItemList* ql = new NotNormalLootItemList(); - - for (uint8 i = 0; i < items.size(); ++i) - { - LootItem &item = items[i]; - if (!item.is_looted && item.freeforall && item.AllowedForPlayer(player)) - { - ql->push_back(NotNormalLootItem(i)); - ++unlootedCount; - } - } - if (ql->empty()) - { - delete ql; - return NULL; - } - - PlayerFFAItems[player->GetGUID().GetCounter()] = ql; - return ql; -} - -NotNormalLootItemList* Loot::FillQuestLoot(Player* player) -{ - if (items.size() == MAX_NR_LOOT_ITEMS) - return NULL; - - NotNormalLootItemList* ql = new NotNormalLootItemList(); - - for (uint8 i = 0; i < quest_items.size(); ++i) - { - LootItem &item = quest_items[i]; - - if (!item.is_looted && (item.AllowedForPlayer(player) || (item.follow_loot_rules && player->GetGroup() && ((player->GetGroup()->GetLootMethod() == MASTER_LOOT && player->GetGroup()->GetMasterLooterGuid() == player->GetGUID()) || player->GetGroup()->GetLootMethod() != MASTER_LOOT)))) - { - ql->push_back(NotNormalLootItem(i)); - - // quest items get blocked when they first appear in a - // player's quest vector - // - // increase once if one looter only, looter-times if free for all - if (item.freeforall || !item.is_blocked) - ++unlootedCount; - if (!player->GetGroup() || (player->GetGroup()->GetLootMethod() != GROUP_LOOT && player->GetGroup()->GetLootMethod() != ROUND_ROBIN)) - item.is_blocked = true; - - if (items.size() + ql->size() == MAX_NR_LOOT_ITEMS) - break; - } - } - if (ql->empty()) - { - delete ql; - return NULL; - } - - PlayerQuestItems[player->GetGUID().GetCounter()] = ql; - return ql; -} - -NotNormalLootItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting) -{ - NotNormalLootItemList* ql = new NotNormalLootItemList(); - - for (uint8 i = 0; i < items.size(); ++i) - { - LootItem &item = items[i]; - if (!item.is_looted && !item.freeforall && (item.AllowedForPlayer(player))) - { - if (presentAtLooting) - item.AddAllowedLooter(player); - if (!item.conditions.empty()) - { - ql->push_back(NotNormalLootItem(i)); - if (!item.is_counted) - { - ++unlootedCount; - item.is_counted = true; - } - } - } - } - if (ql->empty()) - { - delete ql; - return NULL; - } - - PlayerNonQuestNonFFAConditionalItems[player->GetGUID().GetCounter()] = ql; - return ql; -} - -//=================================================== - -void Loot::NotifyItemRemoved(uint8 lootIndex) -{ - // notify all players that are looting this that the item was removed - // convert the index to the slot the player sees - GuidSet::iterator i_next; - for (GuidSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) - { - i_next = i; - ++i_next; - if (Player* player = ObjectAccessor::FindPlayer(*i)) - player->SendNotifyLootItemRemoved(lootIndex); - else - PlayersLooting.erase(i); - } -} - -void Loot::NotifyMoneyRemoved() -{ - // notify all players that are looting this that the money was removed - GuidSet::iterator i_next; - for (GuidSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) - { - i_next = i; - ++i_next; - if (Player* player = ObjectAccessor::FindPlayer(*i)) - player->SendNotifyLootMoneyRemoved(); - else - PlayersLooting.erase(i); - } -} - -void Loot::NotifyQuestItemRemoved(uint8 questIndex) -{ - // when a free for all questitem is looted - // all players will get notified of it being removed - // (other questitems can be looted by each group member) - // bit inefficient but isn't called often - - GuidSet::iterator i_next; - for (GuidSet::iterator i = PlayersLooting.begin(); i != PlayersLooting.end(); i = i_next) - { - i_next = i; - ++i_next; - if (Player* player = ObjectAccessor::FindPlayer(*i)) - { - NotNormalLootItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID().GetCounter()); - if (pq != PlayerQuestItems.end() && pq->second) - { - // find where/if the player has the given item in it's vector - NotNormalLootItemList& pql = *pq->second; - - uint8 j; - for (j = 0; j < pql.size(); ++j) - if (pql[j].index == questIndex) - break; - - if (j < pql.size()) - player->SendNotifyLootItemRemoved(items.size()+j); - } - } - else - PlayersLooting.erase(i); - } -} - -void Loot::generateMoneyLoot(uint32 minAmount, uint32 maxAmount) -{ - if (maxAmount > 0) - { - if (maxAmount <= minAmount) - gold = uint32(maxAmount * sWorld->getRate(RATE_DROP_MONEY)); - else if ((maxAmount - minAmount) < 32700) - gold = uint32(urand(minAmount, maxAmount) * sWorld->getRate(RATE_DROP_MONEY)); - else - gold = uint32(urand(minAmount >> 8, maxAmount >> 8) * sWorld->getRate(RATE_DROP_MONEY)) << 8; - } -} - -LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, NotNormalLootItem* *qitem, NotNormalLootItem* *ffaitem, NotNormalLootItem* *conditem) -{ - LootItem* item = NULL; - bool is_looted = true; - if (lootSlot >= items.size()) - { - uint32 questSlot = lootSlot - items.size(); - NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); - if (itr != PlayerQuestItems.end() && questSlot < itr->second->size()) - { - NotNormalLootItem* qitem2 = &itr->second->at(questSlot); - if (qitem) - *qitem = qitem2; - item = &quest_items[qitem2->index]; - is_looted = qitem2->is_looted; - } - } - else - { - item = &items[lootSlot]; - is_looted = item->is_looted; - if (item->freeforall) - { - NotNormalLootItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID().GetCounter()); - if (itr != PlayerFFAItems.end()) - { - for (NotNormalLootItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) - if (iter->index == lootSlot) - { - NotNormalLootItem* ffaitem2 = (NotNormalLootItem*)&(*iter); - if (ffaitem) - *ffaitem = ffaitem2; - is_looted = ffaitem2->is_looted; - break; - } - } - } - else if (!item->conditions.empty()) - { - NotNormalLootItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); - if (itr != PlayerNonQuestNonFFAConditionalItems.end()) - { - for (NotNormalLootItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) - { - if (iter->index == lootSlot) - { - NotNormalLootItem* conditem2 = (NotNormalLootItem*)&(*iter); - if (conditem) - *conditem = conditem2; - is_looted = conditem2->is_looted; - break; - } - } - } - } - } - - if (is_looted) - return NULL; - - return item; -} - -uint32 Loot::GetMaxSlotInLootFor(Player* player) const -{ - NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); - return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0); -} - -// return true if there is any item that is lootable for any player (not quest item, FFA or conditional) -bool Loot::hasItemForAll() const -{ - // Gold is always lootable - if (gold) - return true; - - for (LootItem const& item : items) - if (!item.is_looted && !item.freeforall && item.conditions.empty()) - return true; - return false; -} - -// return true if there is any FFA, quest or conditional item for the player. -bool Loot::hasItemFor(Player* player) const -{ - NotNormalLootItemMap const& lootPlayerQuestItems = GetPlayerQuestItems(); - NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID().GetCounter()); - if (q_itr != lootPlayerQuestItems.end()) - { - NotNormalLootItemList* q_list = q_itr->second; - for (NotNormalLootItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) - { - const LootItem &item = quest_items[qi->index]; - if (!qi->is_looted && !item.is_looted) - return true; - } - } - - NotNormalLootItemMap const& lootPlayerFFAItems = GetPlayerFFAItems(); - NotNormalLootItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID().GetCounter()); - if (ffa_itr != lootPlayerFFAItems.end()) - { - NotNormalLootItemList* ffa_list = ffa_itr->second; - for (NotNormalLootItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) - { - const LootItem &item = items[fi->index]; - if (!fi->is_looted && !item.is_looted) - return true; - } - } - - NotNormalLootItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems(); - NotNormalLootItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); - if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) - { - NotNormalLootItemList* conditional_list = nn_itr->second; - for (NotNormalLootItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) - { - const LootItem &item = items[ci->index]; - if (!ci->is_looted && !item.is_looted) - return true; - } - } - - return false; -} - -// return true if there is any item over the group threshold (i.e. not underthreshold). -bool Loot::hasOverThresholdItem() const -{ - for (uint8 i = 0; i < items.size(); ++i) - { - if (!items[i].is_looted && !items[i].is_underthreshold && !items[i].freeforall) - return true; - } - - return false; -} - -ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li) -{ - b << uint32(li.itemid); - b << uint32(li.count); // nr of items of this type - b << uint32(ASSERT_NOTNULL(sObjectMgr->GetItemTemplate(li.itemid))->DisplayInfoID); - b << uint32(li.randomSuffix); - b << uint32(li.randomPropertyId); - //b << uint8(0); // slot type - will send after this function call - return b; -} - -ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) -{ - if (lv.permission == NONE_PERMISSION) - { - b << uint32(0); // gold - b << uint8(0); // item count - return b; - } - - Loot &l = lv.loot; - - uint8 itemsShown = 0; - - b << uint32(l.gold); //gold - - size_t count_pos = b.wpos(); // pos of item count byte - b << uint8(0); // item count placeholder - - switch (lv.permission) - { - case GROUP_PERMISSION: - case MASTER_PERMISSION: - case RESTRICTED_PERMISSION: - { - // if you are not the round-robin group looter, you can only see - // blocked rolled items and quest items, and !ffa items - for (uint8 i = 0; i < l.items.size(); ++i) - { - if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer)) - { - uint8 slot_type; - - if (l.items[i].is_blocked) // for ML & restricted is_blocked = !is_underthreshold - { - switch (lv.permission) - { - case GROUP_PERMISSION: - slot_type = LOOT_SLOT_TYPE_ROLL_ONGOING; - break; - case MASTER_PERMISSION: - { - if (lv.viewer->GetGroup() && lv.viewer->GetGroup()->GetMasterLooterGuid() == lv.viewer->GetGUID()) - slot_type = LOOT_SLOT_TYPE_MASTER; - else - slot_type = LOOT_SLOT_TYPE_LOCKED; - break; - } - case RESTRICTED_PERMISSION: - slot_type = LOOT_SLOT_TYPE_LOCKED; - break; - default: - continue; - } - } - else if (!l.items[i].rollWinnerGUID.IsEmpty()) - { - if (l.items[i].rollWinnerGUID == lv.viewer->GetGUID()) - slot_type = LOOT_SLOT_TYPE_OWNER; - else - continue; - } - else if (l.roundRobinPlayer.IsEmpty() || lv.viewer->GetGUID() == l.roundRobinPlayer || !l.items[i].is_underthreshold) - { - // no round robin owner or he has released the loot - // or it IS the round robin group owner - // => item is lootable - slot_type = LOOT_SLOT_TYPE_ALLOW_LOOT; - } - else - // item shall not be displayed. - continue; - - b << uint8(i) << l.items[i]; - b << uint8(slot_type); - ++itemsShown; - } - } - break; - } - case ROUND_ROBIN_PERMISSION: - { - for (uint8 i = 0; i < l.items.size(); ++i) - { - if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer)) - { - if (!l.roundRobinPlayer.IsEmpty() && lv.viewer->GetGUID() != l.roundRobinPlayer) - // item shall not be displayed. - continue; - - b << uint8(i) << l.items[i]; - b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); - ++itemsShown; - } - } - break; - } - case ALL_PERMISSION: - case OWNER_PERMISSION: - { - uint8 slot_type = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; - for (uint8 i = 0; i < l.items.size(); ++i) - { - if (!l.items[i].is_looted && !l.items[i].freeforall && l.items[i].conditions.empty() && l.items[i].AllowedForPlayer(lv.viewer)) - { - b << uint8(i) << l.items[i]; - b << uint8(slot_type); - ++itemsShown; - } - } - break; - } - default: - return b; - } - - LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; - NotNormalLootItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems(); - NotNormalLootItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID().GetCounter()); - if (q_itr != lootPlayerQuestItems.end()) - { - NotNormalLootItemList* q_list = q_itr->second; - for (NotNormalLootItemList::const_iterator qi = q_list->begin(); qi != q_list->end(); ++qi) - { - LootItem &item = l.quest_items[qi->index]; - if (!qi->is_looted && !item.is_looted) - { - b << uint8(l.items.size() + (qi - q_list->begin())); - b << item; - if (item.follow_loot_rules) - { - switch (lv.permission) - { - case MASTER_PERMISSION: - b << uint8(LOOT_SLOT_TYPE_MASTER); - break; - case RESTRICTED_PERMISSION: - b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); - break; - case GROUP_PERMISSION: - case ROUND_ROBIN_PERMISSION: - if (!item.is_blocked) - b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); - else - b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING); - break; - default: - b << uint8(slotType); - break; - } - } - else - b << uint8(slotType); - ++itemsShown; - } - } - } - - NotNormalLootItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems(); - NotNormalLootItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID().GetCounter()); - if (ffa_itr != lootPlayerFFAItems.end()) - { - NotNormalLootItemList* ffa_list = ffa_itr->second; - for (NotNormalLootItemList::const_iterator fi = ffa_list->begin(); fi != ffa_list->end(); ++fi) - { - LootItem &item = l.items[fi->index]; - if (!fi->is_looted && !item.is_looted) - { - b << uint8(fi->index); - b << item; - b << uint8(slotType); - ++itemsShown; - } - } - } - - NotNormalLootItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems(); - NotNormalLootItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID().GetCounter()); - if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) - { - NotNormalLootItemList* conditional_list = nn_itr->second; - for (NotNormalLootItemList::const_iterator ci = conditional_list->begin(); ci != conditional_list->end(); ++ci) - { - LootItem &item = l.items[ci->index]; - if (!ci->is_looted && !item.is_looted) - { - b << uint8(ci->index); - b << item; - switch (lv.permission) - { - case MASTER_PERMISSION: - b << uint8(LOOT_SLOT_TYPE_MASTER); - break; - case RESTRICTED_PERMISSION: - b << (item.is_blocked ? uint8(LOOT_SLOT_TYPE_LOCKED) : uint8(slotType)); - break; - case GROUP_PERMISSION: - case ROUND_ROBIN_PERMISSION: - if (!item.is_blocked) - b << uint8(LOOT_SLOT_TYPE_ALLOW_LOOT); - else - b << uint8(LOOT_SLOT_TYPE_ROLL_ONGOING); - break; - default: - b << uint8(slotType); - break; - } - ++itemsShown; - } - } - } - - //update number of items shown - b.put<uint8>(count_pos, itemsShown); - - return b; -} - -// // --------- LootTemplate::LootGroup --------- // @@ -1113,7 +399,7 @@ LootStoreItem const* LootTemplate::LootGroup::Roll(Loot& loot, uint16 lootMode) if (!possibleLoot.empty()) // If nothing selected yet - an item is taken from equal-chanced part return Trinity::Containers::SelectRandomContainerElement(possibleLoot); - return NULL; // Empty drop from the group + return nullptr; // Empty drop from the group } // True if group includes at least 1 quest drop entry @@ -1239,7 +525,7 @@ void LootTemplate::AddEntry(LootStoreItem* item) if (item->groupid > 0 && item->reference == 0) // Group { if (item->groupid >= Groups.size()) - Groups.resize(item->groupid, NULL); // Adds new group the the loot template if needed + Groups.resize(item->groupid, nullptr); // Adds new group the the loot template if needed if (!Groups[item->groupid - 1]) Groups[item->groupid - 1] = new LootGroup(); @@ -1249,7 +535,7 @@ void LootTemplate::AddEntry(LootStoreItem* item) Entries.push_back(item); } -void LootTemplate::CopyConditions(const ConditionContainer& conditions) +void LootTemplate::CopyConditions(ConditionContainer const& conditions) { for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i) (*i)->conditions.clear(); @@ -1572,10 +858,9 @@ void LoadLootTemplates_Fishing() uint32 count = LootTemplates_Fishing.LoadAndCollectLootIds(lootIdSet); // remove real entries and check existence loot - for (uint32 i = 1; i < sAreaTableStore.GetNumRows(); ++i) - if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(i)) - if (lootIdSet.find(areaEntry->ID) != lootIdSet.end()) - lootIdSet.erase(areaEntry->ID); + for (AreaTableEntry const* areaTable : sAreaTableStore) + if (lootIdSet.find(areaTable->ID) != lootIdSet.end()) + lootIdSet.erase(areaTable->ID); // output error for any still listed (not referenced from appropriate table) ids LootTemplates_Fishing.ReportUnusedIds(lootIdSet); @@ -1819,9 +1104,7 @@ void LoadLootTemplates_Spell() // not report about not trainable spells (optionally supported by DB) // ignore 61756 (Northrend Inscription Research (FAST QA VERSION) for example if (!spellInfo->HasAttribute(SPELL_ATTR0_NOT_SHAPESHIFT) || spellInfo->HasAttribute(SPELL_ATTR0_TRADESPELL)) - { LootTemplates_Spell.ReportNonExistingId(spell_id, "Spell", spellInfo->Id); - } } else lootIdSet.erase(spell_id); diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 4069d5731b5..6d9d160149f 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -19,108 +19,18 @@ #ifndef TRINITY_LOOTMGR_H #define TRINITY_LOOTMGR_H -#include "ItemEnchantmentMgr.h" -#include "ByteBuffer.h" -#include "RefManager.h" -#include "SharedDefines.h" +#include "Define.h" #include "ConditionMgr.h" #include "ObjectGuid.h" -#include <map> -#include <vector> +#include "SharedDefines.h" #include <list> +#include <vector> -enum RollType -{ - ROLL_PASS = 0, - ROLL_NEED = 1, - ROLL_GREED = 2, - ROLL_DISENCHANT = 3, - MAX_ROLL_TYPE = 4 -}; - -enum RollMask -{ - ROLL_FLAG_TYPE_PASS = 0x01, - ROLL_FLAG_TYPE_NEED = 0x02, - ROLL_FLAG_TYPE_GREED = 0x04, - ROLL_FLAG_TYPE_DISENCHANT = 0x08, - - ROLL_ALL_TYPE_NO_DISENCHANT = 0x07, - ROLL_ALL_TYPE_MASK = 0x0F -}; - -#define MAX_NR_LOOT_ITEMS 16 -// note: the client cannot show more than 16 items total -#define MAX_NR_QUEST_ITEMS 32 -// unrelated to the number of quest items shown, just for reserve - -enum LootMethod : uint8 -{ - FREE_FOR_ALL = 0, - ROUND_ROBIN = 1, - MASTER_LOOT = 2, - GROUP_LOOT = 3, - NEED_BEFORE_GREED = 4 -}; - -enum PermissionTypes -{ - ALL_PERMISSION = 0, - GROUP_PERMISSION = 1, - MASTER_PERMISSION = 2, - RESTRICTED_PERMISSION = 3, - ROUND_ROBIN_PERMISSION = 4, - OWNER_PERMISSION = 5, - NONE_PERMISSION = 6 -}; - -enum LootType : uint8 -{ - LOOT_NONE = 0, - - LOOT_CORPSE = 1, - LOOT_PICKPOCKETING = 2, - LOOT_FISHING = 3, - LOOT_DISENCHANTING = 4, - // ignored always by client - LOOT_SKINNING = 6, - LOOT_PROSPECTING = 7, - LOOT_MILLING = 8, - - LOOT_FISHINGHOLE = 20, // unsupported by client, sending LOOT_FISHING instead - LOOT_INSIGNIA = 21, // unsupported by client, sending LOOT_CORPSE instead - LOOT_FISHING_JUNK = 22 // unsupported by client, sending LOOT_FISHING instead -}; - -enum LootError -{ - LOOT_ERROR_DIDNT_KILL = 0, // You don't have permission to loot that corpse. - LOOT_ERROR_TOO_FAR = 4, // You are too far away to loot that corpse. - LOOT_ERROR_BAD_FACING = 5, // You must be facing the corpse to loot it. - LOOT_ERROR_LOCKED = 6, // Someone is already looting that corpse. - LOOT_ERROR_NOTSTANDING = 8, // You need to be standing up to loot something! - LOOT_ERROR_STUNNED = 9, // You can't loot anything while stunned! - LOOT_ERROR_PLAYER_NOT_FOUND = 10, // Player not found - LOOT_ERROR_PLAY_TIME_EXCEEDED = 11, // Maximum play time exceeded - LOOT_ERROR_MASTER_INV_FULL = 12, // That player's inventory is full - LOOT_ERROR_MASTER_UNIQUE_ITEM = 13, // Player has too many of that item already - LOOT_ERROR_MASTER_OTHER = 14, // Can't assign item to that player - LOOT_ERROR_ALREADY_PICKPOCKETED = 15, // Your target has already had its pockets picked - LOOT_ERROR_NOT_WHILE_SHAPESHIFTED = 16 // You can't do that while shapeshifted. -}; - -// type of Loot Item in Loot View -enum LootSlotType -{ - LOOT_SLOT_TYPE_ALLOW_LOOT = 0, // player can loot the item. - LOOT_SLOT_TYPE_ROLL_ONGOING = 1, // roll is ongoing. player cannot loot. - LOOT_SLOT_TYPE_MASTER = 2, // item can only be distributed by group loot master. - LOOT_SLOT_TYPE_LOCKED = 3, // item is shown in red. player cannot loot. - LOOT_SLOT_TYPE_OWNER = 4 // ignore binding confirmation and etc, for single player looting -}; - -class Player; class LootStore; +class LootTemplate; +class Player; +struct Loot; +struct LootItem; struct TC_GAME_API LootStoreItem { @@ -128,8 +38,8 @@ struct TC_GAME_API LootStoreItem uint32 reference; // referenced TemplateleId float chance; // chance to drop for both quest and non-quest items, chance to be used for refs uint16 lootmode; - bool needs_quest : 1; // quest drop (quest is required for item to drop) - uint8 groupid : 7; + bool needs_quest; // quest drop (quest is required for item to drop) + uint8 groupid; uint8 mincount; // mincount for drop items uint8 maxcount; // max drop count for the item mincount or Ref multiplicator ConditionContainer conditions; // additional loot condition @@ -146,58 +56,6 @@ struct TC_GAME_API LootStoreItem // Checks correctness of values }; -typedef std::set<ObjectGuid::LowType> AllowedLooterSet; - -struct TC_GAME_API LootItem -{ - uint32 itemid; - uint32 randomSuffix; - int32 randomPropertyId; - ConditionContainer conditions; // additional loot condition - AllowedLooterSet allowedGUIDs; - ObjectGuid rollWinnerGUID; // Stores the guid of person who won loot, if his bags are full only he can see the item in loot list! - uint8 count : 8; - bool is_looted : 1; - bool is_blocked : 1; - bool freeforall : 1; // free for all - bool is_underthreshold : 1; - bool is_counted : 1; - bool needs_quest : 1; // quest drop - bool follow_loot_rules : 1; - - // Constructor, copies most fields from LootStoreItem, generates random count and random suffixes/properties - // Should be called for non-reference LootStoreItem entries only (reference = 0) - explicit LootItem(LootStoreItem const& li); - - // Empty constructor for creating an empty LootItem to be filled in with DB data - LootItem() : itemid(0), randomSuffix(0), randomPropertyId(0), count(0), is_looted(false), is_blocked(false), - freeforall(false), is_underthreshold(false), is_counted(false), needs_quest(false), follow_loot_rules(false) - { }; - - // Basic checks for player/item compatibility - if false no chance to see the item in the loot - bool AllowedForPlayer(Player const* player) const; - void AddAllowedLooter(Player const* player); - const AllowedLooterSet & GetAllowedLooters() const { return allowedGUIDs; } -}; - -struct NotNormalLootItem -{ - uint8 index; // position in quest_items or items; - bool is_looted; - - NotNormalLootItem() - : index(0), is_looted(false) { } - - NotNormalLootItem(uint8 _index, bool _islooted = false) - : index(_index), is_looted(_islooted) { } -}; - -struct Loot; -class LootTemplate; - -typedef std::vector<NotNormalLootItem> NotNormalLootItemList; -typedef std::vector<LootItem> LootItemList; -typedef std::map<uint32, NotNormalLootItemList*> NotNormalLootItemMap; typedef std::list<LootStoreItem*> LootStoreItemList; typedef std::unordered_map<uint32, LootTemplate*> LootTemplateMap; @@ -214,9 +72,9 @@ class TC_GAME_API LootStore void Verify() const; uint32 LoadAndCollectLootIds(LootIdSet& ids_set); - void CheckLootRefs(LootIdSet* ref_set = NULL) const; // check existence reference and remove it from ref_set + void CheckLootRefs(LootIdSet* ref_set = nullptr) const; // check existence reference and remove it from ref_set void ReportUnusedIds(LootIdSet const& ids_set) const; - void ReportNonExistingId(uint32 lootId, const char* ownerType, uint32 ownerId) const; + void ReportNonExistingId(uint32 lootId, char const* ownerType, uint32 ownerId) const; bool HaveLootFor(uint32 loot_id) const { return m_LootTemplates.find(loot_id) != m_LootTemplates.end(); } bool HaveQuestLootFor(uint32 loot_id) const; @@ -252,7 +110,7 @@ class TC_GAME_API LootTemplate void AddEntry(LootStoreItem* item); // Rolls for every item in the template and adds the rolled items the the loot void Process(Loot& loot, bool rate, uint16 lootMode, uint8 groupId = 0) const; - void CopyConditions(const ConditionContainer& conditions); + void CopyConditions(ConditionContainer const& conditions); void CopyConditions(LootItem* li) const; // True if template includes at least 1 quest drop entry @@ -277,132 +135,6 @@ class TC_GAME_API LootTemplate //===================================================== -class LootValidatorRef : public Reference<Loot, LootValidatorRef> -{ - public: - LootValidatorRef() { } - void targetObjectDestroyLink() override { } - void sourceObjectDestroyLink() override { } -}; - -//===================================================== - -class LootValidatorRefManager : public RefManager<Loot, LootValidatorRef> -{ - public: - typedef LinkedListHead::Iterator< LootValidatorRef > iterator; - - LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); } - - iterator begin() { return iterator(getFirst()); } - iterator end() { return iterator(nullptr); } -}; - -//===================================================== -struct LootView; - -ByteBuffer& operator<<(ByteBuffer& b, LootItem const& li); -ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); - -struct TC_GAME_API Loot -{ - friend ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv); - - NotNormalLootItemMap const& GetPlayerQuestItems() const { return PlayerQuestItems; } - NotNormalLootItemMap const& GetPlayerFFAItems() const { return PlayerFFAItems; } - NotNormalLootItemMap const& GetPlayerNonQuestNonFFAConditionalItems() const { return PlayerNonQuestNonFFAConditionalItems; } - - std::vector<LootItem> items; - std::vector<LootItem> quest_items; - uint32 gold; - uint8 unlootedCount; - ObjectGuid roundRobinPlayer; // GUID of the player having the Round-Robin ownership for the loot. If 0, round robin owner has released. - LootType loot_type; // required for achievement system - uint8 maxDuplicates; // Max amount of items with the same entry that can drop (default is 1; on 25 man raid mode 3) - - // GUIDLow of container that holds this loot (item_instance.entry) - // Only set for inventory items that can be right-click looted - uint32 containerID; - - Loot(uint32 _gold = 0) : gold(_gold), unlootedCount(0), roundRobinPlayer(), loot_type(LOOT_NONE), maxDuplicates(1), containerID(0) { } - ~Loot() { clear(); } - - // if loot becomes invalid this reference is used to inform the listener - void addLootValidatorRef(LootValidatorRef* pLootValidatorRef) - { - i_LootValidatorRefManager.insertFirst(pLootValidatorRef); - } - - // void clear(); - void clear() - { - for (NotNormalLootItemMap::const_iterator itr = PlayerQuestItems.begin(); itr != PlayerQuestItems.end(); ++itr) - delete itr->second; - PlayerQuestItems.clear(); - - for (NotNormalLootItemMap::const_iterator itr = PlayerFFAItems.begin(); itr != PlayerFFAItems.end(); ++itr) - delete itr->second; - PlayerFFAItems.clear(); - - for (NotNormalLootItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.begin(); itr != PlayerNonQuestNonFFAConditionalItems.end(); ++itr) - delete itr->second; - PlayerNonQuestNonFFAConditionalItems.clear(); - - PlayersLooting.clear(); - items.clear(); - quest_items.clear(); - gold = 0; - unlootedCount = 0; - roundRobinPlayer.Clear(); - loot_type = LOOT_NONE; - i_LootValidatorRefManager.clearReferences(); - } - - bool empty() const { return items.empty() && gold == 0; } - bool isLooted() const { return gold == 0 && unlootedCount == 0; } - - void NotifyItemRemoved(uint8 lootIndex); - void NotifyQuestItemRemoved(uint8 questIndex); - void NotifyMoneyRemoved(); - void AddLooter(ObjectGuid GUID) { PlayersLooting.insert(GUID); } - void RemoveLooter(ObjectGuid GUID) { PlayersLooting.erase(GUID); } - - void generateMoneyLoot(uint32 minAmount, uint32 maxAmount); - bool FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bool personal, bool noEmptyError = false, uint16 lootMode = LOOT_MODE_DEFAULT); - - // Inserts the item into the loot (called by LootTemplate processors) - void AddItem(LootStoreItem const & item); - - LootItem* LootItemInSlot(uint32 lootslot, Player* player, NotNormalLootItem** qitem = NULL, NotNormalLootItem** ffaitem = NULL, NotNormalLootItem** conditem = NULL); - uint32 GetMaxSlotInLootFor(Player* player) const; - bool hasItemForAll() const; - bool hasItemFor(Player* player) const; - bool hasOverThresholdItem() const; - - private: - void FillNotNormalLootFor(Player* player, bool presentAtLooting); - NotNormalLootItemList* FillFFALoot(Player* player); - NotNormalLootItemList* FillQuestLoot(Player* player); - NotNormalLootItemList* FillNonQuestNonFFAConditionalLoot(Player* player, bool presentAtLooting); - - GuidSet PlayersLooting; - NotNormalLootItemMap PlayerQuestItems; - NotNormalLootItemMap PlayerFFAItems; - NotNormalLootItemMap PlayerNonQuestNonFFAConditionalItems; - - // All rolls are registered here. They need to know, when the loot is not valid anymore - LootValidatorRefManager i_LootValidatorRefManager; -}; - -struct LootView -{ - Loot &loot; - Player* viewer; - PermissionTypes permission; - LootView(Loot &_loot, Player* _viewer, PermissionTypes _permission = ALL_PERMISSION) - : loot(_loot), viewer(_viewer), permission(_permission) { } -}; - TC_GAME_API extern LootStore LootTemplates_Creature; TC_GAME_API extern LootStore LootTemplates_Fishing; TC_GAME_API extern LootStore LootTemplates_Gameobject; diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index fe642aae1e6..780b98346ac 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -16,17 +16,19 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "DatabaseEnv.h" #include "Mail.h" -#include "Log.h" -#include "World.h" -#include "ObjectMgr.h" -#include "Player.h" -#include "BattlegroundMgr.h" -#include "Item.h" #include "AuctionHouseMgr.h" +#include "BattlegroundMgr.h" #include "CalendarMgr.h" #include "CharacterCache.h" +#include "DatabaseEnv.h" +#include "Item.h" +#include "Log.h" +#include "LootMgr.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "World.h" MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery(stationery) { @@ -188,7 +190,7 @@ void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, uint32 mailId = sObjectMgr->GenerateMailID(); - time_t deliver_time = time(NULL) + deliver_delay; + time_t deliver_time = time(nullptr) + deliver_delay; //expire time if COD 3 days, if no COD 30 days, if auction sale pending 1 hour uint32 expire_delay; @@ -279,13 +281,13 @@ void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, } else if (!m_items.empty()) { - SQLTransaction temp = SQLTransaction(NULL); + SQLTransaction temp = SQLTransaction(nullptr); deleteIncludedItems(temp); } } else if (!m_items.empty()) { - SQLTransaction temp = SQLTransaction(NULL); + SQLTransaction temp = SQLTransaction(nullptr); deleteIncludedItems(temp); } } diff --git a/src/server/game/Mails/Mail.h b/src/server/game/Mails/Mail.h index a7b46eef570..7a71867958e 100644 --- a/src/server/game/Mails/Mail.h +++ b/src/server/game/Mails/Mail.h @@ -20,6 +20,7 @@ #define TRINITY_MAIL_H #include "Common.h" +#include "DatabaseEnvFwd.h" #include "ObjectGuid.h" #include <map> @@ -104,7 +105,7 @@ class TC_GAME_API MailSender class TC_GAME_API MailReceiver { public: // Constructors - explicit MailReceiver(ObjectGuid::LowType receiver_lowguid) : m_receiver(NULL), m_receiver_lowguid(receiver_lowguid) { } + explicit MailReceiver(ObjectGuid::LowType receiver_lowguid) : m_receiver(nullptr), m_receiver_lowguid(receiver_lowguid) { } MailReceiver(Player* receiver); MailReceiver(Player* receiver, ObjectGuid::LowType receiver_lowguid); public: // Accessors diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 4e9f9e27862..0793422f8ad 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -17,25 +17,31 @@ */ #include "Map.h" -#include "MapManager.h" #include "Battleground.h" -#include "MMapFactory.h" #include "CellImpl.h" +#include "DatabaseEnv.h" #include "DisableMgr.h" #include "DynamicTree.h" +#include "GameObjectModel.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "GridStates.h" #include "Group.h" #include "InstanceScript.h" +#include "Log.h" #include "MapInstanced.h" +#include "MapManager.h" +#include "MMapFactory.h" +#include "MotionMaster.h" #include "ObjectAccessor.h" +#include "ObjectGridLoader.h" #include "ObjectMgr.h" #include "Pet.h" #include "ScriptMgr.h" #include "Transport.h" #include "Vehicle.h" #include "VMapFactory.h" +#include "World.h" u_map_magic MapMagic = { {'M','A','P','S'} }; u_map_magic MapVersionMagic = { {'v','1','.','8'} }; @@ -188,11 +194,11 @@ void Map::LoadMap(int gx, int gy, bool reload) sScriptMgr->OnUnloadGridMap(this, GridMaps[gx][gy], gx, gy); delete (GridMaps[gx][gy]); - GridMaps[gx][gy]=NULL; + GridMaps[gx][gy]=nullptr; } // map file name - char* tmp = NULL; + char* tmp = nullptr; int len = sWorld->GetDataPath().length() + strlen("maps/%03u%02u%02u.map") + 1; tmp = new char[len]; snprintf(tmp, len, (char *)(sWorld->GetDataPath() + "maps/%03u%02u%02u.map").c_str(), GetId(), gx, gy); @@ -255,8 +261,8 @@ i_scriptLock(false), _defaultLight(GetDefaultMapLight(id)) for (unsigned int j=0; j < MAX_NUMBER_OF_GRIDS; ++j) { //z code - GridMaps[idx][j] =NULL; - setNGrid(NULL, idx, j); + GridMaps[idx][j] =nullptr; + setNGrid(nullptr, idx, j); } } @@ -361,7 +367,7 @@ void Map::SwitchGridContainers(Creature* obj, bool on) } NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY()); - ASSERT(ngrid != NULL); + ASSERT(ngrid != nullptr); GridType &grid = ngrid->GetGridType(cell.CellX(), cell.CellY()); @@ -406,7 +412,7 @@ void Map::SwitchGridContainers(GameObject* obj, bool on) } NGridType *ngrid = getNGrid(cell.GridX(), cell.GridY()); - ASSERT(ngrid != NULL); + ASSERT(ngrid != nullptr); GridType &grid = ngrid->GetGridType(cell.CellX(), cell.CellY()); @@ -446,7 +452,7 @@ void Map::DeleteFromWorld(Transport* transport) delete transport; } -void Map::EnsureGridCreated(const GridCoord &p) +void Map::EnsureGridCreated(GridCoord const& p) { std::lock_guard<std::mutex> lock(_gridLock); EnsureGridCreated_i(p); @@ -454,7 +460,7 @@ void Map::EnsureGridCreated(const GridCoord &p) //Create NGrid so the object can be added to it //But object data is not loaded here -void Map::EnsureGridCreated_i(const GridCoord &p) +void Map::EnsureGridCreated_i(GridCoord const& p) { if (!getNGrid(p.x_coord, p.y_coord)) { @@ -478,11 +484,11 @@ void Map::EnsureGridCreated_i(const GridCoord &p) } //Load NGrid and make it active -void Map::EnsureGridLoadedForActiveObject(const Cell &cell, WorldObject* object) +void Map::EnsureGridLoadedForActiveObject(Cell const& cell, WorldObject* object) { EnsureGridLoaded(cell); NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); - ASSERT(grid != NULL); + ASSERT(grid != nullptr); // refresh grid state & timer if (grid->GetGridState() != GRID_STATE_ACTIVE) @@ -494,12 +500,12 @@ void Map::EnsureGridLoadedForActiveObject(const Cell &cell, WorldObject* object) } //Create NGrid and load the object data in it -bool Map::EnsureGridLoaded(const Cell &cell) +bool Map::EnsureGridLoaded(Cell const& cell) { EnsureGridCreated(GridCoord(cell.GridX(), cell.GridY())); NGridType *grid = getNGrid(cell.GridX(), cell.GridY()); - ASSERT(grid != NULL); + ASSERT(grid != nullptr); if (!isGridObjectDataLoaded(cell.GridX(), cell.GridY())) { TC_LOG_DEBUG("maps", "Loading grid[%u, %u] for map %u instance %u", cell.GridX(), cell.GridY(), GetId(), i_InstanceId); @@ -649,7 +655,7 @@ bool Map::AddToMap(Transport* obj) return true; } -bool Map::IsGridLoaded(const GridCoord &p) const +bool Map::IsGridLoaded(GridCoord const& p) const { return (getNGrid(p.x_coord, p.y_coord) && isGridObjectDataLoaded(p.x_coord, p.y_coord)); } @@ -683,7 +689,7 @@ void Map::VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::Obj } } -void Map::Update(const uint32 t_diff) +void Map::Update(uint32 t_diff) { _dynamicTree.update(t_diff); /// update worldsessions for existing players @@ -1593,7 +1599,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) ASSERT(i_objectsToRemove.empty()); delete &ngrid; - setNGrid(NULL, x, y); + setNGrid(nullptr, x, y); } int gx = (MAX_NUMBER_OF_GRIDS - 1) - x; int gy = (MAX_NUMBER_OF_GRIDS - 1) - y; @@ -1614,7 +1620,7 @@ bool Map::UnloadGrid(NGridType& ngrid, bool unloadAll) else ((MapInstanced*)m_parentMap)->RemoveGridMapReference(GridCoord(gx, gy)); - GridMaps[gx][gy] = NULL; + GridMaps[gx][gy] = nullptr; } TC_LOG_DEBUG("maps", "Unloading grid[%u, %u] for map %u finished", x, y, GetId()); return true; @@ -1707,7 +1713,7 @@ GridMap::~GridMap() unloadData(); } -bool GridMap::loadData(const char* filename) +bool GridMap::loadData(char const* filename) { // Unload old data if exist unloadData(); @@ -2319,7 +2325,7 @@ inline GridMap* Map::GetGrid(float x, float y) return GridMaps[gx][gy]; } -float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground /*= NULL*/, bool /*swim = false*/) const +float Map::GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground /*= nullptr*/, bool /*swim = false*/) const { if (const_cast<Map*>(this)->GetGrid(x, y)) { @@ -2800,7 +2806,7 @@ void Map::SendInitSelf(Player* player) WorldPacket packet; data.BuildPacket(&packet); - player->GetSession()->SendPacket(&packet); + player->SendDirectMessage(&packet); } void Map::SendInitTransports(Player* player) @@ -2813,7 +2819,7 @@ void Map::SendInitTransports(Player* player) WorldPacket packet; transData.BuildPacket(&packet); - player->GetSession()->SendPacket(&packet); + player->SendDirectMessage(&packet); } void Map::SendRemoveTransports(Player* player) @@ -2826,7 +2832,7 @@ void Map::SendRemoveTransports(Player* player) WorldPacket packet; transData.BuildPacket(&packet); - player->GetSession()->SendPacket(&packet); + player->SendDirectMessage(&packet); } inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y) @@ -2856,12 +2862,12 @@ void Map::SendObjectUpdates() for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) { iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); + iter->first->SendDirectMessage(&packet); packet.clear(); // clean the string } } -void Map::DelayedUpdate(const uint32 t_diff) +void Map::DelayedUpdate(uint32 t_diff) { for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) { @@ -3001,7 +3007,7 @@ uint32 Map::GetPlayersCountExceptGMs() const void Map::SendToPlayers(WorldPacket* data) const { for (MapRefManager::const_iterator itr = m_mapRefManager.begin(); itr != m_mapRefManager.end(); ++itr) - itr->GetSource()->GetSession()->SendPacket(data); + itr->GetSource()->SendDirectMessage(data); } bool Map::ActiveObjectsNearGrid(NGridType const& ngrid) const @@ -3121,7 +3127,7 @@ template TC_GAME_API void Map::RemoveFromMap(DynamicObject*, bool); InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 SpawnMode, Map* _parent) : Map(id, expiry, InstanceId, SpawnMode, _parent), m_resetAfterUnload(false), m_unloadWhenEmpty(false), - i_data(NULL), i_script_id(0) + i_data(nullptr), i_script_id(0) { //lets initialize visibility distance for dungeons InstanceMap::InitVisibilityDistance(); @@ -3134,7 +3140,7 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw InstanceMap::~InstanceMap() { delete i_data; - i_data = NULL; + i_data = nullptr; } void InstanceMap::InitVisibilityDistance() @@ -3203,7 +3209,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) // increase current instances (hourly limit) if (!group || !group->isLFGGroup()) - player->AddInstanceEnterTime(GetInstanceId(), time(NULL)); + player->AddInstanceEnterTime(GetInstanceId(), time(nullptr)); // get or create an instance save for the map InstanceSave* mapSave = sInstanceSaveMgr->GetInstanceSave(GetInstanceId()); @@ -3264,7 +3270,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) data << uint32(60000); data << uint32(i_data ? i_data->GetCompletedEncounterMask() : 0); data << uint8(0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); player->SetPendingBind(mapSave->GetInstanceId(), 60000); } } @@ -3301,7 +3307,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) return true; } -void InstanceMap::Update(const uint32 t_diff) +void InstanceMap::Update(uint32 t_diff) { Map::Update(t_diff); @@ -3323,7 +3329,7 @@ void InstanceMap::RemovePlayerFromMap(Player* player, bool remove) void InstanceMap::CreateInstanceData(bool load) { - if (i_data != NULL) + if (i_data != nullptr) return; InstanceTemplate const* mInstance = sObjectMgr->GetInstanceTemplate(GetId()); @@ -3414,6 +3420,11 @@ bool InstanceMap::Reset(uint8 method) return m_mapRefManager.isEmpty(); } +std::string const& InstanceMap::GetScriptName() const +{ + return sObjectMgr->GetScriptName(i_script_id); +} + void InstanceMap::PermBindAllPlayers() { if (!IsDungeon()) @@ -3451,7 +3462,7 @@ void InstanceMap::PermBindAllPlayers() player->BindToInstance(save, true); WorldPacket data(SMSG_INSTANCE_SAVE_CREATED, 4); data << uint32(0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); player->GetSession()->SendCalendarRaidLockout(save, true); // if group leader is in instance, group also gets bound @@ -3501,6 +3512,74 @@ MapDifficulty const* Map::GetMapDifficulty() const return GetMapDifficultyData(GetId(), GetDifficulty()); } +uint32 Map::GetId() const +{ + return i_mapEntry->MapID; +} + +bool Map::IsRegularDifficulty() const +{ + return GetDifficulty() == REGULAR_DIFFICULTY; +} + +bool Map::Instanceable() const +{ + return i_mapEntry && i_mapEntry->Instanceable(); +} + +bool Map::IsDungeon() const +{ + return i_mapEntry && i_mapEntry->IsDungeon(); +} + +bool Map::IsNonRaidDungeon() const +{ + return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); +} + +bool Map::IsRaid() const +{ + return i_mapEntry && i_mapEntry->IsRaid(); +} + +bool Map::IsRaidOrHeroicDungeon() const +{ + return IsRaid() || i_spawnMode > DUNGEON_DIFFICULTY_NORMAL; +} + +bool Map::IsHeroic() const +{ + return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; +} + +bool Map::Is25ManRaid() const +{ + // since 25man difficulties are 1 and 3, we can check them like that + return IsRaid() && i_spawnMode & RAID_DIFFICULTY_MASK_25MAN; +} + +bool Map::IsBattleground() const +{ + return i_mapEntry && i_mapEntry->IsBattleground(); +} + +bool Map::IsBattleArena() const +{ + return i_mapEntry && i_mapEntry->IsBattleArena(); +} + +bool Map::IsBattlegroundOrArena() const +{ + return i_mapEntry && i_mapEntry->IsBattlegroundOrArena(); +} + +bool Map::GetEntrancePos(int32& mapid, float& x, float& y) const +{ + if (!i_mapEntry) + return false; + return i_mapEntry->GetEntrancePos(mapid, x, y); +} + bool InstanceMap::HasPermBoundPlayers() const { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PERM_BIND_BY_INSTANCE); @@ -3526,7 +3605,7 @@ uint32 InstanceMap::GetMaxResetDelay() const /* ******* Battleground Instance Maps ******* */ BattlegroundMap::BattlegroundMap(uint32 id, time_t expiry, uint32 InstanceId, Map* _parent, uint8 spawnMode) - : Map(id, expiry, InstanceId, spawnMode, _parent), m_bg(NULL) + : Map(id, expiry, InstanceId, spawnMode, _parent), m_bg(nullptr) { //lets initialize visibility distance for BG/Arenas BattlegroundMap::InitVisibilityDistance(); @@ -3537,8 +3616,8 @@ BattlegroundMap::~BattlegroundMap() if (m_bg) { //unlink to prevent crash, always unlink all pointer reference before destruction - m_bg->SetBgMap(NULL); - m_bg = NULL; + m_bg->SetBgMap(nullptr); + m_bg = nullptr; } } @@ -3627,10 +3706,10 @@ Pet* Map::GetPet(ObjectGuid const& guid) Transport* Map::GetTransport(ObjectGuid const& guid) { if (!guid.IsMOTransport()) - return NULL; + return nullptr; GameObject* go = GetGameObject(guid); - return go ? go->ToTransport() : NULL; + return go ? go->ToTransport() : nullptr; } DynamicObject* Map::GetDynamicObject(ObjectGuid const& guid) @@ -3863,7 +3942,7 @@ Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= corpse->DeleteFromDB(trans); CharacterDatabase.CommitTransaction(trans); - Corpse* bones = NULL; + Corpse* bones = nullptr; // create the bones only if the map and the grid is loaded at the corpse's location // ignore bones creating option in case insignia @@ -4032,10 +4111,14 @@ void Map::UpdateAreaDependentAuras() { Map::PlayerList const& players = GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + { if (Player* player = itr->GetSource()) + { if (player->IsInWorld()) { player->UpdateAreaDependentAuras(player->GetAreaId()); player->UpdateZoneDependentAuras(player->GetZoneId()); } + } + } } diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 1a61e65bade..dd0e43158c1 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -21,7 +21,6 @@ #include "Define.h" -#include "DBCStructure.h" #include "GridDefines.h" #include "Cell.h" #include "Timer.h" @@ -29,31 +28,37 @@ #include "GridRefManager.h" #include "MapRefManager.h" #include "DynamicTree.h" -#include "GameObjectModel.h" #include "ObjectGuid.h" +#include "Optional.h" #include <bitset> #include <list> #include <memory> +#include <mutex> -class Unit; -class WorldPacket; -class InstanceScript; +class Battleground; +class BattlegroundMap; +class CreatureGroup; +class GameObjectModel; class Group; +class InstanceMap; class InstanceSave; +class InstanceScript; +class MapInstanced; class Object; -class WorldObject; -class TempSummon; class Player; -class CreatureGroup; -struct ScriptInfo; -struct ScriptAction; -struct Position; -class Battleground; -class MapInstanced; -class BattlegroundMap; -class InstanceMap; +class TempSummon; class Transport; +class Unit; +class WorldObject; +class WorldPacket; +struct MapDifficulty; +struct MapEntry; +struct Position; +struct ScriptAction; +struct ScriptInfo; +struct SummonPropertiesEntry; +enum Difficulty : uint8; namespace Trinity { struct ObjectUpdater; } namespace VMAP { enum class ModelIgnoreFlags : uint32; } @@ -127,7 +132,7 @@ struct map_liquidHeader float liquidLevel; }; -enum ZLiquidStatus +enum ZLiquidStatus : uint32 { LIQUID_MAP_NO_WATER = 0x00000000, LIQUID_MAP_ABOVE_WATER = 0x00000001, @@ -176,14 +181,6 @@ struct PositionFullTerrainStatus Optional<LiquidData> liquidInfo; }; -enum LineOfSightChecks -{ - LINEOFSIGHT_CHECK_VMAP = 0x1, // check static floor layout data - LINEOFSIGHT_CHECK_GOBJECT = 0x2, // check dynamic game object data - - LINEOFSIGHT_ALL_CHECKS = (LINEOFSIGHT_CHECK_VMAP | LINEOFSIGHT_CHECK_GOBJECT) -}; - class TC_GAME_API GridMap { uint32 _flags; @@ -234,7 +231,7 @@ class TC_GAME_API GridMap public: GridMap(); ~GridMap(); - bool loadData(const char* filename); + bool loadData(char const* filename); void unloadData(); uint16 getArea(float x, float y) const; @@ -247,13 +244,6 @@ public: #pragma pack(push, 1) -struct InstanceTemplate -{ - uint32 Parent; - uint32 ScriptId; - bool AllowMount; -}; - enum LevelRequirementVsMode { LEVELREQUIREMENT_HEROIC = 70 @@ -287,7 +277,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> { friend class MapReference; public: - Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = NULL); + Map(uint32 id, time_t, uint32 InstanceId, uint8 SpawnMode, Map* _parent = nullptr); virtual ~Map(); MapEntry const* GetEntry() const { return i_mapEntry; } @@ -312,7 +302,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> template<class T> void RemoveFromMap(T *, bool); void VisitNearbyCellsOf(WorldObject* obj, TypeContainerVisitor<Trinity::ObjectUpdater, GridTypeMapContainer> &gridVisitor, TypeContainerVisitor<Trinity::ObjectUpdater, WorldTypeMapContainer> &worldVisitor); - virtual void Update(const uint32); + virtual void Update(uint32); float GetVisibilityRange() const { return m_VisibleDistance; } //function for setting up visibility distance for maps on per-type/per-Id basis @@ -324,7 +314,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> void DynamicObjectRelocation(DynamicObject* go, float x, float y, float z, float orientation); template<class T, class CONTAINER> - void Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor); + void Visit(Cell const& cell, TypeContainerVisitor<T, CONTAINER>& visitor); bool IsRemovalGrid(float x, float y) const { @@ -337,8 +327,8 @@ class TC_GAME_API Map : public GridRefManager<NGridType> return IsGridLoaded(Trinity::ComputeGridCoord(x, y)); } - bool GetUnloadLock(const GridCoord &p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); } - void SetUnloadLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); } + bool GetUnloadLock(GridCoord const& p) const { return getNGrid(p.x_coord, p.y_coord)->getUnloadLock(); } + void SetUnloadLock(GridCoord const& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadExplicitLock(on); } void LoadGrid(float x, float y); void LoadAllCells(); bool UnloadGrid(NGridType& ngrid, bool pForce); @@ -350,7 +340,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType> } time_t GetGridExpiry(void) const { return i_gridExpiry; } - uint32 GetId(void) const { return i_mapEntry->MapID; } + uint32 GetId() const; static bool ExistMap(uint32 mapid, int gx, int gy); static bool ExistVMap(uint32 mapid, int gx, int gy); @@ -412,33 +402,28 @@ class TC_GAME_API Map : public GridRefManager<NGridType> CANNOT_ENTER_UNSPECIFIED_REASON }; virtual EnterState CannotEnter(Player* /*player*/) { return CAN_ENTER; } - const char* GetMapName() const; + char const* GetMapName() const; // have meaning only for instanced map (that have set real difficulty) Difficulty GetDifficulty() const { return Difficulty(GetSpawnMode()); } - bool IsRegularDifficulty() const { return GetDifficulty() == REGULAR_DIFFICULTY; } + bool IsRegularDifficulty() const; MapDifficulty const* GetMapDifficulty() const; - bool Instanceable() const { return i_mapEntry && i_mapEntry->Instanceable(); } - bool IsDungeon() const { return i_mapEntry && i_mapEntry->IsDungeon(); } - bool IsNonRaidDungeon() const { return i_mapEntry && i_mapEntry->IsNonRaidDungeon(); } - bool IsRaid() const { return i_mapEntry && i_mapEntry->IsRaid(); } - bool IsRaidOrHeroicDungeon() const { return IsRaid() || i_spawnMode > DUNGEON_DIFFICULTY_NORMAL; } - bool IsHeroic() const { return IsRaid() ? i_spawnMode >= RAID_DIFFICULTY_10MAN_HEROIC : i_spawnMode >= DUNGEON_DIFFICULTY_HEROIC; } - bool Is25ManRaid() const { return IsRaid() && i_spawnMode & RAID_DIFFICULTY_MASK_25MAN; } // since 25man difficulties are 1 and 3, we can check them like that - bool IsBattleground() const { return i_mapEntry && i_mapEntry->IsBattleground(); } - bool IsBattleArena() const { return i_mapEntry && i_mapEntry->IsBattleArena(); } - bool IsBattlegroundOrArena() const { return i_mapEntry && i_mapEntry->IsBattlegroundOrArena(); } - bool GetEntrancePos(int32 &mapid, float &x, float &y) - { - if (!i_mapEntry) - return false; - return i_mapEntry->GetEntrancePos(mapid, x, y); - } + bool Instanceable() const; + bool IsDungeon() const; + bool IsNonRaidDungeon() const; + bool IsRaid() const; + bool IsRaidOrHeroicDungeon() const; + bool IsHeroic() const; + bool Is25ManRaid() const; + bool IsBattleground() const; + bool IsBattleArena() const; + bool IsBattlegroundOrArena() const; + bool GetEntrancePos(int32& mapid, float& x, float& y) const; void AddObjectToRemoveList(WorldObject* obj); void AddObjectToSwitchList(WorldObject* obj, bool on); - virtual void DelayedUpdate(const uint32 diff); + virtual void DelayedUpdate(uint32 diff); void resetMarkedCells() { marked_cells.reset(); } bool isCellMarked(uint32 pCellId) { return marked_cells.test(pCellId); } @@ -509,22 +494,22 @@ class TC_GAME_API Map : public GridRefManager<NGridType> return nullptr; } - MapInstanced* ToMapInstanced() { if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); return NULL; } - MapInstanced const* ToMapInstanced() const { if (Instanceable()) return reinterpret_cast<MapInstanced const*>(this); return NULL; } + MapInstanced* ToMapInstanced() { if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); return nullptr; } + MapInstanced const* ToMapInstanced() const { if (Instanceable()) return reinterpret_cast<MapInstanced const*>(this); return nullptr; } - InstanceMap* ToInstanceMap() { if (IsDungeon()) return reinterpret_cast<InstanceMap*>(this); else return NULL; } - InstanceMap const* ToInstanceMap() const { if (IsDungeon()) return reinterpret_cast<InstanceMap const*>(this); return NULL; } + InstanceMap* ToInstanceMap() { if (IsDungeon()) return reinterpret_cast<InstanceMap*>(this); else return nullptr; } + InstanceMap const* ToInstanceMap() const { if (IsDungeon()) return reinterpret_cast<InstanceMap const*>(this); return nullptr; } - BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return NULL; } - BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return NULL; } + BattlegroundMap* ToBattlegroundMap() { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap*>(this); else return nullptr; } + BattlegroundMap const* ToBattlegroundMap() const { if (IsBattlegroundOrArena()) return reinterpret_cast<BattlegroundMap const*>(this); return nullptr; } - float GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground = NULL, bool swim = false) const; + float GetWaterOrGroundLevel(uint32 phasemask, float x, float y, float z, float* ground = nullptr, bool swim = false) const; float GetHeight(uint32 phasemask, float x, float y, float z, bool vmap = true, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const; bool isInLineOfSight(float x1, float y1, float z1, float x2, float y2, float z2, uint32 phasemask, LineOfSightChecks checks, VMAP::ModelIgnoreFlags ignoreFlags) const; void Balance() { _dynamicTree.balance(); } - void RemoveGameObjectModel(const GameObjectModel& model) { _dynamicTree.remove(model); } - void InsertGameObjectModel(const GameObjectModel& model) { _dynamicTree.insert(model); } - bool ContainsGameObjectModel(const GameObjectModel& model) const { return _dynamicTree.contains(model);} + void RemoveGameObjectModel(GameObjectModel const& model) { _dynamicTree.remove(model); } + void InsertGameObjectModel(GameObjectModel const& model) { _dynamicTree.insert(model); } + bool ContainsGameObjectModel(GameObjectModel const& model) const { return _dynamicTree.contains(model);} float GetGameObjectFloor(uint32 phasemask, float x, float y, float z, float maxSearchDist = DEFAULT_HEIGHT_SEARCH) const { return _dynamicTree.getHeight(x, y, z, maxSearchDist, phasemask); @@ -636,9 +621,9 @@ class TC_GAME_API Map : public GridRefManager<NGridType> bool _dynamicObjectsToMoveLock; std::vector<DynamicObject*> _dynamicObjectsToMove; - bool IsGridLoaded(const GridCoord &) const; - void EnsureGridCreated(const GridCoord &); - void EnsureGridCreated_i(const GridCoord &); + bool IsGridLoaded(GridCoord const&) const; + void EnsureGridCreated(GridCoord const&); + void EnsureGridCreated_i(GridCoord const&); bool EnsureGridLoaded(Cell const&); void EnsureGridLoadedForActiveObject(Cell const&, WorldObject* object); @@ -656,12 +641,10 @@ class TC_GAME_API Map : public GridRefManager<NGridType> void setNGrid(NGridType* grid, uint32 x, uint32 y); void ScriptsProcess(); - void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff); - void SendObjectUpdates(); protected: - void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } + void SetUnloadReferenceLock(GridCoord const& p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } std::mutex _mapLock; std::mutex _gridLock; @@ -688,13 +671,13 @@ class TC_GAME_API Map : public GridRefManager<NGridType> TransportsContainer::iterator _transportsUpdateIter; private: - Player* _GetScriptPlayerSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo) const; - Creature* _GetScriptCreatureSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo, bool bReverse = false) const; - Unit* _GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const; - Player* _GetScriptPlayer(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const; - Creature* _GetScriptCreature(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const; - WorldObject* _GetScriptWorldObject(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const; - void _ScriptProcessDoor(Object* source, Object* target, const ScriptInfo* scriptInfo) const; + Player* _GetScriptPlayerSourceOrTarget(Object* source, Object* target, ScriptInfo const* scriptInfo) const; + Creature* _GetScriptCreatureSourceOrTarget(Object* source, Object* target, ScriptInfo const* scriptInfo, bool bReverse = false) const; + Unit* _GetScriptUnit(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const; + Player* _GetScriptPlayer(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const; + Creature* _GetScriptCreature(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const; + WorldObject* _GetScriptWorldObject(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const; + void _ScriptProcessDoor(Object* source, Object* target, ScriptInfo const* scriptInfo) const; GameObject* _FindGameObject(WorldObject* pWorldObject, ObjectGuid::LowType guid) const; time_t i_gridExpiry; @@ -791,10 +774,11 @@ class TC_GAME_API InstanceMap : public Map ~InstanceMap(); bool AddPlayerToMap(Player*) override; void RemovePlayerFromMap(Player*, bool) override; - void Update(const uint32) override; + void Update(uint32) override; void CreateInstanceData(bool load); bool Reset(uint8 method); uint32 GetScriptId() const { return i_script_id; } + std::string const& GetScriptName() const; InstanceScript* GetInstanceScript() { return i_data; } InstanceScript const* GetInstanceScript() const { return i_data; } void PermBindAllPlayers(); diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index d54e758e581..4b8863889a1 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -17,15 +17,17 @@ */ #include "MapInstanced.h" -#include "ObjectMgr.h" -#include "MapManager.h" #include "Battleground.h" -#include "VMapFactory.h" -#include "MMapFactory.h" -#include "InstanceSaveMgr.h" -#include "World.h" +#include "DBCStores.h" #include "Group.h" +#include "InstanceSaveMgr.h" +#include "Log.h" +#include "MapManager.h" +#include "MMapFactory.h" +#include "ObjectMgr.h" #include "Player.h" +#include "VMapFactory.h" +#include "World.h" MapInstanced::MapInstanced(uint32 id, time_t expiry) : Map(id, expiry, 0, DUNGEON_DIFFICULTY_NORMAL) { @@ -44,7 +46,7 @@ void MapInstanced::InitVisibilityDistance() } } -void MapInstanced::Update(const uint32 t) +void MapInstanced::Update(uint32 t) { // take care of loaded GridMaps (when unused, unload it!) Map::Update(t); @@ -73,7 +75,7 @@ void MapInstanced::Update(const uint32 t) } } -void MapInstanced::DelayedUpdate(const uint32 diff) +void MapInstanced::DelayedUpdate(uint32 diff) { for (InstancedMaps::iterator i = m_InstancedMaps.begin(); i != m_InstancedMaps.end(); ++i) i->second->DelayedUpdate(diff); @@ -110,7 +112,7 @@ void MapInstanced::UnloadAll() - create the instance if it's not created already - the player is not actually added to the instance (only in InstanceMap::Add) */ -Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player, uint32 loginInstanceId) +Map* MapInstanced::CreateInstanceForPlayer(uint32 mapId, Player* player, uint32 loginInstanceId /*= 0*/) { if (GetId() != mapId || !player) return nullptr; @@ -190,7 +192,7 @@ Map* MapInstanced::CreateInstanceForPlayer(const uint32 mapId, Player* player, u //ASSERT(!FindInstanceMap(NewInstanceId)); map = FindInstanceMap(newInstanceId); if (!map) - map = CreateInstance(newInstanceId, NULL, diff); + map = CreateInstance(newInstanceId, nullptr, diff); } } @@ -203,13 +205,13 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, std::lock_guard<std::mutex> lock(_mapLock); // make sure we have a valid map id - const MapEntry* entry = sMapStore.LookupEntry(GetId()); + MapEntry const* entry = sMapStore.LookupEntry(GetId()); if (!entry) { TC_LOG_ERROR("maps", "CreateInstance: no entry for map %d", GetId()); ABORT(); } - const InstanceTemplate* iTemplate = sObjectMgr->GetInstanceTemplate(GetId()); + InstanceTemplate const* iTemplate = sObjectMgr->GetInstanceTemplate(GetId()); if (!iTemplate) { TC_LOG_ERROR("maps", "CreateInstance: no instance template for map %d", GetId()); @@ -227,7 +229,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, map->LoadRespawnTimes(); map->LoadCorpseData(); - bool load_data = save != NULL; + bool load_data = save != nullptr; map->CreateInstanceData(load_data); if (sWorld->getBoolConfig(CONFIG_INSTANCEMAP_LOAD_GRIDS)) diff --git a/src/server/game/Maps/MapInstanced.h b/src/server/game/Maps/MapInstanced.h index 2394aa2035a..7f4184fca3b 100644 --- a/src/server/game/Maps/MapInstanced.h +++ b/src/server/game/Maps/MapInstanced.h @@ -33,13 +33,13 @@ class TC_GAME_API MapInstanced : public Map ~MapInstanced() { } // functions overwrite Map versions - void Update(const uint32) override; - void DelayedUpdate(const uint32 diff) override; + void Update(uint32 diff) override; + void DelayedUpdate(uint32 diff) override; //void RelocationNotify(); void UnloadAll() override; EnterState CannotEnter(Player* /*player*/) override; - Map* CreateInstanceForPlayer(const uint32 mapId, Player* player, uint32 loginInstanceId=0); + Map* CreateInstanceForPlayer(uint32 mapId, Player* player, uint32 loginInstanceId = 0); Map* FindInstanceMap(uint32 instanceId) const { InstancedMaps::const_iterator i = m_InstancedMaps.find(instanceId); @@ -47,7 +47,7 @@ class TC_GAME_API MapInstanced : public Map } bool DestroyInstance(InstancedMaps::iterator &itr); - void AddGridMapReference(const GridCoord &p) + void AddGridMapReference(GridCoord const& p) { ++GridMapReference[p.x_coord][p.y_coord]; SetUnloadReferenceLock(GridCoord((MAX_NUMBER_OF_GRIDS - 1) - p.x_coord, (MAX_NUMBER_OF_GRIDS - 1) - p.y_coord), true); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index a0317013d3e..8026f944c2a 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -57,7 +57,7 @@ void MapManager::Initialize() void MapManager::InitializeVisibilityDistanceInfo() { - for (MapMapType::iterator iter=i_maps.begin(); iter != i_maps.end(); ++iter) + for (MapMapType::iterator iter = i_maps.begin(); iter != i_maps.end(); ++iter) (*iter).second->InitVisibilityDistance(); } @@ -71,7 +71,7 @@ Map* MapManager::CreateBaseMap(uint32 id) { Map* map = FindBaseMap(id); - if (map == NULL) + if (map == nullptr) { std::lock_guard<std::mutex> lock(_mapsLock); @@ -98,7 +98,7 @@ Map* MapManager::FindBaseNonInstanceMap(uint32 mapId) const { Map* map = FindBaseMap(mapId); if (map && map->Instanceable()) - return NULL; + return nullptr; return map; } @@ -116,10 +116,10 @@ Map* MapManager::FindMap(uint32 mapid, uint32 instanceId) const { Map* map = FindBaseMap(mapid); if (!map) - return NULL; + return nullptr; if (!map->Instanceable()) - return instanceId == 0 ? map : NULL; + return instanceId == 0 ? map : nullptr; return ((MapInstanced*)map)->FindInstanceMap(instanceId); } diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index 0882efd1e31..e628a7030ae 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -75,7 +75,7 @@ class TC_GAME_API MapManager i_timer.Reset(); } - //void LoadGrid(int mapid, int instId, float x, float y, const WorldObject* obj, bool no_unload = false); + //void LoadGrid(int mapid, int instId, float x, float y, WorldObject const* obj, bool no_unload = false); void UnloadAll(); static bool ExistMapAndVMap(uint32 mapid, float x, float y); @@ -139,11 +139,11 @@ class TC_GAME_API MapManager Map* FindBaseMap(uint32 mapId) const { MapMapType::const_iterator iter = i_maps.find(mapId); - return (iter == i_maps.end() ? NULL : iter->second); + return (iter == i_maps.end() ? nullptr : iter->second); } - MapManager(const MapManager &); - MapManager& operator=(const MapManager &); + MapManager(MapManager const&) = delete; + MapManager& operator=(MapManager const&) = delete; std::mutex _mapsLock; uint32 i_gridCleanUpDelay; diff --git a/src/server/game/Maps/MapObject.h b/src/server/game/Maps/MapObject.h new file mode 100644 index 00000000000..22e920994c8 --- /dev/null +++ b/src/server/game/Maps/MapObject.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef MapObject_h__ +#define MapObject_h__ + +#include "Define.h" +#include "Cell.h" +#include "Position.h" + +class Map; +class ObjectGridLoader; + +enum MapObjectCellMoveState +{ + MAP_OBJECT_CELL_MOVE_NONE, //not in move list + MAP_OBJECT_CELL_MOVE_ACTIVE, //in move list + MAP_OBJECT_CELL_MOVE_INACTIVE, //in move list but should not move +}; + +class TC_GAME_API MapObject +{ + friend class Map; //map for moving creatures + friend class ObjectGridLoader; //grid loader for loading creatures + +protected: + MapObject() : _moveState(MAP_OBJECT_CELL_MOVE_NONE) + { + _newPosition.Relocate(0.0f, 0.0f, 0.0f, 0.0f); + } + +private: + Cell _currentCell; + Cell const& GetCurrentCell() const { return _currentCell; } + void SetCurrentCell(Cell const& cell) { _currentCell = cell; } + + MapObjectCellMoveState _moveState; + Position _newPosition; + void SetNewCellPosition(float x, float y, float z, float o) + { + _moveState = MAP_OBJECT_CELL_MOVE_ACTIVE; + _newPosition.Relocate(x, y, z, o); + } +}; + +#endif // MapObject_h__ diff --git a/src/server/game/Maps/MapReference.cpp b/src/server/game/Maps/MapReference.cpp new file mode 100644 index 00000000000..ca8169129e2 --- /dev/null +++ b/src/server/game/Maps/MapReference.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "MapReference.h" +#include "Map.h" + +void MapReference::targetObjectBuildLink() +{ + // called from link() + getTarget()->m_mapRefManager.insertFirst(this); + getTarget()->m_mapRefManager.incSize(); +} + +void MapReference::targetObjectDestroyLink() +{ + // called from unlink() + if (isValid()) + getTarget()->m_mapRefManager.decSize(); +} + +void MapReference::sourceObjectDestroyLink() +{ + // called from invalidate() + getTarget()->m_mapRefManager.decSize(); +} diff --git a/src/server/game/Maps/MapReference.h b/src/server/game/Maps/MapReference.h index 11a97b6f44b..73b0635390e 100644 --- a/src/server/game/Maps/MapReference.h +++ b/src/server/game/Maps/MapReference.h @@ -20,27 +20,16 @@ #define _MAPREFERENCE_H #include "Reference.h" -#include "Map.h" + +class Map; +class Player; class MapReference : public Reference<Map, Player> { protected: - void targetObjectBuildLink() override - { - // called from link() - getTarget()->m_mapRefManager.insertFirst(this); - getTarget()->m_mapRefManager.incSize(); - } - void targetObjectDestroyLink() override - { - // called from unlink() - if (isValid()) getTarget()->m_mapRefManager.decSize(); - } - void sourceObjectDestroyLink() override - { - // called from invalidate() - getTarget()->m_mapRefManager.decSize(); - } + void targetObjectBuildLink() override; + void targetObjectDestroyLink() override; + void sourceObjectDestroyLink() override; public: MapReference() : Reference<Map, Player>() { } ~MapReference() { unlink(); } diff --git a/src/server/game/Maps/MapScripts.cpp b/src/server/game/Maps/MapScripts.cpp index f5c8cd971b9..e365a54c594 100644 --- a/src/server/game/Maps/MapScripts.cpp +++ b/src/server/game/Maps/MapScripts.cpp @@ -16,17 +16,17 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Map.h" #include "CellImpl.h" #include "GameTime.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" #include "GossipDef.h" -#include "Map.h" +#include "GridNotifiers.h" +#include "Item.h" +#include "Log.h" #include "MapManager.h" +#include "MotionMaster.h" #include "ObjectMgr.h" #include "Pet.h" -#include "Item.h" -#include "ScriptedCreature.h" #include "ScriptMgr.h" #include "Transport.h" #include "WaypointManager.h" @@ -100,9 +100,9 @@ void Map::ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* sou } // Helpers for ScriptProcess method. -inline Player* Map::_GetScriptPlayerSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo) const +inline Player* Map::_GetScriptPlayerSourceOrTarget(Object* source, Object* target, ScriptInfo const* scriptInfo) const { - Player* player = NULL; + Player* player = nullptr; if (!source && !target) TC_LOG_ERROR("scripts", "%s source and target objects are NULL.", scriptInfo->GetDebugInfo().c_str()); else @@ -122,9 +122,9 @@ inline Player* Map::_GetScriptPlayerSourceOrTarget(Object* source, Object* targe return player; } -inline Creature* Map::_GetScriptCreatureSourceOrTarget(Object* source, Object* target, const ScriptInfo* scriptInfo, bool bReverse) const +inline Creature* Map::_GetScriptCreatureSourceOrTarget(Object* source, Object* target, ScriptInfo const* scriptInfo, bool bReverse) const { - Creature* creature = NULL; + Creature* creature = nullptr; if (!source && !target) TC_LOG_ERROR("scripts", "%s source and target objects are NULL.", scriptInfo->GetDebugInfo().c_str()); else @@ -155,9 +155,9 @@ inline Creature* Map::_GetScriptCreatureSourceOrTarget(Object* source, Object* t return creature; } -inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const +inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const { - Unit* unit = NULL; + Unit* unit = nullptr; if (!obj) TC_LOG_ERROR("scripts", "%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target"); else if (!obj->isType(TYPEMASK_UNIT)) @@ -173,9 +173,9 @@ inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* s return unit; } -inline Player* Map::_GetScriptPlayer(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const +inline Player* Map::_GetScriptPlayer(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const { - Player* player = NULL; + Player* player = nullptr; if (!obj) TC_LOG_ERROR("scripts", "%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target"); else @@ -188,9 +188,9 @@ inline Player* Map::_GetScriptPlayer(Object* obj, bool isSource, const ScriptInf return player; } -inline Creature* Map::_GetScriptCreature(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const +inline Creature* Map::_GetScriptCreature(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const { - Creature* creature = NULL; + Creature* creature = nullptr; if (!obj) TC_LOG_ERROR("scripts", "%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target"); else @@ -203,9 +203,9 @@ inline Creature* Map::_GetScriptCreature(Object* obj, bool isSource, const Scrip return creature; } -inline WorldObject* Map::_GetScriptWorldObject(Object* obj, bool isSource, const ScriptInfo* scriptInfo) const +inline WorldObject* Map::_GetScriptWorldObject(Object* obj, bool isSource, ScriptInfo const* scriptInfo) const { - WorldObject* pWorldObject = NULL; + WorldObject* pWorldObject = nullptr; if (!obj) TC_LOG_ERROR("scripts", "%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target"); @@ -219,7 +219,7 @@ inline WorldObject* Map::_GetScriptWorldObject(Object* obj, bool isSource, const return pWorldObject; } -inline void Map::_ScriptProcessDoor(Object* source, Object* target, const ScriptInfo* scriptInfo) const +inline void Map::_ScriptProcessDoor(Object* source, Object* target, ScriptInfo const* scriptInfo) const { bool bOpen = false; ObjectGuid::LowType guid = scriptInfo->ToggleDoor.GOGuid; @@ -290,7 +290,7 @@ void Map::ScriptsProcess() { ScriptAction const& step = iter->second; - Object* source = NULL; + Object* source = nullptr; if (step.sourceGUID) { switch (step.sourceGUID.GetHigh()) @@ -326,7 +326,7 @@ void Map::ScriptsProcess() } } - WorldObject* target = NULL; + WorldObject* target = nullptr; if (step.targetGUID) { switch (step.targetGUID.GetHigh()) @@ -669,30 +669,30 @@ void Map::ScriptsProcess() break; } - Unit* uSource = NULL; - Unit* uTarget = NULL; + Unit* uSource = nullptr; + Unit* uTarget = nullptr; // source/target cast spell at target/source (script->datalong2: 0: s->t 1: s->s 2: t->t 3: t->s switch (step.script->CastSpell.Flags) { case SF_CASTSPELL_SOURCE_TO_TARGET: // source -> target - uSource = source ? source->ToUnit() : NULL; - uTarget = target ? target->ToUnit() : NULL; + uSource = source ? source->ToUnit() : nullptr; + uTarget = target ? target->ToUnit() : nullptr; break; case SF_CASTSPELL_SOURCE_TO_SOURCE: // source -> source - uSource = source ? source->ToUnit() : NULL; + uSource = source ? source->ToUnit() : nullptr; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_TARGET: // target -> target - uSource = target ? target->ToUnit() : NULL; + uSource = target ? target->ToUnit() : nullptr; uTarget = uSource; break; case SF_CASTSPELL_TARGET_TO_SOURCE: // target -> source - uSource = target ? target->ToUnit() : NULL; - uTarget = source ? source->ToUnit() : NULL; + uSource = target ? target->ToUnit() : nullptr; + uTarget = source ? source->ToUnit() : nullptr; break; case SF_CASTSPELL_SEARCH_CREATURE: // source -> creature with entry - uSource = source ? source->ToUnit() : NULL; - uTarget = uSource ? GetClosestCreatureWithEntry(uSource, abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : NULL; + uSource = source ? source->ToUnit() : nullptr; + uTarget = uSource ? uSource->FindNearestCreature(abs(step.script->CastSpell.CreatureEntry), step.script->CastSpell.SearchRadius) : nullptr; break; } @@ -720,7 +720,7 @@ void Map::ScriptsProcess() if (WorldObject* object = _GetScriptWorldObject(source, true, step.script)) { // PlaySound.Flags bitmask: 0/1=anyone/target - Player* player = NULL; + Player* player = nullptr; if (step.script->PlaySound.Flags & SF_PLAYSOUND_TARGET_PLAYER) { // Target must be Player. @@ -749,7 +749,7 @@ void Map::ScriptsProcess() pReceiver->SendNewItem(item, step.script->CreateItem.Amount, false, true); } else - pReceiver->SendEquipError(msg, NULL, NULL, step.script->CreateItem.ItemEntry); + pReceiver->SendEquipError(msg, nullptr, nullptr, step.script->CreateItem.ItemEntry); } break; @@ -783,7 +783,7 @@ void Map::ScriptsProcess() break; } - Creature* cTarget = NULL; + Creature* cTarget = nullptr; auto creatureBounds = _creatureBySpawnIdStore.equal_range(step.script->CallScript.CreatureEntry); if (creatureBounds.first != creatureBounds.second) { @@ -811,7 +811,7 @@ void Map::ScriptsProcess() } // Insert script into schedule but do not start it - ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, NULL); + ScriptsStart(*datamap, step.script->CallScript.ScriptID, cTarget, nullptr); break; } diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index 3eb09166ac9..b6bcfde3723 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -16,20 +16,18 @@ */ #include "TransportMgr.h" -#include "Transport.h" +#include "DatabaseEnv.h" #include "InstanceScript.h" -#include "MoveSpline.h" +#include "Log.h" #include "MapManager.h" +#include "MoveSplineInitArgs.h" +#include "ObjectAccessor.h" +#include "ObjectMgr.h" +#include "Spline.h" +#include "Transport.h" TransportTemplate::~TransportTemplate() { - // Collect shared pointers into a set to avoid deleting the same memory more than once - std::set<TransportSpline*> splines; - for (size_t i = 0; i < keyFrames.size(); ++i) - splines.insert(keyFrames[i].Spline); - - for (std::set<TransportSpline*>::iterator itr = splines.begin(); itr != splines.end(); ++itr) - delete *itr; } TransportMgr::TransportMgr() { } @@ -66,7 +64,7 @@ void TransportMgr::LoadTransportTemplates() Field* fields = result->Fetch(); uint32 entry = fields[0].GetUInt32(); GameObjectTemplate const* goInfo = sObjectMgr->GetGameObjectTemplate(entry); - if (goInfo == NULL) + if (goInfo == nullptr) { TC_LOG_ERROR("sql.sql", "Transport %u has no associated GameObjectTemplate from `gameobject_template` , skipped.", entry); continue; @@ -93,6 +91,17 @@ void TransportMgr::LoadTransportTemplates() TC_LOG_INFO("server.loading", ">> Loaded %u transport templates in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); } +void TransportMgr::LoadTransportAnimationAndRotation() +{ + for (uint32 i = 0; i < sTransportAnimationStore.GetNumRows(); ++i) + if (TransportAnimationEntry const* anim = sTransportAnimationStore.LookupEntry(i)) + AddPathNodeToTransport(anim->TransportEntry, anim->TimeSeg, anim); + + for (uint32 i = 0; i < sTransportRotationStore.GetNumRows(); ++i) + if (TransportRotationEntry const* rot = sTransportRotationStore.LookupEntry(i)) + AddPathRotationToTransport(rot->TransportEntry, rot->TimeSeg, rot); +} + class SplineRawInitializer { public: @@ -213,7 +222,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl if (keyFrames[i - 1].Teleport || i + 1 == keyFrames.size()) { size_t extra = !keyFrames[i - 1].Teleport ? 1 : 0; - TransportSpline* spline = new TransportSpline(); + std::shared_ptr<TransportSpline> spline = std::make_shared<TransportSpline>(); spline->init_spline(&splinePath[start], i - start + extra, Movement::SplineBase::ModeCatmullrom); spline->initLengths(); for (size_t j = start; j < i + extra; ++j) @@ -354,7 +363,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, animNode.Path[timeSeg] = node; } -Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= NULL*/) +Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid /*= 0*/, Map* map /*= nullptr*/) { // instance case, execute GetGameObjectEntry hook if (map) @@ -365,14 +374,14 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid entry = instance->GetGameObjectEntry(0, entry); if (!entry) - return NULL; + return nullptr; } TransportTemplate const* tInfo = GetTransportTemplate(entry); if (!tInfo) { TC_LOG_ERROR("sql.sql", "Transport %u will not be loaded, `transport_template` missing", entry); - return NULL; + return nullptr; } // create transport... @@ -392,7 +401,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid if (!trans->Create(guidLow, entry, mapId, x, y, z, o, 255)) { delete trans; - return NULL; + return nullptr; } if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId)) @@ -401,12 +410,12 @@ Transport* TransportMgr::CreateTransport(uint32 entry, ObjectGuid::LowType guid { TC_LOG_ERROR("entities.transport", "Transport %u (name: %s) attempted creation in instance map (id: %u) but it is not an instanced transport!", entry, trans->GetName().c_str(), mapId); delete trans; - return NULL; + return nullptr; } } // use preset map for instances (need to know which instance) - trans->SetMap(map ? map : sMapMgr->CreateMap(mapId, NULL)); + trans->SetMap(map ? map : sMapMgr->CreateMap(mapId, nullptr)); if (map && map->IsDungeon()) trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript(); @@ -460,30 +469,18 @@ void TransportMgr::CreateInstanceTransports(Map* map) TransportAnimationEntry const* TransportAnimation::GetAnimNode(uint32 time) const { - if (Path.empty()) - return NULL; - - for (TransportPathContainer::const_reverse_iterator itr2 = Path.rbegin(); itr2 != Path.rend(); ++itr2) - if (time >= itr2->first) - return itr2->second; + auto itr = Path.lower_bound(time); + if (itr != Path.end()) + return itr->second; - return Path.begin()->second; + return nullptr; } -G3D::Quat TransportAnimation::GetAnimRotation(uint32 time) const +TransportRotationEntry const* TransportAnimation::GetAnimRotation(uint32 time) const { - if (Rotations.empty()) - return G3D::Quat(0.0f, 0.0f, 0.0f, 1.0f); - - TransportRotationEntry const* rot = Rotations.begin()->second; - for (TransportPathRotationContainer::const_reverse_iterator itr2 = Rotations.rbegin(); itr2 != Rotations.rend(); ++itr2) - { - if (time >= itr2->first) - { - rot = itr2->second; - break; - } - } + auto itr = Rotations.lower_bound(time); + if (itr != Rotations.end()) + return itr->second; - return G3D::Quat(rot->X, rot->Y, rot->Z, rot->W); + return nullptr; } diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index abb86572766..86a38b3303a 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -18,10 +18,9 @@ #ifndef TRANSPORTMGR_H #define TRANSPORTMGR_H -#include <G3D/Quat.h> -#include "Spline.h" #include "DBCStores.h" #include "ObjectGuid.h" +#include <memory> struct KeyFrame; struct GameObjectTemplate; @@ -29,6 +28,11 @@ struct TransportTemplate; class Transport; class Map; +namespace Movement +{ + template <typename length_type> class Spline; +} + typedef Movement::Spline<double> TransportSpline; typedef std::vector<KeyFrame> KeyFrameVec; typedef std::unordered_map<uint32, TransportTemplate> TransportTemplates; @@ -40,7 +44,7 @@ struct KeyFrame { explicit KeyFrame(TaxiPathNodeEntry const* node) : Index(0), Node(node), InitialOrientation(0.0f), DistSinceStop(-1.0f), DistUntilStop(-1.0f), DistFromPrev(-1.0f), TimeFrom(0.0f), TimeTo(0.0f), - Teleport(false), ArriveTime(0), DepartureTime(0), Spline(NULL), NextDistFromPrev(0.0f), NextArriveTime(0) + Teleport(false), ArriveTime(0), DepartureTime(0), Spline(nullptr), NextDistFromPrev(0.0f), NextArriveTime(0) { } @@ -55,7 +59,7 @@ struct KeyFrame bool Teleport; uint32 ArriveTime; uint32 DepartureTime; - TransportSpline* Spline; + std::shared_ptr<TransportSpline> Spline; // Data needed for next frame float NextDistFromPrev; @@ -91,15 +95,13 @@ struct TC_GAME_API TransportAnimation uint32 TotalTime; TransportAnimationEntry const* GetAnimNode(uint32 time) const; - G3D::Quat GetAnimRotation(uint32 time) const; + TransportRotationEntry const* GetAnimRotation(uint32 time) const; }; typedef std::map<uint32, TransportAnimation> TransportAnimationContainer; class TC_GAME_API TransportMgr { - friend TC_GAME_API void LoadDBCStores(std::string const&); - public: static TransportMgr* instance(); @@ -107,8 +109,10 @@ class TC_GAME_API TransportMgr void LoadTransportTemplates(); + void LoadTransportAnimationAndRotation(); + // Creates a transport using given GameObject template entry - Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = NULL); + Transport* CreateTransport(uint32 entry, ObjectGuid::LowType guid = 0, Map* map = nullptr); // Spawns all continent transports, used at core startup void SpawnContinentTransports(); @@ -121,7 +125,7 @@ class TC_GAME_API TransportMgr TransportTemplates::const_iterator itr = _transportTemplates.find(entry); if (itr != _transportTemplates.end()) return &itr->second; - return NULL; + return nullptr; } TransportAnimation const* GetTransportAnimInfo(uint32 entry) const @@ -130,14 +134,14 @@ class TC_GAME_API TransportMgr if (itr != _transportAnimations.end()) return &itr->second; - return NULL; + return nullptr; } private: TransportMgr(); ~TransportMgr(); - TransportMgr(TransportMgr const&); - TransportMgr& operator=(TransportMgr const&); + TransportMgr(TransportMgr const&) = delete; + TransportMgr& operator=(TransportMgr const&) = delete; // Generates and precaches a path for transport to avoid generation each time transport instance is created void GeneratePath(GameObjectTemplate const* goInfo, TransportTemplate* transport); diff --git a/src/server/game/Maps/ZoneScript.cpp b/src/server/game/Maps/ZoneScript.cpp new file mode 100644 index 00000000000..e16007a34f3 --- /dev/null +++ b/src/server/game/Maps/ZoneScript.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ZoneScript.h" +#include "Creature.h" + +uint32 ZoneScript::GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) +{ + return data->id; +} diff --git a/src/server/game/Maps/ZoneScript.h b/src/server/game/Maps/ZoneScript.h index 75fb56e555c..9c957022bc9 100644 --- a/src/server/game/Maps/ZoneScript.h +++ b/src/server/game/Maps/ZoneScript.h @@ -18,18 +18,22 @@ #ifndef ZONE_SCRIPT_H_ #define ZONE_SCRIPT_H_ -#include "Common.h" -#include "Creature.h" +#include "Define.h" +#include "ObjectGuid.h" +class Creature; class GameObject; +class Unit; +class WorldObject; +struct CreatureData; -class ZoneScript +class TC_GAME_API ZoneScript { public: ZoneScript() { } virtual ~ZoneScript() { } - virtual uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data) { return data->id; } + virtual uint32 GetCreatureEntry(ObjectGuid::LowType /*guidLow*/, CreatureData const* data); virtual uint32 GetGameObjectEntry(ObjectGuid::LowType /*guidLow*/, uint32 entry) { return entry; } virtual void OnCreatureCreate(Creature* ) { } diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index 3787c9ba601..81e906ed47d 100644 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -19,10 +19,14 @@ #ifndef TRINITY_FORMULAS_H #define TRINITY_FORMULAS_H -#include "World.h" -#include "SharedDefines.h" -#include "ScriptMgr.h" +#include "DBCStores.h" +#include "Creature.h" +#include "Log.h" +#include "Map.h" #include "Player.h" +#include "ScriptMgr.h" +#include "SharedDefines.h" +#include "World.h" namespace Trinity { @@ -185,7 +189,7 @@ namespace Trinity xpMod *= isBattleGround ? sWorld->getRate(RATE_XP_BG_KILL) : sWorld->getRate(RATE_XP_KILL); if (creature && creature->m_PlayerDamageReq) // if players dealt less than 50% of the damage and were credited anyway (due to CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ), scale XP gained appropriately (linear scaling) - xpMod *= 1.0f - 2.0f*creature->m_PlayerDamageReq / creature->GetMaxHealth(); + xpMod *= 1.0f - 2.0f * creature->m_PlayerDamageReq / creature->GetMaxHealth(); gain = uint32(gain * xpMod); } diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 9e42b516c47..7ea78f14ca4 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -21,7 +21,6 @@ #include "Define.h" #include "DetourNavMesh.h" -#include <cassert> enum SpellEffIndex : uint8 { @@ -1555,6 +1554,16 @@ enum GameObjectDynamicLowFlags GO_DYNFLAG_LO_STOPPED = 0x10 // Transport is stopped }; +// client side GO show states +enum GOState : uint8 +{ + GO_STATE_ACTIVE = 0, // show in world as used and not reset (closed door open) + GO_STATE_READY = 1, // show in world as ready (closed door close) + GO_STATE_ACTIVE_ALTERNATIVE = 2 // show in world as used in alt way and not reset (closed door open by cannon fire) +}; + +#define MAX_GO_STATE 3 + enum GameObjectDestructibleState { GO_DESTRUCTIBLE_INTACT = 0, @@ -3371,7 +3380,7 @@ enum BattlegroundTeamId #define BG_TEAMS_COUNT 2 // indexes of BattlemasterList.dbc -enum BattlegroundTypeId +enum BattlegroundTypeId : uint32 { BATTLEGROUND_TYPE_NONE = 0, // None BATTLEGROUND_AV = 1, // Alterac Valley @@ -3469,7 +3478,7 @@ enum TradeStatus TRADE_STATUS_NOT_ON_TAPLIST = 23 // Related to trading soulbound loot items }; -enum XPColorChar +enum XPColorChar : uint8 { XP_RED, XP_ORANGE, @@ -3478,7 +3487,7 @@ enum XPColorChar XP_GRAY }; -enum RemoveMethod +enum RemoveMethod : uint8 { GROUP_REMOVEMETHOD_DEFAULT = 0, GROUP_REMOVEMETHOD_KICK = 1, @@ -3503,7 +3512,7 @@ enum ActivateTaxiReply ERR_TAXINOTSTANDING = 12 }; -enum DuelCompleteType +enum DuelCompleteType : uint8 { DUEL_INTERRUPTED = 0, DUEL_WON = 1, @@ -3622,14 +3631,6 @@ enum DiminishingLevels DIMINISHING_LEVEL_TAUNT_IMMUNE = 4 }; -/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN -enum SpellCooldownFlags -{ - SPELL_COOLDOWN_FLAG_NONE = 0x0, - SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet - SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set -}; - enum WeaponAttackType : uint8 { BASE_ATTACK = 0, @@ -3649,4 +3650,14 @@ enum CharterTypes ARENA_TEAM_CHARTER_5v5_TYPE = 5 }; +enum LineOfSightChecks +{ + LINEOFSIGHT_CHECK_VMAP = 0x1, // check static floor layout data + LINEOFSIGHT_CHECK_GOBJECT = 0x2, // check dynamic game object data + + LINEOFSIGHT_ALL_CHECKS = (LINEOFSIGHT_CHECK_VMAP | LINEOFSIGHT_CHECK_GOBJECT) +}; + +#define MAX_CREATURE_SPELL_DATA_SLOT 4 + #endif diff --git a/src/server/game/Motd/ServerMotd.cpp b/src/server/game/Motd/ServerMotd.cpp index 3baaaf7a1c0..0f6587b60f2 100644 --- a/src/server/game/Motd/ServerMotd.cpp +++ b/src/server/game/Motd/ServerMotd.cpp @@ -15,11 +15,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "WorldPacket.h" #include "ServerMotd.h" - +#include "Common.h" #include "ScriptMgr.h" +#include "Util.h" +#include "WorldPacket.h" +#include <iterator> +#include <sstream> namespace { diff --git a/src/server/game/Motd/ServerMotd.h b/src/server/game/Motd/ServerMotd.h index 1e3c5edf231..21c7d461282 100644 --- a/src/server/game/Motd/ServerMotd.h +++ b/src/server/game/Motd/ServerMotd.h @@ -18,6 +18,7 @@ #ifndef ServerMotd_h__ #define ServerMotd_h__ +#include "Define.h" #include <string> class WorldPacket; diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 6f4c198f44d..6e771a29979 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -17,8 +17,12 @@ */ #include "MotionMaster.h" -#include "CreatureAISelector.h" #include "Creature.h" +#include "CreatureAISelector.h" +#include "DBCStores.h" +#include "Log.h" +#include "Map.h" +#include "PathGenerator.h" #include "ScriptSystem.h" #include "ConfusedMovementGenerator.h" #include "FleeingMovementGenerator.h" @@ -510,15 +514,16 @@ void MotionMaster::MoveCirclePath(float x, float y, float z, float radius, bool init.Launch(); } -void MotionMaster::MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk) -{ - Movement::PointsArray path(pathPoints, pathPoints + pathSize); - MoveSmoothPath(pointId, path, walk); -} - -void MotionMaster::MoveSmoothPath(uint32 pointId, Movement::PointsArray const& path, bool walk) +void MotionMaster::MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk) { Movement::MoveSplineInit init(_owner); + Movement::PointsArray path; + path.reserve(pathSize); + std::transform(pathPoints, pathPoints + pathSize, std::back_inserter(path), [](Position const& point) + { + return G3D::Vector3(point.GetPositionX(), point.GetPositionY(), point.GetPositionZ()); + }); + init.MovebyPath(path); init.SetSmooth(); init.SetWalk(walk); @@ -540,7 +545,7 @@ void MotionMaster::MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool w TC_LOG_ERROR("misc", "MotionMaster::MoveAlongSplineChain: non-creature %s tried to walk along DB spline chain. Ignoring.", _owner->GetGUID().ToString().c_str()); return; } - SplineChain const* chain = sScriptSystemMgr->GetSplineChain(owner, dbChainId); + std::vector<SplineChainLink> const* chain = sScriptSystemMgr->GetSplineChain(owner, dbChainId); if (!chain) { TC_LOG_ERROR("misc", "MotionMaster::MoveAlongSplineChain: creature with entry %u tried to walk along non-existing spline chain with DB id %u.", owner->GetEntry(), dbChainId); @@ -549,7 +554,7 @@ void MotionMaster::MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool w MoveAlongSplineChain(pointId, *chain, walk); } -void MotionMaster::MoveAlongSplineChain(uint32 pointId, SplineChain const& chain, bool walk) +void MotionMaster::MoveAlongSplineChain(uint32 pointId, std::vector<SplineChainLink> const& chain, bool walk) { Mutate(new SplineChainMovementGenerator(pointId, chain, walk), MOTION_SLOT_ACTIVE); } diff --git a/src/server/game/Movement/MotionMaster.h b/src/server/game/Movement/MotionMaster.h index d73c9464cf5..4e20f9ab814 100644 --- a/src/server/game/Movement/MotionMaster.h +++ b/src/server/game/Movement/MotionMaster.h @@ -20,22 +20,24 @@ #define MOTIONMASTER_H #include "Common.h" -#include <vector> +#include "Errors.h" +#include "ObjectGuid.h" +#include "Position.h" #include "SharedDefines.h" -#include "Object.h" -#include "MoveSplineInitArgs.h" -#include "SplineChain.h" +#include <vector> class MovementGenerator; class Unit; class PathGenerator; +struct SplineChainLink; +struct SplineChainResumeInfo; // Creature Entry ID used for waypoints show, visible only for GMs #define VISUAL_WAYPOINT 1 // assume it is 25 yard per 0.6 second #define SPEED_CHARGE 42.0f -enum MovementGeneratorType +enum MovementGeneratorType : uint8 { IDLE_MOTION_TYPE = 0, // IdleMovementGenerator.h RANDOM_MOTION_TYPE = 1, // RandomMovementGenerator.h @@ -146,11 +148,10 @@ class TC_GAME_API MotionMaster } void MoveJump(float x, float y, float z, float o, float speedXY, float speedZ, uint32 id = EVENT_JUMP, bool hasOrientation = false); void MoveCirclePath(float x, float y, float z, float radius, bool clockwise, uint8 stepCount); - void MoveSmoothPath(uint32 pointId, G3D::Vector3 const* pathPoints, size_t pathSize, bool walk); - void MoveSmoothPath(uint32 pointId, Movement::PointsArray const& points, bool walk); + void MoveSmoothPath(uint32 pointId, Position const* pathPoints, size_t pathSize, bool walk); // Walk along spline chain stored in DB (script_spline_chain_meta and script_spline_chain_waypoints) void MoveAlongSplineChain(uint32 pointId, uint16 dbChainId, bool walk); - void MoveAlongSplineChain(uint32 pointId, SplineChain const& chain, bool walk); + void MoveAlongSplineChain(uint32 pointId, std::vector<SplineChainLink> const& chain, bool walk); void ResumeSplineChain(SplineChainResumeInfo const& info); void MoveFall(uint32 id = 0); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 48524d9c663..20633056e4e 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -16,12 +16,13 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "ConfusedMovementGenerator.h" #include "Creature.h" -#include "Player.h" -#include "PathGenerator.h" -#include "MoveSplineInit.h" #include "MoveSpline.h" -#include "ConfusedMovementGenerator.h" +#include "MoveSplineInit.h" +#include "PathGenerator.h" +#include "Player.h" +#include "Random.h" template<class T> ConfusedMovementGenerator<T>::~ConfusedMovementGenerator() @@ -40,7 +41,7 @@ void ConfusedMovementGenerator<T>::DoInitialize(T* owner) owner->StopMoving(); _timer.Reset(0); - owner->GetPosition(_reference.x, _reference.y, _reference.z); + owner->GetPosition(_x, _y, _z); } template<class T> @@ -71,7 +72,7 @@ bool ConfusedMovementGenerator<T>::DoUpdate(T* owner, uint32 diff) // start moving owner->AddUnitState(UNIT_STATE_CONFUSED_MOVE); - Position destination(_reference); + Position destination(_x, _y, _z); float distance = 4.0f * frand(0.0f, 1.0f) - 2.0f; float angle = frand(0.0f, 1.0f) * float(M_PI) * 2.0f; owner->MovePositionToFirstCollision(destination, distance, angle); diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h index 95ba375de27..c4886c76bc3 100755 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.h @@ -26,7 +26,7 @@ template<class T> class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMovementGenerator<T> > { public: - explicit ConfusedMovementGenerator() : _path(nullptr), _timer(0), _reference(0.f, 0.f, 0.f), _interrupt(false) { } + explicit ConfusedMovementGenerator() : _path(nullptr), _timer(0), _x(0.f), _y(0.f), _z(0.f), _interrupt(false) { } ~ConfusedMovementGenerator(); MovementGeneratorType GetMovementGeneratorType() const override { return CONFUSED_MOTION_TYPE; } @@ -39,7 +39,7 @@ class ConfusedMovementGenerator : public MovementGeneratorMedium< T, ConfusedMov private: PathGenerator* _path; TimeTracker _timer; - G3D::Vector3 _reference; + float _x, _y, _z; bool _interrupt; }; diff --git a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp index 2714027fc85..275a6ab0db2 100644 --- a/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/FormationMovementGenerator.cpp @@ -35,7 +35,7 @@ void FormationMovementGenerator::DoInitialize(Creature* owner) owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(owner); - init.MoveTo(_destination); + init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ()); if (_orientation) init.SetFacing(_destination.GetOrientation()); @@ -81,7 +81,7 @@ bool FormationMovementGenerator::DoUpdate(Creature* owner, uint32 /*diff*/) owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(owner); - init.MoveTo(_destination); + init.MoveTo(_destination.GetPositionX(), _destination.GetPositionY(), _destination.GetPositionZ()); if (_orientation) init.SetFacing(_destination.GetOrientation()); diff --git a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp index 66e9b360daf..498cdf04876 100644 --- a/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/HomeMovementGenerator.cpp @@ -16,11 +16,12 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "HomeMovementGenerator.h" #include "Creature.h" #include "CreatureAI.h" -#include "MoveSplineInit.h" #include "MoveSpline.h" -#include "HomeMovementGenerator.h" +#include "MoveSplineInit.h" +#include "PathGenerator.h" template<class T> HomeMovementGenerator<T>::~HomeMovementGenerator() { } diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp index 36d9e17caf3..a952421833d 100755 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.cpp @@ -48,7 +48,7 @@ void PointMovementGenerator<T>::DoInitialize(T* owner) owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(owner); - init.MoveTo(_destination, _generatePath); + init.MoveTo(_x, _y, _z , _generatePath); if (_speed > 0.0f) init.SetVelocity(_speed); init.Launch(); @@ -56,7 +56,7 @@ void PointMovementGenerator<T>::DoInitialize(T* owner) // Call for creature group update if (Creature* creature = owner->ToCreature()) if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature) - creature->GetFormation()->LeaderMoveTo(Position(_destination), _movementId); + creature->GetFormation()->LeaderMoveTo(Position(_x, _y, _z), _movementId); } template<class T> @@ -83,7 +83,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* owner, uint32 /*diff*/) owner->AddUnitState(UNIT_STATE_ROAMING_MOVE); Movement::MoveSplineInit init(owner); - init.MoveTo(_destination, _generatePath); + init.MoveTo(_x, _y, _z, _generatePath); if (_speed > 0.0f) // Default value for point motion type is 0.0, if 0.0 spline will use GetSpeed on unit init.SetVelocity(_speed); init.Launch(); @@ -91,7 +91,7 @@ bool PointMovementGenerator<T>::DoUpdate(T* owner, uint32 /*diff*/) // Call for creature group update if (Creature* creature = owner->ToCreature()) if (creature->GetFormation() && creature->GetFormation()->getLeader() == creature) - creature->GetFormation()->LeaderMoveTo(Position(_destination), _movementId); + creature->GetFormation()->LeaderMoveTo(Position(_x, _y, _z), _movementId); } return !owner->movespline->Finalized(); diff --git a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h index f68021c51c4..8f4970566a3 100644 --- a/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/PointMovementGenerator.h @@ -21,11 +21,13 @@ #include "MovementGenerator.h" +class Creature; + template<class T> class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementGenerator<T> > { public: - explicit PointMovementGenerator(uint32 id, float x, float y, float z, bool generatePath, float speed = 0.0f) : _movementId(id), _destination(x, y, z), _speed(speed), _generatePath(generatePath), _recalculateSpeed(false), _interrupt(false) { } + PointMovementGenerator(uint32 id, float x, float y, float z, bool generatePath, float speed = 0.0f) : _movementId(id), _x(x), _y(y), _z(z), _speed(speed), _generatePath(generatePath), _recalculateSpeed(false), _interrupt(false) { } MovementGeneratorType GetMovementGeneratorType() const override { return POINT_MOTION_TYPE; } @@ -40,7 +42,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG void MovementInform(T*); uint32 _movementId; - G3D::Vector3 _destination; + float _x, _y, _z; float _speed; bool _generatePath; bool _recalculateSpeed; @@ -50,7 +52,7 @@ class PointMovementGenerator : public MovementGeneratorMedium< T, PointMovementG class AssistanceMovementGenerator : public PointMovementGenerator<Creature> { public: - explicit AssistanceMovementGenerator(float _x, float _y, float _z) : PointMovementGenerator<Creature>(0, _x, _y, _z, true) { } + AssistanceMovementGenerator(float x, float y, float z) : PointMovementGenerator<Creature>(0, x, y, z, true) { } MovementGeneratorType GetMovementGeneratorType() const override { return ASSISTANCE_MOTION_TYPE; } void Finalize(Unit*) override; diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp index 8a21ac683cd..0a1972c0972 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.cpp @@ -16,12 +16,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "RandomMovementGenerator.h" #include "Creature.h" #include "CreatureGroups.h" #include "Map.h" #include "MoveSplineInit.h" #include "MoveSpline.h" -#include "RandomMovementGenerator.h" +#include "PathGenerator.h" +#include "Random.h" template<class T> RandomMovementGenerator<T>::~RandomMovementGenerator() { } @@ -42,7 +44,7 @@ void RandomMovementGenerator<Creature>::DoInitialize(Creature* owner) return; owner->AddUnitState(UNIT_STATE_ROAMING); - owner->GetPosition(_reference.x, _reference.y, _reference.z); + _reference = owner->GetPosition(); owner->StopMoving(); if (!_wanderDistance) diff --git a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h index 5bf0eb03f32..845af1c1748 100644 --- a/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/RandomMovementGenerator.h @@ -26,7 +26,7 @@ template<class T> class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovementGenerator<T> > { public: - explicit RandomMovementGenerator(float distance = 0.0f) : _path(nullptr), _timer(0), _reference(0.f, 0.f, 0.f), _wanderDistance(distance), _interrupt(false) { } + explicit RandomMovementGenerator(float distance = 0.0f) : _path(nullptr), _timer(0), _reference(), _wanderDistance(distance), _interrupt(false) { } ~RandomMovementGenerator(); MovementGeneratorType GetMovementGeneratorType() const override { return RANDOM_MOTION_TYPE; } @@ -41,7 +41,7 @@ class RandomMovementGenerator : public MovementGeneratorMedium< T, RandomMovemen PathGenerator* _path; TimeTracker _timer; - G3D::Vector3 _reference; + Position _reference; float _wanderDistance; bool _interrupt; }; diff --git a/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h b/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h index ef0f0cf384d..8b7ce6fd69a 100644 --- a/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/SplineChainMovementGenerator.h @@ -24,7 +24,7 @@ class TC_GAME_API SplineChainMovementGenerator : public MovementGenerator { public: - explicit SplineChainMovementGenerator(uint32 id, SplineChain const& chain, bool walk = false) : _id(id), _chain(chain), _chainSize(chain.size()), _walk(walk), finished(false), _nextIndex(0), _nextFirstWP(0), _msToNext(0) { } + explicit SplineChainMovementGenerator(uint32 id, std::vector<SplineChainLink> const& chain, bool walk = false) : _id(id), _chain(chain), _chainSize(chain.size()), _walk(walk), finished(false), _nextIndex(0), _nextFirstWP(0), _msToNext(0) { } explicit SplineChainMovementGenerator(SplineChainResumeInfo const& info) : _id(info.PointID), _chain(*info.Chain), _chainSize(info.Chain->size()), _walk(info.IsWalkMode), finished(info.SplineIndex >= info.Chain->size()), _nextIndex(info.SplineIndex), _nextFirstWP(info.PointIndex), _msToNext(info.TimeToNext) { } void Initialize(Unit* me) override; void Finalize(Unit* me) override; @@ -41,7 +41,7 @@ class TC_GAME_API SplineChainMovementGenerator : public MovementGenerator void SendSplineFor(Unit* me, uint32 index, uint32& toNext); uint32 SendPathSpline(Unit* me, Movement::PointsArray const& wp) const; uint32 const _id; - SplineChain const& _chain; + std::vector<SplineChainLink> const& _chain; uint8 const _chainSize; bool const _walk; bool finished; diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index db1960ab72d..ef54cc83bff 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -16,14 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "CreatureAI.h" +#include "TargetedMovementGenerator.h" #include "Creature.h" +#include "CreatureAI.h" +#include "MoveSpline.h" +#include "MoveSplineInit.h" +#include "PathGenerator.h" #include "Player.h" #include "VehicleDefines.h" -#include "MoveSplineInit.h" -#include "MoveSpline.h" #include "World.h" -#include "TargetedMovementGenerator.h" template<class T, typename D> TargetedMovementGenerator<T, D>::~TargetedMovementGenerator() diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 57c831c2e44..f292c0a8091 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -15,21 +15,17 @@ * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ -//Basic headers + #include "WaypointMovementGenerator.h" -//Extended headers -#include "ObjectMgr.h" -#include "Transport.h" -//Flightmaster grid preloading -#include "MapManager.h" -//Creature-specific headers -#include "Creature.h" #include "CreatureAI.h" #include "CreatureGroups.h" -//Player-specific -#include "Player.h" -#include "MoveSplineInit.h" +#include "Log.h" +#include "MapManager.h" #include "MoveSpline.h" +#include "MoveSplineInit.h" +#include "ObjectMgr.h" +#include "Transport.h" +#include "World.h" void WaypointMovementGenerator<Creature>::LoadPath(Creature* creature) { @@ -79,7 +75,7 @@ void WaypointMovementGenerator<Creature>::OnArrived(Creature* creature) { TC_LOG_DEBUG("maps.script", "Creature movement start script %u at point %u for %s.", i_path->at(i_currentNode)->event_id, i_currentNode, creature->GetGUID().ToString().c_str()); creature->ClearUnitState(UNIT_STATE_ROAMING_MOVE); - creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, NULL); + creature->GetMap()->ScriptsStart(sWaypointScripts, i_path->at(i_currentNode)->event_id, creature, nullptr); } // Inform script @@ -240,7 +236,7 @@ bool WaypointMovementGenerator<Creature>::GetResetPos(Creature*, float& x, float if (!i_path || i_path->empty()) return false; - const WaypointData* node = i_path->at(i_currentNode); + WaypointData const* node = i_path->at(i_currentNode); x = node->x; y = node->y; z = node->z; return true; } diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index 726d41ffcae..7426a166ea1 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -26,9 +26,11 @@ */ #include "MovementGenerator.h" -#include "WaypointManager.h" +#include "Creature.h" +#include "DBCStructure.h" #include "Player.h" -#include "World.h" +#include "Timer.h" +#include "WaypointManager.h" #define FLIGHT_TRAVEL_UPDATE 100 #define TIMEDIFF_NEXT_WP 250 @@ -57,7 +59,7 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Crea public: WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) : i_nextMoveTime(0), m_isArrivalDone(false), path_id(_path_id), repeating(_repeating) { } - ~WaypointMovementGenerator() { i_path = NULL; } + ~WaypointMovementGenerator() { i_path = nullptr; } void DoInitialize(Creature*); void DoFinalize(Creature*); void DoReset(Creature*); @@ -148,4 +150,5 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig std::deque<TaxiNodeChangeInfo> _pointsForPathSwitch; //! node indexes and costs where TaxiPath changes }; + #endif diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 6075b9352e8..ecf84d51b94 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "PathGenerator.h" @@ -28,11 +28,11 @@ #include "Metric.h" ////////////////// PathGenerator ////////////////// -PathGenerator::PathGenerator(const Unit* owner) : +PathGenerator::PathGenerator(Unit const* owner) : _polyLength(0), _type(PATHFIND_BLANK), _useStraightPath(false), _forceDestination(false), _pointPathLimit(MAX_POINT_PATH_LENGTH), _straightLine(false), - _endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(NULL), - _navMeshQuery(NULL) + _endPosition(G3D::Vector3::zero()), _sourceUnit(owner), _navMesh(nullptr), + _navMeshQuery(nullptr) { memset(_pathPolyRefs, 0, sizeof(_pathPolyRefs)); @@ -103,7 +103,7 @@ dtPolyRef PathGenerator::GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 for (uint32 i = 0; i < polyPathSize; ++i) { float closestPoint[VERTEX_SIZE]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint, NULL))) + if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(polyPath[i], point, closestPoint, nullptr))) continue; float d = dtVdist2DSqr(point, closestPoint); @@ -184,7 +184,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con // Check both start and end points, if they're both in water, then we can *safely* let the creature move for (uint32 i = 0; i < _pathPoints.size(); ++i) { - ZLiquidStatus status = _sourceUnit->GetBaseMap()->GetLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, NULL); + ZLiquidStatus status = _sourceUnit->GetBaseMap()->GetLiquidStatus(_pathPoints[i].x, _pathPoints[i].y, _pathPoints[i].z, MAP_ALL_LIQUIDS, nullptr); // One of the points is not in the water, cancel movement. if (status == LIQUID_MAP_NO_WATER) { @@ -234,7 +234,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con { float closestPoint[VERTEX_SIZE]; // we may want to use closestPointOnPolyBoundary instead - if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint, NULL))) + if (dtStatusSucceed(_navMeshQuery->closestPointOnPoly(endPoly, endPoint, closestPoint, nullptr))) { dtVcopy(endPoint, closestPoint); SetActualEndPosition(G3D::Vector3(endPoint[2], endPoint[0], endPoint[1])); @@ -333,13 +333,13 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con // we need any point on our suffix start poly to generate poly-path, so we need last poly in prefix data float suffixEndPoint[VERTEX_SIZE]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, NULL))) + if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, nullptr))) { // we can hit offmesh connection as last poly - closestPointOnPoly() don't like that // try to recover by using prev polyref --prefixPolyLength; suffixStartPoly = _pathPolyRefs[prefixPolyLength-1]; - if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, NULL))) + if (dtStatusFailed(_navMeshQuery->closestPointOnPoly(suffixStartPoly, endPoint, suffixEndPoint, nullptr))) { // suffixStartPoly is still invalid, error state BuildShortcut(); @@ -512,8 +512,8 @@ void PathGenerator::BuildPointPath(const float *startPoint, const float *endPoin _pathPolyRefs, // current path _polyLength, // lenth of current path pathPoints, // [out] path corner points - NULL, // [out] flags - NULL, // [out] shortened path + nullptr, // [out] flags + nullptr, // [out] shortened path (int*)&pointCount, _pointPathLimit); // maximum number of points/polygons to use } @@ -678,7 +678,7 @@ bool PathGenerator::HaveTile(const G3D::Vector3& p) const if (tx < 0 || ty < 0) return false; - return (_navMesh->getTileAt(tx, ty, 0) != NULL); + return (_navMesh->getTileAt(tx, ty, 0) != nullptr); } uint32 PathGenerator::FixupCorridor(dtPolyRef* path, uint32 npath, uint32 maxPath, dtPolyRef const* visited, uint32 nvisited) @@ -885,7 +885,7 @@ dtStatus PathGenerator::FindSmoothPath(float const* startPos, float const* endPo return nsmoothPath < MAX_POINT_PATH_LENGTH ? DT_SUCCESS : DT_FAILURE; } -bool PathGenerator::InRangeYZX(const float* v1, const float* v2, float r, float h) const +bool PathGenerator::InRangeYZX(float const* v1, float const* v2, float r, float h) const { const float dx = v2[0] - v1[0]; const float dy = v2[1] - v1[1]; // elevation diff --git a/src/server/game/Movement/PathGenerator.h b/src/server/game/Movement/PathGenerator.h index a3e88b8a705..b840f5eb2c3 100644 --- a/src/server/game/Movement/PathGenerator.h +++ b/src/server/game/Movement/PathGenerator.h @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef _PATH_GENERATOR_H @@ -23,6 +23,7 @@ #include "DetourNavMesh.h" #include "DetourNavMeshQuery.h" #include "MoveSplineInitArgs.h" +#include <G3D/Vector3.h> class Unit; @@ -113,7 +114,7 @@ class TC_GAME_API PathGenerator float Dist3DSqr(G3D::Vector3 const& p1, G3D::Vector3 const& p2) const; bool InRangeYZX(float const* v1, float const* v2, float r, float h) const; - dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = NULL) const; + dtPolyRef GetPathPolyByPosition(dtPolyRef const* polyPath, uint32 polyPathSize, float const* Point, float* Distance = nullptr) const; dtPolyRef GetPolyByLocation(float const* Point, float* Distance) const; bool HaveTile(G3D::Vector3 const& p) const; diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index e0ba41728c2..1d454f11b9c 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "MoveSpline.h" @@ -117,9 +117,9 @@ struct CommonInitializer } }; -void MoveSpline::init_spline(const MoveSplineInitArgs& args) +void MoveSpline::init_spline(MoveSplineInitArgs const& args) { - const SplineBase::EvaluationMode modes[2] = {SplineBase::ModeLinear, SplineBase::ModeCatmullrom}; + static SplineBase::EvaluationMode const modes[2] = { SplineBase::ModeLinear, SplineBase::ModeCatmullrom }; if (args.flags.cyclic) { uint32 cyclic_point = 0; @@ -129,9 +129,7 @@ void MoveSpline::init_spline(const MoveSplineInitArgs& args) spline.init_cyclic_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()], cyclic_point); } else - { spline.init_spline(&args.path[0], args.path.size(), modes[args.flags.isSmooth()]); - } // init spline timestamps if (splineflags.falling) @@ -237,6 +235,15 @@ bool MoveSplineInitArgs::_checkPathBounds() const return true; } +MoveSplineInitArgs::MoveSplineInitArgs(size_t path_capacity /*= 16*/) : path_Idx_offset(0), velocity(0.f), +parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), +HasVelocity(false), TransformForTransport(true) +{ + path.reserve(path_capacity); +} + +MoveSplineInitArgs::~MoveSplineInitArgs() = default; + /// ============================================================================================ MoveSpline::UpdateResult MoveSpline::_updateState(int32& ms_time_diff) diff --git a/src/server/game/Movement/Spline/MoveSpline.h b/src/server/game/Movement/Spline/MoveSpline.h index 0e62862cecc..ac3c5e397dd 100644 --- a/src/server/game/Movement/Spline/MoveSpline.h +++ b/src/server/game/Movement/Spline/MoveSpline.h @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TRINITYSERVER_MOVEPLINE_H @@ -21,6 +21,7 @@ #include "Spline.h" #include "MoveSplineInitArgs.h" +#include <G3D/Vector3.h> namespace Movement { @@ -28,8 +29,8 @@ namespace Movement { Location() : orientation(0) { } Location(float x, float y, float z, float o) : Vector3(x, y, z), orientation(o) { } - Location(const Vector3& v) : Vector3(v), orientation(0) { } - Location(const Vector3& v, float o) : Vector3(v), orientation(o) { } + Location(Vector3 const& v) : Vector3(v), orientation(0) { } + Location(Vector3 const& v, float o) : Vector3(v), orientation(o) { } float orientation; }; @@ -69,7 +70,7 @@ namespace Movement int32 point_Idx; int32 point_Idx_offset; - void init_spline(const MoveSplineInitArgs& args); + void init_spline(MoveSplineInitArgs const& args); protected: MySpline::ControlArray const& getPath() const { return spline.getPoints(); } @@ -90,7 +91,7 @@ namespace Movement void _Interrupt() { splineflags.done = true; } public: - void Initialize(const MoveSplineInitArgs&); + void Initialize(MoveSplineInitArgs const&); bool Initialized() const { return !spline.empty(); } MoveSpline(); diff --git a/src/server/game/Movement/Spline/MoveSplineFlag.h b/src/server/game/Movement/Spline/MoveSplineFlag.h index 0a3b41d412a..5630349812f 100644 --- a/src/server/game/Movement/Spline/MoveSplineFlag.h +++ b/src/server/game/Movement/Spline/MoveSplineFlag.h @@ -1,26 +1,25 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TRINITYSERVER_MOVESPLINEFLAG_H #define TRINITYSERVER_MOVESPLINEFLAG_H -#include "MovementTypedefs.h" -#include <string> +#include "MovementTypedefs.h" namespace Movement { @@ -71,11 +70,11 @@ namespace Movement }; inline uint32& raw() { return (uint32&)*this; } - inline const uint32& raw() const { return (const uint32&)*this; } + inline uint32 const& raw() const { return (uint32 const&)*this; } MoveSplineFlag() { raw() = 0; } MoveSplineFlag(uint32 f) { raw() = f; } - MoveSplineFlag(const MoveSplineFlag& f) { raw() = f.raw(); } + MoveSplineFlag(MoveSplineFlag const& f) { raw() = f.raw(); } // Constant interface diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp index 180ecf23079..5e307eea35c 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.cpp +++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp @@ -1,28 +1,29 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "MoveSplineInit.h" #include "MoveSpline.h" #include "MovementPacketBuilder.h" #include "Unit.h" +#include "PathGenerator.h" #include "Transport.h" -#include "WorldPacket.h" #include "Opcodes.h" +#include "WorldPacket.h" namespace Movement { @@ -184,7 +185,19 @@ namespace Movement args.flags.flying = unit->m_movementInfo.HasMovementFlag((MovementFlags)(MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_DISABLE_GRAVITY)); } - void MoveSplineInit::SetFacing(const Unit* target) + MoveSplineInit::~MoveSplineInit() = default; + + void MoveSplineInit::SetFacing(Vector3 const& spot) + { + TransportPathTransform transform(unit, args.TransformForTransport); + Vector3 finalSpot = transform(spot); + args.facing.f.x = finalSpot.x; + args.facing.f.y = finalSpot.y; + args.facing.f.z = finalSpot.z; + args.flags.EnableFacingPoint(); + } + + void MoveSplineInit::SetFacing(Unit const* target) { args.flags.EnableFacingTarget(); args.facing.target = target->GetGUID().GetRawValue(); @@ -204,7 +217,19 @@ namespace Movement args.flags.EnableFacingAngle(); } - void MoveSplineInit::MoveTo(const Vector3& dest, bool generatePath, bool forceDestination) + void MoveSplineInit::MovebyPath(PointsArray const& controls, int32 path_offset) + { + args.path_Idx_offset = path_offset; + args.path.resize(controls.size()); + std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport)); + } + + void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination) + { + MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination); + } + + void MoveSplineInit::MoveTo(Vector3 const& dest, bool generatePath, bool forceDestination) { if (generatePath) { diff --git a/src/server/game/Movement/Spline/MoveSplineInit.h b/src/server/game/Movement/Spline/MoveSplineInit.h index 3f38da97916..f726af6487f 100644 --- a/src/server/game/Movement/Spline/MoveSplineInit.h +++ b/src/server/game/Movement/Spline/MoveSplineInit.h @@ -1,26 +1,25 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ +* Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> +* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> +* +* This program is free software; you can redistribute it and/or modify it +* under the terms of the GNU General Public License as published by the +* Free Software Foundation; either version 2 of the License, or (at your +* option) any later version. +* +* This program is distributed in the hope that it will be useful, but WITHOUT +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +* more details. +* +* You should have received a copy of the GNU General Public License along +* with this program. If not, see <http://www.gnu.org/licenses/>. +*/ #ifndef TRINITYSERVER_MOVESPLINEINIT_H #define TRINITYSERVER_MOVESPLINEINIT_H #include "MoveSplineInitArgs.h" -#include "PathGenerator.h" class Unit; @@ -54,6 +53,9 @@ namespace Movement public: explicit MoveSplineInit(Unit* m); + ~MoveSplineInit(); + MoveSplineInit(MoveSplineInit const&) = delete; + MoveSplineInit& operator=(MoveSplineInit const&) = delete; /* Final pass of initialization that launches spline movement. */ @@ -80,17 +82,17 @@ namespace Movement */ void SetFacing(float angle); void SetFacing(Vector3 const& point); - void SetFacing(const Unit* target); + void SetFacing(Unit const* target); /* Initializes movement by path * @param path - array of points, shouldn't be empty * @param pointId - Id of fisrt point of the path. Example: when third path point will be done it will notify that pointId + 3 done */ - void MovebyPath(const PointsArray& path, int32 pointId = 0); + void MovebyPath(PointsArray const& path, int32 pointId = 0); /* Initializes simple A to B motion, A is current unit's position, B is destination */ - void MoveTo(const Vector3& destination, bool generatePath = true, bool forceDestination = false); + void MoveTo(Vector3 const& destination, bool generatePath = true, bool forceDestination = false); void MoveTo(float x, float y, float z, bool generatePath = true, bool forceDestination = false); /* Sets Id of fisrt point of the path. When N-th path point will be done ILisener will notify that pointId + N done @@ -156,18 +158,6 @@ namespace Movement inline void MoveSplineInit::SetTransportExit() { args.flags.EnableTransportExit(); } inline void MoveSplineInit::SetOrientationFixed(bool enable) { args.flags.orientationFixed = enable; } - inline void MoveSplineInit::MovebyPath(const PointsArray& controls, int32 path_offset) - { - args.path_Idx_offset = path_offset; - args.path.resize(controls.size()); - std::transform(controls.begin(), controls.end(), args.path.begin(), TransportPathTransform(unit, args.TransformForTransport)); - } - - inline void MoveSplineInit::MoveTo(float x, float y, float z, bool generatePath, bool forceDestination) - { - MoveTo(G3D::Vector3(x, y, z), generatePath, forceDestination); - } - inline void MoveSplineInit::SetParabolic(float amplitude, float time_shift) { args.time_perc = time_shift; @@ -181,16 +171,6 @@ namespace Movement args.flags.EnableAnimation((uint8)anim); } - inline void MoveSplineInit::SetFacing(Vector3 const& spot) - { - TransportPathTransform transform(unit, args.TransformForTransport); - Vector3 finalSpot = transform(spot); - args.facing.f.x = finalSpot.x; - args.facing.f.y = finalSpot.y; - args.facing.f.z = finalSpot.z; - args.flags.EnableFacingPoint(); - } - inline void MoveSplineInit::DisableTransportPathTransformations() { args.TransformForTransport = false; } } #endif // TRINITYSERVER_MOVESPLINEINIT_H diff --git a/src/server/game/Movement/Spline/MoveSplineInitArgs.h b/src/server/game/Movement/Spline/MoveSplineInitArgs.h index 12c22898b6d..d3ce9e66bc4 100644 --- a/src/server/game/Movement/Spline/MoveSplineInitArgs.h +++ b/src/server/game/Movement/Spline/MoveSplineInitArgs.h @@ -1,26 +1,26 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TRINITYSERVER_MOVESPLINEINIT_ARGS_H #define TRINITYSERVER_MOVESPLINEINIT_ARGS_H #include "MoveSplineFlag.h" -#include <G3D/Vector3.h> +#include <vector> class Unit; @@ -43,12 +43,8 @@ namespace Movement struct MoveSplineInitArgs { - MoveSplineInitArgs(size_t path_capacity = 16) : path_Idx_offset(0), velocity(0.f), - parabolic_amplitude(0.f), time_perc(0.f), splineId(0), initialOrientation(0.f), - HasVelocity(false), TransformForTransport(true) - { - path.reserve(path_capacity); - } + MoveSplineInitArgs(size_t path_capacity = 16); + ~MoveSplineInitArgs(); PointsArray path; FacingInfo facing; diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp index e6a02ec5ce7..d747f33082f 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.cpp +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.cpp @@ -1,34 +1,34 @@ /* * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "MovementPacketBuilder.h" -#include "MoveSpline.h" #include "ByteBuffer.h" +#include "MoveSpline.h" +#include "Position.h" namespace Movement { - inline void operator << (ByteBuffer& b, const Vector3& v) + inline void operator<<(ByteBuffer& b, Vector3 const& v) { b << v.x << v.y << v.z; } - inline void operator >> (ByteBuffer& b, Vector3& v) + inline void operator>>(ByteBuffer& b, Vector3& v) { b >> v.x >> v.y >> v.z; } @@ -42,7 +42,7 @@ namespace Movement MonsterMoveFacingAngle = 4 }; - void PacketBuilder::WriteCommonMonsterMovePart(const MoveSpline& move_spline, ByteBuffer& data) + void PacketBuilder::WriteCommonMonsterMovePart(MoveSpline const& move_spline, ByteBuffer& data) { MoveSplineFlag splineflags = move_spline.splineflags; @@ -88,7 +88,7 @@ namespace Movement } } - void PacketBuilder::WriteStopMovement(Vector3 const& pos, uint32 splineId, ByteBuffer& data) + void PacketBuilder::WriteStopMovement(G3D::Vector3 const& pos, uint32 splineId, ByteBuffer& data) { data << uint8(0); // sets/unsets MOVEMENTFLAG2_UNK7 (0x40) data << pos; @@ -96,42 +96,42 @@ namespace Movement data << uint8(MonsterMoveStop); } - void WriteLinearPath(const Spline<int32>& spline, ByteBuffer& data) + void WriteLinearPath(Spline<int32> const& spline, ByteBuffer& data) { uint32 last_idx = spline.getPointCount() - 3; - const Vector3 * real_path = &spline.getPoint(1); + G3D::Vector3 const* real_path = &spline.getPoint(1); data << last_idx; data << real_path[last_idx]; // destination if (last_idx > 1) { - Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; - Vector3 offset; + G3D::Vector3 middle = (real_path[0] + real_path[last_idx]) / 2.f; + G3D::Vector3 offset; // first and last points already appended for (uint32 i = 1; i < last_idx; ++i) { offset = middle - real_path[i]; - data.appendPackXYZ(offset.x, offset.y, offset.z); + data << TaggedPosition<Position::PackedXYZ>(offset.x, offset.y, offset.z); } } } - void WriteCatmullRomPath(const Spline<int32>& spline, ByteBuffer& data) + void WriteCatmullRomPath(Spline<int32> const& spline, ByteBuffer& data) { uint32 count = spline.getPointCount() - 3; data << count; - data.append<Vector3>(&spline.getPoint(2), count); + data.append<G3D::Vector3>(&spline.getPoint(2), count); } - void WriteCatmullRomCyclicPath(const Spline<int32>& spline, ByteBuffer& data) + void WriteCatmullRomCyclicPath(Spline<int32> const& spline, ByteBuffer& data) { uint32 count = spline.getPointCount() - 3; data << uint32(count + 1); data << spline.getPoint(1); // fake point, client will erase it from the spline after first cycle done - data.append<Vector3>(&spline.getPoint(1), count); + data.append<G3D::Vector3>(&spline.getPoint(1), count); } - void PacketBuilder::WriteMonsterMove(const MoveSpline& move_spline, ByteBuffer& data) + void PacketBuilder::WriteMonsterMove(MoveSpline const& move_spline, ByteBuffer& data) { WriteCommonMonsterMovePart(move_spline, data); @@ -148,7 +148,7 @@ namespace Movement WriteLinearPath(spline, data); } - void PacketBuilder::WriteCreate(const MoveSpline& move_spline, ByteBuffer& data) + void PacketBuilder::WriteCreate(MoveSpline const& move_spline, ByteBuffer& data) { //WriteClientStatus(mov, data); //data.append<float>(&mov.m_float_values[SpeedWalk], SpeedMaxCount); @@ -183,9 +183,9 @@ namespace Movement uint32 nodes = move_spline.getPath().size(); data << nodes; - data.append<Vector3>(&move_spline.getPath()[0], nodes); + data.append<G3D::Vector3>(&move_spline.getPath()[0], nodes); data << uint8(move_spline.spline.mode()); // added in 3.1 - data << (move_spline.isCyclic() ? Vector3::zero() : move_spline.FinalDestination()); + data << (move_spline.isCyclic() ? G3D::Vector3::zero() : move_spline.FinalDestination()); } } } diff --git a/src/server/game/Movement/Spline/MovementPacketBuilder.h b/src/server/game/Movement/Spline/MovementPacketBuilder.h index 4a078904424..2648ca46dd3 100644 --- a/src/server/game/Movement/Spline/MovementPacketBuilder.h +++ b/src/server/game/Movement/Spline/MovementPacketBuilder.h @@ -1,20 +1,19 @@ /* * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TRINITYSERVER_PACKET_BUILDER_H @@ -30,17 +29,15 @@ namespace G3D namespace Movement { - using G3D::Vector3; - class MoveSpline; class PacketBuilder { - static void WriteCommonMonsterMovePart(const MoveSpline& mov, ByteBuffer& data); + static void WriteCommonMonsterMovePart(MoveSpline const& mov, ByteBuffer& data); public: - static void WriteMonsterMove(const MoveSpline& mov, ByteBuffer& data); - static void WriteStopMovement(Vector3 const& loc, uint32 splineId, ByteBuffer& data); - static void WriteCreate(const MoveSpline& mov, ByteBuffer& data); + static void WriteMonsterMove(MoveSpline const& mov, ByteBuffer& data); + static void WriteStopMovement(G3D::Vector3 const& loc, uint32 splineId, ByteBuffer& data); + static void WriteCreate(MoveSpline const& mov, ByteBuffer& data); }; } #endif // TRINITYSERVER_PACKET_BUILDER_H diff --git a/src/server/game/Movement/Spline/MovementTypedefs.h b/src/server/game/Movement/Spline/MovementTypedefs.h index c87fea47a82..6a06bde0f49 100644 --- a/src/server/game/Movement/Spline/MovementTypedefs.h +++ b/src/server/game/Movement/Spline/MovementTypedefs.h @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TRINITYSERVER_TYPEDEFS_H diff --git a/src/server/game/Movement/Spline/MovementUtil.cpp b/src/server/game/Movement/Spline/MovementUtil.cpp index 4f7e1d6a7a4..8105d886384 100644 --- a/src/server/game/Movement/Spline/MovementUtil.cpp +++ b/src/server/game/Movement/Spline/MovementUtil.cpp @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "MoveSplineFlag.h" @@ -180,7 +180,7 @@ namespace Movement { for (int i = 0; i < N; ++i) { - if ((t & Flags(1 << i)) && names[i] != NULL) + if ((t & Flags(1 << i)) && names[i] != nullptr) str.append(" ").append(names[i]); } } diff --git a/src/server/game/Movement/Spline/Spline.cpp b/src/server/game/Movement/Spline/Spline.cpp index fff83b788f9..308c14973c6 100644 --- a/src/server/game/Movement/Spline/Spline.cpp +++ b/src/server/game/Movement/Spline/Spline.cpp @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "Spline.h" @@ -94,7 +94,7 @@ inline void C_Evaluate(const Vector3 *vertice, float t, const float (&matrix)[4] position.z = z; }*/ -inline void C_Evaluate(const Vector3 *vertice, float t, const Matrix4& matr, Vector3 &result) +inline void C_Evaluate(Vector3 const* vertice, float t, Matrix4 const& matr, Vector3 &result) { Vector4 tvec(t*t*t, t*t, t, 1.f); Vector4 weights(tvec * matr); @@ -103,7 +103,7 @@ inline void C_Evaluate(const Vector3 *vertice, float t, const Matrix4& matr, Vec + vertice[2] * weights[2] + vertice[3] * weights[3]; } -inline void C_Evaluate_Derivative(const Vector3 *vertice, float t, const Matrix4& matr, Vector3 &result) +inline void C_Evaluate_Derivative(Vector3 const* vertice, float t, Matrix4 const& matr, Vector3 &result) { Vector4 tvec(3.f*t*t, 2.f*t, 1.f, 0.f); Vector4 weights(tvec * matr); @@ -215,7 +215,7 @@ void SplineBase::init_cyclic_spline(const Vector3 * controls, index_type count, (this->*initializers[m_mode])(controls, count, cyclic_point); } -void SplineBase::InitLinear(const Vector3* controls, index_type count, index_type cyclic_point) +void SplineBase::InitLinear(Vector3 const* controls, index_type count, index_type cyclic_point) { ASSERT(count >= 2); const int real_size = count + 1; @@ -235,7 +235,7 @@ void SplineBase::InitLinear(const Vector3* controls, index_type count, index_typ index_hi = cyclic ? count : (count - 1); } -void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, index_type cyclic_point) +void SplineBase::InitCatmullRom(Vector3 const* controls, index_type count, index_type cyclic_point) { const int real_size = count + (cyclic ? (1+2) : (1+1)); @@ -268,7 +268,7 @@ void SplineBase::InitCatmullRom(const Vector3* controls, index_type count, index index_hi = high_index + (cyclic ? 1 : 0); } -void SplineBase::InitBezier3(const Vector3* controls, index_type count, index_type /*cyclic_point*/) +void SplineBase::InitBezier3(Vector3 const* controls, index_type count, index_type /*cyclic_point*/) { index_type c = count / 3u * 3u; index_type t = c / 3u; diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index 59f514bed75..9155369afed 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -1,27 +1,29 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifndef TRINITYSERVER_SPLINE_H #define TRINITYSERVER_SPLINE_H #include "MovementTypedefs.h" +#include "Errors.h" #include <G3D/Vector3.h> #include <limits> +#include <vector> namespace Movement { @@ -76,10 +78,10 @@ protected: typedef float (SplineBase::*SegLenghtMethtod)(index_type) const; static SegLenghtMethtod seglengths[ModesEnd]; - void InitLinear(const Vector3*, index_type, index_type); - void InitCatmullRom(const Vector3*, index_type, index_type); - void InitBezier3(const Vector3*, index_type, index_type); - typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, index_type); + void InitLinear(Vector3 const*, index_type, index_type); + void InitCatmullRom(Vector3 const*, index_type, index_type); + void InitBezier3(Vector3 const*, index_type, index_type); + typedef void (SplineBase::*InitMethtod)(Vector3 const*, index_type, index_type); static InitMethtod initializers[ModesEnd]; void UninitializedSpline() const { ABORT();} @@ -108,9 +110,9 @@ public: EvaluationMode mode() const { return (EvaluationMode)m_mode;} bool isCyclic() const { return cyclic;} - const ControlArray& getPoints() const { return points;} + ControlArray const& getPoints() const { return points;} index_type getPointCount() const { return points.size();} - const Vector3& getPoint(index_type i) const { return points[i];} + Vector3 const& getPoint(index_type i) const { return points[i];} /** Initializes spline. Don't call other methods while spline not initialized. */ void init_spline(const Vector3 * controls, index_type count, EvaluationMode m); diff --git a/src/server/game/Movement/Spline/SplineChain.h b/src/server/game/Movement/Spline/SplineChain.h index 51e0d0a1a2e..8256838718a 100644 --- a/src/server/game/Movement/Spline/SplineChain.h +++ b/src/server/game/Movement/Spline/SplineChain.h @@ -19,6 +19,7 @@ #define TRINITY_SPLINECHAIN_H #include "MoveSplineInitArgs.h" +#include <G3D/Vector3.h> struct TC_GAME_API SplineChainLink { @@ -29,17 +30,16 @@ struct TC_GAME_API SplineChainLink uint32 ExpectedDuration; uint32 TimeToNext; }; -typedef std::vector<SplineChainLink> SplineChain; struct TC_GAME_API SplineChainResumeInfo { SplineChainResumeInfo() : PointID(0), Chain(nullptr), IsWalkMode(false), SplineIndex(0), PointIndex(0), TimeToNext(0) { } - SplineChainResumeInfo(uint32 id, SplineChain const* chain, bool walk, uint8 splineIndex, uint8 wpIndex, uint32 msToNext) : + SplineChainResumeInfo(uint32 id, std::vector<SplineChainLink> const* chain, bool walk, uint8 splineIndex, uint8 wpIndex, uint32 msToNext) : PointID(id), Chain(chain), IsWalkMode(walk), SplineIndex(splineIndex), PointIndex(wpIndex), TimeToNext(msToNext) { } bool Empty() const { return Chain == nullptr; } void Clear() { Chain = nullptr; } uint32 PointID; - SplineChain const* Chain; + std::vector<SplineChainLink> const* Chain; bool IsWalkMode; uint8 SplineIndex; uint8 PointIndex; diff --git a/src/server/game/Movement/Spline/SplineImpl.h b/src/server/game/Movement/Spline/SplineImpl.h index 98f3f5fe079..1502fcc1022 100644 --- a/src/server/game/Movement/Spline/SplineImpl.h +++ b/src/server/game/Movement/Spline/SplineImpl.h @@ -1,19 +1,19 @@ /* - * Copyright (C) 2005-2011 MaNGOS <http://getmangos.com/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. */ namespace Movement diff --git a/src/server/game/Movement/Waypoints/WaypointManager.h b/src/server/game/Movement/Waypoints/WaypointManager.h index 97227becbc1..f62805594ef 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.h +++ b/src/server/game/Movement/Waypoints/WaypointManager.h @@ -19,7 +19,9 @@ #ifndef TRINITY_WAYPOINTMANAGER_H #define TRINITY_WAYPOINTMANAGER_H +#include "Define.h" #include <vector> +#include <unordered_map> enum WaypointMoveType { @@ -62,7 +64,7 @@ class TC_GAME_API WaypointMgr if (itr != _waypointStore.end()) return &itr->second; - return NULL; + return nullptr; } private: diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index bb2d9f539bf..a2d195bea20 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -16,16 +16,18 @@ */ #include "OutdoorPvP.h" -#include "OutdoorPvPMgr.h" +#include "CellImpl.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "GridNotifiersImpl.h" +#include "Group.h" +#include "Log.h" +#include "Map.h" +#include "MapManager.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "Map.h" -#include "Group.h" +#include "OutdoorPvPMgr.h" #include "WorldPacket.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "CellImpl.h" -#include "MapManager.h" class DefenseMessageBuilder { @@ -49,7 +51,7 @@ class DefenseMessageBuilder }; OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp): - m_capturePointSpawnId(), m_capturePoint(NULL), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), + m_capturePointSpawnId(), m_capturePoint(nullptr), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), m_value(0), m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL), m_State(OBJECTIVESTATE_NEUTRAL), m_neutralValuePct(0), m_PvP(pvp) { } @@ -113,7 +115,7 @@ void OPvPCapturePoint::AddCre(uint32 type, ObjectGuid::LowType guid, uint32 entr m_CreatureTypes[m_Creatures[type]] = type; } -bool OPvPCapturePoint::AddObject(uint32 type, uint32 entry, uint32 map, Position const& pos, G3D::Quat const& rot) +bool OPvPCapturePoint::AddObject(uint32 type, uint32 entry, uint32 map, Position const& pos, QuaternionData const& rot) { if (ObjectGuid::LowType guid = sObjectMgr->AddGOData(entry, map, pos, rot, 0)) { @@ -135,7 +137,7 @@ bool OPvPCapturePoint::AddCreature(uint32 type, uint32 entry, uint32 map, Positi return false; } -bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, Position const& pos, G3D::Quat const& rot) +bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, Position const& pos, QuaternionData const& rot) { TC_LOG_DEBUG("outdoorpvp", "Creating capture point %u", entry); @@ -473,7 +475,7 @@ void OutdoorPvP::HandleKill(Player* killer, Unit* killed) { if (Group* group = killer->GetGroup()) { - for (GroupReference* itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next()) { Player* groupGuy = itr->GetSource(); @@ -509,7 +511,7 @@ bool OutdoorPvP::IsInsideObjective(Player* player) const bool OPvPCapturePoint::IsInsideObjective(Player* player) const { - GuidSet const &plSet = m_activePlayers[player->GetTeamId()]; + GuidSet const& plSet = m_activePlayers[player->GetTeamId()]; return plSet.find(player->GetGUID()) != plSet.end(); } @@ -600,7 +602,7 @@ void OutdoorPvP::BroadcastPacket(WorldPacket &data) const for (uint32 team = 0; team < BG_TEAMS_COUNT; ++team) for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr) if (Player* const player = ObjectAccessor::FindPlayer(*itr)) - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } void OutdoorPvP::RegisterZone(uint32 zoneId) @@ -610,7 +612,7 @@ void OutdoorPvP::RegisterZone(uint32 zoneId) bool OutdoorPvP::HasPlayer(Player const* player) const { - GuidSet const &plSet = m_players[player->GetTeamId()]; + GuidSet const& plSet = m_players[player->GetTeamId()]; return plSet.find(player->GetGUID()) != plSet.end(); } @@ -655,7 +657,7 @@ void OutdoorPvP::OnGameObjectRemove(GameObject* go) return; if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId())) - cp->m_capturePoint = NULL; + cp->m_capturePoint = nullptr; } void OutdoorPvP::OnCreatureCreate(Creature* creature) @@ -688,8 +690,7 @@ void OutdoorPvP::BroadcastWorker(Worker& _worker, uint32 zoneId) void OutdoorPvP::SetMapFromZone(uint32 zone) { - AreaTableEntry const* areaTable = sAreaTableStore.LookupEntry(zone); - ASSERT(areaTable); + AreaTableEntry const* areaTable = sAreaTableStore.AssertEntry(zone); Map* map = sMapMgr->CreateBaseMap(areaTable->mapid); ASSERT(!map->Instanceable()); m_map = map; diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index a918365b11d..39348155798 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -18,11 +18,11 @@ #ifndef OUTDOOR_PVP_H_ #define OUTDOOR_PVP_H_ -#include "Util.h" +#include "GameObjectData.h" +#include "Position.h" #include "SharedDefines.h" #include "ZoneScript.h" - -#include <G3D/Quat.h> +#include <map> enum OutdoorPvPTypes { @@ -55,7 +55,7 @@ struct go_type uint32 entry; uint32 map; Position pos; - G3D::Quat rot; + QuaternionData rot; }; // struct for creature spawning @@ -66,14 +66,14 @@ struct creature_type Position pos; }; -// some class predefs -class Player; -class GameObject; -class WorldPacket; class Creature; +class GameObject; +class Map; +class OutdoorPvP; +class Player; class Unit; +class WorldPacket; struct GossipMenuItems; -class OutdoorPvP; class TC_GAME_API OPvPCapturePoint { @@ -126,11 +126,11 @@ class TC_GAME_API OPvPCapturePoint void AddGO(uint32 type, ObjectGuid::LowType guid, uint32 entry = 0); void AddCre(uint32 type, ObjectGuid::LowType guid, uint32 entry = 0); - bool SetCapturePointData(uint32 entry, uint32 map, Position const& pos, G3D::Quat const& rot); + bool SetCapturePointData(uint32 entry, uint32 map, Position const& pos, QuaternionData const& rot); protected: - bool AddObject(uint32 type, uint32 entry, uint32 map, Position const& pos, G3D::Quat const& rot); + bool AddObject(uint32 type, uint32 entry, uint32 map, Position const& pos, QuaternionData const& rot); bool AddCreature(uint32 type, uint32 entry, uint32 map, Position const& pos, TeamId teamId = TEAM_NEUTRAL, uint32 spawntimedelay = 0); bool DelObject(uint32 type); diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index a1de152d9ae..ebe3d568beb 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -16,9 +16,11 @@ */ #include "OutdoorPvPMgr.h" +#include "DatabaseEnv.h" +#include "DisableMgr.h" +#include "Log.h" #include "ObjectMgr.h" #include "Player.h" -#include "DisableMgr.h" #include "ScriptMgr.h" OutdoorPvPMgr::OutdoorPvPMgr() @@ -33,8 +35,7 @@ void OutdoorPvPMgr::Die() m_OutdoorPvPSet.clear(); - for (uint32 i = 0; i < MAX_OUTDOORPVP_TYPES; ++i) - m_OutdoorPvPDatas[i] = 0; + m_OutdoorPvPDatas.fill(0); m_OutdoorPvPMap.clear(); } @@ -66,7 +67,7 @@ void OutdoorPvPMgr::InitOutdoorPvP() typeId = fields[0].GetUInt8(); - if (DisableMgr::IsDisabledFor(DISABLE_TYPE_OUTDOORPVP, typeId, NULL)) + if (DisableMgr::IsDisabledFor(DISABLE_TYPE_OUTDOORPVP, typeId, nullptr)) continue; if (typeId >= MAX_OUTDOORPVP_TYPES) @@ -149,7 +150,7 @@ OutdoorPvP* OutdoorPvPMgr::GetOutdoorPvPToZoneId(uint32 zoneid) if (itr == m_OutdoorPvPMap.end()) { // no handle for this zone, return - return NULL; + return nullptr; } return itr->second; } @@ -181,7 +182,7 @@ ZoneScript* OutdoorPvPMgr::GetZoneScript(uint32 zoneId) if (itr != m_OutdoorPvPMap.end()) return itr->second; else - return NULL; + return nullptr; } bool OutdoorPvPMgr::HandleOpenGo(Player* player, GameObject* go) diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index e69d9482edd..9cd1dcf61c7 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -21,12 +21,15 @@ #define OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL 1000 #include "OutdoorPvP.h" +#include <array> +#include <unordered_map> class Player; class GameObject; class Creature; class ZoneScript; struct GossipMenuItems; +enum LocaleConstant : uint8; // class to handle player enter / leave / areatrigger / GO use events class TC_GAME_API OutdoorPvPMgr @@ -78,7 +81,7 @@ class TC_GAME_API OutdoorPvPMgr private: typedef std::vector<OutdoorPvP*> OutdoorPvPSet; - typedef std::unordered_map<uint32 /* zoneid */, OutdoorPvP*> OutdoorPvPMap; + typedef std::unordered_map<uint32 /*zoneid*/, OutdoorPvP*> OutdoorPvPMap; typedef std::array<uint32, MAX_OUTDOORPVP_TYPES> OutdoorPvPScriptIds; // contains all initiated outdoor pvp events diff --git a/src/server/game/Petitions/PetitionMgr.cpp b/src/server/game/Petitions/PetitionMgr.cpp index d249d3a8f87..ec583353e3e 100644 --- a/src/server/game/Petitions/PetitionMgr.cpp +++ b/src/server/game/Petitions/PetitionMgr.cpp @@ -17,11 +17,12 @@ #include "PetitionMgr.h" #include "DatabaseEnv.h" +#include "Log.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "Player.h" -#include "WorldSession.h" #include "Timer.h" - +#include "WorldSession.h" #include <unordered_map> namespace diff --git a/src/server/game/Petitions/PetitionMgr.h b/src/server/game/Petitions/PetitionMgr.h index 119f24ac255..401f09aab5a 100644 --- a/src/server/game/Petitions/PetitionMgr.h +++ b/src/server/game/Petitions/PetitionMgr.h @@ -21,7 +21,6 @@ #include "Define.h" #include "ObjectGuid.h" #include "SharedDefines.h" - #include <string> #include <utility> #include <vector> diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 76ea5eb5015..9305e226421 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -18,9 +18,10 @@ #include "PoolMgr.h" #include "Containers.h" -#include "ObjectMgr.h" +#include "DatabaseEnv.h" #include "Log.h" #include "MapManager.h" +#include "ObjectMgr.h" //////////////////////////////////////////////////////////// // template class ActivePoolData @@ -177,7 +178,7 @@ PoolObject* PoolGroup<T>::RollOne(ActivePoolData& spawns, uint32 triggerFrom) return &EqualChanced[index]; } - return NULL; + return nullptr; } // Main method to despawn a creature or gameobject in a pool @@ -797,8 +798,8 @@ void PoolMgr::LoadFromDB() if (checkedPools.find(poolItr->second) != checkedPools.end()) { std::ostringstream ss; - ss<< "The pool(s) "; - for (std::set<uint32>::const_iterator itr=checkedPools.begin(); itr != checkedPools.end(); ++itr) + ss << "The pool(s) "; + for (std::set<uint32>::const_iterator itr = checkedPools.begin(); itr != checkedPools.end(); ++itr) ss << *itr << ' '; ss << "create(s) a circular reference, which can cause the server to freeze.\nRemoving the last link between mother pool " << poolItr->first << " and child pool " << poolItr->second; @@ -909,8 +910,8 @@ void PoolMgr::LoadFromDB() uint32 oldMSTime = getMSTime(); QueryResult result = WorldDatabase.Query("SELECT DISTINCT pool_template.entry, pool_pool.pool_id, pool_pool.mother_pool FROM pool_template" - " LEFT JOIN game_event_pool ON pool_template.entry=game_event_pool.pool_entry" - " LEFT JOIN pool_pool ON pool_template.entry=pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL"); + " LEFT JOIN game_event_pool ON pool_template.entry = game_event_pool.pool_entry" + " LEFT JOIN pool_pool ON pool_template.entry = pool_pool.pool_id WHERE game_event_pool.pool_entry IS NULL"); if (!result) { diff --git a/src/server/game/PrecompiledHeaders/gamePCH.cpp b/src/server/game/PrecompiledHeaders/gamePCH.cpp index 11e501ec7f2..b073230fd25 100644 --- a/src/server/game/PrecompiledHeaders/gamePCH.cpp +++ b/src/server/game/PrecompiledHeaders/gamePCH.cpp @@ -1 +1,18 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + #include "gamePCH.h" diff --git a/src/server/game/PrecompiledHeaders/gamePCH.h b/src/server/game/PrecompiledHeaders/gamePCH.h index c7c6ca5d2d6..ba103d21906 100644 --- a/src/server/game/PrecompiledHeaders/gamePCH.h +++ b/src/server/game/PrecompiledHeaders/gamePCH.h @@ -1,10 +1,32 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + //add here most rarely modified headers to speed up debug build compilation -#include "Common.h" -#include "MapManager.h" +#include "Creature.h" +#include "DBCStores.h" +#include "DatabaseEnv.h" +#include "Errors.h" +#include "GameObject.h" #include "Log.h" #include "ObjectAccessor.h" -#include "ObjectDefines.h" -#include "Opcodes.h" -#include "SharedDefines.h" #include "ObjectMgr.h" +#include "PacketUtilities.h" +#include "Player.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 44ba68bcfb3..55100ca7396 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -17,12 +17,14 @@ */ #include "QuestDef.h" -#include "Player.h" -#include "World.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "Log.h" #include "ObjectMgr.h" #include "Opcodes.h" - -#include "Packets/QuestPackets.h" +#include "Player.h" +#include "QuestPackets.h" +#include "World.h" Quest::Quest(Field* questRecord) { diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index eb653ccf096..d2a5e0d5d84 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -19,19 +19,15 @@ #ifndef TRINITYCORE_QUEST_H #define TRINITYCORE_QUEST_H -#include "Define.h" -#include "DatabaseEnv.h" -#include "SharedDefines.h" +#include "Common.h" #include "DBCEnums.h" +#include "DatabaseEnvFwd.h" +#include "SharedDefines.h" #include "WorldPacket.h" - -#include <string> #include <vector> class Player; -class ObjectMgr; - #define MAX_QUEST_LOG_SIZE 25 #define QUEST_OBJECTIVES_COUNT 4 @@ -96,7 +92,7 @@ enum QuestTradeSkill QUEST_TRSKILL_JEWELCRAFTING = 14 }; -enum QuestStatus +enum QuestStatus : uint8 { QUEST_STATUS_NONE = 0, QUEST_STATUS_COMPLETE = 1, @@ -180,14 +176,14 @@ struct QuestLocale { QuestLocale() { ObjectiveText.resize(QUEST_OBJECTIVES_COUNT); } - StringVector Title; - StringVector Details; - StringVector Objectives; - StringVector OfferRewardText; - StringVector RequestItemsText; - StringVector AreaDescription; - StringVector CompletedText; - std::vector< StringVector > ObjectiveText; + std::vector<std::string> Title; + std::vector<std::string> Details; + std::vector<std::string> Objectives; + std::vector<std::string> OfferRewardText; + std::vector<std::string> RequestItemsText; + std::vector<std::string> AreaDescription; + std::vector<std::string> CompletedText; + std::vector<std::vector<std::string>> ObjectiveText; }; // This Quest class provides a convenient way to access a few pretotaled (cached) quest details, diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index 9b290df79ee..b688a212464 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -16,14 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "DatabaseEnv.h" #include "ReputationMgr.h" +#include "DatabaseEnv.h" #include "DBCStores.h" -#include "Player.h" -#include "WorldPacket.h" -#include "World.h" +#include "Log.h" #include "ObjectMgr.h" +#include "Player.h" #include "ScriptMgr.h" +#include "World.h" +#include "WorldPacket.h" #include "WorldSession.h" const int32 ReputationMgr::PointsInRank[MAX_REPUTATION_RANK] = {36000, 3000, 3000, 3000, 6000, 12000, 21000, 1000}; @@ -287,7 +288,7 @@ bool ReputationMgr::SetReputation(FactionEntry const* factionEntry, int32 standi sScriptMgr->OnPlayerReputationChange(_player, factionEntry->ID, standing, incremental); bool res = false; // if spillover definition exists in DB, override DBC - if (const RepSpilloverTemplate* repTemplate = sObjectMgr->GetRepSpilloverTemplate(factionEntry->ID)) + if (RepSpilloverTemplate const* repTemplate = sObjectMgr->GetRepSpilloverTemplate(factionEntry->ID)) { for (uint32 i = 0; i < MAX_SPILLOVER_FACTIONS; ++i) { diff --git a/src/server/game/Reputation/ReputationMgr.h b/src/server/game/Reputation/ReputationMgr.h index b9241bbb10d..1a97d1972af 100644 --- a/src/server/game/Reputation/ReputationMgr.h +++ b/src/server/game/Reputation/ReputationMgr.h @@ -86,13 +86,13 @@ class TC_GAME_API ReputationMgr FactionState const* GetState(FactionEntry const* factionEntry) const { - return factionEntry->CanHaveReputation() ? GetState(factionEntry->reputationListID) : NULL; + return factionEntry->CanHaveReputation() ? GetState(factionEntry->reputationListID) : nullptr; } FactionState const* GetState(RepListID id) const { FactionStateList::const_iterator repItr = _factions.find (id); - return repItr != _factions.end() ? &repItr->second : NULL; + return repItr != _factions.end() ? &repItr->second : nullptr; } bool IsAtWar(uint32 faction_id) const; @@ -112,7 +112,7 @@ class TC_GAME_API ReputationMgr ReputationRank const* GetForcedRankIfAny(FactionTemplateEntry const* factionTemplateEntry) const { ForcedReactions::const_iterator forceItr = _forcedReactions.find(factionTemplateEntry->faction); - return forceItr != _forcedReactions.end() ? &forceItr->second : NULL; + return forceItr != _forcedReactions.end() ? &forceItr->second : nullptr; } public: // modifiers diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 5d71b0ed33e..9f42ded8cc6 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -17,27 +17,32 @@ */ #include "ScriptMgr.h" -#include "ScriptReloadMgr.h" +#include "Chat.h" #include "Config.h" +#include "Creature.h" +#include "CreatureAIImpl.h" #include "DatabaseEnv.h" #include "DBCStores.h" +#include "GossipDef.h" +#include "InstanceScript.h" +#include "Item.h" +#include "LFGScripts.h" +#include "Log.h" +#include "MapManager.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" +#include "Player.h" +#include "ScriptReloadMgr.h" #include "ScriptSystem.h" -#include "Transport.h" -#include "Vehicle.h" #include "SmartAI.h" #include "SpellInfo.h" +#include "SpellMgr.h" #include "SpellScript.h" -#include "GossipDef.h" -#include "CreatureAIImpl.h" -#include "Player.h" +#include "Transport.h" +#include "Vehicle.h" +#include "Weather.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Chat.h" -#include "MapManager.h" -#include "LFGScripts.h" -#include "InstanceScript.h" // Trait which indicates whether this script type // must be assigned in the database. @@ -984,7 +989,7 @@ struct TSpellSummary uint8 Effects; // set of enum SelectEffect } *SpellSummary; -ScriptObject::ScriptObject(const char* name) : _name(name) +ScriptObject::ScriptObject(char const* name) : _name(name) { sScriptMgr->IncreaseScriptCount(); } @@ -1508,7 +1513,7 @@ InstanceScript* ScriptMgr::CreateInstanceData(InstanceMap* map) { ASSERT(map); - GET_SCRIPT_RET(InstanceMapScript, map->GetScriptId(), tmpscript, NULL); + GET_SCRIPT_RET(InstanceMapScript, map->GetScriptId(), tmpscript, nullptr); return tmpscript->GetInstanceScript(map); } @@ -1579,7 +1584,7 @@ CreatureAI* ScriptMgr::GetCreatureAI(Creature* creature) { ASSERT(creature); - GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, NULL); + GET_SCRIPT_RET(CreatureScript, creature->GetScriptId(), tmpscript, nullptr); return tmpscript->GetAI(creature); } @@ -1587,7 +1592,7 @@ GameObjectAI* ScriptMgr::GetGameObjectAI(GameObject* gameobject) { ASSERT(gameobject); - GET_SCRIPT_RET(GameObjectScript, gameobject->GetScriptId(), tmpscript, NULL); + GET_SCRIPT_RET(GameObjectScript, gameobject->GetScriptId(), tmpscript, nullptr); return tmpscript->GetAI(gameobject); } @@ -1604,12 +1609,12 @@ Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/) { /// @todo Implement script-side battlegrounds. ABORT(); - return NULL; + return nullptr; } OutdoorPvP* ScriptMgr::CreateOutdoorPvP(uint32 scriptId) { - GET_SCRIPT_RET(OutdoorPvPScript, scriptId, tmpscript, NULL); + GET_SCRIPT_RET(OutdoorPvPScript, scriptId, tmpscript, nullptr); return tmpscript->GetOutdoorPvP(); } @@ -1624,7 +1629,7 @@ std::vector<ChatCommand> ScriptMgr::GetChatCommands() } // Sort commands in alphabetical order - std::sort(table.begin(), table.end(), [](const ChatCommand& a, const ChatCommand&b) + std::sort(table.begin(), table.end(), [](ChatCommand const& a, ChatCommand const& b) { return strcmp(a.Name, b.Name) < 0; }); @@ -2070,7 +2075,7 @@ void ScriptMgr::OnGroupInviteMember(Group* group, ObjectGuid guid) FOREACH_SCRIPT(GroupScript)->OnInviteMember(group, guid); } -void ScriptMgr::OnGroupRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, const char* reason) +void ScriptMgr::OnGroupRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, char const* reason) { ASSERT(group); FOREACH_SCRIPT(GroupScript)->OnRemoveMember(group, guid, method, kicker, reason); @@ -2119,167 +2124,176 @@ void ScriptMgr::ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& dama FOREACH_SCRIPT(PlayerScript)->ModifySpellDamageTaken(target, attacker, damage); } -SpellScriptLoader::SpellScriptLoader(const char* name) +SpellScriptLoader::SpellScriptLoader(char const* name) : ScriptObject(name) { ScriptRegistry<SpellScriptLoader>::Instance()->AddScript(this); } -ServerScript::ServerScript(const char* name) +ServerScript::ServerScript(char const* name) : ScriptObject(name) { ScriptRegistry<ServerScript>::Instance()->AddScript(this); } -WorldScript::WorldScript(const char* name) +WorldScript::WorldScript(char const* name) : ScriptObject(name) { ScriptRegistry<WorldScript>::Instance()->AddScript(this); } -FormulaScript::FormulaScript(const char* name) +FormulaScript::FormulaScript(char const* name) : ScriptObject(name) { ScriptRegistry<FormulaScript>::Instance()->AddScript(this); } -UnitScript::UnitScript(const char* name, bool addToScripts) +UnitScript::UnitScript(char const* name, bool addToScripts) : ScriptObject(name) { if (addToScripts) ScriptRegistry<UnitScript>::Instance()->AddScript(this); } -WorldMapScript::WorldMapScript(const char* name, uint32 mapId) - : ScriptObject(name), MapScript<Map>(mapId) +WorldMapScript::WorldMapScript(char const* name, uint32 mapId) + : ScriptObject(name), MapScript<Map>(sMapStore.LookupEntry(mapId)) { + if (!GetEntry()) + TC_LOG_ERROR("scripts", "Invalid WorldMapScript for %u; no such map ID.", mapId); + if (GetEntry() && !GetEntry()->IsWorldMap()) TC_LOG_ERROR("scripts", "WorldMapScript for map %u is invalid.", mapId); ScriptRegistry<WorldMapScript>::Instance()->AddScript(this); } -InstanceMapScript::InstanceMapScript(const char* name, uint32 mapId) - : ScriptObject(name), MapScript<InstanceMap>(mapId) +InstanceMapScript::InstanceMapScript(char const* name, uint32 mapId) + : ScriptObject(name), MapScript<InstanceMap>(sMapStore.LookupEntry(mapId)) { + if (!GetEntry()) + TC_LOG_ERROR("scripts", "Invalid InstanceMapScript for %u; no such map ID.", mapId); + if (GetEntry() && !GetEntry()->IsDungeon()) TC_LOG_ERROR("scripts", "InstanceMapScript for map %u is invalid.", mapId); ScriptRegistry<InstanceMapScript>::Instance()->AddScript(this); } -BattlegroundMapScript::BattlegroundMapScript(const char* name, uint32 mapId) - : ScriptObject(name), MapScript<BattlegroundMap>(mapId) +BattlegroundMapScript::BattlegroundMapScript(char const* name, uint32 mapId) + : ScriptObject(name), MapScript<BattlegroundMap>(sMapStore.LookupEntry(mapId)) { + if (!GetEntry()) + TC_LOG_ERROR("scripts", "Invalid BattlegroundMapScript for %u; no such map ID.", mapId); + if (GetEntry() && !GetEntry()->IsBattleground()) TC_LOG_ERROR("scripts", "BattlegroundMapScript for map %u is invalid.", mapId); ScriptRegistry<BattlegroundMapScript>::Instance()->AddScript(this); } -ItemScript::ItemScript(const char* name) +ItemScript::ItemScript(char const* name) : ScriptObject(name) { ScriptRegistry<ItemScript>::Instance()->AddScript(this); } -CreatureScript::CreatureScript(const char* name) +CreatureScript::CreatureScript(char const* name) : UnitScript(name, false) { ScriptRegistry<CreatureScript>::Instance()->AddScript(this); } -GameObjectScript::GameObjectScript(const char* name) +GameObjectScript::GameObjectScript(char const* name) : ScriptObject(name) { ScriptRegistry<GameObjectScript>::Instance()->AddScript(this); } -AreaTriggerScript::AreaTriggerScript(const char* name) +AreaTriggerScript::AreaTriggerScript(char const* name) : ScriptObject(name) { ScriptRegistry<AreaTriggerScript>::Instance()->AddScript(this); } -BattlegroundScript::BattlegroundScript(const char* name) +BattlegroundScript::BattlegroundScript(char const* name) : ScriptObject(name) { ScriptRegistry<BattlegroundScript>::Instance()->AddScript(this); } -OutdoorPvPScript::OutdoorPvPScript(const char* name) +OutdoorPvPScript::OutdoorPvPScript(char const* name) : ScriptObject(name) { ScriptRegistry<OutdoorPvPScript>::Instance()->AddScript(this); } -CommandScript::CommandScript(const char* name) +CommandScript::CommandScript(char const* name) : ScriptObject(name) { ScriptRegistry<CommandScript>::Instance()->AddScript(this); } -WeatherScript::WeatherScript(const char* name) +WeatherScript::WeatherScript(char const* name) : ScriptObject(name) { ScriptRegistry<WeatherScript>::Instance()->AddScript(this); } -AuctionHouseScript::AuctionHouseScript(const char* name) +AuctionHouseScript::AuctionHouseScript(char const* name) : ScriptObject(name) { ScriptRegistry<AuctionHouseScript>::Instance()->AddScript(this); } -ConditionScript::ConditionScript(const char* name) +ConditionScript::ConditionScript(char const* name) : ScriptObject(name) { ScriptRegistry<ConditionScript>::Instance()->AddScript(this); } -VehicleScript::VehicleScript(const char* name) +VehicleScript::VehicleScript(char const* name) : ScriptObject(name) { ScriptRegistry<VehicleScript>::Instance()->AddScript(this); } -DynamicObjectScript::DynamicObjectScript(const char* name) +DynamicObjectScript::DynamicObjectScript(char const* name) : ScriptObject(name) { ScriptRegistry<DynamicObjectScript>::Instance()->AddScript(this); } -TransportScript::TransportScript(const char* name) +TransportScript::TransportScript(char const* name) : ScriptObject(name) { ScriptRegistry<TransportScript>::Instance()->AddScript(this); } -AchievementCriteriaScript::AchievementCriteriaScript(const char* name) +AchievementCriteriaScript::AchievementCriteriaScript(char const* name) : ScriptObject(name) { ScriptRegistry<AchievementCriteriaScript>::Instance()->AddScript(this); } -PlayerScript::PlayerScript(const char* name) +PlayerScript::PlayerScript(char const* name) : UnitScript(name, false) { ScriptRegistry<PlayerScript>::Instance()->AddScript(this); } -AccountScript::AccountScript(const char* name) +AccountScript::AccountScript(char const* name) : ScriptObject(name) { ScriptRegistry<AccountScript>::Instance()->AddScript(this); } -GuildScript::GuildScript(const char* name) +GuildScript::GuildScript(char const* name) : ScriptObject(name) { ScriptRegistry<GuildScript>::Instance()->AddScript(this); } -GroupScript::GroupScript(const char* name) +GroupScript::GroupScript(char const* name) : ScriptObject(name) { ScriptRegistry<GroupScript>::Instance()->AddScript(this); diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index ff89a1314a2..311a7faf911 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -20,12 +20,8 @@ #define SC_SCRIPTMGR_H #include "Common.h" -#include <atomic> -#include "DBCStores.h" -#include "QuestDef.h" -#include "SharedDefines.h" -#include "World.h" -#include "Weather.h" +#include "ObjectGuid.h" +#include <vector> class AccountMgr; class AuctionHouseObject; @@ -59,18 +55,33 @@ class SpellCastTargets; class Transport; class Unit; class Vehicle; +class Weather; class WorldPacket; class WorldSocket; class WorldObject; class WorldSession; struct AchievementCriteriaData; +struct AreaTriggerEntry; struct AuctionEntry; struct ConditionSourceInfo; struct Condition; struct CreatureTemplate; struct CreatureData; struct ItemTemplate; +struct MapEntry; + +enum BattlegroundTypeId : uint32; +enum ContentLevels : uint8; +enum Difficulty : uint8; +enum DuelCompleteType : uint8; +enum QuestStatus : uint8; +enum RemoveMethod : uint8; +enum ShutdownExitCode : uint32; +enum ShutdownMask : uint32; +enum SpellEffIndex : uint8; +enum WeatherState : uint32; +enum XPColorChar : uint8; #define VISIBLE_RANGE 166.0f //MAX visible range (size of grid) @@ -100,7 +111,7 @@ struct ItemTemplate; protected: - MyScriptType(const char* name, uint32 someId) + MyScriptType(char const* name, uint32 someId) : ScriptObject(name), _someId(someId) { ScriptRegistry<MyScriptType>::AddScript(this); @@ -161,7 +172,7 @@ class TC_GAME_API ScriptObject protected: - ScriptObject(const char* name); + ScriptObject(char const* name); virtual ~ScriptObject(); private: @@ -188,22 +199,22 @@ class TC_GAME_API SpellScriptLoader : public ScriptObject { protected: - SpellScriptLoader(const char* name); + SpellScriptLoader(char const* name); public: // Should return a fully valid SpellScript pointer. - virtual SpellScript* GetSpellScript() const { return NULL; } + virtual SpellScript* GetSpellScript() const { return nullptr; } // Should return a fully valid AuraScript pointer. - virtual AuraScript* GetAuraScript() const { return NULL; } + virtual AuraScript* GetAuraScript() const { return nullptr; } }; class TC_GAME_API ServerScript : public ScriptObject { protected: - ServerScript(const char* name); + ServerScript(char const* name); public: @@ -233,7 +244,7 @@ class TC_GAME_API WorldScript : public ScriptObject { protected: - WorldScript(const char* name); + WorldScript(char const* name); public: @@ -266,7 +277,7 @@ class TC_GAME_API FormulaScript : public ScriptObject { protected: - FormulaScript(const char* name); + FormulaScript(char const* name); public: @@ -298,12 +309,7 @@ template<class TMap> class MapScript : public UpdatableScript<TMap> protected: - MapScript(uint32 mapId) - : _mapEntry(sMapStore.LookupEntry(mapId)) - { - if (!_mapEntry) - TC_LOG_ERROR("scripts", "Invalid MapScript for %u; no such map ID.", mapId); - } + MapScript(MapEntry const* mapEntry) : _mapEntry(mapEntry) { } public: @@ -333,7 +339,7 @@ class TC_GAME_API WorldMapScript : public ScriptObject, public MapScript<Map> { protected: - WorldMapScript(const char* name, uint32 mapId); + WorldMapScript(char const* name, uint32 mapId); }; class TC_GAME_API InstanceMapScript @@ -341,26 +347,26 @@ class TC_GAME_API InstanceMapScript { protected: - InstanceMapScript(const char* name, uint32 mapId); + InstanceMapScript(char const* name, uint32 mapId); public: // Gets an InstanceScript object for this instance. - virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return NULL; } + virtual InstanceScript* GetInstanceScript(InstanceMap* /*map*/) const { return nullptr; } }; class TC_GAME_API BattlegroundMapScript : public ScriptObject, public MapScript<BattlegroundMap> { protected: - BattlegroundMapScript(const char* name, uint32 mapId); + BattlegroundMapScript(char const* name, uint32 mapId); }; class TC_GAME_API ItemScript : public ScriptObject { protected: - ItemScript(const char* name); + ItemScript(char const* name); public: @@ -384,7 +390,7 @@ class TC_GAME_API UnitScript : public ScriptObject { protected: - UnitScript(const char* name, bool addToScripts = true); + UnitScript(char const* name, bool addToScripts = true); public: // Called when a unit deals healing to another unit @@ -407,7 +413,7 @@ class TC_GAME_API CreatureScript : public UnitScript { protected: - CreatureScript(const char* name); + CreatureScript(char const* name); public: @@ -422,7 +428,7 @@ class TC_GAME_API GameObjectScript : public ScriptObject { protected: - GameObjectScript(const char* name); + GameObjectScript(char const* name); public: @@ -434,7 +440,7 @@ class TC_GAME_API AreaTriggerScript : public ScriptObject { protected: - AreaTriggerScript(const char* name); + AreaTriggerScript(char const* name); public: @@ -446,7 +452,7 @@ class TC_GAME_API BattlegroundScript : public ScriptObject { protected: - BattlegroundScript(const char* name); + BattlegroundScript(char const* name); public: @@ -458,7 +464,7 @@ class TC_GAME_API OutdoorPvPScript : public ScriptObject { protected: - OutdoorPvPScript(const char* name); + OutdoorPvPScript(char const* name); public: @@ -470,7 +476,7 @@ class TC_GAME_API CommandScript : public ScriptObject { protected: - CommandScript(const char* name); + CommandScript(char const* name); public: @@ -482,7 +488,7 @@ class TC_GAME_API WeatherScript : public ScriptObject, public UpdatableScript<We { protected: - WeatherScript(const char* name); + WeatherScript(char const* name); public: @@ -494,7 +500,7 @@ class TC_GAME_API AuctionHouseScript : public ScriptObject { protected: - AuctionHouseScript(const char* name); + AuctionHouseScript(char const* name); public: @@ -515,7 +521,7 @@ class TC_GAME_API ConditionScript : public ScriptObject { protected: - ConditionScript(const char* name); + ConditionScript(char const* name); public: @@ -527,7 +533,7 @@ class TC_GAME_API VehicleScript : public ScriptObject { protected: - VehicleScript(const char* name); + VehicleScript(char const* name); public: @@ -554,14 +560,14 @@ class TC_GAME_API DynamicObjectScript : public ScriptObject, public UpdatableScr { protected: - DynamicObjectScript(const char* name); + DynamicObjectScript(char const* name); }; class TC_GAME_API TransportScript : public ScriptObject, public UpdatableScript<Transport> { protected: - TransportScript(const char* name); + TransportScript(char const* name); public: @@ -582,7 +588,7 @@ class TC_GAME_API AchievementCriteriaScript : public ScriptObject { protected: - AchievementCriteriaScript(const char* name); + AchievementCriteriaScript(char const* name); public: @@ -594,7 +600,7 @@ class TC_GAME_API PlayerScript : public UnitScript { protected: - PlayerScript(const char* name); + PlayerScript(char const* name); public: @@ -694,7 +700,7 @@ class TC_GAME_API AccountScript : public ScriptObject { protected: - AccountScript(const char* name); + AccountScript(char const* name); public: @@ -721,7 +727,7 @@ class TC_GAME_API GuildScript : public ScriptObject { protected: - GuildScript(const char* name); + GuildScript(char const* name); public: @@ -762,7 +768,7 @@ class TC_GAME_API GroupScript : public ScriptObject { protected: - GroupScript(const char* name); + GroupScript(char const* name); public: @@ -773,7 +779,7 @@ class TC_GAME_API GroupScript : public ScriptObject virtual void OnInviteMember(Group* /*group*/, ObjectGuid /*guid*/) { } // Called when a member is removed from a group. - virtual void OnRemoveMember(Group* /*group*/, ObjectGuid /*guid*/, RemoveMethod /*method*/, ObjectGuid /*kicker*/, const char* /*reason*/) { } + virtual void OnRemoveMember(Group* /*group*/, ObjectGuid /*guid*/, RemoveMethod /*method*/, ObjectGuid /*kicker*/, char const* /*reason*/) { } // Called when the leader of a group is changed. virtual void OnChangeLeader(Group* /*group*/, ObjectGuid /*newLeaderGuid*/, ObjectGuid /*oldLeaderGuid*/) { } @@ -1027,7 +1033,7 @@ class TC_GAME_API ScriptMgr void OnGroupAddMember(Group* group, ObjectGuid guid); void OnGroupInviteMember(Group* group, ObjectGuid guid); - void OnGroupRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, const char* reason); + void OnGroupRemoveMember(Group* group, ObjectGuid guid, RemoveMethod method, ObjectGuid kicker, char const* reason); void OnGroupChangeLeader(Group* group, ObjectGuid newLeaderGuid, ObjectGuid oldLeaderGuid); void OnGroupDisband(Group* group); diff --git a/src/server/game/Scripting/ScriptReloadMgr.cpp b/src/server/game/Scripting/ScriptReloadMgr.cpp index 18b910420b1..04c15b67c86 100644 --- a/src/server/game/Scripting/ScriptReloadMgr.cpp +++ b/src/server/game/Scripting/ScriptReloadMgr.cpp @@ -17,6 +17,7 @@ #include "ScriptReloadMgr.h" #include "Errors.h" +#include "Optional.h" #ifndef TRINITY_API_USE_DYNAMIC_LINKING @@ -36,31 +37,30 @@ ScriptReloadMgr* ScriptReloadMgr::instance() #else +#include "BuiltInConfig.h" +#include "Config.h" +#include "GitRevision.h" +#include "Log.h" +#include "MPSCQueue.h" +#include "Regex.h" +#include "ScriptMgr.h" +#include "SHA1.h" +#include "StartProcess.h" +#include "Timer.h" +#include "World.h" +#include <boost/algorithm/string/replace.hpp> +#include <boost/filesystem.hpp> +#include <boost/system/system_error.hpp> +#include <efsw/efsw.hpp> #include <algorithm> -#include <vector> +#include <fstream> #include <future> #include <memory> -#include <fstream> +#include <sstream> #include <type_traits> -#include <unordered_set> #include <unordered_map> - -#include "Regex.h" - -#include <boost/algorithm/string/replace.hpp> -#include <boost/filesystem.hpp> -#include <boost/system/system_error.hpp> - -#include "efsw/efsw.hpp" - -#include "Log.h" -#include "Config.h" -#include "BuiltInConfig.h" -#include "ScriptMgr.h" -#include "SHA1.h" -#include "StartProcess.h" -#include "MPSCQueue.h" -#include "GitRevision.h" +#include <unordered_set> +#include <vector> namespace fs = boost::filesystem; diff --git a/src/server/game/Scripting/ScriptSystem.cpp b/src/server/game/Scripting/ScriptSystem.cpp index a310d4d6ee0..1b4ad6b98d5 100644 --- a/src/server/game/Scripting/ScriptSystem.cpp +++ b/src/server/game/Scripting/ScriptSystem.cpp @@ -17,10 +17,15 @@ */ #include "ScriptSystem.h" -#include "ObjectMgr.h" +#include "Creature.h" #include "DatabaseEnv.h" +#include "Log.h" +#include "ObjectMgr.h" #include "ScriptMgr.h" -#include "Creature.h" +#include "SplineChain.h" + +SystemMgr::SystemMgr() = default; +SystemMgr::~SystemMgr() = default; SystemMgr* SystemMgr::instance() { @@ -108,7 +113,7 @@ void SystemMgr::LoadScriptSplineChains() uint32 entry = fieldsMeta[0].GetUInt32(); uint16 chainId = fieldsMeta[1].GetUInt16(); uint8 splineId = fieldsMeta[2].GetUInt8(); - SplineChain& chain = m_mSplineChainsMap[{entry,chainId}]; + std::vector<SplineChainLink>& chain = m_mSplineChainsMap[{entry, chainId}]; if (splineId != chain.size()) { @@ -116,8 +121,9 @@ void SystemMgr::LoadScriptSplineChains() continue; } - uint32 expectedDuration = fieldsMeta[3].GetUInt32(), msUntilNext = fieldsMeta[4].GetUInt32(); - chain.push_back(SplineChainLink(expectedDuration, msUntilNext)); + uint32 expectedDuration = fieldsMeta[3].GetUInt32(); + uint32 msUntilNext = fieldsMeta[4].GetUInt32(); + chain.emplace_back(expectedDuration, msUntilNext); if (splineId == 0) ++chainCount; @@ -137,7 +143,7 @@ void SystemMgr::LoadScriptSplineChains() TC_LOG_WARN("server.loading", "Creature #%u has waypoint data for spline chain %u. No such chain exists - entry skipped.", entry, chainId); continue; } - SplineChain& chain = it->second; + std::vector<SplineChainLink>& chain = it->second; if (splineId >= chain.size()) { TC_LOG_WARN("server.loading", "Creature #%u has waypoint data for spline (%u,%u). The specified chain does not have a spline with this index - entry skipped.", entry, chainId, splineId); @@ -157,7 +163,15 @@ void SystemMgr::LoadScriptSplineChains() } } -SplineChain const* SystemMgr::GetSplineChain(Creature const* who, uint16 id) const +std::vector<SplineChainLink> const* SystemMgr::GetSplineChain(uint32 entry, uint16 chainId) const +{ + auto it = m_mSplineChainsMap.find({ entry, chainId }); + if (it == m_mSplineChainsMap.end()) + return nullptr; + return &it->second; +} + +std::vector<SplineChainLink> const* SystemMgr::GetSplineChain(Creature const* who, uint16 id) const { return GetSplineChain(who->GetEntry(), id); } diff --git a/src/server/game/Scripting/ScriptSystem.h b/src/server/game/Scripting/ScriptSystem.h index c67316eb64b..7828c24d680 100644 --- a/src/server/game/Scripting/ScriptSystem.h +++ b/src/server/game/Scripting/ScriptSystem.h @@ -1,14 +1,31 @@ -/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> -* This program is free software licensed under GPL version 2 -* Please see the included DOCS/LICENSE.TXT for more information */ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ #ifndef SC_SYSTEM_H #define SC_SYSTEM_H -#include "ScriptMgr.h" -#include "SplineChain.h" +#include "Define.h" +#include "Hash.h" +#include <unordered_map> +#include <vector> class Creature; +struct SplineChainLink; #define TEXT_SOURCE_RANGE -1000000 //the amount of entries each text source has available @@ -27,8 +44,10 @@ typedef std::vector<ScriptPointMove> ScriptPointVector; class TC_GAME_API SystemMgr { private: - SystemMgr() { } - ~SystemMgr() { } + SystemMgr(); + ~SystemMgr(); + SystemMgr(SystemMgr const&) = delete; + SystemMgr& operator=(SystemMgr const&) = delete; public: static SystemMgr* instance(); @@ -49,20 +68,13 @@ class TC_GAME_API SystemMgr return &itr->second; } - SplineChain const* GetSplineChain(uint32 entry, uint16 chainId) const - { - auto it = m_mSplineChainsMap.find({ entry, chainId }); - if (it == m_mSplineChainsMap.end()) - return nullptr; - return &it->second; - } - - SplineChain const* GetSplineChain(Creature const* who, uint16 id) const; + std::vector<SplineChainLink> const* GetSplineChain(uint32 entry, uint16 chainId) const; + std::vector<SplineChainLink> const* GetSplineChain(Creature const* who, uint16 id) const; protected: PointMoveMap m_mPointMoveMap; //coordinates for waypoints typedef std::pair<uint32, uint16> ChainKeyType; // creature entry + chain ID - std::unordered_map<ChainKeyType, SplineChain> m_mSplineChainsMap; // spline chains + std::unordered_map<ChainKeyType, std::vector<SplineChainLink>> m_mSplineChainsMap; // spline chains }; #define sScriptSystemMgr SystemMgr::instance() diff --git a/src/server/game/Server/Packet.cpp b/src/server/game/Server/Packet.cpp new file mode 100644 index 00000000000..bc4812a765d --- /dev/null +++ b/src/server/game/Server/Packet.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "Packet.h" +#include "Errors.h" + +WorldPackets::Packet::Packet(WorldPacket&& worldPacket) : _worldPacket(std::move(worldPacket)) +{ +} + +WorldPackets::ServerPacket::ServerPacket(OpcodeServer opcode, size_t initialSize /*= 200*/) : Packet(WorldPacket(opcode, initialSize)) +{ +} + +void WorldPackets::ServerPacket::Read() +{ + ASSERT(!"Read not implemented for server packets."); +} + +WorldPackets::ClientPacket::ClientPacket(OpcodeClient expectedOpcode, WorldPacket&& packet) : Packet(std::move(packet)) +{ + ASSERT(GetOpcode() == expectedOpcode); +} + +WorldPackets::ClientPacket::ClientPacket(WorldPacket&& packet) + : Packet(std::move(packet)) +{ +} + +WorldPacket const* WorldPackets::ClientPacket::Write() +{ + ASSERT(!"Write not allowed for client packets."); + // Shut up some compilers + return nullptr; +} diff --git a/src/server/game/Server/Packet.h b/src/server/game/Server/Packet.h index 780e3850a27..8302e6b1353 100644 --- a/src/server/game/Server/Packet.h +++ b/src/server/game/Server/Packet.h @@ -25,7 +25,7 @@ namespace WorldPackets class TC_GAME_API Packet { public: - Packet(WorldPacket&& worldPacket) : _worldPacket(std::move(worldPacket)) { } + Packet(WorldPacket&& worldPacket); virtual ~Packet() = default; @@ -42,12 +42,12 @@ namespace WorldPackets WorldPacket _worldPacket; }; - class ServerPacket : public Packet + class TC_GAME_API ServerPacket : public Packet { public: - ServerPacket(OpcodeServer opcode, size_t initialSize = 200) : Packet(WorldPacket(opcode, initialSize)) { } + ServerPacket(OpcodeServer opcode, size_t initialSize = 200); - void Read() override final { ASSERT(!"Read not implemented for server packets."); } + void Read() override final; void Clear() { _worldPacket.clear(); } WorldPacket&& Move() { return std::move(_worldPacket); } @@ -55,18 +55,13 @@ namespace WorldPackets OpcodeServer GetOpcode() const { return OpcodeServer(_worldPacket.GetOpcode()); } }; - class ClientPacket : public Packet + class TC_GAME_API ClientPacket : public Packet { public: - ClientPacket(WorldPacket&& packet) : Packet(std::move(packet)) { } - ClientPacket(OpcodeClient expectedOpcode, WorldPacket&& packet) : Packet(std::move(packet)) { ASSERT(GetOpcode() == expectedOpcode); } - - WorldPacket const* Write() override final - { - ASSERT(!"Write not allowed for client packets."); - // Shut up some compilers - return nullptr; - } + ClientPacket(WorldPacket&& packet); + ClientPacket(OpcodeClient expectedOpcode, WorldPacket&& packet); + + WorldPacket const* Write() override final; OpcodeClient GetOpcode() const { return OpcodeClient(_worldPacket.GetOpcode()); } }; diff --git a/src/server/game/Server/Packets/PacketUtilities.cpp b/src/server/game/Server/Packets/PacketUtilities.cpp new file mode 100644 index 00000000000..4d87feaabc5 --- /dev/null +++ b/src/server/game/Server/Packets/PacketUtilities.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "PacketUtilities.h" +#include "Errors.h" +#include <sstream> +#include <array> + +WorldPackets::PacketArrayMaxCapacityException::PacketArrayMaxCapacityException(std::size_t requestedSize, std::size_t sizeLimit) +{ + std::ostringstream builder; + builder << "Attempted to read more array elements from packet " << requestedSize << " than allowed " << sizeLimit; + message().assign(builder.str()); +} + +void WorldPackets::CheckCompactArrayMaskOverflow(std::size_t index, std::size_t limit) +{ + ASSERT(index < limit, "Attempted to insert " SZFMTD " values into CompactArray but it can only hold " SZFMTD, index, limit); +} diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h index e4f40580a30..e1229e1ae1c 100644 --- a/src/server/game/Server/Packets/PacketUtilities.h +++ b/src/server/game/Server/Packets/PacketUtilities.h @@ -19,46 +19,13 @@ #define PacketUtilities_h__ #include "ByteBuffer.h" -#include <G3D/Vector2.h> -#include <G3D/Vector3.h> -#include <sstream> -#include <array> - -inline ByteBuffer& operator<<(ByteBuffer& data, G3D::Vector2 const& v) -{ - data << v.x << v.y; - return data; -} - -inline ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector2& v) -{ - data >> v.x >> v.y; - return data; -} - -inline ByteBuffer& operator<<(ByteBuffer& data, G3D::Vector3 const& v) -{ - data << v.x << v.y << v.z; - return data; -} - -inline ByteBuffer& operator>>(ByteBuffer& data, G3D::Vector3& v) -{ - data >> v.x >> v.y >> v.z; - return data; -} namespace WorldPackets { class PacketArrayMaxCapacityException : public ByteBufferException { public: - PacketArrayMaxCapacityException(std::size_t requestedSize, std::size_t sizeLimit) - { - std::ostringstream builder; - builder << "Attempted to read more array elements from packet " << requestedSize << " than allowed " << sizeLimit; - message().assign(builder.str()); - } + PacketArrayMaxCapacityException(std::size_t requestedSize, std::size_t sizeLimit); }; /** @@ -129,6 +96,8 @@ namespace WorldPackets size_type _limit; }; + void CheckCompactArrayMaskOverflow(std::size_t index, std::size_t limit); + template <typename T> class CompactArray { @@ -144,14 +113,14 @@ namespace WorldPackets right._mask = 0; } - CompactArray& operator= (CompactArray const& right) + CompactArray& operator=(CompactArray const& right) { _mask = right._mask; _contents = right._contents; return *this; } - CompactArray& operator= (CompactArray&& right) + CompactArray& operator=(CompactArray&& right) { _mask = right._mask; right._mask = 0; @@ -160,12 +129,12 @@ namespace WorldPackets } uint32 GetMask() const { return _mask; } - T const& operator[](size_t index) const { return _contents.at(index); } - size_t GetSize() const { return _contents.size(); } + T const& operator[](std::size_t index) const { return _contents.at(index); } + std::size_t GetSize() const { return _contents.size(); } - void Insert(size_t index, T const& value) + void Insert(std::size_t index, T const& value) { - ASSERT(index < 0x20); + CheckCompactArrayMaskOverflow(index, sizeof(_mask) * 8); _mask |= 1 << index; if (_contents.size() <= index) @@ -199,11 +168,9 @@ namespace WorldPackets { uint32 mask = v.GetMask(); data << uint32(mask); - for (size_t i = 0; i < v.GetSize(); ++i) - { + for (std::size_t i = 0; i < v.GetSize(); ++i) if (mask & (1 << i)) data << v[i]; - } return data; } @@ -214,15 +181,9 @@ namespace WorldPackets uint32 mask; data >> mask; - for (size_t index = 0; mask != 0; mask >>= 1, ++index) - { + for (std::size_t index = 0; mask != 0; mask >>= 1, ++index) if ((mask & 1) != 0) - { - T value; - data >> value; - v.Insert(index, value); - } - } + v.Insert(index, data.read<T>()); return data; } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 316335ffd47..ce095d36a72 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -17,8 +17,11 @@ */ #include "Opcodes.h" +#include "Log.h" #include "WorldSession.h" #include "Packets/AllPackets.h" +#include <iomanip> +#include <sstream> template<class PacketClass, void(WorldSession::*HandlerFunction)(PacketClass&)> class PacketHandler : public ClientOpcodeHandler @@ -59,6 +62,17 @@ struct get_packet_class<void(WorldSession::*)(PacketClass&)> using type = PacketClass; }; +OpcodeTable::OpcodeTable() +{ + memset(_internalTableClient, 0, sizeof(_internalTableClient)); +} + +OpcodeTable::~OpcodeTable() +{ + for (uint16 i = 0; i < NUM_OPCODE_HANDLERS; ++i) + delete _internalTableClient[i]; +} + template<typename Handler, Handler HandlerFunction> void OpcodeTable::ValidateAndSetClientOpcode(OpcodeClient opcode, char const* name, SessionStatus status, PacketProcessing processing) { @@ -74,7 +88,7 @@ void OpcodeTable::ValidateAndSetClientOpcode(OpcodeClient opcode, char const* na return; } - if (_internalTableClient[opcode] != NULL) + if (_internalTableClient[opcode] != nullptr) { TC_LOG_ERROR("network", "Tried to override client handler of %s with %s (opcode %u)", opcodeTable[opcode]->Name, name, opcode); return; @@ -97,7 +111,7 @@ void OpcodeTable::ValidateAndSetServerOpcode(OpcodeServer opcode, char const* na return; } - if (_internalTableClient[opcode] != NULL) + if (_internalTableClient[opcode] != nullptr) { TC_LOG_ERROR("network", "Tried to override server handler of %s with %s (opcode %u)", opcodeTable[opcode]->Name, name, opcode); return; @@ -1430,4 +1444,30 @@ void OpcodeTable::Initialize() #undef DEFINE_HANDLER #undef DEFINE_SERVER_OPCODE_HANDLER -};
\ No newline at end of file +} + +template<typename T> +inline std::string GetOpcodeNameForLoggingImpl(T id) +{ + uint16 opcode = uint16(id); + std::ostringstream ss; + ss << '['; + + if (static_cast<uint16>(id) < NUM_OPCODE_HANDLERS) + { + if (OpcodeHandler const* handler = opcodeTable[id]) + ss << handler->Name; + else + ss << "UNKNOWN OPCODE"; + } + else + ss << "INVALID OPCODE"; + + ss << " 0x" << std::hex << std::setw(4) << std::setfill('0') << std::uppercase << opcode << std::nouppercase << std::dec << " (" << opcode << ")]"; + return ss.str(); +} + +std::string GetOpcodeNameForLogging(Opcodes opcode) +{ + return GetOpcodeNameForLoggingImpl(opcode); +} diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 9437da07d0b..85e9b395f56 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -23,8 +23,8 @@ #ifndef _OPCODES_H #define _OPCODES_H -#include "Common.h" -#include <iomanip> +#include "Define.h" +#include <string> enum Opcodes : uint16 { @@ -1371,8 +1371,6 @@ enum PacketProcessing class WorldSession; class WorldPacket; -#pragma pack(push, 1) - class OpcodeHandler { public: @@ -1404,21 +1402,12 @@ public: class OpcodeTable { public: - OpcodeTable() - { - memset(_internalTableClient, 0, sizeof(_internalTableClient)); - } + OpcodeTable(); OpcodeTable(OpcodeTable const&) = delete; OpcodeTable& operator=(OpcodeTable const&) = delete; - ~OpcodeTable() - { - for (uint16 i = 0; i < NUM_OPCODE_HANDLERS; ++i) - { - delete _internalTableClient[i]; - } - } + ~OpcodeTable(); void Initialize(); @@ -1438,29 +1427,8 @@ class OpcodeTable extern OpcodeTable opcodeTable; -#pragma pack(pop) - -/// Lookup opcode name for human understandable logging (T = OpcodeClient|OpcodeServer) -template<typename T> -inline std::string GetOpcodeNameForLogging(T id) -{ - uint16 opcode = uint16(id); - std::ostringstream ss; - ss << '['; - - if (static_cast<uint16>(id) < NUM_OPCODE_HANDLERS) - { - if (OpcodeHandler const* handler = opcodeTable[id]) - ss << handler->Name; - else - ss << "UNKNOWN OPCODE"; - } - else - ss << "INVALID OPCODE"; - - ss << " 0x" << std::hex << std::setw(4) << std::setfill('0') << std::uppercase << opcode << std::nouppercase << std::dec << " (" << opcode << ")]"; - return ss.str(); -} +/// Lookup opcode name for human understandable logging +std::string GetOpcodeNameForLogging(Opcodes opcode); #endif /// @} diff --git a/src/server/game/Server/Protocol/PacketLog.cpp b/src/server/game/Server/Protocol/PacketLog.cpp index 0bbaf9c6e98..50e8786defa 100644 --- a/src/server/game/Server/Protocol/PacketLog.cpp +++ b/src/server/game/Server/Protocol/PacketLog.cpp @@ -56,7 +56,7 @@ struct PacketHeader #pragma pack(pop) -PacketLog::PacketLog() : _file(NULL) +PacketLog::PacketLog() : _file(nullptr) { std::call_once(_initializeFlag, &PacketLog::Initialize, this); } @@ -66,7 +66,7 @@ PacketLog::~PacketLog() if (_file) fclose(_file); - _file = NULL; + _file = nullptr; } PacketLog* PacketLog::instance() @@ -95,7 +95,7 @@ void PacketLog::Initialize() header.Build = 12340; header.Locale[0] = 'e'; header.Locale[1] = 'n'; header.Locale[2] = 'U'; header.Locale[3] = 'S'; std::memset(header.SessionKey, 0, sizeof(header.SessionKey)); - header.SniffStartUnixtime = time(NULL); + header.SniffStartUnixtime = time(nullptr); header.SniffStartTicks = getMSTime(); header.OptionalDataSize = 0; diff --git a/src/server/game/Server/Protocol/PacketLog.h b/src/server/game/Server/Protocol/PacketLog.h index e6082940197..0830f5a583b 100644 --- a/src/server/game/Server/Protocol/PacketLog.h +++ b/src/server/game/Server/Protocol/PacketLog.h @@ -43,7 +43,7 @@ class TC_GAME_API PacketLog static PacketLog* instance(); void Initialize(); - bool CanLogPacket() const { return (_file != NULL); } + bool CanLogPacket() const { return (_file != nullptr); } void LogPacket(WorldPacket const& packet, Direction direction, boost::asio::ip::address const& addr, uint16 port); private: diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index 7eda06aefec..a7a959bd0ea 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -20,33 +20,36 @@ \ingroup u2w */ -#include "WorldSocket.h" +#include "WorldSession.h" +#include "AccountMgr.h" +#include "AddonMgr.h" +#include "BattlegroundMgr.h" #include "Config.h" #include "Common.h" #include "DatabaseEnv.h" -#include "QueryCallback.h" -#include "AccountMgr.h" -#include "Log.h" -#include "Opcodes.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "Player.h" -#include "Vehicle.h" -#include "ObjectMgr.h" -#include "GuildMgr.h" +#include "DBCStructure.h" #include "Group.h" #include "Guild.h" -#include "World.h" -#include "BattlegroundMgr.h" +#include "GuildMgr.h" +#include "Log.h" +#include "Map.h" +#include "Metric.h" +#include "MoveSpline.h" +#include "ObjectMgr.h" +#include "Opcodes.h" #include "OutdoorPvPMgr.h" -#include "SocialMgr.h" +#include "PacketUtilities.h" +#include "Player.h" +#include "Realm.h" #include "ScriptMgr.h" -#include "WardenWin.h" -#include "MoveSpline.h" +#include "SocialMgr.h" +#include "QueryHolder.h" +#include "Vehicle.h" #include "WardenMac.h" -#include "PacketUtilities.h" -#include "Metric.h" - +#include "WardenWin.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSocket.h" #include <zlib.h> namespace { @@ -104,13 +107,13 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldS m_timeOutTime(0), AntiDOS(this), m_GUIDLow(0), - _player(NULL), + _player(nullptr), m_Socket(sock), _security(sec), _accountId(id), _accountName(std::move(name)), m_expansion(expansion), - _warden(NULL), + _warden(nullptr), _logoutTime(0), m_inQueue(false), m_playerLoading(false), @@ -124,7 +127,7 @@ WorldSession::WorldSession(uint32 id, std::string&& name, std::shared_ptr<WorldS m_TutorialsChanged(TUTORIALS_FLAG_NONE), recruiterId(recruiter), isRecruiter(isARecruiter), - _RBACData(NULL), + _RBACData(nullptr), expireTime(60000), // 1 min after socket loss, session is deleted forceExit(false), m_currentBankerGUID() @@ -158,7 +161,7 @@ WorldSession::~WorldSession() delete _RBACData; ///- empty incoming packet queue - WorldPacket* packet = NULL; + WorldPacket* packet = nullptr; while (_recvQueue.next(packet)) delete packet; @@ -167,7 +170,7 @@ WorldSession::~WorldSession() std::string const & WorldSession::GetPlayerName() const { - return _player != NULL ? _player->GetName() : DefaultPlayerName; + return _player != nullptr ? _player->GetName() : DefaultPlayerName; } std::string WorldSession::GetPlayerInfo() const @@ -202,21 +205,21 @@ void WorldSession::SendPacket(WorldPacket const* packet) static uint64 sendPacketCount = 0; static uint64 sendPacketBytes = 0; - static time_t firstTime = time(NULL); + static time_t firstTime = time(nullptr); static time_t lastTime = firstTime; // next 60 secs start time static uint64 sendLastPacketCount = 0; static uint64 sendLastPacketBytes = 0; - time_t cur_time = time(NULL); + time_t cur_time = time(nullptr); if ((cur_time - lastTime) < 60) { - sendPacketCount+=1; - sendPacketBytes+=packet->size(); + sendPacketCount += 1; + sendPacketBytes += packet->size(); - sendLastPacketCount+=1; - sendLastPacketBytes+=packet->size(); + sendLastPacketCount += 1; + sendLastPacketBytes += packet->size(); } else { @@ -244,7 +247,7 @@ void WorldSession::QueuePacket(WorldPacket* new_packet) } /// Logging helper for unexpected opcodes -void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason) +void WorldSession::LogUnexpectedOpcode(WorldPacket* packet, char const* status, const char *reason) { TC_LOG_ERROR("network.opcode", "Received unexpected opcode %s Status: %s Reason: %s from %s", GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str(), status, reason, GetPlayerInfo().c_str()); @@ -274,12 +277,12 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) ///- Retrieve packets from the receive queue and call the appropriate handlers /// not process packets if socket already closed - WorldPacket* packet = NULL; + WorldPacket* packet = nullptr; //! Delete packet after processing by default bool deletePacket = true; std::vector<WorldPacket*> requeuePackets; uint32 processedPackets = 0; - time_t currentTime = time(NULL); + time_t currentTime = time(nullptr); while (m_Socket && _recvQueue.next(packet, updater)) { @@ -403,7 +406,7 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater) //logout procedure should happen only in World::UpdateSessions() method!!! if (updater.ProcessLogout()) { - time_t currTime = time(NULL); + time_t currTime = time(nullptr); ///- If necessary, log the player out if (ShouldLogOut(currTime) && !m_playerLoading) LogoutPlayer(true); @@ -493,7 +496,7 @@ void WorldSession::LogoutPlayer(bool save) } } - // Repop at GraveYard or other player far teleport will prevent saving player because of not present map + // Repop at Graveyard or other player far teleport will prevent saving player because of not present map // Teleport player immediately for correct player save while (_player->IsBeingTeleportedFar()) HandleMoveWorldportAck(); @@ -503,7 +506,7 @@ void WorldSession::LogoutPlayer(bool save) guild->HandleMemberLogout(this); ///- Remove pet - _player->RemovePet(NULL, PET_SAVE_AS_CURRENT, true); + _player->RemovePet(nullptr, PET_SAVE_AS_CURRENT, true); ///- Clear whisper whitelist _player->ClearWhisperWhiteList(); @@ -560,7 +563,7 @@ void WorldSession::LogoutPlayer(bool save) if (Map* _map = _player->FindMap()) _map->RemovePlayerFromMap(_player, true); - SetPlayer(NULL); //! Pointer already deleted during RemovePlayerFromMap + SetPlayer(nullptr); //! Pointer already deleted during RemovePlayerFromMap //! Send the 'logout complete' packet to the client //! Client will respond by sending 3x CMSG_CANCEL_TRADE, which we currently dont handle @@ -630,6 +633,11 @@ char const* WorldSession::GetTrinityString(uint32 entry) const return sObjectMgr->GetTrinityString(entry, GetSessionDbLocaleIndex()); } +void WorldSession::ResetTimeOutTime() +{ + m_timeOutTime = int32(sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME)); +} + void WorldSession::Handle_NULL(WorldPacket& null) { TC_LOG_ERROR("network.opcode", "Received unhandled opcode %s from %s", GetOpcodeNameForLogging(static_cast<OpcodeClient>(null.GetOpcode())).c_str(), GetPlayerInfo().c_str()); @@ -737,7 +745,7 @@ void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string c void WorldSession::SendAccountDataTimes(uint32 mask) { WorldPacket data(SMSG_ACCOUNT_DATA_TIMES, 4 + 1 + 4 + NUM_ACCOUNT_DATA_TYPES * 4); - data << uint32(time(NULL)); // Server time + data << uint32(time(nullptr)); // Server time data << uint8(1); data << uint32(mask); // type mask for (uint32 i = 0; i < NUM_ACCOUNT_DATA_TYPES; ++i) @@ -1221,7 +1229,7 @@ void WorldSession::InvalidateRBACData() TC_LOG_DEBUG("rbac", "WorldSession::Invalidaterbac::RBACData [AccountId: %u, Name: %s, realmId: %d]", _RBACData->GetId(), _RBACData->GetName().c_str(), realm.Id.Realm); delete _RBACData; - _RBACData = NULL; + _RBACData = nullptr; } bool WorldSession::DosProtection::EvaluateOpcode(WorldPacket& p, time_t time) const @@ -1515,3 +1523,7 @@ uint32 WorldSession::DosProtection::GetMaxPacketCounterAllowed(uint16 opcode) co return maxPacketCounterAllowed; } + +WorldSession::DosProtection::DosProtection(WorldSession* s) : Session(s), _policy((Policy)sWorld->getIntConfig(CONFIG_PACKET_SPOOF_POLICY)) +{ +} diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index eea430ac1b5..9271fb06e06 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -24,15 +24,15 @@ #define __WORLDSESSION_H #include "Common.h" -#include "SharedDefines.h" -#include "AddonMgr.h" -#include "DatabaseEnv.h" -#include "World.h" +#include "DatabaseEnvFwd.h" +#include "LockedQueue.h" +#include "ObjectGuid.h" #include "Packet.h" -#include "Cryptography/BigNumber.h" -#include "AccountMgr.h" -#include <unordered_set> +#include "QueryCallbackProcessor.h" +#include "SharedDefines.h" +#include <unordered_map> +class BigNumber; class Creature; class GameObject; class InstanceSave; @@ -46,6 +46,7 @@ class Unit; class Warden; class WorldPacket; class WorldSocket; +struct AddonInfo; struct AreaTableEntry; struct AuctionEntry; struct DeclinedName; @@ -284,7 +285,7 @@ class TC_GAME_API WorldSession void SendNotification(uint32 string_id, ...); void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName); void SendPartyResult(PartyOperation operation, std::string const& member, PartyResult res, uint32 val = 0); - void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3); + void SendAreaTriggerMessage(char const* Text, ...) ATTR_PRINTF(2, 3); void SendSetPhaseShift(uint32 phaseShift); void SendQueryTimeResponse(); @@ -438,10 +439,7 @@ class TC_GAME_API WorldSession m_timeOutTime -= int32(diff); } - void ResetTimeOutTime() - { - m_timeOutTime = int32(sWorld->getIntConfig(CONFIG_SOCKET_TIMEOUTTIME)); - } + void ResetTimeOutTime(); bool IsConnectionIdle() const { @@ -999,7 +997,7 @@ class TC_GAME_API WorldSession { friend class World; public: - DosProtection(WorldSession* s) : Session(s), _policy((Policy)sWorld->getIntConfig(CONFIG_PACKET_SPOOF_POLICY)) { } + DosProtection(WorldSession* s); bool EvaluateOpcode(WorldPacket& p, time_t time) const; protected: enum Policy @@ -1030,7 +1028,7 @@ class TC_GAME_API WorldSession bool CanUseBank(ObjectGuid bankerGUID = ObjectGuid::Empty) const; // logging helper - void LogUnexpectedOpcode(WorldPacket* packet, const char* status, const char *reason); + void LogUnexpectedOpcode(WorldPacket* packet, char const* status, const char *reason); void LogUnprocessedTail(WorldPacket* packet); // EnumData helpers diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index ae8b3fd0998..699c5a38a92 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -18,12 +18,16 @@ #include "WorldSocket.h" #include "BigNumber.h" +#include "DatabaseEnv.h" #include "Opcodes.h" -#include "QueryCallback.h" +#include "PacketLog.h" +#include "Random.h" +#include "RBAC.h" +#include "Realm.h" #include "ScriptMgr.h" #include "SHA1.h" -#include "PacketLog.h" - +#include "World.h" +#include "WorldSession.h" #include <memory> class EncryptablePacket : public WorldPacket @@ -505,7 +509,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes sha.UpdateData((uint8*)&t, 4); sha.UpdateData((uint8*)&authSession->LocalChallenge, 4); sha.UpdateData((uint8*)&_authSeed, 4); - sha.UpdateBigNumbers(&account.SessionKey, NULL); + sha.UpdateBigNumbers(&account.SessionKey, nullptr); sha.Finalize(); if (memcmp(sha.GetDigest(), authSession->Digest, SHA_DIGEST_LENGTH) != 0) @@ -546,7 +550,7 @@ void WorldSocket::HandleAuthSessionCallback(std::shared_ptr<AuthSession> authSes //! Negative mutetime indicates amount of seconds to be muted effective on next login - which is now. if (mutetime < 0) { - mutetime = time(NULL) + llabs(mutetime); + mutetime = time(nullptr) + llabs(mutetime); PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_UPD_MUTE_TIME_LOGIN); stmt->setInt64(0, mutetime); diff --git a/src/server/game/Server/WorldSocketMgr.h b/src/server/game/Server/WorldSocketMgr.h index ce81acfea78..e409f8d2ea8 100644 --- a/src/server/game/Server/WorldSocketMgr.h +++ b/src/server/game/Server/WorldSocketMgr.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * * This program is free software; you can redistribute it and/or modify it diff --git a/src/server/game/Skills/SkillDiscovery.cpp b/src/server/game/Skills/SkillDiscovery.cpp index 2c17d3c7530..44d9a6a153f 100644 --- a/src/server/game/Skills/SkillDiscovery.cpp +++ b/src/server/game/Skills/SkillDiscovery.cpp @@ -16,14 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "SkillDiscovery.h" #include "DatabaseEnv.h" #include "Log.h" -#include "World.h" -#include "Util.h" -#include "SkillDiscovery.h" -#include "SpellMgr.h" #include "Player.h" +#include "Random.h" +#include "SpellMgr.h" #include "SpellInfo.h" +#include "Util.h" +#include "World.h" #include <map> struct SkillDiscoveryEntry diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp index 5d5ea4396fb..3b066e71b8b 100644 --- a/src/server/game/Skills/SkillExtraItems.cpp +++ b/src/server/game/Skills/SkillExtraItems.cpp @@ -19,8 +19,9 @@ #include "SkillExtraItems.h" #include "DatabaseEnv.h" #include "Log.h" -#include "Player.h" #include "ObjectMgr.h" +#include "Player.h" +#include "SpellMgr.h" #include <map> // some type definitions diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 62602ac4a63..4fac4728b6c 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -18,6 +18,8 @@ #ifndef TRINITY_SPELLAURADEFINES_H #define TRINITY_SPELLAURADEFINES_H +#include "Define.h" + #define MAX_AURAS 255 // Client-side limit #define MAX_AURAS_GROUP_UPDATE 64 // Limit of SMSG_PARY_MEMBER_STATS_FULL and SMSG_PARTY_MEMBER_STATS @@ -51,6 +53,16 @@ enum AuraEffectHandleModes AURA_EFFECT_HANDLE_REAL_OR_REAPPLY_MASK = (AURA_EFFECT_HANDLE_REAPPLY | AURA_EFFECT_HANDLE_REAL) }; +enum AuraRemoveMode +{ + AURA_REMOVE_NONE = 0, + AURA_REMOVE_BY_DEFAULT = 1, // scripted remove, remove by stack with aura with different ids and sc aura remove + AURA_REMOVE_BY_CANCEL, + AURA_REMOVE_BY_ENEMY_SPELL, // dispel and absorb aura destroy + AURA_REMOVE_BY_EXPIRE, // aura duration has ended + AURA_REMOVE_BY_DEATH +}; + //m_schoolAbsorb enum DAMAGE_ABSORB_TYPE { @@ -58,7 +70,7 @@ enum DAMAGE_ABSORB_TYPE ONLY_MAGIC_ABSORB = -1 }; -enum AuraType +enum AuraType : uint32 { SPELL_AURA_NONE = 0, SPELL_AURA_BIND_SIGHT = 1, diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 2fc4d83b767..5347d056eba 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -16,32 +16,34 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "SpellAuraEffects.h" +#include "Battlefield.h" +#include "BattlefieldMgr.h" +#include "Battleground.h" +#include "CellImpl.h" #include "Common.h" -#include "WorldPacket.h" -#include "Opcodes.h" +#include "DBCStores.h" +#include "GridNotifiersImpl.h" +#include "Item.h" #include "Log.h" +#include "LootMgr.h" +#include "MotionMaster.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "SpellMgr.h" +#include "Opcodes.h" +#include "OutdoorPvPMgr.h" +#include "Pet.h" #include "Player.h" -#include "Unit.h" -#include "ObjectAccessor.h" -#include "CellImpl.h" -#include "Util.h" +#include "ReputationMgr.h" +#include "ScriptMgr.h" #include "Spell.h" #include "SpellHistory.h" -#include "SpellAuraEffects.h" -#include "Battleground.h" -#include "OutdoorPvPMgr.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "ScriptMgr.h" +#include "SpellMgr.h" +#include "Unit.h" +#include "Util.h" #include "Vehicle.h" -#include "Battlefield.h" -#include "BattlefieldMgr.h" -#include "Pet.h" -#include "ReputationMgr.h" +#include "WorldPacket.h" -class Aura; // // EFFECT HANDLER NOTES // @@ -380,7 +382,7 @@ AuraEffect::AuraEffect(Aura* base, uint8 effIndex, int32 *baseAmount, Unit* cast m_base(base), m_spellInfo(base->GetSpellInfo()), m_baseAmount(baseAmount ? *baseAmount : m_spellInfo->Effects[effIndex].BasePoints), m_bonusAmount(0), m_critChance(0.0f), m_donePct(1.0f), -m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex), +m_spellmod(nullptr), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex), m_canBeRecalculated(true), m_isPeriodic(false) { CalculatePeriodic(caster, true, false); @@ -421,7 +423,7 @@ void AuraEffect::GetApplicationList(Container& applicationContainer) const int32 AuraEffect::CalculateAmount(Unit* caster) { // default amount calculation - int32 amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, NULL); + int32 amount = m_spellInfo->Effects[m_effIndex].CalcValue(caster, &m_baseAmount, nullptr); // check item enchant aura cast if (!amount && caster) @@ -536,7 +538,7 @@ void AuraEffect::CalculatePeriodic(Unit* caster, bool resetPeriodicTimer /*= tru { // Apply periodic time mod if (modOwner) - modOwner->ApplySpellMod<SPELLMOD_ACTIVATION_TIME>(GetId(), m_amplitude); + modOwner->ApplySpellMod(GetId(), SPELLMOD_ACTIVATION_TIME, m_amplitude); if (caster) { @@ -1760,7 +1762,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo { int32 basePoints = int32(std::min(oldPower, FurorChance)); target->SetPower(POWER_ENERGY, 0); - target->CastCustomSpell(target, 17099, &basePoints, NULL, NULL, true, NULL, this); + target->CastCustomSpell(target, 17099, &basePoints, nullptr, nullptr, true, nullptr, this); break; } case FORM_BEAR: @@ -1823,12 +1825,12 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo case FORM_DIREBEAR: case FORM_CAT: if (AuraEffect* dummy = target->GetAuraEffect(37315, 0)) - target->CastSpell(target, 37316, true, NULL, dummy); + target->CastSpell(target, 37316, true, nullptr, dummy); break; // Nordrassil Regalia - bonus case FORM_MOONKIN: if (AuraEffect* dummy = target->GetAuraEffect(37324, 0)) - target->CastSpell(target, 37325, true, NULL, dummy); + target->CastSpell(target, 37325, true, nullptr, dummy); break; case FORM_BATTLESTANCE: case FORM_DEFENSIVESTANCE: @@ -1883,7 +1885,7 @@ void AuraEffect::HandleAuraModShapeshift(AuraApplication const* aurApp, uint8 mo { if (Item* pItem = target->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND)) { - target->ToPlayer()->_ApplyWeaponDamage(EQUIPMENT_SLOT_MAINHAND, pItem->GetTemplate(), NULL, apply); + target->ToPlayer()->_ApplyWeaponDamage(EQUIPMENT_SLOT_MAINHAND, pItem->GetTemplate(), nullptr, apply); } } } @@ -2321,7 +2323,7 @@ void AuraEffect::HandleAuraModDisarm(AuraApplication const* aurApp, uint8 mode, player->ApplyItemDependentAuras(item, !apply); if (attackType != MAX_ATTACK) { - player->_ApplyWeaponDamage(slot, item->GetTemplate(), NULL, !apply); + player->_ApplyWeaponDamage(slot, item->GetTemplate(), nullptr, !apply); if (!apply) // apply case already handled on item dependent aura removal (if any) player->UpdateWeaponDependentAuras(attackType); } @@ -4375,7 +4377,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool case 13139: // net-o-matic // root to self part of (root_target->charge->root_self sequence if (caster) - caster->CastSpell(caster, 13138, true, NULL, this); + caster->CastSpell(caster, 13138, true, nullptr, this); break; case 34026: // kill command { @@ -4383,7 +4385,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (!pet) break; - target->CastSpell(target, 34027, true, NULL, this); + target->CastSpell(target, 34027, true, nullptr, this); // set 3 stacks and 3 charges (to make all auras not disappear at once) Aura* owner_aura = target->GetAura(34027, GetCasterGUID()); @@ -4404,15 +4406,15 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (caster) { if (caster->getGender() == GENDER_FEMALE) - caster->CastSpell(target, 37095, true, NULL, this); // Blood Elf Disguise + caster->CastSpell(target, 37095, true, nullptr, this); // Blood Elf Disguise else - caster->CastSpell(target, 37093, true, NULL, this); + caster->CastSpell(target, 37093, true, nullptr, this); } break; } case 55198: // Tidal Force { - target->CastSpell(target, 55166, true, NULL, this); + target->CastSpell(target, 55166, true, nullptr, this); // set 3 stacks and 3 charges (to make all auras not disappear at once) Aura* owner_aura = target->GetAura(55166, GetCasterGUID()); if (owner_aura) @@ -4428,7 +4430,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool } case 39850: // Rocket Blast if (roll_chance_i(20)) // backfire stun - target->CastSpell(target, 51581, true, NULL, this); + target->CastSpell(target, 51581, true, nullptr, this); break; case 43873: // Headless Horseman Laugh target->PlayDistanceSound(11965); @@ -4437,9 +4439,9 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool if (caster) { if (caster->getGender() == GENDER_FEMALE) - caster->CastSpell(target, 46356, true, NULL, this); + caster->CastSpell(target, 46356, true, nullptr, this); else - caster->CastSpell(target, 46355, true, NULL, this); + caster->CastSpell(target, 46355, true, nullptr, this); } break; case 46361: // Reinforced Net @@ -4481,7 +4483,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool } if (finalSpelId) - caster->CastSpell(target, finalSpelId, true, NULL, this); + caster->CastSpell(target, finalSpelId, true, nullptr, this); } switch (m_spellInfo->SpellFamilyName) @@ -4501,7 +4503,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool break; case 36730: // Flame Strike { - target->CastSpell(target, 36731, true, NULL, this); + target->CastSpell(target, 36731, true, nullptr, this); break; } case 44191: // Flame Strike @@ -4510,7 +4512,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool { uint32 spellId = target->GetMap()->IsHeroic() ? 46163 : 44190; - target->CastSpell(target, spellId, true, NULL, this); + target->CastSpell(target, spellId, true, nullptr, this); } break; } @@ -4524,14 +4526,14 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool break; } case 42783: // Wrath of the Astromancer - target->CastSpell(target, GetAmount(), true, NULL, this); + target->CastSpell(target, GetAmount(), true, nullptr, this); break; case 46308: // Burning Winds cast only at creatures at spawn - target->CastSpell(target, 47287, true, NULL, this); + target->CastSpell(target, 47287, true, nullptr, this); break; case 52172: // Coyote Spirit Despawn Aura case 60244: // Blood Parrot Despawn Aura - target->CastSpell((Unit*)NULL, GetAmount(), true, NULL, this); + target->CastSpell((Unit*)nullptr, GetAmount(), true, nullptr, this); break; case 58600: // Restricted Flight Area case 58730: // Restricted Flight Area @@ -4574,7 +4576,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId); for (uint32 i = 0; i < spell->StackAmount; ++i) - caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID()); + caster->CastSpell(target, spell->Id, true, nullptr, nullptr, GetCasterGUID()); break; } target->RemoveAurasDueToSpell(spellId); @@ -4588,7 +4590,7 @@ void AuraEffect::HandleAuraDummy(AuraApplication const* aurApp, uint8 mode, bool { SpellInfo const* spell = sSpellMgr->AssertSpellInfo(spellId); for (uint32 i = 0; i < spell->StackAmount; ++i) - caster->CastSpell(target, spell->Id, true, NULL, NULL, GetCasterGUID()); + caster->CastSpell(target, spell->Id, true, nullptr, nullptr, GetCasterGUID()); break; } target->RemoveAurasDueToSpell(spellId); @@ -4761,8 +4763,8 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod InventoryResult msg = plCaster->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, GetSpellInfo()->Effects[m_effIndex].ItemType, count, &noSpaceForCount); if (msg != EQUIP_ERR_OK) { - count-=noSpaceForCount; - plCaster->SendEquipError(msg, NULL, NULL, GetSpellInfo()->Effects[m_effIndex].ItemType); + count -= noSpaceForCount; + plCaster->SendEquipError(msg, nullptr, nullptr, GetSpellInfo()->Effects[m_effIndex].ItemType); if (count == 0) return; } @@ -4770,7 +4772,7 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const* aurApp, uint8 mod Item* newitem = plCaster->StoreNewItem(dest, GetSpellInfo()->Effects[m_effIndex].ItemType, true); if (!newitem) { - plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + plCaster->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } plCaster->SendNewItem(newitem, count, true, true); @@ -4921,9 +4923,9 @@ void AuraEffect::HandleAuraLinked(AuraApplication const* aurApp, uint8 mode, boo return; // If amount avalible cast with basepoints (Crypt Fever for example) if (GetAmount()) - caster->CastCustomSpell(target, triggeredSpellId, &m_amount, NULL, NULL, true, NULL, this); + caster->CastCustomSpell(target, triggeredSpellId, &m_amount, nullptr, nullptr, true, nullptr, this); else - caster->CastSpell(target, triggeredSpellId, true, NULL, this); + caster->CastSpell(target, triggeredSpellId, true, nullptr, this); } else { @@ -5089,7 +5091,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const } case 62292: // Blaze (Pool of Tar) // should we use custom damage? - target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true); + target->CastSpell((Unit*)nullptr, m_spellInfo->Effects[m_effIndex].TriggerSpell, true); break; case 62399: // Overload Circuit if (target->GetMap()->IsDungeon() && int(target->GetAppliedAuras().count(62399)) >= (target->GetMap()->IsHeroic() ? 4 : 2)) @@ -5102,7 +5104,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const case 64821: // Fuse Armor (Razorscale) if (GetBase()->GetStackAmount() == GetSpellInfo()->StackAmount) { - target->CastSpell(target, 64774, true, NULL, NULL, GetCasterGUID()); + target->CastSpell(target, 64774, true, nullptr, nullptr, GetCasterGUID()); target->RemoveAura(64821); } break; @@ -5113,7 +5115,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const // Mirror Image if (GetId() == 55342) // Set name of summons to name of caster - target->CastSpell((Unit*)NULL, m_spellInfo->Effects[m_effIndex].TriggerSpell, true); + target->CastSpell((Unit*)nullptr, m_spellInfo->Effects[m_effIndex].TriggerSpell, true); break; } case SPELLFAMILY_DRUID: @@ -5162,7 +5164,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const if (GetSpellInfo()->SpellFamilyFlags[1] & 0x80000000) { if (caster) - caster->CastCustomSpell(53352, SPELLVALUE_BASE_POINT0, m_amount, target, true, NULL, this); + caster->CastCustomSpell(53352, SPELLVALUE_BASE_POINT0, m_amount, target, true, nullptr, this); break; } switch (GetSpellInfo()->Id) @@ -5196,7 +5198,7 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const { case 49016: // Hysteria uint32 damage = uint32(target->CountPctFromMaxHealth(1)); - target->DealDamage(target, damage, NULL, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + target->DealDamage(target, damage, nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); break; } // Blood of the North @@ -5228,7 +5230,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) uint32 auraId = auraSpellInfo->Id; // specific code for cases with no trigger spell provided in field - if (triggeredSpellInfo == NULL) + if (triggeredSpellInfo == nullptr) { switch (auraSpellInfo->SpellFamilyName) { @@ -5272,7 +5274,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) // Frost Blast case 27808: if (caster) - caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, int32(target->CountPctFromMaxHealth(21)), target, true, NULL, this); + caster->CastCustomSpell(29879, SPELLVALUE_BASE_POINT0, int32(target->CountPctFromMaxHealth(21)), target, true, nullptr, this); return; // Inoculate Nestlewood Owlkin case 29528: @@ -5312,7 +5314,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) // so instakill will be naturally done before trigger spell case 31347: { - target->CastSpell(target, 31350, true, NULL, this); + target->CastSpell(target, 31350, true, nullptr, this); target->KillSelf(); return; } @@ -5328,9 +5330,9 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) { // cast 24 spells 34269-34289, 34314-34316 for (uint32 spell_id = 34269; spell_id != 34290; ++spell_id) - target->CastSpell(target, spell_id, true, NULL, this); + target->CastSpell(target, spell_id, true, nullptr, this); for (uint32 spell_id = 34314; spell_id != 34317; ++spell_id) - target->CastSpell(target, spell_id, true, NULL, this); + target->CastSpell(target, spell_id, true, nullptr, this); return; } // Remote Toy @@ -5347,7 +5349,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) if (!caster || target->GetTypeId() != TYPEID_UNIT) return; - caster->CastSpell(caster, 38495, true, NULL, this); + caster->CastSpell(caster, 38495, true, nullptr, this); Creature* creatureTarget = target->ToCreature(); @@ -5394,7 +5396,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) case 65922: case 65923: { - Unit* permafrostCaster = NULL; + Unit* permafrostCaster = nullptr; Aura* permafrostAura = target->GetAura(66193); if (!permafrostAura) permafrostAura = target->GetAura(67855); @@ -5420,15 +5422,15 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) } // Mana Tide case 16191: - target->CastCustomSpell(target, triggerSpellId, &m_amount, NULL, NULL, true, NULL, this); + target->CastCustomSpell(target, triggerSpellId, &m_amount, nullptr, nullptr, true, nullptr, this); return; // Negative Energy Periodic case 46284: - target->CastCustomSpell(triggerSpellId, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, NULL, true, NULL, this); + target->CastCustomSpell(triggerSpellId, SPELLVALUE_MAX_TARGETS, m_tickNumber / 10 + 1, nullptr, true, nullptr, this); return; // Slime Pool (Dreadscale & Acidmaw) case 66882: - target->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000 * 2 / 3), NULL, true, NULL, this); + target->CastCustomSpell(triggerSpellId, SPELLVALUE_RADIUS_MOD, (int32)((((float)m_tickNumber / 60) * 0.9f + 0.1f) * 10000 * 2 / 3), nullptr, true, nullptr, this); return; // Beacon of Light case 53563: @@ -5442,7 +5444,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) case 69508: { if (caster) - caster->CastSpell(target, triggerSpellId, true, NULL, NULL, caster->GetGUID()); + caster->CastSpell(target, triggerSpellId, true, nullptr, nullptr, caster->GetGUID()); return; } case 24745: // Summon Templar, Trigger @@ -5477,7 +5479,7 @@ void AuraEffect::HandlePeriodicTriggerSpellAuraTick(Unit* target, Unit* caster) { if (Unit* triggerCaster = triggeredSpellInfo->NeedsToBeTriggeredByCaster(m_spellInfo) ? caster : target) { - triggerCaster->CastSpell(target, triggeredSpellInfo, true, NULL, this); + triggerCaster->CastSpell(target, triggeredSpellInfo, true, nullptr, this); TC_LOG_DEBUG("spells", "AuraEffect::HandlePeriodicTriggerSpellAuraTick: Spell %u Trigger %u", GetId(), triggeredSpellInfo->Id); } } @@ -5561,7 +5563,7 @@ void AuraEffect::HandlePeriodicDamageAurasTick(Unit* target, Unit* caster) const damage = std::max(int32(damage * GetDonePct()), 0); if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DOT>(GetSpellInfo()->Id, damage); + modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage); damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); @@ -5704,7 +5706,7 @@ void AuraEffect::HandlePeriodicHealthLeechAuraTick(Unit* target, Unit* caster) c damage = std::max(int32(damage * GetDonePct()), 0); if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DOT>(GetSpellInfo()->Id, damage); + modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage); damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); @@ -5875,7 +5877,7 @@ void AuraEffect::HandlePeriodicHealAurasTick(Unit* target, Unit* caster) const damage = std::max(int32(damage * GetDonePct()), 0); if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DOT>(GetSpellInfo()->Id, damage); + modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage); damage = target->SpellHealingBonusTaken(caster, GetSpellInfo(), damage, DOT, GetBase()->GetStackAmount()); } @@ -5997,7 +5999,7 @@ void AuraEffect::HandlePeriodicManaLeechAuraTick(Unit* target, Unit* caster) con if (manaFeedVal > 0) { int32 feedAmount = CalculatePct(gainedAmount, manaFeedVal); - caster->CastCustomSpell(caster, 32554, &feedAmount, NULL, NULL, true, NULL, this); + caster->CastCustomSpell(caster, 32554, &feedAmount, nullptr, nullptr, true, nullptr, this); } } } @@ -6142,7 +6144,7 @@ void AuraEffect::HandleProcTriggerSpellAuraProc(AuraApplication* aurApp, ProcEve if (SpellInfo const* triggeredSpellInfo = sSpellMgr->GetSpellInfo(triggerSpellId)) { TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellAuraProc: Triggering spell %u from aura %u proc", triggeredSpellInfo->Id, GetId()); - triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, NULL, this); + triggerCaster->CastSpell(triggerTarget, triggeredSpellInfo, true, nullptr, this); } else TC_LOG_ERROR("spells","AuraEffect::HandleProcTriggerSpellAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId()); @@ -6158,7 +6160,7 @@ void AuraEffect::HandleProcTriggerSpellWithValueAuraProc(AuraApplication* aurApp { int32 basepoints0 = GetAmount(); TC_LOG_DEBUG("spells", "AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Triggering spell %u with value %d from aura %u proc", triggeredSpellInfo->Id, basepoints0, GetId()); - triggerCaster->CastCustomSpell(triggerTarget, triggerSpellId, &basepoints0, NULL, NULL, true, NULL, this); + triggerCaster->CastCustomSpell(triggerTarget, triggerSpellId, &basepoints0, nullptr, nullptr, true, nullptr, this); } else TC_LOG_ERROR("spells","AuraEffect::HandleProcTriggerSpellWithValueAuraProc: Could not trigger spell %u from aura %u proc, because the spell does not have an entry in Spell.dbc.", triggerSpellId, GetId()); @@ -6224,7 +6226,7 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius)) { - target->CastSpell(triggerTarget, GetSpellInfo(), true, NULL, this, GetCasterGUID()); + target->CastSpell(triggerTarget, GetSpellInfo(), true, nullptr, this, GetCasterGUID()); if (Aura* aura = triggerTarget->GetAura(GetId(), GetCasterGUID())) aura->SetCharges(jumps); } @@ -6232,7 +6234,7 @@ void AuraEffect::HandleRaidProcFromChargeAuraProc(AuraApplication* aurApp, ProcE } TC_LOG_DEBUG("spells", "AuraEffect::HandleRaidProcFromChargeAuraProc: Triggering spell %u from aura %u proc", triggerSpellId, GetId()); - target->CastSpell(target, triggerSpellId, true, NULL, this, GetCasterGUID()); + target->CastSpell(target, triggerSpellId, true, nullptr, this, GetCasterGUID()); } @@ -6265,7 +6267,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA if (Unit* triggerTarget = target->GetNextRandomRaidMemberOrPet(radius)) { - target->CastCustomSpell(triggerTarget, GetId(), &value, NULL, NULL, true, NULL, this, GetCasterGUID()); + target->CastCustomSpell(triggerTarget, GetId(), &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID()); if (Aura* aura = triggerTarget->GetAura(GetId(), GetCasterGUID())) aura->SetCharges(jumps); } @@ -6273,7 +6275,7 @@ void AuraEffect::HandleRaidProcFromChargeWithValueAuraProc(AuraApplication* aurA } TC_LOG_DEBUG("spells", "AuraEffect::HandleRaidProcFromChargeWithValueAuraProc: Triggering spell %u from aura %u proc", triggerSpellId, GetId()); - target->CastCustomSpell(target, triggerSpellId, &value, NULL, NULL, true, NULL, this, GetCasterGUID()); + target->CastCustomSpell(target, triggerSpellId, &value, nullptr, nullptr, true, nullptr, this, GetCasterGUID()); } template TC_GAME_API void AuraEffect::GetTargetList(std::list<Unit*>&) const; diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 6a24a73ac1a..cff25bc8e2c 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -17,26 +17,27 @@ */ #include "Common.h" -#include "WorldPacket.h" -#include "Opcodes.h" +#include "CellImpl.h" +#include "Config.h" +#include "DynamicObject.h" +#include "GridNotifiersImpl.h" +#include "Item.h" #include "Log.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "SpellMgr.h" +#include "Opcodes.h" #include "Player.h" -#include "Unit.h" +#include "ScriptMgr.h" #include "Spell.h" -#include "SpellHistory.h" #include "SpellAuraEffects.h" -#include "DynamicObject.h" -#include "ObjectAccessor.h" -#include "Util.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "CellImpl.h" -#include "ScriptMgr.h" +#include "SpellHistory.h" +#include "SpellMgr.h" #include "SpellScript.h" +#include "Unit.h" +#include "Util.h" #include "Vehicle.h" -#include "Config.h" +#include "World.h" +#include "WorldPacket.h" AuraApplication::AuraApplication(Unit* target, Unit* caster, Aura* aura, uint8 effMask): _target(target), _base(aura), _removeMode(AURA_REMOVE_NONE), _slot(MAX_AURAS), @@ -341,7 +342,7 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne Aura::Aura(SpellInfo const* spellproto, WorldObject* owner, Unit* caster, Item* castItem, ObjectGuid casterGUID) : m_spellInfo(spellproto), m_casterGuid(casterGUID ? casterGUID : caster->GetGUID()), -m_castItemGuid(castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_applyTime(time(NULL)), +m_castItemGuid(castItem ? castItem->GetGUID() : ObjectGuid::Empty), m_applyTime(time(nullptr)), m_owner(owner), m_timeCla(0), m_updateTargetMapInterval(0), m_casterLevel(caster ? caster->getLevel() : m_spellInfo->SpellLevel), m_procCharges(0), m_stackAmount(1), m_isRemoved(false), m_isSingleTarget(false), m_isUsingCharges(false), m_dropEvent(nullptr), @@ -363,7 +364,7 @@ AuraScript* Aura::GetScriptByName(std::string const& scriptName) const for (auto itr = m_loadedScripts.begin(); itr != m_loadedScripts.end(); ++itr) if ((*itr)->_GetScriptName()->compare(scriptName) == 0) return *itr; - return NULL; + return nullptr; } void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount) @@ -372,9 +373,9 @@ void Aura::_InitEffects(uint8 effMask, Unit* caster, int32 *baseAmount) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { if (effMask & (uint8(1) << i)) - m_effects[i] = new AuraEffect(this, i, baseAmount ? baseAmount + i : NULL, caster); + m_effects[i] = new AuraEffect(this, i, baseAmount ? baseAmount + i : nullptr, caster); else - m_effects[i] = NULL; + m_effects[i] = nullptr; } } @@ -424,7 +425,7 @@ void Aura::_ApplyForTarget(Unit* target, Unit* caster, AuraApplication * auraApp { if (m_spellInfo->IsCooldownStartedOnEvent()) { - Item* castItem = m_castItemGuid ? caster->ToPlayer()->GetItemByGuid(m_castItemGuid) : NULL; + Item* castItem = m_castItemGuid ? caster->ToPlayer()->GetItemByGuid(m_castItemGuid) : nullptr; caster->GetSpellHistory()->StartCooldown(m_spellInfo, castItem ? castItem->GetEntry() : 0, nullptr, true); } } @@ -647,8 +648,8 @@ void Aura::UpdateOwner(uint32 diff, WorldObject* owner) Unit* caster = GetCaster(); // Apply spellmods for channeled auras // used for example when triggered spell of spell:10 is modded - Spell* modSpell = NULL; - Player* modOwner = NULL; + Spell* modSpell = nullptr; + Player* modOwner = nullptr; if (caster) { modOwner = caster->GetSpellModOwner(); @@ -718,7 +719,7 @@ void Aura::Update(uint32 diff, Unit* caster) int32 Aura::CalcMaxDuration(Unit* caster) const { - Player* modOwner = NULL; + Player* modOwner = nullptr; int32 maxDuration; if (caster) @@ -734,7 +735,7 @@ int32 Aura::CalcMaxDuration(Unit* caster) const // IsPermanent() checks max duration (which we are supposed to calculate here) if (maxDuration != -1 && modOwner) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(GetId(), maxDuration); + modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, maxDuration); return maxDuration; } @@ -744,7 +745,7 @@ void Aura::SetDuration(int32 duration, bool withMods) if (withMods) if (Unit* caster = GetCaster()) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(GetId(), duration); + modOwner->ApplySpellMod(GetId(), SPELLMOD_DURATION, duration); m_duration = duration; SetNeedClientUpdateForTargets(); @@ -799,7 +800,7 @@ uint8 Aura::CalcMaxCharges(Unit* caster) const if (caster) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CHARGES>(GetId(), maxProcCharges); + modOwner->ApplySpellMod(GetId(), SPELLMOD_CHARGES, maxProcCharges); return maxProcCharges; } @@ -1047,7 +1048,7 @@ int32 Aura::CalcDispelChance(Unit const* auraTarget, bool offensive) const // Apply dispel mod from aura caster if (Unit* caster = GetCaster()) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RESIST_DISPEL_CHANCE>(GetId(), resistChance); + modOwner->ApplySpellMod(GetId(), SPELLMOD_RESIST_DISPEL_CHANCE, resistChance); // Dispel resistance from target SPELL_AURA_MOD_DISPEL_RESIST // Only affects offensive dispels @@ -1174,7 +1175,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b if (*itr < 0) target->RemoveAurasDueToSpell(-(*itr)); else if (removeMode != AURA_REMOVE_BY_DEATH) - target->CastSpell(target, *itr, true, NULL, NULL, GetCasterGUID()); + target->CastSpell(target, *itr, true, nullptr, nullptr, GetCasterGUID()); } } if (std::vector<int32> const* spellTriggered = sSpellMgr->GetSpellLinked(GetId() + SPELL_LINK_AURA)) @@ -1237,7 +1238,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b if (caster->HasAura(64760)) { int32 heal = GetEffect(EFFECT_0)->GetAmount(); - caster->CastCustomSpell(target, 64801, &heal, NULL, NULL, true, NULL, GetEffect(EFFECT_0)); + caster->CastCustomSpell(target, 64801, &heal, nullptr, nullptr, true, nullptr, GetEffect(EFFECT_0)); } } break; @@ -1295,7 +1296,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b { int32 damage = (devouringPlague->GetAmount() + devouringPlague->GetBonusAmount()) * devouringPlague->GetDonePct(); if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DOT>(GetSpellInfo()->Id, damage); + modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, damage); damage = target->SpellDamageBonusTaken(caster, GetSpellInfo(), damage, DOT); @@ -1334,7 +1335,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b if (GetCasterGUID() == target->GetGUID()) break; - AuraEffect* aurEff = NULL; + AuraEffect* aurEff = nullptr; // Ebon Plaguebringer / Crypt Fever Unit::AuraEffectList const& TalentAuras = caster->GetAuraEffectsByType(SPELL_AURA_OVERRIDE_CLASS_SCRIPTS); for (Unit::AuraEffectList::const_iterator itr = TalentAuras.begin(); itr != TalentAuras.end(); ++itr) @@ -1392,7 +1393,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b case 66: // Invisibility if (removeMode != AURA_REMOVE_BY_EXPIRE) break; - target->CastSpell(target, 32612, true, NULL, GetEffect(1)); + target->CastSpell(target, 32612, true, nullptr, GetEffect(1)); target->CombatStop(); break; default: @@ -1453,7 +1454,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b if (AuraEffect const* aurEff = caster->GetDummyAuraEffect(SPELLFAMILY_PRIEST, 178, 1)) { int32 basepoints0 = aurEff->GetAmount() * caster->GetCreateMana() / 100; - caster->CastCustomSpell(caster, 64103, &basepoints0, NULL, NULL, true, NULL, GetEffect(0)); + caster->CastCustomSpell(caster, 64103, &basepoints0, nullptr, nullptr, true, nullptr, GetEffect(0)); } } // Power word: shield @@ -1486,7 +1487,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b multiplier += 0.5f; int32 basepoints0 = int32(CalculatePct(caster->GetMaxPower(POWER_MANA), multiplier)); - caster->CastCustomSpell(caster, 47755, &basepoints0, NULL, NULL, true); + caster->CastCustomSpell(caster, 47755, &basepoints0, nullptr, nullptr, true); } // effect on aura target if (AuraEffect const* aurEff = aura->GetEffect(1)) @@ -1500,7 +1501,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b case POWER_MANA: { int32 basepoints0 = int32(CalculatePct(target->GetMaxPower(POWER_MANA), 2)); - caster->CastCustomSpell(target, 63654, &basepoints0, NULL, NULL, true); + caster->CastCustomSpell(target, 63654, &basepoints0, nullptr, nullptr, true); break; } case POWER_RAGE: triggeredSpellId = 63653; break; @@ -1593,7 +1594,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const* aurApp, Unit* caster, b target->RemoveAurasDueToSpell(31666); int32 basepoints0 = aurEff->GetAmount(); - target->CastCustomSpell(target, 31665, &basepoints0, NULL, NULL, true); + target->CastCustomSpell(target, 31665, &basepoints0, nullptr, nullptr, true); } } // Overkill @@ -1812,7 +1813,7 @@ bool Aura::CanStackWith(Aura const* existingAura) const if (HasEffectType(SPELL_AURA_CONTROL_VEHICLE) && existingAura->HasEffectType(SPELL_AURA_CONTROL_VEHICLE)) { - Vehicle* veh = NULL; + Vehicle* veh = nullptr; if (GetOwner()->ToUnit()) veh = GetOwner()->ToUnit()->GetVehicleKit(); @@ -2005,7 +2006,7 @@ float Aura::CalcProcChance(SpellProcEntry const& procEntry, ProcEventInfo& event } // apply chance modifer aura, applies also to ppm chance (see improved judgement of light spell) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_CHANCE_OF_SUCCESS>(GetId(), chance); + modOwner->ApplySpellMod(GetId(), SPELLMOD_CHANCE_OF_SUCCESS, chance); } // proc chance is reduced by an additional 3.333% per level past 60 diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 32eaf8585e8..ee28ee2fd94 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -176,7 +176,7 @@ class TC_GAME_API Aura void SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint8 stackamount, uint8 recalculateMask, int32 * amount); // helpers for aura effects - bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != NULL; } + bool HasEffect(uint8 effIndex) const { return GetEffect(effIndex) != nullptr; } bool HasEffectType(AuraType type) const; AuraEffect* GetEffect(uint8 effIndex) const { ASSERT (effIndex < MAX_SPELL_EFFECTS); return m_effects[effIndex]; } uint8 GetEffectMask() const { uint8 effMask = 0; for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (m_effects[i]) effMask |= 1<<i; return effMask; } @@ -186,8 +186,8 @@ class TC_GAME_API Aura // Helpers for targets ApplicationMap const& GetApplicationMap() { return m_applications; } void GetApplicationList(Unit::AuraApplicationList& applicationList) const; - const AuraApplication* GetApplicationOfTarget(ObjectGuid guid) const { ApplicationMap::const_iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return NULL; } - AuraApplication* GetApplicationOfTarget(ObjectGuid guid) { ApplicationMap::iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return NULL; } + AuraApplication const* GetApplicationOfTarget(ObjectGuid guid) const { ApplicationMap::const_iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return nullptr; } + AuraApplication* GetApplicationOfTarget(ObjectGuid guid) { ApplicationMap::iterator itr = m_applications.find(guid); if (itr != m_applications.end()) return itr->second; return nullptr; } bool IsAppliedOnTarget(ObjectGuid guid) const { return m_applications.find(guid) != m_applications.end(); } void SetNeedClientUpdateForTargets() const; @@ -234,11 +234,16 @@ class TC_GAME_API Aura bool CallScriptEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo); void CallScriptAfterEffectProcHandlers(AuraEffect const* aurEff, AuraApplication const* aurApp, ProcEventInfo& eventInfo); - AuraScript* GetScriptByName(std::string const& scriptName) const; + template <class Script> + Script* GetScript(std::string const& scriptName) const + { + return dynamic_cast<Script*>(GetScriptByName(scriptName)); + } std::vector<AuraScript*> m_loadedScripts; private: + AuraScript* GetScriptByName(std::string const& scriptName) const; void _DeleteRemovedApplications(); protected: diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index d8baf713926..ae65161538b 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -16,46 +16,49 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Spell.h" +#include "Battlefield.h" +#include "BattlefieldMgr.h" +#include "Battleground.h" +#include "CellImpl.h" #include "Common.h" +#include "ConditionMgr.h" #include "DatabaseEnv.h" -#include "WorldPacket.h" -#include "WorldSession.h" -#include "GameTime.h" +#include "DBCStores.h" +#include "DisableMgr.h" +#include "DynamicObject.h" +#include "GameObjectAI.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" -#include "Opcodes.h" +#include "GameTime.h" +#include "InstanceScript.h" +#include "Item.h" #include "Log.h" -#include "UpdateMask.h" -#include "World.h" +#include "LootMgr.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "SpellMgr.h" -#include "Player.h" +#include "Opcodes.h" +#include "PathGenerator.h" #include "Pet.h" -#include "Unit.h" -#include "Spell.h" -#include "DynamicObject.h" -#include "UpdateData.h" -#include "ObjectAccessor.h" -#include "CellImpl.h" +#include "Player.h" +#include "ScriptMgr.h" #include "SharedDefines.h" -#include "LootMgr.h" -#include "VMapFactory.h" -#include "Battleground.h" -#include "Util.h" -#include "TemporarySummon.h" -#include "Vehicle.h" #include "SpellAuraEffects.h" -#include "ScriptMgr.h" -#include "ConditionMgr.h" -#include "DisableMgr.h" -#include "SpellScript.h" -#include "InstanceScript.h" -#include "SpellInfo.h" #include "SpellHistory.h" -#include "Battlefield.h" -#include "BattlefieldMgr.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "SpellScript.h" +#include "TemporarySummon.h" #include "TradeData.h" -#include "GameObjectAI.h" +#include "Unit.h" +#include "UpdateData.h" +#include "UpdateMask.h" +#include "Util.h" +#include "Vehicle.h" +#include "VMapFactory.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; @@ -109,8 +112,8 @@ void SpellDestination::RelocateOffset(Position const& offset) SpellCastTargets::SpellCastTargets() : m_elevation(0), m_speed(0), m_strTarget() { - m_objectTarget = NULL; - m_itemTarget = NULL; + m_objectTarget = nullptr; + m_itemTarget = nullptr; m_itemTargetEntry = 0; @@ -244,7 +247,7 @@ Unit* SpellCastTargets::GetUnitTarget() const if (m_objectTarget) return m_objectTarget->ToUnit(); - return NULL; + return nullptr; } void SpellCastTargets::SetUnitTarget(Unit* target) @@ -270,7 +273,7 @@ GameObject* SpellCastTargets::GetGOTarget() const if (m_objectTarget) return m_objectTarget->ToGameObject(); - return NULL; + return nullptr; } void SpellCastTargets::SetGOTarget(GameObject* target) @@ -296,7 +299,7 @@ Corpse* SpellCastTargets::GetCorpseTarget() const if (m_objectTarget) return m_objectTarget->ToCorpse(); - return NULL; + return nullptr; } WorldObject* SpellCastTargets::GetObjectTarget() const @@ -311,7 +314,7 @@ ObjectGuid SpellCastTargets::GetObjectTargetGUID() const void SpellCastTargets::RemoveObjectTarget() { - m_objectTarget = NULL; + m_objectTarget = nullptr; m_objectTargetGUID.Clear(); m_targetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_GAMEOBJECT_MASK); } @@ -441,11 +444,21 @@ void SpellCastTargets::RemoveDst() m_targetMask &= ~(TARGET_FLAG_DEST_LOCATION); } +bool SpellCastTargets::HasSrc() const +{ + return (GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION) != 0; +} + +bool SpellCastTargets::HasDst() const +{ + return (GetTargetMask() & TARGET_FLAG_DEST_LOCATION) != 0; +} + void SpellCastTargets::Update(Unit* caster) { - m_objectTarget = m_objectTargetGUID ? ((m_objectTargetGUID == caster->GetGUID()) ? caster : ObjectAccessor::GetWorldObject(*caster, m_objectTargetGUID)) : NULL; + m_objectTarget = m_objectTargetGUID ? ((m_objectTargetGUID == caster->GetGUID()) ? caster : ObjectAccessor::GetWorldObject(*caster, m_objectTargetGUID)) : nullptr; - m_itemTarget = NULL; + m_itemTarget = nullptr; if (caster->GetTypeId() == TYPEID_PLAYER) { Player* player = caster->ToPlayer(); @@ -511,14 +524,28 @@ SpellValue::SpellValue(SpellInfo const* proto) AuraStackAmount = 1; } +class TC_GAME_API SpellEvent : public BasicEvent +{ + public: + SpellEvent(Spell* spell); + virtual ~SpellEvent(); + + bool Execute(uint64 e_time, uint32 p_time) override; + void Abort(uint64 e_time) override; + bool IsDeletable() const override; + + protected: + Spell* m_Spell; +}; + Spell::Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID, bool skipCheck) : m_spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(info, caster)), m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerOrOwner()) ? caster->GetCharmerOrOwner() : caster) -, m_spellValue(new SpellValue(m_spellInfo)), _spellEvent(nullptr), m_preGeneratedPath(PathGenerator(m_caster)) +, m_spellValue(new SpellValue(m_spellInfo)), _spellEvent(nullptr) { m_customError = SPELL_CUSTOM_ERROR_NONE; m_skipCheck = skipCheck; - m_selfContainer = NULL; + m_selfContainer = nullptr; m_referencedFromCurrentSpell = false; m_executedCurrently = false; m_needComboPoints = m_spellInfo->NeedsComboPoints(); @@ -552,7 +579,7 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO { m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID); if (m_originalCaster && !m_originalCaster->IsInWorld()) - m_originalCaster = NULL; + m_originalCaster = nullptr; } m_spellState = SPELL_STATE_NULL; @@ -560,14 +587,14 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO if (info->HasAttribute(SPELL_ATTR4_CAN_CAST_WHILE_CASTING)) _triggeredCastFlags = TriggerCastFlags(uint32(_triggeredCastFlags) | TRIGGERED_IGNORE_CAST_IN_PROGRESS | TRIGGERED_CAST_DIRECTLY); - m_CastItem = NULL; + m_CastItem = nullptr; m_castItemGUID.Clear(); m_castItemEntry = 0; - unitTarget = NULL; - itemTarget = NULL; - gameObjTarget = NULL; - destTarget = NULL; + unitTarget = nullptr; + itemTarget = nullptr; + gameObjTarget = nullptr; + destTarget = nullptr; damage = 0; targetMissInfo = SPELL_MISS_NONE; effectHandleMode = SPELL_EFFECT_HANDLE_LAUNCH; @@ -576,12 +603,12 @@ m_caster((info->HasAttribute(SPELL_ATTR6_CAST_BY_CHARMER) && caster->GetCharmerO m_procAttacker = 0; m_procVictim = 0; m_hitMask = 0; - focusObject = NULL; + focusObject = nullptr; m_cast_count = 0; m_glyphIndex = 0; m_preCastSpell = 0; - m_triggeredByAuraSpell = NULL; - m_spellAura = NULL; + m_triggeredByAuraSpell = nullptr; + m_spellAura = nullptr; //Auto Shot & Shoot (wand) m_autoRepeat = m_spellInfo->IsAutoRepeatRangedSpell(); @@ -622,7 +649,7 @@ Spell::~Spell() // Clean the reference to avoid later crash. // If this error is repeating, we may have to add an ASSERT to better track down how we get into this case. TC_LOG_ERROR("spells", "SPELL: deleting spell for spell ID %u. However, spell still referenced.", m_spellInfo->Id); - *m_selfContainer = NULL; + *m_selfContainer = nullptr; } if (m_caster && m_caster->GetTypeId() == TYPEID_PLAYER) @@ -657,7 +684,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets) // try to select correct unit target if not provided by client or by serverside cast if (neededTargets & (TARGET_FLAG_UNIT_MASK)) { - Unit* unit = NULL; + Unit* unit = nullptr; // try to use player selection as a target if (Player* playerCaster = m_caster->ToPlayer()) { @@ -724,7 +751,7 @@ void Spell::SelectExplicitTargets() redirect = m_caster->GetMeleeHitRedirectTarget(target, m_spellInfo); break; default: - redirect = NULL; + redirect = nullptr; break; } if (redirect && (redirect != target)) @@ -1171,7 +1198,7 @@ void Spell::SelectImplicitConeTargets(SpellEffIndex effIndex, SpellImplicitTarge void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType, uint32 effMask) { - Unit* referer = NULL; + Unit* referer = nullptr; switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_SRC: @@ -1202,7 +1229,7 @@ void Spell::SelectImplicitAreaTargets(SpellEffIndex effIndex, SpellImplicitTarge if (!referer) return; - Position const* center = NULL; + Position const* center = nullptr; switch (targetType.GetReferenceType()) { case TARGET_REFERENCE_TYPE_SRC: @@ -1429,7 +1456,7 @@ void Spell::SelectImplicitDestDestTargets(SpellEffIndex effIndex, SpellImplicitT void Spell::SelectImplicitCasterObjectTargets(SpellEffIndex effIndex, SpellImplicitTargetInfo const& targetType) { - WorldObject* target = NULL; + WorldObject* target = nullptr; bool checkIfValid = true; switch (targetType.GetTarget()) @@ -1498,7 +1525,7 @@ void Spell::SelectImplicitChainTargets(SpellEffIndex effIndex, SpellImplicitTarg { uint32 maxTargets = m_spellInfo->Effects[effIndex].ChainTarget; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_JUMP_TARGETS>(m_spellInfo->Id, maxTargets, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_JUMP_TARGETS, maxTargets, this); if (maxTargets > 1) { @@ -1646,7 +1673,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) if (!targetMask) return; - WorldObject* target = NULL; + WorldObject* target = nullptr; switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType()) { @@ -1759,10 +1786,10 @@ void Spell::SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* refere WorldObject* Spell::SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList) { - WorldObject* target = NULL; + WorldObject* target = nullptr; uint32 containerTypeMask = GetSearcherTypeMask(objectType, condList); if (!containerTypeMask) - return NULL; + return nullptr; Trinity::WorldObjectSpellNearbyTargetCheck check(range, m_caster, m_spellInfo, selectionType, condList); Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> searcher(m_caster, target, check, containerTypeMask); SearchTargets<Trinity::WorldObjectLastSearcher<Trinity::WorldObjectSpellNearbyTargetCheck> > (searcher, containerTypeMask, m_caster, m_caster, range); @@ -1877,7 +1904,7 @@ void Spell::SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTar GameObject* Spell::SearchSpellFocus() { - GameObject* focus = NULL; + GameObject* focus = nullptr; Trinity::GameObjectFocusCheck check(m_caster, m_spellInfo->RequiresSpellFocus); Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> searcher(m_caster, focus, check); SearchTargets<Trinity::GameObjectSearcher<Trinity::GameObjectFocusCheck> > (searcher, GRID_MAP_TYPE_MASK_GAMEOBJECT, m_caster, m_caster, m_caster->GetVisibilityRange()); @@ -2217,7 +2244,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) // can't use default call because of threading, do stuff as fast as possible for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (farMask & (1 << i)) - HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_HIT_TARGET); + HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_HIT_TARGET); return; } @@ -2656,7 +2683,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit* unit, uint32 effectMask, bool scaleA for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) if (effectMask & (1 << effectNumber)) - HandleEffects(unit, NULL, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); + HandleEffects(unit, nullptr, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); return SPELL_MISS_NONE; } @@ -2752,7 +2779,7 @@ void Spell::DoAllEffectOnTarget(GOTargetInfo* target) for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) if (effectMask & (1 << effectNumber)) - HandleEffects(NULL, NULL, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); + HandleEffects(nullptr, nullptr, go, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); if (go->AI()) go->AI()->SpellHit(m_caster, m_spellInfo); @@ -2772,7 +2799,7 @@ void Spell::DoAllEffectOnTarget(ItemTargetInfo* target) for (uint32 effectNumber = 0; effectNumber < MAX_SPELL_EFFECTS; ++effectNumber) if (effectMask & (1 << effectNumber)) - HandleEffects(NULL, target->item, NULL, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); + HandleEffects(nullptr, target->item, nullptr, effectNumber, SPELL_EFFECT_HANDLE_HIT_TARGET); CallScriptOnHitHandlers(); @@ -2798,7 +2825,7 @@ bool Spell::UpdateChanneledTargetList() { range = m_spellInfo->GetMaxRange(m_spellInfo->IsPositive()); if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, range, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, range, this); // add little tolerance level range += std::min(MAX_SPELL_RANGE_TOLERANCE, range*0.1f); // 10% but no more than MAX_SPELL_RANGE_TOLERANCE @@ -3051,7 +3078,7 @@ void Spell::cancel() SetReferencedFromCurrent(false); if (m_selfContainer && *m_selfContainer == this) - *m_selfContainer = NULL; + *m_selfContainer = nullptr; m_caster->RemoveDynObject(m_spellInfo->Id); if (m_spellInfo->IsChanneled()) // if not channeled then the object for the current cast wasn't summoned yet @@ -3106,7 +3133,7 @@ void Spell::_cast(bool skipCheck) // As of 3.0.2 pets begin attacking their owner's target immediately // Let any pets know we've attacked something. Check DmgClass for harmful spells only // This prevents spells such as Hunter's Mark from triggering pet attack - if (this->GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE) + if (GetSpellInfo()->DmgClass != SPELL_DAMAGE_CLASS_NONE) if (Unit* unitTarget = m_targets.GetUnitTarget()) for (Unit* controlled : playerCaster->m_Controlled) if (Creature* cControlled = controlled->ToCreature()) @@ -3317,7 +3344,7 @@ void Spell::handle_immediate() // First mod_duration then haste - see Missile Barrage // Apply duration mod if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); // Apply haste mods m_caster->ModSpellDurationTime(m_spellInfo, duration, this); @@ -3445,7 +3472,7 @@ uint64 Spell::handle_delayed(uint64 t_offset) void Spell::_handle_immediate_phase() { - m_spellAura = NULL; + m_spellAura = nullptr; // handle some immediate features of the spell here HandleThreatSpells(); @@ -3460,7 +3487,7 @@ void Spell::_handle_immediate_phase() continue; // call effect handlers to handle destination hit - HandleEffects(NULL, NULL, NULL, j, SPELL_EFFECT_HANDLE_HIT); + HandleEffects(nullptr, nullptr, nullptr, j, SPELL_EFFECT_HANDLE_HIT); } // process items @@ -3897,7 +3924,7 @@ void Spell::SendPetCastResult(SpellCastResult result) WorldPacket data(SMSG_PET_CAST_FAILED, 1 + 4 + 1); WriteCastResultInfo(data, player, m_spellInfo, m_cast_count, result, m_customError); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } void Spell::SendSpellStart() @@ -4221,7 +4248,7 @@ void Spell::SendLogExecute() data.append(*m_effectExecuteData[i]); delete m_effectExecuteData[i]; - m_effectExecuteData[i] = NULL; + m_effectExecuteData[i] = nullptr; } m_caster->SendMessageToSet(&data, true); } @@ -4367,7 +4394,7 @@ void Spell::SendResurrectRequest(Player* target) data << uint8(m_caster->IsSpiritHealer()); // "you'll be afflicted with resurrection sickness" // override delay sent with SMSG_CORPSE_RECLAIM_DELAY, set instant resurrection for spells with this attribute data << uint8(!m_spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_RESURRECTION_TIMER)); - target->GetSession()->SendPacket(&data); + target->SendDirectMessage(&data); } void Spell::TakeCastItem() @@ -4430,9 +4457,9 @@ void Spell::TakeCastItem() // prevent crash at access to deleted m_targets.GetItemTarget if (m_CastItem == m_targets.GetItemTarget()) - m_targets.SetItemTarget(NULL); + m_targets.SetItemTarget(nullptr); - m_CastItem = NULL; + m_CastItem = nullptr; m_castItemGUID.Clear(); m_castItemEntry = 0; } @@ -4455,8 +4482,11 @@ void Spell::TakePower() if (m_caster->GetTypeId() == TYPEID_PLAYER) { if (powerType == POWER_RAGE || powerType == POWER_ENERGY || powerType == POWER_RUNE) + { if (ObjectGuid targetGUID = m_targets.GetUnitTargetGUID()) - for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + { + for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + { if (ihit->targetGUID == targetGUID) { if (ihit->missCondition != SPELL_MISS_NONE) @@ -4464,10 +4494,13 @@ void Spell::TakePower() hit = false; //lower spell cost on fail (by talent aura) if (Player* modOwner = m_caster->ToPlayer()->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_SPELL_COST_REFUND_ON_FAIL>(m_spellInfo->Id, m_powerCost); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_SPELL_COST_REFUND_ON_FAIL, m_powerCost); } break; } + } + } + } } if (powerType == POWER_RUNE) @@ -4556,7 +4589,7 @@ SpellCastResult Spell::CheckRuneCost(uint32 runeCostID) const { runeCost[i] = src->RuneCost[i]; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], const_cast<Spell*>(this)); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], const_cast<Spell*>(this)); } runeCost[RUNE_DEATH] = MAX_RUNES; // calculated later @@ -4596,7 +4629,7 @@ void Spell::TakeRunePower(bool didHit) { runeCost[i] = runeCostData->RuneCost[i]; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_COST>(m_spellInfo->Id, runeCost[i], this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_COST, runeCost[i], this); } // Let's say we use a skill that requires a Frost rune. This is the order: @@ -4673,7 +4706,7 @@ void Spell::TakeReagents() if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : NULL; + ItemTemplate const* castItemTemplate = m_CastItem ? m_CastItem->GetTemplate() : nullptr; // do not take reagents for these item casts if (castItemTemplate && castItemTemplate->Flags & ITEM_FLAG_NO_REAGENT_COST) @@ -4705,14 +4738,14 @@ void Spell::TakeReagents() } } - m_CastItem = NULL; + m_CastItem = nullptr; m_castItemGUID.Clear(); m_castItemEntry = 0; } // if GetItemTarget is also spell reagent if (m_targets.GetItemTargetEntry() == itemid) - m_targets.SetItemTarget(NULL); + m_targets.SetItemTarget(nullptr); p_caster->DestroyItemCount(itemid, itemcount, true); } @@ -4782,7 +4815,7 @@ void Spell::HandleEffects(Unit* pUnitTarget, Item* pItemTarget, GameObject* pGOT TC_LOG_DEBUG("spells", "Spell: %u Effect : %u", m_spellInfo->Id, eff); // we do not need DamageMultiplier here. - damage = CalculateDamage(i, NULL); + damage = CalculateDamage(i, nullptr); bool preventDefault = CallScriptEffectHandlers((SpellEffIndex)i, mode); @@ -4888,7 +4921,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint m_needComboPoints = false; if ((*j)->GetMiscValue() == 1) { - reqCombat=false; + reqCombat = false; break; } } @@ -4989,7 +5022,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint if (DynamicObject* dynObj = m_caster->GetDynObject(m_triggeredByAuraSpell->Id)) losTarget = dynObj; - if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, nullptr, SPELL_DISABLE_LOS) && !target->IsWithinLOSInMap(losTarget, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) return SPELL_FAILED_LINE_OF_SIGHT; } } @@ -5001,7 +5034,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint float x, y, z; m_targets.GetDstPos()->GetPosition(x, y, z); - if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) + if (!m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) && !DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, nullptr, SPELL_DISABLE_LOS) && !m_caster->IsWithinLOS(x, y, z, LINEOFSIGHT_ALL_CHECKS, VMAP::ModelIgnoreFlags::M2)) return SPELL_FAILED_LINE_OF_SIGHT; } @@ -5262,26 +5295,27 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint float objSize = target->GetCombatReach(); float range = m_spellInfo->GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict - m_preGeneratedPath.SetPathLengthLimit(range); + m_preGeneratedPath = Trinity::make_unique<PathGenerator>(m_caster); + m_preGeneratedPath->SetPathLengthLimit(range); // first try with raycast, if it fails fall back to normal path float targetObjectSize = std::min(target->GetCombatReach(), 4.0f); - bool result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true); - if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) + bool result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, true); + if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; - else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) + else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) { - result = m_preGeneratedPath.CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, false); - if (m_preGeneratedPath.GetPathType() & PATHFIND_SHORT) + result = m_preGeneratedPath->CalculatePath(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ() + targetObjectSize, false, false); + if (m_preGeneratedPath->GetPathType() & PATHFIND_SHORT) return SPELL_FAILED_OUT_OF_RANGE; - else if (!result || m_preGeneratedPath.GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) + else if (!result || m_preGeneratedPath->GetPathType() & (PATHFIND_NOPATH | PATHFIND_INCOMPLETE)) return SPELL_FAILED_NOPATH; - else if (m_preGeneratedPath.IsInvalidDestinationZ(target)) // Check position z, if not in a straight line + else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if not in a straight line return SPELL_FAILED_NOPATH; } - else if (m_preGeneratedPath.IsInvalidDestinationZ(target)) // Check position z, if in a straight line + else if (m_preGeneratedPath->IsInvalidDestinationZ(target)) // Check position z, if in a straight line return SPELL_FAILED_NOPATH; - m_preGeneratedPath.ReducePathLenghtByDist(objSize); // move back + m_preGeneratedPath->ReducePathLenghtByDist(objSize); // move back } break; } @@ -5324,7 +5358,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint || (m_spellInfo->Effects[i].TargetA.GetTarget() == TARGET_GAMEOBJECT_TARGET && !m_targets.GetGOTarget())) return SPELL_FAILED_BAD_TARGETS; - Item* pTempItem = NULL; + Item* pTempItem = nullptr; if (m_targets.GetTargetMask() & TARGET_FLAG_TRADE_ITEM) { if (TradeData* pTrade = m_caster->ToPlayer()->GetTradeData()) @@ -5424,7 +5458,7 @@ SpellCastResult Spell::CheckCast(bool strict, uint32* param1 /*= nullptr*/, uint { if (strict) //starting cast, trigger pet stun (cast by pet so it doesn't attack player) if (Pet* pet = m_caster->ToPlayer()->GetPet()) - pet->CastSpell(pet, 32752, true, NULL, NULL, pet->GetGUID()); + pet->CastSpell(pet, 32752, true, nullptr, nullptr, pet->GetGUID()); } else if (!m_spellInfo->HasAttribute(SPELL_ATTR1_DISMISS_PET)) return SPELL_FAILED_ALREADY_HAVE_SUMMON; @@ -5938,6 +5972,11 @@ bool Spell::CheckSpellCancelsConfuse(uint32* param1) const return CheckSpellCancelsAuraEffect(SPELL_AURA_MOD_CONFUSE, param1); } +int32 Spell::CalculateDamage(uint8 i, Unit const* target) const +{ + return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i]); +} + bool Spell::CanAutoCast(Unit* target) { if (!target) @@ -5994,6 +6033,18 @@ bool Spell::CanAutoCast(Unit* target) return false; } +void Spell::CheckSrc() +{ + if (!m_targets.HasSrc()) + m_targets.SetSrc(*m_caster); +} + +void Spell::CheckDst() +{ + if (!m_targets.HasDst()) + m_targets.SetDst(*m_caster); +} + SpellCastResult Spell::CheckRange(bool strict) const { // Don't check for instant cast spells @@ -6083,7 +6134,7 @@ std::pair<float, float> Spell::GetMinMaxRange(bool strict) const maxRange *= ranged->GetTemplate()->RangedModRange * 0.01f; if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RANGE>(m_spellInfo->Id, maxRange, const_cast<Spell*>(this)); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RANGE, maxRange, const_cast<Spell*>(this)); maxRange += rangeMod; @@ -6693,7 +6744,7 @@ void Spell::Delayed() // only called in DealDamage() //check pushback reduce int32 delaytime = 500; // spellcasting delay is normally 500ms int32 delayReduce = 100; // must be initialized to 100 for percent modifiers - m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this); + m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this); delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100; if (delayReduce >= 100) return; @@ -6731,7 +6782,7 @@ void Spell::DelayedChannel() int32 delaytime = CalculatePct(duration, 25); // channeling delay is normally 25% of its time per hit int32 delayReduce = 100; // must be initialized to 100 for percent modifiers - m_caster->ToPlayer()->ApplySpellMod<SPELLMOD_NOT_LOSE_CASTING_TIME>(m_spellInfo->Id, delayReduce, this); + m_caster->ToPlayer()->ApplySpellMod(m_spellInfo->Id, SPELLMOD_NOT_LOSE_CASTING_TIME, delayReduce, this); delayReduce += m_caster->GetTotalAuraModifier(SPELL_AURA_REDUCE_PUSHBACK) - 100; if (delayReduce >= 100) return; @@ -6768,7 +6819,7 @@ bool Spell::UpdatePointers() { m_originalCaster = ObjectAccessor::GetUnit(*m_caster, m_originalCasterGUID); if (m_originalCaster && !m_originalCaster->IsInWorld()) - m_originalCaster = NULL; + m_originalCaster = nullptr; } if (m_castItemGUID && m_caster->GetTypeId() == TYPEID_PLAYER) @@ -6790,7 +6841,7 @@ bool Spell::UpdatePointers() return true; // cache last transport - WorldObject* transport = NULL; + WorldObject* transport = nullptr; // update effect destinations (in case of moved transport dest target) for (uint8 effIndex = 0; effIndex < MAX_SPELL_EFFECTS; ++effIndex) @@ -6847,11 +6898,11 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo } // check for ignore LOS on the effect itself - if (m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, NULL, SPELL_DISABLE_LOS)) + if (m_spellInfo->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_spellInfo->Id, nullptr, SPELL_DISABLE_LOS)) return true; // if spell is triggered, need to check for LOS disable on the aura triggering it and inherit that behaviour - if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, NULL, SPELL_DISABLE_LOS))) + if (IsTriggered() && m_triggeredByAuraSpell && (m_triggeredByAuraSpell->HasAttribute(SPELL_ATTR2_CAN_TARGET_NOT_IN_LOS) || DisableMgr::IsDisabledFor(DISABLE_TYPE_SPELL, m_triggeredByAuraSpell->Id, nullptr, SPELL_DISABLE_LOS))) return true; /// @todo shit below shouldn't be here, but it's temporary @@ -6910,7 +6961,7 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo else { // Get GO cast coordinates if original caster -> GO - WorldObject* caster = NULL; + WorldObject* caster = nullptr; if (m_originalCasterGUID.IsGameObject()) caster = m_caster->GetMap()->GetGameObject(m_originalCasterGUID); if (!caster) @@ -6925,6 +6976,26 @@ bool Spell::CheckEffectTarget(Unit const* target, uint32 eff, Position const* lo return true; } +bool Spell::IsTriggered() const +{ + return (_triggeredCastFlags & TRIGGERED_FULL_MASK) != 0; +} + +bool Spell::IsIgnoringCooldowns() const +{ + return (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) != 0; +} + +bool Spell::IsProcDisabled() const +{ + return (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) != 0; +} + +bool Spell::IsChannelActive() const +{ + return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; +} + bool Spell::IsAutoActionResetSpell() const { /// @todo changed SPELL_INTERRUPT_FLAG_AUTOATTACK -> SPELL_INTERRUPT_FLAG_INTERRUPT to fix compile - is this check correct at all? @@ -7099,7 +7170,7 @@ void Spell::HandleLaunchPhase() if (!m_spellInfo->Effects[i].IsEffect()) continue; - HandleEffects(NULL, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH); + HandleEffects(nullptr, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH); } float multiplier[MAX_SPELL_EFFECTS]; @@ -7155,7 +7226,7 @@ void Spell::HandleLaunchPhase() void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) { - Unit* unit = NULL; + Unit* unit = nullptr; // In case spell hit target, do all effect on that target if (targetInfo.missCondition == SPELL_MISS_NONE) unit = m_caster->GetGUID() == targetInfo.targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, targetInfo.targetGUID); @@ -7172,7 +7243,7 @@ void Spell::DoAllEffectOnLaunchTarget(TargetInfo& targetInfo, float* multiplier) m_damage = 0; m_healing = 0; - HandleEffects(unit, NULL, NULL, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); + HandleEffects(unit, nullptr, nullptr, i, SPELL_EFFECT_HANDLE_LAUNCH_TARGET); if (m_damage > 0) { @@ -7662,7 +7733,7 @@ void Spell::TriggerGlobalCooldown() { // gcd modifier auras are applied only to own spells and only players have such mods if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_GLOBAL_COOLDOWN>(m_spellInfo->Id, gcd, this); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_GLOBAL_COOLDOWN, gcd, this); // Apply haste rating gcd = int32(float(gcd) * m_caster->GetFloatValue(UNIT_MOD_CAST_SPEED)); diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index 7cea09d5c21..6d9bd44e9f1 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -19,21 +19,39 @@ #ifndef __SPELL_H #define __SPELL_H -#include "GridDefines.h" +#include "ConditionMgr.h" +#include "DBCEnums.h" +#include "ObjectGuid.h" +#include "Position.h" #include "SharedDefines.h" -#include "ObjectMgr.h" -#include "SpellInfo.h" -#include "PathGenerator.h" +#include <memory> -class Unit; -class Player; -class GameObject; -class DynamicObject; -class WorldObject; class Aura; -class SpellScript; -class ByteBuffer; +class AuraEffect; +class Corpse; +class DynamicObject; +class GameObject; +class Item; +class Object; +class PathGenerator; +class Player; class SpellEvent; +class SpellImplicitTargetInfo; +class SpellInfo; +class SpellScript; +class Unit; +class WorldObject; +class WorldPacket; +struct SummonPropertiesEntry; +enum AuraType : uint32; +enum CurrentSpellTypes : uint8; +enum LootType : uint8; +enum SpellCastTargetFlags : uint32; +enum SpellTargetCheckTypes : uint8; +enum SpellTargetObjectTypes : uint8; +enum SpellValueMod : uint8; +enum TriggerCastFlags : uint32; +enum WeaponAttackType : uint8; #define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILLISECONDS) #define MAX_SPELL_RANGE_TOLERANCE 3.0f @@ -156,8 +174,8 @@ class TC_GAME_API SpellCastTargets void ModDst(SpellDestination const& spellDest); void RemoveDst(); - bool HasSrc() const { return (GetTargetMask() & TARGET_FLAG_SOURCE_LOCATION) != 0; } - bool HasDst() const { return (GetTargetMask() & TARGET_FLAG_DEST_LOCATION) != 0; } + bool HasSrc() const; + bool HasDst() const; bool HasTraj() const { return m_speed != 0; } float GetElevation() const { return m_elevation; } @@ -225,7 +243,6 @@ static const uint32 SPELL_INTERRUPT_NONPLAYER = 32747; class TC_GAME_API Spell { - friend void Unit::SetCurrentCastSpell(Spell* pSpell); friend class SpellScript; public: @@ -382,13 +399,13 @@ class TC_GAME_API Spell uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionContainer* condList); template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius); - WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList = NULL); + WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList = nullptr); void SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList); void SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal); GameObject* SearchSpellFocus(); - void prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura = NULL); + void prepare(SpellCastTargets const* targets, AuraEffect const* triggeredByAura = nullptr); void cancel(); void update(uint32 difftime); void cast(bool skipCheck = false); @@ -424,7 +441,7 @@ class TC_GAME_API Spell bool CheckSpellCancelsFear(uint32* param1) const; bool CheckSpellCancelsConfuse(uint32* param1) const; - int32 CalculateDamage(uint8 i, Unit const* target) const { return m_caster->CalculateSpellDamage(target, m_spellInfo, i, &m_spellValue->EffectBasePoints[i]); } + int32 CalculateDamage(uint8 i, Unit const* target) const; bool HaveTargetsForEffect(uint8 effect) const; void Delayed(); @@ -438,8 +455,8 @@ class TC_GAME_API Spell bool CheckEffectTarget(Unit const* target, uint32 eff, Position const* losPosition) const; bool CanAutoCast(Unit* target); - void CheckSrc() { if (!m_targets.HasSrc()) m_targets.SetSrc(*m_caster); } - void CheckDst() { if (!m_targets.HasDst()) m_targets.SetDst(*m_caster); } + void CheckSrc(); + void CheckDst(); static void WriteCastResultInfo(WorldPacket& data, Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError, uint32* param1 = nullptr, uint32* param2 = nullptr); static void SendCastResult(Player* caster, SpellInfo const* spellInfo, uint8 castCount, SpellCastResult result, SpellCustomErrors customError = SPELL_CUSTOM_ERROR_NONE, uint32* param1 = nullptr, uint32* param2 = nullptr); @@ -484,10 +501,10 @@ class TC_GAME_API Spell bool IsAutoRepeat() const { return m_autoRepeat; } void SetAutoRepeat(bool rep) { m_autoRepeat = rep; } void ReSetTimer() { m_timer = m_casttime > 0 ? m_casttime : 0; } - bool IsTriggered() const { return (_triggeredCastFlags & TRIGGERED_FULL_MASK) != 0; } - bool IsIgnoringCooldowns() const { return (_triggeredCastFlags & TRIGGERED_IGNORE_SPELL_AND_CATEGORY_CD) != 0; } - bool IsProcDisabled() const { return (_triggeredCastFlags & TRIGGERED_DISALLOW_PROC_EVENTS) != 0; } - bool IsChannelActive() const { return m_caster->GetUInt32Value(UNIT_CHANNEL_SPELL) != 0; } + bool IsTriggered() const; + bool IsIgnoringCooldowns() const; + bool IsProcDisabled() const; + bool IsChannelActive() const; bool IsAutoActionResetSpell() const; bool IsTriggeredByAura(SpellInfo const* auraSpellInfo) const { return (auraSpellInfo == m_triggeredByAuraSpell); } @@ -516,6 +533,9 @@ class TC_GAME_API Spell void CleanupTargetList(); void SetSpellValue(SpellValueMod mod, int32 value); + + Spell** m_selfContainer; // pointer to our spell container (if applicable) + protected: bool HasGlobalCooldown() const; void TriggerGlobalCooldown(); @@ -533,8 +553,6 @@ class TC_GAME_API Spell // e.g. damage around area spell trigered by victim aura and damage enemies of aura caster Unit* m_originalCaster; // cached pointer for m_originalCaster, updated at Spell::UpdatePointers() - Spell** m_selfContainer; // pointer to our spell container (if applicable) - //Spell data SpellSchoolMask m_spellSchoolMask; // Spell school (can be overwrite for some spells (wand shoot for example) WeaponAttackType m_attackType; // For weapon based attack @@ -684,7 +702,7 @@ class TC_GAME_API Spell int32 chance; }; - bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura = NULL) const; + bool CanExecuteTriggersOnHit(uint8 effMask, SpellInfo const* triggeredByAura = nullptr) const; void PrepareTriggersExecutedOnHit(); typedef std::vector<HitTriggerSpell> HitTriggerSpellList; HitTriggerSpellList m_hitTriggerSpells; @@ -709,7 +727,7 @@ class TC_GAME_API Spell bool m_skipCheck; uint8 m_auraScaleMask; - PathGenerator m_preGeneratedPath; + std::unique_ptr<PathGenerator> m_preGeneratedPath; ByteBuffer * m_effectExecuteData[MAX_SPELL_EFFECTS]; @@ -772,16 +790,4 @@ namespace Trinity typedef void(Spell::*pEffect)(SpellEffIndex effIndex); -class TC_GAME_API SpellEvent : public BasicEvent -{ - 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; - protected: - Spell* m_Spell; -}; #endif diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 3dee9ae956b..21ed4ceec23 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -16,45 +16,49 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "Spell.h" +#include "AccountMgr.h" +#include "Battleground.h" +#include "CellImpl.h" #include "Common.h" +#include "Creature.h" +#include "CreatureAI.h" #include "DatabaseEnv.h" -#include "WorldPacket.h" -#include "Opcodes.h" -#include "Log.h" -#include "UpdateMask.h" -#include "World.h" -#include "ObjectMgr.h" -#include "SpellMgr.h" -#include "Player.h" -#include "SkillExtraItems.h" -#include "Unit.h" -#include "Spell.h" #include "DynamicObject.h" -#include "SpellAuras.h" -#include "SpellAuraEffects.h" -#include "SharedDefines.h" -#include "Pet.h" +#include "Formulas.h" #include "GameObject.h" +#include "GameObjectAI.h" #include "GossipDef.h" -#include "Creature.h" -#include "Totem.h" -#include "CreatureAI.h" -#include "Battleground.h" -#include "OutdoorPvPMgr.h" -#include "Language.h" -#include "SocialMgr.h" -#include "Util.h" -#include "TemporarySummon.h" #include "GridNotifiers.h" -#include "CellImpl.h" -#include "Formulas.h" -#include "ScriptMgr.h" -#include "SpellHistory.h" -#include "GameObjectAI.h" -#include "AccountMgr.h" #include "InstanceScript.h" +#include "Item.h" +#include "Language.h" +#include "Log.h" +#include "LootMgr.h" +#include "MotionMaster.h" +#include "ObjectMgr.h" +#include "Opcodes.h" +#include "OutdoorPvPMgr.h" #include "PathGenerator.h" +#include "Pet.h" +#include "Player.h" #include "ReputationMgr.h" +#include "ScriptMgr.h" +#include "SkillExtraItems.h" +#include "SharedDefines.h" +#include "SocialMgr.h" +#include "SpellAuraEffects.h" +#include "SpellAuras.h" +#include "SpellHistory.h" +#include "SpellMgr.h" +#include "TemporarySummon.h" +#include "Totem.h" +#include "UpdateMask.h" +#include "Unit.h" +#include "Util.h" +#include "World.h" +#include "WorldPacket.h" +#include "WorldSession.h" pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= { @@ -282,7 +286,7 @@ void Spell::EffectInstaKill(SpellEffIndex /*effIndex*/) data << uint32(m_spellInfo->Id); m_caster->SendMessageToSet(&data, true); - m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), NULL, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); + m_caster->DealDamage(unitTarget, unitTarget->GetHealth(), nullptr, NODAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); } void Spell::EffectEnvironmentalDMG(SpellEffIndex /*effIndex*/) @@ -428,7 +432,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) // Calculate damage of Immolate/Shadowflame tick int32 pdamage = (aura->GetAmount() + aura->GetBonusAmount()) * aura->GetDonePct(); if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DOT>(GetSpellInfo()->Id, pdamage); + modOwner->ApplySpellMod(GetSpellInfo()->Id, SPELLMOD_DOT, pdamage); pdamage = unitTarget->SpellDamageBonusTaken(m_caster, aura->GetSpellInfo(), pdamage, DOT); @@ -460,7 +464,7 @@ void Spell::EffectSchoolDMG(SpellEffIndex effIndex) if (AuraEffect* aurEff = owner->GetAuraEffect(SPELL_AURA_ADD_FLAT_MODIFIER, SPELLFAMILY_WARLOCK, 214, 0)) { int32 bp0 = aurEff->GetId() == 54037 ? 4 : 8; - m_caster->CastCustomSpell(m_caster, 54425, &bp0, NULL, NULL, true); + m_caster->CastCustomSpell(m_caster, 54425, &bp0, nullptr, nullptr, true); } } } @@ -880,7 +884,7 @@ void Spell::EffectTriggerSpell(SpellEffIndex effIndex) } // original caster guid only for GO cast - m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID); + m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID); } void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex) @@ -928,7 +932,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffIndex effIndex) } // original caster guid only for GO cast - m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, NULL, NULL, m_originalCasterGUID); + m_caster->CastSpell(targets, spellInfo, &values, TRIGGERED_FULL_MASK, nullptr, nullptr, m_originalCasterGUID); } void Spell::EffectForceCast(SpellEffIndex effIndex) @@ -960,7 +964,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex) break; case 52463: // Hide In Mine Car case 52349: // Overtake - unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, NULL, NULL, true, NULL, NULL, m_originalCasterGUID); + unitTarget->CastCustomSpell(unitTarget, spellInfo->Id, &damage, nullptr, nullptr, true, nullptr, nullptr, m_originalCasterGUID); return; } } @@ -968,7 +972,7 @@ void Spell::EffectForceCast(SpellEffIndex effIndex) switch (spellInfo->Id) { case 72298: // Malleable Goo Summon - unitTarget->CastSpell(unitTarget, spellInfo->Id, true, NULL, NULL, m_originalCasterGUID); + unitTarget->CastSpell(unitTarget, spellInfo->Id, true, nullptr, nullptr, m_originalCasterGUID); return; } @@ -1004,7 +1008,7 @@ void Spell::EffectTriggerRitualOfSummoning(SpellEffIndex effIndex) finish(); - m_caster->CastSpell((Unit*)NULL, spellInfo, false); + m_caster->CastSpell((Unit*)nullptr, spellInfo, false); } void Spell::EffectJump(SpellEffIndex effIndex) @@ -1265,7 +1269,7 @@ void Spell::EffectSendEvent(SpellEffIndex effIndex) && effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - WorldObject* target = NULL; + WorldObject* target = nullptr; // call events for object target if present if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) @@ -1379,7 +1383,7 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/) { Unit::AuraEffectList const& RejorRegr = unitTarget->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HEAL); // find most short by duration - AuraEffect* targetAura = NULL; + AuraEffect* targetAura = nullptr; for (Unit::AuraEffectList::const_iterator i = RejorRegr.begin(); i != RejorRegr.end(); ++i) { if ((*i)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_DRUID @@ -1398,7 +1402,7 @@ void Spell::EffectHeal(SpellEffIndex /*effIndex*/) int32 tickheal = (targetAura->GetAmount() + targetAura->GetBonusAmount()) * targetAura->GetDonePct(); if (Player* modOwner = m_caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DOT>(targetAura->GetId(), tickheal); + modOwner->ApplySpellMod(targetAura->GetId(), SPELLMOD_DOT, tickheal); unitTarget->SpellHealingBonusTaken(m_caster, targetAura->GetSpellInfo(), tickheal, DOT); @@ -1529,7 +1533,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(newitemid); if (!pProto) { - player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } @@ -1606,7 +1610,7 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) else { // if not created by another reason from full inventory or unique items amount limitation - player->SendEquipError(msg, NULL, NULL, newitemid); + player->SendEquipError(msg, nullptr, nullptr, newitemid); return; } } @@ -1614,12 +1618,12 @@ void Spell::DoCreateItem(uint32 /*i*/, uint32 itemtype) if (num_to_add) { // create the new item and store it - Item* pItem = player->StoreNewItem(dest, newitemid, true, Item::GenerateItemRandomPropertyId(newitemid)); + Item* pItem = player->StoreNewItem(dest, newitemid, true, GenerateItemRandomPropertyId(newitemid)); // was it successful? return error if not if (!pItem) { - player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } @@ -2054,9 +2058,9 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) // prevent crash at access and unexpected charges counting with item update queue corrupt if (m_CastItem == m_targets.GetItemTarget()) - m_targets.SetItemTarget(NULL); + m_targets.SetItemTarget(nullptr); - m_CastItem = NULL; + m_CastItem = nullptr; m_castItemGUID.Clear(); m_castItemEntry = 0; @@ -2075,9 +2079,9 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) // prevent crash at access and unexpected charges counting with item update queue corrupt if (m_CastItem == m_targets.GetItemTarget()) - m_targets.SetItemTarget(NULL); + m_targets.SetItemTarget(nullptr); - m_CastItem = NULL; + m_CastItem = nullptr; m_castItemGUID.Clear(); m_castItemEntry = 0; @@ -2099,9 +2103,9 @@ void Spell::EffectSummonChangeItem(SpellEffIndex effIndex) // prevent crash at access and unexpected charges counting with item update queue corrupt if (m_CastItem == m_targets.GetItemTarget()) - m_targets.SetItemTarget(NULL); + m_targets.SetItemTarget(nullptr); - m_CastItem = NULL; + m_CastItem = nullptr; m_castItemGUID.Clear(); m_castItemEntry = 0; @@ -2160,9 +2164,9 @@ void Spell::EffectSummonType(SpellEffIndex effIndex) int32 duration = m_spellInfo->GetDuration(); if (Player* modOwner = m_originalCaster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); - TempSummon* summon = NULL; + TempSummon* summon = nullptr; // determine how many units should be summoned uint32 numSummons; @@ -2444,11 +2448,11 @@ void Spell::EffectDispel(SpellEffIndex effIndex) if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->GetCategory() == SPELLCATEGORY_DEVOUR_MAGIC) { int32 heal_amount = m_spellInfo->Effects[EFFECT_1].CalcValue(); - m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true); + m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, nullptr, nullptr, true); // Glyph of Felhunter if (Unit* owner = m_caster->GetOwner()) if (owner->GetAura(56249)) - owner->CastCustomSpell(owner, 19658, &heal_amount, NULL, NULL, true); + owner->CastCustomSpell(owner, 19658, &heal_amount, nullptr, nullptr, true); } } @@ -2594,7 +2598,7 @@ void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/) // not scale value for item based reward (/10 value expected) if (m_CastItem) { - unitTarget->ToPlayer()->RewardHonor(NULL, 1, damage/10); + unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage/10); TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(), unitTarget->ToPlayer()->GetGUID().GetCounter()); return; } @@ -2603,13 +2607,13 @@ void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/) if (damage <= 50) { uint32 honor_reward = Trinity::Honor::hk_honor_at_level(unitTarget->getLevel(), float(damage)); - unitTarget->ToPlayer()->RewardHonor(NULL, 1, honor_reward); + unitTarget->ToPlayer()->RewardHonor(nullptr, 1, honor_reward); TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u", m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().GetCounter()); } else { //maybe we have correct honor_gain in damage already - unitTarget->ToPlayer()->RewardHonor(NULL, 1, damage); + unitTarget->ToPlayer()->RewardHonor(nullptr, 1, damage); TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u", m_spellInfo->Id, damage, unitTarget->ToPlayer()->GetGUID().GetCounter()); } } @@ -2647,8 +2651,8 @@ void Spell::EffectEnchantItemPerm(SpellEffIndex effIndex) unitTarget = player; // and add a scroll DoCreateItem(effIndex, m_spellInfo->Effects[effIndex].ItemType); - itemTarget = NULL; - m_targets.SetItemTarget(NULL); + itemTarget = nullptr; + m_targets.SetItemTarget(nullptr); } else { @@ -2945,7 +2949,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex) if (effectHandleMode != SPELL_EFFECT_HANDLE_HIT) return; - Player* owner = NULL; + Player* owner = nullptr; if (m_originalCaster) { owner = m_originalCaster->ToPlayer(); @@ -3021,7 +3025,7 @@ void Spell::EffectSummonPet(SpellEffIndex effIndex) pet->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); // generate new name for summon pet - std::string new_name=sObjectMgr->GeneratePetName(petentry); + std::string new_name = sObjectMgr->GeneratePetName(petentry); if (!new_name.empty()) pet->SetName(new_name); @@ -3200,7 +3204,7 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex) // Skyshatter Harness item set bonus // Stormstrike if (AuraEffect* aurEff = m_caster->IsScriptOverriden(m_spellInfo, 5634)) - m_caster->CastSpell(m_caster, 38430, true, NULL, aurEff); + m_caster->CastSpell(m_caster, 38430, true, nullptr, aurEff); break; } case SPELLFAMILY_DRUID: @@ -3463,7 +3467,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) Map* map = target->GetMap(); - G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(target->GetOrientation(), 0.f, 0.f); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(target->GetOrientation(), 0.f, 0.f); if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), Position(x, y, z, target->GetOrientation()), rot, 255, GO_STATE_READY)) { delete pGameObj; @@ -3550,7 +3554,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) uint32 spell_id = roll_chance_i(20) ? 8854 : 8855; - m_caster->CastSpell(m_caster, spell_id, true, NULL); + m_caster->CastSpell(m_caster, spell_id, true, nullptr); return; } // Brittle Armor - need remove one 24575 Brittle Armor aura @@ -3631,7 +3635,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) uint8 bag = 19; uint8 slot = 0; - Item* item = NULL; + Item* item = nullptr; while (bag) // 256 = 0 due to var type { @@ -3859,7 +3863,7 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) // proc a spellcast if (Aura* chargesAura = m_caster->GetAura(59907)) { - m_caster->CastSpell(unitTarget, spell_heal, true, NULL, NULL, m_caster->ToTempSummon()->GetSummonerGUID()); + m_caster->CastSpell(unitTarget, spell_heal, true, nullptr, nullptr, m_caster->ToTempSummon()->GetSummonerGUID()); if (chargesAura->ModCharges(-1)) m_caster->ToTempSummon()->UnSummon(); } @@ -3888,14 +3892,14 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex) Creature* totem = unitTarget->GetMap()->GetCreature(unitTarget->m_SummonSlot[slot]); if (totem && totem->IsTotem()) { - m_caster->CastCustomSpell(totem, 55277, &basepoints0, NULL, NULL, true); + m_caster->CastCustomSpell(totem, 55277, &basepoints0, nullptr, nullptr, true); } } // Glyph of Stoneclaw Totem - if (AuraEffect* aur=unitTarget->GetAuraEffect(63298, 0)) + if (AuraEffect* aur = unitTarget->GetAuraEffect(63298, 0)) { basepoints0 *= aur->GetAmount(); - m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, NULL, NULL, true); + m_caster->CastCustomSpell(unitTarget, 55277, &basepoints0, nullptr, nullptr, true); } break; } @@ -4033,7 +4037,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) }; Map* map = m_caster->GetMap(); - G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(pos.GetOrientation(), 0.f, 0.f); if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), pos, rot, 0, GO_STATE_READY)) { delete pGameObj; @@ -4056,8 +4060,8 @@ void Spell::EffectDuel(SpellEffIndex effIndex) WorldPacket data(SMSG_DUEL_REQUESTED, 8 + 8); data << uint64(pGameObj->GetGUID()); data << uint64(caster->GetGUID()); - caster->GetSession()->SendPacket(&data); - target->GetSession()->SendPacket(&data); + caster->SendDirectMessage(&data); + target->SendDirectMessage(&data); // create duel-info DuelInfo* duel = new DuelInfo; @@ -4334,7 +4338,7 @@ void Spell::EffectFeedPet(SpellEffIndex effIndex) player->DestroyItemCount(foodItem, count, true); /// @todo fix crash when a spell has two effects, both pointed at the same item target - m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, NULL, NULL, true); + m_caster->CastCustomSpell(pet, m_spellInfo->Effects[effIndex].TriggerSpell, &benefit, nullptr, nullptr, true); } void Spell::EffectDismissPet(SpellEffIndex effIndex) @@ -4382,7 +4386,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->GetClosePoint(x, y, z, DEFAULT_PLAYER_BOUNDING_RADIUS); Map* map = m_caster->GetMap(); - G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), go_id, map, m_caster->GetPhaseMask(), Position(x, y, z, m_caster->GetOrientation()), rot, 255, GO_STATE_READY)) { delete go; @@ -4633,14 +4637,14 @@ void Spell::EffectCharge(SpellEffIndex /*effIndex*/) float speed = G3D::fuzzyGt(m_spellInfo->Speed, 0.0f) ? m_spellInfo->Speed : SPEED_CHARGE; // Spell is not using explicit target - no generated path - if (m_preGeneratedPath.GetPathType() == PATHFIND_BLANK) + if (m_preGeneratedPath->GetPathType() == PATHFIND_BLANK) { //unitTarget->GetContactPoint(m_caster, pos.m_positionX, pos.m_positionY, pos.m_positionZ); Position pos = unitTarget->GetFirstCollisionPosition(unitTarget->GetCombatReach(), unitTarget->GetRelativeAngle(m_caster)); m_caster->GetMotionMaster()->MoveCharge(pos.m_positionX, pos.m_positionY, pos.m_positionZ, speed); } else - m_caster->GetMotionMaster()->MoveCharge(m_preGeneratedPath, speed); + m_caster->GetMotionMaster()->MoveCharge(*m_preGeneratedPath, speed); } if (effectHandleMode == SPELL_EFFECT_HANDLE_HIT_TARGET) @@ -4924,7 +4928,7 @@ void Spell::EffectDestroyAllTotems(SpellEffIndex /*effIndex*/) } ApplyPct(mana, damage); if (mana) - m_caster->CastCustomSpell(m_caster, 39104, &mana, NULL, NULL, true); + m_caster->CastCustomSpell(m_caster, 39104, &mana, nullptr, nullptr, true); } void Spell::EffectDurabilityDamage(SpellEffIndex effIndex) @@ -5039,7 +5043,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) GameObject* pGameObj = new GameObject; Position pos = { fx, fy, fz, m_caster->GetOrientation() }; - G3D::Quat rot = G3D::Matrix3::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); + QuaternionData rot = QuaternionData::fromEulerAnglesZYX(m_caster->GetOrientation(), 0.f, 0.f); if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), pos, rot, 255, GO_STATE_READY)) { delete pGameObj; @@ -5569,7 +5573,7 @@ void Spell::SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* int32 duration = m_spellInfo->GetDuration(); if (Player* modOwner = m_originalCaster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_DURATION>(m_spellInfo->Id, duration); + modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_DURATION, duration); //TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; Map* map = caster->GetMap(); @@ -5643,7 +5647,7 @@ void Spell::EffectPlayMusic(SpellEffIndex effIndex) WorldPacket data(SMSG_PLAY_MUSIC, 4); data << uint32(soundid); - unitTarget->ToPlayer()->GetSession()->SendPacket(&data); + unitTarget->ToPlayer()->SendDirectMessage(&data); } void Spell::EffectSpecCount(SpellEffIndex /*effIndex*/) @@ -5773,7 +5777,7 @@ void Spell::EffectRechargeManaGem(SpellEffIndex /*effIndex*/) ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(item_id); if (!pProto) { - player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, NULL, NULL); + player->SendEquipError(EQUIP_ERR_ITEM_NOT_FOUND, nullptr, nullptr); return; } @@ -5809,10 +5813,8 @@ void Spell::EffectBind(SpellEffIndex effIndex) player->SetHomebind(homeLoc, areaId); // binding - WorldPacket data(SMSG_BINDPOINTUPDATE, 4 + 4 + 4 + 4 + 4); - data << float(homeLoc.GetPositionX()); - data << float(homeLoc.GetPositionY()); - data << float(homeLoc.GetPositionZ()); + WorldPacket data(SMSG_BINDPOINTUPDATE, 4 * 3 + 4 + 4); + data << TaggedPosition<Position::XYZ>(homeLoc); data << uint32(homeLoc.GetMapId()); data << uint32(areaId); player->SendDirectMessage(&data); diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 599314e2ec4..5401687e3d5 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -15,13 +15,17 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "WorldPacket.h" #include "SpellHistory.h" +#include "DatabaseEnv.h" +#include "Item.h" +#include "ObjectMgr.h" +#include "Opcodes.h" #include "Pet.h" #include "Player.h" -#include "SpellInfo.h" #include "Spell.h" -#include "Opcodes.h" +#include "SpellInfo.h" +#include "SpellMgr.h" +#include "WorldPacket.h" SpellHistory::Clock::duration const SpellHistory::InfinityCooldownDelay = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH)); SpellHistory::Clock::duration const SpellHistory::InfinityCooldownDelayCheck = std::chrono::duration_cast<SpellHistory::Clock::duration>(std::chrono::seconds(MONTH / 2)); @@ -308,10 +312,10 @@ void SpellHistory::StartCooldown(SpellInfo const* spellInfo, uint32 itemId, Spel if (Player* modOwner = _owner->GetSpellModOwner()) { if (cooldown >= 0) - modOwner->ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, cooldown, spell); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, cooldown, spell); if (categoryCooldown >= 0 && !spellInfo->HasAttribute(SPELL_ATTR6_IGNORE_CATEGORY_COOLDOWN_MODS)) - modOwner->ApplySpellMod<SPELLMOD_COOLDOWN>(spellInfo->Id, categoryCooldown, spell); + modOwner->ApplySpellMod(spellInfo->Id, SPELLMOD_COOLDOWN, categoryCooldown, spell); } if (int32 cooldownMod = _owner->GetTotalAuraModifier(SPELL_AURA_MOD_COOLDOWN)) diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index ed1ba883c5b..f45982ced93 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -19,18 +19,28 @@ #define SpellHistory_h__ #include "SharedDefines.h" -#include "QueryResult.h" -#include "Transaction.h" +#include "DatabaseEnvFwd.h" #include "GameTime.h" #include <deque> +#include <vector> +#include <unordered_map> class Item; class Player; class Spell; class SpellInfo; class Unit; +class WorldPacket; struct SpellCategoryEntry; +/// Spell cooldown flags sent in SMSG_SPELL_COOLDOWN +enum SpellCooldownFlags +{ + SPELL_COOLDOWN_FLAG_NONE = 0x0, + SPELL_COOLDOWN_FLAG_INCLUDE_GCD = 0x1, ///< Starts GCD in addition to normal cooldown specified in the packet + SPELL_COOLDOWN_FLAG_INCLUDE_EVENT_COOLDOWNS = 0x2 ///< Starts GCD for spells that should start their cooldown on events, requires SPELL_COOLDOWN_FLAG_INCLUDE_GCD set +}; + class TC_GAME_API SpellHistory { public: diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 8f4f534e076..2a0b972e631 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -15,17 +15,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "SpellAuraDefines.h" -#include "SpellAuras.h" #include "SpellInfo.h" -#include "SpellMgr.h" -#include "Spell.h" +#include "Battleground.h" +#include "Corpse.h" +#include "Creature.h" #include "DBCStores.h" -#include "ConditionMgr.h" +#include "Item.h" +#include "ItemTemplate.h" +#include "Log.h" +#include "ObjectAccessor.h" #include "Player.h" -#include "Battleground.h" +#include "Random.h" +#include "Spell.h" +#include "SpellAuraEffects.h" +#include "SpellMgr.h" #include "Vehicle.h" -#include "Pet.h" uint32 GetTargetFlagMask(SpellTargetObjectTypes objType) { @@ -341,12 +345,12 @@ SpellEffectInfo::SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* Mechanic = Mechanics(spellEntry->EffectMechanic[effIndex]); TargetA = SpellImplicitTargetInfo(spellEntry->EffectImplicitTargetA[effIndex]); TargetB = SpellImplicitTargetInfo(spellEntry->EffectImplicitTargetB[effIndex]); - RadiusEntry = spellEntry->EffectRadiusIndex[effIndex] ? sSpellRadiusStore.LookupEntry(spellEntry->EffectRadiusIndex[effIndex]) : NULL; + RadiusEntry = spellEntry->EffectRadiusIndex[effIndex] ? sSpellRadiusStore.LookupEntry(spellEntry->EffectRadiusIndex[effIndex]) : nullptr; ChainTarget = spellEntry->EffectChainTarget[effIndex]; ItemType = spellEntry->EffectItemType[effIndex]; TriggerSpell = spellEntry->EffectTriggerSpell[effIndex]; SpellClassMask = spellEntry->EffectSpellClassMask[effIndex]; - ImplicitTargetConditions = NULL; + ImplicitTargetConditions = nullptr; } bool SpellEffectInfo::IsEffect() const @@ -519,22 +523,24 @@ int32 SpellEffectInfo::CalcBaseValue(int32 value) const float SpellEffectInfo::CalcValueMultiplier(Unit* caster, Spell* spell) const { float multiplier = ValueMultiplier; - if (Player* modOwner = (caster ? caster->GetSpellModOwner() : NULL)) - modOwner->ApplySpellMod<SPELLMOD_VALUE_MULTIPLIER>(_spellInfo->Id, multiplier, spell); + if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr)) + modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_VALUE_MULTIPLIER, multiplier, spell); + return multiplier; } float SpellEffectInfo::CalcDamageMultiplier(Unit* caster, Spell* spell) const { float multiplierPercent = DamageMultiplier * 100.0f; - if (Player* modOwner = (caster ? caster->GetSpellModOwner() : NULL)) - modOwner->ApplySpellMod<SPELLMOD_DAMAGE_MULTIPLIER>(_spellInfo->Id, multiplierPercent, spell); + if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr)) + modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_DAMAGE_MULTIPLIER, multiplierPercent, spell); + return multiplierPercent / 100.0f; } bool SpellEffectInfo::HasRadius() const { - return RadiusEntry != NULL; + return RadiusEntry != nullptr; } float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const @@ -548,7 +554,7 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const radius += RadiusEntry->RadiusPerLevel * caster->getLevel(); radius = std::min(radius, RadiusEntry->RadiusMax); if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RADIUS>(_spellInfo->Id, radius, spell); + modOwner->ApplySpellMod(_spellInfo->Id, SPELLMOD_RADIUS, radius, spell); } return radius; @@ -766,7 +772,7 @@ SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = SpellInfo::SpellInfo(SpellEntry const* spellEntry) { Id = spellEntry->Id; - CategoryEntry = spellEntry->Category ? sSpellCategoryStore.LookupEntry(spellEntry->Category) : NULL; + CategoryEntry = spellEntry->Category ? sSpellCategoryStore.LookupEntry(spellEntry->Category) : nullptr; Dispel = spellEntry->Dispel; Mechanic = spellEntry->Mechanic; Attributes = spellEntry->Attributes; @@ -792,7 +798,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) TargetAuraSpell = spellEntry->targetAuraSpell; ExcludeCasterAuraSpell = spellEntry->excludeCasterAuraSpell; ExcludeTargetAuraSpell = spellEntry->excludeTargetAuraSpell; - CastTimeEntry = spellEntry->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(spellEntry->CastingTimeIndex) : NULL; + CastTimeEntry = spellEntry->CastingTimeIndex ? sSpellCastTimesStore.LookupEntry(spellEntry->CastingTimeIndex) : nullptr; RecoveryTime = spellEntry->RecoveryTime; CategoryRecoveryTime = spellEntry->CategoryRecoveryTime; StartRecoveryCategory = spellEntry->StartRecoveryCategory; @@ -806,7 +812,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) MaxLevel = spellEntry->maxLevel; BaseLevel = spellEntry->baseLevel; SpellLevel = spellEntry->spellLevel; - DurationEntry = spellEntry->DurationIndex ? sSpellDurationStore.LookupEntry(spellEntry->DurationIndex) : NULL; + DurationEntry = spellEntry->DurationIndex ? sSpellDurationStore.LookupEntry(spellEntry->DurationIndex) : nullptr; PowerType = spellEntry->powerType; ManaCost = spellEntry->manaCost; ManaCostPerlevel = spellEntry->manaCostPerlevel; @@ -814,7 +820,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) ManaPerSecondPerLevel = spellEntry->manaPerSecondPerLevel; ManaCostPercentage = spellEntry->ManaCostPercentage; RuneCostID = spellEntry->runeCostID; - RangeEntry = spellEntry->rangeIndex ? sSpellRangeStore.LookupEntry(spellEntry->rangeIndex) : NULL; + RangeEntry = spellEntry->rangeIndex ? sSpellRangeStore.LookupEntry(spellEntry->rangeIndex) : nullptr; Speed = spellEntry->speed; StackAmount = spellEntry->StackAmount; for (uint8 i = 0; i < 2; ++i) @@ -854,7 +860,7 @@ SpellInfo::SpellInfo(SpellEntry const* spellEntry) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) Effects[i] = SpellEffectInfo(spellEntry, this, i); - ChainEntry = NULL; + ChainEntry = nullptr; ExplicitTargetMask = 0; _spellSpecific = SPELL_SPECIFIC_NORMAL; @@ -1458,7 +1464,7 @@ SpellCastResult SpellInfo::CheckShapeshift(uint32 form) const return SPELL_CAST_OK; bool actAsShifted = false; - SpellShapeshiftEntry const* shapeInfo = NULL; + SpellShapeshiftEntry const* shapeInfo = nullptr; if (form > 0) { shapeInfo = sSpellShapeshiftStore.LookupEntry(form); @@ -3064,7 +3070,8 @@ float SpellInfo::GetMaxRange(bool positive, Unit* caster, Spell* spell) const range = RangeEntry->maxRangeHostile; if (caster) if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_RANGE>(Id, range, spell); + modOwner->ApplySpellMod(Id, SPELLMOD_RANGE, range, spell); + return range; } @@ -3082,7 +3089,7 @@ int32 SpellInfo::GetMaxDuration() const return (DurationEntry->Duration[2] == -1) ? -1 : abs(DurationEntry->Duration[2]); } -uint32 SpellInfo::CalcCastTime(Spell* spell /*= NULL*/) const +uint32 SpellInfo::CalcCastTime(Spell* spell /*= nullptr*/) const { // not all spells have cast time index and this is all is pasiive abilities if (!CastTimeEntry) @@ -3204,7 +3211,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, S // Apply cost mod by spell if (Player* modOwner = caster->GetSpellModOwner()) - modOwner->ApplySpellMod<SPELLMOD_COST>(Id, powerCost, spell); + modOwner->ApplySpellMod(Id, SPELLMOD_COST, powerCost, spell); if (!caster->IsControlledByPlayer()) { @@ -3226,7 +3233,7 @@ int32 SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, S bool SpellInfo::IsRanked() const { - return ChainEntry != NULL; + return ChainEntry != nullptr; } uint8 SpellInfo::GetRank() const @@ -3245,19 +3252,19 @@ SpellInfo const* SpellInfo::GetFirstRankSpell() const SpellInfo const* SpellInfo::GetLastRankSpell() const { if (!ChainEntry) - return NULL; + return nullptr; return ChainEntry->last; } SpellInfo const* SpellInfo::GetNextRankSpell() const { if (!ChainEntry) - return NULL; + return nullptr; return ChainEntry->next; } SpellInfo const* SpellInfo::GetPrevRankSpell() const { if (!ChainEntry) - return NULL; + return nullptr; return ChainEntry->prev; } @@ -3288,7 +3295,7 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const if (!needRankSelection) return this; - for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != NULL; nextSpellInfo = nextSpellInfo->GetPrevRankSpell()) + for (SpellInfo const* nextSpellInfo = this; nextSpellInfo != nullptr; nextSpellInfo = nextSpellInfo->GetPrevRankSpell()) { // if found appropriate level if (uint32(level + 10) >= nextSpellInfo->SpellLevel) @@ -3298,7 +3305,7 @@ SpellInfo const* SpellInfo::GetAuraRankForLevel(uint8 level) const } // not found - return NULL; + return nullptr; } bool SpellInfo::IsRankOf(SpellInfo const* spellInfo) const @@ -3670,7 +3677,7 @@ void SpellInfo::_UnloadImplicitTargetConditionLists() for (uint8 j = i; j < MAX_SPELL_EFFECTS; ++j) { if (Effects[j].ImplicitTargetConditions == cur) - Effects[j].ImplicitTargetConditions = NULL; + Effects[j].ImplicitTargetConditions = nullptr; } delete cur; } diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 483605a1212..8f2f97722df 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -42,7 +42,7 @@ struct SpellEntry; struct SpellCastTimesEntry; struct Condition; -enum SpellCastTargetFlags +enum SpellCastTargetFlags : uint32 { TARGET_FLAG_NONE = 0x00000000, TARGET_FLAG_UNUSED_1 = 0x00000001, // not used @@ -95,7 +95,7 @@ enum SpellTargetReferenceTypes TARGET_REFERENCE_TYPE_DEST }; -enum SpellTargetObjectTypes +enum SpellTargetObjectTypes : uint8 { TARGET_OBJECT_TYPE_NONE = 0, TARGET_OBJECT_TYPE_SRC, @@ -111,7 +111,7 @@ enum SpellTargetObjectTypes TARGET_OBJECT_TYPE_CORPSE_ALLY }; -enum SpellTargetCheckTypes +enum SpellTargetCheckTypes : uint8 { TARGET_CHECK_DEFAULT, TARGET_CHECK_ENTRY, @@ -259,10 +259,10 @@ public: flag96 SpellClassMask; std::vector<Condition*>* ImplicitTargetConditions; - SpellEffectInfo() : _spellInfo(NULL), _effIndex(0), Effect(0), ApplyAuraName(0), Amplitude(0), DieSides(0), + SpellEffectInfo() : _spellInfo(nullptr), _effIndex(0), Effect(0), ApplyAuraName(0), Amplitude(0), DieSides(0), RealPointsPerLevel(0), BasePoints(0), PointsPerComboPoint(0), ValueMultiplier(0), DamageMultiplier(0), - BonusMultiplier(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(NULL), ChainTarget(0), - ItemType(0), TriggerSpell(0), ImplicitTargetConditions(NULL) {} + BonusMultiplier(0), MiscValue(0), MiscValueB(0), Mechanic(MECHANIC_NONE), RadiusEntry(nullptr), ChainTarget(0), + ItemType(0), TriggerSpell(0), ImplicitTargetConditions(nullptr) {} SpellEffectInfo(SpellEntry const* spellEntry, SpellInfo const* spellInfo, uint8 effIndex); bool IsEffect() const; @@ -275,13 +275,13 @@ public: bool IsFarDestTargetEffect() const; bool IsUnitOwnedAuraEffect() const; - int32 CalcValue(Unit const* caster = NULL, int32 const* basePoints = NULL, Unit const* target = NULL) const; + int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr) const; int32 CalcBaseValue(int32 value) const; - float CalcValueMultiplier(Unit* caster, Spell* spell = NULL) const; - float CalcDamageMultiplier(Unit* caster, Spell* spell = NULL) const; + float CalcValueMultiplier(Unit* caster, Spell* spell = nullptr) const; + float CalcDamageMultiplier(Unit* caster, Spell* spell = nullptr) const; bool HasRadius() const; - float CalcRadius(Unit* caster = NULL, Spell* = NULL) const; + float CalcRadius(Unit* caster = nullptr, Spell* = nullptr) const; uint32 GetProvidedTargetMask() const; uint32 GetMissingTargetMask(bool srcSet = false, bool destSet = false, uint32 mask = 0) const; @@ -476,7 +476,7 @@ class TC_GAME_API SpellInfo SpellCastResult CheckShapeshift(uint32 form) const; SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = nullptr, bool strict = true) const; SpellCastResult CheckTarget(Unit const* caster, WorldObject const* target, bool implicit = true) const; - SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = NULL) const; + SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = nullptr) const; SpellCastResult CheckVehicle(Unit const* caster) const; bool CheckTargetCreatureType(Unit const* target) const; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index a14eddcc383..e0800b2782d 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -17,17 +17,21 @@ */ #include "SpellMgr.h" -#include "SpellInfo.h" -#include "Spell.h" -#include "ObjectMgr.h" -#include "SpellAuraDefines.h" -#include "SharedDefines.h" -#include "DBCStores.h" -#include "Chat.h" -#include "BattlegroundMgr.h" -#include "BattlefieldWG.h" #include "BattlefieldMgr.h" +#include "BattlefieldWG.h" +#include "BattlegroundMgr.h" +#include "Chat.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" +#include "Log.h" +#include "Map.h" +#include "MotionMaster.h" +#include "ObjectMgr.h" #include "Player.h" +#include "SharedDefines.h" +#include "Spell.h" +#include "SpellAuraDefines.h" +#include "SpellInfo.h" bool IsPrimaryProfessionSkill(uint32 skill) { @@ -215,7 +219,7 @@ uint32 SpellMgr::GetSpellIdForDifficulty(uint32 spellId, Unit const* caster) con SpellInfo const* SpellMgr::GetSpellForDifficultyFromSpell(SpellInfo const* spell, Unit const* caster) const { if (!spell) - return NULL; + return nullptr; uint32 newSpellId = GetSpellIdForDifficulty(spell->Id, caster); SpellInfo const* newSpell = GetSpellInfo(newSpellId); @@ -233,7 +237,7 @@ SpellChainNode const* SpellMgr::GetSpellChainNode(uint32 spell_id) const { SpellChainMap::const_iterator itr = mSpellChains.find(spell_id); if (itr == mSpellChains.end()) - return NULL; + return nullptr; return &itr->second; } @@ -319,7 +323,7 @@ SpellLearnSkillNode const* SpellMgr::GetSpellLearnSkill(uint32 spell_id) const if (itr != mSpellLearnSkills.end()) return &itr->second; else - return NULL; + return nullptr; } SpellLearnSpellMapBounds SpellMgr::GetSpellLearnSpellMapBounds(uint32 spell_id) const @@ -346,7 +350,7 @@ SpellTargetPosition const* SpellMgr::GetSpellTargetPosition(uint32 spell_id, Spe SpellTargetPositionMap::const_iterator itr = mSpellTargetPositions.find(std::make_pair(spell_id, effIndex)); if (itr != mSpellTargetPositions.end()) return &itr->second; - return NULL; + return nullptr; } SpellSpellGroupMapBounds SpellMgr::GetSpellSpellGroupMapBounds(uint32 spell_id) const @@ -493,7 +497,7 @@ SpellProcEntry const* SpellMgr::GetSpellProcEntry(uint32 spellId) const SpellProcMap::const_iterator itr = mSpellProcMap.find(spellId); if (itr != mSpellProcMap.end()) return &itr->second; - return NULL; + return nullptr; } bool SpellMgr::CanSpellTriggerProcOnEvent(SpellProcEntry const& procEntry, ProcEventInfo& eventInfo) @@ -591,7 +595,7 @@ SpellBonusEntry const* SpellMgr::GetSpellBonusData(uint32 spellId) const if (itr2 != mSpellBonusMap.end()) return &itr2->second; } - return NULL; + return nullptr; } SpellThreatEntry const* SpellMgr::GetSpellThreatEntry(uint32 spellID) const @@ -606,7 +610,7 @@ SpellThreatEntry const* SpellMgr::GetSpellThreatEntry(uint32 spellID) const if (itr != mSpellThreatMap.end()) return &itr->second; } - return NULL; + return nullptr; } SkillLineAbilityMapBounds SpellMgr::GetSkillLineAbilityMapBounds(uint32 spell_id) const @@ -620,7 +624,7 @@ PetAura const* SpellMgr::GetPetAura(uint32 spell_id, uint8 eff) const if (itr != mSpellPetAuraMap.end()) return &itr->second; else - return NULL; + return nullptr; } SpellEnchantProcEntry const* SpellMgr::GetSpellEnchantProcEvent(uint32 enchId) const @@ -628,7 +632,7 @@ SpellEnchantProcEntry const* SpellMgr::GetSpellEnchantProcEvent(uint32 enchId) c SpellEnchantProcEventMap::const_iterator itr = mSpellEnchantProcEventMap.find(enchId); if (itr != mSpellEnchantProcEventMap.end()) return &itr->second; - return NULL; + return nullptr; } bool SpellMgr::IsArenaAllowedEnchancment(uint32 ench_id) const @@ -639,7 +643,7 @@ bool SpellMgr::IsArenaAllowedEnchancment(uint32 ench_id) const const std::vector<int32>* SpellMgr::GetSpellLinked(int32 spell_id) const { SpellLinkedMap::const_iterator itr = mSpellLinkedMap.find(spell_id); - return itr != mSpellLinkedMap.end() ? &(itr->second) : NULL; + return itr != mSpellLinkedMap.end() ? &(itr->second) : nullptr; } PetLevelupSpellSet const* SpellMgr::GetPetLevelupSpellList(uint32 petFamily) const @@ -648,7 +652,7 @@ PetLevelupSpellSet const* SpellMgr::GetPetLevelupSpellList(uint32 petFamily) con if (itr != mPetLevelupSpellMap.end()) return &itr->second; else - return NULL; + return nullptr; } PetDefaultSpellsEntry const* SpellMgr::GetPetDefaultSpellsEntry(int32 id) const @@ -656,7 +660,7 @@ PetDefaultSpellsEntry const* SpellMgr::GetPetDefaultSpellsEntry(int32 id) const PetDefaultSpellsMap::const_iterator itr = mPetDefaultSpellsMap.find(id); if (itr != mPetDefaultSpellsMap.end()) return &itr->second; - return NULL; + return nullptr; } SpellAreaMapBounds SpellMgr::GetSpellAreaMapBounds(uint32 spell_id) const @@ -794,7 +798,7 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 void SpellMgr::UnloadSpellInfoChains() { for (SpellChainMap::iterator itr = mSpellChains.begin(); itr != mSpellChains.end(); ++itr) - mSpellInfoMap[itr->first]->ChainEntry = NULL; + mSpellInfoMap[itr->first]->ChainEntry = nullptr; mSpellChains.clear(); } @@ -810,7 +814,7 @@ void SpellMgr::LoadSpellTalentRanks() if (!talentInfo) continue; - SpellInfo const* lastSpell = NULL; + SpellInfo const* lastSpell = nullptr; for (uint8 rank = MAX_TALENT_RANK - 1; rank > 0; --rank) { if (talentInfo->RankID[rank]) @@ -830,7 +834,7 @@ void SpellMgr::LoadSpellTalentRanks() continue; } - SpellInfo const* prevSpell = NULL; + SpellInfo const* prevSpell = nullptr; for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank) { uint32 spellId = talentInfo->RankID[rank]; @@ -850,7 +854,7 @@ void SpellMgr::LoadSpellTalentRanks() node.rank = rank + 1; node.prev = prevSpell; - node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : NULL; + node.next = node.rank < MAX_TALENT_RANK ? GetSpellInfo(talentInfo->RankID[node.rank]) : nullptr; mSpellChains[spellId] = node; mSpellInfoMap[spellId]->ChainEntry = &mSpellChains[spellId]; @@ -963,7 +967,7 @@ void SpellMgr::LoadSpellRanks() if (itr == rankChain.end()) { - mSpellChains[addedSpell].next = NULL; + mSpellChains[addedSpell].next = nullptr; break; } else @@ -2224,7 +2228,7 @@ bool LoadPetDefaultSpells_helper(CreatureTemplate const* cInfo, PetDefaultSpells return false; // remove duplicates with levelupSpells if any - if (PetLevelupSpellSet const* levelupSpells = cInfo->family ? sSpellMgr->GetPetLevelupSpellList(cInfo->family) : NULL) + if (PetLevelupSpellSet const* levelupSpells = cInfo->family ? sSpellMgr->GetPetLevelupSpellList(cInfo->family) : nullptr) { for (uint8 j = 0; j < MAX_CREATURE_SPELL_DATA_SLOT; ++j) { @@ -2533,11 +2537,10 @@ void SpellMgr::LoadSpellInfoStore() uint32 oldMSTime = getMSTime(); UnloadSpellInfoStore(); - mSpellInfoMap.resize(sSpellStore.GetNumRows(), NULL); + mSpellInfoMap.resize(sSpellStore.GetNumRows(), nullptr); - for (uint32 i = 0; i < sSpellStore.GetNumRows(); ++i) - if (SpellEntry const* spellEntry = sSpellStore.LookupEntry(i)) - mSpellInfoMap[i] = new SpellInfo(spellEntry); + for (SpellEntry const* spellEntry : sSpellStore) + mSpellInfoMap[spellEntry->Id] = new SpellInfo(spellEntry); TC_LOG_INFO("server.loading", ">> Loaded SpellInfo store in %u ms", GetMSTimeDiffToNow(oldMSTime)); } @@ -2561,7 +2564,7 @@ void SpellMgr::LoadSpellInfoCustomAttributes() { uint32 oldMSTime = getMSTime(); uint32 oldMSTime2 = oldMSTime; - SpellInfo* spellInfo = NULL; + SpellInfo* spellInfo = nullptr; QueryResult result = WorldDatabase.Query("SELECT entry, attributes FROM spell_custom_attr"); diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 1696a353ee0..c9fb69a8eb2 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -22,7 +22,7 @@ // For static or at-server-startup loaded spell data #include "Define.h" -#include "DBCStructure.h" +#include "Duration.h" #include "SharedDefines.h" #include "Util.h" @@ -30,6 +30,7 @@ #include <set> #include <vector> #include <unordered_map> +#include <unordered_set> class SpellInfo; class Player; @@ -586,7 +587,7 @@ class TC_GAME_API SpellMgr static SpellMgr* instance(); // Spell correctness for client using - static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = NULL, bool msg = true); + static bool IsSpellValid(SpellInfo const* spellInfo, Player* player = nullptr, bool msg = true); // Spell difficulty uint32 GetSpellDifficultyId(uint32 spellId) const; @@ -662,7 +663,7 @@ class TC_GAME_API SpellMgr SpellAreaForQuestAreaMapBounds GetSpellAreaForQuestAreaMapBounds(uint32 area_id, uint32 quest_id) const; // SpellInfo object management - SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; } + SpellInfo const* GetSpellInfo(uint32 spellId) const { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : nullptr; } // Use this only with 100% valid spellIds SpellInfo const* AssertSpellInfo(uint32 spellId) const { @@ -674,7 +675,7 @@ class TC_GAME_API SpellMgr uint32 GetSpellInfoStoreSize() const { return mSpellInfoMap.size(); } private: - SpellInfo* _GetSpellInfo(uint32 spellId) { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : NULL; } + SpellInfo* _GetSpellInfo(uint32 spellId) { return spellId < GetSpellInfoStoreSize() ? mSpellInfoMap[spellId] : nullptr; } // Modifiers public: diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 32aad8a11ed..3750cae08ef 100644 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -15,12 +15,14 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "SpellScript.h" +#include "Log.h" #include "Spell.h" #include "ScriptMgr.h" #include "SpellAuras.h" #include "SpellMgr.h" -#include "SpellScript.h" #include "SpellMgr.h" +#include <sstream> #include <string> bool _SpellScript::_Validate(SpellInfo const* entry) @@ -33,18 +35,20 @@ bool _SpellScript::_Validate(SpellInfo const* entry) return true; } -bool _SpellScript::ValidateSpellInfo(std::vector<uint32> const& spellIds) +bool _SpellScript::_ValidateSpellInfo(uint32 const* begin, uint32 const* end) { - for (uint32 spellId : spellIds) + bool allValid = true; + while (begin != end) { - if (!sSpellMgr->GetSpellInfo(spellId)) + if (!sSpellMgr->GetSpellInfo(*begin)) { - TC_LOG_ERROR("scripts.spells", "_SpellScript::ValidateSpellInfo: Spell %u does not exist.", spellId); - return false; + TC_LOG_ERROR("scripts.spells", "_SpellScript::ValidateSpellInfo: Spell %u does not exist.", *begin); + allValid = false; } - } - return true; + ++begin; + } + return allValid; } void _SpellScript::_Register() @@ -422,7 +426,7 @@ WorldLocation const* SpellScript::GetExplTargetDest() { if (m_spell->m_targets.HasDst()) return m_spell->m_targets.GetDstPos(); - return NULL; + return nullptr; } void SpellScript::SetExplTargetDest(WorldLocation& loc) @@ -455,7 +459,7 @@ Unit* SpellScript::GetHitUnit() if (!IsInTargetHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitUnit was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } return m_spell->unitTarget; } @@ -465,12 +469,12 @@ Creature* SpellScript::GetHitCreature() if (!IsInTargetHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitCreature was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } if (m_spell->unitTarget) return m_spell->unitTarget->ToCreature(); else - return NULL; + return nullptr; } Player* SpellScript::GetHitPlayer() @@ -478,12 +482,12 @@ Player* SpellScript::GetHitPlayer() if (!IsInTargetHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitPlayer was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } if (m_spell->unitTarget) return m_spell->unitTarget->ToPlayer(); else - return NULL; + return nullptr; } Item* SpellScript::GetHitItem() @@ -491,7 +495,7 @@ Item* SpellScript::GetHitItem() if (!IsInTargetHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitItem was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } return m_spell->itemTarget; } @@ -501,7 +505,7 @@ GameObject* SpellScript::GetHitGObj() if (!IsInTargetHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitGObj was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } return m_spell->gameObjTarget; } @@ -511,7 +515,7 @@ WorldLocation* SpellScript::GetHitDest() if (!IsInEffectHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitDest was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } return m_spell->destTarget; } @@ -561,12 +565,12 @@ Aura* SpellScript::GetHitAura() if (!IsInTargetHook()) { TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u`: function SpellScript::GetHitAura was called, but function has no effect in current hook!", m_scriptName->c_str(), m_scriptSpellId); - return NULL; + return nullptr; } if (!m_spell->m_spellAura) - return NULL; + return nullptr; if (m_spell->m_spellAura->IsRemoved()) - return NULL; + return nullptr; return m_spell->m_spellAura; } @@ -941,7 +945,7 @@ void AuraScript::EffectProcHandler::Call(AuraScript* auraScript, AuraEffect cons bool AuraScript::_Load(Aura* aura) { m_aura = aura; - _PrepareScriptCall((AuraScriptHookType)SPELL_SCRIPT_STATE_LOADING, NULL); + _PrepareScriptCall((AuraScriptHookType)SPELL_SCRIPT_STATE_LOADING, nullptr); bool load = Load(); _FinishScriptCall(); return load; @@ -1189,7 +1193,7 @@ Unit* AuraScript::GetTarget() const TC_LOG_ERROR("scripts", "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId); } - return NULL; + return nullptr; } AuraApplication const* AuraScript::GetTargetApplication() const diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 330727cdc1e..03f06961a4b 100644 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -18,27 +18,34 @@ #ifndef __SPELL_SCRIPT_H #define __SPELL_SCRIPT_H -#include "Util.h" +#include "ObjectGuid.h" #include "SharedDefines.h" #include "SpellAuraDefines.h" -#include "Spell.h" -#include "ScriptReloadMgr.h" +#include "Util.h" +#include <memory> #include <stack> -class Unit; -class SpellInfo; -class SpellScript; -class Spell; class Aura; +class AuraApplication; class AuraEffect; -struct SpellModifier; class Creature; -class GameObject; +class DamageInfo; +class DispelInfo; class DynamicObject; -class Player; +class GameObject; class Item; +class ModuleReference; +class Player; +class ProcEventInfo; +class Spell; +class SpellInfo; +class SpellScript; +class Unit; class WorldLocation; class WorldObject; +struct SpellDestination; +struct SpellModifier; +struct SpellValue; #define SPELL_EFFECT_ANY (uint16)-1 #define SPELL_AURA_ANY (uint16)-1 @@ -61,7 +68,7 @@ class TC_GAME_API _SpellScript virtual bool _Validate(SpellInfo const* entry); public: - _SpellScript() : m_currentScriptState(SPELL_SCRIPT_STATE_NONE), m_scriptName(NULL), m_scriptSpellId(0) {} + _SpellScript() : m_currentScriptState(SPELL_SCRIPT_STATE_NONE), m_scriptName(nullptr), m_scriptSpellId(0) {} virtual ~_SpellScript() { } void _Register(); void _Unload(); @@ -133,7 +140,19 @@ class TC_GAME_API _SpellScript // use for: deallocating memory allocated by script virtual void Unload() { } // Helpers - static bool ValidateSpellInfo(std::vector<uint32> const& spellIds); + static bool ValidateSpellInfo(std::initializer_list<uint32> spellIds) + { + return _ValidateSpellInfo(spellIds.begin(), spellIds.end()); + } + + template <class T> + static bool ValidateSpellInfo(T const& spellIds) + { + return _ValidateSpellInfo(std::begin(spellIds), std::end(spellIds)); + } + + private: + static bool _ValidateSpellInfo(uint32 const* begin, uint32 const* end); }; // SpellScript interface - enum used for runtime checks of script function calls @@ -657,11 +676,11 @@ class TC_GAME_API AuraScript : public _SpellScript #define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) public: - AuraScript() : _SpellScript(), m_aura(NULL), m_auraApplication(NULL), m_defaultActionPrevented(false) + AuraScript() : _SpellScript(), m_aura(nullptr), m_auraApplication(nullptr), m_defaultActionPrevented(false) { } bool _Validate(SpellInfo const* entry) override; bool _Load(Aura* aura); - void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const* aurApp = NULL); + void _PrepareScriptCall(AuraScriptHookType hookType, AuraApplication const* aurApp = nullptr); void _FinishScriptCall(); bool _IsDefaultActionPrevented(); private: diff --git a/src/server/game/Texts/ChatTextBuilder.cpp b/src/server/game/Texts/ChatTextBuilder.cpp new file mode 100644 index 00000000000..8328e7f8bbf --- /dev/null +++ b/src/server/game/Texts/ChatTextBuilder.cpp @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ChatTextBuilder.h" +#include "Chat.h" +#include "ObjectMgr.h" +#include "Unit.h" + +void Trinity::BroadcastTextBuilder::operator()(WorldPacket& data, LocaleConstant locale) const +{ + BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); + ChatHandler::BuildChatPacket(data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); +} + +size_t Trinity::BroadcastTextBuilder::operator()(WorldPacket* data, LocaleConstant locale) const +{ + BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); + return ChatHandler::BuildChatPacket(*data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); +} + +void Trinity::CustomChatTextBuilder::operator()(WorldPacket& data, LocaleConstant locale) const +{ + ChatHandler::BuildChatPacket(data, _msgType, _language, _source, _target, _text, 0, "", locale); +} diff --git a/src/server/game/Texts/ChatTextBuilder.h b/src/server/game/Texts/ChatTextBuilder.h index c913e177894..1fe51dc7258 100644 --- a/src/server/game/Texts/ChatTextBuilder.h +++ b/src/server/game/Texts/ChatTextBuilder.h @@ -18,8 +18,13 @@ #ifndef __CHATTEXT_BUILDER_H #define __CHATTEXT_BUILDER_H -#include "Chat.h" -#include "ObjectMgr.h" +#include "Common.h" +#include "SharedDefines.h" +#include <string> + +class Unit; +class WorldObject; +class WorldPacket; namespace Trinity { @@ -29,17 +34,8 @@ namespace Trinity BroadcastTextBuilder(Unit const* obj, ChatMsg msgType, uint32 textId, WorldObject const* target = nullptr, uint32 achievementId = 0) : _source(obj), _msgType(msgType), _textId(textId), _target(target), _achievementId(achievementId) { } - void operator()(WorldPacket& data, LocaleConstant locale) - { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); - ChatHandler::BuildChatPacket(data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); - } - - size_t operator()(WorldPacket* data, LocaleConstant locale) const - { - BroadcastText const* bct = sObjectMgr->GetBroadcastText(_textId); - return ChatHandler::BuildChatPacket(*data, _msgType, bct ? Language(bct->Language) : LANG_UNIVERSAL, _source, _target, bct ? bct->GetText(locale, _source->getGender()) : "", _achievementId, "", locale); - } + void operator()(WorldPacket& data, LocaleConstant locale) const; + size_t operator()(WorldPacket* data, LocaleConstant locale) const; private: Unit const* _source; @@ -55,10 +51,7 @@ namespace Trinity CustomChatTextBuilder(WorldObject const* obj, ChatMsg msgType, std::string const& text, Language language = LANG_UNIVERSAL, WorldObject const* target = nullptr) : _source(obj), _msgType(msgType), _text(text), _language(language), _target(target) { } - void operator()(WorldPacket& data, LocaleConstant locale) - { - ChatHandler::BuildChatPacket(data, _msgType, _language, _source, _target, _text, 0, "", locale); - } + void operator()(WorldPacket& data, LocaleConstant locale) const; private: WorldObject const* _source; diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index 77a886af3e5..9d2c7d6769f 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -15,15 +15,17 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" -#include "DatabaseEnv.h" -#include "ObjectMgr.h" -#include "Cell.h" +#include "CreatureTextMgr.h" +#include "CreatureTextMgrImpl.h" #include "CellImpl.h" #include "Chat.h" -#include "GridNotifiers.h" +#include "Common.h" +#include "DatabaseEnv.h" +#include "DBCStores.h" #include "GridNotifiersImpl.h" -#include "CreatureTextMgr.h" +#include "Log.h" +#include "ObjectMgr.h" +#include "World.h" class CreatureTextBuilder { @@ -224,7 +226,7 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject } CreatureTextGroup const& textGroupContainer = itr->second; //has all texts in the group - CreatureTextRepeatIds repeatGroup = GetRepeatGroup(source, textGroup);//has all textIDs from the group that were already said + CreatureTextRepeatIds repeatGroup = source->GetTextRepeatGroup(textGroup);//has all textIDs from the group that were already said CreatureTextGroup tempGroup;//will use this to talk after sorting repeatGroup for (CreatureTextGroup::const_iterator giter = textGroupContainer.begin(); giter != textGroupContainer.end(); ++giter) @@ -270,7 +272,7 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject SendChatPacket(finalSource, builder, finalType, whisperTarget, range, team, gmOnly); } - SetRepeatId(source, textGroup, iter->id); + source->SetTextRepeatId(textGroup, iter->id); return iter->duration; } @@ -327,7 +329,7 @@ void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER) return; - whisperTarget->ToPlayer()->GetSession()->SendPacket(data); + whisperTarget->ToPlayer()->SendDirectMessage(data); return; } break; @@ -344,7 +346,7 @@ void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, Map::PlayerList const& players = source->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) - itr->GetSource()->GetSession()->SendPacket(data); + itr->GetSource()->SendDirectMessage(data); return; } case TEXT_RANGE_ZONE: @@ -353,7 +355,7 @@ void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, Map::PlayerList const& players = source->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) - itr->GetSource()->GetSession()->SendPacket(data); + itr->GetSource()->SendDirectMessage(data); return; } case TEXT_RANGE_MAP: @@ -361,7 +363,7 @@ void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, Map::PlayerList const& players = source->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if ((!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) - itr->GetSource()->GetSession()->SendPacket(data); + itr->GetSource()->SendDirectMessage(data); return; } case TEXT_RANGE_WORLD: @@ -369,8 +371,8 @@ void CreatureTextMgr::SendNonChatPacket(WorldObject* source, WorldPacket* data, SessionMap const& smap = sWorld->GetAllSessions(); for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter) if (Player* player = iter->second->GetPlayer()) - if (player->GetSession() && (!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster())) - player->GetSession()->SendPacket(data); + if ((!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster())) + player->SendDirectMessage(data); return; } case TEXT_RANGE_NORMAL: @@ -390,21 +392,6 @@ void CreatureTextMgr::SendEmote(Unit* source, uint32 emote) source->HandleEmoteCommand(emote); } -void CreatureTextMgr::SetRepeatId(Creature* source, uint8 textGroup, uint8 id) -{ - if (!source) - return; - - source->SetTextRepeatId(textGroup, id); -} - -CreatureTextRepeatIds CreatureTextMgr::GetRepeatGroup(Creature* source, uint8 textGroup) -{ - ASSERT(source);//should never happen - - return source->GetTextRepeatGroup(textGroup); -} - bool CreatureTextMgr::TextExist(uint32 sourceEntry, uint8 textGroup) { if (!sourceEntry) diff --git a/src/server/game/Texts/CreatureTextMgr.h b/src/server/game/Texts/CreatureTextMgr.h index 70825f75307..08040882461 100644 --- a/src/server/game/Texts/CreatureTextMgr.h +++ b/src/server/game/Texts/CreatureTextMgr.h @@ -18,12 +18,17 @@ #ifndef TRINITY_CREATURE_TEXT_MGR_H #define TRINITY_CREATURE_TEXT_MGR_H -#include "Creature.h" -#include "GridNotifiers.h" -#include "ObjectAccessor.h" +#include "Common.h" #include "SharedDefines.h" -#include "Opcodes.h" -#include "Group.h" +#include <map> +#include <unordered_map> +#include <vector> + +class Creature; +class Player; +class Unit; +class WorldObject; +class WorldPacket; enum CreatureTextRange { @@ -52,7 +57,7 @@ struct CreatureTextEntry struct CreatureTextLocale { - StringVector Text; + std::vector<std::string> Text; }; struct CreatureTextId @@ -61,7 +66,7 @@ struct CreatureTextId bool operator<(CreatureTextId const& right) const { - return memcmp(this, &right, sizeof(CreatureTextId)) < 0; + return std::tie(entry, textGroup, textId) < std::tie(right.entry, right.textGroup, right.textId); } uint32 entry; @@ -96,12 +101,10 @@ class TC_GAME_API CreatureTextMgr bool TextExist(uint32 sourceEntry, uint8 textGroup); std::string GetLocalizedChatString(uint32 entry, uint8 gender, uint8 textGroup, uint32 id, LocaleConstant locale) const; - template<class Builder> void SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, WorldObject const* whisperTarget = nullptr, CreatureTextRange range = TEXT_RANGE_NORMAL, Team team = TEAM_OTHER, bool gmOnly = false) const; + template<class Builder> + void SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, WorldObject const* whisperTarget = nullptr, CreatureTextRange range = TEXT_RANGE_NORMAL, Team team = TEAM_OTHER, bool gmOnly = false) const; private: - CreatureTextRepeatIds GetRepeatGroup(Creature* source, uint8 textGroup); - void SetRepeatId(Creature* source, uint8 textGroup, uint8 id); - void SendNonChatPacket(WorldObject* source, WorldPacket* data, ChatMsg msgType, WorldObject const* whisperTarget, CreatureTextRange range, Team team, bool gmOnly) const; float GetRangeForChatType(ChatMsg msgType) const; @@ -111,148 +114,4 @@ class TC_GAME_API CreatureTextMgr #define sCreatureTextMgr CreatureTextMgr::instance() -template<class Builder> -class CreatureTextLocalizer -{ - public: - CreatureTextLocalizer(Builder const& builder, ChatMsg msgType) : _builder(builder), _msgType(msgType) - { - _packetCache.resize(TOTAL_LOCALES, NULL); - } - - ~CreatureTextLocalizer() - { - for (size_t i = 0; i < _packetCache.size(); ++i) - { - if (_packetCache[i]) - delete _packetCache[i]->first; - delete _packetCache[i]; - } - } - - void operator()(Player* player) - { - LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); - WorldPacket* messageTemplate; - size_t whisperGUIDpos; - - // create if not cached yet - if (!_packetCache[loc_idx]) - { - messageTemplate = new WorldPacket(); - whisperGUIDpos = _builder(messageTemplate, loc_idx); - _packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos); - } - else - { - messageTemplate = _packetCache[loc_idx]->first; - whisperGUIDpos = _packetCache[loc_idx]->second; - } - - WorldPacket data(*messageTemplate); - switch (_msgType) - { - case CHAT_MSG_MONSTER_WHISPER: - case CHAT_MSG_RAID_BOSS_WHISPER: - data.put<uint64>(whisperGUIDpos, player->GetGUID().GetRawValue()); - break; - default: - break; - } - - player->SendDirectMessage(&data); - } - - private: - std::vector<std::pair<WorldPacket*, size_t>* > _packetCache; - Builder const& _builder; - ChatMsg _msgType; -}; - -template<class Builder> -void CreatureTextMgr::SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, WorldObject const* whisperTarget /*= nullptr*/, CreatureTextRange range /*= TEXT_RANGE_NORMAL*/, Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/) const -{ - if (!source) - return; - - CreatureTextLocalizer<Builder> localizer(builder, msgType); - - switch (msgType) - { - case CHAT_MSG_MONSTER_PARTY: - { - if (!whisperTarget) - return; - - if (Player* whisperPlayer = const_cast<Player*>(whisperTarget->ToPlayer())) - { - if (Group* group = whisperPlayer->GetGroup()) - group->BroadcastWorker(localizer); - } - return; - } - case CHAT_MSG_MONSTER_WHISPER: - case CHAT_MSG_RAID_BOSS_WHISPER: - { - if (range == TEXT_RANGE_NORMAL) // ignores team and gmOnly - { - if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER) - return; - - localizer(const_cast<Player*>(whisperTarget->ToPlayer())); - return; - } - break; - } - default: - break; - } - - switch (range) - { - case TEXT_RANGE_AREA: - { - uint32 areaId = source->GetAreaId(); - Map::PlayerList const& players = source->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) - localizer(itr->GetSource()); - return; - } - case TEXT_RANGE_ZONE: - { - uint32 zoneId = source->GetZoneId(); - Map::PlayerList const& players = source->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) - localizer(itr->GetSource()); - return; - } - case TEXT_RANGE_MAP: - { - Map::PlayerList const& players = source->GetMap()->GetPlayers(); - for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) - if ((!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) - localizer(itr->GetSource()); - return; - } - case TEXT_RANGE_WORLD: - { - SessionMap const& smap = sWorld->GetAllSessions(); - for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter) - if (Player* player = iter->second->GetPlayer()) - if ((!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster())) - localizer(player); - return; - } - case TEXT_RANGE_NORMAL: - default: - break; - } - - float dist = GetRangeForChatType(msgType); - Trinity::PlayerDistWorker<CreatureTextLocalizer<Builder>> worker(source, dist, localizer); - Cell::VisitWorldObjects(source, worker, dist); -} - #endif diff --git a/src/server/game/Texts/CreatureTextMgrImpl.h b/src/server/game/Texts/CreatureTextMgrImpl.h new file mode 100644 index 00000000000..219c257a7e4 --- /dev/null +++ b/src/server/game/Texts/CreatureTextMgrImpl.h @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2008-2017 TrinityCore <http://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef CreatureTextMgrImpl_h__ +#define CreatureTextMgrImpl_h__ + +#include "CreatureTextMgr.h" +#include "CellImpl.h" +#include "Group.h" +#include "GridNotifiers.h" +#include "World.h" +#include "WorldSession.h" + +template<class Builder> +class CreatureTextLocalizer +{ +public: + CreatureTextLocalizer(Builder const& builder, ChatMsg msgType) : _builder(builder), _msgType(msgType) + { + _packetCache.resize(TOTAL_LOCALES, nullptr); + } + + ~CreatureTextLocalizer() + { + for (size_t i = 0; i < _packetCache.size(); ++i) + { + if (_packetCache[i]) + delete _packetCache[i]->first; + delete _packetCache[i]; + } + } + + void operator()(Player const* player) const + { + LocaleConstant loc_idx = player->GetSession()->GetSessionDbLocaleIndex(); + WorldPacket* messageTemplate; + size_t whisperGUIDpos; + + // create if not cached yet + if (!_packetCache[loc_idx]) + { + messageTemplate = new WorldPacket(); + whisperGUIDpos = _builder(messageTemplate, loc_idx); + _packetCache[loc_idx] = new std::pair<WorldPacket*, size_t>(messageTemplate, whisperGUIDpos); + } + else + { + messageTemplate = _packetCache[loc_idx]->first; + whisperGUIDpos = _packetCache[loc_idx]->second; + } + + WorldPacket data(*messageTemplate); + switch (_msgType) + { + case CHAT_MSG_MONSTER_WHISPER: + case CHAT_MSG_RAID_BOSS_WHISPER: + data.put<uint64>(whisperGUIDpos, player->GetGUID().GetRawValue()); + break; + default: + break; + } + + player->SendDirectMessage(&data); + } + +private: + mutable std::vector<std::pair<WorldPacket*, size_t>*> _packetCache; + Builder const& _builder; + ChatMsg _msgType; +}; + +template<class Builder> +void CreatureTextMgr::SendChatPacket(WorldObject* source, Builder const& builder, ChatMsg msgType, WorldObject const* whisperTarget /*= nullptr*/, CreatureTextRange range /*= TEXT_RANGE_NORMAL*/, Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/) const +{ + if (!source) + return; + + CreatureTextLocalizer<Builder> localizer(builder, msgType); + + switch (msgType) + { + case CHAT_MSG_MONSTER_PARTY: + { + if (!whisperTarget) + return; + + if (Player const* whisperPlayer = whisperTarget->ToPlayer()) + if (Group const* group = whisperPlayer->GetGroup()) + group->BroadcastWorker(localizer); + return; + } + case CHAT_MSG_MONSTER_WHISPER: + case CHAT_MSG_RAID_BOSS_WHISPER: + { + if (range == TEXT_RANGE_NORMAL) // ignores team and gmOnly + { + if (!whisperTarget || whisperTarget->GetTypeId() != TYPEID_PLAYER) + return; + + localizer(const_cast<Player*>(whisperTarget->ToPlayer())); + return; + } + break; + } + default: + break; + } + + switch (range) + { + case TEXT_RANGE_AREA: + { + uint32 areaId = source->GetAreaId(); + Map::PlayerList const& players = source->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (itr->GetSource()->GetAreaId() == areaId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) + localizer(itr->GetSource()); + return; + } + case TEXT_RANGE_ZONE: + { + uint32 zoneId = source->GetZoneId(); + Map::PlayerList const& players = source->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if (itr->GetSource()->GetZoneId() == zoneId && (!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) + localizer(itr->GetSource()); + return; + } + case TEXT_RANGE_MAP: + { + Map::PlayerList const& players = source->GetMap()->GetPlayers(); + for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) + if ((!team || Team(itr->GetSource()->GetTeam()) == team) && (!gmOnly || itr->GetSource()->IsGameMaster())) + localizer(itr->GetSource()); + return; + } + case TEXT_RANGE_WORLD: + { + SessionMap const& smap = sWorld->GetAllSessions(); + for (SessionMap::const_iterator iter = smap.begin(); iter != smap.end(); ++iter) + if (Player* player = iter->second->GetPlayer()) + if ((!team || Team(player->GetTeam()) == team) && (!gmOnly || player->IsGameMaster())) + localizer(player); + return; + } + case TEXT_RANGE_NORMAL: + default: + break; + } + + float dist = GetRangeForChatType(msgType); + Trinity::PlayerDistWorker<CreatureTextLocalizer<Builder>> worker(source, dist, localizer); + Cell::VisitWorldObjects(source, worker, dist); +} + +#endif // CreatureTextMgrImpl_h__ diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 360e5cec886..1260ff6937b 100644 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -16,20 +16,21 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "TicketMgr.h" #include "CharacterCache.h" +#include "Chat.h" #include "Common.h" -#include "TicketMgr.h" #include "DatabaseEnv.h" -#include "Log.h" #include "Language.h" +#include "Log.h" +#include "ObjectAccessor.h" +#include "Opcodes.h" +#include "Player.h" +#include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Chat.h" -#include "World.h" -#include "Player.h" -#include "Opcodes.h" -inline float GetAge(uint64 t) { return float(time(NULL) - t) / DAY; } +inline float GetAge(uint64 t) { return float(time(nullptr) - t) / DAY; } /////////////////////////////////////////////////////////////////////////////////////////////////// // GM ticket @@ -37,7 +38,7 @@ GmTicket::GmTicket() : _id(0), _type(TICKET_TYPE_OPEN), _posX(0), _posY(0), _pos _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false) { } -GmTicket::GmTicket(Player* player) : _type(TICKET_TYPE_OPEN), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(time(NULL)), _lastModifiedTime(time(NULL)), +GmTicket::GmTicket(Player* player) : _type(TICKET_TYPE_OPEN), _posX(0), _posY(0), _posZ(0), _mapId(0), _createTime(time(nullptr)), _lastModifiedTime(time(nullptr)), _completed(false), _escalatedStatus(TICKET_UNASSIGNED), _viewed(false), _needResponse(false), _needMoreHelp(false) { @@ -46,7 +47,19 @@ GmTicket::GmTicket(Player* player) : _type(TICKET_TYPE_OPEN), _posX(0), _posY(0) _playerGuid = player->GetGUID(); } -GmTicket::~GmTicket() { } +GmTicket::~GmTicket() +{ +} + +Player* GmTicket::GetPlayer() const +{ + return ObjectAccessor::FindPlayer(_playerGuid); +} + +Player* GmTicket::GetAssignedPlayer() const +{ + return ObjectAccessor::FindPlayer(_assignedTo); +} bool GmTicket::LoadFromDB(Field* fields) { @@ -160,7 +173,7 @@ void GmTicket::SendResponse(WorldSession* session) const std::string GmTicket::FormatMessageString(ChatHandler& handler, bool detailed) const { - time_t curTime = time(NULL); + time_t curTime = time(nullptr); std::stringstream ss; ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTGUID, _id); @@ -183,7 +196,7 @@ std::string GmTicket::FormatMessageString(ChatHandler& handler, bool detailed) c return ss.str(); } -std::string GmTicket::FormatMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName, const char* szCompletedName) const +std::string GmTicket::FormatMessageString(ChatHandler& handler, char const* szClosedName, char const* szAssignedToName, char const* szUnassignedName, char const* szDeletedName, char const* szCompletedName) const { std::stringstream ss; ss << handler.PGetParseString(LANG_COMMAND_TICKETLISTGUID, _id); @@ -251,7 +264,7 @@ void GmTicket::SetChatLog(std::list<uint32> time, std::string const& log) /////////////////////////////////////////////////////////////////////////////////////////////////// // Ticket manager TicketMgr::TicketMgr() : _status(true), _lastTicketId(0), _lastSurveyId(0), _openTicketCount(0), - _lastChange(time(NULL)) { } + _lastChange(time(nullptr)) { } TicketMgr::~TicketMgr() { @@ -355,7 +368,7 @@ void TicketMgr::AddTicket(GmTicket* ticket) _ticketList[ticket->GetId()] = ticket; if (!ticket->IsClosed()) ++_openTicketCount; - SQLTransaction trans = SQLTransaction(NULL); + SQLTransaction trans = SQLTransaction(nullptr); ticket->SaveToDB(trans); } @@ -363,7 +376,7 @@ void TicketMgr::CloseTicket(uint32 ticketId, ObjectGuid source) { if (GmTicket* ticket = GetTicket(ticketId)) { - SQLTransaction trans = SQLTransaction(NULL); + SQLTransaction trans = SQLTransaction(nullptr); ticket->SetClosedBy(source); if (source) --_openTicketCount; diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index 5aab1f4ed94..199265b1aec 100644 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -18,11 +18,14 @@ #ifndef _TICKETMGR_H #define _TICKETMGR_H -#include <string> - -#include "ObjectMgr.h" +#include "ObjectGuid.h" +#include "DatabaseEnvFwd.h" +#include <map> class ChatHandler; +class Player; +class WorldPacket; +class WorldSession; // from blizzard lua enum GMTicketSystemStatus @@ -99,10 +102,10 @@ public: bool IsAssignedNotTo(ObjectGuid guid) const { return IsAssigned() && !IsAssignedTo(guid); } uint32 GetId() const { return _id; } - Player* GetPlayer() const { return ObjectAccessor::FindPlayer(_playerGuid); } + Player* GetPlayer() const; std::string const& GetPlayerName() const { return _playerName; } std::string const& GetMessage() const { return _message; } - Player* GetAssignedPlayer() const { return ObjectAccessor::FindPlayer(_assignedTo); } + Player* GetAssignedPlayer() const; ObjectGuid GetAssignedToGUID() const { return _assignedTo; } std::string GetAssignedToName() const; uint64 GetLastModifiedTime() const { return _lastModifiedTime; } @@ -123,7 +126,7 @@ public: void SetMessage(std::string const& message) { _message = message; - _lastModifiedTime = uint64(time(NULL)); + _lastModifiedTime = uint64(time(nullptr)); } void SetComment(std::string const& comment) { _comment = comment; } void SetViewed() { _viewed = true; } @@ -142,7 +145,7 @@ public: void TeleportTo(Player* player) const; std::string FormatMessageString(ChatHandler& handler, bool detailed = false) const; - std::string FormatMessageString(ChatHandler& handler, const char* szClosedName, const char* szAssignedToName, const char* szUnassignedName, const char* szDeletedName, const char* szCompletedName) const; + std::string FormatMessageString(ChatHandler& handler, char const* szClosedName, char const* szAssignedToName, char const* szUnassignedName, char const* szDeletedName, char const* szCompletedName) const; void SetChatLog(std::list<uint32> time, std::string const& log); std::string const& GetChatLog() const { return _chatLog; } @@ -191,7 +194,7 @@ public: if (itr != _ticketList.end()) return itr->second; - return NULL; + return nullptr; } GmTicket* GetTicketByPlayer(ObjectGuid playerGuid) @@ -200,7 +203,7 @@ public: if (itr->second && itr->second->IsFromPlayer(playerGuid) && !itr->second->IsClosed()) return itr->second; - return NULL; + return nullptr; } GmTicket* GetOldestOpenTicket() @@ -209,7 +212,7 @@ public: if (itr->second && !itr->second->IsClosed() && !itr->second->IsCompleted()) return itr->second; - return NULL; + return nullptr; } void AddTicket(GmTicket* ticket); @@ -221,7 +224,7 @@ public: void SetStatus(bool status) { _status = status; } uint64 GetLastChange() const { return _lastChange; } - void UpdateLastChange() { _lastChange = uint64(time(NULL)); } + void UpdateLastChange() { _lastChange = uint64(time(nullptr)); } uint32 GenerateTicketId() { return ++_lastTicketId; } uint32 GetOpenTicketCount() const { return _openTicketCount; } @@ -236,9 +239,7 @@ public: void SendTicket(WorldSession* session, GmTicket* ticket) const; -protected: - void _RemoveTicket(uint32 ticketId, int64 source = -1, bool permanently = false); - +private: GmTicketList _ticketList; bool _status; diff --git a/src/server/game/Time/GameTime.h b/src/server/game/Time/GameTime.h index efe73a6a0b7..565ffc51c18 100644 --- a/src/server/game/Time/GameTime.h +++ b/src/server/game/Time/GameTime.h @@ -19,7 +19,6 @@ #define __GAMETIME_H #include "Define.h" - #include <chrono> namespace GameTime diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.cpp b/src/server/game/Tools/CharacterDatabaseCleaner.cpp index c03851fdbdf..030f1d170d8 100644 --- a/src/server/game/Tools/CharacterDatabaseCleaner.cpp +++ b/src/server/game/Tools/CharacterDatabaseCleaner.cpp @@ -19,10 +19,11 @@ #include "Common.h" #include "AchievementMgr.h" #include "CharacterDatabaseCleaner.h" -#include "World.h" -#include "Database/DatabaseEnv.h" -#include "SpellMgr.h" +#include "DatabaseEnv.h" #include "DBCStores.h" +#include "Log.h" +#include "SpellMgr.h" +#include "World.h" void CharacterDatabaseCleaner::CleanDatabase() { @@ -67,7 +68,7 @@ void CharacterDatabaseCleaner::CleanDatabase() TC_LOG_INFO("server.loading", ">> Cleaned character database in %u ms", GetMSTimeDiffToNow(oldMSTime)); } -void CharacterDatabaseCleaner::CheckUnique(const char* column, const char* table, bool (*check)(uint32)) +void CharacterDatabaseCleaner::CheckUnique(char const* column, char const* table, bool (*check)(uint32)) { QueryResult result = CharacterDatabase.PQuery("SELECT DISTINCT %s FROM %s", column, table); if (!result) diff --git a/src/server/game/Tools/CharacterDatabaseCleaner.h b/src/server/game/Tools/CharacterDatabaseCleaner.h index e6db1e54c8f..c43d5229bac 100644 --- a/src/server/game/Tools/CharacterDatabaseCleaner.h +++ b/src/server/game/Tools/CharacterDatabaseCleaner.h @@ -32,7 +32,7 @@ namespace CharacterDatabaseCleaner TC_GAME_API void CleanDatabase(); - TC_GAME_API void CheckUnique(const char* column, const char* table, bool (*check)(uint32)); + TC_GAME_API void CheckUnique(char const* column, char const* table, bool (*check)(uint32)); TC_GAME_API bool AchievementProgressCheck(uint32 criteria); TC_GAME_API bool SkillCheck(uint32 skill); diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index e4bf6b2a171..0357fcc4e15 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -16,14 +16,15 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "Common.h" #include "PlayerDump.h" +#include "AccountMgr.h" +#include "CharacterCache.h" +#include "Common.h" #include "DatabaseEnv.h" -#include "UpdateFields.h" +#include "Log.h" #include "ObjectMgr.h" #include "Player.h" -#include "AccountMgr.h" -#include "CharacterCache.h" +#include "UpdateFields.h" #include "World.h" // static data @@ -414,7 +415,7 @@ inline std::string GetTableName(std::string const& str) { // length of "INSERT INTO `" static std::string::size_type const s = 13; - std::string::size_type e = str.find(_TABLE_SIM_, s); + std::string::size_type e = str.find('`', s); if (e == std::string::npos) return ""; @@ -437,7 +438,7 @@ inline bool ValidateFields(TableStruct const& ts, std::string const& str, size_t s += 4; std::string::size_type valPos = str.find("VALUES ('"); - std::string::size_type e = str.find(_TABLE_SIM_, s); + std::string::size_type e = str.find('`', s); if (e == std::string::npos || valPos == std::string::npos) { TC_LOG_ERROR("misc", "LoadPlayerDump: (line " UI64FMTD ") unexpected end of line", lineNumber); @@ -456,7 +457,7 @@ inline bool ValidateFields(TableStruct const& ts, std::string const& str, size_t // length of "`, `" s = e + 4; - e = str.find(_TABLE_SIM_, s); + e = str.find('`', s); } while (e < valPos); return true; @@ -518,10 +519,10 @@ inline void AppendTableDump(StringTransaction& trans, TableStruct const& tableSt do { std::ostringstream ss; - ss << "INSERT INTO " << _TABLE_SIM_ << tableStruct.TableName << _TABLE_SIM_ << " ("; + ss << "INSERT INTO `" << tableStruct.TableName << "` ("; for (auto itr = tableStruct.TableFields.begin(); itr != tableStruct.TableFields.end();) { - ss << _TABLE_SIM_ << itr->FieldName << _TABLE_SIM_; + ss << '`' << itr->FieldName << '`'; ++itr; if (itr != tableStruct.TableFields.end()) diff --git a/src/server/game/Warden/Warden.cpp b/src/server/game/Warden/Warden.cpp index fae8198e092..8107a73158f 100644 --- a/src/server/game/Warden/Warden.cpp +++ b/src/server/game/Warden/Warden.cpp @@ -23,14 +23,15 @@ #include "Opcodes.h" #include "ByteBuffer.h" #include "GameTime.h" +#include "World.h" #include "Util.h" #include "Warden.h" #include "AccountMgr.h" #include <openssl/sha.h> -Warden::Warden() : _session(NULL), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), - _dataSent(false), _previousTimestamp(0), _module(NULL), _initialized(false) +Warden::Warden() : _session(nullptr), _inputCrypto(16), _outputCrypto(16), _checkTimer(10000/*10 sec*/), _clientResponseTimer(0), + _dataSent(false), _previousTimestamp(0), _module(nullptr), _initialized(false) { memset(_inputKey, 0, sizeof(_inputKey)); memset(_outputKey, 0, sizeof(_outputKey)); @@ -41,7 +42,7 @@ Warden::~Warden() { delete[] _module->CompressedData; delete _module; - _module = NULL; + _module = nullptr; _initialized = false; } @@ -138,7 +139,7 @@ void Warden::EncryptData(uint8* buffer, uint32 length) _outputCrypto.UpdateData(length, buffer); } -bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length) +bool Warden::IsValidCheckSum(uint32 checksum, uint8 const* data, const uint16 length) { uint32 newChecksum = BuildChecksum(data, length); @@ -169,7 +170,7 @@ struct keyData { }; }; -uint32 Warden::BuildChecksum(const uint8* data, uint32 length) +uint32 Warden::BuildChecksum(uint8 const* data, uint32 length) { keyData hash; SHA1(data, length, hash.bytes.bytes); @@ -180,7 +181,7 @@ uint32 Warden::BuildChecksum(const uint8* data, uint32 length) return checkSum; } -std::string Warden::Penalty(WardenCheck* check /*= NULL*/) +std::string Warden::Penalty(WardenCheck* check /*= nullptr*/) { WardenActions action; diff --git a/src/server/game/Warden/Warden.h b/src/server/game/Warden/Warden.h index 8f851181f0f..42d60442d27 100644 --- a/src/server/game/Warden/Warden.h +++ b/src/server/game/Warden/Warden.h @@ -119,7 +119,7 @@ class TC_GAME_API Warden static uint32 BuildChecksum(const uint8 *data, uint32 length); // If no check is passed, the default action from config is executed - std::string Penalty(WardenCheck* check = NULL); + std::string Penalty(WardenCheck* check = nullptr); private: WorldSession* _session; diff --git a/src/server/game/Warden/WardenCheckMgr.cpp b/src/server/game/Warden/WardenCheckMgr.cpp index bd0746ea207..3b8387e3381 100644 --- a/src/server/game/Warden/WardenCheckMgr.cpp +++ b/src/server/game/Warden/WardenCheckMgr.cpp @@ -23,6 +23,7 @@ #include "Database/DatabaseEnv.h" #include "WardenCheckMgr.h" #include "Warden.h" +#include "World.h" WardenCheckMgr::WardenCheckMgr() { } @@ -200,7 +201,7 @@ WardenCheck* WardenCheckMgr::GetWardenDataById(uint16 Id) if (Id < CheckStore.size()) return CheckStore[Id]; - return NULL; + return nullptr; } WardenCheckResult* WardenCheckMgr::GetWardenResultById(uint16 Id) @@ -208,5 +209,5 @@ WardenCheckResult* WardenCheckMgr::GetWardenResultById(uint16 Id) CheckResultContainer::const_iterator itr = CheckResultStore.find(Id); if (itr != CheckResultStore.end()) return itr->second; - return NULL; + return nullptr; } diff --git a/src/server/game/Warden/WardenWin.cpp b/src/server/game/Warden/WardenWin.cpp index 3336b4c01ba..6d8fd9dea76 100644 --- a/src/server/game/Warden/WardenWin.cpp +++ b/src/server/game/Warden/WardenWin.cpp @@ -26,11 +26,13 @@ #include "ByteBuffer.h" #include "Database/DatabaseEnv.h" #include "GameTime.h" +#include "World.h" #include "Player.h" #include "Util.h" #include "WardenWin.h" #include "WardenModuleWin.h" #include "WardenCheckMgr.h" +#include "Random.h" #include <openssl/md5.h> WardenWin::WardenWin() : Warden(), _serverTicks(0) {} diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp index 91125282496..fb26ae61a12 100644 --- a/src/server/game/Weather/Weather.cpp +++ b/src/server/game/Weather/Weather.cpp @@ -21,12 +21,14 @@ */ #include "Weather.h" -#include "WorldPacket.h" -#include "Player.h" #include "GameTime.h" #include "Log.h" -#include "Util.h" +#include "Player.h" +#include "Random.h" #include "ScriptMgr.h" +#include "Util.h" +#include "World.h" +#include "WorldPacket.h" #include "WorldSession.h" /// Create the Weather object @@ -196,7 +198,7 @@ void Weather::SendWeatherUpdateToPlayer(Player* player) data << uint32(GetWeatherState()); data << (float)m_grade; data << uint8(0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } /// Send the new weather to all players in the zone diff --git a/src/server/game/Weather/Weather.h b/src/server/game/Weather/Weather.h index beb9610cdf9..51702ea2b65 100644 --- a/src/server/game/Weather/Weather.h +++ b/src/server/game/Weather/Weather.h @@ -43,7 +43,7 @@ struct WeatherData uint32 ScriptId; }; -enum WeatherState +enum WeatherState : uint32 { WEATHER_STATE_FINE = 0, WEATHER_STATE_FOG = 1, diff --git a/src/server/game/Weather/WeatherMgr.cpp b/src/server/game/Weather/WeatherMgr.cpp index 6a7e60a2bc0..95728b7e8ae 100644 --- a/src/server/game/Weather/WeatherMgr.cpp +++ b/src/server/game/Weather/WeatherMgr.cpp @@ -21,10 +21,11 @@ */ #include "WeatherMgr.h" -#include "Weather.h" +#include "DatabaseEnv.h" #include "Log.h" #include "ObjectMgr.h" #include "Player.h" +#include "Weather.h" #include "WorldSession.h" namespace WeatherMgr @@ -41,7 +42,7 @@ namespace WeatherData const* GetWeatherData(uint32 zone_id) { WeatherZoneMap::const_iterator itr = mWeatherZoneMap.find(zone_id); - return (itr != mWeatherZoneMap.end()) ? &itr->second : NULL; + return (itr != mWeatherZoneMap.end()) ? &itr->second : nullptr; } } @@ -69,7 +70,7 @@ Weather* AddWeather(uint32 zone_id) // zone does not have weather, ignore if (!weatherChances) - return NULL; + return nullptr; Weather* w = new Weather(zone_id, weatherChances); m_weathers[w->GetZone()].reset(w); @@ -146,7 +147,7 @@ void SendFineWeatherUpdateToPlayer(Player* player) data << (uint32)WEATHER_STATE_FINE; data << (float)0.0f; data << uint8(0); - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); } void Update(uint32 diff) diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 2f09d03893f..6f5f987e9aa 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -21,7 +21,9 @@ */ #include "World.h" +#include "AccountMgr.h" #include "AchievementMgr.h" +#include "AddonMgr.h" #include "ArenaTeamMgr.h" #include "AuctionHouseBot.h" #include "AuctionHouseMgr.h" @@ -40,6 +42,7 @@ #include "DisableMgr.h" #include "GameEventMgr.h" #include "GameObjectModel.h" +#include "GameTime.h" #include "GitRevision.h" #include "GridNotifiersImpl.h" #include "GroupMgr.h" @@ -47,10 +50,15 @@ #include "InstanceSaveMgr.h" #include "Language.h" #include "LFGMgr.h" +#include "Log.h" #include "LootItemStorage.h" +#include "LootMgr.h" +#include "M2Stores.h" #include "MapManager.h" #include "Memory.h" +#include "Metric.h" #include "MMapFactory.h" +#include "ObjectAccessor.h" #include "ObjectMgr.h" #include "OutdoorPvPMgr.h" #include "PetitionMgr.h" @@ -58,25 +66,27 @@ #include "PlayerDump.h" #include "PoolMgr.h" #include "QueryCallback.h" +#include "Realm.h" #include "ScriptMgr.h" #include "ScriptReloadMgr.h" #include "ServerMotd.h" #include "SkillDiscovery.h" #include "SkillExtraItems.h" -#include "SmartAI.h" -#include "Metric.h" +#include "SmartScriptMgr.h" +#include "SpellMgr.h" #include "TicketMgr.h" #include "TransportMgr.h" #include "Unit.h" +#include "UpdateTime.h" #include "VMapFactory.h" +#include "VMapManager2.h" #include "WardenCheckMgr.h" #include "WaypointMovementGenerator.h" #include "WeatherMgr.h" -#include "WorldSession.h" -#include "M2Stores.h" #include "WhoListStorage.h" -#include "GameTime.h" -#include "UpdateTime.h" +#include "WorldSession.h" + +#include <boost/asio/ip/address.hpp> TC_GAME_API std::atomic<bool> World::m_stopEvent(false); TC_GAME_API uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; @@ -137,7 +147,7 @@ World::~World() m_sessions.erase(m_sessions.begin()); } - CliCommandHolder* command = NULL; + CliCommandHolder* command = nullptr; while (cliCmdQueue.next(command)) delete command; @@ -170,7 +180,7 @@ Player* World::FindPlayerInZone(uint32 zone) if (player->IsInWorld() && player->GetZoneId() == zone) return player; } - return NULL; + return nullptr; } bool World::IsClosed() const @@ -192,9 +202,9 @@ WorldSession* World::FindSession(uint32 id) const SessionMap::const_iterator itr = m_sessions.find(id); if (itr != m_sessions.end()) - return itr->second; // also can return NULL for kicked session + return itr->second; // also can return nullptr for kicked session else - return NULL; + return nullptr; } /// Remove a given session @@ -294,7 +304,7 @@ bool World::HasRecentlyDisconnected(WorldSession* session) { for (DisconnectMap::iterator i = m_disconnects.begin(); i != m_disconnects.end();) { - if (difftime(i->second, time(NULL)) < tolerance) + if (difftime(i->second, time(nullptr)) < tolerance) { if (i->first == session->GetAccountId()) return true; @@ -1189,7 +1199,7 @@ void World::LoadConfigSettings(bool reload) #if TRINITY_PLATFORM == TRINITY_PLATFORM_UNIX || TRINITY_PLATFORM == TRINITY_PLATFORM_APPLE if (dataPath[0] == '~') { - const char* home = getenv("HOME"); + char const* home = getenv("HOME"); if (home) dataPath.replace(0, 1, home); } @@ -1361,7 +1371,7 @@ void World::SetInitialWorldSettings() uint32 startupBegin = getMSTime(); ///- Initialize the random number generator - srand((unsigned int)time(NULL)); + srand((unsigned int)time(nullptr)); ///- Initialize detour memory management dtAllocSetCustom(dtCustomAlloc, dtCustomFree); @@ -1512,6 +1522,9 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading Transport templates..."); sTransportMgr->LoadTransportTemplates(); + TC_LOG_INFO("server.loading", "Loading Transport animations and rotations..."); + sTransportMgr->LoadTransportAnimationAndRotation(); + TC_LOG_INFO("server.loading", "Loading Spell Rank Data..."); sSpellMgr->LoadSpellRanks(); @@ -2337,7 +2350,7 @@ namespace Trinity { public: typedef std::vector<WorldPacket*> WorldPacketList; - explicit WorldWorldTextBuilder(uint32 textId, va_list* args = NULL) : i_textId(textId), i_args(args) { } + explicit WorldWorldTextBuilder(uint32 textId, va_list* args = nullptr) : i_textId(textId), i_args(args) { } void operator()(WorldPacketList& data_list, LocaleConstant loc_idx) { char const* text = sObjectMgr->GetTrinityString(i_textId, loc_idx); @@ -2358,14 +2371,14 @@ namespace Trinity do_helper(data_list, (char*)text); } private: - char* lineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = NULL; return start; } + char* lineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = nullptr; return start; } void do_helper(WorldPacketList& data_list, char* text) { char* pos = text; while (char* line = lineFromMessage(pos)) { WorldPacket* data = new WorldPacket(); - ChatHandler::BuildChatPacket(*data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + ChatHandler::BuildChatPacket(*data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); data_list.push_back(data); } } @@ -2421,7 +2434,7 @@ void World::SendGMText(uint32 string_id, ...) } /// DEPRECATED, only for debug purpose. Send a System Message to all players (except self if mentioned) -void World::SendGlobalText(const char* text, WorldSession* self) +void World::SendGlobalText(char const* text, WorldSession* self) { WorldPacket data; @@ -2431,7 +2444,7 @@ void World::SendGlobalText(const char* text, WorldSession* self) while (char* line = ChatHandler::LineFromMessage(pos)) { - ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, line); + ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, line); SendGlobalMessage(&data, self); } @@ -2462,10 +2475,10 @@ bool World::SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self } /// Send a System Message to all players in the zone (except self if mentioned) -void World::SendZoneText(uint32 zone, const char* text, WorldSession* self, uint32 team) +void World::SendZoneText(uint32 zone, char const* text, WorldSession* self, uint32 team) { WorldPacket data; - ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, NULL, NULL, text); + ChatHandler::BuildChatPacket(data, CHAT_MSG_SYSTEM, LANG_UNIVERSAL, nullptr, nullptr, text); SendZoneMessage(zone, &data, self, team); } @@ -2498,8 +2511,8 @@ BanReturn World::BanAccount(BanMode mode, std::string const& nameOrIP, std::stri /// Ban an account or ban an IP address, duration is in seconds if positive, otherwise permban BanReturn World::BanAccount(BanMode mode, std::string const& nameOrIP, uint32 duration_secs, std::string const& reason, std::string const& author) { - PreparedQueryResult resultAccounts = PreparedQueryResult(NULL); //used for kicking - PreparedStatement* stmt = NULL; + PreparedQueryResult resultAccounts = PreparedQueryResult(nullptr); //used for kicking + PreparedStatement* stmt = nullptr; ///- Update the database with ban information switch (mode) @@ -2575,7 +2588,7 @@ BanReturn World::BanAccount(BanMode mode, std::string const& nameOrIP, uint32 du /// Remove a ban from an account or IP address bool World::RemoveBanAccount(BanMode mode, std::string const& nameOrIP) { - PreparedStatement* stmt = NULL; + PreparedStatement* stmt = nullptr; if (mode == BAN_IP) { stmt = LoginDatabase.GetPreparedStatement(LOGIN_DEL_IP_NOT_BANNED); @@ -2780,7 +2793,7 @@ void World::SendServerMessage(ServerMessageType type, const char *text, Player* data << text; if (player) - player->GetSession()->SendPacket(&data); + player->SendDirectMessage(&data); else SendGlobalMessage(&data); } @@ -2788,7 +2801,7 @@ void World::SendServerMessage(ServerMessageType type, const char *text, Player* void World::UpdateSessions(uint32 diff) { ///- Add new sessions - WorldSession* sess = NULL; + WorldSession* sess = nullptr; while (addSessQueue.next(sess)) AddSession_ (sess); @@ -2805,7 +2818,7 @@ void World::UpdateSessions(uint32 diff) if (!pSession->Update(diff, updater)) // As interval = 0 { if (!RemoveQueuedPlayer(itr->second) && itr->second && getIntConfig(CONFIG_INTERVAL_DISCONNECT_TOLERANCE)) - m_disconnects[itr->second->GetAccountId()] = time(NULL); + m_disconnects[itr->second->GetAccountId()] = time(nullptr); RemoveQueuedPlayer(pSession); m_sessions.erase(itr); delete pSession; @@ -2817,9 +2830,9 @@ void World::UpdateSessions(uint32 diff) // This handles the issued and queued CLI commands void World::ProcessCliCommands() { - CliCommandHolder::Print* zprint = NULL; - void* callbackArg = NULL; - CliCommandHolder* command = NULL; + CliCommandHolder::Print zprint = nullptr; + void* callbackArg = nullptr; + CliCommandHolder* command = nullptr; while (cliCmdQueue.next(command)) { TC_LOG_INFO("misc", "CLI command under processing..."); @@ -2925,7 +2938,7 @@ void World::_UpdateRealmCharCount(PreparedQueryResult resultCharCount) void World::InitWeeklyQuestResetTime() { time_t wstime = uint64(sWorld->getWorldState(WS_WEEKLY_QUEST_RESET_TIME)); - time_t curtime = time(NULL); + time_t curtime = time(nullptr); m_NextWeeklyQuestReset = wstime < curtime ? curtime : time_t(wstime); } @@ -2944,7 +2957,7 @@ void World::InitDailyQuestResetTime(bool loading) } // FIX ME: client not show day start time - time_t curTime = time(NULL); + time_t curTime = time(nullptr); tm localTm; localtime_r(&curTime, &localTm); localTm.tm_hour = getIntConfig(CONFIG_DAILY_QUEST_RESET_TIME_HOUR); @@ -2967,7 +2980,7 @@ void World::InitDailyQuestResetTime(bool loading) void World::InitMonthlyQuestResetTime() { time_t wstime = uint64(sWorld->getWorldState(WS_MONTHLY_QUEST_RESET_TIME)); - time_t curtime = time(NULL); + time_t curtime = time(nullptr); m_NextMonthlyQuestReset = wstime < curtime ? curtime : time_t(wstime); } @@ -2975,10 +2988,10 @@ void World::InitRandomBGResetTime() { time_t bgtime = uint64(sWorld->getWorldState(WS_BG_DAILY_RESET_TIME)); if (!bgtime) - m_NextRandomBGReset = time_t(time(NULL)); // game time not yet init + m_NextRandomBGReset = time_t(time(nullptr)); // game time not yet init // generate time by config - time_t curTime = time(NULL); + time_t curTime = time(nullptr); tm localTm; localtime_r(&curTime, &localTm); localTm.tm_hour = getIntConfig(CONFIG_RANDOM_BG_RESET_HOUR); @@ -3003,10 +3016,10 @@ void World::InitGuildResetTime() { time_t gtime = uint64(getWorldState(WS_GUILD_DAILY_RESET_TIME)); if (!gtime) - m_NextGuildReset = time_t(time(NULL)); // game time not yet init + m_NextGuildReset = time_t(time(nullptr)); // game time not yet init // generate time by config - time_t curTime = time(NULL); + time_t curTime = time(nullptr); tm localTm; localtime_r(&curTime, &localTm); localTm.tm_hour = getIntConfig(CONFIG_GUILD_RESET_HOUR); @@ -3091,7 +3104,7 @@ void World::ResetMonthlyQuests() itr->second->GetPlayer()->ResetMonthlyQuestStatus(); // generate time - time_t curTime = time(NULL); + time_t curTime = time(nullptr); tm localTm; localtime_r(&curTime, &localTm); @@ -3220,6 +3233,16 @@ void World::LoadWorldStates() } +bool World::IsPvPRealm() const +{ + return (getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); +} + +bool World::IsFFAPvPRealm() const +{ + return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; +} + // Setting a worldstate will save it to DB void World::setWorldState(uint32 index, uint64 value) { @@ -3274,3 +3297,13 @@ void World::RemoveOldCorpses() } Realm realm; + +CliCommandHolder::CliCommandHolder(void* callbackArg, char const* command, Print zprint, CommandFinished commandFinished) + : m_callbackArg(callbackArg), m_command(strdup(command)), m_print(zprint), m_commandFinished(commandFinished) +{ +} + +CliCommandHolder::~CliCommandHolder() +{ + free(m_command); +} diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index cdf3703a67a..6b9e21dcf69 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -24,24 +24,23 @@ #define __WORLD_H #include "Common.h" +#include "DatabaseEnvFwd.h" +#include "LockedQueue.h" #include "ObjectGuid.h" -#include "Timer.h" -#include "SharedDefines.h" -#include "QueryResult.h" #include "QueryCallbackProcessor.h" -#include "Realm/Realm.h" +#include "SharedDefines.h" +#include "Timer.h" #include <atomic> -#include <map> -#include <set> #include <list> +#include <map> +#include <unordered_map> -class Object; +class Player; class WorldPacket; class WorldSession; -class Player; class WorldSocket; -class SystemMgr; +struct Realm; // ServerMessages.dbc enum ServerMessageType @@ -53,14 +52,14 @@ enum ServerMessageType SERVER_MSG_RESTART_CANCELLED = 5 }; -enum ShutdownMask +enum ShutdownMask : uint32 { SHUTDOWN_MASK_RESTART = 1, SHUTDOWN_MASK_IDLE = 2, SHUTDOWN_MASK_FORCE = 4 }; -enum ShutdownExitCode +enum ShutdownExitCode : uint32 { SHUTDOWN_EXIT_CODE = 0, ERROR_EXIT_CODE = 1, @@ -531,23 +530,18 @@ enum WorldStates }; /// Storage class for commands issued for delayed execution -struct CliCommandHolder +struct TC_GAME_API CliCommandHolder { - typedef void Print(void*, const char*); - typedef void CommandFinished(void*, bool success); + typedef void(*Print)(void*, char const*); + typedef void(*CommandFinished)(void*, bool success); void* m_callbackArg; - char *m_command; - Print* m_print; - - CommandFinished* m_commandFinished; - - CliCommandHolder(void* callbackArg, const char *command, Print* zprint, CommandFinished* commandFinished) - : m_callbackArg(callbackArg), m_command(strdup(command)), m_print(zprint), m_commandFinished(commandFinished) - { - } + char* m_command; + Print m_print; + CommandFinished m_commandFinished; - ~CliCommandHolder() { free(m_command); } + CliCommandHolder(void* callbackArg, char const* command, Print zprint, CommandFinished commandFinished); + ~CliCommandHolder(); private: CliCommandHolder(CliCommandHolder const& right) = delete; @@ -582,7 +576,7 @@ class TC_GAME_API World bool RemoveSession(uint32 id); /// Get the number of current active sessions void UpdateMaxSessionCounters(); - const SessionMap& GetAllSessions() const { return m_sessions; } + SessionMap const& GetAllSessions() const { return m_sessions; } uint32 GetActiveAndQueuedSessionCount() const { return m_sessions.size(); } uint32 GetActiveSessionCount() const { return m_sessions.size() - m_QueuedPlayer.size(); } uint32 GetQueuedSessionCount() const { return m_QueuedPlayer.size(); } @@ -656,9 +650,9 @@ class TC_GAME_API World void LoadConfigSettings(bool reload = false); void SendWorldText(uint32 string_id, ...); - void SendGlobalText(const char* text, WorldSession* self); + void SendGlobalText(char const* text, WorldSession* self); void SendGMText(uint32 string_id, ...); - void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL); + void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = nullptr); void SendGlobalMessage(WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0); void SendGlobalGMMessage(WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0); bool SendZoneMessage(uint32 zone, WorldPacket* packet, WorldSession* self = nullptr, uint32 team = 0); @@ -669,7 +663,7 @@ class TC_GAME_API World uint32 GetShutDownTimeLeft() const { return m_ShutdownTimer; } void ShutdownServ(uint32 time, uint32 options, uint8 exitcode, const std::string& reason = std::string()); uint32 ShutdownCancel(); - void ShutdownMsg(bool show = false, Player* player = NULL, const std::string& reason = std::string()); + void ShutdownMsg(bool show = false, Player* player = nullptr, const std::string& reason = std::string()); static uint8 GetExitCode() { return m_ExitCode; } static void StopNow(uint8 exitcode) { m_stopEvent = true; m_ExitCode = exitcode; } static bool IsStopped() { return m_stopEvent; } @@ -726,8 +720,8 @@ class TC_GAME_API World void LoadWorldStates(); /// Are we on a "Player versus Player" server? - bool IsPvPRealm() const { return (getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_PVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_RPPVP || getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP); } - bool IsFFAPvPRealm() const { return getIntConfig(CONFIG_GAME_TYPE) == REALM_TYPE_FFA_PVP; } + bool IsPvPRealm() const; + bool IsFFAPvPRealm() const; void KickAll(); void KickAllLess(AccountTypes sec); |