diff options
| author | Xanadu <none@none> | 2010-07-20 02:49:28 +0200 |
|---|---|---|
| committer | Xanadu <none@none> | 2010-07-20 02:49:28 +0200 |
| commit | 79622802f397258ee0f34327ba3ae6977ca3e7ff (patch) | |
| tree | 1868946c234ab9ee256a6b7766a15713eae94235 /src/server/game | |
| parent | 7dd2dc91816ab8b3bc3b99a1b1c99c7ea314d5a8 (diff) | |
| parent | f906976837502fa5aa81b982b901d1509f5aa0c4 (diff) | |
Merge. Revision history for source files should be all back now.
--HG--
branch : trunk
rename : sql/CMakeLists.txt => sql/tools/CMakeLists.txt
rename : src/server/game/Pools/PoolHandler.cpp => src/server/game/Pools/PoolMgr.cpp
rename : src/server/game/Pools/PoolHandler.h => src/server/game/Pools/PoolMgr.h
rename : src/server/game/PrecompiledHeaders/NixCorePCH.cpp => src/server/game/PrecompiledHeaders/gamePCH.cpp
rename : src/server/game/PrecompiledHeaders/NixCorePCH.h => src/server/game/PrecompiledHeaders/gamePCH.h
Diffstat (limited to 'src/server/game')
202 files changed, 4012 insertions, 3213 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 09ec8fae53f..cae50668a3a 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -231,7 +231,7 @@ void PetAI::UpdateAllies() Unit* owner = me->GetCharmerOrOwner(); Group *pGroup = NULL; - m_updateAlliesTimer = 10*IN_MILISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance + m_updateAlliesTimer = 10*IN_MILLISECONDS; //update friendly targets every 10 seconds, lesser checks increase performance if (!owner) return; diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 62b7090a2d0..3033f0556db 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -21,7 +21,7 @@ #ifndef TRINITY_UNITAI_H #define TRINITY_UNITAI_H -#include "Platform/Define.h" +#include "Define.h" #include <list> #include "Unit.h" diff --git a/src/server/game/AI/CreatureAIFactory.h b/src/server/game/AI/CreatureAIFactory.h index 6aa69eaaa29..bc3b9628010 100644 --- a/src/server/game/AI/CreatureAIFactory.h +++ b/src/server/game/AI/CreatureAIFactory.h @@ -21,8 +21,8 @@ #define TRINITY_CREATUREAIFACTORY_H //#include "Policies/Singleton.h" -#include "Dynamic/ObjectRegistry.h" -#include "Dynamic/FactoryHolder.h" +#include "ObjectRegistry.h" +#include "FactoryHolder.h" struct SelectableAI : public FactoryHolder<CreatureAI>, public Permissible<Creature> { diff --git a/src/server/game/AI/CreatureAIImpl.h b/src/server/game/AI/CreatureAIImpl.h index d2f96ffcabc..0f05d233891 100644 --- a/src/server/game/AI/CreatureAIImpl.h +++ b/src/server/game/AI/CreatureAIImpl.h @@ -19,7 +19,7 @@ #define CREATUREAIIMPL_H #include "Common.h" -#include "Platform/Define.h" +#include "Define.h" #include "TemporarySummon.h" #include "CreatureAI.h" #include "SpellMgr.h" diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index d3fd5a8aed9..8283baf87f9 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -21,22 +21,19 @@ #include "Creature.h" #include "CreatureAISelector.h" #include "PassiveAI.h" -#include "Policies/SingletonImp.h" + #include "MovementGenerator.h" #include "Pet.h" #include "TemporarySummon.h" #include "CreatureAIFactory.h" #include "ScriptMgr.h" -INSTANTIATE_SINGLETON_1(CreatureAIRegistry); -INSTANTIATE_SINGLETON_1(MovementGeneratorRegistry); - namespace FactorySelector { CreatureAI* selectAI(Creature *creature) { const CreatureAICreator *ai_factory = NULL; - CreatureAIRegistry &ai_registry(CreatureAIRepository::Instance()); + CreatureAIRegistry& ai_registry(*CreatureAIRepository::instance()); if (creature->isPet()) ai_factory = ai_registry.GetRegistryItem("PetAI"); @@ -106,7 +103,7 @@ namespace FactorySelector MovementGenerator* selectMovementGenerator(Creature *creature) { - MovementGeneratorRegistry &mv_registry(MovementGeneratorRepository::Instance()); + MovementGeneratorRegistry& mv_registry(*MovementGeneratorRepository::instance()); assert(creature->GetCreatureInfo() != NULL); const MovementGeneratorCreator *mv_factory = mv_registry.GetRegistryItem(creature->GetDefaultMovementType()); diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp index 47c8e9e6ad8..c70f471a82f 100644 --- a/src/server/game/AI/EventAI/CreatureEventAI.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp @@ -456,7 +456,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 caster = target; //Allowed to cast only if not casting (unless we interrupt ourself) or if spell is triggered - bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTURRUPT_PREVIOUS)); + bool canCast = !caster->IsNonMeleeSpellCasted(false) || (action.cast.castFlags & (CAST_TRIGGERED | CAST_INTERRUPT_PREVIOUS)); // If cast flag CAST_AURA_NOT_PRESENT is active, check if target already has aura on them if (action.cast.castFlags & CAST_AURA_NOT_PRESENT) @@ -492,7 +492,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32 else { //Interrupt any previous spell - if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTURRUPT_PREVIOUS) + if (caster->IsNonMeleeSpellCasted(false) && action.cast.castFlags & CAST_INTERRUPT_PREVIOUS) caster->InterruptNonMeleeSpells(false); caster->CastSpell(target, action.cast.spellId, (action.cast.castFlags & CAST_TRIGGERED)); @@ -1331,12 +1331,12 @@ void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote) if ((*itr).Event.receive_emote.emoteId != text_emote) return; - Condition* cond = new Condition(); - cond->mConditionType = ConditionType((*itr).Event.receive_emote.condition); - cond->mConditionValue1 = (*itr).Event.receive_emote.conditionValue1; - cond->mConditionValue2 = (*itr).Event.receive_emote.conditionValue2; + Condition cond; + cond.mConditionType = ConditionType((*itr).Event.receive_emote.condition); + cond.mConditionValue1 = (*itr).Event.receive_emote.conditionValue1; + cond.mConditionValue2 = (*itr).Event.receive_emote.conditionValue2; - if (cond->Meets(pPlayer)) + if (cond.Meets(pPlayer)) { sLog.outDebug("CreatureEventAI: ReceiveEmote CreatureEventAI: Condition ok, processing"); ProcessEvent(*itr, pPlayer); diff --git a/src/server/game/AI/EventAI/CreatureEventAI.h b/src/server/game/AI/EventAI/CreatureEventAI.h index 2fc5de46089..84b359787f5 100644 --- a/src/server/game/AI/EventAI/CreatureEventAI.h +++ b/src/server/game/AI/EventAI/CreatureEventAI.h @@ -150,7 +150,7 @@ enum Target enum CastFlags { - CAST_INTURRUPT_PREVIOUS = 0x01, //Interrupt any spell casting + CAST_INTERRUPT_PREVIOUS = 0x01, //Interrupt any spell casting CAST_TRIGGERED = 0x02, //Triggered (this makes spell cost zero mana and have no cast time) CAST_FORCE_CAST = 0x04, //Forces cast even if creature is out of mana or out of range CAST_NO_MELEE_IF_OOM = 0x08, //Prevents creature from entering melee if out of mana or out of range diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp index 83d62ca74dc..9f4105050ae 100644 --- a/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp +++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.cpp @@ -17,19 +17,16 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" -#include "Database/SQLStorage.h" +#include "DatabaseEnv.h" +#include "SQLStorage.h" #include "CreatureEventAI.h" #include "CreatureEventAIMgr.h" #include "ObjectMgr.h" #include "ProgressBar.h" -#include "Policies/SingletonImp.h" #include "ObjectDefines.h" #include "GridDefines.h" #include "ConditionMgr.h" -INSTANTIATE_SINGLETON_1(CreatureEventAIMgr); - // ------------------- void CreatureEventAIMgr::LoadCreatureEventAI_Texts() { @@ -362,11 +359,11 @@ void CreatureEventAIMgr::LoadCreatureEventAI_Scripts() } if (temp.receive_emote.condition) { - Condition* cond = new Condition(); - cond->mConditionType = ConditionType(temp.receive_emote.condition); - cond->mConditionValue1 = temp.receive_emote.conditionValue1; - cond->mConditionValue2 = temp.receive_emote.conditionValue2; - if (!sConditionMgr.isConditionTypeValid(cond)) + Condition cond; + cond.mConditionType = ConditionType(temp.receive_emote.condition); + cond.mConditionValue1 = temp.receive_emote.conditionValue1; + cond.mConditionValue2 = temp.receive_emote.conditionValue2; + if (!sConditionMgr.isConditionTypeValid(&cond)) { sLog.outErrorDb("CreatureEventAI: Creature %u using event %u: param2 (Condition: %u) are not valid.",temp.creature_id, i, temp.receive_emote.condition); continue; diff --git a/src/server/game/AI/EventAI/CreatureEventAIMgr.h b/src/server/game/AI/EventAI/CreatureEventAIMgr.h index ef191b22463..3c8181e9e74 100644 --- a/src/server/game/AI/EventAI/CreatureEventAIMgr.h +++ b/src/server/game/AI/EventAI/CreatureEventAIMgr.h @@ -24,8 +24,9 @@ class CreatureEventAIMgr { + friend class ACE_Singleton<CreatureEventAIMgr, ACE_Null_Mutex>; + CreatureEventAIMgr(){}; public: - CreatureEventAIMgr(){}; ~CreatureEventAIMgr(){}; void LoadCreatureEventAI_Texts(); @@ -42,5 +43,5 @@ class CreatureEventAIMgr CreatureEventAI_TextMap m_CreatureEventAI_TextMap; }; -#define CreatureEAI_Mgr Trinity::Singleton<CreatureEventAIMgr>::Instance() +#define CreatureEAI_Mgr (*ACE_Singleton<CreatureEventAIMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index 8c4ddd14f07..9ab9e06b624 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -5,7 +5,7 @@ * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" #include "Item.h" #include "Spell.h" #include "ObjectMgr.h" @@ -153,7 +153,7 @@ void ScriptedAI::DoPlaySoundToSet(WorldObject* pSource, uint32 uiSoundId) if (!GetSoundEntriesStore()->LookupEntry(uiSoundId)) { - error_log("TSCR: Invalid soundId %u used in DoPlaySoundToSet (Source: TypeId %u, GUID %u)", uiSoundId, pSource->GetTypeId(), pSource->GetGUIDLow()); + sLog.outError("TSCR: Invalid soundId %u used in DoPlaySoundToSet (Source: TypeId %u, GUID %u)", uiSoundId, pSource->GetTypeId(), pSource->GetGUIDLow()); return; } @@ -398,7 +398,7 @@ void ScriptedAI::DoResetThreat() { if (!me->CanHaveThreatList() || me->getThreatManager().isThreatListEmpty()) { - error_log("TSCR: DoResetThreat called for creature that either cannot have threat list or has empty threat list (me entry = %d)", me->GetEntry()); + sLog.outError("TSCR: DoResetThreat called for creature that either cannot have threat list or has empty threat list (me entry = %d)", me->GetEntry()); return; } @@ -441,7 +441,7 @@ void ScriptedAI::DoTeleportPlayer(Unit* pUnit, float fX, float fY, float fZ, flo if (!pUnit || pUnit->GetTypeId() != TYPEID_PLAYER) { if (pUnit) - error_log("TSCR: Creature %u (Entry: %u) Tried to teleport non-player unit (Type: %u GUID: %u) to x: %f y:%f z: %f o: %f. Aborted.", me->GetGUID(), me->GetEntry(), pUnit->GetTypeId(), pUnit->GetGUID(), fX, fY, fZ, fO); + sLog.outError("TSCR: Creature %u (Entry: %u) Tried to teleport non-player unit (Type: %u GUID: %u) to x: %f y:%f z: %f o: %f. Aborted.", me->GetGUID(), me->GetEntry(), pUnit->GetTypeId(), pUnit->GetGUID(), fX, fY, fZ, fO); return; } @@ -578,7 +578,7 @@ bool ScriptedAI::EnterEvadeIfOutOfCombatArea(const uint32 uiDiff) return false; break; default: - error_log("TSCR: EnterEvadeIfOutOfCombatArea used for creature entry %u, but does not have any definition.", me->GetEntry()); + sLog.outError("TSCR: EnterEvadeIfOutOfCombatArea used for creature entry %u, but does not have any definition.", me->GetEntry()); return false; } diff --git a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp index 8b7aca888e1..84e2cff7e2f 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedEscortAI.cpp @@ -9,7 +9,7 @@ SDComment: SDCategory: Npc EndScriptData */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" #include "ScriptedEscortAI.h" enum ePoints @@ -104,7 +104,7 @@ void npc_escortAI::MoveInLineOfSight(Unit* pWho) { if (!me->getVictim()) { - pWho->RemoveAurasDueToSpell(SPELL_AURA_MOD_STEALTH); + pWho->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); AttackStart(pWho); } else if (me->GetMap()->IsDungeon()) @@ -177,7 +177,7 @@ void npc_escortAI::EnterEvadeMode() { AddEscortState(STATE_ESCORT_RETURNING); ReturnToLastPoint(); - debug_log("TSCR: EscortAI has left combat and is now returning to last point"); + sLog.outDebug("TSCR: EscortAI has left combat and is now returning to last point"); } else { @@ -224,7 +224,7 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff) { if (DespawnAtEnd) { - debug_log("TSCR: EscortAI reached end of waypoints"); + sLog.outDebug("TSCR: EscortAI reached end of waypoints"); if (m_bCanReturnToStart) { @@ -235,7 +235,7 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff) m_uiWPWaitTimer = 0; - debug_log("TSCR: EscortAI are returning home to spawn location: %u, %f, %f, %f", POINT_HOME, fRetX, fRetY, fRetZ); + sLog.outDebug("TSCR: EscortAI are returning home to spawn location: %u, %f, %f, %f", POINT_HOME, fRetX, fRetY, fRetZ); return; } @@ -251,7 +251,7 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff) } else { - debug_log("TSCR: EscortAI reached end of waypoints with Despawn off"); + sLog.outDebug("TSCR: EscortAI reached end of waypoints with Despawn off"); return; } @@ -260,7 +260,7 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff) if (!HasEscortState(STATE_ESCORT_PAUSED)) { me->GetMotionMaster()->MovePoint(CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); - debug_log("TSCR: EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); + sLog.outDebug("TSCR: EscortAI start waypoint %u (%f, %f, %f).", CurrentWP->id, CurrentWP->x, CurrentWP->y, CurrentWP->z); WaypointStart(CurrentWP->id); @@ -278,7 +278,7 @@ void npc_escortAI::UpdateAI(const uint32 uiDiff) { if (DespawnAtFar && !IsPlayerOrGroupInRange()) { - debug_log("TSCR: EscortAI failed because player/group was to far away or not found"); + sLog.outDebug("TSCR: EscortAI failed because player/group was to far away or not found"); if (m_bCanInstantRespawn) { @@ -316,7 +316,7 @@ void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) //Combat start position reached, continue waypoint movement if (uiPointId == POINT_LAST_POINT) { - debug_log("TSCR: EscortAI has returned to original position before combat"); + sLog.outDebug("TSCR: EscortAI has returned to original position before combat"); if (m_bIsRunning && me->HasUnitMovementFlag(MOVEMENTFLAG_WALK_MODE)) me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); @@ -330,7 +330,7 @@ void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) } else if (uiPointId == POINT_HOME) { - debug_log("TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list."); + sLog.outDebug("TSCR: EscortAI has returned to original home location and will continue from beginning of waypoint list."); CurrentWP = WaypointList.begin(); m_uiWPWaitTimer = 1; @@ -340,11 +340,11 @@ void npc_escortAI::MovementInform(uint32 uiMoveType, uint32 uiPointId) //Make sure that we are still on the right waypoint if (CurrentWP->id != uiPointId) { - error_log("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u", uiPointId, CurrentWP->id, me->GetEntry()); + sLog.outError("TSCR ERROR: EscortAI reached waypoint out of order %u, expected %u, creature entry %u", uiPointId, CurrentWP->id, me->GetEntry()); return; } - debug_log("TSCR: EscortAI Waypoint %u reached", CurrentWP->id); + sLog.outDebug("TSCR: EscortAI Waypoint %u reached", CurrentWP->id); //Call WP function WaypointReached(CurrentWP->id); @@ -415,14 +415,14 @@ void npc_escortAI::SetRun(bool bRun) if (!m_bIsRunning) me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); else - debug_log("TSCR: EscortAI attempt to set run mode, but is already running."); + sLog.outDebug("TSCR: EscortAI attempt to set run mode, but is already running."); } else { if (m_bIsRunning) me->AddUnitMovementFlag(MOVEMENTFLAG_WALK_MODE); else - debug_log("TSCR: EscortAI attempt to set walk mode, but is already walking."); + sLog.outDebug("TSCR: EscortAI attempt to set walk mode, but is already walking."); } m_bIsRunning = bRun; } @@ -432,13 +432,13 @@ void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID, { if (me->getVictim()) { - error_log("TSCR ERROR: EscortAI attempt to Start while in combat. Scriptname: %s, creature entry: %u", me->GetScriptName().c_str(), me->GetEntry()); + sLog.outError("TSCR ERROR: EscortAI attempt to Start while in combat. Scriptname: %s, creature entry: %u", me->GetScriptName().c_str(), me->GetEntry()); return; } if (HasEscortState(STATE_ESCORT_ESCORTING)) { - error_log("TSCR: EscortAI attempt to Start while already escorting."); + sLog.outError("TSCR: EscortAI attempt to Start while already escorting."); return; } @@ -454,7 +454,7 @@ void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID, if (WaypointList.empty()) { - error_db_log("TSCR: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", pQuest ? pQuest->GetQuestId() : 0); + sLog.outErrorDb("TSCR: EscortAI Start with 0 waypoints (possible missing entry in script_waypoint. Quest: %u).", pQuest ? pQuest->GetQuestId() : 0); return; } @@ -469,19 +469,19 @@ void npc_escortAI::Start(bool bIsActiveAttacker, bool bRun, uint64 uiPlayerGUID, m_bCanReturnToStart = bCanLoopPath; if (m_bCanReturnToStart && m_bCanInstantRespawn) - debug_log("TSCR: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn."); + sLog.outDebug("TSCR: EscortAI is set to return home after waypoint end and instant respawn at waypoint end. Creature will never despawn."); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == WAYPOINT_MOTION_TYPE) { me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MoveIdle(); - debug_log("TSCR: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); + sLog.outDebug("TSCR: EscortAI start with WAYPOINT_MOTION_TYPE, changed to MoveIdle."); } //disable npcflags me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); - debug_log("TSCR: EscortAI started with %u waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = %u", WaypointList.size(), m_bIsActiveAttacker, m_bIsRunning, m_uiPlayerGUID); + sLog.outDebug("TSCR: EscortAI started with %u waypoints. ActiveAttacker = %d, Run = %d, PlayerGUID = %u", WaypointList.size(), m_bIsActiveAttacker, m_bIsRunning, m_uiPlayerGUID); CurrentWP = WaypointList.begin(); diff --git a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp index 4f1543dc778..499e4611693 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedFollowerAI.cpp @@ -9,7 +9,7 @@ SDComment: This AI is under development SDCategory: Npc EndScriptData */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" #include "ScriptedFollowerAI.h" const float MAX_PLAYER_DISTANCE = 100.0f; @@ -102,7 +102,7 @@ void FollowerAI::MoveInLineOfSight(Unit* pWho) { if (!me->getVictim()) { - pWho->RemoveAurasDueToSpell(SPELL_AURA_MOD_STEALTH); + pWho->RemoveAurasByType(SPELL_AURA_MOD_STEALTH); AttackStart(pWho); } else if (me->GetMap()->IsDungeon()) @@ -164,7 +164,7 @@ void FollowerAI::EnterEvadeMode() if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { - debug_log("TSCR: FollowerAI left combat, returning to CombatStartPosition."); + sLog.outDebug("TSCR: FollowerAI left combat, returning to CombatStartPosition."); if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE) { @@ -190,7 +190,7 @@ void FollowerAI::UpdateAI(const uint32 uiDiff) { if (HasFollowState(STATE_FOLLOW_COMPLETE) && !HasFollowState(STATE_FOLLOW_POSTEVENT)) { - debug_log("TSCR: FollowerAI is set completed, despawns."); + sLog.outDebug("TSCR: FollowerAI is set completed, despawns."); me->ForcedDespawn(); return; } @@ -201,7 +201,7 @@ void FollowerAI::UpdateAI(const uint32 uiDiff) { if (HasFollowState(STATE_FOLLOW_RETURNING)) { - debug_log("TSCR: FollowerAI is returning to leader."); + sLog.outDebug("TSCR: FollowerAI is returning to leader."); RemoveFollowState(STATE_FOLLOW_RETURNING); me->GetMotionMaster()->MoveFollow(pPlayer, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); @@ -230,7 +230,7 @@ void FollowerAI::UpdateAI(const uint32 uiDiff) if (bIsMaxRangeExceeded) { - debug_log("TSCR: FollowerAI failed because player/group was to far away or not found"); + sLog.outDebug("TSCR: FollowerAI failed because player/group was to far away or not found"); me->ForcedDespawn(); return; } @@ -273,13 +273,13 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const { if (me->getVictim()) { - debug_log("TSCR: FollowerAI attempt to StartFollow while in combat."); + sLog.outDebug("TSCR: FollowerAI attempt to StartFollow while in combat."); return; } if (HasFollowState(STATE_FOLLOW_INPROGRESS)) { - error_log("TSCR: FollowerAI attempt to StartFollow while already following."); + sLog.outError("TSCR: FollowerAI attempt to StartFollow while already following."); return; } @@ -295,7 +295,7 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const { me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); - debug_log("TSCR: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle."); + sLog.outDebug("TSCR: FollowerAI start with WAYPOINT_MOTION_TYPE, set to MoveIdle."); } me->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_NONE); @@ -304,7 +304,7 @@ void FollowerAI::StartFollow(Player* pLeader, uint32 uiFactionForFollower, const me->GetMotionMaster()->MoveFollow(pLeader, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE); - debug_log("TSCR: FollowerAI start follow %s (GUID %u)", pLeader->GetName(), m_uiLeaderGUID); + sLog.outDebug("TSCR: FollowerAI start follow %s (GUID %u)", pLeader->GetName(), m_uiLeaderGUID); } Player* FollowerAI::GetLeaderForFollower() @@ -323,7 +323,7 @@ Player* FollowerAI::GetLeaderForFollower() if (pMember && pMember->isAlive() && me->IsWithinDistInMap(pMember, MAX_PLAYER_DISTANCE)) { - debug_log("TSCR: FollowerAI GetLeader changed and returned new leader."); + sLog.outDebug("TSCR: FollowerAI GetLeader changed and returned new leader."); m_uiLeaderGUID = pMember->GetGUID(); return pMember; break; @@ -333,7 +333,7 @@ Player* FollowerAI::GetLeaderForFollower() } } - debug_log("TSCR: FollowerAI GetLeader can not find suitable leader."); + sLog.outDebug("TSCR: FollowerAI GetLeader can not find suitable leader."); return NULL; } diff --git a/src/server/game/AI/ScriptedAI/ScriptedGuardAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedGuardAI.cpp index 68dc8690470..4dd19547dda 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedGuardAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedGuardAI.cpp @@ -21,7 +21,7 @@ SDComment: SDCategory: Guards EndScriptData */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" #include "ScriptedGuardAI.h" // **** This script is for use within every single guard to save coding time **** diff --git a/src/server/game/AI/ScriptedAI/ScriptedInstance.h b/src/server/game/AI/ScriptedAI/ScriptedInstance.h index 25593e05300..8a9b8c4c5a3 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedInstance.h +++ b/src/server/game/AI/ScriptedAI/ScriptedInstance.h @@ -8,11 +8,11 @@ #include "InstanceData.h" #include "Map.h" -#define OUT_SAVE_INST_DATA debug_log("TSCR: Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) -#define OUT_SAVE_INST_DATA_COMPLETE debug_log("TSCR: Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) -#define OUT_LOAD_INST_DATA(a) debug_log("TSCR: Loading Instance Data for Instance %s (Map %d, Instance Id %d). Input is '%s'", instance->GetMapName(), instance->GetId(), instance->GetInstanceId(), a) -#define OUT_LOAD_INST_DATA_COMPLETE debug_log("TSCR: 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 error_log("TSCR: Unable to load Instance Data for Instance %s (Map %d, Instance Id: %d).",instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) +#define OUT_SAVE_INST_DATA sLog.outDebug("TSCR: Saving Instance Data for Instance %s (Map %d, Instance Id %d)", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) +#define OUT_SAVE_INST_DATA_COMPLETE sLog.outDebug("TSCR: Saving Instance Data for Instance %s (Map %d, Instance Id %d) completed.", instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) +#define OUT_LOAD_INST_DATA(a) sLog.outDebug("TSCR: Loading Instance Data for Instance %s (Map %d, Instance Id %d). Input is '%s'", instance->GetMapName(), instance->GetId(), instance->GetInstanceId(), a) +#define OUT_LOAD_INST_DATA_COMPLETE sLog.outDebug("TSCR: 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 sLog.outError("TSCR: Unable to load Instance Data for Instance %s (Map %d, Instance Id: %d).",instance->GetMapName(), instance->GetId(), instance->GetInstanceId()) #define ScriptedInstance InstanceData diff --git a/src/server/game/AI/ScriptedAI/ScriptedSimpleAI.cpp b/src/server/game/AI/ScriptedAI/ScriptedSimpleAI.cpp index 08797515837..7d86c8e54a6 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedSimpleAI.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedSimpleAI.cpp @@ -21,7 +21,7 @@ SDComment: Base Class for SimpleAI creatures SDCategory: Creatures EndScriptData */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" #include "ScriptedSimpleAI.h" SimpleAI::SimpleAI(Creature *c) : ScriptedAI(c) diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 52906fb5454..54f80114131 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -18,19 +18,17 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Database/DatabaseEnv.h" -#include "Policies/SingletonImp.h" +#include "DatabaseEnv.h" + #include "AccountMgr.h" #include "ObjectAccessor.h" #include "Player.h" #include "Util.h" -#include "Auth/Sha1.h" +#include "SHA1.h" extern DatabaseType LoginDatabase; -INSTANTIATE_SINGLETON_1(AccountMgr); - AccountMgr::AccountMgr() {} diff --git a/src/server/game/Accounts/AccountMgr.h b/src/server/game/Accounts/AccountMgr.h index b017bf1836a..a0e181cf4a0 100644 --- a/src/server/game/Accounts/AccountMgr.h +++ b/src/server/game/Accounts/AccountMgr.h @@ -24,7 +24,6 @@ #include <string> #include "Common.h" -#include "Policies/Singleton.h" enum AccountOpResult { @@ -59,6 +58,6 @@ class AccountMgr static bool normalizeString(std::string& utf8str); }; -#define accmgr Trinity::Singleton<AccountMgr>::Instance() +#define accmgr (*ACE_Singleton<AccountMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index e0a79fc71ed..bb156c40ca6 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -21,8 +21,8 @@ #include "ObjectMgr.h" #include "World.h" #include "WorldPacket.h" -#include "Database/DatabaseEnv.h" -#include "Policies/SingletonImp.h" +#include "DatabaseEnv.h" + #include "AchievementMgr.h" #include "ArenaTeam.h" @@ -41,8 +41,6 @@ #include "Map.h" #include "InstanceData.h" -INSTANTIATE_SINGLETON_1(AchievementGlobalMgr); - namespace Trinity { class AchievementChatBuilder @@ -873,6 +871,36 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui SetCriteriaProgress(achievementCriteria, counter); break; } + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: + { + time_t nextDailyResetTime = sWorld.GetNextDailyQuestsResetTime(); + CriteriaProgress *progress = GetCriteriaProgress(achievementCriteria); + + if (!miscvalue1) // Login case. + { + // reset if player missed one day. + if (progress && progress->date < (nextDailyResetTime - 2 * DAY)) + SetCriteriaProgress(achievementCriteria, 0, PROGRESS_SET); + continue; + } + + ProgressType progressType; + if (!progress) + // 1st time. Start count. + progressType = PROGRESS_SET; + else if (progress->date < (nextDailyResetTime - 2 * DAY)) + // last progress is older than 2 days. Player missed 1 day => Retart count. + progressType = PROGRESS_SET; + else if (progress->date < (nextDailyResetTime - DAY)) + // last progress is between 1 and 2 days. => 1st time of the day. + progressType = PROGRESS_ACCUMULATE; + else + // last progress is within the day before the reset => Already counted today. + continue; + + SetCriteriaProgress(achievementCriteria, 1, progressType); + break; + } case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: { // speedup for non-login case @@ -935,7 +963,7 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui if (!miscvalue1) continue; - Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : MapManager::Instance().FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); + Map const* map = GetPlayer()->IsInWorld() ? GetPlayer()->GetMap() : sMapMgr.FindMap(GetPlayer()->GetMapId(), GetPlayer()->GetInstanceId()); if (!map || !map->IsDungeon()) continue; @@ -1428,7 +1456,6 @@ void AchievementMgr::UpdateAchievementCriteria(AchievementCriteriaTypes type, ui case ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_RATING: break; // FIXME: not triggered in code as result, need to implement - case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_RAID: case ACHIEVEMENT_CRITERIA_TYPE_BG_OBJECTIVE_CAPTURE: case ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA: @@ -1483,11 +1510,10 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return false; } - CriteriaProgressMap::const_iterator itr = m_criteriaProgress.find(achievementCriteria->ID); - if (itr == m_criteriaProgress.end()) + CriteriaProgress const* progress = GetCriteriaProgress(achievementCriteria); + if (!progress) return false; - CriteriaProgress const* progress = &itr->second; switch(achievementCriteria->requiredType) { @@ -1516,6 +1542,8 @@ bool AchievementMgr::IsCompletedCriteria(AchievementCriteriaEntry const* achieve return progress->counter >= 1; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUEST_COUNT: return progress->counter >= achievementCriteria->complete_quest_count.totalQuestCount; + case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY: + return progress->counter >= achievementCriteria->complete_daily_quest_daily.numberOfDays; case ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_QUESTS_IN_ZONE: return progress->counter >= achievementCriteria->complete_quests_in_zone.questCount; case ACHIEVEMENT_CRITERIA_TYPE_DAMAGE_DONE: @@ -1661,11 +1689,10 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) { AchievementCriteriaEntry const* criteria = *itr; - CriteriaProgressMap::const_iterator itrProgress = m_criteriaProgress.find(criteria->ID); - if (itrProgress == m_criteriaProgress.end()) + CriteriaProgress const* progress = GetCriteriaProgress(criteria); + if (!progress) continue; - CriteriaProgress const* progress = &itrProgress->second; count += progress->counter; // for counters, field4 contains the main count requirement @@ -1701,6 +1728,16 @@ bool AchievementMgr::IsCompletedAchievement(AchievementEntry const* entry) return false; } +CriteriaProgress* AchievementMgr::GetCriteriaProgress(AchievementCriteriaEntry const* entry) +{ + CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); + + if (iter == m_criteriaProgress.end()) + return NULL; + + return &(iter->second); +} + void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype) { // Don't allow to cheat - doing timed achievements without timer active @@ -1711,11 +1748,8 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, if ((sLog.getLogFilter() & LOG_FILTER_ACHIEVEMENT_UPDATES) == 0) sLog.outDetail("AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow()); - CriteriaProgress *progress = NULL; - - CriteriaProgressMap::iterator iter = m_criteriaProgress.find(entry->ID); - - if (iter == m_criteriaProgress.end()) + CriteriaProgress* progress = GetCriteriaProgress(entry); + if (!progress) { // not create record for 0 counter but allow it for timed achievements // we will need to send 0 progress to client to start the timer @@ -1724,12 +1758,9 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, progress = &m_criteriaProgress[entry->ID]; progress->counter = changeValue; - progress->date = time(NULL); } else { - progress = &iter->second; - uint32 newValue = 0; switch(ptype) { @@ -1756,6 +1787,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, } progress->changed = true; + progress->date = time(NULL); // set the date to the latest update. uint32 timeElapsed = 0; bool timedCompleted = false; @@ -1765,7 +1797,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, //has to exist else we wouldn't be here timedCompleted = IsCompletedCriteria(entry, sAchievementStore.LookupEntry(entry->referredAchievement)); // Client expects this in packet - timeElapsed = entry->timeLimit - (timedIter->second/IN_MILISECONDS); + timeElapsed = entry->timeLimit - (timedIter->second/IN_MILLISECONDS); // Remove the timer, we wont need it anymore if (timedCompleted) @@ -1809,7 +1841,7 @@ void AchievementMgr::StartTimedAchievement(AchievementCriteriaTimedTypes type, u if (m_timedAchievements.find((*i)->ID) == m_timedAchievements.end() && !IsCompletedCriteria(*i, achievement)) { // Start the timer - m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILISECONDS; + m_timedAchievements[(*i)->ID] = (*i)->timeLimit * IN_MILLISECONDS; // and at client too SetCriteriaProgress(*i, 0, PROGRESS_SET); diff --git a/src/server/game/Achievements/AchievementMgr.h b/src/server/game/Achievements/AchievementMgr.h index ea9e5e95142..0eedf971c20 100644 --- a/src/server/game/Achievements/AchievementMgr.h +++ b/src/server/game/Achievements/AchievementMgr.h @@ -22,8 +22,8 @@ #include <string> #include "Common.h" -#include "Policies/Singleton.h" -#include "Database/DatabaseEnv.h" +#include "ace/Singleton.h" +#include "DatabaseEnv.h" #include "DBCEnums.h" #include "DBCStores.h" @@ -36,7 +36,7 @@ typedef std::map<uint32,AchievementEntryList> AchievementListByReference struct CriteriaProgress { uint32 counter; - time_t date; + time_t date; // latest update time. bool changed; }; @@ -258,6 +258,7 @@ class AchievementMgr enum ProgressType { PROGRESS_SET, PROGRESS_ACCUMULATE, PROGRESS_HIGHEST }; void SendAchievementEarned(AchievementEntry const* achievement); void SendCriteriaUpdate(AchievementCriteriaEntry const* entry, CriteriaProgress const* progress, uint32 timeElapsed, bool timedCompleted); + CriteriaProgress* GetCriteriaProgress(AchievementCriteriaEntry const* entry); void SetCriteriaProgress(AchievementCriteriaEntry const* entry, uint32 changeValue, ProgressType ptype = PROGRESS_SET); void CompletedCriteriaFor(AchievementEntry const* achievement); bool IsCompletedCriteria(AchievementCriteriaEntry const* criteria, AchievementEntry const* achievement); @@ -341,6 +342,6 @@ class AchievementGlobalMgr AchievementRewardLocales m_achievementRewardLocales; }; -#define achievementmgr Trinity::Singleton<AchievementGlobalMgr>::Instance() +#define achievementmgr (*ACE_Singleton<AchievementGlobalMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/Addons/AddonMgr.cpp b/src/server/game/Addons/AddonMgr.cpp index 66e4fbc8765..830d439bfdd 100644 --- a/src/server/game/Addons/AddonMgr.cpp +++ b/src/server/game/Addons/AddonMgr.cpp @@ -1,8 +1,7 @@ /* + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008-2009 Trinity <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 @@ -18,20 +17,18 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Database/DatabaseEnv.h" -#include "Policies/SingletonImp.h" +#include "DatabaseEnv.h" + #include "AddonMgr.h" #include "ObjectAccessor.h" #include "Player.h" #include "Util.h" -#include "Auth/Sha1.h" +#include "SHA1.h" #include "ProgressBar.h" extern DatabaseType LoginDatabase; -INSTANTIATE_SINGLETON_1(AddonMgr); - AddonMgr::AddonMgr() { } diff --git a/src/server/game/Addons/AddonMgr.h b/src/server/game/Addons/AddonMgr.h index 8f5eed4918f..112415e5b40 100644 --- a/src/server/game/Addons/AddonMgr.h +++ b/src/server/game/Addons/AddonMgr.h @@ -1,8 +1,7 @@ /* + * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008-2009 Trinity <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 @@ -22,7 +21,7 @@ #define _ADDONMGR_H #include "Common.h" -#include "Policies/Singleton.h" +#include "ace/Singleton.h" #include <string> @@ -68,9 +67,10 @@ typedef std::list<SavedAddon> SavedAddonsList; class AddonMgr { + friend class ACE_Singleton<AddonMgr, ACE_Null_Mutex>; + AddonMgr(); public: - AddonMgr(); ~AddonMgr(); void LoadFromDB(); @@ -83,7 +83,7 @@ class AddonMgr SavedAddonsList m_knownAddons; // Known addons. }; -#define sAddonMgr Trinity::Singleton<AddonMgr>::Instance() +#define sAddonMgr (*ACE_Singleton<AddonMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.cpp b/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.cpp index ebbf48e6476..0a4b6c3f32e 100644 --- a/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.cpp @@ -1,11 +1,27 @@ +/* + * Copyright (C) 2008-2010 Trinity <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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #include "ObjectMgr.h" #include "AuctionHouseMgr.h" #include "AuctionHouseBot.h" #include <vector> -#include "Policies/SingletonImp.h" -INSTANTIATE_SINGLETON_1(AuctionHouseBot); - using namespace std; vector<uint32> npcItems; vector<uint32> lootItems; @@ -23,6 +39,7 @@ vector<uint32> blueItemsBin; vector<uint32> purpleItemsBin; vector<uint32> orangeItemsBin; vector<uint32> yellowItemsBin; + AuctionHouseBot::AuctionHouseBot() { debug_Out = false; @@ -693,7 +710,7 @@ void AuctionHouseBot::Update() WorldSession _session(AHBplayerAccount, NULL, SEC_PLAYER, true, 0, LOCALE_enUS); Player _AHBplayer(&_session); _AHBplayer.Initialize(AHBplayerGUID); - ObjectAccessor::Instance().AddObject(&_AHBplayer); + sObjectAccessor.AddObject(&_AHBplayer); // Add New Bids if (!sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) @@ -725,7 +742,7 @@ void AuctionHouseBot::Update() addNewAuctionBuyerBotBid(&_AHBplayer, &NeutralConfig, &_session); _lastrun_n = _newrun; } - ObjectAccessor::Instance().RemoveObject(&_AHBplayer); + sObjectAccessor.RemoveObject(&_AHBplayer); } void AuctionHouseBot::Initialize() @@ -1510,6 +1527,7 @@ void AuctionHouseBot::Commands(uint32 command, uint32 ahMapID, uint32 col, char* uint32 maxItems = (uint32) strtoul(param1, NULL, 0); CharacterDatabase.PExecute("UPDATE auctionhousebot SET maxitems = '%u' WHERE auctionhouse = '%u'", maxItems, ahMapID); config->SetMaxItems(maxItems); + config->CalculatePercents(); } break; case 3: //min time Deprecated (Place holder for future commands) diff --git a/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.h b/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.h index 208a09aa0b2..d1cec5f170e 100644 --- a/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.h +++ b/src/server/game/AuctionHouse/AuctionHouseBot/AuctionHouseBot.h @@ -1,8 +1,27 @@ +/* + * Copyright (C) 2008-2010 Trinity <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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #ifndef AUCTION_HOUSE_BOT_H #define AUCTION_HOUSE_BOT_H #include "World.h" -#include "Config/ConfigEnv.h" +#include "ConfigEnv.h" #include "ItemPrototype.h" #define AHB_GREY 0 @@ -173,7 +192,8 @@ public: void SetMaxItems(uint32 value) { maxItems = value; - CalculatePercents(); + // CalculatePercents() needs to be called, but only if + // SetPercentages() has been called at least once already. } uint32 GetMaxItems() { @@ -1207,9 +1227,11 @@ private: inline uint32 minValue(uint32 a, uint32 b) { return a <= b ? a : b; }; void addNewAuctions(Player *AHBplayer, AHBConfig *config); void addNewAuctionBuyerBotBid(Player *AHBplayer, AHBConfig *config, WorldSession *session); + + friend class ACE_Singleton<AuctionHouseBot, ACE_Null_Mutex>; + AuctionHouseBot(); public: - AuctionHouseBot(); ~AuctionHouseBot(); void Update(); void Initialize(); @@ -1220,6 +1242,6 @@ public: uint32 GetAHBplayerGUID() { return AHBplayerGUID; }; }; -#define auctionbot Trinity::Singleton<AuctionHouseBot>::Instance() +#define auctionbot (*ACE_Singleton<AuctionHouseBot, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index ddd44bbefa2..95e1fb5e931 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -1,19 +1,19 @@ /* + * Copyright (C) 2008-2010 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 "Common.h" @@ -22,21 +22,19 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Database/DatabaseEnv.h" -#include "Database/SQLStorage.h" -#include "Policies/SingletonImp.h" +#include "DatabaseEnv.h" +#include "SQLStorage.h" + #include "DBCStores.h" #include "AccountMgr.h" #include "AuctionHouseMgr.h" #include "Item.h" #include "Language.h" -#include "Log.h" +#include "Logging/Log.h" #include "ProgressBar.h" #include <vector> -INSTANTIATE_SINGLETON_1(AuctionHouseMgr); - using namespace std; AuctionHouseMgr::AuctionHouseMgr() @@ -483,7 +481,11 @@ AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTem bool AuctionHouseObject::RemoveAuction(AuctionEntry *auction, uint32 item_template) { auctionbot.DecrementItemCounts(auction, item_template); - return AuctionsMap.erase(auction->Id) ? true : false; + bool wasInMap = AuctionsMap.erase(auction->Id) ? true : false; + + // we need to delete the entry, it is not referenced any more + delete auction; + return wasInMap; } void AuctionHouseObject::Update() @@ -711,7 +713,7 @@ bool AuctionEntry::BuildAuctionInfo(WorldPacket & data) const data << uint32(bid ? GetAuctionOutBid() : 0); //minimal outbid data << uint32(buyout); //auction->buyout - data << uint32((expire_time-time(NULL))*IN_MILISECONDS);//time left + data << uint32((expire_time-time(NULL))*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 b92cec986c7..24c954a91e8 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -1,27 +1,25 @@ /* + * Copyright (C) 2008-2010 TrinityCore <http://www.trinitycore.org/> * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> * - * Copyright (C) 2008-2010 Trinity <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 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 _AUCTION_HOUSE_MGR_H #define _AUCTION_HOUSE_MGR_H -#include "Policies/Singleton.h" +#include "ace/Singleton.h" #include "SharedDefines.h" @@ -121,51 +119,53 @@ class AuctionHouseObject class AuctionHouseMgr { - public: + friend class ACE_Singleton<AuctionHouseMgr, ACE_Null_Mutex>; AuctionHouseMgr(); - ~AuctionHouseMgr(); + + public: + ~AuctionHouseMgr(); - typedef UNORDERED_MAP<uint32, Item*> ItemMap; + typedef UNORDERED_MAP<uint32, Item*> ItemMap; - AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); - AuctionHouseObject* GetBidsMap(uint32 factionTemplateId); + AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); + AuctionHouseObject* GetBidsMap(uint32 factionTemplateId); - Item* GetAItem(uint32 id) - { - ItemMap::const_iterator itr = mAitems.find(id); - if (itr != mAitems.end()) + Item* GetAItem(uint32 id) { - return itr->second; + ItemMap::const_iterator itr = mAitems.find(id); + if (itr != mAitems.end()) + { + return itr->second; + } + return NULL; } - return NULL; - } - //auction messages - void SendAuctionWonMail(AuctionEntry * auction); - void SendAuctionSalePendingMail(AuctionEntry * auction); - void SendAuctionSuccessfulMail(AuctionEntry * auction); - void SendAuctionExpiredMail(AuctionEntry * auction); - static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem); - static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); + //auction messages + void SendAuctionWonMail(AuctionEntry * auction); + void SendAuctionSalePendingMail(AuctionEntry * auction); + void SendAuctionSuccessfulMail(AuctionEntry * auction); + void SendAuctionExpiredMail(AuctionEntry * auction); + static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item *pItem); + static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); - public: + public: //load first auction items, because of check if item exists, when loading - void LoadAuctionItems(); - void LoadAuctions(); + void LoadAuctionItems(); + void LoadAuctions(); - void AddAItem(Item* it); - bool RemoveAItem(uint32 id); + void AddAItem(Item* it); + bool RemoveAItem(uint32 id); - void Update(); + void Update(); - private: - AuctionHouseObject mHordeAuctions; - AuctionHouseObject mAllianceAuctions; - AuctionHouseObject mNeutralAuctions; + private: + AuctionHouseObject mHordeAuctions; + AuctionHouseObject mAllianceAuctions; + AuctionHouseObject mNeutralAuctions; - ItemMap mAitems; + ItemMap mAitems; }; -#define auctionmgr Trinity::Singleton<AuctionHouseMgr>::Instance() +#define auctionmgr (*ACE_Singleton<AuctionHouseMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/BattleGrounds/BattleGround.cpp b/src/server/game/BattleGrounds/BattleGround.cpp index 5bfe2e139b6..d9d6dc98a58 100644 --- a/src/server/game/BattleGrounds/BattleGround.cpp +++ b/src/server/game/BattleGrounds/BattleGround.cpp @@ -323,7 +323,7 @@ void BattleGround::Update(uint32 diff) plr->ResurrectPlayer(1.0f); plr->CastSpell(plr, 6962, true); plr->CastSpell(plr, SPELL_SPIRIT_HEAL_MANA, true); - ObjectAccessor::Instance().ConvertCorpseForPlayer(*itr); + sObjectAccessor.ConvertCorpseForPlayer(*itr); } m_ResurrectQueue.clear(); } @@ -356,16 +356,16 @@ void BattleGround::Update(uint32 diff) { uint32 newtime = m_PrematureCountDownTimer - diff; // announce every minute - if (newtime > (MINUTE * IN_MILISECONDS)) + if (newtime > (MINUTE * IN_MILLISECONDS)) { - if (newtime / (MINUTE * IN_MILISECONDS) != m_PrematureCountDownTimer / (MINUTE * IN_MILISECONDS)) - PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / (MINUTE * IN_MILISECONDS))); + 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))); } else { //announce every 15 seconds - if (newtime / (15 * IN_MILISECONDS) != m_PrematureCountDownTimer / (15 * IN_MILISECONDS)) - PSendMessageToAll(LANG_BATTLEGROUND_PREMATURE_FINISH_WARNING_SECS, CHAT_MSG_SYSTEM, NULL, (uint32)(m_PrematureCountDownTimer / IN_MILISECONDS)); + 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)); } m_PrematureCountDownTimer = newtime; } @@ -436,7 +436,7 @@ void BattleGround::Update(uint32 diff) AuraApplication * aurApp = iter->second; Aura * aura = aurApp->GetBase(); if (!aura->IsPermanent() - && aura->GetDuration() <= 30*IN_MILISECONDS + && aura->GetDuration() <= 30*IN_MILLISECONDS && aurApp->IsPositive() && (!(aura->GetSpellProto()->Attributes & SPELL_ATTR_UNAFFECTED_BY_INVULNERABILITY)) && (!aura->HasEffectType(SPELL_AURA_MOD_INVISIBILITY))) @@ -856,7 +856,7 @@ void BattleGround::EndBattleGround(uint32 winner) uint32 BattleGround::GetBonusHonorFromKill(uint32 kills) const { //variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill) - uint32 maxLevel = (GetMaxLevel()<80)?GetMaxLevel():80; + uint32 maxLevel = (GetMaxLevel() < 80) ? GetMaxLevel() : 80; return Trinity::Honor::hk_honor_at_level(maxLevel, kills); } @@ -1525,7 +1525,7 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f /* void BattleGround::SpawnBGCreature(uint32 type, uint32 respawntime) { - Map * map = MapManager::Instance().FindMap(GetMapId(),GetInstanceId()); + Map * map = sMapMgr.FindMap(GetMapId(),GetInstanceId()); if (!map) return false; @@ -1962,4 +1962,4 @@ void BattleGround::RewardXPAtKill(Player* plr, Player* victim) if (Pet* pet = plr->GetPet()) pet->GivePetXP(xp); } -}
\ No newline at end of file +} diff --git a/src/server/game/BattleGrounds/BattleGroundMgr.cpp b/src/server/game/BattleGrounds/BattleGroundMgr.cpp index 3bbe8c3cf31..2450cfe6e24 100644 --- a/src/server/game/BattleGrounds/BattleGroundMgr.cpp +++ b/src/server/game/BattleGrounds/BattleGroundMgr.cpp @@ -22,7 +22,7 @@ #include "ObjectMgr.h" #include "World.h" #include "WorldPacket.h" -#include "Policies/SingletonImp.h" + #include "ArenaTeam.h" #include "BattleGroundMgr.h" @@ -49,8 +49,6 @@ #include "SharedDefines.h" #include "Formulas.h" -INSTANTIATE_SINGLETON_1(BattleGroundMgr); - /*********************************************************/ /*** BATTLEGROUND QUEUE SYSTEM ***/ /*********************************************************/ @@ -1271,8 +1269,8 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro *data << uint32(bg->GetTypeID()); *data << uint16(0x1F90); // End of uint64 segment, decomposed this way for simplicity - *data << uint8(0); // 3.3.0 - *data << uint8(0); // 3.3.0 + *data << uint8(0); // 3.3.0, some level, only saw 80... + *data << uint8(0); // 3.3.0, some level, only saw 80... *data << uint32(bg->GetClientInstanceID()); // alliance/horde for BG and skirmish/rated for Arenas // following displays the minimap-icon 0 = faction icon 1 = arenaicon @@ -1287,10 +1285,12 @@ void BattleGroundMgr::BuildBattleGroundStatusPacket(WorldPacket *data, BattleGro break; case STATUS_WAIT_JOIN: // status_invite *data << uint32(bg->GetMapId()); // map id + *data << uint64(0); // 3.3.5, unknown *data << uint32(Time1); // time to remove from queue, milliseconds break; case STATUS_IN_PROGRESS: // status_in_progress *data << uint32(bg->GetMapId()); // map id + *data << uint64(0); // 3.3.5, unknown *data << uint32(Time1); // time to bg auto leave, 0 at bg start, 120000 after bg end, milliseconds *data << uint32(Time2); // time from bg start, milliseconds *data << uint8(/*bg->isArena() ? 0 :*/ 1); // unk, possibly 0 == preparation phase, 1 == battle @@ -1629,8 +1629,11 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI return 0; } + // set battelground difficulty before initialization + bg->SetBracket(bracketEntry); + // generate a new instance id - bg->SetInstanceID(MapManager::Instance().GenerateInstanceId()); // set instance id + bg->SetInstanceID(sMapMgr.GenerateInstanceId()); // set instance id bg->SetClientInstanceID(CreateClientVisibleInstanceId(isRandom ? BATTLEGROUND_RB : bgTypeId, bracketEntry->GetBracketId())); // reset the new bg (set status to status_wait_queue from status_none) @@ -1638,7 +1641,6 @@ BattleGround * BattleGroundMgr::CreateNewBattleGround(BattleGroundTypeId bgTypeI // start the joining of the bg bg->SetStatus(STATUS_WAIT_JOIN); - bg->SetBracket(bracketEntry); bg->SetArenaType(arenaType); bg->SetRated(isRated); bg->SetRandom(isRandom); @@ -1893,8 +1895,8 @@ void BattleGroundMgr::BuildBattleGroundListPacket(WorldPacket *data, const uint6 uint32 win_arena = plr->GetRandomWinner() ? BG_REWARD_WINNER_ARENA_LAST : BG_REWARD_WINNER_ARENA_FIRST; uint32 loos_kills = plr->GetRandomWinner() ? BG_REWARD_LOOSER_HONOR_LAST : BG_REWARD_LOOSER_HONOR_FIRST; - win_kills = (uint32)Trinity::Honor::hk_honor_at_level(plr->getLevel(), win_kills); - loos_kills = (uint32)Trinity::Honor::hk_honor_at_level(plr->getLevel(), loos_kills); + win_kills = Trinity::Honor::hk_honor_at_level(plr->getLevel(), win_kills); + loos_kills = Trinity::Honor::hk_honor_at_level(plr->getLevel(), loos_kills); data->Initialize(SMSG_BATTLEFIELD_LIST); *data << uint64(guid); // battlemaster guid diff --git a/src/server/game/BattleGrounds/BattleGroundMgr.h b/src/server/game/BattleGrounds/BattleGroundMgr.h index 569651a95b3..40dfc39b5e5 100644 --- a/src/server/game/BattleGrounds/BattleGroundMgr.h +++ b/src/server/game/BattleGrounds/BattleGroundMgr.h @@ -22,7 +22,7 @@ #define __BATTLEGROUNDMGR_H #include "Common.h" -#include "Policies/Singleton.h" +#include "ace/Singleton.h" #include "DBCEnums.h" #include "BattleGround.h" @@ -180,9 +180,12 @@ class BGQueueRemoveEvent : public BasicEvent class BattleGroundMgr { + /// Todo: Thread safety? + /* Construction */ + friend class ACE_Singleton<BattleGroundMgr, ACE_Null_Mutex>; + BattleGroundMgr(); + public: - /* Construction */ - BattleGroundMgr(); ~BattleGroundMgr(); void Update(uint32 diff); @@ -271,6 +274,6 @@ class BattleGroundMgr bool m_Testing; }; -#define sBattleGroundMgr Trinity::Singleton<BattleGroundMgr>::Instance() +#define sBattleGroundMgr (*ACE_Singleton<BattleGroundMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/BattleGrounds/Zones/BattleGroundAV.cpp b/src/server/game/BattleGrounds/Zones/BattleGroundAV.cpp index 7f5482cbf16..b477d6723fe 100644 --- a/src/server/game/BattleGrounds/Zones/BattleGroundAV.cpp +++ b/src/server/game/BattleGrounds/Zones/BattleGroundAV.cpp @@ -23,9 +23,9 @@ #include "BattleGround.h" #include "BattleGroundAV.h" -#include "Formulas.h" +#include "Miscellaneous/Formulas.h" #include "GameObject.h" -#include "Language.h" +#include "Miscellaneous/Language.h" #include "Player.h" #include "SpellAuras.h" diff --git a/src/server/game/BattleGrounds/Zones/BattleGroundEY.h b/src/server/game/BattleGrounds/Zones/BattleGroundEY.h index 4fe23c4c821..6b1ec6ced59 100644 --- a/src/server/game/BattleGrounds/Zones/BattleGroundEY.h +++ b/src/server/game/BattleGrounds/Zones/BattleGroundEY.h @@ -25,8 +25,8 @@ class BattleGround; -#define BG_EY_FLAG_RESPAWN_TIME (8*IN_MILISECONDS) //8 seconds -#define BG_EY_FPOINTS_TICK_TIME (2*IN_MILISECONDS) //2 seconds +#define BG_EY_FLAG_RESPAWN_TIME (8*IN_MILLISECONDS) //8 seconds +#define BG_EY_FPOINTS_TICK_TIME (2*IN_MILLISECONDS) //2 seconds enum BG_EY_WorldStates { diff --git a/src/server/game/BattleGrounds/Zones/BattleGroundSA.h b/src/server/game/BattleGrounds/Zones/BattleGroundSA.h index 760be3ca02e..f1299fbb4a4 100644 --- a/src/server/game/BattleGrounds/Zones/BattleGroundSA.h +++ b/src/server/game/BattleGrounds/Zones/BattleGroundSA.h @@ -197,7 +197,7 @@ const float BG_SA_ObjSpawnlocs[BG_SA_MAXOBJ][4] = { 1431.3413f, -219.437f, 30.893f, 0.9736f }, { 1227.667f, -212.555f, 55.372f, 0.5023f }, { 1214.681f, 81.21f, 53.413f, 5.745f }, - { 878.555f, -108.989f, 119.835f, 0.0565f }, + { 878.555f, -108.2f, 117.845f, 0.0f }, { 836.5f, -108.8f, 120.219f, 0.0f }, //Ships { 2679.696777, -826.891235, 3.712860, 5.78367f}, //rot2 1 rot3 0.0002 diff --git a/src/server/game/BattleGrounds/Zones/BattleGroundWS.cpp b/src/server/game/BattleGrounds/Zones/BattleGroundWS.cpp index 71872511274..2521e93ebcf 100644 --- a/src/server/game/BattleGrounds/Zones/BattleGroundWS.cpp +++ b/src/server/game/BattleGrounds/Zones/BattleGroundWS.cpp @@ -70,7 +70,7 @@ void BattleGroundWS::Update(uint32 diff) if (GetStatus() == STATUS_IN_PROGRESS) { - if (GetStartTime() >= 25*MINUTE*IN_MILISECONDS) // Òàéìåð òèêàòü íà÷èíàåò ïîñëå 25 ìèíóò + if (GetStartTime() >= 25*MINUTE*IN_MILLISECONDS) { if (GetTeamScore(ALLIANCE) == 0) { @@ -83,15 +83,15 @@ void BattleGroundWS::Update(uint32 diff) else if (GetTeamScore(HORDE) == 0) EndBattleGround(ALLIANCE); // Alliance has > 0, Horde has 0, alliance wins - else if (GetTeamScore(HORDE) == GetTeamScore(ALLIANCE)) // Team score equal, winner is team that scored the first flag - EndBattleGround(m_FirstFlagCaptureTeam); + else if (GetTeamScore(HORDE) == GetTeamScore(ALLIANCE)) // Team score equal, winner is team that scored the last flag + EndBattleGround(m_LastFlagCaptureTeam); else if (GetTeamScore(HORDE) > GetTeamScore(ALLIANCE)) // Last but not least, check who has the higher score EndBattleGround(HORDE); else EndBattleGround(ALLIANCE); } - else if (GetStartTime() > m_minutesElapsed*MINUTE*IN_MILISECONDS) + else if (GetStartTime() > m_minutesElapsed*MINUTE*IN_MILLISECONDS) { ++m_minutesElapsed; UpdateWorldState(BG_WS_STATE_TIMER, 25-m_minutesElapsed); @@ -325,8 +325,8 @@ void BattleGroundWS::EventPlayerCapturedFlag(Player *Source) // only flag capture should be updated UpdatePlayerScore(Source, SCORE_FLAG_CAPTURES, 1); // +1 flag captures - if (!m_FirstFlagCaptureTeam) - SetFirstFlagCapture(Source->GetTeam()); + // update last flag capture to be used if teamscore is equal + SetLastFlagCapture(Source->GetTeam()); if (GetTeamScore(ALLIANCE) == BG_WS_MAX_TEAM_SCORE) winner = ALLIANCE; @@ -720,7 +720,7 @@ void BattleGroundWS::Reset() m_HonorEndKills = (isBGWeekend) ? 4 : 2; // For WorldState m_minutesElapsed = 0; - m_FirstFlagCaptureTeam = 0; + m_LastFlagCaptureTeam = 0; /* Spirit nodes is static at this BG and then not required deleting at BG reset. if (m_BgCreatures[WS_SPIRIT_MAIN_ALLIANCE]) diff --git a/src/server/game/BattleGrounds/Zones/BattleGroundWS.h b/src/server/game/BattleGrounds/Zones/BattleGroundWS.h index 1a733c14570..ff3a3c893ff 100644 --- a/src/server/game/BattleGrounds/Zones/BattleGroundWS.h +++ b/src/server/game/BattleGrounds/Zones/BattleGroundWS.h @@ -191,7 +191,7 @@ class BattleGroundWS : public BattleGround virtual WorldSafeLocsEntry const* GetClosestGraveYard(Player* player); void UpdateFlagState(uint32 team, uint32 value); - void SetFirstFlagCapture(uint32 team) { m_FirstFlagCaptureTeam = team; } + void SetLastFlagCapture(uint32 team) { m_LastFlagCaptureTeam = team; } void UpdateTeamScore(uint32 team); void UpdatePlayerScore(Player *Source, uint32 type, uint32 value, bool doAddHonor = true); void SetDroppedFlagGUID(uint64 guid, uint32 TeamID) { m_DroppedFlagGUID[GetTeamIndexByTeamId(TeamID)] = guid;} @@ -209,7 +209,7 @@ class BattleGroundWS : public BattleGround uint8 m_FlagState[2]; // for checking flag state int32 m_FlagsTimer[2]; int32 m_FlagsDropTimer[2]; - uint32 m_FirstFlagCaptureTeam; // Winner is based on this if score is equal + uint32 m_LastFlagCaptureTeam; // Winner is based on this if score is equal uint32 m_ReputationCapture; uint32 m_HonorWinKills; diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index 44fe870baa4..d1a9fac4f16 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -1,373 +1,263 @@ +# Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/> +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +######## game ######## + # Enable precompiled headers when using the GCC compiler. -IF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX) - INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) -ENDIF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX) +if(DO_PCH) + include_directories(${CMAKE_CURRENT_BINARY_DIR}) +endif() -SET(game_STAT_SRCS - Account/AccountMgr.cpp - Account/AccountMgr.h - Achievements/AchievementMgr.h - Achievements/AchievementMgr.cpp - Addons/AddonMgr.cpp - Addons/AddonMgr.h - Addons/AddonHandler.cpp - Addons/AddonHandler.h - AI/AuctionHouseBot/AuctionHouseBot.cpp - AI/AuctionHouseBot/AuctionHouseBot.h - AI/EventAI/CreatureEventAI.cpp - AI/EventAI/CreatureEventAIMgr.cpp - AI/ScriptedAI/ScriptedSmartAI.cpp - AI/ScriptedAI/ScriptedSmartAI.h - AI/CombatAI.cpp - AI/CombatAI.h - AI/CreatureAI.cpp - AI/CreatureAI.h - AI/CreatureAIFactory.h - AI/CreatureAIImpl.h - AI/CreatureAIRegistry.cpp - AI/CreatureAIRegistry.h - AI/CreatureAISelector.cpp - AI/CreatureAISelector.h - AI/GuardAI.cpp - AI/GuardAI.h - AI/PassiveAI.cpp - AI/PassiveAI.h - AI/PetAI.cpp - AI/PetAI.h - AI/ReactorAI.cpp - AI/ReactorAI.h - AI/TotemAI.cpp - AI/TotemAI.h - AI/UnitAI.cpp - AI/UnitAI.h - AuctionHouse/AuctionHouseHandler.cpp - AuctionHouse/AuctionHouseMgr.cpp - AuctionHouse/AuctionHouseMgr.h - BattleGrounds/ArenaTeam.cpp - BattleGrounds/ArenaTeam.h - BattleGrounds/ArenaTeamHandler.cpp - BattleGrounds/BattleGround.cpp - BattleGrounds/BattleGroundAA.cpp - BattleGrounds/BattleGroundAB.cpp - BattleGrounds/BattleGroundRB.cpp - BattleGrounds/BattleGroundAV.cpp - BattleGrounds/BattleGroundBE.cpp - BattleGrounds/BattleGroundDS.cpp - BattleGrounds/BattleGroundEY.cpp - BattleGrounds/BattleGroundIC.cpp - BattleGrounds/BattleGroundNA.cpp - BattleGrounds/BattleGroundRL.cpp - BattleGrounds/BattleGroundRV.cpp - BattleGrounds/BattleGroundSA.cpp - BattleGrounds/BattleGroundWS.cpp - BattleGrounds/BattleGround.h - BattleGrounds/BattleGroundAA.h - BattleGrounds/BattleGroundAB.h - BattleGrounds/BattleGroundRB.h - BattleGrounds/BattleGroundAV.h - BattleGrounds/BattleGroundBE.h - BattleGrounds/BattleGroundDS.h - BattleGrounds/BattleGroundEY.h - BattleGrounds/BattleGroundIC.h - BattleGrounds/BattleGroundNA.h - BattleGrounds/BattleGroundRL.h - BattleGrounds/BattleGroundRV.h - BattleGrounds/BattleGroundSA.h - BattleGrounds/BattleGroundWS.h - BattleGrounds/BattleGroundHandler.cpp - BattleGrounds/BattleGroundMgr.cpp - BattleGrounds/BattleGroundMgr.h - Calendar/Calendar.cpp - Calendar/Calendar.h - Calendar/CalendarHandler.cpp - Chat/Channel.cpp - Chat/Channel.h - Chat/ChannelHandler.cpp - Chat/ChannelMgr.h - Chat/ChannelMgr.cpp - Chat/Chat.cpp - Chat/Chat.h - Chat/ChatHandler.cpp - Chat/Debugcmds.cpp - Chat/Level0.cpp - Chat/Level1.cpp - Chat/Level2.cpp - Chat/Level3.cpp - Combat/CombatHandler.cpp - Combat/HostileRefManager.cpp - Combat/HostileRefManager.h - Combat/ThreatManager.cpp - Combat/ThreatManager.h - ConditionMgr/ConditionMgr.cpp - ConditionMgr/ConditionMgr.h - DataStores/DBCEnums.h - DataStores/DBCStores.cpp - DataStores/DBCStores.h - DataStores/DBCStructure.h - DataStores/DBCfmt.h - Entities/Creature/Creature.cpp - Entities/Creature/Creature.h - Entities/Creature/CreatureGroups.cpp - Entities/Creature/CreatureGroups.h - Entities/Creature/GossipDef.cpp - Entities/Creature/GossipDef.h - Entities/Creature/NPCHandler.cpp - Entities/Creature/NPCHandler.h - Entities/Creature/TemporarySummon.cpp - Entities/Creature/TemporarySummon.h - Entities/GameObject/GameObject.cpp - Entities/GameObject/GameObject.h - Entities/Item/Bag.cpp - Entities/Item/Bag.h - Entities/Item/Item.cpp - Entities/Item/Item.h - Entities/Item/ItemEnchantmentMgr.cpp - Entities/Item/ItemEnchantmentMgr.h - Entities/Item/ItemHandler.cpp - Entities/Item/ItemPrototype.h - Entities/Object/Corpse.cpp - Entities/Object/Corpse.h - Entities/Object/DynamicObject.cpp - Entities/Object/DynamicObject.h - Entities/Object/ObjectAccessor.cpp - Entities/Object/ObjectAccessor.h - Entities/Object/Object.cpp - Entities/Object/ObjectDefines.h - Entities/Object/Object.h - Entities/Object/ObjectMgr.cpp - Entities/Object/ObjectMgr.h - Entities/Object/UpdateData.cpp - Entities/Object/UpdateData.h - Entities/Object/UpdateFields.h - Entities/Object/UpdateMask.h - Entities/Pet/Pet.cpp - Entities/Pet/Pet.h - Entities/Pet/PetHandler.cpp - Entities/Player/DuelHandler.cpp - Entities/Player/MiscHandler.cpp - Entities/Player/PetitionsHandler.cpp - Entities/Player/Player.cpp - Entities/Player/Player.h - Entities/Player/SocialMgr.cpp - Entities/Player/SocialMgr.h - Entities/Player/TicketHandler.cpp - Entities/Player/TradeHandler.cpp - Entities/Player/VoiceChatHandler.cpp - Entities/Player/CharacterHandler.cpp - Entities/Unit/StatSystem.cpp - Entities/Unit/Unit.cpp - Entities/Unit/Unit.h - Entities/Totem/Totem.cpp - Entities/Totem/Totem.h - Entities/Vehicle/Vehicle.cpp - Entities/Vehicle/Vehicle.h - Events/GameEventMgr.cpp - Events/GameEventMgr.h - Events/GlobalEvents.cpp - Events/GlobalEvents.h - Events/UnitEvents.h - Globals/Formulas.h - Globals/Language.h - Globals/SharedDefines.h - Groups/Group.cpp - Groups/Group.h - Groups/GroupHandler.cpp - Groups/GroupReference.cpp - Groups/GroupReference.h - Groups/GroupRefManager.h - Guilds/Guild.cpp - Guilds/Guild.h - Guilds/GuildHandler.cpp - Instances/InstanceData.cpp - Instances/InstanceData.h - Instances/InstanceSaveMgr.cpp - Instances/InstanceSaveMgr.h - LookingForGroup/LFG.h - LookingForGroup/LFGHandler.cpp - LookingForGroup/LFGMgr.cpp - LookingForGroup/LFGMgr.h - Loot/LootHandler.cpp - Loot/LootMgr.cpp - Loot/LootMgr.h - Mails/Mail.cpp - Mails/Mail.h - Map/Cell/Cell.h - Map/Cell/CellImpl.h - Map/Grid/GridDefines.h - Map/Grid/GridNotifiers.cpp - Map/Grid/GridNotifiers.h - Map/Grid/GridNotifiersImpl.h - Map/Grid/GridStates.cpp - Map/Grid/GridStates.h - Map/Grid/ObjectGridLoader.cpp - Map/Grid/ObjectGridLoader.h - Map/Map.cpp - Map/Map.h - Map/MapInstanced.cpp - Map/MapInstanced.h - Map/MapManager.cpp - Map/MapManager.h - Map/MapUpdater.cpp - Map/MapUpdater.h - Map/MapReference.h - Map/MapRefManager.h - Map/ObjectPosSelector.cpp - Map/ObjectPosSelector.h - Map/ZoneScript.h - Movement/MovementGenerators/ConfusedMovementGenerator.cpp - Movement/MovementGenerators/ConfusedMovementGenerator.h - Movement/MovementGenerators/FleeingMovementGenerator.cpp - Movement/MovementGenerators/FleeingMovementGenerator.h - Movement/MovementGenerators/HomeMovementGenerator.cpp - Movement/MovementGenerators/HomeMovementGenerator.h - Movement/MovementGenerators/IdleMovementGenerator.cpp - Movement/MovementGenerators/IdleMovementGenerator.h - Movement/MovementGenerators/MovementGenerator.cpp - Movement/MovementGenerators/MovementGenerator.h - Movement/MovementGenerators/MovementGeneratorImpl.h - Movement/MovementGenerators/PointMovementGenerator.cpp - Movement/MovementGenerators/PointMovementGenerator.h - Movement/MovementGenerators/RandomMovementGenerator.cpp - Movement/MovementGenerators/RandomMovementGenerator.h - Movement/MovementGenerators/TargetedMovementGenerator.cpp - Movement/MovementGenerators/TargetedMovementGenerator.h - Movement/MovementGenerators/WaypointMovementGenerator.cpp - Movement/MovementGenerators/WaypointMovementGenerator.h - Movement/DestinationHolder.cpp - Movement/DestinationHolder.h - Movement/DestinationHolderImp.h - Movement/FollowerReference.cpp - Movement/FollowerReference.h - Movement/FollowerRefManager.h - Movement/MotionMaster.cpp - Movement/MotionMaster.h - Movement/MovementHandler.cpp - Movement/Path.h - Movement/TaxiHandler.cpp - Movement/Transports.cpp - Movement/Transports.h - Movement/Traveller.h - Movement/WaypointManager.cpp - Movement/WaypointManager.h - Opcodes/Opcodes.cpp - Opcodes/Opcodes.h - OutdoorPvP/OutdoorPvP.cpp - OutdoorPvP/OutdoorPvP.h - OutdoorPvP/OutdoorPvPEP.cpp - OutdoorPvP/OutdoorPvPEP.h - OutdoorPvP/OutdoorPvPHP.cpp - OutdoorPvP/OutdoorPvPHP.h - OutdoorPvP/OutdoorPvPImpl.h - OutdoorPvP/OutdoorPvPMgr.cpp - OutdoorPvP/OutdoorPvPMgr.h - OutdoorPvP/OutdoorPvPNA.cpp - OutdoorPvP/OutdoorPvPNA.h - OutdoorPvP/OutdoorPvPSI.cpp - OutdoorPvP/OutdoorPvPSI.h - OutdoorPvP/OutdoorPvPTF.cpp - OutdoorPvP/OutdoorPvPTF.h - OutdoorPvP/OutdoorPvPZM.cpp - OutdoorPvP/OutdoorPvPZM.h - Pools/PoolHandler.cpp - Pools/PoolHandler.h - Quests/QueryHandler.cpp - Quests/QuestDef.cpp - Quests/QuestDef.h - Quests/QuestHandler.cpp - Reputation/ReputationMgr.cpp - Reputation/ReputationMgr.h - ScriptMgr/ScriptLoader.cpp - ScriptMgr/ScriptLoader.h - ScriptMgr/ScriptMgr.cpp - ScriptMgr/ScriptMgr.h - ScriptMgr/ScriptSystem.cpp - ScriptMgr/ScriptSystem.h - Skills/SkillHandler.cpp - Skills/SkillDiscovery.cpp - Skills/SkillDiscovery.h - Skills/SkillExtraItems.cpp - Skills/SkillExtraItems.h - Spells/Auras/SpellAuraDefines.h - Spells/Auras/SpellAuras.cpp - Spells/Auras/SpellAuras.h - Spells/Auras/SpellAuraEffects.cpp - Spells/Auras/SpellAuraEffects.h - Spells/Auras/SpellEffects.cpp - Spells/Spell.cpp - Spells/Spell.h - Spells/SpellHandler.cpp - Spells/SpellMgr.cpp - Spells/SpellMgr.h - Tools/PlayerDump.cpp - Tools/PlayerDump.h - Tools/Tools.cpp - Tools/Tools.h - Weather/Weather.cpp - Weather/Weather.h - World/World.cpp - World/World.h - World/WorldLog.cpp - World/WorldLog.h - World/WorldSession.cpp - World/WorldSession.h - World/WorldSocket.cpp - World/WorldSocket.h - World/WorldSocketMgr.cpp - World/WorldSocketMgr.h +# Create game-libary +set(game_STAT_SRCS + Accounts/AccountMgr.cpp + Achievements/AchievementMgr.cpp + Addons/AddonMgr.cpp + AI/CoreAI/CombatAI.cpp + AI/CoreAI/GuardAI.cpp + AI/CoreAI/PassiveAI.cpp + AI/CoreAI/PetAI.cpp + AI/CoreAI/ReactorAI.cpp + AI/CoreAI/TotemAI.cpp + AI/CoreAI/UnitAI.cpp + AI/EventAI/CreatureEventAI.cpp + AI/EventAI/CreatureEventAIMgr.cpp + AI/ScriptedAI/ScriptedSmartAI.cpp + AI/CreatureAIRegistry.cpp + AI/CreatureAISelector.cpp + AI/CreatureAI.cpp + AuctionHouse/AuctionHouseMgr.cpp + AuctionHouse/AuctionHouseBot/AuctionHouseBot.cpp + BattleGrounds/ArenaTeam.cpp + BattleGrounds/Zones/BattleGroundAA.cpp + BattleGrounds/Zones/BattleGroundAB.cpp + BattleGrounds/Zones/BattleGroundRB.cpp + BattleGrounds/Zones/BattleGroundAV.cpp + BattleGrounds/Zones/BattleGroundBE.cpp + BattleGrounds/Zones/BattleGroundDS.cpp + BattleGrounds/Zones/BattleGroundEY.cpp + BattleGrounds/Zones/BattleGroundIC.cpp + BattleGrounds/Zones/BattleGroundNA.cpp + BattleGrounds/Zones/BattleGroundRL.cpp + BattleGrounds/Zones/BattleGroundRV.cpp + BattleGrounds/Zones/BattleGroundSA.cpp + BattleGrounds/Zones/BattleGroundWS.cpp + BattleGrounds/BattleGround.cpp + BattleGrounds/BattleGroundMgr.cpp + Calendar/Calendar.cpp + Chat/Channels/Channel.cpp + Chat/Channels/ChannelMgr.cpp + Chat/Commands/Debugcmds.cpp + Chat/Commands/Level0.cpp + Chat/Commands/Level1.cpp + Chat/Commands/Level2.cpp + Chat/Commands/Level3.cpp + Chat/Chat.cpp + Combat/HostileRefManager.cpp + Combat/ThreatManager.cpp + Conditions/ConditionMgr.cpp + DataStores/DBCStores.cpp + DungeonFinding/LFGMgr.cpp + Entities/Corpse/Corpse.cpp + Entities/Creature/Creature.cpp + Entities/Creature/CreatureGroups.cpp + Entities/Creature/GossipDef.cpp + Entities/Creature/TemporarySummon.cpp + Entities/DynamicObject/DynamicObject.cpp + Entities/GameObject/GameObject.cpp + Entities/Item/Container/Bag.cpp + Entities/Item/Item.cpp + Entities/Item/ItemEnchantmentMgr.cpp + Entities/Object/Updates/UpdateData.cpp + Entities/Object/Object.cpp + Entities/Object/ObjectPosSelector.cpp + Entities/Pet/Pet.cpp + Entities/Player/Player.cpp + Entities/Player/SocialMgr.cpp + Entities/Unit/StatSystem.cpp + Entities/Unit/Unit.cpp + Entities/Totem/Totem.cpp + Entities/Transport/Transport.cpp + Entities/Vehicle/Vehicle.cpp + Events/GameEventMgr.cpp + Globals/GlobalEvents.cpp + Globals/ObjectAccessor.cpp + Globals/ObjectMgr.cpp + Grids/Notifiers/GridNotifiers.cpp + Grids/GridStates.cpp + Grids/ObjectGridLoader.cpp + Groups/Group.cpp + Groups/GroupReference.cpp + Guilds/Guild.cpp + Instances/InstanceData.cpp + Instances/InstanceSaveMgr.cpp + Loot/LootMgr.cpp + Mails/Mail.cpp + Maps/Map.cpp + Maps/MapInstanced.cpp + Maps/MapManager.cpp + Maps/MapUpdater.cpp + Movement/MovementGenerators/ConfusedMovementGenerator.cpp + Movement/MovementGenerators/FleeingMovementGenerator.cpp + Movement/MovementGenerators/HomeMovementGenerator.cpp + Movement/MovementGenerators/IdleMovementGenerator.cpp + Movement/MovementGenerators/PointMovementGenerator.cpp + Movement/MovementGenerators/RandomMovementGenerator.cpp + Movement/MovementGenerators/TargetedMovementGenerator.cpp + Movement/MovementGenerators/WaypointMovementGenerator.cpp + Movement/Waypoints/WaypointManager.cpp + Movement/DestinationHolder.cpp + Movement/FollowerReference.cpp + Movement/MotionMaster.cpp + Movement/MovementGenerator.cpp + OutdoorPvP/Zones/OutdoorPvPEP.cpp + OutdoorPvP/Zones/OutdoorPvPHP.cpp + OutdoorPvP/Zones/OutdoorPvPNA.cpp + OutdoorPvP/Zones/OutdoorPvPSI.cpp + OutdoorPvP/Zones/OutdoorPvPTF.cpp + OutdoorPvP/Zones/OutdoorPvPZM.cpp + OutdoorPvP/OutdoorPvP.cpp + OutdoorPvP/OutdoorPvPMgr.cpp + Pools/PoolMgr.cpp + Quests/QuestDef.cpp + Reputation/ReputationMgr.cpp + Scripting/ScriptLoader.cpp + Scripting/ScriptMgr.cpp + Scripting/ScriptSystem.cpp + Server/Protocol/Handlers/AddonHandler.cpp + Server/Protocol/Handlers/ArenaTeamHandler.cpp + Server/Protocol/Handlers/AuctionHouseHandler.cpp + Server/Protocol/Handlers/BattleGroundHandler.cpp + Server/Protocol/Handlers/CalendarHandler.cpp + Server/Protocol/Handlers/ChannelHandler.cpp + Server/Protocol/Handlers/CharacterHandler.cpp + Server/Protocol/Handlers/ChatHandler.cpp + Server/Protocol/Handlers/CombatHandler.cpp + Server/Protocol/Handlers/DuelHandler.cpp + Server/Protocol/Handlers/GroupHandler.cpp + Server/Protocol/Handlers/GuildHandler.cpp + Server/Protocol/Handlers/ItemHandler.cpp + Server/Protocol/Handlers/LFGHandler.cpp + Server/Protocol/Handlers/LootHandler.cpp + Server/Protocol/Handlers/MiscHandler.cpp + Server/Protocol/Handlers/MovementHandler.cpp + Server/Protocol/Handlers/NPCHandler.cpp + Server/Protocol/Handlers/PetHandler.cpp + Server/Protocol/Handlers/PetitionsHandler.cpp + Server/Protocol/Handlers/QueryHandler.cpp + Server/Protocol/Handlers/QuestHandler.cpp + Server/Protocol/Handlers/SkillHandler.cpp + Server/Protocol/Handlers/SpellHandler.cpp + Server/Protocol/Handlers/TaxiHandler.cpp + Server/Protocol/Handlers/TicketHandler.cpp + Server/Protocol/Handlers/TradeHandler.cpp + Server/Protocol/Handlers/VoiceChatHandler.cpp + Server/Protocol/Opcodes.cpp + Server/Protocol/WorldLog.cpp + Server/WorldSession.cpp + Server/WorldSocket.cpp + Server/WorldSocketMgr.cpp + Skills/SkillDiscovery.cpp + Skills/SkillExtraItems.cpp + Spells/Auras/SpellAuras.cpp + Spells/Auras/SpellAuraEffects.cpp + Spells/Auras/SpellEffects.cpp + Spells/Spell.cpp + Spells/SpellMgr.cpp + Tools/PlayerDump.cpp + Tools/Tools.cpp + Weather/Weather.cpp + World/World.cpp ) include_directories( - ${ACE_INCLUDE_DIR} ${CMAKE_BINARY_DIR} - ${CMAKE_SOURCE_DIR}/dep/include - ${CMAKE_SOURCE_DIR}/src/server/framework + ${CMAKE_SOURCE_DIR}/externals/mersennetwister + ${CMAKE_SOURCE_DIR}/externals/zlib + ${CMAKE_SOURCE_DIR}/src/server/collision + ${CMAKE_SOURCE_DIR}/src/server/collision/Management ${CMAKE_SOURCE_DIR}/src/server/shared - ${CMAKE_SOURCE_DIR}/src/server/shared/vmap + ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration + ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography + ${CMAKE_SOURCE_DIR}/src/server/shared/Cryptography/Authentication ${CMAKE_SOURCE_DIR}/src/server/shared/Database + ${CMAKE_SOURCE_DIR}/src/server/shared/DataStores + ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/CountedReference + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic/LinkedReference + ${CMAKE_SOURCE_DIR}/src/server/shared/Dynamic + ${CMAKE_SOURCE_DIR}/src/server/shared/Logging + ${CMAKE_SOURCE_DIR}/src/server/shared/Packets + ${CMAKE_SOURCE_DIR}/src/server/shared/Policies + ${CMAKE_SOURCE_DIR}/src/server/shared/Threading + ${CMAKE_SOURCE_DIR}/src/server/shared/Utilities ${CMAKE_SOURCE_DIR}/src/server/game - ${CMAKE_SOURCE_DIR}/src/server/game/Account + ${CMAKE_SOURCE_DIR}/src/server/game/Accounts ${CMAKE_SOURCE_DIR}/src/server/game/Achievements ${CMAKE_SOURCE_DIR}/src/server/game/Addons ${CMAKE_SOURCE_DIR}/src/server/game/AI - ${CMAKE_SOURCE_DIR}/src/server/game/AI/AuctionHouseBot + ${CMAKE_SOURCE_DIR}/src/server/game/AI/CoreAI ${CMAKE_SOURCE_DIR}/src/server/game/AI/EventAI ${CMAKE_SOURCE_DIR}/src/server/game/AI/ScriptedAI ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse + ${CMAKE_SOURCE_DIR}/src/server/game/AuctionHouse/AuctionHouseBot ${CMAKE_SOURCE_DIR}/src/server/game/BattleGrounds + ${CMAKE_SOURCE_DIR}/src/server/game/BattleGrounds/Zones ${CMAKE_SOURCE_DIR}/src/server/game/Calendar ${CMAKE_SOURCE_DIR}/src/server/game/Chat + ${CMAKE_SOURCE_DIR}/src/server/game/Chat/Channels + ${CMAKE_SOURCE_DIR}/src/server/game/Chat/Commands ${CMAKE_SOURCE_DIR}/src/server/game/Combat - ${CMAKE_SOURCE_DIR}/src/server/game/ConditionMgr + ${CMAKE_SOURCE_DIR}/src/server/game/Conditions ${CMAKE_SOURCE_DIR}/src/server/game/DataStores + ${CMAKE_SOURCE_DIR}/src/server/game/DungeonFinding ${CMAKE_SOURCE_DIR}/src/server/game/Entities ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Creature + ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Corpse + ${CMAKE_SOURCE_DIR}/src/server/game/Entities/DynamicObject ${CMAKE_SOURCE_DIR}/src/server/game/Entities/GameObject ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item + ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Item/Container ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object + ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Object/Updates ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Pet ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Player ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Totem ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Unit ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Vehicle + ${CMAKE_SOURCE_DIR}/src/server/game/Entities/Transport ${CMAKE_SOURCE_DIR}/src/server/game/Events ${CMAKE_SOURCE_DIR}/src/server/game/Globals + ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Cells + ${CMAKE_SOURCE_DIR}/src/server/game/Grids/Notifiers + ${CMAKE_SOURCE_DIR}/src/server/game/Grids ${CMAKE_SOURCE_DIR}/src/server/game/Groups ${CMAKE_SOURCE_DIR}/src/server/game/Guilds ${CMAKE_SOURCE_DIR}/src/server/game/Instances - ${CMAKE_SOURCE_DIR}/src/server/game/LookingForGroup ${CMAKE_SOURCE_DIR}/src/server/game/Loot ${CMAKE_SOURCE_DIR}/src/server/game/Mails - ${CMAKE_SOURCE_DIR}/src/server/game/Map - ${CMAKE_SOURCE_DIR}/src/server/game/Map/Cell - ${CMAKE_SOURCE_DIR}/src/server/game/Map/Grid + ${CMAKE_SOURCE_DIR}/src/server/game/Maps + ${CMAKE_SOURCE_DIR}/src/server/game/Miscellaneous ${CMAKE_SOURCE_DIR}/src/server/game/Movement ${CMAKE_SOURCE_DIR}/src/server/game/Movement/MovementGenerators - ${CMAKE_SOURCE_DIR}/src/server/game/Opcodes + ${CMAKE_SOURCE_DIR}/src/server/game/Movement/Waypoints ${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP + ${CMAKE_SOURCE_DIR}/src/server/game/OutdoorPvP/Zones ${CMAKE_SOURCE_DIR}/src/server/game/Pools + ${CMAKE_SOURCE_DIR}/src/server/game/PrecompiledHeaders ${CMAKE_SOURCE_DIR}/src/server/game/Quests ${CMAKE_SOURCE_DIR}/src/server/game/Reputation - ${CMAKE_SOURCE_DIR}/src/server/game/ScriptMgr + ${CMAKE_SOURCE_DIR}/src/server/game/Scripting + ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol + ${CMAKE_SOURCE_DIR}/src/server/game/Server/Protocol/Handlers + ${CMAKE_SOURCE_DIR}/src/server/game/Server ${CMAKE_SOURCE_DIR}/src/server/game/Skills ${CMAKE_SOURCE_DIR}/src/server/game/Spells ${CMAKE_SOURCE_DIR}/src/server/game/Spells/Auras @@ -375,33 +265,37 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/server/game/Weather ${CMAKE_SOURCE_DIR}/src/server/game/World ${MYSQL_INCLUDE_DIR} + ${ACE_INCLUDE_DIR} ) if(NOT DO_SCRIPTS) - SET(game_STAT_SRCS ${game_STAT_SRCS} - AI/ScriptedAI/ScriptedEscortAI.cpp - AI/ScriptedAI/ScriptedEscortAI.h - ScriptMgr/ScriptedPch.cpp - ScriptMgr/ScriptedPch.h - AI/ScriptedAI/ScriptedCreature.cpp - AI/ScriptedAI/ScriptedCreature.h - AI/ScriptedAI/ScriptedFollowerAI.cpp - AI/ScriptedAI/ScriptedFollowerAI.h - AI/ScriptedAI/ScriptedGossip.h - AI/ScriptedAI/ScriptedGuardAI.cpp - AI/ScriptedAI/ScriptedGuardAI.h - AI/ScriptedAI/ScriptedInstance.h - AI/ScriptedAI/ScriptedSimpleAI.cpp - AI/ScriptedAI/ScriptedSimpleAI.h - ) - message("-- Added Script Engine to GAME lib") -endif(NOT DO_SCRIPTS) + set(game_STAT_SRCS + ${game_STAT_SRCS} + AI/ScriptedAI/ScriptedEscortAI.cpp + AI/ScriptedAI/ScriptedCreature.cpp + AI/ScriptedAI/ScriptedFollowerAI.cpp + AI/ScriptedAI/ScriptedGuardAI.cpp + AI/ScriptedAI/ScriptedSimpleAI.cpp + ) + message("-- Added basic scriptAI-engines to GAME library") +endif() + +# Add gamePCH.cpp to project on Windows +if(MSVC) + set(game_STAT_SRCS + PrecompiledHeaders/gamePCH.cpp + ${game_STAT_SRCS}) +endif() add_library(game STATIC ${game_STAT_SRCS}) -ADD_DEPENDENCIES(game revision.h) -# Generate precompiled header -IF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX) - ADD_PRECOMPILED_HEADER(game ${CMAKE_SOURCE_DIR}/src/server/game/PrecompiledHeaders/pchlinux.h) -ENDIF(DO_PCH AND CMAKE_COMPILER_IS_GNUCXX) +add_dependencies(game revision.h) +# Generate precompiled header +if(DO_PCH) + if(CMAKE_COMPILER_IS_GNUCXX) + add_precompiled_header(game ${CMAKE_SOURCE_DIR}/src/server/game/PrecompiledHeaders/gamePCH.h) + elseif(MSVC) + add_native_precompiled_header(game ${CMAKE_SOURCE_DIR}/src/server/game/PrecompiledHeaders/gamePCH) + endif() +endif() diff --git a/src/server/game/Chat/Channels/Channel.cpp b/src/server/game/Chat/Channels/Channel.cpp index 0047892972b..bb70e54354c 100644 --- a/src/server/game/Chat/Channels/Channel.cpp +++ b/src/server/game/Chat/Channels/Channel.cpp @@ -707,6 +707,14 @@ void Channel::Invite(uint64 p, const char *newname) return; } + if (IsBanned(newp->GetGUID())) + { + WorldPacket data; + MakePlayerInviteBanned(&data, newname); + SendToOne(&data, p); + return; + } + Player *plr = objmgr.GetPlayer(p); if (!plr) return; @@ -983,10 +991,10 @@ void Channel::MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good) } // done 0x16 -void Channel::MakePlayerNotBanned(WorldPacket *data, uint64 guid) +void Channel::MakePlayerNotBanned(WorldPacket *data, const std::string &name) { MakeNotifyPacket(data, CHAT_PLAYER_NOT_BANNED_NOTICE); - *data << uint64(guid); + *data << name; } // done 0x17 @@ -1035,10 +1043,10 @@ void Channel::MakePlayerInvited(WorldPacket *data, const std::string& name) } // done 0x1E -void Channel::MakePlayerInviteBanned(WorldPacket *data, uint64 guid) +void Channel::MakePlayerInviteBanned(WorldPacket *data, const std::string& name) { MakeNotifyPacket(data, CHAT_PLAYER_INVITE_BANNED_NOTICE); - *data << uint64(guid); + *data << name; } // done 0x1F diff --git a/src/server/game/Chat/Channels/Channel.h b/src/server/game/Chat/Channels/Channel.h index d0b5923e30e..a52a697cba1 100644 --- a/src/server/game/Chat/Channels/Channel.h +++ b/src/server/game/Chat/Channels/Channel.h @@ -187,7 +187,7 @@ class Channel void MakeBanned(WorldPacket *data); //? 0x13 void MakePlayerBanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x14 void MakePlayerUnbanned(WorldPacket *data, uint64 bad, uint64 good); //? 0x15 - void MakePlayerNotBanned(WorldPacket *data, uint64 guid); //? 0x16 + void MakePlayerNotBanned(WorldPacket *data, const std::string& name); //? 0x16 void MakePlayerAlreadyMember(WorldPacket *data, uint64 guid); //+ 0x17 void MakeInvite(WorldPacket *data, uint64 guid); //? 0x18 void MakeInviteWrongFaction(WorldPacket *data); //? 0x19 @@ -195,7 +195,7 @@ class Channel void MakeInvalidName(WorldPacket *data); //? 0x1B void MakeNotModerated(WorldPacket *data); //? 0x1C void MakePlayerInvited(WorldPacket *data, const std::string& name); //+ 0x1D - void MakePlayerInviteBanned(WorldPacket *data, uint64 guid); //? 0x1E + void MakePlayerInviteBanned(WorldPacket *data, const std::string &name);//? 0x1E void MakeThrottled(WorldPacket *data); //? 0x1F void MakeNotInArea(WorldPacket *data); //? 0x20 void MakeNotInLfg(WorldPacket *data); //? 0x21 diff --git a/src/server/game/Chat/Channels/ChannelMgr.cpp b/src/server/game/Chat/Channels/ChannelMgr.cpp index f31d3ffde50..b72a2698d3a 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.cpp +++ b/src/server/game/Chat/Channels/ChannelMgr.cpp @@ -17,21 +17,18 @@ */ #include "ChannelMgr.h" -#include "Policies/SingletonImp.h" -#include "World.h" -INSTANTIATE_SINGLETON_1(AllianceChannelMgr); -INSTANTIATE_SINGLETON_1(HordeChannelMgr); +#include "World.h" ChannelMgr* channelMgr(uint32 team) { if (sWorld.getConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_CHANNEL)) - return &Trinity::Singleton<AllianceChannelMgr>::Instance(); // cross-faction + return ACE_Singleton<AllianceChannelMgr, ACE_Null_Mutex>::instance(); // cross-faction if (team == ALLIANCE) - return &Trinity::Singleton<AllianceChannelMgr>::Instance(); + return ACE_Singleton<AllianceChannelMgr, ACE_Null_Mutex>::instance(); if (team == HORDE) - return &Trinity::Singleton<HordeChannelMgr>::Instance(); + return ACE_Singleton<HordeChannelMgr, ACE_Null_Mutex>::instance(); return NULL; } diff --git a/src/server/game/Chat/Channels/ChannelMgr.h b/src/server/game/Chat/Channels/ChannelMgr.h index 6f3b7c415ae..c4e872de6b6 100644 --- a/src/server/game/Chat/Channels/ChannelMgr.h +++ b/src/server/game/Chat/Channels/ChannelMgr.h @@ -22,14 +22,11 @@ #include "Common.h" #include "Channel.h" -#include "Policies/Singleton.h" +#include "ace/Singleton.h" #include <map> #include <string> -#include "Policies/Singleton.h" - -#include "Channel.h" #include "World.h" class ChannelMgr diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 6e1adffa625..f62dee975da 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -23,7 +23,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "AccountMgr.h" #include "CellImpl.h" @@ -133,11 +133,13 @@ ChatCommand * ChatHandler::getCommandTable() static ChatCommand channelSetCommandTable[] = { { "public", SEC_ADMINISTRATOR, true, &ChatHandler::HandleChannelSetPublic, "", NULL }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand channelCommandTable[] = { { "set", SEC_ADMINISTRATOR, true, NULL, "", channelSetCommandTable }, + { NULL, 0, false, NULL, "", NULL } }; static ChatCommand debugPlayCommandTable[] = @@ -460,6 +462,7 @@ ChatCommand * ChatHandler::getCommandTable() { "creature_involvedrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestInvRelationsCommand,"",NULL }, { "creature_linked_respawn", SEC_GAMEMASTER, true, &ChatHandler::HandleReloadCreatureLinkedRespawnCommand, "", NULL }, { "creature_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesCreatureCommand, "", NULL }, + { "creature_onkill_reputation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadOnKillReputationCommand, "", NULL }, { "creature_questrelation", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureQuestRelationsCommand, "", NULL }, { "creature_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadCreatureTemplateCommand, "", NULL }, //{ "db_script_string", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadDbScriptStringCommand, "", NULL }, @@ -476,10 +479,12 @@ ChatCommand * ChatHandler::getCommandTable() { "gossip_menu_option", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadGossipMenuOptionCommand, "", NULL }, { "item_enchantment_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemEnchantementsCommand, "", NULL }, { "item_loot_template", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLootTemplatesItemCommand, "", NULL }, + { "item_set_names", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadItemSetNamesCommand, "", NULL }, { "locales_achievement_reward", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesAchievementRewardCommand,"", NULL }, { "locales_creature", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesCreatureCommand, "", NULL }, { "locales_gameobject", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesGameobjectCommand, "", NULL }, { "locales_item", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemCommand, "", NULL }, + { "locales_item_set_name", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesItemSetNameCommand, "", NULL }, { "locales_npc_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesNpcTextCommand, "", NULL }, { "locales_page_text", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPageTextCommand, "", NULL }, { "locales_points_of_interest", SEC_ADMINISTRATOR, true, &ChatHandler::HandleReloadLocalesPointsOfInterestCommand, "", NULL }, diff --git a/src/server/game/Chat/Chat.h b/src/server/game/Chat/Chat.h index 58e6f6214c8..6b102129c8a 100644 --- a/src/server/game/Chat/Chat.h +++ b/src/server/game/Chat/Chat.h @@ -364,6 +364,7 @@ class ChatHandler bool HandleReloadEventAISummonsCommand(const char* args); bool HandleReloadEventAIScriptsCommand(const char* args); bool HandleReloadCommandCommand(const char* args); + bool HandleReloadOnKillReputationCommand(const char* args); bool HandleReloadCreatureTemplateCommand(const char* args); bool HandleReloadCreatureQuestRelationsCommand(const char* args); bool HandleReloadCreatureQuestInvRelationsCommand(const char* args); @@ -377,10 +378,12 @@ class ChatHandler bool HandleReloadGOQuestRelationsCommand(const char* args); bool HandleReloadGOQuestInvRelationsCommand(const char* args); bool HandleReloadItemEnchantementsCommand(const char* args); + bool HandleReloadItemSetNamesCommand(const char* args); bool HandleReloadLocalesAchievementRewardCommand(const char* args); bool HandleReloadLocalesCreatureCommand(const char* args); bool HandleReloadLocalesGameobjectCommand(const char* args); bool HandleReloadLocalesItemCommand(const char* args); + bool HandleReloadLocalesItemSetNameCommand(const char* args); bool HandleReloadLocalesNpcTextCommand(const char* args); bool HandleReloadLocalesPageTextCommand(const char* args); bool HandleReloadLocalesPointsOfInterestCommand(const char* args); diff --git a/src/server/game/Chat/Commands/Debugcmds.cpp b/src/server/game/Chat/Commands/Debugcmds.cpp index ee8c623c3d0..a6c973ea002 100644 --- a/src/server/game/Chat/Commands/Debugcmds.cpp +++ b/src/server/game/Chat/Commands/Debugcmds.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "Vehicle.h" #include "Player.h" diff --git a/src/server/game/Chat/Commands/Level0.cpp b/src/server/game/Chat/Commands/Level0.cpp index ed021ac00d4..ff266caa328 100644 --- a/src/server/game/Chat/Commands/Level0.cpp +++ b/src/server/game/Chat/Commands/Level0.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "World.h" #include "Player.h" #include "Opcodes.h" @@ -87,7 +87,7 @@ bool ChatHandler::HandleStartCommand(const char* /*args*/) } // cast spell Stuck - chr->CastSpell(chr,7355,false); + chr->CastSpell(chr, 7355, false); return true; } @@ -103,14 +103,6 @@ bool ChatHandler::HandleServerInfoCommand(const char* /*args*/) uint32 updateTime = sWorld.GetUpdateTime(); PSendSysMessage(_FULLVERSION); - //if (m_session) - // full = _FULLVERSION(REVISION_DATE,REVISION_TIME,"|cffffffff|Hurl:" REVISION_ID "|h" REVISION_ID "|h|r"); - //else - // full = _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_ID); - - //SendSysMessage(full); - //PSendSysMessage(LANG_USING_WORLD_DB,sWorld.GetDBVersion()); - //PSendSysMessage(LANG_USING_EVENT_AI,sWorld.GetCreatureEventAIVersion()); PSendSysMessage(LANG_CONNECTED_PLAYERS, PlayersNum, MaxPlayersNum); PSendSysMessage(LANG_CONNECTED_USERS, activeClientsNum, maxActiveClientsNum, queuedClientsNum, maxQueuedClientsNum); PSendSysMessage(LANG_UPTIME, uptime.c_str()); @@ -143,9 +135,9 @@ bool ChatHandler::HandleDismountCommand(const char* /*args*/) bool ChatHandler::HandleSaveCommand(const char* /*args*/) { - Player *player=m_session->GetPlayer(); + Player *player = m_session->GetPlayer(); - // save GM account without delay and output message (testing, etc) + // save GM account without delay and output message if (m_session->GetSecurity() > SEC_PLAYER) { player->SaveToDB(); @@ -153,9 +145,9 @@ bool ChatHandler::HandleSaveCommand(const char* /*args*/) return true; } - // save or plan save after 20 sec (logout delay) if current next save time more this value and _not_ output any messages to prevent cheat planning + // save if the player has last been saved over 20 seconds ago uint32 save_interval = sWorld.getConfig(CONFIG_INTERVAL_SAVE); - if ((save_interval == 0 || save_interval > 20*IN_MILISECONDS && player->GetSaveTimer() <= save_interval - 20*IN_MILISECONDS)) + if ((save_interval == 0 || save_interval > 20*IN_MILLISECONDS && player->GetSaveTimer() <= save_interval - 20*IN_MILLISECONDS)) player->SaveToDB(); return true; @@ -165,8 +157,8 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/) { bool first = true; - ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock()); - HashMapHolder<Player>::MapType &m = ObjectAccessor::Instance().GetPlayers(); + ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, *HashMapHolder<Player>::GetLock(), true); + HashMapHolder<Player>::MapType &m = sObjectAccessor.GetPlayers(); for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { AccountTypes itr_sec = itr->second->GetSession()->GetSecurity(); @@ -192,35 +184,42 @@ bool ChatHandler::HandleGMListIngameCommand(const char* /*args*/) bool ChatHandler::HandleAccountPasswordCommand(const char* args) { if (!*args) + { + SendSysMessage(LANG_CMD_SYNTAX); + SetSentErrorMessage(true); return false; + } - char *old_pass = strtok ((char*)args, " "); - char *new_pass = strtok (NULL, " "); - char *new_pass_c = strtok (NULL, " "); + char *old_pass = strtok((char*)args, " "); + char *new_pass = strtok(NULL, " "); + char *new_pass_c = strtok(NULL, " "); if (!old_pass || !new_pass || !new_pass_c) + { + SendSysMessage(LANG_CMD_SYNTAX); + SetSentErrorMessage(true); return false; + } std::string password_old = old_pass; std::string password_new = new_pass; std::string password_new_c = new_pass_c; - if (strcmp(new_pass, new_pass_c) != 0) + if (!accmgr.CheckPassword(m_session->GetAccountId(), password_old)) { - SendSysMessage (LANG_NEW_PASSWORDS_NOT_MATCH); - SetSentErrorMessage (true); + SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD); + SetSentErrorMessage(true); return false; } - if (!accmgr.CheckPassword (m_session->GetAccountId(), password_old)) + if (strcmp(new_pass, new_pass_c) != 0) { - SendSysMessage (LANG_COMMAND_WRONGOLDPASSWORD); - SetSentErrorMessage (true); + SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH); + SetSentErrorMessage(true); return false; } AccountOpResult result = accmgr.ChangePassword(m_session->GetAccountId(), password_new); - switch(result) { case AOR_OK: @@ -230,7 +229,6 @@ bool ChatHandler::HandleAccountPasswordCommand(const char* args) SendSysMessage(LANG_PASSWORD_TOO_LONG); SetSentErrorMessage(true); return false; - case AOR_NAME_NOT_EXIST: // not possible case, don't want get account name for output default: SendSysMessage(LANG_COMMAND_NOTCHANGEPASSWORD); SetSentErrorMessage(true); @@ -243,15 +241,23 @@ bool ChatHandler::HandleAccountPasswordCommand(const char* args) bool ChatHandler::HandleAccountAddonCommand(const char* args) { if (!*args) + { + SendSysMessage(LANG_CMD_SYNTAX); + SetSentErrorMessage(true); return false; + } - char *szExp = strtok((char*)args," "); + char *szExp = strtok((char*)args, " "); uint32 account_id = m_session->GetAccountId(); - int expansion=atoi(szExp); //get int anyway (0 if error) + int expansion = atoi(szExp); //get int anyway (0 if error) if (expansion < 0 || expansion > sWorld.getConfig(CONFIG_EXPANSION)) - return false; + { + SendSysMessage(LANG_IMPROPER_VALUE); + SetSentErrorMessage(true); + return false; + } // No SQL injection LoginDatabase.PExecute("UPDATE account SET expansion = '%d' WHERE id = '%u'", expansion, account_id); @@ -264,7 +270,8 @@ bool ChatHandler::HandleAccountLockCommand(const char* args) if (!*args) { SendSysMessage(LANG_USE_BOL); - return true; + SetSentErrorMessage(true); + return false; } std::string argstr = (char*)args; @@ -283,7 +290,8 @@ bool ChatHandler::HandleAccountLockCommand(const char* args) } SendSysMessage(LANG_USE_BOL); - return true; + SetSentErrorMessage(true); + return false; } /// Display the 'Message of the day' for the realm diff --git a/src/server/game/Chat/Commands/Level1.cpp b/src/server/game/Chat/Commands/Level1.cpp index 11189d519a0..771339645fe 100644 --- a/src/server/game/Chat/Commands/Level1.cpp +++ b/src/server/game/Chat/Commands/Level1.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "World.h" @@ -817,7 +817,7 @@ bool ChatHandler::HandleNamegoCommand(const char* args) if (pMap->IsBattleGroundOrArena()) { // only allow if gm mode is on - if (!target->isGameMaster()) + if (!_player->isGameMaster()) { PSendSysMessage(LANG_CANNOT_GO_TO_BG_GM,nameLink.c_str()); SetSentErrorMessage(true); @@ -2381,7 +2381,7 @@ bool ChatHandler::HandleWhispersCommand(const char* args) //Save all players in the world bool ChatHandler::HandleSaveAllCommand(const char* /*args*/) { - ObjectAccessor::Instance().SaveAllPlayers(); + sObjectAccessor.SaveAllPlayers(); SendSysMessage(LANG_PLAYERS_SAVED); return true; } @@ -2502,7 +2502,7 @@ bool ChatHandler::HandleTeleNameCommand(const char * args) PSendSysMessage(LANG_TELEPORTING_TO, nameLink.c_str(), GetTrinityString(LANG_OFFLINE), tele->name.c_str()); Player::SavePositionInDB(tele->mapId,tele->position_x,tele->position_y,tele->position_z,tele->orientation, - MapManager::Instance().GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid); + sMapMgr.GetZoneId(tele->mapId,tele->position_x,tele->position_y,tele->position_z),target_guid); } return true; @@ -2768,7 +2768,7 @@ bool ChatHandler::HandleGoXYCommand(const char* args) else _player->SaveRecallPosition(); - Map const *map = MapManager::Instance().CreateBaseMap(mapid); + Map const *map = sMapMgr.CreateBaseMap(mapid); float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); @@ -2861,7 +2861,7 @@ bool ChatHandler::HandleGoZoneXYCommand(const char* args) // update to parent zone if exist (client map show only zones without parents) AreaTableEntry const* zoneEntry = areaEntry->zone ? GetAreaEntryByAreaID(areaEntry->zone) : areaEntry; - Map const *map = MapManager::Instance().CreateBaseMap(zoneEntry->mapid); + Map const *map = sMapMgr.CreateBaseMap(zoneEntry->mapid); if (map->Instanceable()) { @@ -2936,7 +2936,7 @@ bool ChatHandler::HandleGoGridCommand(const char* args) else _player->SaveRecallPosition(); - Map const *map = MapManager::Instance().CreateBaseMap(mapid); + Map const *map = sMapMgr.CreateBaseMap(mapid); float z = std::max(map->GetHeight(x, y, MAX_HEIGHT), map->GetWaterLevel(x, y)); _player->TeleportTo(mapid, x, y, z, _player->GetOrientation()); diff --git a/src/server/game/Chat/Commands/Level2.cpp b/src/server/game/Chat/Commands/Level2.cpp index 4f299c932e8..77716e25954 100644 --- a/src/server/game/Chat/Commands/Level2.cpp +++ b/src/server/game/Chat/Commands/Level2.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "DBCStores.h" #include "ObjectMgr.h" #include "Player.h" @@ -32,7 +32,7 @@ #include "World.h" #include "GameEventMgr.h" #include "SpellMgr.h" -#include "PoolHandler.h" +#include "PoolMgr.h" #include "AccountMgr.h" #include "WaypointManager.h" #include "Util.h" @@ -1672,7 +1672,7 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) if (/*creature->GetMotionMaster()->empty() ||*/ creature->GetMotionMaster()->GetCurrentMovementGeneratorType () != TARGETED_MOTION_TYPE) { - PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); + PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); SetSentErrorMessage(true); return false; } @@ -1682,7 +1682,7 @@ bool ChatHandler::HandleNpcUnFollowCommand(const char* /*args*/) if (mgen->GetTarget() != player) { - PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU); + PSendSysMessage(LANG_CREATURE_NOT_FOLLOW_YOU, creature->GetName()); SetSentErrorMessage(true); return false; } @@ -2844,7 +2844,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args) // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map); map->Add(wpCreature2); - //MapManager::Instance().GetMap(npcCreature->GetMapId())->Add(wpCreature2); + //sMapMgr.GetMap(npcCreature->GetMapId())->Add(wpCreature2); } WorldDatabase.PExecuteLog("UPDATE waypoint_data SET position_x = '%f',position_y = '%f',position_z = '%f' where id = '%u' AND point='%u'", diff --git a/src/server/game/Chat/Commands/Level3.cpp b/src/server/game/Chat/Commands/Level3.cpp index 8ac26cc5e8f..3ddf9b84365 100644 --- a/src/server/game/Chat/Commands/Level3.cpp +++ b/src/server/game/Chat/Commands/Level3.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "World.h" @@ -45,7 +45,7 @@ #include "SkillDiscovery.h" #include "SkillExtraItems.h" #include "SystemConfig.h" -#include "Config/ConfigEnv.h" +#include "ConfigEnv.h" #include "Util.h" #include "ItemEnchantmentMgr.h" #include "BattleGroundMgr.h" @@ -689,7 +689,7 @@ bool ChatHandler::HandleReloadConfigCommand(const char* /*args*/) { sLog.outString("Re-Loading config settings..."); sWorld.LoadConfigSettings(true); - MapManager::Instance().InitializeVisibilityDistanceInfo(); + sMapMgr.InitializeVisibilityDistanceInfo(); SendGlobalGMSysMessage("World config settings reloaded."); return true; } @@ -749,6 +749,14 @@ bool ChatHandler::HandleReloadCommandCommand(const char*) return true; } +bool ChatHandler::HandleReloadOnKillReputationCommand(const char*) +{ + sLog.outString("Re-Loading creature award reputation definitions..."); + objmgr.LoadReputationOnKill(); + SendGlobalGMSysMessage("DB table `creature_onkill_reputation` reloaded."); + return true; +} + bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args) { if (!*args) @@ -787,24 +795,21 @@ bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args) size_t len = 0; if (const char* temp = fields[9].GetString()) { - if (cInfo->Name) - delete cInfo->Name; + delete[] cInfo->Name; len = strlen(temp)+1; const_cast<CreatureInfo*>(cInfo)->Name = new char[len]; strncpy(cInfo->Name, temp, len); } if (const char* temp = fields[10].GetString()) { - if (cInfo->SubName) - delete cInfo->SubName; + delete[] cInfo->SubName; len = strlen(temp)+1; const_cast<CreatureInfo*>(cInfo)->SubName = new char[len]; strncpy(cInfo->SubName, temp, len); } if (const char* temp = fields[11].GetString()) { - if (cInfo->IconName) - delete cInfo->IconName; + delete[] cInfo->IconName; len = strlen(temp)+1; const_cast<CreatureInfo*>(cInfo)->IconName = new char[len]; strncpy(cInfo->IconName, temp, len); @@ -863,8 +868,7 @@ bool ChatHandler::HandleReloadCreatureTemplateCommand(const char* args) const_cast<CreatureInfo*>(cInfo)->maxgold = fields[63].GetUInt32(); if (const char* temp = fields[64].GetString()) { - if (cInfo->AIName) - delete cInfo->AIName; + delete[] cInfo->AIName; len = strlen(temp)+1; const_cast<CreatureInfo*>(cInfo)->AIName = new char[len]; strncpy(const_cast<char*>(cInfo->AIName), temp, len); @@ -1276,6 +1280,14 @@ bool ChatHandler::HandleReloadItemEnchantementsCommand(const char*) return true; } +bool ChatHandler::HandleReloadItemSetNamesCommand(const char*) +{ + sLog.outString("Re-Loading Item set names..."); + LoadRandomEnchantmentsTable(); + SendGlobalGMSysMessage("DB table `item_set_names` reloaded."); + return true; +} + bool ChatHandler::HandleReloadGameObjectScriptsCommand(const char* arg) { if (sWorld.IsScriptScheduled()) @@ -1494,6 +1506,14 @@ bool ChatHandler::HandleReloadLocalesItemCommand(const char* /*arg*/) return true; } +bool ChatHandler::HandleReloadLocalesItemSetNameCommand(const char* /*arg*/) +{ + sLog.outString("Re-Loading Locales Item set name... "); + objmgr.LoadItemSetNameLocales(); + SendGlobalGMSysMessage("DB table `locales_item_set_name` reloaded."); + return true; +} + bool ChatHandler::HandleReloadLocalesNpcTextCommand(const char* /*arg*/) { sLog.outString("Re-Loading Locales NPC Text ... "); @@ -4493,7 +4513,7 @@ bool ChatHandler::HandleReviveCommand(const char *args) } else // will resurrected at login without corpse - ObjectAccessor::Instance().ConvertCorpseForPlayer(target_guid); + sObjectAccessor.ConvertCorpseForPlayer(target_guid); return true; } @@ -5513,8 +5533,8 @@ bool ChatHandler::HandleResetAllCommand(const char * args) CharacterDatabase.PExecute("UPDATE characters SET at_login = at_login | '%u' WHERE (at_login & '%u') = '0'",atLogin,atLogin); - ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock()); - HashMapHolder<Player>::MapType const& plist = ObjectAccessor::Instance().GetPlayers(); + ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, *HashMapHolder<Player>::GetLock(), true); + HashMapHolder<Player>::MapType const& plist = sObjectAccessor.GetPlayers(); for (HashMapHolder<Player>::MapType::const_iterator itr = plist.begin(); itr != plist.end(); ++itr) itr->second->SetAtLoginFlag(atLogin); @@ -7000,8 +7020,8 @@ bool ChatHandler::HandleInstanceUnbindCommand(const char *args) bool ChatHandler::HandleInstanceStatsCommand(const char* /*args*/) { - PSendSysMessage("instances loaded: %d", MapManager::Instance().GetNumInstances()); - PSendSysMessage("players in instances: %d", MapManager::Instance().GetNumPlayersInInstances()); + PSendSysMessage("instances loaded: %d", sMapMgr.GetNumInstances()); + PSendSysMessage("players in instances: %d", sMapMgr.GetNumPlayersInInstances()); PSendSysMessage("instance saves: %d", sInstanceSaveManager.GetNumInstanceSaves()); PSendSysMessage("players bound: %d", sInstanceSaveManager.GetNumBoundPlayersTotal()); PSendSysMessage("groups bound: %d", sInstanceSaveManager.GetNumBoundGroupsTotal()); diff --git a/src/server/game/Combat/HostileRefManager.h b/src/server/game/Combat/HostileRefManager.h index 80b676312a1..0a240ad44be 100644 --- a/src/server/game/Combat/HostileRefManager.h +++ b/src/server/game/Combat/HostileRefManager.h @@ -22,7 +22,7 @@ #define _HOSTILEREFMANAGER #include "Common.h" -#include "Utilities/LinkedReference/RefManager.h" +#include "RefManager.h" class Unit; class ThreatManager; diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 52f02f0f66d..fbf5a80d42b 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -36,8 +36,13 @@ float ThreatCalcHelper::calcThreat(Unit* pHatedUnit, Unit* /*pHatingUnit*/, float fThreat, SpellSchoolMask schoolMask, SpellEntry const *pThreatSpell) { if (pThreatSpell) + { + if (pThreatSpell->AttributesEx & SPELL_ATTR_EX_NO_THREAT) + return 0.0f; + if (Player* modOwner = pHatedUnit->GetSpellModOwner()) modOwner->ApplySpellMod(pThreatSpell->Id, SPELLMOD_THREAT, fThreat); + } return pHatedUnit->ApplyTotalThreatModifier(fThreat, schoolMask); } diff --git a/src/server/game/Combat/ThreatManager.h b/src/server/game/Combat/ThreatManager.h index 723a553e9d7..2903fe83c38 100644 --- a/src/server/game/Combat/ThreatManager.h +++ b/src/server/game/Combat/ThreatManager.h @@ -23,7 +23,7 @@ #include "Common.h" #include "SharedDefines.h" -#include "Utilities/LinkedReference/Reference.h" +#include "LinkedReference/Reference.h" #include "UnitEvents.h" #include <list> @@ -35,7 +35,7 @@ class Creature; class ThreatManager; struct SpellEntry; -#define THREAT_UPDATE_INTERVAL 1 * IN_MILISECONDS // Server should send threat update to client periodically each second +#define THREAT_UPDATE_INTERVAL 1 * IN_MILLISECONDS // Server should send threat update to client periodically each second //============================================================== // Class to calculate the real threat based diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 8e5a7e5677e..9164f55c6ce 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -19,7 +19,7 @@ */ -#include "Policies/SingletonImp.h" + #include "Player.h" #include "SpellAuras.h" #include "SpellMgr.h" @@ -29,12 +29,10 @@ #include "InstanceData.h" #include "ConditionMgr.h" -INSTANTIATE_SINGLETON_1(ConditionMgr); - // Checks if player meets the condition // Can have CONDITION_SOURCE_TYPE_NONE && !mReferenceId if called from a special event (ie: eventAI) bool Condition::Meets(Player * player, Unit* targetOverride) -{ +{ if (!player) { sLog.outDebug("Condition player not found"); @@ -126,7 +124,7 @@ bool Condition::Meets(Player * player, Unit* targetOverride) break; } case CONDITION_SPELL_SCRIPT_TARGET: - condMeets = true;//spell target condition is handled in spellsystem, here it is always true + condMeets = true;//spell target condition is handled in spellsystem, here it is always true refId = 0;//cant have references! use CONDITION_SOURCE_TYPE_SPELL for it break; case CONDITION_CREATURE_TARGET: @@ -165,7 +163,7 @@ bool Condition::Meets(Player * player, Unit* targetOverride) break; case CONDITION_ITEM_TARGET: { - condMeets = true;//handled in Item::IsTargetValidForItemUse + condMeets = true;//handled in Item::IsTargetValidForItemUse refId = 0;//cant have references for now break; } @@ -201,6 +199,7 @@ ConditionMgr::ConditionMgr() ConditionMgr::~ConditionMgr() { + Clean(); } ConditionList ConditionMgr::GetConditionReferences(uint32 refId) @@ -236,12 +235,12 @@ bool ConditionMgr::IsPlayerMeetToConditionList(Player* player,const ConditionLis }else{ sLog.outDebug("IsPlayerMeetToConditionList: Reference template -%u not found", (*i)->mReferenceId);//checked at loading, should never happen } - + } else//handle normal condition { if (!(*i)->Meets(player, targetOverride)) ElseGroupMap[(*i)->mElseGroup] = false; - } + } } } for (std::map<uint32, bool>::const_iterator i = ElseGroupMap.begin(); i != ElseGroupMap.end(); ++i) @@ -273,7 +272,7 @@ ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType { ConditionMap::const_iterator itr = m_ConditionMap.find(sType); if (itr != m_ConditionMap.end()) - { + { ConditionTypeMap::const_iterator i = (*itr).second.find(uEntry); if (i != (*itr).second.end()) { @@ -287,8 +286,8 @@ ConditionList ConditionMgr::GetConditionsForNotGroupedEntry(ConditionSourceType void ConditionMgr::LoadConditions(bool isReload) { - m_ConditionMap.clear(); // for reload case - m_ConditionReferenceMap.clear(); // for reload case + Clean(); + //must clear all custom handled cases (groupped types) before reload if (isReload) { @@ -336,11 +335,11 @@ void ConditionMgr::LoadConditions(bool isReload) Field *fields = result->Fetch(); Condition* cond = new Condition(); - int32 iSourceTypeOrReferenceId = fields[0].GetInt32(); + int32 iSourceTypeOrReferenceId = fields[0].GetInt32(); cond->mSourceGroup = fields[1].GetUInt32(); cond->mSourceEntry = fields[2].GetUInt32(); cond->mElseGroup = fields[3].GetUInt32(); - int32 iConditionTypeOrReference = fields[4].GetInt32(); + int32 iConditionTypeOrReference = fields[4].GetInt32(); cond->mConditionValue1 = fields[5].GetUInt32(); cond->mConditionValue2 = fields[6].GetUInt32(); cond->mConditionValue3 = fields[7].GetUInt32(); @@ -351,9 +350,10 @@ void ConditionMgr::LoadConditions(bool isReload) if (iConditionTypeOrReference < 0)//it has a reference { - if (iConditionTypeOrReference == iSourceTypeOrReferenceId)//self referencing, skipp + if (iConditionTypeOrReference == iSourceTypeOrReferenceId)//self referencing, skip { sLog.outErrorDb("Condition reference %i is referencing self, skipped", iSourceTypeOrReferenceId); + delete cond; continue; } cond->mReferenceId = uint32(abs(iConditionTypeOrReference)); @@ -373,8 +373,10 @@ void ConditionMgr::LoadConditions(bool isReload) if (cond->mSourceEntry && iSourceTypeOrReferenceId < 0) sLog.outErrorDb("Condition %s %i has useless data in SourceEntry (%u)!", rowType, iSourceTypeOrReferenceId, cond->mSourceEntry); }else if (!isConditionTypeValid(cond))//doesn't have reference, validate ConditionType - continue; - + { + delete cond; + continue; + } if (iSourceTypeOrReferenceId < 0)//it is a reference template { @@ -390,15 +392,19 @@ void ConditionMgr::LoadConditions(bool isReload) }//end of reference templates cond->mSourceType = ConditionSourceType(iSourceTypeOrReferenceId); - + //if not a reference and SourceType is invalid, skip if (iConditionTypeOrReference >= 0 && !isSourceTypeValid(cond)) + { + delete cond; continue; + } //Grouping is only allowed for some types (loot templates, gossip menus, gossip items) if (cond->mSourceGroup && !isGroupable(cond->mSourceType)) { sLog.outErrorDb("Condition type %u has not allowed grouping %u!", uint32(cond->mSourceType), cond->mSourceGroup); + delete cond; continue; }else if (cond->mSourceGroup) { @@ -450,9 +456,15 @@ void ConditionMgr::LoadConditions(bool isReload) break; } if (!bIsDone) + { sLog.outErrorDb("Not handled grouped condition, SourceGroup %u", cond->mSourceGroup); + delete cond; + } else + { + m_AllocatedMemory.push_back(cond); ++count; + } continue; } @@ -505,11 +517,10 @@ bool ConditionMgr::addToGossipMenus(Condition* cond) if ((*itr).second.entry == cond->mSourceGroup && (*itr).second.text_id == cond->mSourceEntry) { (*itr).second.conditions.push_back(cond); - sLog.outDebug("addToGossipMenus: entry %u textId %u", cond->mSourceGroup, cond->mSourceEntry); return true; } } - } + } sLog.outErrorDb("addToGossipMenus: GossipMenu %u not found", cond->mSourceGroup); return false; } @@ -524,12 +535,11 @@ bool ConditionMgr::addToGossipMenuItems(Condition* cond) if ((*itr).second.menu_id == cond->mSourceGroup && (*itr).second.id == cond->mSourceEntry) { (*itr).second.conditions.push_back(cond); - //sLog.outDebug("addToGossipMenuItems: menuId %u id %u", cond->mSourceGroup, cond->mSourceEntry); return true; } } } - sLog.outErrorDb("addToGossipMenuItems: GossipMenuIt %u Item %u not found", cond->mSourceGroup, cond->mSourceEntry); + sLog.outErrorDb("addToGossipMenuItems: GossipMenuId %u Item %u not found", cond->mSourceGroup, cond->mSourceEntry); return false; } @@ -591,7 +601,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) break; } case CONDITION_SOURCE_TYPE_GAMEOBJECT_LOOT_TEMPLATE: - { + { if (!LootTemplates_Gameobject.HaveLootFor(cond->mSourceGroup)) { sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `gameobject_loot_template`, ignoring.", cond->mSourceGroup); @@ -607,7 +617,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) break; } case CONDITION_SOURCE_TYPE_ITEM_LOOT_TEMPLATE: - { + { if (!LootTemplates_Item.HaveLootFor(cond->mSourceGroup)) { sLog.outErrorDb("SourceGroup %u in `condition` table, does not exist in `item_loot_template`, ignoring.", cond->mSourceGroup); @@ -776,7 +786,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) return false; } break; - } + } case CONDITION_SOURCE_TYPE_CREATURE_TEMPLATE_VEHICLE: { if (!sCreatureStorage.LookupEntry<CreatureInfo>(cond->mSourceEntry)) @@ -1043,10 +1053,10 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) { sLog.outErrorDb("SpellTarget condition has non existing spell target type (%u), skipped", cond->mConditionValue1); return false; - } + } switch(cond->mConditionValue1) { - case SPELL_TARGET_TYPE_GAMEOBJECT: + case SPELL_TARGET_TYPE_GAMEOBJECT: { if (cond->mConditionValue2 && !sGOStorage.LookupEntry<GameObjectInfo>(cond->mConditionValue2)) { @@ -1143,3 +1153,31 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) } return true; } + +void ConditionMgr::Clean() +{ + for (ConditionReferenceMap::iterator itr = m_ConditionReferenceMap.begin(); itr != m_ConditionReferenceMap.end(); ++itr) + { + for (ConditionList::const_iterator it = itr->second.begin(); it != itr->second.end(); ++it) + delete *it; + itr->second.clear(); + } + m_ConditionReferenceMap.clear(); + + for (ConditionMap::iterator itr = m_ConditionMap.begin(); itr != m_ConditionMap.end(); ++itr) + { + for (ConditionTypeMap::iterator it = itr->second.begin(); it != itr->second.end(); ++it) + { + for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i) + delete *i; + it->second.clear(); + } + itr->second.clear(); + } + m_ConditionMap.clear(); + + // this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;) + for (std::list<Condition*>::const_iterator itr = m_AllocatedMemory.begin(); itr != m_AllocatedMemory.end(); ++itr) + delete *itr; + m_AllocatedMemory.clear(); +} diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index bc2ce8d01a2..bb9fc2708fa 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -47,7 +47,7 @@ enum ConditionType CONDITION_CLASS = 15, // class 0 +referenceID true if player's class is equal to class CONDITION_RACE = 16, // race 0 +referenceID true if player's race is equal to race CONDITION_ACHIEVEMENT = 17, // achievement_id 0 +referenceID true if achievement is complete - CONDITION_SPELL_SCRIPT_TARGET = 18, // SpellScriptTargetType, TargetEntry, 0 + CONDITION_SPELL_SCRIPT_TARGET = 18, // SpellScriptTargetType, TargetEntry, 0 CONDITION_CREATURE_TARGET = 19, // creature entry 0 +referenceID true if current target is creature with value1 entry CONDITION_TARGET_HEALTH_BELOW_PCT = 20, // 0-100 0 +referenceID true if target's health is below value1 percent, false if over or no target CONDITION_TARGET_RANGE = 21, // minDistance maxDist +referenceID true if target is closer then minDist and further then maxDist or if max is 0 then max dist is infinit @@ -84,7 +84,7 @@ enum ConditionSourceType #define MAX_CONDITIONSOURCETYPE 19 struct Condition -{ +{ ConditionSourceType mSourceType; //SourceTypeOrReferenceId uint32 mSourceGroup; uint32 mSourceEntry; @@ -121,14 +121,16 @@ typedef std::map<uint32, ConditionList > ConditionReferenceMap;//only used for r class ConditionMgr { + friend class ACE_Singleton<ConditionMgr, ACE_Null_Mutex>; + ConditionMgr(); + public: - ConditionMgr(); ~ConditionMgr(); void LoadConditions(bool isReload = false); bool isConditionTypeValid(Condition* cond); ConditionList GetConditionReferences(uint32 refId); - + bool IsPlayerMeetToConditions(Player* player, ConditionList conditions, Unit* targetOverride = NULL); ConditionList GetConditionsForNotGroupedEntry(ConditionSourceType sType, uint32 uEntry); @@ -160,8 +162,11 @@ class ConditionMgr sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU || sourceType == CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION); } + + void Clean(); // free up resources + std::list<Condition*> m_AllocatedMemory; // some garbage collection :) }; -#define sConditionMgr Trinity::Singleton<ConditionMgr>::Instance() +#define sConditionMgr (*ACE_Singleton<ConditionMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index ba0e3af9a64..4ddccd735f5 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -19,8 +19,8 @@ */ #include "DBCStores.h" -#include "Policies/SingletonImp.h" -#include "Log.h" + +#include "Logging/Log.h" #include "ProgressBar.h" #include "SharedDefines.h" #include "SpellMgr.h" @@ -235,15 +235,15 @@ inline void LoadDBC(uint32& availableDbcLocales,barGoLink& bar, StoreProblemList else errlist.push_back(dbc_filename); } - if (sql) - delete sql; + + delete sql; } void LoadDBCStores(const std::string& dataPath) { std::string dbcPath = dataPath+"dbc/"; - const uint32 DBCFilesCount = 87; + const uint32 DBCFilesCount = 89; barGoLink bar(DBCFilesCount); @@ -506,8 +506,7 @@ void LoadDBCStores(const std::string& dataPath) // fill data for (uint32 i = 1; i < sTaxiPathNodeStore.GetNumRows(); ++i) if (TaxiPathNodeEntry const* entry = sTaxiPathNodeStore.LookupEntry(i)) - sTaxiPathNodesByPath[entry->path][entry->index] = TaxiPathNode(entry->mapid,entry->x,entry->y,entry->z,entry->actionFlag,entry->delay); - sTaxiPathNodeStore.Clear(); + sTaxiPathNodesByPath[entry->path].set(entry->index, entry); // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path @@ -579,7 +578,7 @@ void LoadDBCStores(const std::string& dataPath) // error checks if (bad_dbc_files.size() >= DBCFilesCount) { - sLog.outError("\nIncorrect DataDir value in Trinityd.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); + sLog.outError("\nIncorrect DataDir value in worldserver.conf or ALL required *.dbc files (%d) not found by path: %sdbc",DBCFilesCount,dataPath.c_str()); exit(1); } else if (!bad_dbc_files.empty()) @@ -593,13 +592,13 @@ void LoadDBCStores(const std::string& dataPath) } // Check loaded DBC files proper version - if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) added in 3.3.3a - !sCharTitlesStore.LookupEntry(177) || // last char title added in 3.3.3a - !sGemPropertiesStore.LookupEntry(1629) || // last added spell in 3.3.3a - !sItemStore.LookupEntry(54860) || // last gem property added in 3.3.3a - !sItemExtendedCostStore.LookupEntry(2997) || // last item extended cost added in 3.3.3a - !sMapStore.LookupEntry(724) || // last map added in 3.3.3a - !sSpellStore.LookupEntry(76567) ) // last client known item added in 3.3.3a + if (!sAreaStore.LookupEntry(3617) || // last area (areaflag) 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 + !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 { sLog.outError("\nYou have _outdated_ DBC files. Please extract correct versions from current using client."); exit(1); diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index b14814e07a1..1bda56f38cc 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -20,7 +20,7 @@ #define TRINITY_DBCSTORES_H #include "Common.h" -#include "Database/DBCStore.h" +#include "DBCStore.h" #include "DBCStructure.h" #include <list> diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 0fc0d1251f5..7663aaf3dcb 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -21,8 +21,10 @@ #ifndef TRINITY_DBCSTRUCTURE_H #define TRINITY_DBCSTRUCTURE_H +#include "Common.h" #include "DBCEnums.h" -#include "Platform/Define.h" +#include "Define.h" +#include "Path.h" #include "Util.h" #include <map> @@ -1080,12 +1082,14 @@ struct ItemRandomSuffixEntry uint32 prefix[5]; // 22-24 m_allocationPct }; +#define MAX_ITEM_SET_ITEMS 10 struct ItemSetEntry { //uint32 id // 0 m_ID char* name[16]; // 1-16 m_name_lang // 17 string flags, unused - //uint32 itemId[17]; // 18-34 m_itemID + uint32 itemId[MAX_ITEM_SET_ITEMS]; // 18-27 m_itemID + //uint32 unknown[7]; // 28-34 unk, all 0 uint32 spells[8]; // 35-42 m_setSpellID uint32 items_to_triggerspell[8]; // 43-50 m_setThreshold uint32 required_skill_id; // 51 m_requiredSkill @@ -1509,9 +1513,6 @@ struct SpellEntry //uint32 spellDescriptionVariableID; // 232 3.2.0 //uint32 SpellDifficultyId; // 233 3.3.0 - // helpers - int32 CalculateSimpleValue(uint8 eff) const { return EffectBasePoints[eff]+int32(1); } - private: // prevent creating custom entries (copy data from original in fact) SpellEntry(SpellEntry const&); // DON'T must have implementation @@ -1712,8 +1713,8 @@ struct TaxiPathNodeEntry float z; // 6 m_LocZ uint32 actionFlag; // 7 m_flags uint32 delay; // 8 m_delay - // 9 m_arrivalEventID - // 10 m_departureEventID + uint32 arrivalEventID; // 9 m_arrivalEventID + uint32 departureEventID; // 10 m_departureEventID }; struct TotemCategoryEntry @@ -1909,19 +1910,15 @@ struct TaxiPathBySourceAndDestination typedef std::map<uint32,TaxiPathBySourceAndDestination> TaxiPathSetForSource; typedef std::map<uint32,TaxiPathSetForSource> TaxiPathSetBySource; -struct TaxiPathNode +struct TaxiPathNodePtr { - TaxiPathNode() : mapid(0), x(0),y(0),z(0),actionFlag(0),delay(0) {} - TaxiPathNode(uint32 _mapid, float _x, float _y, float _z, uint32 _actionFlag, uint32 _delay) : mapid(_mapid), x(_x),y(_y),z(_z),actionFlag(_actionFlag),delay(_delay) {} - - uint32 mapid; - float x; - float y; - float z; - uint32 actionFlag; - uint32 delay; + TaxiPathNodePtr() : i_ptr(NULL) {} + TaxiPathNodePtr(TaxiPathNodeEntry const* ptr) : i_ptr(ptr) {} + TaxiPathNodeEntry const* i_ptr; + operator TaxiPathNodeEntry const& () const { return *i_ptr; } }; -typedef std::vector<TaxiPathNode> TaxiPathNodeList; + +typedef Path<TaxiPathNodePtr,TaxiPathNodeEntry const> TaxiPathNodeList; typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; #define TaxiMaskSize 12 diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index 1f1b010a6fd..80d8791bd01 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -72,7 +72,7 @@ const char ItemExtendedCostEntryfmt[]="niiiiiiiiiiiiiix"; const char ItemLimitCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxix"; const char ItemRandomPropertiesfmt[]="nxiiiiissssssssssssssssx"; const char ItemRandomSuffixfmt[]="nssssssssssssssssxxiiiiiiiiii"; -const char ItemSetEntryfmt[]="dssssssssssssssssxxxxxxxxxxxxxxxxxxiiiiiiiiiiiiiiiiii"; +const char ItemSetEntryfmt[]="dssssssssssssssssxiiiiiiiiiixxxxxxxiiiiiiiiiiiiiiiiii"; const char LFGDungeonEntryfmt[]="nxxxxxxxxxxxxxxxxxiiiiiiixixxixixxxxxxxxxxxxxxxxx"; const char LockEntryfmt[]="niiiiiiiiiiiiiiiiiiiiiiiixxxxxxxx"; const char MailTemplateEntryfmt[]="nxxxxxxxxxxxxxxxxxssssssssssssssssx"; @@ -95,7 +95,7 @@ const std::string CustomSpellDifficultyfmt="ppppp"; const std::string CustomSpellDifficultyIndex="id"; const char SpellDurationfmt[]="niii"; const char SpellEntryfmt[]="niiiiiiiiiiiixixiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiifxiiiiiiiiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiiiiiiiifffiiiiiiiiiiiiiiifffiiiiiiiiiiiiixssssssssssssssssxssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxiiiiiiiiiiixfffxxxiiiiixxxxxxx"; -const std::string CustomSpellEntryfmt="pappppppppaaaaaapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa"; +const std::string CustomSpellEntryfmt="pappppppppaapapapaaaaaaaaaaapaaapapppppppaaaaapaapaaaaaaaaaaaaaaaaaappppppppppppppppppppppppppppppppppppaaaaaapppppppppaaapppppppppaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaappppppppapppaaaaappaaaaaaa"; const std::string CustomSpellEntryIndex = "Id"; const char SpellFocusObjectfmt[]="nxxxxxxxxxxxxxxxxx"; const char SpellItemEnchantmentfmt[]="nxiiiiiixxxiiissssssssssssssssxiiiiiii"; @@ -110,7 +110,7 @@ const char TalentEntryfmt[]="niiiiiiiixxxxixxixxxxxx"; const char TalentTabEntryfmt[]="nxxxxxxxxxxxxxxxxxxxiiix"; const char TaxiNodesEntryfmt[]="nifffssssssssssssssssxii"; const char TaxiPathEntryfmt[]="niii"; -const char TaxiPathNodeEntryfmt[]="diiifffiixx"; +const char TaxiPathNodeEntryfmt[]="diiifffiiii"; const char TotemCategoryEntryfmt[]="nxxxxxxxxxxxxxxxxxii"; const char VehicleEntryfmt[]="niffffiiiiiiiifffffffffffffffssssfifiixx"; const char VehicleSeatEntryfmt[]="niiffffffffffiiiiiifffffffiiifffiiiiiiiffiiiiixxxxxxxxxxxx"; diff --git a/src/server/game/DungeonFinding/LFG.h b/src/server/game/DungeonFinding/LFG.h index c1b55443852..a5461029c8d 100644 --- a/src/server/game/DungeonFinding/LFG.h +++ b/src/server/game/DungeonFinding/LFG.h @@ -19,7 +19,7 @@ #ifndef _LFG_H #define _LFG_H -#include "Platform/Define.h" +#include "Define.h" #include "Object.h" enum LfgRoles diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index ba418cdb191..6c089a83bc3 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -15,7 +15,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Policies/SingletonImp.h" + #include "Common.h" #include "SharedDefines.h" #include "Group.h" @@ -24,8 +24,6 @@ #include "ObjectMgr.h" #include "WorldPacket.h" -INSTANTIATE_SINGLETON_1(LFGMgr); - /*********************************************************/ /*** LFG QUEUES ***/ /*********************************************************/ @@ -46,8 +44,7 @@ LFGQueue::~LFGQueue() void LFGQueue::AddToQueue(uint64 guid, LfgQueueInfo* pqInfo) { - if (LfgQueueInfo* qInfo = m_LfgQueue[guid]) - delete qInfo; + delete m_LfgQueue[guid]; m_LfgQueue[guid] = pqInfo; // ATM will only add it to the queue... No find group implementation... yet (on purpose) } diff --git a/src/server/game/DungeonFinding/LFGMgr.h b/src/server/game/DungeonFinding/LFGMgr.h index b19da4e3d00..88d33743fa9 100644 --- a/src/server/game/DungeonFinding/LFGMgr.h +++ b/src/server/game/DungeonFinding/LFGMgr.h @@ -20,7 +20,7 @@ #define _LFGMGR_H #include "Common.h" -#include "Policies/Singleton.h" +#include "ace/Singleton.h" #include "Group.h" #include "LFG.h" @@ -237,43 +237,44 @@ typedef std::map<uint8, LFGQueue *> LFGQueueMap; class LFGMgr { -public: + friend class ACE_Singleton<LFGMgr, ACE_Null_Mutex>; LFGMgr(); - ~LFGMgr(); + public: + ~LFGMgr(); - void InitLFG(); - void SendLfgPlayerInfo(Player *plr); - void SendLfgPartyInfo(Player *plr); - void Join(Player *plr); - void Leave(Player *plr, Group *grp = NULL); - void UpdateRoleCheck(Group *grp, Player *plr = NULL); - void Update(uint32 diff); + void InitLFG(); + void SendLfgPlayerInfo(Player *plr); + void SendLfgPartyInfo(Player *plr); + void Join(Player *plr); + void Leave(Player *plr, Group *grp = NULL); + void UpdateRoleCheck(Group *grp, Player *plr = NULL); + void Update(uint32 diff); -private: - void BuildLfgRoleCheck(WorldPacket &data, LfgRoleCheck *pRoleCheck); - void BuildAvailableRandomDungeonList(WorldPacket &data, Player *plr); - void BuildRewardBlock(WorldPacket &data, uint32 dungeon, Player *plr); - void BuildPlayerLockDungeonBlock(WorldPacket &data, LfgLockStatusSet *lockSet); - void BuildPartyLockDungeonBlock(WorldPacket &data, LfgLockStatusMap *lockMap); - bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); + private: + void BuildLfgRoleCheck(WorldPacket &data, LfgRoleCheck *pRoleCheck); + void BuildAvailableRandomDungeonList(WorldPacket &data, Player *plr); + void BuildRewardBlock(WorldPacket &data, uint32 dungeon, Player *plr); + void BuildPlayerLockDungeonBlock(WorldPacket &data, LfgLockStatusSet *lockSet); + void BuildPartyLockDungeonBlock(WorldPacket &data, LfgLockStatusMap *lockMap); + bool CheckGroupRoles(LfgRolesMap &groles, bool removeLeaderFlag = true); - LfgLockStatusMap* GetPartyLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons); - LfgLockStatusSet* GetPlayerLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons); - LfgDungeonSet* GetRandomDungeons(uint8 level, uint8 expansion); - LfgDungeonSet* GetDungeonsByRandom(uint32 randomdungeon); - LfgDungeonSet* GetAllDungeons(); - LfgReward* GetRandomDungeonReward(uint32 dungeon, bool done, uint8 level); - uint8 GetDungeonGroupType(uint32 dungeon); + LfgLockStatusMap* GetPartyLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons); + LfgLockStatusSet* GetPlayerLockStatusDungeons(Player *plr, LfgDungeonSet *dungeons); + LfgDungeonSet* GetRandomDungeons(uint8 level, uint8 expansion); + LfgDungeonSet* GetDungeonsByRandom(uint32 randomdungeon); + LfgDungeonSet* GetAllDungeons(); + LfgReward* GetRandomDungeonReward(uint32 dungeon, bool done, uint8 level); + uint8 GetDungeonGroupType(uint32 dungeon); - LfgRewardList m_RewardList; - LfgRewardList m_RewardDoneList; - LfgDungeonMap m_DungeonsMap; + LfgRewardList m_RewardList; + LfgRewardList m_RewardDoneList; + LfgDungeonMap m_DungeonsMap; - LFGQueueMap m_Queues; - LfgRoleCheckMap m_RoleChecks; - uint32 m_QueueTimer; - bool m_update; + LFGQueueMap m_Queues; + LfgRoleCheckMap m_RoleChecks; + uint32 m_QueueTimer; + bool m_update; }; -#define sLFGMgr Trinity::Singleton<LFGMgr>::Instance() +#define sLFGMgr (*ACE_Singleton<LFGMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 510ea13e78b..2811cfa129f 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -23,7 +23,7 @@ #include "Player.h" #include "UpdateMask.h" #include "ObjectAccessor.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Opcodes.h" #include "GossipDef.h" #include "World.h" @@ -54,7 +54,7 @@ void Corpse::AddToWorld() { ///- Register the corpse for guid lookup if (!IsInWorld()) - ObjectAccessor::Instance().AddObject(this); + sObjectAccessor.AddObject(this); Object::AddToWorld(); } @@ -63,7 +63,7 @@ void Corpse::RemoveFromWorld() { ///- Remove the corpse from the accessor if (IsInWorld()) - ObjectAccessor::Instance().RemoveObject(this); + sObjectAccessor.RemoveObject(this); Object::RemoveFromWorld(); } diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index bab95e99d14..3ba00cec3b1 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -22,7 +22,7 @@ #define TRINITYCORE_CORPSE_H #include "Object.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "GridDefines.h" #include "LootMgr.h" diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index fbfae17a48b..7e79dc42664 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "World.h" #include "ObjectMgr.h" @@ -28,7 +28,7 @@ #include "QuestDef.h" #include "GossipDef.h" #include "Player.h" -#include "PoolHandler.h" +#include "PoolMgr.h" #include "Opcodes.h" #include "Log.h" #include "LootMgr.h" @@ -49,7 +49,7 @@ #include "Vehicle.h" #include "SpellAuraEffects.h" // apply implementation of the singletons -#include "Policies/SingletonImp.h" + TrainerSpell const* TrainerSpellData::Find(uint32 spell_id) const { @@ -171,11 +171,8 @@ Creature::~Creature() { m_vendorItemCounts.clear(); - if (i_AI) - { - delete i_AI; - i_AI = NULL; - } + delete i_AI; + i_AI = NULL; //if (m_uint32Values) // sLog.outError("Deconstruct Creature Entry = %u", GetEntry()); @@ -188,7 +185,7 @@ void Creature::AddToWorld() { if (m_zoneScript) m_zoneScript->OnCreatureCreate(this, true); - ObjectAccessor::Instance().AddObject(this); + sObjectAccessor.AddObject(this); Unit::AddToWorld(); SearchFormation(); AIM_Initialize(); @@ -206,7 +203,7 @@ void Creature::RemoveFromWorld() if (m_formation) formation_mgr.RemoveCreatureFromGroup(m_formation, this); Unit::RemoveFromWorld(); - ObjectAccessor::Instance().RemoveObject(this); + sObjectAccessor.RemoveObject(this); } } @@ -413,13 +410,7 @@ bool Creature::UpdateEntry(uint32 Entry, uint32 team, const CreatureData *data) if (isTrigger()) SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (isTotem() || isTrigger() - || GetCreatureType() == CREATURE_TYPE_CRITTER) - SetReactState(REACT_PASSIVE); - /*else if (isCivilian()) - SetReactState(REACT_DEFENSIVE);*/ - else - SetReactState(REACT_AGGRESSIVE); + InitializeReactState(); if (cInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_TAUNT) { @@ -629,7 +620,7 @@ void Creature::RegenerateMana() if ((*i)->GetMiscValue() == POWER_MANA) addvalue *= ((*i)->GetAmount() + 100) / 100.0f; - addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) * CREATURE_REGEN_INTERVAL / (5 * IN_MILISECONDS); + addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, POWER_MANA) * CREATURE_REGEN_INTERVAL / (5 * IN_MILLISECONDS); ModifyPower(POWER_MANA, addvalue); } @@ -666,7 +657,7 @@ void Creature::RegenerateHealth() for (AuraEffectList::const_iterator i = ModPowerRegenPCTAuras.begin(); i != ModPowerRegenPCTAuras.end(); ++i) addvalue *= ((*i)->GetAmount() + 100) / 100.0f; - addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * CREATURE_REGEN_INTERVAL / (5 * IN_MILISECONDS); + addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * CREATURE_REGEN_INTERVAL / (5 * IN_MILLISECONDS); ModifyHealth(addvalue); } @@ -721,7 +712,7 @@ bool Creature::AIM_Initialize(CreatureAI* ai) Motion_Initialize(); i_AI = ai ? ai : FactorySelector::selectAI(this); - if (oldAI) delete oldAI; + delete oldAI; IsAIEnabled = true; i_AI->InitializeAI(); return true; @@ -1271,16 +1262,26 @@ bool Creature::LoadFromDB(uint32 guid, Map *map) } } - uint32 curhealth = data->curhealth; - if (curhealth) + uint32 curhealth; + + if (!m_regenHealth) + { + curhealth = data->curhealth; + if (curhealth) + { + curhealth = uint32(curhealth*_GetHealthMod(GetCreatureInfo()->rank)); + if (curhealth < 1) + curhealth = 1; + } + SetPower(POWER_MANA,data->curmana); + } + else { - curhealth = uint32(curhealth*_GetHealthMod(GetCreatureInfo()->rank)); - if (curhealth < 1) - curhealth = 1; + curhealth = GetMaxHealth(); + SetPower(POWER_MANA,GetMaxPower(POWER_MANA)); } SetHealth(m_deathState == ALIVE ? curhealth : 0); - SetPower(POWER_MANA,data->curmana); // checked at creature_template loading m_defaultMovementType = MovementGeneratorType(data->movementType); @@ -1472,7 +1473,7 @@ void Creature::setDeathState(DeathState s) { if ((s == JUST_DIED && !m_isDeadByDefault)||(s == JUST_ALIVED && m_isDeadByDefault)) { - m_deathTimer = m_corpseDelay*IN_MILISECONDS; + m_deathTimer = m_corpseDelay*IN_MILLISECONDS; // always save boss respawn time at death to prevent crash cheating if (sWorld.getConfig(CONFIG_SAVE_RESPAWN_TIME_IMMEDIATELY) || isWorldBoss()) @@ -1605,6 +1606,9 @@ void Creature::Respawn(bool force) uint16 poolid = GetDBTableGUIDLow() ? poolhandler.IsPartOfAPool<Creature>(GetDBTableGUIDLow()) : 0; if (poolid) poolhandler.UpdatePool<Creature>(poolid, GetDBTableGUIDLow()); + + //Re-initialize reactstate that could be altered by movementgenerators + InitializeReactState(); } UpdateObjectVisibility(); @@ -1983,7 +1987,7 @@ void Creature::SaveRespawnTime() if (m_respawnTime > time(NULL)) // dead (no corpse) objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),m_respawnTime); else if (m_deathTimer > 0) // dead (corpse) - objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/IN_MILISECONDS); + objmgr.SaveCreatureRespawnTime(m_DBTableGuid,GetInstanceId(),time(NULL)+m_respawnDelay+m_deathTimer/IN_MILLISECONDS); } // this should not be called by petAI or @@ -2166,7 +2170,7 @@ void Creature::AddCreatureSpellCooldown(uint32 spellid) modOwner->ApplySpellMod(spellid, SPELLMOD_COOLDOWN, cooldown); if (cooldown) - _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/IN_MILISECONDS); + _AddCreatureSpellCooldown(spellid, time(NULL) + cooldown/IN_MILLISECONDS); if (spellInfo->Category) _AddCreatureCategoryCooldown(spellInfo->Category, time(NULL)); @@ -2185,7 +2189,7 @@ bool Creature::HasCategoryCooldown(uint32 spell_id) const return true; CreatureSpellCooldowns::const_iterator itr = m_CreatureCategoryCooldowns.find(spellInfo->Category); - return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILISECONDS)) > time(NULL)); + return(itr != m_CreatureCategoryCooldowns.end() && time_t(itr->second + (spellInfo->CategoryRecoveryTime / IN_MILLISECONDS)) > time(NULL)); } bool Creature::HasSpellCooldown(uint32 spell_id) const @@ -2209,7 +2213,7 @@ time_t Creature::GetRespawnTimeEx() const if (m_respawnTime > now) // dead (no corpse) return m_respawnTime; else if (m_deathTimer > 0) // dead (corpse) - return now+m_respawnDelay+m_deathTimer/IN_MILISECONDS; + return now+m_respawnDelay+m_deathTimer/IN_MILLISECONDS; else return now; } @@ -2251,7 +2255,7 @@ void Creature::AllLootRemovedFromCorpse() // corpse was not skinnable -> apply corpse looted timer if (!cinfo || !cinfo->SkinLootId) - nDeathTimer = (uint32)((m_corpseDelay * IN_MILISECONDS) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED)); + nDeathTimer = (uint32)((m_corpseDelay * IN_MILLISECONDS) * sWorld.getRate(RATE_CORPSE_DECAY_LOOTED)); // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update else nDeathTimer = 0; @@ -2413,7 +2417,7 @@ time_t Creature::GetLinkedCreatureRespawnTime() const if (data->mapid == GetMapId()) // look up on the same map targetMap = GetMap(); else // it shouldn't be instanceable map here - targetMap = MapManager::Instance().FindMap(data->mapid); + targetMap = sMapMgr.FindMap(data->mapid); } if (targetMap) return objmgr.GetCreatureRespawnTime(targetGuid,targetMap->GetInstanceId()); diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index d2d93d787da..203106f635e 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -26,7 +26,7 @@ #include "UpdateMask.h" #include "ItemPrototype.h" #include "LootMgr.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Cell.h" #include <list> @@ -66,7 +66,7 @@ enum CreatureFlagsExtra #endif #define MAX_KILL_CREDIT 2 -#define CREATURE_REGEN_INTERVAL 2 * IN_MILISECONDS +#define CREATURE_REGEN_INTERVAL 2 * IN_MILLISECONDS // from `creature_template` table struct CreatureInfo @@ -314,6 +314,9 @@ struct VendorItem int32 maxcount; // 0 for infinity item amount uint32 incrtime; // time for restore items amount if maxcount != 0 uint32 ExtendedCost; + + //helpers + bool IsGoldRequired(ItemPrototype const* pProto) const { return pProto->Flags2 & ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD || !ExtendedCost; } }; typedef std::vector<VendorItem*> VendorItemList; @@ -424,9 +427,20 @@ class Creature : public Unit, public GridObject<Creature> bool canWalk() const { return GetCreatureInfo()->InhabitType & INHABIT_GROUND; } bool canSwim() const { return GetCreatureInfo()->InhabitType & INHABIT_WATER; } //bool canFly() const { return GetCreatureInfo()->InhabitType & INHABIT_AIR; } + void SetReactState(ReactStates st) { m_reactState = st; } ReactStates GetReactState() { return m_reactState; } bool HasReactState(ReactStates state) const { return (m_reactState == state); } + void InitializeReactState() + { + if (isTotem() || isTrigger() || GetCreatureType() == CREATURE_TYPE_CRITTER) + SetReactState(REACT_PASSIVE); + else + SetReactState(REACT_AGGRESSIVE); + /*else if (isCivilian()) + SetReactState(REACT_DEFENSIVE);*/; + } + ///// TODO RENAME THIS!!!!! bool isCanTrainingOf(Player* player, bool msg) const; bool isCanInteractWithBattleMaster(Player* player, bool msg) const; @@ -607,10 +621,10 @@ class Creature : public Unit, public GridObject<Creature> bool hasInvolvedQuest(uint32 quest_id) const; bool isRegeneratingHealth() { return m_regenHealth; } - virtual uint8 GetPetAutoSpellSize() const { return CREATURE_MAX_SPELLS; } + virtual uint8 GetPetAutoSpellSize() const { return MAX_SPELL_CHARM; } virtual uint32 GetPetAutoSpellOnPos(uint8 pos) const { - if (pos >= CREATURE_MAX_SPELLS || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED) + if (pos >= MAX_SPELL_CHARM || m_charmInfo->GetCharmSpell(pos)->GetType() != ACT_ENABLED) return 0; else return m_charmInfo->GetCharmSpell(pos)->GetAction(); @@ -696,7 +710,7 @@ class Creature : public Unit, public GridObject<Creature> bool DisableReputationGain; - CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from ObjMgr::GetCreatureTemplate(GetEntry()) + CreatureInfo const* m_creatureInfo; // in difficulty mode > 0 can different from objmgr.::GetCreatureTemplate(GetEntry()) CreatureData const* m_creatureData; uint16 m_LootMode; // bitmask, default LOOT_MODE_DEFAULT, determines what loot will be lootable diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index c2af59458f7..7bd05123ec5 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -22,13 +22,11 @@ #include "CreatureGroups.h" #include "ObjectMgr.h" #include "ProgressBar.h" -#include "Policies/SingletonImp.h" + #include "CreatureAI.h" #define MAX_DESYNC 5.0f -INSTANTIATE_SINGLETON_1(CreatureGroupManager); - CreatureGroupInfoType CreatureGroupMap; void CreatureGroupManager::AddCreatureToGroup(uint32 groupId, Creature *member) diff --git a/src/server/game/Entities/Creature/CreatureGroups.h b/src/server/game/Entities/Creature/CreatureGroups.h index 521586b7457..4aa49571b5d 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.h +++ b/src/server/game/Entities/Creature/CreatureGroups.h @@ -35,12 +35,15 @@ struct FormationInfo class CreatureGroupManager { + friend class ACE_Singleton<CreatureGroupManager, ACE_Null_Mutex>; public: void AddCreatureToGroup(uint32 group_id, Creature *creature); void RemoveCreatureFromGroup(CreatureGroup *group, Creature *creature); void LoadCreatureFormations(); }; +#define formation_mgr (*ACE_Singleton<CreatureGroupManager, ACE_Null_Mutex>::instance()) + typedef UNORDERED_MAP<uint32/*memberDBGUID*/, FormationInfo*> CreatureGroupInfoType; extern CreatureGroupInfoType CreatureGroupMap; @@ -73,6 +76,4 @@ class CreatureGroup void MemberAttackStart(Creature* member, Unit *target); }; -#define formation_mgr Trinity::Singleton<CreatureGroupManager>::Instance() - #endif diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 3e0fec52bc7..cbbe7dc052b 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -522,7 +522,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const *pQuest, uint64 npcGUID, } // rewarded honor points. Multiply with 10 to satisfy client - data << uint32(10*Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills())); + data << 10 * Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()); data << float(0); // new 3.3.0, honor multiplier? data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0) data << int32(pQuest->GetRewSpellCast()); // casted spell @@ -616,7 +616,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const *pQuest) data << int32(pQuest->GetRewSpellCast()); // casted spell // rewarded honor points - data << uint32(Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills())); + data << Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()); data << float(0); // new reward honor (multipled by ~62 at client side) data << uint32(pQuest->GetSrcItemId()); // source item id data << uint32(pQuest->GetFlags() & 0xFFFF); // quest flags @@ -775,7 +775,7 @@ void PlayerMenu::SendQuestGiverOfferReward(Quest const* pQuest, uint64 npcGUID, data << uint32(pQuest->XPValue(pSession->GetPlayer())*sWorld.getRate(RATE_XP_QUEST)); // rewarded honor points. Multiply with 10 to satisfy client - data << uint32(10*Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills())); + data << 10 * Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills()); data << float(0); // unk, honor multiplier? data << uint32(0x08); // unused by client? data << uint32(pQuest->GetRewSpell()); // reward spell, this spell will display (icon) (casted if RewSpellCast == 0) diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index 48179190a6e..529710eda90 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -23,7 +23,7 @@ #include "Opcodes.h" #include "World.h" #include "ObjectAccessor.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "GridNotifiers.h" #include "CellImpl.h" #include "GridNotifiersImpl.h" @@ -46,7 +46,7 @@ void DynamicObject::AddToWorld() ///- Register the dynamicObject for guid lookup if (!IsInWorld()) { - ObjectAccessor::Instance().AddObject(this); + sObjectAccessor.AddObject(this); WorldObject::AddToWorld(); } } @@ -69,7 +69,7 @@ void DynamicObject::RemoveFromWorld() } } WorldObject::RemoveFromWorld(); - ObjectAccessor::Instance().RemoveObject(this); + sObjectAccessor.RemoveObject(this); } } diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 596b156bd35..c2458a181a5 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -22,14 +22,14 @@ #include "QuestDef.h" #include "GameObject.h" #include "ObjectMgr.h" -#include "PoolHandler.h" +#include "PoolMgr.h" #include "SpellMgr.h" #include "Spell.h" #include "UpdateMask.h" #include "Opcodes.h" #include "WorldPacket.h" #include "World.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "LootMgr.h" #include "GridNotifiers.h" #include "GridNotifiersImpl.h" @@ -117,7 +117,7 @@ void GameObject::AddToWorld() if (m_zoneScript) m_zoneScript->OnGameObjectCreate(this, true); - ObjectAccessor::Instance().AddObject(this); + sObjectAccessor.AddObject(this); WorldObject::AddToWorld(); } } @@ -139,7 +139,7 @@ void GameObject::RemoveFromWorld() sLog.outError("Delete GameObject (GUID: %u Entry: %u) that have references in not found creature %u GO list. Crash possible later.",GetGUIDLow(),GetGOInfo()->id,GUID_LOPART(owner_guid)); } WorldObject::RemoveFromWorld(); - ObjectAccessor::Instance().RemoveObject(this); + sObjectAccessor.RemoveObject(this); } } @@ -1626,7 +1626,7 @@ void GameObject::TakenDamage(uint32 damage, Unit *who) if (m_goValue->building.health <= m_goInfo->building.damagedNumHits) { if (!m_goInfo->building.destroyedDisplayId) - m_goValue->building.health = 0; + m_goValue->building.health = m_goInfo->building.damagedNumHits; else if (!m_goValue->building.health) m_goValue->building.health = 1; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 2154adf80c0..2c1765ea14e 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -25,7 +25,7 @@ #include "SharedDefines.h" #include "Object.h" #include "LootMgr.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" // GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push,N), also any gcc version not support it at some platform #if defined(__GNUC__) @@ -479,7 +479,7 @@ struct GameObjectInfo case GAMEOBJECT_TYPE_AREADAMAGE: autoCloseTime = areadamage.autoCloseTime; break; default: break; } - return autoCloseTime / IN_MILISECONDS; // prior to 3.0.3, conversion was / 0x10000; + return autoCloseTime / IN_MILLISECONDS; // prior to 3.0.3, conversion was / 0x10000; } uint32 GetLootId() const @@ -500,6 +500,16 @@ struct GameObjectInfo 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; + } + } }; class OPvPCapturePoint; diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index aa78126b198..12fd9efee28 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -20,7 +20,7 @@ #include "Common.h" #include "ObjectMgr.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Bag.h" #include "Log.h" @@ -117,11 +117,8 @@ bool Bag::LoadFromDB(uint32 guid, uint64 owner_guid, QueryResult_AutoPtr result) for (uint8 i = 0; i < MAX_BAG_SIZE; ++i) { SetUInt64Value(CONTAINER_FIELD_SLOT_1 + (i*2), 0); - if (m_bagslot[i]) - { - delete m_bagslot[i]; - m_bagslot[i] = NULL; - } + delete m_bagslot[i]; + m_bagslot[i] = NULL; } return true; diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 5c2d94d399b..52d9daeb4c8 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -18,11 +18,13 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + #include <ace/Auto_Ptr.h> + #include "Common.h" #include "Item.h" #include "ObjectMgr.h" #include "WorldPacket.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "ItemEnchantmentMgr.h" #include "SpellMgr.h" #include "ScriptMgr.h" @@ -633,7 +635,7 @@ void Item::SetState(ItemUpdateState state, Player *forplayer) { // pretend the item never existed RemoveFromUpdateQueueOf(forplayer); - forplayer->DeleteRefundReference(GetGUID()); + forplayer->DeleteRefundReference(GetGUIDLow()); delete this; return; } @@ -834,7 +836,7 @@ bool Item::IsTargetValidForItemUse(Unit* pUnitTarget) for (ConditionList::const_iterator itr = conditions.begin(); itr != conditions.end(); ++itr) { - ItemRequiredTarget *irt = new ItemRequiredTarget((ItemRequiredTargetType)(*itr)->mConditionValue1, (*itr)->mConditionValue2); + ACE_Auto_Ptr<ItemRequiredTarget> irt(new ItemRequiredTarget((ItemRequiredTargetType)(*itr)->mConditionValue1, (*itr)->mConditionValue2)); if (irt->IsFitToRequirements(pUnitTarget)) return true; } @@ -1035,20 +1037,11 @@ bool Item::IsBindedNotWith(Player const* player) const if (GetOwnerGUID() == player->GetGUID()) return false; - // not BOA item case - if (!IsBoundAccountWide()) - return true; - - // online - if (Player* owner = objmgr.GetPlayer(GetOwnerGUID())) - { - return owner->GetSession()->GetAccountId() != player->GetSession()->GetAccountId(); - } - // offline slow case - else - { - return objmgr.GetPlayerAccountIdByGUID(GetOwnerGUID()) != player->GetSession()->GetAccountId(); - } + // BOA item case + if (IsBoundAccountWide()) + return false; + + return true; } bool ItemRequiredTarget::IsFitToRequirements(Unit* pUnitTarget) const @@ -1106,7 +1099,7 @@ void Item::SetNotRefundable(Player *owner, bool changestate) SetPaidExtendedCost(0); DeleteRefundDataFromDB(); - owner->DeleteRefundReference(GetGUID()); + owner->DeleteRefundReference(GetGUIDLow()); } void Item::UpdatePlayedTime(Player *owner) @@ -1147,4 +1140,4 @@ uint32 Item::GetPlayedTime() bool Item::IsRefundExpired() { return (GetPlayedTime() > 2*HOUR); -}
\ No newline at end of file +} diff --git a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp index 8594ea864ba..440ea0027e8 100644 --- a/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp +++ b/src/server/game/Entities/Item/ItemEnchantmentMgr.cpp @@ -21,7 +21,7 @@ #include <stdlib.h> #include <functional> #include "ItemEnchantmentMgr.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "ObjectMgr.h" #include "ProgressBar.h" @@ -91,18 +91,10 @@ uint32 GetItemEnchantMod(int32 entry) if (!entry) return 0; - EnchantmentStore::const_iterator tab; - if (entry == -1) - { - tab = RandomItemEnch.begin(); - entry = urand(1, RandomItemEnch.size()) - 1; - for (uint32 i = 0; i < entry; ++i) - ++tab; - } - else - tab = RandomItemEnch.find(entry); - + return 0; + + EnchantmentStore::const_iterator tab = RandomItemEnch.find(entry); if (tab == RandomItemEnch.end()) { sLog.outErrorDb("Item RandomProperty / RandomSuffix id #%u used in `item_template` but it does not have records in `item_enchantment_template` table.",entry); diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 31025005a15..1a91ad10c6b 100644 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -111,8 +111,9 @@ enum ITEM_FLAGS ITEM_FLAGS_OPENABLE = 0x00000004, ITEM_FLAGS_WRAPPED = 0x00000008, ITEM_FLAGS_BROKEN = 0x00000010, // appears red icon (like when item durability == 0) - ITEM_FLAGS_TOTEM = 0x00000020, // ? + ITEM_FLAGS_INDESTRUCTIBLE = 0x00000020, // Item can not be destroyed, except by using spell (item can be reagent for spell and then allowed) ITEM_FLAGS_USABLE = 0x00000040, // ? + ITEM_FLAGS_NO_EQUIP_COOLDOWN = 0x00000080, // ? ITEM_FLAGS_WRAPPER = 0x00000200, // used or not used wrapper ITEM_FLAGS_PARTY_LOOT = 0x00000800, // determines if item is party loot or not ITEM_FLAGS_REFUNDABLE = 0x00001000, // item cost can be refunded within 2 hours after purchase @@ -135,7 +136,7 @@ enum ItemFlagsExtra { ITEM_FLAGS_EXTRA_HORDE_ONLY = 0x00000001, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY = 0x00000002, - ITEM_FLAGS_EXTRA_REFUNDABLE = 0x00000004, + ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD = 0x00000004, // when item uses extended cost, gold is also required ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100 }; @@ -623,7 +624,7 @@ struct ItemPrototype uint32 GetMaxStackSize() const { - return (Stackable == 2147483647 || Stackable <= 0 || Stackable == 1000) ? uint32(0x7FFFFFFF-1) : uint32(Stackable); + return (Stackable == 2147483647 || Stackable <= 0) ? uint32(0x7FFFFFFF-1) : uint32(Stackable); } float getDPS() const @@ -661,6 +662,17 @@ struct ItemLocale std::vector<std::string> Description; }; +struct ItemSetNameEntry +{ + std::string name; + uint32 InventoryType; +}; + +struct ItemSetNameLocale +{ + std::vector<std::string> Name; +}; + // GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform #if defined(__GNUC__) #pragma pack() diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 2a7397db8b8..fe4b8673b8f 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -35,7 +35,7 @@ #include "MapManager.h" #include "ObjectAccessor.h" #include "Log.h" -#include "Transports.h" +#include "Transport.h" #include "TargetedMovementGenerator.h" #include "WaypointMovementGenerator.h" #include "VMapFactory.h" @@ -110,16 +110,12 @@ Object::~Object() { sLog.outCrash("Object::~Object - guid="UI64FMTD", typeid=%d, entry=%u deleted but still in update list!!", GetGUID(), GetTypeId(), GetEntry()); assert(false); - ObjectAccessor::Instance().RemoveUpdateObject(this); + sObjectAccessor.RemoveUpdateObject(this); } - if (m_uint32Values) - { - //DEBUG_LOG("Object desctr 1 check (%p)",(void*)this); - delete [] m_uint32Values; - delete [] m_uint32Values_mirror; - //DEBUG_LOG("Object desctr 2 check (%p)",(void*)this); - } + delete [] m_uint32Values; + delete [] m_uint32Values_mirror; + } void Object::_InitValues() @@ -299,7 +295,11 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const { //WPAssert(this->ToPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE); - FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(const_cast<Player*>(this->ToPlayer())->GetMotionMaster()->top()); + Player *player = const_cast<Object*>(this)->ToPlayer(); + if (!player) + return; + + FlightPathMovementGenerator *fmg = (FlightPathMovementGenerator*)(player->GetMotionMaster()->top()); uint32 flags3 = MOVEFLAG_GLIDE; @@ -324,10 +324,10 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const } } - Path &path = fmg->GetPath(); + TaxiPathNodeList& path = const_cast<TaxiPathNodeList&>(fmg->GetPath()); float x, y, z; - this->ToPlayer()->GetPosition(x, y, z); + player->GetPosition(x, y, z); uint32 inflighttime = uint32(path.GetPassedLength(fmg->GetCurrentNode(), x, y, z) * 32); uint32 traveltime = uint32(path.GetTotalLength() * 32); @@ -342,21 +342,21 @@ void Object::_BuildMovementUpdate(ByteBuffer * data, uint16 flags) const *data << uint32(0); // added in 3.1 - uint32 poscount = uint32(path.Size()); + uint32 poscount = uint32(path.size()); *data << uint32(poscount); // points count for (uint32 i = 0; i < poscount; ++i) { - *data << path.GetNodes()[i].x; - *data << path.GetNodes()[i].y; - *data << path.GetNodes()[i].z; + *data << float(path[i].x); + *data << float(path[i].y); + *data << float(path[i].z); } *data << uint8(0); // added in 3.0.8 - *data << path.GetNodes()[poscount-1].x; - *data << path.GetNodes()[poscount-1].y; - *data << path.GetNodes()[poscount-1].z; + *data << float(path[poscount-1].x); + *data << float(path[poscount-1].y); + *data << float(path[poscount-1].z); } } else @@ -731,7 +731,7 @@ void Object::ClearUpdateMask(bool remove) if (m_objectUpdated) { if (remove) - ObjectAccessor::Instance().RemoveUpdateObject(this); + sObjectAccessor.RemoveUpdateObject(this); m_objectUpdated = false; } } @@ -804,7 +804,7 @@ void Object::SetInt32Value(uint16 index, int32 value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -823,7 +823,7 @@ void Object::SetUInt32Value(uint16 index, uint32 value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -849,7 +849,7 @@ void Object::SetUInt64Value(uint16 index, const uint64 &value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -868,7 +868,7 @@ bool Object::AddUInt64Value(uint16 index, const uint64 &value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -889,7 +889,7 @@ bool Object::RemoveUInt64Value(uint16 index, const uint64 &value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -910,7 +910,7 @@ void Object::SetFloatValue(uint16 index, float value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -936,7 +936,7 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -962,7 +962,7 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -1031,7 +1031,7 @@ void Object::SetFlag(uint16 index, uint32 newFlag) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -1052,7 +1052,7 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -1077,7 +1077,7 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -1102,7 +1102,7 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } @@ -1379,28 +1379,15 @@ bool Position::HasInArc(float arc, const Position *obj) const return true; // move arc to range 0.. 2*pi - while (arc >= 2.0f * M_PI) - arc -= 2.0f * M_PI; - while (arc < 0) - arc += 2.0f * M_PI; + arc = MapManager::NormalizeOrientation(arc); float angle = GetAngle(obj); angle -= m_orientation; - //if (angle > 100 || angle < -100) - //{ - // sLog.outCrash("Invalid Angle %f: this %u %u %f %f %f %f, that %u %u %f %f %f %f", angle, - // GetEntry(), GetGUIDLow(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation(), - // obj->GetEntry(), obj->GetGUIDLow(), obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), obj->GetOrientation()); - // assert(false); - // return false; - //} - // move angle to range -pi ... +pi - while (angle > M_PI) - angle -= 2.0f * M_PI; - while (angle < -M_PI) - angle += 2.0f * M_PI; + angle = MapManager::NormalizeOrientation(angle); + if(angle > M_PI) + angle -= 2.0f*M_PI; float lborder = -1 * (arc/2.0f); // in range -pi..0 float rborder = (arc/2.0f); // in range 0..pi @@ -1515,7 +1502,7 @@ void Object::ForceValuesUpdateAtIndex(uint32 i) { if (!m_objectUpdated) { - ObjectAccessor::Instance().AddUpdateObject(this); + sObjectAccessor.AddUpdateObject(this); m_objectUpdated = true; } } diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index c5a412c3ab7..ad7d0c072ab 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -24,7 +24,7 @@ #include "Common.h" #include "UpdateFields.h" #include "UpdateData.h" -#include "GameSystem/GridReference.h" +#include "GridReference.h" #include "ObjectDefines.h" #include "GridDefines.h" #include "Map.h" diff --git a/src/server/game/Entities/Object/ObjectDefines.h b/src/server/game/Entities/Object/ObjectDefines.h index a0e5ac1952d..15ce30d9a81 100644 --- a/src/server/game/Entities/Object/ObjectDefines.h +++ b/src/server/game/Entities/Object/ObjectDefines.h @@ -21,7 +21,7 @@ #ifndef TRINITY_OBJECTDEFINES_H #define TRINITY_OBJECTDEFINES_H -#include "Platform/Define.h" +#include "Define.h" // used for creating values for respawn for example #define MAKE_PAIR64(l, h) uint64(uint32(l) | (uint64(h) << 32)) diff --git a/src/server/game/Entities/Object/Updates/UpdateData.cpp b/src/server/game/Entities/Object/Updates/UpdateData.cpp index 68f0501f304..0b7a553d666 100644 --- a/src/server/game/Entities/Object/Updates/UpdateData.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateData.cpp @@ -25,7 +25,7 @@ #include "Log.h" #include "Opcodes.h" #include "World.h" -#include <zlib/zlib.h> +#include "zlib.h" UpdateData::UpdateData() : m_blockCount(0) { diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index 5f819375677..ecef0276e7a 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -21,7 +21,7 @@ #ifndef _UPDATEFIELDS_AUTO_H #define _UPDATEFIELDS_AUTO_H -// Auto generated for version 3, 3, 3, 11723 +// Auto generated for version 3, 3, 5, 12340 enum EObjectFields { diff --git a/src/server/game/Entities/Object/Updates/UpdateMask.h b/src/server/game/Entities/Object/Updates/UpdateMask.h index 527bec42aa7..a18a044ee33 100644 --- a/src/server/game/Entities/Object/Updates/UpdateMask.h +++ b/src/server/game/Entities/Object/Updates/UpdateMask.h @@ -32,8 +32,7 @@ class UpdateMask ~UpdateMask() { - if (mUpdateMask) - delete [] mUpdateMask; + delete [] mUpdateMask; } void SetBit (uint32 index) @@ -58,8 +57,7 @@ class UpdateMask void SetCount (uint32 valuesCount) { - if (mUpdateMask) - delete [] mUpdateMask; + delete [] mUpdateMask; mCount = valuesCount; mBlocks = (valuesCount + 31) / 32; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 45b07e7bd96..1f0533ddcda 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "WorldPacket.h" #include "ObjectMgr.h" @@ -74,7 +74,7 @@ void Pet::AddToWorld() if (!IsInWorld()) { ///- Register the pet for guid lookup - ObjectAccessor::Instance().AddObject(this); + sObjectAccessor.AddObject(this); Unit::AddToWorld(); AIM_Initialize(); } @@ -98,7 +98,7 @@ void Pet::RemoveFromWorld() { ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); - ObjectAccessor::Instance().RemoveObject(this); + sObjectAccessor.RemoveObject(this); } } @@ -324,9 +324,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petentry, uint32 petnumber, bool c if (result) { - if (m_declinedname) - delete m_declinedname; - + delete m_declinedname; m_declinedname = new DeclinedName; Field *fields2 = result->Fetch(); for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) @@ -621,7 +619,7 @@ void Creature::Regenerate(Powers power) if ((*i)->GetMiscValue() == power) addvalue *= ((*i)->GetAmount() + 100) / 100.0f; - addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * (isHunterPet()? PET_FOCUS_REGEN_INTERVAL : CREATURE_REGEN_INTERVAL) / (5 * IN_MILISECONDS); + addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * (isHunterPet()? PET_FOCUS_REGEN_INTERVAL : CREATURE_REGEN_INTERVAL) / (5 * IN_MILLISECONDS); ModifyPower(power, (int32)addvalue); } @@ -1114,7 +1112,7 @@ void Pet::_LoadSpellCooldowns() continue; data << uint32(spell_id); - data << uint32(uint32(db_time-curTime)*IN_MILISECONDS); + data << uint32(uint32(db_time-curTime)*IN_MILLISECONDS); _AddCreatureSpellCooldown(spell_id,db_time); @@ -1231,10 +1229,10 @@ void Pet::_LoadAuras(uint32 timediff) // negative effects should continue counting down after logout if (remaintime != -1 && !IsPositiveSpell(spellid)) { - if (remaintime/IN_MILISECONDS <= int32(timediff)) + if (remaintime/IN_MILLISECONDS <= int32(timediff)) continue; - remaintime -= timediff*IN_MILISECONDS; + remaintime -= timediff*IN_MILLISECONDS; } // prevent wrong values of remaincharges diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index 16e80170cd4..2c9b72b4fa6 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -118,7 +118,7 @@ typedef std::vector<uint32> AutoSpellList; #define PET_FOLLOW_DIST 1 #define PET_FOLLOW_ANGLE (M_PI/2) -#define PET_FOCUS_REGEN_INTERVAL 4 * IN_MILISECONDS +#define PET_FOCUS_REGEN_INTERVAL 4 * IN_MILLISECONDS class Player; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2221098a9be..5a8cb7b66fc 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -20,7 +20,7 @@ #include "Common.h" #include "Language.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "Opcodes.h" #include "SpellMgr.h" @@ -50,7 +50,7 @@ #include "Guild.h" #include "Pet.h" #include "Util.h" -#include "Transports.h" +#include "Transport.h" #include "Weather.h" #include "BattleGround.h" #include "BattleGroundAV.h" @@ -59,7 +59,7 @@ #include "OutdoorPvPMgr.h" #include "ArenaTeam.h" #include "Chat.h" -#include "Database/DatabaseImpl.h" +#include "DatabaseImpl.h" #include "Spell.h" #include "SocialMgr.h" #include "GameEventMgr.h" @@ -69,7 +69,7 @@ #include "ConditionMgr.h" #include <cmath> -#define ZONE_UPDATE_INTERVAL (1*IN_MILISECONDS) +#define ZONE_UPDATE_INTERVAL (1*IN_MILLISECONDS) #define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3)) #define PLAYER_SKILL_VALUE_INDEX(x) (PLAYER_SKILL_INDEX(x)+1) @@ -280,6 +280,105 @@ std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi) return ss; } +//== TradeData ================================================= + +TradeData* TradeData::GetTraderData() const +{ + return m_trader->GetTradeData(); +} + +Item* TradeData::GetItem(TradeSlots slot) const +{ + return m_items[slot] ? m_player->GetItemByGuid(m_items[slot]) : NULL; +} + +bool TradeData::HasItem(uint64 item_guid) const +{ + for(uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) + if (m_items[i] == item_guid) + return true; + + return false; +} + +Item* TradeData::GetSpellCastItem() const +{ + return m_spellCastItem ? m_player->GetItemByGuid(m_spellCastItem) : NULL; +} + +void TradeData::SetItem(TradeSlots slot, Item* item) +{ + uint64 itemGuid = item ? item->GetGUID() : 0; + + if (m_items[slot] == itemGuid) + return; + + m_items[slot] = itemGuid; + + SetAccepted(false); + GetTraderData()->SetAccepted(false); + + Update(); + + // need remove possible trader spell applied to changed item + if (slot == TRADE_SLOT_NONTRADED) + GetTraderData()->SetSpell(0); + + // need remove possible player spell applied (possible move reagent) + SetSpell(0); +} + +void TradeData::SetSpell(uint32 spell_id, Item* castItem /*= NULL*/) +{ + uint64 itemGuid = castItem ? castItem->GetGUID() : 0; + + if (m_spell == spell_id && m_spellCastItem == itemGuid) + return; + + m_spell = spell_id; + m_spellCastItem = itemGuid; + + SetAccepted(false); + GetTraderData()->SetAccepted(false); + + Update(true); // send spell info to item owner + Update(false); // send spell info to caster self +} + +void TradeData::SetMoney(uint32 money) +{ + if (m_money == money) + return; + + m_money = money; + + SetAccepted(false); + GetTraderData()->SetAccepted(false); + + Update(true); +} + +void TradeData::Update(bool forTarget /*= true*/) +{ + if (forTarget) + m_trader->GetSession()->SendUpdateTrade(true); // player state for trader + else + m_player->GetSession()->SendUpdateTrade(false); // player state for player +} + +void TradeData::SetAccepted(bool state, bool crosssend /*= false*/) +{ + m_accepted = state; + + if (!state) + { + if (crosssend) + m_trader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + else + m_player->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + } +} + // == Player ==================================================== UpdateMask Player::updateVisualBits; @@ -354,8 +453,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_bHasDelayedTeleport = false; m_teleport_options = 0; - pTrader = 0; - ClearTrade(); + m_trade = NULL; m_cinematic = 0; @@ -379,7 +477,7 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa m_swingErrorMsg = 0; - m_DetectInvTimer = 1*IN_MILISECONDS; + m_DetectInvTimer = 1*IN_MILLISECONDS; for (uint8 j = 0; j < PLAYER_MAX_BATTLEGROUND_QUEUES; ++j) { @@ -477,6 +575,8 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa //Default movement to run mode //m_unit_movement_flags = 0; + m_AreaID = 0; + m_mover = this; m_movedPlayer = this; m_seer = this; @@ -514,10 +614,7 @@ Player::~Player () // Note: buy back item already deleted from DB when player was saved for (uint8 i = 0; i < PLAYER_SLOTS_COUNT; ++i) - { - if (m_items[i]) - delete m_items[i]; - } + delete m_items[i]; for (PlayerSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr) delete itr->second; @@ -539,8 +636,7 @@ Player::~Player () delete PlayerTalkClass; for (size_t x = 0; x < ItemSetEff.size(); x++) - if (ItemSetEff[x]) - delete ItemSetEff[x]; + delete ItemSetEff[x]; delete m_declinedname; delete m_runes; @@ -591,7 +687,7 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c return false; } - SetMap(MapManager::Instance().CreateMap(info->mapId, this, 0)); + SetMap(sMapMgr.CreateMap(info->mapId, this, 0)); uint8 powertype = cEntry->powerType; @@ -941,12 +1037,12 @@ int32 Player::getMaxTimer(MirrorTimerType timer) switch (timer) { case FATIGUE_TIMER: - return MINUTE*IN_MILISECONDS; + return MINUTE*IN_MILLISECONDS; case BREATH_TIMER: { if (!isAlive() || HasAuraType(SPELL_AURA_WATER_BREATHING) || GetSession()->GetSecurity() >= sWorld.getConfig(CONFIG_DISABLE_BREATHING)) return DISABLED_MIRROR_TIMER; - int32 UnderWaterTime = 3*MINUTE*IN_MILISECONDS; + int32 UnderWaterTime = 3*MINUTE*IN_MILLISECONDS; AuraEffectList const& mModWaterBreathing = GetAuraEffectsByType(SPELL_AURA_MOD_WATER_BREATHING); for (AuraEffectList::const_iterator i = mModWaterBreathing.begin(); i != mModWaterBreathing.end(); ++i) UnderWaterTime = uint32(UnderWaterTime * (100.0f + (*i)->GetAmount()) / 100.0f); @@ -956,7 +1052,7 @@ int32 Player::getMaxTimer(MirrorTimerType timer) { if (!isAlive()) return DISABLED_MIRROR_TIMER; - return 1*IN_MILISECONDS; + return 1*IN_MILLISECONDS; } default: return 0; @@ -990,7 +1086,7 @@ void Player::HandleDrowning(uint32 time_diff) // Timer limit - need deal damage if (m_MirrorTimer[BREATH_TIMER] < 0) { - m_MirrorTimer[BREATH_TIMER]+= 1*IN_MILISECONDS; + m_MirrorTimer[BREATH_TIMER]+= 1*IN_MILLISECONDS; // Calculate and deal damage // TODO: Check this formula uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1); @@ -1026,7 +1122,7 @@ void Player::HandleDrowning(uint32 time_diff) // Timer limit - need deal damage or teleport ghost to graveyard if (m_MirrorTimer[FATIGUE_TIMER] < 0) { - m_MirrorTimer[FATIGUE_TIMER]+= 1*IN_MILISECONDS; + m_MirrorTimer[FATIGUE_TIMER]+= 1*IN_MILLISECONDS; if (isAlive()) // Calculate and deal damage { uint32 damage = GetMaxHealth() / 5 + urand(0, getLevel()-1); @@ -1059,7 +1155,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_MILISECONDS; + m_MirrorTimer[FIRE_TIMER]+= 1*IN_MILLISECONDS; // Calculate and deal damage // TODO: Check this formula uint32 damage = urand(600, 700); @@ -1394,7 +1490,7 @@ void Player::Update(uint32 p_time) { m_drunkTimer += p_time; - if (m_drunkTimer > 10*IN_MILISECONDS) + if (m_drunkTimer > 10*IN_MILLISECONDS) HandleSobering(); } @@ -1826,12 +1922,12 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati // Check enter rights before map getting to avoid creating instance copy for player // this check not dependent from map instance copy and same for all instance copies of selected map - if (!MapManager::Instance().CanPlayerEnter(mapid, this, false)) + if (!sMapMgr.CanPlayerEnter(mapid, this, false)) return false; // If the map is not created, assume it is possible to enter it. // It will be created in the WorldPortAck. - Map *map = MapManager::Instance().FindMap(mapid); + Map *map = sMapMgr.FindMap(mapid); if (!map || map->CanEnter(this)) { //lets reset near teleport flag if it wasn't reset during chained teleports @@ -2147,7 +2243,7 @@ void Player::Regenerate(Powers power) // Butchery requires combat for this effect if (power != POWER_RUNIC_POWER || isInCombat()) - addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILISECONDS); + addvalue += GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_POWER_REGEN, power) * ((power != POWER_ENERGY) ? m_regenTimerCount : m_regenTimer) / (5 * IN_MILLISECONDS); } if (addvalue < 0.0f) @@ -2225,7 +2321,7 @@ void Player::RegenerateHealth() for (AuraEffectList::const_iterator i = mModHealthRegenPct.begin(); i != mModHealthRegenPct.end(); ++i) addvalue *= (100.0f + (*i)->GetAmount()) / 100.0f; - addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 2 * IN_MILISECONDS / (5 * IN_MILISECONDS); + addvalue += GetTotalAuraModifier(SPELL_AURA_MOD_REGEN) * 2 * IN_MILLISECONDS / (5 * IN_MILLISECONDS); } else if (HasAuraType(SPELL_AURA_MOD_REGEN_DURING_COMBAT)) addvalue *= GetTotalAuraModifier(SPELL_AURA_MOD_REGEN_DURING_COMBAT) / 100.0f; @@ -2533,13 +2629,6 @@ void Player::GiveXP(uint32 xp, Unit* victim) // XP resting bonus for kill uint32 rested_bonus_xp = victim ? GetXPRestBonus(xp) : 0; - // Heirloom Experience Bonus - float heirloomModifier = 1.0f; - for (int i = 0; i < EQUIPMENT_SLOT_END; ++i) - if (m_items[i] && m_items[i]->GetProto()->Spells->SpellId == 57353) - heirloomModifier += 0.1f; - xp = uint32(xp * heirloomModifier); - SendLogXPGain(xp,victim,rested_bonus_xp); uint32 curXP = GetUInt32Value(PLAYER_XP); @@ -2889,7 +2978,7 @@ void Player::SendInitialSpells() continue; } - time_t cooldown = itr->second.end > curTime ? (itr->second.end-curTime)*IN_MILISECONDS : 0; + time_t cooldown = itr->second.end > curTime ? (itr->second.end-curTime)*IN_MILLISECONDS : 0; if (sEntry->Category) // may be wrong, but anyway better than nothing... { @@ -3342,7 +3431,7 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen if (!Has310Flyer(false) && pSkill->id == SKILL_MOUNTS) for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (spellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - spellInfo->CalculateSimpleValue(i) == 310) + SpellMgr::CalculateSpellEffectAmount(spellInfo, i) == 310) SetHas310Flyer(true); if (HasSkill(pSkill->id)) @@ -3447,6 +3536,15 @@ void Player::learnSpell(uint32 spell_id, bool dependent) bool learning = addSpell(spell_id,active,true,dependent,false); + // prevent duplicated entires in spell book, also not send if not in world (loading) + if (learning && IsInWorld()) + { + WorldPacket data(SMSG_LEARNED_SPELL, 6); + data << uint32(spell_id); + data << uint16(0); + GetSession()->SendPacket(&data); + } + // learn all disabled higher ranks and required spells (recursive) if (disabled) { @@ -3466,15 +3564,6 @@ void Player::learnSpell(uint32 spell_id, bool dependent) learnSpell(itr2->second, false); } } - - // prevent duplicated entires in spell book, also not send if not in world (loading) - if (!learning || !IsInWorld()) - return; - - WorldPacket data(SMSG_LEARNED_SPELL, 6); - data << uint32(spell_id); - data << uint16(0); - GetSession()->SendPacket(&data); } void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) @@ -3616,7 +3705,7 @@ void Player::removeSpell(uint32 spell_id, bool disabled, bool learn_low_rank) SpellEntry const *pSpellInfo = sSpellStore.LookupEntry(spell_id); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (pSpellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - pSpellInfo->CalculateSimpleValue(i) == 310) + SpellMgr::CalculateSpellEffectAmount(pSpellInfo, i) == 310) Has310Flyer(true, spell_id); // with true as first argument its also used to set/remove the flag } } @@ -3710,7 +3799,7 @@ bool Player::Has310Flyer(bool checkAllSpells, uint32 excludeSpellId) pSpellInfo = sSpellStore.LookupEntry(itr->first); for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) if (pSpellInfo->EffectApplyAuraName[i] == SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED && - pSpellInfo->CalculateSimpleValue(i) == 310) + SpellMgr::CalculateSpellEffectAmount(pSpellInfo, i) == 310) { SetHas310Flyer(true); return true; @@ -3767,8 +3856,8 @@ void Player::RemoveArenaSpellCooldowns() SpellEntry const * entry = sSpellStore.LookupEntry(itr->first); // check if spellentry is present and if the cooldown is less than 10 mins if (entry && - entry->RecoveryTime <= 10 * MINUTE * IN_MILISECONDS && - entry->CategoryRecoveryTime <= 10 * MINUTE * IN_MILISECONDS) + entry->RecoveryTime <= 10 * MINUTE * IN_MILLISECONDS && + entry->CategoryRecoveryTime <= 10 * MINUTE * IN_MILLISECONDS) { // remove & notify RemoveSpellCooldown(itr->first, true); @@ -4259,7 +4348,7 @@ void Player::DeleteFromDB(uint64 playerguid, uint32 accountId, bool updateRealmC // convert corpse to bones if exist (to prevent exiting Corpse in World without DB entry) // bones will be deleted by corpse/bones deleting thread shortly - ObjectAccessor::Instance().ConvertCorpseForPlayer(playerguid); + sObjectAccessor.ConvertCorpseForPlayer(playerguid); // remove from guild uint32 guildId = GetGuildIdFromDB(playerguid); @@ -4556,7 +4645,7 @@ void Player::ResurrectPlayer(float restore_percent, bool applySickness) if (Aura * aur = GetAura(15007, GetGUID())) { - aur->SetDuration(delta*IN_MILISECONDS); + aur->SetDuration(delta*IN_MILLISECONDS); } } } @@ -4609,7 +4698,7 @@ void Player::KillPlayer() ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(GetMapId())->Instanceable()); // 6 minutes until repop at graveyard - m_deathTimer = 6*MINUTE*IN_MILISECONDS; + m_deathTimer = 6*MINUTE*IN_MILLISECONDS; UpdateCorpseReclaimDelay(); // dependent at use SetDeathPvP() call before kill SendCorpseReclaimDelay(); @@ -4688,19 +4777,19 @@ void Player::CreateCorpse() corpse->SaveToDB(); // register for player, but not show - ObjectAccessor::Instance().AddCorpse(corpse); + sObjectAccessor.AddCorpse(corpse); } void Player::SpawnCorpseBones() { - if (ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID())) + if (sObjectAccessor.ConvertCorpseForPlayer(GetGUID())) if (!GetSession()->PlayerLogoutWithSave()) // at logout we will already store the player SaveToDB(); // prevent loading as ghost without corpse } Corpse* Player::GetCorpse() const { - return ObjectAccessor::Instance().GetCorpseForPlayerGUID(GetGUID()); + return sObjectAccessor.GetCorpseForPlayerGUID(GetGUID()); } void Player::DurabilityLossAll(double percent, bool inventory) @@ -6120,7 +6209,9 @@ bool Player::SetPosition(float x, float y, float z, float orientation, bool tele SetGroupUpdateFlag(GROUP_UPDATE_FLAG_POSITION); // code block for underwater state update - UpdateUnderwaterState(GetMap(), x, y, z); + // Unit::SetPosition() checks for validity and updates our coordinates + // so we re-fetch them instead of using "raw" coordinates from function params + UpdateUnderwaterState(GetMap(), GetPositionX(), GetPositionY(), GetPositionZ()); if (GetTrader() && !IsWithinDistInMap(GetTrader(), INTERACTION_DISTANCE)) GetSession()->SendCancelTrade(); @@ -6445,7 +6536,7 @@ void Player::RewardReputation(Quest const *pQuest) continue; if (pQuest->RewRepValue[i]) { - int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i], pQuest->RewRepFaction[i], true); + int32 rep = CalculateReputationGain(GetQuestLevel(pQuest), pQuest->RewRepValue[i]/100, pQuest->RewRepFaction[i], true); if (FactionEntry const* factionEntry = sFactionStore.LookupEntry(pQuest->RewRepFaction[i])) GetReputationMgr().ModifyReputation(factionEntry, rep); } @@ -6506,7 +6597,7 @@ void Player::UpdateHonorFields() ///Calculate the amount of honor gained based on the victim ///and the size of the group for which the honor is divided ///An exact honor value can also be given (overriding the calcs) -bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvptoken) +bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, int32 honor, bool pvptoken) { // do not reward honor in arenas, but enable onkill spellproc if (InArena()) @@ -6526,8 +6617,6 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt uint64 victim_guid = 0; uint32 victim_rank = 0; - //uint32 rank_diff = 0; - //time_t now = time(NULL); // need call before fields update to have chance move yesterday data to appropriate fields before today data change. UpdateHonorFields(); @@ -6536,7 +6625,10 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt if (InBattleGround() && GetBattleGround() && GetBattleGround()->isArena()) return true; - if (honor <= 0) + // Promote to float for calculations + float honor_f = honor; + + if (honor_f <= 0) { if (!uVictim || uVictim == this || uVictim->HasAuraType(SPELL_AURA_NO_PVP_CREDIT)) return false; @@ -6550,45 +6642,35 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt if (GetTeam() == pVictim->GetTeam() && !sWorld.IsFFAPvPRealm()) return false; - float f = 1; //need for total kills (?? need more info) - uint32 k_grey = 0; - uint32 k_level = getLevel(); - uint32 v_level = pVictim->getLevel(); - - { - // PLAYER_CHOSEN_TITLE VALUES DESCRIPTION - // [0] Just name - // [1..14] Alliance honor titles and player name - // [15..28] Horde honor titles and player name - // [29..38] Other title and player name - // [39+] Nothing - uint32 victim_title = pVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE); - // Get Killer titles, CharTitlesEntry::bit_index - // Ranks: - // title[1..14] -> rank[5..18] - // title[15..28] -> rank[5..18] - // title[other] -> 0 - if (victim_title == 0) - victim_guid = 0; // Don't show HK: <rank> message, only log. - else if (victim_title < 15) - victim_rank = victim_title + 4; - else if (victim_title < 29) - victim_rank = victim_title - 14 + 4; - else - victim_guid = 0; // Don't show HK: <rank> message, only log. - } - - k_grey = Trinity::XP::GetGrayLevel(k_level); + uint8 k_level = getLevel(); + uint8 k_grey = Trinity::XP::GetGrayLevel(k_level); + uint8 v_level = pVictim->getLevel(); if (v_level <= k_grey) return false; - float diff_level = (k_level == k_grey) ? 1 : ((float(v_level) - float(k_grey)) / (float(k_level) - float(k_grey))); - - int32 v_rank =1; //need more info + // PLAYER_CHOSEN_TITLE VALUES DESCRIPTION + // [0] Just name + // [1..14] Alliance honor titles and player name + // [15..28] Horde honor titles and player name + // [29..38] Other title and player name + // [39+] Nothing + uint32 victim_title = pVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE); + // Get Killer titles, CharTitlesEntry::bit_index + // Ranks: + // title[1..14] -> rank[5..18] + // title[15..28] -> rank[5..18] + // title[other] -> 0 + if (victim_title == 0) + victim_guid = 0; // Don't show HK: <rank> message, only log. + else if (victim_title < 15) + victim_rank = victim_title + 4; + else if (victim_title < 29) + victim_rank = victim_title - 14 + 4; + else + victim_guid = 0; // Don't show HK: <rank> message, only log. - honor = ((f * diff_level * (190 + v_rank*10))/6); - honor *= ((float)k_level) / 21.50537f; //factor of dependence on levels of the killer + honor_f = ceil(Trinity::Honor::hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey)); // count the number of playerkills in one day ApplyModUInt32Value(PLAYER_FIELD_KILLS, 1, true); @@ -6603,7 +6685,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt if (!uVictim->ToCreature()->isRacialLeader()) return false; - honor = 100; // ??? need more info + honor_f = 100.0f; // ??? need more info victim_rank = 19; // HK: Leader } } @@ -6611,35 +6693,37 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, float honor, bool pvpt if (uVictim != NULL) { if (groupsize > 1) - honor /= groupsize; + honor_f /= groupsize; // apply honor multiplier from aura (not stacking-get highest) - honor = int32(float(honor) * (float(GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT))+100.0f)/100.0f); + honor_f *= (GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT) + 100) / 100.0f; } - honor *= sWorld.getRate(RATE_HONOR); + honor_f *= sWorld.getRate(RATE_HONOR); + // Back to int now + honor = honor_f; // honor - for show honor points in log // victim_guid - for show victim name in log // victim_rank [1..4] HK: <dishonored rank> // victim_rank [5..19] HK: <alliance\horde rank> // victim_rank [0,20+] HK: <> WorldPacket data(SMSG_PVP_CREDIT,4+8+4); - data << (uint32) honor; - data << (uint64) victim_guid; - data << (uint32) victim_rank; + data << honor; + data << victim_guid; + data << victim_rank; GetSession()->SendPacket(&data); // add honor points - ModifyHonorPoints(int32(honor)); + ModifyHonorPoints(honor); - ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, uint32(honor), true); + ApplyModUInt32Value(PLAYER_FIELD_TODAY_CONTRIBUTION, honor, true); if (InBattleGround() && honor > 0) { if (BattleGround *bg = GetBattleGround()) { - bg->UpdatePlayerScore(this, SCORE_BONUS_HONOR, uint32(honor), false);//false: prevent looping + bg->UpdatePlayerScore(this, SCORE_BONUS_HONOR, honor, false); //false: prevent looping } } @@ -6762,7 +6846,7 @@ uint32 Player::GetZoneIdFromDB(uint64 guid) float posy = fields[2].GetFloat(); float posz = fields[3].GetFloat(); - zone = MapManager::Instance().GetZoneId(map,posx,posy,posz); + zone = sMapMgr.GetZoneId(map,posx,posy,posz); if (zone > 0) CharacterDatabase.PExecute("UPDATE characters SET zone='%u' WHERE guid='%u'", zone, guidLow); @@ -7725,6 +7809,10 @@ void Player::CastItemCombatSpell(Unit *target, WeaponAttackType attType, uint32 // Apply spell mods ApplySpellMod(pEnchant->spellid[s],SPELLMOD_CHANCE_OF_SUCCESS,chance); + + // Shiv has 100% chance to apply the poison + if (FindCurrentSpellBySpellId(5938)) + chance = 100.0f; if (roll_chance_f(chance)) { @@ -7757,7 +7845,7 @@ void Player::CastItemUseSpell(Item *item,SpellCastTargets const& targets,uint8 c Spell *spell = new Spell(this, spellInfo,false); spell->m_CastItem = item; spell->m_cast_count = cast_count; //set count of casts - spell->m_currentBasePoints[0] = learning_spell_id; + spell->m_currentBasePoints[0] = SpellMgr::CalculateSpellEffectBaseAmount(learning_spell_id); spell->prepare(&targets); return; } @@ -8017,7 +8105,7 @@ void Player::RemovedInsignia(Player* looterPlr) // We have to convert player corpse to bones, not to be able to resurrect there // SpawnCorpseBones isn't handy, 'cos it saves player while he in BG - Corpse *bones = ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID(),true); + Corpse *bones = sObjectAccessor.ConvertCorpseForPlayer(GetGUID(),true); if (!bones) return; @@ -9543,7 +9631,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) { Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item) + if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) { tempcount += pItem->GetCount(); if (tempcount >= count) @@ -9553,7 +9641,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const for (uint8 i = KEYRING_SLOT_START; i < CURRENCYTOKEN_SLOT_END; ++i) { Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item) + if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) { tempcount += pItem->GetCount(); if (tempcount >= count) @@ -9567,7 +9655,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const for (uint32 j = 0; j < pBag->GetBagSize(); j++) { Item* pItem = GetItemByPos(i, j); - if (pItem && pItem->GetEntry() == item) + if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) { tempcount += pItem->GetCount(); if (tempcount >= count) @@ -9582,7 +9670,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; i++) { Item *pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); - if (pItem && pItem->GetEntry() == item) + if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) { tempcount += pItem->GetCount(); if (tempcount >= count) @@ -9596,7 +9684,7 @@ bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const for (uint32 j = 0; j < pBag->GetBagSize(); j++) { Item* pItem = GetItemByPos(i, j); - if (pItem && pItem->GetEntry() == item) + if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) { tempcount += pItem->GetCount(); if (tempcount >= count) @@ -11817,7 +11905,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { - if (pItem->GetEntry() == item) + if (pItem->GetEntry() == item && !pItem->IsInTrade()) { if (pItem->GetCount() + remcount <= count) { @@ -11845,7 +11933,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { - if (pItem->GetEntry() == item) + if (pItem->GetEntry() == item && !pItem->IsInTrade()) { if (pItem->GetCount() + remcount <= count) { @@ -11878,7 +11966,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { if (Item* pItem = pBag->GetItemByPos(j)) { - if (pItem->GetEntry() == item) + if (pItem->GetEntry() == item && !pItem->IsInTrade()) { // all items in bags can be unequipped if (pItem->GetCount() + remcount <= count) @@ -11909,7 +11997,7 @@ void Player::DestroyItemCount(uint32 item, uint32 count, bool update, bool unequ { if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { - if (pItem && pItem->GetEntry() == item) + if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) { if (pItem->GetCount() + remcount <= count) { @@ -12155,7 +12243,7 @@ void Player::SplitItem(uint16 src, uint16 dst, uint32 count) BankItem(dest, pNewItem, true); if (isRefundable) { - AddRefundReference(pNewItem->GetGUID()); + AddRefundReference(pNewItem->GetGUIDLow()); pNewItem->SetPaidExtendedCost(pSrcItem->GetPaidExtendedCost()); pNewItem->SetPaidMoney(pSrcItem->GetPaidMoney()); pNewItem->SetRefundRecipient(GetGUIDLow()); @@ -12667,33 +12755,23 @@ void Player::SendSellError(uint8 msg, Creature* pCreature, uint64 guid, uint32 p GetSession()->SendPacket(&data); } -void Player::ClearTrade() -{ - tradeGold = 0; - acceptTrade = false; - for (uint8 i = 0; i < TRADE_SLOT_COUNT; i++) - tradeItems[i] = 0; -} - void Player::TradeCancel(bool sendback) { - if (pTrader) + if (m_trade) { + Player* trader = m_trade->GetTrader(); + // send yellow "Trade canceled" message to both traders - WorldSession* ws; - ws = GetSession(); if (sendback) - ws->SendCancelTrade(); - ws = pTrader->GetSession(); - if (!ws->PlayerLogout()) - ws->SendCancelTrade(); + GetSession()->SendCancelTrade(); + + trader->GetSession()->SendCancelTrade(); // cleanup - ClearTrade(); - pTrader->ClearTrade(); - // prevent loss of reference - pTrader->pTrader = NULL; - pTrader = NULL; + delete m_trade; + m_trade = NULL; + delete trader->m_trade; + trader->m_trade = NULL; } } @@ -13684,7 +13762,7 @@ void Player::PrepareQuestMenu(uint64 guid) { //we should obtain map pointer from GetMap() in 99% of cases. Special case //only for quests which cast teleport spells on player - Map * _map = IsInWorld() ? GetMap() : MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); + Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()); ASSERT(_map); GameObject *pGameObject = _map->GetGameObject(guid); if (pGameObject) @@ -13859,7 +13937,7 @@ Quest const * Player::GetNextQuest(uint64 guid, Quest const *pQuest) { //we should obtain map pointer from GetMap() in 99% of cases. Special case //only for quests which cast teleport spells on player - Map * _map = IsInWorld() ? GetMap() : MapManager::Instance().FindMap(GetMapId(), GetInstanceId()); + Map * _map = IsInWorld() ? GetMap() : sMapMgr.FindMap(GetMapId(), GetInstanceId()); ASSERT(_map); GameObject *pGameObject = _map->GetGameObject(guid); if (pGameObject) @@ -14135,10 +14213,10 @@ void Player::AddQuest(Quest const *pQuest, Object *questGiver) // shared timed quest if (questGiver && questGiver->GetTypeId() == TYPEID_PLAYER) - limittime = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].m_timer / IN_MILISECONDS; + limittime = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].m_timer / IN_MILLISECONDS; AddTimedQuest(quest_id); - questStatusData.m_timer = limittime * IN_MILISECONDS; + questStatusData.m_timer = limittime * IN_MILLISECONDS; qtime = static_cast<uint32>(time(NULL)) + limittime; } else @@ -14316,7 +14394,8 @@ void Player::RewardQuest(Quest const *pQuest, uint32 reward, Object* questGiver, if (pQuest->IsDaily()) { SetDailyQuestStatus(quest_id); - GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, 1); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST, quest_id); + GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_COMPLETE_DAILY_QUEST_DAILY, quest_id); } if (pQuest->IsWeekly()) @@ -15089,7 +15168,7 @@ void Player::KilledMonsterCredit(uint32 entry, uint64 guid) continue; // just if !ingroup || !noraidgroup || raidgroup QuestStatusData& q_status = mQuestStatus[questid]; - if (q_status.m_status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->GetType() == QUEST_TYPE_RAID)) + if (q_status.m_status == QUEST_STATUS_INCOMPLETE && (!GetGroup() || !GetGroup()->isRaidGroup() || qInfo->IsAllowedInRaid())) { if (qInfo->HasFlag(QUEST_TRINITY_FLAGS_KILL_OR_CAST)) { @@ -15372,7 +15451,7 @@ bool Player::HasQuestForItem(uint32 itemid) const continue; // hide quest if player is in raid-group and quest is no raid quest - if (GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID) + if (GetGroup() && GetGroup()->isRaidGroup() && !qinfo->IsAllowedInRaid()) if (!InBattleGround()) //there are two ways.. we can make every bg-quest a raidquest, or add this code here.. i don't know if this can be exploited by other quests, but i think all other quests depend on a specific area.. but keep this in mind, if something strange happens later continue; @@ -15439,7 +15518,7 @@ void Player::SendQuestReward(Quest const *pQuest, uint32 XP, Object * questGiver data << uint32(pQuest->GetRewOrReqMoney() + int32(pQuest->GetRewMoneyMaxLevel() * sWorld.getRate(RATE_DROP_MONEY))); } - data << uint32(10*Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills())); + data << 10 * Trinity::Honor::hk_honor_at_level(getLevel(), pQuest->GetRewHonorableKills()); data << uint32(pQuest->GetBonusTalents()); // bonus talents data << uint32(pQuest->GetRewArenaPoints()); GetSession()->SendPacket(&data); @@ -15564,9 +15643,7 @@ void Player::_LoadDeclinedNames(QueryResult_AutoPtr result) if (!result) return; - if (m_declinedname) - delete m_declinedname; - + delete m_declinedname; m_declinedname = new DeclinedName; Field *fields = result->Fetch(); for (uint8 i = 0; i < MAX_DECLINED_NAME_CASES; ++i) @@ -15816,11 +15893,8 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) SetUInt64Value(PLAYER_FIELD_INV_SLOT_HEAD + (slot * 2), 0); SetVisibleItemSlot(slot, NULL); - if (m_items[slot]) - { - delete m_items[slot]; - m_items[slot] = NULL; - } + delete m_items[slot]; + m_items[slot] = NULL; } sLog.outDebug("Load Basic value of player %s is: ", m_name.c_str()); @@ -15943,6 +16017,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) // There are no transports on instances instanceId = 0; + m_movementInfo.t_guid = MAKE_NEW_GUID(transGUID, 0, HIGHGUID_TRANSPORT); m_movementInfo.t_x = fields[26].GetFloat(); m_movementInfo.t_y = fields[27].GetFloat(); m_movementInfo.t_z = fields[28].GetFloat(); @@ -15962,7 +16037,7 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) } else { - for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter) + for (MapManager::TransportSet::iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter) { if ((*iter)->GetGUIDLow() == transGUID) { @@ -16031,21 +16106,24 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) // Map could be changed before mapEntry = sMapStore.LookupEntry(mapId); // client without expansion support - if (mapEntry && GetSession()->Expansion() < mapEntry->Expansion()) + if (mapEntry) { - sLog.outDebug("Player %s using client without required expansion tried login at non accessible map %u", GetName(), mapId); - RelocateToHomebind(); - } + if (GetSession()->Expansion() < mapEntry->Expansion()) + { + sLog.outDebug("Player %s using client without required expansion tried login at non accessible map %u", GetName(), mapId); + RelocateToHomebind(); + } - // fix crash (because of if (Map *map = _FindMap(instanceId)) in MapInstanced::CreateInstance) - if (instanceId) - if (InstanceSave * save = GetInstanceSave(mapId, mapEntry->IsRaid())) - if (save->GetInstanceId() != instanceId) - instanceId = 0; + // fix crash (because of if (Map *map = _FindMap(instanceId)) in MapInstanced::CreateInstance) + if (instanceId) + if (InstanceSave * save = GetInstanceSave(mapId, mapEntry->IsRaid())) + if (save->GetInstanceId() != instanceId) + instanceId = 0; + } // NOW player must have valid map // load the player's map here if it's not already loaded - Map *map = MapManager::Instance().CreateMap(mapId, this, instanceId); + Map *map = sMapMgr.CreateMap(mapId, this, instanceId); if (!map) { @@ -16063,14 +16141,14 @@ bool Player::LoadFromDB(uint32 guid, SqlQueryHolder *holder) RelocateToHomebind(); } - map = MapManager::Instance().CreateMap(mapId, this, 0); + map = sMapMgr.CreateMap(mapId, this, 0); if (!map) { PlayerInfo const *info = objmgr.GetPlayerInfo(getRace(), getClass()); mapId = info->mapId; Relocate(info->positionX,info->positionY,info->positionZ,0.0f); sLog.outError("ERROR: Player (guidlow %d) have invalid coordinates (X: %f Y: %f Z: %f O: %f). Teleport to default race/class locations.",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); - map = MapManager::Instance().CreateMap(mapId, this, 0); + map = sMapMgr.CreateMap(mapId, this, 0); if (!map) { sLog.outError("ERROR: Player (guidlow %d) has invalid default map coordinates (X: %f Y: %f Z: %f O: %f). or instance couldn't be created",guid,GetPositionX(),GetPositionY(),GetPositionZ(),GetOrientation()); @@ -16472,10 +16550,10 @@ void Player::_LoadAuras(QueryResult_AutoPtr result, uint32 timediff) // negative effects should continue counting down after logout if (remaintime != -1 && !IsPositiveSpell(spellid)) { - if (remaintime/IN_MILISECONDS <= int32(timediff)) + if (remaintime/IN_MILLISECONDS <= int32(timediff)) continue; - remaintime -= timediff*IN_MILISECONDS; + remaintime -= timediff*IN_MILLISECONDS; } // prevent wrong values of remaincharges @@ -16539,7 +16617,7 @@ void Player::_LoadGlyphAuras() void Player::LoadCorpse() { if (isAlive()) - ObjectAccessor::Instance().ConvertCorpseForPlayer(GetGUID()); + sObjectAccessor.ConvertCorpseForPlayer(GetGUID()); else { if (Corpse *corpse = GetCorpse()) @@ -16640,7 +16718,7 @@ void Player::_LoadInventory(QueryResult_AutoPtr result, uint32 timediff) item->SetRefundRecipient(fields[0].GetUInt32()); item->SetPaidMoney(fields[1].GetUInt32()); item->SetPaidExtendedCost(fields[2].GetUInt32()); - AddRefundReference(item->GetGUID()); + AddRefundReference(item->GetGUIDLow()); } } } @@ -16901,7 +16979,7 @@ void Player::_LoadQuestStatus(QueryResult_AutoPtr result) if (quest_time <= sWorld.GetGameTime()) questStatusData.m_timer = 1; else - questStatusData.m_timer = (quest_time - sWorld.GetGameTime()) * IN_MILISECONDS; + questStatusData.m_timer = (quest_time - sWorld.GetGameTime()) * IN_MILLISECONDS; } else quest_time = 0; @@ -17453,7 +17531,7 @@ bool Player::CheckInstanceLoginValid() } // do checks for satisfy accessreqs, instance full, encounter in progress (raid), perm bind group != perm bind player - return MapManager::Instance().CanPlayerEnter(GetMap()->GetId(), this, true); + return sMapMgr.CanPlayerEnter(GetMap()->GetId(), this, true); } bool Player::_LoadHomeBind(QueryResult_AutoPtr result) @@ -17801,14 +17879,14 @@ void Player::_SaveInventory() // the client auto counts down in real time after having received the initial played time on the first // SMSG_ITEM_REFUND_INFO_RESPONSE packet. // Item::UpdatePlayedTime is only called when needed, which is in DB saves, and item refund info requests. - std::set<uint64>::iterator i_next; - for (std::set<uint64>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end(); itr = i_next) + std::set<uint32>::iterator i_next; + for (std::set<uint32>::iterator itr = m_refundableItems.begin(); itr!= m_refundableItems.end(); itr = i_next) { // use copy iterator because itr may be invalid after operations in this loop i_next = itr; ++i_next; - Item* iPtr = GetItemByGuid(*itr); + Item* iPtr = GetItemByGuid(MAKE_NEW_GUID(*itr, 0, HIGHGUID_ITEM)); if (iPtr) { iPtr->UpdatePlayedTime(this); @@ -17816,7 +17894,7 @@ void Player::_SaveInventory() } else { - sLog.outError("Can't find item guid " UI64FMTD " but is in refundable storage for player %u ! Removing.", *itr, GetGUIDLow()); + sLog.outError("Can't find item guid %u but is in refundable storage for player %u ! Removing.", *itr, GetGUIDLow()); m_refundableItems.erase(itr); } } @@ -17945,11 +18023,11 @@ void Player::_SaveQuestStatus() case QUEST_NEW : CharacterDatabase.PExecute("INSERT INTO character_queststatus (guid,quest,status,rewarded,explored,timer,mobcount1,mobcount2,mobcount3,mobcount4,itemcount1,itemcount2,itemcount3,itemcount4) " "VALUES ('%u', '%u', '%u', '%u', '%u', '" UI64FMTD "', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')", - GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILISECONDS+ sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]); + GetGUIDLow(), i->first, i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILLISECONDS+ sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3]); break; case QUEST_CHANGED : CharacterDatabase.PExecute("UPDATE character_queststatus SET status = '%u',rewarded = '%u',explored = '%u',timer = '" UI64FMTD "',mobcount1 = '%u',mobcount2 = '%u',mobcount3 = '%u',mobcount4 = '%u',itemcount1 = '%u',itemcount2 = '%u',itemcount3 = '%u',itemcount4 = '%u' WHERE guid = '%u' AND quest = '%u' ", - i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILISECONDS + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first); + i->second.m_status, i->second.m_rewarded, i->second.m_explored, uint64(i->second.m_timer / IN_MILLISECONDS + sWorld.GetGameTime()), i->second.m_creatureOrGOcount[0], i->second.m_creatureOrGOcount[1], i->second.m_creatureOrGOcount[2], i->second.m_creatureOrGOcount[3], i->second.m_itemcount[0], i->second.m_itemcount[1], i->second.m_itemcount[2], i->second.m_itemcount[3], GetGUIDLow(), i->first); break; case QUEST_UNCHANGED: break; @@ -18292,7 +18370,7 @@ void Player::ResetInstances(uint8 method, bool isRaid) } // if the map is loaded, reset it - Map *map = MapManager::Instance().FindMap(p->GetMapId(), p->GetInstanceId()); + Map *map = sMapMgr.FindMap(p->GetMapId(), p->GetInstanceId()); if (map && map->IsDungeon()) if (!((InstanceMap*)map)->Reset(method)) { @@ -18647,7 +18725,7 @@ void Player::PetSpellInitialize() for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureSpellCooldowns.begin(); itr != pet->m_CreatureSpellCooldowns.end(); ++itr) { - time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILISECONDS : 0; + time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0; data << uint32(itr->first); // spellid data << uint16(0); // spell category? @@ -18657,7 +18735,7 @@ void Player::PetSpellInitialize() for (CreatureSpellCooldowns::const_iterator itr = pet->m_CreatureCategoryCooldowns.begin(); itr != pet->m_CreatureCategoryCooldowns.end(); ++itr) { - time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILISECONDS : 0; + time_t cooldown = (itr->second > curTime) ? (itr->second - curTime) * IN_MILLISECONDS : 0; data << uint32(itr->first); // spellid data << uint16(0); // spell category? @@ -18811,6 +18889,10 @@ bool Player::IsAffectedBySpellmod(SpellEntry const *spellInfo, SpellModifier *mo if (spell && mod->charges == -1 && spell->m_appliedMods.find(mod->ownerAura) == spell->m_appliedMods.end()) return false; + // +duration to infinite duration spells making them limited + if (mod->op == SPELLMOD_DURATION && GetSpellDuration(spellInfo) == -1) + return false; + return spellmgr.IsAffectedByMod(spellInfo, mod); } @@ -19372,8 +19454,8 @@ void Player::ContinueTaxiFlight() for (uint32 i = 1; i < nodeList.size(); ++i) { - TaxiPathNode const& node = nodeList[i]; - TaxiPathNode const& prevNode = nodeList[i-1]; + TaxiPathNodeEntry const& node = nodeList[i]; + TaxiPathNodeEntry const& prevNode = nodeList[i-1]; // skip nodes at another map if (node.mapid != GetMapId()) @@ -19431,7 +19513,7 @@ void Player::ProhibitSpellScholl(SpellSchoolMask idSchoolMask, uint32 unTimeMs) { data << uint32(unSpellId); data << uint32(unTimeMs); // in m.secs - AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/IN_MILISECONDS); + AddSpellCooldown(unSpellId, 0, curTime + unTimeMs/IN_MILLISECONDS); } } GetSession()->SendPacket(&data); @@ -19615,10 +19697,11 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 } } - int32 price = pProto->BuyPrice * count; + int32 price = crItem->IsGoldRequired(pProto) ? pProto->BuyPrice * count : 0; // reputation discount - price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); + if (price) + price = uint32(floor(price * GetReputationPriceDiscount(pCreature))); if (GetMoney() < price) { @@ -19672,7 +19755,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); it->SaveRefundDataToDB(); - AddRefundReference(it->GetGUID()); + AddRefundReference(it->GetGUIDLow()); } } } @@ -19730,7 +19813,7 @@ bool Player::BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); it->SaveRefundDataToDB(); - AddRefundReference(it->GetGUID()); + AddRefundReference(it->GetGUIDLow()); } } } @@ -19926,8 +20009,8 @@ void Player::AddSpellAndCategoryCooldowns(SpellEntry const* spellInfo, uint32 it if (rec == 0 && catrec == 0) return; - catrecTime = catrec ? curTime+catrec/IN_MILISECONDS : 0; - recTime = rec ? curTime+rec/IN_MILISECONDS : catrecTime; + catrecTime = catrec ? curTime+catrec/IN_MILLISECONDS : 0; + recTime = rec ? curTime+rec/IN_MILLISECONDS : catrecTime; } // self spell cooldown @@ -20919,6 +21002,9 @@ void Player::SendInstanceResetWarning(uint32 mapid, Difficulty difficulty, uint3 void Player::ApplyEquipCooldown(Item * pItem) { + if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_NO_EQUIP_COOLDOWN)) + return; + for (uint8 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i) { _Spell const& spellData = pItem->GetProto()->Spells[i]; @@ -21311,7 +21397,7 @@ bool Player::HasQuestForGO(int32 GOId) const if (!qinfo) continue; - if (GetGroup() && GetGroup()->isRaidGroup() && qinfo->GetType() != QUEST_TYPE_RAID) + if (GetGroup() && GetGroup()->isRaidGroup() && !qinfo->IsAllowedInRaid()) continue; for (uint8 j = 0; j < QUEST_OBJECTIVES_COUNT; ++j) @@ -21646,7 +21732,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim) continue; // member (alive or dead) or his corpse at req. distance // honor can be in PvP and !PvP (racial leader) cases (for alive) - if (pGroupGuy->isAlive() && pGroupGuy->RewardHonor(pVictim,count, -1, true) && pGroupGuy == this) + if (pGroupGuy->isAlive() && pGroupGuy->RewardHonor(pVictim, count, -1, true) && pGroupGuy == this) honored_kill = true; // xp and reputation only in !PvP case @@ -21690,7 +21776,7 @@ bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim) xp = (PvP || GetVehicle()) ? 0 : Trinity::XP::Gain(this, pVictim); // honor can be in PvP and !PvP (racial leader) cases - if (RewardHonor(pVictim,1, -1, true)) + if (RewardHonor(pVictim, 1, -1, true)) honored_kill = true; // xp and reputation only in !PvP case @@ -21938,7 +22024,7 @@ void Player::SendCorpseReclaimDelay(bool load) //! corpse reclaim delay 30 * 1000ms or longer at often deaths WorldPacket data(SMSG_CORPSE_RECLAIM_DELAY, 4); - data << uint32(delay*IN_MILISECONDS); + data << uint32(delay*IN_MILLISECONDS); GetSession()->SendPacket(&data); } @@ -23121,6 +23207,9 @@ void Player::BuildPlayerTalentsInfoData(WorldPacket *data) if (m_specsCount) { + if (m_specsCount > MAX_TALENT_SPECS) + m_specsCount = MAX_TALENT_SPECS; + // loop through all specs (only 1 for now) for (uint32 specIdx = 0; specIdx < m_specsCount; ++specIdx) { @@ -23751,14 +23840,14 @@ void Player::SendDuelCountdown(uint32 counter) GetSession()->SendPacket(&data); } -void Player::AddRefundReference(uint64 it) +void Player::AddRefundReference(uint32 it) { m_refundableItems.insert(it); } -void Player::DeleteRefundReference(uint64 it) +void Player::DeleteRefundReference(uint32 it) { - std::set<uint64>::iterator itr = m_refundableItems.find(it); + std::set<uint32>::iterator itr = m_refundableItems.find(it); if (itr != m_refundableItems.end()) { m_refundableItems.erase(itr); diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index d6de8679323..0b64d7e3821 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -26,7 +26,7 @@ #include "Unit.h" #include "Item.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "NPCHandler.h" #include "QuestDef.h" #include "Group.h" @@ -920,6 +920,55 @@ struct BGData bool HasTaxiPath() const { return taxiPath[0] && taxiPath[1]; } }; +class TradeData +{ + public: // constructors + TradeData(Player* player, Player* trader) : + m_player(player), m_trader(trader), m_accepted(false), m_acceptProccess(false), + m_money(0), m_spell(0) {} + + Player* GetTrader() const { return m_trader; } + TradeData* GetTraderData() const; + + Item* GetItem(TradeSlots slot) const; + bool HasItem(uint64 item_guid) const; + void SetItem(TradeSlots slot, Item* item); + + uint32 GetSpell() const { return m_spell; } + void SetSpell(uint32 spell_id, Item* castItem = NULL); + + Item* GetSpellCastItem() const; + bool HasSpellCastItem() const { return m_spellCastItem != 0; } + + uint32 GetMoney() const { return m_money; } + void SetMoney(uint32 money); + + bool IsAccepted() const { return m_accepted; } + void SetAccepted(bool state, bool crosssend = false); + + bool IsInAcceptProcess() const { return m_acceptProccess; } + void SetInAcceptProcess(bool state) { m_acceptProccess = state; } + + private: // internal functions + + void Update(bool for_trader = true); + + private: // fields + + Player* m_player; // Player who own of this TradeData + Player* m_trader; // Player who trade with m_player + + bool m_accepted; // m_player press accept for trade list + bool m_acceptProccess; // one from player/trader press accept and this processed + + uint32 m_money; // m_player place money to trade + + uint32 m_spell; // m_player apply spell to non-traded slot item + uint64 m_spellCastItem; // applied spell casted by item use + + uint64 m_items[TRADE_SLOT_COUNT]; // traded itmes from m_player side including non-traded slot +}; + class Player : public Unit, public GridObject<Player> { friend class WorldSession; @@ -1137,8 +1186,8 @@ class Player : public Unit, public GridObject<Player> uint8 _CanTakeMoreSimilarItems(uint32 entry, uint32 count, Item* pItem, uint32* no_space_count = NULL) const; uint8 _CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& dest, uint32 entry, uint32 count, Item *pItem = NULL, bool swap = false, uint32* no_space_count = NULL) const; - void AddRefundReference(uint64 it); - void DeleteRefundReference(uint64 it); + void AddRefundReference(uint32 it); + void DeleteRefundReference(uint32 it); void ApplyEquipCooldown(Item * pItem); void SetAmmo(uint32 item); @@ -1191,15 +1240,10 @@ class Player : public Unit, public GridObject<Player> bool BuyItemFromVendorSlot(uint64 vendorguid, uint32 vendorslot, uint32 item, uint8 count, uint8 bag, uint8 slot); float GetReputationPriceDiscount(Creature const* pCreature) const; - Player* GetTrader() const { return pTrader; } - void ClearTrade(); + + Player* GetTrader() const { return m_trade ? m_trade->GetTrader() : NULL; } + TradeData* GetTradeData() const { return m_trade; } void TradeCancel(bool sendback); - Item *GetItemByTradeSlot(uint8 slot) const - { - if (slot < TRADE_SLOT_COUNT && tradeItems[slot]) - return GetItemByGuid(tradeItems[slot]); - return NULL; - } void UpdateEnchantTime(uint32 time); void UpdateItemDuration(uint32 time, bool realtimeonly=false); @@ -1395,11 +1439,19 @@ class Player : public Unit, public GridObject<Player> if (d < 0) SetMoney (GetMoney() > uint32(-d) ? GetMoney() + d : 0); else - SetMoney (GetMoney() < uint32(MAX_MONEY_AMOUNT - d) ? GetMoney() + d : MAX_MONEY_AMOUNT); - - // "At Gold Limit" - if (GetMoney() >= MAX_MONEY_AMOUNT) - SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD,NULL,NULL); + { + uint32 newAmount = 0; + if (GetMoney() < uint32(MAX_MONEY_AMOUNT - d)) + newAmount = GetMoney() + d; + else + { + // "At Gold Limit" + newAmount = MAX_MONEY_AMOUNT; + if (d) + SendEquipError(EQUIP_ERR_TOO_MUCH_GOLD, NULL, NULL); + } + SetMoney (newAmount); + } } void SetMoney(uint32 value) { @@ -1874,7 +1926,7 @@ class Player : public Unit, public GridObject<Player> /*** PVP SYSTEM ***/ /*********************************************************/ void UpdateHonorFields(); - bool RewardHonor(Unit *pVictim, uint32 groupsize, float honor = -1, bool pvptoken = false); + bool RewardHonor(Unit *pVictim, uint32 groupsize, int32 honor = -1, bool pvptoken = false); uint32 GetHonorPoints() { return GetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY); } uint32 GetArenaPoints() { return GetUInt32Value(PLAYER_FIELD_ARENA_CURRENCY); } void ModifyHonorPoints(int32 value); @@ -2074,7 +2126,7 @@ class Player : public Unit, public GridObject<Player> /*** REST SYSTEM ***/ /*********************************************************/ - bool isRested() const { return GetRestTime() >= 10*IN_MILISECONDS; } + bool isRested() const { return GetRestTime() >= 10*IN_MILLISECONDS; } uint32 GetXPRestBonus(uint32 xp); uint32 GetRestTime() const { return m_restTime;} void SetRestTime(uint32 v) { m_restTime = v;} @@ -2460,10 +2512,7 @@ class Player : public Unit, public GridObject<Player> int m_cinematic; - Player *pTrader; - bool acceptTrade; - uint64 tradeItems[TRADE_SLOT_COUNT]; - uint32 tradeGold; + TradeData* m_trade; bool m_DailyQuestChanged; bool m_WeeklyQuestChanged; @@ -2535,7 +2584,7 @@ class Player : public Unit, public GridObject<Player> uint8 _CanStoreItem_InInventorySlots(uint8 slot_begin, uint8 slot_end, ItemPosCountVec& dest, ItemPrototype const *pProto, uint32& count, bool merge, Item *pSrcItem, uint8 skip_bag, uint8 skip_slot) const; Item* _StoreItem(uint16 pos, Item *pItem, uint32 count, bool clone, bool update); - std::set<uint64> m_refundableItems; + std::set<uint32> m_refundableItems; void SendRefundInfo(Item* item); void RefundItem(Item* item); diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index f0f27691007..0de95352d19 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -19,8 +19,8 @@ */ #include "SocialMgr.h" -#include "Policies/SingletonImp.h" -#include "Database/DatabaseEnv.h" + +#include "DatabaseEnv.h" #include "Opcodes.h" #include "WorldPacket.h" #include "Player.h" @@ -28,8 +28,6 @@ #include "World.h" #include "Util.h" -INSTANTIATE_SINGLETON_1(SocialMgr); - PlayerSocial::PlayerSocial() { m_playerGUID = 0; diff --git a/src/server/game/Entities/Player/SocialMgr.h b/src/server/game/Entities/Player/SocialMgr.h index 40f0066ec2e..1f40fcf28e9 100644 --- a/src/server/game/Entities/Player/SocialMgr.h +++ b/src/server/game/Entities/Player/SocialMgr.h @@ -21,8 +21,8 @@ #ifndef __TRINITY_SOCIALMGR_H #define __TRINITY_SOCIALMGR_H -#include "Policies/Singleton.h" -#include "Database/DatabaseEnv.h" +#include "ace/Singleton.h" +#include "DatabaseEnv.h" #include "Common.h" class SocialMgr; @@ -43,7 +43,8 @@ enum SocialFlag { SOCIAL_FLAG_FRIEND = 0x01, SOCIAL_FLAG_IGNORED = 0x02, - SOCIAL_FLAG_MUTED = 0x04 // guessed + SOCIAL_FLAG_MUTED = 0x04, // guessed + SOCIAL_FLAG_RAF = 0x08 // Recruit A Friend }; struct FriendInfo @@ -112,7 +113,7 @@ enum FriendsResult }; #define SOCIALMGR_FRIEND_LIMIT 50 -#define SOCIALMGR_IGNORE_LIMIT 25 +#define SOCIALMGR_IGNORE_LIMIT 50 class PlayerSocial { @@ -139,8 +140,9 @@ class PlayerSocial class SocialMgr { + friend class ACE_Singleton<SocialMgr, ACE_Null_Mutex>; + SocialMgr(); public: - SocialMgr(); ~SocialMgr(); // Misc void RemovePlayerSocial(uint32 guid) { m_socialMap.erase(guid); } @@ -156,6 +158,6 @@ class SocialMgr SocialMap m_socialMap; }; -#define sSocialMgr Trinity::Singleton<SocialMgr>::Instance() +#define sSocialMgr (*ACE_Singleton<SocialMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 444e115f8b9..2a82b5c33df 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -20,7 +20,7 @@ #include "Common.h" -#include "Transports.h" +#include "Transport.h" #include "MapManager.h" #include "ObjectMgr.h" #include "Path.h" @@ -106,7 +106,7 @@ void MapManager::LoadTransports() m_TransportsByMap[*i].insert(t); //If we someday decide to use the grid to track transports, here: - t->SetMap(MapManager::Instance().CreateMap(mapid, t, 0)); + t->SetMap(sMapMgr.CreateMap(mapid, t, 0)); //t->GetMap()->Add<GameObject>((GameObject *)t); ++count; @@ -185,18 +185,13 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z, struct keyFrame { - keyFrame(float _x, float _y, float _z, uint32 _mapid, int _actionflag, int _delay) - { - x = _x; y = _y; z = _z; mapid = _mapid; actionflag = _actionflag; delay = _delay; distFromPrev = -1; distSinceStop = -1; distUntilStop = -1; - tFrom = 0; tTo = 0; - } + explicit keyFrame(TaxiPathNodeEntry const& _node) : node(&_node), + distSinceStop(-1.0f), distUntilStop(-1.0f), distFromPrev(-1.0f), tFrom(0.0f), tTo(0.0f) + { + } + + TaxiPathNodeEntry const* node; - float x; - float y; - float z; - uint32 mapid; - int actionflag; - int delay; float distSinceStop; float distUntilStop; float distFromPrev; @@ -205,24 +200,24 @@ struct keyFrame bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) { - TransportPath path; - objmgr.GetTransportPathNodes(pathid, path); - - if (path.Empty()) + if (pathid >= sTaxiPathNodesByPath.size()) return false; + TaxiPathNodeList const& path = sTaxiPathNodesByPath[pathid]; + std::vector<keyFrame> keyFrames; int mapChange = 0; mapids.clear(); - for (size_t i = 1; i < path.Size() - 1; ++i) + for (size_t i = 1; i < path.size() - 1; ++i) { if (mapChange == 0) { - if ((path[i].mapid == path[i+1].mapid)) + TaxiPathNodeEntry const& node_i = path[i]; + if (node_i.mapid == path[i+1].mapid) { - keyFrame k(path[i].x, path[i].y, path[i].z, path[i].mapid, path[i].actionFlag, path[i].delay); + keyFrame k(node_i); keyFrames.push_back(k); - mapids.insert(k.mapid); + mapids.insert(k.node->mapid); } else { @@ -240,7 +235,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) // first cell is arrived at by teleportation :S keyFrames[0].distFromPrev = 0; - if (keyFrames[0].actionflag == 2) + if (keyFrames[0].node->actionFlag == 2) { lastStop = 0; } @@ -248,18 +243,18 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) // find the rest of the distances between key points for (size_t i = 1; i < keyFrames.size(); ++i) { - if ((keyFrames[i].actionflag == 1) || (keyFrames[i].mapid != keyFrames[i-1].mapid)) + if ((keyFrames[i].node->actionFlag == 1) || (keyFrames[i].node->mapid != keyFrames[i-1].node->mapid)) { keyFrames[i].distFromPrev = 0; } else { keyFrames[i].distFromPrev = - sqrt(pow(keyFrames[i].x - keyFrames[i - 1].x, 2) + - pow(keyFrames[i].y - keyFrames[i - 1].y, 2) + - pow(keyFrames[i].z - keyFrames[i - 1].z, 2)); + sqrt(pow(keyFrames[i].node->x - keyFrames[i - 1].node->x, 2) + + pow(keyFrames[i].node->y - keyFrames[i - 1].node->y, 2) + + pow(keyFrames[i].node->z - keyFrames[i - 1].node->z, 2)); } - if (keyFrames[i].actionflag == 2) + if (keyFrames[i].node->actionFlag == 2) { // remember first stop frame if (firstStop == -1) @@ -272,7 +267,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) for (size_t i = 0; i < keyFrames.size(); ++i) { int j = (i + lastStop) % keyFrames.size(); - if (keyFrames[j].actionflag == 2) + if (keyFrames[j].node->actionFlag == 2) tmpDist = 0; else tmpDist += keyFrames[j].distFromPrev; @@ -284,7 +279,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) int j = (i + (firstStop+1)) % keyFrames.size(); tmpDist += keyFrames[(j + 1) % keyFrames.size()].distFromPrev; keyFrames[j].distUntilStop = tmpDist; - if (keyFrames[j].actionflag == 2) + if (keyFrames[j].node->actionFlag == 2) tmpDist = 0; } @@ -312,14 +307,15 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) // speed = max(30, t) (remember x = 0.5s^2, and when accelerating, a = 1 unit/s^2 int t = 0; bool teleport = false; - if (keyFrames[keyFrames.size() - 1].mapid != keyFrames[0].mapid) + if (keyFrames[keyFrames.size() - 1].node->mapid != keyFrames[0].node->mapid) teleport = true; - WayPoint pos(keyFrames[0].mapid, keyFrames[0].x, keyFrames[0].y, keyFrames[0].z, teleport, 0); + WayPoint pos(keyFrames[0].node->mapid, keyFrames[0].node->x, keyFrames[0].node->y, keyFrames[0].node->z, teleport, 0, + keyFrames[0].node->arrivalEventID, keyFrames[0].node->departureEventID); m_WayPoints[0] = pos; - t += keyFrames[0].delay * 1000; + t += keyFrames[0].node->delay * 1000; - uint32 cM = keyFrames[0].mapid; + uint32 cM = keyFrames[0].node->mapid; for (size_t i = 0; i < keyFrames.size() - 1; ++i) { float d = 0; @@ -337,19 +333,19 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) if (d > 0) { float newX, newY, newZ; - newX = keyFrames[i].x + (keyFrames[i + 1].x - keyFrames[i].x) * d / keyFrames[i + 1].distFromPrev; - newY = keyFrames[i].y + (keyFrames[i + 1].y - keyFrames[i].y) * d / keyFrames[i + 1].distFromPrev; - newZ = keyFrames[i].z + (keyFrames[i + 1].z - keyFrames[i].z) * d / keyFrames[i + 1].distFromPrev; + newX = keyFrames[i].node->x + (keyFrames[i + 1].node->x - keyFrames[i].node->x) * d / keyFrames[i + 1].distFromPrev; + newY = keyFrames[i].node->y + (keyFrames[i + 1].node->y - keyFrames[i].node->y) * d / keyFrames[i + 1].distFromPrev; + newZ = keyFrames[i].node->z + (keyFrames[i + 1].node->z - keyFrames[i].node->z) * d / keyFrames[i + 1].distFromPrev; bool teleport = false; - if (keyFrames[i].mapid != cM) + if (keyFrames[i].node->mapid != cM) { teleport = true; - cM = keyFrames[i].mapid; + cM = keyFrames[i].node->mapid; } // sLog.outString("T: %d, D: %f, x: %f, y: %f, z: %f", t, d, newX, newY, newZ); - WayPoint pos(keyFrames[i].mapid, newX, newY, newZ, teleport, i); + WayPoint pos(keyFrames[i].node->mapid, newX, newY, newZ, teleport, 0); if (teleport) m_WayPoints[t] = pos; } @@ -389,14 +385,14 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) t += (long)keyFrames[i + 1].tTo % 100; bool teleport = false; - if ((keyFrames[i + 1].actionflag == 1) || (keyFrames[i + 1].mapid != keyFrames[i].mapid)) + if ((keyFrames[i + 1].node->actionFlag == 1) || (keyFrames[i + 1].node->mapid != keyFrames[i].node->mapid)) { teleport = true; - cM = keyFrames[i + 1].mapid; + cM = keyFrames[i + 1].node->mapid; } - WayPoint pos(keyFrames[i + 1].mapid, keyFrames[i + 1].x, keyFrames[i + 1].y, keyFrames[i + 1].z, teleport, i); - + WayPoint pos(keyFrames[i + 1].node->mapid, keyFrames[i + 1].node->x, keyFrames[i + 1].node->y, keyFrames[i + 1].node->z, teleport, + 0, keyFrames[i + 1].node->arrivalEventID, keyFrames[i + 1].node->departureEventID); // sLog.outString("T: %d, x: %f, y: %f, z: %f, t:%d", t, pos.x, pos.y, pos.z, teleport); /* if (keyFrames[i+1].delay > 5) @@ -405,7 +401,7 @@ bool Transport::GenerateWaypoints(uint32 pathid, std::set<uint32> &mapids) //if (teleport) m_WayPoints[t] = pos; - t += keyFrames[i + 1].delay * 1000; + t += keyFrames[i + 1].node->delay * 1000; // sLog.outString("------"); } @@ -459,7 +455,7 @@ void Transport::TeleportTransport(uint32 newMapid, float x, float y, float z) //yes, you're right ResetMap(); - Map * newMap = MapManager::Instance().CreateMap(newMapid, this, 0); + Map * newMap = sMapMgr.CreateMap(newMapid, this, 0); SetMap(newMap); assert (GetMap()); @@ -484,13 +480,6 @@ bool Transport::RemovePassenger(Player* passenger) return true; } -void Transport::CheckForEvent(uint32 entry, uint32 wp_id) -{ - uint32 key = entry*100+wp_id; - if (objmgr.TransportEventMap.find(key) != objmgr.TransportEventMap.end()) - GetMap()->ScriptsStart(sEventScripts, objmgr.TransportEventMap[key], this, NULL); -} - void Transport::Update(uint32 /*p_time*/) { if (m_WayPoints.size() <= 1) @@ -499,9 +488,13 @@ void Transport::Update(uint32 /*p_time*/) m_timer = getMSTime() % m_period; while (((m_timer - m_curr->first) % m_pathTime) > ((m_next->first - m_curr->first) % m_pathTime)) { + DoEventIfAny(*m_curr, true); + m_curr = GetNextWayPoint(); m_next = GetNextWayPoint(); + DoEventIfAny(*m_curr,false); + // first check help in case client-server transport coordinates de-synchronization if (m_curr->second.mapid != GetMapId() || m_curr->second.teleport) { @@ -548,9 +541,6 @@ void Transport::Update(uint32 /*p_time*/) if ((sLog.getLogFilter() & LOG_FILTER_TRANSPORT_MOVES) == 0) sLog.outDetail("%s moved to %d %f %f %f %d", this->m_name.c_str(), m_curr->second.id, m_curr->second.x, m_curr->second.y, m_curr->second.z, m_curr->second.mapid); - - //Transport Event System - CheckForEvent(this->GetEntry(), m_curr->second.id); } } @@ -587,3 +577,11 @@ void Transport::UpdateForMap(Map const* targetMap) } } +void Transport::DoEventIfAny(WayPointMap::value_type const& node, bool departure) +{ + if (uint32 eventid = departure ? node.second.departureEventID : node.second.arrivalEventID) + { + sLog.outDebug("Taxi %s event %u of node %u of %s path", departure ? "departure" : "arrival", eventid, node.first, GetName()); + GetMap()->ScriptsStart(sEventScripts, eventid, this, this); + } +} diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index 25b9ade1461..7b93d3e28a8 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -27,35 +27,6 @@ #include <set> #include <string> -class TransportPath -{ - public: - struct PathNode - { - uint32 mapid; - float x,y,z; - uint32 actionFlag; - uint32 delay; - }; - - void SetLength(const unsigned int sz) - { - i_nodes.resize(sz); - } - - unsigned int Size(void) const { return i_nodes.size(); } - bool Empty(void) const { return i_nodes.empty(); } - void Resize(unsigned int sz) { i_nodes.resize(sz); } - void Clear(void) { i_nodes.clear(); } - PathNode* GetNodes(void) { return static_cast<PathNode *>(&i_nodes[0]); } - - PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; } - const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; } - - protected: - std::vector<PathNode> i_nodes; -}; - class Transport : public GameObject { public: @@ -66,7 +37,6 @@ class Transport : public GameObject void Update(uint32 p_time); bool AddPassenger(Player* passenger); bool RemovePassenger(Player* passenger); - void CheckForEvent(uint32 entry, uint32 wp_id); typedef std::set<Player*> PlayerSet; PlayerSet const& GetPassengers() const { return m_passengers; } @@ -75,14 +45,20 @@ class Transport : public GameObject struct WayPoint { WayPoint() : mapid(0), x(0), y(0), z(0), teleport(false), id(0) {} - WayPoint(uint32 _mapid, float _x, float _y, float _z, bool _teleport, uint32 _id) : - mapid(_mapid), x(_x), y(_y), z(_z), teleport(_teleport), id(_id) {} + WayPoint(uint32 _mapid, float _x, float _y, float _z, bool _teleport, uint32 _id = 0, + uint32 _arrivalEventID = 0, uint32 _departureEventID = 0) + : mapid(_mapid), x(_x), y(_y), z(_z), teleport(_teleport), id(_id), + arrivalEventID(_arrivalEventID), departureEventID(_departureEventID) + { + } uint32 mapid; float x; float y; float z; bool teleport; uint32 id; + uint32 arrivalEventID; + uint32 departureEventID; }; typedef std::map<uint32, WayPoint> WayPointMap; @@ -102,6 +78,7 @@ class Transport : public GameObject private: void TeleportTransport(uint32 newMapid, float x, float y, float z); void UpdateForMap(Map const* map); + void DoEventIfAny(WayPointMap::value_type const& node, bool departure); WayPointMap::const_iterator GetNextWayPoint(); }; #endif diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 720e177075f..1fb662c43df 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -54,7 +54,7 @@ #include "Traveller.h" #include "TemporarySummon.h" #include "Vehicle.h" -#include "Transports.h" +#include "Transport.h" #include <math.h> @@ -201,10 +201,8 @@ Unit::~Unit() RemoveAllDynObjects(); _DeleteRemovedAuras(); - if (m_charmInfo) - delete m_charmInfo; - if (m_vehicleKit) - delete m_vehicleKit; + delete m_charmInfo; + delete m_vehicleKit; assert(!m_attacking); assert(m_attackers.empty()); @@ -437,29 +435,6 @@ void Unit::SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 M SendMessageToSet(&data, true); }*/ -void Unit::SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end) -{ - uint32 traveltime = uint32(path.GetTotalLength(start, end) * 32); - - uint32 pathSize = end - start; - - WorldPacket data(SMSG_MONSTER_MOVE, (GetPackGUID().size()+1+4+4+4+4+1+4+4+4+pathSize*4*3)); - data.append(GetPackGUID()); - data << uint8(0); - data << GetPositionX(); - data << GetPositionY(); - data << GetPositionZ(); - data << uint32(getMSTime()); - data << uint8(0); - data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight())? (MOVEFLAG_FLY|MOVEFLAG_WALK) : MOVEFLAG_WALK); - data << uint32(traveltime); - data << uint32(pathSize); - data.append((char*)path.GetNodes(start), pathSize * 4 * 3); - SendMessageToSet(&data, true); -//MONSTER_MOVE_SPLINE_FLY - addUnitState(UNIT_STAT_MOVE); -} - void Unit::SendMonsterMoveTransport(Unit *vehicleOwner) { WorldPacket data(SMSG_MONSTER_MOVE_TRANSPORT, GetPackGUID().size()+vehicleOwner->GetPackGUID().size()); @@ -587,23 +562,6 @@ void Unit::DealDamageMods(Unit *pVictim, uint32 &damage, uint32* absorb) uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDamage, DamageEffectType damagetype, SpellSchoolMask damageSchoolMask, SpellEntry const *spellProto, bool durabilityLoss) { - // if attacker is a player and spell is not empty/fail - if (GetTypeId() == TYPEID_PLAYER && spellProto) - { - // on divine storm dealed damage - heal - if (spellProto->SpellFamilyName == SPELLFAMILY_PALADIN && spellProto->SpellFamilyFlags[1] & 0x20000) - { - Unit *pRaidGrpMember = GetNextRandomRaidMemberOrPet(30.0f); - - int32 divineDmg = damage * (25 + (HasAura(63220) ? 15 : 0)) / 100; //25%, if has Glyph of Divine Storm -> 40% - - if (!pRaidGrpMember) - pRaidGrpMember = this; - - CastCustomSpell(pRaidGrpMember, 54172, &divineDmg, 0, 0, true); - } - } - if (pVictim->GetTypeId() == TYPEID_UNIT && pVictim->ToCreature()->IsAIEnabled) pVictim->ToCreature()->AI()->DamageTaken(this, damage); @@ -611,8 +569,26 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa { // interrupting auras with AURA_INTERRUPT_FLAG_DAMAGE before checking !damage (absorbed damage breaks that type of auras) pVictim->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_TAKE_DAMAGE, spellProto ? spellProto->Id : 0); - } + // copy damage to casters of this aura + AuraEffectList const& vCopyDamage = pVictim->GetAuraEffectsByType(SPELL_AURA_SHARE_DAMAGE_PCT); + for (AuraEffectList::const_iterator i = vCopyDamage.begin(); i != vCopyDamage.end(); ++i) + { + // check damage school mask + if (((*i)->GetMiscValue() & damageSchoolMask) == 0) + continue; + + Unit * shareDamageTarget = (*i)->GetCaster(); + if (!shareDamageTarget) + continue; + SpellEntry const * spell = (*i)->GetSpellProto(); + + uint32 share = damage * (float((*i)->GetAmount()) / 100.0f); + // TODO: check packets if damage is done by pVictim, or by attacker of pVicitm + DealDamageMods(shareDamageTarget, share, NULL); + DealDamage(shareDamageTarget, share, NULL, NODAMAGE, GetSpellSchoolMask(spell), spell, false); + } + } // Rage from Damage made (only from direct weapon damage) if (cleanDamage && damagetype == DIRECT_DAMAGE && this != pVictim && getPowerType() == POWER_RAGE) @@ -1816,14 +1792,20 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff if (spellProto->SpellIconID == 2253) { //reduces all damage taken while Stunned - if (unitflag & UNIT_FLAG_STUNNED) + if (pVictim->m_form == FORM_CAT && (unitflag & UNIT_FLAG_STUNNED)) RemainingDamage -= RemainingDamage * currentAbsorb / 100; continue; } - // Savage Defense (amount store original percent of attack power applied) - if (spellProto->SpellIconID == 50) // only spell with this aura fit + // Savage Defense + if (spellProto->SpellIconID == 146) { - RemainingDamage -= int32(currentAbsorb * pVictim->GetTotalAttackPowerValue(BASE_ATTACK) / 100); + if (RemainingDamage < currentAbsorb) + currentAbsorb = RemainingDamage; + + (*i)->SetAmount(0); // guarantee removal + existExpired = true; // maybe hacky but not crashy + + RemainingDamage -= currentAbsorb; continue; } // Moonkin Form passive @@ -2211,6 +2193,71 @@ void Unit::CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEff } } +void Unit::CalcHealAbsorb(Unit *pVictim, const SpellEntry *healSpell, uint32 &healAmount, uint32 &absorb) +{ + if (!healAmount) + return; + + int32 RemainingHeal = healAmount; + // Get unit state (need for some absorb check) + uint32 unitflag = pVictim->GetUInt32Value(UNIT_FIELD_FLAGS); + // Need remove expired auras after + bool existExpired = false; + + // absorb without mana cost + AuraEffectList const& vHealAbsorb = pVictim->GetAuraEffectsByType(SPELL_AURA_SCHOOL_HEAL_ABSORB); + for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end() && RemainingHeal > 0; ++i) + { + if (!((*i)->GetMiscValue() & healSpell->SchoolMask)) + continue; + + SpellEntry const* spellProto = (*i)->GetSpellProto(); + + // Max Amount can be absorbed by this aura + int32 currentAbsorb = (*i)->GetAmount(); + + // Found empty aura (impossible but..) + if (currentAbsorb <= 0) + { + existExpired = true; + continue; + } + + // currentAbsorb - damage can be absorbed by shield + // If need absorb less damage + if (RemainingHeal < currentAbsorb) + currentAbsorb = RemainingHeal; + + RemainingHeal -= currentAbsorb; + + // Reduce shield amount + (*i)->SetAmount((*i)->GetAmount() - currentAbsorb); + // Need remove it later + if ((*i)->GetAmount() <= 0) + existExpired = true; + } + + // Remove all expired absorb auras + if (existExpired) + { + for (AuraEffectList::const_iterator i = vHealAbsorb.begin(); i != vHealAbsorb.end();) + { + AuraEffect *auraEff = *i; + ++i; + if (auraEff->GetAmount() <= 0) + { + uint32 removedAuras = pVictim->m_removedAurasCount; + auraEff->GetBase()->Remove(AURA_REMOVE_BY_ENEMY_SPELL); + if (removedAuras+1 < pVictim->m_removedAurasCount) + i = vHealAbsorb.begin(); + } + } + } + + absorb = RemainingHeal > 0 ? (healAmount - RemainingHeal) : healAmount; + healAmount = RemainingHeal; +} + void Unit::AttackerStateUpdate (Unit *pVictim, WeaponAttackType attType, bool /*extra*/) { if (hasUnitState(UNIT_STAT_CANNOT_AUTOATTACK) || HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)) @@ -2846,11 +2893,12 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell) return SPELL_MISS_MISS; // Chance resist mechanic (select max value from every mechanic spell effect) - int32 resist_chance = pVictim->GetMechanicResistChance(spell); + int32 resist_chance = pVictim->GetMechanicResistChance(spell)*100; tmp += resist_chance; // Chance resist debuff - tmp -= pVictim->GetTotalAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)); + tmp += pVictim->GetMaxPositiveAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)) * 100; + tmp += pVictim->GetMaxNegativeAuraModifierByMiscValue(SPELL_AURA_MOD_DEBUFF_RESISTANCE, int32(spell->Dispel)) * 100; // Roll chance if (rand < tmp) @@ -3270,8 +3318,8 @@ void Unit::_UpdateAutoRepeatSpell() return; } - //apply delay - if (m_AutoRepeatFirstCast && getAttackTimer(RANGED_ATTACK) < 500) + //apply delay (Auto Shot (spellID 75) not affected) + if (m_AutoRepeatFirstCast && getAttackTimer(RANGED_ATTACK) < 500 && m_currentSpells[CURRENT_AUTOREPEAT_SPELL]->m_spellInfo->Id != 75) setAttackTimer(RANGED_ATTACK,500); m_AutoRepeatFirstCast = false; @@ -3521,7 +3569,18 @@ void Unit::_AddAura(UnitAura * aura, Unit * caster) if (Aura * foundAura = GetOwnedAura(aura->GetId(), aura->GetCasterGUID(), 0, aura)) { if (aura->GetSpellProto()->StackAmount) + { aura->ModStackAmount(foundAura->GetStackAmount()); + } + // Update periodic timers from the previous aura + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + AuraEffect *existingEff = foundAura->GetEffect(i); + AuraEffect *newEff = aura->GetEffect(i); + if (!existingEff || !newEff) + continue; + newEff->SetPeriodicTimer(existingEff->GetPeriodicTimer()); + } // Use the new one to replace the old one // This is the only place where AURA_REMOVE_BY_STACK should be used @@ -4118,7 +4177,7 @@ void Unit::RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit } else { - int32 dur = 2*MINUTE*IN_MILISECONDS < aura->GetDuration() ? 2*MINUTE*IN_MILISECONDS : aura->GetDuration(); + int32 dur = 2*MINUTE*IN_MILLISECONDS < aura->GetDuration() ? 2*MINUTE*IN_MILLISECONDS : aura->GetDuration(); newAura = Aura::TryCreate(aura->GetSpellProto(), effMask, stealer, NULL, &baseDamage[0], NULL, aura->GetCasterGUID()); if (!newAura) @@ -4335,16 +4394,14 @@ void Unit::RemoveAreaAurasDueToLeaveWorld() void Unit::RemoveAllAuras() { - while (!m_appliedAuras.empty() || !m_ownedAuras.empty()) - { - AuraApplicationMap::iterator aurAppIter = m_appliedAuras.begin(); - while (!m_appliedAuras.empty()) - _UnapplyAura(aurAppIter, AURA_REMOVE_BY_DEFAULT); + AuraApplicationMap::iterator aurAppIter; + for (aurAppIter = m_appliedAuras.begin(); aurAppIter != m_appliedAuras.end();) + _UnapplyAura(aurAppIter, AURA_REMOVE_BY_DEFAULT); + + AuraMap::iterator aurIter; + for (aurIter = m_ownedAuras.begin(); aurIter != m_ownedAuras.end();) + RemoveOwnedAura(aurIter); - AuraMap::iterator aurIter = m_ownedAuras.begin(); - while (!m_ownedAuras.empty()) - RemoveOwnedAura(aurIter); - } } void Unit::RemoveArenaAuras(bool onleave) @@ -6561,11 +6618,11 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger return false; // mana cost save - int32 mana = procSpell->manaCost + procSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints0 = mana * 40/100; + basepoints0 = CalculatePowerCost(procSpell, this, SpellSchoolMask(procSpell->SchoolMask)) * 4/10; if (basepoints0 <= 0) return false; + basepoints0 += 1; // standard basepoint increase for CastCustomSpell target = this; triggered_spell_id = 34720; break; @@ -7285,27 +7342,25 @@ bool Unit::HandleDummyAuraProc(Unit *pVictim, uint32 damage, AuraEffect* trigger sLog.outError("Unit::HandleDummyAuraProc: non handled spell id: %u (LO)", procSpell->Id); return false; } - // No thread generated mod - // TODO: exist special flag in spell attributes for this, need found and use! - SpellModifier *mod = new SpellModifier; - mod->op = SPELLMOD_THREAT; - mod->value = -100; - mod->type = SPELLMOD_PCT; - mod->spellId = dummySpell->Id; - mod->mask[0] = 0x02; - mod->mask[2] = 0x00; - this->ToPlayer()->AddSpellMod(mod, true); - - // Remove cooldown (Chain Lightning - have Category Recovery time) + + // Chain Lightning if (procSpell->SpellFamilyFlags[0] & 0x2) + { + // Chain lightning has [LightOverload_Proc_Chance] / [Max_Number_of_Targets] chance to proc of each individual target hit. + // A maxed LO would have a 33% / 3 = 11% chance to proc of each target. + // LO chance was already "accounted" at the proc chance roll, now need to divide the chance by [Max_Number_of_Targets] + float chance = 100.0f / procSpell->EffectChainTarget[effIndex]; + if (!roll_chance_f(chance)) + return false; + + // Remove cooldown (Chain Lightning - have Category Recovery time) ToPlayer()->RemoveSpellCooldown(spellId); + } CastSpell(pVictim, spellId, true, castItem, triggeredByAura); - this->ToPlayer()->AddSpellMod(mod, false); - if (cooldown && GetTypeId() == TYPEID_PLAYER) - ToPlayer()->AddSpellCooldown(dummySpell->Id,0,time(NULL) + cooldown); + ToPlayer()->AddSpellCooldown(dummySpell->Id, 0, time(NULL) + cooldown); return true; } @@ -7744,12 +7799,35 @@ bool Unit::HandleModDamagePctTakenAuraProc(Unit *pVictim, uint32 /*damage*/, Aur // Used in case when access to whole aura is needed // All procs should be handled like this... -bool Unit::HandleAuraProc(Unit * /*pVictim*/, uint32 damage, Aura * triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 procEx, uint32 /*cooldown*/, bool * handled) +bool Unit::HandleAuraProc(Unit * pVictim, uint32 damage, Aura * triggeredByAura, SpellEntry const * procSpell, uint32 /*procFlag*/, uint32 procEx, uint32 /*cooldown*/, bool * handled) { SpellEntry const *dummySpell = triggeredByAura->GetSpellProto(); switch(dummySpell->SpellFamilyName) { + case SPELLFAMILY_PALADIN: + { + // Infusion of Light + if (dummySpell->SpellIconID == 3021) + { + // Flash of Light HoT on Flash of Light when Sacred Shield active + if (procSpell->SpellFamilyFlags[0] & 0x40000000 && procSpell->SpellIconID == 242) + { + *handled = true; + if (pVictim->HasAura(53601)) + { + int32 bp0 = (damage/12) * SpellMgr::CalculateSpellEffectAmount(dummySpell, 2)/100; + CastCustomSpell(pVictim, 66922, &bp0, NULL, NULL, true); + return true; + } + } + // but should not proc on non-critical Holy Shocks + else if ((procSpell->SpellFamilyFlags[0] & 0x200000 || procSpell->SpellFamilyFlags[1] & 0x10000) && !(procEx & PROC_EX_CRITICAL_HIT)) + *handled = true; + break; + } + break; + } case SPELLFAMILY_MAGE: { // Combustion @@ -7783,7 +7861,7 @@ bool Unit::HandleAuraProc(Unit * /*pVictim*/, uint32 damage, Aura * triggeredByA if (!spInfo) return false; - int32 bp0 = this->GetCreateMana() * spInfo->CalculateSimpleValue(0) / 100; + int32 bp0 = this->GetCreateMana() * SpellMgr::CalculateSpellEffectAmount(spInfo, 0) / 100; this->CastCustomSpell(this, 67545, &bp0, NULL, NULL, true, NULL, triggeredByAura->GetEffect(0), this->GetGUID()); return true; } @@ -8137,6 +8215,24 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig target = pVictim; break; } + //Item - Coliseum 25 Heroic Caster Trinket + case 67758: + { + if(!pVictim || !pVictim->isAlive()) + return false; + // stacking + CastSpell(this, 67759, true, NULL, triggeredByAura); + + Aura * dummy = GetAura(67759); + // release at 3 aura in stack (cont contain in basepoint of trigger aura) + if(!dummy || dummy->GetStackAmount() < triggerAmount) + return false; + + RemoveAurasDueToSpell(67759); + trigger_spell_id = 67760; + target = pVictim; + break; + } default: // Illumination if (auraSpellInfo->SpellIconID == 241) @@ -8170,7 +8266,7 @@ bool Unit::HandleProcTriggerSpell(Unit *pVictim, uint32 damage, AuraEffect* trig } // percent stored in effect 1 (class scripts) base points int32 cost = originalSpell->manaCost + originalSpell->ManaCostPercentage * GetCreateMana() / 100; - basepoints0 = cost*auraSpellInfo->CalculateSimpleValue(1)/100; + basepoints0 = cost*SpellMgr::CalculateSpellEffectAmount(auraSpellInfo, 1)/100; trigger_spell_id = 20272; target = this; } @@ -9608,7 +9704,13 @@ void Unit::SetCharm(Unit* charm, bool apply) int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellProto, bool critical) { - int32 gain = pVictim->ModifyHealth(int32(addhealth)); + uint32 absorb = 0; + // calculate heal absorb and reduce healing + CalcHealAbsorb(pVictim, spellProto, addhealth, absorb); + int32 gain = 0; + + if (addhealth) + gain = pVictim->ModifyHealth(int32(addhealth)); Unit* unit = this; @@ -9618,7 +9720,7 @@ int32 Unit::DealHeal(Unit *pVictim, uint32 addhealth, SpellEntry const *spellPro if (unit->GetTypeId() == TYPEID_PLAYER) { // overheal = addhealth - gain - unit->SendHealSpellLog(pVictim, spellProto->Id, addhealth, addhealth - gain, critical); + unit->SendHealSpellLog(pVictim, spellProto->Id, addhealth, addhealth - gain, absorb, critical); if (BattleGround *bg = unit->ToPlayer()->GetBattleGround()) bg->UpdatePlayerScore((Player*)unit, SCORE_HEALING_DONE, gain); @@ -9823,7 +9925,7 @@ void Unit::UnsummonAllTotems() } } -void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical) +void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical) { // we guess size WorldPacket data(SMSG_SPELLHEALLOG, (8+8+4+4+4+4+1)); @@ -9832,7 +9934,7 @@ void Unit::SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 data << uint32(SpellID); data << uint32(Damage); data << uint32(OverHeal); - data << uint32(0); // Absorb amount + data << uint32(Absorb); // Absorb amount data << uint8(critical ? 1 : 0); SendMessageToSet(&data, true); } @@ -9955,7 +10057,8 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 case 5142: // Increased Lightning Damage case 5147: // Improved Consecration / Libram of Resurgence case 5148: // Idol of the Shooting Star - case 6008: // Increased Lightning Damage / Totem of Hex + case 6008: // Increased Lightning Damage + case 8627: // Totem of Hex { DoneTotal += (*i)->GetAmount(); break; @@ -10122,7 +10225,7 @@ uint32 Unit::SpellDamageBonus(Unit *pVictim, SpellEntry const *spellProto, uint3 case 49638: { if (const SpellEntry *proto=sSpellStore.LookupEntry(itr->first)) - ApCoeffMod *= (100.0f + proto->CalculateSimpleValue(0)) / 100.0f; + ApCoeffMod *= (100.0f + SpellMgr::CalculateSpellEffectAmount(proto, 0)) / 100.0f; } break; } @@ -10371,6 +10474,10 @@ int32 Unit::SpellBaseDamageBonusForVictim(SpellSchoolMask schoolMask, Unit *pVic bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolMask schoolMask, WeaponAttackType attackType) const { + // Mobs can't crit with spells. + if (IS_CREATURE_GUID(GetGUID())) + return false; + // not critting spell if ((spellProto->AttributesEx2 & SPELL_ATTR_EX2_CANT_CRIT)) return false; @@ -10445,7 +10552,7 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM } } // Custom crit by class - switch(spellProto->SpellFamilyName) + switch (spellProto->SpellFamilyName) { case SPELLFAMILY_DRUID: // Starfire @@ -10458,6 +10565,11 @@ bool Unit::isSpellCrit(Unit *pVictim, SpellEntry const *spellProto, SpellSchoolM break; } break; + case SPELLFAMILY_ROGUE: + // Shiv-applied poisons can't crit + if (FindCurrentSpellBySpellId(5938)) + crit_chance = 0.0f; + break; case SPELLFAMILY_PALADIN: // Flash of light if (spellProto->SpellFamilyFlags[0] & 0x40000000) @@ -10606,6 +10718,10 @@ uint32 Unit::SpellHealingBonus(Unit *pVictim, SpellEntry const *spellProto, uint if (Unit* owner = GetOwner()) return owner->SpellHealingBonus(pVictim, spellProto, healamount, damagetype, stack); + // no bonus for heal potions/bandages + if (spellProto->SpellFamilyName == SPELLFAMILY_POTION /*|| spellProto->Mechanic == MECHANIC_BANDAGE*/ ) + return healamount; + // Healing Done // Taken/Done total percent damage auras float DoneTotalMod = 1.0f; @@ -10877,7 +10993,7 @@ int32 Unit::SpellBaseHealingBonus(SpellSchoolMask schoolMask) AuraEffectList const& mHealingDone = GetAuraEffectsByType(SPELL_AURA_MOD_HEALING_DONE); for (AuraEffectList::const_iterator i = mHealingDone.begin(); i != mHealingDone.end(); ++i) - if (((*i)->GetMiscValue() & schoolMask) != 0) + if (!(*i)->GetMiscValue() || ((*i)->GetMiscValue() & schoolMask) != 0) AdvertisedBenefit += (*i)->GetAmount(); // Healing bonus of spirit, intellect and strength @@ -11094,17 +11210,7 @@ void Unit::MeleeDamageBonus(Unit *pVictim, uint32 *pdamage, WeaponAttackType att // ..done (base at attack power for marked target and base at attack power for creature type) int32 APbonus = 0; - if (attType == RANGED_ATTACK && pVictim->GetTypeId() == TYPEID_UNIT) - { - APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS); - - // ..done (base at attack power and creature type) - AuraEffectList const& mCreatureAttackPower = GetAuraEffectsByType(SPELL_AURA_MOD_RANGED_ATTACK_POWER_VERSUS); - for (AuraEffectList::const_iterator i = mCreatureAttackPower.begin(); i != mCreatureAttackPower.end(); ++i) - if (creatureTypeMask & uint32((*i)->GetMiscValue())) - APbonus += (*i)->GetAmount(); - } - else if (attType == RANGED_ATTACK) + if (attType == RANGED_ATTACK) { APbonus += pVictim->GetTotalAuraModifier(SPELL_AURA_RANGED_ATTACK_POWER_ATTACKER_BONUS); @@ -12419,7 +12525,7 @@ Unit* Creature::SelectVictim() //====================================================================== //====================================================================== -int32 Unit::ApplyEffectModifiers(SpellEntry const* spellProto, uint8 effect_index, int32 value) +int32 Unit::ApplyEffectModifiers(SpellEntry const* spellProto, uint8 effect_index, int32 value) const { if (Player* modOwner = GetSpellModOwner()) { @@ -12440,57 +12546,10 @@ int32 Unit::ApplyEffectModifiers(SpellEntry const* spellProto, uint8 effect_inde return value; } -int32 Unit::CalculateSpellDamage(Unit const* /*target*/, SpellEntry const* spellProto, uint8 effect_index, int32 const* effBasePoints) +// function uses real base points (typically value - 1) +int32 Unit::CalculateSpellDamage(Unit const* target, SpellEntry const* spellProto, uint8 effect_index, int32 const* basePoints) const { - int32 level = int32(getLevel()); - if (level > int32(spellProto->maxLevel) && spellProto->maxLevel > 0) - level = int32(spellProto->maxLevel); - else if (level < int32(spellProto->baseLevel)) - level = int32(spellProto->baseLevel); - level -= int32(spellProto->spellLevel); - - float basePointsPerLevel = spellProto->EffectRealPointsPerLevel[effect_index]; - int32 basePoints = effBasePoints ? *effBasePoints - 1 : spellProto->EffectBasePoints[effect_index]; - basePoints += int32(level * basePointsPerLevel); - int32 randomPoints = int32(spellProto->EffectDieSides[effect_index]); - - switch(randomPoints) - { - case 0: // not used - case 1: basePoints += 1; break; // range 1..1 - default: - // range can have positive (1..rand) and negative (rand..1) values, so order its for irand - int32 randvalue = (randomPoints >= 1) - ? irand(1, randomPoints) - : irand(randomPoints, 1); - - basePoints += randvalue; - break; - } - - int32 value = basePoints; - - // random damage - //if (comboDamage != 0 && unitPlayer /*&& target && (target->GetGUID() == unitPlayer->GetComboTarget())*/) - if (m_movedPlayer) - if (uint8 comboPoints = m_movedPlayer->GetComboPoints()) - if (float comboDamage = spellProto->EffectPointsPerComboPoint[effect_index]) - value += int32(comboDamage * comboPoints); - - value = ApplyEffectModifiers(spellProto, effect_index, value); - - if (!basePointsPerLevel && (spellProto->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION && spellProto->spellLevel) && - spellProto->Effect[effect_index] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && - spellProto->Effect[effect_index] != SPELL_EFFECT_KNOCK_BACK && - spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_SPEED_ALWAYS && - spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_SPEED_NOT_STACK && - spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_INCREASE_SPEED && - spellProto->EffectApplyAuraName[effect_index] != SPELL_AURA_MOD_DECREASE_SPEED) - //there are many more: slow speed, -healing pct - value = int32(value*0.25f*exp(getLevel()*(70-spellProto->spellLevel)/1000.0f)); - //value = int32(value * (int32)getLevel() / (int32)(spellProto->spellLevel ? spellProto->spellLevel : 1)); - - return value; + return SpellMgr::CalculateSpellEffectAmount(spellProto, effect_index, this, basePoints, target); } int32 Unit::CalcSpellDuration(SpellEntry const* spellProto) @@ -12575,7 +12634,7 @@ int32 Unit::ModSpellDuration(SpellEntry const* spellProto, Unit const* target, i { // Glyph of Thorns if (AuraEffect * aurEff = GetAuraEffect(57862, 0)) - duration += aurEff->GetAmount() * MINUTE * IN_MILISECONDS; + duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS; } break; case SPELLFAMILY_PALADIN: @@ -12583,13 +12642,13 @@ int32 Unit::ModSpellDuration(SpellEntry const* spellProto, Unit const* target, i { // Glyph of Blessing of Might if (AuraEffect * aurEff = GetAuraEffect(57958, 0)) - duration += aurEff->GetAmount() * MINUTE * IN_MILISECONDS; + duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS; } else if (spellProto->SpellFamilyFlags[0] & 0x00010000) { // Glyph of Blessing of Wisdom if (AuraEffect * aurEff = GetAuraEffect(57979, 0)) - duration += aurEff->GetAmount() * MINUTE * IN_MILISECONDS; + duration += aurEff->GetAmount() * MINUTE * IN_MILLISECONDS; } break; } @@ -12607,11 +12666,10 @@ void Unit::ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spel if (!(spellProto->Attributes & (SPELL_ATTR_UNK4|SPELL_ATTR_TRADESPELL)) && spellProto->SpellFamilyName) castTime = int32(float(castTime) * GetFloatValue(UNIT_MOD_CAST_SPEED)); - else - { - if (spellProto->Attributes & SPELL_ATTR_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)) - castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]); - } + else if (spellProto->Attributes & SPELL_ATTR_REQ_AMMO && !(spellProto->AttributesEx2 & SPELL_ATTR_EX2_AUTOREPEAT_FLAG)) + castTime = int32(float(castTime) * m_modAttackSpeedPct[RANGED_ATTACK]); + else if (spellProto->SpellVisual[0] == 3881 && HasAura(67556)) // cooking with Chef Hat. + castTime = 500; } DiminishingLevels Unit::GetDiminishing(DiminishingGroup group) @@ -12654,10 +12712,10 @@ void Unit::IncrDiminishing(DiminishingGroup group) m_Diminishing.push_back(DiminishingReturn(group,getMSTime(),DIMINISHING_LEVEL_2)); } -void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level, int32 limitduration) +float Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster,DiminishingLevels Level, int32 limitduration) { if (duration == -1 || group == DIMINISHING_NONE || caster->IsFriendlyTo(this)) - return; + return 1.0f; // test pet/charm masters instead pets/charmeds Unit const* targetOwner = GetCharmerOrOwner(); @@ -12711,6 +12769,7 @@ void Unit::ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Un } duration = int32(duration * mod); + return mod; } void Unit::ApplyDiminishingAura(DiminishingGroup group, bool apply) @@ -13277,8 +13336,7 @@ void Unit::UpdateCharmAI() { if (!isCharmed()) { - if (i_AI) - delete i_AI; + delete i_AI; i_AI = i_disabledAI; i_disabledAI = NULL; } @@ -13314,7 +13372,8 @@ void Unit::DeleteCharmInfo() } CharmInfo::CharmInfo(Unit* unit) -: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_petnumber(0), m_barInit(false) +: m_unit(unit), m_CommandState(COMMAND_FOLLOW), m_petnumber(0), m_barInit(false), + m_isCommandAttack(false), m_isAtStay(false), m_isFollowing(false), m_isReturning(false) { for (uint8 i = 0; i < MAX_SPELL_CHARM; ++i) m_charmspells[i].SetActionAndType(0,ACT_DISABLED); @@ -13623,7 +13682,6 @@ bool InitTriggerAuraData() isNonTriggerAura[SPELL_AURA_MOD_POWER_REGEN]=true; isNonTriggerAura[SPELL_AURA_REDUCE_PUSHBACK]=true; - isTriggerAura[SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS] = true; return true; } @@ -14064,7 +14122,7 @@ void Unit::StopMoving() // send explicit stop packet // rely on vmaps here because for example stormwind is in air - //float z = MapManager::Instance().GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); + //float z = sMapMgr.GetBaseMap(GetMapId())->GetHeight(GetPositionX(), GetPositionY(), GetPositionZ(), true); //if (fabs(GetPositionZ() - z) < 2.0f) // Relocate(GetPositionX(), GetPositionY(), z); //Relocate(GetPositionX(), GetPositionY(),GetPositionZ()); @@ -15146,6 +15204,10 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type) if (!charmer) return false; + // unmount players when charmed + if (GetTypeId() == TYPEID_PLAYER) + Unmount(); + assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER); assert((type == CHARM_TYPE_VEHICLE) == IsVehicle()); @@ -16272,7 +16334,7 @@ void Unit::NearTeleportTo(float x, float y, float z, float orientation, bool cas bool Unit::SetPosition(float x, float y, float z, float orientation, bool teleport) { // prevent crash when a bad coord is sent by the client - if (!Trinity::IsValidMapCoord(x,y)) + if (!Trinity::IsValidMapCoord(x,y,z,orientation)) { sLog.outDebug("Unit::SetPosition(%f, %f, %f) .. bad coordinates!",x,y,z); return false; diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index a2f4b2cd388..347a862b5d4 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -31,9 +31,12 @@ #include "HostileRefManager.h" #include "FollowerReference.h" #include "FollowerRefManager.h" -#include "Utilities/EventProcessor.h" +#include "EventProcessor.h" #include "MotionMaster.h" #include "DBCStructure.h" +#include "Path.h" +#include "WorldPacket.h" +#include "Timer.h" #include <list> #define WORLD_TRIGGER 12999 @@ -324,7 +327,6 @@ class DynamicObject; class GameObject; class Item; class Pet; -class Path; class PetAura; class Minion; class Guardian; @@ -1104,7 +1106,7 @@ class Unit : public WorldObject DiminishingLevels GetDiminishing(DiminishingGroup group); void IncrDiminishing(DiminishingGroup group); - void ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level, int32 limitduration); + float ApplyDiminishingToDuration(DiminishingGroup group, int32 &duration,Unit* caster, DiminishingLevels Level, int32 limitduration); void ApplyDiminishingAura(DiminishingGroup group, bool apply); void ClearDiminishings() { m_Diminishing.clear(); } @@ -1397,7 +1399,7 @@ class Unit : public WorldObject virtual bool IsUnderWater() const; bool isInAccessiblePlaceFor(Creature const* c) const; - void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, bool critical = false); + void SendHealSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage, uint32 OverHeal, uint32 Absorb, bool critical = false); void SendEnergizeSpellLog(Unit *pVictim, uint32 SpellID, uint32 Damage,Powers powertype); void EnergizeBySpell(Unit *pVictim, uint32 SpellID, uint32 Damage, Powers powertype); uint32 SpellNonMeleeDamageLog(Unit *pVictim, uint32 spellID, uint32 damage); @@ -1436,12 +1438,14 @@ class Unit : public WorldObject void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 Time, Player* player = NULL); void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint32 MoveFlags, uint32 time, float speedZ, Player *player = NULL); //void SendMonsterMove(float NewPosX, float NewPosY, float NewPosZ, uint8 type, uint32 MovementFlags, uint32 Time, Player* player = NULL); - void SendMonsterMoveByPath(Path const& path, uint32 start, uint32 end); void SendMonsterMoveTransport(Unit *vehicleOwner); void SendMonsterMoveWithSpeed(float x, float y, float z, uint32 transitTime = 0, Player* player = NULL); void SendMonsterMoveWithSpeedToCurrentDestination(Player* player = NULL); void SendMovementFlagUpdate(); + template<typename PathElem, typename PathNode> + void SendMonsterMoveByPath(Path<PathElem,PathNode> const& path, uint32 start, uint32 end); + void SendChangeCurrentVictimOpcode(HostileReference* pHostileReference); void SendClearThreatListOpcode(); void SendRemoveFromThreatListOpcode(HostileReference* pHostileReference); @@ -1525,7 +1529,7 @@ class Unit : public WorldObject void DeleteCharmInfo(); void UpdateCharmAI(); //Player * GetMoverSource() const; - Player *m_movedPlayer; + Player * m_movedPlayer; SharedVisionList const& GetSharedVisionList() { return m_sharedVision; } void AddPlayerToVision(Player* plr); void RemovePlayerFromVision(Player* plr); @@ -1831,6 +1835,7 @@ class Unit : public WorldObject uint32 CalcNotIgnoreDamageRedunction(uint32 damage, SpellSchoolMask damageSchoolMask); uint32 CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEntry const *spellInfo, WeaponAttackType attackType=MAX_ATTACK); void CalcAbsorbResist(Unit *pVictim, SpellSchoolMask schoolMask, DamageEffectType damagetype, const uint32 damage, uint32 *absorb, uint32 *resist, SpellEntry const *spellInfo = NULL); + void CalcHealAbsorb(Unit *pVictim, const SpellEntry *spellProto, uint32 &healAmount, uint32 &absorb); void UpdateSpeed(UnitMoveType mtype, bool forced); float GetSpeed(UnitMoveType mtype) const; @@ -1841,8 +1846,8 @@ class Unit : public WorldObject void SetHover(bool on); bool isHover() const { return HasAuraType(SPELL_AURA_HOVER); } - int32 ApplyEffectModifiers(SpellEntry const* spellProto, uint8 effect_index, int32 value); - int32 CalculateSpellDamage(Unit const* target, SpellEntry const* spellProto, uint8 effect_index, int32 const* basePoints = NULL); + int32 ApplyEffectModifiers(SpellEntry const* spellProto, uint8 effect_index, int32 value) const; + int32 CalculateSpellDamage(Unit const* target, SpellEntry const* spellProto, uint8 effect_index, int32 const* basePoints = NULL) const; int32 CalcSpellDuration(SpellEntry const* spellProto); int32 ModSpellDuration(SpellEntry const* spellProto, Unit const* target, int32 duration, bool positive); void ModSpellCastTime(SpellEntry const* spellProto, int32 & castTime, Spell * spell=NULL); @@ -2116,4 +2121,30 @@ namespace Trinity }; } +template<typename Elem, typename Node> +inline void Unit::SendMonsterMoveByPath(Path<Elem,Node> const& path, uint32 start, uint32 end) +{ + uint32 traveltime = uint32(path.GetTotalLength(start, end) * 32); + uint32 pathSize = end - start; + WorldPacket data(SMSG_MONSTER_MOVE, (GetPackGUID().size()+1+4+4+4+4+1+4+4+4+pathSize*4*3)); + data.append(GetPackGUID()); + data << uint8(0); + data << GetPositionX(); + data << GetPositionY(); + data << GetPositionZ(); + data << uint32(getMSTime()); + data << uint8(0); + data << uint32(((GetUnitMovementFlags() & MOVEMENTFLAG_LEVITATING) || isInFlight()) ? (MOVEFLAG_FLY|MOVEFLAG_WALK) : MOVEFLAG_WALK); + data << uint32(traveltime); + data << uint32(pathSize); + + for (uint32 i = start; i < end; ++i) + { + data << float(path[i].x); + data << float(path[i].y); + data << float(path[i].z); + } + + SendMessageToSet(&data, true); +} #endif diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index a154c579605..850296aaafe 100644 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -39,6 +39,27 @@ Vehicle::Vehicle(Unit *unit, VehicleEntry const *vehInfo) : me(unit), m_vehicleI ++m_usableSeatNum; } } + + // HACKY WAY, We must found a more generic way to handle this + // Set inmunities since db ones are rewritten with player's ones + switch (GetVehicleInfo()->m_ID) + { + case 160: + me->SetControlled(true, UNIT_STAT_ROOT); + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_KNOCK_BACK, true); + case 158: + me->ApplySpellImmune(0, IMMUNITY_EFFECT, SPELL_EFFECT_HEAL, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_FEAR, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_PERIODIC_HEAL, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_STUN, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_ROOT, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DECREASE_SPEED, true); + me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_CONFUSE, true); + me->ApplySpellImmune(0, IMMUNITY_ID, 49560, true); // Death Grip jump effect + break; + default: + break; + } assert(!m_Seats.empty()); } diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index a2c6f2f2422..f0500e177bb 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -22,18 +22,15 @@ #include "World.h" #include "ObjectMgr.h" #include "WorldPacket.h" -#include "PoolHandler.h" +#include "PoolMgr.h" #include "ProgressBar.h" #include "Language.h" #include "Log.h" #include "MapManager.h" -#include "Policies/SingletonImp.h" #include "GossipDef.h" #include "Player.h" #include "BattleGroundMgr.h" -INSTANTIATE_SINGLETON_1(GameEventMgr); - bool GameEventMgr::CheckOneGameEvent(uint16 entry) const { switch(mGameEvent[entry].state) @@ -1154,7 +1151,7 @@ uint32 GameEventMgr::Update() // return the next e for (std::set<uint16>::iterator itr = deactivate.begin(); itr != deactivate.end(); ++itr) StopEvent(*itr); sLog.outDetail("Next game event check in %u seconds.", nextEventDelay + 1); - return (nextEventDelay + 1) * IN_MILISECONDS; // Add 1 second to be sure event has started/stopped at next call + return (nextEventDelay + 1) * IN_MILLISECONDS; // Add 1 second to be sure event has started/stopped at next call } void GameEventMgr::UnApplyEvent(uint16 event_id) @@ -1270,7 +1267,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) objmgr.AddCreatureToGrid(*itr, data); // Spawn if necessary (loaded grids only) - Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(data->mapid)); + Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid)); // We use spawn coords to spawn if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { @@ -1298,7 +1295,7 @@ void GameEventMgr::GameEventSpawn(int16 event_id) objmgr.AddGameobjectToGrid(*itr, data); // Spawn if necessary (loaded grids only) // this base map checked as non-instanced and then only existed - Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(data->mapid)); + Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid)); // We use current coords to unspawn, not spawn coords since creature can have changed grid if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { @@ -1345,7 +1342,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { objmgr.RemoveCreatureFromGrid(*itr, data); - if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT), (Creature*)NULL)) + if (Creature* pCreature = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_UNIT), (Creature*)NULL)) pCreature->AddObjectToRemoveList(); } } @@ -1366,7 +1363,7 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { objmgr.RemoveGameobjectFromGrid(*itr, data); - if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) + if (GameObject* pGameobject = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(*itr, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) pGameobject->AddObjectToRemoveList(); } } @@ -1392,7 +1389,7 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) continue; // Update if spawned - Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT), (Creature*)NULL); + Creature* pCreature = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(itr->first, data->id,HIGHGUID_UNIT), (Creature*)NULL); if (pCreature) { if (activate) diff --git a/src/server/game/Events/GameEventMgr.h b/src/server/game/Events/GameEventMgr.h index 2c3e41f5f20..656be331edc 100644 --- a/src/server/game/Events/GameEventMgr.h +++ b/src/server/game/Events/GameEventMgr.h @@ -23,8 +23,8 @@ #include "Common.h" #include "SharedDefines.h" -#include "Platform/Define.h" -#include "Policies/Singleton.h" +#include "Define.h" +#include "ace/Singleton.h" #define max_ge_check_delay DAY // 1 day in seconds @@ -92,9 +92,11 @@ class Creature; class GameEventMgr { + friend class ACE_Singleton<GameEventMgr, ACE_Null_Mutex>; + GameEventMgr(); public: - GameEventMgr(); ~GameEventMgr() {}; + typedef std::set<uint16> ActiveEvents; typedef std::vector<GameEventData> GameEventDataMap; ActiveEvents const& GetActiveEventList() const { return m_ActiveEvents; } @@ -172,7 +174,7 @@ class GameEventMgr GameEventGuidMap mGameEventGameobjectGuids; }; -#define gameeventmgr Trinity::Singleton<GameEventMgr>::Instance() +#define gameeventmgr (*ACE_Singleton<GameEventMgr, ACE_Null_Mutex>::instance()) bool IsHolidayActive(HolidayIds id); bool IsEventActive(uint16 event_id); diff --git a/src/server/game/Globals/GlobalEvents.cpp b/src/server/game/Globals/GlobalEvents.cpp index 300527aad73..e83441cf3bb 100644 --- a/src/server/game/Globals/GlobalEvents.cpp +++ b/src/server/game/Globals/GlobalEvents.cpp @@ -23,9 +23,9 @@ */ #include "Log.h" -#include "Database/DatabaseEnv.h" -#include "Database/DatabaseImpl.h" -#include "Platform/Define.h" +#include "DatabaseEnv.h" +#include "DatabaseImpl.h" +#include "Define.h" #include "MapManager.h" #include "ObjectAccessor.h" #include "GlobalEvents.h" @@ -53,7 +53,7 @@ static void CorpsesEraseCallBack(QueryResult_AutoPtr result, bool bones) /// Resurrectable - convert corpses to bones if (!bones) { - if (!ObjectAccessor::Instance().ConvertCorpseForPlayer(player_guid)) + if (!sObjectAccessor.ConvertCorpseForPlayer(player_guid)) { sLog.outDebug("Corpse %u not found in world or bones creating forbidden. Delete from DB.",guidlow); CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow); @@ -62,7 +62,7 @@ static void CorpsesEraseCallBack(QueryResult_AutoPtr result, bool bones) else ///- or delete bones { - MapManager::Instance().RemoveBonesFromMap(mapid, guid, positionX, positionY); + sMapMgr.RemoveBonesFromMap(mapid, guid, positionX, positionY); ///- remove bones from the database CharacterDatabase.PExecute("DELETE FROM corpse WHERE guid = '%u'",guidlow); diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index cf5bc728c6e..b82944d8327 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -20,7 +20,7 @@ #include "ObjectAccessor.h" #include "ObjectMgr.h" -#include "Policies/SingletonImp.h" + #include "Player.h" #include "Creature.h" #include "GameObject.h" @@ -41,10 +41,6 @@ #include <cmath> -#define CLASS_LOCK Trinity::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex> -INSTANTIATE_SINGLETON_2(ObjectAccessor, CLASS_LOCK); -INSTANTIATE_CLASS_MUTEX(ObjectAccessor, ACE_Thread_Mutex); - ObjectAccessor::ObjectAccessor() { } @@ -151,7 +147,7 @@ Player* ObjectAccessor::FindPlayer(uint64 guid) Player* ObjectAccessor::FindPlayerByName(const char* name) { - Guard guard(*HashMapHolder<Player>::GetLock()); + ACE_GUARD_RETURN(LockType, g, *HashMapHolder<Player>::GetLock(), NULL); HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer(); for (HashMapHolder<Player>::MapType::iterator iter = m.begin(); iter != m.end(); ++iter) if (iter->second->IsInWorld() && strcmp(name, iter->second->GetName()) == 0) @@ -162,7 +158,7 @@ Player* ObjectAccessor::FindPlayerByName(const char* name) void ObjectAccessor::SaveAllPlayers() { - Guard guard(*HashMapHolder<Player>::GetLock()); + ACE_GUARD(LockType, g, *HashMapHolder<Player>::GetLock()); HashMapHolder<Player>::MapType& m = HashMapHolder<Player>::GetContainer(); for (HashMapHolder<Player>::MapType::iterator itr = m.begin(); itr != m.end(); ++itr) itr->second->SaveToDB(); @@ -175,7 +171,7 @@ Pet* ObjectAccessor::GetPet(uint64 guid) Corpse* ObjectAccessor::GetCorpseForPlayerGUID(uint64 guid) { - Guard guard(i_corpseGuard); + ACE_GUARD_RETURN(LockType, guard, i_corpseGuard, NULL); Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid); if (iter == i_player2corpse.end()) @@ -197,7 +193,7 @@ void ObjectAccessor::RemoveCorpse(Corpse* corpse) // Critical section { - Guard guard(i_corpseGuard); + ACE_GUARD(LockType, g, i_corpseGuard); Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID()); if (iter == i_player2corpse.end()) // TODO: Fix this @@ -219,7 +215,7 @@ void ObjectAccessor::AddCorpse(Corpse* corpse) // Critical section { - Guard guard(i_corpseGuard); + ACE_GUARD(LockType, g, i_corpseGuard); assert(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end()); i_player2corpse[corpse->GetOwnerGUID()] = corpse; @@ -234,7 +230,7 @@ void ObjectAccessor::AddCorpse(Corpse* corpse) void ObjectAccessor::AddCorpsesToGrid(GridPair const& gridpair, GridType& grid, Map* map) { - Guard guard(i_corpseGuard); + ACE_GUARD(LockType, g, i_corpseGuard); for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter) { @@ -274,7 +270,7 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool /*insign // done in removecorpse // remove resurrectable corpse from grid object registry (loaded state checked into call) // do not load the map if it's not loaded - //Map *map = MapManager::Instance().FindMap(corpse->GetMapId(), corpse->GetInstanceId()); + //Map *map = sMapMgr.FindMap(corpse->GetMapId(), corpse->GetInstanceId()); //if (map) // map->Remove(corpse, false); @@ -333,7 +329,7 @@ void ObjectAccessor::Update(uint32 /*diff*/) // Critical section { - Guard guard(i_updateGuard); + ACE_GUARD(LockType, g, i_updateGuard); while (!i_objects.empty()) { diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 8e64eb48fa0..fc128d6a4e0 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -21,11 +21,10 @@ #ifndef TRINITY_OBJECTACCESSOR_H #define TRINITY_OBJECTACCESSOR_H -#include "Platform/Define.h" -#include "Policies/Singleton.h" +#include "Define.h" +#include <ace/Singleton.h> #include <ace/Thread_Mutex.h> -#include "Utilities/UnorderedMap.h" -#include "Policies/ThreadingModel.h" +#include "UnorderedMap.h" #include "UpdateData.h" @@ -50,23 +49,22 @@ class HashMapHolder typedef UNORDERED_MAP<uint64, T*> MapType; typedef ACE_Thread_Mutex LockType; - typedef Trinity::GeneralLock<LockType> Guard; static void Insert(T* o) { - Guard guard(i_lock); + ACE_GUARD(LockType, Guard, i_lock); m_objectMap[o->GetGUID()] = o; } static void Remove(T* o) { - Guard guard(i_lock); + ACE_GUARD(LockType, Guard, i_lock); m_objectMap.erase(o->GetGUID()); } static T* Find(uint64 guid) { - Guard guard(i_lock); + ACE_GUARD_RETURN(LockType, Guard, i_lock, NULL); typename MapType::iterator itr = m_objectMap.find(guid); return (itr != m_objectMap.end()) ? itr->second : NULL; } @@ -84,9 +82,9 @@ class HashMapHolder static MapType m_objectMap; }; -class ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassLevelLockable<ObjectAccessor, ACE_Thread_Mutex> > +class ObjectAccessor { - friend class Trinity::OperatorNew<ObjectAccessor>; + friend class ACE_Singleton<ObjectAccessor, ACE_Thread_Mutex>; ObjectAccessor(); ~ObjectAccessor(); ObjectAccessor(const ObjectAccessor&); @@ -220,13 +218,13 @@ class ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassL void AddUpdateObject(Object* obj) { - Guard guard(i_updateGuard); + ACE_GUARD(LockType, Guard, i_updateGuard); i_objects.insert(obj); } void RemoveUpdateObject(Object* obj) { - Guard guard(i_updateGuard); + ACE_GUARD(LockType, Guard, i_updateGuard); i_objects.erase(obj); } @@ -239,7 +237,6 @@ class ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassL Corpse* ConvertCorpseForPlayer(uint64 player_guid, bool insignia = false); typedef ACE_Thread_Mutex LockType; - typedef Trinity::GeneralLock<LockType> Guard; private: @@ -254,4 +251,6 @@ class ObjectAccessor : public Trinity::Singleton<ObjectAccessor, Trinity::ClassL LockType i_updateGuard; LockType i_corpseGuard; }; + +#define sObjectAccessor (*ACE_Singleton<ObjectAccessor, ACE_Thread_Mutex>::instance()) #endif diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index ce86c2a4e77..71cd4c46b80 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -19,11 +19,9 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" -#include "Database/SQLStorage.h" -#include "Database/SQLStorageImpl.h" -#include "Policies/SingletonImp.h" - +#include "DatabaseEnv.h" +#include "SQLStorage.h" +#include "SQLStorageImpl.h" #include "Log.h" #include "MapManager.h" #include "ObjectMgr.h" @@ -33,7 +31,7 @@ #include "Group.h" #include "Guild.h" #include "ArenaTeam.h" -#include "Transports.h" +#include "Transport.h" #include "ProgressBar.h" #include "Language.h" #include "GameEventMgr.h" @@ -48,8 +46,6 @@ #include "Vehicle.h" #include "AchievementMgr.h" -INSTANTIATE_SINGLETON_1(ObjectMgr); - ScriptMapMap sQuestEndScripts; ScriptMapMap sQuestStartScripts; ScriptMapMap sSpellScripts; @@ -1177,14 +1173,14 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guid, uint32 linkedGuid) if (!linkedGuid) // we're removing the linking { mCreatureLinkedRespawnMap.erase(guid); - WorldDatabase.DirectPExecute("DELETE FROM creature_linked_respawn WHERE guid = '%u'",guid); + WorldDatabase.PExecute("DELETE FROM creature_linked_respawn WHERE guid = '%u'",guid); return true; } if (CheckCreatureLinkedRespawn(guid,linkedGuid)) // we add/change linking { mCreatureLinkedRespawnMap[guid] = linkedGuid; - WorldDatabase.DirectPExecute("REPLACE INTO creature_linked_respawn (guid,linkedGuid) VALUES ('%u','%u')",guid,linkedGuid); + WorldDatabase.PExecute("REPLACE INTO creature_linked_respawn (guid,linkedGuid) VALUES ('%u','%u')",guid,linkedGuid); return true; } return false; @@ -1412,7 +1408,7 @@ uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float if (!goinfo) return 0; - Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(mapId)); + Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(mapId)); if (!map) return 0; @@ -1473,7 +1469,7 @@ bool ObjectMgr::MoveCreData(uint32 guid, uint32 mapId, Position pos) AddCreatureToGrid(guid, &data); // Spawn if necessary (loaded grids only) - if (Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(mapId))) + if (Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(mapId))) { // We use spawn coords to spawn if (!map->Instanceable() && map->IsLoaded(data.posX, data.posY)) @@ -1524,7 +1520,7 @@ uint32 ObjectMgr::AddCreData(uint32 entry, uint32 /*team*/, uint32 mapId, float AddCreatureToGrid(guid, &data); // Spawn if necessary (loaded grids only) - if (Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(mapId))) + if (Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(mapId))) { // We use spawn coords to spawn if (!map->Instanceable() && !map->IsRemovalGrid(x, y)) @@ -2260,10 +2256,17 @@ void ObjectMgr::LoadItemPrototypes() const_cast<ItemPrototype*>(proto)->Sheath = SHEATHETYPE_NONE; } - if (proto->RandomProperty && !sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(proto->RandomProperty))) + if (proto->RandomProperty) { - sLog.outErrorDb("Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)",i,proto->RandomProperty); - const_cast<ItemPrototype*>(proto)->RandomProperty = 0; + // To be implemented later + if (proto->RandomProperty == -1) + const_cast<ItemPrototype*>(proto)->RandomProperty = 0; + + else if (!sItemRandomPropertiesStore.LookupEntry(GetItemEnchantMod(proto->RandomProperty))) + { + sLog.outErrorDb("Item (Entry: %u) has unknown (wrong or not listed in `item_enchantment_template`) RandomProperty (%u)",i,proto->RandomProperty); + const_cast<ItemPrototype*>(proto)->RandomProperty = 0; + } } if (proto->RandomSuffix && !sItemRandomSuffixStore.LookupEntry(GetItemEnchantMod(proto->RandomSuffix))) @@ -2368,7 +2371,132 @@ void ObjectMgr::LoadItemPrototypes() } for (std::set<uint32>::const_iterator itr = notFoundOutfit.begin(); itr != notFoundOutfit.end(); ++itr) - sLog.outErrorDb("Item (Entry: %u) not exist in `item_template` but referenced in `CharStartOutfit.dnc`", *itr); + sLog.outErrorDb("Item (Entry: %u) not exist in `item_template` but referenced in `CharStartOutfit.dbc`", *itr); +} + +void ObjectMgr::LoadItemSetNameLocales() +{ + mItemSetNameLocaleMap.clear(); // need for reload case + + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT `entry`,`name_loc1`,`name_loc2`,`name_loc3`,`name_loc4`,`name_loc5`,`name_loc6`,`name_loc7`,`name_loc8` FROM `locales_item_set_names`"); + + if (!result) + return; + + barGoLink bar(result->GetRowCount()); + + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + + ItemSetNameLocale& data = mItemSetNameLocaleMap[entry]; + + for (uint8 i = 1; i < MAX_LOCALE; ++i) + { + std::string str = fields[i].GetCppString(); + if (!str.empty()) + { + int idx = GetOrNewIndexForLocale(LocaleConstant(i)); + if (idx >= 0) + { + if (data.Name.size() <= idx) + data.Name.resize(idx+1); + + data.Name[idx] = str; + } + } + } + } while (result->NextRow()); + + sLog.outString(); + sLog.outString(">> Loaded %lu Item set name locale strings", (uint32)mItemSetNameLocaleMap.size()); +} + +void ObjectMgr::LoadItemSetNames() +{ + mItemSetNameMap.clear(); // needed for reload case + + QueryResult_AutoPtr result = WorldDatabase.Query("SELECT `entry`,`name`,`InventoryType` FROM `item_set_names`"); + + uint32 count = 0; + std::set<uint32> itemSetItems; + + // fill item set member ids + for (uint32 entryId = 0; entryId < sItemSetStore.GetNumRows(); ++entryId) + { + ItemSetEntry const* setEntry = sItemSetStore.LookupEntry(entryId); + if (!setEntry) + continue; + + for (uint32 i = 0; i < MAX_ITEM_SET_ITEMS; ++i) + if (setEntry->itemId[i]) + itemSetItems.insert(setEntry->itemId[i]); + } + + if (result) + { + barGoLink bar(result->GetRowCount()); + do + { + Field *fields = result->Fetch(); + bar.step(); + + uint32 entry = fields[0].GetUInt32(); + if (itemSetItems.find(entry) == itemSetItems.end()) + { + sLog.outErrorDb("Item set name (Entry: %u) not found in ItemSet.dbc, data useless.", entry); + continue; + } + + ItemSetNameEntry &data = mItemSetNameMap[entry]; + data.name = fields[1].GetCppString(); + + uint32 invType = fields[2].GetUInt32(); + if (invType >= MAX_INVTYPE) + { + sLog.outErrorDb("Item set name (Entry: %u) has wrong InventoryType value (%u)", entry, invType); + invType = INVTYPE_NON_EQUIP; + } + + data.InventoryType = invType; + itemSetItems.erase(entry); + ++count; + } while (result->NextRow()); + } + else + { + barGoLink bar(1); + bar.step(); + + sLog.outString(); + sLog.outErrorDb(">> Loaded 0 item set names. DB table `item_set_names` is empty."); + } + + if (!itemSetItems.empty()) + { + ItemPrototype const* pProto; + for (std::set<uint32>::iterator itr = itemSetItems.begin(); itr != itemSetItems.end(); ++itr) + { + uint32 entry = *itr; + // add data from item_template if available + if (pProto = GetItemPrototype(entry)) + { + sLog.outErrorDb("Item set part (Entry: %u) does not have entry in `item_set_names`, adding data from `item_template`.", entry); + ItemSetNameEntry &data = mItemSetNameMap[entry]; + data.name = pProto->Name1; + data.InventoryType = pProto->InventoryType; + ++count; + } + else + sLog.outErrorDb("Item set part (Entry: %u) does not have entry in `item_set_names`, set will not display properly.", entry); + } + } + + sLog.outString(); + sLog.outString(">> Loaded %u item set names", count); } void ObjectMgr::LoadVehicleAccessories() @@ -2462,7 +2590,7 @@ void ObjectMgr::LoadPetLevelInfo() sLog.outErrorDb("Wrong (> %u) level %u in `pet_levelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level); else { - sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `pet_levelstats` table, ignoring.",current_level); + sLog.outDetail("Unused (> MaxPlayerLevel in worldserver.conf) level %u in `pet_levelstats` table, ignoring.",current_level); ++count; // make result loading percent "expected" correct in case disabled detail mode for example. } continue; @@ -2535,6 +2663,47 @@ PetLevelInfo const* ObjectMgr::GetPetLevelInfo(uint32 creature_id, uint8 level) return &itr->second[level-1]; // data for level 1 stored in [0] array element, ... } +void ObjectMgr::PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count) +{ + if (count > 0) + playerInfo[race_][class_].item.push_back(PlayerCreateInfoItem(itemId, count)); + else + { + if (count < -1) + sLog.outErrorDb("Invalid count %i specified on item %u be removed from original player create info (use -1)!", count, itemId); + + uint32 RaceClass = (race_) | (class_ << 8); + bool doneOne = false; + for (uint32 i = 1; i < sCharStartOutfitStore.GetNumRows(); ++i) + { + if (CharStartOutfitEntry const* entry = sCharStartOutfitStore.LookupEntry(i)) + { + if (entry->RaceClassGender == RaceClass || entry->RaceClassGender == (RaceClass | (1 << 16))) + { + bool found = false; + for (uint8 x = 0; x < MAX_OUTFIT_ITEMS; ++x) + { + if (entry->ItemId[x] == itemId) + { + found = true; + const_cast<CharStartOutfitEntry*>(entry)->ItemId[x] = 0; + break; + } + } + + if (!found) + sLog.outErrorDb("Item %u specified to be removed from original create info not found in dbc!", itemId); + + if (!doneOne) + doneOne = true; + else + break; + } + } + } + } +} + void ObjectMgr::LoadPlayerInfo() { // Load playercreate @@ -2665,8 +2834,6 @@ void ObjectMgr::LoadPlayerInfo() continue; } - PlayerInfo* pInfo = &playerInfo[current_race][current_class]; - uint32 item_id = fields[2].GetUInt32(); if (!GetItemPrototype(item_id)) @@ -2675,7 +2842,7 @@ void ObjectMgr::LoadPlayerInfo() continue; } - uint32 amount = fields[3].GetUInt32(); + int32 amount = fields[3].GetInt32(); if (!amount) { @@ -2683,7 +2850,18 @@ void ObjectMgr::LoadPlayerInfo() continue; } - pInfo->item.push_back(PlayerCreateInfoItem(item_id, amount)); + if (!current_race || !current_class) + { + uint32 min_race = current_race ? current_race : 1; + uint32 max_race = current_race ? current_race + 1 : MAX_RACES; + uint32 min_class = current_class ? current_class : 1; + uint32 max_class = current_class ? current_class + 1 : MAX_CLASSES; + for (uint32 r = min_race; r < max_race; ++r) + for (uint32 c = min_class; c < max_class; ++c) + PlayerCreateInfoAddItemHelper(r, c, item_id, amount); + } + else + PlayerCreateInfoAddItemHelper(current_race, current_class, item_id, amount); bar.step(); ++count; @@ -2849,7 +3027,7 @@ void ObjectMgr::LoadPlayerInfo() sLog.outErrorDb("Wrong (> %u) level %u in `player_classlevelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level); else { - sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_classlevelstats` table, ignoring.",current_level); + sLog.outDetail("Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_classlevelstats` table, ignoring.",current_level); ++count; // make result loading percent "expected" correct in case disabled detail mode for example. } continue; @@ -2946,7 +3124,7 @@ void ObjectMgr::LoadPlayerInfo() sLog.outErrorDb("Wrong (> %u) level %u in `player_levelstats` table, ignoring.",STRONG_MAX_LEVEL,current_level); else { - sLog.outDetail("Unused (> MaxPlayerLevel in Trinityd.conf) level %u in `player_levelstats` table, ignoring.",current_level); + sLog.outDetail("Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_levelstats` table, ignoring.",current_level); ++count; // make result loading percent "expected" correct in case disabled detail mode for example. } continue; @@ -3056,7 +3234,7 @@ void ObjectMgr::LoadPlayerInfo() sLog.outErrorDb("Wrong (> %u) level %u in `player_xp_for_level` table, ignoring.", STRONG_MAX_LEVEL,current_level); else { - sLog.outDetail("Unused (> MaxPlayerLevel in TrinityCore.conf) level %u in `player_xp_for_levels` table, ignoring.",current_level); + sLog.outDetail("Unused (> MaxPlayerLevel in worldserver.conf) level %u in `player_xp_for_levels` table, ignoring.",current_level); ++count; // make result loading percent "expected" correct in case disabled detail mode for example. } continue; @@ -3244,7 +3422,7 @@ void ObjectMgr::LoadGuilds() !newGuild->LoadMembersFromDB(guildMembersResult) || !newGuild->LoadBankRightsFromDB(guildBankTabRightsResult) || !newGuild->CheckGuildStructure() -) + ) { newGuild->Disband(); delete newGuild; @@ -4638,26 +4816,9 @@ void ObjectMgr::LoadEventScripts() // Load all possible script entries from gameobjects for (uint32 i = 1; i < sGOStorage.MaxEntry; ++i) { - GameObjectInfo const * goInfo = sGOStorage.LookupEntry<GameObjectInfo>(i); - if (goInfo) - { - switch(goInfo->type) - { - case GAMEOBJECT_TYPE_GOOBER: - if (goInfo->goober.eventId) - evt_scripts.insert(goInfo->goober.eventId); - break; - case GAMEOBJECT_TYPE_CHEST: - if (goInfo->chest.eventId) - evt_scripts.insert(goInfo->chest.eventId); - break; - case GAMEOBJECT_TYPE_CAMERA: - if (goInfo->camera.eventID) - evt_scripts.insert(goInfo->camera.eventID); - default: - break; - } - } + if (GameObjectInfo const * goInfo = sGOStorage.LookupEntry<GameObjectInfo>(i)) + if (uint32 eventId = goInfo->GetEventScriptId()) + evt_scripts.insert(eventId); } // Load all possible script entries from spells for (uint32 i = 1; i < sSpellStore.GetNumRows(); ++i) @@ -4676,6 +4837,20 @@ void ObjectMgr::LoadEventScripts() } } + for(size_t path_idx = 0; path_idx < sTaxiPathNodesByPath.size(); ++path_idx) + { + for(size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx) + { + TaxiPathNodeEntry const& node = sTaxiPathNodesByPath[path_idx][node_idx]; + + if (node.arrivalEventID) + evt_scripts.insert(node.arrivalEventID); + + if (node.departureEventID) + evt_scripts.insert(node.departureEventID); + } + } + // Then check if all scripts are in above list of possible script entries for (ScriptMapMap::const_iterator itr = sEventScripts.begin(); itr != sEventScripts.end(); ++itr) { @@ -4693,7 +4868,7 @@ void ObjectMgr::LoadWaypointScripts() for (ScriptMapMap::const_iterator itr = sWaypointScripts.begin(); itr != sWaypointScripts.end(); ++itr) { - QueryResult_AutoPtr query = WorldDatabase.PQuery("SELECT * FROM waypoint_scripts WHERE id = %u", itr->first); + QueryResult_AutoPtr query = WorldDatabase.PQuery("SELECT * FROM waypoint_data WHERE action = %u", itr->first); if (!query || !query->GetRowCount()) sLog.outErrorDb("There is no waypoint which links to the waypoint script %u", itr->first); } @@ -5307,46 +5482,6 @@ uint32 ObjectMgr::GetTaxiMountDisplayId(uint32 id, uint32 team, bool allowed_alt return mount_id; } -void ObjectMgr::GetTaxiPathNodes(uint32 path, Path &pathnodes, std::vector<uint32>& mapIds) -{ - if (path >= sTaxiPathNodesByPath.size()) - return; - - TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path]; - - pathnodes.Resize(nodeList.size()); - mapIds.resize(nodeList.size()); - - for (size_t i = 0; i < nodeList.size(); ++i) - { - pathnodes[ i ].x = nodeList[i].x; - pathnodes[ i ].y = nodeList[i].y; - pathnodes[ i ].z = nodeList[i].z; - - mapIds[i] = nodeList[i].mapid; - } -} - -void ObjectMgr::GetTransportPathNodes(uint32 path, TransportPath &pathnodes) -{ - if (path >= sTaxiPathNodesByPath.size()) - return; - - TaxiPathNodeList& nodeList = sTaxiPathNodesByPath[path]; - - pathnodes.Resize(nodeList.size()); - - for (size_t i = 0; i < nodeList.size(); ++i) - { - pathnodes[ i ].mapid = nodeList[i].mapid; - pathnodes[ i ].x = nodeList[i].x; - pathnodes[ i ].y = nodeList[i].y; - pathnodes[ i ].z = nodeList[i].z; - pathnodes[ i ].actionFlag = nodeList[i].actionFlag; - pathnodes[ i ].delay = nodeList[i].delay; - } -} - void ObjectMgr::LoadGraveyardZones() { mGraveYardMap.clear(); // need for reload case @@ -5415,7 +5550,7 @@ void ObjectMgr::LoadGraveyardZones() WorldSafeLocsEntry const *ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) { // search for zone associated closest graveyard - uint32 zoneId = MapManager::Instance().GetZoneId(MapId,x,y,z); + uint32 zoneId = sMapMgr.GetZoneId(MapId,x,y,z); // Simulate std. algorithm: // found some graveyard associated to (ghost_zone,ghost_map) @@ -6476,7 +6611,7 @@ void ObjectMgr::LoadCorpses() continue; } - ObjectAccessor::Instance().AddCorpse(corpse); + sObjectAccessor.AddCorpse(corpse); ++count; } @@ -6488,6 +6623,9 @@ void ObjectMgr::LoadCorpses() void ObjectMgr::LoadReputationOnKill() { + // For reload case + mRepOnKill.clear(); + uint32 count = 0; // 0 1 2 @@ -6529,7 +6667,7 @@ void ObjectMgr::LoadReputationOnKill() if (!GetCreatureTemplate(creature_id)) { - sLog.outErrorDb("Table `creature_onkill_reputation` have data for not existed creature entry (%u), skipped",creature_id); + sLog.outErrorDb("Table `creature_onkill_reputation` have data for not existed creature entry (%u), skipped", creature_id); continue; } @@ -6538,7 +6676,7 @@ void ObjectMgr::LoadReputationOnKill() FactionEntry const *factionEntry1 = sFactionStore.LookupEntry(repOnKill.repfaction1); if (!factionEntry1) { - sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction1); + sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`", repOnKill.repfaction1); continue; } } @@ -6548,7 +6686,7 @@ void ObjectMgr::LoadReputationOnKill() FactionEntry const *factionEntry2 = sFactionStore.LookupEntry(repOnKill.repfaction2); if (!factionEntry2) { - sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`",repOnKill.repfaction2); + sLog.outErrorDb("Faction (faction.dbc) %u does not exist but is used in `creature_onkill_reputation`", repOnKill.repfaction2); continue; } } @@ -7953,12 +8091,12 @@ int ObjectMgr::LoadReferenceVendor(int32 vendor, int32 item, std::set<uint32> *s uint32 incrtime = fields[2].GetUInt32(); uint32 ExtendedCost = fields[3].GetUInt32(); - if (!IsVendorItemValid(vendor,item_id,maxcount,incrtime,ExtendedCost,NULL,skip_vendors)) + if (!IsVendorItemValid(vendor, item_id, maxcount, incrtime, ExtendedCost, NULL, skip_vendors)) continue; VendorItemData& vList = m_mCacheVendorItemMap[vendor]; - vList.AddItem(item_id,maxcount,incrtime,ExtendedCost); + vList.AddItem(item_id, maxcount, incrtime, ExtendedCost); ++count; } @@ -8008,12 +8146,12 @@ void ObjectMgr::LoadVendors() uint32 incrtime = fields[3].GetUInt32(); uint32 ExtendedCost = fields[4].GetUInt32(); - if (!IsVendorItemValid(entry,item_id,maxcount,incrtime,ExtendedCost,NULL,&skip_vendors)) + if (!IsVendorItemValid(entry, item_id, maxcount, incrtime, ExtendedCost, NULL, &skip_vendors)) continue; VendorItemData& vList = m_mCacheVendorItemMap[entry]; - vList.AddItem(item_id,maxcount,incrtime,ExtendedCost); + vList.AddItem(item_id, maxcount, incrtime, ExtendedCost); ++count; } @@ -8128,7 +8266,7 @@ void ObjectMgr::LoadGossipMenuItems() QueryResult_AutoPtr result = WorldDatabase.Query( "SELECT menu_id, id, option_icon, option_text, option_id, npc_option_npcflag, " "action_menu_id, action_poi_id, action_script_id, box_coded, box_money, box_text " - "FROM gossip_menu_option"); + "FROM gossip_menu_option ORDER BY menu_id, id"); if (!result) { @@ -8223,9 +8361,10 @@ void ObjectMgr::LoadGossipMenuItems() void ObjectMgr::AddVendorItem(uint32 entry,uint32 item, int32 maxcount, uint32 incrtime, uint32 extendedcost, bool savetodb) { VendorItemData& vList = m_mCacheVendorItemMap[entry]; - vList.AddItem(item,maxcount,incrtime,extendedcost); + vList.AddItem(item, maxcount, incrtime, extendedcost); - if (savetodb) WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')",entry, item, maxcount,incrtime,extendedcost); + if (savetodb) + WorldDatabase.PExecuteLog("INSERT INTO npc_vendor (entry,item,maxcount,incrtime,extendedcost) VALUES('%u','%u','%u','%u','%u')", entry, item, maxcount, incrtime, extendedcost); } bool ObjectMgr::RemoveVendorItem(uint32 entry,uint32 item, bool savetodb) @@ -8273,16 +8412,16 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 max if (pl) ChatHandler(pl).PSendSysMessage(LANG_ITEM_NOT_FOUND, item_id); else - sLog.outErrorDb("Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore",vendor_entry,item_id); + sLog.outErrorDb("Table `(game_event_)npc_vendor` for Vendor (Entry: %u) have in item list non-existed item (%u), ignore", vendor_entry, item_id); return false; } if (ExtendedCost && !sItemExtendedCostStore.LookupEntry(ExtendedCost)) { if (pl) - ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST,ExtendedCost); + ChatHandler(pl).PSendSysMessage(LANG_EXTENDED_COST_NOT_EXIST, ExtendedCost); else - sLog.outErrorDb("Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore",item_id,ExtendedCost,vendor_entry); + sLog.outErrorDb("Table `(game_event_)npc_vendor` have Item (Entry: %u) with wrong ExtendedCost (%u) for vendor (%u), ignore", item_id, ExtendedCost, vendor_entry); return false; } @@ -8307,7 +8446,7 @@ bool ObjectMgr::IsVendorItemValid(uint32 vendor_entry, uint32 item_id, int32 max if (!vItems) return true; // later checks for non-empty lists - if(vItems->FindItemCostPair(item_id,ExtendedCost)) + if (vItems->FindItemCostPair(item_id, ExtendedCost)) { if (pl) ChatHandler(pl).PSendSysMessage(LANG_ITEM_ALREADY_IN_LIST, item_id, ExtendedCost); @@ -8462,40 +8601,6 @@ CreatureInfo const *GetCreatureInfo(uint32 id) return objmgr.GetCreatureTemplate(id); } -void ObjectMgr::LoadTransportEvents() -{ - - QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, waypoint_id, event_id FROM transport_events"); - - if (!result) - { - barGoLink bar1(1); - bar1.step(); - sLog.outString("\n>> Transport events table is empty \n"); - return; - } - - barGoLink bar1(result->GetRowCount()); - - do - { - bar1.step(); - - Field *fields = result->Fetch(); - - //Load event values - uint32 entry = fields[0].GetUInt32(); - uint32 waypoint_id = fields[1].GetUInt32(); - uint32 event_id = fields[2].GetUInt32(); - - uint32 event_count = (entry*100)+waypoint_id; - TransportEventMap[event_count] = event_id; - } - while (result->NextRow()); - - sLog.outString("\n>> Loaded %u transport events \n", result->GetRowCount()); -} - CreatureInfo const* GetCreatureTemplateStore(uint32 entry) { return sCreatureStorage.LookupEntry<CreatureInfo>(entry); diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 79b6ffdd0eb..7b7e0e2bdb9 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -30,16 +30,15 @@ #include "GameObject.h" #include "Corpse.h" #include "QuestDef.h" -#include "Path.h" #include "ItemPrototype.h" #include "NPCHandler.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Mail.h" #include "Map.h" #include "ObjectAccessor.h" #include "ObjectDefines.h" -#include "Policies/Singleton.h" -#include "Database/SQLStorage.h" +#include "ace/Singleton.h" +#include "SQLStorage.h" #include "Vehicle.h" #include "ObjectMgr.h" #include <string> @@ -60,8 +59,6 @@ extern SQLStorage sInstanceTemplate; class Group; class Guild; class ArenaTeam; -class Path; -class TransportPath; class Item; struct GameTele @@ -164,6 +161,7 @@ typedef UNORDERED_MAP<uint32,GameObjectData> GameObjectDataMap; typedef UNORDERED_MAP<uint32,CreatureLocale> CreatureLocaleMap; typedef UNORDERED_MAP<uint32,GameObjectLocale> GameObjectLocaleMap; typedef UNORDERED_MAP<uint32,ItemLocale> ItemLocaleMap; +typedef UNORDERED_MAP<uint32,ItemSetNameLocale> ItemSetNameLocaleMap; typedef UNORDERED_MAP<uint32,QuestLocale> QuestLocaleMap; typedef UNORDERED_MAP<uint32,NpcTextLocale> NpcTextLocaleMap; typedef UNORDERED_MAP<uint32,PageTextLocale> PageTextLocaleMap; @@ -356,11 +354,11 @@ class PlayerDumpReader; class ObjectMgr { friend class PlayerDumpReader; - + friend class ACE_Singleton<ObjectMgr, ACE_Null_Mutex>; + ObjectMgr(); + ~ObjectMgr(); + public: - ObjectMgr(); - ~ObjectMgr(); - typedef UNORDERED_MAP<uint32, Item*> ItemMap; typedef std::set< Group * > GroupSet; @@ -384,9 +382,7 @@ class ObjectMgr typedef std::vector<std::string> ScriptNameMap; - UNORDERED_MAP<uint32, uint32> TransportEventMap; - - Player* GetPlayer(const char* name) const { return ObjectAccessor::Instance().FindPlayerByName(name);} + Player* GetPlayer(const char* name) const { return sObjectAccessor.FindPlayerByName(name);} Player* GetPlayer(uint64 guid) const { return ObjectAccessor::FindPlayer(guid); } static GameObjectInfo const *GetGameObjectInfo(uint32 id) { return sGOStorage.LookupEntry<GameObjectInfo>(id); } @@ -431,6 +427,14 @@ class ObjectMgr static ItemPrototype const* GetItemPrototype(uint32 id) { return sItemStorage.LookupEntry<ItemPrototype>(id); } + ItemSetNameEntry const* GetItemSetNameEntry(uint32 itemId) + { + ItemSetNameMap::iterator itr = mItemSetNameMap.find(itemId); + if(itr != mItemSetNameMap.end()) + return &itr->second; + return NULL; + } + static InstanceTemplate const* GetInstanceTemplate(uint32 map) { return sInstanceTemplate.LookupEntry<InstanceTemplate>(map); @@ -464,8 +468,6 @@ class ObjectMgr uint32 GetNearestTaxiNode(float x, float y, float z, uint32 mapid, uint32 team); void GetTaxiPath(uint32 source, uint32 destination, uint32 &path, uint32 &cost); uint32 GetTaxiMountDisplayId(uint32 id, uint32 team, bool allowed_alt_team = false); - void GetTaxiPathNodes(uint32 path, Path &pathnodes, std::vector<uint32>& mapIds); - void GetTransportPathNodes(uint32 path, TransportPath &pathnodes); Quest const* GetQuestTemplate(uint32 quest_id) const { @@ -585,8 +587,6 @@ class ObjectMgr void LoadGossipScripts(); void LoadWaypointScripts(); - void LoadTransportEvents(); - bool LoadTrinityStrings(DatabaseType& db, char const* table, int32 min_value, int32 max_value); bool LoadTrinityStrings() { return LoadTrinityStrings(WorldDatabase,"trinity_string",MIN_TRINITY_STRING_ID,MAX_TRINITY_STRING_ID); } void LoadDbScriptStrings(); @@ -607,6 +607,8 @@ class ObjectMgr void LoadGameobjectRespawnTimes(); void LoadItemPrototypes(); void LoadItemLocales(); + void LoadItemSetNames(); + void LoadItemSetNameLocales(); void LoadQuestLocales(); void LoadNpcTextLocales(); void LoadPageTextLocales(); @@ -740,6 +742,12 @@ class ObjectMgr if (itr == mItemLocaleMap.end()) return NULL; return &itr->second; } + ItemSetNameLocale const* GetItemSetNameLocale(uint32 entry) const + { + ItemSetNameLocaleMap::const_iterator itr = mItemSetNameLocaleMap.find(entry); + if (itr == mItemSetNameLocaleMap.end())return NULL; + return &itr->second; + } QuestLocale const* GetQuestLocale(uint32 entry) const { QuestLocaleMap::const_iterator itr = mQuestLocaleMap.find(entry); @@ -875,7 +883,7 @@ class ObjectMgr return &iter->second; } void AddVendorItem(uint32 entry,uint32 item, int32 maxcount, uint32 incrtime, uint32 ExtendedCost, bool savetodb = true); // for event - bool RemoveVendorItem(uint32 entry,uint32 item, bool savetodb = true); // for event + bool RemoveVendorItem(uint32 entry, uint32 item, bool savetodb = true); // for event bool IsVendorItemValid(uint32 vendor_entry, uint32 item, int32 maxcount, uint32 ptime, uint32 ExtendedCost, Player* pl = NULL, std::set<uint32>* skip_vendors = NULL, uint32 ORnpcflag = 0) const; void LoadScriptNames(); @@ -1018,6 +1026,7 @@ class ObjectMgr void LoadCreatureAddons(SQLStorage& creatureaddons, char const* entryName, char const* comment); void ConvertCreatureAddonAuras(CreatureDataAddon* addon, char const* table, char const* guidEntryStr); void LoadQuestRelationsHelper(QuestRelations& map,char const* table); + void PlayerCreateInfoAddItemHelper(uint32 race_, uint32 class_, uint32 itemId, int32 count); MailLevelRewardMap m_mailLevelRewardMap; @@ -1045,6 +1054,9 @@ class ObjectMgr HalfNameMap PetHalfName0; HalfNameMap PetHalfName1; + typedef UNORDERED_MAP<uint32, ItemSetNameEntry> ItemSetNameMap; + ItemSetNameMap mItemSetNameMap; + MapObjectGuids mMapObjectGuids; CreatureDataMap mCreatureDataMap; CreatureLinkedRespawnMap mCreatureLinkedRespawnMap; @@ -1052,6 +1064,7 @@ class ObjectMgr GameObjectDataMap mGameObjectDataMap; GameObjectLocaleMap mGameObjectLocaleMap; ItemLocaleMap mItemLocaleMap; + ItemSetNameLocaleMap mItemSetNameLocaleMap; QuestLocaleMap mQuestLocaleMap; NpcTextLocaleMap mNpcTextLocaleMap; PageTextLocaleMap mPageTextLocaleMap; @@ -1070,7 +1083,7 @@ class ObjectMgr }; -#define objmgr Trinity::Singleton<ObjectMgr>::Instance() +#define objmgr (*ACE_Singleton<ObjectMgr, ACE_Null_Mutex>::instance()) // scripting access functions bool LoadTrinityStrings(DatabaseType& db, char const* table,int32 start_value = MAX_CREATURE_AI_TEXT_STRING_ID, int32 end_value = std::numeric_limits<int32>::min()); diff --git a/src/server/game/Grids/Cells/Cell.h b/src/server/game/Grids/Cells/Cell.h index 49e0329ace6..4bc08e3b1b9 100644 --- a/src/server/game/Grids/Cells/Cell.h +++ b/src/server/game/Grids/Cells/Cell.h @@ -23,8 +23,8 @@ #include <cmath> -#include "GameSystem/TypeContainer.h" -#include "GameSystem/TypeContainerVisitor.h" +#include "TypeContainer.h" +#include "TypeContainerVisitor.h" #include "GridDefines.h" diff --git a/src/server/game/Grids/Grid.h b/src/server/game/Grids/Grid.h index 65bf3c92f9d..2e300ac5e38 100644 --- a/src/server/game/Grids/Grid.h +++ b/src/server/game/Grids/Grid.h @@ -32,8 +32,7 @@ Grid's perspective, the loader meets its API requirement is suffice. */ -#include "Platform/Define.h" -#include "Policies/ThreadingModel.h" +#include "Define.h" #include "TypeContainer.h" #include "TypeContainerVisitor.h" @@ -44,8 +43,7 @@ template < class ACTIVE_OBJECT, class WORLD_OBJECT_TYPES, -class GRID_OBJECT_TYPES, -class ThreadModel = Trinity::SingleThreaded<ACTIVE_OBJECT> +class GRID_OBJECT_TYPES > class Grid { @@ -131,9 +129,6 @@ class Grid }*/ private: - typedef typename ThreadModel::Lock Guard; - typedef typename ThreadModel::VolatileType VolatileType; - TypeMapContainer<GRID_OBJECT_TYPES> i_container; TypeMapContainer<WORLD_OBJECT_TYPES> i_objects; //typedef std::set<void*> ActiveGridObjects; diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index 5269d0a094d..620b8dd2a03 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -22,7 +22,7 @@ #define TRINITY_GRIDDEFINES_H #include "Common.h" -#include "GameSystem/NGrid.h" +#include "NGrid.h" #include <cmath> // Forward class definitions @@ -42,7 +42,7 @@ class Player; #define CENTER_GRID_OFFSET (SIZE_OF_GRIDS/2) -#define MIN_GRID_DELAY (MINUTE*IN_MILISECONDS) +#define MIN_GRID_DELAY (MINUTE*IN_MILLISECONDS) #define MIN_MAP_UPDATE_DELAY 50 #define SIZE_OF_GRID_CELL (SIZE_OF_GRIDS/MAX_NUMBER_OF_CELLS) diff --git a/src/server/game/Grids/GridLoader.h b/src/server/game/Grids/GridLoader.h index 03fa0f5b813..ca80451e023 100644 --- a/src/server/game/Grids/GridLoader.h +++ b/src/server/game/Grids/GridLoader.h @@ -32,7 +32,7 @@ GridLoader manages the grid (both local and remote). */ -#include "Platform/Define.h" +#include "Define.h" #include "Grid.h" #include "TypeContainerVisitor.h" diff --git a/src/server/game/Grids/GridRefManager.h b/src/server/game/Grids/GridRefManager.h index 79799105fb7..44a6c9b802c 100644 --- a/src/server/game/Grids/GridRefManager.h +++ b/src/server/game/Grids/GridRefManager.h @@ -21,7 +21,7 @@ #ifndef _GRIDREFMANAGER #define _GRIDREFMANAGER -#include "Utilities/LinkedReference/RefManager.h" +#include "RefManager.h" template<class OBJECT> class GridReference; diff --git a/src/server/game/Grids/GridReference.h b/src/server/game/Grids/GridReference.h index d2e3a455895..0f5b46b4950 100644 --- a/src/server/game/Grids/GridReference.h +++ b/src/server/game/Grids/GridReference.h @@ -21,7 +21,7 @@ #ifndef _GRIDREFERENCE_H #define _GRIDREFERENCE_H -#include "Utilities/LinkedReference/Reference.h" +#include "LinkedReference/Reference.h" template<class OBJECT> class GridRefManager; diff --git a/src/server/game/Grids/GridStates.cpp b/src/server/game/Grids/GridStates.cpp index 9d39531cfad..0f725539d00 100644 --- a/src/server/game/Grids/GridStates.cpp +++ b/src/server/game/Grids/GridStates.cpp @@ -20,7 +20,7 @@ #include "GridStates.h" #include "GridNotifiers.h" -#include "GameSystem/Grid.h" +#include "Grid.h" #include "Log.h" void diff --git a/src/server/game/Grids/NGrid.h b/src/server/game/Grids/NGrid.h index 3810286e123..1411ac71c4a 100644 --- a/src/server/game/Grids/NGrid.h +++ b/src/server/game/Grids/NGrid.h @@ -24,8 +24,8 @@ /** NGrid is nothing more than a wrapper of the Grid with an NxN cells */ -#include "GameSystem/Grid.h" -#include "GameSystem/GridReference.h" +#include "Grid.h" +#include "GridReference.h" #include "Timer.h" #include "Util.h" @@ -74,14 +74,13 @@ template unsigned int N, class ACTIVE_OBJECT, class WORLD_OBJECT_TYPES, -class GRID_OBJECT_TYPES, -class ThreadModel = Trinity::SingleThreaded<ACTIVE_OBJECT> +class GRID_OBJECT_TYPES > class NGrid { public: - typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> GridType; + typedef Grid<ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> GridType; NGrid(uint32 id, int32 x, int32 y, time_t expiry, bool unload = true) : i_gridId(id), i_x(x), i_y(y), i_cellstate(GRID_STATE_INVALID), i_GridObjectDataLoaded(false) { @@ -109,7 +108,7 @@ class NGrid int32 getX() const { return i_x; } int32 getY() const { return i_y; } - void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> >* pTo) + void link(GridRefManager<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> >* pTo) { i_Reference.link(pTo, this); } @@ -178,7 +177,7 @@ class NGrid uint32 i_gridId; GridInfo i_GridInfo; - GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES, ThreadModel> > i_Reference; + GridReference<NGrid<N, ACTIVE_OBJECT, WORLD_OBJECT_TYPES, GRID_OBJECT_TYPES> > i_Reference; int32 i_x; int32 i_y; grid_state_t i_cellstate; diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index b10dfa8791e..88d17b0286f 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -25,7 +25,7 @@ #include "UpdateData.h" #include "Item.h" #include "Map.h" -#include "Transports.h" +#include "Transport.h" #include "ObjectAccessor.h" #include "CellImpl.h" diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index ab69d9a966b..f0da10975ac 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -151,7 +151,7 @@ void LoadHelper(CellCorpseSet const& cell_corpses, CellPair &cell, CorpseMapType uint32 player_guid = itr->first; - Corpse *obj = ObjectAccessor::Instance().GetCorpseForPlayerGUID(player_guid); + Corpse *obj = sObjectAccessor.GetCorpseForPlayerGUID(player_guid); if (!obj) continue; diff --git a/src/server/game/Grids/ObjectGridLoader.h b/src/server/game/Grids/ObjectGridLoader.h index e890bf8d482..c1a59cb4ecb 100644 --- a/src/server/game/Grids/ObjectGridLoader.h +++ b/src/server/game/Grids/ObjectGridLoader.h @@ -21,9 +21,9 @@ #ifndef TRINITY_OBJECTGRIDLOADER_H #define TRINITY_OBJECTGRIDLOADER_H -#include "Utilities/TypeList.h" -#include "Platform/Define.h" -#include "GameSystem/GridLoader.h" +#include "TypeList.h" +#include "Define.h" +#include "GridLoader.h" #include "GridDefines.h" #include "Cell.h" diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index acd19e02838..614c6a45143 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -79,8 +79,7 @@ Group::~Group() itr2->second.save->RemoveGroup(this); // Sub group counters clean up - if (m_subGroupsCounts) - delete[] m_subGroupsCounts; + delete[] m_subGroupsCounts; } bool Group::Create(const uint64 &guid, const char * name) @@ -486,13 +485,6 @@ void Group::Disband(bool hideDestroy) CharacterDatabase.CommitTransaction(); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, false, NULL); ResetInstances(INSTANCE_RESET_GROUP_DISBAND, true, NULL); - // FIXME - Safe check! Debug purposes - Will remove after a time if got no reports - QueryResult_AutoPtr result = CharacterDatabase.PQuery("SELECT COUNT(1) FROM group_instance WHERE guid=%u", lowguid); - if (result) - { - sLog.outError("Group::Disband: %u instances are not being properly deleted from group %u", (*result)[0].GetUInt8(), lowguid); - CharacterDatabase.PExecute("DELETE FROM group_instance WHERE guid=%u", lowguid); - } } m_guid = 0; @@ -1200,7 +1192,7 @@ bool Group::_addMember(const uint64 &guid, const char* name) if (m_subGroupsCounts) { bool groupFound = false; - for (; groupid < MAXRAIDSIZE/MAXGROUPSIZE; ++groupid) + for (; groupid < MAX_RAID_SUBGROUPS; ++groupid) { if (m_subGroupsCounts[groupid] < MAXGROUPSIZE) { @@ -1453,17 +1445,20 @@ void Group::ChangeMembersGroup(const uint64 &guid, const uint8 &group) { if (!isRaidGroup()) return; + Player *player = objmgr.GetPlayer(guid); if (!player) { - uint8 prevSubGroup; - prevSubGroup = GetMemberGroup(guid); - - SubGroupCounterDecrease(prevSubGroup); + uint8 prevSubGroup = GetMemberGroup(guid); + if (prevSubGroup == group) + return; if (_setMembersGroup(guid, group)) + { + SubGroupCounterDecrease(prevSubGroup); SendUpdate(); + } } else // This methods handles itself groupcounter decrease @@ -1475,9 +1470,13 @@ void Group::ChangeMembersGroup(Player *player, const uint8 &group) { if (!player || !isRaidGroup()) return; + + uint8 prevSubGroup = player->GetSubGroup(); + if (prevSubGroup == group) + return; + if (_setMembersGroup(player->GetGUID(), group)) { - uint8 prevSubGroup = player->GetSubGroup(); if (player->GetGroup() == this) player->GetGroupRef().setSubGroup(group); //if player is in BG raid, it is possible that he is also in normal raid - and that normal raid is stored in m_originalGroup reference @@ -1725,7 +1724,7 @@ void Group::ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo) bool isEmpty = true; // if the map is loaded, reset it - Map *map = MapManager::Instance().FindMap(p->GetMapId(), p->GetInstanceId()); + Map *map = sMapMgr.FindMap(p->GetMapId(), p->GetInstanceId()); if (map && map->IsDungeon() && !(method == INSTANCE_RESET_GROUP_DISBAND && !p->CanReset())) { if (p->CanReset()) @@ -1761,34 +1760,39 @@ InstanceGroupBind* Group::GetBoundInstance(Player* player) { uint32 mapid = player->GetMapId(); MapEntry const* mapEntry = sMapStore.LookupEntry(mapid); - if (!mapEntry) - return NULL; + return GetBoundInstance(mapEntry); +} - Difficulty difficulty = player->GetDifficulty(mapEntry->IsRaid()); +InstanceGroupBind* Group::GetBoundInstance(Map* aMap) +{ + // Currently spawn numbering not different from map difficulty + Difficulty difficulty = GetDifficulty(aMap->IsRaid()); // some instances only have one difficulty - MapDifficulty const* mapDiff = GetMapDifficultyData(mapid,difficulty); + MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty); if (!mapDiff) - difficulty = DUNGEON_DIFFICULTY_NORMAL; + return NULL; - BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapid); + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(aMap->GetId()); if (itr != m_boundInstances[difficulty].end()) return &itr->second; else return NULL; } -InstanceGroupBind* Group::GetBoundInstance(Map* aMap) +InstanceGroupBind* Group::GetBoundInstance(MapEntry const* mapEntry) { - // Currently spawn numbering not different from map difficulty - Difficulty difficulty = GetDifficulty(aMap->IsRaid()); - + if (!mapEntry) + return NULL; + + Difficulty difficulty = GetDifficulty(mapEntry->IsRaid()); + // some instances only have one difficulty - MapDifficulty const* mapDiff = GetMapDifficultyData(aMap->GetId(),difficulty); + MapDifficulty const* mapDiff = GetMapDifficultyData(mapEntry->MapID,difficulty); if (!mapDiff) - return NULL; - - BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(aMap->GetId()); + difficulty = DUNGEON_DIFFICULTY_NORMAL; + + BoundInstancesMap::iterator itr = m_boundInstances[difficulty].find(mapEntry->MapID); if (itr != m_boundInstances[difficulty].end()) return &itr->second; else diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 808de417b79..2b93b7b1d6e 100644 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -33,6 +33,7 @@ #define MAXGROUPSIZE 5 #define MAXRAIDSIZE 40 +#define MAX_RAID_SUBGROUPS MAXRAIDSIZE/MAXGROUPSIZE #define TARGETICONCOUNT 8 enum RollVote @@ -260,7 +261,7 @@ class Group { member_citerator mslot = _getMemberCSlot(guid); if (mslot == m_memberSlots.end()) - return (MAXRAIDSIZE/MAXGROUPSIZE+1); + return (MAX_RAID_SUBGROUPS+1); return mslot->group; } @@ -357,6 +358,7 @@ class Group void UnbindInstance(uint32 mapid, uint8 difficulty, bool unload = false); InstanceGroupBind* GetBoundInstance(Player* player); InstanceGroupBind* GetBoundInstance(Map* aMap); + InstanceGroupBind* GetBoundInstance(MapEntry const* mapEntry); BoundInstancesMap& GetBoundInstances(Difficulty difficulty) { return m_boundInstances[difficulty]; } // FG: evil hacks @@ -381,9 +383,9 @@ class Group { // Sub group counters initialization if (!m_subGroupsCounts) - m_subGroupsCounts = new uint8[MAXRAIDSIZE / MAXGROUPSIZE]; + m_subGroupsCounts = new uint8[MAX_RAID_SUBGROUPS]; - memset((void*)m_subGroupsCounts, 0, (MAXRAIDSIZE / MAXGROUPSIZE)*sizeof(uint8)); + memset((void*)m_subGroupsCounts, 0, (MAX_RAID_SUBGROUPS)*sizeof(uint8)); for (member_citerator itr = m_memberSlots.begin(); itr != m_memberSlots.end(); ++itr) ++m_subGroupsCounts[itr->group]; diff --git a/src/server/game/Groups/GroupRefManager.h b/src/server/game/Groups/GroupRefManager.h index 4fdeba2dd8c..19c4c8122c1 100644 --- a/src/server/game/Groups/GroupRefManager.h +++ b/src/server/game/Groups/GroupRefManager.h @@ -21,7 +21,7 @@ #ifndef _GROUPREFMANAGER #define _GROUPREFMANAGER -#include "Utilities/LinkedReference/RefManager.h" +#include "RefManager.h" class Group; class Player; diff --git a/src/server/game/Groups/GroupReference.h b/src/server/game/Groups/GroupReference.h index 76f54c5230f..56dc5a3375f 100644 --- a/src/server/game/Groups/GroupReference.h +++ b/src/server/game/Groups/GroupReference.h @@ -21,7 +21,7 @@ #ifndef _GROUPREFERENCE_H #define _GROUPREFERENCE_H -#include "Utilities/LinkedReference/Reference.h" +#include "LinkedReference/Reference.h" class Group; class Player; diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 418e409998f..f1f3187bc32 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Player.h" @@ -30,7 +30,7 @@ #include "Util.h" #include "Language.h" #include "World.h" -#include "Config/ConfigEnv.h" +#include "ConfigEnv.h" Guild::Guild() { diff --git a/src/server/game/Instances/InstanceData.cpp b/src/server/game/Instances/InstanceData.cpp index 214c5ca2327..7408efe97e5 100644 --- a/src/server/game/Instances/InstanceData.cpp +++ b/src/server/game/Instances/InstanceData.cpp @@ -19,7 +19,7 @@ */ #include "InstanceData.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Map.h" #include "Player.h" #include "GameObject.h" @@ -43,7 +43,7 @@ void InstanceData::HandleGameObject(uint64 GUID, bool open, GameObject *go) if (go) go->SetGoState(open ? GO_STATE_ACTIVE : GO_STATE_READY); else - debug_log("TSCR: InstanceData: HandleGameObject failed"); + sLog.outDebug("TSCR: InstanceData: HandleGameObject failed"); } bool InstanceData::IsEncounterInProgress() const @@ -263,7 +263,7 @@ void InstanceData::DoUseDoorOrButton(uint64 uiGuid, uint32 uiWithRestoreTime, bo pGo->ResetDoorOrButton(); } else - error_log("SD2: Script call DoUseDoorOrButton, but gameobject entry %u is type %u.",pGo->GetEntry(),pGo->GetGoType()); + sLog.outError("SD2: Script call DoUseDoorOrButton, but gameobject entry %u is type %u.",pGo->GetEntry(),pGo->GetGoType()); } } @@ -294,7 +294,7 @@ void InstanceData::DoUpdateWorldState(uint32 uiStateId, uint32 uiStateData) pPlayer->SendUpdateWorldState(uiStateId, uiStateData); } else - debug_log("TSCR: DoUpdateWorldState attempt send data but no players in map."); + sLog.outDebug("TSCR: DoUpdateWorldState attempt send data but no players in map."); } // Send Notify to all players in instance @@ -318,7 +318,7 @@ void InstanceData::DoCompleteAchievement(uint32 achievement) if (!pAE) { - error_log("TSCR: DoCompleteAchievement called for not existing achievement %u", achievement); + sLog.outError("TSCR: DoCompleteAchievement called for not existing achievement %u", achievement); return; } diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index d67364966d6..dd9001402a0 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -20,8 +20,7 @@ */ #include "Common.h" -#include "Database/SQLStorage.h" - +#include "SQLStorage.h" #include "Player.h" #include "GridNotifiers.h" #include "Log.h" @@ -33,21 +32,14 @@ #include "InstanceSaveMgr.h" #include "Timer.h" #include "GridNotifiersImpl.h" -#include "Config/ConfigEnv.h" -#include "Transports.h" +#include "ConfigEnv.h" +#include "Transport.h" #include "ObjectMgr.h" #include "World.h" #include "Group.h" #include "InstanceData.h" #include "ProgressBar.h" -#include "Policies/Singleton.h" -#include "Policies/SingletonImp.h" - -INSTANTIATE_SINGLETON_1(InstanceSaveManager); -InstanceSaveManager::InstanceSaveManager() : lock_instLists(false) -{ -} InstanceSaveManager::~InstanceSaveManager() { @@ -173,7 +165,7 @@ void InstanceSave::SaveToDB() // save instance data too std::string data; - Map *map = MapManager::Instance().FindMap(GetMapId(),m_instanceid); + Map *map = sMapMgr.FindMap(GetMapId(),m_instanceid); if (map) { assert(map->IsDungeon()); @@ -251,7 +243,7 @@ void InstanceSaveManager::_DelHelper(DatabaseType &db, const char *fields, const db.escape_string(fieldValue); ss << (i != 0 ? " AND " : "") << fieldTokens[i] << " = '" << fieldValue << "'"; } - db.DirectPExecute("DELETE FROM %s WHERE %s", table, ss.str().c_str()); + db.PExecute("DELETE FROM %s WHERE %s", table, ss.str().c_str()); } while (result->NextRow()); } } @@ -297,7 +289,7 @@ void InstanceSaveManager::CleanupInstances() { Field *fields = result->Fetch(); if (InstanceSet.find(fields[0].GetUInt32()) == InstanceSet.end()) - WorldDatabase.DirectPExecute("DELETE FROM creature_respawn WHERE instance = '%u'", fields[0].GetUInt32()); + WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE instance = '%u'", fields[0].GetUInt32()); } while (result->NextRow()); } @@ -310,7 +302,7 @@ void InstanceSaveManager::CleanupInstances() { Field *fields = result->Fetch(); if (InstanceSet.find(fields[0].GetUInt32()) == InstanceSet.end()) - WorldDatabase.DirectPExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", fields[0].GetUInt32()); + WorldDatabase.PExecute("DELETE FROM gameobject_respawn WHERE instance = '%u'", fields[0].GetUInt32()); } while (result->NextRow()); } @@ -441,7 +433,7 @@ void InstanceSaveManager::LoadResetTimes() InstResetTimeMapDiffType::iterator itr = instResetTime.find(instance); if (itr != instResetTime.end() && itr->second.second != resettime) { - CharacterDatabase.DirectPExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); + CharacterDatabase.PExecute("UPDATE instance SET resettime = '"UI64FMTD"' WHERE id = '%u'", uint64(resettime), instance); itr->second.second = resettime; } } @@ -470,14 +462,14 @@ void InstanceSaveManager::LoadResetTimes() if (!mapDiff) { sLog.outError("InstanceSaveManager::LoadResetTimes: invalid mapid(%u)/difficulty(%u) pair in instance_reset!", mapid, difficulty); - CharacterDatabase.DirectPExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); + CharacterDatabase.PExecute("DELETE FROM instance_reset WHERE mapid = '%u' AND difficulty = '%u'", mapid,difficulty); continue; } // update the reset time if the hour in the configs changes uint64 newresettime = (oldresettime / DAY) * DAY + diff; if (oldresettime != newresettime) - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty = '%u'", newresettime, mapid, difficulty); + CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty = '%u'", newresettime, mapid, difficulty); SetResetTimeFor(mapid,difficulty,newresettime); } while (result->NextRow()); @@ -508,7 +500,7 @@ void InstanceSaveManager::LoadResetTimes() { // initialize the reset time t = today + period + diff; - CharacterDatabase.DirectPExecute("INSERT INTO instance_reset VALUES ('%u','%u','"UI64FMTD"')", mapid, difficulty, (uint64)t); + CharacterDatabase.PExecute("INSERT INTO instance_reset VALUES ('%u','%u','"UI64FMTD"')", mapid, difficulty, (uint64)t); } if (t < now) @@ -517,7 +509,7 @@ void InstanceSaveManager::LoadResetTimes() // calculate the next reset time t = (t / DAY) * DAY; t += ((today - t) / period + 1) * period + diff; - CharacterDatabase.DirectPExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); + CharacterDatabase.PExecute("UPDATE instance_reset SET resettime = '"UI64FMTD"' WHERE mapid = '%u' AND difficulty= '%u'", (uint64)t, mapid, difficulty); } SetResetTimeFor(mapid,difficulty,t); @@ -615,7 +607,7 @@ void InstanceSaveManager::_ResetSave(InstanceSaveHashMap::iterator &itr) void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) { sLog.outDebug("InstanceSaveMgr::_ResetInstance %u, %u", mapid, instanceId); - Map *map = (MapInstanced*)MapManager::Instance().CreateBaseMap(mapid); + Map *map = (MapInstanced*)sMapMgr.CreateBaseMap(mapid); if (!map->Instanceable()) return; @@ -679,7 +671,7 @@ void InstanceSaveManager::_ResetOrWarnAll(uint32 mapid, Difficulty difficulty, b } // note: this isn't fast but it's meant to be executed very rarely - Map const *map = MapManager::Instance().CreateBaseMap(mapid); // _not_ include difficulty + Map const *map = sMapMgr.CreateBaseMap(mapid); // _not_ include difficulty MapInstanced::InstancedMaps &instMaps = ((MapInstanced*)map)->GetInstancedMaps(); MapInstanced::InstancedMaps::iterator mitr; for (mitr = instMaps.begin(); mitr != instMaps.end(); ++mitr) diff --git a/src/server/game/Instances/InstanceSaveMgr.h b/src/server/game/Instances/InstanceSaveMgr.h index 91cd3d9ebe6..66751cc4f10 100644 --- a/src/server/game/Instances/InstanceSaveMgr.h +++ b/src/server/game/Instances/InstanceSaveMgr.h @@ -22,13 +22,13 @@ #ifndef __InstanceSaveMgr_H #define __InstanceSaveMgr_H -#include "Platform/Define.h" -#include "Policies/Singleton.h" +#include "Define.h" +#include "ace/Singleton.h" #include "ace/Thread_Mutex.h" #include <list> #include <map> -#include "Utilities/UnorderedMap.h" -#include "Database/DatabaseEnv.h" +#include "UnorderedMap.h" +#include "DatabaseEnv.h" #include "DBCEnums.h" #include "ObjectDefines.h" @@ -117,13 +117,14 @@ class InstanceSave typedef UNORDERED_MAP<uint32 /*PAIR32(map,difficulty)*/,time_t /*resetTime*/> ResetTimeByMapDifficultyMap; -class InstanceSaveManager : public Trinity::Singleton<InstanceSaveManager, Trinity::ClassLevelLockable<InstanceSaveManager, ACE_Thread_Mutex> > +class InstanceSaveManager { + friend class ACE_Singleton<InstanceSaveManager, ACE_Null_Mutex>; friend class InstanceSave; public: - InstanceSaveManager(); + InstanceSaveManager() : lock_instLists(false) {}; ~InstanceSaveManager(); - + typedef UNORDERED_MAP<uint32 /*InstanceId*/, InstanceSave*> InstanceSaveHashMap; typedef UNORDERED_MAP<uint32 /*mapId*/, InstanceSaveHashMap> InstanceSaveMapMap; @@ -176,6 +177,7 @@ class InstanceSaveManager : public Trinity::Singleton<InstanceSaveManager, Trini uint32 GetNumBoundGroupsTotal(); private: + void _ResetOrWarnAll(uint32 mapid, Difficulty difficulty, bool warn, uint32 timeleft); void _ResetInstance(uint32 mapid, uint32 instanceId); void _ResetSave(InstanceSaveHashMap::iterator &itr); @@ -189,5 +191,5 @@ class InstanceSaveManager : public Trinity::Singleton<InstanceSaveManager, Trini ResetTimeQueue m_resetTimeQueue; }; -#define sInstanceSaveManager Trinity::Singleton<InstanceSaveManager>::Instance() +#define sInstanceSaveManager (*ACE_Singleton<InstanceSaveManager, ACE_Thread_Mutex>::instance()) #endif diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index 2137c8872b5..77b7f08fd5a 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -188,7 +188,6 @@ bool LootStore::HaveQuestLootForPlayer(uint32 loot_id,Player* player) const void LootStore::ResetConditions() { - LootTemplateMap m_LootTemplates; for (LootTemplateMap::iterator itr = m_LootTemplates.begin(); itr != m_LootTemplates.end(); ++itr) { ConditionList empty; @@ -969,11 +968,11 @@ void LootTemplate::LootGroup::CopyConditions(ConditionList conditions) { for (LootStoreItemList::iterator i = ExplicitlyChanced.begin(); i != ExplicitlyChanced.end(); ++i) { - i->conditions = conditions; + i->conditions.clear(); } for (LootStoreItemList::iterator i = EqualChanced.begin(); i != EqualChanced.end(); ++i) { - i->conditions = conditions; + i->conditions.clear(); } } @@ -1146,7 +1145,7 @@ void LootTemplate::AddEntry(LootStoreItem& item) void LootTemplate::CopyConditions(ConditionList conditions) { for (LootStoreItemList::iterator i = Entries.begin(); i != Entries.end(); ++i) - i->conditions = conditions; + i->conditions.clear(); for (LootGroups::iterator i = Groups.begin(); i != Groups.end(); ++i) i->CopyConditions(conditions); @@ -1197,8 +1196,6 @@ void LootTemplate::Process(Loot& loot, LootStore const& store, bool rate, uint16 if (!Referenced) continue; // Error message already printed at loading stage - const_cast<LootTemplate*>(Referenced)->CopyConditions(i->conditions);//copy conditions from referer template - for (uint32 loop = 0; loop < i->maxcount; ++loop) // Ref multiplicator Referenced->Process(loot, store, rate, lootMode, i->group); } diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h index 65fe3de22e1..00fe2a97888 100644 --- a/src/server/game/Loot/LootMgr.h +++ b/src/server/game/Loot/LootMgr.h @@ -23,7 +23,7 @@ #include "ItemEnchantmentMgr.h" #include "ByteBuffer.h" -#include "Utilities/LinkedReference/RefManager.h" +#include "RefManager.h" #include "SharedDefines.h" #include "ConditionMgr.h" diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index 847009b83dc..77f971bf4d0 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -375,8 +375,8 @@ void WorldSession::HandleMailReturnToSender(WorldPacket & recv_data) CharacterDatabase.CommitTransaction(); pl->RemoveMail(mailId); - // send back only to players and simple drop for other cases - if (m->messageType == MAIL_NORMAL) + // only return mail if the player exists (and delete if not existing) + if (m->messageType == MAIL_NORMAL && m->sender) { MailDraft draft(m->subject, m->body); if (m->mailTemplateId) diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 11bfdcd6f99..6c9b505d6c9 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -28,8 +28,8 @@ #include "InstanceData.h" #include "Map.h" #include "GridNotifiersImpl.h" -#include "Config/ConfigEnv.h" -#include "Transports.h" +#include "ConfigEnv.h" +#include "Transport.h" #include "ObjectAccessor.h" #include "ObjectMgr.h" #include "World.h" @@ -94,10 +94,9 @@ bool Map::ExistMap(uint32 mapid,int gx,int gy) map_fileheader header; fread(&header, sizeof(header), 1, pf); - if (header.mapMagic != uint32(MAP_MAGIC) || - header.versionMagic != uint32(MAP_VERSION_MAGIC)) + if (header.mapMagic != uint32(MAP_MAGIC) || header.versionMagic != uint32(MAP_VERSION_MAGIC)) { - sLog.outError("Map file '%s' is non-compatible version (outdated?). Please, create new using ad.exe program.",tmp); + sLog.outError("Map file '%s' is from an incompatible clientversion. Please recreate using the mapextractor.",tmp); delete [] tmp; fclose(pf); //close file before return return false; @@ -114,7 +113,6 @@ bool Map::ExistVMap(uint32 mapid,int gx,int gy) { if (vmgr->isMapLoadingEnabled()) { - // x and y are swapped !! => fixed now bool exists = vmgr->existsMap((sWorld.GetDataPath()+ "vmaps").c_str(), mapid, gx,gy); if (!exists) { @@ -326,7 +324,7 @@ void Map::DeleteFromWorld(T* obj) template<> void Map::DeleteFromWorld(Player* pl) { - ObjectAccessor::Instance().RemoveObject(pl); + sObjectAccessor.RemoveObject(pl); delete pl; } @@ -335,7 +333,7 @@ Map::EnsureGridCreated(const GridPair &p) { if (!getNGrid(p.x_coord, p.y_coord)) { - Guard guard(*this); + ACE_GUARD(ACE_Thread_Mutex, Guard, Lock); if (!getNGrid(p.x_coord, p.y_coord)) { sLog.outDebug("Creating grid[%u,%u] for map %u instance %u", p.x_coord, p.y_coord, GetId(), i_InstanceId); @@ -396,7 +394,7 @@ bool Map::EnsureGridLoaded(const Cell &cell) loader.LoadN(); // Add resurrectable corpses to world object list in grid - ObjectAccessor::Instance().AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this); + sObjectAccessor.AddCorpsesToGrid(GridPair(cell.GridX(),cell.GridY()),(*grid)(cell.CellX(), cell.CellY()), this); setGridObjectDataLoaded(true,cell.GridX(), cell.GridY()); return true; @@ -829,7 +827,7 @@ bool Map::RemoveBones(uint64 guid, float x, float y) { if (IsRemovalGrid(x, y)) { - Corpse * corpse = ObjectAccessor::Instance().GetObjectInWorld(GetId(), x, y, guid, (Corpse*)NULL); + Corpse * corpse = sObjectAccessor.GetObjectInWorld(GetId(), x, y, guid, (Corpse*)NULL); if (corpse && corpse->GetTypeId() == TYPEID_CORPSE && corpse->GetType() == CORPSE_BONES) corpse->DeleteBonesFromWorld(); else @@ -1209,8 +1207,7 @@ bool GridMap::loadData(char *filename) if (!in) return true; fread(&header, sizeof(header),1,in); - if (header.mapMagic == uint32(MAP_MAGIC) && - header.versionMagic == uint32(MAP_VERSION_MAGIC)) + if (header.mapMagic == uint32(MAP_MAGIC) && header.versionMagic == uint32(MAP_VERSION_MAGIC)) { // loadup area data if (header.areaMapOffset && !loadAreaData(in, header.areaMapOffset, header.areaMapSize)) @@ -1236,18 +1233,18 @@ bool GridMap::loadData(char *filename) fclose(in); return true; } - sLog.outError("Map file '%s' is a non-compatible version (outdated?). Please, create new using the ad.exe program.", filename); + sLog.outError("Map file '%s' is from an incompatible clientversion. Please recreate using the mapextractor.", filename); fclose(in); return false; } void GridMap::unloadData() { - if (m_area_map) delete[] m_area_map; - if (m_V9) delete[] m_V9; - if (m_V8) delete[] m_V8; - if (m_liquid_type) delete[] m_liquid_type; - if (m_liquid_map) delete[] m_liquid_map; + delete[] m_area_map; + delete[] m_V9; + delete[] m_V8; + delete[] m_liquid_type; + delete[] m_liquid_map; m_area_map = NULL; m_V9 = NULL; m_V8 = NULL; @@ -2071,7 +2068,7 @@ void Map::SendInitSelf(Player * player) void Map::SendInitTransports(Player * player) { // Hack to send out transports - MapManager::TransportMap& tmap = MapManager::Instance().m_TransportsByMap; + MapManager::TransportMap& tmap = sMapMgr.m_TransportsByMap; // no transports at map if (tmap.find(player->GetMapId()) == tmap.end()) @@ -2098,7 +2095,7 @@ void Map::SendInitTransports(Player * player) void Map::SendRemoveTransports(Player * player) { // Hack to send out transports - MapManager::TransportMap& tmap = MapManager::Instance().m_TransportsByMap; + MapManager::TransportMap& tmap = sMapMgr.m_TransportsByMap; // no transports at map if (tmap.find(player->GetMapId()) == tmap.end()) @@ -2198,7 +2195,7 @@ void Map::RemoveAllObjectsInRemoveList() { case TYPEID_CORPSE: { - Corpse* corpse = ObjectAccessor::Instance().GetCorpse(*obj, obj->GetGUID()); + Corpse* corpse = sObjectAccessor.GetCorpse(*obj, obj->GetGUID()); if (!corpse) sLog.outError("Tried to delete corpse/bones %u that is not in map.", obj->GetGUIDLow()); else @@ -2352,11 +2349,8 @@ InstanceMap::InstanceMap(uint32 id, time_t expiry, uint32 InstanceId, uint8 Spaw InstanceMap::~InstanceMap() { - if (i_data) - { - delete i_data; - i_data = NULL; - } + delete i_data; + i_data = NULL; } void InstanceMap::InitVisibilityDistance() @@ -2400,6 +2394,32 @@ bool InstanceMap::CanEnter(Player *player) return false; } + // cannot enter if instance is in use by another party/soloer that have a + // permanent save in the same instance id + + PlayerList const &playerList = GetPlayers(); + Player *firstInsidePlayer = NULL; + + if (!playerList.isEmpty()) + for (PlayerList::const_iterator i = playerList.begin(); i != playerList.end(); ++i) + if (Player *iPlayer = i->getSource()) + { + if (iPlayer->isGameMaster()) // bypass GMs + continue; + if (!player->GetGroup()) // player has not group and there is someone inside, deny entry + { + player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS); + return false; + } + // player inside instance has no group or his groups is different to entering player's one, deny entry + if (!iPlayer->GetGroup() || iPlayer->GetGroup() != player->GetGroup() ) + { + player->SendTransferAborted(GetId(), TRANSFER_ABORT_MAX_PLAYERS); + return false; + } + break; + } + return Map::CanEnter(player); } @@ -2413,7 +2433,7 @@ bool InstanceMap::Add(Player *player) // Is it needed? { - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, Lock, false); // Check moved to void WorldSession::HandleMoveWorldportAckOpcode() //if (!CanEnter(player)) //return false; @@ -2738,7 +2758,7 @@ bool BattleGroundMap::CanEnter(Player * player) bool BattleGroundMap::Add(Player * player) { { - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, guard, Lock, false); //Check moved to void WorldSession::HandleMoveWorldportAckOpcode() //if (!CanEnter(player)) //return false; @@ -2882,7 +2902,7 @@ void Map::ScriptsProcess() source = HashMapHolder<Corpse>::Find(step.sourceGUID); break; case HIGHGUID_MO_TRANSPORT: - for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter) + for (MapManager::TransportSet::iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == step.sourceGUID) { @@ -2941,8 +2961,9 @@ void Map::ScriptsProcess() break; } - Creature* cSource = NULL; - cSource = source->ToCreature() != NULL ? source->ToCreature() : target->ToCreature(); + Creature* cSource = source->ToCreature(); + if (!cSource && target) + cSource = target->ToCreature(); if (!cSource) { @@ -2998,8 +3019,9 @@ void Map::ScriptsProcess() break; } - Creature* cSource = NULL; - cSource = source->ToCreature() != NULL ? source->ToCreature() : target->ToCreature(); + Creature* cSource = source->ToCreature(); + if (!cSource && target) + target->ToCreature(); if (!cSource) { @@ -3023,7 +3045,10 @@ void Map::ScriptsProcess() break; } - Creature* cSource = source->ToCreature() != NULL ? source->ToCreature() : target->ToCreature(); + Creature* cSource = source->ToCreature(); + if (!cSource && target) + cSource = target->ToCreature(); + if (!cSource) { sLog.outError("SCRIPT_COMMAND_FIELD_SET (script id: %u) call for non-creature source.", step.script->id); @@ -3049,7 +3074,10 @@ void Map::ScriptsProcess() break; } - Creature* cSource = source->ToCreature() != NULL ? source->ToCreature() : target->ToCreature(); + Creature* cSource = source->ToCreature(); + if (!cSource && target) + cSource = target->ToCreature(); + if (!cSource) { sLog.outError("SCRIPT_COMMAND_MOVE_TO (script id: %u) call for non-creature (TypeId: %u, Entry: %u, GUID: %u), skipping.", @@ -3070,7 +3098,10 @@ void Map::ScriptsProcess() break; } - Creature* cSource = source->ToCreature() != NULL ? source->ToCreature() : target->ToCreature(); + Creature* cSource = source->ToCreature(); + if (!cSource && target) + cSource = target->ToCreature(); + if (!cSource) { sLog.outError("SCRIPT_COMMAND_FLAG_SET (script id: %u) call for non-creature source.", step.script->id); @@ -3096,7 +3127,10 @@ void Map::ScriptsProcess() break; } - Creature* cSource = source->ToCreature() != NULL ? source->ToCreature() : target->ToCreature(); + Creature* cSource = source->ToCreature(); + if (!cSource && target) + cSource = target->ToCreature(); + if (!cSource) { sLog.outError("SCRIPT_COMMAND_FLAG_REMOVE (script id: %u) call for non-creature source.", step.script->id); @@ -3125,7 +3159,12 @@ void Map::ScriptsProcess() if (step.script->datalong2 == 0) { - Player* pSource = target->ToPlayer() != NULL ? target->ToPlayer() : source->ToPlayer(); + Player* pSource = NULL; + if (target) + pSource = target->ToPlayer(); + if (!pSource && source) + pSource = source->ToPlayer(); + // must be only Player if (!pSource) { @@ -3138,7 +3177,12 @@ void Map::ScriptsProcess() } else if (step.script->datalong2 == 1) { - Creature *cSource = target->ToCreature() != NULL ? target->ToCreature() : source->ToCreature(); + Creature *cSource = NULL; + if (target) + cSource = target->ToCreature(); + if (!cSource && source) + cSource = source->ToCreature(); + // must be only Creature if (!cSource) { @@ -3154,16 +3198,14 @@ void Map::ScriptsProcess() case SCRIPT_COMMAND_KILL_CREDIT: { + Player* pSource = NULL; // accept player in any one from target/source arg - if (!target && !source) - { - sLog.outError("SCRIPT_COMMAND_KILL_CREDIT (script id: %u) call for NULL object.", step.script->id); - break; - } - - Player* pSource = target->ToPlayer() != NULL ? target->ToPlayer() : source->ToPlayer(); - // must be only Player - if (!pSource) + if (target) + pSource = target->ToPlayer(); + if (!pSource && source) + pSource = source->ToPlayer(); + + if (!pSource) // must be only Player { sLog.outError("SCRIPT_COMMAND_KILL_CREDIT (script id: %u) call for non-player (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", step.script->id, source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0); @@ -3277,6 +3319,7 @@ void Map::ScriptsProcess() go->GetMap()->Add(go); break; } + case SCRIPT_COMMAND_OPEN_DOOR: { if (!step.script->datalong) // door not specified @@ -3334,6 +3377,7 @@ void Map::ScriptsProcess() ((GameObject*)target)->UseDoorOrButton(time_to_close); break; } + case SCRIPT_COMMAND_CLOSE_DOOR: { if (!step.script->datalong) // guid for door not specified @@ -3392,6 +3436,7 @@ void Map::ScriptsProcess() break; } + case SCRIPT_COMMAND_QUEST_EXPLORED: { if (!source) @@ -3408,7 +3453,7 @@ void Map::ScriptsProcess() // when script called for item spell casting then target == (unit or GO) and source is player WorldObject* worldObject; - Player* pTarget; + Player* pTarget = NULL; pTarget = target->ToPlayer(); if (pTarget) @@ -3577,7 +3622,7 @@ void Map::ScriptsProcess() } // bitmask: 0/1=anyone/target, 0/2=with distance dependent - Player* pTarget; + Player* pTarget = NULL; if (step.script->datalong2 & 1) { if (!target) @@ -3586,7 +3631,7 @@ void Map::ScriptsProcess() break; } - pTarget = target->ToPlayer(); + pTarget = target ? target->ToPlayer() : NULL; if (!pTarget) { sLog.outError("SCRIPT_COMMAND_PLAY_SOUND (script id: %u) in targeted mode call for non-player (TypeId: %u, Entry: %u, GUID: %u), skipping.", @@ -3605,13 +3650,19 @@ void Map::ScriptsProcess() case SCRIPT_COMMAND_CREATE_ITEM: { - if (!target && !source) + if (!source) { - sLog.outError("SCRIPT_COMMAND_CREATE_ITEM (script id: %u) call for NULL object.", step.script->id); + sLog.outError("SCRIPT_COMMAND_CREATE_ITEM (script id: %u) call for NULL source.", + step.script->id); break; } - Player *pReceiver = target->ToPlayer() != NULL ? target->ToPlayer() : source->ToPlayer(); + Player *pReceiver = NULL; + if (target) + pReceiver = target->ToPlayer(); + if (!pReceiver) + pReceiver = source->ToPlayer(); + // only Player if (!pReceiver) { @@ -3798,6 +3849,7 @@ void Map::ScriptsProcess() uSource->SendMovementFlagUpdate(); break; } + case SCRIPT_COMMAND_EQUIP: { if (!source) @@ -3816,6 +3868,7 @@ void Map::ScriptsProcess() cSource->LoadEquipment(step.script->datalong); break; } + case SCRIPT_COMMAND_MODEL: { if (!source) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index ceb526b8244..4d25381fbe1 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -21,8 +21,7 @@ #ifndef TRINITY_MAP_H #define TRINITY_MAP_H -#include "Platform/Define.h" -#include "Policies/ThreadingModel.h" +#include "Define.h" #include "ace/RW_Thread_Mutex.h" #include "ace/Thread_Mutex.h" @@ -31,9 +30,9 @@ #include "Cell.h" #include "Timer.h" #include "SharedDefines.h" -#include "GameSystem/GridRefManager.h" +#include "GridRefManager.h" #include "MapRefManager.h" -#include "mersennetwister/MersenneTwister.h" +#include "MersenneTwister.h" #include <bitset> #include <list> @@ -57,7 +56,7 @@ class BattleGround; // Map file format defines //****************************************** #define MAP_MAGIC 'SPAM' -#define MAP_VERSION_MAGIC '0.1w' +#define MAP_VERSION_MAGIC '1.1v' #define MAP_AREA_MAGIC 'AERA' #define MAP_HEIGHT_MAGIC 'TGHM' #define MAP_LIQUID_MAGIC 'QILM' @@ -66,6 +65,7 @@ struct map_fileheader { uint32 mapMagic; uint32 versionMagic; + uint32 buildMagic; uint32 areaMapOffset; uint32 areaMapSize; uint32 heightMapOffset; @@ -238,7 +238,7 @@ typedef UNORDERED_MAP<Creature*, CreatureMover> CreatureMoveList; typedef std::map<uint32/*leaderDBGUID*/, CreatureGroup*> CreatureGroupHolderType; -class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockable<Map, ACE_Thread_Mutex> +class Map : public GridRefManager<NGridType> { friend class MapReference; public: @@ -489,7 +489,7 @@ class Map : public GridRefManager<NGridType>, public Trinity::ObjectLevelLockabl protected: void SetUnloadReferenceLock(const GridPair &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } - typedef Trinity::ObjectLevelLockable<Map, ACE_Thread_Mutex>::Lock Guard; + ACE_Thread_Mutex Lock; MapEntry const* i_mapEntry; uint8 i_spawnMode; diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index 0736bfa6fb3..008baeb79d9 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -170,7 +170,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) { // if no instanceId via group members or instance saves is found // the instance will be created for the first time - NewInstanceId = MapManager::Instance().GenerateInstanceId(); + NewInstanceId = sMapMgr.GenerateInstanceId(); Difficulty diff = player->GetGroup() ? player->GetGroup()->GetDifficulty(IsRaid()) : player->GetDifficulty(IsRaid()); map = CreateInstance(NewInstanceId, NULL, diff); @@ -183,7 +183,7 @@ Map* MapInstanced::CreateInstance(const uint32 mapId, Player * player) InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, Difficulty difficulty) { // load/create a map - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, Guard, Lock, NULL); // make sure we have a valid map id const MapEntry* entry = sMapStore.LookupEntry(GetId()); @@ -219,7 +219,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave *save, BattleGroundMap* MapInstanced::CreateBattleGround(uint32 InstanceId, BattleGround* bg) { // load/create a map - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, Guard, Lock, NULL); sLog.outDebug("MapInstanced::CreateBattleGround: map bg %d for %d created.", InstanceId, GetId()); diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index de3d0ebbaff..36999aab14f 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -20,16 +20,15 @@ #include "MapManager.h" #include "InstanceSaveMgr.h" -#include "Policies/SingletonImp.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "ObjectAccessor.h" -#include "Transports.h" +#include "Transport.h" #include "GridDefines.h" #include "MapInstanced.h" #include "InstanceData.h" #include "DestinationHolderImp.h" -#include "Config/ConfigEnv.h" +#include "ConfigEnv.h" #include "World.h" #include "CellImpl.h" #include "Corpse.h" @@ -37,10 +36,6 @@ #include "Language.h" #include "WorldPacket.h" -#define CLASS_LOCK Trinity::ClassLevelLockable<MapManager, ACE_Thread_Mutex> -INSTANTIATE_SINGLETON_2(MapManager, CLASS_LOCK); -INSTANTIATE_CLASS_MUTEX(MapManager, ACE_Thread_Mutex); - extern GridState* si_GridStates[]; // debugging code, should be deleted some day MapManager::MapManager() @@ -116,7 +111,7 @@ Map* MapManager::_createBaseMap(uint32 id) if (m == NULL) { - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, Guard, Lock, NULL); const MapEntry* entry = sMapStore.LookupEntry(id); if (entry && entry->Instanceable()) @@ -166,14 +161,35 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) if (!entry->IsDungeon()) return true; + InstanceTemplate const* instance = objmgr.GetInstanceTemplate(mapid); + if (!instance) + return false; + + //The player has a heroic mode and tries to enter into instance which has no a heroic mode + MapDifficulty const* mapDiff = GetMapDifficultyData(entry->MapID,player->GetDifficulty(entry->IsRaid())); + if (!mapDiff) + { + bool isNormalTargetMap = entry->IsRaid() + ? (player->GetRaidDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) + : (player->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL); + + // Send aborted message + // FIX ME: what about absent normal/heroic mode with specific players limit... + player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, isNormalTargetMap ? DUNGEON_DIFFICULTY_NORMAL : DUNGEON_DIFFICULTY_HEROIC); + return false; + } + + //Bypass checks for GMs + if (player->isGameMaster()) + return true; + const char *mapName = entry->name[player->GetSession()->GetSessionDbcLocale()]; Group* pGroup = player->GetGroup(); if (entry->IsRaid()) { // can only enter in a raid group - // GMs can avoid raid limitations - if ((!pGroup || !pGroup->isRaidGroup()) && !player->isGameMaster() && !sWorld.getConfig(CONFIG_INSTANCE_IGNORE_RAID)) + if ((!pGroup || !pGroup->isRaidGroup()) && !sWorld.getConfig(CONFIG_INSTANCE_IGNORE_RAID)) { // probably there must be special opcode, because client has this string constant in GlobalStrings.lua // TODO: this is not a good place to send the message @@ -183,20 +199,6 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) } } - //The player has a heroic mode and tries to enter into instance which has no a heroic mode - MapDifficulty const* mapDiff = GetMapDifficultyData(entry->MapID,player->GetDifficulty(entry->IsRaid())); - if (!mapDiff) - { - bool isNormalTargetMap = entry->IsRaid() - ? (player->GetRaidDifficulty() == RAID_DIFFICULTY_10MAN_NORMAL) - : (player->GetDungeonDifficulty() == DUNGEON_DIFFICULTY_NORMAL); - - // Send aborted message - // FIX ME: what about absent normal/heroic mode with specific players limit... - player->SendTransferAborted(mapid, TRANSFER_ABORT_DIFFICULTY, isNormalTargetMap ? DUNGEON_DIFFICULTY_NORMAL : DUNGEON_DIFFICULTY_HEROIC); - return false; - } - if (!player->isAlive()) { if (Corpse *corpse = player->GetCorpse()) @@ -226,49 +228,24 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) sLog.outDebug("Map::CanPlayerEnter - player '%s' is dead but does not have a corpse!", player->GetName()); } - InstanceTemplate const* instance = objmgr.GetInstanceTemplate(mapid); - if (!instance) - return false; - //Get instance where player's group is bound & its map if (pGroup) { - InstanceGroupBind* boundedInstance = pGroup->GetBoundInstance(player); + InstanceGroupBind* boundedInstance = pGroup->GetBoundInstance(entry); if (boundedInstance && boundedInstance->save) - { - if (Map *boundedMap = MapManager::Instance().FindMap(mapid,boundedInstance->save->GetInstanceId())) - { + if (Map *boundedMap = sMapMgr.FindMap(mapid,boundedInstance->save->GetInstanceId())) + if (!loginCheck && !boundedMap->CanEnter(player)) + return false; + /* + This check has to be moved to InstanceMap::CanEnter() // Player permanently bounded to different instance than groups one - InstancePlayerBind* playerBoundedInstance = player->GetBoundInstance(mapid, player->GetDungeonDifficulty()); + InstancePlayerBind* playerBoundedInstance = player->GetBoundInstance(mapid, player->GetDifficulty(entry->IsRaid())); if (playerBoundedInstance && playerBoundedInstance->perm && playerBoundedInstance->save && boundedInstance->save->GetInstanceId() != playerBoundedInstance->save->GetInstanceId()) { //TODO: send some kind of error message to the player return false; - } - - // Encounters in progress - if (!loginCheck && entry->IsRaid() && ((InstanceMap*)boundedMap)->GetInstanceData() && ((InstanceMap*)boundedMap)->GetInstanceData()->IsEncounterInProgress()) - { - sLog.outDebug("MAP: Player '%s' cannot enter instance '%s' while an encounter is in progress.", player->GetName(), mapName); - player->SendTransferAborted(mapid, TRANSFER_ABORT_ZONE_IN_COMBAT); - return false; - } - - // Instance is full - MapDifficulty const* mapDiff = ((InstanceMap*)boundedMap)->GetMapDifficulty(); - int8 maxPlayers = mapDiff ? mapDiff->maxPlayers : 0; - if (maxPlayers != -1) //-1: unlimited access - { - if (boundedMap->GetPlayersCountExceptGMs() >= (loginCheck ? maxPlayers+1 : maxPlayers)) - { - sLog.outDebug("MAP: Player '%s' cannot enter instance '%s' because it is full.", player->GetName(), mapName); - player->SendTransferAborted(mapid, TRANSFER_ABORT_MAX_PLAYERS); - return false; - } - } - } - } + }*/ } //Other requirements @@ -307,7 +284,7 @@ void MapManager::Update(uint32 diff) for (iter = i_maps.begin(); iter != i_maps.end(); ++iter) iter->second->DelayedUpdate(i_timer.GetCurrent()); - ObjectAccessor::Instance().Update(i_timer.GetCurrent()); + sObjectAccessor.Update(i_timer.GetCurrent()); for (TransportSet::iterator iter = m_Transports.begin(); iter != m_Transports.end(); ++iter) (*iter)->Update(i_timer.GetCurrent()); @@ -361,7 +338,7 @@ void MapManager::InitMaxInstanceId() uint32 MapManager::GetNumInstances() { - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, Guard, Lock, NULL); uint32 ret = 0; for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) @@ -378,7 +355,7 @@ uint32 MapManager::GetNumInstances() uint32 MapManager::GetNumPlayersInInstances() { - Guard guard(*this); + ACE_GUARD_RETURN(ACE_Thread_Mutex, Guard, Lock, NULL); uint32 ret = 0; for (MapMapType::iterator itr = i_maps.begin(); itr != i_maps.end(); ++itr) diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index d94f9fced0e..47cb9d2f795 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -21,8 +21,8 @@ #ifndef TRINITY_MAPMANAGER_H #define TRINITY_MAPMANAGER_H -#include "Platform/Define.h" -#include "Policies/Singleton.h" +#include "Define.h" +#include "ace/Singleton.h" #include "ace/Thread_Mutex.h" #include "Common.h" #include "Map.h" @@ -31,10 +31,9 @@ class Transport; -class MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLockable<MapManager, ACE_Thread_Mutex> > +class MapManager { - - friend class Trinity::OperatorNew<MapManager>; + friend class ACE_Singleton<MapManager, ACE_Thread_Mutex>; typedef UNORDERED_MAP<uint32, Map*> MapMapType; typedef std::pair<UNORDERED_MAP<uint32, Map*>::iterator, bool> MapMapPair; @@ -108,6 +107,21 @@ class MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLock return IsValidMapCoord(loc.GetMapId(), loc.GetPositionX(), loc.GetPositionY(), loc.GetPositionZ(), loc.GetOrientation()); } + // 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) + { + float mod = o *-1; + mod = fmod(mod, 2.0f * static_cast<float>(M_PI)); + mod = -mod + 2.0f * M_PI; + return mod; + } + return fmod(o, 2.0f * static_cast<float>(M_PI)); + } + void DoDelayedMovesAndRemoves(); void LoadTransports(); @@ -147,7 +161,7 @@ class MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLock return (iter == i_maps.end() ? NULL : iter->second); } - typedef Trinity::ClassLevelLockable<MapManager, ACE_Thread_Mutex>::Lock Guard; + ACE_Thread_Mutex Lock; uint32 i_gridCleanUpDelay; MapMapType i_maps; IntervalTimer i_timer; @@ -155,4 +169,5 @@ class MapManager : public Trinity::Singleton<MapManager, Trinity::ClassLevelLock uint32 i_MaxInstanceId; MapUpdater m_updater; }; +#define sMapMgr (*ACE_Singleton<MapManager, ACE_Thread_Mutex>::instance()) #endif diff --git a/src/server/game/Maps/MapRefManager.h b/src/server/game/Maps/MapRefManager.h index 4337aa75fd9..2cf38c1b000 100644 --- a/src/server/game/Maps/MapRefManager.h +++ b/src/server/game/Maps/MapRefManager.h @@ -19,7 +19,7 @@ #ifndef _MAPREFMANAGER #define _MAPREFMANAGER -#include "Utilities/LinkedReference/RefManager.h" +#include "RefManager.h" class MapReference; diff --git a/src/server/game/Maps/MapReference.h b/src/server/game/Maps/MapReference.h index 7cd4fcde76c..e74fdba229b 100644 --- a/src/server/game/Maps/MapReference.h +++ b/src/server/game/Maps/MapReference.h @@ -19,7 +19,7 @@ #ifndef _MAPREFERENCE_H #define _MAPREFERENCE_H -#include "Utilities/LinkedReference/Reference.h" +#include "Reference.h" #include "Map.h" class MapReference : public Reference<Map, Player> diff --git a/src/server/game/Maps/MapUpdater.cpp b/src/server/game/Maps/MapUpdater.cpp index f9bb5e2bbbc..5720ed1eb50 100644 --- a/src/server/game/Maps/MapUpdater.cpp +++ b/src/server/game/Maps/MapUpdater.cpp @@ -1,7 +1,7 @@ #include "MapUpdater.h" #include "DelayExecutor.h" #include "Map.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include <ace/Guard_T.h> #include <ace/Method_Request.h> diff --git a/src/server/game/Miscellaneous/Formulas.h b/src/server/game/Miscellaneous/Formulas.h index e5961834a78..8244e344275 100644 --- a/src/server/game/Miscellaneous/Formulas.h +++ b/src/server/game/Miscellaneous/Formulas.h @@ -27,9 +27,14 @@ namespace Trinity { namespace Honor { + inline float hk_honor_at_level_f(uint8 level, uint32 count = 1) + { + return count * level * 1.55f; + } + inline uint32 hk_honor_at_level(uint8 level, uint32 count = 1) { - return uint32(ceil(count * (33.333f * ((float)level) / 21.50537f))); + return ceil(hk_honor_at_level_f(level, count)); } } namespace XP diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index c0c8fc486f3..435c6549f56 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -87,7 +87,8 @@ enum TrinityStrings LANG_USING_EVENT_AI = 59, LANG_CONNECTED_PLAYERS = 60, LANG_ACCOUNT_ADDON = 61, - // Room for more level 0 62-99 not used + LANG_IMPROPER_VALUE = 62, + // Room for more level 0 63-99 not used // level 1 chat LANG_GLOBAL_NOTIFY = 100, diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 903dd4b09ca..0d5025a5d5f 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -21,7 +21,7 @@ #ifndef TRINITY_SHAREDDEFINES_H #define TRINITY_SHAREDDEFINES_H -#include "Platform/Define.h" +#include "Define.h" #include <cassert> // loot modes for creatures and gameobjects, bitmask! @@ -287,7 +287,7 @@ const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = { #define SPELL_ATTR_EX_NEGATIVE 0x00000080 // 7 #define SPELL_ATTR_EX_NOT_IN_COMBAT_TARGET 0x00000100 // 8 Spell req target not to be in combat state #define SPELL_ATTR_EX_UNK9 0x00000200 // 9 melee spells -#define SPELL_ATTR_EX_UNK10 0x00000400 // 10 no generates threat on cast 100%? (old NO_INITIAL_AGGRO) +#define SPELL_ATTR_EX_NO_THREAT 0x00000400 // 10 no generates threat on cast 100% (old NO_INITIAL_AGGRO) #define SPELL_ATTR_EX_UNK11 0x00000800 // 11 aura #define SPELL_ATTR_EX_UNK12 0x00001000 // 12 #define SPELL_ATTR_EX_UNK13 0x00002000 // 13 @@ -643,7 +643,7 @@ enum SpellEffects SPELL_EFFECT_LANGUAGE = 39, SPELL_EFFECT_DUAL_WIELD = 40, SPELL_EFFECT_JUMP = 41, - SPELL_EFFECT_JUMP2 = 42, + SPELL_EFFECT_JUMP_DEST = 42, SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER= 43, SPELL_EFFECT_SKILL_STEP = 44, SPELL_EFFECT_ADD_HONOR = 45, @@ -750,7 +750,7 @@ enum SpellEffects SPELL_EFFECT_ACTIVATE_RUNE = 146, SPELL_EFFECT_QUEST_FAIL = 147, SPELL_EFFECT_148 = 148, - SPELL_EFFECT_149 = 149, + SPELL_EFFECT_CHARGE_DEST = 149, SPELL_EFFECT_150 = 150, SPELL_EFFECT_TRIGGER_SPELL_2 = 151, SPELL_EFFECT_152 = 152, @@ -2769,4 +2769,31 @@ enum SpellFamilyNames SPELLFAMILY_PET = 17 }; +enum TradeStatus +{ + TRADE_STATUS_BUSY = 0, + TRADE_STATUS_BEGIN_TRADE = 1, + TRADE_STATUS_OPEN_WINDOW = 2, + TRADE_STATUS_TRADE_CANCELED = 3, + TRADE_STATUS_TRADE_ACCEPT = 4, + TRADE_STATUS_BUSY_2 = 5, + TRADE_STATUS_NO_TARGET = 6, + TRADE_STATUS_BACK_TO_TRADE = 7, + TRADE_STATUS_TRADE_COMPLETE = 8, + // 9? + TRADE_STATUS_TARGET_TO_FAR = 10, + TRADE_STATUS_WRONG_FACTION = 11, + TRADE_STATUS_CLOSE_WINDOW = 12, + // 13? + TRADE_STATUS_IGNORE_YOU = 14, + TRADE_STATUS_YOU_STUNNED = 15, + TRADE_STATUS_TARGET_STUNNED = 16, + TRADE_STATUS_YOU_DEAD = 17, + TRADE_STATUS_TARGET_DEAD = 18, + TRADE_STATUS_YOU_LOGOUT = 19, + TRADE_STATUS_TARGET_LOGOUT = 20, + TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action + TRADE_STATUS_ONLY_CONJURED = 22 // You can only trade conjured items... (cross realm BG related). +}; + #endif diff --git a/src/server/game/Movement/DestinationHolder.h b/src/server/game/Movement/DestinationHolder.h index e09a153615c..c0ee668eb99 100644 --- a/src/server/game/Movement/DestinationHolder.h +++ b/src/server/game/Movement/DestinationHolder.h @@ -21,7 +21,7 @@ #ifndef TRINITY_DESTINATION_HOLDER_H #define TRINITY_DESTINATION_HOLDER_H -#include "Platform/Define.h" +#include "Define.h" #include "Timer.h" class WorldObject; diff --git a/src/server/game/Movement/FollowerRefManager.h b/src/server/game/Movement/FollowerRefManager.h index c2068b36f81..e451cd4747a 100644 --- a/src/server/game/Movement/FollowerRefManager.h +++ b/src/server/game/Movement/FollowerRefManager.h @@ -21,7 +21,7 @@ #ifndef _FOLLOWERREFMANAGER #define _FOLLOWERREFMANAGER -#include "Utilities/LinkedReference/RefManager.h" +#include "RefManager.h" class Unit; class TargetedMovementGeneratorBase; diff --git a/src/server/game/Movement/FollowerReference.h b/src/server/game/Movement/FollowerReference.h index e468f79f017..72a6d4f463e 100644 --- a/src/server/game/Movement/FollowerReference.h +++ b/src/server/game/Movement/FollowerReference.h @@ -21,7 +21,7 @@ #ifndef _FOLLOWERREFERENCE_H #define _FOLLOWERREFERENCE_H -#include "Utilities/LinkedReference/Reference.h" +#include "Reference.h" class TargetedMovementGeneratorBase; class Unit; diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index 5c20494bfcc..46a4c806067 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -440,9 +440,17 @@ MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) { if (i_owner->GetTypeId() == TYPEID_PLAYER) { - DEBUG_LOG("Player (GUID: %u) taxi to (Path %u node %u)", i_owner->GetGUIDLow(), path, pathnode); - FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(path,pathnode); - Mutate(mgen, MOTION_SLOT_CONTROLLED); + if (path < sTaxiPathNodesByPath.size()) + { + DEBUG_LOG("%s taxi to (Path %u node %u)", i_owner->GetName(), path, pathnode); + FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(sTaxiPathNodesByPath[path],pathnode); + Mutate(mgen, MOTION_SLOT_CONTROLLED); + } + else + { + sLog.outError("%s attempt taxi to (not existed Path %u node %u)", + i_owner->GetName(), path, pathnode); + } } else { diff --git a/src/server/game/Movement/MovementGenerator.h b/src/server/game/Movement/MovementGenerator.h index ab7a52c483e..9699f6951c2 100644 --- a/src/server/game/Movement/MovementGenerator.h +++ b/src/server/game/Movement/MovementGenerator.h @@ -21,10 +21,10 @@ #ifndef TRINITY_MOVEMENTGENERATOR_H #define TRINITY_MOVEMENTGENERATOR_H -#include "Platform/Define.h" -#include "Policies/Singleton.h" -#include "Dynamic/ObjectRegistry.h" -#include "Dynamic/FactoryHolder.h" +#include "Define.h" +#include "ace/Singleton.h" +#include "ObjectRegistry.h" +#include "FactoryHolder.h" #include "Common.h" #include "MotionMaster.h" diff --git a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp index 43c6052d2d3..73e24486768 100644 --- a/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/ConfusedMovementGenerator.cpp @@ -47,38 +47,44 @@ ConfusedMovementGenerator<T>::Initialize(T &unit) bool is_water_ok, is_land_ok; _InitSpecific(unit, is_water_ok, is_land_ok); - VMAP::IVMapManager *vMaps = VMAP::VMapFactory::createOrGetVMapManager(); - for (uint8 idx = 0; idx <= MAX_CONF_WAYPOINTS; ++idx) { - const bool isInLoS = vMaps->isInLineOfSight(unit.GetMapId(), x, y, z + 2.0f, i_waypoints[idx][0], i_waypoints[idx][1], z + 2.0f); - if (isInLoS) - { - const float wanderX = wander_distance*rand_norm() - wander_distance/2; - const float wanderY = wander_distance*rand_norm() - wander_distance/2; - i_waypoints[idx][0] = x + wanderX; - i_waypoints[idx][1] = y + wanderY; - } - else + float wanderX = x + wander_distance*rand_norm() - wander_distance/2; + float wanderY = y + wander_distance*rand_norm() - wander_distance/2; + Trinity::NormalizeMapCoord(wanderX); + Trinity::NormalizeMapCoord(wanderY); + + float new_z = map->GetHeight(wanderX, wanderY, z, true); + if (new_z > INVALID_HEIGHT && unit.IsWithinLOS(wanderX, wanderY, new_z)) { - i_waypoints[idx][0] = x; - i_waypoints[idx][1] = y; + // Don't move in water if we're not already in + // Don't move on land if we're not already on it either + bool is_water_now = map->IsInWater(x, y, z); + bool is_water_next = map->IsInWater(wanderX, wanderY, new_z); + if ((is_water_now && !is_water_next && !is_land_ok) || (!is_water_now && is_water_next && !is_water_ok)) + { + i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; // Back to previous location + i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; + i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx-1][2] : z; + continue; + } + + // Taken from FleeingMovementGenerator + if (!(new_z - z) || wander_distance / fabs(new_z - z) > 1.0f) + { + i_waypoints[idx][0] = wanderX; + i_waypoints[idx][1] = wanderY; + i_waypoints[idx][2] = new_z; + continue; + } } - - // prevent invalid coordinates generation - Trinity::NormalizeMapCoord(i_waypoints[idx][0]); - Trinity::NormalizeMapCoord(i_waypoints[idx][1]); - - bool is_water = map->IsInWater(i_waypoints[idx][0],i_waypoints[idx][1],z); - // if generated wrong path just ignore - if ((is_water && !is_water_ok) || (!is_water && !is_land_ok)) + else // Back to previous location { i_waypoints[idx][0] = idx > 0 ? i_waypoints[idx-1][0] : x; i_waypoints[idx][1] = idx > 0 ? i_waypoints[idx-1][1] : y; + i_waypoints[idx][2] = idx > 0 ? i_waypoints[idx-1][2] : z; + continue; } - - unit.UpdateGroundPositionZ(i_waypoints[idx][0],i_waypoints[idx][1],z); - i_waypoints[idx][2] = z; } unit.SetUInt64Value(UNIT_FIELD_TARGET, 0); diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index 2a0c7c0253d..416b775ef7e 100644 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -229,24 +229,20 @@ template bool WaypointMovementGenerator<Player>::Update(Player &, const uint32 & template void WaypointMovementGenerator<Player>::MovementInform(Player &); //----------------------------------------------------// -void FlightPathMovementGenerator::LoadPath(Player &) -{ - objmgr.GetTaxiPathNodes(i_pathId, i_path,i_mapIds); -} uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const { - if (i_currentNode >= i_mapIds.size()) - return i_mapIds.size(); + if (i_currentNode >= i_path->size()) + return i_path->size(); - uint32 curMapId = i_mapIds[i_currentNode]; - for (uint32 i = i_currentNode; i < i_mapIds.size(); ++i) + uint32 curMapId = (*i_path)[i_currentNode].mapid; + for (uint32 i = i_currentNode; i < i_path->size(); ++i) { - if (i_mapIds[i] != curMapId) + if ((*i_path)[i].mapid != curMapId) return i; } - return i_mapIds.size(); + return i_path->size(); } void FlightPathMovementGenerator::Initialize(Player &player) @@ -254,23 +250,12 @@ void FlightPathMovementGenerator::Initialize(Player &player) player.getHostileRefManager().setOnlineOfflineState(false); player.addUnitState(UNIT_STAT_IN_FLIGHT); player.SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE | UNIT_FLAG_TAXI_FLIGHT); - LoadPath(player); Traveller<Player> traveller(player); // do not send movement, it was sent already - i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false); - + i_destinationHolder.SetDestination(traveller, (*i_path)[i_currentNode].x, (*i_path)[i_currentNode].y, (*i_path)[i_currentNode].z, false); + // For preloading end grid + InitEndGridInfo(); player.SendMonsterMoveByPath(GetPath(), GetCurrentNode(), GetPathAtMapEnd()); - - // Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will - // be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. - - uint32 nodeCount = i_mapIds.size(); // Get the number of nodes in the path. i_path and i_mapIds are the - // same size when loaded in ObjectMgr::GetTaxiPathNodes, called from LoadPath() - - m_endMapId = i_mapIds[nodeCount -1]; // Get the map ID from the last node - m_preloadTargetNode = nodeCount / 2; // Split the number of nodes in half to preload the flightmaster half-way through the flight - m_endGridX = i_path[nodeCount -1].x; // Get the X position from the last node - m_endGridY = i_path[nodeCount -1].y; // Get tye Y position from the last node } void FlightPathMovementGenerator::Finalize(Player & player) @@ -280,6 +265,7 @@ void FlightPathMovementGenerator::Finalize(Player & player) float x, y, z; i_destinationHolder.GetLocationNow(player.GetBaseMap(), x, y, z); player.SetPosition(x, y, z, player.GetOrientation()); + } bool FlightPathMovementGenerator::Update(Player &player, const uint32 &diff) @@ -292,18 +278,22 @@ bool FlightPathMovementGenerator::Update(Player &player, const uint32 &diff) i_destinationHolder.ResetUpdate(FLIGHT_TRAVEL_UPDATE); if (i_destinationHolder.HasArrived()) { - uint32 curMap = i_mapIds[i_currentNode]; + DoEventIfAny(player,(*i_path)[i_currentNode], false); + + uint32 curMap = (*i_path)[i_currentNode].mapid; ++i_currentNode; if (MovementInProgress()) { + DoEventIfAny(player,(*i_path)[i_currentNode], true); + DEBUG_LOG("loading node %u for player %s", i_currentNode, player.GetName()); - if (i_mapIds[i_currentNode] == curMap) + if ((*i_path)[i_currentNode].mapid == curMap) { // do not send movement, it was sent already - i_destinationHolder.SetDestination(traveller, i_path[i_currentNode].x, i_path[i_currentNode].y, i_path[i_currentNode].z, false); + i_destinationHolder.SetDestination(traveller, (*i_path)[i_currentNode].x, (*i_path)[i_currentNode].y, (*i_path)[i_currentNode].z, false); } - - // check if it's time to preload the flightmaster grid at path end + + // check if it's time to preload the flightmaster grid at path end if (i_currentNode == m_preloadTargetNode) PreloadEndGrid(); @@ -324,13 +314,13 @@ bool FlightPathMovementGenerator::Update(Player &player, const uint32 &diff) void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport() { - if (i_mapIds.empty()) + if (i_path->empty()) return; - uint32 map0 = i_mapIds[0]; - for (size_t i = 1; i < i_mapIds.size(); ++i) + uint32 map0 = (*i_path)[0].mapid; + for (size_t i = 1; i < i_path->size(); ++i) { - if (i_mapIds[i] != map0) + if ((*i_path)[i].mapid != map0) { i_currentNode = i; return; @@ -338,10 +328,22 @@ void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport() } } +void FlightPathMovementGenerator::InitEndGridInfo() +{ + // Storage to preload flightmaster grid at end of flight. For multi-stop flights, this will + // be reinitialized for each flightmaster at the end of each spline (or stop) in the flight. + + uint32 nodeCount = (*i_path).size(); // Get the number of nodes in the path. + m_endMapId = (*i_path)[nodeCount -1].mapid; // Get the map ID from the last node + m_preloadTargetNode = nodeCount - 3; // 2 nodes before the final node, we pre-load the grid + m_endGridX = (*i_path)[nodeCount -1].x; // Get the X position from the last node + m_endGridY = (*i_path)[nodeCount -1].y; // Get the Y position from the last node +} + void FlightPathMovementGenerator::PreloadEndGrid() { // used to preload the final grid where the flightmaster is - Map *endMap = MapManager::Instance().FindMap(m_endMapId); + Map *endMap = sMapMgr.FindMap(m_endMapId); // Load the grid if (endMap) @@ -353,6 +355,17 @@ void FlightPathMovementGenerator::PreloadEndGrid() sLog.outDetail("Unable to determine map to preload flightmaster grid"); } +void FlightPathMovementGenerator::DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure) +{ + if (uint32 eventid = departure ? node.departureEventID : node.arrivalEventID) + { + sLog.outDebug("Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.index, node.path, player.GetName()); + player.GetMap()->ScriptsStart(sEventScripts, eventid, &player, &player); + } +} + + + // // Unique1's ASTAR Pathfinding Code... For future use & reference... // diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index 4b74e80e168..cce0eff290e 100644 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -39,21 +39,24 @@ #include <set> #define FLIGHT_TRAVEL_UPDATE 100 -#define STOP_TIME_FOR_PLAYER 3 * MINUTE * IN_MILISECONDS // 3 Minutes +#define STOP_TIME_FOR_PLAYER 3 * MINUTE * IN_MILLISECONDS // 3 Minutes #define TIMEDIFF_NEXT_WP 250 -template<class T, class P = Path> +template<class T, class P> class PathMovementBase { public: PathMovementBase() : i_currentNode(0) {} virtual ~PathMovementBase() {}; - bool MovementInProgress(void) const { return i_currentNode < i_path.Size(); } + bool MovementInProgress(void) const { return i_currentNode < i_path->size(); } void LoadPath(T &); void ReloadPath(T &); uint32 GetCurrentNode() const { return i_currentNode; } + + bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; } + bool GetPosition(float& x, float& y, float& z) const { i_destinationHolder.GetLocationNowNoMicroMovement(x,y,z); return true; } protected: uint32 i_currentNode; @@ -64,7 +67,7 @@ class PathMovementBase template<class T> class WaypointMovementGenerator - : public MovementGeneratorMedium< T, WaypointMovementGenerator<T> >, public PathMovementBase<T> + : public MovementGeneratorMedium< T, WaypointMovementGenerator<T> >, public PathMovementBase<T, WaypointPath const*> { public: WaypointMovementGenerator(uint32 _path_id = 0, bool _repeating = true) : @@ -93,28 +96,31 @@ class WaypointMovementGenerator */ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, -public PathMovementBase<Player> +public PathMovementBase<Player,TaxiPathNodeList const*> { - uint32 i_pathId; - std::vector<uint32> i_mapIds; public: - explicit FlightPathMovementGenerator(uint32 id, uint32 startNode = 0) : i_pathId(id) { i_currentNode = startNode; } + explicit FlightPathMovementGenerator(TaxiPathNodeList const& pathnodes, uint32 startNode = 0) + { + i_path = &pathnodes; + i_currentNode = startNode; + } void Initialize(Player &); + void Reset(Player &u){}; void Finalize(Player &); - void Reset(Player &) {} bool Update(Player &, const uint32 &); MovementGeneratorType GetMovementGeneratorType() { return FLIGHT_MOTION_TYPE; } - void LoadPath(Player &); - void ReloadPath(Player &) { /* don't reload flight path */ } - - Path& GetPath() { return i_path; } + TaxiPathNodeList const& GetPath() { return *i_path; } uint32 GetPathAtMapEnd() const; - bool HasArrived() const { return (i_currentNode >= i_path.Size()); } + bool HasArrived() const { return (i_currentNode >= i_path->size()); } void SetCurrentNodeAfterTeleport(); void SkipCurrentNode() { ++i_currentNode; } - bool GetDestination(float& x, float& y, float& z) const { i_destinationHolder.GetDestination(x,y,z); return true; } + void DoEventIfAny(Player& player, TaxiPathNodeEntry const& node, bool departure); + bool GetDestination(float& x, float& y, float& z) const { return PathMovementBase<Player,TaxiPathNodeList const*>::GetDestination(x,y,z); } + + void PreloadEndGrid(); + void InitEndGridInfo(); private: // storage for preloading the flightmaster grid at end // before reaching final waypoint @@ -122,7 +128,6 @@ public PathMovementBase<Player> uint32 m_preloadTargetNode; float m_endGridX; float m_endGridY; - void PreloadEndGrid(); }; #endif diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h index 9ec079f3c9c..de73d9270af 100644 --- a/src/server/game/Movement/Waypoints/Path.h +++ b/src/server/game/Movement/Waypoints/Path.h @@ -24,65 +24,64 @@ #include "Common.h" #include <vector> +struct SimplePathNode +{ + float x, y, z; +}; +template<typename PathElem, typename PathNode = PathElem> + class Path { public: - struct PathNode - { - float x,y,z; - }; - - void SetLength(const unsigned int sz) - { - i_nodes.resize(sz); - } + size_t size() const { return i_nodes.size(); } + bool empty() const { return i_nodes.empty(); } + void resize(unsigned int sz) { i_nodes.resize(sz); } + void clear() { i_nodes.clear(); } + void erase(uint32 idx) { i_nodes.erase(i_nodes.begin()+idx); } - unsigned int Size() const { return i_nodes.size(); } - bool Empty() const { return i_nodes.empty(); } - void Resize(unsigned int sz) { i_nodes.resize(sz); } - void Clear(void) { i_nodes.clear(); } - PathNode const* GetNodes(uint32 start = 0) const { return &i_nodes[start]; } - float GetTotalLength() const { return GetTotalLength(0,Size()); } float GetTotalLength(uint32 start, uint32 end) const { - float len = 0, xd, yd, zd; - for (unsigned int idx=start+1; idx < end; ++idx) + float len = 0.0f; + for (uint32 idx=start+1; idx < end; ++idx) { - xd = i_nodes[ idx ].x - i_nodes[ idx-1 ].x; - yd = i_nodes[ idx ].y - i_nodes[ idx-1 ].y; - zd = i_nodes[ idx ].z - i_nodes[ idx-1 ].z; + PathNode const& node = i_nodes[idx]; + PathNode const& prev = i_nodes[idx-1]; + float xd = node.x - prev.x; + float yd = node.y - prev.y; + float zd = node.z - prev.z; len += sqrtf(xd*xd + yd*yd + zd*zd); } return len; } + + float GetTotalLength() const { return GetTotalLength(0,size()); } float GetPassedLength(uint32 curnode, float x, float y, float z) { - float len = 0, xd, yd, zd; - for (unsigned int idx=1; idx < curnode; ++idx) - { - xd = i_nodes[ idx ].x - i_nodes[ idx-1 ].x; - yd = i_nodes[ idx ].y - i_nodes[ idx-1 ].y; - zd = i_nodes[ idx ].z - i_nodes[ idx-1 ].z; - len += sqrtf(xd*xd + yd*yd + zd*zd); - } + float len = GetTotalLength(0,curnode); if (curnode > 0) { - xd = x - i_nodes[curnode-1].x; - yd = y - i_nodes[curnode-1].y; - zd = z - i_nodes[curnode-1].z; + PathNode const& node = i_nodes[curnode-1]; + float xd = x - node.x; + float yd = y - node.y; + float zd = z - node.z; len += sqrtf(xd*xd + yd*yd + zd*zd); } return len; } - PathNode& operator[](const unsigned int idx) { return i_nodes[idx]; } - const PathNode& operator()(const unsigned int idx) const { return i_nodes[idx]; } + PathNode& operator[](size_t idx) { return i_nodes[idx]; } + PathNode const& operator[](size_t idx) const { return i_nodes[idx]; } + + void set(size_t idx, PathElem elem) { i_nodes[idx] = elem; } protected: - std::vector<PathNode> i_nodes; + std::vector<PathElem> i_nodes; }; + +typedef Path<SimplePathNode> SimplePath; + #endif diff --git a/src/server/game/Movement/Waypoints/WaypointManager.cpp b/src/server/game/Movement/Waypoints/WaypointManager.cpp index 0cbdd0bf975..078d272f62a 100644 --- a/src/server/game/Movement/Waypoints/WaypointManager.cpp +++ b/src/server/game/Movement/Waypoints/WaypointManager.cpp @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "GridDefines.h" #include "WaypointManager.h" #include "ProgressBar.h" diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 71659a20be7..b19dc01ccd9 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -165,7 +165,7 @@ bool OPvPCapturePoint::DelCreature(uint32 type) // explicit removal from map // beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted // so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed - //if (Map * map = MapManager::Instance().FindMap(cr->GetMapId())) + //if (Map * map = sMapMgr.FindMap(cr->GetMapId())) // map->Remove(cr,false); // delete respawn time for this creature WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u'", guid); diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index 55ea98a2a1f..8aa19ef94df 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -19,7 +19,7 @@ #ifndef OUTDOOR_PVP_H_ #define OUTDOOR_PVP_H_ -#include "Util.h" +#include "Utilities/Util.h" #include "SharedDefines.h" #include "ZoneScript.h" diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index 4a0baf49a04..1ec2bcb6a9c 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -25,9 +25,6 @@ #include "OutdoorPvPEP.h" #include "ObjectMgr.h" #include "Player.h" -#include "Policies/SingletonImp.h" - -INSTANTIATE_SINGLETON_1(OutdoorPvPMgr); OutdoorPvPMgr::OutdoorPvPMgr() { diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index 1e314bfd169..2a18a602da9 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -22,7 +22,7 @@ #define OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL 1000 #include "OutdoorPvP.h" -#include "Policies/Singleton.h" +#include "ace/Singleton.h" class Player; class GameObject; @@ -79,7 +79,7 @@ private: uint32 m_UpdateTimer; }; -#define sOutdoorPvPMgr Trinity::Singleton<OutdoorPvPMgr>::Instance() +#define sOutdoorPvPMgr (*ACE_Singleton<OutdoorPvPMgr, ACE_Null_Mutex>::instance()) #endif /*OUTDOOR_PVP_MGR_H_*/ diff --git a/src/server/game/Pools/PoolHandler.cpp b/src/server/game/Pools/PoolMgr.cpp index 0b5a55623e0..28fb67ad4dd 100644 --- a/src/server/game/Pools/PoolHandler.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -16,14 +16,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "PoolHandler.h" +#include "PoolMgr.h" #include "ObjectMgr.h" #include "ProgressBar.h" #include "Log.h" #include "MapManager.h" -#include "Policies/SingletonImp.h" - -INSTANTIATE_SINGLETON_1(PoolHandler); //////////////////////////////////////////////////////////// // template class SpawnedPoolData @@ -121,10 +118,10 @@ void PoolGroup<T>::AddEntry(PoolObject& poolitem, uint32 maxentries) template <class T> bool PoolGroup<T>::CheckPool() const { - if (EqualChanced.size() == 0) + if (!EqualChanced.size()) { float chance = 0; - for (uint32 i=0; i<ExplicitlyChanced.size(); ++i) + for (uint32 i = 0; i < ExplicitlyChanced.size(); ++i) chance += ExplicitlyChanced[i].chance; if (chance != 100 && chance != 0) return false; @@ -201,7 +198,7 @@ void PoolGroup<Creature>::Despawn1Object(uint32 guid) { objmgr.RemoveCreatureFromGrid(guid, data); - if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) + if (Creature* pCreature = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) pCreature->AddObjectToRemoveList(); } } @@ -214,7 +211,7 @@ void PoolGroup<GameObject>::Despawn1Object(uint32 guid) { objmgr.RemoveGameobjectFromGrid(guid, data); - if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) + if (GameObject* pGameobject = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) pGameobject->AddObjectToRemoveList(); } } @@ -297,7 +294,7 @@ void PoolGroup<Creature>::Spawn1Object(PoolObject* obj) objmgr.AddCreatureToGrid(obj->guid, data); // Spawn if necessary (loaded grids only) - Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(data->mapid)); + Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid)); // We use spawn coords to spawn if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { @@ -323,7 +320,7 @@ void PoolGroup<GameObject>::Spawn1Object(PoolObject* obj) objmgr.AddGameobjectToGrid(obj->guid, data); // Spawn if necessary (loaded grids only) // this base map checked as non-instanced and then only existed - Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(data->mapid)); + Map* map = const_cast<Map*>(sMapMgr.CreateBaseMap(data->mapid)); // We use current coords to unspawn, not spawn coords since creature can have changed grid if (!map->Instanceable() && map->IsLoaded(data->posX, data->posY)) { @@ -355,7 +352,7 @@ template <> void PoolGroup<Creature>::ReSpawn1Object(PoolObject* obj) { if (CreatureData const* data = objmgr.GetCreatureData(obj->guid)) - if (Creature* pCreature = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) + if (Creature* pCreature = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_UNIT), (Creature*)NULL)) pCreature->GetMap()->Add(pCreature); } @@ -364,7 +361,7 @@ template <> void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj) { if (GameObjectData const* data = objmgr.GetGOData(obj->guid)) - if (GameObject* pGameobject = ObjectAccessor::Instance().GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) + if (GameObject* pGameobject = sObjectAccessor.GetObjectInWorld(MAKE_NEW_GUID(obj->guid, data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) pGameobject->GetMap()->Add(pGameobject); } @@ -375,13 +372,13 @@ void PoolGroup<Pool>::ReSpawn1Object(PoolObject* /*obj*/) } //////////////////////////////////////////////////////////// -// Methods of class PoolHandler +// Methods of class PoolMgr -PoolHandler::PoolHandler() +PoolMgr::PoolMgr() { } -void PoolHandler::LoadFromDB() +void PoolMgr::LoadFromDB() { QueryResult_AutoPtr result = WorldDatabase.Query("SELECT MAX(entry) FROM pool_template"); if (!result) @@ -657,9 +654,9 @@ void PoolHandler::LoadFromDB() } // The initialize method will spawn all pools not in an event and not in another pool, this is why there is 2 left joins with 2 null checks -void PoolHandler::Initialize() +void PoolMgr::Initialize() { - QueryResult_AutoPtr result = WorldDatabase.Query("SELECT DISTINCT pool_template.entry 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 AND pool_pool.pool_id IS NULL"); + QueryResult_AutoPtr 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"); uint32 count=0; if (result) { @@ -667,13 +664,25 @@ void PoolHandler::Initialize() { Field *fields = result->Fetch(); uint16 pool_entry = fields[0].GetUInt16(); + uint16 pool_pool_id = fields[1].GetUInt16(); + if (!CheckPool(pool_entry)) { - sLog.outErrorDb("Pool Id (%u) has all creatures or gameobjects with explicit chance sum <>100 and no equal chance defined. The pool system cannot pick one to spawn.", pool_entry); + if (pool_pool_id) + // The pool is a child pool in pool_pool table. Ideally we should remove it from the pool handler to ensure it never gets spawned, + // however that could recursively invalidate entire chain of mother pools. It can be done in the future but for now we'll do nothing. + sLog.outErrorDb("Pool Id %u has no equal chance pooled entites defined and explicit chance sum is not 100. This broken pool is a child pool of Id %u and cannot be safely removed.", pool_entry, fields[2].GetUInt16()); + else + sLog.outErrorDb("Pool Id %u has no equal chance pooled entites defined and explicit chance sum is not 100. The pool will not be spawned.", pool_entry); continue; } - SpawnPool(pool_entry);; - count++; + + // Don't spawn child pools, they are spawned recursively by their parent pools + if (!pool_pool_id) + { + SpawnPool(pool_entry);; + count++; + } } while (result->NextRow()); } @@ -683,7 +692,7 @@ void PoolHandler::Initialize() // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the creature is respawned only (added back to map) template<> -void PoolHandler::SpawnPool<Creature>(uint16 pool_id, uint32 db_guid) +void PoolMgr::SpawnPool<Creature>(uint16 pool_id, uint32 db_guid) { if (!mPoolCreatureGroups[pool_id].isEmpty()) mPoolCreatureGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid); @@ -692,7 +701,7 @@ void PoolHandler::SpawnPool<Creature>(uint16 pool_id, uint32 db_guid) // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the gameobject is respawned only (added back to map) template<> -void PoolHandler::SpawnPool<GameObject>(uint16 pool_id, uint32 db_guid) +void PoolMgr::SpawnPool<GameObject>(uint16 pool_id, uint32 db_guid) { if (!mPoolGameobjectGroups[pool_id].isEmpty()) mPoolGameobjectGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, db_guid); @@ -701,13 +710,13 @@ void PoolHandler::SpawnPool<GameObject>(uint16 pool_id, uint32 db_guid) // Call to spawn a pool, if cache if true the method will spawn only if cached entry is different // If it's same, the pool is respawned only template<> -void PoolHandler::SpawnPool<Pool>(uint16 pool_id, uint32 sub_pool_id) +void PoolMgr::SpawnPool<Pool>(uint16 pool_id, uint32 sub_pool_id) { if (!mPoolPoolGroups[pool_id].isEmpty()) mPoolPoolGroups[pool_id].SpawnObject(mSpawnedData, mPoolTemplate[pool_id].MaxLimit, sub_pool_id); } -void PoolHandler::SpawnPool(uint16 pool_id) +void PoolMgr::SpawnPool(uint16 pool_id) { SpawnPool<Pool>(pool_id, 0); SpawnPool<GameObject>(pool_id, 0); @@ -715,7 +724,7 @@ void PoolHandler::SpawnPool(uint16 pool_id) } // Call to despawn a pool, all gameobjects/creatures in this pool are removed -void PoolHandler::DespawnPool(uint16 pool_id) +void PoolMgr::DespawnPool(uint16 pool_id) { if (!mPoolCreatureGroups[pool_id].isEmpty()) mPoolCreatureGroups[pool_id].DespawnObject(mSpawnedData); @@ -728,7 +737,7 @@ void PoolHandler::DespawnPool(uint16 pool_id) } // Method that check chance integrity of the creatures and gameobjects in this pool -bool PoolHandler::CheckPool(uint16 pool_id) const +bool PoolMgr::CheckPool(uint16 pool_id) const { return pool_id <= max_pool_id && mPoolGameobjectGroups[pool_id].CheckPool() && @@ -740,7 +749,7 @@ bool PoolHandler::CheckPool(uint16 pool_id) const // Here we cache only the creature/gameobject whose guid is passed as parameter // Then the spawn pool call will use this cache to decide template<typename T> -void PoolHandler::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id) +void PoolMgr::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id) { if (uint16 motherpoolid = IsPartOfAPool<Pool>(pool_id)) SpawnPool<Pool>(motherpoolid, pool_id); @@ -748,6 +757,6 @@ void PoolHandler::UpdatePool(uint16 pool_id, uint32 db_guid_or_pool_id) SpawnPool<T>(pool_id, db_guid_or_pool_id); } -template void PoolHandler::UpdatePool<Pool>(uint16 pool_id, uint32 db_guid_or_pool_id); -template void PoolHandler::UpdatePool<GameObject>(uint16 pool_id, uint32 db_guid_or_pool_id); -template void PoolHandler::UpdatePool<Creature>(uint16 pool_id, uint32 db_guid_or_pool_id);
\ No newline at end of file +template void PoolMgr::UpdatePool<Pool>(uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolMgr::UpdatePool<GameObject>(uint16 pool_id, uint32 db_guid_or_pool_id); +template void PoolMgr::UpdatePool<Creature>(uint16 pool_id, uint32 db_guid_or_pool_id); diff --git a/src/server/game/Pools/PoolHandler.h b/src/server/game/Pools/PoolMgr.h index 0ba4cc7769f..71cae3e4a1b 100644 --- a/src/server/game/Pools/PoolHandler.h +++ b/src/server/game/Pools/PoolMgr.h @@ -19,8 +19,8 @@ #ifndef TRINITY_POOLHANDLER_H #define TRINITY_POOLHANDLER_H -#include "Platform/Define.h" -#include "Policies/Singleton.h" +#include "Define.h" +#include "ace/Singleton.h" #include "Creature.h" #include "GameObject.h" @@ -87,12 +87,13 @@ class PoolGroup PoolObjectList EqualChanced; }; -class PoolHandler +class PoolMgr { - public: - PoolHandler(); - ~PoolHandler() {}; + friend class ACE_Singleton<PoolMgr, ACE_Null_Mutex>; + PoolMgr(); + ~PoolMgr() {}; + public: void LoadFromDB(); void Initialize(); @@ -134,11 +135,11 @@ class PoolHandler SpawnedPoolData mSpawnedData; }; -#define poolhandler Trinity::Singleton<PoolHandler>::Instance() +#define poolhandler (*ACE_Singleton<PoolMgr, ACE_Null_Mutex>::instance()) // Method that tell if the creature is part of a pool and return the pool id if yes template<> -inline uint16 PoolHandler::IsPartOfAPool<Creature>(uint32 db_guid) const +inline uint16 PoolMgr::IsPartOfAPool<Creature>(uint32 db_guid) const { SearchMap::const_iterator itr = mCreatureSearchMap.find(db_guid); if (itr != mCreatureSearchMap.end()) @@ -149,7 +150,7 @@ inline uint16 PoolHandler::IsPartOfAPool<Creature>(uint32 db_guid) const // Method that tell if the gameobject is part of a pool and return the pool id if yes template<> -inline uint16 PoolHandler::IsPartOfAPool<GameObject>(uint32 db_guid) const +inline uint16 PoolMgr::IsPartOfAPool<GameObject>(uint32 db_guid) const { SearchMap::const_iterator itr = mGameobjectSearchMap.find(db_guid); if (itr != mGameobjectSearchMap.end()) @@ -160,7 +161,7 @@ inline uint16 PoolHandler::IsPartOfAPool<GameObject>(uint32 db_guid) const // Method that tell if the pool is part of another pool and return the pool id if yes template<> -inline uint16 PoolHandler::IsPartOfAPool<Pool>(uint32 pool_id) const +inline uint16 PoolMgr::IsPartOfAPool<Pool>(uint32 pool_id) const { SearchMap::const_iterator itr = mPoolSearchMap.find(pool_id); if (itr != mPoolSearchMap.end()) diff --git a/src/server/game/PrecompiledHeaders/NixCorePCH.cpp b/src/server/game/PrecompiledHeaders/NixCorePCH.cpp deleted file mode 100644 index e588392689e..00000000000 --- a/src/server/game/PrecompiledHeaders/NixCorePCH.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pchdef.h"
\ No newline at end of file diff --git a/src/server/game/PrecompiledHeaders/ScriptPCH.cpp b/src/server/game/PrecompiledHeaders/ScriptPCH.cpp index a80690d05da..41fecf3c60d 100644 --- a/src/server/game/PrecompiledHeaders/ScriptPCH.cpp +++ b/src/server/game/PrecompiledHeaders/ScriptPCH.cpp @@ -2,5 +2,5 @@ * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" diff --git a/src/server/game/PrecompiledHeaders/ScriptPCH.h b/src/server/game/PrecompiledHeaders/ScriptPCH.h index 1e83a88b87a..f8515e99f89 100644 --- a/src/server/game/PrecompiledHeaders/ScriptPCH.h +++ b/src/server/game/PrecompiledHeaders/ScriptPCH.h @@ -23,7 +23,7 @@ #include "DBCStores.h" #include "ObjectMgr.h" -#ifdef WIN32 +#ifdef _WIN32 #include <windows.h> #endif diff --git a/src/server/game/PrecompiledHeaders/WinCorePCH.cpp b/src/server/game/PrecompiledHeaders/WinCorePCH.cpp deleted file mode 100644 index e588392689e..00000000000 --- a/src/server/game/PrecompiledHeaders/WinCorePCH.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pchdef.h"
\ No newline at end of file diff --git a/src/server/game/PrecompiledHeaders/WinCorePCH.h b/src/server/game/PrecompiledHeaders/WinCorePCH.h deleted file mode 100644 index cd1ea4a418a..00000000000 --- a/src/server/game/PrecompiledHeaders/WinCorePCH.h +++ /dev/null @@ -1,14 +0,0 @@ -//add here most rarely modified headers to speed up debug build compilation -#include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it -#include "Common.h" - -#include "MapManager.h" -#include "Log.h" -#include "ObjectAccessor.h" -#include "ObjectDefines.h" -#include "Database/SQLStorage.h" -#include "Opcodes.h" -#include "SharedDefines.h" -#include "ObjectMgr.h" - -#include "ScriptedPch.h"
\ No newline at end of file diff --git a/src/server/game/PrecompiledHeaders/gamePCH.cpp b/src/server/game/PrecompiledHeaders/gamePCH.cpp new file mode 100644 index 00000000000..11e501ec7f2 --- /dev/null +++ b/src/server/game/PrecompiledHeaders/gamePCH.cpp @@ -0,0 +1 @@ +#include "gamePCH.h" diff --git a/src/server/game/PrecompiledHeaders/NixCorePCH.h b/src/server/game/PrecompiledHeaders/gamePCH.h index 7252e980e7d..dd56e3fc16c 100644 --- a/src/server/game/PrecompiledHeaders/NixCorePCH.h +++ b/src/server/game/PrecompiledHeaders/gamePCH.h @@ -3,10 +3,10 @@ #include "Common.h" #include "MapManager.h" -#include "Log.h" +#include "Logging/Log.h" #include "ObjectAccessor.h" #include "ObjectDefines.h" -#include "Database/SQLStorage.h" +#include "SQLStorage.h" #include "Opcodes.h" #include "SharedDefines.h" #include "ObjectMgr.h" diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index 2fdd1c58e9b..43ad7ffc114 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -175,7 +175,7 @@ uint32 Quest::XPValue(Player *pPlayer) const if (!xpentry) return 0; - int diffFactor = 2 * (quest_level - pPlayer->getLevel()) + 20; + int32 diffFactor = 2 * (quest_level - pPlayer->getLevel()) + 20; if (diffFactor < 1) diffFactor = 1; else if (diffFactor > 10) @@ -204,3 +204,11 @@ int32 Quest::GetRewOrReqMoney() const return int32(RewOrReqMoney * sWorld.getRate(RATE_DROP_MONEY)); } + +bool Quest::IsAllowedInRaid() const +{ + if (IsRaidQuest()) + return true; + + return sWorld.getConfig(CONFIG_QUEST_IGNORE_RAID); +} diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 20d4ca3d28d..64c9b47627d 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -21,8 +21,9 @@ #ifndef TRINITYCORE_QUEST_H #define TRINITYCORE_QUEST_H -#include "Platform/Define.h" -#include "Database/DatabaseEnv.h" +#include "Define.h" +#include "DatabaseEnv.h" +#include "SharedDefines.h" #include <string> #include <vector> @@ -244,6 +245,8 @@ class Quest bool IsWeekly() const { return QuestFlags & QUEST_FLAGS_WEEKLY; } bool IsDailyOrWeekly() const { return QuestFlags & (QUEST_FLAGS_DAILY | QUEST_FLAGS_WEEKLY); } bool IsAutoAccept() const { return QuestFlags & QUEST_FLAGS_AUTO_ACCEPT; } + bool IsRaidQuest() const { return Type == QUEST_TYPE_RAID || Type == QUEST_TYPE_RAID_10 || Type == QUEST_TYPE_RAID_25; } + bool IsAllowedInRaid() const; // multiple values std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 2006c091287..cf378db2bac 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -14,11 +14,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ScriptedPch.h" - -#ifdef WIN32 - #define DO_SCRIPTS -#endif +#include "ScriptPCH.h" #ifdef DO_SCRIPTS //custom diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index 2dcfd258942..70b1ff6be64 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -2,17 +2,14 @@ * This program is free software licensed under GPL version 2 * Please see the included DOCS/LICENSE.TXT for more information */ -#include "ScriptedPch.h" -#include "Config/Config.h" -#include "Database/DatabaseEnv.h" +#include "ScriptPCH.h" +#include "Config.h" +#include "DatabaseEnv.h" #include "DBCStores.h" #include "ObjectMgr.h" #include "ProgressBar.h" #include "ScriptLoader.h" #include "ScriptSystem.h" -#include "Policies/SingletonImp.h" - -INSTANTIATE_SINGLETON_1(ScriptMgr); int num_sc_scripts; Script *m_scripts[MAX_SCRIPTS]; @@ -45,22 +42,22 @@ ScriptMgr::~ScriptMgr() void ScriptMgr::ScriptsInit() { //Trinity Script startup - outstring_log(" _____ _ _ _ ____ _ _"); - outstring_log("|_ _| __(_)_ __ (_) |_ _ _/ ___| ___ _ __(_)_ __ | |_ "); - outstring_log(" | || '__| | '_ \\| | __| | | \\___ \\ / __| \'__| | \'_ \\| __|"); - outstring_log(" | || | | | | | | | |_| |_| |___) | (__| | | | |_) | |_ "); - outstring_log(" |_||_| |_|_| |_|_|\\__|\\__, |____/ \\___|_| |_| .__/ \\__|"); - outstring_log(" |___/ |_| "); - outstring_log(""); - outstring_log(""); + /*sLog.outString(" _____ _ _ _ ____ _ _"); + sLog.outString("|_ _| __(_)_ __ (_) |_ _ _/ ___| ___ _ __(_)_ __ | |_ "); + sLog.outString(" | || '__| | '_ \\| | __| | | \\___ \\ / __| \'__| | \'_ \\| __|"); + sLog.outString(" | || | | | | | | | |_| |_| |___) | (__| | | | |_) | |_ "); + sLog.outString(" |_||_| |_|_| |_|_|\\__|\\__, |____/ \\___|_| |_| .__/ \\__|"); + sLog.outString(" |___/ |_| "); + sLog.outString(""); + sLog.outString("");*/ //Load database (must be called after SD2Config.SetSource). LoadDatabase(); - outstring_log("TSCR: Loading C++ scripts"); + sLog.outString("Loading C++ scripts"); barGoLink bar(1); bar.step(); - outstring_log(""); + sLog.outString(""); for (uint16 i =0; i<MAX_SCRIPTS; ++i) m_scripts[i]=NULL; @@ -69,9 +66,9 @@ void ScriptMgr::ScriptsInit() AddScripts(); - outstring_log(">> Loaded %i C++ Scripts.", num_sc_scripts); + sLog.outString(">> Loaded %i C++ Scripts.", num_sc_scripts); - outstring_log(">> Load Overriden SQL Data."); + sLog.outString(">> Load Overriden SQL Data."); LoadOverridenSQLData(); } @@ -82,13 +79,13 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) { if (!pSource) { - error_log("TSCR: DoScriptText entry %i, invalid Source pointer.", iTextEntry); + sLog.outError("TSCR: DoScriptText entry %i, invalid Source pointer.", iTextEntry); return; } if (iTextEntry >= 0) { - error_log("TSCR: DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.", pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), iTextEntry); + sLog.outError("TSCR: DoScriptText with source entry %u (TypeId=%u, guid=%u) attempts to process text entry %i, but text entry must be negative.", pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), iTextEntry); return; } @@ -96,11 +93,11 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) if (!pData) { - error_log("TSCR: DoScriptText with source entry %u (TypeId=%u, guid=%u) could not find text entry %i.", pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), iTextEntry); + sLog.outError("TSCR: DoScriptText with source entry %u (TypeId=%u, guid=%u) could not find text entry %i.", pSource->GetEntry(), pSource->GetTypeId(), pSource->GetGUIDLow(), iTextEntry); return; } - debug_log("TSCR: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u", iTextEntry, pData->uiSoundId, pData->uiType, pData->uiLanguage, pData->uiEmote); + sLog.outDebug("TSCR: DoScriptText: text entry=%i, Sound=%u, Type=%u, Language=%u, Emote=%u", iTextEntry, pData->uiSoundId, pData->uiType, pData->uiLanguage, pData->uiEmote); if (pData->uiSoundId) { @@ -109,7 +106,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) pSource->SendPlaySound(pData->uiSoundId, false); } else - error_log("TSCR: DoScriptText entry %i tried to process invalid sound id %u.", iTextEntry, pData->uiSoundId); + sLog.outError("TSCR: DoScriptText entry %i tried to process invalid sound id %u.", iTextEntry, pData->uiSoundId); } if (pData->uiEmote) @@ -117,7 +114,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) if (pSource->GetTypeId() == TYPEID_UNIT || pSource->GetTypeId() == TYPEID_PLAYER) ((Unit*)pSource)->HandleEmoteCommand(pData->uiEmote); else - error_log("TSCR: DoScriptText entry %i tried to process emote for invalid TypeId (%u).", iTextEntry, pSource->GetTypeId()); + sLog.outError("TSCR: DoScriptText entry %i tried to process emote for invalid TypeId (%u).", iTextEntry, pSource->GetTypeId()); } switch(pData->uiType) @@ -139,7 +136,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID()); else - error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry); + sLog.outError("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry); } break; case CHAT_TYPE_BOSS_WHISPER: @@ -147,7 +144,7 @@ void DoScriptText(int32 iTextEntry, WorldObject* pSource, Unit* pTarget) if (pTarget && pTarget->GetTypeId() == TYPEID_PLAYER) pSource->MonsterWhisper(iTextEntry, pTarget->GetGUID(), true); else - error_log("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry); + sLog.outError("TSCR: DoScriptText entry %i cannot whisper without target unit (TYPEID_PLAYER).", iTextEntry); } break; case CHAT_TYPE_ZONE_YELL: @@ -165,7 +162,7 @@ void Script::RegisterSelf() // somebody forgot to allocate memory for a script by a method like this: newscript = new Script if (m_scripts[i] == this) { - error_log("ScriptName: '%s' - Forgot to allocate memory, so this script and/or the script before that can't work.", Name.c_str()); + sLog.outError("ScriptName: '%s' - Forgot to allocate memory, so this script and/or the script before that can't work.", Name.c_str()); // don't register it // and don't delete it because its memory is used for another script return; @@ -200,14 +197,14 @@ void Script::RegisterSelf() else { // TODO: write a better error message than this one :) - error_log("ScriptName: '%s' already assigned with the same ScriptName, so the script can't work.", Name.c_str()); + sLog.outError("ScriptName: '%s' already assigned with the same ScriptName, so the script can't work.", Name.c_str()); delete this; } } else { if (Name.find("example") == std::string::npos) - error_db_log("TrinityScript: RegisterSelf, but script named %s does not have ScriptName assigned in database.",(this)->Name.c_str()); + sLog.outErrorDb("TrinityScript: RegisterSelf, but script named %s does not have ScriptName assigned in database.",(this)->Name.c_str()); delete this; } } @@ -326,7 +323,7 @@ bool ScriptMgr::GossipHello (Player * pPlayer, Creature* pCreature) bool ScriptMgr::GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction) { - debug_log("TSCR: Gossip selection, sender: %d, action: %d", uiSender, uiAction); + sLog.outDebug("TSCR: Gossip selection, sender: %d, action: %d", uiSender, uiAction); Script *tmpscript = m_scripts[pCreature->GetScriptId()]; if (!tmpscript || !tmpscript->pGossipSelect) return false; @@ -337,7 +334,7 @@ bool ScriptMgr::GossipSelect(Player* pPlayer, Creature* pCreature, uint32 uiSend bool ScriptMgr::GossipSelectWithCode(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction, const char* sCode) { - debug_log("TSCR: Gossip selection with code, sender: %d, action: %d", uiSender, uiAction); + sLog.outDebug("TSCR: Gossip selection with code, sender: %d, action: %d", uiSender, uiAction); Script *tmpscript = m_scripts[pCreature->GetScriptId()]; if (!tmpscript || !tmpscript->pGossipSelectWithCode) return false; @@ -350,7 +347,7 @@ bool ScriptMgr::GOSelect(Player* pPlayer, GameObject* pGO, uint32 uiSender, uint { if (!pGO) return false; - debug_log("TSCR: Gossip selection, sender: %d, action: %d", uiSender, uiAction); + sLog.outDebug("TSCR: Gossip selection, sender: %d, action: %d", uiSender, uiAction); Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId]; if (!tmpscript || !tmpscript->pGOSelect) return false; @@ -363,7 +360,7 @@ bool ScriptMgr::GOSelectWithCode(Player* pPlayer, GameObject* pGO, uint32 uiSend { if (!pGO) return false; - debug_log("TSCR: Gossip selection, sender: %d, action: %d",uiSender, uiAction); + sLog.outDebug("TSCR: Gossip selection, sender: %d, action: %d",uiSender, uiAction); Script *tmpscript = m_scripts[pGO->GetGOInfo()->ScriptId]; if (!tmpscript || !tmpscript->pGOSelectWithCode) return false; diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index ed7200d5786..bcb26381809 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -9,9 +9,9 @@ #define SC_SCRIPTMGR_H #include "Common.h" -#include "Platform/CompilerDefs.h" +#include "CompilerDefs.h" #include "DBCStructure.h" -#include "Config/ConfigEnv.h" +#include "ConfigEnv.h" class Player; class Creature; @@ -94,8 +94,9 @@ struct Script class ScriptMgr { + friend class ACE_Singleton<ScriptMgr, ACE_Null_Mutex>; + ScriptMgr(); public: - ScriptMgr(); ~ScriptMgr(); void ScriptsInit(); @@ -158,6 +159,6 @@ void DoScriptText(int32 textEntry, WorldObject* pSource, Unit *pTarget = NULL); #define FUNC_PTR(name, callconvention, returntype, parameters) typedef returntype(callconvention *name)parameters; #endif -#define sScriptMgr Trinity::Singleton<ScriptMgr>::Instance() +#define sScriptMgr (*ACE_Singleton<ScriptMgr, ACE_Null_Mutex>::instance()) #endif diff --git a/src/server/game/Scripting/ScriptSystem.cpp b/src/server/game/Scripting/ScriptSystem.cpp index 0037b100412..54a14228bc1 100644 --- a/src/server/game/Scripting/ScriptSystem.cpp +++ b/src/server/game/Scripting/ScriptSystem.cpp @@ -18,11 +18,11 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "ScriptedPch.h" +#include "ScriptPCH.h" #include "ScriptSystem.h" #include "ProgressBar.h" #include "ObjectMgr.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" SystemMgr::SystemMgr() { @@ -43,24 +43,24 @@ void SystemMgr::LoadVersion() { Field* pFields = Result->Fetch(); - outstring_log("TSCR: Database version is: %s", pFields[0].GetString()); - outstring_log(""); + sLog.outString("TSCR: Database version is: %s", pFields[0].GetString()); + sLog.outString(""); } else { - error_log("TSCR: Missing `version`.`script_version` information."); - outstring_log(""); + sLog.outError("TSCR: Missing `version`.`script_version` information."); + sLog.outString(""); } } void SystemMgr::LoadScriptTexts() { - outstring_log("TSCR: Loading Script Texts..."); + sLog.outString("TSCR: Loading Script Texts..."); LoadTrinityStrings(WorldDatabase,"script_texts",TEXT_SOURCE_RANGE,1+(TEXT_SOURCE_RANGE*2)); QueryResult_AutoPtr Result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM script_texts"); - outstring_log("TSCR: Loading Script Texts additional data..."); + sLog.outString("TSCR: Loading Script Texts additional data..."); if (Result) { @@ -81,52 +81,52 @@ void SystemMgr::LoadScriptTexts() if (iId >= 0) { - error_db_log("TSCR: Entry %i in table `script_texts` is not a negative value.", iId); + sLog.outErrorDb("TSCR: Entry %i in table `script_texts` is not a negative value.", iId); continue; } if (iId > TEXT_SOURCE_RANGE || iId <= TEXT_SOURCE_RANGE*2) { - error_db_log("TSCR: Entry %i in table `script_texts` is out of accepted entry range for table.", iId); + sLog.outErrorDb("TSCR: Entry %i in table `script_texts` is out of accepted entry range for table.", iId); continue; } if (pTemp.uiSoundId) { if (!GetSoundEntriesStore()->LookupEntry(pTemp.uiSoundId)) - error_db_log("TSCR: Entry %i in table `script_texts` has soundId %u but sound does not exist.", iId, pTemp.uiSoundId); + sLog.outErrorDb("TSCR: Entry %i in table `script_texts` has soundId %u but sound does not exist.", iId, pTemp.uiSoundId); } if (!GetLanguageDescByID(pTemp.uiLanguage)) - error_db_log("TSCR: Entry %i in table `script_texts` using Language %u but Language does not exist.", iId, pTemp.uiLanguage); + sLog.outErrorDb("TSCR: Entry %i in table `script_texts` using Language %u but Language does not exist.", iId, pTemp.uiLanguage); if (pTemp.uiType > CHAT_TYPE_ZONE_YELL) - error_db_log("TSCR: Entry %i in table `script_texts` has Type %u but this Chat Type does not exist.", iId, pTemp.uiType); + sLog.outErrorDb("TSCR: Entry %i in table `script_texts` has Type %u but this Chat Type does not exist.", iId, pTemp.uiType); m_mTextDataMap[iId] = pTemp; ++uiCount; } while (Result->NextRow()); - outstring_log(""); - outstring_log(">> Loaded %u additional Script Texts data.", uiCount); + sLog.outString(""); + sLog.outString(">> Loaded %u additional Script Texts data.", uiCount); } else { barGoLink bar(1); bar.step(); - outstring_log(""); - outstring_log(">> Loaded 0 additional Script Texts data. DB table `script_texts` is empty."); + sLog.outString(""); + sLog.outString(">> Loaded 0 additional Script Texts data. DB table `script_texts` is empty."); } } void SystemMgr::LoadScriptTextsCustom() { - outstring_log("TSCR: Loading Custom Texts..."); + sLog.outString("TSCR: Loading Custom Texts..."); LoadTrinityStrings(WorldDatabase,"custom_texts",TEXT_SOURCE_RANGE*2,1+(TEXT_SOURCE_RANGE*3)); QueryResult_AutoPtr Result = WorldDatabase.Query("SELECT entry, sound, type, language, emote FROM custom_texts"); - outstring_log("TSCR: Loading Custom Texts additional data..."); + sLog.outString("TSCR: Loading Custom Texts additional data..."); if (Result) { @@ -147,41 +147,41 @@ void SystemMgr::LoadScriptTextsCustom() if (iId >= 0) { - error_db_log("TSCR: Entry %i in table `custom_texts` is not a negative value.", iId); + sLog.outErrorDb("TSCR: Entry %i in table `custom_texts` is not a negative value.", iId); continue; } if (iId > TEXT_SOURCE_RANGE*2 || iId <= TEXT_SOURCE_RANGE*3) { - error_db_log("TSCR: Entry %i in table `custom_texts` is out of accepted entry range for table.", iId); + sLog.outErrorDb("TSCR: Entry %i in table `custom_texts` is out of accepted entry range for table.", iId); continue; } if (pTemp.uiSoundId) { if (!GetSoundEntriesStore()->LookupEntry(pTemp.uiSoundId)) - error_db_log("TSCR: Entry %i in table `custom_texts` has soundId %u but sound does not exist.", iId, pTemp.uiSoundId); + sLog.outErrorDb("TSCR: Entry %i in table `custom_texts` has soundId %u but sound does not exist.", iId, pTemp.uiSoundId); } if (!GetLanguageDescByID(pTemp.uiLanguage)) - error_db_log("TSCR: Entry %i in table `custom_texts` using Language %u but Language does not exist.", iId, pTemp.uiLanguage); + sLog.outErrorDb("TSCR: Entry %i in table `custom_texts` using Language %u but Language does not exist.", iId, pTemp.uiLanguage); if (pTemp.uiType > CHAT_TYPE_ZONE_YELL) - error_db_log("TSCR: Entry %i in table `custom_texts` has Type %u but this Chat Type does not exist.", iId, pTemp.uiType); + sLog.outErrorDb("TSCR: Entry %i in table `custom_texts` has Type %u but this Chat Type does not exist.", iId, pTemp.uiType); m_mTextDataMap[iId] = pTemp; ++uiCount; } while (Result->NextRow()); - outstring_log(""); - outstring_log(">> Loaded %u additional Custom Texts data.", uiCount); + sLog.outString(""); + sLog.outString(">> Loaded %u additional Custom Texts data.", uiCount); } else { barGoLink bar(1); bar.step(); - outstring_log(""); - outstring_log(">> Loaded 0 additional Custom Texts data. DB table `custom_texts` is empty."); + sLog.outString(""); + sLog.outString(">> Loaded 0 additional Custom Texts data. DB table `custom_texts` is empty."); } } @@ -197,7 +197,7 @@ void SystemMgr::LoadScriptWaypoints() if (Result) uiCreatureCount = Result->GetRowCount(); - outstring_log("TSCR: Loading Script Waypoints for %u creature(s)...", uiCreatureCount); + sLog.outString("TSCR: Loading Script Waypoints for %u creature(s)...", uiCreatureCount); Result = WorldDatabase.Query("SELECT entry, pointid, location_x, location_y, location_z, waittime FROM script_waypoint ORDER BY pointid"); @@ -224,25 +224,25 @@ void SystemMgr::LoadScriptWaypoints() if (!pCInfo) { - error_db_log("TSCR: DB table script_waypoint has waypoint for non-existant creature entry %u", pTemp.uiCreatureEntry); + sLog.outErrorDb("TSCR: DB table script_waypoint has waypoint for non-existant creature entry %u", pTemp.uiCreatureEntry); continue; } if (!pCInfo->ScriptID) - error_db_log("TSCR: DB table script_waypoint has waypoint for creature entry %u, but creature does not have ScriptName defined and then useless.", pTemp.uiCreatureEntry); + sLog.outErrorDb("TSCR: DB table script_waypoint has waypoint for creature entry %u, but creature does not have ScriptName defined and then useless.", pTemp.uiCreatureEntry); m_mPointMoveMap[uiEntry].push_back(pTemp); ++uiNodeCount; } while (Result->NextRow()); - outstring_log(""); - outstring_log(">> Loaded %u Script Waypoint nodes.", uiNodeCount); + sLog.outString(""); + sLog.outString(">> Loaded %u Script Waypoint nodes.", uiNodeCount); } else { barGoLink bar(1); bar.step(); - outstring_log(""); - outstring_log(">> Loaded 0 Script Waypoints. DB table `script_waypoint` is empty."); + sLog.outString(""); + sLog.outString(">> Loaded 0 Script Waypoints. DB table `script_waypoint` is empty."); } } diff --git a/src/server/game/Server/Protocol/Handlers/AddonHandler.cpp b/src/server/game/Server/Protocol/Handlers/AddonHandler.cpp index a9c8101d7b1..13fbd266ea4 100644 --- a/src/server/game/Server/Protocol/Handlers/AddonHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/AddonHandler.cpp @@ -18,17 +18,12 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "zlib/zlib.h" - +#include "zlib.h" #include "AddonHandler.h" -#include "Database/DatabaseEnv.h" -#include "Policies/SingletonImp.h" +#include "DatabaseEnv.h" #include "Opcodes.h" - #include "Log.h" -INSTANTIATE_SINGLETON_1( AddonHandler ); - AddonHandler::AddonHandler() { } diff --git a/src/server/game/Server/Protocol/Handlers/AddonHandler.h b/src/server/game/Server/Protocol/Handlers/AddonHandler.h index 999785339bc..68620751da3 100644 --- a/src/server/game/Server/Protocol/Handlers/AddonHandler.h +++ b/src/server/game/Server/Protocol/Handlers/AddonHandler.h @@ -22,20 +22,21 @@ #define __ADDONHANDLER_H #include "Common.h" -#include "Config/ConfigEnv.h" -#include "Policies/Singleton.h" - +#include "ConfigEnv.h" +#include "ace/Singleton.h" #include "WorldPacket.h" class AddonHandler { + /* Construction */ + friend class ACE_Singleton<AddonHandler, ACE_Null_Mutex>; + AddonHandler(); + public: - /* Construction */ - AddonHandler(); ~AddonHandler(); - //built addon packet + //build addon packet bool BuildAddonPacket(WorldPacket* Source, WorldPacket* Target); }; -#define sAddOnHandler Trinity::Singleton<AddonHandler>::Instance() +#define sAddOnHandler ACE_Singleton<AddonHandler, ACE_Null_Mutex>::instance() #endif diff --git a/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp b/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp index 3a9a14524f9..3c26e17bddd 100644 --- a/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ArenaTeamHandler.cpp @@ -22,7 +22,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "ArenaTeam.h" #include "Log.h" @@ -91,7 +91,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket & recv_data) if (!normalizePlayerName(Invitedname)) return; - player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); + player = sObjectAccessor.FindPlayerByName(Invitedname.c_str()); } if (!player) diff --git a/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp b/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp index 0f615579cb6..442fe55b194 100644 --- a/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ChannelHandler.cpp @@ -18,8 +18,6 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Policies/SingletonImp.h" - #include "ObjectMgr.h" // for normalizePlayerName #include "ChannelMgr.h" diff --git a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp index 416827d73ea..ca08d197c3f 100644 --- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp @@ -25,9 +25,9 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Auth/md5.h" -#include "Database/DatabaseEnv.h" -#include "Database/DatabaseImpl.h" +#include "MD5.h" +#include "DatabaseEnv.h" +#include "DatabaseImpl.h" #include "ArenaTeam.h" #include "Chat.h" @@ -719,7 +719,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder * holder) pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } - ObjectAccessor::Instance().AddObject(pCurrChar); + sObjectAccessor.AddObject(pCurrChar); //sLog.outDebug("Player %s added to Map.",pCurrChar->GetName()); pCurrChar->SendInitialPacketsAfterAddToMap(); diff --git a/src/server/game/Server/Protocol/Handlers/ChatHandler.cpp b/src/server/game/Server/Protocol/Handlers/ChatHandler.cpp index 88e2b5473a5..85f37b52478 100644 --- a/src/server/game/Server/Protocol/Handlers/ChatHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ChatHandler.cpp @@ -24,7 +24,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "CellImpl.h" #include "Chat.h" diff --git a/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp b/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp index f973bc24722..4f43ad3c30b 100644 --- a/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/GroupHandler.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Opcodes.h" #include "Log.h" #include "WorldPacket.h" @@ -126,7 +126,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket & recv_data) if (group) { // not have permissions for invite - if (group->isRaidGroup() && !group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) + if (!group->IsLeader(GetPlayer()->GetGUID()) && !group->IsAssistant(GetPlayer()->GetGUID())) { SendPartyResult(PARTY_OP_INVITE, "", ERR_NOT_LEADER); return; @@ -534,8 +534,10 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data) std::string name; uint8 groupNr; recv_data >> name; - recv_data >> groupNr; + + if (groupNr >= MAX_RAID_SUBGROUPS) + return; /** error handling **/ uint64 senderGuid = GetPlayer()->GetGUID(); @@ -546,16 +548,18 @@ void WorldSession::HandleGroupChangeSubGroupOpcode(WorldPacket & recv_data) return; /********************/ - Player *movedPlayer=objmgr.GetPlayer(name.c_str()); - if (!movedPlayer) - return; - - //Do not allow leader to change group of player in combat - if (movedPlayer->isInCombat()) - return; + Player *movedPlayer = objmgr.GetPlayer(name.c_str()); + if (movedPlayer) + { + //Do not allow leader to change group of player in combat + if (movedPlayer->isInCombat()) + return; - // everything's fine, do it - group->ChangeMembersGroup(movedPlayer, groupNr); + // everything's fine, do it + group->ChangeMembersGroup(movedPlayer, groupNr); + } + else + group->ChangeMembersGroup(objmgr.GetPlayerGUIDByName(name.c_str()), groupNr); } void WorldSession::HandleGroupAssistantLeaderOpcode(WorldPacket & recv_data) @@ -593,7 +597,7 @@ void WorldSession::HandlePartyAssignmentOpcode(WorldPacket & recv_data) /** error handling **/ uint64 senderGuid = GetPlayer()->GetGUID(); - if (!group->IsLeader(senderGuid) && group->IsAssistant(senderGuid)) + if (!group->IsLeader(senderGuid) && !group->IsAssistant(senderGuid)) return; /********************/ diff --git a/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp b/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp index 6803fe63a86..4db1961e7af 100644 --- a/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/GuildHandler.cpp @@ -75,7 +75,7 @@ void WorldSession::HandleGuildInviteOpcode(WorldPacket& recvPacket) recvPacket >> Invitedname; if (normalizePlayerName(Invitedname)) - player = ObjectAccessor::Instance().FindPlayerByName(Invitedname.c_str()); + player = sObjectAccessor.FindPlayerByName(Invitedname.c_str()); if (!player) { diff --git a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp index 53aede43492..39c3b61a445 100644 --- a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp @@ -263,6 +263,12 @@ void WorldSession::HandleDestroyItemOpcode(WorldPacket & recv_data) return; } + if (pItem->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_INDESTRUCTIBLE)) + { + _player->SendEquipError(EQUIP_ERR_CANT_DROP_SOULBOUND, NULL, NULL); + return; + } + if (count) { uint32 i_count = count; @@ -766,7 +772,7 @@ void WorldSession::SendListInventory(uint64 vendorguid) ++count; // reputation discount - int32 price = uint32(floor(pProto->BuyPrice * discountMod)); + int32 price = crItem->IsGoldRequired(pProto) ? uint32(floor(pProto->BuyPrice * discountMod)) : 0; data << uint32(vendorslot+1); // client expects counting to start at 1 data << uint32(crItem->item); @@ -1003,40 +1009,25 @@ void WorldSession::HandleItemNameQueryOpcode(WorldPacket & recv_data) recv_data.read_skip<uint64>(); // guid sLog.outDebug("WORLD: CMSG_ITEM_NAME_QUERY %u", itemid); - ItemPrototype const *pProto = objmgr.GetItemPrototype(itemid); - if (pProto) + ItemSetNameEntry const *pName = objmgr.GetItemSetNameEntry(itemid); + if (pName) { - std::string Name; - Name = pProto->Name1; - + std::string Name = pName->name; int loc_idx = GetSessionDbLocaleIndex(); if (loc_idx >= 0) { - ItemLocale const *il = objmgr.GetItemLocale(pProto->ItemId); - if (il) - { - if (il->Name.size() > size_t(loc_idx) && !il->Name[loc_idx].empty()) - Name = il->Name[loc_idx]; - } + ItemSetNameLocale const *isnl = objmgr.GetItemSetNameLocale(itemid); + if (isnl) + if (isnl->Name.size() > size_t(loc_idx) && !isnl->Name[loc_idx].empty()) + Name = isnl->Name[loc_idx]; } - // guess size - WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+10)); - data << uint32(pProto->ItemId); + + WorldPacket data(SMSG_ITEM_NAME_QUERY_RESPONSE, (4+Name.size()+1+4)); + data << uint32(itemid); data << Name; - data << uint32(pProto->InventoryType); + data << uint32(pName->InventoryType); SendPacket(&data); - return; } -// This is a BS check, there are lots of items listed in Item.dbc that do not even exist on official -- so we can NEVER get the data for them. -// If you *really* want to spam your error log -- uncomment this. -/* else - { - // listed in dbc or not expected to exist unknown item - if (sItemStore.LookupEntry(itemid)) - sLog.outErrorDb("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (item listed in Item.dbc but not exist in DB)", itemid); - else - sLog.outError("WORLD: CMSG_ITEM_NAME_QUERY for item %u failed (unknown item, not listed in Item.dbc)", itemid); - } */ } void WorldSession::HandleWrapItemOpcode(WorldPacket& recv_data) diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp index ea6f892c126..4225a99c72b 100644 --- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp @@ -20,8 +20,8 @@ #include "Common.h" #include "Language.h" -#include "Database/DatabaseEnv.h" -#include "Database/DatabaseImpl.h" +#include "DatabaseEnv.h" +#include "DatabaseImpl.h" #include "WorldPacket.h" #include "Opcodes.h" #include "Log.h" @@ -30,12 +30,12 @@ #include "World.h" #include "ObjectMgr.h" #include "WorldSession.h" -#include "Auth/BigNumber.h" -#include "Auth/Sha1.h" +#include "BigNumber.h" +#include "SHA1.h" #include "UpdateData.h" #include "LootMgr.h" #include "Chat.h" -#include <zlib/zlib.h> +#include "zlib.h" #include "ObjectAccessor.h" #include "Object.h" #include "BattleGround.h" @@ -232,8 +232,8 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) data << uint32(clientcount); // clientcount place holder, listed count data << uint32(clientcount); // clientcount place holder, online count - ObjectAccessor::Guard guard(*HashMapHolder<Player>::GetLock()); - HashMapHolder<Player>::MapType& m = ObjectAccessor::Instance().GetPlayers(); + ACE_GUARD(ACE_Thread_Mutex, g, *HashMapHolder<Player>::GetLock()); + HashMapHolder<Player>::MapType& m = sObjectAccessor.GetPlayers(); for (HashMapHolder<Player>::MapType::const_iterator itr = m.begin(); itr != m.end(); ++itr) { if (security == SEC_PLAYER) @@ -374,7 +374,7 @@ void WorldSession::HandleLogoutRequestOpcode(WorldPacket & /*recv_data*/) return; } - //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in TrinityCore.conf + //instant logout in taverns/cities or on taxi or for admins, gm's, mod's if its enabled in worldserver.conf if (GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING) || GetPlayer()->isInFlight() || GetSecurity() >= sWorld.getConfig(CONFIG_INSTANT_LOGOUT)) { @@ -931,11 +931,13 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data) if (!at) return; - if (!GetPlayer()->Satisfy(objmgr.GetAccessRequirement(at->access_id), at->target_mapId, true)) - return; + // MapManager::CanPlayerEnter() calls players->Satisfy() so this is not needed here + // if (!GetPlayer()->Satisfy(objmgr.GetAccessRequirement(at->access_id), at->target_mapId, true)) + // return; + // Check only if target map != current player's map // check if player can enter instance : instance not full, and raid instance not in encounter fight - if (!MapManager::Instance().CanPlayerEnter(at->target_mapId, GetPlayer(), false)) + if (GetPlayer()->GetMapId() != at->target_mapId && !sMapMgr.CanPlayerEnter(at->target_mapId, GetPlayer(), false)) return; GetPlayer()->TeleportTo(at->target_mapId,at->target_X,at->target_Y,at->target_Z,at->target_Orientation,TELE_TO_NOT_LEAVE_TRANSPORT); diff --git a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp index 1148fe174fc..a31361e9275 100644 --- a/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MovementHandler.cpp @@ -28,7 +28,7 @@ #include "Vehicle.h" #include "SpellAuras.h" #include "MapManager.h" -#include "Transports.h" +#include "Transport.h" #include "BattleGround.h" #include "WaypointMovementGenerator.h" #include "InstanceSaveMgr.h" @@ -75,7 +75,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() } // relocate the player to the teleport destination - Map * newMap = MapManager::Instance().CreateMap(loc.GetMapId(), GetPlayer(), 0); + Map * newMap = sMapMgr.CreateMap(loc.GetMapId(), GetPlayer(), 0); // the CanEnter checks are done in TeleporTo but conditions may change // while the player is in transit, for example the map may get full if (!newMap || !newMap->CanEnter(GetPlayer())) @@ -198,7 +198,7 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data) uint32 flags, time; recv_data >> flags >> time; DEBUG_LOG("Guid " UI64FMTD, guid); - DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILISECONDS); + DEBUG_LOG("Flags %u, time %u", flags, time/IN_MILLISECONDS); Unit *mover = _player->m_mover; Player *plMover = mover->GetTypeId() == TYPEID_PLAYER ? (Player*)mover : NULL; @@ -302,7 +302,7 @@ void WorldSession::HandleMovementOpcodes(WorldPacket & recv_data) if (plMover && !plMover->GetTransport()) { // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list - for (MapManager::TransportSet::const_iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter) + for (MapManager::TransportSet::const_iterator iter = sMapMgr.m_Transports.begin(); iter != sMapMgr.m_Transports.end(); ++iter) { if ((*iter)->GetGUID() == movementInfo.t_guid) { diff --git a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp index 4e73fb381af..00da860db89 100644 --- a/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/NPCHandler.cpp @@ -20,7 +20,7 @@ #include "Common.h" #include "Language.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Opcodes.h" diff --git a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp index 1067ad49bc4..fc2c3baf735 100644 --- a/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/QueryHandler.cpp @@ -20,8 +20,8 @@ #include "Common.h" #include "Language.h" -#include "Database/DatabaseEnv.h" -#include "Database/DatabaseImpl.h" +#include "DatabaseEnv.h" +#include "DatabaseImpl.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Opcodes.h" @@ -302,7 +302,7 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recv_data*/) if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0) { // if corpse map have entrance - if (Map const* entranceMap = MapManager::Instance().CreateBaseMap(corpseMapEntry->entrance_map)) + if (Map const* entranceMap = sMapMgr.CreateBaseMap(corpseMapEntry->entrance_map)) { mapid = corpseMapEntry->entrance_map; x = corpseMapEntry->entrance_x; @@ -536,4 +536,4 @@ void WorldSession::HandleQuestPOIQuery(WorldPacket& recv_data) } SendPacket(&data); -}
\ No newline at end of file +} diff --git a/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp b/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp index 8043f5ed149..d513dc4b84c 100644 --- a/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/QuestHandler.cpp @@ -422,7 +422,7 @@ void WorldSession::HandleQuestConfirmAccept(WorldPacket& recv_data) if (!pOriginalPlayer) return; - if (pQuest->GetType() == QUEST_TYPE_RAID) + if (pQuest->IsRaidQuest()) { if (!_player->IsInSameRaidWith(pOriginalPlayer)) return; diff --git a/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp b/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp index 312065f9f13..e6ad7a4c9e4 100644 --- a/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SkillHandler.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Opcodes.h" #include "Log.h" #include "Player.h" diff --git a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp index b8a4a127824..a526c61a5e7 100644 --- a/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/SpellHandler.cpp @@ -538,11 +538,7 @@ void WorldSession::HandleSpellClick(WorldPacket & recv_data) // TODO: Unit::SetCharmedBy: 28782 is not in world but 0 is trying to charm it! -> crash if (!unit->IsInWorld()) - { - sLog.outCrash("Spell click target %u is not in world!", unit->GetEntry()); - assert(false); return; - } SpellClickInfoMapBounds clickPair = objmgr.GetSpellClickInfoMapBounds(unit->GetEntry()); for (SpellClickInfoMap::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr) diff --git a/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp b/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp index b0660527f71..3402c99ce8b 100644 --- a/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/TaxiHandler.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "Opcodes.h" @@ -222,7 +222,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); flight->SetCurrentNodeAfterTeleport(); - Path::PathNode const& node = flight->GetPath()[flight->GetCurrentNode()]; + TaxiPathNodeEntry const& node = flight->GetPath()[flight->GetCurrentNode()]; flight->SkipCurrentNode(); GetPlayer()->TeleportTo(curDestNode->map_id,node.x,node.y,node.z,GetPlayer()->GetOrientation()); @@ -259,6 +259,8 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recv_data) GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next return; } + else + GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node GetPlayer()->CleanupAfterTaxiFlight(); GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ()); diff --git a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp index 448a6e0520d..6191b88587e 100644 --- a/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/TradeHandler.cpp @@ -27,37 +27,11 @@ #include "Opcodes.h" #include "Player.h" #include "Item.h" +#include "Spell.h" #include "SocialMgr.h" #include "Language.h" -enum TradeStatus -{ - TRADE_STATUS_BUSY = 0, - TRADE_STATUS_BEGIN_TRADE = 1, - TRADE_STATUS_OPEN_WINDOW = 2, - TRADE_STATUS_TRADE_CANCELED = 3, - TRADE_STATUS_TRADE_ACCEPT = 4, - TRADE_STATUS_BUSY_2 = 5, - TRADE_STATUS_NO_TARGET = 6, - TRADE_STATUS_BACK_TO_TRADE = 7, - TRADE_STATUS_TRADE_COMPLETE = 8, - // 9? - TRADE_STATUS_TARGET_TO_FAR = 10, - TRADE_STATUS_WRONG_FACTION = 11, - TRADE_STATUS_CLOSE_WINDOW = 12, - // 13? - TRADE_STATUS_IGNORE_YOU = 14, - TRADE_STATUS_YOU_STUNNED = 15, - TRADE_STATUS_TARGET_STUNNED = 16, - TRADE_STATUS_YOU_DEAD = 17, - TRADE_STATUS_TARGET_DEAD = 18, - TRADE_STATUS_YOU_LOGOUT = 19, - TRADE_STATUS_TARGET_LOGOUT = 20, - TRADE_STATUS_TRIAL_ACCOUNT = 21, // Trial accounts can not perform that action - TRADE_STATUS_ONLY_CONJURED = 22 // You can only trade conjured items... (cross realm BG related). -}; - -void WorldSession::SendTradeStatus(uint32 status) +void WorldSession::SendTradeStatus(TradeStatus status) { WorldPacket data; @@ -106,68 +80,50 @@ void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/) // recvPacket.print_storage(); } -void WorldSession::SendUpdateTrade() +void WorldSession::SendUpdateTrade(bool trader_data /*= true*/) { - Item *item = NULL; + TradeData* view_trade = trader_data ? _player->GetTradeData()->GetTraderData() : _player->GetTradeData(); - if (!_player || !_player->pTrader) - return; + WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, 1+4+4+4+4+4+7*(1+4+4+4+4+8+4+4+4+4+8+4+4+4+4+4+4)); + data << uint8(trader_data); // 1 means traders data, 0 means own + data << uint32(0); // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?) + data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = next field in most cases + data << uint32(TRADE_SLOT_COUNT); // trade slots count/number?, = prev field in most cases + data << uint32(view_trade->GetMoney()); // trader gold + data << uint32(view_trade->GetSpell()); // spell casted on lowest slot item - // reset trade status - if (_player->acceptTrade) - { - _player->acceptTrade = false; - SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - } - - if (_player->pTrader->acceptTrade) - { - _player->pTrader->acceptTrade = false; - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - } - - WorldPacket data(SMSG_TRADE_STATUS_EXTENDED, (100)); // guess size - data << (uint8) 1; // can be different (only seen 0 and 1) - data << (uint32) 0; // added in 2.4.0, this value must be equal to value from TRADE_STATUS_OPEN_WINDOW status packet (different value for different players to block multiple trades?) - data << (uint32) TRADE_SLOT_COUNT; // trade slots count/number?, = next field in most cases - data << (uint32) TRADE_SLOT_COUNT; // trade slots count/number?, = prev field in most cases - data << (uint32) _player->pTrader->tradeGold; // trader gold - data << (uint32) 0; // spell casted on lowest slot item + Item *item = NULL; for (uint8 i = 0; i < TRADE_SLOT_COUNT; ++i) { - item = (_player->pTrader->tradeItems[i] != 0 ? _player->pTrader->GetItemByGuid(_player->pTrader->tradeItems[i]) : NULL); + data << uint8(i); // trade slot number, if not specified, then end of packet - data << (uint8) i; // trade slot number, if not specified, then end of packet - - if (item) + if (Item* item = view_trade->GetItem(TradeSlots(i))) { - data << (uint32) item->GetProto()->ItemId; // entry - // display id - data << (uint32) item->GetProto()->DisplayInfoID; - // stack count - data << (uint32) item->GetUInt32Value(ITEM_FIELD_STACK_COUNT); - data << (uint32) 0; // probably gift=1, created_by=0? - // gift creator - data << (uint64) item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR); - data << (uint32) item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT); - for (uint8 j = 0; j < 3; ++j) - data << (uint32) 0; // enchantment id (permanent/gems?) + data << uint32(item->GetProto()->ItemId); // entry + data << uint32(item->GetProto()->DisplayInfoID);// display id + data << uint32(item->GetCount()); // stack count + // wrapped: hide stats but show giftcreator name + data << uint32(item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAGS_WRAPPED) ? 1 : 0); + data << uint64(item->GetUInt64Value(ITEM_FIELD_GIFTCREATOR)); + // perm. enchantment and gems + data << uint32(item->GetEnchantmentId(PERM_ENCHANTMENT_SLOT)); + for (uint32 enchant_slot = SOCK_ENCHANTMENT_SLOT; enchant_slot < SOCK_ENCHANTMENT_SLOT+MAX_GEM_SOCKETS; ++enchant_slot) + data << uint32(item->GetEnchantmentId(EnchantmentSlot(enchant_slot))); // creator - data << (uint64) item->GetUInt64Value(ITEM_FIELD_CREATOR); - data << (uint32) item->GetSpellCharges(); // charges - data << (uint32) item->GetItemSuffixFactor(); // SuffixFactor - // random properties id - data << (int32) item->GetItemRandomPropertyId(); - data << (uint32) item->GetProto()->LockID; // lock id + data << uint64(item->GetUInt64Value(ITEM_FIELD_CREATOR)); + data << uint32(item->GetSpellCharges()); // charges + data << uint32(item->GetItemSuffixFactor()); // SuffixFactor + data << uint32(item->GetItemRandomPropertyId());// random properties id + data << uint32(item->GetProto()->LockID); // lock id // max durability - data << (uint32) item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY); + data << uint32(item->GetUInt32Value(ITEM_FIELD_MAXDURABILITY)); // durability - data << (uint32) item->GetUInt32Value(ITEM_FIELD_DURABILITY); + data << uint32(item->GetUInt32Value(ITEM_FIELD_DURABILITY)); } else { - for (uint8 j = 0; j < 18; j++) + for (uint8 j = 0; j < 18; ++j) data << uint32(0); } } @@ -179,11 +135,15 @@ void WorldSession::SendUpdateTrade() void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { - for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) + Player* trader = _player->GetTrader(); + if (!trader) + return; + + for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { ItemPosCountVec traderDst; ItemPosCountVec playerDst; - bool traderCanTrade = (myItems[i] == NULL || _player->pTrader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, myItems[i], false) == EQUIP_ERR_OK); + 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); if (traderCanTrade && playerCanTrade) { @@ -196,25 +156,25 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) sLog.outDebug("partner storing: %u",myItems[i]->GetGUIDLow()); if (_player->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) { - sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", - _player->GetName(),_player->GetSession()->GetAccountId(), - myItems[i]->GetProto()->Name1,myItems[i]->GetEntry(),myItems[i]->GetCount(), - _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId()); + sLog.outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", + _player->GetName(), _player->GetSession()->GetAccountId(), + myItems[i]->GetProto()->Name1, myItems[i]->GetEntry(), myItems[i]->GetCount(), + trader->GetName(), trader->GetSession()->GetAccountId()); } // store - _player->pTrader->MoveItemToInventory(traderDst, myItems[i], true, true); + trader->MoveItemToInventory(traderDst, myItems[i], true, true); } if (hisItems[i]) { // logging sLog.outDebug("player storing: %u",hisItems[i]->GetGUIDLow()); - if (_player->pTrader->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) + if (trader->GetSession()->GetSecurity() > SEC_PLAYER && sWorld.getConfig(CONFIG_GM_LOG_TRADE)) { - sLog.outCommand(_player->pTrader->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", - _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId(), - hisItems[i]->GetProto()->Name1,hisItems[i]->GetEntry(),hisItems[i]->GetCount(), - _player->GetName(),_player->GetSession()->GetAccountId()); + sLog.outCommand(trader->GetSession()->GetAccountId(),"GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", + trader->GetName(), trader->GetSession()->GetAccountId(), + hisItems[i]->GetProto()->Name1, hisItems[i]->GetEntry(), hisItems[i]->GetCount(), + _player->GetName(), _player->GetSession()->GetAccountId()); } // store @@ -239,8 +199,8 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) { if (!playerCanTrade) sLog.outError("player can't store item: %u",hisItems[i]->GetGUIDLow()); - if (_player->pTrader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK) - _player->pTrader->MoveItemToInventory(traderDst, hisItems[i], true, true); + if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK) + trader->MoveItemToInventory(traderDst, hisItems[i], true, true); else sLog.outError("trader can't take item back: %u",hisItems[i]->GetGUIDLow()); } @@ -250,135 +210,231 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) //============================================================== +static void setAcceptTradeMode(TradeData* myTrade, TradeData* hisTrade, Item **myItems, Item **hisItems) +{ + myTrade->SetInAcceptProcess(true); + hisTrade->SetInAcceptProcess(true); + + // store items in local list and set 'in-trade' flag + for(uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) + { + if (Item* item = myTrade->GetItem(TradeSlots(i))) + { + DEBUG_LOG("player trade item %u bag: %u slot: %u", item->GetGUIDLow(), item->GetBagSlot(), item->GetSlot()); + //Can return NULL + myItems[i] = item; + myItems[i]->SetInTrade(); + } + + if (Item* item = hisTrade->GetItem(TradeSlots(i))) + { + DEBUG_LOG("partner trade item %u bag: %u slot: %u", item->GetGUIDLow(), item->GetBagSlot(), item->GetSlot()); + hisItems[i] = item; + hisItems[i]->SetInTrade(); + } + } +} + +static void clearAcceptTradeMode(TradeData* myTrade, TradeData* hisTrade) +{ + myTrade->SetInAcceptProcess(false); + hisTrade->SetInAcceptProcess(false); +} + +static void clearAcceptTradeMode(Item **myItems, Item **hisItems) +{ + // clear 'in-trade' flag + for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) + { + if (myItems[i]) + myItems[i]->SetInTrade(false); + if (hisItems[i]) + hisItems[i]->SetInTrade(false); + } +} + void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) { + TradeData* my_trade = _player->m_trade; + if (!my_trade) + return; + + Player* trader = my_trade->GetTrader(); + + TradeData* his_trade = trader->m_trade; + 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 }; - bool myCanCompleteTrade=true,hisCanCompleteTrade=true; + bool myCanCompleteTrade = true, hisCanCompleteTrade = true; - if (!GetPlayer()->pTrader) - return; + // set before checks for propertly undo at problems (it already set in to client) + my_trade->SetAccepted(true); // not accept case incorrect money amount - if (_player->tradeGold > _player->GetMoney()) + if (my_trade->GetMoney() > _player->GetMoney()) { SendNotification(LANG_NOT_ENOUGH_GOLD); - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - _player->acceptTrade = false; + my_trade->SetAccepted(false, true); return; } // not accept case incorrect money amount - if (_player->pTrader->tradeGold > _player->pTrader->GetMoney()) + if (his_trade->GetMoney() > trader->GetMoney()) { - _player->pTrader->GetSession()->SendNotification(LANG_NOT_ENOUGH_GOLD); - SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - _player->pTrader->acceptTrade = false; + trader->GetSession()->SendNotification(LANG_NOT_ENOUGH_GOLD); + his_trade->SetAccepted(false, true); return; } // not accept if some items now can't be trade (cheating) - for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) + for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { - if (_player->tradeItems[i] != 0) + if (Item* item = my_trade->GetItem(TradeSlots(i))) { - if (Item* item =_player->GetItemByGuid(_player->tradeItems[i])) + if (!item->CanBeTraded()) { - if (!item->CanBeTraded()) - { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); - return; - } + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; } } - if (_player->pTrader->tradeItems[i] != 0) + + if (Item* item = his_trade->GetItem(TradeSlots(i))) { - if (Item* item =_player->pTrader->GetItemByGuid(_player->pTrader->tradeItems[i])) + if (!item->CanBeTraded()) { - if (!item->CanBeTraded()) - { - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); - return; - } + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; } } } - _player->acceptTrade = true; - if (_player->pTrader->acceptTrade) + if (his_trade->IsAccepted()) { - // inform partner client - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + setAcceptTradeMode(my_trade, his_trade, myItems, hisItems); + + Spell* my_spell = NULL; + SpellCastTargets my_targets; + + Spell* his_spell = NULL; + SpellCastTargets his_targets; - // store items in local list and set 'in-trade' flag - for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) + // not accept if spell can't be casted now (cheating) + if (uint32 my_spell_id = my_trade->GetSpell()) { - if (_player->tradeItems[i] != 0) + SpellEntry const* spellEntry = sSpellStore.LookupEntry(my_spell_id); + Item* castItem = my_trade->GetSpellCastItem(); + + if (!spellEntry || !his_trade->GetItem(TRADE_SLOT_NONTRADED) || + my_trade->HasSpellCastItem() && !castItem) { - //Can return NULL - myItems[i] = _player->GetItemByGuid(_player->tradeItems[i]); - if (myItems[i]) - { - myItems[i]->SetInTrade(); - sLog.outDebug("Player trade item bag: %u slot: %u", myItems[i]->GetBagSlot(), myItems[i]->GetSlot()); - } + clearAcceptTradeMode(my_trade, his_trade); + clearAcceptTradeMode(myItems, hisItems); + + my_trade->SetSpell(0); + return; } - if (_player->pTrader->tradeItems[i] != 0) + + my_spell = new Spell(_player, spellEntry, true); + my_spell->m_CastItem = castItem; + my_targets.setTradeItemTarget(_player); + my_spell->m_targets = my_targets; + + SpellCastResult res = my_spell->CheckCast(true); + if (res != SPELL_CAST_OK) { - //Can return NULL - hisItems[i]=_player->pTrader->GetItemByGuid(_player->pTrader->tradeItems[i]); - if (hisItems[i]) - { - hisItems[i]->SetInTrade(); - sLog.outDebug("Player trade item bag: %u slot: %u", hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot()); - } + my_spell->SendCastResult(res); + + clearAcceptTradeMode(my_trade, his_trade); + clearAcceptTradeMode(myItems, hisItems); + + delete my_spell; + my_trade->SetSpell(0); + return; } } - // test if item will fit in each inventory - hisCanCompleteTrade = (_player->pTrader->CanStoreItems(myItems,TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); - myCanCompleteTrade = (_player->CanStoreItems(hisItems,TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); - - // clear 'in-trade' flag - for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) + // not accept if spell can't be casted now (cheating) + if (uint32 his_spell_id = his_trade->GetSpell()) { - if (myItems[i]) myItems[i]->SetInTrade(false); - if (hisItems[i]) hisItems[i]->SetInTrade(false); + SpellEntry const* spellEntry = sSpellStore.LookupEntry(his_spell_id); + Item* castItem = his_trade->GetSpellCastItem(); + + if (!spellEntry || !my_trade->GetItem(TRADE_SLOT_NONTRADED) || his_trade->HasSpellCastItem() && !castItem) + { + delete my_spell; + his_trade->SetSpell(0); + + clearAcceptTradeMode(my_trade, his_trade); + clearAcceptTradeMode(myItems, hisItems); + return; + } + + his_spell = new Spell(trader, spellEntry, true); + his_spell->m_CastItem = castItem; + his_targets.setTradeItemTarget(trader); + his_spell->m_targets = his_targets; + + SpellCastResult res = his_spell->CheckCast(true); + if (res != SPELL_CAST_OK) + { + his_spell->SendCastResult(res); + + clearAcceptTradeMode(my_trade, his_trade); + clearAcceptTradeMode(myItems, hisItems); + + delete my_spell; + delete his_spell; + + his_trade->SetSpell(0); + return; + } } + // inform partner client + trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + + // test if item will fit in each inventory + hisCanCompleteTrade = (trader->CanStoreItems(myItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); + myCanCompleteTrade = (_player->CanStoreItems(hisItems, TRADE_SLOT_TRADED_COUNT) == EQUIP_ERR_OK); + + clearAcceptTradeMode(myItems, hisItems); + // in case of missing space report error if (!myCanCompleteTrade) { + clearAcceptTradeMode(my_trade, his_trade); + SendNotification(LANG_NOT_FREE_TRADE_SLOTS); - GetPlayer()->pTrader->GetSession()->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); - SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + trader->GetSession()->SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); + my_trade->SetAccepted(false); + his_trade->SetAccepted(false); return; } else if (!hisCanCompleteTrade) { + clearAcceptTradeMode(my_trade, his_trade); + SendNotification(LANG_NOT_PARTNER_FREE_TRADE_SLOTS); - GetPlayer()->pTrader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS); - SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); + trader->GetSession()->SendNotification(LANG_NOT_FREE_TRADE_SLOTS); + my_trade->SetAccepted(false); + his_trade->SetAccepted(false); return; } // execute trade: 1. remove - for (int i=0; i<TRADE_SLOT_TRADED_COUNT; ++i) + for (uint8 i = 0; i < TRADE_SLOT_TRADED_COUNT; ++i) { - Item* iPtr = NULL; if (myItems[i]) { myItems[i]->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, _player->GetGUID()); - iPtr = _player->GetItemByGuid(_player->tradeItems[i]); - _player->MoveItemFromInventory(iPtr->GetBagSlot(), iPtr->GetSlot(), true); + _player->MoveItemFromInventory(myItems[i]->GetBagSlot(), myItems[i]->GetSlot(), true); } if (hisItems[i]) { - hisItems[i]->SetUInt64Value(ITEM_FIELD_GIFTCREATOR,_player->pTrader->GetGUID()); - iPtr = _player->pTrader->GetItemByGuid(_player->pTrader->tradeItems[i]); - _player->pTrader->MoveItemFromInventory(iPtr->GetBagSlot(), iPtr->GetSlot(), true); + hisItems[i]->SetUInt64Value(ITEM_FIELD_GIFTCREATOR, trader->GetGUID()); + trader->MoveItemFromInventory(hisItems[i]->GetBagSlot(), hisItems[i]->GetSlot(), true); } } @@ -388,72 +444,80 @@ void WorldSession::HandleAcceptTradeOpcode(WorldPacket& /*recvPacket*/) // logging money if (sWorld.getConfig(CONFIG_GM_LOG_TRADE)) { - if (_player->GetSession()->GetSecurity() > SEC_PLAYER && _player->tradeGold > 0) + if (_player->GetSession()->GetSecurity() > SEC_PLAYER && my_trade->GetMoney() > 0) { sLog.outCommand(_player->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", - _player->GetName(),_player->GetSession()->GetAccountId(), - _player->tradeGold, - _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId()); + _player->GetName(), _player->GetSession()->GetAccountId(), + my_trade->GetMoney(), + trader->GetName(), trader->GetSession()->GetAccountId()); } - if (_player->pTrader->GetSession()->GetSecurity() > SEC_PLAYER && _player->pTrader->tradeGold > 0) + if (trader->GetSession()->GetSecurity() > SEC_PLAYER && his_trade->GetMoney() > 0) { - sLog.outCommand(_player->pTrader->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", - _player->pTrader->GetName(),_player->pTrader->GetSession()->GetAccountId(), - _player->pTrader->tradeGold, - _player->GetName(),_player->GetSession()->GetAccountId()); + sLog.outCommand(trader->GetSession()->GetAccountId(),"GM %s (Account: %u) give money (Amount: %u) to player: %s (Account: %u)", + trader->GetName(), trader->GetSession()->GetAccountId(), + his_trade->GetMoney(), + _player->GetName(), _player->GetSession()->GetAccountId()); } } // update money - _player->ModifyMoney(-int32(_player->tradeGold)); - _player->ModifyMoney(_player->pTrader->tradeGold); - _player->pTrader->ModifyMoney(-int32(_player->pTrader->tradeGold)); - _player->pTrader->ModifyMoney(_player->tradeGold); + _player->ModifyMoney(-int32(my_trade->GetMoney())); + _player->ModifyMoney(his_trade->GetMoney()); + trader->ModifyMoney(-int32(his_trade->GetMoney())); + trader->ModifyMoney(my_trade->GetMoney()); + + if (my_spell) + my_spell->prepare(&my_targets); + + if (his_spell) + his_spell->prepare(&his_targets); - _player->ClearTrade(); - _player->pTrader->ClearTrade(); + // cleanup + clearAcceptTradeMode(my_trade, his_trade); + delete _player->m_trade; + _player->m_trade = NULL; + delete trader->m_trade; + trader->m_trade = NULL; // desynchronized with the other saves here (SaveInventoryAndGoldToDB() not have own transaction guards) CharacterDatabase.BeginTransaction(); _player->SaveInventoryAndGoldToDB(); - _player->pTrader->SaveInventoryAndGoldToDB(); + trader->SaveInventoryAndGoldToDB(); CharacterDatabase.CommitTransaction(); - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); + trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); SendTradeStatus(TRADE_STATUS_TRADE_COMPLETE); - - _player->pTrader->pTrader = NULL; - _player->pTrader = NULL; } else { - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); + trader->GetSession()->SendTradeStatus(TRADE_STATUS_TRADE_ACCEPT); } } void WorldSession::HandleUnacceptTradeOpcode(WorldPacket& /*recvPacket*/) { - if (!GetPlayer()->pTrader) + TradeData* my_trade = _player->GetTradeData(); + if (!my_trade) return; - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_BACK_TO_TRADE); - _player->acceptTrade = false; + my_trade->SetAccepted(false, true); } void WorldSession::HandleBeginTradeOpcode(WorldPacket& /*recvPacket*/) { - if (!_player->pTrader) + TradeData* my_trade = _player->m_trade; + if (!my_trade) return; - _player->pTrader->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); - _player->pTrader->ClearTrade(); - + my_trade->GetTrader()->GetSession()->SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); SendTradeStatus(TRADE_STATUS_OPEN_WINDOW); - _player->ClearTrade(); } void WorldSession::SendCancelTrade() { + if (m_playerRecentlyLogout) + return; + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); } @@ -466,7 +530,7 @@ void WorldSession::HandleCancelTradeOpcode(WorldPacket& /*recvPacket*/) void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) { - if (GetPlayer()->pTrader) + if (GetPlayer()->m_trade) return; uint64 ID; @@ -511,7 +575,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) return; } - if (pOther == GetPlayer() || pOther->pTrader) + if (pOther == GetPlayer() || pOther->m_trade) { SendTradeStatus(TRADE_STATUS_BUSY); return; @@ -566,35 +630,30 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) } // OK start trade - _player->pTrader = pOther; - pOther->pTrader =_player; + _player->m_trade = new TradeData(_player, pOther); + pOther->m_trade = new TradeData(pOther, _player); WorldPacket data(SMSG_TRADE_STATUS, 12); - data << (uint32) TRADE_STATUS_BEGIN_TRADE; - data << (uint64)_player->GetGUID(); - _player->pTrader->GetSession()->SendPacket(&data); + data << uint32(TRADE_STATUS_BEGIN_TRADE); + data << uint64(_player->GetGUID()); + pOther->GetSession()->SendPacket(&data); } void WorldSession::HandleSetTradeGoldOpcode(WorldPacket& recvPacket) { - if (!_player->pTrader) - return; - uint32 gold; - recvPacket >> gold; - // gold can be incorrect, but this is checked at trade finished. - _player->tradeGold = gold; + TradeData* my_trade = _player->GetTradeData(); + if (!my_trade) + return; - _player->pTrader->GetSession()->SendUpdateTrade(); + // gold can be incorrect, but this is checked at trade finished. + my_trade->SetMoney(gold); } void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) { - if (!_player->pTrader) - return; - // send update uint8 tradeSlot; uint8 bag; @@ -604,6 +663,10 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) recvPacket >> bag; recvPacket >> slot; + TradeData* my_trade = _player->GetTradeData(); + if (!my_trade) + return; + // invalid slot number if (tradeSlot >= TRADE_SLOT_COUNT) { @@ -612,7 +675,7 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) } // check cheating, can't fail with correct client operations - Item* item = _player->GetItemByPos(bag,slot); + Item* item = _player->GetItemByPos(bag, slot); if (!item || (tradeSlot != TRADE_SLOT_NONTRADED && !item->CanBeTraded())) { SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); @@ -622,35 +685,29 @@ void WorldSession::HandleSetTradeItemOpcode(WorldPacket& recvPacket) uint64 iGUID = item->GetGUID(); // prevent place single item into many trade slots using cheating and client bugs - for (int i = 0; i < TRADE_SLOT_COUNT; ++i) + if (my_trade->HasItem(iGUID)) { - if (_player->tradeItems[i] == iGUID) - { - // cheating attempt - SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); - return; - } + // cheating attempt + SendTradeStatus(TRADE_STATUS_TRADE_CANCELED); + return; } - _player->tradeItems[tradeSlot] = iGUID; - - _player->pTrader->GetSession()->SendUpdateTrade(); + my_trade->SetItem(TradeSlots(tradeSlot), item); } void WorldSession::HandleClearTradeItemOpcode(WorldPacket& recvPacket) { - if (!_player->pTrader) - return; - uint8 tradeSlot; recvPacket >> tradeSlot; + TradeData* my_trade = _player->m_trade; + if (!my_trade) + return; + // invalid slot number if (tradeSlot >= TRADE_SLOT_COUNT) return; - _player->tradeItems[tradeSlot] = 0; - - _player->pTrader->GetSession()->SendUpdateTrade(); + my_trade->SetItem(TradeSlots(tradeSlot), NULL); } diff --git a/src/server/game/Server/Protocol/Opcodes.cpp b/src/server/game/Server/Protocol/Opcodes.cpp index 0b67199b4ea..8a45aa9e910 100644 --- a/src/server/game/Server/Protocol/Opcodes.cpp +++ b/src/server/game/Server/Protocol/Opcodes.cpp @@ -361,7 +361,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x14A*/ { "SMSG_ATTACKERSTATEUPDATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14B*/ { "SMSG_BATTLEFIELD_PORT_DENIED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14C*/ { "SMSG_DAMAGE_DONE_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x14D*/ { "SMSG_DAMAGE_TAKEN_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x14D*/ { "SMSG_UNIT_SPELLCAST_START", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14E*/ { "SMSG_CANCEL_COMBAT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x14F*/ { "SMSG_SPELLBREAKLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x150*/ { "SMSG_SPELLHEALLOG", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -570,7 +570,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x21B*/ { "SMSG_GMTICKET_SYSTEMSTATUS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x21C*/ { "CMSG_SPIRIT_HEALER_ACTIVATE", STATUS_LOGGEDIN, &WorldSession::HandleSpiritHealerActivateOpcode}, /*0x21D*/ { "CMSG_SET_STAT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x21E*/ { "SMSG_SET_REST_START_OBSOLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x21E*/ { "SMSG_QUEST_FORCE_REMOVE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x21F*/ { "CMSG_SKILL_BUY_STEP", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x220*/ { "CMSG_SKILL_BUY_RANK", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x221*/ { "CMSG_XP_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, @@ -1148,8 +1148,8 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x45D*/ { "CMSG_FORCE_PITCH_RATE_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x45E*/ { "SMSG_SPLINE_SET_PITCH_RATE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x45F*/ { "SMSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x460*/ { "MSG_MOVE_ABANDON_TRANSPORT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x461*/ { "CMSG_MOVE_ABANDON_TRANSPORT_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x460*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x461*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST2", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x462*/ { "CMSG_UPDATE_MISSILE_TRAJECTORY", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x463*/ { "SMSG_UPDATE_ACCOUNT_DATA_COMPLETE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x464*/ { "SMSG_TRIGGER_MOVIE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -1165,7 +1165,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x46E*/ { "CMSG_COMPLETE_ACHIEVEMENT_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x46F*/ { "SMSG_QUESTUPDATE_ADD_PVP_KILL", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x470*/ { "CMSG_SET_CRITERIA_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x471*/ { "SMSG_GROUP_SWAP_FAILED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x471*/ { "SMSG_CALENDAR_UPDATE_INVITE_LIST3", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x472*/ { "CMSG_UNITANIMTIER_CHEAT", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x473*/ { "CMSG_CHAR_CUSTOMIZE", STATUS_AUTHED, &WorldSession::HandleCharCustomize }, /*0x474*/ { "SMSG_CHAR_CUSTOMIZE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, @@ -1258,13 +1258,13 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4CB*/ { "UMSG_UNKNOWN_1227", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4CC*/ { "UMSG_UNKNOWN_1228", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4CD*/ { "SMSG_MULTIPLE_PACKETS", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4CE*/ { "SMSG_UNKNOWN_1230", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4CF*/ { "CMSG_UNKNOWN_1231_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4D0*/ { "SMSG_UNKNOWN_1232", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4D1*/ { "CMSG_UNKNOWN_1233_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, - /*0x4D2*/ { "SMSG_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4D3*/ { "SMSG_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4D4*/ { "SMSG_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CE*/ { "SMSG_FORCE_UNK1_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4CF*/ { "CMSG_FORCE_UNK1_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D0*/ { "SMSG_FORCE_UNK2_SPEED_CHANGE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D1*/ { "CMSG_FORCE_UNK2_SPEED_CHANGE_ACK", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4D2*/ { "MSG_MOVE_UNKNOWN_1234", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D3*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1235", STATUS_NEVER, &WorldSession::Handle_ServerSide }, + /*0x4D4*/ { "SMSG_SPLINE_MOVE_UNKNOWN_1236", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4D5*/ { "CMSG_EQUIPMENT_SET_USE", STATUS_LOGGEDIN, &WorldSession::HandleEquipmentSetUse }, /*0x4D6*/ { "SMSG_EQUIPMENT_SET_USE_RESULT", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4D7*/ { "UMSG_UNKNOWN_1239", STATUS_NEVER, &WorldSession::Handle_NULL }, @@ -1275,7 +1275,7 @@ OpcodeHandler opcodeTable[NUM_MSG_TYPES] = /*0x4DC*/ { "UMSG_UNKNOWN_1244", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4DD*/ { "UMSG_UNKNOWN_1245", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4DE*/ { "SMSG_BATTLEFIELD_MGR_ENTRY_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, - /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONS", STATUS_NEVER, &WorldSession::Handle_NULL }, + /*0x4DF*/ { "CMSG_BATTLEFIELD_MGR_ENTRY_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL }, /*0x4E0*/ { "SMSG_BATTLEFIELD_MGR_ENTERED", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4E1*/ { "SMSG_BATTLEFIELD_MGR_QUEUE_INVITE", STATUS_NEVER, &WorldSession::Handle_ServerSide }, /*0x4E2*/ { "CMSG_BATTLEFIELD_MGR_QUEUE_INVITE_RESPONSE", STATUS_NEVER, &WorldSession::Handle_NULL }, diff --git a/src/server/game/Server/Protocol/Opcodes.h b/src/server/game/Server/Protocol/Opcodes.h index 4ae6931c3f5..44a06ddb8d3 100644 --- a/src/server/game/Server/Protocol/Opcodes.h +++ b/src/server/game/Server/Protocol/Opcodes.h @@ -1343,7 +1343,11 @@ enum Opcodes SMSG_UNKNOWN_1304 = 0x518, // something with player movement (move event 58?), speed packet UMSG_UNKNOWN_1305 = 0x519, // not found UMSG_UNKNOWN_1306 = 0x51A, // not found - NUM_MSG_TYPES = 0x51B + CMSG_COMMENTATOR_SKIRMISH_QUEUE_COMMAND = 0x51B, // lua: CommentatorSetSkirmishMatchmakingMode/CommentatorRequestSkirmishQueueData/CommentatorRequestSkirmishMode/CommentatorStartSkirmishMatch + SMSG_UNKNOWN_1308 = 0x51C, // event EVENT_COMMENTATOR_SKIRMISH_QUEUE_REQUEST, CGCommentator::QueueNode + SMSG_UNKNOWN_1309 = 0x51D, // event EVENT_COMMENTATOR_SKIRMISH_QUEUE_REQUEST + SMSG_UNKNOWN_1310 = 0x51E, // some compressed packet? + NUM_MSG_TYPES = 0x51F }; /// Player state diff --git a/src/server/game/Server/Protocol/WorldLog.cpp b/src/server/game/Server/Protocol/WorldLog.cpp index 7c6c4020336..e66bff0b504 100644 --- a/src/server/game/Server/Protocol/WorldLog.cpp +++ b/src/server/game/Server/Protocol/WorldLog.cpp @@ -23,14 +23,9 @@ */ #include "WorldLog.h" -#include "Policies/SingletonImp.h" -#include "Config/ConfigEnv.h" +#include "ConfigEnv.h" #include "Log.h" -#define CLASS_LOCK Trinity::ClassLevelLockable<WorldLog, ACE_Thread_Mutex> -INSTANTIATE_SINGLETON_2(WorldLog, CLASS_LOCK); -INSTANTIATE_CLASS_MUTEX(WorldLog, ACE_Thread_Mutex); - WorldLog::WorldLog() : i_file(NULL) { Initialize(); @@ -67,7 +62,7 @@ void WorldLog::outTimestampLog(char const *fmt, ...) { if (LogWorld()) { - Guard guard(*this); + ACE_GUARD(ACE_Thread_Mutex, Guard, Lock); ASSERT(i_file); Log::outTimestamp(i_file); @@ -95,7 +90,7 @@ void WorldLog::outLog(char const *fmt, ...) { if (LogWorld()) { - Guard guard(*this); + ACE_GUARD(ACE_Thread_Mutex, Guard, Lock); ASSERT(i_file); va_list args; @@ -117,6 +112,3 @@ void WorldLog::outLog(char const *fmt, ...) va_end(ap2); } } - -#define sWorldLog WorldLog::Instance() - diff --git a/src/server/game/Server/Protocol/WorldLog.h b/src/server/game/Server/Protocol/WorldLog.h index 4ee9bb178ec..fd228ce4559 100644 --- a/src/server/game/Server/Protocol/WorldLog.h +++ b/src/server/game/Server/Protocol/WorldLog.h @@ -26,19 +26,19 @@ #define TRINITY_WORLDLOG_H #include "Common.h" -#include "Policies/Singleton.h" +#include "ace/Singleton.h" #include "Errors.h" #include <stdarg.h> /// %Log packets to a file -class WorldLog : public Trinity::Singleton<WorldLog, Trinity::ClassLevelLockable<WorldLog, ACE_Thread_Mutex> > +class WorldLog { - friend class Trinity::OperatorNew<WorldLog>; + friend class ACE_Singleton<WorldLog, ACE_Thread_Mutex>; WorldLog(); WorldLog(const WorldLog &); WorldLog& operator=(const WorldLog &); - typedef Trinity::ClassLevelLockable<WorldLog, ACE_Thread_Mutex>::Lock Guard; + ACE_Thread_Mutex Lock; /// Close the file in destructor ~WorldLog(); @@ -57,7 +57,7 @@ class WorldLog : public Trinity::Singleton<WorldLog, Trinity::ClassLevelLockable bool m_dbWorld; }; -#define sWorldLog WorldLog::Instance() +#define sWorldLog (*ACE_Singleton<WorldLog, ACE_Thread_Mutex>::instance()) #endif /// @} diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index bc737717840..6de0cb27381 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -24,7 +24,7 @@ #include "WorldSocket.h" // must be first to make ACE happy with ACE includes in it #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "Opcodes.h" #include "WorldPacket.h" @@ -40,7 +40,7 @@ #include "OutdoorPvPMgr.h" #include "MapManager.h" #include "SocialMgr.h" -#include "zlib/zlib.h" +#include "zlib.h" #include "ScriptMgr.h" #include "LFGMgr.h" @@ -82,7 +82,6 @@ WorldSession::~WorldSession() delete packet; LoginDatabase.PExecute("UPDATE account SET online = 0 WHERE id = %u;", GetAccountId()); - CharacterDatabase.PExecute("UPDATE characters SET online = 0 WHERE account = %u;", GetAccountId()); } void WorldSession::SizeError(WorldPacket const& packet, uint32 size) const diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index c17f3e3f3e6..dbcc94f071b 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -205,12 +205,12 @@ class WorldSession void SendBattlegGroundList(uint64 guid, BattleGroundTypeId bgTypeId); - void SendTradeStatus(uint32 status); + void SendTradeStatus(TradeStatus status); void SendCancelTrade(); void SendStablePet(uint64 guid); void SendPetitionQueryOpcode(uint64 petitionguid); - void SendUpdateTrade(); + void SendUpdateTrade(bool trader_data = true); //pet void SendPetNameQuery(uint64 guid, uint32 petnumber); diff --git a/src/server/game/Server/WorldSocket.cpp b/src/server/game/Server/WorldSocket.cpp index c07b369d0b9..f7b128fb761 100644 --- a/src/server/game/Server/WorldSocket.cpp +++ b/src/server/game/Server/WorldSocket.cpp @@ -38,9 +38,9 @@ #include "SharedDefines.h" #include "ByteBuffer.h" #include "Opcodes.h" -#include "Database/DatabaseEnv.h" -#include "Auth/BigNumber.h" -#include "Auth/Sha1.h" +#include "DatabaseEnv.h" +#include "BigNumber.h" +#include "SHA1.h" #include "WorldSession.h" #include "WorldSocketMgr.h" #include "Log.h" @@ -120,8 +120,7 @@ m_LastPingTime(ACE_Time_Value::zero) WorldSocket::~WorldSocket (void) { - if (m_RecvWPct) - delete m_RecvWPct; + delete m_RecvWPct; if (m_OutBuffer) m_OutBuffer->release(); @@ -769,7 +768,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) // NOTE: ATM the socket is singlethread, have this in mind ... uint8 digest[20]; uint32 clientSeed; - uint32 unk2, unk3; + uint32 unk2, unk3, unk5, unk6, unk7; uint64 unk4; uint32 BuiltNumberClient; uint32 id, security; @@ -798,6 +797,7 @@ int WorldSocket::HandleAuthSession (WorldPacket& recvPacket) recvPacket >> account; recvPacket >> unk3; recvPacket >> clientSeed; + recvPacket >> unk5 >> unk6 >> unk7; recvPacket >> unk4; recvPacket.read (digest, 20); diff --git a/src/server/game/Server/WorldSocket.h b/src/server/game/Server/WorldSocket.h index 70654274215..d07e9a3f2e4 100644 --- a/src/server/game/Server/WorldSocket.h +++ b/src/server/game/Server/WorldSocket.h @@ -43,7 +43,7 @@ #endif /* ACE_LACKS_PRAGMA_ONCE */ #include "Common.h" -#include "Auth/AuthCrypt.h" +#include "AuthCrypt.h" class ACE_Message_Block; class WorldPacket; diff --git a/src/server/game/Server/WorldSocketMgr.cpp b/src/server/game/Server/WorldSocketMgr.cpp index c23d08e6f78..6ccb30b64ef 100644 --- a/src/server/game/Server/WorldSocketMgr.cpp +++ b/src/server/game/Server/WorldSocketMgr.cpp @@ -42,8 +42,8 @@ #include "Log.h" #include "Common.h" -#include "Config/ConfigEnv.h" -#include "Database/DatabaseEnv.h" +#include "ConfigEnv.h" +#include "DatabaseEnv.h" #include "WorldSocket.h" /** @@ -84,8 +84,7 @@ class ReactorRunnable : protected ACE_Task_Base Stop(); Wait(); - if (m_Reactor) - delete m_Reactor; + delete m_Reactor; } void Stop() @@ -220,11 +219,8 @@ WorldSocketMgr::WorldSocketMgr() : WorldSocketMgr::~WorldSocketMgr() { - if (m_NetThreads) - delete [] m_NetThreads; - - if (m_Acceptor) - delete m_Acceptor; + delete [] m_NetThreads; + delete m_Acceptor; } int diff --git a/src/server/game/Skills/SkillDiscovery.cpp b/src/server/game/Skills/SkillDiscovery.cpp index 163f7a2bf7e..fb34cff150c 100644 --- a/src/server/game/Skills/SkillDiscovery.cpp +++ b/src/server/game/Skills/SkillDiscovery.cpp @@ -18,10 +18,9 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "ProgressBar.h" -#include "Policies/SingletonImp.h" #include "World.h" #include "Util.h" #include "SkillDiscovery.h" diff --git a/src/server/game/Skills/SkillExtraItems.cpp b/src/server/game/Skills/SkillExtraItems.cpp index cc50d3683f4..982556c0557 100644 --- a/src/server/game/Skills/SkillExtraItems.cpp +++ b/src/server/game/Skills/SkillExtraItems.cpp @@ -19,7 +19,7 @@ */ #include "SkillExtraItems.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "Log.h" #include "ProgressBar.h" #include "Player.h" diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 8b21062e371..a3a037ae5a8 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -344,8 +344,8 @@ enum AuraType SPELL_AURA_297 = 297, SPELL_AURA_298 = 298, SPELL_AURA_299 = 299, - SPELL_AURA_300 = 300, - SPELL_AURA_301 = 301, + SPELL_AURA_SHARE_DAMAGE_PCT = 300, + SPELL_AURA_SCHOOL_HEAL_ABSORB = 301, SPELL_AURA_302 = 302, SPELL_AURA_303 = 303, SPELL_AURA_304 = 304, @@ -354,12 +354,12 @@ enum AuraType SPELL_AURA_307 = 307, SPELL_AURA_308 = 308, SPELL_AURA_309 = 309, - SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS = 310, + SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE = 310, SPELL_AURA_311 = 311, SPELL_AURA_312 = 312, SPELL_AURA_313 = 313, - SPELL_AURA_314 = 314, - SPELL_AURA_315 = 315, + SPELL_AURA_PREVENT_RESSURECTION = 314, + SPELL_AURA_UNDERWATER_WALKING = 315, SPELL_AURA_PERIODIC_HASTE = 316, TOTAL_AURAS = 317 }; diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 6a3e52d9646..7a70155a23e 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -271,7 +271,7 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleNULL, //214 Tamed Pet Passive &AuraEffect::HandleArenaPreparation, //215 SPELL_AURA_ARENA_PREPARATION &AuraEffect::HandleModCastingSpeed, //216 SPELL_AURA_HASTE_SPELLS - &AuraEffect::HandleUnused, //217 unused (3.2.0) + &AuraEffect::HandleNULL, //217 69106 - killing spree helper - unknown use &AuraEffect::HandleAuraModRangedHaste, //218 SPELL_AURA_HASTE_RANGED &AuraEffect::HandleModManaRegen, //219 SPELL_AURA_MOD_MANA_REGEN_FROM_STAT &AuraEffect::HandleModRatingFromStat, //220 SPELL_AURA_MOD_RATING_FROM_STAT @@ -347,36 +347,36 @@ pAuraEffectHandler AuraEffectHandler[TOTAL_AURAS]= &AuraEffect::HandleAuraModCritPct, //290 SPELL_AURA_MOD_CRIT_PCT &AuraEffect::HandleNoImmediateEffect, //291 SPELL_AURA_MOD_XP_QUEST_PCT implemented in Player::RewardQuest &AuraEffect::HandleNULL, //292 call stabled pet - &AuraEffect::HandleNULL, //293 2 test spells + &AuraEffect::HandleNULL, //293 auras which probably add set of abilities to their target based on it's miscvalue &AuraEffect::HandleNoImmediateEffect, //294 SPELL_AURA_PREVENT_REGENERATE_POWER implemented in Player::Regenerate(Powers power) - &AuraEffect::HandleNULL, //296 2 spells - &AuraEffect::HandleNULL, //297 1 spell (counter spell school?) - &AuraEffect::HandleNULL, //298 unused + &AuraEffect::HandleNULL, //295 0 spells in 3.3.5 + &AuraEffect::HandleNULL, //296 6 spells, something vehicle or character display related + &AuraEffect::HandleNULL, //297 Spirit Burst spells + &AuraEffect::HandleNULL, //298 70569 - Strangulating, maybe prevents talk or cast &AuraEffect::HandleNULL, //299 unused - &AuraEffect::HandleNULL, //300 3 spells (share damage?) - &AuraEffect::HandleNULL, //301 5 spells - &AuraEffect::HandleNULL, //302 unused - &AuraEffect::HandleNULL, //303 17 spells - &AuraEffect::HandleNULL, //304 2 spells (alcohol effect?) + &AuraEffect::HandleNoImmediateEffect, //300 SPELL_AURA_SHARE_DAMAGE_PCT implemented in Unit::DealDamage + &AuraEffect::HandleNoImmediateEffect, //301 SPELL_AURA_SCHOOL_HEAL_ABSORB implemented in Unit::CalcHealAbsorb + &AuraEffect::HandleNULL, //302 0 spells in 3.3.5 + &AuraEffect::HandleNULL, //303 SPELL_AURA_MOD_DMG_VERSUS_AURASTATE_PCT? - 22 and 19 look like serverside aurastates (22 - dark, gas cloud, 19 light, ooze) + &AuraEffect::HandleUnused, //304 clientside &AuraEffect::HandleAuraModIncreaseSpeed, //305 SPELL_AURA_MOD_MINIMUM_SPEED - &AuraEffect::HandleNULL, //306 1 spell - &AuraEffect::HandleNULL, //307 absorb healing? + &AuraEffect::HandleNULL, //306 0 spells in 3.3.5 + &AuraEffect::HandleNULL, //307 0 spells in 3.3.5 &AuraEffect::HandleNULL, //308 new aura for hunter traps - &AuraEffect::HandleNULL, //309 absorb healing? - &AuraEffect::HandleNoImmediateEffect, //310 5 spells SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS implemented in Unit::MeleeDamageBonus - &AuraEffect::HandleNULL, //311 0 spells in 3.3 - &AuraEffect::HandleNULL, //312 0 spells in 3.3 - &AuraEffect::HandleNULL, //313 0 spells in 3.3 - &AuraEffect::HandleNULL, //314 1 test spell (reduce duration of silince/magic) - &AuraEffect::HandleNULL, //315 underwater walking + &AuraEffect::HandleNULL, //309 0 spells in 3.3.5 + &AuraEffect::HandleNoImmediateEffect, //310 SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE implemented in Spell::CalculateDamageDone + &AuraEffect::HandleNULL, //311 0 spells in 3.3.5 + &AuraEffect::HandleNULL, //312 0 spells in 3.3.5 + &AuraEffect::HandleNULL, //313 0 spells in 3.3.5 + &AuraEffect::HandleNoImmediateEffect, //314 SPELL_AURA_PREVENT_RESSURECTION todo + &AuraEffect::HandleNoImmediateEffect, //315 SPELL_AURA_UNDERWATER_WALKING todo &AuraEffect::HandleNoImmediateEffect, //316 SPELL_AURA_PERIODIC_HASTE implemented in AuraEffect::CalculatePeriodic - &AuraEffect::HandleNULL }; AuraEffect::AuraEffect(Aura * base, uint8 effIndex, int32 *baseAmount, Unit * caster) : m_base(base), m_spellProto(base->GetSpellProto()), m_spellmod(NULL), m_periodicTimer(0), m_tickNumber(0), m_effIndex(effIndex), m_isPeriodic(false), m_canBeRecalculated(true), - m_baseAmount (baseAmount ? *baseAmount : m_spellProto->EffectBasePoints[m_effIndex] + 1) + m_baseAmount (baseAmount ? *baseAmount : m_spellProto->EffectBasePoints[m_effIndex]) { CalculatePeriodic(caster, true); @@ -387,8 +387,7 @@ AuraEffect::AuraEffect(Aura * base, uint8 effIndex, int32 *baseAmount, Unit * ca AuraEffect::~AuraEffect() { - if (m_spellmod) - delete m_spellmod; + delete m_spellmod; } void AuraEffect::GetTargetList(std::list<Unit *> & targetList) const @@ -406,10 +405,7 @@ int32 AuraEffect::CalculateAmount(Unit * caster) { int32 amount; // default amount calculation - if (caster) - amount = caster->CalculateSpellDamage(NULL, m_spellProto, m_effIndex, &m_baseAmount); - else - amount = m_baseAmount + 1; + amount = SpellMgr::CalculateSpellEffectAmount(m_spellProto, m_effIndex, caster, &m_baseAmount, NULL); // check item enchant aura cast if (!amount && caster) @@ -483,16 +479,32 @@ int32 AuraEffect::CalculateAmount(Unit * caster) // Ice Barrier if (GetSpellProto()->SpellFamilyFlags[1] & 0x1 && GetSpellProto()->SpellFamilyFlags[2] & 0x8) { - // +80.67% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8067f; + // +80.68% from sp bonus + DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f; + // Glyph of Ice Barrier: its weird having a SPELLMOD_ALL_EFFECTS here but its blizzards doing :) + // Glyph of Ice Barrier is only applied at the spell damage bonus because it was already applied to the base value in CalculateSpellDamage + if (Player* modOwner = caster->GetSpellModOwner()) + modOwner->ApplySpellMod(GetSpellProto()->Id, SPELLMOD_ALL_EFFECTS, DoneActualBenefit); + } + // Fire Ward + else if(GetSpellProto()->SpellFamilyFlags[0] & 0x8 && GetSpellProto()->SpellFamilyFlags[2] & 0x8) + { + // +80.68% from sp bonus + DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f; + } + // Frost Ward + else if(GetSpellProto()->SpellFamilyFlags[0] & 0x100 && GetSpellProto()->SpellFamilyFlags[2] & 0x8) + { + // +80.68% from sp bonus + DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f; } break; case SPELLFAMILY_WARLOCK: // Shadow Ward - if (m_spellProto->SpellFamilyFlags[2]& 0x40) + if (m_spellProto->SpellFamilyFlags[2] & 0x40) { - // +30% from sp bonus - DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.3f; + // +80.68% from sp bonus + DoneActualBenefit += caster->SpellBaseDamageBonus(GetSpellSchoolMask(m_spellProto)) * 0.8068f; } break; case SPELLFAMILY_PRIEST: @@ -607,7 +619,7 @@ int32 AuraEffect::CalculateAmount(Unit * caster) if (spellmgr.GetSpellRank(m_spellProto->Id) >= 9) { if (GetBase()->GetUnitOwner()->HasAuraState(AURA_STATE_HEALTH_ABOVE_75_PERCENT, m_spellProto, caster)) - amount += int32(amount * m_spellProto->CalculateSimpleValue(2) / 100.0f); + amount += int32(amount * SpellMgr::CalculateSpellEffectAmount(m_spellProto, 2, caster) / 100.0f); } } break; @@ -718,7 +730,7 @@ void AuraEffect::CalculatePeriodic(Unit * caster, bool create) case SPELL_AURA_OBS_MOD_POWER: // 3 spells have no amplitude set if (!m_amplitude) - m_amplitude = 1 * IN_MILISECONDS; + m_amplitude = 1 * IN_MILLISECONDS; case SPELL_AURA_PERIODIC_DAMAGE: case SPELL_AURA_PERIODIC_HEAL: case SPELL_AURA_PERIODIC_ENERGIZE: @@ -747,7 +759,7 @@ void AuraEffect::CalculatePeriodic(Unit * caster, bool create) { m_isPeriodic = true; m_amplitude = irand (0, 60) + 30; - m_amplitude *= IN_MILISECONDS; + m_amplitude *= IN_MILLISECONDS; } break; } @@ -768,7 +780,8 @@ void AuraEffect::CalculatePeriodic(Unit * caster, bool create) modOwner->ModSpellCastTime(m_spellProto, m_amplitude); } // For spells that can benefit from haste - else if (modOwner->HasAuraType(SPELL_AURA_PERIODIC_HASTE)) { + else if (modOwner->HasAuraType(SPELL_AURA_PERIODIC_HASTE)) + { const Unit::AuraEffectList &effList = modOwner->GetAuraEffectsByType(SPELL_AURA_PERIODIC_HASTE); for (Unit::AuraEffectList::const_iterator itr = effList.begin(), end = effList.end(); itr != end; ++itr) { @@ -1032,7 +1045,7 @@ void AuraEffect::UpdatePeriodic(Unit * caster) if (GetId() == 7057) { m_amplitude = irand (0 , 60) + 30; - m_amplitude *= IN_MILISECONDS; + m_amplitude *= IN_MILLISECONDS; } break; case SPELL_AURA_PERIODIC_TRIGGER_SPELL: @@ -1296,10 +1309,7 @@ void AuraEffect::PeriodicTick(Unit * target, Unit * caster) const bool crit = IsPeriodicTickCrit(target, caster); if (crit) - { damage = caster->SpellCriticalDamageBonus(m_spellProto, damage, target); - damage -= target->GetSpellCritDamageReduction(damage); - } // Reduce damage from resilience for players and pets only. // As of patch 3.3 pets inherit 100% of master resilience. @@ -1308,7 +1318,7 @@ void AuraEffect::PeriodicTick(Unit * target, Unit * caster) const { if (crit) damage -= modOwner->GetSpellCritDamageReduction(damage); - damage -= modOwner->GetSpellDamageReduction(damage); + damage -= modOwner->GetSpellDamageReduction(damage); } caster->CalcAbsorbResist(target, GetSpellSchoolMask(GetSpellProto()), DOT, damage, &absorb, &resist, m_spellProto); @@ -1367,10 +1377,7 @@ void AuraEffect::PeriodicTick(Unit * target, Unit * caster) const bool crit = IsPeriodicTickCrit(target, caster); if (crit) - { damage = caster->SpellCriticalDamageBonus(m_spellProto, damage, target); - damage -= target->GetSpellCritDamageReduction(damage); - } //Calculate armor mitigation if it is a physical spell if (GetSpellSchoolMask(GetSpellProto()) & SPELL_SCHOOL_MASK_NORMAL) @@ -1470,7 +1477,37 @@ void AuraEffect::PeriodicTick(Unit * target, Unit * caster) const int32 damage = m_amount > 0 ? m_amount : 0; if (GetAuraType() == SPELL_AURA_OBS_MOD_HEALTH) + { + // Taken mods + float TakenTotalMod = 1.0f; + + // Tenacity increase healing % taken + if (AuraEffect const* Tenacity = target->GetAuraEffect(58549, 0)) + TakenTotalMod *= (Tenacity->GetAmount() + 100.0f) / 100.0f; + + // Healing taken percent + float minval = target->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + if (minval) + TakenTotalMod *= (100.0f + minval) / 100.0f; + + float maxval = target->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HEALING_PCT); + if (maxval) + TakenTotalMod *= (100.0f + maxval) / 100.0f; + + // Healing over time taken percent + float minval_hot = target->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_HOT_PCT); + if (minval_hot) + TakenTotalMod *= (100.0f + minval_hot) / 100.0f; + + float maxval_hot = target->GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HOT_PCT); + if (maxval_hot) + TakenTotalMod *= (100.0f + maxval_hot) / 100.0f; + + TakenTotalMod = TakenTotalMod > 0.0f ? TakenTotalMod : 0.0f; + damage = uint32(target->GetMaxHealth() * damage / 100); + damage = uint32(damage * TakenTotalMod); + } else { // Wild Growth = amount + (6 - 2*doneTicks) * ticks* amount / 100 @@ -1811,13 +1848,6 @@ void AuraEffect::PeriodicDummyTick(Unit * target, Unit * caster) const else target->RemoveAurasDueToSpell(58670); break; - case 58600: // No fly Zone - Dalaran - if (GetTickNumber() == 10) - { - target->RemoveAurasByType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED); - target->RemoveAurasByType(SPELL_AURA_FLY); - } - break; case 62292: // Blaze (Pool of Tar) // should we use custom damage? target->CastSpell((Unit*)NULL, m_spellProto->EffectTriggerSpell[m_effIndex], true); @@ -2473,14 +2503,14 @@ void AuraEffect::HandleShapeshiftBoosts(Unit * target, bool apply) const } // Heart of the Wild if (HotWSpellId) - { + { // hacky, but the only way as spell family is not SPELLFAMILY_DRUID Unit::AuraEffectList const& mModTotalStatPct = target->GetAuraEffectsByType(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE); for (Unit::AuraEffectList::const_iterator i = mModTotalStatPct.begin(); i != mModTotalStatPct.end(); ++i) { // Heart of the Wild if ((*i)->GetSpellProto()->SpellIconID == 240 && (*i)->GetMiscValue() == 3) { - int32 HotWMod = (*i)->GetSpellProto()->EffectBasePoints[1] + 1; + int32 HotWMod = (*i)->GetAmount(); target->CastCustomSpell(target, HotWSpellId, &HotWMod, NULL, NULL, true, NULL, this); break; @@ -2490,11 +2520,11 @@ void AuraEffect::HandleShapeshiftBoosts(Unit * target, bool apply) const switch(GetMiscValue()) { case FORM_CAT: - // Savage Roar + // Savage Roar if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_DRUID, 0 , 0x10000000, 0)) target->CastSpell(target, 62071, true); // Nurturing Instinct - if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT, SPELLFAMILY_DRUID, 2254,0)) + if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_MOD_SPELL_HEALING_OF_STAT_PERCENT, SPELLFAMILY_DRUID, 2254, 0)) { uint32 spellId = 0; switch (aurEff->GetId()) @@ -2524,9 +2554,9 @@ void AuraEffect::HandleShapeshiftBoosts(Unit * target, bool apply) const target->CastCustomSpell(target, 48418, &bp, NULL, NULL, true); } // Survival of the Fittest - if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE,SPELLFAMILY_DRUID, 961, 0)) + if (AuraEffect const * aurEff = target->GetAuraEffect(SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE, SPELLFAMILY_DRUID, 961, 0)) { - int32 bp = 100 + aurEff->GetSpellProto()->CalculateSimpleValue(2); + int32 bp = 100 + SpellMgr::CalculateSpellEffectAmount(aurEff->GetSpellProto(), 2); target->CastCustomSpell(target, 62069, &bp, NULL, NULL, true, 0, this); } break; @@ -3093,7 +3123,7 @@ void AuraEffect::HandleAuraTransform(AuraApplication const * aurApp, uint8 mode, // for players, start regeneration after 1s (in polymorph fast regeneration case) // only if caster is Player (after patch 2.4.2) if (IS_PLAYER_GUID(GetCasterGUID())) - target->ToPlayer()->setRegenTimerCount(1*IN_MILISECONDS); + target->ToPlayer()->setRegenTimerCount(1*IN_MILLISECONDS); //dismount polymorphed target (after patch 2.4.2) if (target->IsMounted()) diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.h b/src/server/game/Spells/Auras/SpellAuraEffects.h index c2c99b167e0..d44e73f360f 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.h +++ b/src/server/game/Spells/Auras/SpellAuraEffects.h @@ -45,6 +45,9 @@ class AuraEffect int32 GetAmount() const { return m_amount; } void SetAmount(int32 amount) { m_amount = amount; m_canBeRecalculated = false;} + int32 GetPeriodicTimer() const { return m_periodicTimer; } + void SetPeriodicTimer(int32 periodicTimer) { m_periodicTimer = periodicTimer; } + int32 CalculateAmount(Unit * caster); void CalculatePeriodic(Unit * caster, bool create = false); void CalculateSpellMod(); diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 1b75ab75473..3ebfa44492c 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -77,14 +77,15 @@ AuraApplication::AuraApplication(Unit * target, Unit * caster, Aura * aura, uint else sLog.outDebug("Aura: %u Effect: %d could not find empty unit visible slot", GetBase()->GetId(), GetEffectMask()); } - m_flags |= (_CheckPositive(caster) ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | - (GetBase()->GetCasterGUID() == GetTarget()->GetGUID() ? AFLAG_CASTER : AFLAG_NONE); m_isNeedManyNegativeEffects = false; if (GetBase()->GetCasterGUID() == GetTarget()->GetGUID()) // caster == target - 1 negative effect is enough for aura to be negative m_isNeedManyNegativeEffects = false; else if (caster) m_isNeedManyNegativeEffects = caster->IsFriendlyTo(m_target); + + m_flags |= (_CheckPositive(caster) ? AFLAG_POSITIVE : AFLAG_NEGATIVE) | + (GetBase()->GetCasterGUID() == GetTarget()->GetGUID() ? AFLAG_CASTER : AFLAG_NONE); } void AuraApplication::_Remove() @@ -305,7 +306,7 @@ m_spellProto(spellproto), m_owner(owner), m_casterGuid(casterGUID ? casterGUID : m_procCharges(0), m_stackAmount(1), m_isRemoved(false), m_casterLevel(caster ? caster->getLevel() : m_spellProto->spellLevel) { if (m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel) - m_timeCla = 1 * IN_MILISECONDS; + m_timeCla = 1 * IN_MILLISECONDS; Player* modOwner = NULL; @@ -342,8 +343,7 @@ Aura::~Aura() { // free effects memory for (uint8 i = 0 ; i < MAX_SPELL_EFFECTS; ++i) - if (m_effects[i]) - delete m_effects[i]; + delete m_effects[i]; assert(m_applications.empty()); _DeleteRemovedApplications(); @@ -391,9 +391,17 @@ void Aura::_UnapplyForTarget(Unit * target, Unit * caster, AuraApplication * aur assert(auraApp); ApplicationMap::iterator itr = m_applications.find(target->GetGUID()); + // TODO: Figure out why this happens. + if (itr == m_applications.end()) + { + sLog.outError("Aura::_UnapplyForTarget, target:%u, caster:%u, spell:%u was not found in owners application map!", + target->GetGUIDLow(), caster->GetGUIDLow(), auraApp->GetBase()->GetSpellProto()->Id); + } + else + m_applications.erase(itr); + // aura has to be already applied - assert(itr->second == auraApp); - m_applications.erase(itr); + //assert(itr->second == auraApp); m_removedApplications.push_back(auraApp); // reset cooldown state for spells @@ -412,7 +420,7 @@ void Aura::_Remove(AuraRemoveMode removeMode) assert (!m_isRemoved); m_isRemoved = true; ApplicationMap::iterator appItr = m_applications.begin(); - while (!m_applications.empty()) + for (appItr = m_applications.begin(); appItr != m_applications.end();) { AuraApplication * aurApp = appItr->second; Unit * target = aurApp->GetTarget(); @@ -459,8 +467,10 @@ void Aura::UpdateTargetMap(Unit * caster, bool apply) for (std::map<Unit *, uint8>::iterator itr = targets.begin(); itr!= targets.end();) { bool addUnit = true; - // check target immunities - if (itr->first->IsImmunedToSpell(GetSpellProto())) + // check target immunities + if (itr->first->IsImmunedToSpell(GetSpellProto()) + // check area target requirements + || (itr->first != GetOwner() && !CheckAreaTarget(itr->first))) addUnit = false; if (addUnit) @@ -532,7 +542,7 @@ void Aura::_ApplyEffectForTargets(uint8 effIndex) UnitList targetList; for (ApplicationMap::iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter) { - if ((appIter->second->GetEffectsToApply() & (1<<effIndex)) && CheckTarget(appIter->second->GetTarget()) && !appIter->second->HasEffect(effIndex)) + if ((appIter->second->GetEffectsToApply() & (1<<effIndex)) && !appIter->second->HasEffect(effIndex)) targetList.push_back(appIter->second->GetTarget()); } @@ -632,45 +642,6 @@ void Aura::Update(uint32 diff, Unit * caster) } } -bool Aura::CheckTarget(Unit *target) -{ - // some special cases - switch(GetId()) - { - case 45828: // AV Marshal's HP/DMG auras - case 45829: - case 45830: - case 45821: - case 45822: // AV Warmaster's HP/DMG auras - case 45823: - case 45824: - case 45826: - switch(target->GetEntry()) - { - // alliance - case 14762: // Dun Baldar North Marshal - case 14763: // Dun Baldar South Marshal - case 14764: // Icewing Marshal - case 14765: // Stonehearth Marshal - case 11948: // Vandar Stormspike - // horde - case 14772: // East Frostwolf Warmaster - case 14776: // Tower Point Warmaster - case 14773: // Iceblood Warmaster - case 14777: // West Frostwolf Warmaster - case 11946: // Drek'thar - return true; - default: - return false; - break; - } - break; - default: - return true; - break; - } -} - void Aura::SetDuration(int32 duration, bool withMods) { if (withMods) @@ -691,7 +662,7 @@ void Aura::RefreshDuration() m_effects[i]->ResetPeriodic(); if (m_spellProto->manaPerSecond || m_spellProto->manaPerSecondPerLevel) - m_timeCla = 1 * IN_MILISECONDS; + m_timeCla = 1 * IN_MILLISECONDS; } void Aura::SetCharges(uint8 charges) @@ -781,33 +752,6 @@ bool Aura::CanBeSaved() const return true; } -bool Aura::HasEffectType(AuraType type) const -{ - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (m_effects[i] && m_effects[i]->GetAuraType() == type) - return true; - } - return false; -} - -void Aura::RecalculateAmountOfEffects() -{ - assert (!IsRemoved()); - Unit * caster = GetCaster(); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_effects[i]) - m_effects[i]->RecalculateAmount(caster); -} - -void Aura::HandleAllEffects(AuraApplication const * aurApp, uint8 mode, bool apply) -{ - assert (!IsRemoved()); - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_effects[i] && !IsRemoved()) - m_effects[i]->HandleEffect(aurApp, mode, apply); -} - bool Aura::IsVisible() const { // Is this blizzlike? show totem passive auras @@ -842,6 +786,39 @@ void Aura::SetLoadedState(int32 maxduration, int32 duration, int32 charges, uint } } +bool Aura::HasEffectType(AuraType type) const +{ + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + { + if (m_effects[i] && m_effects[i]->GetAuraType() == type) + return true; + } + return false; +} + +void Aura::RecalculateAmountOfEffects() +{ + assert (!IsRemoved()); + Unit * caster = GetCaster(); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (m_effects[i]) + m_effects[i]->RecalculateAmount(caster); +} + +void Aura::HandleAllEffects(AuraApplication const * aurApp, uint8 mode, bool apply) +{ + assert (!IsRemoved()); + for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) + if (m_effects[i] && !IsRemoved()) + m_effects[i]->HandleEffect(aurApp, mode, apply); +} + +void Aura::SetNeedClientUpdateForTargets() const +{ + for (ApplicationMap::const_iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter) + appIter->second->SetNeedClientUpdate(); +} + // trigger effects on real aura apply/remove void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, bool apply) { @@ -895,6 +872,10 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, if (GetStackAmount() >= 5 && !target->HasAura(33652)) target->CastSpell(target, 33652, true); break; + case 50836: //Petrifying Grip, becomes stoned + if (GetStackAmount() >= 5 && !target->HasAura(50812)) + target->CastSpell(target, 50812, true); + break; case 60970: // Heroic Fury (remove Intercept cooldown) if (target->GetTypeId() == TYPEID_PLAYER) target->ToPlayer()->RemoveSpellCooldown(20252, true); @@ -936,20 +917,17 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, // Arcane Potency if (AuraEffect const * aurEff = caster->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_MAGE, 2120, 0)) { - if (roll_chance_i(aurEff->GetAmount())) - { - uint32 spellId = 0; + uint32 spellId = 0; - switch (aurEff->GetId()) - { - case 31571: spellId = 57529; break; - case 31572: spellId = 57531; break; - default: - sLog.outError("Aura::HandleAuraSpecificMods: Unknown rank of Arcane Potency (%d) found", aurEff->GetId()); - } - if (spellId) - caster->CastSpell(caster, spellId, true); + switch (aurEff->GetId()) + { + case 31571: spellId = 57529; break; + case 31572: spellId = 57531; break; + default: + sLog.outError("Aura::HandleAuraSpecificMods: Unknown rank of Arcane Potency (%d) found", aurEff->GetId()); } + if (spellId) + caster->CastSpell(caster, spellId, true); } break; } @@ -1278,7 +1256,7 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, data << uint64(player->GetGUID()); data << uint8(0x0); // flags (0x1, 0x2) data << uint32(GetSpellProto()->Id); - data << uint32(aurEff->GetAmount()*IN_MILISECONDS); + data << uint32(aurEff->GetAmount()*IN_MILLISECONDS); player->SendDirectMessage(&data); } break; @@ -1514,10 +1492,44 @@ void Aura::HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, } } -void Aura::SetNeedClientUpdateForTargets() const +bool Aura::CheckAreaTarget(Unit *target) { - for (ApplicationMap::const_iterator appIter = m_applications.begin(); appIter != m_applications.end(); ++appIter) - appIter->second->SetNeedClientUpdate(); + // for owner check use Spell::CheckTarget + assert(GetOwner() != target); + + // some special cases + switch(GetId()) + { + case 45828: // AV Marshal's HP/DMG auras + case 45829: + case 45830: + case 45821: + case 45822: // AV Warmaster's HP/DMG auras + case 45823: + case 45824: + case 45826: + switch(target->GetEntry()) + { + // alliance + case 14762: // Dun Baldar North Marshal + case 14763: // Dun Baldar South Marshal + case 14764: // Icewing Marshal + case 14765: // Stonehearth Marshal + case 11948: // Vandar Stormspike + // horde + case 14772: // East Frostwolf Warmaster + case 14776: // Tower Point Warmaster + case 14773: // Iceblood Warmaster + case 14777: // West Frostwolf Warmaster + case 11946: // Drek'thar + return true; + default: + return false; + break; + } + break; + } + return true; } void Aura::_DeleteRemovedApplications() diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index be76b520bd9..97c0076fcd5 100644 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -163,7 +163,7 @@ class Aura void SetNeedClientUpdateForTargets() const; void HandleAuraSpecificMods(AuraApplication const * aurApp, Unit * caster, bool apply); - bool CheckTarget(Unit *target); + bool CheckAreaTarget(Unit *target); private: void _DeleteRemovedApplications(); protected: diff --git a/src/server/game/Spells/Auras/SpellEffects.cpp b/src/server/game/Spells/Auras/SpellEffects.cpp index 2f7486d53d9..0b2191d5e48 100644 --- a/src/server/game/Spells/Auras/SpellEffects.cpp +++ b/src/server/game/Spells/Auras/SpellEffects.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "Opcodes.h" #include "Log.h" @@ -107,11 +107,11 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectUnused, // 39 SPELL_EFFECT_LANGUAGE &Spell::EffectDualWield, // 40 SPELL_EFFECT_DUAL_WIELD &Spell::EffectJump, // 41 SPELL_EFFECT_JUMP - &Spell::EffectJump, // 42 SPELL_EFFECT_JUMP2 + &Spell::EffectJumpDest, // 42 SPELL_EFFECT_JUMP_DEST &Spell::EffectTeleUnitsFaceCaster, // 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER &Spell::EffectLearnSkill, // 44 SPELL_EFFECT_SKILL_STEP &Spell::EffectAddHonor, // 45 SPELL_EFFECT_ADD_HONOR honor/pvp related - &Spell::EffectNULL, // 46 SPELL_EFFECT_SPAWN we must spawn pet there + &Spell::EffectUnused, // 46 SPELL_EFFECT_SPAWN clientside, unit appears as if it was just spawned &Spell::EffectTradeSkill, // 47 SPELL_EFFECT_TRADE_SKILL &Spell::EffectUnused, // 48 SPELL_EFFECT_STEALTH one spell: Base Stealth &Spell::EffectUnused, // 49 SPELL_EFFECT_DETECT one spell: Detect @@ -154,7 +154,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT &Spell::EffectWMODamage, // 87 SPELL_EFFECT_WMO_DAMAGE &Spell::EffectWMORepair, // 88 SPELL_EFFECT_WMO_REPAIR - &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE + &Spell::EffectUnused, // 89 SPELL_EFFECT_WMO_CHANGE // 0 intact // 1 damaged // 2 destroyed // 3 rebuilding &Spell::EffectKillCreditPersonal, // 90 SPELL_EFFECT_KILL_CREDIT Kill credit but only for single person &Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash &Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM @@ -203,10 +203,10 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectNULL, //135 SPELL_EFFECT_CALL_PET &Spell::EffectHealPct, //136 SPELL_EFFECT_HEAL_PCT &Spell::EffectEnergizePct, //137 SPELL_EFFECT_ENERGIZE_PCT - &Spell::EffectJump2, //138 SPELL_EFFECT_LEAP_BACK Leap back - &Spell::EffectUnused, //139 SPELL_EFFECT_CLEAR_QUEST (misc - is quest ID) + &Spell::EffectLeapBack, //138 SPELL_EFFECT_LEAP_BACK Leap back + &Spell::EffectQuestClear, //139 SPELL_EFFECT_CLEAR_QUEST Reset quest status (miscValue - quest ID) &Spell::EffectForceCast, //140 SPELL_EFFECT_FORCE_CAST - &Spell::EffectNULL, //141 SPELL_EFFECT_141 damage and reduce speed? + &Spell::EffectForceCastWithValue, //141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE &Spell::EffectTriggerSpellWithValue, //142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE &Spell::EffectApplyAreaAura, //143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER &Spell::EffectKnockBack, //144 SPELL_EFFECT_KNOCK_BACK_2 Spectral Blast @@ -214,7 +214,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]= &Spell::EffectActivateRune, //146 SPELL_EFFECT_ACTIVATE_RUNE &Spell::EffectQuestFail, //147 SPELL_EFFECT_QUEST_FAIL quest fail &Spell::EffectUnused, //148 SPELL_EFFECT_148 unused - &Spell::EffectCharge2, //149 SPELL_EFFECT_CHARGE2 swoop + &Spell::EffectChargeDest, //149 SPELL_EFFECT_CHARGE_DEST &Spell::EffectUnused, //150 SPELL_EFFECT_150 unused &Spell::EffectTriggerRitualOfSummoning, //151 SPELL_EFFECT_TRIGGER_SPELL_2 &Spell::EffectNULL, //152 SPELL_EFFECT_152 summon Refer-a-Friend @@ -303,7 +303,7 @@ void Spell::EffectEnvirinmentalDMG(uint32 i) // Note: this hack with damage replace required until GO casting not implemented // environment damage spells already have around enemies targeting but this not help in case not existed GO casting support // currently each enemy selected explicitly and self cast damage, we prevent apply self casted spell bonuses/etc - damage = m_spellInfo->CalculateSimpleValue(i); + damage = SpellMgr::CalculateSpellEffectAmount(m_spellInfo, i, m_caster); m_caster->CalcAbsorbResist(m_caster, GetSpellSchoolMask(m_spellInfo), SPELL_DIRECT_DAMAGE, damage, &absorb, &resist, m_spellInfo); @@ -391,8 +391,9 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) return; break; } - // gruul's shatter - case 33671: + case 33671: // gruul's shatter + case 50811: // krystallus shatter ( Normal ) + case 61547: // krystallus shatter ( Heroic ) { // don't damage self and only players if (unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -430,6 +431,22 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) damage = (m_caster->getLevel() - 60) * 4 + 60; break; } + + // Loken Pulsing Shockwave + case 59837: + case 52942: + { + // don't damage self and only players + if(unitTarget->GetGUID() == m_caster->GetGUID() || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + float radius = GetSpellRadiusForHostile(sSpellRadiusStore.LookupEntry(m_spellInfo->EffectRadiusIndex[0])); + if (!radius) + return; + float distance = m_caster->GetDistance2d(unitTarget); + damage = (distance > radius) ? 0 : int32(m_spellInfo->EffectBasePoints[0]*distance); + break; + } } break; } @@ -504,7 +521,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) damage += pdamage * aura->GetTotalTicks() * pct_dir / 100; uint32 pct_dot = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, (effect_idx + 2)) / 3; - m_currentBasePoints[1] = pdamage * aura->GetTotalTicks() * pct_dot / 100; + m_currentBasePoints[1] = SpellMgr::CalculateSpellEffectBaseAmount(pdamage * aura->GetTotalTicks() * pct_dot / 100); apply_direct_bonus = false; // Glyph of Conflagrate @@ -566,7 +583,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) if ((*i)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_PRIEST && ((*i)->GetSpellProto()->SpellIconID == 95)) { - int chance = (*i)->GetSpellProto()->CalculateSimpleValue(1); + int chance = SpellMgr::CalculateSpellEffectAmount((*i)->GetSpellProto(), 1, m_caster); if (roll_chance_i(chance)) // Mind Trauma m_caster->CastSpell(unitTarget, 48301, true, 0); @@ -621,7 +638,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) { if ((*iter)->GetSpellProto()->SpellFamilyName == SPELLFAMILY_ROGUE && (*iter)->GetSpellProto()->SpellIconID == 1960) { - uint32 chance = (*iter)->GetSpellProto()->CalculateSimpleValue(2); + uint32 chance = SpellMgr::CalculateSpellEffectAmount((*iter)->GetSpellProto(), 2, m_caster); if (chance && roll_chance_i(chance)) needConsume = false; @@ -710,7 +727,7 @@ void Spell::SpellDamageSchoolDmg(uint32 effect_idx) // Add main hand dps * effect[2] amount float average = (m_caster->GetFloatValue(UNIT_FIELD_MINDAMAGE) + m_caster->GetFloatValue(UNIT_FIELD_MAXDAMAGE)) / 2; int32 count = m_caster->CalculateSpellDamage(unitTarget, m_spellInfo, 2); - damage += count * int32(average * IN_MILISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); + damage += count * int32(average * IN_MILLISECONDS) / m_caster->GetAttackTime(BASE_ATTACK); } // Shield of Righteousness else if (m_spellInfo->SpellFamilyFlags[1]&0x00100000) @@ -769,33 +786,6 @@ void Spell::EffectDummy(uint32 i) { switch (m_spellInfo->Id) { - // Magic Pull - case 51336: - m_caster->CastSpell(unitTarget,50770,true); - break; - // Wrath of the Astromancer - case 42784: - { - uint32 count = 0; - for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - if (ihit->effectMask & (1<<i)) - ++count; - - damage = 12000; // maybe wrong value - damage /= count; - - SpellEntry const *spellInfo = sSpellStore.LookupEntry(42784); - - // now deal the damage - for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) - if (ihit->effectMask & (1<<i)) - { - if (Unit* casttarget = Unit::GetUnit((*unitTarget), ihit->targetGUID)) - m_caster->DealDamage(casttarget, damage, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, spellInfo, false); - } - - return; - } case 8063: // Deviate Fish { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -939,6 +929,46 @@ void Spell::EffectDummy(uint32 i) } return; } + case 14537: // Six Demon Bag + { + if( !unitTarget || !unitTarget->isAlive()) return; + + uint32 ClearSpellId[6] = + { + 15662, // Fireball + 11538, // Frostball + 21179, // Chain Lightning + 14621, // Polymorph + 25189, // Enveloping Winds + 14642 // Summon Felhund minion + }; + + uint32 effect = 0; + uint32 rand = urand(0, 100); + + if (rand >= 0 && rand < 25) // Fireball (25% chance) + effect = ClearSpellId[0]; + else if (rand >= 25 && rand < 50) // Frostball (25% chance) + effect = ClearSpellId[1]; + else if (rand >=50 && rand < 70) // Chain Lighting (25% chance) + effect = ClearSpellId[2]; + else if (rand >= 70 && rand < 80) // Polymorph (10% chance) + { + effect = ClearSpellId[3]; + if (urand(0, 100) <= 30) // 30% chance to self-cast + unitTarget = m_caster; + } + else if (rand >=80 && rand < 95) // Enveloping Winds (15% chance) + effect = ClearSpellId[4]; + else // Summon Felhund minion (5% chance) + { + effect = ClearSpellId[5]; + unitTarget = m_caster; + } + + m_caster->CastSpell(unitTarget, effect, true); + return; + } case 15998: // Capture Worg Pup case 29435: // Capture Female Kaliri Hatchling { @@ -1146,6 +1176,20 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(m_caster, spell_id, true, NULL); return; } + case 34665: //Administer Antidote + { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT + || unitTarget->GetEntry() != 16880 || unitTarget->ToCreature()->isPet()) + return; + + unitTarget->ToCreature()->UpdateEntry(16992); + m_caster->ToPlayer()->RewardPlayerAndGroupAtEvent(16992, unitTarget); + + if (unitTarget->IsAIEnabled) + unitTarget->ToCreature()->AI()->AttackStart(m_caster); + + return; + } case 35745: // Socrethar's Stone { uint32 spell_id; @@ -1206,6 +1250,29 @@ void Spell::EffectDummy(uint32 i) DoCreateItem(i, newitemid); return; } + // Wrath of the Astromancer + case 42784: + { + uint32 count = 0; + for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + if (ihit->effectMask & (1<<i)) + ++count; + + damage = 12000; // maybe wrong value + damage /= count; + + SpellEntry const *spellInfo = sSpellStore.LookupEntry(42784); + + // now deal the damage + for (std::list<TargetInfo>::iterator ihit= m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit) + if (ihit->effectMask & (1<<i)) + { + if (Unit* casttarget = Unit::GetUnit((*unitTarget), ihit->targetGUID)) + m_caster->DealDamage(casttarget, damage, NULL, SPELL_DIRECT_DAMAGE, SPELL_SCHOOL_MASK_ARCANE, spellInfo, false); + } + + return; + } // Demon Broiled Surprise case 43723: { @@ -1238,20 +1305,6 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(m_caster, 42337, true, NULL); return; } - case 34665: //Administer Antidote - { - if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT - || unitTarget->GetEntry() != 16880 || unitTarget->ToCreature()->isPet()) - return; - - unitTarget->ToCreature()->UpdateEntry(16992); - m_caster->ToPlayer()->RewardPlayerAndGroupAtEvent(16992, unitTarget); - - if (unitTarget->IsAIEnabled) - unitTarget->ToCreature()->AI()->AttackStart(m_caster); - - return; - } case 44997: // Converting Sentry { //Converted Sentry Credit @@ -1310,6 +1363,10 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(m_caster, 49378, true); } return; + // Magic Pull + case 51336: + m_caster->CastSpell(unitTarget,50770,true); + break; case 52845: // Brewfest Mount Transformation (Faction Swap) if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -1391,8 +1448,8 @@ void Spell::EffectDummy(uint32 i) { case 0: { - uint32 spellID = m_spellInfo->CalculateSimpleValue(0); - uint32 reqAuraID = m_spellInfo->CalculateSimpleValue(1); + uint32 spellID = SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 0); + uint32 reqAuraID = SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 1); if (m_caster->HasAuraEffect(reqAuraID,0)) m_caster->CastSpell(m_caster,spellID,true,NULL); @@ -1415,6 +1472,11 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(m_caster, 54586, true); return; } + case 54171: //Divine Storm + { + m_caster->CastCustomSpell(unitTarget, 54172, &damage, 0, 0, true); + return; + } case 58418: // Portal to Orgrimmar case 58420: // Portal to Stormwind return; // implemented in EffectScript[0] @@ -1721,41 +1783,14 @@ void Spell::EffectDummy(uint32 i) m_caster->CastSpell(m_caster, 63848, true); break; } - switch(m_spellInfo->Id) + switch (m_spellInfo->Id) { case 5938: // Shiv { if (m_caster->GetTypeId() != TYPEID_PLAYER) return; - Player *pCaster = m_caster->ToPlayer(); - - Item *item = pCaster->GetWeaponForAttack(OFF_ATTACK); - if (!item) - return; - - // all poison enchantments is temporary - uint32 enchant_id = item->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT); - if (!enchant_id) - return; - - SpellItemEnchantmentEntry const *pEnchant = sSpellItemEnchantmentStore.LookupEntry(enchant_id); - if (!pEnchant) - return; - - for (int s=0; s<3; s++) - { - if (pEnchant->type[s] != ITEM_ENCHANTMENT_TYPE_COMBAT_SPELL) - continue; - - SpellEntry const* combatEntry = sSpellStore.LookupEntry(pEnchant->spellid[s]); - if (!combatEntry || combatEntry->Dispel != DISPEL_POISON) - continue; - - m_caster->CastSpell(unitTarget, combatEntry, true, item); - } - - m_caster->CastSpell(unitTarget, 5940, true); + m_caster->CastSpell(unitTarget, 5940, true); return; } case 14185: // Preparation @@ -1850,7 +1885,7 @@ void Spell::EffectDummy(uint32 i) if (Pet *pPet = m_caster->ToPlayer()->GetPet()) if (pPet->isAlive()) - pPet->CastSpell(unitTarget, m_spellInfo->CalculateSimpleValue(i), true); + pPet->CastSpell(unitTarget, SpellMgr::CalculateSpellEffectAmount(m_spellInfo, i), true); return; } } @@ -1900,10 +1935,6 @@ void Spell::EffectDummy(uint32 i) switch(m_spellInfo->Id) { - case 54171: //Divine Storm - { - m_caster->CastCustomSpell(unitTarget, 54172, &damage, 0, 0, true); - } case 20425: // Judgement of command { if (!unitTarget) @@ -2131,7 +2162,7 @@ void Spell::EffectDummy(uint32 i) if (m_targets.HasDst()) targets.setDst(&m_targets.m_dstPos); - spell_id = m_currentBasePoints[0]; + spell_id = CalculateDamage(0, NULL); } // Corpse Explosion else if (m_spellInfo->SpellIconID == 1737) @@ -2150,7 +2181,7 @@ void Spell::EffectDummy(uint32 i) { bp = damage; } - m_caster->CastCustomSpell(unitTarget,m_spellInfo->CalculateSimpleValue(1),&bp,NULL,NULL,true); + m_caster->CastCustomSpell(unitTarget, SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 1), &bp,NULL,NULL,true); // Corpse Explosion (Suicide) unitTarget->CastCustomSpell(unitTarget,43999,&bp,NULL,NULL,true); // Set corpse look @@ -2183,7 +2214,7 @@ void Spell::EffectDummy(uint32 i) targets.setUnitTarget(unitTarget); Spell* spell = new Spell(m_caster, spellInfo, triggered, m_originalCasterGUID, NULL, true); - if (bp) spell->m_currentBasePoints[0] = bp; + if (bp) spell->m_currentBasePoints[0] = SpellMgr::CalculateSpellEffectBaseAmount(bp); spell->prepare(&targets); } @@ -2276,6 +2307,28 @@ void Spell::EffectForceCast(uint32 i) caster->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID); } +void Spell::EffectForceCastWithValue(uint32 i) +{ + if (!unitTarget) + return; + + uint32 triggered_spell_id = m_spellInfo->EffectTriggerSpell[i]; + + // normal case + SpellEntry const *spellInfo = sSpellStore.LookupEntry(triggered_spell_id); + + if (!spellInfo) + { + sLog.outError("EffectForceCastWithValue of spell %u: triggering unknown spell id %i", m_spellInfo->Id,triggered_spell_id); + return; + } + int32 bp = damage; + Unit * caster = GetTriggeredSpellCaster(spellInfo, m_caster, unitTarget); + + caster->CastCustomSpell(unitTarget, spellInfo->Id, &bp, &bp, &bp, true, NULL, NULL, m_originalCasterGUID); +} + + void Spell::EffectTriggerSpell(uint32 effIndex) { // only unit case known @@ -2480,6 +2533,33 @@ void Spell::EffectJump(uint32 i) if (m_caster->isInFlight()) return; + float x,y,z,o; + if (m_targets.getUnitTarget()) + { + m_targets.getUnitTarget()->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE); + o = m_caster->GetOrientation(); + } + else if (m_targets.getGOTarget()) + { + m_targets.getGOTarget()->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE); + o = m_caster->GetOrientation(); + } + else + { + sLog.outError("Spell::EffectJump - unsupported target mode for spell ID %u", m_spellInfo->Id); + return; + } + + float speedXY, speedZ; + CalculateJumpSpeeds(i, m_caster->GetExactDist2d(x, y), speedXY, speedZ); + m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ); +} + +void Spell::EffectJumpDest(uint32 i) +{ + if (m_caster->isInFlight()) + return; + // Init dest coordinates float x,y,z,o; if (m_targets.HasDst()) @@ -2503,32 +2583,26 @@ void Spell::EffectJump(uint32 i) else o = m_caster->GetOrientation(); } - else if (m_targets.getUnitTarget()) - { - m_targets.getUnitTarget()->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE); - o = m_caster->GetOrientation(); - } - else if (m_targets.getGOTarget()) - { - m_targets.getGOTarget()->GetContactPoint(m_caster,x,y,z,CONTACT_DISTANCE); - o = m_caster->GetOrientation(); - } else { - sLog.outError("Spell::EffectJump - unsupported target mode for spell ID %u", m_spellInfo->Id); + sLog.outError("Spell::EffectJumpDest - unsupported target mode for spell ID %u", m_spellInfo->Id); return; } - //m_caster->NearTeleportTo(x,y,z,o,true); - float speedZ; + float speedXY, speedZ; + CalculateJumpSpeeds(i, m_caster->GetExactDist2d(x, y), speedXY, speedZ); + m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ); +} + +void Spell::CalculateJumpSpeeds(uint8 i, float dist, float & speedXY, float & speedZ) +{ if (m_spellInfo->EffectMiscValue[i]) speedZ = float(m_spellInfo->EffectMiscValue[i])/10; else if (m_spellInfo->EffectMiscValueB[i]) speedZ = float(m_spellInfo->EffectMiscValueB[i])/10; else speedZ = 10.0f; - float speedXY = m_caster->GetExactDist2d(x, y) * 10.0f / speedZ; - m_caster->GetMotionMaster()->MoveJump(x, y, z, speedXY, speedZ); + speedXY = dist * 10.0f / speedZ; } void Spell::EffectTeleportUnits(uint32 /*i*/) @@ -2536,6 +2610,27 @@ void Spell::EffectTeleportUnits(uint32 /*i*/) if (!unitTarget || unitTarget->isInFlight()) return; + // Pre effects + uint8 uiMaxSafeLevel = 0; + switch (m_spellInfo->Id) + { + case 48129: // Scroll of Recall + uiMaxSafeLevel = 40; + case 60320: // Scroll of Recall II + if (!uiMaxSafeLevel) + uiMaxSafeLevel = 70; + case 60321: // Scroll of Recal III + if (!uiMaxSafeLevel) + uiMaxSafeLevel = 80; + + if (unitTarget->getLevel() > uiMaxSafeLevel) + { + unitTarget->AddAura(60444,unitTarget); //Apply Lost! Aura + return; + } + break; + } + // If not exist data for dest location - return if (!m_targets.HasDst()) { @@ -2912,6 +3007,10 @@ void Spell::SpellDamageHeal(uint32 /*i*/) else addhealth = caster->SpellHealingBonus(unitTarget, m_spellInfo, addhealth, HEAL); + // Remove Grievious bite if fully healed + if (unitTarget->HasAura(48920) && (unitTarget->GetHealth() + addhealth >= unitTarget->GetMaxHealth())) + unitTarget->RemoveAura(48920); + m_damage -= addhealth; } } @@ -3138,7 +3237,9 @@ void Spell::EffectCreateItem2(uint32 i) // create some random items player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); - } + } + else + player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); // create some random items } } @@ -3706,7 +3807,7 @@ void Spell::EffectSummonType(uint32 i) TempSummonType summonType = (duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_DESPAWN; - TempSummon * summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration); + summon = m_originalCaster->SummonCreature(entry, pos, summonType, duration); if (!summon) continue; if (properties->Category == SUMMON_CATEGORY_ALLY) @@ -3736,7 +3837,7 @@ void Spell::EffectSummonType(uint32 i) if (m_spellInfo->EffectBasePoints[i]) { - SpellEntry const *spellProto = sSpellStore.LookupEntry(m_spellInfo->CalculateSimpleValue(i)); + SpellEntry const *spellProto = sSpellStore.LookupEntry(SpellMgr::CalculateSpellEffectAmount(m_spellInfo, i)); if (spellProto) m_caster->CastSpell(summon, spellProto, true); } @@ -3747,7 +3848,10 @@ void Spell::EffectSummonType(uint32 i) } if (summon) + { summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + summon->SetCreatorGUID(m_originalCaster->GetGUID()); + } } void Spell::EffectLearnSpell(uint32 i) @@ -3829,7 +3933,7 @@ void Spell::EffectDispel(uint32 i) bool success = false; // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance." - if (GetDispelChance(itr->first->GetCaster(), unitTarget, itr->first->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success) > 99) + if (!GetDispelChance(itr->first->GetCaster(), unitTarget, itr->first->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success)) { dispel_list.erase(itr); continue; @@ -3885,7 +3989,7 @@ void Spell::EffectDispel(uint32 i) // Devour Magic if (m_spellInfo->SpellFamilyName == SPELLFAMILY_WARLOCK && m_spellInfo->Category == SPELLCATEGORY_DEVOUR_MAGIC) { - int32 heal_amount = m_spellInfo->CalculateSimpleValue(1); + int32 heal_amount = SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 1); m_caster->CastCustomSpell(m_caster, 19658, &heal_amount, NULL, NULL, true); } } @@ -3926,7 +4030,7 @@ void Spell::EffectDistract(uint32 /*i*/) // Set creature Distracted, Stop it, And turn it unitTarget->SetOrientation(angle); unitTarget->StopMoving(); - unitTarget->GetMotionMaster()->MoveDistract(damage * IN_MILISECONDS); + unitTarget->GetMotionMaster()->MoveDistract(damage * IN_MILLISECONDS); } } @@ -3998,7 +4102,7 @@ void Spell::EffectLearnSkill(uint32 i) uint32 skillid = m_spellInfo->EffectMiscValue[i]; uint16 skillval = unitTarget->ToPlayer()->GetPureSkillValue(skillid); - unitTarget->ToPlayer()->SetSkill(skillid, m_spellInfo->CalculateSimpleValue(i), skillval?skillval:1, damage*75); + unitTarget->ToPlayer()->SetSkill(skillid, SpellMgr::CalculateSpellEffectAmount(m_spellInfo, i), skillval?skillval:1, damage*75); } void Spell::EffectAddHonor(uint32 /*i*/) @@ -4853,7 +4957,7 @@ void Spell::EffectSummonObjectWild(uint32 i) int32 duration = GetSpellDuration(m_spellInfo); - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0); + pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); pGameObj->SetSpellId(m_spellInfo->Id); // Wild object not have owner and check clickable by players @@ -4896,7 +5000,7 @@ void Spell::EffectSummonObjectWild(uint32 i) if (linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { - linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0); + linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); linkedGO->SetSpellId(m_spellInfo->Id); // Wild object not have owner and check clickable by players @@ -5015,7 +5119,7 @@ void Spell::EffectScriptEffect(uint32 effIndex) case 55693: // Remove Collapsing Cave Aura if (!unitTarget) return; - unitTarget->RemoveAurasDueToSpell(m_spellInfo->CalculateSimpleValue(effIndex)); + unitTarget->RemoveAurasDueToSpell(SpellMgr::CalculateSpellEffectAmount(m_spellInfo, effIndex)); break; // PX-238 Winter Wondervolt TRAP case 26275: @@ -5558,8 +5662,8 @@ void Spell::EffectScriptEffect(uint32 effIndex) if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER || effIndex != 0) return; - uint32 spellID = m_spellInfo->CalculateSimpleValue(0); - uint32 questID = m_spellInfo->CalculateSimpleValue(1); + uint32 spellID = SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 0); + uint32 questID = SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 1); if (unitTarget->ToPlayer()->GetQuestStatus(questID) == QUEST_STATUS_COMPLETE && !unitTarget->ToPlayer()->GetQuestRewardStatus (questID)) unitTarget->CastSpell(unitTarget, spellID, true); @@ -5980,6 +6084,17 @@ void Spell::EffectScriptEffect(uint32 effIndex) unitTarget->CastSpell(unitTarget, spellTarget[urand(0,4)], true); break; } + case 64142: // Upper Deck - Create Foam Sword + if (unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + Player *plr = unitTarget->ToPlayer(); + static uint32 const itemId[] = {45061, 45176, 45177, 45178, 45179, 0}; + // player can only have one of these items + for (uint32 const *itr = &itemId[0]; *itr; ++itr) + if (plr->HasItemCount(*itr, 1, true)) + return; + DoCreateItem(effIndex, itemId[urand(0,4)]); + return; } break; } @@ -6476,7 +6591,7 @@ void Spell::EffectDuel(uint32 i) pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction()); pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1); int32 duration = GetSpellDuration(m_spellInfo); - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0); + pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); pGameObj->SetSpellId(m_spellInfo->Id); m_caster->AddGameObject(pGameObj); @@ -6554,7 +6669,7 @@ void Spell::EffectSummonPlayer(uint32 /*i*/) WorldPacket data(SMSG_SUMMON_REQUEST, 8+4+4); data << uint64(m_caster->GetGUID()); // summoner guid data << uint32(m_caster->GetZoneId()); // summoner zone - data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILISECONDS); // auto decline after msecs + data << uint32(MAX_PLAYER_SUMMON_DELAY*IN_MILLISECONDS); // auto decline after msecs unitTarget->ToPlayer()->GetSession()->SendPacket(&data); } @@ -6652,7 +6767,7 @@ void Spell::EffectEnchantHeldItem(uint32 i) return; // Apply the temporary enchantment - item->SetEnchantment(slot, enchant_id, duration*IN_MILISECONDS, 0); + item->SetEnchantment(slot, enchant_id, duration*IN_MILLISECONDS, 0); item_owner->ApplyEnchantment(item, slot, true); } } @@ -6782,7 +6897,7 @@ void Spell::EffectSummonObject(uint32 i) //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL,m_caster->getLevel()); int32 duration = GetSpellDuration(m_spellInfo); - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0); + pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); pGameObj->SetSpellId(m_spellInfo->Id); m_caster->AddGameObject(pGameObj); @@ -6821,6 +6936,13 @@ void Spell::EffectResurrect(uint32 /*effIndex*/) return; } break; + // Defibrillate ( Gnomish Army Knife) have 67% chance on success_list + case 54732: + if (roll_chance_i(33)) + { + return; + } + break; default: break; } @@ -6955,7 +7077,14 @@ void Spell::EffectQuestComplete(uint32 i) return; uint32 quest_id = m_spellInfo->EffectMiscValue[i]; - pPlayer->AreaExploredOrEventHappens(quest_id); + if (quest_id) + { + uint16 log_slot = pPlayer->FindQuestSlot(quest_id); + if (log_slot < MAX_QUEST_LOG_SIZE) + pPlayer->AreaExploredOrEventHappens(quest_id); + else + pPlayer->CompleteQuest(quest_id); // quest not in log - for internal use + } } void Spell::EffectForceDeselect(uint32 /*i*/) @@ -7027,9 +7156,6 @@ void Spell::EffectSkinning(uint32 /*i*/) void Spell::EffectCharge(uint32 /*i*/) { - if (!m_caster) - return; - Unit *target = m_targets.getUnitTarget(); if (!target) return; @@ -7043,22 +7169,14 @@ void Spell::EffectCharge(uint32 /*i*/) m_caster->Attack(target, true); } -void Spell::EffectCharge2(uint32 /*i*/) +void Spell::EffectChargeDest(uint32 /*i*/) { - float x, y, z; if (m_targets.HasDst()) - m_targets.m_dstPos.GetPosition(x, y, z); - else if (Unit *target = m_targets.getUnitTarget()) { - target->GetContactPoint(m_caster, x, y, z); - // not all charge effects used in negative spells - if (!IsPositiveSpell(m_spellInfo->Id) && m_caster->GetTypeId() == TYPEID_PLAYER) - m_caster->Attack(target, true); + float x, y, z; + m_targets.m_dstPos.GetPosition(x, y, z); + m_caster->GetMotionMaster()->MoveCharge(x, y, z); } - else - return; - - m_caster->GetMotionMaster()->MoveCharge(x, y, z); } void Spell::EffectKnockBack(uint32 i) @@ -7101,7 +7219,7 @@ void Spell::EffectKnockBack(uint32 i) unitTarget->KnockbackFrom(x, y, speedxy, speedz); } -void Spell::EffectJump2(uint32 i) +void Spell::EffectLeapBack(uint32 i) { float speedxy = float(m_spellInfo->EffectMiscValue[i])/10; float speedz = float(damage/10); @@ -7117,6 +7235,50 @@ void Spell::EffectJump2(uint32 i) } } +void Spell::EffectQuestClear(uint32 i) +{ + Player *pPlayer = NULL; + if (m_caster->GetTypeId() == TYPEID_PLAYER) + pPlayer = m_caster->ToPlayer(); + else if (unitTarget && unitTarget->GetTypeId() == TYPEID_PLAYER) + pPlayer = unitTarget->ToPlayer(); + + if (!pPlayer) + return; + + uint32 quest_id = m_spellInfo->EffectMiscValue[i]; + + Quest const* pQuest = objmgr.GetQuestTemplate(quest_id); + + if (!pQuest) + return; + + QuestStatusMap::iterator qs_itr = pPlayer->getQuestStatusMap().find(quest_id); + // Player has never done this quest + if (qs_itr == pPlayer->getQuestStatusMap().end()) + return; + + // remove all quest entries for 'entry' from quest log + for (uint8 slot = 0; slot < MAX_QUEST_LOG_SIZE; ++slot) + { + uint32 quest = pPlayer->GetQuestSlotQuestId(slot); + if (quest == quest_id) + { + pPlayer->SetQuestSlot(slot, 0); + + // we ignore unequippable quest items in this case, its' still be equipped + pPlayer->TakeQuestSourceItem(quest, false); + } + } + + // set quest status to not started (will be updated in DB at next save) + pPlayer->SetQuestStatus(quest_id, QUEST_STATUS_NONE); + + // reset rewarded for restart repeatable quest + QuestStatusData &data = qs_itr->second; + data.m_rewarded = false; +} + void Spell::EffectSendTaxi(uint32 i) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -7152,7 +7314,7 @@ void Spell::EffectDispelMechanic(uint32 i) continue; bool success = false; GetDispelChance(aura->GetCaster(), unitTarget, aura->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success); - if((GetAllSpellMechanicMask(aura->GetSpellProto()) & (1<<(mechanic))) && success) + if ((GetAllSpellMechanicMask(aura->GetSpellProto()) & (1 << mechanic)) && success) dispel_list.push(std::make_pair(aura->GetId(), aura->GetCasterGUID())); } @@ -7356,7 +7518,7 @@ void Spell::EffectTransmitted(uint32 effIndex) case 3: lastSec = 17; break; } - duration = duration - lastSec*IN_MILISECONDS + FISHING_BOBBER_READY_TIME*IN_MILISECONDS; + duration = duration - lastSec*IN_MILLISECONDS + FISHING_BOBBER_READY_TIME*IN_MILLISECONDS; break; } case GAMEOBJECT_TYPE_SUMMONING_RITUAL: @@ -7377,7 +7539,7 @@ void Spell::EffectTransmitted(uint32 effIndex) break; } - pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0); + pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); pGameObj->SetOwnerGUID(m_caster->GetGUID()); @@ -7396,7 +7558,7 @@ void Spell::EffectTransmitted(uint32 effIndex) if (linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { - linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILISECONDS : 0); + linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); //linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); linkedGO->SetSpellId(m_spellInfo->Id); linkedGO->SetOwnerGUID(m_caster->GetGUID()); @@ -7543,7 +7705,7 @@ void Spell::EffectStealBeneficialBuff(uint32 i) bool success = false; // 2.4.3 Patch Notes: "Dispel effects will no longer attempt to remove effects that have 100% dispel resistance." - if (GetDispelChance(itr->first->GetCaster(), unitTarget, itr->first->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success) > 99) + if (!GetDispelChance(itr->first->GetCaster(), unitTarget, itr->first->GetId(), !unitTarget->IsFriendlyTo(m_caster), &success)) { steal_list.erase(itr); continue; diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 5016e5ebc2b..510be691d18 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -19,7 +19,7 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" +#include "DatabaseEnv.h" #include "WorldPacket.h" #include "WorldSession.h" #include "GridNotifiers.h" @@ -41,7 +41,6 @@ #include "MapManager.h" #include "ObjectAccessor.h" #include "CellImpl.h" -#include "Policies/SingletonImp.h" #include "SharedDefines.h" #include "LootMgr.h" #include "VMapFactory.h" @@ -53,7 +52,7 @@ #include "ScriptMgr.h" #include "ConditionMgr.h" -#define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILISECONDS) +#define SPELL_CHANNEL_UPDATE_INTERVAL (1 * IN_MILLISECONDS) extern pEffect SpellEffects[TOTAL_SPELL_EFFECTS]; @@ -149,6 +148,15 @@ void SpellCastTargets::setItemTarget(Item* item) m_targetMask |= TARGET_FLAG_ITEM; } +void SpellCastTargets::setTradeItemTarget(Player* caster) +{ + m_itemTargetGUID = uint64(TRADE_SLOT_NONTRADED); + m_itemTargetEntry = 0; + m_targetMask |= TARGET_FLAG_TRADE_ITEM; + + Update(caster); +} + void SpellCastTargets::setCorpseTarget(Corpse* corpse) { m_CorpseTargetGUID = corpse->GetGUID(); @@ -164,12 +172,13 @@ void SpellCastTargets::Update(Unit* caster) m_itemTarget = NULL; if (caster->GetTypeId() == TYPEID_PLAYER) { + Player *player = caster->ToPlayer(); if (m_targetMask & TARGET_FLAG_ITEM) - m_itemTarget = caster->ToPlayer()->GetItemByGuid(m_itemTargetGUID); + m_itemTarget = player->GetItemByGuid(m_itemTargetGUID); else if (m_targetMask & TARGET_FLAG_TRADE_ITEM) - if (m_itemTargetGUID == TRADE_SLOT_NONTRADED) // here it is not guid but slot. Also prevent hacking slots - if (Player* pTrader = caster->ToPlayer()->GetTrader()) - m_itemTarget = pTrader->GetItemByTradeSlot(m_itemTargetGUID); + if (m_itemTargetGUID == TRADE_SLOT_NONTRADED) // here it is not guid but slot. Also prevents hacking slots + if (TradeData* pTrade = player->GetTradeData()) + m_itemTarget = pTrade->GetTraderData()->GetItem(TRADE_SLOT_NONTRADED); if (m_itemTarget) m_itemTargetEntry = m_itemTarget->GetEntry(); @@ -390,13 +399,12 @@ Spell::Spell(Unit* Caster, SpellEntry const *info, bool triggered, uint64 origin } for (int i=0; i <3; ++i) - m_currentBasePoints[i] = m_spellInfo->CalculateSimpleValue(i); + m_currentBasePoints[i] = m_spellInfo->EffectBasePoints[i]; m_spellState = SPELL_STATE_NULL; m_TriggerSpells.clear(); m_IsTriggeredSpell = triggered; - //m_AreaAura = false; m_CastItem = NULL; unitTarget = NULL; @@ -1336,7 +1344,15 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool // Now Reduce spell duration using data received at spell hit int32 duration = m_spellAura->GetMaxDuration(); int32 limitduration = GetDiminishingReturnsLimitDuration(m_diminishGroup,aurSpellInfo); - unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel,limitduration); + float diminishMod = unit->ApplyDiminishingToDuration(m_diminishGroup, duration, m_originalCaster, m_diminishLevel,limitduration); + + // unit is immune to aura if it was diminished to 0 duration + if (diminishMod == 0.0f) + { + m_spellAura->Remove(); + return SPELL_MISS_IMMUNE; + } + ((UnitAura*)m_spellAura)->SetDiminishGroup(m_diminishGroup); bool positive = IsPositiveSpell(m_spellAura->GetId()); @@ -1350,12 +1366,6 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool if (IsChanneledSpell(m_spellInfo)) m_originalCaster->ModSpellCastTime(aurSpellInfo, duration, this); - if (duration == 0 && !positive) - { - m_spellAura->Remove(); - return SPELL_MISS_IMMUNE; - } - if (duration != m_spellAura->GetMaxDuration()) { m_spellAura->SetMaxDuration(duration); @@ -1989,7 +1999,6 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if (cur == TARGET_DST_TARGET_ENEMY || cur == TARGET_DEST_TARGET_ANY) { m_targets.setDst(target); - AddUnitTarget(target, i); break; } @@ -2018,9 +2027,6 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) Position pos; target->GetNearPosition(pos, dist, angle); m_targets.setDst(&pos); - // Teleports use this as destination - if (m_spellInfo->Effect[i] != SPELL_EFFECT_TELEPORT_UNITS) - AddUnitTarget(target, i); break; } @@ -2416,6 +2422,117 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) if (!unitList.empty()) { + // Special target selection for smart heals and energizes + uint32 maxSize = 0; + int32 power = -1; + switch (m_spellInfo->SpellFamilyName) + { + case SPELLFAMILY_GENERIC: + switch (m_spellInfo->Id) + { + case 52759: // Ancestral Awakening + case 71610: // Echoes of Light (Althor's Abacus normal version) + case 71641: // Echoes of Light (Althor's Abacus heroic version) + maxSize = 1; + power = POWER_HEALTH; + break; + case 54968: // Glyph of Holy Light + maxSize = m_spellInfo->MaxAffectedTargets; + power = POWER_HEALTH; + break; + case 57669: // Replenishment + // In arenas Replenishment may only affect the caster + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->InArena()) + { + unitList.clear(); + unitList.push_back(m_caster); + break; + } + maxSize = 10; + power = POWER_MANA; + break; + default: + break; + } + break; + case SPELLFAMILY_PRIEST: + if (m_spellInfo->SpellFamilyFlags[0] == 0x10000000) // Circle of Healing + { + maxSize = m_caster->HasAura(55675) ? 6 : 5; // Glyph of Circle of Healing + power = POWER_HEALTH; + } + else if (m_spellInfo->Id == 64844) // Divine Hymn + { + maxSize = 3; + power = POWER_HEALTH; + } + else if (m_spellInfo->Id == 64904) // Hymn of Hope + { + maxSize = 3; + power = POWER_MANA; + } + else + break; + + // Remove targets outside caster's raid + for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();) + { + if (!(*itr)->IsInRaidWith(m_caster)) + itr = unitList.erase(itr); + else + ++itr; + } + break; + case SPELLFAMILY_DRUID: + if (m_spellInfo->SpellFamilyFlags[1] == 0x04000000) // Wild Growth + { + maxSize = m_caster->HasAura(62970) ? 6 : 5; // Glyph of Wild Growth + power = POWER_HEALTH; + } + else + break; + + // Remove targets outside caster's raid + for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();) + { + if (!(*itr)->IsInRaidWith(m_caster)) + itr = unitList.erase(itr); + else + ++itr; + } + break; + default: + break; + } + + if (maxSize && power != -1) + { + if (power == POWER_HEALTH) + { + if (unitList.size() > maxSize) + { + unitList.sort(Trinity::HealthPctOrderPred()); + unitList.resize(maxSize); + } + } + else + { + for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();) + { + if ((*itr)->getPowerType() != (Powers)power) + itr = unitList.erase(itr); + else + ++itr; + } + if (unitList.size() > maxSize) + { + unitList.sort(Trinity::PowerPctOrderPred((Powers)power)); + unitList.resize(maxSize); + } + } + } + + // Other special target selection goes here if (uint32 maxTargets = m_spellValue->MaxAffectedTargets) { Unit::AuraEffectList const& Auras = m_caster->GetAuraEffectsByType(SPELL_AURA_MOD_MAX_AFFECTED_TARGETS); @@ -2438,56 +2555,6 @@ void Spell::SelectEffectTargets(uint32 i, uint32 cur) case 59725: // Improved Spell Reflection - aoe aura unitList.remove(m_caster); break; - case 57669: //Replenishment (special target selection) 10 targets with lowest mana - { - for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();) - { - if ((*itr)->getPowerType() != POWER_MANA) - itr = unitList.erase(itr); - else - ++itr; - } - if (unitList.size() > 10) - { - unitList.sort(Trinity::PowerPctOrderPred(POWER_MANA)); - unitList.resize(10); - } - break; - } - case 52759: // Ancestral Awakening - { - if (unitList.size() > 1) - { - unitList.sort(Trinity::HealthPctOrderPred()); - unitList.resize(1); - } - break; - } - } - if (m_spellInfo->EffectImplicitTargetA[i] == TARGET_DEST_TARGET_ANY - && m_spellInfo->EffectImplicitTargetB[i] == TARGET_UNIT_AREA_ALLY_DST)// Wild Growth, Circle of Healing, Glyph of holy light target special selection - { - for (std::list<Unit*>::iterator itr = unitList.begin() ; itr != unitList.end();) - { - if (!(*itr)->IsInRaidWith(m_targets.getUnitTarget())) - itr = unitList.erase(itr); - else - ++itr; - } - - uint32 maxsize = 5; - - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DRUID && m_spellInfo->SpellFamilyFlags[1] & 0x04000000) // Wild Growth - maxsize += m_caster->HasAura(62970) ? 1 : 0; // Glyph of Wild Growth - - if (m_spellInfo->SpellFamilyName == SPELLFAMILY_PRIEST && m_spellInfo->SpellFamilyFlags[0] & 0x10000000 && m_spellInfo->SpellIconID == 2214) // Circle of Healing - maxsize += m_caster->HasAura(55675) ? 1 : 0; // Glyph of Circle of Healing - - if (unitList.size() > maxsize) - { - unitList.sort(Trinity::HealthPctOrderPred()); - unitList.resize(maxsize); - } } // Death Pact if (m_spellInfo->SpellFamilyName == SPELLFAMILY_DEATHKNIGHT && m_spellInfo->SpellFamilyFlags[0] & 0x00080000) @@ -2844,6 +2911,32 @@ void Spell::cast(bool skipCheck) SetExecutedCurrently(false); return; } + + // additional check after cast bar completes (must not be in CheckCast) + // if trade not complete then remember it in trade data + if (m_targets.getTargetMask() & TARGET_FLAG_TRADE_ITEM) + { + if (m_caster->GetTypeId() == TYPEID_PLAYER) + { + if (TradeData* my_trade = m_caster->ToPlayer()->GetTradeData()) + { + if (!my_trade->IsInAcceptProcess()) + { + // Spell will be casted at completing the trade. Silently ignore at this place + my_trade->SetSpell(m_spellInfo->Id, m_CastItem); + SendCastResult(SPELL_FAILED_DONT_REPORT); + SendInterrupted(0); + m_caster->ToPlayer()->RestoreSpellMods(this); + // cleanup after mod system + // triggered spell pointer can be not removed in some cases + m_caster->ToPlayer()->SetSpellModTakingSpell(this, false); + finish(false); + SetExecutedCurrently(false); + return; + } + } + } + } } SelectSpellTargets(); @@ -2909,6 +3002,12 @@ void Spell::cast(bool skipCheck) TakePower(); TakeReagents(); // we must remove reagents before HandleEffects to allow place crafted item in same slot } + else if (Item* targetItem = m_targets.getItemTarget()) + { + /// Not own traded item (in trader trade slot) req. reagents including triggered spell case + if (targetItem->GetOwnerGUID() != m_caster->GetGUID()) + TakeReagents(); + } // are there any spells need to be triggered after hit? // handle SPELL_AURA_ADD_TARGET_TRIGGER auras @@ -2938,8 +3037,9 @@ void Spell::cast(bool skipCheck) switch(m_spellInfo->Effect[i]) { case SPELL_EFFECT_CHARGE: + case SPELL_EFFECT_CHARGE_DEST: case SPELL_EFFECT_JUMP: - case SPELL_EFFECT_JUMP2: + case SPELL_EFFECT_JUMP_DEST: case SPELL_EFFECT_LEAP_BACK: case SPELL_EFFECT_ACTIVATE_RUNE: HandleEffects(NULL,NULL,NULL,i); @@ -4274,7 +4374,12 @@ void Spell::TakeRunePower() void Spell::TakeReagents() { if (m_IsTriggeredSpell) // reagents used in triggered spell removed by original spell or don't must be removed. - return; + { + Item* targetItem = m_targets.getItemTarget(); + /// Not own traded item (in trader trade slot) req. reagents including triggered spell case + if (!(targetItem && targetItem->GetOwnerGUID() != m_caster->GetGUID())) + return; + } if (m_caster->GetTypeId() != TYPEID_PLAYER) return; @@ -4669,7 +4774,7 @@ SpellCastResult Spell::CheckCast(bool strict) // - with greater than 10 min CD without SPELL_ATTR_EX4_USABLE_IN_ARENA flag // - with SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA flag if ((m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_NOT_USABLE_IN_ARENA) || - GetSpellRecoveryTime(m_spellInfo) > 10 * MINUTE * IN_MILISECONDS && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA)) + GetSpellRecoveryTime(m_spellInfo) > 10 * MINUTE * IN_MILLISECONDS && !(m_spellInfo->AttributesEx4 & SPELL_ATTR_EX4_USABLE_IN_ARENA)) if (MapEntry const* mapEntry = sMapStore.LookupEntry(m_caster->GetMapId())) if (mapEntry->IsBattleArena()) return SPELL_FAILED_NOT_IN_ARENA; @@ -5212,24 +5317,6 @@ SpellCastResult Spell::CheckCast(bool strict) if (m_caster->GetTypeId() != TYPEID_PLAYER || !m_caster->ToPlayer()->IsInFeralForm()) return SPELL_FAILED_ONLY_SHAPESHIFT; break; - // Wild Growth - case 48438: - case 53248: - case 53249: - case 53251: - { - if (m_caster->GetTypeId() != TYPEID_PLAYER) - return SPELL_FAILED_DONT_REPORT; - - Unit* target = m_targets.getUnitTarget(); - if (!target || target->GetTypeId() != TYPEID_PLAYER) - return SPELL_FAILED_BAD_TARGETS; - - if (!m_caster->ToPlayer()->IsInSameRaidWith(target->ToPlayer())) - return SPELL_FAILED_TARGET_NOT_IN_RAID; - - break; - } case 1515: { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -5304,6 +5391,9 @@ SpellCastResult Spell::CheckCast(bool strict) if (target->GetTypeId() == TYPEID_UNIT && target->ToCreature()->IsVehicle()) return SPELL_FAILED_BAD_IMPLICIT_TARGETS; + if (target->IsMounted()) + return SPELL_FAILED_CANT_BE_CHARMED; + if (target->GetCharmerGUID()) return SPELL_FAILED_CHARMED; @@ -5357,23 +5447,12 @@ SpellCastResult Spell::CheckCast(bool strict) // allow always ghost flight spells if (m_originalCaster && m_originalCaster->GetTypeId() == TYPEID_PLAYER && m_originalCaster->isAlive()) { - // 4197 = Wintergrasp || 4395 = Dalaran && 4564 = Krasus Landing - if (m_originalCaster->GetZoneId() == 4197 || m_originalCaster->GetZoneId() == 4395 && m_originalCaster->GetAreaId() != 4564) - return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; + if (AreaTableEntry const* pArea = GetAreaEntryByAreaID(m_originalCaster->GetAreaId())) + if (pArea->flags & AREA_FLAG_NO_FLY_ZONE) + return m_IsTriggeredSpell ? SPELL_FAILED_DONT_REPORT : SPELL_FAILED_NOT_HERE; } break; } - case SPELL_AURA_RANGED_AP_ATTACKER_CREATURES_BONUS: - { - if (!m_targets.getUnitTarget() && m_targets.getUnitTarget()->GetTypeId() != TYPEID_UNIT) - return SPELL_FAILED_BAD_IMPLICIT_TARGETS; - - // can be casted at non-friendly unit or own pet/charm - if (m_caster->IsFriendlyTo(m_targets.getUnitTarget())) - return SPELL_FAILED_TARGET_FRIENDLY; - - break; - } case SPELL_AURA_PERIODIC_MANA_LEECH: { if (!m_targets.getUnitTarget()) @@ -5392,6 +5471,26 @@ SpellCastResult Spell::CheckCast(bool strict) } } + // check trade slot case (last, for allow catch any another cast problems) + if (m_targets.getTargetMask() & TARGET_FLAG_TRADE_ITEM) + { + if (m_caster->GetTypeId() != TYPEID_PLAYER) + return SPELL_FAILED_NOT_TRADING; + + TradeData* my_trade = m_caster->ToPlayer()->GetTradeData(); + + if (!my_trade) + return SPELL_FAILED_NOT_TRADING; + + TradeSlots slot = TradeSlots(m_targets.getItemTargetGUID()); + if (slot != TRADE_SLOT_NONTRADED) + return SPELL_FAILED_ITEM_NOT_READY; + + if (!m_IsTriggeredSpell) + if (my_trade->GetSpell()) + return SPELL_FAILED_ITEM_ALREADY_ENCHANTED; + } + // all ok return SPELL_CAST_OK; } @@ -5892,7 +5991,7 @@ SpellCastResult Spell::CheckItems() else if (!(p_caster->HasItemCount(m_spellInfo->EffectItemType[i],1))) return SPELL_FAILED_TOO_MANY_OF_ITEM; else - p_caster->CastSpell(m_caster,m_spellInfo->CalculateSimpleValue(1),false); // move this to anywhere + p_caster->CastSpell(m_caster,SpellMgr::CalculateSpellEffectAmount(m_spellInfo, 1),false); // move this to anywhere return SPELL_FAILED_DONT_REPORT; } } @@ -6346,6 +6445,8 @@ bool Spell::CheckTarget(Unit* target, uint32 eff) case SPELL_AURA_AOE_CHARM: if (target->GetTypeId() == TYPEID_UNIT && target->IsVehicle()) return false; + if (target->IsMounted()) + return false; if (target->GetCharmerGUID()) return false; if (int32 damage = CalculateDamage(eff, target)) @@ -6687,8 +6788,9 @@ int32 Spell::CalculateDamageDone(Unit *unit, const uint32 effectMask, float *mul { if (IsAreaEffectTarget[m_spellInfo->EffectImplicitTargetA[i]] || IsAreaEffectTarget[m_spellInfo->EffectImplicitTargetB[i]]) { - if (int32 reducedPct = unit->GetMaxNegativeAuraModifier(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE)) - m_damage = m_damage * (100 + reducedPct) / 100; + m_damage = float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask); + if (m_caster->GetTypeId() == TYPEID_UNIT) + m_damage = float(m_damage) * unit->GetTotalAuraMultiplierByMiscMask(SPELL_AURA_MOD_CREATURE_AOE_DAMAGE_AVOIDANCE, m_spellInfo->SchoolMask); if (m_caster->GetTypeId() == TYPEID_PLAYER) { @@ -6748,8 +6850,8 @@ SpellCastResult Spell::CanOpenLock(uint32 effIndex, uint32 lockId, SkillType& sk if (skillId != SKILL_NONE) { // skill bonus provided by casting spell (mostly item spells) - // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) (use m_currentBasePoints, CalculateDamage returns wrong value) - uint32 spellSkillBonus = uint32(m_currentBasePoints[effIndex]); + // add the damage modifier from the spell casted (cheat lock / skeleton key etc.) + uint32 spellSkillBonus = uint32(CalculateDamage(effIndex, NULL)); reqSkillValue = lockInfo->Skill[j]; // castitem check: rogue using skeleton keys. the skill values should not be added in this case. @@ -6778,15 +6880,15 @@ void Spell::SetSpellValue(SpellValueMod mod, int32 value) switch(mod) { case SPELLVALUE_BASE_POINT0: - m_spellValue->EffectBasePoints[0] = value - int32(1); + m_spellValue->EffectBasePoints[0] = SpellMgr::CalculateSpellEffectBaseAmount(value); m_currentBasePoints[0] = m_spellValue->EffectBasePoints[0]; //this should be removed in the future break; case SPELLVALUE_BASE_POINT1: - m_spellValue->EffectBasePoints[1] = value - int32(1); + m_spellValue->EffectBasePoints[1] = SpellMgr::CalculateSpellEffectBaseAmount(value); m_currentBasePoints[1] = m_spellValue->EffectBasePoints[1]; break; case SPELLVALUE_BASE_POINT2: - m_spellValue->EffectBasePoints[2] = value - int32(1); + m_spellValue->EffectBasePoints[2] = SpellMgr::CalculateSpellEffectBaseAmount(value); m_currentBasePoints[2] = m_spellValue->EffectBasePoints[2]; break; case SPELLVALUE_RADIUS_MOD: diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index a987e35e65d..ffbcfdb056d 100644 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -180,6 +180,7 @@ class SpellCastTargets Item* getItemTarget() const { return m_itemTarget; } uint32 getItemTargetEntry() const { return m_itemTargetEntry; } void setItemTarget(Item* item); + void setTradeItemTarget(Player* caster); void updateTradeSlotItem() { if (m_itemTarget && (m_targetMask & TARGET_FLAG_TRADE_ITEM)) @@ -303,7 +304,9 @@ class Spell void EffectAddFarsight(uint32 i); void EffectHealMechanical(uint32 i); void EffectJump(uint32 i); - void EffectJump2(uint32 i); + void EffectJumpDest(uint32 i); + void EffectLeapBack(uint32 i); + void EffectQuestClear(uint32 i); void EffectTeleUnitsFaceCaster(uint32 i); void EffectLearnSkill(uint32 i); void EffectAddHonor(uint32 i); @@ -315,6 +318,7 @@ class Spell void EffectLearnPetSpell(uint32 i); void EffectWeaponDmg(uint32 i); void EffectForceCast(uint32 i); + void EffectForceCastWithValue(uint32 i); void EffectTriggerSpell(uint32 i); void EffectTriggerMissileSpell(uint32 i); void EffectThreat(uint32 i); @@ -345,7 +349,7 @@ class Spell void EffectSelfResurrect(uint32 i); void EffectSkinning(uint32 i); void EffectCharge(uint32 i); - void EffectCharge2(uint32 i); + void EffectChargeDest(uint32 i); void EffectProspecting(uint32 i); void EffectMilling(uint32 i); void EffectRenamePet(uint32 i); @@ -460,7 +464,7 @@ class Spell void HandleThreatSpells(uint32 spellId); const SpellEntry * const m_spellInfo; - int32 m_currentBasePoints[3]; // cache SpellEntry::EffectBasePoints and use for set custom base points + int32 m_currentBasePoints[3]; // overrides SpellEntry::EffectBasePoints IMPORTANT: base points != points calculated Item* m_CastItem; uint64 m_castItemGUID; uint8 m_cast_count; @@ -642,8 +646,10 @@ class Spell void SpellDamageWeaponDmg(uint32 i); void SpellDamageHeal(uint32 i); + // effect helpers void GetSummonPosition(uint32 i, Position &pos, float radius = 0.0f, uint32 count = 0); void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const *properties); + void CalculateJumpSpeeds(uint8 i, float dist, float & speedxy, float & speedz); SpellCastResult CanOpenLock(uint32 effIndex, uint32 lockid, SkillType& skillid, int32& reqSkillValue, int32& skillValue); // ------------------------------------------- @@ -769,14 +775,14 @@ namespace Trinity } } - #ifdef WIN32 + #ifdef _WIN32 template<> inline void Visit(CorpseMapType &) {} template<> inline void Visit(GameObjectMapType &) {} template<> inline void Visit(DynamicObjectMapType &) {} #endif }; - #ifndef WIN32 + #ifndef _WIN32 template<> inline void SpellNotifierCreatureAndPlayer::Visit(CorpseMapType&) {} template<> inline void SpellNotifierCreatureAndPlayer::Visit(GameObjectMapType&) {} template<> inline void SpellNotifierCreatureAndPlayer::Visit(DynamicObjectMapType&) {} diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index 510fdccb98a..55a421b7a57 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -83,8 +83,9 @@ SpellMgr::SpellMgr() case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: case SPELL_EFFECT_APPLY_AREA_AURA_RAID: case SPELL_EFFECT_CHARGE: + case SPELL_EFFECT_CHARGE_DEST: case SPELL_EFFECT_JUMP: - case SPELL_EFFECT_JUMP2: + case SPELL_EFFECT_JUMP_DEST: case SPELL_EFFECT_LEAP_BACK: EffectTargetType[i] = SPELL_REQUIRE_CASTER; break; @@ -290,7 +291,7 @@ int32 GetSpellMaxDuration(SpellEntry const *spellInfo) return (du->Duration[2] == -1) ? -1 : abs(du->Duration[2]); } -int32 GetDispelChance(Unit* auraCaster, Unit* target, uint32 spellId, bool offensive, bool *result) +uint32 GetDispelChance(Unit* auraCaster, Unit* target, uint32 spellId, bool offensive, bool *result) { // we assume that aura dispel chance is 100% on start // need formula for level difference based chance @@ -310,7 +311,9 @@ int32 GetDispelChance(Unit* auraCaster, Unit* target, uint32 spellId, bool offen if (result) *result = !roll_chance_i(resist_chance); - return resist_chance; + resist_chance = resist_chance < 0 ? 0 : resist_chance; + resist_chance = resist_chance > 100 ? 100 : resist_chance; + return 100 - resist_chance; } uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell * spell) @@ -750,20 +753,47 @@ bool SpellMgr::_isPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) con if (spellproto->Attributes & SPELL_ATTR_NEGATIVE_1) return false; - switch(spellId) + switch (spellproto->SpellFamilyName) { - //case 37675: // Chaos Blast removed from mangos - case 34700: // Allergic Reaction - case 61987: // Avenging Wrath Marker - case 61988: // Divine Shield exclude aura - case 50524: // Runic Power Feed - return false; - case 12042: // Arcane Power - case 30877: // Tag Murloc - return true; + case SPELLFAMILY_GENERIC: + switch (spellId) + { + case 34700: // Allergic Reaction + case 61987: // Avenging Wrath Marker + case 61988: // Divine Shield exclude aura + return false; + case 30877: // Tag Murloc + return true; + default: + break; + } + break; + case SPELLFAMILY_MAGE: + // Amplify Magic, Dampen Magic + if (spellproto->SpellFamilyFlags[0] == 0x00002000) + return true; + break; + case SPELLFAMILY_PRIEST: + switch (spellId) + { + case 64844: // Divine Hymn + case 64904: // Hymn of Hope + case 47585: // Dispersion + return true; + default: + break; + } + break; + case SPELLFAMILY_HUNTER: + // Aspect of the Viper + if (spellId == 34074) + return true; + break; + default: + break; } - switch(spellproto->Mechanic) + switch (spellproto->Mechanic) { case MECHANIC_IMMUNE_SHIELD: return true; @@ -809,16 +839,16 @@ bool SpellMgr::_isPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) con case SPELL_AURA_MOD_HEALING_PCT: case SPELL_AURA_MOD_HEALING_DONE: case SPELL_AURA_MOD_DAMAGE_PERCENT_DONE: - if (spellproto->CalculateSimpleValue(effIndex) < 0) + if (SpellMgr::CalculateSpellEffectAmount(spellproto, effIndex) < 0) return false; break; case SPELL_AURA_MOD_DAMAGE_TAKEN: // dependent from bas point sign (positive -> negative) - if (spellproto->CalculateSimpleValue(effIndex) > 0) + if (SpellMgr::CalculateSpellEffectAmount(spellproto, effIndex) > 0) return false; break; case SPELL_AURA_MOD_CRIT_PCT: case SPELL_AURA_MOD_SPELL_CRIT_CHANCE: - if (spellproto->CalculateSimpleValue(effIndex) > 0) + if (SpellMgr::CalculateSpellEffectAmount(spellproto, effIndex) > 0) return true; // some expected positive spells have SPELL_ATTR_EX_NEGATIVE break; case SPELL_AURA_ADD_TARGET_TRIGGER: @@ -861,6 +891,7 @@ bool SpellMgr::_isPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) con case SPELL_AURA_PERIODIC_LEECH: case SPELL_AURA_MOD_STALKED: case SPELL_AURA_PERIODIC_DAMAGE_PERCENT: + case SPELL_AURA_PREVENT_RESSURECTION: return false; case SPELL_AURA_PERIODIC_DAMAGE: // used in positive spells also. // part of negative spell if casted at self (prevent cancel) @@ -896,7 +927,7 @@ bool SpellMgr::_isPositiveEffect(uint32 spellId, uint32 effIndex, bool deep) con switch(spellproto->EffectMiscValue[effIndex]) { case SPELLMOD_COST: // dependent from bas point sign (negative -> positive) - if (spellproto->CalculateSimpleValue(effIndex) > 0) + if (SpellMgr::CalculateSpellEffectAmount(spellproto, effIndex) > 0) { if (!deep) { @@ -1142,7 +1173,7 @@ void SpellMgr::LoadSpellTargetPositions() // additional requirements if (spellInfo->Effect[i]==SPELL_EFFECT_BIND && spellInfo->EffectMiscValue[i]) { - uint32 area_id = MapManager::Instance().GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z); + uint32 area_id = sMapMgr.GetAreaId(st.target_mapId, st.target_X, st.target_Y, st.target_Z); if (area_id != uint32(spellInfo->EffectMiscValue[i])) { sLog.outErrorDb("Spell (Id: %u) listed in `spell_target_position` expected point to zone %u bit point to zone %u.",Spell_ID, spellInfo->EffectMiscValue[i], area_id); @@ -1781,6 +1812,80 @@ bool SpellMgr::IsSkillBonusSpell(uint32 spellId) const return false; } +bool SpellMgr::IsSkillTypeSpell(uint32 spellId, SkillType type) const +{ + SkillLineAbilityMapBounds bounds = GetSkillLineAbilityMapBounds(spellId); + + for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) + if (_spell_idx->second->skillId == uint32(type)) + return true; + + return false; +} + +// basepoints provided here have to be valid basepoints (use SpellMgr::CalculateSpellEffectBaseAmount) +int32 SpellMgr::CalculateSpellEffectAmount(SpellEntry const * spellEntry, uint8 effIndex, Unit const * caster, int32 const * effBasePoints, Unit const * target) +{ + float basePointsPerLevel = spellEntry->EffectRealPointsPerLevel[effIndex]; + int32 basePoints = effBasePoints ? *effBasePoints : spellEntry->EffectBasePoints[effIndex]; + int32 randomPoints = int32(spellEntry->EffectDieSides[effIndex]); + + // base amount modification based on spell lvl vs caster lvl + if (caster) + { + int32 level = int32(caster->getLevel()); + if (level > int32(spellEntry->maxLevel) && spellEntry->maxLevel > 0) + level = int32(spellEntry->maxLevel); + else if (level < int32(spellEntry->baseLevel)) + level = int32(spellEntry->baseLevel); + level -= int32(spellEntry->spellLevel); + basePoints += int32(level * basePointsPerLevel); + } + + // roll in a range <1;EffectDieSides> as of patch 3.3.3 + switch(randomPoints) + { + case 0: // not used + case 1: basePoints += 1; break; // range 1..1 + default: + // range can have positive (1..rand) and negative (rand..1) values, so order its for irand + int32 randvalue = (randomPoints >= 1) + ? irand(1, randomPoints) + : irand(randomPoints, 1); + + basePoints += randvalue; + break; + } + + int32 value = basePoints; + + // random damage + if (caster) + { + // bonus amount from combo points + if (caster->m_movedPlayer) + if (uint8 comboPoints = caster->m_movedPlayer->GetComboPoints()) + if (float comboDamage = spellEntry->EffectPointsPerComboPoint[effIndex]) + value += int32(comboDamage * comboPoints); + + value = caster->ApplyEffectModifiers(spellEntry, effIndex, value); + + // amount multiplication based on caster's level + if (!basePointsPerLevel && (spellEntry->Attributes & SPELL_ATTR_LEVEL_DAMAGE_CALCULATION && spellEntry->spellLevel) && + spellEntry->Effect[effIndex] != SPELL_EFFECT_WEAPON_PERCENT_DAMAGE && + spellEntry->Effect[effIndex] != SPELL_EFFECT_KNOCK_BACK && + spellEntry->EffectApplyAuraName[effIndex] != SPELL_AURA_MOD_SPEED_ALWAYS && + spellEntry->EffectApplyAuraName[effIndex] != SPELL_AURA_MOD_SPEED_NOT_STACK && + spellEntry->EffectApplyAuraName[effIndex] != SPELL_AURA_MOD_INCREASE_SPEED && + spellEntry->EffectApplyAuraName[effIndex] != SPELL_AURA_MOD_DECREASE_SPEED) + //there are many more: slow speed, -healing pct + value = int32(value*0.25f*exp(caster->getLevel()*(70-spellEntry->spellLevel)/1000.0f)); + //value = int32(value * (int32)getLevel() / (int32)(spellProto->spellLevel ? spellProto->spellLevel : 1)); + } + + return value; +} + SpellEntry const* SpellMgr::SelectAuraRankForPlayerLevel(SpellEntry const* spellInfo, uint32 playerLevel) const { // ignore passive spells @@ -1843,7 +1948,7 @@ void SpellMgr::LoadSpellLearnSkills() { SpellLearnSkillNode dbc_node; dbc_node.skill = entry->EffectMiscValue[i]; - dbc_node.step = entry->CalculateSimpleValue(i); + dbc_node.step = SpellMgr::CalculateSpellEffectAmount(entry, i); if (dbc_node.skill != SKILL_RIDING) dbc_node.value = 1; else @@ -2030,7 +2135,7 @@ void SpellMgr::LoadSpellPetAuras() continue; } - PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[eff] == TARGET_UNIT_PET, spellInfo->CalculateSimpleValue(eff)); + PetAura pa(pet, aura, spellInfo->EffectImplicitTargetA[eff] == TARGET_UNIT_PET, SpellMgr::CalculateSpellEffectAmount(spellInfo, eff)); mSpellPetAuraMap[(spell<<8) + eff] = pa; } @@ -2847,38 +2952,38 @@ int32 GetDiminishingReturnsLimitDuration(DiminishingGroup group, SpellEntry cons { // Wyvern Sting if (spellproto->SpellFamilyFlags[1] & 0x1000) - return 6 * IN_MILISECONDS; + return 6 * IN_MILLISECONDS; // Hunter's Mark if (spellproto->SpellFamilyFlags[0] & 0x400) - return 120 * IN_MILISECONDS; + return 120 * IN_MILLISECONDS; break; } case SPELLFAMILY_PALADIN: { // Repentance - limit to 6 seconds in PvP if (spellproto->SpellFamilyFlags[0] & 0x4) - return 6 * IN_MILISECONDS; + return 6 * IN_MILLISECONDS; break; } case SPELLFAMILY_DRUID: { // Faerie Fire - limit to 40 seconds in PvP (3.1) if (spellproto->SpellFamilyFlags[0] & 0x400) - return 40 * IN_MILISECONDS; + return 40 * IN_MILLISECONDS; break; } case SPELLFAMILY_PRIEST: { // Vampiric Embrace - limit to 60 seconds in PvP (3.1) if ((spellproto->SpellFamilyFlags[0] & 0x4) && spellproto->SpellIconID == 150) - return 60 * IN_MILISECONDS; + return 60 * IN_MILLISECONDS; break; } default: break; } - return 10 * IN_MILISECONDS; + return 10 * IN_MILLISECONDS; } bool IsDiminishingReturnsGroupDurationLimited(DiminishingGroup group) @@ -2974,7 +3079,13 @@ bool SpellArea::IsFitToRequirements(Player const* player, uint32 newZone, uint32 switch(spellId) { case 58600: // No fly Zone - Dalaran (Krasus Landing exception) - if (!player || player->GetAreaId() == 4564 || !player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !player->HasAuraType(SPELL_AURA_FLY) || player->HasAura(44795)) + if (!player) + return false; + + AreaTableEntry const* pArea = GetAreaEntryByAreaID(player->GetAreaId()); + if (!(pArea && pArea->flags & AREA_FLAG_NO_FLY_ZONE)) + return false; + if (!player->HasAuraType(SPELL_AURA_MOD_INCREASE_MOUNTED_FLIGHT_SPEED) && !player->HasAuraType(SPELL_AURA_FLY) || player->HasAura(44795)) return false; break; } @@ -3018,6 +3129,7 @@ bool SpellMgr::CanAurasStack(SpellEntry const *spellInfo_1, SpellEntry const *sp { // DOT or HOT from different casters will stack case SPELL_AURA_PERIODIC_DAMAGE: + case SPELL_AURA_PERIODIC_DUMMY: case SPELL_AURA_PERIODIC_HEAL: case SPELL_AURA_PERIODIC_TRIGGER_SPELL: case SPELL_AURA_PERIODIC_ENERGIZE: @@ -3350,8 +3462,9 @@ void SpellMgr::LoadSpellCustomAttr() count++; break; case SPELL_EFFECT_CHARGE: + case SPELL_EFFECT_CHARGE_DEST: case SPELL_EFFECT_JUMP: - case SPELL_EFFECT_JUMP2: + case SPELL_EFFECT_JUMP_DEST: case SPELL_EFFECT_LEAP_BACK: if (!spellInfo->speed && !spellInfo->SpellFamilyName) spellInfo->speed = SPEED_CHARGE; @@ -3505,6 +3618,12 @@ void SpellMgr::LoadSpellCustomAttr() case 39365: // Thundering Storm case 41071: // Raise Dead (HACK) case 52124: // Sky Darkener Assault + case 42442: // Vengeance Landing Cannonfire + case 45863: // Cosmetic - Incinerate to Random Target + case 25425: // Shoot + case 45761: // Shoot + case 42611: // Shoot + case 62374: // Pursued spellInfo->MaxAffectedTargets = 1; count++; break; @@ -3526,6 +3645,8 @@ void SpellMgr::LoadSpellCustomAttr() case 54172: // Divine Storm (heal) case 29213: // Curse of the Plaguebringer - Noth case 28542: // Life Drain - Sapphiron + case 66588: // Flaming Spear + case 54171: // Divine Storm spellInfo->MaxAffectedTargets = 3; count++; break; @@ -3587,6 +3708,15 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->procCharges = 6; count++; break; + case 47201: // Everlasting Affliction + case 47202: + case 47203: + case 47204: + case 47205: + // add corruption to affected spells + spellInfo->EffectSpellClassMask[1][0] |= 2; + count++; + break; case 51852: // The Eye of Acherus (no spawn in phase 2 in db) spellInfo->EffectMiscValue[0] |= 1; count++; @@ -3650,10 +3780,6 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->rangeIndex = 13; count++; break; - case 62374: // Pursued - spellInfo->MaxAffectedTargets = 1; - count++; - break; case 48743: // Death Pact spellInfo->AttributesEx &= ~SPELL_ATTR_EX_CANT_TARGET_SELF; count++; @@ -3675,30 +3801,6 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->EffectMiscValue[0] = MECHANIC_IMMUNE_SHIELD; count++; break; - case 42442: // Vengeance Landing Cannonfire - spellInfo->MaxAffectedTargets = 1; - count++; - break; - case 45863: // Cosmetic - Incinerate to Random Target - spellInfo->MaxAffectedTargets = 1; - count++; - break; - case 25425: // Shoot - spellInfo->MaxAffectedTargets = 1; - count++; - break; - case 45761: // Shoot - spellInfo->MaxAffectedTargets = 1; - count++; - break; - case 42611: // Shoot - spellInfo->MaxAffectedTargets = 1; - count++; - break; - case 66588: // Flaming Spear - spellInfo->MaxAffectedTargets = 3; - count++; - break; case 53651: spellInfo->AttributesEx3 |= SPELL_ATTR_EX3_NO_INITIAL_AGGRO; count++; @@ -3805,17 +3907,6 @@ void SpellMgr::LoadEnchantCustomAttr() sLog.outString(">> Loaded %u custom enchant attributes", count); } -bool SpellMgr::IsSkillTypeSpell(uint32 spellId, SkillType type) const -{ - SkillLineAbilityMapBounds bounds = GetSkillLineAbilityMapBounds(spellId); - - for (SkillLineAbilityMap::const_iterator _spell_idx = bounds.first; _spell_idx != bounds.second; ++_spell_idx) - if (_spell_idx->second->skillId == uint32(type)) - return true; - - return false; -} - void SpellMgr::LoadSpellLinked() { mSpellLinkedMap.clear(); // need for reload case diff --git a/src/server/game/Spells/SpellMgr.h b/src/server/game/Spells/SpellMgr.h index 224760029e7..872a19a27f1 100644 --- a/src/server/game/Spells/SpellMgr.h +++ b/src/server/game/Spells/SpellMgr.h @@ -28,9 +28,9 @@ #include "SpellAuraDefines.h" #include "DBCStructure.h" #include "DBCStores.h" -#include "Database/SQLStorage.h" +#include "SQLStorage.h" -#include "Utilities/UnorderedMap.h" +#include "UnorderedMap.h" #include "Player.h" @@ -192,7 +192,7 @@ AuraState GetSpellAuraState(SpellEntry const * spellInfo); inline float GetSpellRadiusForHostile(SpellRadiusEntry const *radius) { return (radius ? radius->radiusHostile : 0); } inline float GetSpellRadiusForFriend(SpellRadiusEntry const *radius) { return (radius ? radius->radiusFriend : 0); } uint32 GetSpellCastTime(SpellEntry const* spellInfo, Spell * spell = NULL); -int32 GetDispelChance(Unit* auraCaster, Unit* target, uint32 spellId, bool offensive, bool *result); +uint32 GetDispelChance(Unit* auraCaster, Unit* target, uint32 spellId, bool offensive, bool *result); inline float GetSpellMinRangeForHostile(SpellRangeEntry const *range) { return (range ? range->minRangeHostile : 0); } inline float GetSpellMaxRangeForHostile(SpellRangeEntry const *range) { return (range ? range->maxRangeHostile : 0); } inline float GetSpellMinRangeForFriend(SpellRangeEntry const *range) { return (range ? range->minRangeFriend : 0); } @@ -1212,6 +1212,8 @@ class SpellMgr bool IsSkillBonusSpell(uint32 spellId) const; bool IsSkillTypeSpell(uint32 spellId, SkillType type) const; + static int32 CalculateSpellEffectAmount(SpellEntry const * spellEntry, uint8 effIndex, Unit const * caster = NULL, int32 const * basePoints = NULL, Unit const * target = NULL); + static int32 CalculateSpellEffectBaseAmount(int32 value) {return value-1;}; // Spell correctess for client using static bool IsSpellValid(SpellEntry const * spellInfo, Player* pl = NULL, bool msg = true); @@ -1322,21 +1324,20 @@ class SpellMgr } void SetSpellDifficultyId(uint32 spellId, uint32 id) { mSpellDifficultySearcherMap[spellId] = id; } - const SpellsRequiringSpellMap GetSpellsRequiringSpell() - { - return this->mSpellsReqSpell; - } - - uint32 GetSpellRequired(uint32 spell_id) const - { - SpellRequiredMap::const_iterator itr = mSpellReq.find(spell_id); + const SpellsRequiringSpellMap GetSpellsRequiringSpell() + { + return this->mSpellsReqSpell; + } - if (itr == mSpellReq.end()) - return NULL; + uint32 GetSpellRequired(uint32 spell_id) const + { + SpellRequiredMap::const_iterator itr = mSpellReq.find(spell_id); - return itr->second; - } + if (itr == mSpellReq.end()) + return NULL; + return itr->second; + } // Modifiers public: diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 8ebcbce50c8..964e7f9b3b1 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -20,8 +20,8 @@ #include "Common.h" #include "PlayerDump.h" -#include "Database/DatabaseEnv.h" -#include "Database/SQLStorage.h" +#include "DatabaseEnv.h" +#include "SQLStorage.h" #include "UpdateFields.h" #include "ObjectMgr.h" diff --git a/src/server/game/Weather/Weather.cpp b/src/server/game/Weather/Weather.cpp index d74f945fd5a..0bfb7f19345 100644 --- a/src/server/game/Weather/Weather.cpp +++ b/src/server/game/Weather/Weather.cpp @@ -37,7 +37,7 @@ Weather::Weather(uint32 zone, WeatherZoneChances const* weatherChances) : m_zone m_type = WEATHER_TYPE_FINE; m_grade = 0; - sLog.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (MINUTE*IN_MILISECONDS))); + sLog.outDetail("WORLD: Starting weather system for zone %u (change every %u minutes).", m_zone, (uint32)(m_timer.GetInterval() / (MINUTE*IN_MILLISECONDS))); } /// Launch a weather update diff --git a/src/server/game/World/TimeMgr.cpp b/src/server/game/World/TimeMgr.cpp deleted file mode 100644 index 42ecc77bbf9..00000000000 --- a/src/server/game/World/TimeMgr.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2008-2010 Trinity <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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "TimeMgr.h" -#include "Policies/SingletonImp.h" - -INSTANTIATE_SINGLETON_1(GameTime); - -bool PeriodicTimer::Update(const uint32 &diff) -{ - if((i_expireTime -= diff) > 0) - return false; - - i_expireTime += i_period > diff ? i_period : diff; - return true; -} - -void PeriodicTimer::SetPeriodic(int32 period, int32 start_time) -{ - i_expireTime=start_time, i_period=period; -} diff --git a/src/server/game/World/TimeMgr.h b/src/server/game/World/TimeMgr.h deleted file mode 100644 index 5776bb1151c..00000000000 --- a/src/server/game/World/TimeMgr.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2008-2010 Trinity <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, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef _TIMEMGR_H -#define _TIMEMGR_H - -#include "Timer.h" -#include "Policies/Singleton.h" - -struct IntervalTimer -{ - public: - IntervalTimer() : _interval(0), _current(0) {} - - void Update(time_t diff) { _current += diff; if(_current<0) _current=0;} - bool Passed() { return _current >= _interval; } - void Reset() { if(_current >= _interval) _current -= _interval; } - - void SetCurrent(time_t current) { _current = current; } - void SetInterval(time_t interval) { _interval = interval; } - time_t GetInterval() const { return _interval; } - time_t GetCurrent() const { return _current; } - - private: - time_t _interval; - time_t _current; -}; - -template <typename T> struct TimeTrack -{ - public: - TimeTrack(T expire) : i_expireTime(expire) {} - void Update(T diff) { i_expireTime -= diff; } - bool Passed(void) const { return (i_expireTime <= 0); } - void Reset(T interval) { i_expireTime = interval; } - T GetExpireTime(void) const { return i_expireTime; } - private: - T i_expireTime; -}; - -typedef TimeTrack<time_t> TimeTracker; -typedef TimeTrack<int32> TimeTrackerSmall; - -struct PeriodicTimer -{ - public: - PeriodicTimer(int32 period, int32 start_time) : - i_expireTime(start_time), i_period(period) {} - - bool Update(const uint32 &diff); - void SetPeriodic(int32 period, int32 start_time); - - private: - int32 i_period; - int32 i_expireTime; -}; - -class GameTime -{ - public: - /// When server started? - time_t const& GetStartTime() const { return m_startTime; } - /// What time is it? - time_t const& GetGameTime() const { return m_gameTime; } - /// Uptime (in secs) - uint32 GetUptime() const { return uint32(m_gameTime - m_startTime); } - - void SetGameTime(void) { m_gameTime = time(NULL); } - void SetStartTime(void){ m_startTime = time(NULL); } - private: - time_t m_gameTime; - time_t m_startTime; -}; - -#define sGameTime Trinity::Singleton<GameTime>::Instance() - -#endif diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 0b00621dc72..05065140c35 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -23,8 +23,8 @@ */ #include "Common.h" -#include "Database/DatabaseEnv.h" -#include "Config/ConfigEnv.h" +#include "DatabaseEnv.h" +#include "ConfigEnv.h" #include "SystemConfig.h" #include "Log.h" #include "Opcodes.h" @@ -48,7 +48,6 @@ #include "ItemEnchantmentMgr.h" #include "MapManager.h" #include "CreatureAIRegistry.h" -#include "Policies/SingletonImp.h" #include "BattleGroundMgr.h" #include "OutdoorPvPMgr.h" #include "TemporarySummon.h" @@ -57,23 +56,21 @@ #include "VMapFactory.h" #include "GlobalEvents.h" #include "GameEventMgr.h" -#include "PoolHandler.h" -#include "Database/DatabaseImpl.h" +#include "PoolMgr.h" +#include "DatabaseImpl.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" #include "InstanceSaveMgr.h" #include "Util.h" #include "Language.h" #include "CreatureGroups.h" -#include "Transports.h" +#include "Transport.h" #include "ProgressBar.h" #include "ScriptMgr.h" #include "AddonMgr.h" #include "LFGMgr.h" #include "ConditionMgr.h" -INSTANTIATE_SINGLETON_1(World); - volatile bool World::m_stopEvent = false; uint8 World::m_ExitCode = SHUTDOWN_EXIT_CODE; volatile uint32 World::m_worldLoopCounter = 0; @@ -142,7 +139,7 @@ World::~World() VMAP::VMapFactory::clear(); - if (m_resultQueue) delete m_resultQueue; + delete m_resultQueue; //TODO free addSessQueue } @@ -316,17 +313,18 @@ int32 World::GetQueuePos(WorldSession* sess) void World::AddQueuedPlayer(WorldSession* sess) { sess->SetInQueue(true); - m_QueuedPlayer.push_back (sess); + m_QueuedPlayer.push_back(sess); // The 1st SMSG_AUTH_RESPONSE needs to contain other info too. - WorldPacket packet (SMSG_AUTH_RESPONSE, 1 + 4 + 1 + 4 + 1); - packet << uint8 (AUTH_WAIT_QUEUE); - packet << uint32 (0); // BillingTimeRemaining - packet << uint8 (0); // BillingPlanFlags - packet << uint32 (0); // BillingTimeRested - packet << uint8 (sess->Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account - packet << uint32(GetQueuePos (sess)); - sess->SendPacket (&packet); + WorldPacket packet(SMSG_AUTH_RESPONSE, 1+4+1+4+1); + packet << uint8(AUTH_WAIT_QUEUE); + packet << uint32(0); // BillingTimeRemaining + packet << uint8(0); // BillingPlanFlags + packet << uint32(0); // BillingTimeRested + packet << uint8(sess->Expansion()); // 0 - normal, 1 - TBC, 2 - WOTLK, must be set in database manually for each account + packet << uint32(GetQueuePos(sess)); // Queue position + packet << uint8(0); // Unk 3.3.0 + sess->SendPacket(&packet); //sess->SendAuthWaitQue (GetQueuePos (sess)); } @@ -616,7 +614,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_MAIL_LEVEL_REQ] = sConfig.GetIntDefault("LevelReq.Mail", 1); m_configs[CONFIG_ALLOW_PLAYER_COMMANDS] = sConfig.GetBoolDefault("AllowPlayerCommands", 1); m_configs[CONFIG_GRID_UNLOAD] = sConfig.GetBoolDefault("GridUnload", true); - m_configs[CONFIG_INTERVAL_SAVE] = sConfig.GetIntDefault("PlayerSaveInterval", 15 * MINUTE * IN_MILISECONDS); + m_configs[CONFIG_INTERVAL_SAVE] = sConfig.GetIntDefault("PlayerSaveInterval", 15 * MINUTE * IN_MILLISECONDS); m_configs[CONFIG_INTERVAL_DISCONNECT_TOLERANCE] = sConfig.GetIntDefault("DisconnectToleranceInterval", 0); m_configs[CONFIG_STATS_SAVE_ONLY_ON_LOGOUT] = sConfig.GetBoolDefault("PlayerSave.Stats.SaveOnlyOnLogout", true); @@ -627,14 +625,14 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_MIN_LEVEL_STAT_SAVE] = 0; } - m_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfig.GetIntDefault("GridCleanUpDelay", 5 * MINUTE * IN_MILISECONDS); + m_configs[CONFIG_INTERVAL_GRIDCLEAN] = sConfig.GetIntDefault("GridCleanUpDelay", 5 * MINUTE * IN_MILLISECONDS); if (m_configs[CONFIG_INTERVAL_GRIDCLEAN] < MIN_GRID_DELAY) { sLog.outError("GridCleanUpDelay (%i) must be greater %u. Use this minimal value.",m_configs[CONFIG_INTERVAL_GRIDCLEAN],MIN_GRID_DELAY); m_configs[CONFIG_INTERVAL_GRIDCLEAN] = MIN_GRID_DELAY; } if (reload) - MapManager::Instance().SetGridCleanUpDelay(m_configs[CONFIG_INTERVAL_GRIDCLEAN]); + sMapMgr.SetGridCleanUpDelay(m_configs[CONFIG_INTERVAL_GRIDCLEAN]); m_configs[CONFIG_INTERVAL_MAPUPDATE] = sConfig.GetIntDefault("MapUpdateInterval", 100); if (m_configs[CONFIG_INTERVAL_MAPUPDATE] < MIN_MAP_UPDATE_DELAY) @@ -643,15 +641,15 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_INTERVAL_MAPUPDATE] = MIN_MAP_UPDATE_DELAY; } if (reload) - MapManager::Instance().SetMapUpdateInterval(m_configs[CONFIG_INTERVAL_MAPUPDATE]); + sMapMgr.SetMapUpdateInterval(m_configs[CONFIG_INTERVAL_MAPUPDATE]); - m_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfig.GetIntDefault("ChangeWeatherInterval", 10 * MINUTE * IN_MILISECONDS); + m_configs[CONFIG_INTERVAL_CHANGEWEATHER] = sConfig.GetIntDefault("ChangeWeatherInterval", 10 * MINUTE * IN_MILLISECONDS); if (reload) { uint32 val = sConfig.GetIntDefault("WorldServerPort", DEFAULT_WORLDSERVER_PORT); if (val != m_configs[CONFIG_PORT_WORLD]) - sLog.outError("WorldServerPort option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[CONFIG_PORT_WORLD]); + sLog.outError("WorldServerPort option can't be changed at worldserver.conf reload, using current value (%u).",m_configs[CONFIG_PORT_WORLD]); } else m_configs[CONFIG_PORT_WORLD] = sConfig.GetIntDefault("WorldServerPort", DEFAULT_WORLDSERVER_PORT); @@ -660,7 +658,7 @@ void World::LoadConfigSettings(bool reload) { uint32 val = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME); if (val != m_configs[CONFIG_SOCKET_SELECTTIME]) - sLog.outError("SocketSelectTime option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[CONFIG_SOCKET_SELECTTIME]); + sLog.outError("SocketSelectTime option can't be changed at worldserver.conf reload, using current value (%u).",m_configs[CONFIG_SOCKET_SELECTTIME]); } else m_configs[CONFIG_SOCKET_SELECTTIME] = sConfig.GetIntDefault("SocketSelectTime", DEFAULT_SOCKET_SELECT_TIME); @@ -669,7 +667,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_SESSION_ADD_DELAY] = sConfig.GetIntDefault("SessionAddDelay", 10000); m_configs[CONFIG_GROUP_XP_DISTANCE] = sConfig.GetIntDefault("MaxGroupXPDistance", 74); - /// \todo Add MonsterSight and GuarderSight (with meaning) in Trinityd.conf or put them as define + /// \todo Add MonsterSight and GuarderSight (with meaning) in worldserver.conf or put them as define m_configs[CONFIG_SIGHT_MONSTER] = sConfig.GetIntDefault("MonsterSight", 50); m_configs[CONFIG_SIGHT_GUARDER] = sConfig.GetIntDefault("GuarderSight", 50); @@ -677,7 +675,7 @@ void World::LoadConfigSettings(bool reload) { uint32 val = sConfig.GetIntDefault("GameType", 0); if (val != m_configs[CONFIG_GAME_TYPE]) - sLog.outError("GameType option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[CONFIG_GAME_TYPE]); + sLog.outError("GameType option can't be changed at worldserver.conf reload, using current value (%u).",m_configs[CONFIG_GAME_TYPE]); } else m_configs[CONFIG_GAME_TYPE] = sConfig.GetIntDefault("GameType", 0); @@ -686,7 +684,7 @@ void World::LoadConfigSettings(bool reload) { uint32 val = sConfig.GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT); if (val != m_configs[CONFIG_REALM_ZONE]) - sLog.outError("RealmZone option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[CONFIG_REALM_ZONE]); + sLog.outError("RealmZone option can't be changed at worldserver.conf reload, using current value (%u).",m_configs[CONFIG_REALM_ZONE]); } else m_configs[CONFIG_REALM_ZONE] = sConfig.GetIntDefault("RealmZone", REALM_ZONE_DEVELOPMENT); @@ -865,7 +863,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_CAST_UNSTUCK] = sConfig.GetBoolDefault("CastUnstuck", true); m_configs[CONFIG_INSTANCE_RESET_TIME_HOUR] = sConfig.GetIntDefault("Instance.ResetTimeHour", 4); - m_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfig.GetIntDefault("Instance.UnloadDelay", 30 * MINUTE * IN_MILISECONDS); + m_configs[CONFIG_INSTANCE_UNLOAD_DELAY] = sConfig.GetIntDefault("Instance.UnloadDelay", 30 * MINUTE * IN_MILLISECONDS); m_configs[CONFIG_MAX_PRIMARY_TRADE_SKILL] = sConfig.GetIntDefault("MaxPrimaryTradeSkill", 2); m_configs[CONFIG_MIN_PETITION_SIGNS] = sConfig.GetIntDefault("MinPetitionSigns", 9); @@ -913,7 +911,7 @@ void World::LoadConfigSettings(bool reload) } if (reload) { - m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILISECONDS); + m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS); m_timers[WUPDATE_UPTIME].Reset(); } @@ -926,7 +924,7 @@ void World::LoadConfigSettings(bool reload) } if (reload) { - m_timers[WUPDATE_CLEANDB].SetInterval(m_configs[CONFIG_LOGDB_CLEARINTERVAL] * MINUTE * IN_MILISECONDS); + m_timers[WUPDATE_CLEANDB].SetInterval(m_configs[CONFIG_LOGDB_CLEARINTERVAL] * MINUTE * IN_MILLISECONDS); m_timers[WUPDATE_CLEANDB].Reset(); } m_configs[CONFIG_LOGDB_CLEARTIME] = sConfig.GetIntDefault("LogDB.Opt.ClearTime", 1209600); // 14 days default @@ -990,7 +988,7 @@ void World::LoadConfigSettings(bool reload) { uint32 val = sConfig.GetIntDefault("Expansion",1); if (val != m_configs[CONFIG_EXPANSION]) - sLog.outError("Expansion option can't be changed at Trinityd.conf reload, using current value (%u).",m_configs[CONFIG_EXPANSION]); + sLog.outError("Expansion option can't be changed at worldserver.conf reload, using current value (%u).",m_configs[CONFIG_EXPANSION]); } else m_configs[CONFIG_EXPANSION] = sConfig.GetIntDefault("Expansion",1); @@ -1015,6 +1013,7 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = sConfig.GetIntDefault("Quests.HighLevelHideDiff", 7); if (m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] > MAX_LEVEL) m_configs[CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF] = MAX_LEVEL; + m_configs[CONFIG_QUEST_IGNORE_RAID] = sConfig.GetBoolDefault("Quests.IgnoreRaid", false); m_configs[CONFIG_RANDOM_BG_RESET_HOUR] = sConfig.GetIntDefault("BattleGround.Random.ResetHour", 6); if (m_configs[CONFIG_RANDOM_BG_RESET_HOUR] < 0 || m_configs[CONFIG_RANDOM_BG_RESET_HOUR] > 23) @@ -1061,11 +1060,11 @@ void World::LoadConfigSettings(bool reload) m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.Enable", false); m_configs[CONFIG_BATTLEGROUND_QUEUE_ANNOUNCER_PLAYERONLY] = sConfig.GetBoolDefault("Battleground.QueueAnnouncer.PlayerOnly", false); m_configs[CONFIG_BATTLEGROUND_INVITATION_TYPE] = sConfig.GetIntDefault ("Battleground.InvitationType", 0); - m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault ("BattleGround.PrematureFinishTimer", 5 * MINUTE * IN_MILISECONDS); - m_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfig.GetIntDefault ("BattleGround.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILISECONDS); + m_configs[CONFIG_BATTLEGROUND_PREMATURE_FINISH_TIMER] = sConfig.GetIntDefault ("BattleGround.PrematureFinishTimer", 5 * MINUTE * IN_MILLISECONDS); + m_configs[CONFIG_BATTLEGROUND_PREMADE_GROUP_WAIT_FOR_MATCH] = sConfig.GetIntDefault ("BattleGround.PremadeGroupWaitForMatch", 30 * MINUTE * IN_MILLISECONDS); m_configs[CONFIG_BG_XP_FOR_KILL] = sConfig.GetBoolDefault("Battleground.GiveXPForKills", false); m_configs[CONFIG_ARENA_MAX_RATING_DIFFERENCE] = sConfig.GetIntDefault ("Arena.MaxRatingDifference", 150); - m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILISECONDS); + m_configs[CONFIG_ARENA_RATING_DISCARD_TIMER] = sConfig.GetIntDefault ("Arena.RatingDiscardTimer", 10 * MINUTE * IN_MILLISECONDS); m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_POINTS] = sConfig.GetBoolDefault("Arena.AutoDistributePoints", false); m_configs[CONFIG_ARENA_AUTO_DISTRIBUTE_INTERVAL_DAYS] = sConfig.GetIntDefault ("Arena.AutoDistributeInterval", 7); m_configs[CONFIG_ARENA_QUEUE_ANNOUNCER_ENABLE] = sConfig.GetBoolDefault("Arena.QueueAnnouncer.Enable", false); @@ -1180,7 +1179,7 @@ void World::LoadConfigSettings(bool reload) if (reload) { if (dataPath != m_dataPath) - sLog.outError("DataDir option can't be changed at Trinityd.conf reload, using current value (%s).",m_dataPath.c_str()); + sLog.outError("DataDir option can't be changed at worldserver.conf reload, using current value (%s).",m_dataPath.c_str()); } else { @@ -1273,7 +1272,7 @@ void World::SetInitialWorldSettings() ||m_configs[CONFIG_EXPANSION] && ( !MapManager::ExistMapAndVMap(530,10349.6f,-6357.29f) || !MapManager::ExistMapAndVMap(530,-3961.64f,-13931.2f))) { - sLog.outError("Correct *.map files not found in path '%smaps' or *.vmap/*vmdir files in '%svmaps'. Please place *.map/*.vmap/*.vmdir files in appropriate directories or correct the DataDir value in the Trinityd.conf file.",m_dataPath.c_str(),m_dataPath.c_str()); + sLog.outError("Correct *.map files not found in path '%smaps' or *.vmtree/*.vmtile files in '%svmaps'. Please place *.map/*.vmtree/*.vmtile files in appropriate directories or correct the DataDir value in the worldserver.conf file.",m_dataPath.c_str(),m_dataPath.c_str()); exit(1); } @@ -1319,6 +1318,7 @@ void World::SetInitialWorldSettings() objmgr.LoadCreatureLocales(); objmgr.LoadGameObjectLocales(); objmgr.LoadItemLocales(); + objmgr.LoadItemSetNameLocales(); objmgr.LoadQuestLocales(); objmgr.LoadNpcTextLocales(); objmgr.LoadPageTextLocales(); @@ -1331,7 +1331,7 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Page Texts..."); objmgr.LoadPageTexts(); - sLog.outString("Loading Game Object Templates..."); // must be after LoadPageTexts + sLog.outString("Loading Game Object Templates..."); // must be after LoadPageTexts objmgr.LoadGameobjectInfo(); sLog.outString("Loading Spell Rank Data..."); @@ -1370,9 +1370,12 @@ void World::SetInitialWorldSettings() sLog.outString("Loading Item Random Enchantments Table..."); LoadRandomEnchantmentsTable(); - sLog.outString("Loading Items..."); // must be after LoadRandomEnchantmentsTable and LoadPageTexts + sLog.outString("Loading Items..."); // must be after LoadRandomEnchantmentsTable and LoadPageTexts objmgr.LoadItemPrototypes(); + sLog.outString("Loading Item set names..."); // must be after LoadItemPrototypes + objmgr.LoadItemSetNames(); + sLog.outString("Loading Creature Model Based Info Data..."); objmgr.LoadCreatureModelInfo(); @@ -1407,15 +1410,15 @@ void World::SetInitialWorldSettings() objmgr.LoadCreatureAddons(); // must be after LoadCreatureTemplates() and LoadCreatures() sLog.outString("Loading Vehicle Accessories..."); - objmgr.LoadVehicleAccessories(); // must be after LoadCreatureTemplates() + objmgr.LoadVehicleAccessories(); // must be after LoadCreatureTemplates() - sLog.outString("Loading Creature Respawn Data..."); // must be after PackInstances() + sLog.outString("Loading Creature Respawn Data..."); // must be after PackInstances() objmgr.LoadCreatureRespawnTimes(); sLog.outString("Loading Gameobject Data..."); objmgr.LoadGameobjects(); - sLog.outString("Loading Gameobject Respawn Data..."); // must be after PackInstances() + sLog.outString("Loading Gameobject Respawn Data..."); // must be after PackInstances() objmgr.LoadGameobjectRespawnTimes(); sLog.outString("Loading Objects Pooling Data..."); @@ -1439,7 +1442,7 @@ void World::SetInitialWorldSettings() sLog.outString("Loading UNIT_NPC_FLAG_SPELLCLICK Data..."); objmgr.LoadNPCSpellClickSpells(); - sLog.outString("Loading SpellArea Data..."); // must be after quest load + sLog.outString("Loading SpellArea Data..."); // must be after quest load spellmgr.LoadSpellAreas(); sLog.outString("Loading AreaTrigger definitions..."); @@ -1602,7 +1605,7 @@ void World::SetInitialWorldSettings() sLog.outString(">>> Scripts loaded"); sLog.outString(); - sLog.outString("Loading Scripts text locales..."); // must be after Load*Scripts calls + sLog.outString("Loading Scripts text locales..."); // must be after Load*Scripts calls objmgr.LoadDbScriptStrings(); sLog.outString("Loading CreatureEventAI Texts..."); @@ -1635,24 +1638,24 @@ void World::SetInitialWorldSettings() static uint32 abtimer = 0; abtimer = sConfig.GetIntDefault("AutoBroadcast.Timer", 60000); - m_timers[WUPDATE_OBJECTS].SetInterval(IN_MILISECONDS/2); + m_timers[WUPDATE_OBJECTS].SetInterval(IN_MILLISECONDS/2); m_timers[WUPDATE_SESSIONS].SetInterval(0); - m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILISECONDS); - m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILISECONDS); - m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILISECONDS); + m_timers[WUPDATE_WEATHERS].SetInterval(1*IN_MILLISECONDS); + m_timers[WUPDATE_AUCTIONS].SetInterval(MINUTE*IN_MILLISECONDS); + m_timers[WUPDATE_UPTIME].SetInterval(m_configs[CONFIG_UPTIME_UPDATE]*MINUTE*IN_MILLISECONDS); //Update "uptime" table based on configuration entry in minutes. - m_timers[WUPDATE_CORPSES].SetInterval(20*MINUTE*IN_MILISECONDS); + m_timers[WUPDATE_CORPSES].SetInterval(20*MINUTE*IN_MILLISECONDS); //erase corpses every 20 minutes - m_timers[WUPDATE_CLEANDB].SetInterval(m_configs[CONFIG_LOGDB_CLEARINTERVAL]*MINUTE*IN_MILISECONDS); + m_timers[WUPDATE_CLEANDB].SetInterval(m_configs[CONFIG_LOGDB_CLEARINTERVAL]*MINUTE*IN_MILLISECONDS); // clean logs table every 14 days by default m_timers[WUPDATE_AUTOBROADCAST].SetInterval(abtimer); //to set mailtimer to return mails every day between 4 and 5 am //mailtimer is increased when updating auctions //one second is 1000 -(tested on win system) - mail_timer = ((((localtime(&m_gameTime)->tm_hour + 20) % 24)* HOUR * IN_MILISECONDS) / m_timers[WUPDATE_AUCTIONS].GetInterval()); + mail_timer = ((((localtime(&m_gameTime)->tm_hour + 20) % 24)* HOUR * IN_MILLISECONDS) / m_timers[WUPDATE_AUCTIONS].GetInterval()); //1440 - mail_timer_expires = ((DAY * IN_MILISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval())); + mail_timer_expires = ((DAY * IN_MILLISECONDS) / (m_timers[WUPDATE_AUCTIONS].GetInterval())); sLog.outDebug("Mail timer set to: %u, mail return is called every %u minutes", mail_timer, mail_timer_expires); ///- Initilize static helper structures @@ -1661,7 +1664,7 @@ void World::SetInitialWorldSettings() ///- Initialize MapManager sLog.outString("Starting Map System"); - MapManager::Instance().Initialize(); + sMapMgr.Initialize(); sLog.outString("Starting Game Event system..."); uint32 nextGameEvent = gameeventmgr.Initialize(); @@ -1670,7 +1673,7 @@ void World::SetInitialWorldSettings() sLog.outString("Starting Arena Season..."); gameeventmgr.StartArenaSeason(); - sLog.outString("Loading World States..."); // must be loaded before battleground and outdoor PvP + sLog.outString("Loading World States..."); // must be loaded before battleground and outdoor PvP LoadWorldStates(); ///- Initialize Looking For Group @@ -1688,10 +1691,7 @@ void World::SetInitialWorldSettings() //Not sure if this can be moved up in the sequence (with static data loading) as it uses MapManager sLog.outString("Loading Transports..."); - MapManager::Instance().LoadTransports(); - - sLog.outString("Loading Transports Events..."); - objmgr.LoadTransportEvents(); + sMapMgr.LoadTransports(); sLog.outString("Deleting expired bans..."); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate <= UNIX_TIMESTAMP() AND unbandate<>bandate"); @@ -1943,12 +1943,12 @@ void World::Update(uint32 diff) /// <li> Handle all other objects ///- Update objects when the timer has passed (maps, transport, creatures,...) - MapManager::Instance().Update(diff); // As interval = 0 + sMapMgr.Update(diff); // As interval = 0 /*if (m_timers[WUPDATE_OBJECTS].Passed()) { m_timers[WUPDATE_OBJECTS].Reset(); - MapManager::Instance().DoDelayedMovesAndRemoves(); + sMapMgr.DoDelayedMovesAndRemoves(); }*/ static uint32 autobroadcaston = 0; diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index 1a95253fa03..07d7d3c51db 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -27,7 +27,7 @@ #include "Common.h" #include "Timer.h" -#include "Policies/Singleton.h" +#include <ace/Singleton.h> #include "SharedDefines.h" #include "ace/Atomic_Op.h" #include "QueryResult.h" @@ -188,6 +188,7 @@ enum WorldConfigs CONFIG_WORLD_BOSS_LEVEL_DIFF, CONFIG_QUEST_LOW_LEVEL_HIDE_DIFF, CONFIG_QUEST_HIGH_LEVEL_HIDE_DIFF, + CONFIG_QUEST_IGNORE_RAID, CONFIG_DETECT_POS_COLLISION, CONFIG_RESTRICTED_LFG_CHANNEL, CONFIG_SILENTLY_GM_JOIN_TO_CHANNEL, @@ -779,6 +780,6 @@ class World extern uint32 realmID; -#define sWorld Trinity::Singleton<World>::Instance() +#define sWorld (*ACE_Singleton<World, ACE_Null_Mutex>::instance()) #endif /// @} |
