diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp index ac1e647b2..5aa3f3069 100644 --- a/src/server/game/Battlegrounds/Battleground.cpp +++ b/src/server/game/Battlegrounds/Battleground.cpp @@ -204,6 +204,8 @@ Battleground::Battleground() Battleground::~Battleground() { + _reviveEvents.KillAllEvents(false); + // remove objects and creatures // (this is done automatically in mapmanager update, when the instance is reset after the reset time) uint32 size = uint32(BgCreatures.size()); @@ -325,6 +327,9 @@ inline void Battleground::_ProcessResurrect(uint32 diff) // *** BATTLEGROUND RESURRECTION SYSTEM *** // ********************************************************* // this should be handled by spell system + + _reviveEvents.Update(diff); + m_LastResurrectTime += diff; if (m_LastResurrectTime >= RESURRECTION_INTERVAL) { diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h index 54c7e8553..b3734621e 100644 --- a/src/server/game/Battlegrounds/Battleground.h +++ b/src/server/game/Battlegrounds/Battleground.h @@ -668,6 +668,9 @@ protected: // pussywizard: uint32 m_UpdateTimer; + + EventProcessor _reviveEvents; + private: // Battleground BattlegroundTypeId m_RealTypeID; diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp index 41920d0f5..3c84c5dc9 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAB.cpp @@ -281,9 +281,13 @@ void BattlegroundAB::NodeDeoccupied(uint8 node) --_controlledPoints[_capturePointInfo[node]._ownerTeamId]; _capturePointInfo[node]._ownerTeamId = TEAM_NEUTRAL; - RelocateDeadPlayers(BgCreatures[node]); - DelCreature(node); // Delete spirit healer + _reviveEvents.AddEventAtOffset([this, node]() + { + RelocateDeadPlayers(BgCreatures[node]); + DelCreature(node); // Delete spirit healer + }, 500ms); + DelCreature(BG_AB_ALL_NODES_COUNT + node); // Delete aura trigger } diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp index e1827861b..2fbca7a3a 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.cpp @@ -790,15 +790,22 @@ void BattlegroundAV::PopulateNode(BG_AV_Nodes node) trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false); } } -void BattlegroundAV::DePopulateNode(BG_AV_Nodes node) +void BattlegroundAV::DePopulateNode(BG_AV_Nodes node, bool ignoreSpiritGuide) { uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + (4 * node); for (uint8 i = 0; i < 4; i++) + { if (BgCreatures[c_place + i]) + { DelCreature(c_place + i); + } + } + //spiritguide - if (!IsTower(node) && BgCreatures[node]) + if (!ignoreSpiritGuide && !IsTower(node)) + { DelCreature(node); + } //remove bonus honor aura trigger creature when node is lost if (node < BG_AV_NODES_MAX)//fail safe @@ -1031,6 +1038,8 @@ void BattlegroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) SpawnBGObject(object - 22, RESPAWN_IMMEDIATELY); else SpawnBGObject(object + 22, RESPAWN_IMMEDIATELY); + + bool ignoreSpiritGuide = false; if (IsTower(node)) { //spawning/despawning of bigflag+aura @@ -1045,9 +1054,18 @@ void BattlegroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object) SpawnBGObject(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION + 3 * node, RESPAWN_IMMEDIATELY); //neutral aura spawn SpawnBGObject(static_cast(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION) + prevOwnerId + 3 * node, RESPAWN_ONE_DAY); //teeamaura despawn - RelocateDeadPlayers(BgCreatures[node]); + ignoreSpiritGuide = true; + + _reviveEvents.AddEventAtOffset([this, node]() + { + RelocateDeadPlayers(BgCreatures[node]); + + if (!IsTower(node)) + DelCreature(node); // Delete spirit healer + }, 500ms); } - DePopulateNode(node); + + DePopulateNode(node, ignoreSpiritGuide); } SpawnBGObject(object, RESPAWN_ONE_DAY); //delete old banner diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h index 23402390c..dcde68101 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundAV.h +++ b/src/server/game/Battlegrounds/Zones/BattlegroundAV.h @@ -1621,7 +1621,7 @@ private: void DefendNode(BG_AV_Nodes node, TeamId teamId); void PopulateNode(BG_AV_Nodes node); - void DePopulateNode(BG_AV_Nodes node); + void DePopulateNode(BG_AV_Nodes node, bool ignoreSpiritGuid = false); BG_AV_Nodes GetNodeThroughObject(uint32 object); uint32 GetObjectThroughNode(BG_AV_Nodes node); diff --git a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp index cf033f7ee..3c9388c06 100644 --- a/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp +++ b/src/server/game/Battlegrounds/Zones/BattlegroundIC.cpp @@ -566,78 +566,89 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* gameOb // All the node points are iterated to find the clicked one for (uint8 i = 0; i < MAX_NODE_TYPES; ++i) { - if (nodePoint[i].gameobject_entry == gameObject->GetEntry()) + ICNodePoint& point = nodePoint[i]; + if (point.gameobject_entry == gameObject->GetEntry()) { // THIS SHOULD NEEVEER HAPPEN - if (nodePoint[i].faction == player->GetTeamId()) + if (point.faction == player->GetTeamId()) + { return; + } // Prevent capturing of keep if none of gates was destroyed - if (nodePoint[i].gameobject_entry == GO_ALLIANCE_BANNER) + if (point.gameobject_entry == GO_ALLIANCE_BANNER) { - if (GateStatus[BG_IC_A_FRONT] != BG_IC_GATE_DESTROYED && - GateStatus[BG_IC_A_WEST] != BG_IC_GATE_DESTROYED && - GateStatus[BG_IC_A_EAST] != BG_IC_GATE_DESTROYED) + if (GateStatus[BG_IC_A_FRONT] != BG_IC_GATE_DESTROYED && GateStatus[BG_IC_A_WEST] != BG_IC_GATE_DESTROYED && GateStatus[BG_IC_A_EAST] != BG_IC_GATE_DESTROYED) + { return; + } } - else if (nodePoint[i].gameobject_entry == GO_HORDE_BANNER) + else if (point.gameobject_entry == GO_HORDE_BANNER) { - if (GateStatus[BG_IC_H_FRONT] != BG_IC_GATE_DESTROYED && - GateStatus[BG_IC_H_WEST] != BG_IC_GATE_DESTROYED && - GateStatus[BG_IC_H_EAST] != BG_IC_GATE_DESTROYED) + if (GateStatus[BG_IC_H_FRONT] != BG_IC_GATE_DESTROYED && GateStatus[BG_IC_H_WEST] != BG_IC_GATE_DESTROYED && GateStatus[BG_IC_H_EAST] != BG_IC_GATE_DESTROYED) + { return; + } } - uint32 nextBanner = GetNextBanner(&nodePoint[i], player->GetTeamId(), false); + uint32 nextBanner = GetNextBanner(&point, player->GetTeamId(), false); // we set the new settings of the nodePoint - nodePoint[i].faction = player->GetTeamId(); - nodePoint[i].last_entry = nodePoint[i].gameobject_entry; - nodePoint[i].gameobject_entry = nextBanner; + point.faction = player->GetTeamId(); + point.last_entry = point.gameobject_entry; + point.gameobject_entry = nextBanner; // this is just needed if the next banner is grey - if (nodePoint[i].banners[BANNER_A_CONTESTED] == nextBanner || nodePoint[i].banners[BANNER_H_CONTESTED] == nextBanner) + if (point.banners[BANNER_A_CONTESTED] == nextBanner || point.banners[BANNER_H_CONTESTED] == nextBanner) { - nodePoint[i].timer = BANNER_STATE_CHANGE_TIME; // 1 minute for last change (real faction banner) - nodePoint[i].needChange = true; + point.timer = BANNER_STATE_CHANGE_TIME; // 1 minute for last change (real faction banner) + point.needChange = true; - RelocateDeadPlayers(BgCreatures[static_cast(BG_IC_NPC_SPIRIT_GUIDE_1) + nodePoint[i].nodeType - 2]); + _reviveEvents.AddEventAtOffset([this, point]() + { + RelocateDeadPlayers(BgCreatures[static_cast(BG_IC_NPC_SPIRIT_GUIDE_1) + point.nodeType - 2]); - // if we are here means that the point has been lost, or it is the first capture - - if (nodePoint[i].nodeType != NODE_TYPE_REFINERY && nodePoint[i].nodeType != NODE_TYPE_QUARRY) - if (BgCreatures[static_cast(BG_IC_NPC_SPIRIT_GUIDE_1) + (nodePoint[i].nodeType) - 2]) - DelCreature(static_cast(BG_IC_NPC_SPIRIT_GUIDE_1) + (nodePoint[i].nodeType) - 2); + // if we are here means that the point has been lost, or it is the first capture + if (point.nodeType != NODE_TYPE_REFINERY && point.nodeType != NODE_TYPE_QUARRY) + { + if (BgCreatures[static_cast(BG_IC_NPC_SPIRIT_GUIDE_1) + (point.nodeType) - 2]) + { + DelCreature(static_cast(BG_IC_NPC_SPIRIT_GUIDE_1) + (point.nodeType) - 2); + } + } + }, 500ms); UpdatePlayerScore(player, SCORE_BASES_ASSAULTED, 1); - SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_1, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, nodePoint[i].string); - SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_2, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, nodePoint[i].string, (player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE)); - HandleContestedNodes(&nodePoint[i]); + SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_1, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, point.string); + SendMessage2ToAll(LANG_BG_IC_TEAM_ASSAULTED_NODE_2, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, point.string, (player->GetTeamId() == TEAM_ALLIANCE ? LANG_BG_IC_ALLIANCE : LANG_BG_IC_HORDE)); + HandleContestedNodes(&point); } - else if (nextBanner == nodePoint[i].banners[BANNER_A_CONTROLLED] || nextBanner == nodePoint[i].banners[BANNER_H_CONTROLLED]) + else if (nextBanner == point.banners[BANNER_A_CONTROLLED] || nextBanner == point.banners[BANNER_H_CONTROLLED]) // if we are going to spawn the definitve faction banner, we dont need the timer anymore { - nodePoint[i].timer = BANNER_STATE_CHANGE_TIME; - nodePoint[i].needChange = false; - SendMessage2ToAll(LANG_BG_IC_TEAM_DEFENDED_NODE, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, nodePoint[i].string); - HandleCapturedNodes(&nodePoint[i], true); + point.timer = BANNER_STATE_CHANGE_TIME; + point.needChange = false; + SendMessage2ToAll(LANG_BG_IC_TEAM_DEFENDED_NODE, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, point.string); + HandleCapturedNodes(&point, true); UpdatePlayerScore(player, SCORE_BASES_DEFENDED, 1); } - GameObject* banner = GetBGObject(nodePoint[i].gameobject_type); + GameObject* banner = GetBGObject(point.gameobject_type); if (!banner) // this should never happen + { return; + } float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() }; - DelObject(nodePoint[i].gameobject_type); - AddObject(nodePoint[i].gameobject_type, nodePoint[i].gameobject_entry, cords[0], cords[1], cords[2], cords[3], 0, 0, 0, 0, RESPAWN_ONE_DAY); + DelObject(point.gameobject_type); + AddObject(point.gameobject_type, point.gameobject_entry, cords[0], cords[1], cords[2], cords[3], 0, 0, 0, 0, RESPAWN_ONE_DAY); - GetBGObject(nodePoint[i].gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, nodePoint[i].faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]); + GetBGObject(point.gameobject_type)->SetUInt32Value(GAMEOBJECT_FACTION, point.faction == TEAM_ALLIANCE ? BG_IC_Factions[1] : BG_IC_Factions[0]); - UpdateNodeWorldState(&nodePoint[i]); + UpdateNodeWorldState(&point); // we dont need iterating if we are here // If the needChange bool was set true, we will handle the rest in the Update Map function. return;