diff options
Diffstat (limited to 'src/server/game')
143 files changed, 2759 insertions, 2687 deletions
diff --git a/src/server/game/AI/CoreAI/PetAI.cpp b/src/server/game/AI/CoreAI/PetAI.cpp index 2522c97de25..c870f786af3 100644 --- a/src/server/game/AI/CoreAI/PetAI.cpp +++ b/src/server/game/AI/CoreAI/PetAI.cpp @@ -55,7 +55,7 @@ void PetAI::_stopAttack() { if (!me->IsAlive()) { - TC_LOG_DEBUG("misc", "Creature stoped attacking cuz his dead [guid=%u]", me->GetGUIDLow()); + TC_LOG_DEBUG("misc", "Creature stoped attacking cuz his dead [guid=%u]", me->GetGUID().GetCounter()); me->GetMotionMaster()->Clear(); me->GetMotionMaster()->MoveIdle(); me->CombatStop(); @@ -97,7 +97,7 @@ void PetAI::UpdateAI(uint32 diff) if (_needToStop()) { - TC_LOG_DEBUG("misc", "Pet AI stopped attacking [guid=%u]", me->GetGUIDLow()); + TC_LOG_DEBUG("misc", "Pet AI stopped attacking [guid=%u]", me->GetGUID().GetCounter()); _stopAttack(); return; } @@ -439,7 +439,7 @@ void PetAI::HandleReturnMovement() ClearCharmInfoFlags(); me->GetCharmInfo()->SetIsReturning(true); me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(me->GetGUIDLow(), x, y, z); + me->GetMotionMaster()->MovePoint(me->GetGUID().GetCounter(), x, y, z); } } else // COMMAND_FOLLOW @@ -492,7 +492,7 @@ void PetAI::MovementInform(uint32 moveType, uint32 data) { // Pet is returning to where stay was clicked. data should be // pet's GUIDLow since we set that as the waypoint ID - if (data == me->GetGUIDLow() && me->GetCharmInfo()->IsReturning()) + if (data == me->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning()) { ClearCharmInfoFlags(); me->GetCharmInfo()->SetIsAtStay(true); @@ -505,7 +505,7 @@ void PetAI::MovementInform(uint32 moveType, uint32 data) { // If data is owner's GUIDLow then we've reached follow point, // otherwise we're probably chasing a creature - if (me->GetCharmerOrOwner() && me->GetCharmInfo() && data == me->GetCharmerOrOwner()->GetGUIDLow() && me->GetCharmInfo()->IsReturning()) + if (me->GetCharmerOrOwner() && me->GetCharmInfo() && data == me->GetCharmerOrOwner()->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning()) { ClearCharmInfoFlags(); me->GetCharmInfo()->SetIsFollowing(true); diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp index 5aa6ea8ea7a..f0d9d34db69 100644 --- a/src/server/game/AI/CoreAI/UnitAI.cpp +++ b/src/server/game/AI/CoreAI/UnitAI.cpp @@ -29,7 +29,15 @@ void UnitAI::AttackStart(Unit* victim) { if (victim && me->Attack(victim, true)) + { + // Clear distracted state on attacking + if (me->HasUnitState(UNIT_STATE_DISTRACTED)) + { + me->ClearUnitState(UNIT_STATE_DISTRACTED); + me->GetMotionMaster()->Clear(); + } me->GetMotionMaster()->MoveChase(victim); + } } void UnitAI::AttackStartCaster(Unit* victim, float dist) diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h index 1939c96dac9..c93ed0db008 100644 --- a/src/server/game/AI/CoreAI/UnitAI.h +++ b/src/server/game/AI/CoreAI/UnitAI.h @@ -255,8 +255,8 @@ class UnitAI static void FillAISpellInfo(); virtual void sGossipHello(Player* /*player*/) { } - virtual void sGossipSelect(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/) { } - virtual void sGossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, char const* /*code*/) { } + virtual void sGossipSelect(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/) { } + virtual void sGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, char const* /*code*/) { } virtual void sQuestAccept(Player* /*player*/, Quest const* /*quest*/) { } virtual void sQuestSelect(Player* /*player*/, Quest const* /*quest*/) { } virtual void sQuestReward(Player* /*player*/, Quest const* /*quest*/, uint32 /*opt*/) { } diff --git a/src/server/game/AI/CreatureAISelector.cpp b/src/server/game/AI/CreatureAISelector.cpp index 07bd49bdcc6..d3e11733997 100644 --- a/src/server/game/AI/CreatureAISelector.cpp +++ b/src/server/game/AI/CreatureAISelector.cpp @@ -94,7 +94,7 @@ namespace FactorySelector // select NullCreatureAI if not another cases ainame = (ai_factory == NULL) ? "NullCreatureAI" : ai_factory->key(); - TC_LOG_DEBUG("scripts", "Creature %s (Entry: %u GUID: %u DB GUID: %u) is using AI type: %s.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUIDLow(), creature->GetDBTableGUIDLow(), ainame.c_str()); + TC_LOG_DEBUG("scripts", "Creature %s (Entry: %u GUID: %u DB GUID: %u) is using AI type: %s.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId(), ainame.c_str()); return (ai_factory == NULL ? new NullCreatureAI(creature) : ai_factory->Create(creature)); } @@ -141,7 +141,7 @@ namespace FactorySelector std::string ainame = (ai_factory == NULL || go->GetScriptId()) ? "NullGameObjectAI" : ai_factory->key(); - TC_LOG_DEBUG("scripts", "GameObject %u used AI is %s.", go->GetGUIDLow(), ainame.c_str()); + TC_LOG_DEBUG("scripts", "GameObject %u used AI is %s.", go->GetGUID().GetCounter(), ainame.c_str()); return (ai_factory == NULL ? new NullGameObjectAI(go) : ai_factory->Create(go)); } diff --git a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp index f1ba985458e..7b145268d22 100644 --- a/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp +++ b/src/server/game/AI/ScriptedAI/ScriptedCreature.cpp @@ -168,7 +168,7 @@ void ScriptedAI::DoPlaySoundToSet(WorldObject* source, uint32 soundId) if (!sSoundEntriesStore.LookupEntry(soundId)) { - TC_LOG_ERROR("scripts", "Invalid soundId %u used in DoPlaySoundToSet (Source: TypeId %u, GUID %u)", soundId, source->GetTypeId(), source->GetGUIDLow()); + TC_LOG_ERROR("scripts", "Invalid soundId %u used in DoPlaySoundToSet (Source: TypeId %u, GUID %u)", soundId, source->GetTypeId(), source->GetGUID().GetCounter()); return; } @@ -470,6 +470,7 @@ void BossAI::_Reset() if (!me->IsAlive()) return; + me->SetCombatPulseDelay(0); me->ResetLootMode(); events.Reset(); summons.DespawnAll(); @@ -500,6 +501,7 @@ void BossAI::_EnterCombat() instance->SetBossState(_bossId, IN_PROGRESS); } + me->SetCombatPulseDelay(5); me->setActive(true); DoZoneInCombat(); ScheduleTasks(); diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp index 1a51bb2d897..46cf934356d 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.cpp +++ b/src/server/game/AI/SmartScripts/SmartAI.cpp @@ -208,7 +208,7 @@ void SmartAI::EndPath(bool fail) if (targets->size() == 1 && GetScript()->IsPlayer((*targets->begin()))) { Player* player = (*targets->begin())->ToPlayer(); - if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse()) + if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse()) player->GroupEventHappens(mEscortQuestID, me); if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) @@ -220,7 +220,7 @@ void SmartAI::EndPath(bool fail) { Player* groupGuy = groupRef->GetSource(); - if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->GetCorpse()) + if (!fail && groupGuy->IsAtGroupRewardDistance(me) && !groupGuy->HasCorpse()) groupGuy->AreaExploredOrEventHappens(mEscortQuestID); if (fail && groupGuy->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) groupGuy->FailQuest(mEscortQuestID); @@ -233,7 +233,7 @@ void SmartAI::EndPath(bool fail) if (GetScript()->IsPlayer((*iter))) { Player* player = (*iter)->ToPlayer(); - if (!fail && player->IsAtGroupRewardDistance(me) && !player->GetCorpse()) + if (!fail && player->IsAtGroupRewardDistance(me) && !player->HasCorpse()) player->AreaExploredOrEventHappens(mEscortQuestID); if (fail && player->GetQuestStatus(mEscortQuestID) == QUEST_STATUS_INCOMPLETE) player->FailQuest(mEscortQuestID); @@ -453,45 +453,15 @@ void SmartAI::MoveInLineOfSight(Unit* who) GetScript()->OnMoveInLineOfSight(who); - if (me->HasReactState(REACT_PASSIVE) || AssistPlayerInCombat(who)) + if (AssistPlayerInCombat(who)) return; - if (!CanAIAttack(who)) - return; - - if (!me->CanStartAttack(who, false)) - return; - - if (me->IsHostileTo(who)) - { - float fAttackRadius = me->GetAttackDistance(who); - if (me->IsWithinDistInMap(who, fAttackRadius) && me->IsWithinLOSInMap(who)) - { - if (!me->GetVictim()) - { - // Clear distracted state on combat - if (me->HasUnitState(UNIT_STATE_DISTRACTED)) - { - me->ClearUnitState(UNIT_STATE_DISTRACTED); - me->GetMotionMaster()->Clear(); - } - - AttackStart(who); - } - else/* if (me->GetMap()->IsDungeon())*/ - { - who->SetInCombatWith(me); - me->AddThreat(who, 0.0f); - } - } - } + CreatureAI::MoveInLineOfSight(who); } bool SmartAI::CanAIAttack(const Unit* /*who*/) const { - if (me->GetReactState() == REACT_PASSIVE) - return false; - return true; + return !(me->HasReactState(REACT_PASSIVE)); } bool SmartAI::AssistPlayerInCombat(Unit* who) @@ -728,12 +698,12 @@ void SmartAI::sGossipHello(Player* player) GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_HELLO, player); } -void SmartAI::sGossipSelect(Player* player, uint32 sender, uint32 action) +void SmartAI::sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) { - GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, sender, action); + GetScript()->ProcessEventsFor(SMART_EVENT_GOSSIP_SELECT, player, menuId, gossipListId); } -void SmartAI::sGossipSelectCode(Player* /*player*/, uint32 /*sender*/, uint32 /*action*/, const char* /*code*/) { } +void SmartAI::sGossipSelectCode(Player* /*player*/, uint32 /*menuId*/, uint32 /*gossipListId*/, const char* /*code*/) { } void SmartAI::sQuestAccept(Player* player, Quest const* quest) { diff --git a/src/server/game/AI/SmartScripts/SmartAI.h b/src/server/game/AI/SmartScripts/SmartAI.h index 1e287cd5b9e..ea03a821846 100644 --- a/src/server/game/AI/SmartScripts/SmartAI.h +++ b/src/server/game/AI/SmartScripts/SmartAI.h @@ -175,8 +175,8 @@ class SmartAI : public CreatureAI void SetInvincibilityHpLevel(uint32 level) { mInvincibilityHpLevel = level; } void sGossipHello(Player* player) override; - void sGossipSelect(Player* player, uint32 sender, uint32 action) override; - void sGossipSelectCode(Player* player, uint32 sender, uint32 action, const char* code) override; + void sGossipSelect(Player* player, uint32 menuId, uint32 gossipListId) override; + void sGossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, const char* code) override; void sQuestAccept(Player* player, Quest const* quest) override; //void sQuestSelect(Player* player, Quest const* quest) override; void sQuestReward(Player* player, Quest const* quest, uint32 opt) override; diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index dadffe735d2..efee565e151 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -114,7 +114,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u mLastInvoker = unit->GetGUID(); if (Unit* tempInvoker = GetLastInvoker()) - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: Invoker: %s (guidlow: %u)", tempInvoker->GetName().c_str(), tempInvoker->GetGUIDLow()); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: Invoker: %s (guidlow: %u)", tempInvoker->GetName().c_str(), tempInvoker->GetGUID().GetCounter()); switch (e.GetActionType()) { @@ -162,7 +162,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u mUseTextTimer = true; sCreatureTextMgr->SendChat(talker, uint8(e.action.talk.textGroupID), talkTarget); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_TALK: talker: %s (GuidLow: %u), textGuid: %u", - talker->GetName().c_str(), talker->GetGUIDLow(), talkTarget ? talkTarget->GetGUIDLow() : 0); + talker->GetName().c_str(), talker->GetGUID().GetCounter(), talkTarget ? talkTarget->GetGUID().GetCounter() : 0); break; } case SMART_ACTION_SIMPLE_TALK: @@ -180,7 +180,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u sCreatureTextMgr->SendChat(me, uint8(e.action.talk.textGroupID), IsPlayer(templastInvoker) ? templastInvoker : 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_NORMAL, 0, TEAM_OTHER, false, (*itr)->ToPlayer()); } TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SIMPLE_TALK: talker: %s (GuidLow: %u), textGroupId: %u", - (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), uint8(e.action.talk.textGroupID)); + (*itr)->GetName().c_str(), (*itr)->GetGUID().GetCounter(), uint8(e.action.talk.textGroupID)); } delete targets; @@ -198,7 +198,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToUnit()->HandleEmoteCommand(e.action.emote.emote); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_PLAY_EMOTE: target: %s (GuidLow: %u), emote: %u", - (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.emote.emote); + (*itr)->GetName().c_str(), (*itr)->GetGUID().GetCounter(), e.action.emote.emote); } } @@ -217,7 +217,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->PlayDirectSound(e.action.sound.sound, e.action.sound.onlySelf ? (*itr)->ToPlayer() : nullptr); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SOUND: target: %s (GuidLow: %u), sound: %u, onlyself: %u", - (*itr)->GetName().c_str(), (*itr)->GetGUIDLow(), e.action.sound.sound, e.action.sound.onlySelf); + (*itr)->GetName().c_str(), (*itr)->GetGUID().GetCounter(), e.action.sound.sound, e.action.sound.onlySelf); } } @@ -238,7 +238,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToCreature()->setFaction(e.action.faction.factionID); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.faction.factionID); + (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), e.action.faction.factionID); } else { @@ -248,7 +248,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToCreature()->setFaction(ci->faction); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_FACTION: Creature entry %u, GuidLow %u set faction to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), ci->faction); + (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), ci->faction); } } } @@ -280,7 +280,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u uint32 displayId = ObjectMgr::ChooseDisplayId(ci); (*itr)->ToCreature()->SetDisplayId(displayId); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), displayId); + (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), displayId); } } //if no param1, then use value from param2 (modelId) @@ -288,14 +288,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToCreature()->SetDisplayId(e.action.morphOrMount.model); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u set displayid to %u", - (*itr)->GetEntry(), (*itr)->GetGUIDLow(), e.action.morphOrMount.model); + (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter(), e.action.morphOrMount.model); } } else { (*itr)->ToCreature()->DeMorph(); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_MORPH_TO_ENTRY_OR_MODEL: Creature entry %u, GuidLow %u demorphs.", - (*itr)->GetEntry(), (*itr)->GetGUIDLow()); + (*itr)->GetEntry(), (*itr)->GetGUID().GetCounter()); } } @@ -314,7 +314,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToPlayer()->FailQuest(e.action.quest.quest); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FAIL_QUEST: Player guidLow %u fails quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); + (*itr)->GetGUID().GetCounter(), e.action.quest.quest); } } @@ -335,7 +335,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToPlayer()->AddQuestAndCheckCompletion(q, NULL); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_QUEST: Player guidLow %u add quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); + (*itr)->GetGUID().GetCounter(), e.action.quest.quest); } } } @@ -397,7 +397,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u uint32 emote = temp[urand(0, count - 1)]; (*itr)->ToUnit()->HandleEmoteCommand(emote); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RANDOM_EMOTE: Creature guidLow %u handle random emote %u", - (*itr)->GetGUIDLow(), emote); + (*itr)->GetGUID().GetCounter(), emote); } } @@ -416,7 +416,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { me->getThreatManager().modifyThreatPercent(target, e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_ALL_PCT: Creature guidLow %u modify threat for unit %u, value %i", - me->GetGUIDLow(), target->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); + me->GetGUID().GetCounter(), target->GetGUID().GetCounter(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); } } break; @@ -436,7 +436,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { me->getThreatManager().modifyThreatPercent((*itr)->ToUnit(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_THREAT_SINGLE_PCT: Creature guidLow %u modify threat for unit %u, value %i", - me->GetGUIDLow(), (*itr)->GetGUIDLow(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); + me->GetGUID().GetCounter(), (*itr)->GetGUID().GetCounter(), e.action.threatPCT.threatINC ? (int32)e.action.threatPCT.threatINC : -(int32)e.action.threatPCT.threatDEC); } } @@ -463,7 +463,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u (*itr)->ToPlayer()->GroupEventHappens(e.action.quest.quest, me); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS: Player guidLow %u credited quest %u", - (*itr)->GetGUIDLow(), e.action.quest.quest); + (*itr)->GetGUID().GetCounter(), e.action.quest.quest); } } @@ -512,7 +512,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u go->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_CAST:: %s: %u casts spell %u on target %u with castflags %u", - (me ? me->GetGUID() : go->GetGUID()).GetTypeName(), me ? me->GetGUIDLow() : go->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags); + (me ? me->GetGUID() : go->GetGUID()).GetTypeName(), me ? me->GetGUID().GetCounter() : go->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.flags); } else TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str()); @@ -543,7 +543,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u tempLastInvoker->CastSpell((*itr)->ToUnit(), e.action.cast.spell, (e.action.cast.flags & SMARTCAST_TRIGGERED) != 0); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INVOKER_CAST: Invoker %u casts spell %u on target %u with castflags %u", - tempLastInvoker->GetGUIDLow(), e.action.cast.spell, (*itr)->GetGUIDLow(), e.action.cast.flags); + tempLastInvoker->GetGUID().GetCounter(), e.action.cast.spell, (*itr)->GetGUID().GetCounter(), e.action.cast.flags); } else TC_LOG_DEBUG("scripts.ai", "Spell %u not cast because it has flag SMARTCAST_AURA_NOT_PRESENT and the target (%s) already has the aura", e.action.cast.spell, (*itr)->GetGUID().ToString().c_str()); @@ -564,7 +564,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToUnit()->AddAura(e.action.cast.spell, (*itr)->ToUnit()); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ADD_AURA: Adding aura %u to unit %u", - e.action.cast.spell, (*itr)->GetGUIDLow()); + e.action.cast.spell, (*itr)->GetGUID().GetCounter()); } } @@ -585,7 +585,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u (*itr)->ToGameObject()->SetLootState(GO_READY); (*itr)->ToGameObject()->UseDoorOrButton(0, false, unit); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ACTIVATE_GOBJECT. Gameobject %u (entry: %u) activated", - (*itr)->GetGUIDLow(), (*itr)->GetEntry()); + (*itr)->GetGUID().GetCounter(), (*itr)->GetEntry()); } } @@ -604,7 +604,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToGameObject()->ResetDoorOrButton(); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_RESET_GOBJECT. Gameobject %u (entry: %u) reset", - (*itr)->GetGUIDLow(), (*itr)->GetEntry()); + (*itr)->GetGUID().GetCounter(), (*itr)->GetEntry()); } } @@ -623,7 +623,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToUnit()->SetUInt32Value(UNIT_NPC_EMOTESTATE, e.action.emote.emote); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EMOTE_STATE. Unit %u set emotestate to %u", - (*itr)->GetGUIDLow(), e.action.emote.emote); + (*itr)->GetGUID().GetCounter(), e.action.emote.emote); } } @@ -644,13 +644,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS", - (*itr)->GetGUIDLow(), e.action.unitFlag.flag); + (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag); } else { (*itr)->ToUnit()->SetFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_UNIT_FLAG. Unit %u added flag %u to UNIT_FIELD_FLAGS_2", - (*itr)->GetGUIDLow(), e.action.unitFlag.flag); + (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag); } } } @@ -672,13 +672,13 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS, e.action.unitFlag.flag); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS", - (*itr)->GetGUIDLow(), e.action.unitFlag.flag); + (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag); } else { (*itr)->ToUnit()->RemoveFlag(UNIT_FIELD_FLAGS_2, e.action.unitFlag.flag); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_REMOVE_UNIT_FLAG. Unit %u removed flag %u to UNIT_FIELD_FLAGS_2", - (*itr)->GetGUIDLow(), e.action.unitFlag.flag); + (*itr)->GetGUID().GetCounter(), e.action.unitFlag.flag); } } } @@ -693,7 +693,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u ENSURE_AI(SmartAI, me->AI())->SetAutoAttack(e.action.autoAttack.attack != 0); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_AUTO_ATTACK: Creature: %u bool on = %u", - me->GetGUIDLow(), e.action.autoAttack.attack); + me->GetGUID().GetCounter(), e.action.autoAttack.attack); break; } case SMART_ACTION_ALLOW_COMBAT_MOVEMENT: @@ -704,7 +704,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u bool move = e.action.combatMove.move != 0; ENSURE_AI(SmartAI, me->AI())->SetCombatMove(move); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_ALLOW_COMBAT_MOVEMENT: Creature %u bool on = %u", - me->GetGUIDLow(), e.action.combatMove.move); + me->GetGUID().GetCounter(), e.action.combatMove.move); break; } case SMART_ACTION_SET_EVENT_PHASE: @@ -714,7 +714,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u SetPhase(e.action.setEventPhase.phase); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_SET_EVENT_PHASE: Creature %u set event phase %u", - GetBaseObject()->GetGUIDLow(), e.action.setEventPhase.phase); + GetBaseObject()->GetGUID().GetCounter(), e.action.setEventPhase.phase); break; } case SMART_ACTION_INC_EVENT_PHASE: @@ -725,7 +725,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u IncPhase(e.action.incEventPhase.inc); DecPhase(e.action.incEventPhase.dec); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_INC_EVENT_PHASE: Creature %u inc event phase by %u, " - "decrease by %u", GetBaseObject()->GetGUIDLow(), e.action.incEventPhase.inc, e.action.incEventPhase.dec); + "decrease by %u", GetBaseObject()->GetGUID().GetCounter(), e.action.incEventPhase.inc, e.action.incEventPhase.dec); break; } case SMART_ACTION_EVADE: @@ -734,7 +734,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; me->AI()->EnterEvadeMode(); - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_EVADE: Creature %u EnterEvadeMode", me->GetGUIDLow()); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_EVADE: Creature %u EnterEvadeMode", me->GetGUID().GetCounter()); break; } case SMART_ACTION_FLEE_FOR_ASSIST: @@ -748,7 +748,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u Trinity::BroadcastTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, BROADCAST_TEXT_FLEE_FOR_ASSIST); sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE); } - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %u DoFleeToGetAssistance", me->GetGUIDLow()); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction:: SMART_ACTION_FLEE_FOR_ASSIST: Creature %u DoFleeToGetAssistance", me->GetGUID().GetCounter()); break; } case SMART_ACTION_CALL_GROUPEVENTHAPPENS: @@ -760,7 +760,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { unit->ToPlayer()->GroupEventHappens(e.action.quest.quest, GetBaseObject()); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_GROUPEVENTHAPPENS: Player %u, group credit for quest %u", - unit->GetGUIDLow(), e.action.quest.quest); + unit->GetGUID().GetCounter(), e.action.quest.quest); } // Special handling for vehicles @@ -804,7 +804,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u (*itr)->ToUnit()->RemoveAllAuras(); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_REMOVEAURASFROMSPELL: Unit %u, spell %u", - (*itr)->GetGUIDLow(), e.action.removeAura.spell); + (*itr)->GetGUID().GetCounter(), e.action.removeAura.spell); } delete targets; @@ -828,7 +828,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { ENSURE_AI(SmartAI, me->AI())->SetFollow((*itr)->ToUnit(), (float)e.action.follow.dist, (float)e.action.follow.angle, e.action.follow.credit, e.action.follow.entry, e.action.follow.creditType); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_FOLLOW: Creature %u following target %u", - me->GetGUIDLow(), (*itr)->GetGUIDLow()); + me->GetGUID().GetCounter(), (*itr)->GetGUID().GetCounter()); break; } } @@ -865,7 +865,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u uint32 phase = temp[urand(0, count - 1)]; SetPhase(phase); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE: Creature %u sets event phase to %u", - GetBaseObject()->GetGUIDLow(), phase); + GetBaseObject()->GetGUID().GetCounter(), phase); break; } case SMART_ACTION_RANDOM_PHASE_RANGE: @@ -876,7 +876,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u uint32 phase = urand(e.action.randomPhaseRange.phaseMin, e.action.randomPhaseRange.phaseMax); SetPhase(phase); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_RANDOM_PHASE_RANGE: Creature %u sets event phase to %u", - GetBaseObject()->GetGUIDLow(), phase); + GetBaseObject()->GetGUID().GetCounter(), phase); break; } case SMART_ACTION_CALL_KILLEDMONSTER: @@ -890,7 +890,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { player->RewardPlayerAndGroupAtEvent(e.action.killedMonster.creature, player); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", - player->GetGUIDLow(), e.action.killedMonster.creature); + player->GetGUID().GetCounter(), e.action.killedMonster.creature); } } else // Specific target type @@ -905,7 +905,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { (*itr)->ToPlayer()->KilledMonsterCredit(e.action.killedMonster.creature); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_KILLEDMONSTER: Player %u, Killcredit: %u", - (*itr)->GetGUIDLow(), e.action.killedMonster.creature); + (*itr)->GetGUID().GetCounter(), e.action.killedMonster.creature); } else if (IsUnit(*itr)) // Special handling for vehicles if (Vehicle* vehicle = (*itr)->ToUnit()->GetVehicleKit()) @@ -985,7 +985,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (me && !me->isDead()) { me->Kill(me); - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature %u", me->GetGUIDLow()); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_DIE: Creature %u", me->GetGUID().GetCounter()); } break; } @@ -994,7 +994,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u if (me) { me->SetInCombatWithZone(); - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: Creature %u", me->GetGUIDLow()); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_IN_COMBAT_WITH_ZONE: Creature %u", me->GetGUID().GetCounter()); } break; } @@ -1008,7 +1008,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u Trinity::BroadcastTextBuilder builder(me, CHAT_MSG_MONSTER_EMOTE, BROADCAST_TEXT_CALL_FOR_HELP); sCreatureTextMgr->SendChatPacket(me, builder, CHAT_MSG_MONSTER_EMOTE); } - TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %u", me->GetGUIDLow()); + TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_CALL_FOR_HELP: Creature %u", me->GetGUID().GetCounter()); } break; } @@ -1018,7 +1018,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u { me->SetSheath(SheathState(e.action.setSheath.sheath)); TC_LOG_DEBUG("scripts.ai", "SmartScript::ProcessAction: SMART_ACTION_SET_SHEATH: Creature %u, State: %u", - me->GetGUIDLow(), e.action.setSheath.sheath); + me->GetGUID().GetCounter(), e.action.setSheath.sheath); } break; } @@ -1136,6 +1136,14 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, x, y, z); break; } + case SMART_ACTION_RISE_UP: + { + if (!me) + break; + + me->GetMotionMaster()->MovePoint(SMART_RANDOM_POINT, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ() + (float)e.action.moveRandom.distance); + break; + } case SMART_ACTION_SET_VISIBILITY: { if (me) @@ -3471,14 +3479,14 @@ void SmartScript::GetScript() SmartAIEventList e; if (me) { - e = sSmartScriptMgr->GetScript(-((int32)me->GetDBTableGUIDLow()), mScriptType); + e = sSmartScriptMgr->GetScript(-((int32)me->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)me->GetEntry(), mScriptType); FillScript(e, me, NULL); } else if (go) { - e = sSmartScriptMgr->GetScript(-((int32)go->GetDBTableGUIDLow()), mScriptType); + e = sSmartScriptMgr->GetScript(-((int32)go->GetSpawnId()), mScriptType); if (e.empty()) e = sSmartScriptMgr->GetScript((int32)go->GetEntry(), mScriptType); FillScript(e, go, NULL); @@ -3668,5 +3676,12 @@ void SmartScript::SetScript9(SmartScriptHolder& e, uint32 entry) Unit* SmartScript::GetLastInvoker() { - return ObjectAccessor::FindUnit(mLastInvoker); + WorldObject* lookupRoot = me; + if (!lookupRoot) + lookupRoot = go; + + if (lookupRoot) + return ObjectAccessor::GetUnit(*lookupRoot, mLastInvoker); + + return ObjectAccessor::FindPlayer(mLastInvoker); } diff --git a/src/server/game/AI/SmartScripts/SmartScript.h b/src/server/game/AI/SmartScripts/SmartScript.h index 51628eded54..cb338cd3584 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.h +++ b/src/server/game/AI/SmartScripts/SmartScript.h @@ -118,7 +118,7 @@ class SmartScript smart = false; if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action called by Creature (GUID: %u Entry: %u) skipped to prevent crash.", c ? c->GetDBTableGUIDLow() : 0, c ? c->GetEntry() : 0, me ? me->GetDBTableGUIDLow() : 0, me ? me->GetEntry() : 0); + TC_LOG_ERROR("sql.sql", "SmartScript: Action target Creature (GUID: %u Entry: %u) is not using SmartAI, action called by Creature (GUID: %u Entry: %u) skipped to prevent crash.", c ? c->GetSpawnId() : 0, c ? c->GetEntry() : 0, me ? me->GetSpawnId() : 0, me ? me->GetEntry() : 0); return smart; } @@ -132,7 +132,7 @@ class SmartScript if (!go || go->GetAIName() != "SmartGameObjectAI") smart = false; if (!smart) - TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: %u Entry: %u) skipped to prevent crash.", g ? g->GetDBTableGUIDLow() : 0, g ? g->GetEntry() : 0, go ? go->GetDBTableGUIDLow() : 0, go ? go->GetEntry() : 0); + TC_LOG_ERROR("sql.sql", "SmartScript: Action target GameObject (GUID: %u Entry: %u) is not using SmartGameObjectAI, action called by GameObject (GUID: %u Entry: %u) skipped to prevent crash.", g ? g->GetSpawnId() : 0, g ? g->GetEntry() : 0, go ? go->GetSpawnId() : 0, go ? go->GetEntry() : 0); return smart; } @@ -177,33 +177,25 @@ class SmartScript GameObject* FindGameObjectNear(WorldObject* searchObject, uint32 guid) const { - GameObject* gameObject = NULL; + auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; - CellCoord p(Trinity::ComputeCellCoord(searchObject->GetPositionX(), searchObject->GetPositionY())); - Cell cell(p); - - Trinity::GameObjectWithDbGUIDCheck goCheck(*searchObject, guid); - Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(searchObject, gameObject, goCheck); - - TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > objectChecker(checker); - cell.Visit(p, objectChecker, *searchObject->GetMap(), *searchObject, searchObject->GetGridActivationRange()); - - return gameObject; + return bounds.first->second; } Creature* FindCreatureNear(WorldObject* searchObject, uint32 guid) const { - Creature* creature = NULL; - CellCoord p(Trinity::ComputeCellCoord(searchObject->GetPositionX(), searchObject->GetPositionY())); - Cell cell(p); + auto bounds = searchObject->GetMap()->GetCreatureBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; - Trinity::CreatureWithDbGUIDCheck target_check(searchObject, guid); - Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(searchObject, creature, target_check); - - TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker); - cell.Visit(p, unit_checker, *searchObject->GetMap(), *searchObject, searchObject->GetGridActivationRange()); + auto creatureItr = std::find_if(bounds.first, bounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair) + { + return pair.second->IsAlive(); + }); - return creature; + return creatureItr != bounds.second ? creatureItr->second : bounds.first->second; } ObjectListMap* mTargetStorage; @@ -211,20 +203,27 @@ class SmartScript void OnReset(); void ResetBaseObject() { - if (meOrigGUID) + WorldObject* lookupRoot = me; + if (!lookupRoot) + lookupRoot = go; + + if (lookupRoot) { - if (Creature* m = HashMapHolder<Creature>::Find(meOrigGUID)) + if (!meOrigGUID) { - me = m; - go = NULL; + if (Creature* m = ObjectAccessor::GetCreature(*lookupRoot, meOrigGUID)) + { + me = m; + go = NULL; + } } - } - if (goOrigGUID) - { - if (GameObject* o = HashMapHolder<GameObject>::Find(goOrigGUID)) + if (!goOrigGUID) { - me = NULL; - go = o; + if (GameObject* o = ObjectAccessor::GetGameObject(*lookupRoot, goOrigGUID)) + { + me = NULL; + go = o; + } } } goOrigGUID.Clear(); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 6ccc581c54e..f0e3c3caff6 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1198,6 +1198,7 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_ADD_GO_FLAG: case SMART_ACTION_REMOVE_GO_FLAG: case SMART_ACTION_SUMMON_CREATURE_GROUP: + case SMART_ACTION_RISE_UP: break; default: TC_LOG_ERROR("sql.sql", "SmartAIMgr: Not handled action_type(%u), event_type(%u), Entry %d SourceType %u Event %u, skipped.", e.GetActionType(), e.GetEventType(), e.entryOrGuid, e.GetScriptType(), e.event_id); diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 60a4ce5e8ed..2f9b032c14c 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -539,8 +539,9 @@ enum SMART_ACTION SMART_ACTION_GAME_EVENT_STOP = 111, // GameEventId SMART_ACTION_GAME_EVENT_START = 112, // GameEventId SMART_ACTION_START_CLOSEST_WAYPOINT = 113, // wp1, wp2, wp3, wp4, wp5, wp6, wp7 + SMART_ACTION_RISE_UP = 114, // distance - SMART_ACTION_END = 114 + SMART_ACTION_END = 115 }; struct SmartAction diff --git a/src/server/game/Accounts/AccountMgr.cpp b/src/server/game/Accounts/AccountMgr.cpp index 0b85addfbf8..7ec1665bffc 100644 --- a/src/server/game/Accounts/AccountMgr.cpp +++ b/src/server/game/Accounts/AccountMgr.cpp @@ -81,7 +81,7 @@ AccountOpResult AccountMgr::DeleteAccount(uint32 accountId) { do { - ObjectGuid guid(HIGHGUID_PLAYER, (*result)[0].GetUInt32()); + ObjectGuid guid(HighGuid::Player, (*result)[0].GetUInt32()); // Kick if player is online if (Player* p = ObjectAccessor::FindConnectedPlayer(guid)) diff --git a/src/server/game/Achievements/AchievementMgr.cpp b/src/server/game/Achievements/AchievementMgr.cpp index 51106d7cfe1..2662273697f 100644 --- a/src/server/game/Achievements/AchievementMgr.cpp +++ b/src/server/game/Achievements/AchievementMgr.cpp @@ -522,11 +522,11 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_BY_ACHIEVEMENT); stmt->setUInt16(0, iter->first); - stmt->setUInt32(1, GetPlayer()->GetGUIDLow()); + stmt->setUInt32(1, GetPlayer()->GetGUID().GetCounter()); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT); - stmt->setUInt32(0, GetPlayer()->GetGUIDLow()); + stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter()); stmt->setUInt16(1, iter->first); stmt->setUInt32(2, uint32(iter->second.date)); trans->Append(stmt); @@ -543,14 +543,14 @@ void AchievementMgr::SaveToDB(SQLTransaction& trans) continue; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACHIEVEMENT_PROGRESS_BY_CRITERIA); - stmt->setUInt32(0, GetPlayer()->GetGUIDLow()); + stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter()); stmt->setUInt16(1, iter->first); trans->Append(stmt); if (iter->second.counter) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACHIEVEMENT_PROGRESS); - stmt->setUInt32(0, GetPlayer()->GetGUIDLow()); + stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter()); stmt->setUInt16(1, iter->first); stmt->setUInt32(2, iter->second.counter); stmt->setUInt32(3, uint32(iter->second.date)); @@ -1356,7 +1356,7 @@ void AchievementMgr::SetCriteriaProgress(AchievementCriteriaEntry const* entry, if (entry->timeLimit && timedIter == m_timedAchievements.end()) return; - TC_LOG_DEBUG("achievement", "AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUIDLow()); + TC_LOG_DEBUG("achievement", "AchievementMgr::SetCriteriaProgress(%u, %u) for (GUID:%u)", entry->ID, changeValue, m_player->GetGUID().GetCounter()); CriteriaProgress* progress = GetCriteriaProgress(entry); if (!progress) @@ -1509,7 +1509,7 @@ void AchievementMgr::CompletedAchievement(AchievementEntry const* achievement) return; TC_LOG_DEBUG("achievement", "AchievementMgr::CompletedAchievement(%u). Player: %s (%u)", - achievement->ID, m_player->GetName().c_str(), m_player->GetGUIDLow()); + achievement->ID, m_player->GetName().c_str(), m_player->GetGUID().GetCounter()); SendAchievementEarned(achievement); CompletedAchievementData& ca = m_completedAchievements[achievement->ID]; diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp index 4b48f1f341b..1809e306a45 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.cpp +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.cpp @@ -61,12 +61,25 @@ AuctionHouseObject* AuctionHouseMgr::GetAuctionsMap(uint32 factionTemplateId) return &mNeutralAuctions; } +AuctionHouseObject* AuctionHouseMgr::GetAuctionsMapByHouseId(uint8 auctionHouseId) +{ + if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) + return &mNeutralAuctions; + + switch(auctionHouseId) + { + case AUCTIONHOUSE_ALLIANCE : return &mAllianceAuctions; + case AUCTIONHOUSE_HORDE : return &mHordeAuctions; + default : return &mNeutralAuctions; + } +} + uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item* pItem, uint32 count) { uint32 MSV = pItem->GetTemplate()->SellPrice; if (MSV <= 0) - return AH_MINIMUM_DEPOSIT; + return AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT); float multiplier = CalculatePct(float(entry->depositPercent), 3); uint32 timeHr = (((time / 60) / 60) / 12); @@ -77,8 +90,8 @@ uint32 AuctionHouseMgr::GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 TC_LOG_DEBUG("auctionHouse", "Multiplier: %f", multiplier); TC_LOG_DEBUG("auctionHouse", "Deposit: %u", deposit); - if (deposit < AH_MINIMUM_DEPOSIT) - return AH_MINIMUM_DEPOSIT; + if (deposit < AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT)) + return AH_MINIMUM_DEPOSIT * sWorld->getRate(RATE_AUCTION_DEPOSIT); else return deposit; } @@ -91,7 +104,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& return; uint32 bidderAccId = 0; - ObjectGuid bidderGuid(HIGHGUID_PLAYER, auction->bidder); + ObjectGuid bidderGuid(HighGuid::Player, auction->bidder); Player* bidder = ObjectAccessor::FindConnectedPlayer(bidderGuid); // data for gm.log std::string bidderName; @@ -114,7 +127,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& if (logGmTrade) { - ObjectGuid ownerGuid = ObjectGuid(HIGHGUID_PLAYER, auction->owner); + ObjectGuid ownerGuid = ObjectGuid(HighGuid::Player, auction->owner); std::string ownerName; if (!sObjectMgr->GetPlayerNameByGUID(ownerGuid, ownerName)) ownerName = sObjectMgr->GetTrinityStringForDBCLocale(LANG_UNKNOWN); @@ -132,7 +145,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& // owner in `data` will set at mail receive and item extracting PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER); stmt->setUInt32(0, auction->bidder); - stmt->setUInt32(1, pItem->GetGUIDLow()); + stmt->setUInt32(1, pItem->GetGUID().GetCounter()); trans->Append(stmt); if (bidder) @@ -155,7 +168,7 @@ void AuctionHouseMgr::SendAuctionWonMail(AuctionEntry* auction, SQLTransaction& void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTransaction& trans) { - ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner); + ObjectGuid owner_guid(HighGuid::Player, auction->owner); Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid); // owner exist (online or offline) @@ -167,7 +180,7 @@ void AuctionHouseMgr::SendAuctionSalePendingMail(AuctionEntry* auction, SQLTrans //call this method to send mail to auction owner, when auction is successful, it does not clear ram void AuctionHouseMgr::SendAuctionSuccessfulMail(AuctionEntry* auction, SQLTransaction& trans) { - ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner); + ObjectGuid owner_guid(HighGuid::Player, auction->owner); Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid); // owner exist @@ -198,7 +211,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti if (!pItem) return; - ObjectGuid owner_guid(HIGHGUID_PLAYER, auction->owner); + ObjectGuid owner_guid(HighGuid::Player, auction->owner); Player* owner = ObjectAccessor::FindConnectedPlayer(owner_guid); uint32 owner_accId = sObjectMgr->GetPlayerAccountIdByGUID(owner_guid); // owner exist @@ -221,7 +234,7 @@ void AuctionHouseMgr::SendAuctionExpiredMail(AuctionEntry* auction, SQLTransacti //this function sends mail to old bidder void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 newPrice, Player* newBidder, SQLTransaction& trans) { - ObjectGuid oldBidder_guid(HIGHGUID_PLAYER, auction->bidder); + ObjectGuid oldBidder_guid(HighGuid::Player, auction->bidder); Player* oldBidder = ObjectAccessor::FindConnectedPlayer(oldBidder_guid); uint32 oldBidder_accId = 0; @@ -243,7 +256,7 @@ void AuctionHouseMgr::SendAuctionOutbiddedMail(AuctionEntry* auction, uint32 new //this function sends mail, when auction is cancelled to old bidder void AuctionHouseMgr::SendAuctionCancelledToBidderMail(AuctionEntry* auction, SQLTransaction& trans) { - ObjectGuid bidder_guid = ObjectGuid(HIGHGUID_PLAYER, auction->bidder); + ObjectGuid bidder_guid = ObjectGuid(HighGuid::Player, auction->bidder); Player* bidder = ObjectAccessor::FindConnectedPlayer(bidder_guid); uint32 bidder_accId = 0; @@ -342,7 +355,7 @@ void AuctionHouseMgr::LoadAuctions() continue; } - GetAuctionsMap(aItem->factionTemplateId)->AddAuction(aItem); + GetAuctionsMapByHouseId(aItem->houseId)->AddAuction(aItem); ++count; } while (result->NextRow()); @@ -355,8 +368,8 @@ void AuctionHouseMgr::LoadAuctions() void AuctionHouseMgr::AddAItem(Item* it) { ASSERT(it); - ASSERT(mAitems.find(it->GetGUIDLow()) == mAitems.end()); - mAitems[it->GetGUIDLow()] = it; + ASSERT(mAitems.find(it->GetGUID().GetCounter()) == mAitems.end()); + mAitems[it->GetGUID().GetCounter()] = it; } bool AuctionHouseMgr::RemoveAItem(uint32 id, bool deleteItem) @@ -385,44 +398,32 @@ void AuctionHouseMgr::Update() AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntry(uint32 factionTemplateId) { - uint32 houseid = 7; // goblin auction house + uint32 houseid = AUCTIONHOUSE_NEUTRAL; // goblin auction house if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) { // FIXME: found way for proper auctionhouse selection by another way // AuctionHouse.dbc have faction field with _player_ factions associated with auction house races. // but no easy way convert creature faction to player race faction for specific city - switch (factionTemplateId) - { - case 12: houseid = 1; break; // human - case 29: houseid = 6; break; // orc, and generic for horde - case 55: houseid = 2; break; // dwarf, and generic for alliance - case 68: houseid = 4; break; // undead - case 80: houseid = 3; break; // n-elf - case 104: houseid = 5; break; // trolls - case 120: houseid = 7; break; // booty bay, neutral - case 474: houseid = 7; break; // gadgetzan, neutral - case 855: houseid = 7; break; // everlook, neutral - case 1604: houseid = 6; break; // b-elfs, - default: // for unknown case - { - FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId); - if (!u_entry) - houseid = 7; // goblin auction house - else if (u_entry->ourMask & FACTION_MASK_ALLIANCE) - houseid = 1; // human auction house - else if (u_entry->ourMask & FACTION_MASK_HORDE) - houseid = 6; // orc auction house - else - houseid = 7; // goblin auction house - break; - } - } + FactionTemplateEntry const* u_entry = sFactionTemplateStore.LookupEntry(factionTemplateId); + if (!u_entry) + houseid = AUCTIONHOUSE_NEUTRAL; // goblin auction house + else if (u_entry->ourMask & FACTION_MASK_ALLIANCE) + houseid = AUCTIONHOUSE_ALLIANCE; // human auction house + else if (u_entry->ourMask & FACTION_MASK_HORDE) + houseid = AUCTIONHOUSE_HORDE; // orc auction house + else + houseid = AUCTIONHOUSE_NEUTRAL; // goblin auction house } return sAuctionHouseStore.LookupEntry(houseid); } +AuctionHouseEntry const* AuctionHouseMgr::GetAuctionHouseEntryFromHouse(uint8 houseId) +{ + return (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) ? sAuctionHouseStore.LookupEntry(AUCTIONHOUSE_NEUTRAL) : sAuctionHouseStore.LookupEntry(houseId); +} + void AuctionHouseObject::AddAuction(AuctionEntry* auction) { ASSERT(auction); @@ -498,7 +499,7 @@ void AuctionHouseObject::BuildListBidderItems(WorldPacket& data, Player* player, for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) { AuctionEntry* Aentry = itr->second; - if (Aentry && Aentry->bidder == player->GetGUIDLow()) + if (Aentry && Aentry->bidder == player->GetGUID().GetCounter()) { if (itr->second->BuildAuctionInfo(data)) ++count; @@ -513,7 +514,7 @@ void AuctionHouseObject::BuildListOwnerItems(WorldPacket& data, Player* player, for (AuctionEntryMap::const_iterator itr = AuctionsMap.begin(); itr != AuctionsMap.end(); ++itr) { AuctionEntry* Aentry = itr->second; - if (Aentry && Aentry->owner == player->GetGUIDLow()) + if (Aentry && Aentry->owner == player->GetGUID().GetCounter()) { if (Aentry->BuildAuctionInfo(data)) ++count; @@ -687,7 +688,7 @@ void AuctionEntry::SaveToDB(SQLTransaction& trans) const { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AUCTION); stmt->setUInt32(0, Id); - stmt->setUInt32(1, auctioneer); + stmt->setUInt8(1, houseId); stmt->setUInt32(2, itemGUIDLow); stmt->setUInt32(3, owner); stmt->setUInt32(4, buyout); @@ -702,7 +703,7 @@ void AuctionEntry::SaveToDB(SQLTransaction& trans) const bool AuctionEntry::LoadFromDB(Field* fields) { Id = fields[0].GetUInt32(); - auctioneer = fields[1].GetUInt32(); + houseId = fields[1].GetUInt8(); itemGUIDLow = fields[2].GetUInt32(); itemEntry = fields[3].GetUInt32(); itemCount = fields[4].GetUInt32(); @@ -714,25 +715,10 @@ bool AuctionEntry::LoadFromDB(Field* fields) startbid = fields[10].GetUInt32(); deposit = fields[11].GetUInt32(); - CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(auctioneer); - if (!auctioneerData) - { - TC_LOG_ERROR("misc", "Auction %u has not a existing auctioneer (GUID : %u)", Id, auctioneer); - return false; - } - - CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id); - if (!auctioneerInfo) - { - TC_LOG_ERROR("misc", "Auction %u has not a existing auctioneer (GUID : %u Entry: %u)", Id, auctioneer, auctioneerData->id); - return false; - } - - factionTemplateId = auctioneerInfo->faction; - auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntry(factionTemplateId); + auctionHouseEntry = AuctionHouseMgr::GetAuctionHouseEntryFromHouse(houseId); if (!auctionHouseEntry) { - TC_LOG_ERROR("misc", "Auction %u has auctioneer (GUID : %u Entry: %u) with wrong faction %u", Id, auctioneer, auctioneerData->id, factionTemplateId); + TC_LOG_ERROR("misc", "Auction %u has invalid house id %u", Id, houseId); return false; } @@ -756,7 +742,7 @@ std::string AuctionEntry::BuildAuctionMailBody(uint32 lowGuid, uint32 bid, uint3 { std::ostringstream strm; strm.width(16); - strm << std::right << std::hex << ObjectGuid(HIGHGUID_PLAYER, lowGuid).GetRawValue(); // HIGHGUID_PLAYER always present, even for empty guids + strm << std::right << std::hex << ObjectGuid(HighGuid::Player, lowGuid).GetRawValue(); // HighGuid::Player always present, even for empty guids strm << std::dec << ':' << bid << ':' << buyout; strm << ':' << deposit << ':' << cut; return strm.str(); diff --git a/src/server/game/AuctionHouse/AuctionHouseMgr.h b/src/server/game/AuctionHouse/AuctionHouseMgr.h index d67c8143996..f05d8583329 100644 --- a/src/server/game/AuctionHouse/AuctionHouseMgr.h +++ b/src/server/game/AuctionHouse/AuctionHouseMgr.h @@ -61,10 +61,17 @@ enum MailAuctionAnswers AUCTION_SALE_PENDING = 6 }; +enum AuctionHouses +{ + AUCTIONHOUSE_ALLIANCE = 2, + AUCTIONHOUSE_HORDE = 6, + AUCTIONHOUSE_NEUTRAL = 7 +}; + struct AuctionEntry { uint32 Id; - uint32 auctioneer; // creature low guid + uint8 houseId; uint32 itemGUIDLow; uint32 itemEntry; uint32 itemCount; @@ -76,11 +83,9 @@ struct AuctionEntry uint32 bidder; uint32 deposit; //deposit can be calculated only when creating auction AuctionHouseEntry const* auctionHouseEntry; // in AuctionHouse.dbc - uint32 factionTemplateId; // helpers - uint32 GetHouseId() const { return auctionHouseEntry->houseId; } - uint32 GetHouseFaction() const { return auctionHouseEntry->faction; } + uint8 GetHouseId() const { return houseId; } uint32 GetAuctionCut() const; uint32 GetAuctionOutBid() const; bool BuildAuctionInfo(WorldPacket & data) const; @@ -148,6 +153,7 @@ class AuctionHouseMgr typedef std::unordered_map<uint32, Item*> ItemMap; AuctionHouseObject* GetAuctionsMap(uint32 factionTemplateId); + AuctionHouseObject* GetAuctionsMapByHouseId(uint8 auctionHouseId); AuctionHouseObject* GetBidsMap(uint32 factionTemplateId); Item* GetAItem(uint32 id) @@ -169,7 +175,7 @@ class AuctionHouseMgr static uint32 GetAuctionDeposit(AuctionHouseEntry const* entry, uint32 time, Item* pItem, uint32 count); static AuctionHouseEntry const* GetAuctionHouseEntry(uint32 factionTemplateId); - + static AuctionHouseEntry const* GetAuctionHouseEntryFromHouse(uint8 houseId); public: //load first auction items, because of check if item exists, when loading diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp index 4bf6aa950c6..80c32cf66e7 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotBuyer.cpp @@ -102,6 +102,10 @@ uint32 AuctionBotBuyer::GetItemInformation(BuyerConfiguration& config) for (AuctionHouseObject::AuctionEntryMap::const_iterator itr = house->GetAuctionsBegin(); itr != house->GetAuctionsEnd(); ++itr) { AuctionEntry* entry = itr->second; + + if (!entry->owner) + continue; // Skip auctions owned by AHBot + Item* item = sAuctionMgr->GetAItem(entry->itemGUIDLow); if (!item) continue; @@ -135,10 +139,10 @@ uint32 AuctionBotBuyer::GetItemInformation(BuyerConfiguration& config) itemInfo.MinBuyPrice = std::min(itemInfo.MinBuyPrice, itemBuyPrice); } - // Add/update to EligibleItems if: - // has a bid by player or - // has no bids and not owned by bot - if ((entry->bid && entry->bidder) || (entry->owner && !entry->bid)) + // Add/update EligibleItems if: + // * no bid + // * bid from player + if (!entry->bid || entry->bidder) { config.EligibleItems[entry->Id].LastExist = now; config.EligibleItems[entry->Id].AuctionId = entry->Id; diff --git a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp index 733bd5e9ec8..22dc5bb0bd0 100644 --- a/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp +++ b/src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp @@ -906,15 +906,17 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config) items = sAuctionBotConfig->GetItemPerCycleNormal(); uint32 houseid = 0; - uint32 auctioneer = 0; switch (config.GetHouseType()) { case AUCTION_HOUSE_ALLIANCE: - houseid = 1; auctioneer = 79707; break; + houseid = AUCTIONHOUSE_ALLIANCE; + break; case AUCTION_HOUSE_HORDE: - houseid = 6; auctioneer = 4656; break; + houseid = AUCTIONHOUSE_HORDE; + break; default: - houseid = 7; auctioneer = 23442; break; + houseid = AUCTIONHOUSE_NEUTRAL; + break; } AuctionHouseEntry const* ahEntry = sAuctionHouseStore.LookupEntry(houseid); @@ -991,11 +993,11 @@ void AuctionBotSeller::AddNewAuctions(SellerConfiguration& config) AuctionEntry* auctionEntry = new AuctionEntry(); auctionEntry->Id = sObjectMgr->GenerateAuctionID(); auctionEntry->owner = 0; - auctionEntry->itemGUIDLow = item->GetGUIDLow(); + auctionEntry->itemGUIDLow = item->GetGUID().GetCounter(); auctionEntry->itemEntry = item->GetEntry(); auctionEntry->startbid = bidPrice; auctionEntry->buyout = buyoutPrice; - auctionEntry->auctioneer = auctioneer; + auctionEntry->houseId = houseid; auctionEntry->bidder = 0; auctionEntry->bid = 0; auctionEntry->deposit = sAuctionMgr->GetAuctionDeposit(ahEntry, etime, item, stackCount); diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index a22db18fa7e..d22ac0ea5d5 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -695,7 +695,7 @@ void BfGraveyard::Resurrect() player->CastSpell(player, 6962, true); player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true); - sObjectAccessor->ConvertCorpseForPlayer(player->GetGUID()); + player->SpawnCorpseBones(false); } m_ResurrectQueue.clear(); @@ -770,7 +770,7 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl } Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, PHASEMASK_NORMAL, entry, x, y, z, o)) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnCreature: Can't create creature entry: %u", entry); delete creature; @@ -803,7 +803,7 @@ GameObject* Battlefield::SpawnGameObject(uint32 entry, float x, float y, float z // Create gameobject GameObject* go = new GameObject; - if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, PHASEMASK_NORMAL, x, y, z, o, 0, 0, 0, 0, 100, GO_STATE_READY)) + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, PHASEMASK_NORMAL, x, y, z, o, 0, 0, 0, 0, 100, GO_STATE_READY)) { TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Gameobject template %u not found in database! Battlefield not created!", entry); TC_LOG_ERROR("bg.battlefield", "Battlefield::SpawnGameObject: Cannot create gameobject template %u! Battlefield not created!", entry); @@ -901,7 +901,7 @@ bool BfCapturePoint::SetCapturePointData(GameObject* capturePoint) TC_LOG_DEBUG("bg.battlefield", "Creating capture point %u", capturePoint->GetEntry()); - m_capturePointGUID = ObjectGuid(HIGHGUID_GAMEOBJECT, capturePoint->GetEntry(), capturePoint->GetGUIDLow()); + m_capturePointGUID = ObjectGuid(HighGuid::GameObject, capturePoint->GetEntry(), capturePoint->GetGUID().GetCounter()); // check info existence GameObjectTemplate const* goinfo = capturePoint->GetGOInfo(); diff --git a/src/server/game/Battlefield/BattlefieldMgr.cpp b/src/server/game/Battlefield/BattlefieldMgr.cpp index 0060cf4f304..00da81fb992 100644 --- a/src/server/game/Battlefield/BattlefieldMgr.cpp +++ b/src/server/game/Battlefield/BattlefieldMgr.cpp @@ -80,7 +80,7 @@ void BattlefieldMgr::HandlePlayerEnterZone(Player* player, uint32 zoneId) return; bf->HandlePlayerEnterZone(player, zoneId); - TC_LOG_DEBUG("bg.battlefield", "Player %u entered battlefield id %u", player->GetGUIDLow(), bf->GetTypeId()); + TC_LOG_DEBUG("bg.battlefield", "Player %u entered battlefield id %u", player->GetGUID().GetCounter(), bf->GetTypeId()); } void BattlefieldMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneId) @@ -94,7 +94,7 @@ void BattlefieldMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneId) return; itr->second->HandlePlayerLeaveZone(player, zoneId); - TC_LOG_DEBUG("bg.battlefield", "Player %u left battlefield id %u", player->GetGUIDLow(), itr->second->GetTypeId()); + TC_LOG_DEBUG("bg.battlefield", "Player %u left battlefield id %u", player->GetGUID().GetCounter(), itr->second->GetTypeId()); } Battlefield* BattlefieldMgr::GetBattlefieldToZoneId(uint32 zoneId) diff --git a/src/server/game/Battlegrounds/Arena.cpp b/src/server/game/Battlegrounds/Arena.cpp index dc0388348fc..60cc609a06a 100644 --- a/src/server/game/Battlegrounds/Arena.cpp +++ b/src/server/game/Battlegrounds/Arena.cpp @@ -40,7 +40,7 @@ Arena::Arena() void Arena::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); + PlayerScores[player->GetGUID().GetCounter()] = new ArenaScore(player->GetGUID(), player->GetBGTeam()); if (player->GetBGTeam() == ALLIANCE) // gold { @@ -177,7 +177,7 @@ void Arena::EndBattleground(uint32 winner) if (sWorld->getBoolConfig(CONFIG_ARENA_LOG_EXTENDED_INFO)) for (auto const& score : PlayerScores) - if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, score.first))) + if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HighGuid::Player, score.first))) { TC_LOG_DEBUG("bg.arena", "Statistics match Type: %u for %s (GUID: %u, Team: %d, IP: %s): %s", GetArenaType(), player->GetName().c_str(), score.first, player->GetArenaTeamId(GetArenaType() == 5 ? 2 : GetArenaType() == 3), diff --git a/src/server/game/Battlegrounds/ArenaTeam.cpp b/src/server/game/Battlegrounds/ArenaTeam.cpp index 3b7e9ac3f33..e75c07d8946 100644 --- a/src/server/game/Battlegrounds/ArenaTeam.cpp +++ b/src/server/game/Battlegrounds/ArenaTeam.cpp @@ -193,7 +193,7 @@ bool ArenaTeam::LoadArenaTeamFromDB(QueryResult result) TeamId = fields[0].GetUInt32(); TeamName = fields[1].GetString(); - CaptainGuid = ObjectGuid(HIGHGUID_PLAYER, fields[2].GetUInt32()); + CaptainGuid = ObjectGuid(HighGuid::Player, fields[2].GetUInt32()); Type = fields[3].GetUInt8(); BackgroundColor = fields[4].GetUInt32(); EmblemStyle = fields[5].GetUInt8(); @@ -232,7 +232,7 @@ bool ArenaTeam::LoadMembersFromDB(QueryResult result) break; ArenaTeamMember newMember; - newMember.Guid = ObjectGuid(HIGHGUID_PLAYER, fields[1].GetUInt32()); + newMember.Guid = ObjectGuid(HighGuid::Player, fields[1].GetUInt32()); newMember.WeekGames = fields[2].GetUInt16(); newMember.WeekWins = fields[3].GetUInt16(); newMember.SeasonGames = fields[4].GetUInt16(); @@ -305,8 +305,8 @@ void ArenaTeam::SetCaptain(ObjectGuid guid) if (oldCaptain) { TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] promoted player: %s [GUID: %u] to leader of arena team [Id: %u, Name: %s] [Type: %u].", - oldCaptain->GetName().c_str(), oldCaptain->GetGUIDLow(), newCaptain->GetName().c_str(), - newCaptain->GetGUIDLow(), GetId(), GetName().c_str(), GetType()); + oldCaptain->GetName().c_str(), oldCaptain->GetGUID().GetCounter(), newCaptain->GetName().c_str(), + newCaptain->GetGUID().GetCounter(), GetId(), GetName().c_str(), GetType()); } } } @@ -328,7 +328,7 @@ void ArenaTeam::DelMember(ObjectGuid guid, bool cleanDb) // delete all info regarding this team for (uint32 i = 0; i < ARENA_TEAM_END; ++i) player->SetArenaTeamInfoField(GetSlot(), ArenaTeamInfoType(i), 0); - TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] left arena team type: %u [Id: %u, Name: %s].", player->GetName().c_str(), player->GetGUIDLow(), GetType(), GetId(), GetName().c_str()); + TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] left arena team type: %u [Id: %u, Name: %s].", player->GetName().c_str(), player->GetGUID().GetCounter(), GetType(), GetId(), GetName().c_str()); } // Only used for single member deletion, for arena team disband we use a single query for more efficiency @@ -353,7 +353,7 @@ void ArenaTeam::Disband(WorldSession* session) BroadcastEvent(ERR_ARENA_TEAM_DISBANDED_S, ObjectGuid::Empty, 2, session->GetPlayerName(), GetName(), ""); if (Player* player = session->GetPlayer()) - TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u, Name: %s].", player->GetName().c_str(), player->GetGUIDLow(), GetType(), GetId(), GetName().c_str()); + TC_LOG_DEBUG("bg.arena", "Player: %s [GUID: %u] disbanded arena team type: %u [Id: %u, Name: %s].", player->GetName().c_str(), player->GetGUID().GetCounter(), GetType(), GetId(), GetName().c_str()); } // Update database diff --git a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp index d54f7814137..4fdb34e8d2f 100644 --- a/src/server/game/Battlegrounds/ArenaTeamMgr.cpp +++ b/src/server/game/Battlegrounds/ArenaTeamMgr.cpp @@ -158,7 +158,7 @@ void ArenaTeamMgr::DistributeArenaPoints() for (std::map<uint32, uint32>::iterator playerItr = PlayerPoints.begin(); playerItr != PlayerPoints.end(); ++playerItr) { // Add points to player if online - if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, playerItr->first))) + if (Player* player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HighGuid::Player, playerItr->first))) player->ModifyArenaPoints(playerItr->second, trans); else // Update database { diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index 3e9b68d4611..ad8a7b9e729 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -367,7 +367,7 @@ inline void Battleground::_ProcessResurrect(uint32 diff) player->ResurrectPlayer(1.0f); player->CastSpell(player, 6962, true); player->CastSpell(player, SPELL_SPIRIT_HEAL_MANA, true); - sObjectAccessor->ConvertCorpseForPlayer(*itr); + player->SpawnCorpseBones(false); } m_ResurrectQueue.clear(); } @@ -782,10 +782,10 @@ void Battleground::EndBattleground(uint32 winner) if (isBattleground() && sWorld->getBoolConfig(CONFIG_BATTLEGROUND_STORE_STATISTICS_ENABLE)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PVPSTATS_PLAYER); - BattlegroundScoreMap::const_iterator score = PlayerScores.find(player->GetGUIDLow()); + BattlegroundScoreMap::const_iterator score = PlayerScores.find(player->GetGUID().GetCounter()); stmt->setUInt32(0, battlegroundId); - stmt->setUInt32(1, player->GetGUIDLow()); + stmt->setUInt32(1, player->GetGUID().GetCounter()); stmt->setUInt32(2, score->second->GetKillingBlows()); stmt->setUInt32(3, score->second->GetDeaths()); stmt->setUInt32(4, score->second->GetHonorableKills()); @@ -889,8 +889,11 @@ void Battleground::RemovePlayerAtLeave(ObjectGuid guid, bool Transport, bool Sen player->SpawnCorpseBones(); } } - else // try to resurrect the offline player. If he is alive nothing will happen - sObjectAccessor->ConvertCorpseForPlayer(guid); + else + { + SQLTransaction trans(nullptr); + Player::OfflineResurrect(guid, trans); + } RemovePlayer(player, guid, team); // BG subclass specific code @@ -1251,7 +1254,7 @@ void Battleground::BuildPvPLogDataPacket(WorldPacket& data) bool Battleground::UpdatePlayerScore(Player* player, uint32 type, uint32 value, bool doAddHonor) { - BattlegroundScoreMap::const_iterator itr = PlayerScores.find(player->GetGUIDLow()); + BattlegroundScoreMap::const_iterator itr = PlayerScores.find(player->GetGUID().GetCounter()); if (itr == PlayerScores.end()) // player not found... return false; @@ -1326,7 +1329,7 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created // So we must create it specific for this instance GameObject* go = new GameObject; - if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, GetBgMap(), + if (!go->Create(GetBgMap()->GenerateLowGuid<HighGuid::GameObject>(), entry, GetBgMap(), PHASEMASK_NORMAL, x, y, z, o, rotation0, rotation1, rotation2, rotation3, 100, goState)) { TC_LOG_ERROR("bg.battleground", "Battleground::AddObject: cannot create gameobject (entry: %u) for BG (map: %u, instance id: %u)!", @@ -1335,7 +1338,7 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float return false; } /* - uint32 guid = go->GetGUIDLow(); + uint32 guid = go->GetGUID().GetCounter(); // without this, UseButtonOrDoor caused the crash, since it tried to get go info from godata // iirc that was changed, so adding to go data map is no longer required if that was the only function using godata from GameObject without checking if it existed @@ -1469,7 +1472,7 @@ Creature* Battleground::AddCreature(uint32 entry, uint32 type, float x, float y, Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, x, y, z, o)) + if (!creature->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, PHASEMASK_NORMAL, entry, x, y, z, o)) { TC_LOG_ERROR("bg.battleground", "Battleground::AddCreature: cannot create creature (entry: %u) for BG (map: %u, instance id: %u)!", entry, m_MapId, m_InstanceID); diff --git a/src/server/game/Battlegrounds/BattlegroundQueue.cpp b/src/server/game/Battlegrounds/BattlegroundQueue.cpp index d9950f4ccbc..73c0f1c22a5 100644 --- a/src/server/game/Battlegrounds/BattlegroundQueue.cpp +++ b/src/server/game/Battlegrounds/BattlegroundQueue.cpp @@ -476,7 +476,7 @@ bool BattlegroundQueue::InviteGroupToBG(GroupQueueInfo* ginfo, Battleground* bg, uint32 queueSlot = player->GetBattlegroundQueueIndex(bgQueueTypeId); TC_LOG_DEBUG("bg.battleground", "Battleground: invited player %s (%u) to BG instance %u queueindex %u bgtype %u", - player->GetName().c_str(), player->GetGUIDLow(), bg->GetInstanceID(), queueSlot, bg->GetTypeID()); + player->GetName().c_str(), player->GetGUID().GetCounter(), bg->GetInstanceID(), queueSlot, bg->GetTypeID()); // send status packet sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_JOIN, INVITE_ACCEPT_WAIT_TIME, 0, ginfo->ArenaType, 0); @@ -1041,7 +1041,7 @@ bool BGQueueRemoveEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) BattlegroundQueue &bgQueue = sBattlegroundMgr->GetBattlegroundQueue(m_BgQueueTypeId); if (bgQueue.IsPlayerInvited(m_PlayerGuid, m_BgInstanceGUID, m_RemoveTime)) { - TC_LOG_DEBUG("bg.battleground", "Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.", player->GetGUIDLow(), m_BgInstanceGUID); + TC_LOG_DEBUG("bg.battleground", "Battleground: removing player %u from bg queue for instance %u because of not pressing enter battle in time.", player->GetGUID().GetCounter(), m_BgInstanceGUID); player->RemoveBattlegroundQueueId(m_BgQueueTypeId); bgQueue.RemovePlayer(m_PlayerGuid, true); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 00b6862369d..f9d32e68e0e 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -222,7 +222,7 @@ void BattlegroundAB::StartingEventOpenDoors() void BattlegroundAB::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new BattlegroundABScore(player->GetGUID()); + PlayerScores[player->GetGUID().GetCounter()] = new BattlegroundABScore(player->GetGUID()); } void BattlegroundAB::RemovePlayer(Player* /*player*/, ObjectGuid /*guid*/, uint32 /*team*/) @@ -309,7 +309,7 @@ int32 BattlegroundAB::_GetNodeNameId(uint8 node) case BG_AB_NODE_LUMBER_MILL:return LANG_BG_AB_NODE_LUMBER_MILL; case BG_AB_NODE_GOLD_MINE: return LANG_BG_AB_NODE_GOLD_MINE; default: - ASSERT(false); + ABORT(); } return 0; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index 9c654a1793c..4ac02bab9ec 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -302,7 +302,7 @@ Creature* BattlegroundAV::AddAVCreature(uint16 cinfoid, uint16 type) if (!isStatic && ((cinfoid >= AV_NPC_A_GRAVEDEFENSE0 && cinfoid <= AV_NPC_A_GRAVEDEFENSE3) || (cinfoid >= AV_NPC_H_GRAVEDEFENSE0 && cinfoid <= AV_NPC_H_GRAVEDEFENSE3))) { - CreatureData &data = sObjectMgr->NewOrExistCreatureData(creature->GetDBTableGUIDLow()); + CreatureData &data = sObjectMgr->NewOrExistCreatureData(creature->GetSpawnId()); data.spawndist = 5; } //else spawndist will be 15, so creatures move maximum=10 @@ -435,7 +435,7 @@ void BattlegroundAV::StartingEventOpenDoors() void BattlegroundAV::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new BattlegroundAVScore(player->GetGUID()); + PlayerScores[player->GetGUID().GetCounter()] = new BattlegroundAVScore(player->GetGUID()); } void BattlegroundAV::EndBattleground(uint32 winner) @@ -789,7 +789,7 @@ BG_AV_Nodes BattlegroundAV::GetNodeThroughObject(uint32 object) if (object == BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE) return BG_AV_NODES_SNOWFALL_GRAVE; TC_LOG_ERROR("bg.battleground", "BattlegroundAV: ERROR! GetPlace got a wrong object :("); - ASSERT(false); + ABORT(); return BG_AV_Nodes(0); } @@ -827,7 +827,7 @@ uint32 BattlegroundAV::GetObjectThroughNode(BG_AV_Nodes node) else if (m_Nodes[node].Owner == AV_NEUTRAL_TEAM) return BG_AV_OBJECT_FLAG_N_SNOWFALL_GRAVE; TC_LOG_ERROR("bg.battleground", "BattlegroundAV: Error! GetPlaceNode couldn't resolve node %i", node); - ASSERT(false); + ABORT(); return 0; } @@ -1402,22 +1402,22 @@ void BattlegroundAV::AssaultNode(BG_AV_Nodes node, uint16 team) if (m_Nodes[node].TotalOwner == team) { TC_LOG_FATAL("bg.battleground", "Assaulting team is TotalOwner of node"); - ASSERT(false); + ABORT(); } if (m_Nodes[node].Owner == team) { TC_LOG_FATAL("bg.battleground", "Assaulting team is owner of node"); - ASSERT(false); + ABORT(); } if (m_Nodes[node].State == POINT_DESTROYED) { TC_LOG_FATAL("bg.battleground", "Destroyed node is being assaulted"); - ASSERT(false); + ABORT(); } if (m_Nodes[node].State == POINT_ASSAULTED && m_Nodes[node].TotalOwner) //only assault an assaulted node if no totalowner exists { TC_LOG_FATAL("bg.battleground", "Assault on an not assaulted node with total owner"); - ASSERT(false); + ABORT(); } //the timer gets another time, if the previous owner was 0 == Neutral m_Nodes[node].Timer = (m_Nodes[node].PrevOwner)? BG_AV_CAPTIME : BG_AV_SNOWFALL_FIRSTCAP; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp index fac6bbcfe99..7ab513c9201 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundEY.cpp @@ -161,7 +161,8 @@ void BattlegroundEY::CheckSomeoneJoinedPoint() GameObject* obj = NULL; for (uint8 i = 0; i < EY_POINTS_MAX; ++i) { - obj = HashMapHolder<GameObject>::Find(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); + obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); + if (obj) { uint8 j = 0; @@ -201,7 +202,8 @@ void BattlegroundEY::CheckSomeoneLeftPoint() GameObject* obj = NULL; for (uint8 i = 0; i < EY_POINTS_MAX; ++i) { - obj = HashMapHolder<GameObject>::Find(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); + obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]); + if (obj) { uint8 j = 0; @@ -362,7 +364,7 @@ void BattlegroundEY::UpdatePointsIcons(uint32 Team, uint32 Point) void BattlegroundEY::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new BattlegroundEYScore(player->GetGUID()); + PlayerScores[player->GetGUID().GetCounter()] = new BattlegroundEYScore(player->GetGUID()); m_PlayersNearPoint[EY_POINTS_MAX].push_back(player->GetGUID()); } @@ -588,7 +590,8 @@ void BattlegroundEY::RespawnFlagAfterDrop() { RespawnFlag(true); - GameObject* obj = HashMapHolder<GameObject>::Find(GetDroppedFlagGUID()); + GameObject* obj = GetBgMap()->GetGameObject(GetDroppedFlagGUID()); + if (obj) obj->Delete(); else diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index 9f13d4ab659..bc2fc387e89 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -245,7 +245,7 @@ void BattlegroundIC::StartingEventOpenDoors() void BattlegroundIC::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new BattlegroundICScore(player->GetGUID()); + PlayerScores[player->GetGUID().GetCounter()] = new BattlegroundICScore(player->GetGUID()); if (nodePoint[NODE_TYPE_QUARRY].nodeState == (player->GetTeamId() == TEAM_ALLIANCE ? NODE_STATE_CONTROLLED_A : NODE_STATE_CONTROLLED_H)) player->CastSpell(player, SPELL_QUARRY, true); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp index f267bf7c6c6..bfae37c64e6 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundSA.cpp @@ -476,7 +476,7 @@ void BattlegroundSA::FillInitialWorldStates(WorldPacket& data) void BattlegroundSA::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new BattlegroundSAScore(player->GetGUID()); + PlayerScores[player->GetGUID().GetCounter()] = new BattlegroundSAScore(player->GetGUID()); SendTransportInit(player); @@ -744,7 +744,7 @@ bool BattlegroundSA::CanInteractWithObject(uint32 objectId) return false; break; default: - ASSERT(false); + ABORT(); break; } @@ -877,7 +877,7 @@ void BattlegroundSA::CaptureGraveyard(BG_SA_Graveyards i, Player* Source) break; default: - ASSERT(false); + ABORT(); break; }; } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp index f94639efaf4..69f6b012c8b 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundWS.cpp @@ -227,7 +227,7 @@ void BattlegroundWS::StartingEventOpenDoors() void BattlegroundWS::AddPlayer(Player* player) { Battleground::AddPlayer(player); - PlayerScores[player->GetGUIDLow()] = new BattlegroundWGScore(player->GetGUID()); + PlayerScores[player->GetGUID().GetCounter()] = new BattlegroundWGScore(player->GetGUID()); } void BattlegroundWS::RespawnFlag(uint32 Team, bool captured) diff --git a/src/server/game/Calendar/CalendarMgr.cpp b/src/server/game/Calendar/CalendarMgr.cpp index bc1faa783fb..fd63dd04bf6 100644 --- a/src/server/game/Calendar/CalendarMgr.cpp +++ b/src/server/game/Calendar/CalendarMgr.cpp @@ -58,7 +58,7 @@ void CalendarMgr::LoadFromDB() Field* fields = result->Fetch(); uint64 eventId = fields[0].GetUInt64(); - ObjectGuid creatorGUID = ObjectGuid(HIGHGUID_PLAYER, fields[1].GetUInt32()); + ObjectGuid creatorGUID = ObjectGuid(HighGuid::Player, fields[1].GetUInt32()); std::string title = fields[2].GetString(); std::string description = fields[3].GetString(); CalendarEventType type = CalendarEventType(fields[4].GetUInt8()); @@ -91,8 +91,8 @@ void CalendarMgr::LoadFromDB() uint64 inviteId = fields[0].GetUInt64(); uint64 eventId = fields[1].GetUInt64(); - ObjectGuid invitee = ObjectGuid(HIGHGUID_PLAYER, fields[2].GetUInt32()); - ObjectGuid senderGUID = ObjectGuid(HIGHGUID_PLAYER, fields[3].GetUInt32()); + ObjectGuid invitee = ObjectGuid(HighGuid::Player, fields[2].GetUInt32()); + ObjectGuid senderGUID = ObjectGuid(HighGuid::Player, fields[3].GetUInt32()); CalendarInviteStatus status = CalendarInviteStatus(fields[4].GetUInt8()); uint32 statusTime = fields[5].GetUInt32(); CalendarModerationRank rank = CalendarModerationRank(fields[6].GetUInt8()); diff --git a/src/server/game/Chat/Chat.cpp b/src/server/game/Chat/Chat.cpp index 0d6816fc80d..2f003a58a69 100644 --- a/src/server/game/Chat/Chat.cpp +++ b/src/server/game/Chat/Chat.cpp @@ -917,19 +917,15 @@ GameObject* ChatHandler::GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid Player* pl = m_session->GetPlayer(); - GameObject* obj = pl->GetMap()->GetGameObject(ObjectGuid(HIGHGUID_GAMEOBJECT, entry, lowguid)); + GameObject* obj = pl->GetMap()->GetGameObject(ObjectGuid(HighGuid::GameObject, entry, lowguid)); if (!obj && sObjectMgr->GetGOData(lowguid)) // guid is DB guid of object { - // search near player then - CellCoord p(Trinity::ComputeCellCoord(pl->GetPositionX(), pl->GetPositionY())); - Cell cell(p); + auto bounds = pl->GetMap()->GetGameObjectBySpawnIdStore().equal_range(lowguid); + if (bounds.first == bounds.second) + return nullptr; - Trinity::GameObjectWithDbGUIDCheck go_check(*pl, lowguid); - Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(pl, obj, go_check); - - TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > object_checker(checker); - cell.Visit(p, object_checker, *pl->GetMap(), *pl, pl->GetGridActivationRange()); + return bounds.first->second; } return obj; @@ -1067,7 +1063,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text) uint32 lowguid = atoul(idS); if (CreatureData const* data = sObjectMgr->GetCreatureData(lowguid)) - return ObjectGuid(HIGHGUID_UNIT, data->id, lowguid); + return ObjectGuid(HighGuid::Unit, data->id, lowguid); else return ObjectGuid::Empty; } @@ -1076,7 +1072,7 @@ ObjectGuid ChatHandler::extractGuidFromLink(char* text) uint32 lowguid = atoul(idS); if (GameObjectData const* data = sObjectMgr->GetGOData(lowguid)) - return ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, lowguid); + return ObjectGuid(HighGuid::GameObject, data->id, lowguid); else return ObjectGuid::Empty; } diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 9106bfdd394..f7260326857 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -299,10 +299,10 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) switch (object->GetTypeId()) { case TYPEID_UNIT: - condMeets &= object->ToCreature()->GetDBTableGUIDLow() == ConditionValue3; + condMeets &= object->ToCreature()->GetSpawnId() == ConditionValue3; break; case TYPEID_GAMEOBJECT: - condMeets &= object->ToGameObject()->GetDBTableGUIDLow() == ConditionValue3; + condMeets &= object->ToGameObject()->GetSpawnId() == ConditionValue3; break; default: break; diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index d9061dfb106..e268b376b34 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -570,7 +570,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->PathID].set(entry->NodeIndex, entry); + sTaxiPathNodesByPath[entry->PathID][entry->NodeIndex] = entry; // Initialize global taxinodes mask // include existed nodes that have at least single not spell base (scripted) path diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index c680494cd72..092ef714145 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -22,13 +22,8 @@ #include "Common.h" #include "DBCEnums.h" #include "Define.h" -#include "Path.h" #include "Util.h" -#include <map> -#include <set> -#include <vector> - // Structures using to access raw DBC data and required packing to portability #pragma pack(push, 1) @@ -2211,15 +2206,7 @@ struct TaxiPathBySourceAndDestination typedef std::map<uint32, TaxiPathBySourceAndDestination> TaxiPathSetForSource; typedef std::map<uint32, TaxiPathSetForSource> TaxiPathSetBySource; -struct TaxiPathNodePtr -{ - TaxiPathNodePtr() : i_ptr(NULL) { } - TaxiPathNodePtr(TaxiPathNodeEntry const* ptr) : i_ptr(ptr) { } - TaxiPathNodeEntry const* i_ptr; - operator TaxiPathNodeEntry const& () const { return *i_ptr; } -}; - -typedef Path<TaxiPathNodePtr, TaxiPathNodeEntry const> TaxiPathNodeList; +typedef std::vector<TaxiPathNodeEntry const*> TaxiPathNodeList; typedef std::vector<TaxiPathNodeList> TaxiPathNodesByPath; #define TaxiMaskSize 14 diff --git a/src/server/game/DungeonFinding/LFGMgr.cpp b/src/server/game/DungeonFinding/LFGMgr.cpp index 1f52623461c..250f6e07718 100644 --- a/src/server/game/DungeonFinding/LFGMgr.cpp +++ b/src/server/game/DungeonFinding/LFGMgr.cpp @@ -58,7 +58,7 @@ void LFGMgr::_LoadFromDB(Field* fields, ObjectGuid guid) if (!guid.IsGroup()) return; - SetLeader(guid, ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32())); + SetLeader(guid, ObjectGuid(HighGuid::Player, fields[0].GetUInt32())); uint32 dungeon = fields[17].GetUInt32(); uint8 state = fields[18].GetUInt8(); diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index b1ae61cef11..2f0734ff4d0 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -89,7 +89,7 @@ void LFGPlayerScript::OnMapChanged(Player* player) player->RemoveAurasDueToSpell(LFG_SPELL_LUCK_OF_THE_DRAW); player->TeleportTo(player->m_homebindMapId, player->m_homebindX, player->m_homebindY, player->m_homebindZ, 0.0f); TC_LOG_ERROR("lfg", "LFGPlayerScript::OnMapChanged, Player %s (%u) is in LFG dungeon map but does not have a valid group! " - "Teleporting to homebind.", player->GetName().c_str(), player->GetGUIDLow()); + "Teleporting to homebind.", player->GetName().c_str(), player->GetGUID().GetCounter()); return; } diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 192a897238a..360cfdf1ae3 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -22,6 +22,7 @@ #include "UpdateMask.h" #include "ObjectAccessor.h" #include "DatabaseEnv.h" +#include "World.h" Corpse::Corpse(CorpseType type) : WorldObject(type != CORPSE_BONES), m_type(type) { @@ -44,7 +45,7 @@ void Corpse::AddToWorld() { ///- Register the corpse for guid lookup if (!IsInWorld()) - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<Corpse>(GetGUID(), this); Object::AddToWorld(); } @@ -53,15 +54,15 @@ void Corpse::RemoveFromWorld() { ///- Remove the corpse from the accessor if (IsInWorld()) - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<Corpse>(GetGUID()); - Object::RemoveFromWorld(); + WorldObject::RemoveFromWorld(); } bool Corpse::Create(uint32 guidlow, Map* map) { SetMap(map); - Object::_Create(guidlow, 0, HIGHGUID_CORPSE); + Object::_Create(guidlow, 0, HighGuid::Corpse); return true; } @@ -82,9 +83,9 @@ bool Corpse::Create(uint32 guidlow, Player* owner) //in other way we will get a crash in Corpse::SaveToDB() SetMap(owner->GetMap()); - WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetPhaseMask()); + WorldObject::_Create(guidlow, HighGuid::Corpse, owner->GetPhaseMask()); - SetObjectScale(1); + SetObjectScale(1.0f); SetGuidValue(CORPSE_FIELD_OWNER, owner->GetGUID()); _gridCoord = Trinity::ComputeGridCoord(GetPositionX(), GetPositionY()); @@ -100,7 +101,6 @@ void Corpse::SaveToDB() uint16 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CORPSE); - stmt->setUInt32(index++, GetGUIDLow()); // corpseGuid stmt->setUInt32(index++, GetOwnerGUID().GetCounter()); // guid stmt->setFloat (index++, GetPositionX()); // posX stmt->setFloat (index++, GetPositionY()); // posY @@ -130,7 +130,7 @@ void Corpse::DeleteBonesFromWorld() if (!corpse) { - TC_LOG_ERROR("entities.player", "Bones %u not found in world.", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Bones %u not found in world.", GetGUID().GetCounter()); return; } @@ -139,35 +139,30 @@ void Corpse::DeleteBonesFromWorld() void Corpse::DeleteFromDB(SQLTransaction& trans) { - PreparedStatement* stmt = NULL; - if (GetType() == CORPSE_BONES) - { - // Only specific bones - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE); - stmt->setUInt32(0, GetGUIDLow()); - } - else - { - // all corpses (not bones) - stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_CORPSES); - stmt->setUInt32(0, GetOwnerGUID().GetCounter()); - } - trans->Append(stmt); + DeleteFromDB(GetOwnerGUID(), trans); +} + +void Corpse::DeleteFromDB(ObjectGuid const& ownerGuid, SQLTransaction& trans) +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSE); + stmt->setUInt32(0, ownerGuid.GetCounter()); + CharacterDatabase.ExecuteOrAppend(trans, stmt); } bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 - // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, corpseGuid, guid FROM corpse WHERE corpseType <> 0 + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, guid FROM corpse WHERE mapId = ? AND instanceId = ? + - uint32 ownerGuid = fields[17].GetUInt32(); + uint32 ownerGuid = fields[16].GetUInt32(); float posX = fields[0].GetFloat(); float posY = fields[1].GetFloat(); float posZ = fields[2].GetFloat(); float o = fields[3].GetFloat(); uint32 mapId = fields[4].GetUInt16(); - Object::_Create(guid, 0, HIGHGUID_CORPSE); + Object::_Create(guid, 0, HighGuid::Corpse); SetObjectScale(1.0f); SetUInt32Value(CORPSE_FIELD_DISPLAY_ID, fields[5].GetUInt32()); @@ -177,7 +172,7 @@ bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) SetUInt32Value(CORPSE_FIELD_GUILD, fields[9].GetUInt32()); SetUInt32Value(CORPSE_FIELD_FLAGS, fields[10].GetUInt8()); SetUInt32Value(CORPSE_FIELD_DYNAMIC_FLAGS, fields[11].GetUInt8()); - SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid(HIGHGUID_PLAYER, ownerGuid)); + SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid(HighGuid::Player, ownerGuid)); m_time = time_t(fields[12].GetUInt32()); @@ -203,6 +198,10 @@ bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) bool Corpse::IsExpired(time_t t) const { + // Deleted character + if (!sWorld->GetCharacterNameData(GetOwnerGUID())) + return true; + if (m_type == CORPSE_BONES) return m_time < t - 60 * MINUTE; else diff --git a/src/server/game/Entities/Corpse/Corpse.h b/src/server/game/Entities/Corpse/Corpse.h index c3a693d30d3..eeb22a064ba 100644 --- a/src/server/game/Entities/Corpse/Corpse.h +++ b/src/server/game/Entities/Corpse/Corpse.h @@ -63,6 +63,7 @@ class Corpse : public WorldObject, public GridObject<Corpse> void DeleteBonesFromWorld(); void DeleteFromDB(SQLTransaction& trans); + static void DeleteFromDB(ObjectGuid const& ownerGuid, SQLTransaction& trans); ObjectGuid GetOwnerGUID() const { return GetGuidValue(CORPSE_FIELD_OWNER); } diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 84a12fd6409..c8a258ad386 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -138,8 +138,8 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/) Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0), m_lootRecipient(), m_lootRecipientGroup(0), _skinner(), _pickpocketLootRestore(0), m_corpseRemoveTime(0), m_respawnTime(0), -m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE), -m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), +m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), +m_defaultMovementType(IDLE_MOTION_TYPE), m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_homePosition(), m_transportHomePosition(), m_creatureInfo(NULL), m_creatureData(NULL), m_waypointID(0), m_path_id(0), m_formation(NULL) { @@ -176,7 +176,13 @@ void Creature::AddToWorld() { if (GetZoneScript()) GetZoneScript()->OnCreatureCreate(this); - sObjectAccessor->AddObject(this); + + GetMap()->GetObjectsStore().Insert<Creature>(GetGUID(), this); + if (m_spawnId) + GetMap()->GetCreatureBySpawnIdStore().insert(std::make_pair(m_spawnId, this)); + + TC_LOG_DEBUG("entities.unit", "Adding creature %u with entry %u and DBGUID %u to world in map %u", GetGUID().GetCounter(), GetEntry(), m_spawnId, GetMap()->GetId()); + Unit::AddToWorld(); SearchFormation(); AIM_Initialize(); @@ -191,10 +197,17 @@ void Creature::RemoveFromWorld() { if (GetZoneScript()) GetZoneScript()->OnCreatureRemove(this); + if (m_formation) sFormationMgr->RemoveCreatureFromGroup(m_formation, this); + Unit::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + + if (m_spawnId) + Trinity::Containers::MultimapErasePair(GetMap()->GetCreatureBySpawnIdStore(), m_spawnId, this); + + TC_LOG_DEBUG("entities.unit", "Removing creature %u with entry %u and DBGUID %u to world in map %u", GetGUID().GetCounter(), GetEntry(), m_spawnId, GetMap()->GetId()); + GetMap()->GetObjectsStore().Remove<Creature>(GetGUID()); } } @@ -213,7 +226,7 @@ void Creature::SearchFormation() if (IsSummon()) return; - uint32 lowguid = GetDBTableGUIDLow(); + uint32 lowguid = GetSpawnId(); if (!lowguid) return; @@ -447,11 +460,11 @@ void Creature::Update(uint32 diff) { case JUST_RESPAWNED: // Must not be called, see Creature::setDeathState JUST_RESPAWNED -> ALIVE promoting. - TC_LOG_ERROR("entities.unit", "Creature (GUID: %u Entry: %u) in wrong state: JUST_RESPAWNED (4)", GetGUIDLow(), GetEntry()); + TC_LOG_ERROR("entities.unit", "Creature (GUID: %u Entry: %u) in wrong state: JUST_RESPAWNED (4)", GetGUID().GetCounter(), GetEntry()); break; case JUST_DIED: // Must not be called, see Creature::setDeathState JUST_DIED -> CORPSE promoting. - TC_LOG_ERROR("entities.unit", "Creature (GUID: %u Entry: %u) in wrong state: JUST_DEAD (1)", GetGUIDLow(), GetEntry()); + TC_LOG_ERROR("entities.unit", "Creature (GUID: %u Entry: %u) in wrong state: JUST_DEAD (1)", GetGUID().GetCounter(), GetEntry()); break; case DEAD: { @@ -462,7 +475,7 @@ void Creature::Update(uint32 diff) if (!allowed) // Will be rechecked on next Update call break; - ObjectGuid dbtableHighGuid(HIGHGUID_UNIT, GetEntry(), m_DBTableGuid); + ObjectGuid dbtableHighGuid(HighGuid::Unit, GetEntry(), m_spawnId); time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid); if (!linkedRespawntime) // Can respawn Respawn(); @@ -526,10 +539,44 @@ void Creature::Update(uint32 diff) LastCharmerGUID.Clear(); } + // if periodic combat pulse is enabled and we are both in combat and in a dungeon, do this now + if (m_combatPulseDelay > 0 && IsInCombat() && GetMap()->IsDungeon()) + { + if (diff > m_combatPulseTime) + m_combatPulseTime = 0; + else + m_combatPulseTime -= diff; + + if (m_combatPulseTime == 0) + { + Map::PlayerList const &players = GetMap()->GetPlayers(); + if (!players.isEmpty()) + for (Map::PlayerList::const_iterator it = players.begin(); it != players.end(); ++it) + { + if (Player* player = it->GetSource()) + { + if (player->IsGameMaster()) + continue; + + if (player->IsAlive() && this->IsHostileTo(player)) + { + if (CanHaveThreatList()) + AddThreat(player, 0.0f); + this->SetInCombatWith(player); + player->SetInCombatWith(this); + } + } + } + + m_combatPulseTime = m_combatPulseDelay * IN_MILLISECONDS; + } + } + if (!IsInEvadeMode() && IsAIEnabled) { // do not allow the AI to be changed during update m_AI_locked = true; + i_AI->UpdateAI(diff); m_AI_locked = false; } @@ -918,7 +965,7 @@ void Creature::SaveToDB() { // this should only be used when the creature has already been loaded // preferably after adding to map, because mapid may not be valid otherwise - CreatureData const* data = sObjectMgr->GetCreatureData(m_DBTableGuid); + CreatureData const* data = sObjectMgr->GetCreatureData(m_spawnId); if (!data) { TC_LOG_ERROR("entities.unit", "Creature::SaveToDB failed, cannot get creature data!"); @@ -932,9 +979,10 @@ void Creature::SaveToDB() void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) { // update in loaded data - if (!m_DBTableGuid) - m_DBTableGuid = GetGUIDLow(); - CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_DBTableGuid); + if (!m_spawnId) + m_spawnId = sObjectMgr->GenerateCreatureSpawnId(); + + CreatureData& data = sObjectMgr->NewOrExistCreatureData(m_spawnId); uint32 displayId = GetNativeDisplayId(); uint32 npcflag = GetUInt32Value(UNIT_NPC_FLAGS); @@ -998,13 +1046,14 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) SQLTransaction trans = WorldDatabase.BeginTransaction(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); + trans->Append(stmt); uint8 index = 0; stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_CREATURE); - stmt->setUInt32(index++, m_DBTableGuid); + stmt->setUInt32(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt16(index++, uint16(mapid)); stmt->setUInt8(index++, spawnMask); @@ -1168,7 +1217,7 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 entry, CreatureData const* SetOriginalEntry(entry); - Object::_Create(guidlow, entry, (vehId || cinfo->VehicleId) ? HIGHGUID_VEHICLE : HIGHGUID_UNIT); + Object::_Create(guidlow, entry, (vehId || cinfo->VehicleId) ? HighGuid::Vehicle : HighGuid::Unit); if (!UpdateEntry(entry, data)) return false; @@ -1190,26 +1239,18 @@ bool Creature::CreateFromProto(uint32 guidlow, uint32 entry, CreatureData const* return true; } -bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap) +bool Creature::LoadCreatureFromDB(uint32 spawnId, Map* map, bool addToMap) { - CreatureData const* data = sObjectMgr->GetCreatureData(guid); + CreatureData const* data = sObjectMgr->GetCreatureData(spawnId); if (!data) { - TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) not found in table `creature`, can't load. ", guid); + TC_LOG_ERROR("sql.sql", "Creature (GUID: %u) not found in table `creature`, can't load. ", spawnId); return false; } - m_DBTableGuid = guid; - if (map->GetInstanceId() == 0) - { - if (map->GetCreature(ObjectGuid(HIGHGUID_UNIT, data->id, guid))) - return false; - } - else - guid = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT); - - if (!Create(guid, map, data->phaseMask, data->id, data->posX, data->posY, data->posZ, data->orientation, data)) + m_spawnId = spawnId; + if (!Create(map->GenerateLowGuid<HighGuid::Unit>(), map, data->phaseMask, data->id, data->posX, data->posY, data->posZ, data->orientation, data)) return false; //We should set first home position, because then AI calls home movement @@ -1220,7 +1261,7 @@ bool Creature::LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap) m_respawnDelay = data->spawntimesecs; m_deathState = ALIVE; - m_respawnTime = GetMap()->GetCreatureRespawnTime(m_DBTableGuid); + m_respawnTime = GetMap()->GetCreatureRespawnTime(m_spawnId); if (m_respawnTime) // respawn on Update { m_deathState = DEAD; @@ -1315,31 +1356,31 @@ bool Creature::hasInvolvedQuest(uint32 quest_id) const void Creature::DeleteFromDB() { - if (!m_DBTableGuid) + if (!m_spawnId) { - TC_LOG_ERROR("entities.unit", "Trying to delete not saved creature! LowGUID: %u, Entry: %u", GetGUIDLow(), GetEntry()); + TC_LOG_ERROR("entities.unit", "Trying to delete not saved creature! LowGUID: %u, Entry: %u", GetGUID().GetCounter(), GetEntry()); return; } - GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid); - sObjectMgr->DeleteCreatureData(m_DBTableGuid); + GetMap()->RemoveCreatureRespawnTime(m_spawnId); + sObjectMgr->DeleteCreatureData(m_spawnId); SQLTransaction trans = WorldDatabase.BeginTransaction(); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_CREATURE_ADDON); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_CREATURE); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); trans->Append(stmt); WorldDatabase.CommitTransaction(trans); @@ -1536,8 +1577,8 @@ void Creature::Respawn(bool force) if (getDeathState() == DEAD) { - if (m_DBTableGuid) - GetMap()->RemoveCreatureRespawnTime(m_DBTableGuid); + if (m_spawnId) + GetMap()->RemoveCreatureRespawnTime(m_spawnId); TC_LOG_DEBUG("entities.unit", "Respawning creature %s (%s)", GetName().c_str(), GetGUID().ToString().c_str()); @@ -1570,9 +1611,9 @@ void Creature::Respawn(bool force) TriggerJustRespawned = true;//delay event to next tick so all creatures are created on the map before processing } - uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<Creature>(GetDBTableGUIDLow()) : 0; + uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<Creature>(GetSpawnId()) : 0; if (poolid) - sPoolMgr->UpdatePool<Creature>(poolid, GetDBTableGUIDLow()); + sPoolMgr->UpdatePool<Creature>(poolid, GetSpawnId()); //Re-initialize reactstate that could be altered by movementgenerators InitializeReactState(); @@ -1793,7 +1834,7 @@ Unit* Creature::SelectNearestTargetInAttackDistance(float dist) const if (dist > MAX_VISIBILITY_DISTANCE) { - TC_LOG_ERROR("entities.unit", "Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUIDLow(), GetEntry()); + TC_LOG_ERROR("entities.unit", "Creature (GUID: %u Entry: %u) SelectNearestTargetInAttackDistance called with dist > MAX_VISIBILITY_DISTANCE. Distance set to ATTACK_DISTANCE.", GetGUID().GetCounter(), GetEntry()); dist = ATTACK_DISTANCE; } @@ -1976,10 +2017,10 @@ bool Creature::_IsTargetAcceptable(const Unit* target) const void Creature::SaveRespawnTime() { - if (IsSummon() || !m_DBTableGuid || (m_creatureData && !m_creatureData->dbData)) + if (IsSummon() || !m_spawnId || (m_creatureData && !m_creatureData->dbData)) return; - GetMap()->SaveCreatureRespawnTime(m_DBTableGuid, m_respawnTime); + GetMap()->SaveCreatureRespawnTime(m_spawnId, m_respawnTime); } // this should not be called by petAI or @@ -2011,9 +2052,9 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool /*force*/) const CreatureAddon const* Creature::GetCreatureAddon() const { - if (m_DBTableGuid) + if (m_spawnId) { - if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_DBTableGuid)) + if (CreatureAddon const* addon = sObjectMgr->GetCreatureAddon(m_spawnId)) return addon; } @@ -2082,7 +2123,7 @@ bool Creature::LoadCreaturesAddon(bool reload) SpellInfo const* AdditionalSpellInfo = sSpellMgr->GetSpellInfo(*itr); if (!AdditionalSpellInfo) { - TC_LOG_ERROR("sql.sql", "Creature (GUID: %u Entry: %u) has wrong spell %u defined in `auras` field.", GetGUIDLow(), GetEntry(), *itr); + TC_LOG_ERROR("sql.sql", "Creature (GUID: %u Entry: %u) has wrong spell %u defined in `auras` field.", GetGUID().GetCounter(), GetEntry(), *itr); continue; } @@ -2090,13 +2131,13 @@ bool Creature::LoadCreaturesAddon(bool reload) if (HasAura(*itr)) { if (!reload) - TC_LOG_ERROR("sql.sql", "Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetDBTableGUIDLow(), GetEntry(), *itr); + TC_LOG_ERROR("sql.sql", "Creature (GUID: %u Entry: %u) has duplicate aura (spell %u) in `auras` field.", GetSpawnId(), GetEntry(), *itr); continue; } AddAura(*itr, this); - TC_LOG_DEBUG("entities.unit", "Spell: %u added to creature (GUID: %u Entry: %u)", *itr, GetGUIDLow(), GetEntry()); + TC_LOG_DEBUG("entities.unit", "Spell: %u added to creature (GUID: %u Entry: %u)", *itr, GetGUID().GetCounter(), GetEntry()); } } @@ -2176,9 +2217,9 @@ time_t Creature::GetRespawnTimeEx() const void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, float* dist) const { - if (m_DBTableGuid) + if (m_spawnId) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(GetSpawnId())) { x = data->posX; y = data->posY; @@ -2646,7 +2687,7 @@ void Creature::SetTextRepeatId(uint8 textGroup, uint8 id) if (std::find(repeats.begin(), repeats.end(), id) == repeats.end()) repeats.push_back(id); else - TC_LOG_ERROR("sql.sql", "CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), GetName().c_str(), GetGUIDLow(), GetEntry(), uint32(id)); + TC_LOG_ERROR("sql.sql", "CreatureTextMgr: TextGroup %u for Creature(%s) GuidLow %u Entry %u, id %u already added", uint32(textGroup), GetName().c_str(), GetGUID().GetCounter(), GetEntry(), uint32(id)); } CreatureTextRepeatIds Creature::GetTextRepeatGroup(uint8 textGroup) diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 4c1b39211cb..79832b70f52 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -435,7 +435,7 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void SelectLevel(); void LoadEquipment(int8 id = 1, bool force = false); - uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } + uint32 GetSpawnId() const { return m_spawnId; } void Update(uint32 time) override; // overwrited Unit::Update void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr, float* dist =nullptr) const; @@ -529,8 +529,8 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject void setDeathState(DeathState s) override; // override virtual Unit::setDeathState - bool LoadFromDB(uint32 guid, Map* map) { return LoadCreatureFromDB(guid, map, false); } - bool LoadCreatureFromDB(uint32 guid, Map* map, bool addToMap = true); + bool LoadFromDB(uint32 spawnId, Map* map) { return LoadCreatureFromDB(spawnId, map, false); } + bool LoadCreatureFromDB(uint32 spawnId, Map* map, bool addToMap = true); void SaveToDB(); // overriden in Pet virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); @@ -601,6 +601,14 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject float GetRespawnRadius() const { return m_respawnradius; } void SetRespawnRadius(float dist) { m_respawnradius = dist; } + uint32 GetCombatPulseDelay() const { return m_combatPulseDelay; } + void SetCombatPulseDelay(uint32 delay) // (secs) interval at which the creature pulses the entire zone into combat (only works in dungeons) + { + m_combatPulseDelay = delay; + if (m_combatPulseTime == 0 || m_combatPulseTime > delay) + m_combatPulseTime = delay; + } + uint32 m_groupLootTimer; // (msecs)timer used for group loot uint32 lootingGroupLowGUID; // used to find group which is looting corpse @@ -686,13 +694,15 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject uint32 m_respawnDelay; // (secs) delay between corpse disappearance and respawning uint32 m_corpseDelay; // (secs) delay between death and corpse disappearance float m_respawnradius; + uint32 m_combatPulseTime; // (msecs) remaining time for next zone-in-combat pulse + uint32 m_combatPulseDelay; // (secs) how often the creature puts the entire zone in combat (only works in dungeons) ReactStates m_reactState; // for AI, not charmInfo void RegenerateMana(); void RegenerateHealth(); void Regenerate(Powers power); MovementGeneratorType m_defaultMovementType; - uint32 m_DBTableGuid; ///< For new or temporary creatures is 0 for saved it is lowguid + uint32 m_spawnId; ///< For new or temporary creatures is 0 for saved it is lowguid uint8 m_equipmentId; int8 m_originalEquipmentId; // can be -1 diff --git a/src/server/game/Entities/Creature/CreatureGroups.cpp b/src/server/game/Entities/Creature/CreatureGroups.cpp index 2ccf4471788..f29e896f050 100644 --- a/src/server/game/Entities/Creature/CreatureGroups.cpp +++ b/src/server/game/Entities/Creature/CreatureGroups.cpp @@ -41,7 +41,7 @@ void FormationMgr::AddCreatureToGroup(uint32 groupId, Creature* member) //Add member to an existing group if (itr != map->CreatureGroupHolder.end()) { - TC_LOG_DEBUG("entities.unit", "Group found: %u, inserting creature GUID: %u, Group InstanceID %u", groupId, member->GetGUIDLow(), member->GetInstanceId()); + TC_LOG_DEBUG("entities.unit", "Group found: %u, inserting creature GUID: %u, Group InstanceID %u", groupId, member->GetGUID().GetCounter(), member->GetInstanceId()); itr->second->AddMember(member); } //Create new group @@ -56,7 +56,7 @@ void FormationMgr::AddCreatureToGroup(uint32 groupId, Creature* member) void FormationMgr::RemoveCreatureFromGroup(CreatureGroup* group, Creature* member) { - TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetDBTableGUIDLow()); + TC_LOG_DEBUG("entities.unit", "Deleting member pointer to GUID: %u from group %u", group->GetId(), member->GetSpawnId()); group->RemoveMember(member); if (group->isEmpty()) @@ -142,16 +142,16 @@ void FormationMgr::LoadCreatureFormations() void CreatureGroup::AddMember(Creature* member) { - TC_LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding unit GUID: %u.", member->GetGUIDLow()); + TC_LOG_DEBUG("entities.unit", "CreatureGroup::AddMember: Adding unit GUID: %u.", member->GetGUID().GetCounter()); //Check if it is a leader - if (member->GetDBTableGUIDLow() == m_groupID) + if (member->GetSpawnId() == m_groupID) { - TC_LOG_DEBUG("entities.unit", "Unit GUID: %u is formation leader. Adding group.", member->GetGUIDLow()); + TC_LOG_DEBUG("entities.unit", "Unit GUID: %u is formation leader. Adding group.", member->GetGUID().GetCounter()); m_leader = member; } - m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetDBTableGUIDLow())->second; + m_members[member] = sFormationMgr->CreatureGroupMap.find(member->GetSpawnId())->second; member->SetFormation(this); } @@ -166,7 +166,7 @@ void CreatureGroup::RemoveMember(Creature* member) void CreatureGroup::MemberAttackStart(Creature* member, Unit* target) { - uint8 groupAI = sFormationMgr->CreatureGroupMap[member->GetDBTableGUIDLow()]->groupAI; + uint8 groupAI = sFormationMgr->CreatureGroupMap[member->GetSpawnId()]->groupAI; if (!groupAI) return; @@ -205,7 +205,7 @@ void CreatureGroup::FormationReset(bool dismiss) itr->first->GetMotionMaster()->Initialize(); else itr->first->GetMotionMaster()->MoveIdle(); - TC_LOG_DEBUG("entities.unit", "Set %s movement for member GUID: %u", dismiss ? "default" : "idle", itr->first->GetGUIDLow()); + TC_LOG_DEBUG("entities.unit", "Set %s movement for member GUID: %u", dismiss ? "default" : "idle", itr->first->GetGUID().GetCounter()); } } m_Formed = !dismiss; @@ -227,12 +227,8 @@ void CreatureGroup::LeaderMoveTo(float x, float y, float z) continue; if (itr->second->point_1) - { - if (m_leader->GetCurrentWaypointID() == itr->second->point_1) - itr->second->follow_angle = (2 * float(M_PI)) - itr->second->follow_angle; - if (m_leader->GetCurrentWaypointID() == itr->second->point_2) - itr->second->follow_angle = (2 * float(M_PI)) + itr->second->follow_angle; - } + if (m_leader->GetCurrentWaypointID() == itr->second->point_1 - 1 || m_leader->GetCurrentWaypointID() == itr->second->point_2 - 1) + itr->second->follow_angle = float(M_PI) * 2 - itr->second->follow_angle; float angle = itr->second->follow_angle; float dist = itr->second->follow_dist; diff --git a/src/server/game/Entities/Creature/GossipDef.cpp b/src/server/game/Entities/Creature/GossipDef.cpp index 63be8d06739..db67f1f74f1 100644 --- a/src/server/game/Entities/Creature/GossipDef.cpp +++ b/src/server/game/Entities/Creature/GossipDef.cpp @@ -381,10 +381,10 @@ void PlayerMenu::SendQuestGiverStatus(uint8 questStatus, ObjectGuid npcGUID) con void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGUID, bool activateAccept) const { - std::string questTitle = quest->GetTitle(); - std::string questDetails = quest->GetDetails(); - std::string questObjectives = quest->GetObjectives(); - std::string questEndText = quest->GetEndText(); + std::string questTitle = quest->GetTitle(); + std::string questDetails = quest->GetDetails(); + std::string questObjectives = quest->GetObjectives(); + std::string questAreaDescription = quest->GetAreaDescription(); int32 locale = _session->GetSessionDbLocaleIndex(); if (locale >= 0) @@ -394,7 +394,7 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails); ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives); - ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText); + ObjectMgr::GetLocaleString(localeData->AreaDescription, locale, questAreaDescription); } } @@ -489,11 +489,11 @@ void PlayerMenu::SendQuestGiverQuestDetails(Quest const* quest, ObjectGuid npcGU void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const { - std::string questTitle = quest->GetTitle(); - std::string questDetails = quest->GetDetails(); - std::string questObjectives = quest->GetObjectives(); - std::string questEndText = quest->GetEndText(); - std::string questCompletedText = quest->GetCompletedText(); + std::string questTitle = quest->GetTitle(); + std::string questDetails = quest->GetDetails(); + std::string questObjectives = quest->GetObjectives(); + std::string questAreaDescription = quest->GetAreaDescription(); + std::string questCompletedText = quest->GetCompletedText(); std::string questObjectiveText[QUEST_OBJECTIVES_COUNT]; for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) @@ -507,7 +507,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const ObjectMgr::GetLocaleString(localeData->Title, locale, questTitle); ObjectMgr::GetLocaleString(localeData->Details, locale, questDetails); ObjectMgr::GetLocaleString(localeData->Objectives, locale, questObjectives); - ObjectMgr::GetLocaleString(localeData->EndText, locale, questEndText); + ObjectMgr::GetLocaleString(localeData->AreaDescription, locale, questAreaDescription); ObjectMgr::GetLocaleString(localeData->CompletedText, locale, questCompletedText); for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) @@ -585,9 +585,9 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const for (uint8 i = 0; i < QUEST_REPUTATIONS_COUNT; ++i) // unk (0) data << int32(quest->RewardFactionValueIdOverride[i]); - data << uint32(quest->GetPointMapId()); - data << float(quest->GetPointX()); - data << float(quest->GetPointY()); + data << uint32(quest->GetPOIContinent()); + data << float(quest->GetPOIx()); + data << float(quest->GetPOIy()); data << uint32(quest->GetPointOpt()); if (sWorld->getBoolConfig(CONFIG_UI_QUESTLEVELS_IN_DIALOGS)) @@ -596,7 +596,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << questTitle; data << questObjectives; data << questDetails; - data << questEndText; + data << questAreaDescription; data << questCompletedText; // display in quest objectives window once all objectives are completed for (uint8 i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) @@ -607,7 +607,7 @@ void PlayerMenu::SendQuestQueryResponse(Quest const* quest) const data << uint32(quest->RequiredNpcOrGo[i]); data << uint32(quest->RequiredNpcOrGoCount[i]); - data << uint32(quest->RequiredSourceItemId[i]); + data << uint32(quest->ItemDrop[i]); data << uint32(0); // req source count? } diff --git a/src/server/game/Entities/Creature/TemporarySummon.cpp b/src/server/game/Entities/Creature/TemporarySummon.cpp index 2a3e91b7574..46422444bbb 100644 --- a/src/server/game/Entities/Creature/TemporarySummon.cpp +++ b/src/server/game/Entities/Creature/TemporarySummon.cpp @@ -368,7 +368,7 @@ void Puppet::InitSummon() { Minion::InitSummon(); if (!SetCharmedBy(GetOwner(), CHARM_TYPE_POSSESS)) - ASSERT(false); + ABORT(); } void Puppet::Update(uint32 time) diff --git a/src/server/game/Entities/DynamicObject/DynamicObject.cpp b/src/server/game/Entities/DynamicObject/DynamicObject.cpp index 71d0f13488c..714a0a35caf 100644 --- a/src/server/game/Entities/DynamicObject/DynamicObject.cpp +++ b/src/server/game/Entities/DynamicObject/DynamicObject.cpp @@ -51,7 +51,7 @@ void DynamicObject::AddToWorld() ///- Register the dynamicObject for guid lookup and for caster if (!IsInWorld()) { - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<DynamicObject>(GetGUID(), this); WorldObject::AddToWorld(); BindToCaster(); } @@ -74,7 +74,8 @@ void DynamicObject::RemoveFromWorld() UnbindFromCaster(); WorldObject::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<DynamicObject>(GetGUID()); + } } @@ -88,7 +89,7 @@ bool DynamicObject::CreateDynamicObject(uint32 guidlow, Unit* caster, uint32 spe return false; } - WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetPhaseMask()); + WorldObject::_Create(guidlow, HighGuid::DynamicObject, caster->GetPhaseMask()); SetEntry(spellId); SetObjectScale(1); diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 9777672e175..42ed4674a53 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -52,7 +52,7 @@ GameObject::GameObject() : WorldObject(false), MapObject(), m_goInfo = NULL; m_goData = NULL; - m_DBTableGuid = 0; + m_spawnId = 0; m_rotation = 0; m_lootRecipientGroup = 0; @@ -115,7 +115,7 @@ void GameObject::RemoveFromOwner() // This happens when a mage portal is despawned after the caster changes map (for example using the portal) TC_LOG_DEBUG("misc", "Removed GameObject (GUID: %u Entry: %u SpellId: %u LinkedGO: %u) that just lost any reference to the owner (%s) GO list", - GetGUIDLow(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), ownerGUID.ToString().c_str()); + GetGUID().GetCounter(), GetGOInfo()->entry, m_spellId, GetGOInfo()->GetLinkedGameObjectEntry(), ownerGUID.ToString().c_str()); SetOwnerGUID(ObjectGuid::Empty); } @@ -127,7 +127,9 @@ void GameObject::AddToWorld() if (m_zoneScript) m_zoneScript->OnGameObjectCreate(this); - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<GameObject>(GetGUID(), this); + if (m_spawnId) + GetMap()->GetGameObjectBySpawnIdStore().insert(std::make_pair(m_spawnId, this)); // The state can be changed after GameObject::Create but before GameObject::AddToWorld bool toggledState = GetGoType() == GAMEOBJECT_TYPE_CHEST ? getLootState() == GO_READY : (GetGoState() == GO_STATE_READY || IsTransport()); @@ -156,8 +158,12 @@ void GameObject::RemoveFromWorld() if (m_model) if (GetMap()->ContainsGameObjectModel(*m_model)) GetMap()->RemoveGameObjectModel(*m_model); + WorldObject::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + + if (m_spawnId) + Trinity::Containers::MultimapErasePair(GetMap()->GetGameObjectBySpawnIdStore(), m_spawnId, this); + GetMap()->GetObjectsStore().Remove<GameObject>(GetGUID()); } } @@ -200,7 +206,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa if (goinfo->type == GAMEOBJECT_TYPE_TRANSPORT) m_updateFlag = (m_updateFlag | UPDATEFLAG_TRANSPORT) & ~UPDATEFLAG_POSITION; - Object::_Create(guidlow, goinfo->entry, HIGHGUID_GAMEOBJECT); + Object::_Create(guidlow, goinfo->entry, HighGuid::GameObject); m_goInfo = goinfo; @@ -273,7 +279,7 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa break; } - if (GameObjectAddon const* addon = sObjectMgr->GetGameObjectAddon(guidlow)) + if (GameObjectAddon const* addon = sObjectMgr->GetGameObjectAddon(GetSpawnId())) { if (addon->InvisibilityValue) { @@ -390,7 +396,7 @@ void GameObject::Update(uint32 diff) time_t now = time(NULL); if (m_respawnTime <= now) // timer expired { - ObjectGuid dbtableHighGuid(HIGHGUID_GAMEOBJECT, GetEntry(), m_DBTableGuid); + ObjectGuid dbtableHighGuid(HighGuid::GameObject, GetEntry(), m_spawnId); time_t linkedRespawntime = GetMap()->GetLinkedRespawnTime(dbtableHighGuid); if (linkedRespawntime) // Can't respawn, the master is dead { @@ -446,9 +452,9 @@ void GameObject::Update(uint32 diff) } // Respawn timer - uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0; + uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<GameObject>(GetSpawnId()) : 0; if (poolid) - sPoolMgr->UpdatePool<GameObject>(poolid, GetDBTableGUIDLow()); + sPoolMgr->UpdatePool<GameObject>(poolid, GetSpawnId()); else GetMap()->AddToMap(this); } @@ -686,9 +692,9 @@ void GameObject::Delete() SetGoState(GO_STATE_READY); SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags); - uint32 poolid = GetDBTableGUIDLow() ? sPoolMgr->IsPartOfAPool<GameObject>(GetDBTableGUIDLow()) : 0; + uint32 poolid = GetSpawnId() ? sPoolMgr->IsPartOfAPool<GameObject>(GetSpawnId()) : 0; if (poolid) - sPoolMgr->UpdatePool<GameObject>(poolid, GetDBTableGUIDLow()); + sPoolMgr->UpdatePool<GameObject>(poolid, GetSpawnId()); else AddObjectToRemoveList(); } @@ -737,7 +743,7 @@ void GameObject::SaveToDB() { // this should only be used when the gameobject has already been loaded // preferably after adding to map, because mapid may not be valid otherwise - GameObjectData const* data = sObjectMgr->GetGOData(m_DBTableGuid); + GameObjectData const* data = sObjectMgr->GetGOData(m_spawnId); if (!data) { TC_LOG_ERROR("misc", "GameObject::SaveToDB failed, cannot get gameobject data!"); @@ -754,10 +760,11 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) if (!goI) return; - if (!m_DBTableGuid) - m_DBTableGuid = GetGUIDLow(); + if (!m_spawnId) + m_spawnId = sObjectMgr->GenerateGameObjectSpawnId(); + // update in loaded data (changing data only in this place) - GameObjectData& data = sObjectMgr->NewGOData(m_DBTableGuid); + GameObjectData& data = sObjectMgr->NewGOData(m_spawnId); // data->guid = guid must not be updated at save data.id = GetEntry(); @@ -783,11 +790,11 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) uint8 index = 0; PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); trans->Append(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_INS_GAMEOBJECT); - stmt->setUInt32(index++, m_DBTableGuid); + stmt->setUInt32(index++, m_spawnId); stmt->setUInt32(index++, GetEntry()); stmt->setUInt16(index++, uint16(mapid)); stmt->setUInt8(index++, spawnMask); @@ -808,13 +815,13 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask) WorldDatabase.CommitTransaction(trans); } -bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) +bool GameObject::LoadGameObjectFromDB(uint32 spawnId, Map* map, bool addToMap) { - GameObjectData const* data = sObjectMgr->GetGOData(guid); + GameObjectData const* data = sObjectMgr->GetGOData(spawnId); if (!data) { - TC_LOG_ERROR("sql.sql", "Gameobject (GUID: %u) not found in table `gameobject`, can't load. ", guid); + TC_LOG_ERROR("sql.sql", "Gameobject (GUID: %u) not found in table `gameobject`, can't load. ", spawnId); return false; } @@ -835,10 +842,8 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) GOState go_state = data->go_state; uint32 artKit = data->artKit; - m_DBTableGuid = guid; - if (map->GetInstanceId() != 0) guid = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); - - if (!Create(guid, entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit)) + m_spawnId = spawnId; + if (!Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit)) return false; if (data->spawntimesecs >= 0) @@ -854,13 +859,13 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) else { m_respawnDelayTime = data->spawntimesecs; - m_respawnTime = GetMap()->GetGORespawnTime(m_DBTableGuid); + m_respawnTime = GetMap()->GetGORespawnTime(m_spawnId); // ready to respawn if (m_respawnTime && m_respawnTime <= time(NULL)) { m_respawnTime = 0; - GetMap()->RemoveGORespawnTime(m_DBTableGuid); + GetMap()->RemoveGORespawnTime(m_spawnId); } } } @@ -881,18 +886,18 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) void GameObject::DeleteFromDB() { - GetMap()->RemoveGORespawnTime(m_DBTableGuid); - sObjectMgr->DeleteGOData(m_DBTableGuid); + GetMap()->RemoveGORespawnTime(m_spawnId); + sObjectMgr->DeleteGOData(m_spawnId); PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_GAMEOBJECT); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); WorldDatabase.Execute(stmt); stmt = WorldDatabase.GetPreparedStatement(WORLD_DEL_EVENT_GAMEOBJECT); - stmt->setUInt32(0, m_DBTableGuid); + stmt->setUInt32(0, m_spawnId); WorldDatabase.Execute(stmt); } @@ -960,7 +965,7 @@ Unit* GameObject::GetOwner() const void GameObject::SaveRespawnTime() { if (m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault) - GetMap()->SaveGORespawnTime(m_DBTableGuid, m_respawnTime); + GetMap()->SaveGORespawnTime(m_spawnId, m_respawnTime); } bool GameObject::IsNeverVisible() const @@ -1017,7 +1022,7 @@ void GameObject::Respawn() if (m_spawnedByDefault && m_respawnTime > 0) { m_respawnTime = time(NULL); - GetMap()->RemoveGORespawnTime(m_DBTableGuid); + GetMap()->RemoveGORespawnTime(m_spawnId); } } @@ -1142,7 +1147,7 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f void GameObject::SetGoArtKit(uint8 kit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, kit); - GameObjectData* data = const_cast<GameObjectData*>(sObjectMgr->GetGOData(m_DBTableGuid)); + GameObjectData* data = const_cast<GameObjectData*>(sObjectMgr->GetGOData(m_spawnId)); if (data) data->artKit = kit; } @@ -1335,7 +1340,7 @@ void GameObject::Use(Unit* user) if (info->goober.eventId) { - TC_LOG_DEBUG("maps.script", "Goober ScriptStart id %u for GO entry %u (GUID %u).", info->goober.eventId, GetEntry(), GetDBTableGUIDLow()); + TC_LOG_DEBUG("maps.script", "Goober ScriptStart id %u for GO entry %u (GUID %u).", info->goober.eventId, GetEntry(), GetSpawnId()); GetMap()->ScriptsStart(sEventScripts, info->goober.eventId, player, this); EventInform(info->goober.eventId, user); } @@ -1741,7 +1746,7 @@ void GameObject::Use(Unit* user) default: if (GetGoType() >= MAX_GAMEOBJECT_TYPE) TC_LOG_ERROR("misc", "GameObject::Use(): unit (type: %u, guid: %u, name: %s) tries to use object (guid: %u, entry: %u, name: %s) of unknown type (%u)", - user->GetTypeId(), user->GetGUIDLow(), user->GetName().c_str(), GetGUIDLow(), GetEntry(), GetGOInfo()->name.c_str(), GetGoType()); + user->GetTypeId(), user->GetGUID().GetCounter(), user->GetName().c_str(), GetGUID().GetCounter(), GetEntry(), GetGOInfo()->name.c_str(), GetGoType()); break; } @@ -2273,9 +2278,9 @@ void GameObject::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* t void GameObject::GetRespawnPosition(float &x, float &y, float &z, float* ori /* = NULL*/) const { - if (m_DBTableGuid) + if (m_spawnId) { - if (GameObjectData const* data = sObjectMgr->GetGOData(GetDBTableGUIDLow())) + if (GameObjectData const* data = sObjectMgr->GetGOData(GetSpawnId())) { x = data->posX; y = data->posY; diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 7ef8ef2737d..b91f1b6eeee 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -662,7 +662,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map bool IsDynTransport() const; bool IsDestructibleBuilding() const; - uint32 GetDBTableGUIDLow() const { return m_DBTableGuid; } + uint32 GetSpawnId() const { return m_spawnId; } void UpdateRotationFields(float rotation2 = 0.0f, float rotation3 = 0.0f); @@ -671,8 +671,8 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void SaveToDB(); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask); - bool LoadFromDB(uint32 guid, Map* map) { return LoadGameObjectFromDB(guid, map, false); } - bool LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap = true); + bool LoadFromDB(uint32 spawnId, Map* map) { return LoadGameObjectFromDB(spawnId, map, false); } + bool LoadGameObjectFromDB(uint32 spawnId, Map* map, bool addToMap = true); void DeleteFromDB(); void SetOwnerGUID(ObjectGuid owner) @@ -680,7 +680,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map // Owner already found and different than expected owner - remove object from old owner if (owner && GetOwnerGUID() && GetOwnerGUID() != owner) { - ASSERT(false); + ABORT(); } m_spawnedByDefault = false; // all object with owner is despawned after delay SetGuidValue(OBJECT_FIELD_CREATED_BY, owner); @@ -843,6 +843,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map float GetStationaryY() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionY(); return GetPositionY(); } float GetStationaryZ() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetPositionZ(); return GetPositionZ(); } float GetStationaryO() const override { if (GetGOInfo()->type != GAMEOBJECT_TYPE_MO_TRANSPORT) return m_stationaryPosition.GetOrientation(); return GetOrientation(); } + void RelocateStationaryPosition(float x, float y, float z, float o) { m_stationaryPosition.Relocate(x, y, z, o); } float GetInteractionDistance(); @@ -869,7 +870,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map typedef std::map<uint32, ObjectGuid> ChairSlotAndUser; ChairSlotAndUser ChairListSlots; - uint32 m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid + uint32 m_spawnId; ///< For new or temporary gameobjects is 0 for saved it is lowguid GameObjectTemplate const* m_goInfo; GameObjectData const* m_goData; GameObjectValue m_goValue; diff --git a/src/server/game/Entities/Item/Container/Bag.cpp b/src/server/game/Entities/Item/Container/Bag.cpp index e3a325d9c2d..69a77dd9213 100644 --- a/src/server/game/Entities/Item/Container/Bag.cpp +++ b/src/server/game/Entities/Item/Container/Bag.cpp @@ -76,7 +76,7 @@ bool Bag::Create(uint32 guidlow, uint32 itemid, Player const* owner) if (!itemProto || itemProto->ContainerSlots > MAX_BAG_SIZE) return false; - Object::_Create(guidlow, 0, HIGHGUID_CONTAINER); + Object::_Create(guidlow, 0, HighGuid::Container); SetEntry(itemid); SetObjectScale(1.0f); diff --git a/src/server/game/Entities/Item/Item.cpp b/src/server/game/Entities/Item/Item.cpp index 141bac5e50f..f5eb9972af5 100644 --- a/src/server/game/Entities/Item/Item.cpp +++ b/src/server/game/Entities/Item/Item.cpp @@ -257,7 +257,7 @@ Item::Item() bool Item::Create(uint32 guidlow, uint32 itemid, Player const* owner) { - Object::_Create(guidlow, 0, HIGHGUID_ITEM); + Object::_Create(guidlow, 0, HighGuid::Item); SetEntry(itemid); SetObjectScale(1.0f); @@ -317,7 +317,7 @@ void Item::SaveToDB(SQLTransaction& trans) if (!isInTransaction) trans = CharacterDatabase.BeginTransaction(); - uint32 guid = GetGUIDLow(); + uint32 guid = GetGUID().GetCounter(); switch (uState) { case ITEM_NEW: @@ -405,7 +405,7 @@ bool Item::LoadFromDB(uint32 guid, ObjectGuid owner_guid, Field* fields, uint32 // create item before any checks for store correct guid // and allow use "FSetState(ITEM_REMOVED); SaveToDB();" for deleting item from DB - Object::_Create(guid, 0, HIGHGUID_ITEM); + Object::_Create(guid, 0, HighGuid::Item); // Set entry, MUST be before proto check SetEntry(entry); @@ -420,8 +420,8 @@ bool Item::LoadFromDB(uint32 guid, ObjectGuid owner_guid, Field* fields, uint32 SetOwnerGUID(owner_guid); bool need_save = false; // need explicit save data at load fixes - SetGuidValue(ITEM_FIELD_CREATOR, ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32())); - SetGuidValue(ITEM_FIELD_GIFTCREATOR, ObjectGuid(HIGHGUID_PLAYER, fields[1].GetUInt32())); + SetGuidValue(ITEM_FIELD_CREATOR, ObjectGuid(HighGuid::Player, fields[0].GetUInt32())); + SetGuidValue(ITEM_FIELD_GIFTCREATOR, ObjectGuid(HighGuid::Player, fields[1].GetUInt32())); SetCount(fields[2].GetUInt32()); uint32 duration = fields[3].GetUInt32(); @@ -489,7 +489,7 @@ void Item::DeleteFromDB(SQLTransaction& trans, uint32 itemGuid) void Item::DeleteFromDB(SQLTransaction& trans) { - DeleteFromDB(trans, GetGUIDLow()); + DeleteFromDB(trans, GetGUID().GetCounter()); // Delete the items if this is a container if (!loot.isLooted()) @@ -506,7 +506,7 @@ void Item::DeleteFromInventoryDB(SQLTransaction& trans, uint32 itemGuid) void Item::DeleteFromInventoryDB(SQLTransaction& trans) { - DeleteFromInventoryDB(trans, GetGUIDLow()); + DeleteFromInventoryDB(trans, GetGUID().GetCounter()); } ItemTemplate const* Item::GetTemplate() const @@ -1061,7 +1061,7 @@ Item* Item::CreateItem(uint32 itemEntry, uint32 count, Player const* player) ASSERT(count != 0 && "pProto->Stackable == 0 but checked at loading already"); Item* item = NewItemOrBag(proto); - if (item->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), itemEntry, player)) + if (item->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), itemEntry, player)) { item->SetCount(count); return item; @@ -1070,7 +1070,7 @@ Item* Item::CreateItem(uint32 itemEntry, uint32 count, Player const* player) delete item; } else - ASSERT(false); + ABORT(); return NULL; } @@ -1101,7 +1101,7 @@ bool Item::IsBindedNotWith(Player const* player) const return false; if (HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_BOP_TRADEABLE)) - if (allowedGUIDs.find(player->GetGUIDLow()) != allowedGUIDs.end()) + if (allowedGUIDs.find(player->GetGUID().GetCounter()) != allowedGUIDs.end()) return false; // BOA item case @@ -1118,16 +1118,28 @@ void Item::BuildUpdate(UpdateDataMapType& data_map) ClearUpdateMask(false); } +void Item::AddToObjectUpdate() +{ + if (Player* owner = GetOwner()) + owner->GetMap()->AddUpdateObject(this); +} + +void Item::RemoveFromObjectUpdate() +{ + if (Player* owner = GetOwner()) + owner->GetMap()->RemoveUpdateObject(this); +} + void Item::SaveRefundDataToDB() { SQLTransaction trans = CharacterDatabase.BeginTransaction(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_REFUND_INSTANCE); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, GetRefundRecipient()); stmt->setUInt32(2, GetPaidMoney()); stmt->setUInt16(3, uint16(GetPaidExtendedCost())); @@ -1141,7 +1153,7 @@ void Item::DeleteRefundDataFromDB(SQLTransaction* trans) if (trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); (*trans)->Append(stmt); } @@ -1220,7 +1232,7 @@ void Item::ClearSoulboundTradeable(Player* currentOwner) allowedGUIDs.clear(); SetState(ITEM_CHANGED, currentOwner); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_BOP_TRADE); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } @@ -1242,7 +1254,7 @@ void Item::ItemContainerSaveLootToDB() if (loot.isLooted()) // no money and no loot return; - uint32 container_id = GetGUIDLow(); + uint32 container_id = GetGUID().GetCounter(); SQLTransaction trans = CharacterDatabase.BeginTransaction(); loot.containerID = container_id; // Save this for when a LootItem is removed @@ -1310,7 +1322,7 @@ bool Item::ItemContainerLoadLootFromDB() // Default. If there are no records for this item then it will be rolled for in Player::SendLoot() m_lootGenerated = false; - uint32 container_id = GetGUIDLow(); + uint32 container_id = GetGUID().GetCounter(); // Save this for later use loot.containerID = container_id; @@ -1364,7 +1376,7 @@ bool Item::ItemContainerLoadLootFromDB() // If container item is in a bag, add that player as an allowed looter if (GetBagSlot()) - loot_item.allowedGUIDs.insert(GetOwner()->GetGUIDLow()); + loot_item.allowedGUIDs.insert(GetOwner()->GetGUID().GetCounter()); // Finally add the LootItem to the container loot.items.push_back(loot_item); @@ -1386,7 +1398,7 @@ bool Item::ItemContainerLoadLootFromDB() void Item::ItemContainerDeleteLootItemsFromDB() { // Deletes items associated with an openable item from the DB - uint32 containerId = GetGUIDLow(); + uint32 containerId = GetGUID().GetCounter(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEMS); stmt->setUInt32(0, containerId); SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -1397,7 +1409,7 @@ void Item::ItemContainerDeleteLootItemsFromDB() void Item::ItemContainerDeleteLootItemFromDB(uint32 itemID) { // Deletes a single item associated with an openable item from the DB - uint32 containerId = GetGUIDLow(); + uint32 containerId = GetGUID().GetCounter(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_ITEM); stmt->setUInt32(0, containerId); stmt->setUInt32(1, itemID); @@ -1409,7 +1421,7 @@ void Item::ItemContainerDeleteLootItemFromDB(uint32 itemID) void Item::ItemContainerDeleteLootMoneyFromDB() { // Deletes the money loot associated with an openable item from the DB - uint32 containerId = GetGUIDLow(); + uint32 containerId = GetGUID().GetCounter(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEMCONTAINER_MONEY); stmt->setUInt32(0, containerId); SQLTransaction trans = CharacterDatabase.BeginTransaction(); diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index b832aeb5614..ad74906b4c9 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -350,6 +350,9 @@ class Item : public Object void BuildUpdate(UpdateDataMapType&) override; + void AddToObjectUpdate() override; + void RemoveFromObjectUpdate() override; + uint32 GetScriptId() const { return GetTemplate()->ScriptId; } private: std::string m_text; diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index fc55c09bffa..21a65440a55 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -67,7 +67,7 @@ WorldObject::~WorldObject() { TC_LOG_FATAL("misc", "WorldObject::~WorldObject Corpse Type: %d (%s) deleted but still in map!!", ToCorpse()->GetType(), GetGUID().ToString().c_str()); - ASSERT(false); + ABORT(); } ResetMap(); } @@ -80,15 +80,13 @@ Object::~Object() TC_LOG_FATAL("misc", "Object::~Object %s deleted but still in world!!", GetGUID().ToString().c_str()); if (isType(TYPEMASK_ITEM)) TC_LOG_FATAL("misc", "Item slot %u", ((Item*)this)->GetSlot()); - ASSERT(false); - RemoveFromWorld(); + ABORT(); } if (m_objectUpdated) { TC_LOG_FATAL("misc", "Object::~Object %s deleted but still in update list!!", GetGUID().ToString().c_str()); - ASSERT(false); - sObjectAccessor->RemoveUpdateObject(this); + ABORT(); } delete [] m_uint32Values; @@ -133,7 +131,8 @@ void Object::AddToWorld() m_inWorld = true; // synchronize values mirror with values array (changes will send in updatecreate opcode any way - ClearUpdateMask(true); + ASSERT(!m_objectUpdated); + ClearUpdateMask(false); } void Object::RemoveFromWorld() @@ -418,7 +417,7 @@ void Object::BuildMovementUpdate(ByteBuffer* data, uint16 flags) const case TYPEID_GAMEOBJECT: case TYPEID_DYNAMICOBJECT: case TYPEID_CORPSE: - *data << uint32(GetGUIDLow()); // GetGUIDLow() + *data << uint32(GetGUID().GetCounter()); // GetGUID().GetCounter() break; //! Unit, Player and default here are sending wrong values. /// @todo Research the proper formula @@ -509,6 +508,15 @@ void Object::BuildValuesUpdate(uint8 updateType, ByteBuffer* data, Player* targe data->append(fieldBuffer); } +void Object::AddToObjectUpdateIfNeeded() +{ + if (m_inWorld && !m_objectUpdated) + { + AddToObjectUpdate(); + m_objectUpdated = true; + } +} + void Object::ClearUpdateMask(bool remove) { _changesMask.Clear(); @@ -516,7 +524,8 @@ void Object::ClearUpdateMask(bool remove) if (m_objectUpdated) { if (remove) - sObjectAccessor->RemoveUpdateObject(this); + RemoveFromObjectUpdate(); + m_objectUpdated = false; } } @@ -614,11 +623,7 @@ void Object::SetInt32Value(uint16 index, int32 value) m_int32Values[index] = value; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -631,11 +636,7 @@ void Object::SetUInt32Value(uint16 index, uint32 value) m_uint32Values[index] = value; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -657,11 +658,7 @@ void Object::SetUInt64Value(uint16 index, uint64 value) _changesMask.SetBit(index); _changesMask.SetBit(index + 1); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -674,11 +671,7 @@ bool Object::AddGuidValue(uint16 index, ObjectGuid value) _changesMask.SetBit(index); _changesMask.SetBit(index + 1); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); return true; } @@ -696,11 +689,7 @@ bool Object::RemoveGuidValue(uint16 index, ObjectGuid value) _changesMask.SetBit(index); _changesMask.SetBit(index + 1); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); return true; } @@ -717,11 +706,7 @@ void Object::SetFloatValue(uint16 index, float value) m_floatValues[index] = value; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -741,11 +726,8 @@ void Object::SetByteValue(uint16 index, uint8 offset, uint8 value) m_uint32Values[index] |= uint32(uint32(value) << (offset * 8)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); + } } @@ -765,11 +747,7 @@ void Object::SetUInt16Value(uint16 index, uint8 offset, uint16 value) m_uint32Values[index] |= uint32(uint32(value) << (offset * 16)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -782,11 +760,7 @@ void Object::SetGuidValue(uint16 index, ObjectGuid value) _changesMask.SetBit(index); _changesMask.SetBit(index + 1); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -856,11 +830,7 @@ void Object::SetFlag(uint16 index, uint32 newFlag) m_uint32Values[index] = newval; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -877,11 +847,7 @@ void Object::RemoveFlag(uint16 index, uint32 oldFlag) m_uint32Values[index] = newval; _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -921,11 +887,7 @@ void Object::SetByteFlag(uint16 index, uint8 offset, uint8 newFlag) m_uint32Values[index] |= uint32(uint32(newFlag) << (offset * 8)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -944,11 +906,7 @@ void Object::RemoveByteFlag(uint16 index, uint8 offset, uint8 oldFlag) m_uint32Values[index] &= ~uint32(uint32(oldFlag) << (offset * 8)); _changesMask.SetBit(index); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } } @@ -1158,7 +1116,7 @@ bool WorldObject::_IsWithinDist(WorldObject const* obj, float dist2compare, bool float sizefactor = GetObjectSize() + obj->GetObjectSize(); float maxdist = dist2compare + sizefactor; - if (GetTransport() && obj->GetTransport() && obj->GetTransport()->GetGUIDLow() == GetTransport()->GetGUIDLow()) + if (GetTransport() && obj->GetTransport() && obj->GetTransport()->GetGUID().GetCounter() == GetTransport()->GetGUID().GetCounter()) { float dtx = m_movementInfo.transport.pos.m_positionX - obj->m_movementInfo.transport.pos.m_positionX; float dty = m_movementInfo.transport.pos.m_positionY - obj->m_movementInfo.transport.pos.m_positionY; @@ -1747,11 +1705,7 @@ bool WorldObject::CanDetectStealthOf(WorldObject const* obj, bool checkAlert) co void Object::ForceValuesUpdateAtIndex(uint32 i) { _changesMask.SetBit(i); - if (m_inWorld && !m_objectUpdated) - { - sObjectAccessor->AddUpdateObject(this); - m_objectUpdated = true; - } + AddToObjectUpdateIfNeeded(); } void Unit::BuildHeartBeatMsg(WorldPacket* data) const @@ -1789,13 +1743,13 @@ void WorldObject::SendObjectDeSpawnAnim(ObjectGuid guid) void WorldObject::SetMap(Map* map) { ASSERT(map); - ASSERT(!IsInWorld() || GetTypeId() == TYPEID_CORPSE); + ASSERT(!IsInWorld()); if (m_currMap == map) // command add npc: first create, than loadfromdb return; if (m_currMap) { TC_LOG_FATAL("misc", "WorldObject::SetMap: obj %u new map %u %u, old map %u %u", (uint32)GetTypeId(), map->GetId(), map->GetInstanceId(), m_currMap->GetId(), m_currMap->GetInstanceId()); - ASSERT(false); + ABORT(); } m_currMap = map; m_mapId = map->GetId(); @@ -1829,7 +1783,7 @@ void WorldObject::AddObjectToRemoveList() Map* map = FindMap(); if (!map) { - TC_LOG_ERROR("misc", "Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).", GetTypeId(), GetEntry(), GetGUIDLow(), GetMapId()); + TC_LOG_ERROR("misc", "Object (TypeId: %u Entry: %u GUID: %u) at attempt add to move list not have valid map (Id: %u).", GetTypeId(), GetEntry(), GetGUID().GetCounter(), GetMapId()); return; } @@ -1909,8 +1863,8 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert summon = new Minion(properties, summoner, false); break; } - - if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) + + if (!summon->Create(GenerateLowGuid<HighGuid::Unit>(), this, phase, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) { delete summon; return NULL; @@ -1964,6 +1918,11 @@ void WorldObject::SetZoneScript() } } +void WorldObject::ClearZoneScript() +{ + m_zoneScript = NULL; +} + TempSummon* WorldObject::SummonCreature(uint32 entry, const Position &pos, TempSummonType spwtype, uint32 duration, uint32 /*vehId*/) const { if (Map* map = FindMap()) @@ -2004,7 +1963,7 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float Map* map = GetMap(); GameObject* go = new GameObject(); - if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), entry, map, GetPhaseMask(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY)) + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), entry, map, GetPhaseMask(), x, y, z, ang, rotation0, rotation1, rotation2, rotation3, 100, GO_STATE_READY)) { delete go; return NULL; @@ -2288,7 +2247,7 @@ void WorldObject::MovePosition(Position &pos, float dist, float angle) if (!Trinity::IsValidMapCoord(destx, desty, pos.m_positionZ)) { TC_LOG_FATAL("misc", "WorldObject::MovePosition: Object (TypeId: %u Entry: %u GUID: %u) has invalid coordinates X: %f and Y: %f were passed!", - GetTypeId(), GetEntry(), GetGUIDLow(), destx, desty); + GetTypeId(), GetEntry(), GetGUID().GetCounter(), destx, desty); return; } @@ -2563,6 +2522,16 @@ void WorldObject::BuildUpdate(UpdateDataMapType& data_map) ClearUpdateMask(false); } +void WorldObject::AddToObjectUpdate() +{ + GetMap()->AddUpdateObject(this); +} + +void WorldObject::RemoveFromObjectUpdate() +{ + GetMap()->RemoveUpdateObject(this); +} + ObjectGuid WorldObject::GetTransGUID() const { if (GetTransport()) diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index e673e346a5f..43d1ecdeabd 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -101,9 +101,6 @@ class Object virtual void RemoveFromWorld(); ObjectGuid GetGUID() const { return GetGuidValue(OBJECT_FIELD_GUID); } - uint32 GetGUIDLow() const { return GetGuidValue(OBJECT_FIELD_GUID).GetCounter(); } - uint32 GetGUIDMid() const { return GetGuidValue(OBJECT_FIELD_GUID).GetEntry(); } - uint32 GetGUIDHigh() const { return GetGuidValue(OBJECT_FIELD_GUID).GetHigh(); } PackedGuid const& GetPackGUID() const { return m_PackGUID; } uint32 GetEntry() const { return GetUInt32Value(OBJECT_FIELD_ENTRY); } void SetEntry(uint32 entry) { SetUInt32Value(OBJECT_FIELD_ENTRY, entry); } @@ -234,6 +231,10 @@ class Object uint16 _fieldNotifyFlags; + virtual void AddToObjectUpdate() = 0; + virtual void RemoveFromObjectUpdate() = 0; + void AddToObjectUpdateIfNeeded(); + bool m_objectUpdated; private: @@ -535,6 +536,7 @@ class WorldObject : public Object, public WorldLocation Map const* GetBaseMap() const; void SetZoneScript(); + void ClearZoneScript(); ZoneScript* GetZoneScript() const { return m_zoneScript; } TempSummon* SummonCreature(uint32 id, Position const &pos, TempSummonType spwtype = TEMPSUMMON_MANUAL_DESPAWN, uint32 despwtime = 0, uint32 vehId = 0) const; @@ -555,6 +557,9 @@ class WorldObject : public Object, public WorldLocation virtual void UpdateObjectVisibility(bool forced = true); void BuildUpdate(UpdateDataMapType&) override; + void AddToObjectUpdate() override; + void RemoveFromObjectUpdate() override; + //relocation and visibility system functions void AddToNotify(uint16 f) { m_notifyflags |= f;} bool isNeedNotify(uint16 f) const { return (m_notifyflags & f) != 0; } diff --git a/src/server/game/Entities/Object/ObjectGuid.cpp b/src/server/game/Entities/Object/ObjectGuid.cpp index b86a253a84d..552705d8df8 100644 --- a/src/server/game/Entities/Object/ObjectGuid.cpp +++ b/src/server/game/Entities/Object/ObjectGuid.cpp @@ -28,18 +28,18 @@ char const* ObjectGuid::GetTypeName(HighGuid high) { switch (high) { - case HIGHGUID_ITEM: return "Item"; - case HIGHGUID_PLAYER: return "Player"; - case HIGHGUID_GAMEOBJECT: return "Gameobject"; - case HIGHGUID_TRANSPORT: return "Transport"; - case HIGHGUID_UNIT: return "Creature"; - case HIGHGUID_PET: return "Pet"; - case HIGHGUID_VEHICLE: return "Vehicle"; - case HIGHGUID_DYNAMICOBJECT: return "DynObject"; - case HIGHGUID_CORPSE: return "Corpse"; - case HIGHGUID_MO_TRANSPORT: return "MoTransport"; - case HIGHGUID_INSTANCE: return "InstanceID"; - case HIGHGUID_GROUP: return "Group"; + case HighGuid::Item: return "Item"; + case HighGuid::Player: return "Player"; + case HighGuid::GameObject: return "Gameobject"; + case HighGuid::Transport: return "Transport"; + case HighGuid::Unit: return "Creature"; + case HighGuid::Pet: return "Pet"; + case HighGuid::Vehicle: return "Vehicle"; + case HighGuid::DynamicObject: return "DynObject"; + case HighGuid::Corpse: return "Corpse"; + case HighGuid::Mo_Transport: return "MoTransport"; + case HighGuid::Instance: return "InstanceID"; + case HighGuid::Group: return "Group"; default: return "<unknown>"; } @@ -57,15 +57,14 @@ std::string ObjectGuid::ToString() const return str.str(); } -template<HighGuid high> -uint32 ObjectGuidGenerator<high>::Generate() +ObjectGuid ObjectGuid::Global(HighGuid type, LowType counter) { - if (_nextGuid >= ObjectGuid::GetMaxCounter(high) - 1) - { - TC_LOG_ERROR("", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high)); - World::StopNow(ERROR_EXIT_CODE); - } - return _nextGuid++; + return ObjectGuid(type, counter); +} + +ObjectGuid ObjectGuid::MapSpecific(HighGuid type, uint32 entry, LowType counter) +{ + return ObjectGuid(type, entry, counter); } ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid) @@ -92,14 +91,8 @@ ByteBuffer& operator>>(ByteBuffer& buf, PackedGuidReader const& guid) return buf; } -template uint32 ObjectGuidGenerator<HIGHGUID_ITEM>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_PLAYER>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_GAMEOBJECT>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_TRANSPORT>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_UNIT>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_PET>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_VEHICLE>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_DYNAMICOBJECT>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_CORPSE>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_INSTANCE>::Generate(); -template uint32 ObjectGuidGenerator<HIGHGUID_GROUP>::Generate(); +void ObjectGuidGeneratorBase::HandleCounterOverflow(HighGuid high) +{ + TC_LOG_ERROR("misc", "%s guid overflow!! Can't continue, shutting down server. ", ObjectGuid::GetTypeName(high)); + World::StopNow(ERROR_EXIT_CODE); +}
\ No newline at end of file diff --git a/src/server/game/Entities/Object/ObjectGuid.h b/src/server/game/Entities/Object/ObjectGuid.h index b541328c467..705cc3eac3e 100644 --- a/src/server/game/Entities/Object/ObjectGuid.h +++ b/src/server/game/Entities/Object/ObjectGuid.h @@ -22,6 +22,7 @@ #include "Common.h" #include "ByteBuffer.h" +#include <type_traits> #include <functional> #include <unordered_set> @@ -52,23 +53,57 @@ enum TypeMask TYPEMASK_SEER = TYPEMASK_PLAYER | TYPEMASK_UNIT | TYPEMASK_DYNAMICOBJECT }; -enum HighGuid +enum class HighGuid { - HIGHGUID_ITEM = 0x4000, // blizz 4000 - HIGHGUID_CONTAINER = 0x4000, // blizz 4000 - HIGHGUID_PLAYER = 0x0000, // blizz 0000 - HIGHGUID_GAMEOBJECT = 0xF110, // blizz F110 - HIGHGUID_TRANSPORT = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) - HIGHGUID_UNIT = 0xF130, // blizz F130 - HIGHGUID_PET = 0xF140, // blizz F140 - HIGHGUID_VEHICLE = 0xF150, // blizz F550 - HIGHGUID_DYNAMICOBJECT = 0xF100, // blizz F100 - HIGHGUID_CORPSE = 0xF101, // blizz F100 - HIGHGUID_MO_TRANSPORT = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) - HIGHGUID_INSTANCE = 0x1F40, // blizz 1F40 - HIGHGUID_GROUP = 0x1F50 + Item = 0x4000, // blizz 4000 + Container = 0x4000, // blizz 4000 + Player = 0x0000, // blizz 0000 + GameObject = 0xF110, // blizz F110 + Transport = 0xF120, // blizz F120 (for GAMEOBJECT_TYPE_TRANSPORT) + Unit = 0xF130, // blizz F130 + Pet = 0xF140, // blizz F140 + Vehicle = 0xF150, // blizz F550 + DynamicObject = 0xF100, // blizz F100 + Corpse = 0xF101, // blizz F100 + Mo_Transport = 0x1FC0, // blizz 1FC0 (for GAMEOBJECT_TYPE_MO_TRANSPORT) + Instance = 0x1F40, // blizz 1F40 + Group = 0x1F50, }; +template<HighGuid high> +struct ObjectGuidTraits +{ + static bool const Global = false; + static bool const MapSpecific = false; +}; + +#define GUID_TRAIT_GLOBAL(highguid) \ + template<> struct ObjectGuidTraits<highguid> \ + { \ + static bool const Global = true; \ + static bool const MapSpecific = false; \ + }; + +#define GUID_TRAIT_MAP_SPECIFIC(highguid) \ + template<> struct ObjectGuidTraits<highguid> \ + { \ + static bool const Global = false; \ + static bool const MapSpecific = true; \ + }; + +GUID_TRAIT_GLOBAL(HighGuid::Player) +GUID_TRAIT_GLOBAL(HighGuid::Item) +GUID_TRAIT_GLOBAL(HighGuid::Mo_Transport) +GUID_TRAIT_GLOBAL(HighGuid::Group) +GUID_TRAIT_GLOBAL(HighGuid::Instance) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Transport) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Unit) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Vehicle) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Pet) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::GameObject) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::DynamicObject) +GUID_TRAIT_MAP_SPECIFIC(HighGuid::Corpse) + class ObjectGuid; class PackedGuid; @@ -85,6 +120,12 @@ class ObjectGuid typedef uint32 LowType; + template<HighGuid type> + static typename std::enable_if<ObjectGuidTraits<type>::Global, ObjectGuid>::type Create(LowType counter) { return Global(type, counter); } + + template<HighGuid type> + static typename std::enable_if<ObjectGuidTraits<type>::MapSpecific, ObjectGuid>::type Create(uint32 entry, LowType counter) { return MapSpecific(type, entry, counter); } + ObjectGuid() : _guid(0) { } explicit ObjectGuid(uint64 guid) : _guid(guid) { } ObjectGuid(HighGuid hi, uint32 entry, LowType counter) : _guid(counter ? uint64(counter) | (uint64(entry) << 24) | (uint64(hi) << 48) : 0) { } @@ -123,41 +164,41 @@ class ObjectGuid uint32 GetMaxCounter() const { return GetMaxCounter(GetHigh()); } bool IsEmpty() const { return _guid == 0; } - bool IsCreature() const { return GetHigh() == HIGHGUID_UNIT; } - bool IsPet() const { return GetHigh() == HIGHGUID_PET; } - bool IsVehicle() const { return GetHigh() == HIGHGUID_VEHICLE; } + bool IsCreature() const { return GetHigh() == HighGuid::Unit; } + bool IsPet() const { return GetHigh() == HighGuid::Pet; } + bool IsVehicle() const { return GetHigh() == HighGuid::Vehicle; } bool IsCreatureOrPet() const { return IsCreature() || IsPet(); } bool IsCreatureOrVehicle() const { return IsCreature() || IsVehicle(); } bool IsAnyTypeCreature() const { return IsCreature() || IsPet() || IsVehicle(); } - bool IsPlayer() const { return !IsEmpty() && GetHigh() == HIGHGUID_PLAYER; } + bool IsPlayer() const { return !IsEmpty() && GetHigh() == HighGuid::Player; } bool IsUnit() const { return IsAnyTypeCreature() || IsPlayer(); } - bool IsItem() const { return GetHigh() == HIGHGUID_ITEM; } - bool IsGameObject() const { return GetHigh() == HIGHGUID_GAMEOBJECT; } - bool IsDynamicObject() const { return GetHigh() == HIGHGUID_DYNAMICOBJECT; } - bool IsCorpse() const { return GetHigh() == HIGHGUID_CORPSE; } - bool IsTransport() const { return GetHigh() == HIGHGUID_TRANSPORT; } - bool IsMOTransport() const { return GetHigh() == HIGHGUID_MO_TRANSPORT; } + bool IsItem() const { return GetHigh() == HighGuid::Item; } + bool IsGameObject() const { return GetHigh() == HighGuid::GameObject; } + bool IsDynamicObject() const { return GetHigh() == HighGuid::DynamicObject; } + bool IsCorpse() const { return GetHigh() == HighGuid::Corpse; } + bool IsTransport() const { return GetHigh() == HighGuid::Transport; } + bool IsMOTransport() const { return GetHigh() == HighGuid::Mo_Transport; } bool IsAnyTypeGameObject() const { return IsGameObject() || IsTransport() || IsMOTransport(); } - bool IsInstance() const { return GetHigh() == HIGHGUID_INSTANCE; } - bool IsGroup() const { return GetHigh() == HIGHGUID_GROUP; } + bool IsInstance() const { return GetHigh() == HighGuid::Instance; } + bool IsGroup() const { return GetHigh() == HighGuid::Group; } static TypeID GetTypeId(HighGuid high) { switch (high) { - case HIGHGUID_ITEM: return TYPEID_ITEM; - //case HIGHGUID_CONTAINER: return TYPEID_CONTAINER; HIGHGUID_CONTAINER==HIGHGUID_ITEM currently - case HIGHGUID_UNIT: return TYPEID_UNIT; - case HIGHGUID_PET: return TYPEID_UNIT; - case HIGHGUID_PLAYER: return TYPEID_PLAYER; - case HIGHGUID_GAMEOBJECT: return TYPEID_GAMEOBJECT; - case HIGHGUID_DYNAMICOBJECT: return TYPEID_DYNAMICOBJECT; - case HIGHGUID_CORPSE: return TYPEID_CORPSE; - case HIGHGUID_MO_TRANSPORT: return TYPEID_GAMEOBJECT; - case HIGHGUID_VEHICLE: return TYPEID_UNIT; + case HighGuid::Item: return TYPEID_ITEM; + //case HighGuid::Container: return TYPEID_CONTAINER; HighGuid::Container==HighGuid::Item currently + case HighGuid::Unit: return TYPEID_UNIT; + case HighGuid::Pet: return TYPEID_UNIT; + case HighGuid::Player: return TYPEID_PLAYER; + case HighGuid::GameObject: return TYPEID_GAMEOBJECT; + case HighGuid::DynamicObject: return TYPEID_DYNAMICOBJECT; + case HighGuid::Corpse: return TYPEID_CORPSE; + case HighGuid::Mo_Transport: return TYPEID_GAMEOBJECT; + case HighGuid::Vehicle: return TYPEID_UNIT; // unknown - case HIGHGUID_INSTANCE: - case HIGHGUID_GROUP: + case HighGuid::Instance: + case HighGuid::Group: default: return TYPEID_OBJECT; } } @@ -178,19 +219,19 @@ class ObjectGuid { switch (high) { - case HIGHGUID_ITEM: - case HIGHGUID_PLAYER: - case HIGHGUID_DYNAMICOBJECT: - case HIGHGUID_CORPSE: - case HIGHGUID_MO_TRANSPORT: - case HIGHGUID_INSTANCE: - case HIGHGUID_GROUP: + case HighGuid::Item: + case HighGuid::Player: + case HighGuid::DynamicObject: + case HighGuid::Corpse: + case HighGuid::Mo_Transport: + case HighGuid::Instance: + case HighGuid::Group: return false; - case HIGHGUID_GAMEOBJECT: - case HIGHGUID_TRANSPORT: - case HIGHGUID_UNIT: - case HIGHGUID_PET: - case HIGHGUID_VEHICLE: + case HighGuid::GameObject: + case HighGuid::Transport: + case HighGuid::Unit: + case HighGuid::Pet: + case HighGuid::Vehicle: default: return true; } @@ -198,6 +239,9 @@ class ObjectGuid bool HasEntry() const { return HasEntry(GetHigh()); } + static ObjectGuid Global(HighGuid type, LowType counter); + static ObjectGuid MapSpecific(HighGuid type, uint32 entry, LowType counter); + explicit ObjectGuid(uint32 const&) = delete; // no implementation, used to catch wrong type assignment ObjectGuid(HighGuid, uint32, uint64 counter) = delete; // no implementation, used to catch wrong type assignment ObjectGuid(HighGuid, uint64 counter) = delete; // no implementation, used to catch wrong type assignment @@ -233,18 +277,33 @@ class PackedGuid ByteBuffer _packedGuid; }; -template<HighGuid high> -class ObjectGuidGenerator + +class ObjectGuidGeneratorBase { - public: - explicit ObjectGuidGenerator(uint32 start = 1) : _nextGuid(start) { } +public: + ObjectGuidGeneratorBase(ObjectGuid::LowType start = 1) : _nextGuid(start) { } - void Set(uint32 val) { _nextGuid = val; } - uint32 Generate(); - uint32 GetNextAfterMaxUsed() const { return _nextGuid; } + virtual void Set(uint32 val) { _nextGuid = val; } + virtual ObjectGuid::LowType Generate() = 0; + ObjectGuid::LowType GetNextAfterMaxUsed() const { return _nextGuid; } - private: - uint32 _nextGuid; +protected: + static void HandleCounterOverflow(HighGuid high); + uint64 _nextGuid; +}; + +template<HighGuid high> +class ObjectGuidGenerator : public ObjectGuidGeneratorBase +{ +public: + explicit ObjectGuidGenerator(ObjectGuid::LowType start = 1) : ObjectGuidGeneratorBase(start) { } + + ObjectGuid::LowType Generate() override + { + if (_nextGuid >= ObjectGuid::GetMaxCounter(high) - 1) + HandleCounterOverflow(high); + return _nextGuid++; + } }; ByteBuffer& operator<<(ByteBuffer& buf, ObjectGuid const& guid); diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index c9b9c72d432..57fc56af89c 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -66,7 +66,7 @@ void Pet::AddToWorld() if (!IsInWorld()) { ///- Register the pet for guid lookup - sObjectAccessor->AddObject(this); + GetMap()->GetObjectsStore().Insert<Pet>(GetGUID(), this); Unit::AddToWorld(); AIM_Initialize(); } @@ -90,7 +90,7 @@ void Pet::RemoveFromWorld() { ///- Don't call the function for Creature, normal mobs + totems go in a different storage Unit::RemoveFromWorld(); - sObjectAccessor->RemoveObject(this); + GetMap()->GetObjectsStore().Remove<Pet>(GetGUID()); } } @@ -98,7 +98,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c { m_loading = true; - uint32 ownerid = owner->GetGUIDLow(); + uint32 ownerid = owner->GetGUID().GetCounter(); PreparedStatement* stmt; PreparedQueryResult result; @@ -174,7 +174,8 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c } Map* map = owner->GetMap(); - uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_PET); + uint32 guid = map->GenerateLowGuid<HighGuid::Pet>(); + if (!Create(guid, map, owner->GetPhaseMask(), petEntry, petId)) return false; @@ -191,7 +192,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c if (!IsPositionValid()) { TC_LOG_ERROR("entities.pet", "Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", - GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); + GetGUID().GetCounter(), GetEntry(), GetPositionX(), GetPositionY()); return false; } @@ -248,7 +249,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c if (!IsPositionValid()) { TC_LOG_ERROR("entities.pet", "Pet (guidlow %d, entry %d) not loaded. Suggested coordinates isn't valid (X: %f Y: %f)", - GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); + GetGUID().GetCounter(), GetEntry(), GetPositionX(), GetPositionY()); return false; } @@ -332,7 +333,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c CleanupActionBar(); // remove unknown spells from action bar after load - TC_LOG_DEBUG("entities.pet", "New Pet has guid %u", GetGUIDLow()); + TC_LOG_DEBUG("entities.pet", "New Pet has guid %u", GetGUID().GetCounter()); owner->PetSpellInitialize(); @@ -344,7 +345,7 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c if (getPetType() == HUNTER_PET) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_DECLINED_NAME); - stmt->setUInt32(0, owner->GetGUIDLow()); + stmt->setUInt32(0, owner->GetGUID().GetCounter()); stmt->setUInt32(1, GetCharmInfo()->GetPetNumber()); result = CharacterDatabase.Query(stmt); @@ -769,7 +770,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature) if (!IsPositionValid()) { TC_LOG_ERROR("entities.pet", "Pet (guidlow %d, entry %d) not created base at creature. Suggested coordinates isn't valid (X: %f Y: %f)", - GetGUIDLow(), GetEntry(), GetPositionX(), GetPositionY()); + GetGUID().GetCounter(), GetEntry(), GetPositionX(), GetPositionY()); return false; } @@ -806,7 +807,7 @@ bool Pet::CreateBaseAtCreatureInfo(CreatureTemplate const* cinfo, Unit* owner) bool Pet::CreateBaseAtTamed(CreatureTemplate const* cinfo, Map* map, uint32 phaseMask) { TC_LOG_DEBUG("entities.pet", "Pet::CreateBaseForTamed"); - uint32 guid=sObjectMgr->GenerateLowGuid(HIGHGUID_PET); + uint32 guid=map->GenerateLowGuid<HighGuid::Pet>(); uint32 petId = sObjectMgr->GeneratePetNumber(); if (!Create(guid, map, phaseMask, cinfo->Entry, petId)) return false; @@ -1183,7 +1184,7 @@ void Pet::_SaveSpells(SQLTransaction& trans) void Pet::_LoadAuras(uint32 timediff) { - TC_LOG_DEBUG("entities.pet", "Loading auras for pet %u", GetGUIDLow()); + TC_LOG_DEBUG("entities.pet", "Loading auras for pet %u", GetGUID().GetCounter()); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_AURA); stmt->setUInt32(0, m_charmInfo->GetPetNumber()); @@ -1679,7 +1680,7 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/) uint32 exceptPetNumber = onlinePet ? onlinePet->GetCharmInfo()->GetPetNumber() : 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHAR_PET); - stmt->setUInt32(0, owner->GetGUIDLow()); + stmt->setUInt32(0, owner->GetGUID().GetCounter()); stmt->setUInt32(1, exceptPetNumber); PreparedQueryResult resultPets = CharacterDatabase.Query(stmt); @@ -1688,7 +1689,7 @@ void Pet::resetTalentsForAllPetsOf(Player* owner, Pet* onlinePet /*= NULL*/) return; stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SPELL_LIST); - stmt->setUInt32(0, owner->GetGUIDLow()); + stmt->setUInt32(0, owner->GetGUID().GetCounter()); stmt->setUInt32(1, exceptPetNumber); PreparedQueryResult result = CharacterDatabase.Query(stmt); @@ -1840,9 +1841,9 @@ bool Pet::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 Entry, uint3 SetMap(map); SetPhaseMask(phaseMask, false); - Object::_Create(guidlow, petId, HIGHGUID_PET); + Object::_Create(guidlow, petId, HighGuid::Pet); - m_DBTableGuid = guidlow; + m_spawnId = guidlow; m_originalEntry = Entry; if (!InitEntry(Entry)) diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h index b1d7fcaa28a..e47bf220195 100644 --- a/src/server/game/Entities/Pet/Pet.h +++ b/src/server/game/Entities/Pet/Pet.h @@ -159,11 +159,11 @@ class Pet : public Guardian private: void SaveToDB(uint32, uint8, uint32) override // override of Creature::SaveToDB - must not be called { - ASSERT(false); + ABORT(); } void DeleteFromDB() override // override of Creature::DeleteFromDB - must not be called { - ASSERT(false); + ABORT(); } }; #endif diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 25531760b69..1be3c2454b2 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -962,7 +962,7 @@ bool Player::Create(uint32 guidlow, CharacterCreateInfo* createInfo) //FIXME: outfitId not used in player creating /// @todo need more checks against packet modifications - Object::_Create(guidlow, 0, HIGHGUID_PLAYER); + Object::_Create(guidlow, 0, HighGuid::Player); m_name = createInfo->Name; @@ -1802,7 +1802,7 @@ void Player::Update(uint32 p_time) { // m_nextSave reset in SaveToDB call SaveToDB(); - TC_LOG_DEBUG("entities.player", "Player '%s' (GUID: %u) saved", GetName().c_str(), GetGUIDLow()); + TC_LOG_DEBUG("entities.player", "Player '%s' (GUID: %u) saved", GetName().c_str(), GetGUID().GetCounter()); } else m_nextSave -= p_time; @@ -1911,7 +1911,7 @@ void Player::setDeathState(DeathState s) { if (!cur) { - TC_LOG_ERROR("entities.player", "setDeathState: attempt to kill a dead player %s(%d)", GetName().c_str(), GetGUIDLow()); + TC_LOG_ERROR("entities.player", "setDeathState: attempt to kill a dead player %s(%d)", GetName().c_str(), GetGUID().GetCounter()); return; } @@ -1978,7 +1978,7 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) return false; } - *data << ObjectGuid(HIGHGUID_PLAYER, guid); + *data << ObjectGuid(HighGuid::Player, guid); *data << fields[1].GetString(); // name *data << uint8(plrRace); // race *data << uint8(plrClass); // class @@ -2022,6 +2022,8 @@ bool Player::BuildEnumData(PreparedQueryResult result, WorldPacket* data) uint32 charFlags = 0; uint32 playerFlags = fields[14].GetUInt32(); + if (atLoginFlags & AT_LOGIN_RESURRECT) + playerFlags &= ~PLAYER_FLAGS_GHOST; if (playerFlags & PLAYER_FLAGS_HIDE_HELM) charFlags |= CHARACTER_FLAG_HIDE_HELM; if (playerFlags & PLAYER_FLAGS_HIDE_CLOAK) @@ -2158,13 +2160,13 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati if (!MapManager::IsValidMapCoord(mapid, x, y, z, orientation)) { TC_LOG_ERROR("maps", "TeleportTo: invalid map (%d) or invalid coordinates (X: %f, Y: %f, Z: %f, O: %f) given when teleporting player (GUID: %u, name: %s, map: %d, X: %f, Y: %f, Z: %f, O: %f).", - mapid, x, y, z, orientation, GetGUIDLow(), GetName().c_str(), GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); + mapid, x, y, z, orientation, GetGUID().GetCounter(), GetName().c_str(), GetMapId(), GetPositionX(), GetPositionY(), GetPositionZ(), GetOrientation()); return false; } if (!GetSession()->HasPermission(rbac::RBAC_PERM_SKIP_CHECK_DISABLE_MAP) && DisableMgr::IsDisabledFor(DISABLE_TYPE_MAP, mapid, this)) { - TC_LOG_ERROR("maps", "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUIDLow(), GetName().c_str(), mapid); + TC_LOG_ERROR("maps", "Player (GUID: %u, name: %s) tried to enter a forbidden map %u", GetGUID().GetCounter(), GetName().c_str(), mapid); SendTransferAborted(mapid, TRANSFER_ABORT_MAP_NOT_ALLOWED); return false; } @@ -2485,17 +2487,18 @@ void Player::RemoveFromWorld() sBattlefieldMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); } - ///- Do not add/remove the player from the object storage - ///- It will crash when updating the ObjectAccessor - ///- The player should only be removed when logging out - Unit::RemoveFromWorld(); - + // Remove items from world before self - player must be found in Item::RemoveFromObjectUpdate for (uint8 i = PLAYER_SLOT_START; i < PLAYER_SLOT_END; ++i) { if (m_items[i]) m_items[i]->RemoveFromWorld(); } + ///- Do not add/remove the player from the object storage + ///- It will crash when updating the ObjectAccessor + ///- The player should only be removed when logging out + Unit::RemoveFromWorld(); + for (ItemMap::iterator iter = mMitems.begin(); iter != mMitems.end(); ++iter) iter->second->RemoveFromWorld(); @@ -2806,7 +2809,7 @@ GameObject* Player::GetGameObjectIfCanInteractWith(ObjectGuid guid, GameobjectTy return go; TC_LOG_DEBUG("maps", "GetGameObjectIfCanInteractWith: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name.c_str(), - go->GetGUIDLow(), GetName().c_str(), GetGUIDLow(), go->GetDistance(this)); + go->GetGUID().GetCounter(), GetName().c_str(), GetGUID().GetCounter(), go->GetDistance(this)); } } @@ -4536,10 +4539,6 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe charDelete_method = CHAR_DELETE_REMOVE; } - // 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 - sObjectAccessor->ConvertCorpseForPlayer(playerguid); - if (uint32 guildId = GetGuildIdFromDB(playerguid)) if (Guild* guild = sGuildMgr->GetGuildById(guildId)) guild->DeleteMember(playerguid, false, false, true); @@ -4679,7 +4678,7 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe { do { - if (Player* pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, (*resultFriends)[0].GetUInt32()))) + if (Player* pFriend = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, 0, (*resultFriends)[0].GetUInt32()))) { pFriend->GetSocial()->RemoveFromSocialList(guid, false); sSocialMgr->SendFriendStatus(pFriend, FRIEND_REMOVED, guid, false); @@ -4840,6 +4839,8 @@ void Player::DeleteFromDB(ObjectGuid playerguid, uint32 accountId, bool updateRe stmt->setUInt32(0, guid); trans->Append(stmt); + Corpse::DeleteFromDB(playerguid, trans); + CharacterDatabase.CommitTransaction(trans); break; } @@ -4899,7 +4900,7 @@ void Player::DeleteOldCharacters(uint32 keepDays) do { Field* fields = result->Fetch(); - Player::DeleteFromDB(ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()), fields[1].GetUInt32(), true, true); + Player::DeleteFromDB(ObjectGuid(HighGuid::Player, fields[0].GetUInt32()), fields[1].GetUInt32(), true, true); } while (result->NextRow()); } @@ -4939,21 +4940,20 @@ void Player::BuildPlayerRepop() // there must be SMSG.FORCE_RUN_SPEED_CHANGE, SMSG.FORCE_SWIM_SPEED_CHANGE, SMSG.MOVE_WATER_WALK // there must be SMSG.STOP_MIRROR_TIMER - // there we must send 888 opcode - // the player cannot have a corpse already, only bones which are not returned by GetCorpse - if (GetCorpse()) + // the player cannot have a corpse already on current map, only bones which are not returned by GetCorpse + WorldLocation corpseLocation = GetCorpseLocation(); + if (corpseLocation.GetMapId() == GetMapId()) { - TC_LOG_ERROR("entities.player", "BuildPlayerRepop: player %s(%d) already has a corpse", GetName().c_str(), GetGUIDLow()); + TC_LOG_ERROR("entities.player", "BuildPlayerRepop: player %s(%d) already has a corpse", GetName().c_str(), GetGUID().GetCounter()); return; } // create a corpse and place it at the player's location - CreateCorpse(); - Corpse* corpse = GetCorpse(); + Corpse* corpse = CreateCorpse(); if (!corpse) { - TC_LOG_ERROR("entities.player", "Error creating corpse for Player %s [%u]", GetName().c_str(), GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Error creating corpse for Player %s [%u]", GetName().c_str(), GetGUID().GetCounter()); return; } GetMap()->AddToMap(corpse); @@ -5092,7 +5092,16 @@ void Player::KillPlayer() UpdateObjectVisibility(); } -void Player::CreateCorpse() +void Player::OfflineResurrect(ObjectGuid const& guid, SQLTransaction& trans) +{ + Corpse::DeleteFromDB(guid, trans); + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ADD_AT_LOGIN_FLAG); + stmt->setUInt16(0, uint16(AT_LOGIN_RESURRECT)); + stmt->setUInt64(1, guid.GetCounter()); + CharacterDatabase.ExecuteOrAppend(trans, stmt); +} + +Corpse* Player::CreateCorpse() { // prevent existence 2 corpse for player SpawnCorpseBones(); @@ -5102,12 +5111,14 @@ void Player::CreateCorpse() Corpse* corpse = new Corpse((m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE); SetPvPDeath(false); - if (!corpse->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_CORPSE), this)) + if (!corpse->Create(GetMap()->GenerateLowGuid<HighGuid::Corpse>(), this)) { delete corpse; - return; + return nullptr; } + _corpseLocation.WorldRelocate(*this); + _uf = GetUInt32Value(UNIT_FIELD_BYTES_0); _pb = GetUInt32Value(PLAYER_BYTES); _pb2 = GetUInt32Value(PLAYER_BYTES_2); @@ -5158,19 +5169,21 @@ void Player::CreateCorpse() corpse->SaveToDB(); // register for player, but not show - sObjectAccessor->AddCorpse(corpse); + GetMap()->AddCorpse(corpse); + return corpse; } -void Player::SpawnCorpseBones() +void Player::SpawnCorpseBones(bool triggerSave /*= true*/) { - if (sObjectAccessor->ConvertCorpseForPlayer(GetGUID())) - if (!GetSession()->PlayerLogoutWithSave()) // at logout we will already store the player - SaveToDB(); // prevent loading as ghost without corpse + _corpseLocation.WorldRelocate(); + if (GetMap()->ConvertCorpseToBones(GetGUID())) + if (triggerSave && !GetSession()->PlayerLogoutWithSave()) // at logout we will already store the player + SaveToDB(); // prevent loading as ghost without corpse } Corpse* Player::GetCorpse() const { - return sObjectAccessor->GetCorpseForPlayerGUID(GetGUID()); + return GetMap()->GetCorpseByPlayer(GetGUID()); } void Player::DurabilityLossAll(double percent, bool inventory) @@ -6521,20 +6534,20 @@ void Player::SendActionButtons(uint32 state) const } GetSession()->SendPacket(&data); - TC_LOG_DEBUG("network", "SMSG_ACTION_BUTTONS sent '%u' spec '%u' Sent", GetGUIDLow(), m_activeSpec); + TC_LOG_DEBUG("network", "SMSG_ACTION_BUTTONS sent '%u' spec '%u' Sent", GetGUID().GetCounter(), m_activeSpec); } bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) { if (button >= MAX_ACTION_BUTTONS) { - TC_LOG_DEBUG("entities.player", "Action %u not added into button %u for player %s (GUID: %u): button must be < %u", action, button, GetName().c_str(), GetGUIDLow(), MAX_ACTION_BUTTONS ); + TC_LOG_DEBUG("entities.player", "Action %u not added into button %u for player %s (GUID: %u): button must be < %u", action, button, GetName().c_str(), GetGUID().GetCounter(), MAX_ACTION_BUTTONS ); return false; } if (action >= MAX_ACTION_BUTTON_ACTION_VALUE) { - TC_LOG_DEBUG("entities.player", "Action %u not added into button %u for player %s (GUID: %u): action must be < %u", action, button, GetName().c_str(), GetGUIDLow(), MAX_ACTION_BUTTON_ACTION_VALUE); + TC_LOG_DEBUG("entities.player", "Action %u not added into button %u for player %s (GUID: %u): action must be < %u", action, button, GetName().c_str(), GetGUID().GetCounter(), MAX_ACTION_BUTTON_ACTION_VALUE); return false; } @@ -6543,20 +6556,20 @@ bool Player::IsActionButtonDataValid(uint8 button, uint32 action, uint8 type) case ACTION_BUTTON_SPELL: if (!sSpellMgr->GetSpellInfo(action)) { - TC_LOG_DEBUG("entities.player", "Spell action %u not added into button %u for player %s (GUID: %u): spell not exist", action, button, GetName().c_str(), GetGUIDLow()); + TC_LOG_DEBUG("entities.player", "Spell action %u not added into button %u for player %s (GUID: %u): spell not exist", action, button, GetName().c_str(), GetGUID().GetCounter()); return false; } if (!HasSpell(action)) { - TC_LOG_DEBUG("entities.player", "Spell action %u not added into button %u for player %s (GUID: %u): player don't known this spell", action, button, GetName().c_str(), GetGUIDLow()); + TC_LOG_DEBUG("entities.player", "Spell action %u not added into button %u for player %s (GUID: %u): player don't known this spell", action, button, GetName().c_str(), GetGUID().GetCounter()); return false; } break; case ACTION_BUTTON_ITEM: if (!sObjectMgr->GetItemTemplate(action)) { - TC_LOG_DEBUG("entities.player", "Item action %u not added into button %u for player %s (GUID: %u): item not exist", action, button, GetName().c_str(), GetGUIDLow()); + TC_LOG_DEBUG("entities.player", "Item action %u not added into button %u for player %s (GUID: %u): item not exist", action, button, GetName().c_str(), GetGUID().GetCounter()); return false; } break; @@ -6584,7 +6597,7 @@ ActionButton* Player::addActionButton(uint8 button, uint32 action, uint8 type) // set data and update to CHANGED if not NEW ab.SetActionAndType(action, ActionButtonType(type)); - TC_LOG_DEBUG("entities.player", "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUIDLow(), action, type, button); + TC_LOG_DEBUG("entities.player", "Player '%u' Added Action '%u' (type %u) to Button '%u'", GetGUID().GetCounter(), action, type, button); return &ab; } @@ -6599,7 +6612,7 @@ void Player::removeActionButton(uint8 button) else buttonItr->second.uState = ACTIONBUTTON_DELETED; // saved, will deleted at next save - TC_LOG_DEBUG("entities.player", "Action Button '%u' Removed from Player '%u'", button, GetGUIDLow()); + TC_LOG_DEBUG("entities.player", "Action Button '%u' Removed from Player '%u'", button, GetGUID().GetCounter()); } ActionButton const* Player::GetActionButton(uint8 button) @@ -6733,7 +6746,7 @@ void Player::CheckAreaExploreAndOutdoor() AreaTableEntry const* areaEntry = GetAreaEntryByAreaFlagAndMap(areaFlag, GetMapId()); if (!areaEntry) { - TC_LOG_ERROR("entities.player", "Player %u discovered unknown area (x: %f y: %f z: %f map: %u", GetGUIDLow(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId()); + TC_LOG_ERROR("entities.player", "Player %u discovered unknown area (x: %f y: %f z: %f map: %u", GetGUID().GetCounter(), GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId()); return; } @@ -6768,7 +6781,7 @@ void Player::CheckAreaExploreAndOutdoor() GiveXP(XP, NULL); SendExplorationExperience(area, XP); } - TC_LOG_DEBUG("entities.player", "Player %u discovered a new area: %u", GetGUIDLow(), area); + TC_LOG_DEBUG("entities.player", "Player %u discovered a new area: %u", GetGUID().GetCounter(), area); } } } @@ -7198,7 +7211,7 @@ void Player::ModifyHonorPoints(int32 value, SQLTransaction trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_HONOR_POINTS); stmt->setUInt32(0, newValue); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); trans->Append(stmt); } } @@ -7214,7 +7227,7 @@ void Player::ModifyArenaPoints(int32 value, SQLTransaction trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ARENA_POINTS); stmt->setUInt32(0, newValue); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); trans->Append(stmt); } } @@ -7597,6 +7610,20 @@ void Player::DuelComplete(DuelCompleteType type) duel->opponent->SetGuidValue(PLAYER_DUEL_ARBITER, ObjectGuid::Empty); duel->opponent->SetUInt32Value(PLAYER_DUEL_TEAM, 0); + if (sWorld->getBoolConfig(CONFIG_RESET_COOLDOWN_AFTER_DUEL) && + type != DUEL_INTERRUPTED) + { + if (!HasCoolDownBeforeDuel()) + RemoveArenaSpellCooldowns(true); + else + ChatHandler(GetSession()).PSendSysMessage(LANG_COOLDOWN_NOT_RESET_AFTER_DUEL); + + if (!duel->opponent->HasCoolDownBeforeDuel()) + duel->opponent->RemoveArenaSpellCooldowns(true); + else + ChatHandler(duel->opponent->GetSession()).PSendSysMessage(LANG_COOLDOWN_NOT_RESET_AFTER_DUEL); + } + delete duel->opponent->duel; duel->opponent->duel = NULL; delete duel; @@ -7619,7 +7646,7 @@ void Player::_ApplyItemMods(Item* item, uint8 slot, bool apply) if (item->IsBroken()) return; - TC_LOG_DEBUG("entities.player.items", "applying mods for item %u ", item->GetGUIDLow()); + TC_LOG_DEBUG("entities.player.items", "applying mods for item %u ", item->GetGUID().GetCounter()); uint8 attacktype = Player::GetAttackBySlot(slot); @@ -8278,7 +8305,7 @@ void Player::CastItemCombatSpell(Unit* target, WeaponAttackType attType, uint32 if (!spellInfo) { TC_LOG_ERROR("entities.player.items", "Player::CastItemCombatSpell(GUID: %u, name: %s, enchant: %i): unknown spell %i is cast, ignoring...", - GetGUIDLow(), GetName().c_str(), pEnchant->ID, pEnchant->spellid[s]); + GetGUID().GetCounter(), GetName().c_str(), pEnchant->ID, pEnchant->spellid[s]); continue; } @@ -8579,9 +8606,11 @@ void Player::RemovedInsignia(Player* looterPlr) RepopAtGraveyard(); } + _corpseLocation.WorldRelocate(); + // 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 = sObjectAccessor->ConvertCorpseForPlayer(GetGUID(), true); + Corpse* bones = GetMap()->ConvertCorpseToBones(GetGUID(), true); if (!bones) return; @@ -9632,7 +9661,7 @@ uint32 Player::GetXPRestBonus(uint32 xp) SetRestBonus(GetRestBonus() - rested_bonus); - TC_LOG_DEBUG("entities.player", "GetXPRestBonus: Player %s (%u) gain %u xp (+%u Rested Bonus). Rested points=%f", GetName().c_str(), GetGUIDLow(), xp+rested_bonus, rested_bonus, GetRestBonus()); + TC_LOG_DEBUG("entities.player", "GetXPRestBonus: Player %s (%u) gain %u xp (+%u Rested Bonus). Rested points=%f", GetName().c_str(), GetGUID().GetCounter(), xp+rested_bonus, rested_bonus, GetRestBonus()); return rested_bonus; } @@ -9664,7 +9693,7 @@ void Player::ResetPetTalents() CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { - TC_LOG_ERROR("entities.player", "Object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); + TC_LOG_ERROR("entities.player", "Object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().GetCounter(), pet->GetTypeId()); return; } pet->resetTalents(); @@ -11623,7 +11652,7 @@ InventoryResult Player::CanBankItem(uint8 bag, uint8 slot, ItemPosCountVec &dest if (pItemslot >= CURRENCYTOKEN_SLOT_START && pItemslot < CURRENCYTOKEN_SLOT_END) { TC_LOG_ERROR("entities.player", "Possible hacking attempt: Player %s [guid: %u] tried to move token [guid: %u, entry: %u] out of the currency bag!", - GetName().c_str(), GetGUIDLow(), pItem->GetGUIDLow(), pProto->ItemId); + GetName().c_str(), GetGUID().GetCounter(), pItem->GetGUID().GetCounter(), pProto->ItemId); return EQUIP_ERR_ITEMS_CANT_BE_SWAPPED; } @@ -12060,7 +12089,7 @@ Item* Player::StoreNewItem(ItemPosCountVec const& dest, uint32 item, bool update ss << ' ' << *itr; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_ITEM_BOP_TRADE); - stmt->setUInt32(0, pItem->GetGUIDLow()); + stmt->setUInt32(0, pItem->GetGUID().GetCounter()); stmt->setString(1, ss.str()); CharacterDatabase.Execute(stmt); } @@ -12101,7 +12130,7 @@ Item* Player::_StoreItem(uint16 pos, Item* pItem, uint32 count, bool clone, bool uint8 bag = pos >> 8; uint8 slot = pos & 255; - TC_LOG_DEBUG("entities.player.items", "STORAGE: StoreItem bag = %u, slot = %u, item = %u, count = %u, guid = %u", bag, slot, pItem->GetEntry(), count, pItem->GetGUIDLow()); + TC_LOG_DEBUG("entities.player.items", "STORAGE: StoreItem bag = %u, slot = %u, item = %u, count = %u, guid = %u", bag, slot, pItem->GetEntry(), count, pItem->GetGUID().GetCounter()); Item* pItem2 = GetItemByPos(bag, slot); @@ -12527,7 +12556,7 @@ void Player::DestroyItem(uint8 bag, uint8 slot, bool update) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); - stmt->setUInt32(0, pItem->GetGUIDLow()); + stmt->setUInt32(0, pItem->GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } @@ -12893,7 +12922,7 @@ void Player::DestroyItemCount(Item* pItem, uint32 &count, bool update) if (!pItem) return; - TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyItemCount item (GUID: %u, Entry: %u) count = %u", pItem->GetGUIDLow(), pItem->GetEntry(), count); + TC_LOG_DEBUG("entities.player.items", "STORAGE: DestroyItemCount item (GUID: %u, Entry: %u) count = %u", pItem->GetGUID().GetCounter(), pItem->GetEntry(), count); if (pItem->GetCount() <= count) { @@ -14248,7 +14277,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool VendorItemData const* vendorItems = creature->GetVendorItems(); if (!vendorItems || vendorItems->Empty()) { - TC_LOG_ERROR("sql.sql", "Creature %s (Entry: %u GUID: %u DB GUID: %u) has UNIT_NPC_FLAG_VENDOR set but has an empty trading item list.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUIDLow(), creature->GetDBTableGUIDLow()); + TC_LOG_ERROR("sql.sql", "Creature %s (Entry: %u GUID: %u DB GUID: %u) has UNIT_NPC_FLAG_VENDOR set but has an empty trading item list.", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId()); canTalk = false; } break; @@ -14283,7 +14312,7 @@ void Player::PrepareGossipMenu(WorldObject* source, uint32 menuId /*= 0*/, bool case GOSSIP_OPTION_TRAINER: if (getClass() != creature->GetCreatureTemplate()->trainer_class && creature->GetCreatureTemplate()->trainer_type == TRAINER_TYPE_CLASS) TC_LOG_ERROR("sql.sql", "GOSSIP_OPTION_TRAINER:: Player %s (GUID: %u) request wrong gossip menu: %u with wrong class: %u at Creature: %s (Entry: %u, Trainer Class: %u)", - GetName().c_str(), GetGUIDLow(), menu->GetGossipMenu().GetMenuId(), getClass(), creature->GetName().c_str(), creature->GetEntry(), creature->GetCreatureTemplate()->trainer_class); + GetName().c_str(), GetGUID().GetCounter(), menu->GetGossipMenu().GetMenuId(), getClass(), creature->GetName().c_str(), creature->GetEntry(), creature->GetCreatureTemplate()->trainer_class); // no break; case GOSSIP_OPTION_GOSSIP: case GOSSIP_OPTION_SPIRITGUIDE: @@ -14411,7 +14440,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men { if (gossipOptionId > GOSSIP_OPTION_QUESTGIVER) { - TC_LOG_ERROR("entities.player", "Player guid %u request invalid gossip option for GameObject entry %u", GetGUIDLow(), source->GetEntry()); + TC_LOG_ERROR("entities.player", "Player guid %u request invalid gossip option for GameObject entry %u", GetGUID().GetCounter(), source->GetEntry()); return; } } @@ -14444,7 +14473,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men break; } case GOSSIP_OPTION_OUTDOORPVP: - sOutdoorPvPMgr->HandleGossipOption(this, source->GetGUID(), gossipListId); + sOutdoorPvPMgr->HandleGossipOption(this, source->ToCreature(), gossipListId); break; case GOSSIP_OPTION_SPIRITHEALER: if (isDead()) @@ -14515,7 +14544,7 @@ void Player::OnGossipSelect(WorldObject* source, uint32 gossipListId, uint32 men if (bgTypeId == BATTLEGROUND_TYPE_NONE) { - TC_LOG_ERROR("entities.player", "a user (guid %u) requested battlegroundlist from a npc who is no battlemaster", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "a user (guid %u) requested battlegroundlist from a npc who is no battlemaster", GetGUID().GetCounter()); return; } @@ -15060,15 +15089,15 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) uint32 qtime = 0; if (quest->HasSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED)) { - uint32 limittime = quest->GetLimitTime(); + uint32 timeAllowed = quest->GetTimeAllowed(); // shared timed quest if (questGiver && questGiver->GetTypeId() == TYPEID_PLAYER) - limittime = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].Timer / IN_MILLISECONDS; + timeAllowed = questGiver->ToPlayer()->getQuestStatusMap()[quest_id].Timer / IN_MILLISECONDS; AddTimedQuest(quest_id); - questStatusData.Timer = limittime * IN_MILLISECONDS; - qtime = static_cast<uint32>(time(NULL)) + limittime; + questStatusData.Timer = timeAllowed * IN_MILLISECONDS; + qtime = static_cast<uint32>(time(NULL)) + timeAllowed; } else questStatusData.Timer = 0; @@ -15092,7 +15121,7 @@ void Player::AddQuest(Quest const* quest, Object* questGiver) // prepare Quest Tracker datas PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_QUEST_TRACK); stmt->setUInt32(0, quest_id); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); stmt->setString(2, GitRevision::GetHash()); stmt->setString(3, GitRevision::GetDate()); @@ -15125,7 +15154,7 @@ void Player::CompleteQuest(uint32 quest_id) // prepare Quest Tracker datas PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_COMPLETE_TIME); stmt->setUInt32(0, quest_id); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); // add to Quest Tracker CharacterDatabase.Execute(stmt); @@ -15158,10 +15187,10 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) { - if (quest->RequiredSourceItemId[i]) + if (quest->ItemDrop[i]) { - uint32 count = quest->RequiredSourceItemCount[i]; - DestroyItemCount(quest->RequiredSourceItemId[i], count ? count : 9999, true); + uint32 count = quest->ItemDropQuantity[i]; + DestroyItemCount(quest->ItemDrop[i], count ? count : 9999, true); } } @@ -15368,9 +15397,9 @@ void Player::FailQuest(uint32 questId) // Destroy items received on starting the quest. DestroyItemCount(quest->RequiredItemId[i], quest->RequiredItemCount[i], true, true); for (uint8 i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - if (quest->RequiredSourceItemId[i] > 0 && quest->RequiredSourceItemCount[i] > 0) + if (quest->ItemDrop[i] > 0 && quest->ItemDropQuantity[i] > 0) // Destroy items received during the quest. - DestroyItemCount(quest->RequiredSourceItemId[i], quest->RequiredSourceItemCount[i], true, true); + DestroyItemCount(quest->ItemDrop[i], quest->ItemDropQuantity[i], true, true); } } @@ -15552,7 +15581,7 @@ bool Player::SatisfyQuestClass(Quest const* qInfo, bool msg) const bool Player::SatisfyQuestRace(Quest const* qInfo, bool msg) { - uint32 reqraces = qInfo->GetRequiredRaces(); + uint32 reqraces = qInfo->GetAllowableRaces(); if (reqraces == 0) return true; if ((reqraces & getRaceMask()) == 0) @@ -16673,7 +16702,7 @@ bool Player::HasQuestForItem(uint32 itemid) const for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j) { // examined item is a source item - if (qinfo->RequiredSourceItemId[j] == itemid) + if (qinfo->ItemDrop[j] == itemid) { ItemTemplate const* pProto = sObjectMgr->GetItemTemplate(itemid); @@ -16682,9 +16711,9 @@ bool Player::HasQuestForItem(uint32 itemid) const return true; // allows custom amount drop when not 0 - if (qinfo->RequiredSourceItemCount[j]) + if (qinfo->ItemDropQuantity[j]) { - if (GetItemCount(itemid, true) < qinfo->RequiredSourceItemCount[j]) + if (GetItemCount(itemid, true) < qinfo->ItemDropQuantity[j]) return true; } else if (GetItemCount(itemid, true) < pProto->GetMaxStackSize()) return true; @@ -16868,7 +16897,7 @@ bool Player::HasPvPForcingQuest() const void Player::Initialize(uint32 guid) { - Object::_Create(guid, 0, HIGHGUID_PLAYER); + Object::_Create(guid, 0, HighGuid::Player); } void Player::_LoadDeclinedNames(PreparedQueryResult result) @@ -17012,7 +17041,7 @@ void Player::SetHomebind(WorldLocation const& loc, uint32 areaId) stmt->setFloat (2, m_homebindX); stmt->setFloat (3, m_homebindY); stmt->setFloat (4, m_homebindZ); - stmt->setUInt32(5, GetGUIDLow()); + stmt->setUInt32(5, GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } @@ -17077,7 +17106,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) return false; } - Object::_Create(guid.GetCounter(), 0, HIGHGUID_PLAYER); + Object::_Create(guid.GetCounter(), 0, HighGuid::Player); m_name = fields[2].GetString(); @@ -17299,11 +17328,11 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // currently we do not support transport in bg else if (transLowGUID) { - ObjectGuid transGUID(HIGHGUID_MO_TRANSPORT, transLowGUID); + ObjectGuid transGUID(HighGuid::Mo_Transport, transLowGUID); Transport* transport = NULL; - if (GameObject* go = HashMapHolder<GameObject>::Find(transGUID)) - transport = go->ToTransport(); + if (Transport* go = HashMapHolder<Transport>::Find(transGUID)) + transport = go; if (transport) { @@ -17360,12 +17389,12 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) if (!nodeEntry) // don't know taxi start node, to homebind { - TC_LOG_ERROR("entities.player", "Character %u have wrong data in taxi destination list, teleport to homebind.", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Character %u have wrong data in taxi destination list, teleport to homebind.", GetGUID().GetCounter()); RelocateToHomebind(); } else // have start node, to it { - TC_LOG_ERROR("entities.player", "Character %u have too short taxi destination list, teleport to original node.", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Character %u have too short taxi destination list, teleport to original node.", GetGUID().GetCounter()); mapId = nodeEntry->map_id; Relocate(nodeEntry->x, nodeEntry->y, nodeEntry->z, 0.0f); } @@ -17507,7 +17536,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) if (HasAtLoginFlag(AT_LOGIN_RENAME)) { - TC_LOG_ERROR("entities.player", "Player (GUID: %u) tried to login while forced to rename, can't load.'", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Player (GUID: %u) tried to login while forced to rename, can't load.'", GetGUID().GetCounter()); return false; } @@ -17584,7 +17613,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) if (m_specsCount > MAX_TALENT_SPECS || m_activeSpec > MAX_TALENT_SPEC || m_specsCount < MIN_TALENT_SPECS) { m_activeSpec = 0; - TC_LOG_ERROR("entities.player", "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName().c_str(), GetGUIDLow(), m_specsCount, m_activeSpec); + TC_LOG_ERROR("entities.player", "Player %s(GUID: %u) has SpecCount = %u and ActiveSpec = %u.", GetName().c_str(), GetGUID().GetCounter(), m_specsCount, m_activeSpec); } _LoadTalents(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_TALENTS)); @@ -17624,7 +17653,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // unread mails and next delivery time, actual mails not loaded _LoadMailInit(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_COUNT), holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_MAIL_DATE)); - m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUIDLow()); + m_social = sSocialMgr->LoadFromDB(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SOCIAL_LIST), GetGUID().GetCounter()); // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded @@ -17805,12 +17834,12 @@ void Player::_LoadActions(PreparedQueryResult result) void Player::_LoadAuras(PreparedQueryResult result, uint32 timediff) { - TC_LOG_DEBUG("entities.player.loading", "Loading auras for player %u", GetGUIDLow()); + TC_LOG_DEBUG("entities.player.loading", "Loading auras for player %u", GetGUID().GetCounter()); /* 0 1 2 3 4 5 6 7 8 9 10 QueryResult* result = CharacterDatabase.PQuery("SELECT casterGuid, spell, effectMask, recalculateMask, stackCount, amount0, amount1, amount2, base_amount0, base_amount1, base_amount2, 11 12 13 - maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = '%u'", GetGUIDLow()); + maxDuration, remainTime, remainCharges FROM character_aura WHERE guid = '%u'", GetGUID().GetCounter()); */ if (result) @@ -17909,23 +17938,29 @@ void Player::_LoadGlyphAuras() } } -void Player::LoadCorpse() +void Player::LoadCorpse(PreparedQueryResult result) { - if (IsAlive()) - sObjectAccessor->ConvertCorpseForPlayer(GetGUID()); - else + if (IsAlive() || HasAtLoginFlag(AT_LOGIN_RESURRECT)) + SpawnCorpseBones(false); + + if (!IsAlive()) { - if (Corpse* corpse = GetCorpse()) - ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, corpse && !sMapStore.LookupEntry(corpse->GetMapId())->Instanceable()); + if (result && !HasAtLoginFlag(AT_LOGIN_RESURRECT)) + { + Field* fields = result->Fetch(); + _corpseLocation.WorldRelocate(fields[0].GetUInt16(), fields[1].GetFloat(), fields[2].GetFloat(), fields[3].GetFloat(), fields[4].GetFloat()); + ApplyModFlag(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTE_RELEASE_TIMER, !sMapStore.LookupEntry(_corpseLocation.GetMapId())->Instanceable()); + } else - //Prevent Dead Player login without corpse ResurrectPlayer(0.5f); } + + RemoveAtLoginFlag(AT_LOGIN_RESURRECT); } void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { - //QueryResult* result = CharacterDatabase.PQuery("SELECT data, text, bag, slot, item, item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag, slot", GetGUIDLow()); + //QueryResult* result = CharacterDatabase.PQuery("SELECT data, text, bag, slot, item, item_template FROM character_inventory JOIN item_instance ON character_inventory.item = item_instance.guid WHERE character_inventory.guid = '%u' ORDER BY bag, slot", GetGUID().GetCounter()); //NOTE: the "order by `bag`" is important because it makes sure //the bagMap is filled before items in the bags are loaded //NOTE2: the "order by `slot`" is needed because mainhand weapons are (wrongly?) @@ -17984,12 +18019,12 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) { if (IsBagPos(item->GetPos())) if (Bag* pBag = item->ToBag()) - bagMap[item->GetGUIDLow()] = pBag; + bagMap[item->GetGUID().GetCounter()] = pBag; } else if (IsBagPos(item->GetPos())) if (item->IsBag()) - invalidBagMap[item->GetGUIDLow()] = item; + invalidBagMap[item->GetGUID().GetCounter()] = item; } else { @@ -18012,7 +18047,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) else { TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) which doesnt have a valid bag (Bag GUID: %u, slot: %u). Possible cheat?", - GetGUIDLow(), GetName().c_str(), item->GetGUIDLow(), item->GetEntry(), bagGuid, slot); + GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry(), bagGuid, slot); item->DeleteFromInventoryDB(trans); delete item; continue; @@ -18026,7 +18061,7 @@ void Player::_LoadInventory(PreparedQueryResult result, uint32 timeDiff) else { TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) which can't be loaded into inventory (Bag GUID: %u, slot: %u) by reason %u. Item will be sent by mail.", - GetGUIDLow(), GetName().c_str(), item->GetGUIDLow(), item->GetEntry(), bagGuid, slot, err); + GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry(), bagGuid, slot, err); item->DeleteFromInventoryDB(trans); problematicItems.push_back(item); } @@ -18071,14 +18106,14 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F if (IsAlive() && item->IsLimitedToAnotherMapOrZone(GetMapId(), zoneId)) { TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (GUID: %u, name: '%s', map: %u) has item (GUID: %u, entry: %u) limited to another map (%u). Deleting item.", - GetGUIDLow(), GetName().c_str(), GetMapId(), item->GetGUIDLow(), item->GetEntry(), zoneId); + GetGUID().GetCounter(), GetName().c_str(), GetMapId(), item->GetGUID().GetCounter(), item->GetEntry(), zoneId); remove = true; } // "Conjured items disappear if you are logged out for more than 15 minutes" else if (timeDiff > 15 * MINUTE && proto->Flags & ITEM_PROTO_FLAG_CONJURED) { TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (GUID: %u, name: '%s', diff: %u) has conjured item (GUID: %u, entry: %u) with expired lifetime (15 minutes). Deleting item.", - GetGUIDLow(), GetName().c_str(), timeDiff, item->GetGUIDLow(), item->GetEntry()); + GetGUID().GetCounter(), GetName().c_str(), timeDiff, item->GetGUID().GetCounter(), item->GetEntry()); remove = true; } else if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE)) @@ -18086,10 +18121,10 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F if (item->GetPlayedTime() > (2 * HOUR)) { TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) with expired refund time (%u). Deleting refund data and removing refundable flag.", - GetGUIDLow(), GetName().c_str(), item->GetGUIDLow(), item->GetEntry(), item->GetPlayedTime()); + GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry(), item->GetPlayedTime()); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_REFUND_INSTANCE); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); trans->Append(stmt); item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); @@ -18097,8 +18132,8 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F else { stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEM_REFUNDS); - stmt->setUInt32(0, item->GetGUIDLow()); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); + stmt->setUInt32(1, GetGUID().GetCounter()); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { item->SetRefundRecipient((*result)[0].GetUInt32()); @@ -18109,7 +18144,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F else { TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) with refundable flags, but without data in item_refund_instance. Removing flag.", - GetGUIDLow(), GetName().c_str(), item->GetGUIDLow(), item->GetEntry()); + GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry()); item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); } } @@ -18117,7 +18152,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F else if (item->HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_BOP_TRADEABLE)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_ITEM_BOP_TRADE); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { std::string strGUID = (*result)[0].GetString(); @@ -18137,7 +18172,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F else { TC_LOG_DEBUG("entities.player.loading", "Player::_LoadInventory: player (GUID: %u, name: '%s') has item (GUID: %u, entry: %u) with ITEM_FLAG_BOP_TRADEABLE flag, but without data in item_soulbound_trade_data. Removing flag.", - GetGUIDLow(), GetName().c_str(), item->GetGUIDLow(), item->GetEntry()); + GetGUID().GetCounter(), GetName().c_str(), item->GetGUID().GetCounter(), item->GetEntry()); item->RemoveFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_BOP_TRADEABLE); } } @@ -18159,7 +18194,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F else { TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has broken item (GUID: %u, entry: %u) in inventory. Deleting item.", - GetGUIDLow(), GetName().c_str(), itemGuid, itemEntry); + GetGUID().GetCounter(), GetName().c_str(), itemGuid, itemEntry); remove = true; } // Remove item from inventory if necessary @@ -18174,7 +18209,7 @@ Item* Player::_LoadItem(SQLTransaction& trans, uint32 zoneId, uint32 timeDiff, F else { TC_LOG_ERROR("entities.player", "Player::_LoadInventory: player (GUID: %u, name: '%s') has unknown item (entry: %u) in inventory. Deleting item.", - GetGUIDLow(), GetName().c_str(), itemEntry); + GetGUID().GetCounter(), GetName().c_str(), itemEntry); Item::DeleteFromInventoryDB(trans, itemGuid); Item::DeleteFromDB(trans, itemGuid); } @@ -18204,7 +18239,7 @@ void Player::_LoadMailedItems(Mail* mail) if (!proto) { - TC_LOG_ERROR("entities.player", "Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUIDLow(), itemGuid, itemTemplate, mail->messageID); + TC_LOG_ERROR("entities.player", "Player %u has unknown item_template (ProtoType) in mailed items(GUID: %u template: %u) in mail (%u), deleted.", GetGUID().GetCounter(), itemGuid, itemTemplate, mail->messageID); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_INVALID_MAIL_ITEM); stmt->setUInt32(0, itemGuid); @@ -18218,7 +18253,7 @@ void Player::_LoadMailedItems(Mail* mail) Item* item = NewItemOrBag(proto); - if (!item->LoadFromDB(itemGuid, ObjectGuid(HIGHGUID_PLAYER, fields[13].GetUInt32()), fields, itemTemplate)) + if (!item->LoadFromDB(itemGuid, ObjectGuid(HighGuid::Player, fields[13].GetUInt32()), fields, itemTemplate)) { TC_LOG_ERROR("entities.player", "Player::_LoadMailedItems - Item in mail (%u) doesn't exist !!!! - item guid: %u, deleted from mail", mail->messageID, itemGuid); @@ -18256,7 +18291,7 @@ void Player::_LoadMail() m_mail.clear(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_MAIL); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) @@ -18318,7 +18353,7 @@ void Player::_LoadQuestStatus(PreparedQueryResult result) //// 0 1 2 3 4 5 6 7 8 9 10 //QueryResult* result = CharacterDatabase.PQuery("SELECT quest, status, explored, timer, mobcount1, mobcount2, mobcount3, mobcount4, itemcount1, itemcount2, itemcount3, // 11 12 - // itemcount4, playercount FROM character_queststatus WHERE guid = '%u'", GetGUIDLow()); + // itemcount4, playercount FROM character_queststatus WHERE guid = '%u'", GetGUID().GetCounter()); if (result) { @@ -18341,7 +18376,7 @@ void Player::_LoadQuestStatus(PreparedQueryResult result) { questStatusData.Status = QUEST_STATUS_INCOMPLETE; TC_LOG_ERROR("entities.player", "Player %s (GUID: %u) has invalid quest %d status (%u), replaced by QUEST_STATUS_INCOMPLETE(3).", - GetName().c_str(), GetGUIDLow(), quest_id, qstatus); + GetName().c_str(), GetGUID().GetCounter(), quest_id, qstatus); } questStatusData.Explored = (fields[2].GetUInt8() > 0); @@ -18390,7 +18425,7 @@ void Player::_LoadQuestStatus(PreparedQueryResult result) ++slot; } - TC_LOG_DEBUG("entities.player.loading", "Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.Status, quest_id, GetGUIDLow()); + TC_LOG_DEBUG("entities.player.loading", "Quest status is {%u} for quest {%u} for player (GUID: %u)", questStatusData.Status, quest_id, GetGUID().GetCounter()); } } while (result->NextRow()); @@ -18443,7 +18478,7 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result) m_DFQuests.clear(); - //QueryResult* result = CharacterDatabase.PQuery("SELECT quest, time FROM character_queststatus_daily WHERE guid = '%u'", GetGUIDLow()); + //QueryResult* result = CharacterDatabase.PQuery("SELECT quest, time FROM character_queststatus_daily WHERE guid = '%u'", GetGUID().GetCounter()); if (result) { @@ -18464,7 +18499,7 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result) if (quest_daily_idx >= PLAYER_MAX_DAILY_QUESTS) // max amount with exist data in query { - TC_LOG_ERROR("entities.player", "Player (GUID: %u) have more 25 daily quest records in `charcter_queststatus_daily`", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Player (GUID: %u) have more 25 daily quest records in `charcter_queststatus_daily`", GetGUID().GetCounter()); break; } @@ -18480,7 +18515,7 @@ void Player::_LoadDailyQuestStatus(PreparedQueryResult result) SetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx, quest_id); ++quest_daily_idx; - TC_LOG_DEBUG("entities.player.loading", "Daily quest (%u) cooldown for player (GUID: %u)", quest_id, GetGUIDLow()); + TC_LOG_DEBUG("entities.player.loading", "Daily quest (%u) cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter()); } while (result->NextRow()); } @@ -18503,7 +18538,7 @@ void Player::_LoadWeeklyQuestStatus(PreparedQueryResult result) continue; m_weeklyquests.insert(quest_id); - TC_LOG_DEBUG("entities.player.loading", "Weekly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow()); + TC_LOG_DEBUG("entities.player.loading", "Weekly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter()); } while (result->NextRow()); } @@ -18527,7 +18562,7 @@ void Player::_LoadSeasonalQuestStatus(PreparedQueryResult result) continue; m_seasonalquests[event_id].insert(quest_id); - TC_LOG_DEBUG("entities.player.loading", "Seasonal quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow()); + TC_LOG_DEBUG("entities.player.loading", "Seasonal quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter()); } while (result->NextRow()); } @@ -18550,7 +18585,7 @@ void Player::_LoadMonthlyQuestStatus(PreparedQueryResult result) continue; m_monthlyquests.insert(quest_id); - TC_LOG_DEBUG("entities.player.loading", "Monthly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUIDLow()); + TC_LOG_DEBUG("entities.player.loading", "Monthly quest {%u} cooldown for player (GUID: %u)", quest_id, GetGUID().GetCounter()); } while (result->NextRow()); } @@ -18560,7 +18595,7 @@ void Player::_LoadMonthlyQuestStatus(PreparedQueryResult result) void Player::_LoadSpells(PreparedQueryResult result) { - //QueryResult* result = CharacterDatabase.PQuery("SELECT spell, active, disabled FROM character_spell WHERE guid = '%u'", GetGUIDLow()); + //QueryResult* result = CharacterDatabase.PQuery("SELECT spell, active, disabled FROM character_spell WHERE guid = '%u'", GetGUID().GetCounter()); if (result) { @@ -18572,7 +18607,7 @@ void Player::_LoadSpells(PreparedQueryResult result) void Player::_LoadGroup(PreparedQueryResult result) { - //QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM group_member WHERE memberGuid=%u", GetGUIDLow()); + //QueryResult* result = CharacterDatabase.PQuery("SELECT guid FROM group_member WHERE memberGuid=%u", GetGUID().GetCounter()); if (result) { if (Group* group = sGroupMgr->GetGroupByDbStoreId((*result)[0].GetUInt32())) @@ -18626,12 +18661,12 @@ void Player::_LoadBoundInstances(PreparedQueryResult result) if (!mapEntry || !mapEntry->IsDungeon()) { - TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d (%s)", GetName().c_str(), GetGUIDLow(), mapId, mapname.c_str()); + TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed or not dungeon map %d (%s)", GetName().c_str(), GetGUID().GetCounter(), mapId, mapname.c_str()); deleteInstance = true; } else if (difficulty >= MAX_DIFFICULTY) { - TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUIDLow(), difficulty, mapId, mapname.c_str()); + TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUID().GetCounter(), difficulty, mapId, mapname.c_str()); deleteInstance = true; } else @@ -18639,12 +18674,12 @@ void Player::_LoadBoundInstances(PreparedQueryResult result) MapDifficulty const* mapDiff = GetMapDifficultyData(mapId, Difficulty(difficulty)); if (!mapDiff) { - TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUIDLow(), difficulty, mapId, mapname.c_str()); + TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) has bind to not existed difficulty %d instance for map %u (%s)", GetName().c_str(), GetGUID().GetCounter(), difficulty, mapId, mapname.c_str()); deleteInstance = true; } else if (!perm && group) { - TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d (%s), %d, %d", GetName().c_str(), GetGUIDLow(), group->GetLowGUID(), mapId, mapname.c_str(), instanceId, difficulty); + TC_LOG_ERROR("entities.player", "_LoadBoundInstances: player %s(%d) is in group %d but has a non-permanent character bind to map %d (%s), %d, %d", GetName().c_str(), GetGUID().GetCounter(), group->GetLowGUID(), mapId, mapname.c_str(), instanceId, difficulty); deleteInstance = true; } } @@ -18653,7 +18688,7 @@ void Player::_LoadBoundInstances(PreparedQueryResult result) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, instanceId); CharacterDatabase.Execute(stmt); @@ -18709,7 +18744,7 @@ void Player::UnbindInstance(BoundInstancesMap::iterator &itr, Difficulty difficu { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INSTANCE_BY_INSTANCE_GUID); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, itr->second.save->GetInstanceId()); CharacterDatabase.Execute(stmt); @@ -18739,7 +18774,7 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, b stmt->setUInt32(0, save->GetInstanceId()); stmt->setBool(1, permanent); - stmt->setUInt32(2, GetGUIDLow()); + stmt->setUInt32(2, GetGUID().GetCounter()); stmt->setUInt32(3, bind.save->GetInstanceId()); CharacterDatabase.Execute(stmt); @@ -18749,7 +18784,7 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, b { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_INSTANCE); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, save->GetInstanceId()); stmt->setBool(2, permanent); @@ -18770,7 +18805,7 @@ InstancePlayerBind* Player::BindToInstance(InstanceSave* save, bool permanent, b bind.save = save; bind.perm = permanent; if (!load) - TC_LOG_DEBUG("maps", "Player::BindToInstance: %s(%d) is now bound to map %d, instance %d, difficulty %d", GetName().c_str(), GetGUIDLow(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty()); + TC_LOG_DEBUG("maps", "Player::BindToInstance: %s(%d) is now bound to map %d, instance %d, difficulty %d", GetName().c_str(), GetGUID().GetCounter(), save->GetMapId(), save->GetInstanceId(), save->GetDifficulty()); sScriptMgr->OnPlayerBindToInstance(this, save->GetDifficulty(), save->GetMapId(), permanent); return &bind; } @@ -19037,7 +19072,7 @@ bool Player::_LoadHomeBind(PreparedQueryResult result) else { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_HOMEBIND); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } } @@ -19051,7 +19086,7 @@ bool Player::_LoadHomeBind(PreparedQueryResult result) m_homebindZ = info->positionZ; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PLAYER_HOMEBIND); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt16(1, m_homebindMapId); stmt->setUInt16(2, m_homebindAreaId); stmt->setFloat (3, m_homebindX); @@ -19099,7 +19134,7 @@ void Player::SaveToDB(bool create /*=false*/) //! Insert query /// @todo: Filter out more redundant fields that can take their default value at player create stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER); - stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt32(index++, GetSession()->GetAccountId()); stmt->setString(index++, GetName()); stmt->setUInt8(index++, getRace()); @@ -19124,7 +19159,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setFloat(index++, finiteAlways(GetTransOffsetO())); uint32 transLowGUID = 0; if (GetTransport()) - transLowGUID = GetTransport()->GetGUIDLow(); + transLowGUID = GetTransport()->GetGUID().GetCounter(); stmt->setUInt32(index++, transLowGUID); std::ostringstream ss; @@ -19244,7 +19279,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setFloat(index++, finiteAlways(GetTransOffsetO())); uint32 transLowGUID = 0; if (GetTransport()) - transLowGUID = GetTransport()->GetGUIDLow(); + transLowGUID = GetTransport()->GetGUID().GetCounter(); stmt->setUInt32(index++, transLowGUID); std::ostringstream ss; @@ -19324,7 +19359,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, IsInWorld() && !GetSession()->PlayerLogout() ? 1 : 0); // Index - stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetGUID().GetCounter()); } SQLTransaction trans = CharacterDatabase.BeginTransaction(); @@ -19377,7 +19412,7 @@ void Player::SaveGoldToDB(SQLTransaction& trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_MONEY); stmt->setUInt32(0, GetMoney()); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); trans->Append(stmt); } @@ -19391,7 +19426,7 @@ void Player::_SaveActions(SQLTransaction& trans) { case ACTIONBUTTON_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt8(1, m_activeSpec); stmt->setUInt8(2, itr->first); stmt->setUInt32(3, itr->second.GetAction()); @@ -19405,7 +19440,7 @@ void Player::_SaveActions(SQLTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ACTION); stmt->setUInt32(0, itr->second.GetAction()); stmt->setUInt8(1, uint8(itr->second.GetType())); - stmt->setUInt32(2, GetGUIDLow()); + stmt->setUInt32(2, GetGUID().GetCounter()); stmt->setUInt8(3, itr->first); stmt->setUInt8(4, m_activeSpec); trans->Append(stmt); @@ -19415,7 +19450,7 @@ void Player::_SaveActions(SQLTransaction& trans) break; case ACTIONBUTTON_DELETED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_BY_BUTTON_SPEC); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt8(1, itr->first); stmt->setUInt8(2, m_activeSpec); trans->Append(stmt); @@ -19432,7 +19467,7 @@ void Player::_SaveActions(SQLTransaction& trans) void Player::_SaveAuras(SQLTransaction& trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_AURA); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); for (AuraMap::const_iterator itr = m_ownedAuras.begin(); itr != m_ownedAuras.end(); ++itr) @@ -19465,7 +19500,7 @@ void Player::_SaveAuras(SQLTransaction& trans) uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_AURA); - stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt64(index++, itr->second->GetCasterGUID().GetRawValue()); stmt->setUInt64(index++, itr->second->GetCastItemGUID().GetRawValue()); stmt->setUInt32(index++, itr->second->GetId()); @@ -19497,11 +19532,11 @@ void Player::_SaveInventory(SQLTransaction& trans) continue; stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_ITEM); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); trans->Append(stmt); m_items[i]->FSetState(ITEM_NEW); } @@ -19525,7 +19560,7 @@ void Player::_SaveInventory(SQLTransaction& trans) } else { - TC_LOG_ERROR("entities.player", "Can't find %s but is in refundable storage for player %u ! Removing.", itr->ToString().c_str(), GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Can't find %s but is in refundable storage for player %u ! Removing.", itr->ToString().c_str(), GetGUID().GetCounter()); m_refundableItems.erase(itr); } } @@ -19538,7 +19573,7 @@ void Player::_SaveInventory(SQLTransaction& trans) if (m_itemUpdateQueue.empty()) return; - uint32 lowGuid = GetGUIDLow(); + uint32 lowGuid = GetGUID().GetCounter(); for (size_t i = 0; i < m_itemUpdateQueue.size(); ++i) { Item* item = m_itemUpdateQueue[i]; @@ -19546,7 +19581,7 @@ void Player::_SaveInventory(SQLTransaction& trans) continue; Bag* container = item->GetContainer(); - uint32 bag_guid = container ? container->GetGUIDLow() : 0; + uint32 bag_guid = container ? container->GetGUID().GetCounter() : 0; if (item->GetState() != ITEM_REMOVED) { @@ -19555,8 +19590,8 @@ void Player::_SaveInventory(SQLTransaction& trans) { uint32 bagTestGUID = 0; if (Item* test2 = GetItemByPos(INVENTORY_SLOT_BAG_0, item->GetBagSlot())) - bagTestGUID = test2->GetGUIDLow(); - TC_LOG_ERROR("entities.player", "Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u (state %d) are incorrect, the player doesn't have an item at that position!", lowGuid, GetName().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), (int32)item->GetState()); + bagTestGUID = test2->GetGUID().GetCounter(); + TC_LOG_ERROR("entities.player", "Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u (state %d) are incorrect, the player doesn't have an item at that position!", lowGuid, GetName().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUID().GetCounter(), (int32)item->GetState()); // according to the test that was just performed nothing should be in this slot, delete stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_BAG_SLOT); stmt->setUInt32(0, bagTestGUID); @@ -19572,7 +19607,7 @@ void Player::_SaveInventory(SQLTransaction& trans) } else if (test != item) { - TC_LOG_ERROR("entities.player", "Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u are incorrect, the item with guid %u is there instead!", lowGuid, GetName().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUIDLow(), test->GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Player(GUID: %u Name: %s)::_SaveInventory - the bag(%u) and slot(%u) values for the item with guid %u are incorrect, the item with guid %u is there instead!", lowGuid, GetName().c_str(), item->GetBagSlot(), item->GetSlot(), item->GetGUID().GetCounter(), test->GetGUID().GetCounter()); // save all changes to the item... if (item->GetState() != ITEM_NEW) // only for existing items, no dupes item->SaveToDB(trans); @@ -19589,12 +19624,12 @@ void Player::_SaveInventory(SQLTransaction& trans) stmt->setUInt32(0, lowGuid); stmt->setUInt32(1, bag_guid); stmt->setUInt8 (2, item->GetSlot()); - stmt->setUInt32(3, item->GetGUIDLow()); + stmt->setUInt32(3, item->GetGUID().GetCounter()); trans->Append(stmt); break; case ITEM_REMOVED: stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_INVENTORY_BY_ITEM); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); trans->Append(stmt); case ITEM_UNCHANGED: break; @@ -19701,7 +19736,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_CHAR_QUESTSTATUS); - stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt32(index++, statusItr->first); stmt->setUInt8(index++, uint8(statusItr->second.Status)); stmt->setBool(index++, statusItr->second.Explored); @@ -19720,7 +19755,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) else { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_BY_QUEST); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, saveItr->first); trans->Append(stmt); } @@ -19733,7 +19768,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) if (saveItr->second == QUEST_DEFAULT_SAVE_TYPE) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_QUESTSTATUS_REWARDED); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, saveItr->first); trans->Append(stmt); @@ -19741,7 +19776,7 @@ void Player::_SaveQuestStatus(SQLTransaction& trans) else if (saveItr->second == QUEST_FORCE_DELETE_SAVE_TYPE || !keepAbandoned) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_QUESTSTATUS_REWARDED_BY_QUEST); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, saveItr->first); trans->Append(stmt); } @@ -19764,7 +19799,7 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans) // we don't need transactions here. PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_DAILY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); for (uint32 quest_daily_idx = 0; quest_daily_idx < PLAYER_MAX_DAILY_QUESTS; ++quest_daily_idx) @@ -19772,7 +19807,7 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans) if (GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, GetUInt32Value(PLAYER_FIELD_DAILY_QUESTS_1+quest_daily_idx)); stmt->setUInt64(2, uint64(m_lastDailyQuestTime)); trans->Append(stmt); @@ -19784,7 +19819,7 @@ void Player::_SaveDailyQuestStatus(SQLTransaction& trans) for (DFQuestsDoneList::iterator itr = m_DFQuests.begin(); itr != m_DFQuests.end(); ++itr) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_DAILY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, (*itr)); stmt->setUInt64(2, uint64(m_lastDailyQuestTime)); trans->Append(stmt); @@ -19799,7 +19834,7 @@ void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans) // we don't need transactions here. PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_WEEKLY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); for (QuestSet::const_iterator iter = m_weeklyquests.begin(); iter != m_weeklyquests.end(); ++iter) @@ -19807,7 +19842,7 @@ void Player::_SaveWeeklyQuestStatus(SQLTransaction& trans) uint32 questId = *iter; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_WEEKLY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, questId); trans->Append(stmt); } @@ -19822,7 +19857,7 @@ void Player::_SaveSeasonalQuestStatus(SQLTransaction& trans) // we don't need transactions here. PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_SEASONAL); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); for (SeasonalEventQuestMap::const_iterator iter = m_seasonalquests.begin(); iter != m_seasonalquests.end(); ++iter) @@ -19834,7 +19869,7 @@ void Player::_SaveSeasonalQuestStatus(SQLTransaction& trans) uint32 questId = *itr; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_SEASONAL); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, questId); stmt->setUInt32(2, eventId); trans->Append(stmt); @@ -19851,7 +19886,7 @@ void Player::_SaveMonthlyQuestStatus(SQLTransaction& trans) // we don't need transactions here. PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_QUESTSTATUS_MONTHLY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); for (QuestSet::const_iterator iter = m_monthlyquests.begin(); iter != m_monthlyquests.end(); ++iter) @@ -19859,7 +19894,7 @@ void Player::_SaveMonthlyQuestStatus(SQLTransaction& trans) uint32 questId = *iter; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHARACTER_QUESTSTATUS_MONTHLY); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, questId); trans->Append(stmt); } @@ -19882,7 +19917,7 @@ void Player::_SaveSkills(SQLTransaction& trans) if (itr->second.uState == SKILL_DELETED) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SKILL_BY_SKILL); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, itr->first); trans->Append(stmt); @@ -19898,7 +19933,7 @@ void Player::_SaveSkills(SQLTransaction& trans) { case SKILL_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SKILLS); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt16(1, uint16(itr->first)); stmt->setUInt16(2, value); stmt->setUInt16(3, max); @@ -19909,7 +19944,7 @@ void Player::_SaveSkills(SQLTransaction& trans) stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_SKILLS); stmt->setUInt16(0, value); stmt->setUInt16(1, max); - stmt->setUInt32(2, GetGUIDLow()); + stmt->setUInt32(2, GetGUID().GetCounter()); stmt->setUInt16(3, uint16(itr->first)); trans->Append(stmt); @@ -19933,7 +19968,7 @@ void Player::_SaveSpells(SQLTransaction& trans) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_SPELL_BY_SPELL); stmt->setUInt32(0, itr->first); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); trans->Append(stmt); } @@ -19941,7 +19976,7 @@ void Player::_SaveSpells(SQLTransaction& trans) if (!itr->second->dependent && (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_SPELL); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, itr->first); stmt->setBool(2, itr->second->active); stmt->setBool(3, itr->second->disabled); @@ -19972,13 +20007,13 @@ void Player::_SaveStats(SQLTransaction& trans) PreparedStatement* stmt = NULL; stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_STATS); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_STATS); - stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt32(index++, GetMaxHealth()); for (uint8 i = 0; i < MAX_POWERS; ++i) @@ -20440,7 +20475,7 @@ void Player::StopCastingCharm() if (charm->GetCharmerGUID()) { TC_LOG_FATAL("entities.player", "Charmed unit has charmer %s", charm->GetCharmerGUID().ToString().c_str()); - ASSERT(false); + ABORT(); } else SetCharm(charm, false); @@ -20523,7 +20558,7 @@ void Player::AddMItem(Item* it) { ASSERT(it); //ASSERT deleted, because items can be added before loading - mMitems[it->GetGUIDLow()] = it; + mMitems[it->GetGUID().GetCounter()] = it; } bool Player::RemoveMItem(uint32 id) @@ -20942,8 +20977,8 @@ void Player::RemovePetitionsAndSigns(ObjectGuid guid, uint32 type) do // this part effectively does nothing, since the deletion / modification only takes place _after_ the PetitionQuery. Though I don't know if the result remains intact if I execute the delete query beforehand. { // and SendPetitionQueryOpcode reads data from the DB Field* fields = result->Fetch(); - ObjectGuid ownerguid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); - ObjectGuid petitionguid = ObjectGuid(HIGHGUID_ITEM, fields[1].GetUInt32()); + ObjectGuid ownerguid = ObjectGuid(HighGuid::Player, fields[0].GetUInt32()); + ObjectGuid petitionguid = ObjectGuid(HighGuid::Item, fields[1].GetUInt32()); // send update if charter owner in game Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid); @@ -21158,6 +21193,7 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc // fill destinations path tail uint32 sourcepath = 0; uint32 totalcost = 0; + uint32 firstcost = 0; uint32 prevnode = sourcenode; uint32 lastnode = 0; @@ -21176,6 +21212,8 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc } totalcost += cost; + if (i == 1) + firstcost = cost; if (prevnode == sourcenode) sourcepath = path; @@ -21214,8 +21252,6 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc } //Checks and preparations done, DO FLIGHT - ModifyMoney(-(int32)totalcost); - UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost); UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_FLIGHT_PATHS_TAKEN, 1); // prevent stealth flight @@ -21226,11 +21262,15 @@ bool Player::ActivateTaxiPathTo(std::vector<uint32> const& nodes, Creature* npc TaxiNodesEntry const* lastPathNode = sTaxiNodesStore.LookupEntry(nodes[nodes.size()-1]); ASSERT(lastPathNode); m_taxi.ClearTaxiDestinations(); + ModifyMoney(-(int32)totalcost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, totalcost); TeleportTo(lastPathNode->map_id, lastPathNode->x, lastPathNode->y, lastPathNode->z, GetOrientation()); return false; } else { + ModifyMoney(-(int32)firstcost); + UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, firstcost); GetSession()->SendActivateTaxiReply(ERR_TAXIOK); GetSession()->SendDoFlight(mount_display_id, sourcepath); } @@ -21266,7 +21306,7 @@ void Player::ContinueTaxiFlight() if (!sourceNode) return; - TC_LOG_DEBUG("entities.unit", "WORLD: Restart character %u taxi flight", GetGUIDLow()); + TC_LOG_DEBUG("entities.unit", "WORLD: Restart character %u taxi flight", GetGUID().GetCounter()); uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourceNode, GetTeam(), true); if (!mountDisplayId) @@ -21281,30 +21321,30 @@ void Player::ContinueTaxiFlight() float distPrev = MAP_SIZE*MAP_SIZE; float distNext = - (nodeList[0].LocX-GetPositionX())*(nodeList[0].LocX-GetPositionX())+ - (nodeList[0].LocY-GetPositionY())*(nodeList[0].LocY-GetPositionY())+ - (nodeList[0].LocZ-GetPositionZ())*(nodeList[0].LocZ-GetPositionZ()); + (nodeList[0]->LocX - GetPositionX())*(nodeList[0]->LocX - GetPositionX()) + + (nodeList[0]->LocY - GetPositionY())*(nodeList[0]->LocY - GetPositionY()) + + (nodeList[0]->LocZ - GetPositionZ())*(nodeList[0]->LocZ - GetPositionZ()); for (uint32 i = 1; i < nodeList.size(); ++i) { - TaxiPathNodeEntry const& node = nodeList[i]; - TaxiPathNodeEntry 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()) + if (node->MapID != GetMapId()) continue; distPrev = distNext; distNext = - (node.LocX-GetPositionX())*(node.LocX-GetPositionX())+ - (node.LocY-GetPositionY())*(node.LocY-GetPositionY())+ - (node.LocZ-GetPositionZ())*(node.LocZ-GetPositionZ()); + (node->LocX - GetPositionX())*(node->LocX - GetPositionX()) + + (node->LocY - GetPositionY())*(node->LocY - GetPositionY()) + + (node->LocZ - GetPositionZ())*(node->LocZ - GetPositionZ()); float distNodes = - (node.LocX-prevNode.LocX)*(node.LocX-prevNode.LocX)+ - (node.LocY-prevNode.LocY)*(node.LocY-prevNode.LocY)+ - (node.LocZ-prevNode.LocZ)*(node.LocZ-prevNode.LocZ); + (node->LocX - prevNode->LocX)*(node->LocX - prevNode->LocX) + + (node->LocY - prevNode->LocY)*(node->LocY - prevNode->LocY) + + (node->LocZ - prevNode->LocZ)*(node->LocZ - prevNode->LocZ); if (distNext + distPrev < distNodes) { @@ -21368,7 +21408,7 @@ void Player::InitDisplayIds() PlayerInfo const* info = sObjectMgr->GetPlayerInfo(getRace(), getClass()); if (!info) { - TC_LOG_ERROR("entities.player", "Player %u has incorrect race/class pair. Can't init display ids.", GetGUIDLow()); + TC_LOG_ERROR("entities.player", "Player %u has incorrect race/class pair. Can't init display ids.", GetGUID().GetCounter()); return; } @@ -21442,7 +21482,7 @@ inline bool Player::_StoreOrEquipNewItem(uint32 vendorslot, uint32 item, uint8 c if (pProto->Flags & ITEM_PROTO_FLAG_REFUNDABLE && crItem->ExtendedCost && pProto->GetMaxStackSize() == 1) { it->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_REFUNDABLE); - it->SetRefundRecipient(GetGUIDLow()); + it->SetRefundRecipient(GetGUID().GetCounter()); it->SetPaidMoney(price); it->SetPaidExtendedCost(crItem->ExtendedCost); it->SaveRefundDataToDB(); @@ -21676,7 +21716,7 @@ void Player::UpdateHomebindTime(uint32 time) data << uint32(m_HomebindTimer); data << uint32(1); GetSession()->SendPacket(&data); - TC_LOG_DEBUG("maps", "PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName().c_str(), GetGUIDLow()); + TC_LOG_DEBUG("maps", "PLAYER: Player '%s' (GUID: %u) will be teleported to homebind in 60 seconds", GetName().c_str(), GetGUID().GetCounter()); } } @@ -22044,9 +22084,9 @@ void Player::ReportedAfkBy(Player* reporter) return; // check if player has 'Idle' or 'Inactive' debuff - if (m_bgData.bgAfkReporter.find(reporter->GetGUIDLow()) == m_bgData.bgAfkReporter.end() && !HasAura(43680) && !HasAura(43681) && reporter->CanReportAfkDueToLimit()) + if (m_bgData.bgAfkReporter.find(reporter->GetGUID().GetCounter()) == m_bgData.bgAfkReporter.end() && !HasAura(43680) && !HasAura(43681) && reporter->CanReportAfkDueToLimit()) { - m_bgData.bgAfkReporter.insert(reporter->GetGUIDLow()); + m_bgData.bgAfkReporter.insert(reporter->GetGUID().GetCounter()); // 3 players have to complain to apply debuff if (m_bgData.bgAfkReporter.size() >= 3) { @@ -22179,7 +22219,7 @@ void Player::UpdateVisibilityOf(WorldObject* target) m_clientGUIDs.erase(target->GetGUID()); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Object %u (Type: %u) out of range for player %u. Distance = %f", target->GetGUIDLow(), target->GetTypeId(), GetGUIDLow(), GetDistance(target)); + TC_LOG_DEBUG("maps", "Object %u (Type: %u) out of range for player %u. Distance = %f", target->GetGUID().GetCounter(), target->GetTypeId(), GetGUID().GetCounter(), GetDistance(target)); #endif } } @@ -22191,7 +22231,7 @@ void Player::UpdateVisibilityOf(WorldObject* target) m_clientGUIDs.insert(target->GetGUID()); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Object %u (Type: %u) is visible now for player %u. Distance = %f", target->GetGUIDLow(), target->GetTypeId(), GetGUIDLow(), GetDistance(target)); + TC_LOG_DEBUG("maps", "Object %u (Type: %u) is visible now for player %u. Distance = %f", target->GetGUID().GetCounter(), target->GetTypeId(), GetGUID().GetCounter(), GetDistance(target)); #endif // target aura duration for caster show only if target exist at caster client @@ -22267,7 +22307,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi m_clientGUIDs.erase(target->GetGUID()); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Object %u (Type: %u, Entry: %u) is out of range for player %u. Distance = %f", target->GetGUIDLow(), target->GetTypeId(), target->GetEntry(), GetGUIDLow(), GetDistance(target)); + TC_LOG_DEBUG("maps", "Object %u (Type: %u, Entry: %u) is out of range for player %u. Distance = %f", target->GetGUID().GetCounter(), target->GetTypeId(), target->GetEntry(), GetGUID().GetCounter(), GetDistance(target)); #endif } } @@ -22279,7 +22319,7 @@ void Player::UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& vi UpdateVisibilityOf_helper(m_clientGUIDs, target, visibleNow); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Object %u (Type: %u, Entry: %u) is visible now for player %u. Distance = %f", target->GetGUIDLow(), target->GetTypeId(), target->GetEntry(), GetGUIDLow(), GetDistance(target)); + TC_LOG_DEBUG("maps", "Object %u (Type: %u, Entry: %u) is visible now for player %u. Distance = %f", target->GetGUID().GetCounter(), target->GetTypeId(), target->GetEntry(), GetGUID().GetCounter(), GetDistance(target)); #endif } } @@ -23276,7 +23316,7 @@ void Player::UpdateForQuestWorldObjects() { if (itr->IsGameObject()) { - if (GameObject* obj = HashMapHolder<GameObject>::Find(*itr)) + if (GameObject* obj = ObjectAccessor::GetGameObject(*this, *itr)) obj->BuildValuesUpdateBlockForPlayer(&udata, this); } else if (itr->IsCreatureOrVehicle()) @@ -24650,7 +24690,7 @@ void Player::_LoadSkills(PreparedQueryResult result) if (!rcEntry) { TC_LOG_ERROR("entities.player", "Character: %s (GUID: %u Race: %u Class: %u) has skill %u not allowed for his race/class combination", - GetName().c_str(), GetGUIDLow(), uint32(getRace()), uint32(getClass()), skill); + GetName().c_str(), GetGUID().GetCounter(), uint32(getRace()), uint32(getClass()), skill); mSkillStatus.insert(SkillStatusMap::value_type(skill, SkillStatusData(0, SKILL_DELETED))); continue; @@ -24673,11 +24713,11 @@ void Player::_LoadSkills(PreparedQueryResult result) if (value == 0) { - TC_LOG_ERROR("entities.player", "Character %u has skill %u with value 0. Will be deleted.", GetGUIDLow(), skill); + TC_LOG_ERROR("entities.player", "Character %u has skill %u with value 0. Will be deleted.", GetGUID().GetCounter(), skill); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHARACTER_SKILL); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt16(1, skill); CharacterDatabase.Execute(stmt); @@ -24710,7 +24750,7 @@ void Player::_LoadSkills(PreparedQueryResult result) if (count >= PLAYER_MAX_SKILLS) // client limit { - TC_LOG_ERROR("entities.player", "Character %u has more than %u skills.", GetGUIDLow(), PLAYER_MAX_SKILLS); + TC_LOG_ERROR("entities.player", "Character %u has more than %u skills.", GetGUID().GetCounter(), PLAYER_MAX_SKILLS); break; } } @@ -25446,11 +25486,11 @@ void Player::SendEquipmentSetList() data << itr->second.IconName; for (uint32 i = 0; i < EQUIPMENT_SLOT_END; ++i) { - // ignored slots stored in IgnoreMask, client wants "1" as raw GUID, so no HIGHGUID_ITEM + // ignored slots stored in IgnoreMask, client wants "1" as raw GUID, so no HighGuid::Item if (itr->second.IgnoreMask & (1 << i)) data.appendPackGUID(uint64(1)); else - data << ObjectGuid(HIGHGUID_ITEM, 0, itr->second.Items[i]).WriteAsPacked(); + data << ObjectGuid(HighGuid::Item, 0, itr->second.Items[i]).WriteAsPacked(); } ++count; // client have limit but it checked at loading and set @@ -25520,7 +25560,7 @@ void Player::_SaveEquipmentSets(SQLTransaction& trans) stmt->setUInt32(j++, eqset.IgnoreMask); for (uint8 i=0; i<EQUIPMENT_SLOT_END; ++i) stmt->setUInt32(j++, eqset.Items[i]); - stmt->setUInt32(j++, GetGUIDLow()); + stmt->setUInt32(j++, GetGUID().GetCounter()); stmt->setUInt64(j++, eqset.Guid); stmt->setUInt32(j, index); trans->Append(stmt); @@ -25529,7 +25569,7 @@ void Player::_SaveEquipmentSets(SQLTransaction& trans) break; case EQUIPMENT_SET_NEW: stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_EQUIP_SET); - stmt->setUInt32(j++, GetGUIDLow()); + stmt->setUInt32(j++, GetGUID().GetCounter()); stmt->setUInt64(j++, eqset.Guid); stmt->setUInt32(j++, index); stmt->setString(j++, eqset.Name.c_str()); @@ -25554,11 +25594,11 @@ void Player::_SaveEquipmentSets(SQLTransaction& trans) void Player::_SaveBGData(SQLTransaction& trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_PLAYER_BGDATA); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); /* guid, bgInstanceID, bgTeam, x, y, z, o, map, taxi[0], taxi[1], mountSpell */ stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PLAYER_BGDATA); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, m_bgData.bgInstanceID); stmt->setUInt16(2, m_bgData.bgTeam); stmt->setFloat (3, m_bgData.joinPos.GetPositionX()); @@ -25596,7 +25636,7 @@ void Player::RemoveAtLoginFlag(AtLoginFlags flags, bool persist /*= false*/) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_REM_AT_LOGIN_FLAG); stmt->setUInt16(0, uint16(flags)); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } @@ -25647,7 +25687,7 @@ void Player::_LoadGlyphs(PreparedQueryResult result) void Player::_SaveGlyphs(SQLTransaction& trans) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_GLYPHS); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); trans->Append(stmt); @@ -25656,7 +25696,7 @@ void Player::_SaveGlyphs(SQLTransaction& trans) uint8 index = 0; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GLYPHS); - stmt->setUInt32(index++, GetGUIDLow()); + stmt->setUInt32(index++, GetGUID().GetCounter()); stmt->setUInt8(index++, spec); @@ -25689,7 +25729,7 @@ void Player::_SaveTalents(SQLTransaction& trans) if (itr->second->state == PLAYERSPELL_REMOVED || itr->second->state == PLAYERSPELL_CHANGED) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_TALENT_BY_SPELL_SPEC); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, itr->first); stmt->setUInt8(2, itr->second->spec); trans->Append(stmt); @@ -25698,7 +25738,7 @@ void Player::_SaveTalents(SQLTransaction& trans) if (itr->second->state == PLAYERSPELL_NEW || itr->second->state == PLAYERSPELL_CHANGED) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_TALENT); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt32(1, itr->first); stmt->setUInt8(2, itr->second->spec); trans->Append(stmt); @@ -25737,7 +25777,7 @@ void Player::UpdateSpecCount(uint8 count) for (ActionButtonList::iterator itr = m_actionButtons.begin(); itr != m_actionButtons.end(); ++itr) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_ACTION); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt8(1, 1); stmt->setUInt8(2, itr->first); stmt->setUInt32(3, itr->second.GetAction()); @@ -25752,7 +25792,7 @@ void Player::UpdateSpecCount(uint8 count) stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_ACTION_EXCEPT_SPEC); stmt->setUInt8(0, m_activeSpec); - stmt->setUInt32(1, GetGUIDLow()); + stmt->setUInt32(1, GetGUID().GetCounter()); trans->Append(stmt); m_activeSpec = 0; @@ -25893,7 +25933,7 @@ void Player::ActivateSpec(uint8 spec) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); stmt->setUInt8(1, m_activeSpec); if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) _LoadActions(result); @@ -25971,7 +26011,7 @@ void Player::SendRefundInfo(Item* item) return; } - if (GetGUIDLow() != item->GetRefundRecipient()) // Formerly refundable item got traded + if (GetGUID().GetCounter() != item->GetRefundRecipient()) // Formerly refundable item got traded { TC_LOG_DEBUG("entities.player.items", "Item refund: item was traded!"); item->SetNotRefundable(this); @@ -26041,7 +26081,7 @@ void Player::RefundItem(Item* item) return; } - if (GetGUIDLow() != item->GetRefundRecipient()) // Formerly refundable item got traded + if (GetGUID().GetCounter() != item->GetRefundRecipient()) // Formerly refundable item got traded { TC_LOG_DEBUG("entities.player.items", "Item refund: item was traded!"); item->SetNotRefundable(this); @@ -26150,7 +26190,7 @@ void Player::SendItemRetrievalMail(uint32 itemEntry, uint32 count) draft.AddItem(item); } - draft.SendMailTo(trans, MailReceiver(this, GetGUIDLow()), sender); + draft.SendMailTo(trans, MailReceiver(this, GetGUID().GetCounter()), sender); CharacterDatabase.CommitTransaction(trans); } @@ -26161,7 +26201,7 @@ void Player::SetRandomWinner(bool isWinner) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_BATTLEGROUND_RANDOM); - stmt->setUInt32(0, GetGUIDLow()); + stmt->setUInt32(0, GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } @@ -26169,7 +26209,7 @@ void Player::SetRandomWinner(bool isWinner) void Player::_LoadRandomBGStatus(PreparedQueryResult result) { - //QueryResult result = CharacterDatabase.PQuery("SELECT guid FROM character_battleground_random WHERE guid = '%u'", GetGUIDLow()); + //QueryResult result = CharacterDatabase.PQuery("SELECT guid FROM character_battleground_random WHERE guid = '%u'", GetGUID().GetCounter()); if (result) m_IsBGRandomWinner = true; @@ -26419,14 +26459,14 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy pet->Relocate(x, y, z, ang); if (!pet->IsPositionValid()) { - TC_LOG_ERROR("misc", "Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)", pet->GetGUIDLow(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY()); + TC_LOG_ERROR("misc", "Pet (guidlow %d, entry %d) not summoned. Suggested coordinates isn't valid (X: %f Y: %f)", pet->GetGUID().GetCounter(), pet->GetEntry(), pet->GetPositionX(), pet->GetPositionY()); delete pet; return NULL; } Map* map = GetMap(); uint32 pet_number = sObjectMgr->GeneratePetNumber(); - if (!pet->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_PET), map, GetPhaseMask(), entry, pet_number)) + if (!pet->Create(map->GenerateLowGuid<HighGuid::Pet>(), map, GetPhaseMask(), entry, pet_number)) { TC_LOG_ERROR("misc", "no such creature entry %u", entry); delete pet; diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index a031840a1d8..0c1fdd8f03d 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -27,6 +27,7 @@ #include "PetDefines.h" #include "QuestDef.h" #include "SpellMgr.h" +#include "SpellHistory.h" #include "Unit.h" #include <limits> @@ -284,7 +285,7 @@ struct PvPInfo struct DuelInfo { - DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0), isMounted(false) { } + DuelInfo() : initiator(NULL), opponent(NULL), startTimer(0), startTime(0), outOfBound(0), isMounted(false), hasCoolDownBeforeDuel(false) { } Player* initiator; Player* opponent; @@ -292,6 +293,7 @@ struct DuelInfo time_t startTime; time_t outOfBound; bool isMounted; + bool hasCoolDownBeforeDuel; }; struct Areas @@ -503,15 +505,16 @@ enum PlayerExtraFlags // 2^n values enum AtLoginFlags { - AT_LOGIN_NONE = 0x00, - AT_LOGIN_RENAME = 0x01, - AT_LOGIN_RESET_SPELLS = 0x02, - AT_LOGIN_RESET_TALENTS = 0x04, - AT_LOGIN_CUSTOMIZE = 0x08, - AT_LOGIN_RESET_PET_TALENTS = 0x10, - AT_LOGIN_FIRST = 0x20, - AT_LOGIN_CHANGE_FACTION = 0x40, - AT_LOGIN_CHANGE_RACE = 0x80 + AT_LOGIN_NONE = 0x000, + AT_LOGIN_RENAME = 0x001, + AT_LOGIN_RESET_SPELLS = 0x002, + AT_LOGIN_RESET_TALENTS = 0x004, + AT_LOGIN_CUSTOMIZE = 0x008, + AT_LOGIN_RESET_PET_TALENTS = 0x010, + AT_LOGIN_FIRST = 0x020, + AT_LOGIN_CHANGE_FACTION = 0x040, + AT_LOGIN_CHANGE_RACE = 0x080, + AT_LOGIN_RESURRECT = 0x100, }; typedef std::map<uint32, QuestStatusData> QuestStatusMap; @@ -819,6 +822,7 @@ enum PlayerLoginQueryIndex PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES = 30, PLAYER_LOGIN_QUERY_LOAD_SEASONAL_QUEST_STATUS = 31, PLAYER_LOGIN_QUERY_LOAD_MONTHLY_QUEST_STATUS = 32, + PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION = 33, MAX_PLAYER_LOGIN_QUERY }; @@ -952,6 +956,8 @@ class PlayerTaxi m_TaxiDestinations.pop_front(); return GetTaxiDestination(); } + + std::deque<uint32> const& GetPath() const { return m_TaxiDestinations; } bool empty() const { return m_TaxiDestinations.empty(); } friend std::ostringstream& operator<< (std::ostringstream& ss, PlayerTaxi const& taxi); @@ -1341,7 +1347,7 @@ class Player : public Unit, public GridObject<Player> void AddItemDurations(Item* item); void RemoveItemDurations(Item* item); void SendItemDurations(); - void LoadCorpse(); + void LoadCorpse(PreparedQueryResult result); void LoadPet(); bool AddItem(uint32 itemId, uint32 count); @@ -1833,17 +1839,20 @@ class Player : public Unit, public GridObject<Player> bool UpdatePosition(const Position &pos, bool teleport = false) { return UpdatePosition(pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), teleport); } void UpdateUnderwaterState(Map* m, float x, float y, float z) override; - void SendMessageToSet(WorldPacket* data, bool self) override {SendMessageToSetInRange(data, GetVisibilityRange(), self); }// overwrite Object::SendMessageToSet - void SendMessageToSetInRange(WorldPacket* data, float fist, bool self) override;// overwrite Object::SendMessageToSetInRange + void SendMessageToSet(WorldPacket* data, bool self) override { SendMessageToSetInRange(data, GetVisibilityRange(), self); } + void SendMessageToSetInRange(WorldPacket* data, float dist, bool self) override; void SendMessageToSetInRange(WorldPacket* data, float dist, bool self, bool own_team_only); void SendMessageToSet(WorldPacket* data, Player const* skipped_rcvr) override; void SendTeleportAckPacket(); Corpse* GetCorpse() const; - void SpawnCorpseBones(); - void CreateCorpse(); + void SpawnCorpseBones(bool triggerSave = true); + Corpse* CreateCorpse(); void KillPlayer(); + static void OfflineResurrect(ObjectGuid const& guid, SQLTransaction& trans); + bool HasCorpse() const { return _corpseLocation.GetMapId() != MAPID_INVALID; } + WorldLocation GetCorpseLocation() const { return _corpseLocation; } uint32 GetResurrectionSpellId(); void ResurrectPlayer(float restore_percent, bool applySickness = false); void BuildPlayerRepop(); @@ -1875,7 +1884,7 @@ class Player : public Unit, public GridObject<Player> void UpdateWeaponSkill (WeaponAttackType attType); void UpdateCombatSkills(Unit* victim, WeaponAttackType attType, bool defence); - void SetSkill(uint16 id, uint16 step, uint16 currVal, uint16 maxVal); + void SetSkill(uint16 id, uint16 step, uint16 newVal, uint16 maxVal); uint16 GetMaxSkillValue(uint32 skill) const; // max + perm. bonus + temp bonus uint16 GetPureMaxSkillValue(uint32 skill) const; // max uint16 GetSkillValue(uint32 skill) const; // skill value + perm. bonus + temp bonus @@ -1939,6 +1948,9 @@ class Player : public Unit, public GridObject<Player> void SetHonorPoints(uint32 value); void SetArenaPoints(uint32 value); + bool HasCoolDownBeforeDuel() const { return duel->hasCoolDownBeforeDuel; } + void UpdateHasCoolDownBeforeDuel() { duel->hasCoolDownBeforeDuel = GetSpellHistory()->GetArenaCooldownsSize() > 0; } + //End of PvP System void SetDrunkValue(uint8 newDrunkValue, uint32 itemId = 0); @@ -2622,6 +2634,8 @@ class Player : public Unit, public GridObject<Player> uint32 _pendingBindTimer; uint32 _activeCheats; + + WorldLocation _corpseLocation; }; void AddItemsSetItem(Player* player, Item* item); diff --git a/src/server/game/Entities/Player/SocialMgr.cpp b/src/server/game/Entities/Player/SocialMgr.cpp index 77cd701ee35..e7989c405a8 100644 --- a/src/server/game/Entities/Player/SocialMgr.cpp +++ b/src/server/game/Entities/Player/SocialMgr.cpp @@ -205,7 +205,7 @@ void SocialMgr::GetFriendInfo(Player* player, uint32 friendGUID, FriendInfo &fri friendInfo.Level = 0; friendInfo.Class = 0; - Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, friendGUID)); + Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, friendGUID)); if (!target) return; @@ -290,10 +290,10 @@ void SocialMgr::BroadcastToFriendListers(Player* player, WorldPacket* packet) AccountTypes gmSecLevel = AccountTypes(sWorld->getIntConfig(CONFIG_GM_LEVEL_IN_WHO_LIST)); for (SocialMap::const_iterator itr = m_socialMap.begin(); itr != m_socialMap.end(); ++itr) { - PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUIDLow()); + PlayerSocialMap::const_iterator itr2 = itr->second.m_playerSocialMap.find(player->GetGUID().GetCounter()); if (itr2 != itr->second.m_playerSocialMap.end() && (itr2->second.Flags & SOCIAL_FLAG_FRIEND)) { - Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HIGHGUID_PLAYER, 0, itr->first)); + Player* target = ObjectAccessor::FindPlayer(ObjectGuid(HighGuid::Player, 0, itr->first)); if (!target) continue; diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index d6a130c0317..144805b88b5 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -54,7 +54,7 @@ bool Transport::Create(uint32 guidlow, uint32 entry, uint32 mapid, float x, floa return false; } - Object::_Create(guidlow, 0, HIGHGUID_MO_TRANSPORT); + Object::_Create(guidlow, 0, HighGuid::Mo_Transport); GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry); @@ -312,7 +312,7 @@ Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data) if (!creature->IsPositionValid()) { - TC_LOG_ERROR("entities.transport", "Creature (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)",creature->GetGUIDLow(),creature->GetEntry(),creature->GetPositionX(),creature->GetPositionY()); + TC_LOG_ERROR("entities.transport", "Creature (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)",creature->GetGUID().GetCounter(),creature->GetEntry(),creature->GetPositionX(),creature->GetPositionY()); delete creature; return NULL; } @@ -351,10 +351,11 @@ GameObject* Transport::CreateGOPassenger(uint32 guid, GameObjectData const* data go->m_movementInfo.transport.pos.Relocate(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); go->Relocate(x, y, z, o); + go->RelocateStationaryPosition(x, y, z, o); if (!go->IsPositionValid()) { - TC_LOG_ERROR("entities.transport", "GameObject (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUIDLow(), go->GetEntry(), go->GetPositionX(), go->GetPositionY()); + TC_LOG_ERROR("entities.transport", "GameObject (guidlow %d, entry %d) not created. Suggested coordinates aren't valid (X: %f Y: %f)", go->GetGUID().GetCounter(), go->GetEntry(), go->GetPositionX(), go->GetPositionY()); delete go; return NULL; } @@ -451,7 +452,7 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu pos.GetPosition(x, y, z, o); CalculatePassengerPosition(x, y, z, &o); - if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, phase, entry, x, y, z, o, nullptr, vehId)) + if (!summon->Create(map->GenerateLowGuid<HighGuid::Unit>(), map, phase, entry, x, y, z, o, nullptr, vehId)) { delete summon; return NULL; @@ -703,6 +704,7 @@ void Transport::UpdatePassengerPositions(PassengerSet& passengers) break; case TYPEID_GAMEOBJECT: GetMap()->GameObjectRelocation(passenger->ToGameObject(), x, y, z, o, false); + passenger->ToGameObject()->RelocateStationaryPosition(x, y, z, o); break; case TYPEID_DYNAMICOBJECT: GetMap()->DynamicObjectRelocation(passenger->ToDynObject(), x, y, z, o); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index d02a22d43f4..f085bab165a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -721,7 +721,7 @@ uint32 Unit::DealDamage(Unit* victim, uint32 damage, CleanDamage const* cleanDam if (!victim->ToCreature()->hasLootRecipient()) victim->ToCreature()->SetLootRecipient(this); - if (IsControlledByPlayer()) + if (IsControlledByPlayer() || (ToTempSummon() && ToTempSummon()->GetSummoner() && ToTempSummon()->GetSummoner()->GetTypeId() == TYPEID_PLAYER)) victim->ToCreature()->LowerPlayerDamageReq(health < damage ? health : damage); } @@ -841,7 +841,7 @@ void Unit::CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo { if (!spellInfo) { - TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell by caster: %s %u)", (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell by caster: %s %u)", (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry())); return; } @@ -869,7 +869,7 @@ void Unit::CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { - TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry())); return; } @@ -919,7 +919,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { - TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry())); return; } SpellCastTargets targets; @@ -933,7 +933,7 @@ void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { - TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry())); return; } SpellCastTargets targets; @@ -947,7 +947,7 @@ void Unit::CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castI SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId); if (!spellInfo) { - TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUIDLow() : GetEntry())); + TC_LOG_ERROR("entities.unit", "CastSpell: unknown spell id %u by caster: %s %u)", spellId, (GetTypeId() == TYPEID_PLAYER ? "player (GUID:" : "creature (Entry:"), (GetTypeId() == TYPEID_PLAYER ? GetGUID().GetCounter() : GetEntry())); return; } SpellCastTargets targets; @@ -1977,10 +1977,10 @@ void Unit::AttackerStateUpdate (Unit* victim, WeaponAttackType attType, bool ext if (GetTypeId() == TYPEID_PLAYER) TC_LOG_DEBUG("entities.unit", "AttackerStateUpdate: (Player) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", - GetGUIDLow(), victim->GetGUIDLow(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); + GetGUID().GetCounter(), victim->GetGUID().GetCounter(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); else TC_LOG_DEBUG("entities.unit", "AttackerStateUpdate: (NPC) %u attacked %u (TypeId: %u) for %u dmg, absorbed %u, blocked %u, resisted %u.", - GetGUIDLow(), victim->GetGUIDLow(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); + GetGUID().GetCounter(), victim->GetGUID().GetCounter(), victim->GetTypeId(), damageInfo.damage, damageInfo.absorb, damageInfo.blocked_amount, damageInfo.resist); } } @@ -2257,9 +2257,9 @@ void Unit::SendMeleeAttackStop(Unit* victim) TC_LOG_DEBUG("entities.unit", "WORLD: Sent SMSG_ATTACKSTOP"); if (victim) - TC_LOG_DEBUG("entities.unit", "%s %u stopped attacking %s %u", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUIDLow()); + TC_LOG_DEBUG("entities.unit", "%s %u stopped attacking %s %u", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUID().GetCounter(), (victim->GetTypeId() == TYPEID_PLAYER ? "player" : "creature"), victim->GetGUID().GetCounter()); else - TC_LOG_DEBUG("entities.unit", "%s %u stopped attacking", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUIDLow()); + TC_LOG_DEBUG("entities.unit", "%s %u stopped attacking", (GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), GetGUID().GetCounter()); } bool Unit::isSpellBlocked(Unit* victim, SpellInfo const* spellProto, WeaponAttackType attackType) @@ -3520,7 +3520,7 @@ void Unit::_UnapplyAura(AuraApplication * aurApp, AuraRemoveMode removeMode) else ++iter; } - ASSERT(false); + ABORT(); } void Unit::_RemoveNoStackAurasDueToAura(Aura* aura) @@ -3630,7 +3630,7 @@ void Unit::RemoveOwnedAura(Aura* aura, AuraRemoveMode removeMode) } } - ASSERT(false); + ABORT(); } Aura* Unit::GetOwnedAura(uint32 spellId, ObjectGuid casterGUID, ObjectGuid itemCasterGUID, uint8 reqEffMask, Aura* except) const @@ -4181,7 +4181,7 @@ void Unit::DelayOwnedAuras(uint32 spellId, ObjectGuid caster, int32 delaytime) // update for out of range group members (on 1 slot use) aura->SetNeedClientUpdateForTargets(); - TC_LOG_DEBUG("spells", "Aura %u partially interrupted on unit %u, new duration: %u ms", aura->GetId(), GetGUIDLow(), aura->GetDuration()); + TC_LOG_DEBUG("spells", "Aura %u partially interrupted on unit %u, new duration: %u ms", aura->GetId(), GetGUID().GetCounter(), aura->GetDuration()); } } } @@ -9450,7 +9450,7 @@ void Unit::SetMinion(Minion *minion, bool apply) { OutDebugInfo(); (*itr)->OutDebugInfo(); - ASSERT(false); + ABORT(); } ASSERT((*itr)->GetTypeId() == TYPEID_UNIT); @@ -13171,6 +13171,10 @@ bool Unit::IsInFeralForm() const bool Unit::IsInDisallowedMountForm() const { + if (SpellInfo const* transformSpellInfo = sSpellMgr->GetSpellInfo(getTransForm())) + if (transformSpellInfo->HasAttribute(SPELL_ATTR0_CASTABLE_WHILE_MOUNTED)) + return false; + if (ShapeshiftForm form = GetShapeshiftForm()) { SpellShapeshiftEntry const* shapeshift = sSpellShapeshiftStore.LookupEntry(form); @@ -13600,7 +13604,7 @@ void Unit::RemoveFromWorld() if (GetCharmerGUID()) { TC_LOG_FATAL("entities.unit", "Unit %u has charmer guid when removed from world", GetEntry()); - ASSERT(false); + ABORT(); } if (Unit* owner = GetOwner()) @@ -13608,7 +13612,7 @@ void Unit::RemoveFromWorld() if (owner->m_Controlled.find(this) != owner->m_Controlled.end()) { TC_LOG_FATAL("entities.unit", "Unit %u is in controlled list of %u when removed from world", GetEntry(), owner->GetEntry()); - ASSERT(false); + ABORT(); } } @@ -15832,11 +15836,11 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au ASSERT(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER); ASSERT((type == CHARM_TYPE_VEHICLE) == IsVehicle()); - TC_LOG_DEBUG("entities.unit", "SetCharmedBy: charmer %u (GUID %u), charmed %u (GUID %u), type %u.", charmer->GetEntry(), charmer->GetGUIDLow(), GetEntry(), GetGUIDLow(), uint32(type)); + TC_LOG_DEBUG("entities.unit", "SetCharmedBy: charmer %u (GUID %u), charmed %u (GUID %u), type %u.", charmer->GetEntry(), charmer->GetGUID().GetCounter(), GetEntry(), GetGUID().GetCounter(), uint32(type)); if (this == charmer) { - TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Unit %u (GUID %u) is trying to charm itself!", GetEntry(), GetGUIDLow()); + TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Unit %u (GUID %u) is trying to charm itself!", GetEntry(), GetGUID().GetCounter()); return false; } @@ -15845,14 +15849,14 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au if (GetTypeId() == TYPEID_PLAYER && ToPlayer()->GetTransport()) { - TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Player on transport is trying to charm %u (GUID %u)", GetEntry(), GetGUIDLow()); + TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: Player on transport is trying to charm %u (GUID %u)", GetEntry(), GetGUID().GetCounter()); return false; } // Already charmed if (GetCharmerGUID()) { - TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: %u (GUID %u) has already been charmed but %u (GUID %u) is trying to charm it!", GetEntry(), GetGUIDLow(), charmer->GetEntry(), charmer->GetGUIDLow()); + TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: %u (GUID %u) has already been charmed but %u (GUID %u) is trying to charm it!", GetEntry(), GetGUID().GetCounter(), charmer->GetEntry(), charmer->GetGUID().GetCounter()); return false; } @@ -15879,7 +15883,7 @@ bool Unit::SetCharmedBy(Unit* charmer, CharmType type, AuraApplication const* au // StopCastingCharm may remove a possessed pet? if (!IsInWorld()) { - TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: %u (GUID %u) is not in world but %u (GUID %u) is trying to charm it!", GetEntry(), GetGUIDLow(), charmer->GetEntry(), charmer->GetGUIDLow()); + TC_LOG_FATAL("entities.unit", "Unit::SetCharmedBy: %u (GUID %u) is not in world but %u (GUID %u) is trying to charm it!", GetEntry(), GetGUID().GetCounter(), charmer->GetEntry(), charmer->GetGUID().GetCounter()); return false; } @@ -15976,7 +15980,7 @@ void Unit::RemoveCharmedBy(Unit* charmer) { // TC_LOG_FATAL("entities.unit", "Unit::RemoveCharmedBy: this: " UI64FMTD " true charmer: " UI64FMTD " false charmer: " UI64FMTD, // GetGUID(), GetCharmerGUID(), charmer->GetGUID()); -// ASSERT(false); +// ABORT(); return; } @@ -16971,6 +16975,12 @@ void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* a } } + // If vehicle flag for fixed position set (cannons), or if the following hardcoded units, then set state rooted + // 30236 | Argent Cannon + // 39759 | Tankbuster Cannon + if ((vehicle->GetVehicleInfo()->m_flags & VEHICLE_FLAG_FIXED_POSITION) || vehicle->GetBase()->GetEntry() == 30236 || vehicle->GetBase()->GetEntry() == 39759) + SetControlled(true, UNIT_STATE_ROOT); + ASSERT(!m_vehicle); (void)vehicle->AddPassenger(this, seatId); } @@ -17273,7 +17283,7 @@ void Unit::SendChangeCurrentVictimOpcode(HostileReference* pHostileReference) for (ThreatContainer::StorageType::const_iterator itr = tlist.begin(); itr != tlist.end(); ++itr) { data << (*itr)->getUnitGuid().WriteAsPacked(); - data << uint32((*itr)->getThreat()); + data << uint32((*itr)->getThreat() * 100); } SendMessageToSet(&data, false); } diff --git a/src/server/game/Entities/Vehicle/Vehicle.cpp b/src/server/game/Entities/Vehicle/Vehicle.cpp index b6f9534ac51..982b931fd4f 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.cpp +++ b/src/server/game/Entities/Vehicle/Vehicle.cpp @@ -115,12 +115,12 @@ void Vehicle::Uninstall() if (_status == STATUS_UNINSTALLING && !GetBase()->HasUnitTypeMask(UNIT_MASK_MINION)) { TC_LOG_ERROR("entities.vehicle", "Vehicle GuidLow: %u, Entry: %u attempts to uninstall, but already has STATUS_UNINSTALLING! " - "Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUIDLow(), _me->GetEntry()); + "Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUID().GetCounter(), _me->GetEntry()); return; } _status = STATUS_UNINSTALLING; - TC_LOG_DEBUG("entities.vehicle", "Vehicle::Uninstall Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow()); + TC_LOG_DEBUG("entities.vehicle", "Vehicle::Uninstall Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUID().GetCounter()); RemoveAllPassengers(); if (GetBase()->GetTypeId() == TYPEID_UNIT) @@ -143,7 +143,7 @@ void Vehicle::Reset(bool evading /*= false*/) if (GetBase()->GetTypeId() != TYPEID_UNIT) return; - TC_LOG_DEBUG("entities.vehicle", "Vehicle::Reset (Entry: %u, GuidLow: %u, DBGuid: %u)", GetCreatureEntry(), _me->GetGUIDLow(), _me->ToCreature()->GetDBTableGUIDLow()); + TC_LOG_DEBUG("entities.vehicle", "Vehicle::Reset (Entry: %u, GuidLow: %u, DBGuid: %u)", GetCreatureEntry(), _me->GetGUID().GetCounter(), _me->ToCreature()->GetSpawnId()); ApplyAllImmunities(); InstallAllAccessories(evading); @@ -192,6 +192,12 @@ void Vehicle::ApplyAllImmunities() _me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_DAMAGE_PERCENT_TAKEN, true); } + // If vehicle flag for fixed position set (cannons), or if the following hardcoded units, then set state rooted + // 30236 | Argent Cannon + // 39759 | Tankbuster Cannon + if ((GetVehicleInfo()->m_flags & VEHICLE_FLAG_FIXED_POSITION) || GetBase()->GetEntry() == 30236 || GetBase()->GetEntry() == 39759) + _me->SetControlled(true, UNIT_STATE_ROOT); + // Different immunities for vehicles goes below switch (GetVehicleInfo()->m_ID) { @@ -221,7 +227,7 @@ void Vehicle::ApplyAllImmunities() void Vehicle::RemoveAllPassengers() { - TC_LOG_DEBUG("entities.vehicle", "Vehicle::RemoveAllPassengers. Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUIDLow()); + TC_LOG_DEBUG("entities.vehicle", "Vehicle::RemoveAllPassengers. Entry: %u, GuidLow: %u", _creatureEntry, _me->GetGUID().GetCounter()); /// Setting to_Abort to true will cause @VehicleJoinEvent::Abort to be executed on next @Unit::UpdateEvents call /// This will properly "reset" the pending join process for the passenger. @@ -358,13 +364,13 @@ void Vehicle::InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 typ if (_status == STATUS_UNINSTALLING) { TC_LOG_ERROR("entities.vehicle", "Vehicle (GuidLow: %u, DB GUID: %u, Entry: %u) attempts to install accessory (Entry: %u) on seat %d with STATUS_UNINSTALLING! " - "Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUIDLow(), - (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : _me->GetGUIDLow()), GetCreatureEntry(), entry, (int32)seatId); + "Check Uninstall/PassengerBoarded script hooks for errors.", _me->GetGUID().GetCounter(), + (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetSpawnId() : _me->GetGUID().GetCounter()), GetCreatureEntry(), entry, (int32)seatId); return; } TC_LOG_DEBUG("entities.vehicle", "Vehicle (GuidLow: %u, DB Guid: %u, Entry %u): installing accessory (Entry: %u) on seat: %d", - _me->GetGUIDLow(), (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : _me->GetGUIDLow()), GetCreatureEntry(), + _me->GetGUID().GetCounter(), (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetSpawnId() : _me->GetGUID().GetCounter()), GetCreatureEntry(), entry, (int32)seatId); TempSummon* accessory = _me->SummonCreature(entry, *_me, TempSummonType(type), summonTime); @@ -399,13 +405,13 @@ bool Vehicle::AddPassenger(Unit* unit, int8 seatId) if (_status == STATUS_UNINSTALLING) { TC_LOG_ERROR("entities.vehicle", "Passenger GuidLow: %u, Entry: %u, attempting to board vehicle GuidLow: %u, Entry: %u during uninstall! SeatId: %d", - unit->GetGUIDLow(), unit->GetEntry(), _me->GetGUIDLow(), _me->GetEntry(), (int32)seatId); + unit->GetGUID().GetCounter(), unit->GetEntry(), _me->GetGUID().GetCounter(), _me->GetEntry(), (int32)seatId); return false; } TC_LOG_DEBUG("entities.vehicle", "Unit %s scheduling enter vehicle (entry: %u, vehicleId: %u, guid: %u (dbguid: %u) on seat %d", - unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), - (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetDBTableGUIDLow() : 0), (int32)seatId); + unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUID().GetCounter(), + (_me->GetTypeId() == TYPEID_UNIT ? _me->ToCreature()->GetSpawnId() : 0), (int32)seatId); // The seat selection code may kick other passengers off the vehicle. // While the validity of the following may be arguable, it is possible that when such a passenger @@ -474,7 +480,7 @@ Vehicle* Vehicle::RemovePassenger(Unit* unit) ASSERT(seat != Seats.end()); TC_LOG_DEBUG("entities.vehicle", "Unit %s exit vehicle entry %u id %u dbguid %u seat %d", - unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUIDLow(), (int32)seat->first); + unit->GetName().c_str(), _me->GetEntry(), _vehicleInfo->m_ID, _me->GetGUID().GetCounter(), (int32)seat->first); if (seat->second.SeatInfo->CanEnterOrExit() && ++UsableSeatNum) _me->SetFlag(UNIT_NPC_FLAGS, (_me->GetTypeId() == TYPEID_PLAYER ? UNIT_NPC_FLAG_PLAYER_VEHICLE : UNIT_NPC_FLAG_SPELLCLICK)); @@ -849,7 +855,7 @@ void VehicleJoinEvent::Abort(uint64) if (Target) { TC_LOG_DEBUG("entities.vehicle", "Passenger GuidLow: %u, Entry: %u, board on vehicle GuidLow: %u, Entry: %u SeatId: %d cancelled", - Passenger->GetGUIDLow(), Passenger->GetEntry(), Target->GetBase()->GetGUIDLow(), Target->GetBase()->GetEntry(), (int32)Seat->first); + Passenger->GetGUID().GetCounter(), Passenger->GetEntry(), Target->GetBase()->GetGUID().GetCounter(), Target->GetBase()->GetEntry(), (int32)Seat->first); /// @SPELL_AURA_CONTROL_VEHICLE auras can be applied even when the passenger is not (yet) on the vehicle. /// When this code is triggered it means that something went wrong in @Vehicle::AddPassenger, and we should remove @@ -858,7 +864,7 @@ void VehicleJoinEvent::Abort(uint64) } else TC_LOG_DEBUG("entities.vehicle", "Passenger GuidLow: %u, Entry: %u, board on uninstalled vehicle SeatId: %d cancelled", - Passenger->GetGUIDLow(), Passenger->GetEntry(), (int32)Seat->first); + Passenger->GetGUID().GetCounter(), Passenger->GetEntry(), (int32)Seat->first); if (Passenger->IsInWorld() && Passenger->HasUnitTypeMask(UNIT_MASK_ACCESSORY)) Passenger->ToCreature()->DespawnOrUnsummon(); diff --git a/src/server/game/Entities/Vehicle/VehicleDefines.h b/src/server/game/Entities/Vehicle/VehicleDefines.h index c00bc429f38..3726e9ddf8f 100644 --- a/src/server/game/Entities/Vehicle/VehicleDefines.h +++ b/src/server/game/Entities/Vehicle/VehicleDefines.h @@ -44,7 +44,8 @@ enum VehicleFlags VEHICLE_FLAG_FULLSPEEDPITCHING = 0x00000020, // Sets MOVEFLAG2_FULLSPEEDPITCHING VEHICLE_FLAG_CUSTOM_PITCH = 0x00000040, // If set use pitchMin and pitchMax from DBC, otherwise pitchMin = -pi/2, pitchMax = pi/2 VEHICLE_FLAG_ADJUST_AIM_ANGLE = 0x00000400, // Lua_IsVehicleAimAngleAdjustable - VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800 // Lua_IsVehicleAimPowerAdjustable + VEHICLE_FLAG_ADJUST_AIM_POWER = 0x00000800, // Lua_IsVehicleAimPowerAdjustable + VEHICLE_FLAG_FIXED_POSITION = 0x00200000 // Used for cannons, when they should be rooted }; enum VehicleSpells diff --git a/src/server/game/Events/GameEventMgr.cpp b/src/server/game/Events/GameEventMgr.cpp index 2264612f89b..8f2d0491a91 100644 --- a/src/server/game/Events/GameEventMgr.cpp +++ b/src/server/game/Events/GameEventMgr.cpp @@ -917,7 +917,7 @@ void GameEventMgr::LoadFromDB() uint32 GameEventMgr::GetNPCFlag(Creature* cr) { uint32 mask = 0; - uint32 guid = cr->GetDBTableGUIDLow(); + uint32 guid = cr->GetSpawnId(); for (ActiveEvents::iterator e_itr = m_ActiveEvents.begin(); e_itr != m_ActiveEvents.end(); ++e_itr) { @@ -1115,25 +1115,34 @@ void GameEventMgr::ApplyNewEvent(uint16 event_id) void GameEventMgr::UpdateEventNPCFlags(uint16 event_id) { + std::unordered_map<uint32, std::unordered_set<ObjectGuid::LowType>> creaturesByMap; + // go through the creatures whose npcflags are changed in the event for (NPCFlagList::iterator itr = mGameEventNPCFlags[event_id].begin(); itr != mGameEventNPCFlags[event_id].end(); ++itr) - { // get the creature data from the low guid to get the entry, to be able to find out the whole guid if (CreatureData const* data = sObjectMgr->GetCreatureData(itr->first)) + creaturesByMap[data->mapid].insert(itr->first); + + for (auto const& p : creaturesByMap) + { + sMapMgr->DoForAllMapsWithMapId(p.first, [this, &p](Map* map) { - Creature* cr = HashMapHolder<Creature>::Find(ObjectGuid(HIGHGUID_UNIT, data->id, itr->first)); - // if we found the creature, modify its npcflag - if (cr) + for (auto& spawnId : p.second) { - uint32 npcflag = GetNPCFlag(cr); - if (const CreatureTemplate* ci = cr->GetCreatureTemplate()) - npcflag |= ci->npcflag; - cr->SetUInt32Value(UNIT_NPC_FLAGS, npcflag); - // reset gossip options, since the flag change might have added / removed some - //cr->ResetGossipOptions(); + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(spawnId); + for (auto itr = creatureBounds.first; itr != creatureBounds.second; ++itr) + { + Creature* creature = itr->second; + uint32 npcflag = GetNPCFlag(creature); + if (CreatureTemplate const* creatureTemplate = creature->GetCreatureTemplate()) + npcflag |= creatureTemplate->npcflag; + + creature->SetUInt32Value(UNIT_NPC_FLAGS, npcflag); + // reset gossip options, since the flag change might have added / removed some + //cr->ResetGossipOptions(); + } } - // if we didn't find it, then the npcflag will be updated when the creature is loaded - } + }); } } @@ -1252,8 +1261,16 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { sObjectMgr->RemoveCreatureFromGrid(*itr, data); - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, *itr), (Creature*)NULL)) - creature->AddObjectToRemoveList(); + sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map) + { + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(*itr); + for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second;) + { + Creature* creature = itr2->second; + ++itr2; + creature->AddObjectToRemoveList(); + } + }); } } @@ -1274,8 +1291,16 @@ void GameEventMgr::GameEventUnspawn(int16 event_id) { sObjectMgr->RemoveGameobjectFromGrid(*itr, data); - if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, *itr), (GameObject*)NULL)) - pGameobject->AddObjectToRemoveList(); + sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr](Map* map) + { + auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(*itr); + for (auto itr2 = gameobjectBounds.first; itr2 != gameobjectBounds.second;) + { + GameObject* go = itr2->second; + ++itr2; + go->AddObjectToRemoveList(); + } + }); } } if (internal_event_id < 0 || internal_event_id >= int32(mGameEventPoolIds.size())) @@ -1300,53 +1325,43 @@ void GameEventMgr::ChangeEquipOrModel(int16 event_id, bool activate) continue; // Update if spawned - Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, itr->first), (Creature*)NULL); - if (creature) + sMapMgr->DoForAllMapsWithMapId(data->mapid, [&itr, activate](Map* map) + { - if (activate) + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(itr->first); + for (auto itr2 = creatureBounds.first; itr2 != creatureBounds.second; ++itr2) { - itr->second.equipement_id_prev = creature->GetCurrentEquipmentId(); - itr->second.modelid_prev = creature->GetDisplayId(); - creature->LoadEquipment(itr->second.equipment_id, true); - if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid && - sObjectMgr->GetCreatureModelInfo(itr->second.modelid)) + Creature* creature = itr2->second; + if (activate) { - creature->SetDisplayId(itr->second.modelid); - creature->SetNativeDisplayId(itr->second.modelid); + itr->second.equipement_id_prev = creature->GetCurrentEquipmentId(); + itr->second.modelid_prev = creature->GetDisplayId(); + creature->LoadEquipment(itr->second.equipment_id, true); + if (itr->second.modelid > 0 && itr->second.modelid_prev != itr->second.modelid && + sObjectMgr->GetCreatureModelInfo(itr->second.modelid)) + { + creature->SetDisplayId(itr->second.modelid); + creature->SetNativeDisplayId(itr->second.modelid); + } } - } - else - { - creature->LoadEquipment(itr->second.equipement_id_prev, true); - if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid && - sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev)) + else { - creature->SetDisplayId(itr->second.modelid_prev); - creature->SetNativeDisplayId(itr->second.modelid_prev); + creature->LoadEquipment(itr->second.equipement_id_prev, true); + if (itr->second.modelid_prev > 0 && itr->second.modelid_prev != itr->second.modelid && + sObjectMgr->GetCreatureModelInfo(itr->second.modelid_prev)) + { + creature->SetDisplayId(itr->second.modelid_prev); + creature->SetNativeDisplayId(itr->second.modelid_prev); + } } } - } - else // If not spawned - { - CreatureData const* data2 = sObjectMgr->GetCreatureData(itr->first); - if (data2 && activate) - { - CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(data2->id); - uint32 displayID = ObjectMgr::ChooseDisplayId(cinfo, data2); - sObjectMgr->GetCreatureModelRandomGender(&displayID); - - if (data2->equipmentId == 0) - itr->second.equipement_id_prev = 0; ///@todo: verify this line - else if (data2->equipmentId != -1) - itr->second.equipement_id_prev = data->equipmentId; - itr->second.modelid_prev = displayID; - } - } + }); // now last step: put in data - // just to have write access to it CreatureData& data2 = sObjectMgr->NewOrExistCreatureData(itr->first); if (activate) { + itr->second.modelid_prev = data2.displayid; + itr->second.equipement_id_prev = data2.equipmentId; data2.displayid = itr->second.modelid; data2.equipmentId = itr->second.equipment_id; } @@ -1594,24 +1609,43 @@ void GameEventMgr::SendWorldStateUpdate(Player* player, uint16 event_id) } } -void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate) +class GameEventAIHookWorker { - //! Iterate over every supported source type (creature and gameobject) - //! Not entirely sure how this will affect units in non-loaded grids. +public: + GameEventAIHookWorker(uint16 eventId, bool activate) : _eventId(eventId), _activate(activate) { } + + void Visit(std::unordered_map<ObjectGuid, Creature*>& creatureMap) { - boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Creature>::GetLock()); - HashMapHolder<Creature>::MapType const& m = ObjectAccessor::GetCreatures(); - for (HashMapHolder<Creature>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) - if (iter->second->IsInWorld()) - iter->second->AI()->sOnGameEvent(activate, event_id); + for (auto const& p : creatureMap) + if (p.second->IsInWorld() && p.second->IsAIEnabled) + p.second->AI()->sOnGameEvent(_activate, _eventId); } + + void Visit(std::unordered_map<ObjectGuid, GameObject*>& gameObjectMap) { - boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<GameObject>::GetLock()); - HashMapHolder<GameObject>::MapType const& m = ObjectAccessor::GetGameObjects(); - for (HashMapHolder<GameObject>::MapType::const_iterator iter = m.begin(); iter != m.end(); ++iter) - if (iter->second->IsInWorld()) - iter->second->AI()->OnGameEvent(activate, event_id); + for (auto const& p : gameObjectMap) + if (p.second->IsInWorld()) + p.second->AI()->OnGameEvent(_activate, _eventId); } + + template<class T> + void Visit(std::unordered_map<ObjectGuid, T*>&) { } + +private: + uint16 _eventId; + bool _activate; +}; + +void GameEventMgr::RunSmartAIScripts(uint16 event_id, bool activate) +{ + //! Iterate over every supported source type (creature and gameobject) + //! Not entirely sure how this will affect units in non-loaded grids. + sMapMgr->DoForAllMaps([event_id, activate](Map* map) + { + GameEventAIHookWorker worker(event_id, activate); + TypeContainerVisitor<GameEventAIHookWorker, MapStoredObjectTypesContainer> visitor(worker); + visitor.Visit(map->GetObjectsStore()); + }); } uint16 GameEventMgr::GetEventIdForQuest(Quest const* quest) const diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 35d6ba91401..ca974ba9a37 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -28,99 +28,61 @@ #include "ObjectMgr.h" #include "Pet.h" #include "Player.h" +#include "Transport.h" #include "World.h" #include <boost/thread/shared_mutex.hpp> #include <boost/thread/locks.hpp> -ObjectAccessor::ObjectAccessor() { } - -ObjectAccessor::~ObjectAccessor() { } - -template<class T> T* ObjectAccessor::GetObjectInWorld(uint32 mapid, float x, float y, ObjectGuid guid, T* /*fake*/) -{ - T* obj = HashMapHolder<T>::Find(guid); - if (!obj || obj->GetMapId() != mapid) - return NULL; - - CellCoord p = Trinity::ComputeCellCoord(x, y); - if (!p.IsCoordValid()) - { - TC_LOG_ERROR("misc", "ObjectAccessor::GetObjectInWorld: invalid coordinates supplied X:%f Y:%f grid cell [%u:%u]", x, y, p.x_coord, p.y_coord); - return NULL; - } - - CellCoord q = Trinity::ComputeCellCoord(obj->GetPositionX(), obj->GetPositionY()); - if (!q.IsCoordValid()) - { - TC_LOG_ERROR("misc", "ObjectAccessor::GetObjecInWorld: object (GUID: %u TypeId: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", obj->GetGUIDLow(), obj->GetTypeId(), obj->GetPositionX(), obj->GetPositionY(), q.x_coord, q.y_coord); - return NULL; - } - - int32 dx = int32(p.x_coord) - int32(q.x_coord); - int32 dy = int32(p.y_coord) - int32(q.y_coord); - - if (dx > -2 && dx < 2 && dy > -2 && dy < 2) - return obj; - else - return NULL; -} - -Player* ObjectAccessor::GetObjectInWorld(ObjectGuid guid, Player* /*typeSpecifier*/) -{ - Player* player = HashMapHolder<Player>::Find(guid); - return player && player->IsInWorld() ? player : NULL; -} - -WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid guid) +WorldObject* ObjectAccessor::GetWorldObject(WorldObject const& p, ObjectGuid const& guid) { switch (guid.GetHigh()) { - case HIGHGUID_PLAYER: return GetPlayer(p, guid); - case HIGHGUID_TRANSPORT: - case HIGHGUID_MO_TRANSPORT: - case HIGHGUID_GAMEOBJECT: return GetGameObject(p, guid); - case HIGHGUID_VEHICLE: - case HIGHGUID_UNIT: return GetCreature(p, guid); - case HIGHGUID_PET: return GetPet(p, guid); - case HIGHGUID_DYNAMICOBJECT: return GetDynamicObject(p, guid); - case HIGHGUID_CORPSE: return GetCorpse(p, guid); + case HighGuid::Player: return GetPlayer(p, guid); + case HighGuid::Transport: + case HighGuid::Mo_Transport: + case HighGuid::GameObject: return GetGameObject(p, guid); + case HighGuid::Vehicle: + case HighGuid::Unit: return GetCreature(p, guid); + case HighGuid::Pet: return GetPet(p, guid); + case HighGuid::DynamicObject: return GetDynamicObject(p, guid); + case HighGuid::Corpse: return GetCorpse(p, guid); default: return NULL; } } -Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid guid, uint32 typemask) +Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid const& guid, uint32 typemask) { switch (guid.GetHigh()) { - case HIGHGUID_ITEM: + case HighGuid::Item: if (typemask & TYPEMASK_ITEM && p.GetTypeId() == TYPEID_PLAYER) return ((Player const&)p).GetItemByGuid(guid); break; - case HIGHGUID_PLAYER: + case HighGuid::Player: if (typemask & TYPEMASK_PLAYER) return GetPlayer(p, guid); break; - case HIGHGUID_TRANSPORT: - case HIGHGUID_MO_TRANSPORT: - case HIGHGUID_GAMEOBJECT: + case HighGuid::Transport: + case HighGuid::Mo_Transport: + case HighGuid::GameObject: if (typemask & TYPEMASK_GAMEOBJECT) return GetGameObject(p, guid); break; - case HIGHGUID_UNIT: - case HIGHGUID_VEHICLE: + case HighGuid::Unit: + case HighGuid::Vehicle: if (typemask & TYPEMASK_UNIT) return GetCreature(p, guid); break; - case HIGHGUID_PET: + case HighGuid::Pet: if (typemask & TYPEMASK_UNIT) return GetPet(p, guid); break; - case HIGHGUID_DYNAMICOBJECT: + case HighGuid::DynamicObject: if (typemask & TYPEMASK_DYNAMICOBJECT) return GetDynamicObject(p, guid); break; - case HIGHGUID_CORPSE: + case HighGuid::Corpse: break; default: break; @@ -129,51 +91,62 @@ Object* ObjectAccessor::GetObjectByTypeMask(WorldObject const& p, ObjectGuid gui return NULL; } -Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, ObjectGuid guid) +Corpse* ObjectAccessor::GetCorpse(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Corpse*)NULL); + return u.GetMap()->GetCorpse(guid); } -GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, ObjectGuid guid) +GameObject* ObjectAccessor::GetGameObject(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (GameObject*)NULL); + return u.GetMap()->GetGameObject(guid); } -Transport* ObjectAccessor::GetTransport(WorldObject const& u, ObjectGuid guid) +Transport* ObjectAccessor::GetTransport(WorldObject const& u, ObjectGuid const& guid) { - if (!guid.IsMOTransport()) - return NULL; + return u.GetMap()->GetTransport(guid); +} - GameObject* go = GetGameObject(u, guid); - return go ? go->ToTransport() : NULL; +DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, ObjectGuid const& guid) +{ + return u.GetMap()->GetDynamicObject(guid); } -DynamicObject* ObjectAccessor::GetDynamicObject(WorldObject const& u, ObjectGuid guid) +Unit* ObjectAccessor::GetUnit(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (DynamicObject*)NULL); + if (guid.IsPlayer()) + return GetPlayer(u, guid); + + if (guid.IsPet()) + return GetPet(u, guid); + + return GetCreature(u, guid); } -Unit* ObjectAccessor::GetUnit(WorldObject const& u, ObjectGuid guid) +Creature* ObjectAccessor::GetCreature(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Unit*)NULL); + return u.GetMap()->GetCreature(guid); } -Creature* ObjectAccessor::GetCreature(WorldObject const& u, ObjectGuid guid) +Pet* ObjectAccessor::GetPet(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Creature*)NULL); + return u.GetMap()->GetPet(guid); } -Pet* ObjectAccessor::GetPet(WorldObject const& u, ObjectGuid guid) +Player* ObjectAccessor::GetPlayer(Map const* m, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Pet*)NULL); + if (Player* player = HashMapHolder<Player>::Find(guid)) + if (player->IsInWorld() && player->GetMap() == m) + return player; + + return nullptr; } -Player* ObjectAccessor::GetPlayer(WorldObject const& u, ObjectGuid guid) +Player* ObjectAccessor::GetPlayer(WorldObject const& u, ObjectGuid const& guid) { - return GetObjectInMap(guid, u.GetMap(), (Player*)NULL); + return GetPlayer(u.GetMap(), guid); } -Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, ObjectGuid guid) +Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, ObjectGuid const& guid) { if (guid.IsPet()) return GetPet(u, guid); @@ -184,26 +157,17 @@ Creature* ObjectAccessor::GetCreatureOrPetOrVehicle(WorldObject const& u, Object return NULL; } -Pet* ObjectAccessor::FindPet(ObjectGuid guid) -{ - return GetObjectInWorld(guid, (Pet*)NULL); -} - -Player* ObjectAccessor::FindPlayer(ObjectGuid guid) +Player* ObjectAccessor::FindPlayer(ObjectGuid const& guid) { - return GetObjectInWorld(guid, (Player*)NULL); + Player* player = HashMapHolder<Player>::Find(guid); + return player && player->IsInWorld() ? player : nullptr; } -Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid guid) +Player* ObjectAccessor::FindConnectedPlayer(ObjectGuid const& guid) { return HashMapHolder<Player>::Find(guid); } -Unit* ObjectAccessor::FindUnit(ObjectGuid guid) -{ - return GetObjectInWorld(guid, (Unit*)NULL); -} - Player* ObjectAccessor::FindPlayerByName(std::string const& name) { boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock()); @@ -242,6 +206,11 @@ Player* ObjectAccessor::FindConnectedPlayerByName(std::string const& name) return NULL; } +HashMapHolder<Player>::MapType const& ObjectAccessor::GetPlayers() +{ + return HashMapHolder<Player>::GetContainer(); +} + void ObjectAccessor::SaveAllPlayers() { boost::shared_lock<boost::shared_mutex> lock(*HashMapHolder<Player>::GetLock()); @@ -251,207 +220,6 @@ void ObjectAccessor::SaveAllPlayers() itr->second->SaveToDB(); } -Corpse* ObjectAccessor::GetCorpseForPlayerGUID(ObjectGuid guid) -{ - boost::shared_lock<boost::shared_mutex> lock(_corpseLock); - - Player2CorpsesMapType::iterator iter = i_player2corpse.find(guid); - if (iter == i_player2corpse.end()) - return NULL; - - ASSERT(iter->second->GetType() != CORPSE_BONES); - - return iter->second; -} - -void ObjectAccessor::RemoveCorpse(Corpse* corpse) -{ - ASSERT(corpse && corpse->GetType() != CORPSE_BONES); - - boost::upgrade_lock<boost::shared_mutex> lock(_corpseLock); - - /// @todo more works need to be done for corpse and other world object - if (Map* map = corpse->FindMap()) - { - corpse->DestroyForNearbyPlayers(); - if (corpse->IsInGrid()) - map->RemoveFromMap(corpse, false); - else - { - corpse->RemoveFromWorld(); - corpse->ResetMap(); - } - } - else - - corpse->RemoveFromWorld(); - - // Critical section - { - boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock); - - Player2CorpsesMapType::iterator iter = i_player2corpse.find(corpse->GetOwnerGUID()); - if (iter == i_player2corpse.end()) /// @todo Fix this - return; - - // build mapid*cellid -> guid_set map - CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY()); - sObjectMgr->DeleteCorpseCellData(corpse->GetMapId(), cellCoord.GetId(), corpse->GetOwnerGUID().GetCounter()); - - i_player2corpse.erase(iter); - } -} - -void ObjectAccessor::AddCorpse(Corpse* corpse) -{ - ASSERT(corpse && corpse->GetType() != CORPSE_BONES); - - // Critical section - { - boost::unique_lock<boost::shared_mutex> lock(_corpseLock); - - ASSERT(i_player2corpse.find(corpse->GetOwnerGUID()) == i_player2corpse.end()); - i_player2corpse[corpse->GetOwnerGUID()] = corpse; - - // build mapid*cellid -> guid_set map - CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY()); - sObjectMgr->AddCorpseCellData(corpse->GetMapId(), cellCoord.GetId(), corpse->GetOwnerGUID().GetCounter(), corpse->GetInstanceId()); - } -} - -void ObjectAccessor::AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, Map* map) -{ - boost::shared_lock<boost::shared_mutex> lock(_corpseLock); - - for (Player2CorpsesMapType::iterator iter = i_player2corpse.begin(); iter != i_player2corpse.end(); ++iter) - { - // We need this check otherwise a corpose may be added to a grid twice - if (iter->second->IsInGrid()) - continue; - - if (iter->second->GetGridCoord() == gridpair) - { - // verify, if the corpse in our instance (add only corpses which are) - if (map->Instanceable()) - { - if (iter->second->GetInstanceId() == map->GetInstanceId()) - grid.AddWorldObject(iter->second); - } - else - grid.AddWorldObject(iter->second); - } - } -} - -Corpse* ObjectAccessor::ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia /*=false*/) -{ - Corpse* corpse = GetCorpseForPlayerGUID(player_guid); - if (!corpse) - { - //in fact this function is called from several places - //even when player doesn't have a corpse, not an error - return NULL; - } - - TC_LOG_DEBUG("misc", "Deleting Corpse and spawned bones."); - - // Map can be NULL - Map* map = corpse->FindMap(); - - // remove corpse from player_guid -> corpse map and from current map - RemoveCorpse(corpse); - - // remove corpse from DB - SQLTransaction trans = CharacterDatabase.BeginTransaction(); - corpse->DeleteFromDB(trans); - CharacterDatabase.CommitTransaction(trans); - - Corpse* bones = NULL; - // create the bones only if the map and the grid is loaded at the corpse's location - // ignore bones creating option in case insignia - - if (map && (insignia || - (map->IsBattlegroundOrArena() ? sWorld->getBoolConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld->getBoolConfig(CONFIG_DEATH_BONES_WORLD))) && - !map->IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY())) - { - // Create bones, don't change Corpse - bones = new Corpse; - bones->Create(corpse->GetGUIDLow(), map); - - for (uint8 i = OBJECT_FIELD_TYPE + 1; i < CORPSE_END; ++i) // don't overwrite guid and object type - bones->SetUInt32Value(i, corpse->GetUInt32Value(i)); - - bones->SetGridCoord(corpse->GetGridCoord()); - // bones->m_time = m_time; // don't overwrite time - // bones->m_type = m_type; // don't overwrite type - bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); - bones->SetPhaseMask(corpse->GetPhaseMask(), false); - - bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES); - bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty); - - for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) - { - if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i)) - bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0); - } - - // add bones in grid store if grid loaded where corpse placed - map->AddToMap(bones); - } - - // all references to the corpse should be removed at this point - delete corpse; - - return bones; -} - -void ObjectAccessor::RemoveOldCorpses() -{ - time_t now = time(NULL); - Player2CorpsesMapType::iterator next; - for (Player2CorpsesMapType::iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); itr = next) - { - next = itr; - ++next; - - if (!itr->second->IsExpired(now)) - continue; - - ConvertCorpseForPlayer(itr->first); - } -} - -void ObjectAccessor::Update(uint32 /*diff*/) -{ - UpdateDataMapType update_players; - - while (!i_objects.empty()) - { - Object* obj = *i_objects.begin(); - ASSERT(obj && obj->IsInWorld()); - i_objects.erase(i_objects.begin()); - obj->BuildUpdate(update_players); - } - - WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 - for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) - { - iter->second.BuildPacket(&packet); - iter->first->GetSession()->SendPacket(&packet); - packet.clear(); // clean the string - } -} - -void ObjectAccessor::UnloadAll() -{ - for (Player2CorpsesMapType::const_iterator itr = i_player2corpse.begin(); itr != i_player2corpse.end(); ++itr) - { - itr->second->RemoveFromWorld(); - delete itr->second; - } -} - /// Define the static members of HashMapHolder template <class T> typename HashMapHolder<T>::MapType HashMapHolder<T>::_objectMap; @@ -460,15 +228,5 @@ template <class T> boost::shared_mutex HashMapHolder<T>::_lock; /// Global definitions for the hashmap storage template class HashMapHolder<Player>; -template class HashMapHolder<Pet>; -template class HashMapHolder<GameObject>; -template class HashMapHolder<DynamicObject>; -template class HashMapHolder<Creature>; -template class HashMapHolder<Corpse>; - -template Player* ObjectAccessor::GetObjectInWorld<Player>(uint32 mapid, float x, float y, ObjectGuid guid, Player* /*fake*/); -template Pet* ObjectAccessor::GetObjectInWorld<Pet>(uint32 mapid, float x, float y, ObjectGuid guid, Pet* /*fake*/); -template Creature* ObjectAccessor::GetObjectInWorld<Creature>(uint32 mapid, float x, float y, ObjectGuid guid, Creature* /*fake*/); -template Corpse* ObjectAccessor::GetObjectInWorld<Corpse>(uint32 mapid, float x, float y, ObjectGuid guid, Corpse* /*fake*/); -template GameObject* ObjectAccessor::GetObjectInWorld<GameObject>(uint32 mapid, float x, float y, ObjectGuid guid, GameObject* /*fake*/); -template DynamicObject* ObjectAccessor::GetObjectInWorld<DynamicObject>(uint32 mapid, float x, float y, ObjectGuid guid, DynamicObject* /*fake*/); + +template class HashMapHolder<Transport>; diff --git a/src/server/game/Globals/ObjectAccessor.h b/src/server/game/Globals/ObjectAccessor.h index 2d32e747eb1..d5fb8564b96 100644 --- a/src/server/game/Globals/ObjectAccessor.h +++ b/src/server/game/Globals/ObjectAccessor.h @@ -30,7 +30,6 @@ #include "UpdateData.h" #include "Object.h" - class Creature; class Corpse; class Unit; @@ -46,6 +45,9 @@ template <class T> class HashMapHolder { public: + static_assert(std::is_same<Player, T>::value + || std::is_same<Transport, T>::value, + "Only Player and Transport can be registered in global HashMapHolder"); typedef std::unordered_map<ObjectGuid, T*> MapType; @@ -83,165 +85,47 @@ class HashMapHolder static MapType _objectMap; }; -class ObjectAccessor +namespace ObjectAccessor { - private: - ObjectAccessor(); - ~ObjectAccessor(); - ObjectAccessor(const ObjectAccessor&); - ObjectAccessor& operator=(const ObjectAccessor&); - - public: - /// @todo: Override these template functions for each holder type and add assertions - - static ObjectAccessor* instance() - { - static ObjectAccessor instance; - return &instance; - } - - template<class T> static T* GetObjectInOrOutOfWorld(ObjectGuid guid, T* /*typeSpecifier*/) - { - return HashMapHolder<T>::Find(guid); - } - - static Unit* GetObjectInOrOutOfWorld(ObjectGuid guid, Unit* /*typeSpecifier*/) - { - if (guid.IsPlayer()) - return (Unit*)GetObjectInOrOutOfWorld(guid, (Player*)NULL); - - if (guid.IsPet()) - return (Unit*)GetObjectInOrOutOfWorld(guid, (Pet*)NULL); - - return (Unit*)GetObjectInOrOutOfWorld(guid, (Creature*)NULL); - } - - // returns object if is in world - template<class T> static T* GetObjectInWorld(ObjectGuid guid, T* /*typeSpecifier*/) - { - return HashMapHolder<T>::Find(guid); - } - - // Player may be not in world while in ObjectAccessor - static Player* GetObjectInWorld(ObjectGuid guid, Player* /*typeSpecifier*/); - - static Unit* GetObjectInWorld(ObjectGuid guid, Unit* /*typeSpecifier*/) - { - if (guid.IsPlayer()) - return (Unit*)GetObjectInWorld(guid, (Player*)NULL); - - if (guid.IsPet()) - return (Unit*)GetObjectInWorld(guid, (Pet*)NULL); - - return (Unit*)GetObjectInWorld(guid, (Creature*)NULL); - } - - // returns object if is in map - template<class T> static T* GetObjectInMap(ObjectGuid guid, Map* map, T* /*typeSpecifier*/) - { - ASSERT(map); - if (T * obj = GetObjectInWorld(guid, (T*)NULL)) - if (obj->GetMap() == map) - return obj; - return NULL; - } - - template<class T> static T* GetObjectInWorld(uint32 mapid, float x, float y, ObjectGuid guid, T* /*fake*/); - - // these functions return objects only if in map of specified object - static WorldObject* GetWorldObject(WorldObject const&, ObjectGuid); - static Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid, uint32 typemask); - static Corpse* GetCorpse(WorldObject const& u, ObjectGuid guid); - static GameObject* GetGameObject(WorldObject const& u, ObjectGuid guid); - static Transport* GetTransport(WorldObject const& u, ObjectGuid guid); - static DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid guid); - static Unit* GetUnit(WorldObject const&, ObjectGuid guid); - static Creature* GetCreature(WorldObject const& u, ObjectGuid guid); - static Pet* GetPet(WorldObject const&, ObjectGuid guid); - static Player* GetPlayer(WorldObject const&, ObjectGuid guid); - static Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid); - - // these functions return objects if found in whole world - // ACCESS LIKE THAT IS NOT THREAD SAFE - static Pet* FindPet(ObjectGuid); - static Player* FindPlayer(ObjectGuid); - static Creature* FindCreature(ObjectGuid); - static Unit* FindUnit(ObjectGuid); - static Player* FindPlayerByName(std::string const& name); - - // this returns Player even if he is not in world, for example teleporting - static Player* FindConnectedPlayer(ObjectGuid); - static Player* FindConnectedPlayerByName(std::string const& name); - - // when using this, you must use the hashmapholder's lock - static HashMapHolder<Player>::MapType const& GetPlayers() - { - return HashMapHolder<Player>::GetContainer(); - } - - // when using this, you must use the hashmapholder's lock - static HashMapHolder<Creature>::MapType const& GetCreatures() - { - return HashMapHolder<Creature>::GetContainer(); - } - - // when using this, you must use the hashmapholder's lock - static HashMapHolder<GameObject>::MapType const& GetGameObjects() - { - return HashMapHolder<GameObject>::GetContainer(); - } - - template<class T> static void AddObject(T* object) - { - HashMapHolder<T>::Insert(object); - } - - template<class T> static void RemoveObject(T* object) - { - HashMapHolder<T>::Remove(object); - } - - static void SaveAllPlayers(); - - //non-static functions - void AddUpdateObject(Object* obj) - { - std::lock_guard<std::mutex> lock(_objectLock); - i_objects.insert(obj); - } - - void RemoveUpdateObject(Object* obj) - { - std::lock_guard<std::mutex> lock(_objectLock); - i_objects.erase(obj); - } - - //Thread safe - Corpse* GetCorpseForPlayerGUID(ObjectGuid guid); - void RemoveCorpse(Corpse* corpse); - void AddCorpse(Corpse* corpse); - void AddCorpsesToGrid(GridCoord const& gridpair, GridType& grid, Map* map); - Corpse* ConvertCorpseForPlayer(ObjectGuid player_guid, bool insignia = false); - - //Thread unsafe - void Update(uint32 diff); - void RemoveOldCorpses(); - void UnloadAll(); - - private: - static void _buildChangeObjectForPlayer(WorldObject*, UpdateDataMapType&); - static void _buildPacket(Player*, Object*, UpdateDataMapType&); - void _update(); - - typedef std::unordered_map<ObjectGuid, Corpse*> Player2CorpsesMapType; - typedef std::unordered_map<Player*, UpdateData>::value_type UpdateDataValueType; - - std::set<Object*> i_objects; - Player2CorpsesMapType i_player2corpse; - - std::mutex _objectLock; - boost::shared_mutex _corpseLock; + // these functions return objects only if in map of specified object + WorldObject* GetWorldObject(WorldObject const&, ObjectGuid const&); + Object* GetObjectByTypeMask(WorldObject const&, ObjectGuid const&, uint32 typemask); + Corpse* GetCorpse(WorldObject const& u, ObjectGuid const& guid); + GameObject* GetGameObject(WorldObject const& u, ObjectGuid const& guid); + Transport* GetTransport(WorldObject const& u, ObjectGuid const& guid); + DynamicObject* GetDynamicObject(WorldObject const& u, ObjectGuid const& guid); + Unit* GetUnit(WorldObject const&, ObjectGuid const& guid); + Creature* GetCreature(WorldObject const& u, ObjectGuid const& guid); + Pet* GetPet(WorldObject const&, ObjectGuid const& guid); + Player* GetPlayer(Map const*, ObjectGuid const& guid); + Player* GetPlayer(WorldObject const&, ObjectGuid const& guid); + Creature* GetCreatureOrPetOrVehicle(WorldObject const&, ObjectGuid const&); + + // these functions return objects if found in whole world + // ACCESS LIKE THAT IS NOT THREAD SAFE + Player* FindPlayer(ObjectGuid const&); + Player* FindPlayerByName(std::string const& name); + + // this returns Player even if he is not in world, for example teleporting + Player* FindConnectedPlayer(ObjectGuid const&); + Player* FindConnectedPlayerByName(std::string const& name); + + // when using this, you must use the hashmapholder's lock + HashMapHolder<Player>::MapType const& GetPlayers(); + + template<class T> + void AddObject(T* object) + { + HashMapHolder<T>::Insert(object); + } + + template<class T> + void RemoveObject(T* object) + { + HashMapHolder<T>::Remove(object); + } + + void SaveAllPlayers(); }; -#define sObjectAccessor ObjectAccessor::instance() #endif diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 71b06c1a308..b5d8d08a6a4 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -223,15 +223,8 @@ ObjectMgr::ObjectMgr(): _itemTextId(1), _mailId(1), _hiPetNumber(1), - _hiCharGuid(1), - _hiCreatureGuid(1), - _hiPetGuid(1), - _hiVehicleGuid(1), - _hiItemGuid(1), - _hiGoGuid(1), - _hiDoGuid(1), - _hiCorpseGuid(1), - _hiMoTransGuid(1), + _creatureSpawnId(1), + _gameObjectSpawnId(1), DBCLocaleIndex(LOCALE_enUS) { for (uint8 i = 0; i < MAX_CLASSES; ++i) @@ -1386,8 +1379,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - guid = ObjectGuid(HIGHGUID_UNIT, slave->id, guidLow); - linkedGuid = ObjectGuid(HIGHGUID_UNIT, master->id, linkedGuidLow); + guid = ObjectGuid(HighGuid::Unit, slave->id, guidLow); + linkedGuid = ObjectGuid(HighGuid::Unit, master->id, linkedGuidLow); break; } case CREATURE_TO_GO: @@ -1423,8 +1416,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - guid = ObjectGuid(HIGHGUID_UNIT, slave->id, guidLow); - linkedGuid = ObjectGuid(HIGHGUID_GAMEOBJECT, master->id, linkedGuidLow); + guid = ObjectGuid(HighGuid::Unit, slave->id, guidLow); + linkedGuid = ObjectGuid(HighGuid::GameObject, master->id, linkedGuidLow); break; } case GO_TO_GO: @@ -1460,8 +1453,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - guid = ObjectGuid(HIGHGUID_GAMEOBJECT, slave->id, guidLow); - linkedGuid = ObjectGuid(HIGHGUID_GAMEOBJECT, master->id, linkedGuidLow); + guid = ObjectGuid(HighGuid::GameObject, slave->id, guidLow); + linkedGuid = ObjectGuid(HighGuid::GameObject, master->id, linkedGuidLow); break; } case GO_TO_CREATURE: @@ -1497,8 +1490,8 @@ void ObjectMgr::LoadLinkedRespawn() break; } - guid = ObjectGuid(HIGHGUID_GAMEOBJECT, slave->id, guidLow); - linkedGuid = ObjectGuid(HIGHGUID_UNIT, master->id, linkedGuidLow); + guid = ObjectGuid(HighGuid::GameObject, slave->id, guidLow); + linkedGuid = ObjectGuid(HighGuid::Unit, master->id, linkedGuidLow); break; } } @@ -1518,7 +1511,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow) CreatureData const* master = GetCreatureData(guidLow); ASSERT(master); - ObjectGuid guid(HIGHGUID_UNIT, master->id, guidLow); + ObjectGuid guid(HighGuid::Unit, master->id, guidLow); if (!linkedGuidLow) // we're removing the linking { @@ -1549,7 +1542,7 @@ bool ObjectMgr::SetCreatureLinkedRespawn(uint32 guidLow, uint32 linkedGuidLow) return false; } - ObjectGuid linkedGuid(HIGHGUID_UNIT, slave->id, linkedGuidLow); + ObjectGuid linkedGuid(HighGuid::Unit, slave->id, linkedGuidLow); _linkedRespawnStore[guid] = linkedGuid; PreparedStatement *stmt = WorldDatabase.GetPreparedStatement(WORLD_REP_CREATURE_LINKED_RESPAWN); @@ -1848,7 +1841,8 @@ uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float if (!map) return 0; - uint32 guid = GenerateLowGuid(HIGHGUID_GAMEOBJECT); + uint32 guid = GenerateGameObjectSpawnId(); + GameObjectData& data = NewGOData(guid); data.id = entry; data.mapid = mapId; @@ -1888,38 +1882,6 @@ uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float return guid; } -bool ObjectMgr::MoveCreatureData(uint32 guid, uint32 mapId, const Position& pos) -{ - CreatureData& data = NewOrExistCreatureData(guid); - if (!data.id) - return false; - - RemoveCreatureFromGrid(guid, &data); - if (data.posX == pos.GetPositionX() && data.posY == pos.GetPositionY() && data.posZ == pos.GetPositionZ()) - return true; - data.posX = pos.GetPositionX(); - data.posY = pos.GetPositionY(); - data.posZ = pos.GetPositionZ(); - data.orientation = pos.GetOrientation(); - AddCreatureToGrid(guid, &data); - - // Spawn if necessary (loaded grids only) - if (Map* map = sMapMgr->CreateBaseMap(mapId)) - { - // We use spawn coords to spawn - if (!map->Instanceable() && map->IsGridLoaded(data.posX, data.posY)) - { - Creature* creature = new Creature(); - if (!creature->LoadCreatureFromDB(guid, map)) - { - TC_LOG_ERROR("misc", "MoveCreatureData: Cannot add creature guid %u to map", guid); - delete creature; - return false; - } - } - } - return true; -} uint32 ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay /*= 0*/) { @@ -1929,8 +1891,11 @@ uint32 ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float x, float y, uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats CreatureBaseStats const* stats = GetCreatureBaseStats(level, cInfo->unit_class); + Map* map = sMapMgr->CreateBaseMap(mapId); + if (!map) + return 0; - uint32 guid = GenerateLowGuid(HIGHGUID_UNIT); + uint32 guid = GenerateCreatureSpawnId(); CreatureData& data = NewOrExistCreatureData(guid); data.id = entry; data.mapid = mapId; @@ -1955,19 +1920,15 @@ uint32 ObjectMgr::AddCreatureData(uint32 entry, uint32 mapId, float x, float y, AddCreatureToGrid(guid, &data); - // Spawn if necessary (loaded grids only) - if (Map* map = sMapMgr->CreateBaseMap(mapId)) + // We use spawn coords to spawn + if (!map->Instanceable() && !map->IsRemovalGrid(x, y)) { - // We use spawn coords to spawn - if (!map->Instanceable() && !map->IsRemovalGrid(x, y)) + Creature* creature = new Creature(); + if (!creature->LoadCreatureFromDB(guid, map)) { - Creature* creature = new Creature(); - if (!creature->LoadCreatureFromDB(guid, map)) - { - TC_LOG_ERROR("misc", "AddCreature: Cannot add creature entry %u to map", entry); - delete creature; - return 0; - } + TC_LOG_ERROR("misc", "AddCreature: Cannot add creature entry %u to map", entry); + delete creature; + return 0; } } @@ -2163,7 +2124,7 @@ void ObjectMgr::RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data Player* ObjectMgr::GetPlayerByLowGUID(uint32 lowguid) const { - ObjectGuid guid(HIGHGUID_PLAYER, lowguid); + ObjectGuid guid(HighGuid::Player, lowguid); return ObjectAccessor::FindPlayer(guid); } @@ -2177,7 +2138,7 @@ ObjectGuid ObjectMgr::GetPlayerGUIDByName(std::string const& name) const PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) - return ObjectGuid(HIGHGUID_PLAYER, (*result)[0].GetUInt32()); + return ObjectGuid(HighGuid::Player, (*result)[0].GetUInt32()); return ObjectGuid::Empty; } @@ -3966,31 +3927,31 @@ void ObjectMgr::LoadQuests() mExclusiveQuestGroups.clear(); QueryResult result = WorldDatabase.Query("SELECT " - //0 1 2 3 4 5 6 7 8 - "ID, QuestType, QuestLevel, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, LimitTime, RequiredRaces," + //0 1 2 3 4 5 6 7 8 + "ID, QuestType, QuestLevel, MinLevel, QuestSortID, QuestInfoID, SuggestedGroupNum, TimeAllowed, AllowableRaces," // 9 10 11 12 "RequiredFactionId1, RequiredFactionId2, RequiredFactionValue1, RequiredFactionValue2, " - // 13 14 15 16 17 18 19 20 - "NextQuestIdChain, RewardXPId, RewardOrRequiredMoney, RewardMoneyMaxLevel, RewardSpell, RewardSpellCast, RewardHonor, RewardHonorMultiplier, " - // 21 22 23 24 25 26 - "SourceItemId, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, " + // 13 14 15 16 17 18 19 20 + "RewardNextQuest, RewardXPDifficulty, RewardMoney, RewardBonusMoney, RewardDisplaySpell, RewardSpell, RewardHonor, RewardKillHonor, " + // 21 22 23 24 25 26 + "StartItem, Flags, RewardTitle, RequiredPlayerKills, RewardTalents, RewardArenaPoints, " // 27 28 29 30 31 32 33 34 "RewardItem1, RewardAmount1, RewardItem2, RewardAmount2, RewardItem3, RewardAmount3, RewardItem4, RewardAmount4, " // 35 36 37 38 39 40 41 42 43 44 45 46 "RewardChoiceItemID1, RewardChoiceItemQuantity1, RewardChoiceItemID2, RewardChoiceItemQuantity2, RewardChoiceItemID3, RewardChoiceItemQuantity3, RewardChoiceItemID4, RewardChoiceItemQuantity4, RewardChoiceItemID5, RewardChoiceItemQuantity5, RewardChoiceItemID6, RewardChoiceItemQuantity6, " // 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 "RewardFactionID1, RewardFactionValue1, RewardFactionOverride1, RewardFactionID2, RewardFactionValue2, RewardFactionOverride2, RewardFactionID3, RewardFactionValue3, RewardFactionOverride3, RewardFactionID4, RewardFactionValue4, RewardFactionOverride4, RewardFactionID5, RewardFactionValue5, RewardFactionOverride5," - // 62 63 64 65 - "PointMapId, PointX, PointY, PointOption, " - // 66 67 68 69 70 - "LogTitle, LogDescription, QuestDescription, EndText, QuestCompletionLog, " + // 62 63 64 65 + "POIContinent, POIx, POIy, POIPriority, " + // 66 67 68 69 70 + "LogTitle, LogDescription, QuestDescription, AreaDescription, QuestCompletionLog, " // 71 72 73 74 75 76 77 78 "RequiredNpcOrGo1, RequiredNpcOrGo2, RequiredNpcOrGo3, RequiredNpcOrGo4, RequiredNpcOrGoCount1, RequiredNpcOrGoCount2, RequiredNpcOrGoCount3, RequiredNpcOrGoCount4, " - // 79 80 81 82 83 84 85 86 - "RequiredSourceItemId1, RequiredSourceItemId2, RequiredSourceItemId3, RequiredSourceItemId4, RequiredSourceItemCount1, RequiredSourceItemCount2, RequiredSourceItemCount3, RequiredSourceItemCount4, " + // 79 80 81 82 83 84 85 86 + "ItemDrop1, ItemDrop2, ItemDrop3, ItemDrop4, ItemDropQuantity1, ItemDropQuantity2, ItemDropQuantity3, ItemDropQuantity4, " // 87 88 89 90 91 92 93 94 95 96 97 98 "RequiredItemId1, RequiredItemId2, RequiredItemId3, RequiredItemId4, RequiredItemId5, RequiredItemId6, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredItemCount6, " - // 99 100 101 102 103 + // 99 100 101 102 103 "Unknown0, ObjectiveText1, ObjectiveText2, ObjectiveText3, ObjectiveText4" " FROM quest_template"); if (!result) @@ -4011,7 +3972,7 @@ void ObjectMgr::LoadQuests() } while (result->NextRow()); std::map<uint32, uint32> usedMailTemplates; - + // Load `quest_details` // 0 1 2 3 4 5 6 7 8 result = WorldDatabase.Query("SELECT ID, Emote1, Emote2, Emote3, Emote4, EmoteDelay1, EmoteDelay2, EmoteDelay3, EmoteDelay4 FROM quest_details"); @@ -4215,13 +4176,13 @@ void ObjectMgr::LoadQuests() qinfo->RequiredClasses = 0; } } - // RequiredRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race - if (qinfo->RequiredRaces) + // AllowableRaces, can be 0/RACEMASK_ALL_PLAYABLE to allow any race + if (qinfo->AllowableRaces) { - if (!(qinfo->RequiredRaces & RACEMASK_ALL_PLAYABLE)) + if (!(qinfo->AllowableRaces & RACEMASK_ALL_PLAYABLE)) { - TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `RequiredRaces` (%u), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->RequiredRaces); - qinfo->RequiredRaces = 0; + TC_LOG_ERROR("sql.sql", "Quest %u does not contain any playable races in `AllowableRaces` (%u), value set to 0 (all races).", qinfo->GetQuestId(), qinfo->AllowableRaces); + qinfo->AllowableRaces = 0; } } // RequiredSkillId, can be 0 @@ -4323,26 +4284,26 @@ void ObjectMgr::LoadQuests() // quest can't reward this title } - if (qinfo->SourceItemId) + if (qinfo->StartItem) { - if (!sObjectMgr->GetItemTemplate(qinfo->SourceItemId)) + if (!sObjectMgr->GetItemTemplate(qinfo->StartItem)) { - TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = %u but item with entry %u does not exist, quest can't be done.", - qinfo->GetQuestId(), qinfo->SourceItemId, qinfo->SourceItemId); - qinfo->SourceItemId = 0; // quest can't be done for this requirement + TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = %u but item with entry %u does not exist, quest can't be done.", + qinfo->GetQuestId(), qinfo->StartItem, qinfo->StartItem); + qinfo->StartItem = 0; // quest can't be done for this requirement } - else if (qinfo->SourceItemIdCount == 0) + else if (qinfo->StartItemCount == 0) { - TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = %u but `SourceItemIdCount` = 0, set to 1 but need fix in DB.", - qinfo->GetQuestId(), qinfo->SourceItemId); - qinfo->SourceItemIdCount = 1; // update to 1 for allow quest work for backward compatibility with DB + TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = %u but `StartItemCount` = 0, set to 1 but need fix in DB.", + qinfo->GetQuestId(), qinfo->StartItem); + qinfo->StartItemCount = 1; // update to 1 for allow quest work for backward compatibility with DB } } - else if (qinfo->SourceItemIdCount>0) + else if (qinfo->StartItemCount>0) { - TC_LOG_ERROR("sql.sql", "Quest %u has `SourceItemId` = 0 but `SourceItemIdCount` = %u, useless value.", - qinfo->GetQuestId(), qinfo->SourceItemIdCount); - qinfo->SourceItemIdCount=0; // no quest work changes in fact + TC_LOG_ERROR("sql.sql", "Quest %u has `StartItem` = 0 but `StartItemCount` = %u, useless value.", + qinfo->GetQuestId(), qinfo->StartItemCount); + qinfo->StartItemCount=0; // no quest work changes in fact } if (qinfo->SourceSpellid) @@ -4393,22 +4354,22 @@ void ObjectMgr::LoadQuests() for (uint8 j = 0; j < QUEST_SOURCE_ITEM_IDS_COUNT; ++j) { - uint32 id = qinfo->RequiredSourceItemId[j]; + uint32 id = qinfo->ItemDrop[j]; if (id) { if (!sObjectMgr->GetItemTemplate(id)) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSourceItemId%d` = %u but item with entry %u does not exist, quest can't be done.", + TC_LOG_ERROR("sql.sql", "Quest %u has `ItemDrop%d` = %u but item with entry %u does not exist, quest can't be done.", qinfo->GetQuestId(), j+1, id, id); // no changes, quest can't be done for this requirement } } else { - if (qinfo->RequiredSourceItemCount[j]>0) + if (qinfo->ItemDropQuantity[j]>0) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RequiredSourceItemId%d` = 0 but `RequiredSourceItemCount%d` = %u.", - qinfo->GetQuestId(), j+1, j+1, qinfo->RequiredSourceItemCount[j]); + TC_LOG_ERROR("sql.sql", "Quest %u has `ItemDrop%d` = 0 but `ItemDropQuantity%d` = %u.", + qinfo->GetQuestId(), j+1, j+1, qinfo->ItemDropQuantity[j]); // no changes, quest ignore this data } } @@ -4529,55 +4490,55 @@ void ObjectMgr::LoadQuests() } } - if (qinfo->RewardSpell) + if (qinfo->RewardDisplaySpell) { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardDisplaySpell); if (!spellInfo) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u does not exist, spell removed as display reward.", - qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell); - qinfo->RewardSpell = 0; // no spell reward will display for this quest + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u does not exist, spell removed as display reward.", + qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell); + qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest } else if (!SpellMgr::IsSpellValid(spellInfo)) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is broken, quest will not have a spell reward.", - qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell); - qinfo->RewardSpell = 0; // no spell reward will display for this quest + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u is broken, quest will not have a spell reward.", + qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell); + qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest } - else if (GetTalentSpellCost(qinfo->RewardSpell)) + else if (GetTalentSpellCost(qinfo->RewardDisplaySpell)) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.", - qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell); - qinfo->RewardSpell = 0; // no spell reward will display for this quest + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u is talent, quest will not have a spell reward.", + qinfo->GetQuestId(), qinfo->RewardDisplaySpell, qinfo->RewardDisplaySpell); + qinfo->RewardDisplaySpell = 0; // no spell reward will display for this quest } } - if (qinfo->RewardSpellCast > 0) + if (qinfo->RewardSpell > 0) { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpellCast); + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(qinfo->RewardSpell); if (!spellInfo) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u does not exist, quest will not have a spell reward.", - qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast); - qinfo->RewardSpellCast = 0; // no spell will be cast on player + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u does not exist, quest will not have a spell reward.", + qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell); + qinfo->RewardSpell = 0; // no spell will be cast on player } else if (!SpellMgr::IsSpellValid(spellInfo)) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpellCast` = %u but spell %u is broken, quest will not have a spell reward.", - qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast); - qinfo->RewardSpellCast = 0; // no spell will be cast on player + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is broken, quest will not have a spell reward.", + qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell); + qinfo->RewardSpell = 0; // no spell will be cast on player } - else if (GetTalentSpellCost(qinfo->RewardSpellCast)) + else if (GetTalentSpellCost(qinfo->RewardSpell)) { - TC_LOG_ERROR("sql.sql", "Quest %u has `RewardSpell` = %u but spell %u is talent, quest will not have a spell reward.", - qinfo->GetQuestId(), qinfo->RewardSpellCast, qinfo->RewardSpellCast); - qinfo->RewardSpellCast = 0; // no spell will be cast on player + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardDisplaySpell` = %u but spell %u is talent, quest will not have a spell reward.", + qinfo->GetQuestId(), qinfo->RewardSpell, qinfo->RewardSpell); + qinfo->RewardSpell = 0; // no spell will be cast on player } } @@ -4602,14 +4563,14 @@ void ObjectMgr::LoadQuests() usedMailTemplates[qinfo->RewardMailTemplateId] = qinfo->GetQuestId(); } - if (qinfo->NextQuestIdChain) + if (qinfo->RewardNextQuest) { - QuestMap::iterator qNextItr = _questTemplates.find(qinfo->NextQuestIdChain); + QuestMap::iterator qNextItr = _questTemplates.find(qinfo->RewardNextQuest); if (qNextItr == _questTemplates.end()) { - TC_LOG_ERROR("sql.sql", "Quest %u has `NextQuestIdChain` = %u but quest %u does not exist, quest chain will not work.", - qinfo->GetQuestId(), qinfo->NextQuestIdChain, qinfo->NextQuestIdChain); - qinfo->NextQuestIdChain = 0; + TC_LOG_ERROR("sql.sql", "Quest %u has `RewardNextQuest` = %u but quest %u does not exist, quest chain will not work.", + qinfo->GetQuestId(), qinfo->RewardNextQuest, qinfo->RewardNextQuest); + qinfo->RewardNextQuest = 0; } else qNextItr->second->prevChainQuests.push_back(qinfo->GetQuestId()); @@ -4644,7 +4605,7 @@ void ObjectMgr::LoadQuests() if (qinfo->ExclusiveGroup) mExclusiveQuestGroups.insert(std::pair<int32, uint32>(qinfo->ExclusiveGroup, qinfo->GetQuestId())); - if (qinfo->LimitTime) + if (qinfo->TimeAllowed) qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_TIMED); if (qinfo->RequiredPlayerKills) qinfo->SetSpecialFlag(QUEST_SPECIAL_FLAGS_PLAYER_KILL); @@ -4720,7 +4681,7 @@ void ObjectMgr::LoadQuestLocales() AddLocaleString(fields[1 + 11 * (i - 1) + 2].GetString(), locale, data.Objectives); AddLocaleString(fields[1 + 11 * (i - 1) + 3].GetString(), locale, data.OfferRewardText); AddLocaleString(fields[1 + 11 * (i - 1) + 4].GetString(), locale, data.RequestItemsText); - AddLocaleString(fields[1 + 11 * (i - 1) + 5].GetString(), locale, data.EndText); + AddLocaleString(fields[1 + 11 * (i - 1) + 5].GetString(), locale, data.AreaDescription); AddLocaleString(fields[1 + 11 * (i - 1) + 6].GetString(), locale, data.CompletedText); for (uint8 k = 0; k < 4; ++k) @@ -5090,13 +5051,13 @@ void ObjectMgr::LoadEventScripts() { for (size_t node_idx = 0; node_idx < sTaxiPathNodesByPath[path_idx].size(); ++node_idx) { - TaxiPathNodeEntry const& node = sTaxiPathNodesByPath[path_idx][node_idx]; + TaxiPathNodeEntry const* node = sTaxiPathNodesByPath[path_idx][node_idx]; - if (node.ArrivalEventID) - evt_scripts.insert(node.ArrivalEventID); + if (node->ArrivalEventID) + evt_scripts.insert(node->ArrivalEventID); - if (node.DepartureEventID) - evt_scripts.insert(node.DepartureEventID); + if (node->DepartureEventID) + evt_scripts.insert(node->DepartureEventID); } } @@ -5658,7 +5619,7 @@ void ObjectMgr::ReturnOrDeleteOldMails(bool serverUp) Player* player = NULL; if (serverUp) - player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HIGHGUID_PLAYER, m->receiver)); + player = ObjectAccessor::FindConnectedPlayer(ObjectGuid(HighGuid::Player, m->receiver)); if (player && player->m_mailsLoaded) { // this code will run very improbably (the time is between 4 and 5 am, in game is online a player, who has old mail @@ -6454,29 +6415,21 @@ void ObjectMgr::SetHighestGuids() { QueryResult result = CharacterDatabase.Query("SELECT MAX(guid) FROM characters"); if (result) - _hiCharGuid = (*result)[0].GetUInt32()+1; - - result = WorldDatabase.Query("SELECT MAX(guid) FROM creature"); - if (result) - _hiCreatureGuid = (*result)[0].GetUInt32()+1; + GetGuidSequenceGenerator<HighGuid::Player>().Set((*result)[0].GetUInt32()+1); result = CharacterDatabase.Query("SELECT MAX(guid) FROM item_instance"); if (result) - _hiItemGuid = (*result)[0].GetUInt32()+1; + GetGuidSequenceGenerator<HighGuid::Item>().Set((*result)[0].GetUInt32()+1); // Cleanup other tables from nonexistent guids ( >= _hiItemGuid) - CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", _hiItemGuid); // One-time query - CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", _hiItemGuid); // One-time query - CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", _hiItemGuid); // One-time query - CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", _hiItemGuid); // One-time query - - result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject"); - if (result) - _hiGoGuid = (*result)[0].GetUInt32()+1; + CharacterDatabase.PExecute("DELETE FROM character_inventory WHERE item >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query + CharacterDatabase.PExecute("DELETE FROM mail_items WHERE item_guid >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query + CharacterDatabase.PExecute("DELETE FROM auctionhouse WHERE itemguid >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query + CharacterDatabase.PExecute("DELETE FROM guild_bank_item WHERE item_guid >= '%u'", GetGuidSequenceGenerator<HighGuid::Item>().GetNextAfterMaxUsed()); // One-time query result = WorldDatabase.Query("SELECT MAX(guid) FROM transports"); if (result) - _hiMoTransGuid = (*result)[0].GetUInt32()+1; + GetGuidSequenceGenerator<HighGuid::Mo_Transport>().Set((*result)[0].GetUInt32()+1); result = CharacterDatabase.Query("SELECT MAX(id) FROM auctionhouse"); if (result) @@ -6486,10 +6439,6 @@ void ObjectMgr::SetHighestGuids() if (result) _mailId = (*result)[0].GetUInt32()+1; - result = CharacterDatabase.Query("SELECT MAX(corpseGuid) FROM corpse"); - if (result) - _hiCorpseGuid = (*result)[0].GetUInt32()+1; - result = CharacterDatabase.Query("SELECT MAX(arenateamid) FROM arena_team"); if (result) sArenaTeamMgr->SetNextArenaTeamId((*result)[0].GetUInt32()+1); @@ -6505,6 +6454,14 @@ void ObjectMgr::SetHighestGuids() result = CharacterDatabase.Query("SELECT MAX(guid) FROM groups"); if (result) sGroupMgr->SetGroupDbStoreSize((*result)[0].GetUInt32()+1); + + result = WorldDatabase.Query("SELECT MAX(guid) FROM creature"); + if (result) + _creatureSpawnId = (*result)[0].GetUInt32() + 1; + + result = WorldDatabase.Query("SELECT MAX(guid) FROM gameobject"); + if (result) + _gameObjectSpawnId = (*result)[0].GetUInt32() + 1; } uint32 ObjectMgr::GenerateAuctionID() @@ -6537,59 +6494,29 @@ uint32 ObjectMgr::GenerateMailID() return _mailId++; } -uint32 ObjectMgr::GenerateLowGuid(HighGuid guidhigh) +uint32 ObjectMgr::GeneratePetNumber() { - switch (guidhigh) + return ++_hiPetNumber; +} + +uint32 ObjectMgr::GenerateCreatureSpawnId() +{ + if (_creatureSpawnId >= uint32(0xFFFFFF)) { - case HIGHGUID_ITEM: - { - ASSERT(_hiItemGuid < 0xFFFFFFFE && "Item guid overflow!"); - return _hiItemGuid++; - } - case HIGHGUID_UNIT: - { - ASSERT(_hiCreatureGuid < 0x00FFFFFE && "Creature guid overflow!"); - return _hiCreatureGuid++; - } - case HIGHGUID_PET: - { - ASSERT(_hiPetGuid < 0x00FFFFFE && "Pet guid overflow!"); - return _hiPetGuid++; - } - case HIGHGUID_VEHICLE: - { - ASSERT(_hiVehicleGuid < 0x00FFFFFF && "Vehicle guid overflow!"); - return _hiVehicleGuid++; - } - case HIGHGUID_PLAYER: - { - ASSERT(_hiCharGuid < 0xFFFFFFFE && "Player guid overflow!"); - return _hiCharGuid++; - } - case HIGHGUID_GAMEOBJECT: - { - ASSERT(_hiGoGuid < 0x00FFFFFE && "Gameobject guid overflow!"); - return _hiGoGuid++; - } - case HIGHGUID_CORPSE: - { - ASSERT(_hiCorpseGuid < 0xFFFFFFFE && "Corpse guid overflow!"); - return _hiCorpseGuid++; - } - case HIGHGUID_DYNAMICOBJECT: - { - ASSERT(_hiDoGuid < 0xFFFFFFFE && "DynamicObject guid overflow!"); - return _hiDoGuid++; - } - case HIGHGUID_MO_TRANSPORT: - { - ASSERT(_hiMoTransGuid < 0xFFFFFFFE && "MO Transport guid overflow!"); - return _hiMoTransGuid++; - } - default: - ASSERT(false && "ObjectMgr::GenerateLowGuid - Unknown HIGHGUID type"); - return 0; + TC_LOG_ERROR("misc", "Creature spawn id overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); + } + return _creatureSpawnId++; +} + +uint32 ObjectMgr::GenerateGameObjectSpawnId() +{ + if (_gameObjectSpawnId >= uint32(0xFFFFFF)) + { + TC_LOG_ERROR("misc", "Creature spawn id overflow!! Can't continue, shutting down server. "); + World::StopNow(ERROR_EXIT_CODE); } + return _gameObjectSpawnId++; } void ObjectMgr::LoadGameObjectLocales() @@ -6973,49 +6900,6 @@ std::string ObjectMgr::GeneratePetName(uint32 entry) return *(list0.begin()+urand(0, list0.size()-1)) + *(list1.begin()+urand(0, list1.size()-1)); } -uint32 ObjectMgr::GeneratePetNumber() -{ - return ++_hiPetNumber; -} - -void ObjectMgr::LoadCorpses() -{ - uint32 oldMSTime = getMSTime(); - - PreparedQueryResult result = CharacterDatabase.Query(CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES)); - if (!result) - { - TC_LOG_INFO("server.loading", ">> Loaded 0 corpses. DB table `corpse` is empty."); - return; - } - - uint32 count = 0; - do - { - Field* fields = result->Fetch(); - uint32 guid = fields[16].GetUInt32(); - CorpseType type = CorpseType(fields[13].GetUInt8()); - if (type >= MAX_CORPSE_TYPE) - { - TC_LOG_ERROR("misc", "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type); - continue; - } - - Corpse* corpse = new Corpse(type); - if (!corpse->LoadCorpseFromDB(guid, fields)) - { - delete corpse; - continue; - } - - sObjectAccessor->AddCorpse(corpse); - ++count; - } - while (result->NextRow()); - - TC_LOG_INFO("server.loading", ">> Loaded %u corpses in %u ms", count, GetMSTimeDiffToNow(oldMSTime)); -} - void ObjectMgr::LoadReputationRewardRate() { uint32 oldMSTime = getMSTime(); @@ -7474,20 +7358,6 @@ void ObjectMgr::DeleteGOData(uint32 guid) _gameObjectDataStore.erase(guid); } -void ObjectMgr::AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance) -{ - // corpses are always added to spawn mode 0 and they are spawned by their instance id - CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(mapid, 0)][cellid]; - cell_guids.corpses[player_guid] = instance; -} - -void ObjectMgr::DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid) -{ - // corpses are always added to spawn mode 0 and they are spawned by their instance id - CellObjectGuids& cell_guids = _mapObjectGuidsStore[MAKE_PAIR32(mapid, 0)][cellid]; - cell_guids.corpses.erase(player_guid); -} - void ObjectMgr::LoadQuestRelationsHelper(QuestRelations& map, QuestRelationsReverse* reverseMap, std::string const& table, bool starter, bool go) { uint32 oldMSTime = getMSTime(); @@ -8706,7 +8576,7 @@ void ObjectMgr::LoadScriptNames() do { - _scriptNamesStore.emplace_back((*result)[0].GetCString()); + _scriptNamesStore.push_back((*result)[0].GetString()); } while (result->NextRow()); @@ -9187,7 +9057,7 @@ VehicleAccessoryList const* ObjectMgr::GetVehicleAccessoryList(Vehicle* veh) con if (Creature* cre = veh->GetBase()->ToCreature()) { // Give preference to GUID-based accessories - VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetDBTableGUIDLow()); + VehicleAccessoryContainer::const_iterator itr = _vehicleAccessoryStore.find(cre->GetSpawnId()); if (itr != _vehicleAccessoryStore.end()) return &itr->second; } diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index 26f3ba7cff3..462370001dd 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -36,12 +36,14 @@ #include "ObjectAccessor.h" #include "ObjectDefines.h" #include "VehicleDefines.h" +#include "ConditionMgr.h" +#include "DBCStores.h" #include <string> #include <tuple> #include <map> #include <limits> -#include "ConditionMgr.h" #include <functional> +#include <memory> class Item; struct AccessRequirement; @@ -443,13 +445,11 @@ struct BroadcastText typedef std::unordered_map<uint32, BroadcastText> BroadcastTextContainer; -typedef std::set<uint32> CellGuidSet; -typedef std::map<uint32/*player guid*/, uint32/*instance*/> CellCorpseSet; +typedef std::set<ObjectGuid::LowType> CellGuidSet; struct CellObjectGuids { CellGuidSet creatures; CellGuidSet gameobjects; - CellCorpseSet corpses; }; typedef std::unordered_map<uint32/*cell_id*/, CellObjectGuids> CellObjectGuidsMap; typedef std::unordered_map<uint32/*(mapid, spawnMode) pair*/, CellObjectGuidsMap> MapObjectGuids; @@ -1023,7 +1023,6 @@ class ObjectMgr void LoadExplorationBaseXP(); void LoadPetNames(); void LoadPetNumber(); - void LoadCorpses(); void LoadFishingBaseSkillLevel(); void LoadReputationRewardRate(); @@ -1059,11 +1058,20 @@ class ObjectMgr CreatureBaseStats const* GetCreatureBaseStats(uint8 level, uint8 unitClass); void SetHighestGuids(); - uint32 GenerateLowGuid(HighGuid guidhigh); + + template<HighGuid type> + inline ObjectGuidGeneratorBase& GetGenerator() + { + static_assert(ObjectGuidTraits<type>::Global, "Only global guid can be generated in ObjectMgr context"); + return GetGuidSequenceGenerator<type>(); + } + uint32 GenerateAuctionID(); uint64 GenerateEquipmentSetGuid(); uint32 GenerateMailID(); uint32 GeneratePetNumber(); + uint32 GenerateCreatureSpawnId(); + uint32 GenerateGameObjectSpawnId(); typedef std::multimap<int32, uint32> ExclusiveQuestGroups; typedef std::pair<ExclusiveQuestGroups::const_iterator, ExclusiveQuestGroups::const_iterator> ExclusiveQuestGroupsBounds; @@ -1209,9 +1217,6 @@ class ObjectMgr LocaleConstant GetDBCLocaleIndex() const { return DBCLocaleIndex; } void SetDBCLocaleIndex(LocaleConstant locale) { DBCLocaleIndex = locale; } - void AddCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid, uint32 instance); - void DeleteCorpseCellData(uint32 mapid, uint32 cellid, uint32 player_guid); - // grid objects void AddCreatureToGrid(uint32 guid, CreatureData const* data); void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data); @@ -1219,7 +1224,6 @@ class ObjectMgr void RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data); uint32 AddGOData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0); uint32 AddCreatureData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0); - bool MoveCreatureData(uint32 guid, uint32 map, const Position& pos); // reserved names void LoadReservedPlayersNames(); @@ -1327,17 +1331,21 @@ class ObjectMgr uint32 _mailId; uint32 _hiPetNumber; + uint32 _creatureSpawnId; + uint32 _gameObjectSpawnId; + // first free low guid for selected guid type - uint32 _hiCharGuid; - uint32 _hiCreatureGuid; - uint32 _hiPetGuid; - uint32 _hiVehicleGuid; - uint32 _hiItemGuid; - uint32 _hiGoGuid; - uint32 _hiDoGuid; - uint32 _hiCorpseGuid; - uint32 _hiMoTransGuid; + template<HighGuid high> + inline ObjectGuidGeneratorBase& GetGuidSequenceGenerator() + { + auto itr = _guidGenerators.find(high); + if (itr == _guidGenerators.end()) + itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first; + + return *itr->second; + } + std::map<HighGuid, std::unique_ptr<ObjectGuidGeneratorBase>> _guidGenerators; QuestMap _questTemplates; typedef std::unordered_map<uint32, GossipText> GossipTextContainer; diff --git a/src/server/game/Grids/GridDefines.h b/src/server/game/Grids/GridDefines.h index 28670ad4968..8eae906ba87 100644 --- a/src/server/game/Grids/GridDefines.h +++ b/src/server/game/Grids/GridDefines.h @@ -20,6 +20,7 @@ #define TRINITY_GRIDDEFINES_H #include "Common.h" +#include "ObjectGuid.h" #include "NGrid.h" #include <cmath> @@ -58,6 +59,7 @@ class Player; // Creature used instead pet to simplify *::Visit templates (not required duplicate code for Creature->Pet case) typedef TYPELIST_4(Player, Creature/*pets*/, Corpse/*resurrectable*/, DynamicObject/*farsight target*/) AllWorldObjectTypes; typedef TYPELIST_4(GameObject, Creature/*except pets*/, DynamicObject, Corpse/*Bones*/) AllGridObjectTypes; +typedef TYPELIST_5(Creature, GameObject, DynamicObject, Pet, Corpse) AllMapStoredObjectTypes; typedef GridRefManager<Corpse> CorpseMapType; typedef GridRefManager<Creature> CreatureMapType; @@ -80,6 +82,7 @@ typedef NGrid<MAX_NUMBER_OF_CELLS, Player, AllWorldObjectTypes, AllGridObjectTyp typedef TypeMapContainer<AllGridObjectTypes> GridTypeMapContainer; typedef TypeMapContainer<AllWorldObjectTypes> WorldTypeMapContainer; +typedef TypeUnorderedMapContainer<AllMapStoredObjectTypes, ObjectGuid> MapStoredObjectTypesContainer; template<uint32 LIMIT> struct CoordPair diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index 16e36d98d33..c2f5f75f98e 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -722,18 +722,6 @@ namespace Trinity NearestGameObjectTypeInObjectRangeCheck(NearestGameObjectTypeInObjectRangeCheck const&); }; - class GameObjectWithDbGUIDCheck - { - public: - GameObjectWithDbGUIDCheck(WorldObject const& /*obj*/, uint32 db_guid) : i_db_guid(db_guid) { } - bool operator()(GameObject const* go) const - { - return go->GetDBTableGUIDLow() == i_db_guid; - } - private: - uint32 i_db_guid; - }; - // Unit checks class MostHPMissingInRange @@ -835,18 +823,6 @@ namespace Trinity float i_range; }; - class CreatureWithDbGUIDCheck - { - public: - CreatureWithDbGUIDCheck(WorldObject const* /*obj*/, uint32 lowguid) : i_lowguid(lowguid) { } - bool operator()(Creature* u) - { - return u->GetDBTableGUIDLow() == i_lowguid; - } - private: - uint32 i_lowguid; - }; - class AnyFriendlyUnitInObjectRangeCheck { public: diff --git a/src/server/game/Grids/ObjectGridLoader.cpp b/src/server/game/Grids/ObjectGridLoader.cpp index c7e1056a3ef..de0ab490e9c 100644 --- a/src/server/game/Grids/ObjectGridLoader.cpp +++ b/src/server/game/Grids/ObjectGridLoader.cpp @@ -62,7 +62,7 @@ class ObjectWorldLoader { public: explicit ObjectWorldLoader(ObjectGridLoader& gloader) - : i_cell(gloader.i_cell), i_map(gloader.i_map), i_corpses (0) + : i_cell(gloader.i_cell), i_map(gloader.i_map), i_grid(gloader.i_grid), i_corpses(gloader.i_corpses) { } void Visit(CorpseMapType &m); @@ -72,8 +72,9 @@ class ObjectWorldLoader private: Cell i_cell; Map* i_map; + NGridType& i_grid; public: - uint32 i_corpses; + uint32& i_corpses; }; template<class T> void ObjectGridLoader::SetObjectCell(T* /*obj*/, CellCoord const& /*cellCoord*/) { } @@ -129,38 +130,6 @@ void LoadHelper(CellGuidSet const& guid_set, CellCoord &cell, GridRefManager<T> } } -void LoadHelper(CellCorpseSet const& cell_corpses, CellCoord &cell, CorpseMapType &m, uint32 &count, Map* map) -{ - if (cell_corpses.empty()) - return; - - for (CellCorpseSet::const_iterator itr = cell_corpses.begin(); itr != cell_corpses.end(); ++itr) - { - if (itr->second != map->GetInstanceId()) - continue; - - ObjectGuid player_guid(HIGHGUID_PLAYER, itr->first); - - Corpse* obj = sObjectAccessor->GetCorpseForPlayerGUID(player_guid); - if (!obj) - continue; - - /// @todo this is a hack - // corpse's map should be reset when the map is unloaded - // but it may still exist when the grid is unloaded but map is not - // in that case map == currMap - obj->SetMap(map); - - if (obj->IsInGrid()) - { - obj->AddToWorld(); - continue; - } - - AddObjectHelper(cell, m, count, map, obj); - } -} - void ObjectGridLoader::Visit(GameObjectMapType &m) { CellCoord cellCoord = i_cell.GetCellCoord(); @@ -175,22 +144,28 @@ void ObjectGridLoader::Visit(CreatureMapType &m) LoadHelper(cell_guids.creatures, cellCoord, m, i_creatures, i_map); } -void ObjectWorldLoader::Visit(CorpseMapType &m) +void ObjectWorldLoader::Visit(CorpseMapType& /*m*/) { CellCoord cellCoord = i_cell.GetCellCoord(); - // corpses are always added to spawn mode 0 and they are spawned by their instance id - CellObjectGuids const& cell_guids = sObjectMgr->GetCellObjectGuids(i_map->GetId(), 0, cellCoord.GetId()); - LoadHelper(cell_guids.corpses, cellCoord, m, i_corpses, i_map); + if (std::unordered_set<Corpse*> const* corpses = i_map->GetCorpsesInCell(cellCoord.GetId())) + { + for (Corpse* corpse : *corpses) + { + corpse->AddToWorld(); + i_grid.GetGridType(i_cell.CellX(), i_cell.CellY()).AddWorldObject(corpse); + ++i_corpses; + } + } } void ObjectGridLoader::LoadN(void) { i_gameObjects = 0; i_creatures = 0; i_corpses = 0; i_cell.data.Part.cell_y = 0; - for (unsigned int x=0; x < MAX_NUMBER_OF_CELLS; ++x) + for (uint32 x = 0; x < MAX_NUMBER_OF_CELLS; ++x) { i_cell.data.Part.cell_x = x; - for (unsigned int y=0; y < MAX_NUMBER_OF_CELLS; ++y) + for (uint32 y = 0; y < MAX_NUMBER_OF_CELLS; ++y) { i_cell.data.Part.cell_y = y; @@ -205,7 +180,6 @@ void ObjectGridLoader::LoadN(void) ObjectWorldLoader worker(*this); TypeContainerVisitor<ObjectWorldLoader, WorldTypeMapContainer> visitor(worker); i_grid.VisitGrid(x, y, visitor); - i_corpses += worker.i_corpses; } } } diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 7e3b758d92c..cc9ef29a8e8 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -93,7 +93,7 @@ bool Group::Create(Player* leader) ObjectGuid leaderGuid = leader->GetGUID(); uint32 lowguid = sGroupMgr->GenerateGroupId(); - m_guid = ObjectGuid(HIGHGUID_GROUP, lowguid); + m_guid = ObjectGuid(HighGuid::Group, lowguid); m_leaderGuid = leaderGuid; m_leaderName = leader->GetName(); leader->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_GROUP_LEADER); @@ -162,15 +162,15 @@ bool Group::Create(Player* leader) void Group::LoadGroupFromDB(Field* fields) { m_dbStoreId = fields[16].GetUInt32(); - m_guid = ObjectGuid(HIGHGUID_GROUP, sGroupMgr->GenerateGroupId()); - m_leaderGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); + m_guid = ObjectGuid(HighGuid::Group, sGroupMgr->GenerateGroupId()); + m_leaderGuid = ObjectGuid(HighGuid::Player, fields[0].GetUInt32()); // group leader not exist if (!sObjectMgr->GetPlayerNameByGUID(m_leaderGuid, m_leaderName)) return; m_lootMethod = LootMethod(fields[1].GetUInt8()); - m_looterGuid = ObjectGuid(HIGHGUID_PLAYER, fields[2].GetUInt32()); + m_looterGuid = ObjectGuid(HighGuid::Player, fields[2].GetUInt32()); m_lootThreshold = ItemQualities(fields[3].GetUInt8()); for (uint8 i = 0; i < TARGETICONCOUNT; ++i) @@ -192,7 +192,7 @@ void Group::LoadGroupFromDB(Field* fields) else m_raidDifficulty = Difficulty(r_diff); - m_masterLooterGuid = ObjectGuid(HIGHGUID_PLAYER, fields[15].GetUInt32()); + m_masterLooterGuid = ObjectGuid(HighGuid::Player, fields[15].GetUInt32()); if (m_groupType & GROUPTYPE_LFG) sLFGMgr->_LoadFromDB(fields, GetGUID()); @@ -201,7 +201,7 @@ void Group::LoadGroupFromDB(Field* fields) void Group::LoadMemberFromDB(uint32 guidLow, uint8 memberFlags, uint8 subgroup, uint8 roles) { MemberSlot member; - member.guid = ObjectGuid(HIGHGUID_PLAYER, guidLow); + member.guid = ObjectGuid(HighGuid::Player, guidLow); // skip non-existed member if (!sObjectMgr->GetPlayerNameByGUID(member.guid, member.name)) @@ -659,7 +659,7 @@ void Group::ChangeLeader(ObjectGuid newLeaderGuid) // Update the group leader PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_GROUP_LEADER); - stmt->setUInt32(0, newLeader->GetGUIDLow()); + stmt->setUInt32(0, newLeader->GetGUID().GetCounter()); stmt->setUInt32(1, m_dbStoreId); trans->Append(stmt); @@ -925,7 +925,8 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) //roll for over-threshold item if it's one-player loot if (item->Quality >= uint32(m_lootThreshold)) { - ObjectGuid newitemGUID = ObjectGuid(HIGHGUID_ITEM, sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM)); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); + Roll* r = new Roll(newitemGUID, *i); //a vector is filled with only near party members @@ -1009,7 +1010,8 @@ void Group::GroupLoot(Loot* loot, WorldObject* pLootedObject) continue; } - ObjectGuid newitemGUID = ObjectGuid(HIGHGUID_ITEM, sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM)); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); + Roll* r = new Roll(newitemGUID, *i); //a vector is filled with only near party members @@ -1070,7 +1072,8 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) //roll for over-threshold item if it's one-player loot if (item->Quality >= uint32(m_lootThreshold)) { - ObjectGuid newitemGUID = ObjectGuid(HIGHGUID_ITEM, sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM)); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); + Roll* r = new Roll(newitemGUID, *i); for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) @@ -1145,7 +1148,8 @@ void Group::NeedBeforeGreed(Loot* loot, WorldObject* lootedObject) continue; item = sObjectMgr->GetItemTemplate(i->itemid); - ObjectGuid newitemGUID = ObjectGuid(HIGHGUID_ITEM, sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM)); + ObjectGuid newitemGUID = ObjectGuid::Create<HighGuid::Item>(sObjectMgr->GetGenerator<HighGuid::Item>().Generate()); + Roll* r = new Roll(newitemGUID, *i); for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 04eb99b3097..fab22b30f47 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -194,10 +194,10 @@ void Guild::EventLogEntry::WritePacket(WorldPacket& data) const // Event type data << uint8(m_eventType); // Player 1 - data << ObjectGuid(HIGHGUID_PLAYER, m_playerGuid1); + data << ObjectGuid(HighGuid::Player, m_playerGuid1); // Player 2 not for left/join guild events if (m_eventType != GUILD_EVENT_LOG_JOIN_GUILD && m_eventType != GUILD_EVENT_LOG_LEAVE_GUILD) - data << ObjectGuid(HIGHGUID_PLAYER, m_playerGuid2); + data << ObjectGuid(HighGuid::Player, m_playerGuid2); // New Rank - only for promote/demote guild events if (m_eventType == GUILD_EVENT_LOG_PROMOTE_PLAYER || m_eventType == GUILD_EVENT_LOG_DEMOTE_PLAYER) data << uint8(m_newRank); @@ -233,7 +233,7 @@ void Guild::BankEventLogEntry::SaveToDB(SQLTransaction& trans) const void Guild::BankEventLogEntry::WritePacket(WorldPacket& data) const { data << uint8(m_eventType); - data << ObjectGuid(HIGHGUID_PLAYER, m_playerGuid); + data << ObjectGuid(HighGuid::Player, m_playerGuid); switch (m_eventType) { @@ -554,7 +554,7 @@ bool Guild::BankTab::SetItem(SQLTransaction& trans, uint8 slotId, Item* item) stmt->setUInt32(0, m_guildId); stmt->setUInt8 (1, m_tabId); stmt->setUInt8 (2, slotId); - stmt->setUInt32(3, item->GetGUIDLow()); + stmt->setUInt32(3, item->GetGUID().GetCounter()); CharacterDatabase.ExecuteOrAppend(trans, stmt); item->SetGuidValue(ITEM_FIELD_CONTAINED, ObjectGuid::Empty); @@ -893,7 +893,7 @@ void Guild::PlayerMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData { ASSERT(pFrom); // Bank -> Char - m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUIDLow(), + m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_WITHDRAW_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUID().GetCounter(), pFrom->GetItem()->GetEntry(), count); } @@ -978,11 +978,11 @@ void Guild::BankMoveItemData::LogBankEvent(SQLTransaction& trans, MoveItemData* ASSERT(pFrom->GetItem()); if (pFrom->IsBank()) // Bank -> Bank - m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUIDLow(), + m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_MOVE_ITEM, pFrom->GetContainer(), m_pPlayer->GetGUID().GetCounter(), pFrom->GetItem()->GetEntry(), count, m_container); else // Char -> Bank - m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, m_container, m_pPlayer->GetGUIDLow(), + m_pGuild->_LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_ITEM, m_container, m_pPlayer->GetGUID().GetCounter(), pFrom->GetItem()->GetEntry(), count); } @@ -993,7 +993,7 @@ void Guild::BankMoveItemData::LogAction(MoveItemData* pFrom) const { sLog->outCommand(m_pPlayer->GetSession()->GetAccountId(), "GM %s (Guid: %u) (Account: %u) deposit item: %s (Entry: %d Count: %u) to guild bank named: %s (Guild ID: %u)", - m_pPlayer->GetName().c_str(), m_pPlayer->GetGUIDLow(), m_pPlayer->GetSession()->GetAccountId(), + m_pPlayer->GetName().c_str(), m_pPlayer->GetGUID().GetCounter(), m_pPlayer->GetSession()->GetAccountId(), pFrom->GetItem()->GetTemplate()->Name1.c_str(), pFrom->GetItem()->GetEntry(), pFrom->GetItem()->GetCount(), m_pGuild->GetName().c_str(), m_pGuild->GetId()); } @@ -1522,7 +1522,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) Player* player = session->GetPlayer(); // Do not show invitations from ignored players - if (pInvitee->GetSocial()->HasIgnore(player->GetGUIDLow())) + if (pInvitee->GetSocial()->HasIgnore(player->GetGUID().GetCounter())) return; if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && pInvitee->GetTeam() != player->GetTeam()) @@ -1554,7 +1554,7 @@ void Guild::HandleInviteMember(WorldSession* session, std::string const& name) TC_LOG_DEBUG("guild", "Player %s invited %s to join his Guild", player->GetName().c_str(), name.c_str()); pInvitee->SetGuildIdInvited(m_id); - _LogEvent(GUILD_EVENT_LOG_INVITE_PLAYER, player->GetGUIDLow(), pInvitee->GetGUIDLow()); + _LogEvent(GUILD_EVENT_LOG_INVITE_PLAYER, player->GetGUID().GetCounter(), pInvitee->GetGUID().GetCounter()); WorldPacket data(SMSG_GUILD_INVITE, 8 + 10); // Guess size data << player->GetName(); @@ -1595,7 +1595,7 @@ void Guild::HandleLeaveMember(WorldSession* session) { DeleteMember(player->GetGUID(), false, false); - _LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUIDLow()); + _LogEvent(GUILD_EVENT_LOG_LEAVE_GUILD, player->GetGUID().GetCounter()); _BroadcastEvent(GE_LEFT, player->GetGUID(), player->GetName().c_str()); SendCommandResult(session, GUILD_COMMAND_QUIT, ERR_GUILD_COMMAND_SUCCESS, m_name); @@ -1629,7 +1629,7 @@ void Guild::HandleRemoveMember(WorldSession* session, std::string const& name) ObjectGuid guid = member->GetGUID(); // After call to DeleteMember pointer to member becomes invalid DeleteMember(guid, false, true); - _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUIDLow(), guid.GetCounter()); + _LogEvent(GUILD_EVENT_LOG_UNINVITE_PLAYER, player->GetGUID().GetCounter(), guid.GetCounter()); _BroadcastEvent(GE_REMOVED, ObjectGuid::Empty, name.c_str(), player->GetName().c_str()); } } @@ -1683,7 +1683,7 @@ void Guild::HandleUpdateMemberRank(WorldSession* session, std::string const& nam uint32 newRankId = member->GetRankId() + (demote ? 1 : -1); member->ChangeRank(newRankId); - _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUIDLow(), member->GetGUID().GetCounter(), newRankId); + _LogEvent(demote ? GUILD_EVENT_LOG_DEMOTE_PLAYER : GUILD_EVENT_LOG_PROMOTE_PLAYER, player->GetGUID().GetCounter(), member->GetGUID().GetCounter(), newRankId); _BroadcastEvent(demote ? GE_DEMOTION : GE_PROMOTION, ObjectGuid::Empty, player->GetName().c_str(), name.c_str(), _GetRankName(newRankId).c_str()); } } @@ -1743,7 +1743,7 @@ void Guild::HandleMemberDepositMoney(WorldSession* session, uint32 amount) player->ModifyMoney(-int32(amount)); player->SaveGoldToDB(trans); - _LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUIDLow(), amount); + _LogBankEvent(trans, GUILD_BANK_LOG_DEPOSIT_MONEY, uint8(0), player->GetGUID().GetCounter(), amount); CharacterDatabase.CommitTransaction(trans); @@ -1794,7 +1794,7 @@ bool Guild::HandleMemberWithdrawMoney(WorldSession* session, uint32 amount, bool _ModifyBankMoney(trans, amount, false); // Log guild bank event - _LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUIDLow(), amount); + _LogBankEvent(trans, repair ? GUILD_BANK_LOG_REPAIR_MONEY : GUILD_BANK_LOG_WITHDRAW_MONEY, uint8(0), player->GetGUID().GetCounter(), amount); CharacterDatabase.CommitTransaction(trans); std::string aux = ByteArrayToHexStr(reinterpret_cast<uint8*>(&m_bankMoney), 8, true); @@ -1942,7 +1942,7 @@ bool Guild::LoadFromDB(Field* fields) { m_id = fields[0].GetUInt32(); m_name = fields[1].GetString(); - m_leaderGuid = ObjectGuid(HIGHGUID_PLAYER, fields[2].GetUInt32()); + m_leaderGuid = ObjectGuid(HighGuid::Player, fields[2].GetUInt32()); m_emblemInfo.LoadFromDB(fields); m_info = fields[8].GetString(); m_motd = fields[9].GetString(); @@ -1973,7 +1973,7 @@ void Guild::LoadRankFromDB(Field* fields) bool Guild::LoadMemberFromDB(Field* fields) { uint32 lowguid = fields[1].GetUInt32(); - Member *member = new Member(m_id, ObjectGuid(HIGHGUID_PLAYER, lowguid), fields[2].GetUInt8()); + Member *member = new Member(m_id, ObjectGuid(HighGuid::Player, lowguid), fields[2].GetUInt8()); if (!member->LoadFromDB(fields)) { _DeleteMemberFromDB(lowguid); @@ -2152,7 +2152,7 @@ void Guild::BroadcastToGuild(WorldSession* session, bool officerOnly, std::strin for (Members::const_iterator itr = m_members.begin(); itr != m_members.end(); ++itr) if (Player* player = itr->second->FindConnectedPlayer()) if (player->GetSession() && _HasRankRight(player, officerOnly ? GR_RIGHT_OFFCHATLISTEN : GR_RIGHT_GCHATLISTEN) && - !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUIDLow())) + !player->GetSocial()->HasIgnore(session->GetPlayer()->GetGUID().GetCounter())) player->GetSession()->SendPacket(&data); } } @@ -2692,7 +2692,7 @@ void Guild::_MoveItems(MoveItemData* pSrc, MoveItemData* pDest, uint32 splitedAm if (pItemSrc->GetCount() == 0) { TC_LOG_FATAL("guild", "Guild::SwapItems: Player %s(GUIDLow: %u) tried to move item %u from tab %u slot %u to tab %u slot %u, but item %u has a stack of zero!", - player->GetName(), player->GetGUIDLow(), pItemSrc->GetEntry(), tabId, slotId, destTabId, destSlotId, pItemSrc->GetEntry()); + player->GetName(), player->GetGUID().GetCounter(), pItemSrc->GetEntry(), tabId, slotId, destTabId, destSlotId, pItemSrc->GetEntry()); //return; // Commented out for now, uncomment when it's verified that this causes a crash!! } // */ diff --git a/src/server/game/Handlers/ArenaTeamHandler.cpp b/src/server/game/Handlers/ArenaTeamHandler.cpp index ead05033a35..5616eb89b07 100644 --- a/src/server/game/Handlers/ArenaTeamHandler.cpp +++ b/src/server/game/Handlers/ArenaTeamHandler.cpp @@ -125,7 +125,7 @@ void WorldSession::HandleArenaTeamInviteOpcode(WorldPacket& recvData) } // OK result but don't send invite - if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID().GetCounter())) return; if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD) && player->GetTeam() != GetPlayer()->GetTeam()) diff --git a/src/server/game/Handlers/AuctionHouseHandler.cpp b/src/server/game/Handlers/AuctionHouseHandler.cpp index 8ee14d6baa9..0293901c9e3 100644 --- a/src/server/game/Handlers/AuctionHouseHandler.cpp +++ b/src/server/game/Handlers/AuctionHouseHandler.cpp @@ -149,12 +149,11 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) if (bid > MAX_MONEY_AMOUNT || buyout > MAX_MONEY_AMOUNT) { - TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "WORLD: HandleAuctionSellItem - Player %s (GUID %u) attempted to sell item with higher price than max gold amount.", _player->GetName().c_str(), _player->GetGUID().GetCounter()); SendAuctionCommandResult(0, AUCTION_SELL_ITEM, ERR_AUCTION_DATABASE_ERROR); return; } - Creature* creature = GetPlayer()->GetNPCIfCanInteractWith(auctioneer, UNIT_NPC_FLAG_AUCTIONEER); if (!creature) { @@ -202,7 +201,7 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) if (itemEntry == 0) itemEntry = item->GetTemplate()->ItemId; - if (sAuctionMgr->GetAItem(item->GetGUIDLow()) || !item->CanBeTraded() || item->IsNotEmptyBag() || + if (sAuctionMgr->GetAItem(item->GetGUID().GetCounter()) || !item->CanBeTraded() || item->IsNotEmptyBag() || item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION) || item->GetCount() < count[i] || itemEntry != item->GetTemplate()->ItemId) { @@ -259,9 +258,26 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AuctionEntry* AH = new AuctionEntry(); if (sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_AUCTION)) - AH->auctioneer = 23442; ///@TODO - HARDCODED DB GUID, BAD BAD BAD + AH->houseId = AUCTIONHOUSE_NEUTRAL; else - AH->auctioneer = auctioneer.GetCounter(); + { + CreatureData const* auctioneerData = sObjectMgr->GetCreatureData(creature->GetSpawnId()); + if (!auctioneerData) + { + TC_LOG_ERROR("misc", "Data for auctioneer not found (%s)", auctioneer.ToString().c_str()); + return; + } + + CreatureTemplate const* auctioneerInfo = sObjectMgr->GetCreatureTemplate(auctioneerData->id); + if (!auctioneerInfo) + { + TC_LOG_ERROR("misc", "Non existing auctioneer (%s)", auctioneer.ToString().c_str()); + return; + } + + const AuctionHouseEntry* AHEntry = sAuctionMgr->GetAuctionHouseEntry(auctioneerInfo->faction); + AH->houseId = AHEntry->houseId; + } // Required stack size of auction matches to current item stack size, just move item to auctionhouse if (itemsCount == 1 && item->GetCount() == count[0]) @@ -273,10 +289,10 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } AH->Id = sObjectMgr->GenerateAuctionID(); - AH->itemGUIDLow = item->GetGUIDLow(); + AH->itemGUIDLow = item->GetGUID().GetCounter(); AH->itemEntry = item->GetEntry(); AH->itemCount = item->GetCount(); - AH->owner = _player->GetGUIDLow(); + AH->owner = _player->GetGUID().GetCounter(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; @@ -285,8 +301,8 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; - TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", - _player->GetName().c_str(), _player->GetGUIDLow(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUIDLow(), AH->auctioneer, item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); + TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", + _player->GetName().c_str(), _player->GetGUID().GetCounter(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetGUID().GetCounter(), item->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(item); auctionHouse->AddAuction(AH); @@ -321,10 +337,10 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) } AH->Id = sObjectMgr->GenerateAuctionID(); - AH->itemGUIDLow = newItem->GetGUIDLow(); + AH->itemGUIDLow = newItem->GetGUID().GetCounter(); AH->itemEntry = newItem->GetEntry(); AH->itemCount = newItem->GetCount(); - AH->owner = _player->GetGUIDLow(); + AH->owner = _player->GetGUID().GetCounter(); AH->startbid = bid; AH->bidder = 0; AH->bid = 0; @@ -333,8 +349,8 @@ void WorldSession::HandleAuctionSellItem(WorldPacket& recvData) AH->deposit = deposit; AH->auctionHouseEntry = auctionHouseEntry; - TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) to auctioneer %u with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", - _player->GetName().c_str(), _player->GetGUIDLow(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUIDLow(), AH->auctioneer, newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); + TC_LOG_INFO("network", "CMSG_AUCTION_SELL_ITEM: Player %s (guid %d) is selling item %s entry %u (guid %d) with count %u with initial bid %u with buyout %u and with time %u (in sec) in auctionhouse %u", + _player->GetName().c_str(), _player->GetGUID().GetCounter(), newItem->GetTemplate()->Name1.c_str(), newItem->GetEntry(), newItem->GetGUID().GetCounter(), newItem->GetCount(), bid, buyout, auctionTime, AH->GetHouseId()); sAuctionMgr->AddAItem(newItem); auctionHouse->AddAuction(AH); @@ -410,7 +426,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) AuctionEntry* auction = auctionHouse->GetAuction(auctionId); Player* player = GetPlayer(); - if (!auction || auction->owner == player->GetGUIDLow()) + if (!auction || auction->owner == player->GetGUID().GetCounter()) { //you cannot bid your own auction: SendAuctionCommandResult(0, AUCTION_PLACE_BID, ERR_AUCTION_BID_OWN); @@ -418,7 +434,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) } // impossible have online own another character (use this for speedup check in case online owner) - ObjectGuid ownerGuid(HIGHGUID_PLAYER, auction->owner); + ObjectGuid ownerGuid(HighGuid::Player, auction->owner); Player* auction_owner = ObjectAccessor::FindPlayer(ownerGuid); if (!auction_owner && sObjectMgr->GetPlayerAccountIdByGUID(ownerGuid) == player->GetSession()->GetAccountId()) { @@ -452,7 +468,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) { if (auction->bidder > 0) { - if (auction->bidder == player->GetGUIDLow()) + if (auction->bidder == player->GetGUID().GetCounter()) player->ModifyMoney(-int32(price - auction->bid)); else { @@ -464,7 +480,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) else player->ModifyMoney(-int32(price)); - auction->bidder = player->GetGUIDLow(); + auction->bidder = player->GetGUID().GetCounter(); auction->bid = price; GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, price); @@ -479,7 +495,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) else { //buyout: - if (player->GetGUIDLow() == auction->bidder) + if (player->GetGUID().GetCounter() == auction->bidder) player->ModifyMoney(-int32(auction->buyout - auction->bid)); else { @@ -487,7 +503,7 @@ void WorldSession::HandleAuctionPlaceBid(WorldPacket& recvData) if (auction->bidder) //buyout for bidded auction .. sAuctionMgr->SendAuctionOutbiddedMail(auction, auction->buyout, GetPlayer(), trans); } - auction->bidder = player->GetGUIDLow(); + auction->bidder = player->GetGUID().GetCounter(); auction->bid = auction->buyout; GetPlayer()->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_AUCTION_BID, auction->buyout); @@ -535,7 +551,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) Player* player = GetPlayer(); SQLTransaction trans = CharacterDatabase.BeginTransaction(); - if (auction && auction->owner == player->GetGUIDLow()) + if (auction && auction->owner == player->GetGUID().GetCounter()) { Item* pItem = sAuctionMgr->GetAItem(auction->itemGUIDLow); if (pItem) @@ -566,7 +582,7 @@ void WorldSession::HandleAuctionRemoveItem(WorldPacket& recvData) { SendAuctionCommandResult(0, AUCTION_CANCEL, ERR_AUCTION_DATABASE_ERROR); //this code isn't possible ... maybe there should be assert - TC_LOG_ERROR("network", "CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", player->GetGUIDLow(), auctionId); + TC_LOG_ERROR("network", "CHEATER : %u, he tried to cancel auction (id: %u) of another player, or auction is NULL", player->GetGUID().GetCounter(), auctionId); return; } diff --git a/src/server/game/Handlers/BattleGroundHandler.cpp b/src/server/game/Handlers/BattleGroundHandler.cpp index 2ec89ac2a26..fec0b8e0d40 100644 --- a/src/server/game/Handlers/BattleGroundHandler.cpp +++ b/src/server/game/Handlers/BattleGroundHandler.cpp @@ -86,7 +86,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) if (!sBattlemasterListStore.LookupEntry(bgTypeId_)) { - TC_LOG_ERROR("network", "Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUIDLow()); + TC_LOG_ERROR("network", "Battleground: invalid bgtype (%u) received. possible cheater? player guid %u", bgTypeId_, _player->GetGUID().GetCounter()); return; } @@ -194,7 +194,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, ginfo->ArenaType, 0); SendPacket(&data); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", - bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); + bgQueueTypeId, bgTypeId, _player->GetGUID().GetCounter(), _player->GetName().c_str()); } else { @@ -242,7 +242,7 @@ void WorldSession::HandleBattlemasterJoinOpcode(WorldPacket& recvData) sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for bg queue type %u bg type %u: GUID %u, NAME %s", - bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); + bgQueueTypeId, bgTypeId, member->GetGUID().GetCounter(), member->GetName().c_str()); } TC_LOG_DEBUG("bg.battleground", "Battleground: group end"); } @@ -335,7 +335,7 @@ void WorldSession::HandleBattlefieldListOpcode(WorldPacket &recvData) BattlemasterListEntry const* bl = sBattlemasterListStore.LookupEntry(bgTypeId); if (!bl) { - TC_LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId, _player->GetName().c_str(), _player->GetGUIDLow()); + TC_LOG_DEBUG("bg.battleground", "BattlegroundHandler: invalid bgtype (%u) with player (Name: %s, GUID: %u) received.", bgTypeId, _player->GetName().c_str(), _player->GetGUID().GetCounter()); return; } @@ -424,13 +424,13 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data2, ERR_GROUP_JOIN_BATTLEGROUND_DESERTERS); _player->GetSession()->SendPacket(&data2); action = 0; - TC_LOG_DEBUG("bg.battleground", "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUIDLow()); + TC_LOG_DEBUG("bg.battleground", "Player %s (%u) has a deserter debuff, do not port him to battleground!", _player->GetName().c_str(), _player->GetGUID().GetCounter()); } //if player don't match battleground max level, then do not allow him to enter! (this might happen when player leveled up during his waiting in queue if (_player->getLevel() > bg->GetMaxLevel()) { TC_LOG_ERROR("network", "Player %s (%u) has level (%u) higher than maxlevel (%u) of battleground (%u)! Do not port him to battleground!", - _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID()); + _player->GetName().c_str(), _player->GetGUID().GetCounter(), _player->getLevel(), bg->GetMaxLevel(), bg->GetTypeID()); action = 0; } } @@ -480,7 +480,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) sBattlegroundMgr->SendToBattleground(_player, ginfo.IsInvitedToBGInstanceGUID, bgTypeId); // add only in HandleMoveWorldPortAck() // bg->AddPlayer(_player, team); - TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); + TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) joined battle for bg %u, bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUID().GetCounter(), bg->GetInstanceID(), bg->GetTypeID(), bgQueueTypeId); } else // leave queue { @@ -505,7 +505,7 @@ void WorldSession::HandleBattleFieldPortOpcode(WorldPacket &recvData) if (!ginfo.ArenaType) sBattlegroundMgr->ScheduleQueueUpdate(ginfo.ArenaMatchmakerRating, ginfo.ArenaType, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); SendPacket(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUIDLow(), bg->GetTypeID(), bgQueueTypeId); + TC_LOG_DEBUG("bg.battleground", "Battleground: player %s (%u) left queue for bgtype %u, queue type %u.", _player->GetName().c_str(), _player->GetGUID().GetCounter(), bg->GetTypeID(), bgQueueTypeId); } } @@ -741,7 +741,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) member->GetSession()->SendPacket(&data); sBattlegroundMgr->BuildGroupJoinedBattlegroundPacket(&data, err); member->GetSession()->SendPacket(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUIDLow(), member->GetName().c_str()); + TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena as group bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, member->GetGUID().GetCounter(), member->GetName().c_str()); } } else @@ -754,7 +754,7 @@ void WorldSession::HandleBattlemasterJoinArena(WorldPacket& recvData) // send status packet (in queue) sBattlegroundMgr->BuildBattlegroundStatusPacket(&data, bg, queueSlot, STATUS_WAIT_QUEUE, avgTime, 0, arenatype, 0); SendPacket(&data); - TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUIDLow(), _player->GetName().c_str()); + TC_LOG_DEBUG("bg.battleground", "Battleground: player joined queue for arena, skirmish, bg queue type %u bg type %u: GUID %u, NAME %s", bgQueueTypeId, bgTypeId, _player->GetGUID().GetCounter(), _player->GetName().c_str()); } sBattlegroundMgr->ScheduleQueueUpdate(matchmakerRating, arenatype, bgQueueTypeId, bgTypeId, bracketEntry->GetBracketId()); } diff --git a/src/server/game/Handlers/CalendarHandler.cpp b/src/server/game/Handlers/CalendarHandler.cpp index 0cd170dfba7..e9b3bea5991 100644 --- a/src/server/game/Handlers/CalendarHandler.cpp +++ b/src/server/game/Handlers/CalendarHandler.cpp @@ -447,7 +447,7 @@ void WorldSession::HandleCalendarEventInvite(WorldPacket& recvData) if (PreparedQueryResult result = CharacterDatabase.Query(stmt)) { Field* fields = result->Fetch(); - inviteeGuid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); + inviteeGuid = ObjectGuid(HighGuid::Player, fields[0].GetUInt32()); inviteeTeam = Player::TeamForRace(fields[1].GetUInt8()); inviteeGuildId = Player::GetGuildIdFromDB(inviteeGuid); } diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 11b31d98cc8..ba22ab6aa07 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -203,6 +203,10 @@ bool LoginQueryHolder::Initialize() stmt->setUInt32(0, m_accountId); res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES, stmt); + stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSE_LOCATION); + stmt->setUInt64(0, lowGuid); + res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION, stmt); + return res; } @@ -219,7 +223,7 @@ void WorldSession::HandleCharEnum(PreparedQueryResult result) { do { - ObjectGuid guid(HIGHGUID_PLAYER, (*result)[0].GetUInt32()); + ObjectGuid guid(HighGuid::Player, (*result)[0].GetUInt32()); TC_LOG_INFO("network", "Loading %s from account %u.", guid.ToString().c_str(), GetAccountId()); if (Player::BuildEnumData(result, &data)) { @@ -601,7 +605,8 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte Player newChar(this); newChar.GetMotionMaster()->Initialize(); - if (!newChar.Create(sObjectMgr->GenerateLowGuid(HIGHGUID_PLAYER), createInfo)) + if (!newChar.Create(sObjectMgr->GetGenerator<HighGuid::Player>().Generate(), createInfo)) + { // Player not create (race/class/etc problem?) newChar.CleanupsBeforeDelete(); @@ -638,7 +643,7 @@ void WorldSession::HandleCharCreateCallback(PreparedQueryResult result, Characte SendCharCreate(CHAR_CREATE_SUCCESS); - TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), createInfo->Name.c_str(), newChar.GetGUIDLow()); + TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Create Character:[%s] (GUID: %u)", GetAccountId(), GetRemoteAddress().c_str(), createInfo->Name.c_str(), newChar.GetGUID().GetCounter()); sScriptMgr->OnPlayerCreate(&newChar); sWorld->AddCharacterNameData(newChar.GetGUID(), newChar.GetName(), newChar.getGender(), newChar.getRace(), newChar.getClass(), newChar.getLevel()); @@ -832,7 +837,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) TC_LOG_DEBUG("network", "WORLD: Sent server info"); } - //QueryResult* result = CharacterDatabase.PQuery("SELECT guildid, rank FROM guild_member WHERE guid = '%u'", pCurrChar->GetGUIDLow()); + //QueryResult* result = CharacterDatabase.PQuery("SELECT guildid, rank FROM guild_member WHERE guid = '%u'", pCurrChar->GetGUID().GetCounter()); if (PreparedQueryResult resultGuild = holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GUILD)) { Field* fields = resultGuild->Fetch(); @@ -852,7 +857,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) else { // remove wrong guild data - TC_LOG_ERROR("network", "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName().c_str(), pCurrChar->GetGUIDLow(), pCurrChar->GetGuildId()); + TC_LOG_ERROR("network", "Player %s (GUID: %u) marked as member of not existing guild (id: %u), removing guild membership for player.", pCurrChar->GetName().c_str(), pCurrChar->GetGUID().GetCounter(), pCurrChar->GetGuildId()); pCurrChar->SetInGuild(0); } } @@ -891,14 +896,14 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) pCurrChar->TeleportTo(pCurrChar->m_homebindMapId, pCurrChar->m_homebindX, pCurrChar->m_homebindY, pCurrChar->m_homebindZ, pCurrChar->GetOrientation()); } - sObjectAccessor->AddObject(pCurrChar); + ObjectAccessor::AddObject(pCurrChar); //TC_LOG_DEBUG("Player %s added to Map.", pCurrChar->GetName().c_str()); pCurrChar->SendInitialPacketsAfterAddToMap(); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_ONLINE); - stmt->setUInt32(0, pCurrChar->GetGUIDLow()); + stmt->setUInt32(0, pCurrChar->GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); @@ -919,10 +924,10 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) } // friend status - sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true); + sSocialMgr->SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUID().GetCounter(), true); // Place character in world (and load zone) before some object loading - pCurrChar->LoadCorpse(); + pCurrChar->LoadCorpse(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CORPSE_LOCATION)); // setting Ghost+speed if dead if (pCurrChar->m_deathState != ALIVE) @@ -981,7 +986,7 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) std::string IP_str = GetRemoteAddress(); TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Login Character:[%s] (GUID: %u) Level: %d", - GetAccountId(), IP_str.c_str(), pCurrChar->GetName().c_str(), pCurrChar->GetGUIDLow(), pCurrChar->getLevel()); + GetAccountId(), IP_str.c_str(), pCurrChar->GetName().c_str(), pCurrChar->GetGUID().GetCounter(), pCurrChar->getLevel()); if (!pCurrChar->IsStandState() && !pCurrChar->HasUnitState(UNIT_STATE_STUNNED)) pCurrChar->SetStandState(UNIT_STAND_STATE_STAND); @@ -1671,11 +1676,11 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) } } - // resurrect the character in case he's dead - sObjectAccessor->ConvertCorpseForPlayer(factionChangeInfo.Guid); - SQLTransaction trans = CharacterDatabase.BeginTransaction(); + // resurrect the character in case he's dead + Player::OfflineResurrect(factionChangeInfo.Guid, trans); + CharacterDatabase.EscapeString(factionChangeInfo.Name); Player::Customize(&factionChangeInfo, trans); @@ -1819,6 +1824,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) trans->Append(stmt); } + /// @todo: make this part async if (!sWorld->getBoolConfig(CONFIG_ALLOW_TWO_SIDE_INTERACTION_GUILD)) { // Reset guild @@ -1942,7 +1948,7 @@ void WorldSession::HandleCharFactionOrRaceChange(WorldPacket& recvData) { Quest const* quest = iter->second; uint32 newRaceMask = (team == TEAM_ALLIANCE) ? RACEMASK_ALLIANCE : RACEMASK_HORDE; - if (!(quest->GetRequiredRaces() & newRaceMask)) + if (!(quest->GetAllowableRaces() & newRaceMask)) { stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_QUESTSTATUS_REWARDED_ACTIVE_BY_QUEST); stmt->setUInt32(0, lowGuid); diff --git a/src/server/game/Handlers/ChatHandler.cpp b/src/server/game/Handlers/ChatHandler.cpp index 2acbaba1f67..e13b417215b 100644 --- a/src/server/game/Handlers/ChatHandler.cpp +++ b/src/server/game/Handlers/ChatHandler.cpp @@ -115,7 +115,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) break; default: TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid language/message type combination", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); recvData.rfinish(); return; @@ -226,7 +226,7 @@ void WorldSession::HandleMessagechatOpcode(WorldPacket& recvData) if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_SEVERITY) && !ChatHandler(this).isValidChatMessage(msg.c_str())) { TC_LOG_ERROR("network", "Player %s (GUID: %u) sent a chatmessage with an invalid link: %s", GetPlayer()->GetName().c_str(), - GetPlayer()->GetGUIDLow(), msg.c_str()); + GetPlayer()->GetGUID().GetCounter(), msg.c_str()); if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK)) KickPlayer(); diff --git a/src/server/game/Handlers/CombatHandler.cpp b/src/server/game/Handlers/CombatHandler.cpp index ac33880cb98..78aeaa1b41b 100644 --- a/src/server/game/Handlers/CombatHandler.cpp +++ b/src/server/game/Handlers/CombatHandler.cpp @@ -75,7 +75,7 @@ void WorldSession::HandleSetSheathedOpcode(WorldPacket& recvData) uint32 sheathed; recvData >> sheathed; - //TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUIDLow(), sheathed); + //TC_LOG_DEBUG("network", "WORLD: Recvd CMSG_SETSHEATHED Message guidlow:%u value1:%u", GetPlayer()->GetGUID().GetCounter(), sheathed); if (sheathed >= MAX_SHEATH_STATE) { diff --git a/src/server/game/Handlers/DuelHandler.cpp b/src/server/game/Handlers/DuelHandler.cpp index 954fb66a9db..6e8ff5547d7 100644 --- a/src/server/game/Handlers/DuelHandler.cpp +++ b/src/server/game/Handlers/DuelHandler.cpp @@ -40,8 +40,11 @@ void WorldSession::HandleDuelAcceptedOpcode(WorldPacket& recvPacket) return; //TC_LOG_DEBUG("network", "WORLD: Received CMSG_DUEL_ACCEPTED"); - TC_LOG_DEBUG("network", "Player 1 is: %u (%s)", player->GetGUIDLow(), player->GetName().c_str()); - TC_LOG_DEBUG("network", "Player 2 is: %u (%s)", plTarget->GetGUIDLow(), plTarget->GetName().c_str()); + TC_LOG_DEBUG("network", "Player 1 is: %u (%s)", player->GetGUID().GetCounter(), player->GetName().c_str()); + TC_LOG_DEBUG("network", "Player 2 is: %u (%s)", plTarget->GetGUID().GetCounter(), plTarget->GetName().c_str()); + + player->UpdateHasCoolDownBeforeDuel(); + plTarget->UpdateHasCoolDownBeforeDuel(); time_t now = time(NULL); player->duel->startTimer = now; diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index f8531adeb88..30764fea2a3 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -107,7 +107,7 @@ void WorldSession::HandleGroupInviteOpcode(WorldPacket& recvData) return; } - if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + if (player->GetSocial()->HasIgnore(GetPlayer()->GetGUID().GetCounter())) { SendPartyResult(PARTY_OP_INVITE, membername, ERR_IGNORING_YOU_S); return; @@ -210,7 +210,7 @@ void WorldSession::HandleGroupAcceptOpcode(WorldPacket& recvData) if (group->GetLeaderGUID() == GetPlayer()->GetGUID()) { - TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + TC_LOG_ERROR("network", "HandleGroupAcceptOpcode: player %s(%d) tried to accept an invite to his own group", GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } @@ -283,7 +283,7 @@ void WorldSession::HandleGroupUninviteGuidOpcode(WorldPacket& recvData) if (guid == GetPlayer()->GetGUID()) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteGuidOpcode: leader %s(%d) tried to uninvite himself from the group.", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } @@ -328,7 +328,7 @@ void WorldSession::HandleGroupUninviteOpcode(WorldPacket& recvData) if (GetPlayer()->GetName() == membername) { TC_LOG_ERROR("network", "WorldSession::HandleGroupUninviteOpcode: leader %s(%d) tried to uninvite himself from the group.", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } diff --git a/src/server/game/Handlers/ItemHandler.cpp b/src/server/game/Handlers/ItemHandler.cpp index 672e1c69920..13987c983f7 100644 --- a/src/server/game/Handlers/ItemHandler.cpp +++ b/src/server/game/Handlers/ItemHandler.cpp @@ -1157,7 +1157,7 @@ void WorldSession::HandleWrapItemOpcode(WorldPacket& recvData) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_GIFT); stmt->setUInt32(0, item->GetOwnerGUID().GetCounter()); - stmt->setUInt32(1, item->GetGUIDLow()); + stmt->setUInt32(1, item->GetGUID().GetCounter()); stmt->setUInt32(2, item->GetEntry()); stmt->setUInt32(3, item->GetUInt32Value(ITEM_FIELD_FLAGS)); trans->Append(stmt); diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp index 18ad2e828f0..9876e939395 100644 --- a/src/server/game/Handlers/LootHandler.cpp +++ b/src/server/game/Handlers/LootHandler.cpp @@ -110,7 +110,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) switch (guid.GetHigh()) { - case HIGHGUID_GAMEOBJECT: + case HighGuid::GameObject: { GameObject* go = GetPlayer()->GetMap()->GetGameObject(guid); @@ -120,7 +120,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) break; } - case HIGHGUID_CORPSE: // remove insignia ONLY in BG + case HighGuid::Corpse: // remove insignia ONLY in BG { Corpse* bones = ObjectAccessor::GetCorpse(*player, guid); @@ -132,7 +132,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) break; } - case HIGHGUID_ITEM: + case HighGuid::Item: { if (Item* item = player->GetItemByGuid(guid)) { @@ -141,8 +141,8 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/) } break; } - case HIGHGUID_UNIT: - case HIGHGUID_VEHICLE: + case HighGuid::Unit: + case HighGuid::Vehicle: { Creature* creature = player->GetMap()->GetCreature(guid); bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING); diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index d55af4bac35..5f25f57addd 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -110,7 +110,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) { TC_LOG_INFO("network", "Player %u is sending mail to %s (GUID: not existed!) with subject %s " "and body %s includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", - player->GetGUIDLow(), receiverName.c_str(), subject.c_str(), body.c_str(), + player->GetGUID().GetCounter(), receiverName.c_str(), subject.c_str(), body.c_str(), items_count, money, COD, stationery, package); player->SendMailResult(0, MAIL_SEND, MAIL_ERR_RECIPIENT_NOT_FOUND); return; @@ -118,7 +118,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) TC_LOG_INFO("network", "Player %u is sending mail to %s (%s) with subject %s and body %s " "includes %u items, %u copper and %u COD copper with unk1 = %u, unk2 = %u", - player->GetGUIDLow(), receiverName.c_str(), receiverGuid.ToString().c_str(), subject.c_str(), + player->GetGUID().GetCounter(), receiverName.c_str(), receiverGuid.ToString().c_str(), subject.c_str(), body.c_str(), items_count, money, COD, stationery, package); if (player->GetGUID() == receiverGuid) @@ -293,7 +293,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (log) { sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail item: %s (Entry: %u Count: %u) " - "to: %s (%s) (Account: %u)", GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), + "to: %s (%s) (Account: %u)", GetPlayerName().c_str(), GetGUIDLow(), GetAccountId(), item->GetTemplate()->Name1.c_str(), item->GetEntry(), item->GetCount(), receiverName.c_str(), receiverGuid.ToString().c_str(), receiverAccountId); } @@ -315,7 +315,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (log && money > 0) { sLog->outCommand(GetAccountId(), "GM %s (GUID: %u) (Account: %u) mail money: %u to: %s (%s) (Account: %u)", - GetPlayerName().c_str(), GetGuidLow(), GetAccountId(), money, receiverName.c_str(), receiverGuid.ToString().c_str(), receiverAccountId); + GetPlayerName().c_str(), GetGUIDLow(), GetAccountId(), money, receiverName.c_str(), receiverGuid.ToString().c_str(), receiverAccountId); } } @@ -499,7 +499,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) if (m->COD > 0) //if there is COD, take COD money from player and send them to sender by mail { - ObjectGuid sender_guid(HIGHGUID_PLAYER, m->sender); + ObjectGuid sender_guid(HighGuid::Player, m->sender); Player* receiver = ObjectAccessor::FindConnectedPlayer(sender_guid); uint32 sender_accId = 0; @@ -539,7 +539,7 @@ void WorldSession::HandleMailTakeItem(WorldPacket& recvData) m->COD = 0; m->state = MAIL_STATE_CHANGED; player->m_mailsUpdated = true; - player->RemoveMItem(it->GetGUIDLow()); + player->RemoveMItem(it->GetGUID().GetCounter()); uint32 count = it->GetCount(); // save counts before store and possible merge with deleting it->SetState(ITEM_UNCHANGED); // need to set this state, otherwise item cannot be removed later, if neccessary @@ -649,7 +649,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData) switch ((*itr)->messageType) { case MAIL_NORMAL: // sender guid - data << ObjectGuid(HIGHGUID_PLAYER, (*itr)->sender); + data << ObjectGuid(HighGuid::Player, (*itr)->sender); break; case MAIL_CREATURE: case MAIL_GAMEOBJECT: @@ -676,7 +676,7 @@ void WorldSession::HandleGetMailList(WorldPacket& recvData) // item index (0-6?) data << uint8(i); // item guid low? - data << uint32((item ? item->GetGUIDLow() : 0)); + data << uint32((item ? item->GetGUID().GetCounter() : 0)); // entry data << uint32((item ? item->GetEntry() : 0)); for (uint8 j = 0; j < MAX_INSPECTED_ENCHANTMENT_SLOT; ++j) @@ -735,7 +735,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) } Item* bodyItem = new Item; // This is not bag and then can be used new Item. - if (!bodyItem->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_ITEM), MAIL_BODY_ITEM_TEMPLATE, player)) + if (!bodyItem->Create(sObjectMgr->GetGenerator<HighGuid::Item>().Generate(), MAIL_BODY_ITEM_TEMPLATE, player)) { delete bodyItem; return; @@ -757,7 +757,7 @@ void WorldSession::HandleMailCreateTextItem(WorldPacket& recvData) bodyItem->SetText(m->body); if (m->messageType == MAIL_NORMAL) - bodyItem->SetGuidValue(ITEM_FIELD_CREATOR, ObjectGuid(HIGHGUID_PLAYER, m->sender)); + bodyItem->SetGuidValue(ITEM_FIELD_CREATOR, ObjectGuid(HighGuid::Player, m->sender)); bodyItem->SetFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_MAIL_TEXT_MASK); @@ -812,7 +812,7 @@ void WorldSession::HandleQueryNextMailTime(WorldPacket & /*recvData*/) if (sentSenders.count(m->sender)) continue; - data << uint64(m->messageType == MAIL_NORMAL ? ObjectGuid(HIGHGUID_PLAYER, m->sender) : ObjectGuid::Empty); // player guid + data << uint64(m->messageType == MAIL_NORMAL ? ObjectGuid(HighGuid::Player, m->sender) : ObjectGuid::Empty); // player guid data << uint32(m->messageType != MAIL_NORMAL ? m->sender : 0); // non-player entries data << uint32(m->messageType); data << uint32(m->stationery); diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index 7a9760ecf80..2eebbfc1004 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -66,7 +66,7 @@ void WorldSession::HandleRepopRequestOpcode(WorldPacket& recvData) if (GetPlayer()->getDeathState() == JUST_DIED) { TC_LOG_DEBUG("network", "HandleRepopRequestOpcode: got request after player %s(%d) was killed and before he was updated", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); GetPlayer()->KillPlayer(); } @@ -564,7 +564,7 @@ void WorldSession::HandleAddFriendOpcodeCallBack(PreparedQueryResult result, std { Field* fields = result->Fetch(); - friendGuid = ObjectGuid(HIGHGUID_PLAYER, 0, fields[0].GetUInt32()); + friendGuid = ObjectGuid(HighGuid::Player, 0, fields[0].GetUInt32()); team = Player::TeamForRace(fields[1].GetUInt8()); friendAccountId = fields[2].GetUInt32(); @@ -649,7 +649,7 @@ void WorldSession::HandleAddIgnoreOpcodeCallBack(PreparedQueryResult result) if (result) { - IgnoreGuid = ObjectGuid(HIGHGUID_PLAYER, (*result)[0].GetUInt32()); + IgnoreGuid = ObjectGuid(HighGuid::Player, (*result)[0].GetUInt32()); if (IgnoreGuid) { @@ -741,7 +741,6 @@ void WorldSession::HandleReclaimCorpseOpcode(WorldPacket& recvData) return; Corpse* corpse = _player->GetCorpse(); - if (!corpse) return; @@ -811,7 +810,7 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) if (player->IsInFlight()) { TC_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) in flight, ignore Area Trigger ID:%u", - player->GetName().c_str(), player->GetGUIDLow(), triggerId); + player->GetName().c_str(), player->GetGUID().GetCounter(), triggerId); return; } @@ -819,14 +818,14 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket& recvData) if (!atEntry) { TC_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) send unknown (by DBC) Area Trigger ID:%u", - player->GetName().c_str(), player->GetGUIDLow(), triggerId); + player->GetName().c_str(), player->GetGUID().GetCounter(), triggerId); return; } if (!player->IsInAreaTriggerRadius(atEntry)) { TC_LOG_DEBUG("network", "HandleAreaTriggerOpcode: Player '%s' (GUID: %u) too far, ignore Area Trigger ID: %u", - player->GetName().c_str(), player->GetGUIDLow(), triggerId); + player->GetName().c_str(), player->GetGUID().GetCounter(), triggerId); return; } @@ -1191,7 +1190,7 @@ void WorldSession::HandleWorldTeleportOpcode(WorldPacket& recvData) if (GetPlayer()->IsInFlight()) { TC_LOG_DEBUG("network", "Player '%s' (GUID: %u) in flight, ignore worldport command.", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow()); + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter()); return; } @@ -1335,7 +1334,7 @@ void WorldSession::HandleFarSightOpcode(WorldPacket& recvData) if (apply) { - TC_LOG_DEBUG("network", "Added FarSight %s to player %u", _player->GetGuidValue(PLAYER_FARSIGHT).ToString().c_str(), _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "Added FarSight %s to player %u", _player->GetGuidValue(PLAYER_FARSIGHT).ToString().c_str(), _player->GetGUID().GetCounter()); if (WorldObject* target = _player->GetViewpoint()) _player->SetSeer(target); else @@ -1343,7 +1342,7 @@ void WorldSession::HandleFarSightOpcode(WorldPacket& recvData) } else { - TC_LOG_DEBUG("network", "Player %u set vision to self", _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "Player %u set vision to self", _player->GetGUID().GetCounter()); _player->SetSeer(_player); } @@ -1411,7 +1410,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData) if (mode >= MAX_DUNGEON_DIFFICULTY) { - TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode); + TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUID().GetCounter(), mode); return; } @@ -1423,7 +1422,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData) if (map && map->IsDungeon()) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player (Name: %s, GUID: %u) tried to reset the instance while player is inside!", - _player->GetName().c_str(), _player->GetGUIDLow()); + _player->GetName().c_str(), _player->GetGUID().GetCounter()); return; } @@ -1444,7 +1443,7 @@ void WorldSession::HandleSetDungeonDifficultyOpcode(WorldPacket& recvData) if (groupGuy->GetMap()->IsNonRaidDungeon()) { TC_LOG_DEBUG("network", "WorldSession::HandleSetDungeonDifficultyOpcode: player %d tried to reset the instance while group member (Name: %s, GUID: %u) is inside!", - _player->GetGUIDLow(), groupGuy->GetName().c_str(), groupGuy->GetGUIDLow()); + _player->GetGUID().GetCounter(), groupGuy->GetName().c_str(), groupGuy->GetGUID().GetCounter()); return; } } @@ -1470,7 +1469,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData) if (mode >= MAX_RAID_DIFFICULTY) { - TC_LOG_ERROR("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUIDLow(), mode); + TC_LOG_ERROR("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %d sent an invalid instance mode %d!", _player->GetGUID().GetCounter(), mode); return; } @@ -1478,7 +1477,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData) Map* map = _player->FindMap(); if (map && map->IsDungeon()) { - TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUID().GetCounter()); return; } @@ -1501,7 +1500,7 @@ void WorldSession::HandleSetRaidDifficultyOpcode(WorldPacket& recvData) if (groupGuy->GetMap()->IsRaid()) { - TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "WorldSession::HandleSetRaidDifficultyOpcode: player %d tried to reset the instance while inside!", _player->GetGUID().GetCounter()); return; } } @@ -1695,7 +1694,7 @@ void WorldSession::HandleInstanceLockResponse(WorldPacket& recvPacket) if (!_player->HasPendingBind()) { TC_LOG_INFO("network", "InstanceLockResponse: Player %s (guid %u) tried to bind himself/teleport to graveyard without a pending bind!", - _player->GetName().c_str(), _player->GetGUIDLow()); + _player->GetName().c_str(), _player->GetGUID().GetCounter()); return; } diff --git a/src/server/game/Handlers/MovementHandler.cpp b/src/server/game/Handlers/MovementHandler.cpp index cedfed2e7c5..84816bf3f33 100644 --- a/src/server/game/Handlers/MovementHandler.cpp +++ b/src/server/game/Handlers/MovementHandler.cpp @@ -79,7 +79,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() // while the player is in transit, for example the map may get full if (!newMap || !newMap->CanEnter(GetPlayer())) { - TC_LOG_ERROR("network", "Map %d (%s) could not be created for player %d (%s), porting player to homebind", loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown", GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); + TC_LOG_ERROR("network", "Map %d (%s) could not be created for player %d (%s), porting player to homebind", loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown", GetPlayer()->GetGUID().GetCounter(), GetPlayer()->GetName().c_str()); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); return; } @@ -96,7 +96,7 @@ void WorldSession::HandleMoveWorldportAckOpcode() if (!GetPlayer()->GetMap()->AddPlayerToMap(GetPlayer())) { TC_LOG_ERROR("network", "WORLD: failed to teleport player %s (%d) to map %d (%s) because of unknown reason!", - GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown"); + GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter(), loc.GetMapId(), newMap ? newMap->GetMapName() : "Unknown"); GetPlayer()->ResetMap(); GetPlayer()->SetMap(oldMap); GetPlayer()->TeleportTo(GetPlayer()->m_homebindMapId, GetPlayer()->m_homebindX, GetPlayer()->m_homebindY, GetPlayer()->m_homebindZ, GetPlayer()->GetOrientation()); @@ -142,8 +142,8 @@ void WorldSession::HandleMoveWorldportAckOpcode() } // resurrect character at enter into instance where his corpse exist after add to map - Corpse* corpse = GetPlayer()->GetCorpse(); - if (corpse && corpse->GetType() != CORPSE_BONES && corpse->GetMapId() == GetPlayer()->GetMapId()) + Corpse* corpse = GetPlayer()->GetMap()->GetCorpseByPlayer(GetPlayer()->GetGUID()); + if (corpse && corpse->GetType() != CORPSE_BONES) { if (mEntry->IsDungeon()) { diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 3c4bbd87b3f..f8d7f73e077 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -403,10 +403,12 @@ void WorldSession::SendSpiritResurrect() // get corpse nearest graveyard WorldSafeLocsEntry const* corpseGrave = NULL; - Corpse* corpse = _player->GetCorpse(); - if (corpse) - corpseGrave = sObjectMgr->GetClosestGraveYard( - corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetMapId(), _player->GetTeam()); + WorldLocation corpseLocation = _player->GetCorpseLocation(); + if (_player->HasCorpse()) + { + corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(), + corpseLocation.GetPositionZ(), corpseLocation.GetMapId(), _player->GetTeam()); + } // now can spawn bones _player->SpawnCorpseBones(); @@ -494,7 +496,7 @@ void WorldSession::SendStablePet(ObjectGuid guid) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SLOTS_DETAIL); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT); stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT); @@ -596,7 +598,7 @@ void WorldSession::HandleStablePet(WorldPacket& recvData) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SLOTS); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt8(1, PET_SAVE_FIRST_STABLE_SLOT); stmt->setUInt8(2, PET_SAVE_LAST_STABLE_SLOT); @@ -657,7 +659,7 @@ void WorldSession::HandleUnstablePet(WorldPacket& recvData) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_ENTRY); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt32(1, petnumber); stmt->setUInt8(2, PET_SAVE_FIRST_STABLE_SLOT); stmt->setUInt8(3, PET_SAVE_LAST_STABLE_SLOT); @@ -786,7 +788,7 @@ void WorldSession::HandleStableSwapPet(WorldPacket& recvData) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PET_SLOT_BY_ID); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt32(1, petId); _stableSwapCallback.SetParam(petId); diff --git a/src/server/game/Handlers/PetHandler.cpp b/src/server/game/Handlers/PetHandler.cpp index 8ec887ea94d..4495c044c61 100644 --- a/src/server/game/Handlers/PetHandler.cpp +++ b/src/server/game/Handlers/PetHandler.cpp @@ -46,7 +46,7 @@ void WorldSession::HandleDismissCritter(WorldPacket& recvData) if (!pet) { TC_LOG_DEBUG("network", "Vanitypet (%s) does not exist - player '%s' (guid: %u / account: %u) attempted to dismiss it (possibly lagged out)", - guid.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUIDLow(), GetAccountId()); + guid.ToString().c_str(), GetPlayer()->GetName().c_str(), GetPlayer()->GetGUID().GetCounter(), GetAccountId()); return; } @@ -146,7 +146,7 @@ void WorldSession::HandlePetActionHelper(Unit* pet, ObjectGuid guid1, uint32 spe if (!charmInfo) { TC_LOG_DEBUG("network", "WorldSession::HandlePetAction(petGuid: %s, tagGuid: %s, spellId: %u, flag: %u): object (GUID: %u Entry: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", - guid1.ToString().c_str(), guid2.ToString().c_str(), spellid, flag, pet->GetGUIDLow(), pet->GetEntry(), pet->GetTypeId()); + guid1.ToString().c_str(), guid2.ToString().c_str(), spellid, flag, pet->GetGUID().GetCounter(), pet->GetEntry(), pet->GetTypeId()); return; } @@ -482,7 +482,7 @@ void WorldSession::HandlePetSetAction(WorldPacket& recvData) CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { - TC_LOG_ERROR("network", "WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); + TC_LOG_ERROR("network", "WorldSession::HandlePetSetAction: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().GetCounter(), pet->GetTypeId()); return; } @@ -593,7 +593,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) recvData >> name; recvData >> isdeclined; - Pet* pet = ObjectAccessor::FindPet(petguid); + Pet* pet = ObjectAccessor::GetPet(*_player, petguid); // check it! if (!pet || !pet->IsPet() || ((Pet*)pet)->getPetType()!= HUNTER_PET || !pet->HasByteFlag(UNIT_FIELD_BYTES_2, 2, UNIT_CAN_BE_RENAMED) || @@ -646,7 +646,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_PET_DECLINEDNAME); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); for (uint8 i = 0; i < 5; i++) stmt->setString(i + 1, declinedname.name[i]); @@ -656,7 +656,7 @@ void WorldSession::HandlePetRename(WorldPacket& recvData) PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHAR_PET_NAME); stmt->setString(0, name); - stmt->setUInt32(1, _player->GetGUIDLow()); + stmt->setUInt32(1, _player->GetGUID().GetCounter()); stmt->setUInt32(2, pet->GetCharmInfo()->GetPetNumber()); trans->Append(stmt); @@ -729,7 +729,7 @@ void WorldSession::HandlePetSpellAutocastOpcode(WorldPacket& recvPacket) CharmInfo* charmInfo = pet->GetCharmInfo(); if (!charmInfo) { - TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUIDLow(), pet->GetTypeId()); + TC_LOG_ERROR("network", "WorldSession::HandlePetSpellAutocastOpcod: object (GUID: %u TypeId: %u) is considered pet-like but doesn't have a charminfo!", pet->GetGUID().GetCounter(), pet->GetTypeId()); return; } diff --git a/src/server/game/Handlers/PetitionsHandler.cpp b/src/server/game/Handlers/PetitionsHandler.cpp index 05e793455da..c7a3f419d62 100644 --- a/src/server/game/Handlers/PetitionsHandler.cpp +++ b/src/server/game/Handlers/PetitionsHandler.cpp @@ -191,7 +191,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) if (!charter) return; - charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUIDLow()); + charter->SetUInt32Value(ITEM_FIELD_ENCHANTMENT_1_1, charter->GetGUID().GetCounter()); // ITEM_FIELD_ENCHANTMENT_1_1 is guild/arenateam id // ITEM_FIELD_ENCHANTMENT_1_1+1 is current signatures count (showed on item) charter->SetState(ITEM_CHANGED, _player); @@ -201,7 +201,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) // we checked above, if this player is in an arenateam, so this must be // datacorruption PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_BY_OWNER); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt8(1, type); PreparedQueryResult result = CharacterDatabase.Query(stmt); @@ -217,7 +217,7 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) } // delete petitions with the same guid as this one - ssInvalidPetitionGUIDs << '\'' << charter->GetGUIDLow() << '\''; + ssInvalidPetitionGUIDs << '\'' << charter->GetGUID().GetCounter() << '\''; TC_LOG_DEBUG("network", "Invalid petition GUIDs: %s", ssInvalidPetitionGUIDs.str().c_str()); CharacterDatabase.EscapeString(name); @@ -226,8 +226,8 @@ void WorldSession::HandlePetitionBuyOpcode(WorldPacket& recvData) trans->PAppend("DELETE FROM petition_sign WHERE petitionguid IN (%s)", ssInvalidPetitionGUIDs.str().c_str()); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_PETITION); - stmt->setUInt32(0, _player->GetGUIDLow()); - stmt->setUInt32(1, charter->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); + stmt->setUInt32(1, charter->GetGUID().GetCounter()); stmt->setString(2, name); stmt->setUInt8(3, uint8(type)); trans->Append(stmt); @@ -253,7 +253,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData) if (!result) { - TC_LOG_DEBUG("entities.player.items", "Petition %s is not found for player %u %s", petitionguid.ToString().c_str(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); + TC_LOG_DEBUG("entities.player.items", "Petition %s is not found for player %u %s", petitionguid.ToString().c_str(), GetPlayer()->GetGUID().GetCounter(), GetPlayer()->GetName().c_str()); return; } Field* fields = result->Fetch(); @@ -286,7 +286,7 @@ void WorldSession::HandlePetitionShowSignOpcode(WorldPacket& recvData) Field* fields2 = result->Fetch(); uint32 lowGuid = fields2[0].GetUInt32(); - data << ObjectGuid(HIGHGUID_PLAYER, 0, lowGuid); // Player GUID + data << ObjectGuid(HighGuid::Player, 0, lowGuid); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); @@ -322,7 +322,7 @@ void WorldSession::SendPetitionQueryOpcode(ObjectGuid petitionguid) if (result) { Field* fields = result->Fetch(); - ownerguid = ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); + ownerguid = ObjectGuid(HighGuid::Player, fields[0].GetUInt32()); name = fields[1].GetString(); type = fields[2].GetUInt8(); } @@ -461,16 +461,16 @@ void WorldSession::HandlePetitionSignOpcode(WorldPacket& recvData) if (!result) { - TC_LOG_ERROR("network", "Petition %s is not found for player %u %s", petitionGuid.ToString().c_str(), GetPlayer()->GetGUIDLow(), GetPlayer()->GetName().c_str()); + TC_LOG_ERROR("network", "Petition %s is not found for player %u %s", petitionGuid.ToString().c_str(), GetPlayer()->GetGUID().GetCounter(), GetPlayer()->GetName().c_str()); return; } fields = result->Fetch(); - ObjectGuid ownerGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()); + ObjectGuid ownerGuid(HighGuid::Player, fields[0].GetUInt32()); uint64 signs = fields[1].GetUInt64(); uint8 type = fields[2].GetUInt8(); - uint32 playerGuid = _player->GetGUIDLow(); + uint32 playerGuid = _player->GetGUID().GetCounter(); if (ownerGuid == _player->GetGUID()) return; @@ -585,7 +585,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData) ObjectGuid petitionguid; recvData >> petitionguid; // petition guid - TC_LOG_DEBUG("network", "Petition %s declined by %u", petitionguid.ToString().c_str(), _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "Petition %s declined by %u", petitionguid.ToString().c_str(), _player->GetGUID().GetCounter()); PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_PETITION_OWNER_BY_GUID); @@ -597,7 +597,7 @@ void WorldSession::HandlePetitionDeclineOpcode(WorldPacket& recvData) return; Field* fields = result->Fetch(); - ObjectGuid ownerguid(HIGHGUID_PLAYER, 0, fields[0].GetUInt32()); + ObjectGuid ownerguid(HighGuid::Player, 0, fields[0].GetUInt32()); Player* owner = ObjectAccessor::FindConnectedPlayer(ownerguid); if (owner) // petition owner online @@ -708,7 +708,7 @@ void WorldSession::HandleOfferPetitionOpcode(WorldPacket& recvData) for (uint8 i = 1; i <= signs; ++i) { Field* fields2 = result->Fetch(); - data << uint64(ObjectGuid(HIGHGUID_PLAYER, fields2[0].GetUInt32())); // Player GUID + data << uint64(ObjectGuid(HighGuid::Player, fields2[0].GetUInt32())); // Player GUID data << uint32(0); // there 0 ... result->NextRow(); @@ -732,7 +732,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData) if (!item) return; - TC_LOG_DEBUG("network", "Petition %s turned in by %u", petitionGuid.ToString().c_str(), _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "Petition %s turned in by %u", petitionGuid.ToString().c_str(), _player->GetGUID().GetCounter()); // Get petition data from db uint32 ownerguidlo; @@ -752,12 +752,12 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData) } else { - TC_LOG_ERROR("network", "Player %s (guid: %u) tried to turn in petition (%s) that is not present in the database", _player->GetName().c_str(), _player->GetGUIDLow(), petitionGuid.ToString().c_str()); + TC_LOG_ERROR("network", "Player %s (guid: %u) tried to turn in petition (%s) that is not present in the database", _player->GetName().c_str(), _player->GetGUID().GetCounter(), petitionGuid.ToString().c_str()); return; } // Only the petition owner can turn in the petition - if (_player->GetGUIDLow() != ownerguidlo) + if (_player->GetGUID().GetCounter() != ownerguidlo) return; // Petition type (guild/arena) specific checks @@ -853,7 +853,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData) for (uint8 i = 0; i < signatures; ++i) { Field* fields = result->Fetch(); - guild->AddMember(ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32())); + guild->AddMember(ObjectGuid(HighGuid::Player, fields[0].GetUInt32())); result->NextRow(); } } @@ -880,7 +880,7 @@ void WorldSession::HandleTurnInPetitionOpcode(WorldPacket& recvData) for (uint8 i = 0; i < signatures; ++i) { Field* fields = result->Fetch(); - ObjectGuid memberGUID(HIGHGUID_PLAYER, fields[0].GetUInt32()); + ObjectGuid memberGUID(HighGuid::Player, fields[0].GetUInt32()); TC_LOG_DEBUG("network", "PetitionsHandler: Adding arena team (guid: %u) member %s", arenaTeam->GetId(), memberGUID.ToString().c_str()); arenaTeam->AddMember(memberGUID); result->NextRow(); diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index 906c3017100..6d896bee26c 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -218,11 +218,7 @@ void WorldSession::HandleGameObjectQueryOpcode(WorldPacket& recvData) void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recvData*/) { - TC_LOG_DEBUG("network", "WORLD: Received MSG_CORPSE_QUERY"); - - Corpse* corpse = GetPlayer()->GetCorpse(); - - if (!corpse) + if (!_player->HasCorpse()) { WorldPacket data(MSG_CORPSE_QUERY, 1); data << uint8(0); // corpse not found @@ -230,24 +226,25 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recvData*/) return; } - uint32 mapid = corpse->GetMapId(); - float x = corpse->GetPositionX(); - float y = corpse->GetPositionY(); - float z = corpse->GetPositionZ(); - uint32 corpsemapid = mapid; + WorldLocation corpseLocation = _player->GetCorpseLocation(); + uint32 corpseMapID = corpseLocation.GetMapId(); + uint32 mapID = corpseLocation.GetMapId(); + float x = corpseLocation.GetPositionX(); + float y = corpseLocation.GetPositionY(); + float z = corpseLocation.GetPositionZ(); // if corpse at different map - if (mapid != _player->GetMapId()) + if (mapID != _player->GetMapId()) { // search entrance map for proper show entrance - if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapid)) + if (MapEntry const* corpseMapEntry = sMapStore.LookupEntry(mapID)) { if (corpseMapEntry->IsDungeon() && corpseMapEntry->entrance_map >= 0) { // if corpse map have entrance if (Map const* entranceMap = sMapMgr->CreateBaseMap(corpseMapEntry->entrance_map)) { - mapid = corpseMapEntry->entrance_map; + mapID = corpseMapEntry->entrance_map; x = corpseMapEntry->entrance_x; y = corpseMapEntry->entrance_y; z = entranceMap->GetHeight(GetPlayer()->GetPhaseMask(), x, y, MAX_HEIGHT); @@ -258,11 +255,11 @@ void WorldSession::HandleCorpseQueryOpcode(WorldPacket & /*recvData*/) WorldPacket data(MSG_CORPSE_QUERY, 1+(6*4)); data << uint8(1); // corpse found - data << int32(mapid); + data << int32(mapID); data << float(x); data << float(y); data << float(z); - data << int32(corpsemapid); + data << int32(corpseMapID); data << uint32(0); // unknown SendPacket(&data); } diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index b6297e1705a..91bc8309b18 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -48,14 +48,14 @@ void WorldSession::HandleQuestgiverStatusQueryOpcode(WorldPacket& recvData) { case TYPEID_UNIT: { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", questGiver->GetGUIDLow()); + TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for npc, guid = %u", questGiver->GetGUID().GetCounter()); if (!questGiver->ToCreature()->IsHostileTo(_player)) // do not show quest status to enemies questStatus = _player->GetQuestDialogStatus(questGiver); break; } case TYPEID_GAMEOBJECT: { - TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", questGiver->GetGUIDLow()); + TC_LOG_DEBUG("network", "WORLD: Received CMSG_QUESTGIVER_STATUS_QUERY for GameObject guid = %u", questGiver->GetGUID().GetCounter()); questStatus = _player->GetQuestDialogStatus(questGiver); break; } @@ -260,7 +260,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) if (reward >= QUEST_REWARD_CHOICES_COUNT) { - TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUIDLow(), reward); + TC_LOG_ERROR("network", "Error in CMSG_QUESTGIVER_CHOOSE_REWARD: player %s (guid %d) tried to get invalid reward (%u) (possible packet-hacking detected)", _player->GetName().c_str(), _player->GetGUID().GetCounter(), reward); return; } @@ -280,7 +280,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPacket& recvData) (_player->GetQuestStatus(questId) != QUEST_STATUS_COMPLETE && !quest->IsAutoComplete())) { TC_LOG_ERROR("network", "Error in QUEST_STATUS_COMPLETE: player %s (guid %u) tried to complete quest %u, but is not allowed to do so (possible packet-hacking or high latency)", - _player->GetName().c_str(), _player->GetGUIDLow(), questId); + _player->GetName().c_str(), _player->GetGUID().GetCounter(), questId); return; } if (_player->CanRewardQuest(quest, reward, true)) @@ -418,14 +418,14 @@ void WorldSession::HandleQuestLogRemoveQuest(WorldPacket& recvData) _player->RemoveActiveQuest(questId); _player->RemoveTimedAchievement(ACHIEVEMENT_TIMED_TYPE_QUEST, questId); - TC_LOG_INFO("network", "Player %u abandoned quest %u", _player->GetGUIDLow(), questId); + TC_LOG_INFO("network", "Player %u abandoned quest %u", _player->GetGUID().GetCounter(), questId); if (sWorld->getBoolConfig(CONFIG_QUEST_ENABLE_QUEST_TRACKER)) // check if Quest Tracker is enabled { // prepare Quest Tracker datas PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_QUEST_TRACK_ABANDON_TIME); stmt->setUInt32(0, questId); - stmt->setUInt32(1, _player->GetGUIDLow()); + stmt->setUInt32(1, _player->GetGUID().GetCounter()); // add to Quest Tracker CharacterDatabase.Execute(stmt); @@ -494,7 +494,7 @@ void WorldSession::HandleQuestgiverCompleteQuest(WorldPacket& recvData) if (!_player->CanSeeStartQuest(quest) && _player->GetQuestStatus(questId) == QUEST_STATUS_NONE) { TC_LOG_ERROR("network", "Possible hacking attempt: Player %s [guid: %u] tried to complete quest [entry: %u] without being in possession of the quest!", - _player->GetName().c_str(), _player->GetGUIDLow(), questId); + _player->GetName().c_str(), _player->GetGUID().GetCounter(), questId); return; } diff --git a/src/server/game/Handlers/ReferAFriendHandler.cpp b/src/server/game/Handlers/ReferAFriendHandler.cpp index f87198834b9..db5d0997eeb 100644 --- a/src/server/game/Handlers/ReferAFriendHandler.cpp +++ b/src/server/game/Handlers/ReferAFriendHandler.cpp @@ -27,7 +27,7 @@ void WorldSession::HandleGrantLevel(WorldPacket& recvData) ObjectGuid guid; recvData >> guid.ReadAsPacked(); - Player* target = ObjectAccessor::GetObjectInWorld(guid, _player); + Player* target = ObjectAccessor::GetPlayer(*_player, guid); // check cheating uint8 levels = _player->GetGrantableLevels(); @@ -70,7 +70,8 @@ void WorldSession::HandleAcceptGrantLevel(WorldPacket& recvData) ObjectGuid guid; recvData >> guid.ReadAsPacked(); - Player* other = ObjectAccessor::GetObjectInWorld(guid, _player); + Player* other = ObjectAccessor::GetPlayer(*_player, guid); + if (!(other && other->GetSession())) return; diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index a6108b36c13..0f0640e3a2e 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -200,7 +200,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) { pUser->SendEquipError(EQUIP_ERR_CANT_DO_RIGHT_NOW, item, NULL); TC_LOG_ERROR("network", "Possible hacking attempt: Player %s [guid: %u] tried to open item [guid: %u, entry: %u] which is not openable!", - pUser->GetName().c_str(), pUser->GetGUIDLow(), item->GetGUIDLow(), proto->ItemId); + pUser->GetName().c_str(), pUser->GetGUID().GetCounter(), item->GetGUID().GetCounter(), proto->ItemId); return; } @@ -213,7 +213,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) if (!lockInfo) { pUser->SendEquipError(EQUIP_ERR_ITEM_LOCKED, item, NULL); - TC_LOG_ERROR("network", "WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", item->GetGUIDLow(), lockId); + TC_LOG_ERROR("network", "WORLD::OpenItem: item [guid = %u] has an unknown lockId: %u!", item->GetGUID().GetCounter(), lockId); return; } @@ -229,7 +229,7 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); PreparedQueryResult result = CharacterDatabase.Query(stmt); @@ -246,14 +246,14 @@ void WorldSession::HandleOpenItemOpcode(WorldPacket& recvPacket) } else { - TC_LOG_ERROR("network", "Wrapped item %u don't have record in character_gifts table and will deleted", item->GetGUIDLow()); + TC_LOG_ERROR("network", "Wrapped item %u don't have record in character_gifts table and will deleted", item->GetGUID().GetCounter()); pUser->DestroyItem(item->GetBagSlot(), item->GetSlot(), true); return; } stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_GIFT); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); CharacterDatabase.Execute(stmt); } @@ -579,7 +579,7 @@ void WorldSession::HandleMirrorImageDataRequest(WorldPacket& recvData) recvData >> guid; // Get unit for which data is needed by client - Unit* unit = ObjectAccessor::GetObjectInWorld(guid, (Unit*)NULL); + Unit* unit = ObjectAccessor::GetUnit(*_player, guid); if (!unit) return; diff --git a/src/server/game/Handlers/TaxiHandler.cpp b/src/server/game/Handlers/TaxiHandler.cpp index af0f5b0fc75..a671250c17d 100644 --- a/src/server/game/Handlers/TaxiHandler.cpp +++ b/src/server/game/Handlers/TaxiHandler.cpp @@ -24,7 +24,6 @@ #include "Log.h" #include "ObjectMgr.h" #include "Player.h" -#include "Path.h" #include "WaypointMovementGenerator.h" void WorldSession::HandleTaxiNodeStatusQueryOpcode(WorldPacket& recvData) @@ -212,7 +211,7 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData) MovementInfo movementInfo; // used only for proper packet read ReadMovementInfo(recvData, &movementInfo); - recvData.read_skip<uint32>(); // unk + recvData.read_skip<uint32>(); // spline id // in taxi flight packet received in 2 case: // 1) end taxi path in far (multi-node) flight @@ -220,59 +219,32 @@ void WorldSession::HandleMoveSplineDoneOpcode(WorldPacket& recvData) // we need process only (1) uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination(); - if (!curDest) - return; - - TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest); - - // far teleport case - if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId()) + if (curDest) { - if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) - { - // short preparations to continue flight - FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); - - flight->SetCurrentNodeAfterTeleport(); - TaxiPathNodeEntry const& node = flight->GetPath()[flight->GetCurrentNode()]; - flight->SkipCurrentNode(); + TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest); - GetPlayer()->TeleportTo(curDestNode->map_id, node.LocX, node.LocY, node.LocZ, GetPlayer()->GetOrientation()); - } - return; - } - - uint32 destinationnode = GetPlayer()->m_taxi.NextTaxiDestination(); - if (destinationnode > 0) // if more destinations to go - { - // current source node for next destination - uint32 sourcenode = GetPlayer()->m_taxi.GetTaxiSource(); - - // Add to taximask middle hubs in taxicheat mode (to prevent having player with disabled taxicheat and not having back flight path) - if (GetPlayer()->isTaxiCheater()) + // far teleport case + if (curDestNode && curDestNode->map_id != GetPlayer()->GetMapId()) { - if (GetPlayer()->m_taxi.SetTaximaskNode(sourcenode)) + if (GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType() == FLIGHT_MOTION_TYPE) { - WorldPacket data(SMSG_NEW_TAXI_PATH, 0); - _player->GetSession()->SendPacket(&data); - } - } + // short preparations to continue flight + FlightPathMovementGenerator* flight = (FlightPathMovementGenerator*)(GetPlayer()->GetMotionMaster()->top()); - TC_LOG_DEBUG("network", "WORLD: Taxi has to go from %u to %u", sourcenode, destinationnode); + flight->SetCurrentNodeAfterTeleport(); + TaxiPathNodeEntry const* node = flight->GetPath()[flight->GetCurrentNode()]; + flight->SkipCurrentNode(); - uint32 mountDisplayId = sObjectMgr->GetTaxiMountDisplayId(sourcenode, GetPlayer()->GetTeam()); - - uint32 path, cost; - sObjectMgr->GetTaxiPath(sourcenode, destinationnode, path, cost); + GetPlayer()->TeleportTo(curDestNode->map_id, node->LocX, node->LocY, node->LocZ, GetPlayer()->GetOrientation()); + } + } - if (path && mountDisplayId) - SendDoFlight(mountDisplayId, path, 1); // skip start fly node - else - GetPlayer()->m_taxi.ClearTaxiDestinations(); // clear problematic path and next return; } - else - GetPlayer()->m_taxi.ClearTaxiDestinations(); // not destinations, clear source node + + // at this point only 1 node is expected (final destination) + if (GetPlayer()->m_taxi.GetPath().size() != 1) + return; GetPlayer()->CleanupAfterTaxiFlight(); GetPlayer()->SetFallInformation(0, GetPlayer()->GetPositionZ()); diff --git a/src/server/game/Handlers/TicketHandler.cpp b/src/server/game/Handlers/TicketHandler.cpp index f3b421a4b93..cf6181f02b4 100644 --- a/src/server/game/Handlers/TicketHandler.cpp +++ b/src/server/game/Handlers/TicketHandler.cpp @@ -217,7 +217,7 @@ void WorldSession::HandleGMSurveySubmit(WorldPacket& recvData) recvData >> comment; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_GM_SURVEY); - stmt->setUInt32(0, GetPlayer()->GetGUIDLow()); + stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter()); stmt->setUInt32(1, nextSurveyID); stmt->setUInt32(2, mainSurvey); stmt->setString(3, comment); @@ -240,7 +240,7 @@ void WorldSession::HandleReportLag(WorldPacket& recvData) recvData >> z; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_LAG_REPORT); - stmt->setUInt32(0, GetPlayer()->GetGUIDLow()); + stmt->setUInt32(0, GetPlayer()->GetGUID().GetCounter()); stmt->setUInt8 (1, lagType); stmt->setUInt16(2, mapId); stmt->setFloat (3, x); diff --git a/src/server/game/Handlers/TradeHandler.cpp b/src/server/game/Handlers/TradeHandler.cpp index c50888544de..fbfd16ae1c6 100644 --- a/src/server/game/Handlers/TradeHandler.cpp +++ b/src/server/game/Handlers/TradeHandler.cpp @@ -60,13 +60,13 @@ void WorldSession::SendTradeStatus(TradeStatusInfo const& info) void WorldSession::HandleIgnoreTradeOpcode(WorldPacket& /*recvPacket*/) { - TC_LOG_DEBUG("network", "WORLD: Ignore Trade %u", _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "WORLD: Ignore Trade %u", _player->GetGUID().GetCounter()); // recvPacket.print_storage(); } void WorldSession::HandleBusyTradeOpcode(WorldPacket& /*recvPacket*/) { - TC_LOG_DEBUG("network", "WORLD: Busy Trade %u", _player->GetGUIDLow()); + TC_LOG_DEBUG("network", "WORLD: Busy Trade %u", _player->GetGUID().GetCounter()); // recvPacket.print_storage(); } @@ -141,7 +141,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) if (myItems[i]) { // logging - TC_LOG_DEBUG("network", "partner storing: %u", myItems[i]->GetGUIDLow()); + TC_LOG_DEBUG("network", "partner storing: %u", myItems[i]->GetGUID().GetCounter()); if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(_player->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", @@ -159,7 +159,7 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) if (hisItems[i]) { // logging - TC_LOG_DEBUG("network", "player storing: %u", hisItems[i]->GetGUIDLow()); + TC_LOG_DEBUG("network", "player storing: %u", hisItems[i]->GetGUID().GetCounter()); if (HasPermission(rbac::RBAC_PERM_LOG_GM_TRADE)) { sLog->outCommand(trader->GetSession()->GetAccountId(), "GM %s (Account: %u) trade: %s (Entry: %d Count: %u) to player: %s (Account: %u)", @@ -182,21 +182,21 @@ void WorldSession::moveItems(Item* myItems[], Item* hisItems[]) if (myItems[i]) { if (!traderCanTrade) - TC_LOG_ERROR("network", "trader can't store item: %u", myItems[i]->GetGUIDLow()); + TC_LOG_ERROR("network", "trader can't store item: %u", myItems[i]->GetGUID().GetCounter()); if (_player->CanStoreItem(NULL_BAG, NULL_SLOT, playerDst, myItems[i], false) == EQUIP_ERR_OK) _player->MoveItemToInventory(playerDst, myItems[i], true, true); else - TC_LOG_ERROR("network", "player can't take item back: %u", myItems[i]->GetGUIDLow()); + TC_LOG_ERROR("network", "player can't take item back: %u", myItems[i]->GetGUID().GetCounter()); } // return the already removed items to the original owner if (hisItems[i]) { if (!playerCanTrade) - TC_LOG_ERROR("network", "player can't store item: %u", hisItems[i]->GetGUIDLow()); + TC_LOG_ERROR("network", "player can't store item: %u", hisItems[i]->GetGUID().GetCounter()); if (trader->CanStoreItem(NULL_BAG, NULL_SLOT, traderDst, hisItems[i], false) == EQUIP_ERR_OK) trader->MoveItemToInventory(traderDst, hisItems[i], true, true); else - TC_LOG_ERROR("network", "trader can't take item back: %u", hisItems[i]->GetGUIDLow()); + TC_LOG_ERROR("network", "trader can't take item back: %u", hisItems[i]->GetGUID().GetCounter()); } } } @@ -214,7 +214,7 @@ static void setAcceptTradeMode(TradeData* myTrade, TradeData* hisTrade, Item* *m { if (Item* item = myTrade->GetItem(TradeSlots(i))) { - TC_LOG_DEBUG("network", "player trade item %u bag: %u slot: %u", item->GetGUIDLow(), item->GetBagSlot(), item->GetSlot()); + TC_LOG_DEBUG("network", "player trade item %u bag: %u slot: %u", item->GetGUID().GetCounter(), item->GetBagSlot(), item->GetSlot()); //Can return NULL myItems[i] = item; myItems[i]->SetInTrade(); @@ -222,7 +222,7 @@ static void setAcceptTradeMode(TradeData* myTrade, TradeData* hisTrade, Item* *m if (Item* item = hisTrade->GetItem(TradeSlots(i))) { - TC_LOG_DEBUG("network", "partner trade item %u bag: %u slot: %u", item->GetGUIDLow(), item->GetBagSlot(), item->GetSlot()); + TC_LOG_DEBUG("network", "partner trade item %u bag: %u slot: %u", item->GetGUID().GetCounter(), item->GetBagSlot(), item->GetSlot()); hisItems[i] = item; hisItems[i]->SetInTrade(); } @@ -668,7 +668,7 @@ void WorldSession::HandleInitiateTradeOpcode(WorldPacket& recvPacket) return; } - if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUIDLow())) + if (pOther->GetSocial()->HasIgnore(GetPlayer()->GetGUID().GetCounter())) { info.Status = TRADE_STATUS_IGNORE_YOU; SendTradeStatus(info); diff --git a/src/server/game/Handlers/VehicleHandler.cpp b/src/server/game/Handlers/VehicleHandler.cpp index 6328eb3e2fe..3bb2ca78931 100644 --- a/src/server/game/Handlers/VehicleHandler.cpp +++ b/src/server/game/Handlers/VehicleHandler.cpp @@ -63,7 +63,7 @@ void WorldSession::HandleChangeSeatsOnControlledVehicle(WorldPacket &recvData) { recvData.rfinish(); // prevent warnings spam TC_LOG_ERROR("network", "HandleChangeSeatsOnControlledVehicle, Opcode: %u, Player %u tried to switch seats but current seatflags %u don't permit that.", - recvData.GetOpcode(), GetPlayer()->GetGUIDLow(), seat->m_flags); + recvData.GetOpcode(), GetPlayer()->GetGUID().GetCounter(), seat->m_flags); return; } @@ -176,7 +176,7 @@ void WorldSession::HandleEjectPassenger(WorldPacket &data) if (seat->IsEjectable()) unit->ExitVehicle(); else - TC_LOG_ERROR("network", "Player %u attempted to eject %s from non-ejectable seat.", GetPlayer()->GetGUIDLow(), guid.ToString().c_str()); + TC_LOG_ERROR("network", "Player %u attempted to eject %s from non-ejectable seat.", GetPlayer()->GetGUID().GetCounter(), guid.ToString().c_str()); } else TC_LOG_ERROR("network", "HandleEjectPassenger: %s tried to eject invalid %s ", GetPlayer()->GetGUID().ToString().c_str(), guid.ToString().c_str()); @@ -194,7 +194,7 @@ void WorldSession::HandleRequestVehicleExit(WorldPacket& /*recvData*/) GetPlayer()->ExitVehicle(); else TC_LOG_ERROR("network", "Player %u tried to exit vehicle, but seatflags %u (ID: %u) don't permit that.", - GetPlayer()->GetGUIDLow(), seat->m_ID, seat->m_flags); + GetPlayer()->GetGUID().GetCounter(), seat->m_ID, seat->m_flags); } } } diff --git a/src/server/game/Instances/InstanceSaveMgr.cpp b/src/server/game/Instances/InstanceSaveMgr.cpp index b8a2168b34e..b3dd3e9f01f 100644 --- a/src/server/game/Instances/InstanceSaveMgr.cpp +++ b/src/server/game/Instances/InstanceSaveMgr.cpp @@ -555,7 +555,10 @@ void InstanceSaveManager::_ResetInstance(uint32 mapid, uint32 instanceId) ((InstanceMap*)iMap)->Reset(INSTANCE_RESET_RESPAWN_DELAY); if (iMap) + { iMap->DeleteRespawnTimes(); + iMap->DeleteCorpseData(); + } else Map::DeleteRespawnTimesInDB(mapid, instanceId); diff --git a/src/server/game/Instances/InstanceScript.h b/src/server/game/Instances/InstanceScript.h index 3e90e430590..e832d7cdffe 100644 --- a/src/server/game/Instances/InstanceScript.h +++ b/src/server/game/Instances/InstanceScript.h @@ -174,11 +174,11 @@ class InstanceScript : public ZoneScript inline Creature* GetCreature(uint32 type) { - return ObjectAccessor::GetObjectInMap<Creature>(GetObjectGuid(type), instance, nullptr); + return instance->GetCreature(GetObjectGuid(type)); } inline GameObject* GetGameObject(uint32 type) { - return ObjectAccessor::GetObjectInMap<GameObject>(GetObjectGuid(type), instance, nullptr); + return instance->GetGameObject(GetObjectGuid(type)); } // Called when a player successfully enters the instance. diff --git a/src/server/game/Loot/LootMgr.cpp b/src/server/game/Loot/LootMgr.cpp index c825db1e1eb..22ebe6c679e 100644 --- a/src/server/game/Loot/LootMgr.cpp +++ b/src/server/game/Loot/LootMgr.cpp @@ -399,7 +399,7 @@ bool LootItem::AllowedForPlayer(Player const* player) const void LootItem::AddAllowedLooter(const Player* player) { - allowedGUIDs.insert(player->GetGUIDLow()); + allowedGUIDs.insert(player->GetGUID().GetCounter()); } // @@ -481,7 +481,7 @@ bool Loot::FillLoot(uint32 lootId, LootStore const& store, Player* lootOwner, bo void Loot::FillNotNormalLootFor(Player* player, bool presentAtLooting) { - uint32 plguid = player->GetGUIDLow(); + uint32 plguid = player->GetGUID().GetCounter(); QuestItemMap::const_iterator qmapitr = PlayerQuestItems.find(plguid); if (qmapitr == PlayerQuestItems.end()) @@ -536,7 +536,7 @@ QuestItemList* Loot::FillFFALoot(Player* player) return NULL; } - PlayerFFAItems[player->GetGUIDLow()] = ql; + PlayerFFAItems[player->GetGUID().GetCounter()] = ql; return ql; } @@ -574,7 +574,7 @@ QuestItemList* Loot::FillQuestLoot(Player* player) return NULL; } - PlayerQuestItems[player->GetGUIDLow()] = ql; + PlayerQuestItems[player->GetGUID().GetCounter()] = ql; return ql; } @@ -606,7 +606,7 @@ QuestItemList* Loot::FillNonQuestNonFFAConditionalLoot(Player* player, bool pres return NULL; } - PlayerNonQuestNonFFAConditionalItems[player->GetGUIDLow()] = ql; + PlayerNonQuestNonFFAConditionalItems[player->GetGUID().GetCounter()] = ql; return ql; } @@ -657,7 +657,7 @@ void Loot::NotifyQuestItemRemoved(uint8 questIndex) ++i_next; if (Player* player = ObjectAccessor::FindPlayer(*i)) { - QuestItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator pq = PlayerQuestItems.find(player->GetGUID().GetCounter()); if (pq != PlayerQuestItems.end() && pq->second) { // find where/if the player has the given item in it's vector @@ -724,7 +724,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite if (lootSlot >= items.size()) { uint32 questSlot = lootSlot - items.size(); - QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); if (itr != PlayerQuestItems.end() && questSlot < itr->second->size()) { QuestItem* qitem2 = &itr->second->at(questSlot); @@ -740,7 +740,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite is_looted = item->is_looted; if (item->freeforall) { - QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator itr = PlayerFFAItems.find(player->GetGUID().GetCounter()); if (itr != PlayerFFAItems.end()) { for (QuestItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) @@ -756,7 +756,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite } else if (!item->conditions.empty()) { - QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator itr = PlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); if (itr != PlayerNonQuestNonFFAConditionalItems.end()) { for (QuestItemList::const_iterator iter=itr->second->begin(); iter!= itr->second->end(); ++iter) @@ -782,7 +782,7 @@ LootItem* Loot::LootItemInSlot(uint32 lootSlot, Player* player, QuestItem* *qite uint32 Loot::GetMaxSlotInLootFor(Player* player) const { - QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator itr = PlayerQuestItems.find(player->GetGUID().GetCounter()); return items.size() + (itr != PlayerQuestItems.end() ? itr->second->size() : 0); } @@ -790,7 +790,7 @@ uint32 Loot::GetMaxSlotInLootFor(Player* player) const bool Loot::hasItemFor(Player* player) const { QuestItemMap const& lootPlayerQuestItems = GetPlayerQuestItems(); - QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(player->GetGUID().GetCounter()); if (q_itr != lootPlayerQuestItems.end()) { QuestItemList* q_list = q_itr->second; @@ -803,7 +803,7 @@ bool Loot::hasItemFor(Player* player) const } QuestItemMap const& lootPlayerFFAItems = GetPlayerFFAItems(); - QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(player->GetGUID().GetCounter()); if (ffa_itr != lootPlayerFFAItems.end()) { QuestItemList* ffa_list = ffa_itr->second; @@ -816,7 +816,7 @@ bool Loot::hasItemFor(Player* player) const } QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = GetPlayerNonQuestNonFFAConditionalItems(); - QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUIDLow()); + QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(player->GetGUID().GetCounter()); if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) { QuestItemList* conditional_list = nn_itr->second; @@ -964,7 +964,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) LootSlotType slotType = lv.permission == OWNER_PERMISSION ? LOOT_SLOT_TYPE_OWNER : LOOT_SLOT_TYPE_ALLOW_LOOT; QuestItemMap const& lootPlayerQuestItems = l.GetPlayerQuestItems(); - QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUIDLow()); + QuestItemMap::const_iterator q_itr = lootPlayerQuestItems.find(lv.viewer->GetGUID().GetCounter()); if (q_itr != lootPlayerQuestItems.end()) { QuestItemList* q_list = q_itr->second; @@ -1005,7 +1005,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) } QuestItemMap const& lootPlayerFFAItems = l.GetPlayerFFAItems(); - QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUIDLow()); + QuestItemMap::const_iterator ffa_itr = lootPlayerFFAItems.find(lv.viewer->GetGUID().GetCounter()); if (ffa_itr != lootPlayerFFAItems.end()) { QuestItemList* ffa_list = ffa_itr->second; @@ -1023,7 +1023,7 @@ ByteBuffer& operator<<(ByteBuffer& b, LootView const& lv) } QuestItemMap const& lootPlayerNonQuestNonFFAConditionalItems = l.GetPlayerNonQuestNonFFAConditionalItems(); - QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUIDLow()); + QuestItemMap::const_iterator nn_itr = lootPlayerNonQuestNonFFAConditionalItems.find(lv.viewer->GetGUID().GetCounter()); if (nn_itr != lootPlayerNonQuestNonFFAConditionalItems.end()) { QuestItemList* conditional_list = nn_itr->second; diff --git a/src/server/game/Mails/Mail.cpp b/src/server/game/Mails/Mail.cpp index e8eec55ed12..fd9392fb62f 100644 --- a/src/server/game/Mails/Mail.cpp +++ b/src/server/game/Mails/Mail.cpp @@ -45,7 +45,7 @@ MailSender::MailSender(Object* sender, MailStationery stationery) : m_stationery break;*/ case TYPEID_PLAYER: m_messageType = MAIL_NORMAL; - m_senderId = sender->GetGUIDLow(); + m_senderId = sender->GetGUID().GetCounter(); break; default: m_messageType = MAIL_NORMAL; @@ -67,19 +67,19 @@ MailSender::MailSender(Player* sender) { m_messageType = MAIL_NORMAL; m_stationery = sender->IsGameMaster() ? MAIL_STATIONERY_GM : MAIL_STATIONERY_DEFAULT; - m_senderId = sender->GetGUIDLow(); + m_senderId = sender->GetGUID().GetCounter(); } -MailReceiver::MailReceiver(Player* receiver) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUIDLow()) { } +MailReceiver::MailReceiver(Player* receiver) : m_receiver(receiver), m_receiver_lowguid(receiver->GetGUID().GetCounter()) { } MailReceiver::MailReceiver(Player* receiver, uint32 receiver_lowguid) : m_receiver(receiver), m_receiver_lowguid(receiver_lowguid) { - ASSERT(!receiver || receiver->GetGUIDLow() == receiver_lowguid); + ASSERT(!receiver || receiver->GetGUID().GetCounter() == receiver_lowguid); } MailDraft& MailDraft::AddItem(Item* item) { - m_items[item->GetGUIDLow()] = item; return *this; + m_items[item->GetGUID().GetCounter()] = item; return *this; } void MailDraft::prepareItems(Player* receiver, SQLTransaction& trans) @@ -117,7 +117,7 @@ void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/ if (inDB) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_ITEM_INSTANCE); - stmt->setUInt32(0, item->GetGUIDLow()); + stmt->setUInt32(0, item->GetGUID().GetCounter()); trans->Append(stmt); } @@ -129,7 +129,7 @@ void MailDraft::deleteIncludedItems(SQLTransaction& trans, bool inDB /*= false*/ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 receiver_guid, SQLTransaction& trans) { - ObjectGuid receiverGuid(HIGHGUID_PLAYER, receiver_guid); + ObjectGuid receiverGuid(HighGuid::Player, receiver_guid); Player* receiver = ObjectAccessor::FindConnectedPlayer(receiverGuid); uint32 rc_account = 0; @@ -158,7 +158,7 @@ void MailDraft::SendReturnToSender(uint32 sender_acc, uint32 sender_guid, uint32 // owner in data will set at mail receive and item extracting PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_ITEM_OWNER); stmt->setUInt32(0, receiver_guid); - stmt->setUInt32(1, item->GetGUIDLow()); + stmt->setUInt32(1, item->GetGUID().GetCounter()); trans->Append(stmt); } } @@ -226,7 +226,7 @@ void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, Item* pItem = mailItemIter->second; stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_MAIL_ITEM); stmt->setUInt32(0, mailId); - stmt->setUInt32(1, pItem->GetGUIDLow()); + stmt->setUInt32(1, pItem->GetGUID().GetCounter()); stmt->setUInt32(2, receiver.GetPlayerGUIDLow()); trans->Append(stmt); } @@ -249,7 +249,7 @@ void MailDraft::SendMailTo(SQLTransaction& trans, MailReceiver const& receiver, for (MailItemMap::const_iterator mailItemIter = m_items.begin(); mailItemIter != m_items.end(); ++mailItemIter) { Item* item = mailItemIter->second; - m->AddItem(item->GetGUIDLow(), item->GetEntry()); + m->AddItem(item->GetGUID().GetCounter(), item->GetEntry()); } m->messageType = sender.GetMailMessageType(); diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 354bbe4e269..2af77ffdec3 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -50,9 +50,9 @@ GridState* si_GridStates[MAX_GRID_STATE]; Map::~Map() { - sScriptMgr->OnDestroyMap(this); + // UnloadAll must be called before deleting the map - UnloadAll(); + sScriptMgr->OnDestroyMap(this); while (!i_worldObjects.empty()) { @@ -400,11 +400,18 @@ void Map::DeleteFromWorld(T* obj) template<> void Map::DeleteFromWorld(Player* player) { - sObjectAccessor->RemoveObject(player); - sObjectAccessor->RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway + ObjectAccessor::RemoveObject(player); + RemoveUpdateObject(player); /// @todo I do not know why we need this, it should be removed in ~Object anyway delete player; } +template<> +void Map::DeleteFromWorld(Transport* transport) +{ + ObjectAccessor::RemoveObject(transport); + delete transport; +} + void Map::EnsureGridCreated(const GridCoord &p) { std::lock_guard<std::mutex> lock(_gridLock); @@ -468,8 +475,6 @@ bool Map::EnsureGridLoaded(const Cell &cell) ObjectGridLoader loader(*grid, this, cell); loader.LoadN(); - // Add resurrectable corpses to world object list in grid - sObjectAccessor->AddCorpsesToGrid(GridCoord(cell.GridX(), cell.GridY()), grid->GetGridType(cell.CellX(), cell.CellY()), this); Balance(); return true; } @@ -487,7 +492,7 @@ bool Map::AddPlayerToMap(Player* player) CellCoord cellCoord = Trinity::ComputeCellCoord(player->GetPositionX(), player->GetPositionY()); if (!cellCoord.IsCoordValid()) { - TC_LOG_ERROR("maps", "Map::Add: Player (GUID: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUIDLow(), player->GetPositionX(), player->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord); + TC_LOG_ERROR("maps", "Map::Add: Player (GUID: %u) has invalid coordinates X:%f Y:%f grid cell [%u:%u]", player->GetGUID().GetCounter(), player->GetPositionX(), player->GetPositionY(), cellCoord.x_coord, cellCoord.y_coord); return false; } @@ -507,6 +512,9 @@ bool Map::AddPlayerToMap(Player* player) player->m_clientGUIDs.clear(); player->UpdateObjectVisibility(false); + if (player->IsAlive()) + ConvertCorpseToBones(player->GetGUID()); + sScriptMgr->OnPlayerEnterMap(this, player); return true; } @@ -678,6 +686,26 @@ void Map::Update(const uint32 t_diff) player->Update(t_diff); VisitNearbyCellsOf(player, grid_object_update, world_object_update); + + // Handle updates for creatures in combat with player and are more than 60 yards away + if (player->IsInCombat()) + { + std::vector<Creature*> updateList; + HostileReference* ref = player->getHostileRefManager().getFirst(); + + while (ref) + { + if (Unit* unit = ref->GetSource()->GetOwner()) + if (unit->ToCreature() && unit->GetMapId() == player->GetMapId() && !unit->IsWithinDistInMap(player, GetVisibilityRange(), false)) + updateList.push_back(unit->ToCreature()); + + ref = ref->next(); + } + + // Process deferred update list for player + for (Creature* c : updateList) + VisitNearbyCellsOf(c, grid_object_update, world_object_update); + } } // non-player active objects, increasing iterator in the loop in case of object removal @@ -703,6 +731,8 @@ void Map::Update(const uint32 t_diff) obj->Update(t_diff); } + SendObjectUpdates(); + ///- Process necessary scripts if (!m_scriptSchedule.empty()) { @@ -939,7 +969,7 @@ void Map::CreatureRelocation(Creature* creature, float x, float y, float z, floa if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell)) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", creature->GetGUIDLow(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", creature->GetGUID().GetCounter(), creature->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif AddCreatureToMoveList(creature, x, y, z, ang); // in diffcell/diffgrid case notifiers called at finishing move creature in Map::MoveAllCreaturesInMoveList @@ -971,7 +1001,7 @@ void Map::GameObjectRelocation(GameObject* go, float x, float y, float z, float if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell)) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif AddGameObjectToMoveList(go, x, y, z, orientation); // in diffcell/diffgrid case notifiers called at finishing move go in Map::MoveAllGameObjectsInMoveList @@ -1004,7 +1034,7 @@ void Map::DynamicObjectRelocation(DynamicObject* dynObj, float x, float y, float if (old_cell.DiffCell(new_cell) || old_cell.DiffGrid(new_cell)) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", dynObj->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u) added to moving list from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", dynObj->GetGUID().GetCounter(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif AddDynamicObjectToMoveList(dynObj, x, y, z, orientation); // in diffcell/diffgrid case notifiers called at finishing move dynObj in Map::MoveAllGameObjectsInMoveList @@ -1115,7 +1145,7 @@ void Map::MoveAllCreaturesInMoveList() { // ... or unload (if respawn grid also not loaded) #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) cannot be move to unloaded respawn grid.", c->GetGUIDLow(), c->GetEntry()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) cannot be move to unloaded respawn grid.", c->GetGUID().GetCounter(), c->GetEntry()); #endif //AddObjectToRemoveList(Pet*) should only be called in Pet::Remove //This may happen when a player just logs in and a pet moves to a nearby unloaded cell @@ -1169,7 +1199,7 @@ void Map::MoveAllGameObjectsInMoveList() { // ... or unload (if respawn grid also not loaded) #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) cannot be move to unloaded respawn grid.", go->GetGUIDLow(), go->GetEntry()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) cannot be move to unloaded respawn grid.", go->GetGUID().GetCounter(), go->GetEntry()); #endif AddObjectToRemoveList(go); } @@ -1208,7 +1238,7 @@ void Map::MoveAllDynamicObjectsInMoveList() else { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) cannot be moved to unloaded grid.", dynObj->GetGUIDLow()); + TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) cannot be moved to unloaded grid.", dynObj->GetGUID().GetCounter()); #endif } } @@ -1226,7 +1256,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) if (old_cell.DiffCell(new_cell)) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", c->GetGUID().GetCounter(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); #endif c->RemoveFromGrid(); @@ -1235,7 +1265,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) else { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved in same grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved in same grid[%u, %u]cell[%u, %u].", c->GetGUID().GetCounter(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); #endif } @@ -1248,7 +1278,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) EnsureGridLoadedForActiveObject(new_cell, c); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Active creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Active creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", c->GetGUID().GetCounter(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif c->RemoveFromGrid(); @@ -1261,7 +1291,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY()))) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", c->GetGUID().GetCounter(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif c->RemoveFromGrid(); @@ -1273,7 +1303,7 @@ bool Map::CreatureCellRelocation(Creature* c, Cell new_cell) // fail to move: normal creature attempt move to unloaded grid #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", c->GetGUID().GetCounter(), c->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif return false; } @@ -1287,7 +1317,7 @@ bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell) if (old_cell.DiffCell(new_cell)) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); #endif go->RemoveFromGrid(); @@ -1296,7 +1326,7 @@ bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell) else { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved in same grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved in same grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); #endif } @@ -1309,7 +1339,7 @@ bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell) EnsureGridLoadedForActiveObject(new_cell, go); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Active GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Active GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif go->RemoveFromGrid(); @@ -1322,7 +1352,7 @@ bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell) if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY()))) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif go->RemoveFromGrid(); @@ -1334,7 +1364,7 @@ bool Map::GameObjectCellRelocation(GameObject* go, Cell new_cell) // fail to move: normal GameObject attempt move to unloaded grid #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif return false; } @@ -1348,7 +1378,7 @@ bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell) if (old_cell.DiffCell(new_cell)) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved in grid[%u, %u] from cell[%u, %u] to cell[%u, %u].", go->GetGUID().GetCounter(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.CellX(), new_cell.CellY()); #endif go->RemoveFromGrid(); @@ -1357,7 +1387,7 @@ bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell) else { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved in same grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); + TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved in same grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY()); #endif } @@ -1370,7 +1400,7 @@ bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell) EnsureGridLoadedForActiveObject(new_cell, go); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Active DynamicObject (GUID: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "Active DynamicObject (GUID: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif go->RemoveFromGrid(); @@ -1383,7 +1413,7 @@ bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell) if (IsGridLoaded(GridCoord(new_cell.GridX(), new_cell.GridY()))) { #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) moved from grid[%u, %u]cell[%u, %u] to grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif go->RemoveFromGrid(); @@ -1395,7 +1425,7 @@ bool Map::DynamicObjectCellRelocation(DynamicObject* go, Cell new_cell) // fail to move: normal GameObject attempt move to unloaded grid #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); + TC_LOG_DEBUG("maps", "DynamicObject (GUID: %u) attempted to move from grid[%u, %u]cell[%u, %u] to unloaded grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), old_cell.GridX(), old_cell.GridY(), old_cell.CellX(), old_cell.CellY(), new_cell.GridX(), new_cell.GridY(), new_cell.CellX(), new_cell.CellY()); #endif return false; } @@ -1414,7 +1444,7 @@ bool Map::CreatureRespawnRelocation(Creature* c, bool diffGridOnly) c->GetMotionMaster()->Clear(); #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to respawn grid[%u, %u]cell[%u, %u].", c->GetGUIDLow(), c->GetEntry(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); + TC_LOG_DEBUG("maps", "Creature (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to respawn grid[%u, %u]cell[%u, %u].", c->GetGUID().GetCounter(), c->GetEntry(), c->GetCurrentCell().GridX(), c->GetCurrentCell().GridY(), c->GetCurrentCell().CellX(), c->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); #endif // teleport it to respawn point (like normal respawn if player see) @@ -1441,7 +1471,7 @@ bool Map::GameObjectRespawnRelocation(GameObject* go, bool diffGridOnly) return true; #ifdef TRINITY_DEBUG - TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to respawn grid[%u, %u]cell[%u, %u].", go->GetGUIDLow(), go->GetEntry(), go->GetCurrentCell().GridX(), go->GetCurrentCell().GridY(), go->GetCurrentCell().CellX(), go->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); + TC_LOG_DEBUG("maps", "GameObject (GUID: %u Entry: %u) moved from grid[%u, %u]cell[%u, %u] to respawn grid[%u, %u]cell[%u, %u].", go->GetGUID().GetCounter(), go->GetEntry(), go->GetCurrentCell().GridX(), go->GetCurrentCell().GridY(), go->GetCurrentCell().CellX(), go->GetCurrentCell().CellY(), resp_cell.GridX(), resp_cell.GridY(), resp_cell.CellX(), resp_cell.CellY()); #endif // teleport it to respawn point (like normal respawn if player see) @@ -2477,7 +2507,7 @@ bool Map::CheckGridIntegrity(Creature* c, bool moved) const if (xy_cell != cur_cell) { TC_LOG_DEBUG("maps", "Creature (GUID: %u) X: %f Y: %f (%s) is in grid[%u, %u]cell[%u, %u] instead of grid[%u, %u]cell[%u, %u]", - c->GetGUIDLow(), + c->GetGUID().GetCounter(), c->GetPositionX(), c->GetPositionY(), (moved ? "final" : "original"), cur_cell.GridX(), cur_cell.GridY(), cur_cell.CellX(), cur_cell.CellY(), xy_cell.GridX(), xy_cell.GridY(), xy_cell.CellX(), xy_cell.CellY()); @@ -2516,7 +2546,7 @@ void Map::UpdateObjectsVisibilityFor(Player* player, Cell cell, CellCoord cellpa void Map::SendInitSelf(Player* player) { - TC_LOG_DEBUG("maps", "Creating player data for himself %u", player->GetGUIDLow()); + TC_LOG_DEBUG("maps", "Creating player data for himself %u", player->GetGUID().GetCounter()); UpdateData data; @@ -2571,11 +2601,33 @@ inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y) if (x >= MAX_NUMBER_OF_GRIDS || y >= MAX_NUMBER_OF_GRIDS) { TC_LOG_ERROR("maps", "map::setNGrid() Invalid grid coordinates found: %d, %d!", x, y); - ASSERT(false); + ABORT(); } i_grids[x][y] = grid; } +void Map::SendObjectUpdates() +{ + UpdateDataMapType update_players; + + while (!_updateObjects.empty()) + { + Object* obj = *_updateObjects.begin(); + ASSERT(obj->IsInWorld()); + + _updateObjects.erase(_updateObjects.begin()); + obj->BuildUpdate(update_players); + } + + WorldPacket packet; // here we allocate a std::vector with a size of 0x10000 + for (UpdateDataMapType::iterator iter = update_players.begin(); iter != update_players.end(); ++iter) + { + iter->second.BuildPacket(&packet); + iter->first->GetSession()->SendPacket(&packet); + packet.clear(); // clean the string + } +} + void Map::DelayedUpdate(const uint32 t_diff) { for (_transportsUpdateIter = _transports.begin(); _transportsUpdateIter != _transports.end();) @@ -2613,7 +2665,7 @@ void Map::AddObjectToRemoveList(WorldObject* obj) obj->CleanupsBeforeDelete(false); // remove or simplify at least cross referenced links i_objectsToRemove.insert(obj); - //TC_LOG_DEBUG("maps", "Object (GUID: %u TypeId: %u) added to removing list.", obj->GetGUIDLow(), obj->GetTypeId()); + //TC_LOG_DEBUG("maps", "Object (GUID: %u TypeId: %u) added to removing list.", obj->GetGUID().GetCounter(), obj->GetTypeId()); } void Map::AddObjectToSwitchList(WorldObject* obj, bool on) @@ -2630,7 +2682,7 @@ void Map::AddObjectToSwitchList(WorldObject* obj, bool on) else if (itr->second != on) i_objectsToSwitch.erase(itr); else - ASSERT(false); + ABORT(); } void Map::RemoveAllObjectsInRemoveList() @@ -2670,7 +2722,7 @@ void Map::RemoveAllObjectsInRemoveList() { Corpse* corpse = ObjectAccessor::GetCorpse(*obj, obj->GetGUID()); if (!corpse) - TC_LOG_ERROR("maps", "Tried to delete corpse/bones %u that is not in map.", obj->GetGUIDLow()); + TC_LOG_ERROR("maps", "Tried to delete corpse/bones %u that is not in map.", obj->GetGUID().GetCounter()); else RemoveFromMap(corpse, true); break; @@ -2768,7 +2820,7 @@ void Map::AddToActive(Creature* c) AddToActiveHelper(c); // also not allow unloading spawn grid to prevent creating creature clone at load - if (!c->IsPet() && c->GetDBTableGUIDLow()) + if (!c->IsPet() && c->GetSpawnId()) { float x, y, z; c->GetRespawnPosition(x, y, z); @@ -2779,7 +2831,7 @@ void Map::AddToActive(Creature* c) { GridCoord p2 = Trinity::ComputeGridCoord(c->GetPositionX(), c->GetPositionY()); TC_LOG_ERROR("maps", "Active creature (GUID: %u Entry: %u) added to grid[%u, %u] but spawn grid[%u, %u] was not loaded.", - c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); + c->GetGUID().GetCounter(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); } } } @@ -2799,7 +2851,7 @@ void Map::RemoveFromActive(Creature* c) RemoveFromActiveHelper(c); // also allow unloading spawn grid - if (!c->IsPet() && c->GetDBTableGUIDLow()) + if (!c->IsPet() && c->GetSpawnId()) { float x, y, z; c->GetRespawnPosition(x, y, z); @@ -2810,7 +2862,7 @@ void Map::RemoveFromActive(Creature* c) { GridCoord p2 = Trinity::ComputeGridCoord(c->GetPositionX(), c->GetPositionY()); TC_LOG_ERROR("maps", "Active creature (GUID: %u Entry: %u) removed from grid[%u, %u] but spawn grid[%u, %u] was not loaded.", - c->GetGUIDLow(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); + c->GetGUID().GetCounter(), c->GetEntry(), p.x_coord, p.y_coord, p2.x_coord, p2.y_coord); } } } @@ -2866,8 +2918,8 @@ bool InstanceMap::CanEnter(Player* player) { if (player->GetMapRef().getTarget() == this) { - TC_LOG_ERROR("maps", "InstanceMap::CanEnter - player %s(%u) already in map %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetId(), GetInstanceId(), GetSpawnMode()); - ASSERT(false); + TC_LOG_ERROR("maps", "InstanceMap::CanEnter - player %s(%u) already in map %d, %d, %d!", player->GetName().c_str(), player->GetGUID().GetCounter(), GetId(), GetInstanceId(), GetSpawnMode()); + ABORT(); return false; } @@ -2961,7 +3013,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) // cannot enter other instances if bound permanently if (playerBind->save != mapSave) { - TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is permanently bound to instance %s %d, %d, %d, %d, %d, %d but he is being put into instance %s %d, %d, %d, %d, %d, %d", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset()); + TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is permanently bound to instance %s %d, %d, %d, %d, %d, %d but he is being put into instance %s %d, %d, %d, %d, %d, %d", player->GetName().c_str(), player->GetGUID().GetCounter(), GetMapName(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset()); return false; } } @@ -2973,10 +3025,10 @@ bool InstanceMap::AddPlayerToMap(Player* player) InstanceGroupBind* groupBind = group->GetBoundInstance(this); if (playerBind && playerBind->save != mapSave) { - TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); + TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %s %d, %d, %d, %d, %d, %d but he is in group %s and is bound to instance %d, %d, %d, %d, %d, %d!", player->GetName().c_str(), player->GetGUID().GetCounter(), GetMapName(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), mapSave->GetPlayerCount(), mapSave->GetGroupCount(), mapSave->CanReset(), group->GetLeaderGUID().ToString().c_str(), playerBind->save->GetMapId(), playerBind->save->GetInstanceId(), playerBind->save->GetDifficulty(), playerBind->save->GetPlayerCount(), playerBind->save->GetGroupCount(), playerBind->save->CanReset()); if (groupBind) TC_LOG_ERROR("maps", "InstanceMap::Add: the group is bound to the instance %s %d, %d, %d, %d, %d, %d", GetMapName(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty(), groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount(), groupBind->save->CanReset()); - //ASSERT(false); + //ABORT(); return false; } // bind to the group or keep using the group save @@ -2987,7 +3039,7 @@ bool InstanceMap::AddPlayerToMap(Player* player) // cannot jump to a different instance without resetting it if (groupBind->save != mapSave) { - TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUIDLow(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); + TC_LOG_ERROR("maps", "InstanceMap::Add: player %s(%d) is being put into instance %d, %d, %d but he is in group %s which is bound to instance %d, %d, %d!", player->GetName().c_str(), player->GetGUID().GetCounter(), mapSave->GetMapId(), mapSave->GetInstanceId(), mapSave->GetDifficulty(), group->GetLeaderGUID().ToString().c_str(), groupBind->save->GetMapId(), groupBind->save->GetInstanceId(), groupBind->save->GetDifficulty()); TC_LOG_ERROR("maps", "MapSave players: %d, group count: %d", mapSave->GetPlayerCount(), mapSave->GetGroupCount()); if (groupBind->save) TC_LOG_ERROR("maps", "GroupBind save players: %d, group count: %d", groupBind->save->GetPlayerCount(), groupBind->save->GetGroupCount()); @@ -3146,7 +3198,7 @@ void InstanceMap::PermBindAllPlayers(Player* source) InstanceSave* save = sInstanceSaveMgr->GetInstanceSave(GetInstanceId()); if (!save) { - TC_LOG_ERROR("maps", "Cannot bind player (GUID: %u, Name: %s), because no instance save is available for instance map (Name: %s, Entry: %u, InstanceId: %u)!", source->GetGUIDLow(), source->GetName().c_str(), source->GetMap()->GetMapName(), source->GetMapId(), GetInstanceId()); + TC_LOG_ERROR("maps", "Cannot bind player (GUID: %u, Name: %s), because no instance save is available for instance map (Name: %s, Entry: %u, InstanceId: %u)!", source->GetGUID().GetCounter(), source->GetName().c_str(), source->GetMap()->GetMapName(), source->GetMapId(), GetInstanceId()); return; } @@ -3179,7 +3231,10 @@ void InstanceMap::UnloadAll() ASSERT(!HavePlayers()); if (m_resetAfterUnload == true) + { DeleteRespawnTimes(); + DeleteCorpseData(); + } Map::UnloadAll(); } @@ -3255,8 +3310,8 @@ bool BattlegroundMap::CanEnter(Player* player) { if (player->GetMapRef().getTarget() == this) { - TC_LOG_ERROR("maps", "BGMap::CanEnter - player %u is already in map!", player->GetGUIDLow()); - ASSERT(false); + TC_LOG_ERROR("maps", "BGMap::CanEnter - player %u is already in map!", player->GetGUID().GetCounter()); + ABORT(); return false; } @@ -3301,17 +3356,27 @@ void BattlegroundMap::RemoveAllPlayers() player->TeleportTo(player->GetBattlegroundEntryPoint()); } -Creature* Map::GetCreature(ObjectGuid guid) +Corpse* Map::GetCorpse(ObjectGuid const& guid) +{ + return _objectsStore.Find<Corpse>(guid); +} + +Creature* Map::GetCreature(ObjectGuid const& guid) +{ + return _objectsStore.Find<Creature>(guid); +} + +GameObject* Map::GetGameObject(ObjectGuid const& guid) { - return ObjectAccessor::GetObjectInMap(guid, this, (Creature*)NULL); + return _objectsStore.Find<GameObject>(guid); } -GameObject* Map::GetGameObject(ObjectGuid guid) +Pet* Map::GetPet(ObjectGuid const& guid) { - return ObjectAccessor::GetObjectInMap(guid, this, (GameObject*)NULL); + return _objectsStore.Find<Pet>(guid); } -Transport* Map::GetTransport(ObjectGuid guid) +Transport* Map::GetTransport(ObjectGuid const& guid) { if (!guid.IsMOTransport()) return NULL; @@ -3320,9 +3385,9 @@ Transport* Map::GetTransport(ObjectGuid guid) return go ? go->ToTransport() : NULL; } -DynamicObject* Map::GetDynamicObject(ObjectGuid guid) +DynamicObject* Map::GetDynamicObject(ObjectGuid const& guid) { - return ObjectAccessor::GetObjectInMap(guid, this, (DynamicObject*)NULL); + return _objectsStore.Find<DynamicObject>(guid); } void Map::UpdateIteratorBack(Player* player) @@ -3450,9 +3515,9 @@ time_t Map::GetLinkedRespawnTime(ObjectGuid guid) const ObjectGuid linkedGuid = sObjectMgr->GetLinkedRespawnGuid(guid); switch (linkedGuid.GetHigh()) { - case HIGHGUID_UNIT: + case HighGuid::Unit: return GetCreatureRespawnTime(linkedGuid.GetCounter()); - case HIGHGUID_GAMEOBJECT: + case HighGuid::GameObject: return GetGORespawnTime(linkedGuid.GetCounter()); default: break; @@ -3461,6 +3526,142 @@ time_t Map::GetLinkedRespawnTime(ObjectGuid guid) const return time_t(0); } +void Map::LoadCorpseData() +{ + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CORPSES); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, GetInstanceId()); + + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + // SELECT posX, posY, posZ, orientation, mapId, displayId, itemCache, bytes1, bytes2, guildId, flags, dynFlags, time, corpseType, instanceId, phaseMask, guid FROM corpse WHERE mapId = ? AND instanceId = ? + PreparedQueryResult result = CharacterDatabase.Query(stmt); + if (!result) + return; + + do + { + Field* fields = result->Fetch(); + CorpseType type = CorpseType(fields[13].GetUInt8()); + uint32 guid = fields[16].GetUInt32(); + if (type >= MAX_CORPSE_TYPE || type == CORPSE_BONES) + { + TC_LOG_ERROR("misc", "Corpse (guid: %u) have wrong corpse type (%u), not loading.", guid, type); + continue; + } + + Corpse* corpse = new Corpse(type); + + if (!corpse->LoadCorpseFromDB(GenerateLowGuid<HighGuid::Corpse>(), fields)) + { + delete corpse; + continue; + } + + AddCorpse(corpse); + + } while (result->NextRow()); +} + +void Map::DeleteCorpseData() +{ + // DELETE FROM corpse WHERE mapId = ? AND instanceId = ? + PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CORPSES_FROM_MAP); + stmt->setUInt32(0, GetId()); + stmt->setUInt32(1, GetInstanceId()); + CharacterDatabase.Execute(stmt); +} + +void Map::AddCorpse(Corpse* corpse) +{ + corpse->SetMap(this); + + CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY()); + _corpsesByCell[cellCoord.GetId()].insert(corpse); + _corpsesByPlayer[corpse->GetOwnerGUID()] = corpse; +} + +void Map::RemoveCorpse(Corpse* corpse) +{ + ASSERT(corpse && corpse->GetType() != CORPSE_BONES); + + corpse->DestroyForNearbyPlayers(); + if (corpse->IsInGrid()) + RemoveFromMap(corpse, false); + else + { + corpse->RemoveFromWorld(); + corpse->ResetMap(); + } + + CellCoord cellCoord = Trinity::ComputeCellCoord(corpse->GetPositionX(), corpse->GetPositionY()); + _corpsesByCell[cellCoord.GetId()].erase(corpse); + _corpsesByPlayer.erase(corpse->GetOwnerGUID()); +} + +Corpse* Map::ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia /*= false*/) +{ + Corpse* corpse = GetCorpseByPlayer(ownerGuid); + if (!corpse) + return nullptr; + + RemoveCorpse(corpse); + + // remove corpse from DB + SQLTransaction trans = CharacterDatabase.BeginTransaction(); + corpse->DeleteFromDB(trans); + CharacterDatabase.CommitTransaction(trans); + + Corpse* bones = NULL; + + // create the bones only if the map and the grid is loaded at the corpse's location + // ignore bones creating option in case insignia + if ((insignia || + (IsBattlegroundOrArena() ? sWorld->getBoolConfig(CONFIG_DEATH_BONES_BG_OR_ARENA) : sWorld->getBoolConfig(CONFIG_DEATH_BONES_WORLD))) && + !IsRemovalGrid(corpse->GetPositionX(), corpse->GetPositionY())) + { + // Create bones, don't change Corpse + bones = new Corpse(); + bones->Create(corpse->GetGUID().GetCounter(), this); + + for (uint8 i = OBJECT_FIELD_TYPE + 1; i < CORPSE_END; ++i) // don't overwrite guid and object type + bones->SetUInt32Value(i, corpse->GetUInt32Value(i)); + + bones->SetGridCoord(corpse->GetGridCoord()); + bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); + bones->SetPhaseMask(corpse->GetPhaseMask(), false); + + bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES); + bones->SetGuidValue(CORPSE_FIELD_OWNER, ObjectGuid::Empty); + + for (uint8 i = 0; i < EQUIPMENT_SLOT_END; ++i) + if (corpse->GetUInt32Value(CORPSE_FIELD_ITEM + i)) + bones->SetUInt32Value(CORPSE_FIELD_ITEM + i, 0); + + // add bones in grid store if grid loaded where corpse placed + AddToMap(bones); + } + + // all references to the corpse should be removed at this point + delete corpse; + + return bones; +} + +void Map::RemoveOldCorpses() +{ + time_t now = time(nullptr); + + std::vector<ObjectGuid> corpses; + corpses.reserve(_corpsesByPlayer.size()); + + for (auto const& p : _corpsesByPlayer) + if (p.second->IsExpired(now)) + corpses.push_back(p.first); + + for (ObjectGuid const& ownerGuid : corpses) + ConvertCorpseToBones(ownerGuid); +} + void Map::SendZoneDynamicInfo(Player* player) { uint32 zoneId = GetZoneId(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index 15d2169fbbc..2ba5e10c82c 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -34,6 +34,7 @@ #include <bitset> #include <list> +#include <memory> class Unit; class WorldPacket; @@ -443,10 +444,38 @@ class Map : public GridRefManager<NGridType> TempSummon* SummonCreature(uint32 entry, Position const& pos, SummonPropertiesEntry const* properties = NULL, uint32 duration = 0, Unit* summoner = NULL, uint32 spellId = 0, uint32 vehId = 0); void SummonCreatureGroup(uint8 group, std::list<TempSummon*>* list = NULL); - Creature* GetCreature(ObjectGuid guid); - GameObject* GetGameObject(ObjectGuid guid); - Transport* GetTransport(ObjectGuid guid); - DynamicObject* GetDynamicObject(ObjectGuid guid); + Corpse* GetCorpse(ObjectGuid const& guid); + Creature* GetCreature(ObjectGuid const& guid); + GameObject* GetGameObject(ObjectGuid const& guid); + Transport* GetTransport(ObjectGuid const& guid); + DynamicObject* GetDynamicObject(ObjectGuid const& guid); + Pet* GetPet(ObjectGuid const& guid); + + MapStoredObjectTypesContainer& GetObjectsStore() { return _objectsStore; } + + typedef std::unordered_multimap<ObjectGuid::LowType, Creature*> CreatureBySpawnIdContainer; + CreatureBySpawnIdContainer& GetCreatureBySpawnIdStore() { return _creatureBySpawnIdStore; } + + typedef std::unordered_multimap<ObjectGuid::LowType, GameObject*> GameObjectBySpawnIdContainer; + GameObjectBySpawnIdContainer& GetGameObjectBySpawnIdStore() { return _gameobjectBySpawnIdStore; } + + std::unordered_set<Corpse*> const* GetCorpsesInCell(uint32 cellId) const + { + auto itr = _corpsesByCell.find(cellId); + if (itr != _corpsesByCell.end()) + return &itr->second; + + return nullptr; + } + + Corpse* GetCorpseByPlayer(ObjectGuid const& ownerGuid) const + { + auto itr = _corpsesByPlayer.find(ownerGuid); + if (itr != _corpsesByPlayer.end()) + return itr->second; + + return nullptr; + } MapInstanced* ToMapInstanced() { if (Instanceable()) return reinterpret_cast<MapInstanced*>(this); return NULL; } MapInstanced const* ToMapInstanced() const { if (Instanceable()) return reinterpret_cast<MapInstanced const*>(this); return NULL; } @@ -495,6 +524,13 @@ class Map : public GridRefManager<NGridType> void LoadRespawnTimes(); void DeleteRespawnTimes(); + void LoadCorpseData(); + void DeleteCorpseData(); + void AddCorpse(Corpse* corpse); + void RemoveCorpse(Corpse* corpse); + Corpse* ConvertCorpseToBones(ObjectGuid const& ownerGuid, bool insignia = false); + void RemoveOldCorpses(); + static void DeleteRespawnTimesInDB(uint16 mapId, uint32 instanceId); void SendInitTransports(Player* player); @@ -507,7 +543,32 @@ class Map : public GridRefManager<NGridType> void UpdateAreaDependentAuras(); + template<HighGuid high> + inline ObjectGuid::LowType GenerateLowGuid() + { + static_assert(ObjectGuidTraits<high>::MapSpecific, "Only map specific guid can be generated in Map context"); + return GetGuidSequenceGenerator<high>().Generate(); + } + + template<HighGuid high> + inline ObjectGuid::LowType GetMaxLowGuid() + { + static_assert(ObjectGuidTraits<high>::MapSpecific, "Only map specific guid can be retrieved in Map context"); + return GetGuidSequenceGenerator<high>().GetNextAfterMaxUsed(); + } + + void AddUpdateObject(Object* obj) + { + _updateObjects.insert(obj); + } + + void RemoveUpdateObject(Object* obj) + { + _updateObjects.erase(obj); + } + private: + void LoadMapAndVMap(int gx, int gy); void LoadVMap(int gx, int gy); void LoadMap(int gx, int gy, bool reload = false); @@ -561,6 +622,8 @@ class Map : public GridRefManager<NGridType> void UpdateActiveCells(const float &x, const float &y, const uint32 t_diff); + void SendObjectUpdates(); + protected: void SetUnloadReferenceLock(const GridCoord &p, bool on) { getNGrid(p.x_coord, p.y_coord)->setUnloadReferenceLock(on); } @@ -653,6 +716,25 @@ class Map : public GridRefManager<NGridType> ZoneDynamicInfoMap _zoneDynamicInfo; uint32 _defaultLight; + + template<HighGuid high> + inline ObjectGuidGeneratorBase& GetGuidSequenceGenerator() + { + auto itr = _guidGenerators.find(high); + if (itr == _guidGenerators.end()) + itr = _guidGenerators.insert(std::make_pair(high, std::unique_ptr<ObjectGuidGenerator<high>>(new ObjectGuidGenerator<high>()))).first; + + return *itr->second; + } + + std::map<HighGuid, std::unique_ptr<ObjectGuidGeneratorBase>> _guidGenerators; + MapStoredObjectTypesContainer _objectsStore; + CreatureBySpawnIdContainer _creatureBySpawnIdStore; + GameObjectBySpawnIdContainer _gameobjectBySpawnIdStore; + std::unordered_map<uint32/*cellId*/, std::unordered_set<Corpse*>> _corpsesByCell; + std::unordered_map<ObjectGuid, Corpse*> _corpsesByPlayer; + + std::unordered_set<Object*> _updateObjects; }; enum InstanceResetMethod diff --git a/src/server/game/Maps/MapInstanced.cpp b/src/server/game/Maps/MapInstanced.cpp index e4632bb7515..d1b8bd66209 100644 --- a/src/server/game/Maps/MapInstanced.cpp +++ b/src/server/game/Maps/MapInstanced.cpp @@ -194,13 +194,13 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, if (!entry) { TC_LOG_ERROR("maps", "CreateInstance: no entry for map %d", GetId()); - ASSERT(false); + ABORT(); } const InstanceTemplate* iTemplate = sObjectMgr->GetInstanceTemplate(GetId()); if (!iTemplate) { TC_LOG_ERROR("maps", "CreateInstance: no instance template for map %d", GetId()); - ASSERT(false); + ABORT(); } // some instances only have one difficulty @@ -212,6 +212,7 @@ InstanceMap* MapInstanced::CreateInstance(uint32 InstanceId, InstanceSave* save, ASSERT(map->IsDungeon()); map->LoadRespawnTimes(); + map->LoadCorpseData(); bool load_data = save != NULL; map->CreateInstanceData(load_data); @@ -279,6 +280,6 @@ bool MapInstanced::DestroyInstance(InstancedMaps::iterator &itr) bool MapInstanced::CanEnter(Player* /*player*/) { - //ASSERT(false); + //ABORT(); return true; } diff --git a/src/server/game/Maps/MapManager.cpp b/src/server/game/Maps/MapManager.cpp index 29f4b4ab7c2..0e7f9dbb611 100644 --- a/src/server/game/Maps/MapManager.cpp +++ b/src/server/game/Maps/MapManager.cpp @@ -79,6 +79,7 @@ Map* MapManager::CreateBaseMap(uint32 id) { map = new Map(id, i_gridCleanUpDelay, 0, REGULAR_DIFFICULTY); map->LoadRespawnTimes(); + map->LoadCorpseData(); } i_maps[id] = map; @@ -163,10 +164,10 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) if (!player->IsAlive()) { - if (Corpse* corpse = player->GetCorpse()) + if (player->HasCorpse()) { // let enter in ghost mode in instance that connected to inner instance with corpse - uint32 corpseMap = corpse->GetMapId(); + uint32 corpseMap = player->GetCorpseLocation().GetMapId(); do { if (corpseMap == mapid) @@ -183,9 +184,8 @@ bool MapManager::CanPlayerEnter(uint32 mapid, Player* player, bool loginCheck) TC_LOG_DEBUG("maps", "MAP: Player '%s' does not have a corpse in instance '%s' and cannot enter.", player->GetName().c_str(), mapName); return false; } + TC_LOG_DEBUG("maps", "MAP: Player '%s' has corpse in instance '%s' and can enter.", player->GetName().c_str(), mapName); - player->ResurrectPlayer(0.5f, false); - player->SpawnCorpseBones(); } else TC_LOG_DEBUG("maps", "Map::CanPlayerEnter - player '%s' is dead but does not have a corpse!", player->GetName().c_str()); @@ -250,8 +250,6 @@ void MapManager::Update(uint32 diff) for (iter = i_maps.begin(); iter != i_maps.end(); ++iter) iter->second->DelayedUpdate(uint32(i_timer.GetCurrent())); - sObjectAccessor->Update(uint32(i_timer.GetCurrent())); - i_timer.SetCurrent(0); } diff --git a/src/server/game/Maps/MapManager.h b/src/server/game/Maps/MapManager.h index dc6c0bb642f..5b957e00281 100644 --- a/src/server/game/Maps/MapManager.h +++ b/src/server/game/Maps/MapManager.h @@ -21,6 +21,7 @@ #include "Object.h" #include "Map.h" +#include "MapInstanced.h" #include "GridStates.h" #include "MapUpdater.h" @@ -125,6 +126,12 @@ class MapManager MapUpdater * GetMapUpdater() { return &m_updater; } + template<typename Worker> + void DoForAllMaps(Worker&& worker); + + template<typename Worker> + void DoForAllMapsWithMapId(uint32 mapId, Worker&& worker); + private: typedef std::unordered_map<uint32, Map*> MapMapType; typedef std::vector<bool> InstanceIds; @@ -150,5 +157,45 @@ class MapManager uint32 _nextInstanceId; MapUpdater m_updater; }; + +template<typename Worker> +void MapManager::DoForAllMaps(Worker&& worker) +{ + std::lock_guard<std::mutex> lock(_mapsLock); + + for (auto& mapPair : i_maps) + { + Map* map = mapPair.second; + if (MapInstanced* mapInstanced = map->ToMapInstanced()) + { + MapInstanced::InstancedMaps& instances = mapInstanced->GetInstancedMaps(); + for (auto& instancePair : instances) + worker(instancePair.second); + } + else + worker(map); + } +} + +template<typename Worker> +inline void MapManager::DoForAllMapsWithMapId(uint32 mapId, Worker&& worker) +{ + std::lock_guard<std::mutex> lock(_mapsLock); + + auto itr = i_maps.find(mapId); + if (itr != i_maps.end()) + { + Map* map = itr->second; + if (MapInstanced* mapInstanced = map->ToMapInstanced()) + { + MapInstanced::InstancedMaps& instances = mapInstanced->GetInstancedMaps(); + for (auto& p : instances) + worker(p.second); + } + else + worker(map); + } +} + #define sMapMgr MapManager::instance() #endif diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index dadc2eeeac3..cac6e3b91ea 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -112,7 +112,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl Movement::PointsArray splinePath, allPoints; bool mapChange = false; for (size_t i = 0; i < path.size(); ++i) - allPoints.push_back(G3D::Vector3(path[i].LocX, path[i].LocY, path[i].LocZ)); + allPoints.push_back(G3D::Vector3(path[i]->LocX, path[i]->LocY, path[i]->LocZ)); // Add extra points to allow derivative calculations for all path nodes allPoints.insert(allPoints.begin(), allPoints.front().lerp(allPoints[1], -0.2f)); @@ -128,8 +128,8 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl { if (!mapChange) { - TaxiPathNodeEntry const& node_i = path[i]; - if (i != path.size() - 1 && (node_i.Flags & 1 || node_i.MapID != path[i + 1].MapID)) + TaxiPathNodeEntry const* node_i = path[i]; + if (i != path.size() - 1 && (node_i->Flags & 1 || node_i->MapID != path[i + 1]->MapID)) { keyFrames.back().Teleport = true; mapChange = true; @@ -142,7 +142,7 @@ void TransportMgr::GeneratePath(GameObjectTemplate const* goInfo, TransportTempl k.InitialOrientation = Position::NormalizeOrientation(std::atan2(h.y, h.x) + float(M_PI)); keyFrames.push_back(k); - splinePath.push_back(G3D::Vector3(node_i.LocX, node_i.LocY, node_i.LocZ)); + splinePath.push_back(G3D::Vector3(node_i->LocX, node_i->LocY, node_i->LocZ)); transport->mapsUsed.insert(k.Node->MapID); } } @@ -381,7 +381,8 @@ Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* float o = tInfo->keyFrames.begin()->InitialOrientation; // initialize the gameobject base - uint32 guidLow = guid ? guid : sObjectMgr->GenerateLowGuid(HIGHGUID_MO_TRANSPORT); + ObjectGuid::LowType guidLow = guid ? guid : sObjectMgr->GetGenerator<HighGuid::Mo_Transport>().Generate(); + if (!trans->Create(guidLow, entry, mapId, x, y, z, o, 255)) { delete trans; @@ -404,7 +405,7 @@ Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* trans->m_zoneScript = map->ToInstanceMap()->GetInstanceScript(); // Passengers will be loaded once a player is near - + HashMapHolder<Transport>::Insert(trans); trans->GetMap()->AddToMap<Transport>(trans); return trans; } diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index fff7b9d8afa..c273ea7fb15 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -37,7 +37,7 @@ typedef std::unordered_map<uint32, std::set<uint32> > TransportInstanceMap; struct KeyFrame { - explicit KeyFrame(TaxiPathNodeEntry const& _node) : Index(0), Node(&_node), InitialOrientation(0.0f), + explicit KeyFrame(TaxiPathNodeEntry const* node) : Index(0), Node(node), InitialOrientation(0.0f), DistSinceStop(-1.0f), DistUntilStop(-1.0f), DistFromPrev(-1.0f), TimeFrom(0.0f), TimeTo(0.0f), Teleport(false), ArriveTime(0), DepartureTime(0), Spline(NULL), NextDistFromPrev(0.0f), NextArriveTime(0) { diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index a4ba9866064..d374c8c509a 100644 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -1202,6 +1202,8 @@ enum TrinityStrings LANG_BAN_ACCOUNT_YOUPERMBANNEDMESSAGE_WORLD = 11007, LANG_NPCINFO_INHABIT_TYPE = 11008, - LANG_NPCINFO_FLAGS_EXTRA = 11009 + LANG_NPCINFO_FLAGS_EXTRA = 11009, + + LANG_COOLDOWN_NOT_RESET_AFTER_DUEL = 11010 }; #endif diff --git a/src/server/game/Movement/MotionMaster.cpp b/src/server/game/Movement/MotionMaster.cpp index b69322f5720..cb8cab1849d 100644 --- a/src/server/game/Movement/MotionMaster.cpp +++ b/src/server/game/Movement/MotionMaster.cpp @@ -193,7 +193,7 @@ void MotionMaster::MoveRandom(float spawndist) { if (_owner->GetTypeId() == TYPEID_UNIT) { - TC_LOG_DEBUG("misc", "Creature (GUID: %u) start moving random", _owner->GetGUIDLow()); + TC_LOG_DEBUG("misc", "Creature (GUID: %u) start moving random", _owner->GetGUID().GetCounter()); Mutate(new RandomMovementGenerator<Creature>(spawndist), MOTION_SLOT_IDLE); } } @@ -204,22 +204,22 @@ void MotionMaster::MoveTargetedHome() if (_owner->GetTypeId() == TYPEID_UNIT && !_owner->ToCreature()->GetCharmerOrOwnerGUID()) { - TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted home", _owner->GetEntry(), _owner->GetGUIDLow()); + TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted home", _owner->GetEntry(), _owner->GetGUID().GetCounter()); Mutate(new HomeMovementGenerator<Creature>(), MOTION_SLOT_ACTIVE); } else if (_owner->GetTypeId() == TYPEID_UNIT && _owner->ToCreature()->GetCharmerOrOwnerGUID()) { - TC_LOG_DEBUG("misc", "Pet or controlled creature (Entry: %u GUID: %u) targeting home", _owner->GetEntry(), _owner->GetGUIDLow()); + TC_LOG_DEBUG("misc", "Pet or controlled creature (Entry: %u GUID: %u) targeting home", _owner->GetEntry(), _owner->GetGUID().GetCounter()); Unit* target = _owner->ToCreature()->GetCharmerOrOwner(); if (target) { - TC_LOG_DEBUG("misc", "Following %s (GUID: %u)", target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : ((Creature*)target)->GetDBTableGUIDLow()); + TC_LOG_DEBUG("misc", "Following %s (GUID: %u)", target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : ((Creature*)target)->GetSpawnId()); Mutate(new FollowMovementGenerator<Creature>(target, PET_FOLLOW_DIST, PET_FOLLOW_ANGLE), MOTION_SLOT_ACTIVE); } } else { - TC_LOG_ERROR("misc", "Player (GUID: %u) attempt targeted home", _owner->GetGUIDLow()); + TC_LOG_ERROR("misc", "Player (GUID: %u) attempt targeted home", _owner->GetGUID().GetCounter()); } } @@ -227,13 +227,13 @@ void MotionMaster::MoveConfused() { if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (GUID: %u) move confused", _owner->GetGUIDLow()); + TC_LOG_DEBUG("misc", "Player (GUID: %u) move confused", _owner->GetGUID().GetCounter()); Mutate(new ConfusedMovementGenerator<Player>(), MOTION_SLOT_CONTROLLED); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) move confused", - _owner->GetEntry(), _owner->GetGUIDLow()); + _owner->GetEntry(), _owner->GetGUID().GetCounter()); Mutate(new ConfusedMovementGenerator<Creature>(), MOTION_SLOT_CONTROLLED); } } @@ -248,17 +248,17 @@ void MotionMaster::MoveChase(Unit* target, float dist, float angle) if (_owner->GetTypeId() == TYPEID_PLAYER) { TC_LOG_DEBUG("misc", "Player (GUID: %u) chase to %s (GUID: %u)", - _owner->GetGUIDLow(), + _owner->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", - target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); + target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId()); Mutate(new ChaseMovementGenerator<Player>(target, dist, angle), MOTION_SLOT_ACTIVE); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) chase to %s (GUID: %u)", - _owner->GetEntry(), _owner->GetGUIDLow(), + _owner->GetEntry(), _owner->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", - target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); + target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId()); Mutate(new ChaseMovementGenerator<Creature>(target, dist, angle), MOTION_SLOT_ACTIVE); } } @@ -272,17 +272,17 @@ void MotionMaster::MoveFollow(Unit* target, float dist, float angle, MovementSlo //_owner->AddUnitState(UNIT_STATE_FOLLOW); if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (GUID: %u) follow to %s (GUID: %u)", _owner->GetGUIDLow(), + TC_LOG_DEBUG("misc", "Player (GUID: %u) follow to %s (GUID: %u)", _owner->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", - target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); + target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId()); Mutate(new FollowMovementGenerator<Player>(target, dist, angle), slot); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) follow to %s (GUID: %u)", - _owner->GetEntry(), _owner->GetGUIDLow(), + _owner->GetEntry(), _owner->GetGUID().GetCounter(), target->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", - target->GetTypeId() == TYPEID_PLAYER ? target->GetGUIDLow() : target->ToCreature()->GetDBTableGUIDLow()); + target->GetTypeId() == TYPEID_PLAYER ? target->GetGUID().GetCounter() : target->ToCreature()->GetSpawnId()); Mutate(new FollowMovementGenerator<Creature>(target, dist, angle), slot); } } @@ -291,13 +291,13 @@ void MotionMaster::MovePoint(uint32 id, float x, float y, float z, bool generate { if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), id, x, y, z); + TC_LOG_DEBUG("misc", "Player (GUID: %u) targeted point (Id: %u X: %f Y: %f Z: %f)", _owner->GetGUID().GetCounter(), id, x, y, z); Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) targeted point (ID: %u X: %f Y: %f Z: %f)", - _owner->GetEntry(), _owner->GetGUIDLow(), id, x, y, z); + _owner->GetEntry(), _owner->GetGUID().GetCounter(), id, x, y, z); Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath), MOTION_SLOT_ACTIVE); } } @@ -371,7 +371,7 @@ void MotionMaster::MoveJumpTo(float angle, float speedXY, float speedZ) void MotionMaster::MoveJump(float x, float y, float z, float speedXY, float speedZ, uint32 id) { - TC_LOG_DEBUG("misc", "Unit (GUID: %u) jump to point (X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), x, y, z); + TC_LOG_DEBUG("misc", "Unit (GUID: %u) jump to point (X: %f Y: %f Z: %f)", _owner->GetGUID().GetCounter(), x, y, z); if (speedXY <= 0.1f) return; @@ -476,13 +476,13 @@ void MotionMaster::MoveCharge(float x, float y, float z, float speed /*= SPEED_C if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", _owner->GetGUIDLow(), x, y, z); + TC_LOG_DEBUG("misc", "Player (GUID: %u) charge point (X: %f Y: %f Z: %f)", _owner->GetGUID().GetCounter(), x, y, z); Mutate(new PointMovementGenerator<Player>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) charge point (X: %f Y: %f Z: %f)", - _owner->GetEntry(), _owner->GetGUIDLow(), x, y, z); + _owner->GetEntry(), _owner->GetGUID().GetCounter(), x, y, z); Mutate(new PointMovementGenerator<Creature>(id, x, y, z, generatePath, speed), MOTION_SLOT_CONTROLLED); } } @@ -504,12 +504,12 @@ void MotionMaster::MoveSeekAssistance(float x, float y, float z) { if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_ERROR("misc", "Player (GUID: %u) attempt to seek assistance", _owner->GetGUIDLow()); + TC_LOG_ERROR("misc", "Player (GUID: %u) attempt to seek assistance", _owner->GetGUID().GetCounter()); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) seek assistance (X: %f Y: %f Z: %f)", - _owner->GetEntry(), _owner->GetGUIDLow(), x, y, z); + _owner->GetEntry(), _owner->GetGUID().GetCounter(), x, y, z); _owner->AttackStop(); _owner->ToCreature()->SetReactState(REACT_PASSIVE); Mutate(new AssistanceMovementGenerator(x, y, z), MOTION_SLOT_ACTIVE); @@ -520,12 +520,12 @@ void MotionMaster::MoveSeekAssistanceDistract(uint32 time) { if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_ERROR("misc", "Player (GUID: %u) attempt to call distract after assistance", _owner->GetGUIDLow()); + TC_LOG_ERROR("misc", "Player (GUID: %u) attempt to call distract after assistance", _owner->GetGUID().GetCounter()); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) is distracted after assistance call (Time: %u)", - _owner->GetEntry(), _owner->GetGUIDLow(), time); + _owner->GetEntry(), _owner->GetGUID().GetCounter(), time); Mutate(new AssistanceDistractMovementGenerator(time), MOTION_SLOT_ACTIVE); } } @@ -537,17 +537,17 @@ void MotionMaster::MoveFleeing(Unit* enemy, uint32 time) if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (GUID: %u) flee from %s (GUID: %u)", _owner->GetGUIDLow(), + TC_LOG_DEBUG("misc", "Player (GUID: %u) flee from %s (GUID: %u)", _owner->GetGUID().GetCounter(), enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", - enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUIDLow() : enemy->ToCreature()->GetDBTableGUIDLow()); + enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId()); Mutate(new FleeingMovementGenerator<Player>(enemy->GetGUID()), MOTION_SLOT_CONTROLLED); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) flee from %s (GUID: %u)%s", - _owner->GetEntry(), _owner->GetGUIDLow(), + _owner->GetEntry(), _owner->GetGUID().GetCounter(), enemy->GetTypeId() == TYPEID_PLAYER ? "player" : "creature", - enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUIDLow() : enemy->ToCreature()->GetDBTableGUIDLow(), + enemy->GetTypeId() == TYPEID_PLAYER ? enemy->GetGUID().GetCounter() : enemy->ToCreature()->GetSpawnId(), time ? " for a limited time" : ""); if (time) Mutate(new TimedFleeingMovementGenerator(enemy->GetGUID(), time), MOTION_SLOT_CONTROLLED); @@ -563,7 +563,8 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) if (path < sTaxiPathNodesByPath.size()) { TC_LOG_DEBUG("misc", "%s taxi to (Path %u node %u)", _owner->GetName().c_str(), path, pathnode); - FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(sTaxiPathNodesByPath[path], pathnode); + FlightPathMovementGenerator* mgen = new FlightPathMovementGenerator(pathnode); + mgen->LoadPath(_owner->ToPlayer()); Mutate(mgen, MOTION_SLOT_CONTROLLED); } else @@ -575,7 +576,7 @@ void MotionMaster::MoveTaxiFlight(uint32 path, uint32 pathnode) else { TC_LOG_ERROR("misc", "Creature (Entry: %u GUID: %u) attempt taxi to (Path %u node %u)", - _owner->GetEntry(), _owner->GetGUIDLow(), path, pathnode); + _owner->GetEntry(), _owner->GetGUID().GetCounter(), path, pathnode); } } @@ -586,12 +587,12 @@ void MotionMaster::MoveDistract(uint32 timer) if (_owner->GetTypeId() == TYPEID_PLAYER) { - TC_LOG_DEBUG("misc", "Player (GUID: %u) distracted (timer: %u)", _owner->GetGUIDLow(), timer); + TC_LOG_DEBUG("misc", "Player (GUID: %u) distracted (timer: %u)", _owner->GetGUID().GetCounter(), timer); } else { TC_LOG_DEBUG("misc", "Creature (Entry: %u GUID: %u) (timer: %u)", - _owner->GetEntry(), _owner->GetGUIDLow(), timer); + _owner->GetEntry(), _owner->GetGUID().GetCounter(), timer); } DistractMovementGenerator* mgen = new DistractMovementGenerator(timer); @@ -644,7 +645,7 @@ void MotionMaster::MovePath(uint32 path_id, bool repeatable) TC_LOG_DEBUG("misc", "%s (GUID: %u) start moving over path(Id:%u, repeatable: %s)", _owner->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature", - _owner->GetGUIDLow(), path_id, repeatable ? "YES" : "NO"); + _owner->GetGUID().GetCounter(), path_id, repeatable ? "YES" : "NO"); } void MotionMaster::MoveRotate(uint32 time, RotateDirection direction) diff --git a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp index 31859899ce8..40bf3af5194 100644 --- a/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/TargetedMovementGenerator.cpp @@ -232,7 +232,7 @@ void ChaseMovementGenerator<Creature>::MovementInform(Creature* unit) { // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle if (unit->AI()) - unit->AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); + unit->AI()->MovementInform(CHASE_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter()); } //-----------------------------------------------// @@ -304,7 +304,7 @@ void FollowMovementGenerator<Creature>::MovementInform(Creature* unit) { // Pass back the GUIDLow of the target. If it is pet's owner then PetAI will handle if (unit->AI()) - unit->AI()->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUIDLow()); + unit->AI()->MovementInform(FOLLOW_MOTION_TYPE, i_target.getTarget()->GetGUID().GetCounter()); } //-----------------------------------------------// diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp index f91fc1985d5..fe618e6ece7 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.cpp @@ -41,7 +41,7 @@ void WaypointMovementGenerator<Creature>::LoadPath(Creature* creature) if (!i_path) { // No path id found for entry - TC_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u DB GUID: %u) doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUIDLow(), creature->GetDBTableGUIDLow(), path_id); + TC_LOG_ERROR("sql.sql", "WaypointMovementGenerator::LoadPath: creature %s (Entry: %u GUID: %u DB GUID: %u) doesn't have waypoint path id: %u", creature->GetName().c_str(), creature->GetEntry(), creature->GetGUID().GetCounter(), creature->GetSpawnId(), path_id); return; } @@ -245,17 +245,62 @@ bool WaypointMovementGenerator<Creature>::GetResetPos(Creature*, float& x, float uint32 FlightPathMovementGenerator::GetPathAtMapEnd() const { - if (i_currentNode >= i_path->size()) - return i_path->size(); + if (i_currentNode >= i_path.size()) + return i_path.size(); - uint32 curMapId = (*i_path)[i_currentNode].MapID; - for (uint32 i = i_currentNode; i < i_path->size(); ++i) - { - if ((*i_path)[i].MapID != curMapId) + uint32 curMapId = i_path[i_currentNode]->MapID; + for (uint32 i = i_currentNode; i < i_path.size(); ++i) + if (i_path[i]->MapID != curMapId) return i; - } - return i_path->size(); + return i_path.size(); +} + +#define SKIP_SPLINE_POINT_DISTANCE_SQ (40.0f * 40.0f) + +bool IsNodeIncludedInShortenedPath(TaxiPathNodeEntry const* p1, TaxiPathNodeEntry const* p2) +{ + return p1->MapID != p2->MapID || std::pow(p1->LocX - p2->LocX, 2) + std::pow(p1->LocY - p2->LocY, 2) > SKIP_SPLINE_POINT_DISTANCE_SQ; +} + +void FlightPathMovementGenerator::LoadPath(Player* player) +{ + _pointsForPathSwitch.clear(); + std::deque<uint32> const& taxi = player->m_taxi.GetPath(); + for (uint32 src = 0, dst = 1; dst < taxi.size(); src = dst++) + { + uint32 path, cost; + sObjectMgr->GetTaxiPath(taxi[src], taxi[dst], path, cost); + if (path > sTaxiPathNodesByPath.size()) + return; + + TaxiPathNodeList const& nodes = sTaxiPathNodesByPath[path]; + if (!nodes.empty()) + { + TaxiPathNodeEntry const* start = nodes[0]; + TaxiPathNodeEntry const* end = nodes[nodes.size() - 1]; + bool passedPreviousSegmentProximityCheck = false; + for (uint32 i = 0; i < nodes.size(); ++i) + { + if (passedPreviousSegmentProximityCheck || !src || i_path.empty() || IsNodeIncludedInShortenedPath(i_path[i_path.size() - 1], nodes[i])) + { + if ((!src || (IsNodeIncludedInShortenedPath(start, nodes[i]) && i >= 2)) && + (dst == taxi.size() - 1 || (IsNodeIncludedInShortenedPath(end, nodes[i]) && i < nodes.size() - 1))) + { + passedPreviousSegmentProximityCheck = true; + i_path.push_back(nodes[i]); + } + } + else + { + i_path.pop_back(); + --_pointsForPathSwitch.back().PathIndex; + } + } + } + + _pointsForPathSwitch.push_back({ uint32(i_path.size() - 1), int32(cost) }); + } } void FlightPathMovementGenerator::DoInitialize(Player* player) @@ -296,7 +341,7 @@ void FlightPathMovementGenerator::DoReset(Player* player) uint32 end = GetPathAtMapEnd(); for (uint32 i = GetCurrentNode(); i != end; ++i) { - G3D::Vector3 vertice((*i_path)[i].LocX, (*i_path)[i].LocY, (*i_path)[i].LocZ); + G3D::Vector3 vertice(i_path[i]->LocX, i_path[i]->LocY, i_path[i]->LocZ); init.Path().push_back(vertice); } init.SetFirstPointId(GetCurrentNode()); @@ -313,9 +358,21 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/) bool departureEvent = true; do { - DoEventIfAny(player, (*i_path)[i_currentNode], departureEvent); + DoEventIfAny(player, i_path[i_currentNode], departureEvent); + while (!_pointsForPathSwitch.empty() && _pointsForPathSwitch.front().PathIndex <= i_currentNode) + { + _pointsForPathSwitch.pop_front(); + player->m_taxi.NextTaxiDestination(); + if (!_pointsForPathSwitch.empty()) + { + player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GOLD_SPENT_FOR_TRAVELLING, _pointsForPathSwitch.front().Cost); + player->ModifyMoney(-_pointsForPathSwitch.front().Cost); + } + } + if (pointId == i_currentNode) break; + if (i_currentNode == _preloadTargetNode) PreloadEndGrid(); i_currentNode += (uint32)departureEvent; @@ -324,18 +381,18 @@ bool FlightPathMovementGenerator::DoUpdate(Player* player, uint32 /*diff*/) while (true); } - return i_currentNode < (i_path->size()-1); + return i_currentNode < (i_path.size() - 1); } void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport() { - if (i_path->empty()) + if (i_path.empty() || i_currentNode >= i_path.size()) return; - uint32 map0 = (*i_path)[0].MapID; - for (size_t i = 1; i < i_path->size(); ++i) + uint32 map0 = i_path[i_currentNode]->MapID; + for (size_t i = i_currentNode + 1; i < i_path.size(); ++i) { - if ((*i_path)[i].MapID != map0) + if (i_path[i]->MapID != map0) { i_currentNode = i; return; @@ -343,19 +400,21 @@ void FlightPathMovementGenerator::SetCurrentNodeAfterTeleport() } } -void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure) +void FlightPathMovementGenerator::DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure) { - if (uint32 eventid = departure ? node.DepartureEventID : node.ArrivalEventID) + if (uint32 eventid = departure ? node->DepartureEventID : node->ArrivalEventID) { - TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node.NodeIndex, node.PathID, player->GetName().c_str()); + TC_LOG_DEBUG("maps.script", "Taxi %s event %u of node %u of path %u for player %s", departure ? "departure" : "arrival", eventid, node->NodeIndex, node->PathID, player->GetName().c_str()); player->GetMap()->ScriptsStart(sEventScripts, eventid, player, player); } } bool FlightPathMovementGenerator::GetResetPos(Player*, float& x, float& y, float& z) { - const TaxiPathNodeEntry& node = (*i_path)[i_currentNode]; - x = node.LocX; y = node.LocY; z = node.LocZ; + TaxiPathNodeEntry const* node = i_path[i_currentNode]; + x = node->LocX; + y = node->LocY; + z = node->LocZ; return true; } @@ -363,11 +422,11 @@ 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(); //! Number of nodes in path. - _endMapId = (*i_path)[nodeCount - 1].MapID; //! MapId of last node + uint32 nodeCount = i_path.size(); //! Number of nodes in path. + _endMapId = i_path[nodeCount - 1]->MapID; //! MapId of last node _preloadTargetNode = nodeCount - 3; - _endGridX = (*i_path)[nodeCount - 1].LocX; - _endGridY = (*i_path)[nodeCount - 1].LocY; + _endGridX = i_path[nodeCount - 1]->LocX; + _endGridY = i_path[nodeCount - 1]->LocY; } void FlightPathMovementGenerator::PreloadEndGrid() @@ -378,7 +437,7 @@ void FlightPathMovementGenerator::PreloadEndGrid() // Load the grid if (endMap) { - TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path->size()-1)); + TC_LOG_DEBUG("misc", "Preloading rid (%f, %f) for map %u at node index %u/%u", _endGridX, _endGridY, _endMapId, _preloadTargetNode, (uint32)(i_path.size() - 1)); endMap->LoadGrid(_endGridX, _endGridY); } else diff --git a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h index eb8533159a9..caf76b5ea19 100755 --- a/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h +++ b/src/server/game/Movement/MovementGenerators/WaypointMovementGenerator.h @@ -27,13 +27,8 @@ #include "MovementGenerator.h" #include "WaypointManager.h" -#include "Path.h" - #include "Player.h" -#include <vector> -#include <set> - #define FLIGHT_TRAVEL_UPDATE 100 #define STOP_TIME_FOR_PLAYER 3 * MINUTE * IN_MILLISECONDS // 3 Minutes #define TIMEDIFF_NEXT_WP 250 @@ -42,11 +37,9 @@ template<class T, class P> class PathMovementBase { public: - PathMovementBase() : i_path(NULL), i_currentNode(0) { } + PathMovementBase() : i_path(), i_currentNode(0) { } virtual ~PathMovementBase() { }; - // template pattern, not defined .. override required - void LoadPath(T &); uint32 GetCurrentNode() const { return i_currentNode; } protected: @@ -110,30 +103,30 @@ class WaypointMovementGenerator<Creature> : public MovementGeneratorMedium< Crea * and hence generates ground and activities for the player. */ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, FlightPathMovementGenerator >, - public PathMovementBase<Player, TaxiPathNodeList const*> + public PathMovementBase<Player, TaxiPathNodeList> { public: - explicit FlightPathMovementGenerator(TaxiPathNodeList const& pathnodes, uint32 startNode = 0) + explicit FlightPathMovementGenerator(uint32 startNode = 0) { - i_path = &pathnodes; i_currentNode = startNode; _endGridX = 0.0f; _endGridY = 0.0f; _endMapId = 0; _preloadTargetNode = 0; } + void LoadPath(Player* player); void DoInitialize(Player*); void DoReset(Player*); void DoFinalize(Player*); bool DoUpdate(Player*, uint32); MovementGeneratorType GetMovementGeneratorType() const override { return FLIGHT_MOTION_TYPE; } - TaxiPathNodeList const& 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; } - void DoEventIfAny(Player* player, TaxiPathNodeEntry const& node, bool departure); + void DoEventIfAny(Player* player, TaxiPathNodeEntry const* node, bool departure); bool GetResetPos(Player*, float& x, float& y, float& z); @@ -141,9 +134,18 @@ class FlightPathMovementGenerator : public MovementGeneratorMedium< Player, Flig void PreloadEndGrid(); private: - float _endGridX; //! X coord of last node location - float _endGridY; //! Y coord of last node location - uint32 _endMapId; //! map Id of last node location - uint32 _preloadTargetNode; //! node index where preloading starts + + float _endGridX; //! X coord of last node location + float _endGridY; //! Y coord of last node location + uint32 _endMapId; //! map Id of last node location + uint32 _preloadTargetNode; //! node index where preloading starts + + struct TaxiNodeChangeInfo + { + uint32 PathIndex; + int32 Cost; + }; + + std::deque<TaxiNodeChangeInfo> _pointsForPathSwitch; //! node indexes and costs where TaxiPath changes }; #endif diff --git a/src/server/game/Movement/PathGenerator.cpp b/src/server/game/Movement/PathGenerator.cpp index 186b5d400b2..3b4f19adb0b 100644 --- a/src/server/game/Movement/PathGenerator.cpp +++ b/src/server/game/Movement/PathGenerator.cpp @@ -35,7 +35,7 @@ PathGenerator::PathGenerator(const Unit* owner) : { memset(_pathPolyRefs, 0, sizeof(_pathPolyRefs)); - TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUIDLow()); + TC_LOG_DEBUG("maps", "++ PathGenerator::PathGenerator for %u \n", _sourceUnit->GetGUID().GetCounter()); uint32 mapId = _sourceUnit->GetMapId(); if (DisableMgr::IsPathfindingEnabled(mapId)) @@ -50,7 +50,7 @@ PathGenerator::PathGenerator(const Unit* owner) : PathGenerator::~PathGenerator() { - TC_LOG_DEBUG("maps", "++ PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUIDLow()); + TC_LOG_DEBUG("maps", "++ PathGenerator::~PathGenerator() for %u \n", _sourceUnit->GetGUID().GetCounter()); } bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool forceDest, bool straightLine) @@ -70,7 +70,7 @@ bool PathGenerator::CalculatePath(float destX, float destY, float destZ, bool fo _forceDestination = forceDest; _straightLine = straightLine; - TC_LOG_DEBUG("maps", "++ PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUIDLow()); + TC_LOG_DEBUG("maps", "++ PathGenerator::CalculatePath() for %u \n", _sourceUnit->GetGUID().GetCounter()); // make sure navMesh works - we can run on map w/o mmap // check if the start and end point have a .mmtile loaded (can we pass via not loaded tile on the way?) @@ -392,7 +392,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con // this is probably an error state, but we'll leave it // and hopefully recover on the next Update // we still need to copy our preffix - TC_LOG_ERROR("maps", "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow()); + TC_LOG_ERROR("maps", "%u's Path Build failed: 0 length path", _sourceUnit->GetGUID().GetCounter()); } TC_LOG_DEBUG("maps", "++ m_polyLength=%u prefixPolyLength=%u suffixPolyLength=%u \n", _polyLength, prefixPolyLength, suffixPolyLength); @@ -453,7 +453,7 @@ void PathGenerator::BuildPolyPath(G3D::Vector3 const& startPos, G3D::Vector3 con if (!_polyLength || dtStatusFailed(dtResult)) { // only happens if we passed bad data to findPath(), or navmesh is messed up - TC_LOG_ERROR("maps", "%u's Path Build failed: 0 length path", _sourceUnit->GetGUIDLow()); + TC_LOG_ERROR("maps", "%u's Path Build failed: 0 length path", _sourceUnit->GetGUID().GetCounter()); BuildShortcut(); _type = PATHFIND_NOPATH; return; diff --git a/src/server/game/Movement/Spline/MoveSpline.cpp b/src/server/game/Movement/Spline/MoveSpline.cpp index ccf8824051b..d8173aab331 100644 --- a/src/server/game/Movement/Spline/MoveSpline.cpp +++ b/src/server/game/Movement/Spline/MoveSpline.cpp @@ -202,7 +202,7 @@ bool MoveSplineInitArgs::Validate(Unit* unit) const #define CHECK(exp) \ if (!(exp))\ {\ - TC_LOG_ERROR("misc", "MoveSplineInitArgs::Validate: expression '%s' failed for GUID: %u Entry: %u", #exp, unit->GetTypeId() == TYPEID_PLAYER ? unit->GetGUIDLow() : unit->ToCreature()->GetDBTableGUIDLow(), unit->GetEntry());\ + TC_LOG_ERROR("misc", "MoveSplineInitArgs::Validate: expression '%s' failed for GUID: %u Entry: %u", #exp, unit->GetTypeId() == TYPEID_PLAYER ? unit->GetGUID().GetCounter() : unit->ToCreature()->GetSpawnId(), unit->GetEntry());\ return false;\ } CHECK(path.size() > 1); diff --git a/src/server/game/Movement/Spline/Spline.h b/src/server/game/Movement/Spline/Spline.h index c8b7a19c943..59f514bed75 100644 --- a/src/server/game/Movement/Spline/Spline.h +++ b/src/server/game/Movement/Spline/Spline.h @@ -82,7 +82,7 @@ protected: typedef void (SplineBase::*InitMethtod)(const Vector3*, index_type, index_type); static InitMethtod initializers[ModesEnd]; - void UninitializedSpline() const { ASSERT(false);} + void UninitializedSpline() const { ABORT();} public: diff --git a/src/server/game/Movement/Waypoints/Path.h b/src/server/game/Movement/Waypoints/Path.h deleted file mode 100644 index bb8abc37eb3..00000000000 --- a/src/server/game/Movement/Waypoints/Path.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2008-2015 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITYCORE_PATH_H -#define TRINITYCORE_PATH_H - -#include "Common.h" -#include <deque> - -struct PathNode -{ - PathNode(): x(0.0f), y(0.0f), z(0.0f) { } - PathNode(float _x, float _y, float _z): x(_x), y(_y), z(_z) { } - float x, y, z; -}; -template<typename PathElem, typename PathNode = PathElem> - -class Path -{ - public: - 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); } - void crop(unsigned int start, unsigned int end) - { - while (start && !i_nodes.empty()) - { - i_nodes.pop_front(); - --start; - } - - while (end && !i_nodes.empty()) - { - i_nodes.pop_back(); - --end; - } - } - - float GetTotalLength(uint32 start, uint32 end) const - { - float len = 0.0f; - for (uint32 idx=start+1; idx < end; ++idx) - { - 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 += std::sqrt(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) const - { - float len = GetTotalLength(0, curnode); - - if (curnode > 0) - { - PathNode const& node = i_nodes[curnode-1]; - float xd = x - node.x; - float yd = y - node.y; - float zd = z - node.z; - len += std::sqrt(xd*xd + yd*yd + zd*zd); - } - - return len; - } - - 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::deque<PathElem> i_nodes; -}; - -typedef Path<PathNode> SimplePath; - -#endif diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.cpp b/src/server/game/OutdoorPvP/OutdoorPvP.cpp index 3648fe5cde5..d914ef01108 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvP.cpp @@ -25,6 +25,7 @@ #include "GridNotifiers.h" #include "GridNotifiersImpl.h" #include "CellImpl.h" +#include "MapManager.h" class DefenseMessageBuilder { @@ -48,7 +49,7 @@ class DefenseMessageBuilder }; OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp): - m_capturePointGUID(), m_capturePoint(NULL), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), + m_capturePointSpawnId(), m_capturePoint(NULL), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0), m_value(0), m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL), m_State(OBJECTIVESTATE_NEUTRAL), m_neutralValuePct(0), m_PvP(pvp) { } @@ -94,7 +95,7 @@ void OPvPCapturePoint::AddGO(uint32 type, uint32 guid, uint32 entry) entry = data->id; } - m_Objects[type] = ObjectGuid(HIGHGUID_GAMEOBJECT, entry, guid); + m_Objects[type] = ObjectGuid(HighGuid::GameObject, entry, guid); m_ObjectTypes[m_Objects[type]] = type; } @@ -108,7 +109,7 @@ void OPvPCapturePoint::AddCre(uint32 type, uint32 guid, uint32 entry) entry = data->id; } - m_Creatures[type] = ObjectGuid(HIGHGUID_UNIT, entry, guid); + m_Creatures[type] = ObjectGuid(HighGuid::Unit, entry, guid); m_CreatureTypes[m_Creatures[type]] = type; } @@ -146,8 +147,9 @@ bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, float x, fl return false; } - m_capturePointGUID = ObjectGuid(HIGHGUID_GAMEOBJECT, entry, sObjectMgr->AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3)); - if (!m_capturePointGUID) + m_capturePointSpawnId = sObjectMgr->AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3); + + if (m_capturePointSpawnId == 0) return false; // get the needed values from goinfo @@ -161,24 +163,25 @@ bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, float x, fl bool OPvPCapturePoint::DelCreature(uint32 type) { - if (!m_Creatures[type]) + uint32 spawnId = m_Creatures[type]; + if (!spawnId) { TC_LOG_DEBUG("outdoorpvp", "opvp creature type %u was already deleted", type); return false; } - Creature* cr = HashMapHolder<Creature>::Find(m_Creatures[type]); - if (!cr) + auto bounds = m_PvP->GetMap()->GetCreatureBySpawnIdStore().equal_range(spawnId); + for (auto itr = bounds.first; itr != bounds.second;) { - // can happen when closing the core - m_Creatures[type].Clear(); - return false; + Creature* c = itr->second; + ++itr; + // Don't save respawn time + c->SetRespawnTime(0); + c->RemoveCorpse(); + c->AddObjectToRemoveList(); } + TC_LOG_DEBUG("outdoorpvp", "deleting opvp creature type %u", type); - uint32 guid = cr->GetDBTableGUIDLow(); - // Don't save respawn time - cr->SetRespawnTime(0); - cr->RemoveCorpse(); // 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 @@ -186,15 +189,13 @@ bool OPvPCapturePoint::DelCreature(uint32 type) // map->Remove(cr, false); // delete respawn time for this creature PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CREATURE_RESPAWN); - stmt->setUInt32(0, guid); - stmt->setUInt16(1, cr->GetMapId()); - stmt->setUInt32(2, 0); // instance id, always 0 for world maps + stmt->setUInt32(0, spawnId); + stmt->setUInt16(1, m_PvP->GetMap()->GetId()); stmt->setUInt32(2, 0); // instance id, always 0 for world maps CharacterDatabase.Execute(stmt); - cr->AddObjectToRemoveList(); - sObjectMgr->DeleteCreatureData(guid); + sObjectMgr->DeleteCreatureData(spawnId); m_CreatureTypes[m_Creatures[type]] = 0; - m_Creatures[type].Clear(); + m_Creatures[type] = 0; return true; } @@ -203,25 +204,26 @@ bool OPvPCapturePoint::DelObject(uint32 type) if (!m_Objects[type]) return false; - GameObject* obj = HashMapHolder<GameObject>::Find(m_Objects[type]); - if (!obj) + uint32 spawnId = m_Objects[type]; + auto bounds = m_PvP->GetMap()->GetGameObjectBySpawnIdStore().equal_range(spawnId); + for (auto itr = bounds.first; itr != bounds.second;) { - m_Objects[type].Clear(); - return false; + GameObject* go = itr->second; + ++itr; + // Don't save respawn time + go->SetRespawnTime(0); + go->Delete(); } - uint32 guid = obj->GetDBTableGUIDLow(); - obj->SetRespawnTime(0); // not save respawn time - obj->Delete(); - sObjectMgr->DeleteGOData(guid); + sObjectMgr->DeleteGOData(spawnId); m_ObjectTypes[m_Objects[type]] = 0; - m_Objects[type].Clear(); + m_Objects[type] = 0; return true; } bool OPvPCapturePoint::DelCapturePoint() { - sObjectMgr->DeleteGOData(m_capturePointGUID.GetCounter()); - m_capturePointGUID.Clear(); + sObjectMgr->DeleteGOData(m_capturePointSpawnId); + m_capturePointSpawnId = 0; if (m_capturePoint) { @@ -234,15 +236,30 @@ bool OPvPCapturePoint::DelCapturePoint() void OPvPCapturePoint::DeleteSpawns() { - for (std::map<uint32, ObjectGuid>::iterator i = m_Objects.begin(); i != m_Objects.end(); ++i) + for (std::map<uint32, uint32>::iterator i = m_Objects.begin(); i != m_Objects.end(); ++i) DelObject(i->first); - for (std::map<uint32, ObjectGuid>::iterator i = m_Creatures.begin(); i != m_Creatures.end(); ++i) + for (std::map<uint32, uint32>::iterator i = m_Creatures.begin(); i != m_Creatures.end(); ++i) DelCreature(i->first); DelCapturePoint(); } void OutdoorPvP::DeleteSpawns() { + // Remove script from any registered gameobjects/creatures + for (auto itr = m_GoScriptStore.begin(); itr != m_GoScriptStore.end(); ++itr) + { + if (GameObject* go = itr->second) + go->ClearZoneScript(); + } + m_GoScriptStore.clear(); + + for (auto itr = m_CreatureScriptStore.begin(); itr != m_CreatureScriptStore.end(); ++itr) + { + if (Creature* creature = itr->second) + creature->ClearZoneScript(); + } + m_CreatureScriptStore.clear(); + for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) { itr->second->DeleteSpawns(); @@ -251,7 +268,7 @@ void OutdoorPvP::DeleteSpawns() m_capturePoints.clear(); } -OutdoorPvP::OutdoorPvP() : m_TypeId(0), m_sendUpdate(true) { } +OutdoorPvP::OutdoorPvP() : m_TypeId(0), m_sendUpdate(true), m_map(nullptr) { } OutdoorPvP::~OutdoorPvP() { @@ -511,19 +528,19 @@ bool OPvPCapturePoint::HandleCustomSpell(Player* player, uint32 /*spellId*/, Gam return true; } -bool OutdoorPvP::HandleOpenGo(Player* player, ObjectGuid guid) +bool OutdoorPvP::HandleOpenGo(Player* player, GameObject* go) { for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (itr->second->HandleOpenGo(player, guid) >= 0) + if (itr->second->HandleOpenGo(player, go) >= 0) return true; return false; } -bool OutdoorPvP::HandleGossipOption(Player* player, ObjectGuid guid, uint32 id) +bool OutdoorPvP::HandleGossipOption(Player* player, Creature* creature, uint32 id) { for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr) - if (itr->second->HandleGossipOption(player, guid, id)) + if (itr->second->HandleGossipOption(player, creature, id)) return true; return false; @@ -547,7 +564,7 @@ bool OutdoorPvP::HandleDropFlag(Player* player, uint32 id) return false; } -bool OPvPCapturePoint::HandleGossipOption(Player* /*player*/, ObjectGuid /*guid*/, uint32 /*id*/) +bool OPvPCapturePoint::HandleGossipOption(Player* /*player*/, Creature* /*guid*/, uint32 /*id*/) { return false; } @@ -562,13 +579,12 @@ bool OPvPCapturePoint::HandleDropFlag(Player* /*player*/, uint32 /*id*/) return false; } -int32 OPvPCapturePoint::HandleOpenGo(Player* /*player*/, ObjectGuid guid) +int32 OPvPCapturePoint::HandleOpenGo(Player* /*player*/, GameObject* go) { - std::map<ObjectGuid, uint32>::iterator itr = m_ObjectTypes.find(guid); + std::map<uint32, uint32>::iterator itr = m_ObjectTypes.find(go->GetSpawnId()); if (itr != m_ObjectTypes.end()) - { return itr->second; - } + return -1; } @@ -621,22 +637,37 @@ void OutdoorPvP::TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2) void OutdoorPvP::OnGameObjectCreate(GameObject* go) { + GoScriptPair sp(go->GetGUID().GetCounter(), go); + m_GoScriptStore.insert(sp); if (go->GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT) return; - if (OPvPCapturePoint *cp = GetCapturePoint(go->GetGUID())) + if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId())) cp->m_capturePoint = go; } void OutdoorPvP::OnGameObjectRemove(GameObject* go) { + m_GoScriptStore.erase(go->GetGUID().GetCounter()); + if (go->GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT) return; - if (OPvPCapturePoint *cp = GetCapturePoint(go->GetGUID())) + if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId())) cp->m_capturePoint = NULL; } +void OutdoorPvP::OnCreatureCreate(Creature* creature) +{ + CreatureScriptPair sp(creature->GetGUID().GetCounter(), creature); + m_CreatureScriptStore.insert(sp); +} + +void OutdoorPvP::OnCreatureRemove(Creature* creature) +{ + m_CreatureScriptStore.erase(creature->GetGUID().GetCounter()); +} + void OutdoorPvP::SendDefenseMessage(uint32 zoneId, uint32 id) { DefenseMessageBuilder builder(zoneId, id); @@ -653,3 +684,12 @@ void OutdoorPvP::BroadcastWorker(Worker& _worker, uint32 zoneId) if (player->GetZoneId() == zoneId) _worker(player); } + +void OutdoorPvP::SetMapFromZone(uint32 zone) +{ + AreaTableEntry const* areaTable = GetAreaEntryByAreaID(zone); + ASSERT(areaTable); + Map* map = sMapMgr->CreateBaseMap(areaTable->mapid); + ASSERT(!map->Instanceable()); + m_map = map; +} diff --git a/src/server/game/OutdoorPvP/OutdoorPvP.h b/src/server/game/OutdoorPvP/OutdoorPvP.h index d5839956e32..d075da19ebc 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvP.h +++ b/src/server/game/OutdoorPvP/OutdoorPvP.h @@ -109,7 +109,7 @@ class OPvPCapturePoint virtual bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); - virtual int32 HandleOpenGo(Player* player, ObjectGuid guid); + virtual int32 HandleOpenGo(Player* player, GameObject* go); // returns true if the state of the objective has changed, in this case, the OutdoorPvP must send a world state ui update. virtual bool Update(uint32 diff); @@ -120,7 +120,7 @@ class OPvPCapturePoint virtual void SendChangePhase(); - virtual bool HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid); + virtual bool HandleGossipOption(Player* player, Creature* guid, uint32 gossipid); virtual bool CanTalkTo(Player* player, Creature* c, GossipMenuItems const& gso); @@ -128,7 +128,7 @@ class OPvPCapturePoint virtual void DeleteSpawns(); - ObjectGuid m_capturePointGUID; + uint32 m_capturePointSpawnId; GameObject* m_capturePoint; @@ -178,10 +178,10 @@ class OPvPCapturePoint // map to store the various gameobjects and creatures spawned by the objective // type, guid - std::map<uint32, ObjectGuid> m_Objects; - std::map<uint32, ObjectGuid> m_Creatures; - std::map<ObjectGuid, uint32> m_ObjectTypes; - std::map<ObjectGuid, uint32> m_CreatureTypes; + std::map<uint32, uint32> m_Objects; + std::map<uint32, uint32> m_Creatures; + std::map<uint32, uint32> m_ObjectTypes; + std::map<uint32, uint32> m_CreatureTypes; }; // base class for specific outdoor pvp handlers @@ -200,7 +200,9 @@ class OutdoorPvP : public ZoneScript // deletes all gos/creatures spawned by the pvp void DeleteSpawns(); - typedef std::map<ObjectGuid/*guid*/, OPvPCapturePoint*> OPvPCapturePointMap; + typedef std::map<uint32/*spawnId*/, OPvPCapturePoint*> OPvPCapturePointMap; + typedef std::pair<ObjectGuid::LowType, GameObject*> GoScriptPair; + typedef std::pair<ObjectGuid::LowType, Creature*> CreatureScriptPair; virtual void FillInitialWorldStates(WorldPacket & /*data*/) { } @@ -211,14 +213,15 @@ class OutdoorPvP : public ZoneScript virtual bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); // called on go use - virtual bool HandleOpenGo(Player* player, ObjectGuid guid); + virtual bool HandleOpenGo(Player* player, GameObject* go); // setup stuff virtual bool SetupOutdoorPvP() {return true;} void OnGameObjectCreate(GameObject* go) override; void OnGameObjectRemove(GameObject* go) override; - void OnCreatureCreate(Creature*) override { } + void OnCreatureCreate(Creature*) override; + void OnCreatureRemove(Creature*) override; // send world state update to all players present void SendUpdateWorldState(uint32 field, uint32 value); @@ -240,7 +243,7 @@ class OutdoorPvP : public ZoneScript virtual bool HandleDropFlag(Player* player, uint32 spellId); - virtual bool HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid); + virtual bool HandleGossipOption(Player* player, Creature* creature, uint32 gossipid); virtual bool CanTalkTo(Player* player, Creature* c, GossipMenuItems const& gso); @@ -261,6 +264,8 @@ class OutdoorPvP : public ZoneScript void SendDefenseMessage(uint32 zoneId, uint32 id); + Map* GetMap() const { return m_map; } + protected: // the map of the objectives belonging to this outdoorpvp @@ -284,10 +289,10 @@ class OutdoorPvP : public ZoneScript void AddCapturePoint(OPvPCapturePoint* cp) { - m_capturePoints[cp->m_capturePointGUID] = cp; + m_capturePoints[cp->m_capturePointSpawnId] = cp; } - OPvPCapturePoint * GetCapturePoint(ObjectGuid guid) const + OPvPCapturePoint * GetCapturePoint(uint32 guid) const { OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.find(guid); if (itr != m_capturePoints.end()) @@ -303,6 +308,13 @@ class OutdoorPvP : public ZoneScript template<class Worker> void BroadcastWorker(Worker& _worker, uint32 zoneId); + + // Hack to store map because this code is just shit + void SetMapFromZone(uint32 zone); + std::map<ObjectGuid::LowType, GameObject*> m_GoScriptStore; + std::map<ObjectGuid::LowType, Creature*> m_CreatureScriptStore; + + Map* m_map; }; #endif /*OUTDOOR_PVP_H_*/ diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp index 4d7b80da157..e7b6765c177 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.cpp @@ -123,7 +123,7 @@ void OutdoorPvPMgr::HandlePlayerEnterZone(Player* player, uint32 zoneid) return; itr->second->HandlePlayerEnterZone(player, zoneid); - TC_LOG_DEBUG("outdoorpvp", "Player %u entered outdoorpvp id %u", player->GetGUIDLow(), itr->second->GetTypeId()); + TC_LOG_DEBUG("outdoorpvp", "Player %u entered outdoorpvp id %u", player->GetGUID().GetCounter(), itr->second->GetTypeId()); } void OutdoorPvPMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneid) @@ -137,7 +137,7 @@ void OutdoorPvPMgr::HandlePlayerLeaveZone(Player* player, uint32 zoneid) return; itr->second->HandlePlayerLeaveZone(player, zoneid); - TC_LOG_DEBUG("outdoorpvp", "Player %u left outdoorpvp id %u", player->GetGUIDLow(), itr->second->GetTypeId()); + TC_LOG_DEBUG("outdoorpvp", "Player %u left outdoorpvp id %u", player->GetGUID().GetCounter(), itr->second->GetTypeId()); } OutdoorPvP* OutdoorPvPMgr::GetOutdoorPvPToZoneId(uint32 zoneid) @@ -181,21 +181,21 @@ ZoneScript* OutdoorPvPMgr::GetZoneScript(uint32 zoneId) return NULL; } -bool OutdoorPvPMgr::HandleOpenGo(Player* player, ObjectGuid guid) +bool OutdoorPvPMgr::HandleOpenGo(Player* player, GameObject* go) { for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr) { - if ((*itr)->HandleOpenGo(player, guid)) + if ((*itr)->HandleOpenGo(player, go)) return true; } return false; } -void OutdoorPvPMgr::HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid) +void OutdoorPvPMgr::HandleGossipOption(Player* player, Creature* creature, uint32 gossipid) { for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr) { - if ((*itr)->HandleGossipOption(player, guid, gossipid)) + if ((*itr)->HandleGossipOption(player, creature, gossipid)) return; } } diff --git a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h index 4f03dd37fac..542aad0ef0d 100644 --- a/src/server/game/OutdoorPvP/OutdoorPvPMgr.h +++ b/src/server/game/OutdoorPvP/OutdoorPvPMgr.h @@ -70,7 +70,7 @@ class OutdoorPvPMgr bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go); // handle custom go if registered - bool HandleOpenGo(Player* player, ObjectGuid guid); + bool HandleOpenGo(Player* player, GameObject* go); ZoneScript* GetZoneScript(uint32 zoneId); @@ -78,7 +78,7 @@ class OutdoorPvPMgr void Update(uint32 diff); - void HandleGossipOption(Player* player, ObjectGuid guid, uint32 gossipid); + void HandleGossipOption(Player* player, Creature* creature, uint32 gossipid); bool CanTalkTo(Player* player, Creature* creature, GossipMenuItems const& gso); diff --git a/src/server/game/Pools/PoolMgr.cpp b/src/server/game/Pools/PoolMgr.cpp index 3f561539917..8f3d4a758f3 100644 --- a/src/server/game/Pools/PoolMgr.cpp +++ b/src/server/game/Pools/PoolMgr.cpp @@ -221,8 +221,17 @@ void PoolGroup<Creature>::Despawn1Object(uint32 guid) { sObjectMgr->RemoveCreatureFromGrid(guid, data); - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, guid), (Creature*)NULL)) - creature->AddObjectToRemoveList(); + Map* map = sMapMgr->CreateBaseMap(data->mapid); + if (!map->Instanceable()) + { + auto creatureBounds = map->GetCreatureBySpawnIdStore().equal_range(guid); + for (auto itr = creatureBounds.first; itr != creatureBounds.second;) + { + Creature* creature = itr->second; + ++itr; + creature->AddObjectToRemoveList(); + } + } } } @@ -234,8 +243,17 @@ void PoolGroup<GameObject>::Despawn1Object(uint32 guid) { sObjectMgr->RemoveGameobjectFromGrid(guid, data); - if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, guid), (GameObject*)NULL)) - pGameobject->AddObjectToRemoveList(); + Map* map = sMapMgr->CreateBaseMap(data->mapid); + if (!map->Instanceable()) + { + auto gameobjectBounds = map->GetGameObjectBySpawnIdStore().equal_range(guid); + for (auto itr = gameobjectBounds.first; itr != gameobjectBounds.second;) + { + GameObject* go = itr->second; + ++itr; + go->AddObjectToRemoveList(); + } + } } } @@ -507,20 +525,16 @@ void PoolGroup<Quest>::SpawnObject(ActivePoolData& spawns, uint32 limit, uint32 // Method that does the respawn job on the specified creature template <> -void PoolGroup<Creature>::ReSpawn1Object(PoolObject* obj) +void PoolGroup<Creature>::ReSpawn1Object(PoolObject* /*obj*/) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(obj->guid)) - if (Creature* creature = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_UNIT, data->id, obj->guid), (Creature*)NULL)) - creature->GetMap()->AddToMap(creature); + // Creature is still on map, nothing to do } // Method that does the respawn job on the specified gameobject template <> -void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* obj) +void PoolGroup<GameObject>::ReSpawn1Object(PoolObject* /*obj*/) { - if (GameObjectData const* data = sObjectMgr->GetGOData(obj->guid)) - if (GameObject* pGameobject = ObjectAccessor::GetObjectInWorld(ObjectGuid(HIGHGUID_GAMEOBJECT, data->id, obj->guid), (GameObject*)NULL)) - pGameobject->GetMap()->AddToMap(pGameobject); + // GameObject is still on map, nothing to do } // Nothing to do for a child Pool diff --git a/src/server/game/Quests/QuestDef.cpp b/src/server/game/Quests/QuestDef.cpp index eea0fd72e8b..58bc4915d3f 100644 --- a/src/server/game/Quests/QuestDef.cpp +++ b/src/server/game/Quests/QuestDef.cpp @@ -29,21 +29,21 @@ Quest::Quest(Field* questRecord) ZoneOrSort = questRecord[4].GetInt16(); Type = questRecord[5].GetUInt16(); SuggestedPlayers = questRecord[6].GetUInt8(); - LimitTime = questRecord[7].GetUInt32(); - RequiredRaces = questRecord[8].GetUInt16(); + TimeAllowed = questRecord[7].GetUInt32(); + AllowableRaces = questRecord[8].GetUInt16(); RequiredFactionId1 = questRecord[9].GetUInt16(); RequiredFactionId2 = questRecord[10].GetUInt16(); RequiredFactionValue1 = questRecord[11].GetInt32(); RequiredFactionValue2 = questRecord[12].GetInt32(); - NextQuestIdChain = questRecord[13].GetUInt32(); - RewardXPId = questRecord[14].GetUInt8(); - RewardOrRequiredMoney = questRecord[15].GetInt32(); - RewardMoneyMaxLevel = questRecord[16].GetUInt32(); - RewardSpell = questRecord[17].GetUInt32(); - RewardSpellCast = questRecord[18].GetInt32(); + RewardNextQuest = questRecord[13].GetUInt32(); + RewardXPDifficulty = questRecord[14].GetUInt8(); + RewardMoney = questRecord[15].GetInt32(); + RewardBonusMoney = questRecord[16].GetUInt32(); + RewardDisplaySpell = questRecord[17].GetUInt32(); + RewardSpell = questRecord[18].GetInt32(); RewardHonor = questRecord[19].GetUInt32(); - RewardHonorMultiplier = questRecord[20].GetFloat(); - SourceItemId = questRecord[21].GetUInt32(); + RewardKillHonor = questRecord[20].GetFloat(); + StartItem = questRecord[21].GetUInt32(); Flags = questRecord[22].GetUInt32(); RewardTitleId = questRecord[23].GetUInt8(); RequiredPlayerKills = questRecord[24].GetUInt8(); @@ -69,14 +69,14 @@ Quest::Quest(Field* questRecord) RewardFactionValueIdOverride[i] = questRecord[49+i*3].GetInt32(); } - PointMapId = questRecord[62].GetUInt16(); - PointX = questRecord[63].GetFloat(); - PointY = questRecord[64].GetFloat(); - PointOption = questRecord[65].GetUInt32(); + POIContinent = questRecord[62].GetUInt16(); + POIx = questRecord[63].GetFloat(); + POIy = questRecord[64].GetFloat(); + POIPriority = questRecord[65].GetUInt32(); Title = questRecord[66].GetString(); Objectives = questRecord[67].GetString(); Details = questRecord[68].GetString(); - EndText = questRecord[69].GetString(); + AreaDescription = questRecord[69].GetString(); CompletedText = questRecord[70].GetString(); for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) @@ -86,10 +86,10 @@ Quest::Quest(Field* questRecord) RequiredNpcOrGoCount[i] = questRecord[75+i].GetUInt16(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - RequiredSourceItemId[i] = questRecord[79+i].GetUInt32(); + ItemDrop[i] = questRecord[79+i].GetUInt32(); for (int i = 0; i < QUEST_SOURCE_ITEM_IDS_COUNT; ++i) - RequiredSourceItemCount[i] = questRecord[83+i].GetUInt16(); + ItemDropQuantity[i] = questRecord[83+i].GetUInt16(); for (int i = 0; i < QUEST_ITEM_OBJECTIVES_COUNT; ++i) RequiredItemId[i] = questRecord[87+i].GetUInt32(); @@ -102,6 +102,9 @@ Quest::Quest(Field* questRecord) for (int i = 0; i < QUEST_OBJECTIVES_COUNT; ++i) ObjectiveText[i] = questRecord[100+i].GetString(); + EmoteOnIncomplete = 0; + EmoteOnComplete = 0; + //int32 VerifiedBuild = questRecord[104].GetInt32(); _reqItemsCount = 0; @@ -169,7 +172,7 @@ void Quest::LoadQuestTemplateAddon(Field* fields) RequiredMaxRepFaction = fields[12].GetUInt16(); RequiredMinRepValue = fields[13].GetInt32(); RequiredMaxRepValue = fields[14].GetInt32(); - SourceItemIdCount = fields[15].GetUInt8(); + StartItemCount = fields[15].GetUInt8(); SpecialFlags = fields[16].GetUInt8(); if (SpecialFlags & QUEST_SPECIAL_FLAGS_AUTO_ACCEPT) @@ -191,7 +194,7 @@ uint32 Quest::XPValue(Player* player) const else if (diffFactor > 10) diffFactor = 10; - uint32 xp = diffFactor * xpentry->Exp[RewardXPId] / 10; + uint32 xp = diffFactor * xpentry->Exp[RewardXPDifficulty] / 10; if (xp <= 100) xp = 5 * ((xp + 2) / 5); else if (xp <= 500) @@ -210,11 +213,11 @@ uint32 Quest::XPValue(Player* player) const int32 Quest::GetRewOrReqMoney() const { // RequiredMoney: the amount is the negative copper sum. - if (RewardOrRequiredMoney <= 0) - return RewardOrRequiredMoney; + if (RewardMoney <= 0) + return RewardMoney; // RewardMoney: the positive amount - return int32(RewardOrRequiredMoney * sWorld->getRate(RATE_MONEY_QUEST)); + return int32(RewardMoney * sWorld->getRate(RATE_MONEY_QUEST)); } uint32 Quest::GetRewMoneyMaxLevel() const @@ -224,7 +227,7 @@ uint32 Quest::GetRewMoneyMaxLevel() const return 0; // Else, return the rewarded copper sum modified by the rate - return uint32(RewardMoneyMaxLevel * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST)); + return uint32(RewardBonusMoney * sWorld->getRate(RATE_MONEY_MAX_LEVEL_QUEST)); } bool Quest::IsAutoAccept() const diff --git a/src/server/game/Quests/QuestDef.h b/src/server/game/Quests/QuestDef.h index 78fd065e9bd..91b4a3181f5 100644 --- a/src/server/game/Quests/QuestDef.h +++ b/src/server/game/Quests/QuestDef.h @@ -182,7 +182,7 @@ struct QuestLocale StringVector Objectives; StringVector OfferRewardText; StringVector RequestItemsText; - StringVector EndText; + StringVector AreaDescription; StringVector CompletedText; std::vector< StringVector > ObjectiveText; }; @@ -217,7 +217,7 @@ class Quest int32 GetQuestLevel() const { return Level; } uint32 GetType() const { return Type; } uint32 GetRequiredClasses() const { return RequiredClasses; } - uint32 GetRequiredRaces() const { return RequiredRaces; } + uint32 GetAllowableRaces() const { return AllowableRaces; } uint32 GetRequiredSkill() const { return RequiredSkillId; } uint32 GetRequiredSkillValue() const { return RequiredSkillPoints; } uint32 GetRepObjectiveFaction() const { return RequiredFactionId1; } @@ -229,38 +229,38 @@ class Quest uint32 GetRequiredMaxRepFaction() const { return RequiredMaxRepFaction; } int32 GetRequiredMaxRepValue() const { return RequiredMaxRepValue; } uint32 GetSuggestedPlayers() const { return SuggestedPlayers; } - uint32 GetLimitTime() const { return LimitTime; } + uint32 GetTimeAllowed() const { return TimeAllowed; } int32 GetPrevQuestId() const { return PrevQuestId; } int32 GetNextQuestId() const { return NextQuestId; } int32 GetExclusiveGroup() const { return ExclusiveGroup; } - uint32 GetNextQuestInChain() const { return NextQuestIdChain; } + uint32 GetNextQuestInChain() const { return RewardNextQuest; } uint32 GetCharTitleId() const { return RewardTitleId; } uint32 GetPlayersSlain() const { return RequiredPlayerKills; } uint32 GetBonusTalents() const { return RewardTalents; } int32 GetRewArenaPoints() const {return RewardArenaPoints; } - uint32 GetXPId() const { return RewardXPId; } - uint32 GetSrcItemId() const { return SourceItemId; } - uint32 GetSrcItemCount() const { return SourceItemIdCount; } + uint32 GetXPId() const { return RewardXPDifficulty; } + uint32 GetSrcItemId() const { return StartItem; } + uint32 GetSrcItemCount() const { return StartItemCount; } uint32 GetSrcSpell() const { return SourceSpellid; } std::string const& GetTitle() const { return Title; } std::string const& GetDetails() const { return Details; } std::string const& GetObjectives() const { return Objectives; } std::string const& GetOfferRewardText() const { return OfferRewardText; } std::string const& GetRequestItemsText() const { return RequestItemsText; } - std::string const& GetEndText() const { return EndText; } + std::string const& GetAreaDescription() const { return AreaDescription; } std::string const& GetCompletedText() const { return CompletedText; } int32 GetRewOrReqMoney() const; uint32 GetRewHonorAddition() const { return RewardHonor; } - float GetRewHonorMultiplier() const { return RewardHonorMultiplier; } + float GetRewHonorMultiplier() const { return RewardKillHonor; } uint32 GetRewMoneyMaxLevel() const; // use in XP calculation at client - uint32 GetRewSpell() const { return RewardSpell; } - int32 GetRewSpellCast() const { return RewardSpellCast; } + uint32 GetRewSpell() const { return RewardDisplaySpell; } + int32 GetRewSpellCast() const { return RewardSpell; } uint32 GetRewMailTemplateId() const { return RewardMailTemplateId; } uint32 GetRewMailDelaySecs() const { return RewardMailDelay; } - uint32 GetPointMapId() const { return PointMapId; } - float GetPointX() const { return PointX; } - float GetPointY() const { return PointY; } - uint32 GetPointOpt() const { return PointOption; } + uint32 GetPOIContinent() const { return POIContinent; } + float GetPOIx() const { return POIx; } + float GetPOIy() const { return POIy; } + uint32 GetPointOpt() const { return POIPriority; } uint32 GetIncompleteEmote() const { return EmoteOnIncomplete; } uint32 GetCompleteEmote() const { return EmoteOnComplete; } bool IsRepeatable() const { return SpecialFlags & QUEST_SPECIAL_FLAGS_REPEATABLE; } @@ -281,8 +281,8 @@ class Quest std::string ObjectiveText[QUEST_OBJECTIVES_COUNT]; uint32 RequiredItemId[QUEST_ITEM_OBJECTIVES_COUNT]; uint32 RequiredItemCount[QUEST_ITEM_OBJECTIVES_COUNT]; - uint32 RequiredSourceItemId[QUEST_SOURCE_ITEM_IDS_COUNT]; - uint32 RequiredSourceItemCount[QUEST_SOURCE_ITEM_IDS_COUNT]; + uint32 ItemDrop[QUEST_SOURCE_ITEM_IDS_COUNT]; + uint32 ItemDropQuantity[QUEST_SOURCE_ITEM_IDS_COUNT]; int32 RequiredNpcOrGo[QUEST_OBJECTIVES_COUNT]; // >0 Creature <0 Gameobject uint32 RequiredNpcOrGoCount[QUEST_OBJECTIVES_COUNT]; uint32 RewardChoiceItemId[QUEST_REWARD_CHOICES_COUNT]; @@ -322,38 +322,38 @@ class Quest uint32 MinLevel; int32 Level; uint32 Type; - uint32 RequiredRaces; + uint32 AllowableRaces; uint32 RequiredFactionId1; int32 RequiredFactionValue1; uint32 RequiredFactionId2; int32 RequiredFactionValue2; uint32 SuggestedPlayers; - uint32 LimitTime; + uint32 TimeAllowed; uint32 Flags; uint32 RewardTitleId; uint32 RequiredPlayerKills; uint32 RewardTalents; int32 RewardArenaPoints; - uint32 NextQuestIdChain; - uint32 RewardXPId; - uint32 SourceItemId; + uint32 RewardNextQuest; + uint32 RewardXPDifficulty; + uint32 StartItem; std::string Title; std::string Details; std::string Objectives; std::string OfferRewardText; std::string RequestItemsText; - std::string EndText; + std::string AreaDescription; std::string CompletedText; uint32 RewardHonor; - float RewardHonorMultiplier; - int32 RewardOrRequiredMoney; - uint32 RewardMoneyMaxLevel; - uint32 RewardSpell; - int32 RewardSpellCast; - uint32 PointMapId; - float PointX; - float PointY; - uint32 PointOption; + float RewardKillHonor; + int32 RewardMoney; + uint32 RewardBonusMoney; + uint32 RewardDisplaySpell; + int32 RewardSpell; + uint32 POIContinent; + float POIx; + float POIy; + uint32 POIPriority; uint32 EmoteOnIncomplete; uint32 EmoteOnComplete; @@ -372,7 +372,7 @@ class Quest int32 RequiredMinRepValue = 0; uint32 RequiredMaxRepFaction = 0; int32 RequiredMaxRepValue = 0; - uint32 SourceItemIdCount = 0; + uint32 StartItemCount = 0; uint32 SpecialFlags = 0; // custom flags, not sniffed/WDB }; diff --git a/src/server/game/Reputation/ReputationMgr.cpp b/src/server/game/Reputation/ReputationMgr.cpp index a3e458503d6..a4065fa6f82 100644 --- a/src/server/game/Reputation/ReputationMgr.cpp +++ b/src/server/game/Reputation/ReputationMgr.cpp @@ -512,7 +512,7 @@ void ReputationMgr::LoadFromDB(PreparedQueryResult result) // Set initial reputations (so everything is nifty before DB data load) Initialize(); - //QueryResult* result = CharacterDatabase.PQuery("SELECT faction, standing, flags FROM character_reputation WHERE guid = '%u'", GetGUIDLow()); + //QueryResult* result = CharacterDatabase.PQuery("SELECT faction, standing, flags FROM character_reputation WHERE guid = '%u'", GetGUID().GetCounter()); if (result) { @@ -574,12 +574,12 @@ void ReputationMgr::SaveToDB(SQLTransaction& trans) if (itr->second.needSave) { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_CHAR_REPUTATION_BY_FACTION); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt16(1, uint16(itr->second.ID)); trans->Append(stmt); stmt = CharacterDatabase.GetPreparedStatement(CHAR_INS_CHAR_REPUTATION_BY_FACTION); - stmt->setUInt32(0, _player->GetGUIDLow()); + stmt->setUInt32(0, _player->GetGUID().GetCounter()); stmt->setUInt16(1, uint16(itr->second.ID)); stmt->setInt32(2, itr->second.Standing); stmt->setUInt16(3, uint16(itr->second.Flags)); diff --git a/src/server/game/Scripting/MapScripts.cpp b/src/server/game/Scripting/MapScripts.cpp index f5c4375712c..a369750b0c6 100644 --- a/src/server/game/Scripting/MapScripts.cpp +++ b/src/server/game/Scripting/MapScripts.cpp @@ -114,8 +114,8 @@ inline Player* Map::_GetScriptPlayerSourceOrTarget(Object* source, Object* targe if (!player) TC_LOG_ERROR("scripts", "%s neither source nor target object is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.", scriptInfo->GetDebugInfo().c_str(), - source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUIDLow() : 0, - target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUIDLow() : 0); + source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUID().GetCounter() : 0, + target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUID().GetCounter() : 0); } return player; } @@ -147,8 +147,8 @@ inline Creature* Map::_GetScriptCreatureSourceOrTarget(Object* source, Object* t if (!creature) TC_LOG_ERROR("scripts", "%s neither source nor target are creatures (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.", scriptInfo->GetDebugInfo().c_str(), - source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUIDLow() : 0, - target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUIDLow() : 0); + source ? source->GetTypeId() : 0, source ? source->GetEntry() : 0, source ? source->GetGUID().GetCounter() : 0, + target ? target->GetTypeId() : 0, target ? target->GetEntry() : 0, target ? target->GetGUID().GetCounter() : 0); } return creature; } @@ -160,7 +160,7 @@ inline Unit* Map::_GetScriptUnit(Object* obj, bool isSource, const ScriptInfo* s TC_LOG_ERROR("scripts", "%s %s object is NULL.", scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target"); else if (!obj->isType(TYPEMASK_UNIT)) TC_LOG_ERROR("scripts", "%s %s object is not unit (TypeId: %u, Entry: %u, GUID: %u), skipping.", - scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow()); + scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUID().GetCounter()); else { unit = obj->ToUnit(); @@ -181,7 +181,7 @@ inline Player* Map::_GetScriptPlayer(Object* obj, bool isSource, const ScriptInf player = obj->ToPlayer(); if (!player) TC_LOG_ERROR("scripts", "%s %s object is not a player (TypeId: %u, Entry: %u, GUID: %u).", - scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow()); + scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUID().GetCounter()); } return player; } @@ -196,7 +196,7 @@ inline Creature* Map::_GetScriptCreature(Object* obj, bool isSource, const Scrip creature = obj->ToCreature(); if (!creature) TC_LOG_ERROR("scripts", "%s %s object is not a creature (TypeId: %u, Entry: %u, GUID: %u).", scriptInfo->GetDebugInfo().c_str(), - isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow()); + isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUID().GetCounter()); } return creature; } @@ -212,7 +212,7 @@ inline WorldObject* Map::_GetScriptWorldObject(Object* obj, bool isSource, const pWorldObject = dynamic_cast<WorldObject*>(obj); if (!pWorldObject) TC_LOG_ERROR("scripts", "%s %s object is not a world object (TypeId: %u, Entry: %u, GUID: %u).", - scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUIDLow()); + scriptInfo->GetDebugInfo().c_str(), isSource ? "source" : "target", obj->GetTypeId(), obj->GetEntry(), obj->GetGUID().GetCounter()); } return pWorldObject; } @@ -236,13 +236,13 @@ inline void Map::_ScriptProcessDoor(Object* source, Object* target, const Script TC_LOG_ERROR("scripts", "%s source object is NULL.", scriptInfo->GetDebugInfo().c_str()); else if (!source->isType(TYPEMASK_UNIT)) TC_LOG_ERROR("scripts", "%s source object is not unit (TypeId: %u, Entry: %u, GUID: %u), skipping.", scriptInfo->GetDebugInfo().c_str(), - source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); + source->GetTypeId(), source->GetEntry(), source->GetGUID().GetCounter()); else { WorldObject* wSource = dynamic_cast <WorldObject*> (source); if (!wSource) TC_LOG_ERROR("scripts", "%s source object could not be cast to world object (TypeId: %u, Entry: %u, GUID: %u), skipping.", - scriptInfo->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); + scriptInfo->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUID().GetCounter()); else { GameObject* pDoor = _FindGameObject(wSource, guid); @@ -250,7 +250,7 @@ inline void Map::_ScriptProcessDoor(Object* source, Object* target, const Script TC_LOG_ERROR("scripts", "%s gameobject was not found (guid: %u).", scriptInfo->GetDebugInfo().c_str(), guid); else if (pDoor->GetGoType() != GAMEOBJECT_TYPE_DOOR) TC_LOG_ERROR("scripts", "%s gameobject is not a door (GoType: %u, Entry: %u, GUID: %u).", - scriptInfo->GetDebugInfo().c_str(), pDoor->GetGoType(), pDoor->GetEntry(), pDoor->GetGUIDLow()); + scriptInfo->GetDebugInfo().c_str(), pDoor->GetGoType(), pDoor->GetEntry(), pDoor->GetGUID().GetCounter()); else if (bOpen == (pDoor->GetGoState() == GO_STATE_READY)) { pDoor->UseDoorOrButton(nTimeToToggle); @@ -268,18 +268,11 @@ inline void Map::_ScriptProcessDoor(Object* source, Object* target, const Script inline GameObject* Map::_FindGameObject(WorldObject* searchObject, uint32 guid) const { - GameObject* gameobject = NULL; + auto bounds = searchObject->GetMap()->GetGameObjectBySpawnIdStore().equal_range(guid); + if (bounds.first == bounds.second) + return nullptr; - CellCoord p(Trinity::ComputeCellCoord(searchObject->GetPositionX(), searchObject->GetPositionY())); - Cell cell(p); - - Trinity::GameObjectWithDbGUIDCheck goCheck(*searchObject, guid); - Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck> checker(searchObject, gameobject, goCheck); - - TypeContainerVisitor<Trinity::GameObjectSearcher<Trinity::GameObjectWithDbGUIDCheck>, GridTypeMapContainer > objectChecker(checker); - cell.Visit(p, objectChecker, *searchObject->GetMap(), *searchObject, searchObject->GetGridActivationRange()); - - return gameobject; + return bounds.first->second; } /// Process queued scripts @@ -300,33 +293,30 @@ void Map::ScriptsProcess() { switch (step.sourceGUID.GetHigh()) { - case HIGHGUID_ITEM: // as well as HIGHGUID_CONTAINER + case HighGuid::Item: // as well as HighGuid::Container if (Player* player = HashMapHolder<Player>::Find(step.ownerGUID)) source = player->GetItemByGuid(step.sourceGUID); break; - case HIGHGUID_UNIT: - case HIGHGUID_VEHICLE: - source = HashMapHolder<Creature>::Find(step.sourceGUID); + case HighGuid::Unit: + case HighGuid::Vehicle: + source = GetCreature(step.sourceGUID); break; - case HIGHGUID_PET: - source = HashMapHolder<Pet>::Find(step.sourceGUID); + case HighGuid::Pet: + source = GetPet(step.sourceGUID); break; - case HIGHGUID_PLAYER: + case HighGuid::Player: source = HashMapHolder<Player>::Find(step.sourceGUID); break; - case HIGHGUID_TRANSPORT: - case HIGHGUID_GAMEOBJECT: - source = HashMapHolder<GameObject>::Find(step.sourceGUID); + case HighGuid::Transport: + case HighGuid::GameObject: + source = GetGameObject(step.sourceGUID); break; - case HIGHGUID_CORPSE: - source = HashMapHolder<Corpse>::Find(step.sourceGUID); + case HighGuid::Corpse: + source = GetCorpse(step.sourceGUID); break; - case HIGHGUID_MO_TRANSPORT: - { - GameObject* go = HashMapHolder<GameObject>::Find(step.sourceGUID); - source = go ? go->ToTransport() : NULL; + case HighGuid::Mo_Transport: + source = GetTransport(step.sourceGUID); break; - } default: TC_LOG_ERROR("scripts", "%s source with unsupported high guid %s.", step.script->GetDebugInfo().c_str(), step.sourceGUID.ToString().c_str()); @@ -339,29 +329,26 @@ void Map::ScriptsProcess() { switch (step.targetGUID.GetHigh()) { - case HIGHGUID_UNIT: - case HIGHGUID_VEHICLE: - target = HashMapHolder<Creature>::Find(step.targetGUID); + case HighGuid::Unit: + case HighGuid::Vehicle: + target = GetCreature(step.targetGUID); break; - case HIGHGUID_PET: - target = HashMapHolder<Pet>::Find(step.targetGUID); + case HighGuid::Pet: + target = GetPet(step.targetGUID); break; - case HIGHGUID_PLAYER: // empty GUID case also + case HighGuid::Player: // empty GUID case also target = HashMapHolder<Player>::Find(step.targetGUID); break; - case HIGHGUID_TRANSPORT: - case HIGHGUID_GAMEOBJECT: - target = HashMapHolder<GameObject>::Find(step.targetGUID); + case HighGuid::Transport: + case HighGuid::GameObject: + target = GetGameObject(step.targetGUID); break; - case HIGHGUID_CORPSE: - target = HashMapHolder<Corpse>::Find(step.targetGUID); + case HighGuid::Corpse: + target = GetCorpse(step.targetGUID); break; - case HIGHGUID_MO_TRANSPORT: - { - GameObject* go = HashMapHolder<GameObject>::Find(step.targetGUID); - target = go ? go->ToTransport() : NULL; + case HighGuid::Mo_Transport: + target = GetTransport(step.targetGUID); break; - } default: TC_LOG_ERROR("scripts", "%s target with unsupported high guid %s.", step.script->GetDebugInfo().c_str(), step.targetGUID.ToString().c_str()); @@ -470,7 +457,7 @@ void Map::ScriptsProcess() if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) TC_LOG_ERROR("scripts", "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, - cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); + cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUID().GetCounter()); else cSource->SetFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } @@ -484,7 +471,7 @@ void Map::ScriptsProcess() if (step.script->FlagToggle.FieldID <= OBJECT_FIELD_ENTRY || step.script->FlagToggle.FieldID >= cSource->GetValuesCount()) TC_LOG_ERROR("scripts", "%s wrong field %u (max count: %u) in object (TypeId: %u, Entry: %u, GUID: %u) specified, skipping.", step.script->GetDebugInfo().c_str(), step.script->FlagToggle.FieldID, - cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUIDLow()); + cSource->GetValuesCount(), cSource->GetTypeId(), cSource->GetEntry(), cSource->GetGUID().GetCounter()); else cSource->RemoveFlag(step.script->FlagToggle.FieldID, step.script->FlagToggle.FieldValue); } @@ -526,7 +513,7 @@ void Map::ScriptsProcess() if (source->GetTypeId() != TYPEID_UNIT && source->GetTypeId() != TYPEID_GAMEOBJECT && source->GetTypeId() != TYPEID_PLAYER) { TC_LOG_ERROR("scripts", "%s source is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", - step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow()); + step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUID().GetCounter()); break; } worldObject = dynamic_cast<WorldObject*>(source); @@ -539,7 +526,7 @@ void Map::ScriptsProcess() if (target->GetTypeId() != TYPEID_UNIT && target->GetTypeId() != TYPEID_GAMEOBJECT && target->GetTypeId() != TYPEID_PLAYER) { TC_LOG_ERROR("scripts", "%s target is not unit, gameobject or player (TypeId: %u, Entry: %u, GUID: %u), skipping.", - step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); + step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUID().GetCounter()); break; } worldObject = dynamic_cast<WorldObject*>(target); @@ -547,8 +534,8 @@ void Map::ScriptsProcess() else { TC_LOG_ERROR("scripts", "%s neither source nor target is player (source: TypeId: %u, Entry: %u, GUID: %u; target: TypeId: %u, Entry: %u, GUID: %u), skipping.", - step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUIDLow(), - target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); + step.script->GetDebugInfo().c_str(), source->GetTypeId(), source->GetEntry(), source->GetGUID().GetCounter(), + target->GetTypeId(), target->GetEntry(), target->GetGUID().GetCounter()); break; } } @@ -653,7 +640,7 @@ void Map::ScriptsProcess() if (target->GetTypeId() != TYPEID_GAMEOBJECT) { TC_LOG_ERROR("scripts", "%s target object is not gameobject (TypeId: %u, Entry: %u, GUID: %u), skipping.", - step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUIDLow()); + step.script->GetDebugInfo().c_str(), target->GetTypeId(), target->GetEntry(), target->GetGUID().GetCounter()); break; } @@ -795,22 +782,15 @@ void Map::ScriptsProcess() } Creature* cTarget = NULL; - WorldObject* wSource = dynamic_cast <WorldObject*> (source); - if (wSource) //using grid searcher - { - CellCoord p(Trinity::ComputeCellCoord(wSource->GetPositionX(), wSource->GetPositionY())); - Cell cell(p); - - Trinity::CreatureWithDbGUIDCheck target_check(wSource, step.script->CallScript.CreatureEntry); - Trinity::CreatureSearcher<Trinity::CreatureWithDbGUIDCheck> checker(wSource, cTarget, target_check); - - TypeContainerVisitor<Trinity::CreatureSearcher <Trinity::CreatureWithDbGUIDCheck>, GridTypeMapContainer > unit_checker(checker); - cell.Visit(p, unit_checker, *wSource->GetMap(), *wSource, wSource->GetGridActivationRange()); - } - else //check hashmap holders + auto creatureBounds = _creatureBySpawnIdStore.equal_range(step.script->CallScript.CreatureEntry); + if (creatureBounds.first != creatureBounds.second) { - if (CreatureData const* data = sObjectMgr->GetCreatureData(step.script->CallScript.CreatureEntry)) - cTarget = ObjectAccessor::GetObjectInWorld<Creature>(data->mapid, data->posX, data->posY, ObjectGuid(HIGHGUID_UNIT, data->id, step.script->CallScript.CreatureEntry), cTarget); + // Prefer alive (last respawned) creature + auto creatureItr = std::find_if(creatureBounds.first, creatureBounds.second, [](Map::CreatureBySpawnIdContainer::value_type const& pair) + { + return pair.second->IsAlive(); + }); + cTarget = creatureItr != creatureBounds.second ? creatureItr->second : creatureBounds.first->second; } if (!cTarget) @@ -839,7 +819,7 @@ void Map::ScriptsProcess() { if (cSource->isDead()) TC_LOG_ERROR("scripts", "%s creature is already dead (Entry: %u, GUID: %u)", - step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUIDLow()); + step.script->GetDebugInfo().c_str(), cSource->GetEntry(), cSource->GetGUID().GetCounter()); else { cSource->setDeathState(JUST_DIED); diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index aed829a7b57..0ece05f1d93 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -108,7 +108,7 @@ class ScriptRegistry TC_LOG_ERROR("scripts", "Script '%s' already assigned with the same script name, so the script can't work.", script->GetName().c_str()); - ASSERT(false); // Error that should be fixed ASAP. + ABORT(); // Error that should be fixed ASAP. } } else @@ -960,7 +960,7 @@ bool ScriptMgr::OnAreaTrigger(Player* player, AreaTriggerEntry const* trigger) Battleground* ScriptMgr::CreateBattleground(BattlegroundTypeId /*typeId*/) { /// @todo Implement script-side battlegrounds. - ASSERT(false); + ABORT(); return NULL; } diff --git a/src/server/game/Server/WorldSession.cpp b/src/server/game/Server/WorldSession.cpp index bb22d27221e..45a816eda9b 100644 --- a/src/server/game/Server/WorldSession.cpp +++ b/src/server/game/Server/WorldSession.cpp @@ -180,9 +180,9 @@ std::string WorldSession::GetPlayerInfo() const } /// Get player guid if available. Use for logging purposes only -uint32 WorldSession::GetGuidLow() const +uint32 WorldSession::GetGUIDLow() const { - return GetPlayer() ? GetPlayer()->GetGUIDLow() : 0; + return GetPlayer() ? GetPlayer()->GetGUID().GetCounter() : 0; } /// Send a packet to the client @@ -538,8 +538,8 @@ void WorldSession::LogoutPlayer(bool save) } //! Broadcast a logout message to the player's friends - sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUIDLow(), true); - sSocialMgr->RemovePlayerSocial(_player->GetGUIDLow()); + sSocialMgr->SendFriendStatus(_player, FRIEND_OFFLINE, _player->GetGUID().GetCounter(), true); + sSocialMgr->RemovePlayerSocial(_player->GetGUID().GetCounter()); //! Call script hook before deletion sScriptMgr->OnPlayerLogout(_player); @@ -550,7 +550,7 @@ void WorldSession::LogoutPlayer(bool save) // calls to GetMap in this case may cause crashes _player->CleanupsBeforeDelete(); TC_LOG_INFO("entities.player.character", "Account: %d (IP: %s) Logout Character:[%s] (GUID: %u) Level: %d", - GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUIDLow(), _player->getLevel()); + GetAccountId(), GetRemoteAddress().c_str(), _player->GetName().c_str(), _player->GetGUID().GetCounter(), _player->getLevel()); if (Map* _map = _player->FindMap()) _map->RemovePlayerFromMap(_player, true); @@ -709,7 +709,7 @@ void WorldSession::LoadAccountData(PreparedQueryResult result, uint32 mask) void WorldSession::SetAccountData(AccountDataType type, time_t tm, std::string const& data) { uint32 id = 0; - uint32 index = 0; + CharacterDatabaseStatements index; if ((1 << type) & GLOBAL_CACHE_MASK) { id = GetAccountId(); @@ -830,7 +830,7 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi) { \ TC_LOG_DEBUG("entities.unit", "WorldSession::ReadMovementInfo: Violation of MovementFlags found (%s). " \ "MovementFlags: %u, MovementFlags2: %u for player GUID: %u. Mask %u will be removed.", \ - STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUIDLow(), maskToRemove); \ + STRINGIZE(check), mi->GetMovementFlags(), mi->GetExtraMovementFlags(), GetPlayer()->GetGUID().GetCounter(), maskToRemove); \ mi->RemoveMovementFlag((maskToRemove)); \ } \ } @@ -840,13 +840,33 @@ void WorldSession::ReadMovementInfo(WorldPacket &data, MovementInfo* mi) mi->RemoveMovementFlag((maskToRemove)); #endif - /*! This must be a packet spoofing attempt. MOVEMENTFLAG_ROOT sent from the client is not valid in conjunction with any of the moving movement flags such as MOVEMENTFLAG_FORWARD. It will freeze clients that receive this player's movement info. */ - REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), - MOVEMENTFLAG_ROOT); + // Only adjust movement flag removal for vehicles with the VEHICLE_FLAG_FIXED_POSITION flag, or the hard coded exceptions below: + // 30236 | Argent Cannon + // 39759 | Tankbuster Cannon + if (GetPlayer()->GetVehicleBase() && ((GetPlayer()->GetVehicle()->GetVehicleInfo()->m_flags & VEHICLE_FLAG_FIXED_POSITION) || GetPlayer()->GetVehicleBase()->GetEntry() == 30236 || GetPlayer()->GetVehicleBase()->GetEntry() == 39759)) + { + // Actually players in rooted vehicles still send commands, don't clear root for these! + // Check specifically for the following conditions: + // MOVEMENTFLAG_ROOT + no other flags (0x800) + // MOVEMENTFLAG_ROOT + MOVEMENTFLAG_LEFT (0x810) + // MOVEMENTFLAG_ROOT + MOVEMENTFLAG_RIGHT (0x820) + // MOVEMENTFLAG_ROOT + MOVEMENTFLAG_PITCH_UP (0x840) + // MOVEMENTFLAG_ROOT + MOVEMENTFLAG_PITCH_DOWN (0x880) + // If none of these are true, clear the root + if (mi->HasMovementFlag(MOVEMENTFLAG_ROOT) && mi->HasMovementFlag(MOVEMENTFLAG_LEFT | MOVEMENTFLAG_RIGHT | MOVEMENTFLAG_PITCH_UP | MOVEMENTFLAG_PITCH_DOWN)) + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), + MOVEMENTFLAG_MASK_MOVING); + } + else + { + // Only remove here for non vehicles + REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_ROOT), + MOVEMENTFLAG_ROOT); + } //! Cannot hover without SPELL_AURA_HOVER REMOVE_VIOLATING_FLAGS(mi->HasMovementFlag(MOVEMENTFLAG_HOVER) && !GetPlayer()->HasAuraType(SPELL_AURA_HOVER), @@ -1082,7 +1102,7 @@ void WorldSession::SetPlayer(Player* player) // set m_GUID that can be used while player loggined and later until m_playerRecentlyLogout not reset if (_player) - m_GUIDLow = _player->GetGUIDLow(); + m_GUIDLow = _player->GetGUID().GetCounter(); } void WorldSession::InitializeQueryCallbackParameters() diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 3753f796768..e597cbff27b 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -287,7 +287,7 @@ class WorldSession std::string const& GetPlayerName() const; std::string GetPlayerInfo() const; - uint32 GetGuidLow() const; + uint32 GetGUIDLow() const; void SetSecurity(AccountTypes security) { _security = security; } std::string const& GetRemoteAddress() const { return m_Address; } void SetPlayer(Player* player); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index f7491175a50..0cc075a3dde 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1556,7 +1556,7 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app { newPhase = PHASEMASK_NORMAL; if (Creature* creature = target->ToCreature()) - if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetDBTableGUIDLow())) + if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetSpawnId())) newPhase = data->phaseMask; } diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index 4eea5eed03d..e42f66c6ffb 100644 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -323,7 +323,7 @@ Aura* Aura::Create(SpellInfo const* spellproto, uint8 effMask, WorldObject* owne aura = new DynObjAura(spellproto, effMask, owner, caster, baseAmount, castItem, casterGUID); break; default: - ASSERT(false); + ABORT(); return NULL; } // aura can be removed in Unit::_AddAura call @@ -436,8 +436,8 @@ void Aura::_UnapplyForTarget(Unit* target, Unit* caster, AuraApplication * auraA if (itr == m_applications.end()) { TC_LOG_ERROR("spells", "Aura::_UnapplyForTarget, target:%u, caster:%u, spell:%u was not found in owners application map!", - target->GetGUIDLow(), caster ? caster->GetGUIDLow() : 0, auraApp->GetBase()->GetSpellInfo()->Id); - ASSERT(false); + target->GetGUID().GetCounter(), caster ? caster->GetGUID().GetCounter() : 0, auraApp->GetBase()->GetSpellInfo()->Id); + ABORT(); } // aura has to be already applied @@ -528,7 +528,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) else { // ok, we have one unit twice in target map (impossible, but...) - ASSERT(false); + ABORT(); } } @@ -586,7 +586,7 @@ void Aura::UpdateTargetMap(Unit* caster, bool apply) TC_LOG_FATAL("spells", "Aura %u: Owner %s (map %u) is not in the same map as target %s (map %u).", GetSpellInfo()->Id, GetOwner()->GetName().c_str(), GetOwner()->IsInWorld() ? GetOwner()->GetMap()->GetId() : uint32(-1), itr->first->GetName().c_str(), itr->first->IsInWorld() ? itr->first->GetMap()->GetId() : uint32(-1)); - ASSERT(false); + ABORT(); } itr->first->_CreateAuraApplication(this, itr->second); ++itr; @@ -1022,9 +1022,6 @@ void Aura::UnregisterSingleTarget() { ASSERT(m_isSingleTarget); Unit* caster = GetCaster(); - /// @todo find a better way to do this. - if (!caster) - caster = ObjectAccessor::GetObjectInOrOutOfWorld(GetCasterGUID(), (Unit*)NULL); ASSERT(caster); caster->GetSingleCastAuras().remove(this); SetIsSingleTarget(false); diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index 03f14d1cdc8..e1302d48d2f 100644 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -210,10 +210,10 @@ ObjectGuid SpellCastTargets::GetOrigUnitTargetGUID() const { switch (m_origObjectTargetGUID.GetHigh()) { - case HIGHGUID_PLAYER: - case HIGHGUID_VEHICLE: - case HIGHGUID_UNIT: - case HIGHGUID_PET: + case HighGuid::Player: + case HighGuid::Vehicle: + case HighGuid::Unit: + case HighGuid::Pet: return m_origObjectTargetGUID; default: return ObjectGuid(); @@ -2218,6 +2218,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) uint8 mask = target->effectMask; Unit* unit = m_caster->GetGUID() == target->targetGUID ? m_caster : ObjectAccessor::GetUnit(*m_caster, target->targetGUID); + if (!unit && !target->targetGUID.IsPlayer()) // only players may be targeted across maps + return; + if (!unit) { uint8 farMask = 0; @@ -2230,7 +2233,7 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target) if (!farMask) return; // find unit in world - unit = ObjectAccessor::FindUnit(target->targetGUID); + unit = ObjectAccessor::FindPlayer(target->targetGUID); if (!unit) return; @@ -3428,7 +3431,7 @@ void Spell::_handle_finish_phase() if (m_caster->m_extraAttacks && m_spellInfo->HasEffect(SPELL_EFFECT_ADD_EXTRA_ATTACKS)) { - if (Unit* victim = ObjectAccessor::FindUnit(m_targets.GetOrigUnitTargetGUID())) + if (Unit* victim = ObjectAccessor::GetUnit(*m_caster, m_targets.GetOrigUnitTargetGUID())) m_caster->HandleProcExtraAttackFor(victim); else m_caster->m_extraAttacks = 0; @@ -3557,7 +3560,7 @@ void Spell::finish(bool ok) SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spell); if (spellInfo && spellInfo->SpellIconID == 2056) { - TC_LOG_DEBUG("spells", "Statue %d is unsummoned in spell %d finish", m_caster->GetGUIDLow(), m_spellInfo->Id); + TC_LOG_DEBUG("spells", "Statue %d is unsummoned in spell %d finish", m_caster->GetGUID().GetCounter(), m_spellInfo->Id); m_caster->setDeathState(JUST_DIED); return; } @@ -4241,7 +4244,7 @@ void Spell::TakeCastItem() { // This code is to avoid a crash // I'm not sure, if this is really an error, but I guess every item needs a prototype - TC_LOG_ERROR("spells", "Cast item has no item prototype highId=%d, lowId=%d", m_CastItem->GetGUIDHigh(), m_CastItem->GetGUIDLow()); + TC_LOG_ERROR("spells", "Cast item has no item prototype %s", m_CastItem->GetGUID().ToString().c_str()); return; } @@ -6585,8 +6588,8 @@ SpellEvent::~SpellEvent() else { TC_LOG_ERROR("spells", "~SpellEvent: %s %u tried to delete non-deletable spell %u. Was not deleted, causes memory leak.", - (m_Spell->GetCaster()->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), m_Spell->GetCaster()->GetGUIDLow(), m_Spell->m_spellInfo->Id); - ASSERT(false); + (m_Spell->GetCaster()->GetTypeId() == TYPEID_PLAYER ? "Player" : "Creature"), m_Spell->GetCaster()->GetGUID().GetCounter(), m_Spell->m_spellInfo->Id); + ABORT(); } } @@ -7044,7 +7047,7 @@ bool Spell::CallScriptEffectHandlers(SpellEffIndex effIndex, SpellEffectHandleMo hookType = SPELL_SCRIPT_HOOK_EFFECT_HIT_TARGET; break; default: - ASSERT(false); + ABORT(); return false; } (*scritr)->_PrepareScriptCall(hookType); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 91eb7330dda..10dfbd511df 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1232,7 +1232,7 @@ void Spell::EffectUnlearnSpecialization(SpellEffIndex effIndex) player->RemoveSpell(spellToUnlearn); - TC_LOG_DEBUG("spells", "Spell: Player %u has unlearned spell %u from NpcGUID: %u", player->GetGUIDLow(), spellToUnlearn, m_caster->GetGUIDLow()); + TC_LOG_DEBUG("spells", "Spell: Player %u has unlearned spell %u from NpcGUID: %u", player->GetGUID().GetCounter(), spellToUnlearn, m_caster->GetGUID().GetCounter()); } void Spell::EffectPowerDrain(SpellEffIndex effIndex) @@ -1712,7 +1712,7 @@ void Spell::EffectPersistentAA(SpellEffIndex effIndex) if (!caster->IsInWorld()) return; DynamicObject* dynObj = new DynamicObject(false); - if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL)) + if (!dynObj->CreateDynamicObject(caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_AREA_SPELL)) { delete dynObj; return; @@ -1884,7 +1884,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) if (!gameObjTarget->isSpawned() && !player->IsGameMaster()) { TC_LOG_ERROR("spells", "Possible hacking attempt: Player %s [guid: %u] tried to loot a gameobject [entry: %u id: %u] which is on respawn time without being in GM mode!", - player->GetName().c_str(), player->GetGUIDLow(), gameObjTarget->GetEntry(), gameObjTarget->GetGUIDLow()); + player->GetName().c_str(), player->GetGUID().GetCounter(), gameObjTarget->GetEntry(), gameObjTarget->GetGUID().GetCounter()); return; } // special case, already has GossipHello inside so return and avoid calling twice @@ -1922,7 +1922,7 @@ void Spell::SendLoot(ObjectGuid guid, LootType loottype) /// @todo possible must be moved to loot release (in different from linked triggering) if (gameObjTarget->GetGOInfo()->chest.eventId) { - TC_LOG_DEBUG("spells", "Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId, gameObjTarget->GetDBTableGUIDLow()); + TC_LOG_DEBUG("spells", "Chest ScriptStart id %u for GO %u", gameObjTarget->GetGOInfo()->chest.eventId, gameObjTarget->GetSpawnId()); player->GetMap()->ScriptsStart(sEventScripts, gameObjTarget->GetGOInfo()->chest.eventId, player, gameObjTarget); } @@ -1991,7 +1991,7 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) /// @todo Add script for spell 41920 - Filling, becouse server it freze when use this spell // handle outdoor pvp object opening, return true if go was registered for handling // these objects must have been spawned by outdoorpvp! - else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget->GetGUID())) + else if (gameObjTarget->GetGOInfo()->type == GAMEOBJECT_TYPE_GOOBER && sOutdoorPvPMgr->HandleOpenGo(player, gameObjTarget)) return; lockId = goInfo->GetLockId(); guid = gameObjTarget->GetGUID(); @@ -2032,9 +2032,9 @@ void Spell::EffectOpenLock(SpellEffIndex effIndex) if (gameObjTarget) { // Allow one skill-up until respawned - if (!gameObjTarget->IsInSkillupList(player->GetGUIDLow()) && + if (!gameObjTarget->IsInSkillupList(player->GetGUID().GetCounter()) && player->UpdateGatherSkill(skillId, pureSkillValue, reqSkillValue)) - gameObjTarget->AddToSkillupList(player->GetGUIDLow()); + gameObjTarget->AddToSkillupList(player->GetGUID().GetCounter()); } else if (itemTarget) { @@ -2376,7 +2376,7 @@ void Spell::EffectLearnSpell(SpellEffIndex effIndex) uint32 spellToLearn = (m_spellInfo->Id == 483 || m_spellInfo->Id == 55884) ? damage : m_spellInfo->Effects[effIndex].TriggerSpell; player->LearnSpell(spellToLearn, false); - TC_LOG_DEBUG("spells", "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUIDLow(), spellToLearn, m_caster->GetGUIDLow()); + TC_LOG_DEBUG("spells", "Spell: Player %u has learned spell %u from NpcGUID=%u", player->GetGUID().GetCounter(), spellToLearn, m_caster->GetGUID().GetCounter()); } void Spell::EffectDispel(SpellEffIndex effIndex) @@ -2550,7 +2550,7 @@ void Spell::EffectAddFarsight(SpellEffIndex effIndex) return; DynamicObject* dynObj = new DynamicObject(true); - if (!dynObj->CreateDynamicObject(sObjectMgr->GenerateLowGuid(HIGHGUID_DYNAMICOBJECT), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) + if (!dynObj->CreateDynamicObject(m_caster->GetMap()->GenerateLowGuid<HighGuid::DynamicObject>(), m_caster, m_spellInfo->Id, *destTarget, radius, DYNAMIC_OBJECT_FARSIGHT_FOCUS)) { delete dynObj; return; @@ -2627,7 +2627,7 @@ void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/) if (m_CastItem) { unitTarget->ToPlayer()->RewardHonor(NULL, 1, damage/10); - TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(), unitTarget->ToPlayer()->GetGUIDLow()); + TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %d honor points (item %u) for player: %u", m_spellInfo->Id, damage/10, m_CastItem->GetEntry(), unitTarget->ToPlayer()->GetGUID().GetCounter()); return; } @@ -2636,13 +2636,13 @@ void Spell::EffectAddHonor(SpellEffIndex /*effIndex*/) { uint32 honor_reward = Trinity::Honor::hk_honor_at_level(unitTarget->getLevel(), float(damage)); unitTarget->ToPlayer()->RewardHonor(NULL, 1, honor_reward); - TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u", m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUIDLow()); + TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (scale) to player: %u", m_spellInfo->Id, honor_reward, unitTarget->ToPlayer()->GetGUID().GetCounter()); } else { //maybe we have correct honor_gain in damage already unitTarget->ToPlayer()->RewardHonor(NULL, 1, damage); - TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u", m_spellInfo->Id, damage, unitTarget->ToPlayer()->GetGUIDLow()); + TC_LOG_DEBUG("spells", "SpellEffect::AddHonor (spell_id %u) rewards %u honor points (non scale) for player: %u", m_spellInfo->Id, damage, unitTarget->ToPlayer()->GetGUID().GetCounter()); } } @@ -3502,7 +3502,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) Map* map = target->GetMap(); - if (!pGameObj->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, + if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { delete pGameObj; @@ -3527,7 +3527,7 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) if (uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry()) { GameObject* linkedGO = new GameObject; - if (linkedGO->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map, + if (linkedGO->Create(map->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_MILLISECONDS : 0); @@ -4126,7 +4126,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) Player* target = unitTarget->ToPlayer(); // caster or target already have requested duel - if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUIDLow())) + if (caster->duel || target->duel || !target->GetSocial() || target->GetSocial()->HasIgnore(caster->GetGUID().GetCounter())) return; // Players can only fight a duel in zones with this flag @@ -4150,7 +4150,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) uint32 gameobject_id = m_spellInfo->Effects[effIndex].MiscValue; Map* map = m_caster->GetMap(); - if (!pGameObj->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, + if (!pGameObj->Create(map->GenerateLowGuid<HighGuid::GameObject>(), gameobject_id, map, m_caster->GetPhaseMask(), m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2, m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2, @@ -4216,7 +4216,7 @@ void Spell::EffectStuck(SpellEffIndex /*effIndex*/) return; TC_LOG_DEBUG("spells", "Spell Effect: Stuck"); - TC_LOG_DEBUG("spells", "Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)", player->GetName().c_str(), player->GetGUIDLow(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); + TC_LOG_DEBUG("spells", "Player %s (guid %u) used auto-unstuck future at map %u (%f, %f, %f)", player->GetName().c_str(), player->GetGUID().GetCounter(), player->GetMapId(), player->GetPositionX(), player->GetPositionY(), player->GetPositionZ()); if (player->IsInFlight()) return; @@ -4497,7 +4497,7 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) m_caster->GetClosePoint(x, y, z, DEFAULT_WORLD_OBJECT_SIZE); Map* map = m_caster->GetMap(); - if (!go->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, + if (!go->Create(map->GenerateLowGuid<HighGuid::GameObject>(), go_id, map, m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete go; @@ -5126,7 +5126,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) GameObject* pGameObj = new GameObject; - if (!pGameObj->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap, + if (!pGameObj->Create(cMap->GenerateLowGuid<HighGuid::GameObject>(), name_id, cMap, m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { delete pGameObj; @@ -5192,7 +5192,7 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) if (uint32 linkedEntry = pGameObj->GetGOInfo()->GetLinkedGameObjectEntry()) { GameObject* linkedGO = new GameObject; - if (linkedGO->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap, + if (linkedGO->Create(cMap->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_MILLISECONDS : 0); diff --git a/src/server/game/Spells/SpellHistory.cpp b/src/server/game/Spells/SpellHistory.cpp index 09e3be690b1..208b4cf7ed9 100644 --- a/src/server/game/Spells/SpellHistory.cpp +++ b/src/server/game/Spells/SpellHistory.cpp @@ -637,6 +637,23 @@ void SpellHistory::BuildCooldownPacket(WorldPacket& data, uint8 flags, PacketCoo } } +uint16 SpellHistory::GetArenaCooldownsSize() +{ + uint16 count = 0; + + for (auto itr = _spellCooldowns.begin(); itr != _spellCooldowns.end();) + { + SpellInfo const* spellInfo = sSpellMgr->EnsureSpellInfo(itr->first); + + if (spellInfo->RecoveryTime < 10 * MINUTE * IN_MILLISECONDS && + spellInfo->CategoryRecoveryTime < 10 * MINUTE * IN_MILLISECONDS) + ++count; + ++itr; + } + + return count; +} + template void SpellHistory::LoadFromDB<Player>(PreparedQueryResult cooldownsResult); template void SpellHistory::LoadFromDB<Pet>(PreparedQueryResult cooldownsResult); template void SpellHistory::SaveToDB<Player>(SQLTransaction& trans); diff --git a/src/server/game/Spells/SpellHistory.h b/src/server/game/Spells/SpellHistory.h index f1533d57aef..4d0642d644e 100644 --- a/src/server/game/Spells/SpellHistory.h +++ b/src/server/game/Spells/SpellHistory.h @@ -117,6 +117,7 @@ public: void BuildCooldownPacket(WorldPacket& data, uint8 flags, uint32 spellId, uint32 cooldown) const; CooldownStorageType::size_type GetCooldownsSizeForPacket() const { return _spellCooldowns.size(); } + uint16 GetArenaCooldownsSize(); private: Player* GetPlayerOwner() const; diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index f27f9220aaa..55d0ad0b4dc 100644 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3105,11 +3105,13 @@ void SpellMgr::LoadSpellInfoCorrections() case 28796: // Poison Bolt Volly - Faerlina spellInfo->MaxAffectedTargets = 5; break; + case 54835: // Curse of the Plaguebringer - Noth (H) + spellInfo->MaxAffectedTargets = 8; + break; case 40827: // Sinful Beam case 40859: // Sinister Beam case 40860: // Vile Beam case 40861: // Wicked Beam - case 54835: // Curse of the Plaguebringer - Noth (H) case 54098: // Poison Bolt Volly - Faerlina (H) spellInfo->MaxAffectedTargets = 10; break; diff --git a/src/server/game/Texts/CreatureTextMgr.cpp b/src/server/game/Texts/CreatureTextMgr.cpp index f9ccd2efd16..9f75d917aea 100644 --- a/src/server/game/Texts/CreatureTextMgr.cpp +++ b/src/server/game/Texts/CreatureTextMgr.cpp @@ -202,7 +202,7 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject CreatureTextMap::const_iterator sList = mTextMap.find(source->GetEntry()); if (sList == mTextMap.end()) { - TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Could not find Text for Creature %s (Entry %u, GUID %u) in 'creature_text' table. Ignoring.", source->GetName().c_str(), source->GetEntry(), source->GetGUIDLow()); + TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Could not find Text for Creature %s (Entry %u, GUID %u) in 'creature_text' table. Ignoring.", source->GetName().c_str(), source->GetEntry(), source->GetGUID().GetCounter()); return 0; } @@ -210,7 +210,7 @@ uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, WorldObject CreatureTextHolder::const_iterator itr = textHolder.find(textGroup); if (itr == textHolder.end()) { - TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Could not find TextGroup %u for Creature %s (Entry %u, GUID %u) in 'creature_text' table. Ignoring.", uint32(textGroup), source->GetName().c_str(), source->GetEntry(), source->GetGUIDLow()); + TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Could not find TextGroup %u for Creature %s (Entry %u, GUID %u) in 'creature_text' table. Ignoring.", uint32(textGroup), source->GetName().c_str(), source->GetEntry(), source->GetGUID().GetCounter()); return 0; } diff --git a/src/server/game/Tickets/TicketMgr.cpp b/src/server/game/Tickets/TicketMgr.cpp index 3d26f349ca5..dbf66c6bd71 100644 --- a/src/server/game/Tickets/TicketMgr.cpp +++ b/src/server/game/Tickets/TicketMgr.cpp @@ -53,7 +53,7 @@ bool GmTicket::LoadFromDB(Field* fields) // ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, haveTicket uint8 index = 0; _id = fields[ index].GetUInt32(); - _playerGuid = ObjectGuid(HIGHGUID_PLAYER, fields[++index].GetUInt32()); + _playerGuid = ObjectGuid(HighGuid::Player, fields[++index].GetUInt32()); _playerName = fields[++index].GetString(); _message = fields[++index].GetString(); _createTime = fields[++index].GetUInt32(); @@ -63,7 +63,7 @@ bool GmTicket::LoadFromDB(Field* fields) _posZ = fields[++index].GetFloat(); _lastModifiedTime = fields[++index].GetUInt32(); _closedBy = ObjectGuid(uint64(fields[++index].GetInt32())); - _assignedTo = ObjectGuid(HIGHGUID_PLAYER, fields[++index].GetUInt32()); + _assignedTo = ObjectGuid(HighGuid::Player, fields[++index].GetUInt32()); _comment = fields[++index].GetString(); _response = fields[++index].GetString(); _completed = fields[++index].GetBool(); @@ -75,8 +75,8 @@ bool GmTicket::LoadFromDB(Field* fields) void GmTicket::SaveToDB(SQLTransaction& trans) const { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 - // ticketId, guid, name, message, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, completed, escalated, viewed + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 + // id, playerGuid, name, description, createTime, mapId, posX, posY, posZ, lastModifiedTime, closedBy, assignedTo, comment, response, completed, escalated, viewed, needMoreHelp, resolvedBy uint8 index = 0; PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_REP_GM_TICKET); stmt->setUInt32( index, _id); @@ -97,6 +97,7 @@ void GmTicket::SaveToDB(SQLTransaction& trans) const stmt->setUInt8 (++index, uint8(_escalatedStatus)); stmt->setBool (++index, _viewed); stmt->setBool (++index, _needMoreHelp); + stmt->setInt32 (++index, int32(_resolvedBy.GetCounter())); CharacterDatabase.ExecuteOrAppend(trans, stmt); } @@ -361,6 +362,19 @@ void TicketMgr::CloseTicket(uint32 ticketId, ObjectGuid source) } } +void TicketMgr::ResolveAndCloseTicket(uint32 ticketId, ObjectGuid source) +{ + if (GmTicket* ticket = GetTicket(ticketId)) + { + SQLTransaction trans = SQLTransaction(nullptr); + ticket->SetClosedBy(source); + ticket->SetResolvedBy(source); + if (source) + --_openTicketCount; + ticket->SaveToDB(trans); + } +} + void TicketMgr::RemoveTicket(uint32 ticketId) { if (GmTicket* ticket = GetTicket(ticketId)) diff --git a/src/server/game/Tickets/TicketMgr.h b/src/server/game/Tickets/TicketMgr.h index e9892c22edc..f7d3178978f 100644 --- a/src/server/game/Tickets/TicketMgr.h +++ b/src/server/game/Tickets/TicketMgr.h @@ -119,6 +119,7 @@ public: _escalatedStatus = TICKET_ASSIGNED; } void SetClosedBy(ObjectGuid value) { _closedBy = value; } + void SetResolvedBy(ObjectGuid value) { _resolvedBy = value; } void SetCompleted() { _completed = true; } void SetMessage(std::string const& message) { @@ -158,7 +159,8 @@ private: std::string _message; uint64 _createTime; uint64 _lastModifiedTime; - ObjectGuid _closedBy; // 0 = Open, -1 = Console, playerGuid = player abandoned ticket, other = GM who closed it. + ObjectGuid _closedBy; // 0 = Open, -1 = Console, playerGuid = player abandoned ticket or read the GM response message, other = GM who closed it. + ObjectGuid _resolvedBy; // 0 = Open, -1 = Resolved by Console, GM who resolved it by closing or completing the ticket. ObjectGuid _assignedTo; std::string _comment; bool _completed; @@ -216,6 +218,7 @@ public: void AddTicket(GmTicket* ticket); void CloseTicket(uint32 ticketId, ObjectGuid source); + void ResolveAndCloseTicket(uint32 ticketId, ObjectGuid source); // used when GM resolves a ticket by simply closing it void RemoveTicket(uint32 ticketId); bool GetStatus() const { return _status; } diff --git a/src/server/game/Tools/PlayerDump.cpp b/src/server/game/Tools/PlayerDump.cpp index 83100d3fbec..8710100d9b3 100644 --- a/src/server/game/Tools/PlayerDump.cpp +++ b/src/server/game/Tools/PlayerDump.cpp @@ -408,18 +408,21 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s // make sure the same guid doesn't already exist and is safe to use bool incHighest = true; - if (guid != 0 && guid < sObjectMgr->_hiCharGuid) + if (guid && guid < sObjectMgr->GetGenerator<HighGuid::Player>().GetNextAfterMaxUsed()) + { PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_SEL_CHECK_GUID); stmt->setUInt32(0, guid); PreparedQueryResult result = CharacterDatabase.Query(stmt); if (result) - guid = sObjectMgr->_hiCharGuid; // use first free if exists + guid = sObjectMgr->GetGenerator<HighGuid::Player>().GetNextAfterMaxUsed(); // use first free if exists + else incHighest = false; } else - guid = sObjectMgr->_hiCharGuid; + guid = sObjectMgr->GetGenerator<HighGuid::Player>().GetNextAfterMaxUsed(); + // normalize the name if specified and check if it exists if (!normalizePlayerName(name)) @@ -578,9 +581,9 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s if (!changenth(line, 1, newguid)) // character_inventory.guid update ROLLBACK(DUMP_FILE_BROKEN); - if (!changeGuid(line, 2, items, sObjectMgr->_hiItemGuid, true)) + if (!changeGuid(line, 2, items,sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed(), true)) ROLLBACK(DUMP_FILE_BROKEN); // character_inventory.bag update - if (!changeGuid(line, 4, items, sObjectMgr->_hiItemGuid)) + if (!changeGuid(line, 4, items, sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); // character_inventory.item update break; } @@ -596,7 +599,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s { if (!changeGuid(line, 1, mails, sObjectMgr->_mailId)) ROLLBACK(DUMP_FILE_BROKEN); // mail_items.id - if (!changeGuid(line, 2, items, sObjectMgr->_hiItemGuid)) + if (!changeGuid(line, 2, items, sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); // mail_items.item_guid if (!changenth(line, 3, newguid)) // mail_items.receiver ROLLBACK(DUMP_FILE_BROKEN); @@ -605,7 +608,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s case DTT_ITEM: { // item, owner, data field:item, owner guid - if (!changeGuid(line, 1, items, sObjectMgr->_hiItemGuid)) + if (!changeGuid(line, 1, items, sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); // item_instance.guid update if (!changenth(line, 3, newguid)) // item_instance.owner_guid update ROLLBACK(DUMP_FILE_BROKEN); @@ -615,7 +618,7 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s { if (!changenth(line, 1, newguid)) // character_gifts.guid update ROLLBACK(DUMP_FILE_BROKEN); - if (!changeGuid(line, 2, items, sObjectMgr->_hiItemGuid)) + if (!changeGuid(line, 2, items, sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed())) ROLLBACK(DUMP_FILE_BROKEN); // character_gifts.item_guid update break; } @@ -674,13 +677,15 @@ DumpReturn PlayerDumpReader::LoadDump(std::string const& file, uint32 account, s CharacterDatabase.CommitTransaction(trans); // in case of name conflict player has to rename at login anyway - sWorld->AddCharacterNameData(ObjectGuid(HIGHGUID_PLAYER, guid), name, gender, race, playerClass, level); + sWorld->AddCharacterNameData(ObjectGuid(HighGuid::Player, guid), name, gender, race, playerClass, level); + + sObjectMgr->GetGenerator<HighGuid::Item>().Set(sObjectMgr->GetGenerator<HighGuid::Item>().GetNextAfterMaxUsed() + items.size()); - sObjectMgr->_hiItemGuid += items.size(); sObjectMgr->_mailId += mails.size(); if (incHighest) - ++sObjectMgr->_hiCharGuid; + sObjectMgr->GetGenerator<HighGuid::Player>().Generate(); + fclose(fin); diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index b29f39809c6..85e79168b71 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1190,6 +1190,7 @@ void World::LoadConfigSettings(bool reload) m_int_configs[CONFIG_MAX_WHO] = sConfigMgr->GetIntDefault("MaxWhoListReturns", 49); m_bool_configs[CONFIG_START_ALL_SPELLS] = sConfigMgr->GetBoolDefault("PlayerStart.AllSpells", false); m_int_configs[CONFIG_HONOR_AFTER_DUEL] = sConfigMgr->GetIntDefault("HonorPointsAfterDuel", 0); + m_bool_configs[CONFIG_RESET_COOLDOWN_AFTER_DUEL] = sConfigMgr->GetBoolDefault("ResetCoolDownAfterDuel", 0); m_bool_configs[CONFIG_START_ALL_EXPLORED] = sConfigMgr->GetBoolDefault("PlayerStart.MapsExplored", false); m_bool_configs[CONFIG_START_ALL_REP] = sConfigMgr->GetBoolDefault("PlayerStart.AllReputation", false); m_bool_configs[CONFIG_ALWAYS_MAXSKILL] = sConfigMgr->GetBoolDefault("AlwaysMaxWeaponSkill", false); @@ -1365,11 +1366,6 @@ void World::SetInitialWorldSettings() LoginDatabase.PExecute("UPDATE realmlist SET icon = %u, timezone = %u WHERE id = '%d'", server_type, realm_zone, realmID); // One-time query - ///- Remove the bones (they should not exist in DB though) and old corpses after a restart - PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_DEL_OLD_CORPSES); - stmt->setUInt32(0, 3 * DAY); - CharacterDatabase.Execute(stmt); - ///- Load the DBC files TC_LOG_INFO("server.loading", "Initialize data stores..."); LoadDBCStores(m_dataPath); @@ -1636,9 +1632,6 @@ void World::SetInitialWorldSettings() TC_LOG_INFO("server.loading", "Loading pet level stats..."); sObjectMgr->LoadPetLevelInfo(); - TC_LOG_INFO("server.loading", "Loading Player Corpses..."); - sObjectMgr->LoadCorpses(); - TC_LOG_INFO("server.loading", "Loading Player level dependent mail rewards..."); sObjectMgr->LoadMailLevelRewards(); @@ -2158,7 +2151,10 @@ void World::Update(uint32 diff) if (m_timers[WUPDATE_CORPSES].Passed()) { m_timers[WUPDATE_CORPSES].Reset(); - sObjectAccessor->RemoveOldCorpses(); + sMapMgr->DoForAllMaps([](Map* map) + { + map->RemoveOldCorpses(); + }); } ///- Process Game events when necessary @@ -2526,7 +2522,7 @@ BanReturn World::BanCharacter(std::string const& name, std::string const& durati guid = (*resultCharacter)[0].GetUInt32(); } else - guid = pBanned->GetGUIDLow(); + guid = pBanned->GetGUID().GetCounter(); // make sure there is only one active ban PreparedStatement* stmt = CharacterDatabase.GetPreparedStatement(CHAR_UPD_CHARACTER_BAN); @@ -2565,7 +2561,7 @@ bool World::RemoveBanCharacter(std::string const& name) guid = (*resultCharacter)[0].GetUInt32(); } else - guid = pBanned->GetGUIDLow(); + guid = pBanned->GetGUID().GetCounter(); if (!guid) return false; @@ -3209,7 +3205,7 @@ void World::LoadCharacterNameData() do { Field* fields = result->Fetch(); - AddCharacterNameData(ObjectGuid(HIGHGUID_PLAYER, fields[0].GetUInt32()), fields[1].GetString(), + AddCharacterNameData(ObjectGuid(HighGuid::Player, fields[0].GetUInt32()), fields[1].GetString(), fields[3].GetUInt8() /*gender*/, fields[2].GetUInt8() /*race*/, fields[4].GetUInt8() /*class*/, fields[5].GetUInt8() /*level*/); ++count; } while (result->NextRow()); @@ -3272,3 +3268,9 @@ void World::ReloadRBAC() if (WorldSession* session = itr->second) session->InvalidateRBACData(); } + +void World::RemoveOldCorpses() +{ + m_timers[WUPDATE_CORPSES].SetCurrent(m_timers[WUPDATE_CORPSES].GetInterval()); +} + diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index af89adcb04e..1f71975cde2 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -161,6 +161,7 @@ enum WorldBoolConfigs CONFIG_ALLOW_TRACK_BOTH_RESOURCES, CONFIG_CALCULATE_CREATURE_ZONE_AREA_DATA, CONFIG_CALCULATE_GAMEOBJECT_ZONE_AREA_DATA, + CONFIG_RESET_COOLDOWN_AFTER_DUEL, BOOL_CONFIG_VALUE_COUNT }; @@ -761,6 +762,8 @@ class World void ReloadRBAC(); + void RemoveOldCorpses(); + protected: void _UpdateGameTime(); // callback for UpdateRealmCharacters |
