From 8d38ec47fb2b27641d28eb51048afcc13f3b3b1a Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 17 Mar 2018 09:56:43 +0100 Subject: [PATCH 1/5] Core/Misc: Graveyards can now use conditions, SourceType = 27, SourceEntry = graveyard_zone.ID --- src/server/game/Battlegrounds/Battleground.cpp | 2 +- src/server/game/Conditions/ConditionMgr.cpp | 7 +++++++ src/server/game/Conditions/ConditionMgr.h | 3 ++- src/server/game/Entities/Player/Player.cpp | 4 ++-- src/server/game/Globals/ObjectMgr.cpp | 11 ++++++++++- src/server/game/Globals/ObjectMgr.h | 2 +- src/server/game/Handlers/NPCHandler.cpp | 6 ++---- src/server/scripts/Commands/cs_debug.cpp | 2 +- src/server/scripts/Commands/cs_misc.cpp | 2 +- 9 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index c3c7eb6a0d..e98f94629f 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -1837,7 +1837,7 @@ void Battleground::SetBgRaid(uint32 TeamID, Group* bg_raid) WorldSafeLocsEntry const* Battleground::GetClosestGraveYard(Player* player) { - return sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam()); + return sObjectMgr->GetClosestGraveYard(*player, player->GetTeam(), player); } void Battleground::StartTimedAchievement(AchievementCriteriaTimedTypes type, uint32 entry) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index 2f0efa9ab1..fcf84c1b74 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1835,6 +1835,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: case CONDITION_SOURCE_TYPE_NONE: + case CONDITION_SOURCE_TYPE_GRAVEYARD: + if (!sWorldSafeLocsStore.LookupEntry(cond->SourceEntry)) + { + TC_LOG_ERROR("sql.sql", "%s SourceEntry in `condition` table, does not exist in WorldSafeLocs, ignoring.", cond->ToString().c_str()); + return false; + } + break; default: break; } diff --git a/src/server/game/Conditions/ConditionMgr.h b/src/server/game/Conditions/ConditionMgr.h index af15d3947c..7c586027aa 100644 --- a/src/server/game/Conditions/ConditionMgr.h +++ b/src/server/game/Conditions/ConditionMgr.h @@ -137,7 +137,8 @@ enum ConditionSourceType CONDITION_SOURCE_TYPE_SPELL_PROC = 24, CONDITION_SOURCE_TYPE_TERRAIN_SWAP = 25, CONDITION_SOURCE_TYPE_PHASE = 26, - CONDITION_SOURCE_TYPE_MAX = 27 // MAX + CONDITION_SOURCE_TYPE_GRAVEYARD = 27, + CONDITION_SOURCE_TYPE_MAX = 28 // MAX }; enum RelationType diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 00f4a87ada..9eb05b1471 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5147,7 +5147,7 @@ void Player::RepopAtGraveyard() if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(GetZoneId())) ClosestGrave = bf->GetClosestGraveYard(this); else - ClosestGrave = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam()); + ClosestGrave = sObjectMgr->GetClosestGraveYard(*this, GetTeam(), this); } // stop countdown until repop @@ -22589,7 +22589,7 @@ void Player::SetBattlegroundEntryPoint() // If map is dungeon find linked graveyard if (GetMap()->IsDungeon()) { - if (const WorldSafeLocsEntry* entry = sObjectMgr->GetClosestGraveYard(GetPositionX(), GetPositionY(), GetPositionZ(), GetMapId(), GetTeam())) + if (const WorldSafeLocsEntry* entry = sObjectMgr->GetClosestGraveYard(*this, GetTeam(), this)) m_bgData.joinPos = WorldLocation(entry->map_id, entry->x, entry->y, entry->z, 0.0f); else TC_LOG_ERROR("entities.player", "Player::SetBattlegroundEntryPoint: Dungeon (MapID: %u) has no linked graveyard, setting home location as entry point.", GetMapId()); diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index df69a0a65e..d60e0944d8 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6335,8 +6335,12 @@ WorldSafeLocsEntry const* ObjectMgr::GetDefaultGraveYard(uint32 team) const else return nullptr; } -WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) const +WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& location, uint32 team, WorldObject* conditionObject) const { + float x, y, z; + location.GetPosition(x, y, z); + uint32 MapId = location.GetMapId(); + // search for zone associated closest graveyard uint32 zoneId = sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), MapId, x, y, z); @@ -6382,6 +6386,8 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float MapEntry const* mapEntry = sMapStore.LookupEntry(MapId); + ConditionSourceInfo conditionSource(conditionObject); + for (; range.first != range.second; ++range.first) { GraveYardData const& data = range.first->second; @@ -6398,6 +6404,9 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(float x, float y, float if (data.team != 0 && team != 0 && data.team != team) continue; + if (conditionObject && !sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_GRAVEYARD, data.safeLocId, conditionSource)) + continue; + // find now nearest graveyard at other map if (MapId != entry->map_id) { diff --git a/src/server/game/Globals/ObjectMgr.h b/src/server/game/Globals/ObjectMgr.h index e04baf7b52..7d443adc5f 100644 --- a/src/server/game/Globals/ObjectMgr.h +++ b/src/server/game/Globals/ObjectMgr.h @@ -856,7 +856,7 @@ class TC_GAME_API ObjectMgr QuestGreeting const* GetQuestGreeting(ObjectGuid guid) const; WorldSafeLocsEntry const* GetDefaultGraveYard(uint32 team) const; - WorldSafeLocsEntry const* GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team) const; + WorldSafeLocsEntry const* GetClosestGraveYard(WorldLocation const& location, uint32 team, WorldObject* conditionObject) const; bool AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = true); void RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool persist = false); void LoadGraveyardZones(); diff --git a/src/server/game/Handlers/NPCHandler.cpp b/src/server/game/Handlers/NPCHandler.cpp index 41bbeea955..676403aa1f 100644 --- a/src/server/game/Handlers/NPCHandler.cpp +++ b/src/server/game/Handlers/NPCHandler.cpp @@ -404,8 +404,7 @@ void WorldSession::SendSpiritResurrect() WorldLocation corpseLocation = _player->GetCorpseLocation(); if (_player->HasCorpse()) { - corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation.GetPositionX(), corpseLocation.GetPositionY(), - corpseLocation.GetPositionZ(), corpseLocation.GetMapId(), _player->GetTeam()); + corpseGrave = sObjectMgr->GetClosestGraveYard(corpseLocation, _player->GetTeam(), _player); } // now can spawn bones @@ -414,8 +413,7 @@ void WorldSession::SendSpiritResurrect() // teleport to nearest from corpse graveyard, if different from nearest to player ghost if (corpseGrave) { - WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveYard( - _player->GetPositionX(), _player->GetPositionY(), _player->GetPositionZ(), _player->GetMapId(), _player->GetTeam()); + WorldSafeLocsEntry const* ghostGrave = sObjectMgr->GetClosestGraveYard(*_player, _player->GetTeam(), _player); if (corpseGrave != ghostGrave) _player->TeleportTo(corpseGrave->map_id, corpseGrave->x, corpseGrave->y, corpseGrave->z, _player->GetOrientation()); diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp index 1419271dbc..c574392707 100644 --- a/src/server/scripts/Commands/cs_debug.cpp +++ b/src/server/scripts/Commands/cs_debug.cpp @@ -1582,7 +1582,7 @@ public: if (Battlefield* bf = sBattlefieldMgr->GetBattlefieldToZoneId(player->GetZoneId())) nearestLoc = bf->GetClosestGraveYard(player); else - nearestLoc = sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), player->GetTeam()); + nearestLoc = sObjectMgr->GetClosestGraveYard(*player, player->GetTeam(), player); } } else diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp index c8f972d24e..e86ba856f8 100644 --- a/src/server/scripts/Commands/cs_misc.cpp +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -1076,7 +1076,7 @@ public: Player* player = handler->GetSession()->GetPlayer(); uint32 zone_id = player->GetZoneId(); - WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(player->GetPositionX(), player->GetPositionY(), player->GetPositionZ(), player->GetMapId(), team); + WorldSafeLocsEntry const* graveyard = sObjectMgr->GetClosestGraveYard(*player, team, nullptr); if (graveyard) { uint32 graveyardId = graveyard->ID; From 04f488e55e45fa67b42f4e991b1d8ff818cc6331 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 17 Mar 2018 10:12:00 +0100 Subject: [PATCH 2/5] Core/Players: Include graveyards from terrain swap maps --- src/server/game/Globals/ObjectMgr.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index d60e0944d8..19d68df78c 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6342,7 +6342,7 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& lo uint32 MapId = location.GetMapId(); // search for zone associated closest graveyard - uint32 zoneId = sMapMgr->GetZoneId(PhasingHandler::GetEmptyPhaseShift(), MapId, x, y, z); + uint32 zoneId = sMapMgr->GetZoneId(conditionObject->GetPhaseShift(), MapId, x, y, z); if (!zoneId) { @@ -6392,23 +6392,24 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& lo { GraveYardData const& data = range.first->second; - WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.LookupEntry(data.safeLocId); - if (!entry) - { - TC_LOG_ERROR("sql.sql", "Table `graveyard_zone` has record for not existing graveyard (WorldSafeLocsID %u), skipped.", data.safeLocId); - continue; - } + WorldSafeLocsEntry const* entry = sWorldSafeLocsStore.AssertEntry(data.safeLocId); // skip enemy faction graveyard // team == 0 case can be at call from .neargrave if (data.team != 0 && team != 0 && data.team != team) continue; - if (conditionObject && !sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_GRAVEYARD, data.safeLocId, conditionSource)) - continue; + if (conditionObject) + { + if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_GRAVEYARD, data.safeLocId, conditionSource)) + continue; + + if (int16(entry->MapID) == mapEntry->ParentMapID && !conditionObject->GetPhaseShift().HasVisibleMapId(entry->MapID)) + continue; + } // find now nearest graveyard at other map - if (MapId != entry->map_id) + if (MapId != entry->MapID && int16(entry->MapID) != mapEntry->ParentMapID) { // if find graveyard at different map from where entrance placed (or no entrance data), use any first if (!mapEntry From cc3639cbb9111113b7ae3e47515dc2bd6dc990f3 Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 17 Mar 2018 10:37:50 +0100 Subject: [PATCH 3/5] fix build --- src/server/game/Globals/ObjectMgr.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 19d68df78c..8c1da64918 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -6404,12 +6404,12 @@ WorldSafeLocsEntry const* ObjectMgr::GetClosestGraveYard(WorldLocation const& lo if (!sConditionMgr->IsObjectMeetingNotGroupedConditions(CONDITION_SOURCE_TYPE_GRAVEYARD, data.safeLocId, conditionSource)) continue; - if (int16(entry->MapID) == mapEntry->ParentMapID && !conditionObject->GetPhaseShift().HasVisibleMapId(entry->MapID)) + if (int16(entry->map_id) == mapEntry->rootPhaseMap && !conditionObject->GetPhaseShift().HasVisibleMapId(entry->map_id)) continue; } // find now nearest graveyard at other map - if (MapId != entry->MapID && int16(entry->MapID) != mapEntry->ParentMapID) + if (MapId != entry->map_id && int16(entry->map_id) != mapEntry->rootPhaseMap) { // if find graveyard at different map from where entrance placed (or no entrance data), use any first if (!mapEntry From 712239e21511060ad865bdca8d75432344d88d2e Mon Sep 17 00:00:00 2001 From: Aokromes Date: Sat, 17 Mar 2018 14:17:45 +0100 Subject: [PATCH 4/5] Core/Conditions: Add missing break --- src/server/game/Conditions/ConditionMgr.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/server/game/Conditions/ConditionMgr.cpp b/src/server/game/Conditions/ConditionMgr.cpp index fcf84c1b74..e3a656d9ea 100644 --- a/src/server/game/Conditions/ConditionMgr.cpp +++ b/src/server/game/Conditions/ConditionMgr.cpp @@ -1835,6 +1835,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond) const case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION: case CONDITION_SOURCE_TYPE_SMART_EVENT: case CONDITION_SOURCE_TYPE_NONE: + break; case CONDITION_SOURCE_TYPE_GRAVEYARD: if (!sWorldSafeLocsStore.LookupEntry(cond->SourceEntry)) { From 16c97d35a1dd846a6d39f2378bd168ac14211596 Mon Sep 17 00:00:00 2001 From: Ovah Date: Sat, 17 Mar 2018 19:41:20 +0000 Subject: [PATCH 5/5] Phasing --- src/server/game/DataStores/DBCStructure.h | 6 +++--- src/server/game/DataStores/DBCfmt.h | 2 +- src/server/game/Entities/Player/Player.cpp | 9 ++++++++- src/server/game/Entities/Unit/Unit.cpp | 2 +- .../game/Spells/Auras/SpellAuraEffects.cpp | 18 ++++++++++++------ 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 53e6203f9c..33288f6cc1 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -688,9 +688,9 @@ struct AreaTriggerEntry float x; // 2 m_x float y; // 3 m_y float z; // 4 m_z - //uint32 // 5 - //uint32 // 6 - //uint32 // 7 + uint32 PhaseUseFlags; // 5 PhaseUseFlags + uint32 PhaseID; // 6 PhaseID + uint32 PhaseGroupID; // 7 PhaseGroupID float radius; // 8 m_radius float box_x; // 9 m_box_length float box_y; // 10 m_box_width diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index b782b104b3..0c0a1a1e7c 100644 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -30,7 +30,7 @@ char const AchievementCriteriafmt[] = "niiiliiiisiiiiixxiiiiii"; char const AreaTableEntryfmt[] = "niiiixxxxxisiiiiiffiixxxxx"; char const AreaGroupEntryfmt[] = "niiiiiii"; char const AreaPOIEntryfmt[] = "niiiiiiiiiiiffixixxixx"; -char const AreaTriggerEntryfmt[] = "nifffxxxfffff"; +char const AreaTriggerEntryfmt[] = "nifffiiifffff"; char const ArmorLocationfmt[] = "nfffff"; char const AuctionHouseEntryfmt[] = "niiix"; char const BankBagSlotPricesEntryfmt[] = "ni"; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 9eb05b1471..3a95b677de 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2584,9 +2584,16 @@ void Player::SetInWater(bool apply) bool Player::IsInAreaTriggerRadius(const AreaTriggerEntry* trigger) const { - if (!trigger || GetMapId() != trigger->mapid) + if (!trigger) return false; + if (int32(GetMapId()) != trigger->mapid && !GetPhaseShift().HasVisibleMapId(trigger->mapid)) + return false; + + if (trigger->PhaseID || trigger->PhaseGroupID || trigger->PhaseUseFlags) + if (!PhasingHandler::InDbPhaseShift(this, trigger->PhaseUseFlags, trigger->PhaseID, trigger->PhaseGroupID)) + return false; + if (trigger->radius > 0.f) { // if we have radius check it diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 757a219462..8669e13c45 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -3924,7 +3924,7 @@ void Unit::RemoveNotOwnSingleTargetAuras(bool onPhaseChange /*= false*/) for (AuraList::iterator iter = scAuras.begin(); iter != scAuras.end();) { Aura* aura = *iter; - if (aura->GetUnitOwner() != this && !aura->GetUnitOwner()->IsInPhase(this)) + if (aura->GetUnitOwner() != this && (!onPhaseChange || !aura->GetUnitOwner()->IsInPhase(this))) { aura->Remove(); iter = scAuras.begin(); diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 7f39a3992a..9c972139b4 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1704,15 +1704,17 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app Unit* target = aurApp->GetTarget(); - PhasingHandler::AddPhase(target, uint32(GetMiscValueB()), true); - - // call functions which may have additional effects after chainging state of unit - // phase auras normally not expected at BG but anyway better check if (apply) { + PhasingHandler::AddPhase(target, uint32(GetMiscValueB()), true); + + // call functions which may have additional effects after chainging state of unit + // phase auras normally not expected at BG but anyway better check // drop flag at invisibiliy in bg target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } + else + PhasingHandler::RemovePhase(target, uint32(GetMiscValueB()), true); } void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, bool apply) const @@ -1724,13 +1726,17 @@ void AuraEffect::HandlePhaseGroup(AuraApplication const* aurApp, uint8 mode, boo PhasingHandler::AddPhaseGroup(target, uint32(GetMiscValueB()), true); - // call functions which may have additional effects after chainging state of unit - // phase auras normally not expected at BG but anyway better check if (apply) { + PhasingHandler::AddPhaseGroup(target, uint32(GetMiscValueB()), true); + + // call functions which may have additional effects after chainging state of unit + // phase auras normally not expected at BG but anyway better check // drop flag at invisibiliy in bg target->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_IMMUNE_OR_LOST_SELECTION); } + else + PhasingHandler::RemovePhaseGroup(target, uint32(GetMiscValueB()), true); } /**********************/