diff options
Diffstat (limited to 'src')
88 files changed, 864 insertions, 1242 deletions
diff --git a/src/server/authserver/Authentication/AuthCodes.h b/src/server/authserver/Authentication/AuthCodes.h index eb9f443f624..c42a11007d8 100644 --- a/src/server/authserver/Authentication/AuthCodes.h +++ b/src/server/authserver/Authentication/AuthCodes.h @@ -110,7 +110,8 @@ namespace Battlenet { AUTH_OK = 0, AUTH_INTERNAL_ERROR = 100, - AUTH_CORRUPTED_MODULE = 102, + AUTH_CORRUPTED_MODULE = 101, + AUTH_NO_BATTLETAGS = 102, AUTH_BAD_SERVER_PROOF = 103, AUTH_UNKNOWN_ACCOUNT = 104, AUTH_CLOSED = 105, diff --git a/src/server/authserver/Server/BattlenetPackets.h b/src/server/authserver/Server/BattlenetPackets.h index 1505f21cc39..d9bfe8a4857 100644 --- a/src/server/authserver/Server/BattlenetPackets.h +++ b/src/server/authserver/Server/BattlenetPackets.h @@ -33,8 +33,15 @@ namespace Battlenet enum Channel { AUTHENTICATION = 0, - CREEP = 1, - WOW = 2 + CONNECTION = 1, + WOW = 2, + FRIEND = 3, + PRESENCE = 4, + CHAT = 5, + SUPPORT = 7, + ACHIEVEMENT = 8, + CACHE = 11, + PROFILE = 14 }; enum AuthOpcode @@ -48,7 +55,7 @@ namespace Battlenet SMSG_AUTH_PROOF_REQUEST = 0x2 }; - enum CreepOpcodes + enum ConnectionOpcodes { CMSG_PING = 0x0, CMSG_ENABLE_ENCRYPTION = 0x5, @@ -261,7 +268,7 @@ namespace Battlenet class Pong final : public ServerPacket { public: - Pong() : ServerPacket(PacketHeader(SMSG_PONG, CREEP)) + Pong() : ServerPacket(PacketHeader(SMSG_PONG, CONNECTION)) { } diff --git a/src/server/authserver/Server/BattlenetSocket.cpp b/src/server/authserver/Server/BattlenetSocket.cpp index dad52f64877..1c6951bc608 100644 --- a/src/server/authserver/Server/BattlenetSocket.cpp +++ b/src/server/authserver/Server/BattlenetSocket.cpp @@ -36,9 +36,9 @@ std::map<Battlenet::PacketHeader, Battlenet::Socket::PacketHandler> InitHandlers handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_RECONNECT, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthReconnect; handlers[Battlenet::PacketHeader(Battlenet::CMSG_AUTH_PROOF_RESPONSE, Battlenet::AUTHENTICATION)] = &Battlenet::Socket::HandleAuthProofResponse; - handlers[Battlenet::PacketHeader(Battlenet::CMSG_PING, Battlenet::CREEP)] = &Battlenet::Socket::HandlePing; - handlers[Battlenet::PacketHeader(Battlenet::CMSG_ENABLE_ENCRYPTION, Battlenet::CREEP)] = &Battlenet::Socket::HandleEnableEncryption; - handlers[Battlenet::PacketHeader(Battlenet::CMSG_DISCONNECT, Battlenet::CREEP)] = &Battlenet::Socket::HandleDisconnect; + handlers[Battlenet::PacketHeader(Battlenet::CMSG_PING, Battlenet::CONNECTION)] = &Battlenet::Socket::HandlePing; + handlers[Battlenet::PacketHeader(Battlenet::CMSG_ENABLE_ENCRYPTION, Battlenet::CONNECTION)] = &Battlenet::Socket::HandleEnableEncryption; + handlers[Battlenet::PacketHeader(Battlenet::CMSG_DISCONNECT, Battlenet::CONNECTION)] = &Battlenet::Socket::HandleDisconnect; handlers[Battlenet::PacketHeader(Battlenet::CMSG_REALM_UPDATE_SUBSCRIBE, Battlenet::WOW)] = &Battlenet::Socket::HandleRealmUpdateSubscribe; handlers[Battlenet::PacketHeader(Battlenet::CMSG_JOIN_REQUEST, Battlenet::WOW)] = &Battlenet::Socket::HandleRealmJoinRequest; diff --git a/src/server/collision/CMakeLists.txt b/src/server/collision/CMakeLists.txt index a83bb9dad1c..a2024bff7cb 100644 --- a/src/server/collision/CMakeLists.txt +++ b/src/server/collision/CMakeLists.txt @@ -34,6 +34,7 @@ include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/shared/Configuration ${CMAKE_SOURCE_DIR}/src/server/shared/Debugging diff --git a/src/server/game/AI/SmartScripts/SmartScript.cpp b/src/server/game/AI/SmartScripts/SmartScript.cpp index 23386f82d73..140bb5507b4 100644 --- a/src/server/game/AI/SmartScripts/SmartScript.cpp +++ b/src/server/game/AI/SmartScripts/SmartScript.cpp @@ -1045,7 +1045,7 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u delete targets; break; } - case SMART_ACTION_SET_INGAME_PHASE_MASK: + case SMART_ACTION_SET_INGAME_PHASE_ID: { ObjectList* targets = GetTargets(e, unit); @@ -1053,12 +1053,23 @@ void SmartScript::ProcessAction(SmartScriptHolder& e, Unit* unit, uint32 var0, u break; for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) - { - if (IsUnit(*itr)) - (*itr)->ToUnit()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); - else if (IsGameObject(*itr)) - (*itr)->ToGameObject()->SetPhaseMask(e.action.ingamePhaseMask.mask, true); - } + (*itr)->SetInPhase(e.action.ingamePhaseId.id, true, e.action.ingamePhaseId.apply == 1); + + delete targets; + break; + } + case SMART_ACTION_SET_INGAME_PHASE_GROUP: + { + ObjectList* targets = GetTargets(e, unit); + + if (!targets) + break; + + std::set<uint32> const& phases = GetPhasesForGroup(e.action.ingamePhaseGroup.groupId); + + for (ObjectList::const_iterator itr = targets->begin(); itr != targets->end(); ++itr) + for (auto phase : phases) + (*itr)->SetInPhase(phase, true, e.action.ingamePhaseGroup.apply == 1); delete targets; break; diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp index 2e8453904a1..af24298c60d 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.cpp @@ -1008,6 +1008,44 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) } break; } + case SMART_ACTION_SET_INGAME_PHASE_ID: + { + uint32 phaseId = e.action.ingamePhaseId.id; + uint32 apply = e.action.ingamePhaseId.apply; + + if (apply != 0 && apply != 1) + { + TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_ID uses invalid apply value %u (Should be 0 or 1) for creature %u, skipped", apply, e.entryOrGuid); + return false; + } + + PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseId); + if (!phase) + { + TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_ID uses invalid phaseid %u for creature %u, skipped", phaseId, e.entryOrGuid); + return false; + } + break; + } + case SMART_ACTION_SET_INGAME_PHASE_GROUP: + { + uint32 phaseGroup = e.action.ingamePhaseGroup.groupId; + uint32 apply = e.action.ingamePhaseGroup.apply; + + if (apply != 0 && apply != 1) + { + TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid apply value %u (Should be 0 or 1) for creature %u, skipped", apply, e.entryOrGuid); + return false; + } + + PhaseGroupEntry const* phase = sPhaseGroupStore.LookupEntry(phaseGroup); + if (!phase) + { + TC_LOG_ERROR("sql.sql", "SmartScript: SMART_ACTION_SET_INGAME_PHASE_GROUP uses invalid phase group id %u for creature %u, skipped", phaseGroup, e.entryOrGuid); + return false; + } + break; + } case SMART_ACTION_FOLLOW: case SMART_ACTION_SET_ORIENTATION: case SMART_ACTION_STORE_TARGET_LIST: @@ -1037,7 +1075,6 @@ bool SmartAIMgr::IsEventValid(SmartScriptHolder& e) case SMART_ACTION_SET_RUN: case SMART_ACTION_SET_SWIM: case SMART_ACTION_FORCE_DESPAWN: - case SMART_ACTION_SET_INGAME_PHASE_MASK: case SMART_ACTION_SET_UNIT_FLAG: case SMART_ACTION_REMOVE_UNIT_FLAG: case SMART_ACTION_PLAYMOVIE: diff --git a/src/server/game/AI/SmartScripts/SmartScriptMgr.h b/src/server/game/AI/SmartScripts/SmartScriptMgr.h index 5574e45c614..8ec2cdb1ff9 100644 --- a/src/server/game/AI/SmartScripts/SmartScriptMgr.h +++ b/src/server/game/AI/SmartScripts/SmartScriptMgr.h @@ -433,7 +433,7 @@ enum SMART_ACTION SMART_ACTION_THREAT_SINGLE_PCT = 13, // Threat% SMART_ACTION_THREAT_ALL_PCT = 14, // Threat% SMART_ACTION_CALL_AREAEXPLOREDOREVENTHAPPENS = 15, // QuestID - SMART_ACTION_UNUSED_16 = 16, // UNUSED + SMART_ACTION_SET_INGAME_PHASE_GROUP = 16, // phaseGroupId, apply SMART_ACTION_SET_EMOTE_STATE = 17, // emoteID SMART_ACTION_SET_UNIT_FLAG = 18, // Flags (may be more than one field OR'd together), Target SMART_ACTION_REMOVE_UNIT_FLAG = 19, // Flags (may be more than one field OR'd together), Target @@ -461,7 +461,7 @@ enum SMART_ACTION SMART_ACTION_FORCE_DESPAWN = 41, // timer SMART_ACTION_SET_INVINCIBILITY_HP_LEVEL = 42, // MinHpValue(+pct, -flat) SMART_ACTION_MOUNT_TO_ENTRY_OR_MODEL = 43, // Creature_template entry(param1) OR ModelId (param2) (or 0 for both to dismount) - SMART_ACTION_SET_INGAME_PHASE_MASK = 44, // mask + SMART_ACTION_SET_INGAME_PHASE_ID = 44, // PhaseId, apply SMART_ACTION_SET_DATA = 45, // Field, Data (only creature @todo) SMART_ACTION_MOVE_FORWARD = 46, // distance SMART_ACTION_SET_VISIBILITY = 47, // on/off @@ -728,9 +728,16 @@ struct SmartAction struct { - uint32 mask; - } ingamePhaseMask; + uint32 id; + uint32 apply; + } ingamePhaseId; + struct + { + uint32 groupId; + uint32 apply; + } ingamePhaseGroup; + struct { uint32 field; diff --git a/src/server/game/Accounts/BattlenetAccountMgr.cpp b/src/server/game/Accounts/BattlenetAccountMgr.cpp index ca05ffd6141..00cf1f88298 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.cpp +++ b/src/server/game/Accounts/BattlenetAccountMgr.cpp @@ -73,6 +73,16 @@ uint32 Battlenet::AccountMgr::GetId(std::string const& username) return 0; } +uint32 Battlenet::AccountMgr::GetIdByGameAccount(uint32 gameAccountId) +{ + PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT); + stmt->setUInt32(0, gameAccountId); + if (PreparedQueryResult result = LoginDatabase.Query(stmt)) + return (*result)[0].GetUInt32(); + + return 0; +} + bool Battlenet::AccountMgr::GetName(uint32 accountId, std::string& name) { PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_SEL_BNET_ACCOUNT_EMAIL_BY_ID); diff --git a/src/server/game/Accounts/BattlenetAccountMgr.h b/src/server/game/Accounts/BattlenetAccountMgr.h index 54a2841177d..61bfd044b68 100644 --- a/src/server/game/Accounts/BattlenetAccountMgr.h +++ b/src/server/game/Accounts/BattlenetAccountMgr.h @@ -36,6 +36,7 @@ namespace Battlenet uint32 GetId(std::string const& username); bool GetName(uint32 accountId, std::string& name); + uint32 GetIdByGameAccount(uint32 gameAccountId); std::string CalculateShaPassHash(std::string const& name, std::string const& password); bool GetAccountIdAndIndex(std::string const& account, uint32* battlenetAccountId, uint8* battlenetAccountIndex); diff --git a/src/server/game/Battlefield/Battlefield.cpp b/src/server/game/Battlefield/Battlefield.cpp index a797f6109ca..046af770aff 100644 --- a/src/server/game/Battlefield/Battlefield.cpp +++ b/src/server/game/Battlefield/Battlefield.cpp @@ -479,14 +479,12 @@ void Battlefield::HideNpc(Creature* creature) creature->CombatStop(); creature->SetReactState(REACT_PASSIVE); creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - creature->SetPhaseMask(2, true); creature->DisappearAndDie(); creature->SetVisible(false); } void Battlefield::ShowNpc(Creature* creature, bool aggressive) { - creature->SetPhaseMask(1, true); creature->SetVisible(true); creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); if (!creature->IsAlive()) @@ -800,7 +798,6 @@ Creature* Battlefield::SpawnCreature(uint32 entry, float x, float y, float z, fl delete creature; return NULL; } - creature->SetHomePosition(x, y, z, o); CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index dff99280e73..ba207c1ffc3 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1539,6 +1539,7 @@ bool Battleground::AddObject(uint32 type, uint32 entry, float x, float y, float delete go; return false; } + /* uint32 guid = go->GetGUIDLow(); diff --git a/src/server/game/CMakeLists.txt b/src/server/game/CMakeLists.txt index dc0edd5c1cf..932b792c3bf 100644 --- a/src/server/game/CMakeLists.txt +++ b/src/server/game/CMakeLists.txt @@ -103,7 +103,9 @@ set(game_STAT_SRCS include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/zlib diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 339ec579b1a..edf15aaf1ff 100644 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -75,7 +75,7 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn return false; // not in same map or phase - if (!hatedUnit->IsInMap(hatingUnit) || !hatedUnit->InSamePhase(hatingUnit)) + if (!hatedUnit->IsInMap(hatingUnit) || !hatedUnit->IsInPhase(hatingUnit)) return false; // spell not causing threat @@ -182,7 +182,7 @@ void HostileReference::updateOnlineStatus() && (getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->IsGameMaster()) && !getTarget()->HasUnitState(UNIT_STATE_IN_FLIGHT) && getTarget()->IsInMap(GetSourceUnit()) - && getTarget()->InSamePhase(GetSourceUnit()) + && getTarget()->IsInPhase(GetSourceUnit()) ) { Creature* creature = GetSourceUnit()->ToCreature(); diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 74beed534c6..0217363862e 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -295,9 +295,9 @@ bool Condition::Meets(ConditionSourceInfo& sourceInfo) condMeets = ConditionValue2 == sWorld->getWorldState(ConditionValue1); break; } - case CONDITION_PHASEMASK: + case CONDITION_PHASEID: { - condMeets = object->GetPhaseMask() & ConditionValue1; + condMeets = object->IsInPhase(ConditionValue1); break; } case CONDITION_TITLE: @@ -474,7 +474,7 @@ uint32 Condition::GetSearcherTypeMaskForCondition() case CONDITION_WORLD_STATE: mask |= GRID_MAP_TYPE_MASK_ALL; break; - case CONDITION_PHASEMASK: + case CONDITION_PHASEID: mask |= GRID_MAP_TYPE_MASK_ALL; break; case CONDITION_TITLE: @@ -1512,11 +1512,11 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) } break; case CONDITION_SOURCE_TYPE_PHASE_DEFINITION: - if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType)) + /*if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType)) { TC_LOG_ERROR("sql.sql", "Condition source type `CONDITION_SOURCE_TYPE_PHASE_DEFINITION` does not support condition type %u, ignoring.", cond->ConditionType); return false; - } + }*/ break; case CONDITION_SOURCE_TYPE_NPC_VENDOR: { @@ -1995,12 +1995,17 @@ bool ConditionMgr::isConditionTypeValid(Condition* cond) TC_LOG_ERROR("sql.sql", "World state condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } - case CONDITION_PHASEMASK: + case CONDITION_PHASEID: { + if (!sPhaseStore.LookupEntry(cond->ConditionValue1)) + { + TC_LOG_ERROR("sql.sql", "Phase condition has nonexistent phaseid in value1 (%u), skipped", cond->ConditionValue1); + return false; + } if (cond->ConditionValue2) - TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value2 (%u)!", cond->ConditionValue2); + TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value2 (%u)!", cond->ConditionValue2); if (cond->ConditionValue3) - TC_LOG_ERROR("sql.sql", "Phasemask condition has useless data in value3 (%u)!", cond->ConditionValue3); + TC_LOG_ERROR("sql.sql", "Phase condition has useless data in value3 (%u)!", cond->ConditionValue3); break; } case CONDITION_TITLE: diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index 8843aa243a7..35aa60772bd 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -59,7 +59,7 @@ enum ConditionTypes CONDITION_AREAID = 23, // area_id 0 0 true if in area_id CONDITION_CREATURE_TYPE = 24, // cinfo.type 0 0 true if creature_template.type = value1 CONDITION_SPELL = 25, // spell_id 0 0 true if player has learned spell - CONDITION_PHASEMASK = 26, // phasemask 0 0 true if object is in phasemask + CONDITION_PHASEID = 26, // phaseid 0 0 true if object is in phaseid CONDITION_LEVEL = 27, // level ComparisonType 0 true if unit's level is equal to param1 (param2 can modify the statement) CONDITION_QUEST_COMPLETE = 28, // quest_id 0 0 true if player has quest_id with all objectives complete, but not yet rewarded CONDITION_NEAR_CREATURE = 29, // creature entry distance 0 true if there is a creature of entry in range diff --git a/src/server/game/DungeonFinding/LFGScripts.cpp b/src/server/game/DungeonFinding/LFGScripts.cpp index 49264dff039..6a38afb398d 100644 --- a/src/server/game/DungeonFinding/LFGScripts.cpp +++ b/src/server/game/DungeonFinding/LFGScripts.cpp @@ -46,7 +46,7 @@ void LFGPlayerScript::OnLogout(Player* player) } } -void LFGPlayerScript::OnLogin(Player* player) +void LFGPlayerScript::OnLogin(Player* player, bool /*loginFirst*/) { if (!sLFGMgr->isOptionEnabled(LFG_OPTION_ENABLE_DUNGEON_FINDER | LFG_OPTION_ENABLE_RAID_BROWSER)) return; diff --git a/src/server/game/DungeonFinding/LFGScripts.h b/src/server/game/DungeonFinding/LFGScripts.h index 87881ed7524..1ed37bd9d05 100644 --- a/src/server/game/DungeonFinding/LFGScripts.h +++ b/src/server/game/DungeonFinding/LFGScripts.h @@ -36,7 +36,7 @@ class LFGPlayerScript : public PlayerScript // Player Hooks void OnLogout(Player* player); - void OnLogin(Player* player); + void OnLogin(Player* player, bool loginFirst); void OnMapChanged(Player* player); }; diff --git a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp index f399686d5d5..a8e32b82f01 100644 --- a/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp +++ b/src/server/game/Entities/AreaTrigger/AreaTrigger.cpp @@ -81,6 +81,9 @@ bool AreaTrigger::CreateAreaTrigger(uint32 guidlow, uint32 triggerEntry, Unit* c SetFloatValue(AREATRIGGER_FINAL_POS + 1, pos.GetPositionY()); SetFloatValue(AREATRIGGER_FINAL_POS + 2, pos.GetPositionZ()); + for (auto phase : caster->GetPhases()) + SetInPhase(phase, false, true); + if (!GetMap()->AddToMap(this)) return false; diff --git a/src/server/game/Entities/Corpse/Corpse.cpp b/src/server/game/Entities/Corpse/Corpse.cpp index 2fa82acdaf5..b6b46ff45df 100644 --- a/src/server/game/Entities/Corpse/Corpse.cpp +++ b/src/server/game/Entities/Corpse/Corpse.cpp @@ -187,7 +187,6 @@ bool Corpse::LoadCorpseFromDB(uint32 guid, Field* fields) // place SetLocationInstanceId(instanceId); SetLocationMapId(mapId); - SetPhaseMask(phaseMask, false); Relocate(posX, posY, posZ, o); if (!IsPositionValid()) diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp index 0f86669f14c..f976fb2c3e4 100644 --- a/src/server/game/Entities/Creature/Creature.cpp +++ b/src/server/game/Entities/Creature/Creature.cpp @@ -738,7 +738,13 @@ bool Creature::Create(uint32 guidlow, Map* map, uint32 phaseMask, uint32 entry, { ASSERT(map); SetMap(map); - SetPhaseMask(phaseMask, false); + + if (data && data->phaseid) + SetInPhase(data->phaseid, false, true); + + if (data && data->phaseGroup) + for (auto ph : GetPhasesForGroup(data->phaseGroup)) + SetInPhase(ph, false, true); CreatureTemplate const* cinfo = sObjectMgr->GetCreatureTemplate(entry); if (!cinfo) @@ -1506,8 +1512,6 @@ void Creature::setDeathState(DeathState s) SetMeleeDamageSchool(SpellSchools(cinfo->dmgschool)); LoadCreaturesAddon(true); Motion_Initialize(); - if (GetCreatureData() && GetPhaseMask() != GetCreatureData()->phaseMask) - SetPhaseMask(GetCreatureData()->phaseMask, false); Unit::setDeathState(ALIVE); } } diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h index 8a22ce61f0d..617fdbb204e 100644 --- a/src/server/game/Entities/Creature/Creature.h +++ b/src/server/game/Entities/Creature/Creature.h @@ -82,6 +82,7 @@ struct CreatureTemplate uint32 Modelid3; uint32 Modelid4; std::string Name; + std::string FemaleName; std::string SubName; std::string IconName; uint32 GossipMenuId; @@ -225,6 +226,7 @@ typedef std::unordered_map<uint16, CreatureBaseStats> CreatureBaseStatsContainer struct CreatureLocale { StringVector Name; + StringVector FemaleName; StringVector SubName; }; @@ -254,7 +256,7 @@ struct CreatureData CreatureData() : id(0), mapid(0), phaseMask(0), displayid(0), equipmentId(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), spawntimesecs(0), spawndist(0.0f), currentwaypoint(0), curhealth(0), curmana(0), movementType(0), - spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), dbData(true) { } + spawnMask(0), npcflag(0), unit_flags(0), dynamicflags(0), phaseid(0), phaseGroup(0), dbData(true) { } uint32 id; // entry in creature_template uint16 mapid; uint32 phaseMask; @@ -274,6 +276,8 @@ struct CreatureData uint32 npcflag; uint32 unit_flags; // enum UnitFlags mask values uint32 dynamicflags; + uint32 phaseid; + uint32 phaseGroup; bool dbData; }; diff --git a/src/server/game/Entities/GameObject/GameObject.cpp b/src/server/game/Entities/GameObject/GameObject.cpp index 4e1b8ed29b2..a2528c78516 100644 --- a/src/server/game/Entities/GameObject/GameObject.cpp +++ b/src/server/game/Entities/GameObject/GameObject.cpp @@ -180,8 +180,6 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map* map, uint32 phaseMa return false; } - SetPhaseMask(phaseMask, false); - SetZoneScript(); if (m_zoneScript) { @@ -832,6 +830,16 @@ bool GameObject::LoadGameObjectFromDB(uint32 guid, Map* map, bool addToMap) if (!Create(guid, entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state, artKit)) return false; + if (data->phaseid) + SetInPhase(data->phaseid, false, true); + + if (data->phaseGroup) + { + // Set the gameobject in all the phases of the phasegroup + for (auto ph : GetPhasesForGroup(data->phaseGroup)) + SetInPhase(ph, false, true); + } + if (data->spawntimesecs >= 0) { m_spawnedByDefault = true; @@ -2071,9 +2079,9 @@ void GameObject::SetDisplayId(uint32 displayid) UpdateModel(); } -void GameObject::SetPhaseMask(uint32 newPhaseMask, bool update) +void GameObject::SetInPhase(uint32 id, bool update, bool apply) { - WorldObject::SetPhaseMask(newPhaseMask, update); + WorldObject::SetInPhase(id, update, apply); if (m_model && m_model->isEnabled()) EnableCollision(true); } diff --git a/src/server/game/Entities/GameObject/GameObject.h b/src/server/game/Entities/GameObject/GameObject.h index 47a92ee4fa5..11df5a17409 100644 --- a/src/server/game/Entities/GameObject/GameObject.h +++ b/src/server/game/Entities/GameObject/GameObject.h @@ -592,7 +592,7 @@ struct GameObjectData { explicit GameObjectData() : id(0), mapid(0), phaseMask(0), posX(0.0f), posY(0.0f), posZ(0.0f), orientation(0.0f), rotation0(0.0f), rotation1(0.0f), rotation2(0.0f), rotation3(0.0f), spawntimesecs(0), - animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), dbData(true) { } + animprogress(0), go_state(GO_STATE_ACTIVE), spawnMask(0), artKit(0), phaseid(0), phaseGroup(0), dbData(true) { } uint32 id; // entry in gamobject_template uint16 mapid; uint32 phaseMask; @@ -609,6 +609,8 @@ struct GameObjectData GOState go_state; uint8 spawnMask; uint8 artKit; + uint32 phaseid; + uint32 phaseGroup; bool dbData; }; @@ -725,7 +727,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); } static void SetGoArtKit(uint8 artkit, GameObject* go, uint32 lowguid = 0); - void SetPhaseMask(uint32 newPhaseMask, bool update); + void SetInPhase(uint32 id, bool update, bool apply); void EnableCollision(bool enable); void Use(Unit* user); @@ -877,6 +879,7 @@ class GameObject : public WorldObject, public GridObject<GameObject>, public Map //! Following check does check 3d distance return IsInRange(obj->GetPositionX(), obj->GetPositionY(), obj->GetPositionZ(), dist2compare); } + GameObjectAI* m_AI; }; #endif diff --git a/src/server/game/Entities/Item/Item.h b/src/server/game/Entities/Item/Item.h index 8a10784b3c2..211b5beaf04 100644 --- a/src/server/game/Entities/Item/Item.h +++ b/src/server/game/Entities/Item/Item.h @@ -231,6 +231,7 @@ class Item : public Object void SetBinding(bool val) { ApplyModFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND, val); } bool IsSoulBound() const { return HasFlag(ITEM_FIELD_FLAGS, ITEM_FLAG_SOULBOUND); } bool IsBoundAccountWide() const { return (GetTemplate()->Flags & ITEM_PROTO_FLAG_BIND_TO_ACCOUNT) != 0; } + bool IsBattlenetAccountBound() const { return GetTemplate()->Flags2 & ITEM_FLAGS_EXTRA_BNET_ACCOUNT_BOUND; } bool IsBindedNotWith(Player const* player) const; bool IsBoundByEnchant() const; virtual void SaveToDB(SQLTransaction& trans); diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index 28839775732..38f1469f7bd 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -1496,7 +1496,7 @@ bool WorldObject::IsWithinDist(WorldObject const* obj, float dist2compare, bool bool WorldObject::IsWithinDistInMap(WorldObject const* obj, float dist2compare, bool is3D /*= true*/) const { - return obj && IsInMap(obj) && InSamePhase(obj) && _IsWithinDist(obj, dist2compare, is3D); + return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D); } bool WorldObject::IsWithinLOS(float ox, float oy, float oz) const @@ -1935,7 +1935,7 @@ bool WorldObject::CanSeeOrDetect(WorldObject const* obj, bool ignoreStealth, boo bool WorldObject::CanNeverSee(WorldObject const* obj) const { - return GetMap() != obj->GetMap() || !InSamePhase(obj); + return GetMap() != obj->GetMap() || !IsInPhase(obj); } bool WorldObject::CanDetect(WorldObject const* obj, bool ignoreStealth) const @@ -2332,9 +2332,9 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert } } - uint32 phase = PHASEMASK_NORMAL; + std::set<uint32> phases; if (summoner) - phase = summoner->GetPhaseMask(); + phases = summoner->GetPhases(); TempSummon* summon = NULL; switch (mask) @@ -2356,12 +2356,16 @@ TempSummon* Map::SummonCreature(uint32 entry, Position const& pos, SummonPropert break; } - if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, phase, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) + if (!summon->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), this, 0, entry, pos.GetPositionX(), pos.GetPositionY(), pos.GetPositionZ(), pos.GetOrientation(), nullptr, vehId)) { delete summon; return NULL; } + // Set the summon to the summoner's phase + for (auto phaseId : phases) + summon->SetInPhase(phaseId, false, true); + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); summon->SetHomePosition(pos); @@ -2456,6 +2460,9 @@ GameObject* WorldObject::SummonGameObject(uint32 entry, float x, float y, float return NULL; } + for (auto phase : GetPhases()) + go->SetInPhase(phase, false, true); + go->SetRespawnTime(respawnTime); if (GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT) //not sure how to handle this ToUnit()->AddGameObject(go); @@ -2838,9 +2845,36 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update) UpdateObjectVisibility(); } +void WorldObject::SetInPhase(uint32 id, bool update, bool apply) +{ + if (apply) + _phases.insert(id); + else + _phases.erase(id); + + if (update && IsInWorld()) + UpdateObjectVisibility(); +} + +bool WorldObject::IsInPhase(WorldObject const* obj) const +{ + // PhaseId 169 is the default fallback phase + if (_phases.empty() && obj->GetPhases().empty()) + return true; + + if (_phases.empty() && obj->IsInPhase(169)) + return true; + + if (obj->GetPhases().empty() && IsInPhase(169)) + return true; + + return Trinity::Containers::Intersects(_phases.begin(), _phases.end(), obj->GetPhases().begin(), obj->GetPhases().end()); +} + bool WorldObject::InSamePhase(WorldObject const* obj) const { - return InSamePhase(obj->GetPhaseMask()); + return IsInPhase(obj); + // return InSamePhase(obj->GetPhaseMask()); } void WorldObject::PlayDistanceSound(uint32 sound_id, Player* target /*= NULL*/) diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h index 5e525f1e0d5..2d7a6f12016 100644 --- a/src/server/game/Entities/Object/Object.h +++ b/src/server/game/Entities/Object/Object.h @@ -676,9 +676,13 @@ class WorldObject : public Object, public WorldLocation uint32 GetInstanceId() const { return m_InstanceId; } virtual void SetPhaseMask(uint32 newPhaseMask, bool update); + virtual void SetInPhase(uint32 id, bool update, bool apply); uint32 GetPhaseMask() const { return m_phaseMask; } bool InSamePhase(WorldObject const* obj) const; bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); } + bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); } + bool IsInPhase(WorldObject const* obj) const; + std::set<uint32> const& GetPhases() const { return _phases; } uint32 GetZoneId() const; uint32 GetAreaId() const; @@ -861,6 +865,7 @@ class WorldObject : public Object, public WorldLocation //uint32 m_mapId; // object at map with map_id uint32 m_InstanceId; // in map copy with instance id uint32 m_phaseMask; // in area phase state + std::set<uint32> _phases; uint16 m_notifyflags; uint16 m_executed_notifies; diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp index 82c6f1541ef..c1b0ef43dbf 100644 --- a/src/server/game/Entities/Pet/Pet.cpp +++ b/src/server/game/Entities/Pet/Pet.cpp @@ -179,6 +179,9 @@ bool Pet::LoadPetFromDB(Player* owner, uint32 petEntry, uint32 petnumber, bool c if (!Create(guid, map, owner->GetPhaseMask(), petEntry, petId)) return false; + for (auto itr : owner->GetPhases()) + SetInPhase(itr, false, true); + setPetType(petType); setFaction(owner->getFaction()); SetUInt32Value(UNIT_CREATED_BY_SPELL, summonSpellId); diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 0325c288944..d578f2cebd0 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -668,7 +668,7 @@ void KillRewarder::Reward() } -Player::Player(WorldSession* session): Unit(true), phaseMgr(this) +Player::Player(WorldSession* session): Unit(true) { m_speakTime = 0; m_speakCount = 0; @@ -2892,7 +2892,6 @@ void Player::SetGameMaster(bool on) getHostileRefManager().setOnlineOfflineState(false); CombatStopWithPets(); - SetPhaseMask(uint32(PHASEMASK_ANYWHERE), false); // see and visible in all phases m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, GetSession()->GetSecurity()); } else @@ -2917,9 +2916,6 @@ void Player::SetGameMaster(bool on) getHostileRefManager().setOnlineOfflineState(true); m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER); - - phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); - phaseMgr.Update(); } UpdateObjectVisibility(); @@ -3160,11 +3156,6 @@ void Player::GiveLevel(uint8 level) UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL); - PhaseUpdateData phaseUpdateData; - phaseUpdateData.AddConditionType(CONDITION_LEVEL); - - phaseMgr.NotifyConditionChanged(phaseUpdateData); - // Refer-A-Friend if (GetSession()->GetRecruiterId()) if (level < sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL)) @@ -7789,8 +7780,6 @@ void Player::UpdateArea(uint32 newArea) // so apply them accordingly m_areaUpdateId = newArea; - phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE); - AreaTableEntry const* area = GetAreaEntryByAreaID(newArea); pvpInfo.IsInFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA); UpdatePvPState(true); @@ -7821,14 +7810,10 @@ void Player::UpdateArea(uint32 newArea) RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_RESTING); SetRestType(REST_TYPE_NO); } - - phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE); } void Player::UpdateZone(uint32 newZone, uint32 newArea) { - phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE); - if (m_zoneUpdateId != newZone) { sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId); @@ -7933,8 +7918,6 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea) UpdateLocalChannels(newZone); UpdateZoneDependentAuras(newZone); - - phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE); } //If players are too far away from the duel flag... they lose the duel @@ -15484,10 +15467,6 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver, m_RewardedQuests.insert(quest_id); m_RewardedQuestsSave[quest_id] = true; - PhaseUpdateData phaseUpdateData; - phaseUpdateData.AddQuestUpdate(quest_id); - phaseMgr.NotifyConditionChanged(phaseUpdateData); - // StoreNewItem, mail reward, etc. save data directly to the database // to prevent exploitable data desynchronisation we save the quest status to the database too // (to prevent rewarding this quest another time while rewards were already given out) @@ -16137,11 +16116,6 @@ void Player::SetQuestStatus(uint32 questId, QuestStatus status, bool update /*= m_QuestStatusSave[questId] = true; } - PhaseUpdateData phaseUpdateData; - phaseUpdateData.AddQuestUpdate(questId); - - phaseMgr.NotifyConditionChanged(phaseUpdateData); - if (update) SendQuestUpdate(questId); } @@ -16153,11 +16127,6 @@ void Player::RemoveActiveQuest(uint32 questId, bool update /*= true*/) { m_QuestStatus.erase(itr); m_QuestStatusSave[questId] = false; - - PhaseUpdateData phaseUpdateData; - phaseUpdateData.AddQuestUpdate(questId); - - phaseMgr.NotifyConditionChanged(phaseUpdateData); } if (update) @@ -16171,11 +16140,6 @@ void Player::RemoveRewardedQuest(uint32 questId, bool update /*= true*/) { m_RewardedQuests.erase(rewItr); m_RewardedQuestsSave[questId] = false; - - PhaseUpdateData phaseUpdateData; - phaseUpdateData.AddQuestUpdate(questId); - - phaseMgr.NotifyConditionChanged(phaseUpdateData); } if (update) @@ -25642,7 +25606,7 @@ void Player::_LoadSkills(PreparedQueryResult result) base_skill = 1; // skill mast be known and then > 0 in any case if (GetPureSkillValue(SKILL_FIRST_AID) < base_skill) - SetSkill(SKILL_FIRST_AID, 0, base_skill, base_skill); + SetSkill(SKILL_FIRST_AID, 4 /*artisan*/, base_skill, 300); if (GetPureSkillValue(SKILL_AXES) < base_skill) SetSkill(SKILL_AXES, 0, base_skill, base_skill); if (GetPureSkillValue(SKILL_DEFENSE) < base_skill) @@ -27538,6 +27502,9 @@ Pet* Player::SummonPet(uint32 entry, float x, float y, float z, float ang, PetTy return NULL; } + for (auto itr : GetPhases()) + pet->SetInPhase(itr, false, true); + pet->SetCreatorGUID(GetGUID()); pet->SetUInt32Value(UNIT_FIELD_FACTIONTEMPLATE, getFaction()); @@ -27910,3 +27877,24 @@ void Player::ReadMovementInfo(WorldPacket& data, MovementInfo* mi, Movement::Ext #undef REMOVE_VIOLATING_FLAGS } + +void Player::UpdatePhasing() +{ + if (!IsInWorld()) + return; + + std::set<uint32> phaseIds; + std::set<uint32> terrainswaps; + std::set<uint32> worldAreaSwaps; + + for (auto phase : GetPhases()) + { + PhaseInfo const* info = sObjectMgr->GetPhaseInfo(phase); + if (!info) + continue; + terrainswaps.insert(info->terrainSwapMap); + worldAreaSwaps.insert(info->worldMapAreaSwap); + } + + GetSession()->SendSetPhaseShift(GetPhases(), terrainswaps, worldAreaSwaps); +} diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 94d90de8813..3d0300a681b 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -25,7 +25,6 @@ #include "Item.h" #include "PetDefines.h" -#include "PhaseMgr.h" #include "QuestDef.h" #include "SpellMgr.h" #include "Unit.h" @@ -56,7 +55,6 @@ class PlayerMenu; class PlayerSocial; class SpellCastTargets; class UpdateMask; -class PhaseMgr; typedef std::deque<Mail*> PlayerMails; @@ -1333,8 +1331,6 @@ class Player : public Unit, public GridObject<Player> Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime); void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false); - PhaseMgr& GetPhaseMgr() { return phaseMgr; } - /// Handles said message in regular chat based on declared language and in config pre-defined Range. void Say(std::string const& text, const uint32 language); /// Handles yelled message in regular chat based on declared language and in config pre-defined Range. @@ -2362,6 +2358,8 @@ class Player : public Unit, public GridObject<Player> void UpdateVisibilityOf(WorldObject* target); void UpdateTriggerVisibility(); + void UpdatePhasing(); + template<class T> void UpdateVisibilityOf(T* target, UpdateData& data, std::set<Unit*>& visibleNow); @@ -2890,8 +2888,6 @@ class Player : public Unit, public GridObject<Player> uint32 _activeCheats; uint32 _maxPersonalArenaRate; - - PhaseMgr phaseMgr; }; void AddItemsSetItem(Player*player, Item* item); diff --git a/src/server/game/Entities/Transport/Transport.cpp b/src/server/game/Entities/Transport/Transport.cpp index 4509d0f4d12..0c22caed882 100644 --- a/src/server/game/Entities/Transport/Transport.cpp +++ b/src/server/game/Entities/Transport/Transport.cpp @@ -301,6 +301,15 @@ Creature* Transport::CreateNPCPassenger(uint32 guid, CreatureData const* data) return NULL; } + if (data->phaseid) + creature->SetInPhase(data->phaseid, false, true); + else if (data->phaseGroup) + for (auto phase : GetPhasesForGroup(data->phaseGroup)) + creature->SetInPhase(phase, false, true); + else + for (auto phase : GetPhases()) // Set the creature to the transport's phases + creature->SetInPhase(phase, false, true); + if (!map->AddToMap(creature)) { delete creature; @@ -405,9 +414,11 @@ TempSummon* Transport::SummonPassenger(uint32 entry, Position const& pos, TempSu } } - uint32 phase = PHASEMASK_NORMAL; + std::set<uint32> phases; if (summoner) - phase = summoner->GetPhaseMask(); + phases = summoner->GetPhases(); + else + phases = GetPhases(); // If there was no summoner, try to use the transport phases TempSummon* summon = NULL; switch (mask) @@ -433,12 +444,15 @@ 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(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, 0, entry, x, y, z, o, nullptr, vehId)) { delete summon; return NULL; } + for (auto itr : phases) + summon->SetInPhase(itr, false, true); + summon->SetUInt32Value(UNIT_CREATED_BY_SPELL, spellId); summon->SetTransport(this); diff --git a/src/server/game/Entities/Transport/Transport.h b/src/server/game/Entities/Transport/Transport.h index e644417f1ac..7da8c11861c 100644 --- a/src/server/game/Entities/Transport/Transport.h +++ b/src/server/game/Entities/Transport/Transport.h @@ -27,7 +27,7 @@ struct CreatureData; class Transport : public GameObject, public TransportBase { - friend Transport* TransportMgr::CreateTransport(uint32, uint32, Map*); + friend Transport* TransportMgr::CreateTransport(uint32, uint32, Map*, uint32, uint32); Transport(); public: diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 4e9954116eb..6ece5f249ba 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -435,7 +435,7 @@ float Unit::GetMeleeReach() const bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const { - if (!obj || !IsInMap(obj) || !InSamePhase(obj)) + if (!obj || !IsInMap(obj) || !IsInPhase(obj)) return false; float dx = GetPositionX() - obj->GetPositionX(); @@ -451,7 +451,7 @@ bool Unit::IsWithinCombatRange(const Unit* obj, float dist2compare) const bool Unit::IsWithinMeleeRange(const Unit* obj, float dist) const { - if (!obj || !IsInMap(obj) || !InSamePhase(obj)) + if (!obj || !IsInMap(obj) || !IsInPhase(obj)) return false; float dx = GetPositionX() - obj->GetPositionX(); @@ -3125,7 +3125,7 @@ void Unit::_ApplyAuraEffect(Aura* aura, uint8 effIndex) AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID()); ASSERT(aurApp); if (!aurApp->GetEffectMask()) - _ApplyAura(aurApp, 1<<effIndex); + _ApplyAura(aurApp, 1 << effIndex); else aurApp->_HandleEffect(effIndex, true); } @@ -3163,7 +3163,7 @@ void Unit::_ApplyAura(AuraApplication * aurApp, uint8 effMask) // apply effects of the aura for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) { - if (effMask & 1<<i && (!aurApp->GetRemoveMode())) + if (effMask & 1 << i && (!aurApp->GetRemoveMode())) aurApp->_HandleEffect(i, true); } } @@ -3618,6 +3618,8 @@ void Unit::RemoveAurasByType(AuraType auraType, uint64 casterGUID, Aura* except, { Aura* aura = (*iter)->GetBase(); AuraApplication * aurApp = aura->GetApplicationOfTarget(GetGUID()); + if (!aurApp) + continue; ++iter; if (aura != except && (!casterGUID || aura->GetCasterGUID() == casterGUID) @@ -3643,7 +3645,7 @@ void Unit::RemoveAurasWithAttribute(uint32 flags) } } -void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) +void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase, bool phaseid) { // single target auras from other casters for (AuraApplicationMap::iterator iter = m_appliedAuras.begin(); iter != m_appliedAuras.end();) @@ -3653,12 +3655,12 @@ void Unit::RemoveNotOwnSingleTargetAuras(uint32 newPhase) if (aura->GetCasterGUID() != GetGUID() && aura->GetSpellInfo()->IsSingleTarget()) { - if (!newPhase) + if (!newPhase && !phaseid) RemoveAura(iter); else { Unit* caster = aura->GetCaster(); - if (!caster || !caster->InSamePhase(newPhase)) + if (!caster || (newPhase && !caster->InSamePhase(newPhase)) || (!newPhase && !caster->IsInPhase(this))) RemoveAura(iter); else ++iter; @@ -8953,9 +8955,8 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto { // Shatter case 911: - if (!victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this)) - break; - AddPct(crit_chance, (*i)->GetAmount()*20); + if (victim->HasAuraState(AURA_STATE_FROZEN, spellProto, this)) + AddPct(crit_chance, (*i)->GetAmount()*20); break; case 7917: // Glyph of Shadowburn if (victim->HasAuraState(AURA_STATE_HEALTHLESS_35_PERCENT, spellProto, this)) @@ -8976,7 +8977,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto case SPELLFAMILY_MAGE: // Glyph of Fire Blast if (spellProto->SpellFamilyFlags[0] == 0x2 && spellProto->SpellIconID == 12) - if (victim->HasAuraWithMechanic((1<<MECHANIC_STUN) | (1<<MECHANIC_KNOCKOUT))) + if (victim->HasAuraWithMechanic((1 << MECHANIC_STUN) | (1 << MECHANIC_KNOCKOUT))) if (AuraEffect const* aurEff = GetAuraEffect(56369, EFFECT_0)) crit_chance += aurEff->GetAmount(); break; @@ -8997,7 +8998,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto crit_chance += aurEff->GetAmount(); break; } - break; + break; case SPELLFAMILY_ROGUE: // Shiv-applied poisons can't crit if (FindCurrentSpellBySpellId(5938)) @@ -9019,7 +9020,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto return 100.0f; break; } - break; + break; case SPELLFAMILY_SHAMAN: // Lava Burst if (spellProto->SpellFamilyFlags[1] & 0x00001000) @@ -9029,7 +9030,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto return 100.0f; break; } - break; + break; } } break; @@ -9050,7 +9051,7 @@ float Unit::GetUnitSpellCriticalChance(Unit* victim, SpellInfo const* spellProto crit_chance += rendAndTear->GetAmount(); break; } - break; + break; } } /// Intentional fallback. Calculate critical strike chance for both Ranged and Melee spells @@ -14656,61 +14657,54 @@ float Unit::MeleeSpellMissChance(const Unit* victim, WeaponAttackType attType, u return missChance; } -void Unit::SetPhaseMask(uint32 newPhaseMask, bool update) +void Unit::SetInPhase(uint32 id, bool update, bool apply) { - if (newPhaseMask == GetPhaseMask()) + WorldObject::SetInPhase(id, update, apply); + + if (!IsInWorld()) return; + + RemoveNotOwnSingleTargetAuras(0, true); - if (IsInWorld()) + if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout())) { - RemoveNotOwnSingleTargetAuras(newPhaseMask); // we can lost access to caster or target + HostileRefManager& refManager = getHostileRefManager(); + HostileReference* ref = refManager.getFirst(); - // modify hostile references for new phasemask, some special cases deal with hostile references themselves - if (GetTypeId() == TYPEID_UNIT || (!ToPlayer()->IsGameMaster() && !ToPlayer()->GetSession()->PlayerLogout())) + while (ref) { - HostileRefManager& refManager = getHostileRefManager(); - HostileReference* ref = refManager.getFirst(); + if (Unit* unit = ref->GetSource()->GetOwner()) + if (Creature* creature = unit->ToCreature()) + refManager.setOnlineOfflineState(creature, creature->IsInPhase(this)); - while (ref) - { - if (Unit* unit = ref->GetSource()->GetOwner()) - if (Creature* creature = unit->ToCreature()) - refManager.setOnlineOfflineState(creature, creature->InSamePhase(newPhaseMask)); - - ref = ref->next(); - } + ref = ref->next(); + } - // modify threat lists for new phasemask - if (GetTypeId() != TYPEID_PLAYER) - { - std::list<HostileReference*> threatList = getThreatManager().getThreatList(); - std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList(); + // modify threat lists for new phasemask + if (GetTypeId() != TYPEID_PLAYER) + { + std::list<HostileReference*> threatList = getThreatManager().getThreatList(); + std::list<HostileReference*> offlineThreatList = getThreatManager().getOfflineThreatList(); - // merge expects sorted lists - threatList.sort(); - offlineThreatList.sort(); - threatList.merge(offlineThreatList); + // merge expects sorted lists + threatList.sort(); + offlineThreatList.sort(); + threatList.merge(offlineThreatList); - for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) - if (Unit* unit = (*itr)->getTarget()) - unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->InSamePhase(newPhaseMask)); - } + for (std::list<HostileReference*>::const_iterator itr = threatList.begin(); itr != threatList.end(); ++itr) + if (Unit* unit = (*itr)->getTarget()) + unit->getHostileRefManager().setOnlineOfflineState(ToCreature(), unit->IsInPhase(this)); } } - WorldObject::SetPhaseMask(newPhaseMask, update); - - if (!IsInWorld()) - return; - for (ControlList::const_iterator itr = m_Controlled.begin(); itr != m_Controlled.end(); ++itr) if ((*itr)->GetTypeId() == TYPEID_UNIT) - (*itr)->SetPhaseMask(newPhaseMask, true); + (*itr)->SetInPhase(id, true, apply); for (uint8 i = 0; i < MAX_SUMMON_SLOT; ++i) if (m_SummonSlot[i]) if (Creature* summon = GetMap()->GetCreature(m_SummonSlot[i])) - summon->SetPhaseMask(newPhaseMask, true); + summon->SetInPhase(id, true, apply); } void Unit::UpdateObjectVisibility(bool forced) diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h index 8adccb25f84..eb0882e3b64 100644 --- a/src/server/game/Entities/Unit/Unit.h +++ b/src/server/game/Entities/Unit/Unit.h @@ -1762,7 +1762,7 @@ class Unit : public WorldObject void RemoveAurasDueToSpellBySteal(uint32 spellId, uint64 casterGUID, Unit* stealer); void RemoveAurasDueToItemSpell(uint32 spellId, uint64 castItemGuid); void RemoveAurasByType(AuraType auraType, uint64 casterGUID = 0, Aura* except = NULL, bool negative = true, bool positive = true); - void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0); + void RemoveNotOwnSingleTargetAuras(uint32 newPhase = 0x0, bool phaseid = false); void RemoveAurasWithInterruptFlags(uint32 flag, uint32 except = 0); void RemoveAurasWithAttribute(uint32 flags); void RemoveAurasWithFamily(SpellFamilyNames family, uint32 familyFlag1, uint32 familyFlag2, uint32 familyFlag3, uint64 casterGUID); @@ -1928,7 +1928,7 @@ class Unit : public WorldObject void SetVisible(bool x); // common function for visibility checks for player/creatures with detection code - void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask + void SetInPhase(uint32 id, bool update, bool apply); void UpdateObjectVisibility(bool forced = true); SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY]; diff --git a/src/server/game/Globals/ObjectAccessor.cpp b/src/server/game/Globals/ObjectAccessor.cpp index 7de319df07f..13609f8e949 100644 --- a/src/server/game/Globals/ObjectAccessor.cpp +++ b/src/server/game/Globals/ObjectAccessor.cpp @@ -371,7 +371,6 @@ Corpse* ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia // 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->SetUInt64Value(CORPSE_FIELD_OWNER, 0); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index f64f57602c7..2ccaef0456b 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -324,9 +324,18 @@ void ObjectMgr::LoadCreatureLocales() { uint32 oldMSTime = getMSTime(); - _creatureLocaleStore.clear(); // need for reload case + _creatureLocaleStore.clear(); // need for reload case - QueryResult result = WorldDatabase.Query("SELECT entry, name_loc1, subname_loc1, name_loc2, subname_loc2, name_loc3, subname_loc3, name_loc4, subname_loc4, name_loc5, subname_loc5, name_loc6, subname_loc6, name_loc7, subname_loc7, name_loc8, subname_loc8 FROM locales_creature"); + QueryResult result = WorldDatabase.Query("SELECT entry, " + "name_loc1, femaleName_loc1, subname_loc1, " + "name_loc2, femaleName_loc2, subname_loc2, " + "name_loc3, femaleName_loc3, subname_loc3, " + "name_loc4, femaleName_loc4, subname_loc4, " + "name_loc5, femaleName_loc5, subname_loc5, " + "name_loc6, femaleName_loc6, subname_loc6, " + "name_loc7, femaleName_loc7, subname_loc7, " + "name_loc8, femaleName_loc8, subname_loc8 " + "FROM locales_creature"); if (!result) return; @@ -342,8 +351,9 @@ void ObjectMgr::LoadCreatureLocales() for (uint8 i = 1; i < TOTAL_LOCALES; ++i) { LocaleConstant locale = (LocaleConstant) i; - AddLocaleString(fields[1 + 2 * (i - 1)].GetString(), locale, data.Name); - AddLocaleString(fields[1 + 2 * (i - 1) + 1].GetString(), locale, data.SubName); + AddLocaleString(fields[1 + 3 * (i - 1)].GetString(), locale, data.Name); + AddLocaleString(fields[1 + 3 * (i - 1) + 1].GetString(), locale, data.FemaleName); + AddLocaleString(fields[1 + 3 * (i - 1) + 2].GetString(), locale, data.SubName); } } while (result->NextRow()); @@ -419,19 +429,19 @@ void ObjectMgr::LoadCreatureTemplates() // 0 1 2 3 4 5 6 7 8 QueryResult result = WorldDatabase.Query("SELECT entry, difficulty_entry_1, difficulty_entry_2, difficulty_entry_3, KillCredit1, KillCredit2, modelid1, modelid2, modelid3, " - // 9 10 11 12 13 14 15 16 17 18 19 20 21 - "modelid4, name, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, " - // 22 23 24 25 26 27 28 29 30 31 32 33 + // 9 10 11 12 13 14 15 16 17 18 19 20 21 22 + "modelid4, name, femaleName, subname, IconName, gossip_menu_id, minlevel, maxlevel, exp, exp_unk, faction, npcflag, speed_walk, speed_run, " + // 23 24 25 26 27 28 29 30 31 32 33 34 "scale, rank, mindmg, maxdmg, dmgschool, attackpower, dmg_multiplier, baseattacktime, rangeattacktime, unit_class, unit_flags, unit_flags2, " - // 34 35 36 37 38 39 40 41 42 + // 35 36 37 38 39 40 41 42 43 "dynamicflags, family, trainer_type, trainer_class, trainer_race, minrangedmg, maxrangedmg, rangedattackpower, type, " - // 43 44 45 46 47 48 49 50 51 52 53 + // 44 45 46 47 48 49 50 51 52 53 54 "type_flags, type_flags2, lootid, pickpocketloot, skinloot, resistance1, resistance2, resistance3, resistance4, resistance5, resistance6, " - // 54 55 56 57 58 59 60 61 62 63 64 65 66 67 + // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 "spell1, spell2, spell3, spell4, spell5, spell6, spell7, spell8, PetSpellDataId, VehicleId, mingold, maxgold, AIName, MovementType, " - // 68 69 70 71 72 73 74 75 76 77 78 79 + // 69 70 71 72 73 74 75 76 77 78 79 80 "InhabitType, HoverHeight, Health_mod, Mana_mod, Mana_mod_extra, Armor_mod, RacialLeader, questItem1, questItem2, questItem3, questItem4, questItem5, " - // 80 81 82 83 84 85 + // 81 82 83 84 85 86 " questItem6, movementId, RegenHealth, mechanic_immune_mask, flags_extra, ScriptName " "FROM creature_template;"); @@ -465,72 +475,73 @@ void ObjectMgr::LoadCreatureTemplates() creatureTemplate.Modelid3 = fields[8].GetUInt32(); creatureTemplate.Modelid4 = fields[9].GetUInt32(); creatureTemplate.Name = fields[10].GetString(); - creatureTemplate.SubName = fields[11].GetString(); - creatureTemplate.IconName = fields[12].GetString(); - creatureTemplate.GossipMenuId = fields[13].GetUInt32(); - creatureTemplate.minlevel = fields[14].GetUInt8(); - creatureTemplate.maxlevel = fields[15].GetUInt8(); - creatureTemplate.expansion = uint32(fields[16].GetInt16()); - creatureTemplate.expansionUnknown = uint32(fields[17].GetUInt16()); - creatureTemplate.faction = uint32(fields[18].GetUInt16()); - creatureTemplate.npcflag = fields[19].GetUInt32(); - creatureTemplate.speed_walk = fields[20].GetFloat(); - creatureTemplate.speed_run = fields[21].GetFloat(); - creatureTemplate.scale = fields[22].GetFloat(); - creatureTemplate.rank = uint32(fields[23].GetUInt8()); - creatureTemplate.mindmg = fields[24].GetFloat(); - creatureTemplate.maxdmg = fields[25].GetFloat(); - creatureTemplate.dmgschool = uint32(fields[26].GetInt8()); - creatureTemplate.attackpower = fields[27].GetUInt32(); - creatureTemplate.dmg_multiplier = fields[28].GetFloat(); - creatureTemplate.baseattacktime = fields[29].GetUInt32(); - creatureTemplate.rangeattacktime = fields[30].GetUInt32(); - creatureTemplate.unit_class = uint32(fields[31].GetUInt8()); - creatureTemplate.unit_flags = fields[32].GetUInt32(); - creatureTemplate.unit_flags2 = fields[33].GetUInt32(); - creatureTemplate.dynamicflags = fields[34].GetUInt32(); - creatureTemplate.family = uint32(fields[35].GetUInt8()); - creatureTemplate.trainer_type = uint32(fields[36].GetUInt8()); - creatureTemplate.trainer_class = uint32(fields[37].GetUInt8()); - creatureTemplate.trainer_race = uint32(fields[38].GetUInt8()); - creatureTemplate.minrangedmg = fields[39].GetFloat(); - creatureTemplate.maxrangedmg = fields[40].GetFloat(); - creatureTemplate.rangedattackpower = uint32(fields[41].GetUInt16()); - creatureTemplate.type = uint32(fields[42].GetUInt8()); - creatureTemplate.type_flags = fields[43].GetUInt32(); - creatureTemplate.type_flags2 = fields[44].GetUInt32(); - creatureTemplate.lootid = fields[45].GetUInt32(); - creatureTemplate.pickpocketLootId = fields[46].GetUInt32(); - creatureTemplate.SkinLootId = fields[47].GetUInt32(); + creatureTemplate.FemaleName = fields[11].GetString(); + creatureTemplate.SubName = fields[12].GetString(); + creatureTemplate.IconName = fields[13].GetString(); + creatureTemplate.GossipMenuId = fields[14].GetUInt32(); + creatureTemplate.minlevel = fields[15].GetUInt8(); + creatureTemplate.maxlevel = fields[16].GetUInt8(); + creatureTemplate.expansion = uint32(fields[17].GetInt16()); + creatureTemplate.expansionUnknown = uint32(fields[18].GetUInt16()); + creatureTemplate.faction = uint32(fields[19].GetUInt16()); + creatureTemplate.npcflag = fields[20].GetUInt32(); + creatureTemplate.speed_walk = fields[21].GetFloat(); + creatureTemplate.speed_run = fields[22].GetFloat(); + creatureTemplate.scale = fields[23].GetFloat(); + creatureTemplate.rank = uint32(fields[24].GetUInt8()); + creatureTemplate.mindmg = fields[25].GetFloat(); + creatureTemplate.maxdmg = fields[26].GetFloat(); + creatureTemplate.dmgschool = uint32(fields[27].GetInt8()); + creatureTemplate.attackpower = fields[28].GetUInt32(); + creatureTemplate.dmg_multiplier = fields[29].GetFloat(); + creatureTemplate.baseattacktime = fields[30].GetUInt32(); + creatureTemplate.rangeattacktime = fields[31].GetUInt32(); + creatureTemplate.unit_class = uint32(fields[32].GetUInt8()); + creatureTemplate.unit_flags = fields[33].GetUInt32(); + creatureTemplate.unit_flags2 = fields[34].GetUInt32(); + creatureTemplate.dynamicflags = fields[35].GetUInt32(); + creatureTemplate.family = uint32(fields[36].GetUInt8()); + creatureTemplate.trainer_type = uint32(fields[37].GetUInt8()); + creatureTemplate.trainer_class = uint32(fields[38].GetUInt8()); + creatureTemplate.trainer_race = uint32(fields[39].GetUInt8()); + creatureTemplate.minrangedmg = fields[40].GetFloat(); + creatureTemplate.maxrangedmg = fields[41].GetFloat(); + creatureTemplate.rangedattackpower = uint32(fields[42].GetUInt16()); + creatureTemplate.type = uint32(fields[43].GetUInt8()); + creatureTemplate.type_flags = fields[44].GetUInt32(); + creatureTemplate.type_flags2 = fields[45].GetUInt32(); + creatureTemplate.lootid = fields[46].GetUInt32(); + creatureTemplate.pickpocketLootId = fields[47].GetUInt32(); + creatureTemplate.SkinLootId = fields[48].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - creatureTemplate.resistance[i] = fields[48 + i - 1].GetInt16(); + creatureTemplate.resistance[i] = fields[49 + i - 1].GetInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - creatureTemplate.spells[i] = fields[54 + i].GetUInt32(); - - creatureTemplate.PetSpellDataId = fields[62].GetUInt32(); - creatureTemplate.VehicleId = fields[63].GetUInt32(); - creatureTemplate.mingold = fields[64].GetUInt32(); - creatureTemplate.maxgold = fields[65].GetUInt32(); - creatureTemplate.AIName = fields[66].GetString(); - creatureTemplate.MovementType = uint32(fields[67].GetUInt8()); - creatureTemplate.InhabitType = uint32(fields[68].GetUInt8()); - creatureTemplate.HoverHeight = fields[69].GetFloat(); - creatureTemplate.ModHealth = fields[70].GetFloat(); - creatureTemplate.ModMana = fields[71].GetFloat(); - creatureTemplate.ModManaExtra = fields[72].GetFloat(); - creatureTemplate.ModArmor = fields[73].GetFloat(); - creatureTemplate.RacialLeader = fields[74].GetBool(); + creatureTemplate.spells[i] = fields[55 + i].GetUInt32(); + + creatureTemplate.PetSpellDataId = fields[63].GetUInt32(); + creatureTemplate.VehicleId = fields[64].GetUInt32(); + creatureTemplate.mingold = fields[65].GetUInt32(); + creatureTemplate.maxgold = fields[66].GetUInt32(); + creatureTemplate.AIName = fields[67].GetString(); + creatureTemplate.MovementType = uint32(fields[68].GetUInt8()); + creatureTemplate.InhabitType = uint32(fields[69].GetUInt8()); + creatureTemplate.HoverHeight = fields[70].GetFloat(); + creatureTemplate.ModHealth = fields[71].GetFloat(); + creatureTemplate.ModMana = fields[72].GetFloat(); + creatureTemplate.ModManaExtra = fields[73].GetFloat(); + creatureTemplate.ModArmor = fields[74].GetFloat(); + creatureTemplate.RacialLeader = fields[75].GetBool(); for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - creatureTemplate.questItems[i] = fields[75 + i].GetUInt32(); + creatureTemplate.questItems[i] = fields[76 + i].GetUInt32(); - creatureTemplate.movementId = fields[81].GetUInt32(); - creatureTemplate.RegenHealth = fields[82].GetBool(); - creatureTemplate.MechanicImmuneMask = fields[83].GetUInt32(); - creatureTemplate.flags_extra = fields[84].GetUInt32(); - creatureTemplate.ScriptID = GetScriptId(fields[85].GetCString()); + creatureTemplate.movementId = fields[82].GetUInt32(); + creatureTemplate.RegenHealth = fields[83].GetBool(); + creatureTemplate.MechanicImmuneMask = fields[84].GetUInt32(); + creatureTemplate.flags_extra = fields[85].GetUInt32(); + creatureTemplate.ScriptID = GetScriptId(fields[86].GetCString()); ++count; } @@ -1627,8 +1638,8 @@ void ObjectMgr::LoadCreatures() // 0 1 2 3 4 5 6 7 8 9 10 QueryResult result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, " - // 11 12 13 14 15 16 17 18 19 20 21 - "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags " + // 11 12 13 14 15 16 17 18 19 20 21 22 23 + "currentwaypoint, curhealth, curmana, MovementType, spawnMask, phaseMask, eventEntry, pool_entry, creature.npcflag, creature.unit_flags, creature.dynamicflags, creature.phaseid, creature.phasegroup " "FROM creature " "LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid " "LEFT OUTER JOIN pool_creature ON creature.guid = pool_creature.guid"); @@ -1685,6 +1696,8 @@ void ObjectMgr::LoadCreatures() data.npcflag = fields[19].GetUInt32(); data.unit_flags = fields[20].GetUInt32(); data.dynamicflags = fields[21].GetUInt32(); + data.phaseid = fields[22].GetUInt32(); + data.phaseGroup = fields[23].GetUInt32(); MapEntry const* mapEntry = sMapStore.LookupEntry(data.mapid); if (!mapEntry) @@ -1754,6 +1767,12 @@ void ObjectMgr::LoadCreatures() data.phaseMask = 1; } + if (data.phaseGroup && data.phaseid) + { + TC_LOG_ERROR("sql.sql", "Table `creature` have creature (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id); + data.phaseGroup = 0; + } + // Add to grid if not managed by the game event or pool system if (gameEvent == 0 && PoolId == 0) AddCreatureToGrid(guid, &data); @@ -1937,8 +1956,8 @@ void ObjectMgr::LoadGameobjects() // 0 1 2 3 4 5 6 QueryResult result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation, " - // 7 8 9 10 11 12 13 14 15 16 17 - "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry " + // 7 8 9 10 11 12 13 14 15 16 17 18 19 + "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, eventEntry, pool_entry, phaseid, phasegroup " "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid " "LEFT OUTER JOIN pool_gameobject ON gameobject.guid = pool_gameobject.guid"); @@ -2035,6 +2054,14 @@ void ObjectMgr::LoadGameobjects() data.phaseMask = fields[15].GetUInt32(); int16 gameEvent = fields[16].GetInt8(); uint32 PoolId = fields[17].GetUInt32(); + data.phaseid = fields[18].GetUInt32(); + data.phaseGroup = fields[19].GetUInt32(); + + if (data.phaseGroup && data.phaseid) + { + TC_LOG_ERROR("sql.sql", "Table `gameobject` have gameobject (GUID: %u Entry: %u) with both `phaseid` and `phasegroup` set, `phasegroup` set to 0", guid, data.id); + data.phaseGroup = 0; + } if (data.rotation2 < -1.0f || data.rotation2 > 1.0f) { @@ -9149,8 +9176,8 @@ void ObjectMgr::LoadPhaseDefinitions() uint32 oldMSTime = getMSTime(); - // 0 1 2 3 4 5 - QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phasemask, phaseId, terrainswapmap, flags FROM `phase_definitions` ORDER BY `entry` ASC"); + // 0 1 2 3 + QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phaseId, phaseGroup FROM `phase_definitions` ORDER BY `entry` ASC"); if (!result) { @@ -9168,18 +9195,14 @@ void ObjectMgr::LoadPhaseDefinitions() PhaseDefinition.zoneId = fields[0].GetUInt32(); PhaseDefinition.entry = fields[1].GetUInt32(); - PhaseDefinition.phasemask = fields[2].GetUInt32(); - PhaseDefinition.phaseId = fields[3].GetUInt32(); - PhaseDefinition.terrainswapmap = fields[4].GetUInt32(); - PhaseDefinition.flags = fields[5].GetUInt32(); + PhaseDefinition.phaseId = fields[2].GetUInt32(); + PhaseDefinition.phaseGroup = fields[3].GetUInt32(); - // Checks - if ((PhaseDefinition.flags & PHASE_FLAG_OVERWRITE_EXISTING) && (PhaseDefinition.flags & PHASE_FLAG_NEGATE_PHASE)) + if (PhaseDefinition.phaseGroup && PhaseDefinition.phaseId) { - TC_LOG_ERROR("sql.sql", "Flags defined in phase_definitions in zoneId %d and entry %u does contain PHASE_FLAG_OVERWRITE_EXISTING and PHASE_FLAG_NEGATE_PHASE. Setting flags to PHASE_FLAG_OVERWRITE_EXISTING", PhaseDefinition.zoneId, PhaseDefinition.entry); - PhaseDefinition.flags &= ~PHASE_FLAG_NEGATE_PHASE; + TC_LOG_ERROR("sql.sql", "Phase definition for zone %u (Entry: %u) has phaseGroup and phaseId set, phaseGroup set to 0", PhaseDefinition.zoneId, PhaseDefinition.entry); + PhaseDefinition.phaseGroup = 0; } - _PhaseDefinitionStore[PhaseDefinition.zoneId].push_back(PhaseDefinition); ++count; @@ -9189,18 +9212,18 @@ void ObjectMgr::LoadPhaseDefinitions() TC_LOG_INFO("server.loading", ">> Loaded %u phasing definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } -void ObjectMgr::LoadSpellPhaseInfo() +void ObjectMgr::LoadPhaseInfo() { - _SpellPhaseStore.clear(); + _PhaseInfoStore.clear(); uint32 oldMSTime = getMSTime(); - // 0 1 2 - QueryResult result = WorldDatabase.Query("SELECT id, phasemask, terrainswapmap FROM `spell_phase`"); + // 0 1 2 + QueryResult result = WorldDatabase.Query("SELECT id, worldmapareaswap, terrainswapmap FROM `phase_info`"); if (!result) { - TC_LOG_INFO("server.loading", ">> Loaded 0 spell dbc infos. DB table `spell_phase` is empty."); + TC_LOG_INFO("server.loading", ">> Loaded 0 phase infos. DB table `phase_info` is empty."); return; } @@ -9209,31 +9232,25 @@ void ObjectMgr::LoadSpellPhaseInfo() { Field* fields = result->Fetch(); - SpellPhaseInfo spellPhaseInfo; - spellPhaseInfo.spellId = fields[0].GetUInt32(); - - SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellPhaseInfo.spellId); - if (!spell) - { - TC_LOG_ERROR("sql.sql", "Spell %u defined in `spell_phase` does not exists, skipped.", spellPhaseInfo.spellId); - continue; - } + PhaseInfo phaseInfo; + phaseInfo.phaseId = fields[0].GetUInt32(); - if (!spell->HasAura(SPELL_AURA_PHASE)) + PhaseEntry const* phase = sPhaseStore.LookupEntry(phaseInfo.phaseId); + if (!phase) { - TC_LOG_ERROR("sql.sql", "Spell %u defined in `spell_phase` does not have aura effect type SPELL_AURA_PHASE, useless value.", spellPhaseInfo.spellId); + TC_LOG_ERROR("sql.sql", "Phase %u defined in `phase_info` does not exists, skipped.", phaseInfo.phaseId); continue; } - spellPhaseInfo.phasemask = fields[1].GetUInt32(); - spellPhaseInfo.terrainswapmap = fields[2].GetUInt32(); + phaseInfo.worldMapAreaSwap = fields[1].GetUInt32(); + phaseInfo.terrainSwapMap = fields[2].GetUInt32(); - _SpellPhaseStore[spellPhaseInfo.spellId] = spellPhaseInfo; + _PhaseInfoStore[phaseInfo.phaseId] = phaseInfo; ++count; } while (result->NextRow()); - TC_LOG_INFO("server.loading", ">> Loaded %u spell dbc infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); + TC_LOG_INFO("server.loading", ">> Loaded %u phase infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime)); } GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry) diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index a5894ed1805..62a770f06a8 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -42,11 +42,9 @@ #include <limits> #include "ConditionMgr.h" #include <functional> -#include "PhaseMgr.h" #include "DB2Stores.h" class Item; -class PhaseMgr; struct AccessRequirement; struct PlayerInfo; struct PlayerLevelInfo; @@ -132,6 +130,34 @@ typedef std::map<uint32, PageText> PageTextContainer; // Benchmarked: Faster than std::map (insert/find) typedef std::unordered_map<uint16, InstanceTemplate> InstanceTemplateContainer; +// Phasing (visibility) +enum PhasingFlags +{ + PHASE_FLAG_OVERWRITE_EXISTING = 0x01, // don't stack with existing phases, overwrites existing phases + PHASE_FLAG_NO_MORE_PHASES = 0x02, // stop calculating phases after this phase was applied (no more phases will be applied) + PHASE_FLAG_NEGATE_PHASE = 0x04 // negate instead to add the phasemask +}; + +struct PhaseInfo +{ + uint32 phaseId; + uint32 worldMapAreaSwap; + uint32 terrainSwapMap; +}; + +typedef std::unordered_map<uint32, PhaseInfo> PhaseInfoContainer; + +struct PhaseDefinition +{ + uint32 zoneId; + uint32 entry; + uint32 phaseId; + uint32 phaseGroup; +}; + +typedef std::list<PhaseDefinition> PhaseDefinitionContainer; +typedef std::unordered_map<uint32 /*zoneId*/, PhaseDefinitionContainer> PhaseDefinitionStore; + struct GameTele { float position_x; @@ -1018,10 +1044,7 @@ class ObjectMgr void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel); void LoadPhaseDefinitions(); - void LoadSpellPhaseInfo(); - - PhaseDefinitionStore const* GetPhaseDefinitionStore() { return &_PhaseDefinitionStore; } - SpellPhaseStore const* GetSpellPhaseStore() { return &_SpellPhaseStore; } + void LoadPhaseInfo(); std::string GeneratePetName(uint32 entry); uint32 GetBaseXP(uint8 level); @@ -1277,6 +1300,8 @@ class ObjectMgr return _gossipMenuItemsStore.equal_range(uiMenuId); } + PhaseInfo const* GetPhaseInfo(uint32 phase) { return _PhaseInfoStore.find(phase) != _PhaseInfoStore.end() ? &_PhaseInfoStore[phase] : nullptr; } + // for wintergrasp only GraveYardContainer GraveYardStore; @@ -1389,7 +1414,7 @@ class ObjectMgr InstanceTemplateContainer _instanceTemplateStore; PhaseDefinitionStore _PhaseDefinitionStore; - SpellPhaseStore _SpellPhaseStore; + PhaseInfoContainer _PhaseInfoStore; private: void LoadScripts(ScriptsType type); diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.cpp b/src/server/game/Grids/Notifiers/GridNotifiers.cpp index 08b681ae53f..8040728133f 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.cpp +++ b/src/server/game/Grids/Notifiers/GridNotifiers.cpp @@ -263,7 +263,7 @@ void MessageDistDeliverer::Visit(PlayerMapType &m) for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { Player* target = iter->GetSource(); - if (!target->InSamePhase(i_phaseMask)) + if (!target->IsInPhase(i_source)) continue; if (target->GetExactDist2dSq(i_source) > i_distSq) @@ -288,7 +288,7 @@ void MessageDistDeliverer::Visit(CreatureMapType &m) for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { Creature* target = iter->GetSource(); - if (!target->InSamePhase(i_phaseMask)) + if (!target->IsInPhase(i_source)) continue; if (target->GetExactDist2dSq(i_source) > i_distSq) @@ -310,7 +310,7 @@ void MessageDistDeliverer::Visit(DynamicObjectMapType &m) for (DynamicObjectMapType::iterator iter = m.begin(); iter != m.end(); ++iter) { DynamicObject* target = iter->GetSource(); - if (!target->InSamePhase(i_phaseMask)) + if (!target->IsInPhase(i_source)) continue; if (target->GetExactDist2dSq(i_source) > i_distSq) diff --git a/src/server/game/Grids/Notifiers/GridNotifiers.h b/src/server/game/Grids/Notifiers/GridNotifiers.h index e229c782f49..e82533b1cb2 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiers.h +++ b/src/server/game/Grids/Notifiers/GridNotifiers.h @@ -126,12 +126,11 @@ namespace Trinity { WorldObject* i_source; WorldPacket* i_message; - uint32 i_phaseMask; float i_distSq; uint32 team; Player const* skipped_receiver; MessageDistDeliverer(WorldObject* src, WorldPacket* msg, float dist, bool own_team_only = false, Player const* skipped = NULL) - : i_source(src), i_message(msg), i_phaseMask(src->GetPhaseMask()), i_distSq(dist * dist) + : i_source(src), i_message(msg), i_distSq(dist * dist) , team(0) , skipped_receiver(skipped) { @@ -176,12 +175,12 @@ namespace Trinity struct WorldObjectSearcher { uint32 i_mapTypeMask; - uint32 i_phaseMask; - WorldObject* &i_object; + WorldObject*& i_object; + WorldObject const* _searcher; Check &i_check; WorldObjectSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) - : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_object(result), i_check(check) { } void Visit(GameObjectMapType &m); void Visit(PlayerMapType &m); @@ -197,12 +196,12 @@ namespace Trinity struct WorldObjectLastSearcher { uint32 i_mapTypeMask; - uint32 i_phaseMask; WorldObject* &i_object; + WorldObject const* _searcher; Check &i_check; WorldObjectLastSearcher(WorldObject const* searcher, WorldObject* & result, Check& check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) - : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_object(result), i_check(check) { } void Visit(GameObjectMapType &m); void Visit(PlayerMapType &m); @@ -218,12 +217,12 @@ namespace Trinity struct WorldObjectListSearcher { uint32 i_mapTypeMask; - uint32 i_phaseMask; + WorldObject const* _searcher; std::list<WorldObject*> &i_objects; Check& i_check; WorldObjectListSearcher(WorldObject const* searcher, std::list<WorldObject*> &objects, Check & check, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) - : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } + : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_objects(objects), i_check(check) { } void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); @@ -239,18 +238,18 @@ namespace Trinity struct WorldObjectWorker { uint32 i_mapTypeMask; - uint32 i_phaseMask; + WorldObject const* _searcher; Do const& i_do; WorldObjectWorker(WorldObject const* searcher, Do const& _do, uint32 mapTypeMask = GRID_MAP_TYPE_MASK_ALL) - : i_mapTypeMask(mapTypeMask), i_phaseMask(searcher->GetPhaseMask()), i_do(_do) { } + : i_mapTypeMask(mapTypeMask), _searcher(searcher), i_do(_do) { } void Visit(GameObjectMapType &m) { if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_GAMEOBJECT)) return; for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -259,7 +258,7 @@ namespace Trinity if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_PLAYER)) return; for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } void Visit(CreatureMapType &m) @@ -267,7 +266,7 @@ namespace Trinity if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CREATURE)) return; for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -276,7 +275,7 @@ namespace Trinity if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_CORPSE)) return; for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -285,7 +284,7 @@ namespace Trinity if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_DYNAMICOBJECT)) return; for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -294,7 +293,7 @@ namespace Trinity if (!(i_mapTypeMask & GRID_MAP_TYPE_MASK_AREATRIGGER)) return; for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -306,12 +305,12 @@ namespace Trinity template<class Check> struct GameObjectSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; GameObject* &i_object; Check &i_check; GameObjectSearcher(WorldObject const* searcher, GameObject* & result, Check& check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(GameObjectMapType &m); @@ -322,12 +321,12 @@ namespace Trinity template<class Check> struct GameObjectLastSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; GameObject* &i_object; Check& i_check; GameObjectLastSearcher(WorldObject const* searcher, GameObject* & result, Check& check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(GameObjectMapType &m); @@ -337,12 +336,12 @@ namespace Trinity template<class Check> struct GameObjectListSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; std::list<GameObject*> &i_objects; Check& i_check; GameObjectListSearcher(WorldObject const* searcher, std::list<GameObject*> &objects, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } + : _searcher(searcher), i_objects(objects), i_check(check) { } void Visit(GameObjectMapType &m); @@ -353,12 +352,12 @@ namespace Trinity struct GameObjectWorker { GameObjectWorker(WorldObject const* searcher, Functor& func) - : _func(func), _phaseMask(searcher->GetPhaseMask()) { } + : _func(func), _searcher(searcher) { } void Visit(GameObjectMapType& m) { for (GameObjectMapType::iterator itr = m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) _func(itr->GetSource()); } @@ -366,7 +365,7 @@ namespace Trinity private: Functor& _func; - uint32 _phaseMask; + WorldObject const* _searcher; }; // Unit searchers @@ -375,12 +374,12 @@ namespace Trinity template<class Check> struct UnitSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; Unit* &i_object; Check & i_check; UnitSearcher(WorldObject const* searcher, Unit* & result, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(CreatureMapType &m); void Visit(PlayerMapType &m); @@ -392,12 +391,12 @@ namespace Trinity template<class Check> struct UnitLastSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; Unit* &i_object; Check & i_check; UnitLastSearcher(WorldObject const* searcher, Unit* & result, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(CreatureMapType &m); void Visit(PlayerMapType &m); @@ -409,12 +408,12 @@ namespace Trinity template<class Check> struct UnitListSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; std::list<Unit*> &i_objects; Check& i_check; UnitListSearcher(WorldObject const* searcher, std::list<Unit*> &objects, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } + : _searcher(searcher), i_objects(objects), i_check(check) { } void Visit(PlayerMapType &m); void Visit(CreatureMapType &m); @@ -427,12 +426,12 @@ namespace Trinity template<class Check> struct CreatureSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; Creature* &i_object; Check & i_check; CreatureSearcher(WorldObject const* searcher, Creature* & result, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(CreatureMapType &m); @@ -443,12 +442,12 @@ namespace Trinity template<class Check> struct CreatureLastSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; Creature* &i_object; Check & i_check; CreatureLastSearcher(WorldObject const* searcher, Creature* & result, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(CreatureMapType &m); @@ -458,12 +457,12 @@ namespace Trinity template<class Check> struct CreatureListSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; std::list<Creature*> &i_objects; Check& i_check; CreatureListSearcher(WorldObject const* searcher, std::list<Creature*> &objects, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } + : _searcher(searcher), i_objects(objects), i_check(check) { } void Visit(CreatureMapType &m); @@ -473,16 +472,16 @@ namespace Trinity template<class Do> struct CreatureWorker { - uint32 i_phaseMask; + WorldObject const* _searcher; Do& i_do; CreatureWorker(WorldObject const* searcher, Do& _do) - : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) { } + : _searcher(searcher), i_do(_do) { } void Visit(CreatureMapType &m) { for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -494,12 +493,12 @@ namespace Trinity template<class Check> struct PlayerSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; Player* &i_object; Check & i_check; PlayerSearcher(WorldObject const* searcher, Player* & result, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) { } + : _searcher(searcher), i_object(result), i_check(check) { } void Visit(PlayerMapType &m); @@ -509,12 +508,12 @@ namespace Trinity template<class Check> struct PlayerListSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; std::list<Player*> &i_objects; Check& i_check; PlayerListSearcher(WorldObject const* searcher, std::list<Player*> &objects, Check & check) - : i_phaseMask(searcher->GetPhaseMask()), i_objects(objects), i_check(check) { } + : _searcher(searcher), i_objects(objects), i_check(check) { } void Visit(PlayerMapType &m); @@ -524,11 +523,11 @@ namespace Trinity template<class Check> struct PlayerLastSearcher { - uint32 i_phaseMask; + WorldObject const* _searcher; Player* &i_object; Check& i_check; - PlayerLastSearcher(WorldObject const* searcher, Player*& result, Check& check) : i_phaseMask(searcher->GetPhaseMask()), i_object(result), i_check(check) + PlayerLastSearcher(WorldObject const* searcher, Player*& result, Check& check) : _searcher(searcher), i_object(result), i_check(check) { } @@ -540,16 +539,16 @@ namespace Trinity template<class Do> struct PlayerWorker { - uint32 i_phaseMask; + WorldObject const* _searcher; Do& i_do; PlayerWorker(WorldObject const* searcher, Do& _do) - : i_phaseMask(searcher->GetPhaseMask()), i_do(_do) { } + : _searcher(searcher), i_do(_do) { } void Visit(PlayerMapType &m) { for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) i_do(itr->GetSource()); } @@ -569,7 +568,7 @@ namespace Trinity void Visit(PlayerMapType &m) { for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_searcher) && itr->GetSource()->IsWithinDist(i_searcher, i_dist)) + if (itr->GetSource()->IsInPhase(i_searcher) && itr->GetSource()->IsWithinDist(i_searcher, i_dist)) i_do(itr->GetSource()); } @@ -1344,7 +1343,7 @@ namespace Trinity AllWorldObjectsInRange(const WorldObject* object, float maxRange) : m_pObject(object), m_fRange(maxRange) { } bool operator() (WorldObject* go) { - return m_pObject->IsWithinDist(go, m_fRange, false) && m_pObject->InSamePhase(go); + return m_pObject->IsWithinDist(go, m_fRange, false) && m_pObject->IsInPhase(go); } private: const WorldObject* m_pObject; diff --git a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h index febc42af25a..e73f18abf90 100644 --- a/src/server/game/Grids/Notifiers/GridNotifiersImpl.h +++ b/src/server/game/Grids/Notifiers/GridNotifiersImpl.h @@ -54,7 +54,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(GameObjectMapType &m) for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -77,7 +77,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(PlayerMapType &m) for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -100,7 +100,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CreatureMapType &m) for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -123,7 +123,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(CorpseMapType &m) for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -146,7 +146,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(DynamicObjectMapType &m) for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -169,7 +169,7 @@ void Trinity::WorldObjectSearcher<Check>::Visit(AreaTriggerMapType &m) for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -188,7 +188,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(GameObjectMapType &m) for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -204,7 +204,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(PlayerMapType &m) for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -220,7 +220,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(CreatureMapType &m) for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -236,7 +236,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(CorpseMapType &m) for (CorpseMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -252,7 +252,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(DynamicObjectMapType &m) for (DynamicObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -268,7 +268,7 @@ void Trinity::WorldObjectLastSearcher<Check>::Visit(AreaTriggerMapType &m) for (AreaTriggerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -353,7 +353,7 @@ void Trinity::GameObjectSearcher<Check>::Visit(GameObjectMapType &m) for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -369,7 +369,7 @@ void Trinity::GameObjectLastSearcher<Check>::Visit(GameObjectMapType &m) { for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -381,7 +381,7 @@ template<class Check> void Trinity::GameObjectListSearcher<Check>::Visit(GameObjectMapType &m) { for (GameObjectMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) if (i_check(itr->GetSource())) i_objects.push_back(itr->GetSource()); } @@ -397,7 +397,7 @@ void Trinity::UnitSearcher<Check>::Visit(CreatureMapType &m) for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -417,7 +417,7 @@ void Trinity::UnitSearcher<Check>::Visit(PlayerMapType &m) for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -433,7 +433,7 @@ void Trinity::UnitLastSearcher<Check>::Visit(CreatureMapType &m) { for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -446,7 +446,7 @@ void Trinity::UnitLastSearcher<Check>::Visit(PlayerMapType &m) { for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -458,7 +458,7 @@ template<class Check> void Trinity::UnitListSearcher<Check>::Visit(PlayerMapType &m) { for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) if (i_check(itr->GetSource())) i_objects.push_back(itr->GetSource()); } @@ -467,7 +467,7 @@ template<class Check> void Trinity::UnitListSearcher<Check>::Visit(CreatureMapType &m) { for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) if (i_check(itr->GetSource())) i_objects.push_back(itr->GetSource()); } @@ -483,7 +483,7 @@ void Trinity::CreatureSearcher<Check>::Visit(CreatureMapType &m) for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -499,7 +499,7 @@ void Trinity::CreatureLastSearcher<Check>::Visit(CreatureMapType &m) { for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -511,7 +511,7 @@ template<class Check> void Trinity::CreatureListSearcher<Check>::Visit(CreatureMapType &m) { for (CreatureMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) if (i_check(itr->GetSource())) i_objects.push_back(itr->GetSource()); } @@ -520,7 +520,7 @@ template<class Check> void Trinity::PlayerListSearcher<Check>::Visit(PlayerMapType &m) { for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) - if (itr->GetSource()->InSamePhase(i_phaseMask)) + if (itr->GetSource()->IsInPhase(_searcher)) if (i_check(itr->GetSource())) i_objects.push_back(itr->GetSource()); } @@ -534,7 +534,7 @@ void Trinity::PlayerSearcher<Check>::Visit(PlayerMapType &m) for (PlayerMapType::iterator itr=m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) @@ -550,7 +550,7 @@ void Trinity::PlayerLastSearcher<Check>::Visit(PlayerMapType& m) { for (PlayerMapType::iterator itr = m.begin(); itr != m.end(); ++itr) { - if (!itr->GetSource()->InSamePhase(i_phaseMask)) + if (!itr->GetSource()->IsInPhase(_searcher)) continue; if (i_check(itr->GetSource())) diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index f0ddd714657..ce92f9f1b53 100644 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1605,7 +1605,7 @@ void Group::UpdatePlayerOutOfRange(Player* player) for (GroupReference* itr = GetFirstMember(); itr != NULL; itr = itr->next()) { member = itr->GetSource(); - if (member && !member->IsWithinDist(player, member->GetSightRange(), false)) + if (member && member != player && (!member->IsInMap(player) || !member->IsWithinDist(player, member->GetSightRange(), false))) member->GetSession()->SendPacket(&data); } } diff --git a/src/server/game/Guilds/Guild.cpp b/src/server/game/Guilds/Guild.cpp index 5fb10feccf0..2c6e2253494 100644 --- a/src/server/game/Guilds/Guild.cpp +++ b/src/server/game/Guilds/Guild.cpp @@ -99,7 +99,10 @@ inline uint32 _GetGuildBankTabPrice(uint8 tabId) void Guild::SendCommandResult(WorldSession* session, GuildCommandType type, GuildCommandError errCode, std::string const& param) { - WorldPacket data(SMSG_GUILD_COMMAND_RESULT, 8 + param.size() + 1); + // Note: SMSG_GUILD_COMMAND_RESULT and SMSG_GUILD_COMMAND_RESULT_2 do exactly the same in the client, they just have different structures. + // There's no particular reason why we use SMSG_GUILD_COMMAND_RESULT_2, this one is processed inmediately as it is read from the client. + // SMSG_GUILD_COMMAND_RESULT is a JAM opcode + WorldPacket data(SMSG_GUILD_COMMAND_RESULT_2, 8 + param.size() + 1); data << uint32(type); data << param; data << uint32(errCode); diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp index 5345113d106..86f978f1848 100644 --- a/src/server/game/Handlers/CharacterHandler.cpp +++ b/src/server/game/Handlers/CharacterHandler.cpp @@ -1092,7 +1092,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) SendNotification(LANG_RESET_TALENTS); } - if (pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST)) + bool firstLogin = pCurrChar->HasAtLoginFlag(AT_LOGIN_FIRST); + if (firstLogin) { pCurrChar->RemoveAtLoginFlag(AT_LOGIN_FIRST); @@ -1140,7 +1141,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder* holder) // Handle Login-Achievements (should be handled after loading) _player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_ON_LOGIN, 1); - sScriptMgr->OnPlayerLogin(pCurrChar); + sScriptMgr->OnPlayerLogin(pCurrChar, firstLogin); + delete holder; } diff --git a/src/server/game/Handlers/GroupHandler.cpp b/src/server/game/Handlers/GroupHandler.cpp index 971daa550c0..8565da90f40 100644 --- a/src/server/game/Handlers/GroupHandler.cpp +++ b/src/server/game/Handlers/GroupHandler.cpp @@ -32,6 +32,7 @@ #include "World.h" #include "WorldPacket.h" #include "WorldSession.h" +#include "SpellAuraEffects.h" class Aura; @@ -944,8 +945,7 @@ void WorldSession::BuildPartyMemberStatsChangedPacket(Player* player, WorldPacke if (mask == GROUP_UPDATE_FLAG_NONE) return; - std::set<uint32> phases; - player->GetPhaseMgr().GetActivePhases(phases); + std::set<uint32> const& phases = player->GetPhases(); if (mask & GROUP_UPDATE_FLAG_POWER_TYPE) // if update power type, update current/max power also mask |= (GROUP_UPDATE_FLAG_CUR_POWER | GROUP_UPDATE_FLAG_MAX_POWER); @@ -1197,8 +1197,7 @@ void WorldSession::HandleRequestPartyMemberStatsOpcode(WorldPacket& recvData) Pet* pet = player->GetPet(); Powers powerType = player->getPowerType(); - std::set<uint32> phases; - player->GetPhaseMgr().GetActivePhases(phases); + std::set<uint32> const& phases = player->GetPhases(); WorldPacket data(SMSG_PARTY_MEMBER_STATS_FULL, 4+2+2+2+1+2*6+8+1+8); data << uint8(0); // only for SMSG_PARTY_MEMBER_STATS_FULL, probably arena/bg related diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp index e65643e7ffe..536d6a7dc95 100644 --- a/src/server/game/Handlers/MailHandler.cpp +++ b/src/server/game/Handlers/MailHandler.cpp @@ -28,6 +28,7 @@ #include "DBCStores.h" #include "Item.h" #include "AccountMgr.h" +#include "BattlenetAccountMgr.h" #include "GuildMgr.h" bool WorldSession::CanOpenMailBox(uint64 guid) @@ -192,6 +193,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) uint8 mailsCount = 0; //do not allow to send to one player more than 100 mails uint8 receiverLevel = 0; uint32 receiverAccountId = 0; + uint32 receiverBnetAccountId = 0; if (receiver) { @@ -199,6 +201,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) mailsCount = receiver->GetMailSize(); receiverLevel = receiver->getLevel(); receiverAccountId = receiver->GetSession()->GetAccountId(); + receiverBnetAccountId = receiver->GetSession()->GetBattlenetAccountId(); } else { @@ -225,6 +228,7 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) } receiverAccountId = sObjectMgr->GetPlayerAccountIdByGUID(receiverGuid); + receiverBnetAccountId = Battlenet::AccountMgr::GetIdByGameAccount(receiverAccountId); } // do not allow to have more than 100 mails in mailbox.. mails count is in opcode uint8!!! - so max can be 255.. @@ -288,8 +292,11 @@ void WorldSession::HandleSendMail(WorldPacket& recvData) if (item->IsBoundAccountWide() && item->IsSoulBound() && player->GetSession()->GetAccountId() != receiverAccountId) { - player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT); - return; + if (!item->IsBattlenetAccountBound() || !player->GetSession()->GetBattlenetAccountId() || player->GetSession()->GetBattlenetAccountId() != receiverBnetAccountId) + { + player->SendMailResult(0, MAIL_SEND, MAIL_ERR_EQUIP_ERROR, EQUIP_ERR_NOT_SAME_ACCOUNT); + return; + } } if (item->GetTemplate()->Flags & ITEM_PROTO_FLAG_CONJURED || item->GetUInt32Value(ITEM_FIELD_DURATION)) diff --git a/src/server/game/Handlers/MiscHandler.cpp b/src/server/game/Handlers/MiscHandler.cpp index fe731121f1c..7a66d747342 100644 --- a/src/server/game/Handlers/MiscHandler.cpp +++ b/src/server/game/Handlers/MiscHandler.cpp @@ -1749,7 +1749,7 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/) SendAccountDataTimes(GLOBAL_CACHE_MASK); } -void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps) +void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps) { ObjectGuid guid = _player->GetGUID(); @@ -1766,9 +1766,9 @@ void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set< data.WriteByteSeq(guid[7]); data.WriteByteSeq(guid[4]); - data << uint32(0); - //for (uint8 i = 0; i < worldMapAreaCount; ++i) - // data << uint16(0); // WorldMapArea.dbc id (controls map display) + data << uint32(worldMapAreaSwaps.size()); + for (auto mapSwap : worldMapAreaSwaps) + data << uint16(mapSwap); // WorldMapArea.dbc id (controls map display) data.WriteByteSeq(guid[1]); diff --git a/src/server/game/Handlers/QueryHandler.cpp b/src/server/game/Handlers/QueryHandler.cpp index ea30bcbab9b..95c130e59dd 100644 --- a/src/server/game/Handlers/QueryHandler.cpp +++ b/src/server/game/Handlers/QueryHandler.cpp @@ -96,62 +96,75 @@ void WorldSession::HandleCreatureQueryOpcode(WorldPacket& recvData) uint64 guid; recvData >> guid; - CreatureTemplate const* ci = sObjectMgr->GetCreatureTemplate(entry); - if (ci) + CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry); + if (creatureInfo) { + std::string Name, FemaleName, SubName; + Name = creatureInfo->Name; + FemaleName = creatureInfo->FemaleName; + SubName = creatureInfo->SubName; - std::string Name, SubName; - Name = ci->Name; - SubName = ci->SubName; - - int loc_idx = GetSessionDbLocaleIndex(); - if (loc_idx >= 0) + LocaleConstant locale = GetSessionDbLocaleIndex(); + if (locale >= 0) { - if (CreatureLocale const* cl = sObjectMgr->GetCreatureLocale(entry)) + if (CreatureLocale const* creatureLocale = sObjectMgr->GetCreatureLocale(entry)) { - ObjectMgr::GetLocaleString(cl->Name, loc_idx, Name); - ObjectMgr::GetLocaleString(cl->SubName, loc_idx, SubName); + ObjectMgr::GetLocaleString(creatureLocale->Name, locale, Name); + ObjectMgr::GetLocaleString(creatureLocale->FemaleName, locale, FemaleName); + ObjectMgr::GetLocaleString(creatureLocale->SubName, locale, SubName); } } - TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", ci->Name.c_str(), entry); - // guess size - WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); - data << uint32(entry); // creature entry - data << Name; - for (int i = 0; i < 7; i++) - data << uint8(0); // name2, ..., name8 - - data << SubName; - data << ci->IconName; // "Directions" for guard, string for Icons 2.3.0 - data << uint32(ci->type_flags); // flags - data << uint32(ci->type_flags2); // unknown meaning - data << uint32(ci->type); // CreatureType.dbc - data << uint32(ci->family); // CreatureFamily.dbc - data << uint32(ci->rank); // Creature Rank (elite, boss, etc) - data << uint32(ci->KillCredit[0]); // new in 3.1, kill credit - data << uint32(ci->KillCredit[1]); // new in 3.1, kill credit - data << uint32(ci->Modelid1); // Modelid1 - data << uint32(ci->Modelid2); // Modelid2 - data << uint32(ci->Modelid3); // Modelid3 - data << uint32(ci->Modelid4); // Modelid4 - data << float(ci->ModHealth); // dmg/hp modifier - data << float(ci->ModMana); // dmg/mana modifier - data << uint8(ci->RacialLeader); - for (uint32 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - data << uint32(ci->questItems[i]); // itemId[6], quest drop - data << uint32(ci->movementId); // CreatureMovementInfo.dbc - data << uint32(ci->expansionUnknown); // unknown meaning + TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY '%s' - Entry: %u.", creatureInfo->Name.c_str(), entry); + + WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 100); // guess size + data << uint32(entry); // creature entry + data << Name; // Name + + for (uint8 i = 0; i < 3; i++) + data << uint8(0); // name2, ..., name3 + + data << FemaleName; // FemaleName + + for (uint8 i = 0; i < 3; i++) + data << uint8(0); // name5, ..., name8 + + data << SubName; // SubName + data << creatureInfo->IconName; // "Directions" for guard, string for Icons 2.3.0 + data << uint32(creatureInfo->type_flags); // flags + data << uint32(creatureInfo->type_flags2); // unknown meaning + data << uint32(creatureInfo->type); // CreatureType.dbc + data << uint32(creatureInfo->family); // CreatureFamily.dbc + data << uint32(creatureInfo->rank); // Creature Rank (elite, boss, etc) + data << uint32(creatureInfo->KillCredit[0]); // new in 3.1, kill credit + data << uint32(creatureInfo->KillCredit[1]); // new in 3.1, kill credit + data << uint32(creatureInfo->Modelid1); // Modelid1 + data << uint32(creatureInfo->Modelid2); // Modelid2 + data << uint32(creatureInfo->Modelid3); // Modelid3 + data << uint32(creatureInfo->Modelid4); // Modelid4 + data << float(creatureInfo->ModHealth); // dmg/hp modifier + data << float(creatureInfo->ModMana); // dmg/mana modifier + data << uint8(creatureInfo->RacialLeader); // RacialLeader + + for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) + data << uint32(creatureInfo->questItems[i]); // itemId[6], quest drop + + data << uint32(creatureInfo->movementId); // CreatureMovementInfo.dbc + data << uint32(creatureInfo->expansionUnknown); // unknown meaning + SendPacket(&data); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } else { TC_LOG_DEBUG("network", "WORLD: CMSG_CREATURE_QUERY - NO CREATURE INFO! (GUID: %u, ENTRY: %u)", GUID_LOPART(guid), entry); + WorldPacket data(SMSG_CREATURE_QUERY_RESPONSE, 4); data << uint32(entry | 0x80000000); SendPacket(&data); + TC_LOG_DEBUG("network", "WORLD: Sent SMSG_CREATURE_QUERY_RESPONSE"); } } diff --git a/src/server/game/Instances/InstanceScript.cpp b/src/server/game/Instances/InstanceScript.cpp index 1b6399fb6fd..c8d495baab2 100644 --- a/src/server/game/Instances/InstanceScript.cpp +++ b/src/server/game/Instances/InstanceScript.cpp @@ -469,11 +469,8 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi void InstanceScript::UpdatePhasing() { - PhaseUpdateData phaseUdateData; - phaseUdateData.AddConditionType(CONDITION_INSTANCE_INFO); - Map::PlayerList const& players = instance->GetPlayers(); for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr) if (Player* player = itr->GetSource()) - player->GetPhaseMgr().NotifyConditionChanged(phaseUdateData); + player->UpdatePhasing(); } diff --git a/src/server/game/Maps/Map.cpp b/src/server/game/Maps/Map.cpp index 0203c7e0821..a1ee67fe6e4 100644 --- a/src/server/game/Maps/Map.cpp +++ b/src/server/game/Maps/Map.cpp @@ -2520,7 +2520,7 @@ void Map::SendInitTransports(Player* player) // Hack to send out transports UpdateData transData(player->GetMapId()); for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) - if (*i != player->GetTransport()) + if (*i != player->GetTransport() && player->IsInPhase(*i)) (*i)->BuildCreateUpdateBlockForPlayer(&transData, player); WorldPacket packet; @@ -2541,6 +2541,26 @@ void Map::SendRemoveTransports(Player* player) player->GetSession()->SendPacket(&packet); } +void Map::SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases) +{ + // Hack to send out transports + UpdateData transData(player->GetMapId()); + for (TransportsContainer::const_iterator i = _transports.begin(); i != _transports.end(); ++i) + { + if (*i == player->GetTransport()) + continue; + + if (player->IsInPhase(*i) && !Trinity::Containers::Intersects(previousPhases.begin(), previousPhases.end(), (*i)->GetPhases().begin(), (*i)->GetPhases().end())) + (*i)->BuildCreateUpdateBlockForPlayer(&transData, player); + else if (!player->IsInPhase(*i)) + (*i)->BuildOutOfRangeUpdateBlock(&transData); + } + + WorldPacket packet; + transData.BuildPacket(&packet); + player->GetSession()->SendPacket(&packet); +} + inline void Map::setNGrid(NGridType *grid, uint32 x, uint32 y) { if (x >= MAX_NUMBER_OF_GRIDS || y >= MAX_NUMBER_OF_GRIDS) diff --git a/src/server/game/Maps/Map.h b/src/server/game/Maps/Map.h index c160d7a0f91..3b66fd0fed5 100644 --- a/src/server/game/Maps/Map.h +++ b/src/server/game/Maps/Map.h @@ -510,6 +510,7 @@ class Map : public GridRefManager<NGridType> void SendInitTransports(Player* player); void SendRemoveTransports(Player* player); + void SendUpdateTransportVisibility(Player* player, std::set<uint32> const& previousPhases); void SendZoneDynamicInfo(Player* player); void SetZoneMusic(uint32 zoneId, uint32 musicId); diff --git a/src/server/game/Maps/PhaseMgr.cpp b/src/server/game/Maps/PhaseMgr.cpp deleted file mode 100644 index 13d357702ab..00000000000 --- a/src/server/game/Maps/PhaseMgr.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#include "PhaseMgr.h" -#include "Chat.h" -#include "Group.h" -#include "Language.h" -#include "ObjectMgr.h" -#include "Player.h" - -////////////////////////////////////////////////////////////////// -// Updating - -PhaseMgr::PhaseMgr(Player* _player) : player(_player), phaseData(_player), _UpdateFlags(0) -{ - _PhaseDefinitionStore = sObjectMgr->GetPhaseDefinitionStore(); - _SpellPhaseStore = sObjectMgr->GetSpellPhaseStore(); -} - -void PhaseMgr::Update() -{ - if (IsUpdateInProgress()) - return; - - if (_UpdateFlags & PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED) - { - phaseData.SendPhaseshiftToPlayer(); - player->SetGroupUpdateFlag(GROUP_UPDATE_FLAG_PHASE); - } - - if (_UpdateFlags & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED) - phaseData.SendPhaseMaskToPlayer(); - - _UpdateFlags = 0; -} - -void PhaseMgr::RemoveUpdateFlag(PhaseUpdateFlag updateFlag) -{ - _UpdateFlags &= ~updateFlag; - - if (updateFlag == PHASE_UPDATE_FLAG_ZONE_UPDATE) - { - // Update zone changes - if (phaseData.HasActiveDefinitions()) - { - phaseData.ResetDefinitions(); - _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); - } - - if (_PhaseDefinitionStore->find(player->GetZoneId()) != _PhaseDefinitionStore->end()) - Recalculate(); - } - - Update(); -} - -///////////////////////////////////////////////////////////////// -// Notifier - -void PhaseMgr::NotifyConditionChanged(PhaseUpdateData const& updateData) -{ - if (NeedsPhaseUpdateWithData(updateData)) - { - Recalculate(); - Update(); - } -} - -////////////////////////////////////////////////////////////////// -// Phasing Definitions - -void PhaseMgr::Recalculate() -{ - if (phaseData.HasActiveDefinitions()) - { - phaseData.ResetDefinitions(); - _UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED); - } - - PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); - if (itr != _PhaseDefinitionStore->end()) - { - for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) - { - if (CheckDefinition(&(*phase))) - { - phaseData.AddPhaseDefinition(&(*phase)); - - if (phase->phasemask) - _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - - if (phase->phaseId || phase->terrainswapmap) - _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - - if (phase->IsLastDefinition()) - break; - } - } - } -} - -inline bool PhaseMgr::CheckDefinition(PhaseDefinition const* phaseDefinition) -{ - ConditionList const* conditions = sConditionMgr->GetConditionsForPhaseDefinition(phaseDefinition->zoneId, phaseDefinition->entry); - if (!conditions) - return true; - - ConditionSourceInfo srcInfo(player); - return sConditionMgr->IsObjectMeetToConditions(srcInfo, *conditions); -} - -bool PhaseMgr::NeedsPhaseUpdateWithData(PhaseUpdateData const& updateData) const -{ - PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); - if (itr != _PhaseDefinitionStore->end()) - { - for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) - { - ConditionList const* conditionList = sConditionMgr->GetConditionsForPhaseDefinition(phase->zoneId, phase->entry); - if (!conditionList) - continue; - - for (ConditionList::const_iterator condition = conditionList->begin(); condition != conditionList->end(); ++condition) - if (updateData.IsConditionRelated(*condition)) - return true; - } - } - return false; -} - -////////////////////////////////////////////////////////////////// -// Auras - -void PhaseMgr::RegisterPhasingAuraEffect(AuraEffect const* auraEffect) -{ - std::list<PhaseInfo> phases; - - if (auraEffect->GetAuraType() == SPELL_AURA_PHASE) - { - PhaseInfo phaseInfo; - - if (auraEffect->GetMiscValue()) - { - _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - phaseInfo.phasemask = auraEffect->GetMiscValue(); - } - else - { - SpellPhaseStore::const_iterator itr = _SpellPhaseStore->find(auraEffect->GetId()); - if (itr != _SpellPhaseStore->end()) - { - if (itr->second.phasemask) - { - _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - phaseInfo.phasemask = itr->second.phasemask; - } - - if (itr->second.terrainswapmap) - phaseInfo.terrainswapmap = itr->second.terrainswapmap; - } - } - - phaseInfo.phaseId = auraEffect->GetMiscValueB(); - - if (phaseInfo.NeedsClientSideUpdate()) - _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - - phases.push_back(phaseInfo); - } - else if (auraEffect->GetAuraType() == SPELL_AURA_PHASE_GROUP) - { - uint32 group = auraEffect->GetMiscValueB(); - std::set<uint32> const& groupPhases = GetPhasesForGroup(group); - for (auto itr = groupPhases.begin(); itr != groupPhases.end(); ++itr) - { - PhaseInfo phaseInfo; - phaseInfo.phaseId = auraEffect->GetMiscValueB(); - if (phaseInfo.NeedsClientSideUpdate()) - _UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - phases.push_back(phaseInfo); - } - } - - for (auto itr = phases.begin(); itr != phases.end(); ++itr) - phaseData.AddAuraInfo(auraEffect->GetId(), *itr); - - Update(); -} - -void PhaseMgr::UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect) -{ - _UpdateFlags |= phaseData.RemoveAuraInfo(auraEffect->GetId()); - - Update(); -} - -////////////////////////////////////////////////////////////////// -// Commands - -void PhaseMgr::SendDebugReportToPlayer(Player* const debugger) -{ - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName().c_str(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags); - - PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId()); - if (itr == _PhaseDefinitionStore->end()) - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId()); - else - { - for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase) - { - if (CheckDefinition(&(*phase))) - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask); - else - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId); - - if (phase->IsLastDefinition()) - { - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId); - break; - } - } - } - - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask); - - ChatHandler(debugger->GetSession()).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask()); -} - -void PhaseMgr::SetCustomPhase(uint32 phaseMask) -{ - phaseData._CustomPhasemask = phaseMask; - - _UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - - Update(); -} - -////////////////////////////////////////////////////////////////// -// Phase Data - -uint32 PhaseData::GetCurrentPhasemask() const -{ - if (player->IsGameMaster()) - return uint32(PHASEMASK_ANYWHERE); - - if (_CustomPhasemask) - return _CustomPhasemask; - - return GetPhaseMaskForSpawn(); -} - -inline uint32 PhaseData::GetPhaseMaskForSpawn() const -{ - uint32 const phase = (_PhasemaskThroughDefinitions | _PhasemaskThroughAuras); - return (phase ? phase : PHASEMASK_NORMAL); -} - -void PhaseData::SendPhaseMaskToPlayer() -{ - // Server side update - uint32 const phasemask = GetCurrentPhasemask(); - if (player->GetPhaseMask() == phasemask) - return; - - player->SetPhaseMask(phasemask, false); - - if (player->IsVisible()) - player->UpdateObjectVisibility(); -} - -void PhaseData::SendPhaseshiftToPlayer() -{ - // Client side update - std::set<uint32> phaseIds; - std::set<uint32> terrainswaps; - - for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) - { - for (auto ph = itr->second.begin(); ph != itr->second.end(); ++ph) - { - if (ph->terrainswapmap) - terrainswaps.insert(ph->terrainswapmap); - - if (ph->phaseId) - phaseIds.insert(ph->phaseId); - } - } - - // Phase Definitions - for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr) - { - if ((*itr)->phaseId) - phaseIds.insert((*itr)->phaseId); - - if ((*itr)->terrainswapmap) - terrainswaps.insert((*itr)->terrainswapmap); - } - - player->GetSession()->SendSetPhaseShift(phaseIds, terrainswaps); -} - -void PhaseData::GetActivePhases(std::set<uint32>& phases) const -{ - for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) - for (auto phase = itr->second.begin(); phase != itr->second.end(); ++phase) - if (phase->phaseId) - phases.insert(phase->phaseId); - - // Phase Definitions - for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr) - if ((*itr)->phaseId) - phases.insert((*itr)->phaseId); -} - -void PhaseData::AddPhaseDefinition(PhaseDefinition const* phaseDefinition) -{ - if (phaseDefinition->IsOverwritingExistingPhases()) - { - activePhaseDefinitions.clear(); - _PhasemaskThroughDefinitions = phaseDefinition->phasemask; - } - else - { - if (phaseDefinition->IsNegatingPhasemask()) - _PhasemaskThroughDefinitions &= ~phaseDefinition->phasemask; - else - _PhasemaskThroughDefinitions |= phaseDefinition->phasemask; - } - - activePhaseDefinitions.push_back(phaseDefinition); -} - -void PhaseData::AddAuraInfo(uint32 spellId, PhaseInfo const& phaseInfo) -{ - if (phaseInfo.phasemask) - _PhasemaskThroughAuras |= phaseInfo.phasemask; - - spellPhaseInfo[spellId].push_back(phaseInfo); -} - -uint32 PhaseData::RemoveAuraInfo(uint32 spellId) -{ - PhaseInfoContainer::const_iterator rAura = spellPhaseInfo.find(spellId); - if (rAura != spellPhaseInfo.end()) - { - uint32 updateflag = 0; - - for (auto phase = rAura->second.begin(); phase != rAura->second.end(); ++phase) - { - if (phase->NeedsClientSideUpdate()) - updateflag |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED; - - if (phase->NeedsServerSideUpdate()) - { - _PhasemaskThroughAuras = 0; - updateflag |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED; - } - } - - if (updateflag & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED) - { - spellPhaseInfo.erase(rAura); - - for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr) - for (auto ph = itr->second.begin(); ph != itr->second.end(); ++ph) - _PhasemaskThroughAuras |= ph->phasemask; - } - - return updateflag; - } - - return 0; -} - -////////////////////////////////////////////////////////////////// -// Phase Update Data - -void PhaseUpdateData::AddQuestUpdate(uint32 questId) -{ - AddConditionType(CONDITION_QUESTREWARDED); - AddConditionType(CONDITION_QUESTTAKEN); - AddConditionType(CONDITION_QUEST_COMPLETE); - AddConditionType(CONDITION_QUEST_NONE); - - _questId = questId; -} - -bool PhaseUpdateData::IsConditionRelated(Condition const* condition) const -{ - switch (condition->ConditionType) - { - case CONDITION_QUESTREWARDED: - case CONDITION_QUESTTAKEN: - case CONDITION_QUEST_COMPLETE: - case CONDITION_QUEST_NONE: - return condition->ConditionValue1 == _questId && ((1 << condition->ConditionType) & _conditionTypeFlags); - default: - return (1 << condition->ConditionType) & _conditionTypeFlags; - } -} - -bool PhaseMgr::IsConditionTypeSupported(ConditionTypes conditionType) -{ - switch (conditionType) - { - case CONDITION_QUESTREWARDED: - case CONDITION_QUESTTAKEN: - case CONDITION_QUEST_COMPLETE: - case CONDITION_QUEST_NONE: - case CONDITION_TEAM: - case CONDITION_CLASS: - case CONDITION_RACE: - case CONDITION_INSTANCE_INFO: - case CONDITION_LEVEL: - return true; - default: - return false; - } -} - -void PhaseMgr::GetActivePhases(std::set<uint32>& phases) const -{ - phaseData.GetActivePhases(phases); -} diff --git a/src/server/game/Maps/PhaseMgr.h b/src/server/game/Maps/PhaseMgr.h deleted file mode 100644 index f5226e6468c..00000000000 --- a/src/server/game/Maps/PhaseMgr.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/> - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef TRINITY_PHASEMGR_H -#define TRINITY_PHASEMGR_H - -#include "SharedDefines.h" -#include "SpellAuras.h" -#include "SpellAuraEffects.h" -#include "ConditionMgr.h" - -class ObjectMgr; -class Player; - -// Phasing (visibility) -enum PhasingFlags -{ - PHASE_FLAG_OVERWRITE_EXISTING = 0x01, // don't stack with existing phases, overwrites existing phases - PHASE_FLAG_NO_MORE_PHASES = 0x02, // stop calculating phases after this phase was applied (no more phases will be applied) - PHASE_FLAG_NEGATE_PHASE = 0x04 // negate instead to add the phasemask -}; - -enum PhaseUpdateFlag -{ - PHASE_UPDATE_FLAG_ZONE_UPDATE = 0x01, - PHASE_UPDATE_FLAG_AREA_UPDATE = 0x02, - - // Internal flags - PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED = 0x08, - PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED = 0x10, -}; - -struct PhaseDefinition -{ - uint32 zoneId; - uint32 entry; - uint32 phasemask; - uint32 phaseId; - uint32 terrainswapmap; - uint8 flags; - - bool IsOverwritingExistingPhases() const { return flags & PHASE_FLAG_OVERWRITE_EXISTING; } - bool IsLastDefinition() const { return flags & PHASE_FLAG_NO_MORE_PHASES; } - bool IsNegatingPhasemask() const { return flags & PHASE_FLAG_NEGATE_PHASE; } -}; - -typedef std::list<PhaseDefinition> PhaseDefinitionContainer; -typedef std::unordered_map<uint32 /*zoneId*/, PhaseDefinitionContainer> PhaseDefinitionStore; - -struct SpellPhaseInfo -{ - uint32 spellId; - uint32 phasemask; - uint32 terrainswapmap; -}; - -typedef std::unordered_map<uint32 /*spellId*/, SpellPhaseInfo> SpellPhaseStore; - -struct PhaseInfo -{ - PhaseInfo() : phasemask(0), terrainswapmap(0), phaseId(0) {} - - uint32 phasemask; - uint32 terrainswapmap; - uint32 phaseId; - - bool NeedsServerSideUpdate() const { return phasemask; } - bool NeedsClientSideUpdate() const { return terrainswapmap || phaseId; } -}; - -typedef std::unordered_map<uint32 /*spellId*/, std::list<PhaseInfo>> PhaseInfoContainer; - -struct PhaseData -{ - PhaseData(Player* _player) : _PhasemaskThroughDefinitions(0), _PhasemaskThroughAuras(0), _CustomPhasemask(0), player(_player) {} - - uint32 _PhasemaskThroughDefinitions; - uint32 _PhasemaskThroughAuras; - uint32 _CustomPhasemask; - - uint32 GetCurrentPhasemask() const; - inline uint32 GetPhaseMaskForSpawn() const; - - void ResetDefinitions() { _PhasemaskThroughDefinitions = 0; activePhaseDefinitions.clear(); } - void AddPhaseDefinition(PhaseDefinition const* phaseDefinition); - bool HasActiveDefinitions() const { return !activePhaseDefinitions.empty(); } - - void AddAuraInfo(uint32 spellId, PhaseInfo const& phaseInfo); - uint32 RemoveAuraInfo(uint32 spellId); - - void SendPhaseMaskToPlayer(); - void SendPhaseshiftToPlayer(); - - void GetActivePhases(std::set<uint32>& phases) const; - -private: - Player* player; - std::list<PhaseDefinition const*> activePhaseDefinitions; - PhaseInfoContainer spellPhaseInfo; -}; - -struct PhaseUpdateData -{ - PhaseUpdateData(): _conditionTypeFlags(0), _questId(0) { } - void AddConditionType(ConditionTypes const conditionType) { _conditionTypeFlags |= (1 << conditionType); } - void AddQuestUpdate(uint32 const questId); - - bool IsConditionRelated(Condition const* condition) const; - -private: - uint32 _conditionTypeFlags; - uint32 _questId; -}; - -class PhaseMgr -{ -public: - PhaseMgr(Player* _player); - ~PhaseMgr() {} - - uint32 GetCurrentPhasemask() { return phaseData.GetCurrentPhasemask(); }; - inline uint32 GetPhaseMaskForSpawn() { return phaseData.GetCurrentPhasemask(); } - - // Phase definitions update handling - void NotifyConditionChanged(PhaseUpdateData const& updateData); - void NotifyStoresReloaded() { Recalculate(); Update(); } - - void Update(); - - // Aura phase effects - void RegisterPhasingAuraEffect(AuraEffect const* auraEffect); - void UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect); - - // Update flags (delayed phasing) - void AddUpdateFlag(PhaseUpdateFlag updateFlag) { _UpdateFlags |= updateFlag; } - void RemoveUpdateFlag(PhaseUpdateFlag updateFlag); - - // Needed for modify phase command - void SetCustomPhase(uint32 phaseMask); - - // Debug - void SendDebugReportToPlayer(Player* const debugger); - - static bool IsConditionTypeSupported(ConditionTypes conditionType); - - void GetActivePhases(std::set<uint32>& phases) const; - -private: - void Recalculate(); - - inline bool CheckDefinition(PhaseDefinition const* phaseDefinition); - - bool NeedsPhaseUpdateWithData(PhaseUpdateData const& updateData) const; - - inline bool IsUpdateInProgress() const { return (_UpdateFlags & PHASE_UPDATE_FLAG_ZONE_UPDATE) || (_UpdateFlags & PHASE_UPDATE_FLAG_AREA_UPDATE); } - - PhaseDefinitionStore const* _PhaseDefinitionStore; - SpellPhaseStore const* _SpellPhaseStore; - - Player* player; - PhaseData phaseData; - uint8 _UpdateFlags; -}; - -#endif diff --git a/src/server/game/Maps/TransportMgr.cpp b/src/server/game/Maps/TransportMgr.cpp index 28869d264c4..ba7d3784157 100644 --- a/src/server/game/Maps/TransportMgr.cpp +++ b/src/server/game/Maps/TransportMgr.cpp @@ -348,7 +348,7 @@ void TransportMgr::AddPathNodeToTransport(uint32 transportEntry, uint32 timeSeg, animNode.Path[timeSeg] = node; } -Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* map /*= NULL*/) +Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* map /*= NULL*/, uint32 phaseid /*= 0*/, uint32 phasegroup /*= 0*/) { // instance case, execute GetGameObjectEntry hook if (map) @@ -388,6 +388,13 @@ Transport* TransportMgr::CreateTransport(uint32 entry, uint32 guid /*= 0*/, Map* return NULL; } + if (phaseid) + trans->SetInPhase(phaseid, false, true); + + if (phasegroup) + for (auto ph : GetPhasesForGroup(phasegroup)) + trans->SetInPhase(ph, false, true); + if (MapEntry const* mapEntry = sMapStore.LookupEntry(mapId)) { if (mapEntry->Instanceable() != tInfo->inInstance) @@ -416,7 +423,7 @@ void TransportMgr::SpawnContinentTransports() uint32 oldMSTime = getMSTime(); - QueryResult result = WorldDatabase.Query("SELECT guid, entry FROM transports"); + QueryResult result = WorldDatabase.Query("SELECT guid, entry, phaseid, phasegroup FROM transports"); uint32 count = 0; if (result) @@ -426,10 +433,12 @@ void TransportMgr::SpawnContinentTransports() Field* fields = result->Fetch(); uint32 guid = fields[0].GetUInt32(); uint32 entry = fields[1].GetUInt32(); + uint32 phaseid = fields[2].GetUInt32(); + uint32 phasegroup = fields[3].GetUInt32(); if (TransportTemplate const* tInfo = GetTransportTemplate(entry)) if (!tInfo->inInstance) - if (CreateTransport(entry, guid)) + if (CreateTransport(entry, guid, nullptr, phaseid, phasegroup)) ++count; } while (result->NextRow()); diff --git a/src/server/game/Maps/TransportMgr.h b/src/server/game/Maps/TransportMgr.h index 5da856b185c..759b761c3f1 100644 --- a/src/server/game/Maps/TransportMgr.h +++ b/src/server/game/Maps/TransportMgr.h @@ -105,7 +105,7 @@ class TransportMgr void LoadTransportTemplates(); // Creates a transport using given GameObject template entry - Transport* CreateTransport(uint32 entry, uint32 guid = 0, Map* map = NULL); + Transport* CreateTransport(uint32 entry, uint32 guid = 0, Map* map = nullptr, uint32 phaseid = 0, uint32 phasegroup = 0); // Spawns all continent transports, used at core startup void SpawnContinentTransports(); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index f74faafb761..475e8ee3fa8 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -406,7 +406,7 @@ enum SpellAttr3 SPELL_ATTR3_MAIN_HAND = 0x00000400, // 10 Main hand weapon required SPELL_ATTR3_BATTLEGROUND = 0x00000800, // 11 Can only be cast in battleground SPELL_ATTR3_ONLY_TARGET_GHOSTS = 0x00001000, // 12 - SPELL_ATTR3_UNK13 = 0x00002000, // 13 + SPELL_ATTR3_DONT_DISPLAY_CHANNEL_BAR = 0x00002000, // 13 Clientside attribute - will not display channeling bar SPELL_ATTR3_IS_HONORLESS_TARGET = 0x00004000, // 14 "Honorless Target" only this spells have this flag SPELL_ATTR3_UNK15 = 0x00008000, // 15 Auto Shoot, Shoot, Throw, - this is autoshot flag SPELL_ATTR3_CANT_TRIGGER_PROC = 0x00010000, // 16 confirmed with many patchnotes diff --git a/src/server/game/Scripting/ScriptMgr.cpp b/src/server/game/Scripting/ScriptMgr.cpp index d99975e72d8..82189485ee6 100644 --- a/src/server/game/Scripting/ScriptMgr.cpp +++ b/src/server/game/Scripting/ScriptMgr.cpp @@ -1242,9 +1242,9 @@ void ScriptMgr::OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck) FOREACH_SCRIPT(PlayerScript)->OnSpellCast(player, spell, skipCheck); } -void ScriptMgr::OnPlayerLogin(Player* player) +void ScriptMgr::OnPlayerLogin(Player* player, bool firstLogin) { - FOREACH_SCRIPT(PlayerScript)->OnLogin(player); + FOREACH_SCRIPT(PlayerScript)->OnLogin(player, firstLogin); } void ScriptMgr::OnPlayerLogout(Player* player) diff --git a/src/server/game/Scripting/ScriptMgr.h b/src/server/game/Scripting/ScriptMgr.h index a8c7b899916..a0845b4c3d1 100644 --- a/src/server/game/Scripting/ScriptMgr.h +++ b/src/server/game/Scripting/ScriptMgr.h @@ -743,7 +743,7 @@ class PlayerScript : public UnitScript virtual void OnSpellCast(Player* /*player*/, Spell* /*spell*/, bool /*skipCheck*/) { } // Called when a player logs in. - virtual void OnLogin(Player* /*player*/) { } + virtual void OnLogin(Player* /*player*/, bool /*firstLogin*/) { } // Called when a player logs out. virtual void OnLogout(Player* /*player*/) { } @@ -1033,7 +1033,7 @@ class ScriptMgr void OnPlayerEmote(Player* player, uint32 emote); void OnPlayerTextEmote(Player* player, uint32 textEmote, uint32 emoteNum, uint64 guid); void OnPlayerSpellCast(Player* player, Spell* spell, bool skipCheck); - void OnPlayerLogin(Player* player); + void OnPlayerLogin(Player* player, bool firstLogin); void OnPlayerLogout(Player* player); void OnPlayerCreate(Player* player); void OnPlayerDelete(uint64 guid); diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 1145a631594..9c44fa8fad3 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -233,7 +233,7 @@ class WorldSession void SendPetNameInvalid(uint32 error, std::string const& name, DeclinedName *declinedName); void SendPartyResult(PartyOperation operation, std::string const& member, PartyResult res, uint32 val = 0); void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3); - void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps); + void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps, std::set<uint32> const& worldMapAreaSwaps); void SendQueryTimeResponse(); void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0); @@ -246,7 +246,7 @@ class WorldSession AccountTypes GetSecurity() const { return _security; } uint32 GetAccountId() const { return _accountId; } - uint32 GetBattlenetAccountId() const { return _accountId; } + uint32 GetBattlenetAccountId() const { return _battlenetAccountId; } Player* GetPlayer() const { return _player; } std::string const& GetPlayerName() const; std::string GetPlayerInfo() const; diff --git a/src/server/game/Spells/Auras/SpellAuraDefines.h b/src/server/game/Spells/Auras/SpellAuraDefines.h index 0f396ee4bc6..628e4e0721d 100644 --- a/src/server/game/Spells/Auras/SpellAuraDefines.h +++ b/src/server/game/Spells/Auras/SpellAuraDefines.h @@ -407,7 +407,7 @@ enum AuraType SPELL_AURA_BYPASS_ARMOR_FOR_CASTER = 345, SPELL_AURA_ENABLE_ALT_POWER = 346, // NYI SPELL_AURA_MOD_SPELL_COOLDOWN_BY_HASTE = 347, // NYI - SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT = 348, // NYI + SPELL_AURA_DEPOSIT_BONUS_MONEY_IN_GUILD_BANK_ON_LOOT = 348, SPELL_AURA_MOD_CURRENCY_GAIN = 349, SPELL_AURA_MOD_GATHERING_ITEMS_GAINED_PERCENT = 350, // NYI SPELL_AURA_351 = 351, diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index bb1396b5633..03512b85460 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1608,31 +1608,8 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app Unit* target = aurApp->GetTarget(); - if (Player* player = target->ToPlayer()) - { - if (apply) - player->GetPhaseMgr().RegisterPhasingAuraEffect(this); - else - player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this); - } - else - { - uint32 newPhase = 0; - Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE); - if (!phases.empty()) - for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr) - newPhase |= (*itr)->GetMiscValue(); - - if (!newPhase) - { - newPhase = PHASEMASK_NORMAL; - if (Creature* creature = target->ToCreature()) - if (CreatureData const* data = sObjectMgr->GetCreatureData(creature->GetDBTableGUIDLow())) - newPhase = data->phaseMask; - } - - target->SetPhaseMask(newPhase, false); - } + std::set<uint32> const& oldPhases = target->GetPhases(); + target->SetInPhase(GetMiscValueB(), false, apply); // call functions which may have additional effects after chainging state of unit // phase auras normally not expected at BG but anyway better check @@ -1642,6 +1619,13 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } + if (Player* player = target->ToPlayer()) + { + if (player->IsInWorld()) + player->GetMap()->SendUpdateTransportVisibility(player, oldPhases); + player->UpdatePhasing(); + } + // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases) if (target->IsVisible()) target->UpdateObjectVisibility(); @@ -1654,13 +1638,10 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo Unit* target = aurApp->GetTarget(); - if (Player* player = target->ToPlayer()) - { - if (apply) - player->GetPhaseMgr().RegisterPhasingAuraEffect(this); - else - player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this); - } + std::set<uint32> const& oldPhases = target->GetPhases(); + std::set<uint32> const& phases = GetPhasesForGroup(GetMiscValueB()); + for (auto phase : phases) + target->SetInPhase(phase, false, apply); // call functions which may have additional effects after chainging state of unit // phase auras normally not expected at BG but anyway better check @@ -1670,6 +1651,13 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } + if (Player* player = target->ToPlayer()) + { + if (player->IsInWorld()) + player->GetMap()->SendUpdateTransportVisibility(player, oldPhases); + player->UpdatePhasing(); + } + // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases) if (target->IsVisible()) target->UpdateObjectVisibility(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 1750dbc26f2..bdfe78d941a 100644 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -3206,6 +3206,9 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) return; } + for (auto phase : m_caster->GetPhases()) + pGameObj->SetInPhase(phase, false, true); + int32 duration = m_spellInfo->GetDuration(); pGameObj->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); @@ -3227,6 +3230,9 @@ void Spell::EffectSummonObjectWild(SpellEffIndex effIndex) if (linkedGO->Create(sObjectMgr->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)) { + for (auto phase : m_caster->GetPhases()) + linkedGO->SetInPhase(phase, false, true); + linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); linkedGO->SetSpellId(m_spellInfo->Id); @@ -3848,7 +3854,7 @@ void Spell::EffectDuel(SpellEffIndex effIndex) Map* map = m_caster->GetMap(); if (!pGameObj->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, - map, m_caster->GetPhaseMask(), + map, 0, m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2, m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2, m_caster->GetPositionZ(), @@ -3858,6 +3864,9 @@ void Spell::EffectDuel(SpellEffIndex effIndex) return; } + for (auto phase : m_caster->GetPhases()) + pGameObj->SetInPhase(phase, false, true); + pGameObj->SetUInt32Value(GAMEOBJECT_FACTION, m_caster->getFaction()); pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()+1); int32 duration = m_spellInfo->GetDuration(); @@ -4208,12 +4217,15 @@ void Spell::EffectSummonObject(SpellEffIndex effIndex) Map* map = m_caster->GetMap(); if (!go->Create(sObjectMgr->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)) + 0, x, y, z, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete go; return; } + for (auto phase : m_caster->GetPhases()) + go->SetInPhase(phase, false, true); + //pGameObj->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); int32 duration = m_spellInfo->GetDuration(); go->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); @@ -4837,12 +4849,15 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) GameObject* pGameObj = new GameObject; if (!pGameObj->Create(sObjectMgr->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)) + 0, fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { delete pGameObj; return; } + for (auto phase : m_caster->GetPhases()) + pGameObj->SetInPhase(phase, false, true); + int32 duration = m_spellInfo->GetDuration(); switch (goinfo->type) @@ -4903,8 +4918,11 @@ void Spell::EffectTransmitted(SpellEffIndex effIndex) { GameObject* linkedGO = new GameObject; if (linkedGO->Create(sObjectMgr->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)) + 0, fx, fy, fz, m_caster->GetOrientation(), 0.0f, 0.0f, 0.0f, 0.0f, 100, GO_STATE_READY)) { + for (auto phase : m_caster->GetPhases()) + linkedGO->SetInPhase(phase, false, true); + linkedGO->SetRespawnTime(duration > 0 ? duration/IN_MILLISECONDS : 0); //linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel()); linkedGO->SetSpellId(m_spellInfo->Id); diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index 7491920c36a..040f1df3cf5 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -17,6 +17,7 @@ #include "SpellInfo.h" #include "SpellAuraDefines.h" +#include "SpellAuraEffects.h" #include "SpellMgr.h" #include "Spell.h" #include "DBCStores.h" @@ -1369,10 +1370,8 @@ bool SpellInfo::CanPierceImmuneAura(SpellInfo const* aura) const if (Attributes & SPELL_ATTR0_UNAFFECTED_BY_INVULNERABILITY) return true; - // these spells (Cyclone for example) can pierce all... - if ((AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) - // ...but not these (Divine shield for example) - && !(aura && (aura->Mechanic == MECHANIC_IMMUNE_SHIELD || aura->Mechanic == MECHANIC_INVULNERABILITY))) + // these spells (Cyclone for example) can pierce all... // ...but not these (Divine shield, Ice block, Cyclone and Banish for example) + if ((AttributesEx & SPELL_ATTR1_UNAFFECTED_BY_SCHOOL_IMMUNE) && !(aura && (aura->Mechanic == MECHANIC_IMMUNE_SHIELD || aura->Mechanic == MECHANIC_INVULNERABILITY || aura->Mechanic == MECHANIC_BANISH))) return true; return false; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index a9507b174b6..4375ad09e4c 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1457,7 +1457,7 @@ void World::SetInitialWorldSettings() sSpellMgr->LoadSpellGroupStackRules(); TC_LOG_INFO("server.loading", "Loading Spell Phase Dbc Info..."); - sObjectMgr->LoadSpellPhaseInfo(); + sObjectMgr->LoadPhaseInfo(); TC_LOG_INFO("server.loading", "Loading NPC Texts..."); sObjectMgr->LoadGossipText(); @@ -3284,10 +3284,7 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const void World::UpdatePhaseDefinitions() { - SessionMap::const_iterator itr; - for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr) - if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld()) - itr->second->GetPlayer()->GetPhaseMgr().NotifyStoresReloaded(); + } void World::ReloadRBAC() diff --git a/src/server/scripts/CMakeLists.txt b/src/server/scripts/CMakeLists.txt index 4ffa9925e0f..c12f16a7ab5 100644 --- a/src/server/scripts/CMakeLists.txt +++ b/src/server/scripts/CMakeLists.txt @@ -48,7 +48,9 @@ message("") include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/SFMT ${CMAKE_SOURCE_DIR}/dep/zlib diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index d0a005f356e..52886d60c4b 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -934,6 +934,9 @@ public: return false; } + for (auto phase : handler->GetSession()->GetPlayer()->GetPhases()) + v->SetInPhase(phase, false, true); + map->AddToMap(v->ToCreature()); return true; @@ -962,13 +965,14 @@ public: std::set<uint32> terrainswap; std::set<uint32> phaseId; + std::set<uint32> worldMapSwap; terrainswap.insert((uint32)atoi(t)); if (p) phaseId.insert((uint32)atoi(p)); - handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap); + handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap, worldMapSwap); return true; } @@ -1393,7 +1397,7 @@ public: if (unit && unit->GetTypeId() == TYPEID_PLAYER) player = unit->ToPlayer(); - player->GetPhaseMgr().SendDebugReportToPlayer(handler->GetSession()->GetPlayer()); + return true; } }; diff --git a/src/server/scripts/Commands/cs_gobject.cpp b/src/server/scripts/Commands/cs_gobject.cpp index e556854c2ab..de23c33e591 100644 --- a/src/server/scripts/Commands/cs_gobject.cpp +++ b/src/server/scripts/Commands/cs_gobject.cpp @@ -152,12 +152,15 @@ public: GameObject* object = new GameObject; uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); - if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMgr().GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) + if (!object->Create(guidLow, objectInfo->entry, map, 0, x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY)) { delete object; return false; } + for (auto phase : player->GetPhases()) + object->SetInPhase(phase, false, true); + if (spawntimeSecs) { uint32 value = atoi((char*)spawntimeSecs); @@ -165,7 +168,7 @@ public: } // fill the gameobject data and save to the db - object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn()); + object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMask()); // delete the old object and do a clean load from DB with a fresh new GameObject instance. // this is required to avoid weird behavior and memory leaks delete object; @@ -507,7 +510,7 @@ public: //set phasemask for selected object static bool HandleGameObjectSetPhaseCommand(ChatHandler* handler, char const* args) { - // number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r + /*// number or [name] Shift-click form |color|Hgameobject:go_id|h[name]|h|r char* id = handler->extractKeyFromLink((char*)args, "Hgameobject"); if (!id) return false; @@ -539,7 +542,7 @@ public: } object->SetPhaseMask(phaseMask, true); - object->SaveToDB(); + object->SaveToDB();*/ return true; } diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index bff12d4330e..1d812a8f4eb 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -370,7 +370,8 @@ public: target->GetContactPoint(_player, x, y, z); _player->TeleportTo(target->GetMapId(), x, y, z, _player->GetAngle(target), TELE_TO_GM_MODE); - _player->SetPhaseMask(target->GetPhaseMask(), true); + for (auto phase : target->GetPhases()) + _player->SetInPhase(phase, true, true); } else { @@ -494,7 +495,8 @@ public: float x, y, z; handler->GetSession()->GetPlayer()->GetClosePoint(x, y, z, target->GetObjectSize()); target->TeleportTo(handler->GetSession()->GetPlayer()->GetMapId(), x, y, z, target->GetOrientation()); - target->SetPhaseMask(handler->GetSession()->GetPlayer()->GetPhaseMask(), true); + for (auto phase : handler->GetSession()->GetPlayer()->GetPhases()) + target->SetInPhase(phase, true, true); } else { diff --git a/src/server/scripts/Commands/cs_modify.cpp b/src/server/scripts/Commands/cs_modify.cpp index d47ee20fac5..17fea409671 100644 --- a/src/server/scripts/Commands/cs_modify.cpp +++ b/src/server/scripts/Commands/cs_modify.cpp @@ -52,6 +52,7 @@ public: static ChatCommand modifyCommandTable[] = { { "bit", rbac::RBAC_PERM_COMMAND_MODIFY_BIT, false, &HandleModifyBitCommand, "", NULL }, + { "currency", rbac::RBAC_PERM_COMMAND_MODIFY_CURRENCY, false, &HandleModifyCurrencyCommand, "", NULL }, { "drunk", rbac::RBAC_PERM_COMMAND_MODIFY_DRUNK, false, &HandleModifyDrunkCommand, "", NULL }, { "energy", rbac::RBAC_PERM_COMMAND_MODIFY_ENERGY, false, &HandleModifyEnergyCommand, "", NULL }, { "faction", rbac::RBAC_PERM_COMMAND_MODIFY_FACTION, false, &HandleModifyFactionCommand, "", NULL }, @@ -1267,24 +1268,19 @@ public: return true; } - //set temporary phase mask for player + // Toggles a phaseid on a player static bool HandleModifyPhaseCommand(ChatHandler* handler, const char* args) { if (!*args) return false; - uint32 phasemask = (uint32)atoi((char*)args); + uint32 phase = (uint32)atoi((char*)args); Unit* target = handler->getSelectedUnit(); if (target) - { - if (target->GetTypeId() == TYPEID_PLAYER) - target->ToPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); - else - target->SetPhaseMask(phasemask, true); - } + target->SetInPhase(phase, true, !target->IsInPhase(phase)); else - handler->GetSession()->GetPlayer()->GetPhaseMgr().SetCustomPhase(phasemask); + handler->GetSession()->GetPlayer()->SetInPhase(phase, true, !handler->GetSession()->GetPlayer()->IsInPhase(phase)); return true; } diff --git a/src/server/scripts/Commands/cs_npc.cpp b/src/server/scripts/Commands/cs_npc.cpp index 3b3eb303d58..84716ad9590 100644 --- a/src/server/scripts/Commands/cs_npc.cpp +++ b/src/server/scripts/Commands/cs_npc.cpp @@ -264,7 +264,7 @@ public: uint32 guid = sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT); CreatureData& data = sObjectMgr->NewOrExistCreatureData(guid); data.id = id; - data.phaseMask = chr->GetPhaseMgr().GetPhaseMaskForSpawn(); + data.phaseMask = chr->GetPhaseMask(); data.posX = chr->GetTransOffsetX(); data.posY = chr->GetTransOffsetY(); data.posZ = chr->GetTransOffsetZ(); @@ -272,20 +272,23 @@ public: Creature* creature = trans->CreateNPCPassenger(guid, &data); - creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); + creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMask()); sObjectMgr->AddCreatureToGrid(guid, &data); return true; } Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o)) { delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); + for (auto phase : chr->GetPhases()) + creature->SetInPhase(phase, false, true); + + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); uint32 db_guid = creature->GetDBTableGUIDLow(); @@ -1096,20 +1099,14 @@ public: return true; } - //npc phasemask handling - //change phasemask of creature or pet + //npc phase handling + //change phase of creature or pet static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args) { if (!*args) return false; - uint32 phasemask = (uint32) atoi((char*)args); - if (phasemask == 0) - { - handler->SendSysMessage(LANG_BAD_VALUE); - handler->SetSentErrorMessage(true); - return false; - } + uint32 phase = (uint32) atoi((char*)args); Creature* creature = handler->getSelectedCreature(); if (!creature) @@ -1119,7 +1116,7 @@ public: return false; } - creature->SetPhaseMask(phasemask, true); + creature->SetInPhase(phase, true, !creature->IsInPhase(phase)); if (!creature->IsPet()) creature->SaveToDB(); diff --git a/src/server/scripts/Commands/cs_reload.cpp b/src/server/scripts/Commands/cs_reload.cpp index 0274de02ae0..9d1f098542d 100644 --- a/src/server/scripts/Commands/cs_reload.cpp +++ b/src/server/scripts/Commands/cs_reload.cpp @@ -450,71 +450,72 @@ public: cInfo->Modelid4 = fields[8].GetUInt32(); cInfo->Name = fields[9].GetString(); cInfo->SubName = fields[10].GetString(); - cInfo->IconName = fields[11].GetString(); - cInfo->GossipMenuId = fields[12].GetUInt32(); - cInfo->minlevel = fields[13].GetUInt8(); - cInfo->maxlevel = fields[14].GetUInt8(); - cInfo->expansion = fields[15].GetUInt16(); - cInfo->expansionUnknown = fields[16].GetUInt16(); - cInfo->faction = fields[17].GetUInt16(); - cInfo->npcflag = fields[18].GetUInt32(); - cInfo->speed_walk = fields[19].GetFloat(); - cInfo->speed_run = fields[20].GetFloat(); - cInfo->scale = fields[21].GetFloat(); - cInfo->rank = fields[22].GetUInt8(); - cInfo->mindmg = fields[23].GetFloat(); - cInfo->maxdmg = fields[24].GetFloat(); - cInfo->dmgschool = fields[25].GetUInt8(); - cInfo->attackpower = fields[26].GetUInt32(); - cInfo->dmg_multiplier = fields[27].GetFloat(); - cInfo->baseattacktime = fields[28].GetUInt32(); - cInfo->rangeattacktime = fields[29].GetUInt32(); - cInfo->unit_class = fields[30].GetUInt8(); - cInfo->unit_flags = fields[31].GetUInt32(); - cInfo->unit_flags2 = fields[32].GetUInt32(); - cInfo->dynamicflags = fields[33].GetUInt32(); - cInfo->family = fields[34].GetUInt8(); - cInfo->trainer_type = fields[35].GetUInt8(); - cInfo->trainer_class = fields[36].GetUInt8(); - cInfo->trainer_race = fields[37].GetUInt8(); - cInfo->minrangedmg = fields[38].GetFloat(); - cInfo->maxrangedmg = fields[39].GetFloat(); - cInfo->rangedattackpower = fields[40].GetUInt16(); - cInfo->type = fields[41].GetUInt8(); - cInfo->type_flags = fields[42].GetUInt32(); - cInfo->type_flags2 = fields[43].GetUInt32(); - cInfo->lootid = fields[44].GetUInt32(); - cInfo->pickpocketLootId = fields[45].GetUInt32(); - cInfo->SkinLootId = fields[46].GetUInt32(); + cInfo->FemaleName = fields[11].GetString(); + cInfo->IconName = fields[12].GetString(); + cInfo->GossipMenuId = fields[13].GetUInt32(); + cInfo->minlevel = fields[14].GetUInt8(); + cInfo->maxlevel = fields[15].GetUInt8(); + cInfo->expansion = fields[16].GetUInt16(); + cInfo->expansionUnknown = fields[17].GetUInt16(); + cInfo->faction = fields[18].GetUInt16(); + cInfo->npcflag = fields[19].GetUInt32(); + cInfo->speed_walk = fields[20].GetFloat(); + cInfo->speed_run = fields[21].GetFloat(); + cInfo->scale = fields[22].GetFloat(); + cInfo->rank = fields[23].GetUInt8(); + cInfo->mindmg = fields[24].GetFloat(); + cInfo->maxdmg = fields[25].GetFloat(); + cInfo->dmgschool = fields[26].GetUInt8(); + cInfo->attackpower = fields[27].GetUInt32(); + cInfo->dmg_multiplier = fields[28].GetFloat(); + cInfo->baseattacktime = fields[29].GetUInt32(); + cInfo->rangeattacktime = fields[30].GetUInt32(); + cInfo->unit_class = fields[31].GetUInt8(); + cInfo->unit_flags = fields[32].GetUInt32(); + cInfo->unit_flags2 = fields[33].GetUInt32(); + cInfo->dynamicflags = fields[34].GetUInt32(); + cInfo->family = fields[35].GetUInt8(); + cInfo->trainer_type = fields[36].GetUInt8(); + cInfo->trainer_class = fields[37].GetUInt8(); + cInfo->trainer_race = fields[38].GetUInt8(); + cInfo->minrangedmg = fields[39].GetFloat(); + cInfo->maxrangedmg = fields[40].GetFloat(); + cInfo->rangedattackpower = fields[41].GetUInt16(); + cInfo->type = fields[42].GetUInt8(); + cInfo->type_flags = fields[43].GetUInt32(); + cInfo->type_flags2 = fields[44].GetUInt32(); + cInfo->lootid = fields[45].GetUInt32(); + cInfo->pickpocketLootId = fields[46].GetUInt32(); + cInfo->SkinLootId = fields[47].GetUInt32(); for (uint8 i = SPELL_SCHOOL_HOLY; i < MAX_SPELL_SCHOOL; ++i) - cInfo->resistance[i] = fields[47 + i -1].GetUInt16(); + cInfo->resistance[i] = fields[48 + i -1].GetUInt16(); for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i) - cInfo->spells[i] = fields[53 + i].GetUInt32(); - - cInfo->PetSpellDataId = fields[61].GetUInt32(); - cInfo->VehicleId = fields[62].GetUInt32(); - cInfo->mingold = fields[63].GetUInt32(); - cInfo->maxgold = fields[64].GetUInt32(); - cInfo->AIName = fields[65].GetString(); - cInfo->MovementType = fields[66].GetUInt8(); - cInfo->InhabitType = fields[67].GetUInt8(); - cInfo->HoverHeight = fields[68].GetFloat(); - cInfo->ModHealth = fields[69].GetFloat(); - cInfo->ModMana = fields[70].GetFloat(); - cInfo->ModManaExtra = fields[71].GetFloat(); - cInfo->ModArmor = fields[72].GetFloat(); - cInfo->RacialLeader = fields[73].GetBool(); + cInfo->spells[i] = fields[54 + i].GetUInt32(); + + cInfo->PetSpellDataId = fields[62].GetUInt32(); + cInfo->VehicleId = fields[63].GetUInt32(); + cInfo->mingold = fields[64].GetUInt32(); + cInfo->maxgold = fields[65].GetUInt32(); + cInfo->AIName = fields[66].GetString(); + cInfo->MovementType = fields[67].GetUInt8(); + cInfo->InhabitType = fields[68].GetUInt8(); + cInfo->HoverHeight = fields[69].GetFloat(); + cInfo->ModHealth = fields[70].GetFloat(); + cInfo->ModMana = fields[71].GetFloat(); + cInfo->ModManaExtra = fields[72].GetFloat(); + cInfo->ModArmor = fields[73].GetFloat(); + cInfo->RacialLeader = fields[74].GetBool(); for (uint8 i = 0; i < MAX_CREATURE_QUEST_ITEMS; ++i) - cInfo->questItems[i] = fields[74 + i].GetUInt32(); + cInfo->questItems[i] = fields[75 + i].GetUInt32(); - cInfo->movementId = fields[80].GetUInt32(); - cInfo->RegenHealth = fields[81].GetBool(); - cInfo->MechanicImmuneMask = fields[82].GetUInt32(); - cInfo->flags_extra = fields[83].GetUInt32(); - cInfo->ScriptID = sObjectMgr->GetScriptId(fields[84].GetCString()); + cInfo->movementId = fields[81].GetUInt32(); + cInfo->RegenHealth = fields[82].GetBool(); + cInfo->MechanicImmuneMask = fields[83].GetUInt32(); + cInfo->flags_extra = fields[84].GetUInt32(); + cInfo->ScriptID = sObjectMgr->GetScriptId(fields[85].GetCString()); sObjectMgr->CheckCreatureTemplate(cInfo); } diff --git a/src/server/scripts/Commands/cs_wp.cpp b/src/server/scripts/Commands/cs_wp.cpp index 5306e0e1d9e..210c47a7d3d 100644 --- a/src/server/scripts/Commands/cs_wp.cpp +++ b/src/server/scripts/Commands/cs_wp.cpp @@ -694,7 +694,7 @@ public: } // re-create Creature* wpCreature2 = new Creature(); - if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) + if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), VISUAL_WAYPOINT, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation())) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); delete wpCreature2; @@ -702,7 +702,10 @@ public: return false; } - wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); + for (auto phase : chr->GetPhases()) + wpCreature2->SetInPhase(phase, false, true); + + wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); /// @todo Should we first use "Create" then use "LoadFromDB"? if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map)) @@ -918,13 +921,16 @@ public: float o = chr->GetOrientation(); Creature* wpCreature = new Creature(); - if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete wpCreature; return false; } + for (auto phase : chr->GetPhases()) + wpCreature->SetInPhase(phase, false, true); + // Set "wpguid" column to the visual waypoint PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_UPD_WAYPOINT_DATA_WPGUID); @@ -934,7 +940,7 @@ public: WorldDatabase.Execute(stmt); - wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); + wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map)) { @@ -982,14 +988,17 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); + for (auto phase : chr->GetPhases()) + creature->SetInPhase(phase, false, true); + + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); @@ -1031,14 +1040,17 @@ public: Map* map = chr->GetMap(); Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, x, y, z, o)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMask(), id, x, y, z, o)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); delete creature; return false; } - creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn()); + for (auto phase : chr->GetPhases()) + creature->SetInPhase(phase, false, true); + + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask()); if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map)) { handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp index f7aedb42561..a3804f8b35a 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/boss_nefarian.cpp @@ -178,7 +178,6 @@ public: _Reset(); me->SetVisible(true); - me->SetPhaseMask(1, true); me->SetUInt32Value(UNIT_NPC_FLAGS, 1); me->setFaction(35); me->SetStandState(UNIT_STAND_STATE_SIT_HIGH_CHAIR); diff --git a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp index be8bc34acf1..8bd1ef26aec 100644 --- a/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp +++ b/src/server/scripts/EasternKingdoms/BlackrockMountain/BlackwingLair/instance_blackwing_lair.cpp @@ -155,7 +155,7 @@ public: { case 177807: // Egg if (GetBossState(BOSS_FIREMAW) == DONE) - go->SetPhaseMask(2, true); + go->SetLootState(GO_JUST_DEACTIVATED); else EggList.push_back(go->GetGUID()); break; @@ -201,7 +201,7 @@ public: { for (std::list<uint64>::const_iterator itr = EggList.begin(); itr != EggList.end(); ++itr) if (GameObject* egg = instance->GetGameObject((*itr))) - egg->SetPhaseMask(2, true); + egg->SetLootState(GO_JUST_DEACTIVATED); } SetData(DATA_EGG_EVENT, NOT_STARTED); break; diff --git a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp index 1c042f4d185..4b352b98af2 100644 --- a/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp +++ b/src/server/scripts/Northrend/AzjolNerub/Ahnkahet/boss_herald_volazj.cpp @@ -111,8 +111,14 @@ public: me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); me->SetControlled(true, UNIT_STATE_STUNNED); } - // phase mask - target->CastSpell(target, SPELL_INSANITY_TARGET+insanityHandled, true); + + // phase the player + target->CastSpell(target, SPELL_INSANITY_TARGET + insanityHandled, true); + + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(SPELL_INSANITY_TARGET + insanityHandled); + if (!spellInfo) + return; + // summon twisted party members for this target Map::PlayerList const &players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) @@ -125,21 +131,22 @@ public: { // clone player->CastSpell(summon, SPELL_CLONE_PLAYER, true); - // set phase - summon->SetPhaseMask((1<<(4+insanityHandled)), true); + // phase the summon + summon->SetInPhase(spellInfo->Effects[EFFECT_0].MiscValueB, true, true); } } ++insanityHandled; } } - void ResetPlayersPhaseMask() + void ResetPlayersPhase() { Map::PlayerList const &players = me->GetMap()->GetPlayers(); for (Map::PlayerList::const_iterator i = players.begin(); i != players.end(); ++i) { Player* player = i->GetSource(); - player->RemoveAurasDueToSpell(GetSpellForPhaseMask(player->GetPhaseMask())); + for (uint32 index = 0; index <= 4; ++index) + player->RemoveAurasDueToSpell(SPELL_INSANITY_TARGET + index); } } @@ -153,11 +160,14 @@ public: instance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_QUICK_DEMISE_START_EVENT); // Visible for all players in insanity - me->SetPhaseMask((1|16|32|64|128|256), true); + me->SetInPhase(169, true, true); + for (uint32 i = 173; i <= 177; ++i) + me->SetInPhase(i, true, true); + // Used for Insanity handling insanityHandled = 0; - ResetPlayersPhaseMask(); + ResetPlayersPhase(); // Cleanup Summons.DespawnAll(); @@ -178,33 +188,8 @@ public: Summons.Summon(summon); } - uint32 GetSpellForPhaseMask(uint32 phase) - { - uint32 spell = 0; - switch (phase) - { - case 16: - spell = SPELL_INSANITY_PHASING_1; - break; - case 32: - spell = SPELL_INSANITY_PHASING_2; - break; - case 64: - spell = SPELL_INSANITY_PHASING_3; - break; - case 128: - spell = SPELL_INSANITY_PHASING_4; - break; - case 256: - spell = SPELL_INSANITY_PHASING_5; - break; - } - return spell; - } - void SummonedCreatureDespawn(Creature* summon) override { - uint32 phase = summon->GetPhaseMask(); uint32 nextPhase = 0; Summons.Despawn(summon); @@ -214,16 +199,17 @@ public: if (Creature* visage = ObjectAccessor::GetCreature(*me, *iter)) { // Not all are dead - if (phase == visage->GetPhaseMask()) + if (visage->IsInPhase(summon)) return; else - nextPhase = visage->GetPhaseMask(); + { + nextPhase = *visage->GetPhases().begin(); + break; + } } } // Roll Insanity - uint32 spell = GetSpellForPhaseMask(phase); - uint32 spell2 = GetSpellForPhaseMask(nextPhase); Map* map = me->GetMap(); if (!map) return; @@ -235,12 +221,9 @@ public: { if (Player* player = i->GetSource()) { - if (player->HasAura(spell)) - { - player->RemoveAurasDueToSpell(spell); - if (spell2) // if there is still some different mask cast spell for it - player->CastSpell(player, spell2, true); - } + for (uint32 index = 0; index <= 4; ++index) + player->RemoveAurasDueToSpell(SPELL_INSANITY_TARGET + index); + player->CastSpell(player, SPELL_INSANITY_TARGET + nextPhase - 173, true); } } } @@ -292,7 +275,7 @@ public: instance->SetBossState(DATA_HERALD_VOLAZJ, DONE); Summons.DespawnAll(); - ResetPlayersPhaseMask(); + ResetPlayersPhase(); } void KilledUnit(Unit* who) override diff --git a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp index 6d03774ea8c..78e8f2d248e 100644 --- a/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp +++ b/src/server/scripts/Northrend/ChamberOfAspects/RubySanctum/boss_halion.cpp @@ -380,7 +380,7 @@ class boss_halion : public CreatureScript if (events.IsInPhase(PHASE_THREE)) { // Don't consider copied damage. - if (!me->InSamePhase(attacker)) + if (!me->IsInPhase(attacker)) return; if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER))) @@ -541,7 +541,7 @@ class boss_twilight_halion : public CreatureScript if (events.IsInPhase(PHASE_THREE)) { // Don't consider copied damage. - if (!me->InSamePhase(attacker)) + if (!me->IsInPhase(attacker)) return; if (Creature* controller = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HALION_CONTROLLER))) diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp index 4303026ba64..21a0f92c7b5 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/halls_of_reflection.cpp @@ -636,7 +636,7 @@ class npc_jaina_or_sylvanas_intro_hor : public CreatureScript if (Creature* lichking = ObjectAccessor::GetCreature(*me, _lichkingGUID)) { if (GameObject* frostmourne = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_FROSTMOURNE))) - frostmourne->SetPhaseMask(2, true); + frostmourne->SetLootState(GO_JUST_DEACTIVATED); lichking->CastSpell(lichking, SPELL_TAKE_FROSTMOURNE, true); lichking->CastSpell(lichking, SPELL_FROSTMOURNE_VISUAL, true); } diff --git a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp index 6f33e80b92b..b17a5dbc8f5 100644 --- a/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp +++ b/src/server/scripts/Northrend/FrozenHalls/HallsOfReflection/instance_halls_of_reflection.cpp @@ -248,7 +248,7 @@ class instance_halls_of_reflection : public InstanceMapScript case GO_FROSTMOURNE: FrostmourneGUID = go->GetGUID(); if (GetData(DATA_INTRO_EVENT) == DONE) - go->SetPhaseMask(2, true); + go->SetLootState(GO_JUST_DEACTIVATED); break; case GO_ENTRANCE_DOOR: EntranceDoorGUID = go->GetGUID(); diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp index 569a81ee9cc..55c1003ff0c 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp @@ -538,6 +538,11 @@ class boss_the_lich_king : public CreatureScript Trinity::GameObjectWorker<FrozenThroneResetWorker> worker(me, reset); me->VisitNearbyGridObject(333.0f, worker); + // Restore Tirion's gossip only after The Lich King fully resets to prevent + // restarting the encounter while LK still runs back to spawn point + if (Creature* tirion = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_HIGHLORD_TIRION_FORDRING))) + tirion->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + // Reset any light override me->GetMap()->SetZoneOverrideLight(AREA_THE_FROZEN_THRONE, 0, 5000); } @@ -1180,11 +1185,6 @@ class npc_tirion_fordring_tft : public CreatureScript void JustReachedHome() override { me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - - if (_instance->GetBossState(DATA_THE_LICH_KING) == DONE) - return; - - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } void UpdateAI(uint32 diff) override diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp index 0c504842c08..68344593434 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_valithria_dreamwalker.cpp @@ -618,7 +618,7 @@ class npc_the_lich_king_controller : public CreatureScript void JustSummoned(Creature* summon) override { // must not be in dream phase - summon->SetPhaseMask((summon->GetPhaseMask() & ~0x10), true); + summon->SetInPhase(173, true, false); if (summon->GetEntry() != NPC_SUPPRESSER) if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) summon->AI()->AttackStart(target); diff --git a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp index c5c70cf3957..9875eb5aa68 100644 --- a/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp +++ b/src/server/scripts/Northrend/Naxxramas/boss_kelthuzad.cpp @@ -305,7 +305,7 @@ public: if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) { trigger->ResetDoorOrButton(); - trigger->SetPhaseMask(1, true); + trigger->SetLootState(GO_READY); } for (uint8 i = 0; i <= 3; ++i) @@ -394,7 +394,7 @@ public: break; case EVENT_TRIGGER: if (GameObject* trigger = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_KELTHUZAD_TRIGGER))) - trigger->SetPhaseMask(2, true); + trigger->SetLootState(GO_JUST_DEACTIVATED); break; case EVENT_PHASE: events.Reset(); diff --git a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp index 8a1fb6a9829..4fa80c7bac2 100644 --- a/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp +++ b/src/server/scripts/Northrend/Nexus/EyeOfEternity/instance_eye_of_eternity.cpp @@ -90,7 +90,6 @@ public: delete go; return; } - instance->AddToMap(go); } diff --git a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp index 2b15ddf32c4..d78a07f5c2b 100644 --- a/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp +++ b/src/server/scripts/Northrend/Nexus/Oculus/instance_oculus.cpp @@ -69,7 +69,7 @@ class instance_oculus : public InstanceMapScript case NPC_VAROS: VarosGUID = creature->GetGUID(); if (GetBossState(DATA_DRAKOS) == DONE) - creature->SetPhaseMask(1, true); + creature->SetPhaseMask(1, true); break; case NPC_UROM: UromGUID = creature->GetGUID(); diff --git a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp index 7ae1c7840db..753d4ebea01 100644 --- a/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp +++ b/src/server/scripts/Northrend/VioletHold/boss_zuramat.cpp @@ -190,7 +190,8 @@ public: { summon->AI()->AttackStart(me->GetVictim()); summon->CastSpell((Unit*)NULL, SPELL_ZURAMAT_ADD_2); - summon->SetPhaseMask(17, true); + summon->SetInPhase(169, true, true); // Normal phase + summon->SetInPhase(173, true, true); // Void phase } }; diff --git a/src/server/scripts/Northrend/zone_borean_tundra.cpp b/src/server/scripts/Northrend/zone_borean_tundra.cpp index 38d73e0673d..08936df4589 100644 --- a/src/server/scripts/Northrend/zone_borean_tundra.cpp +++ b/src/server/scripts/Northrend/zone_borean_tundra.cpp @@ -1853,7 +1853,7 @@ public: me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); break; case 20: - me->SetPhaseMask(1, true); + me->SetInPhase(170, true, false); Talk(SAY_5); me->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION); player->GroupEventHappens(QUEST_ESCAPING_THE_MIST, me); diff --git a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp index a3ef9ce7b5c..b43904f2223 100644 --- a/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp +++ b/src/server/scripts/OutdoorPvP/OutdoorPvPSI.cpp @@ -170,6 +170,9 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } + for (auto phase : player->GetPhases()) + go->SetInPhase(phase, false, true); + go->SetRespawnTime(0); if (!map->AddToMap(go)) @@ -204,6 +207,9 @@ bool OutdoorPvPSI::HandleDropFlag(Player* player, uint32 spellId) return true; } + for (auto phase : player->GetPhases()) + go->SetInPhase(phase, false, true); + go->SetRespawnTime(0); if (!map->AddToMap(go)) diff --git a/src/server/shared/Database/Implementation/LoginDatabase.cpp b/src/server/shared/Database/Implementation/LoginDatabase.cpp index df9ab6fcf29..5623bd56a95 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.cpp +++ b/src/server/shared/Database/Implementation/LoginDatabase.cpp @@ -120,4 +120,5 @@ void LoginDatabaseConnection::DoPrepareStatements() PrepareStatement(LOGIN_SEL_BNET_CHECK_PASSWORD, "SELECT 1 FROM battlenet_accounts WHERE id = ? AND sha_pass_hash = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK, "UPDATE battlenet_accounts SET locked = ? WHERE id = ?", CONNECTION_ASYNC); PrepareStatement(LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY, "UPDATE battlenet_accounts SET lock_country = ? WHERE id = ?", CONNECTION_ASYNC); + PrepareStatement(LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT, "SELECT battlenet_account FROM account WHERE id = ?", CONNECTION_SYNCH); } diff --git a/src/server/shared/Database/Implementation/LoginDatabase.h b/src/server/shared/Database/Implementation/LoginDatabase.h index 4fdfb91fed3..3b4558874bc 100644 --- a/src/server/shared/Database/Implementation/LoginDatabase.h +++ b/src/server/shared/Database/Implementation/LoginDatabase.h @@ -139,6 +139,7 @@ enum LoginDatabaseStatements LOGIN_SEL_BNET_CHECK_PASSWORD, LOGIN_UPD_BNET_ACCOUNT_LOCK, LOGIN_UPD_BNET_ACCOUNT_LOCK_CONTRY, + LOGIN_SEL_BNET_ACCOUNT_ID_BY_GAME_ACCOUNT, MAX_LOGINDATABASE_STATEMENTS }; diff --git a/src/server/worldserver/CMakeLists.txt b/src/server/worldserver/CMakeLists.txt index af76cac3fb5..2f4d557fec0 100644 --- a/src/server/worldserver/CMakeLists.txt +++ b/src/server/worldserver/CMakeLists.txt @@ -45,6 +45,7 @@ include_directories( ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include ${CMAKE_SOURCE_DIR}/dep/gsoap ${CMAKE_SOURCE_DIR}/dep/sockets/include ${CMAKE_SOURCE_DIR}/dep/SFMT diff --git a/src/tools/mmaps_generator/CMakeLists.txt b/src/tools/mmaps_generator/CMakeLists.txt index 591e0cc8e98..c0268680657 100644 --- a/src/tools/mmaps_generator/CMakeLists.txt +++ b/src/tools/mmaps_generator/CMakeLists.txt @@ -18,7 +18,9 @@ set(mmap_gen_Includes ${CMAKE_SOURCE_DIR}/dep/bzip2 ${CMAKE_SOURCE_DIR}/dep/g3dlite/include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Recast/Include ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour + ${CMAKE_SOURCE_DIR}/dep/recastnavigation/Detour/Include ${CMAKE_SOURCE_DIR}/src/server/shared ${CMAKE_SOURCE_DIR}/src/server/game/Conditions ${CMAKE_SOURCE_DIR}/src/server/collision |