fix(Core/Battlegrounds): Delay a little bit relocation of dead players. (#9302)
Fixes #8958
This commit is contained in:
@@ -204,6 +204,8 @@ Battleground::Battleground()
|
|||||||
|
|
||||||
Battleground::~Battleground()
|
Battleground::~Battleground()
|
||||||
{
|
{
|
||||||
|
_reviveEvents.KillAllEvents(false);
|
||||||
|
|
||||||
// remove objects and creatures
|
// remove objects and creatures
|
||||||
// (this is done automatically in mapmanager update, when the instance is reset after the reset time)
|
// (this is done automatically in mapmanager update, when the instance is reset after the reset time)
|
||||||
uint32 size = uint32(BgCreatures.size());
|
uint32 size = uint32(BgCreatures.size());
|
||||||
@@ -325,6 +327,9 @@ inline void Battleground::_ProcessResurrect(uint32 diff)
|
|||||||
// *** BATTLEGROUND RESURRECTION SYSTEM ***
|
// *** BATTLEGROUND RESURRECTION SYSTEM ***
|
||||||
// *********************************************************
|
// *********************************************************
|
||||||
// this should be handled by spell system
|
// this should be handled by spell system
|
||||||
|
|
||||||
|
_reviveEvents.Update(diff);
|
||||||
|
|
||||||
m_LastResurrectTime += diff;
|
m_LastResurrectTime += diff;
|
||||||
if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
|
if (m_LastResurrectTime >= RESURRECTION_INTERVAL)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -668,6 +668,9 @@ protected:
|
|||||||
|
|
||||||
// pussywizard:
|
// pussywizard:
|
||||||
uint32 m_UpdateTimer;
|
uint32 m_UpdateTimer;
|
||||||
|
|
||||||
|
EventProcessor _reviveEvents;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Battleground
|
// Battleground
|
||||||
BattlegroundTypeId m_RealTypeID;
|
BattlegroundTypeId m_RealTypeID;
|
||||||
|
|||||||
@@ -281,9 +281,13 @@ void BattlegroundAB::NodeDeoccupied(uint8 node)
|
|||||||
--_controlledPoints[_capturePointInfo[node]._ownerTeamId];
|
--_controlledPoints[_capturePointInfo[node]._ownerTeamId];
|
||||||
|
|
||||||
_capturePointInfo[node]._ownerTeamId = TEAM_NEUTRAL;
|
_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
|
DelCreature(BG_AB_ALL_NODES_COUNT + node); // Delete aura trigger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -790,15 +790,22 @@ void BattlegroundAV::PopulateNode(BG_AV_Nodes node)
|
|||||||
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
|
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);
|
uint32 c_place = AV_CPLACE_DEFENSE_STORM_AID + (4 * node);
|
||||||
for (uint8 i = 0; i < 4; i++)
|
for (uint8 i = 0; i < 4; i++)
|
||||||
|
{
|
||||||
if (BgCreatures[c_place + i])
|
if (BgCreatures[c_place + i])
|
||||||
|
{
|
||||||
DelCreature(c_place + i);
|
DelCreature(c_place + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//spiritguide
|
//spiritguide
|
||||||
if (!IsTower(node) && BgCreatures[node])
|
if (!ignoreSpiritGuide && !IsTower(node))
|
||||||
|
{
|
||||||
DelCreature(node);
|
DelCreature(node);
|
||||||
|
}
|
||||||
|
|
||||||
//remove bonus honor aura trigger creature when node is lost
|
//remove bonus honor aura trigger creature when node is lost
|
||||||
if (node < BG_AV_NODES_MAX)//fail safe
|
if (node < BG_AV_NODES_MAX)//fail safe
|
||||||
@@ -1031,6 +1038,8 @@ void BattlegroundAV::EventPlayerAssaultsPoint(Player* player, uint32 object)
|
|||||||
SpawnBGObject(object - 22, RESPAWN_IMMEDIATELY);
|
SpawnBGObject(object - 22, RESPAWN_IMMEDIATELY);
|
||||||
else
|
else
|
||||||
SpawnBGObject(object + 22, RESPAWN_IMMEDIATELY);
|
SpawnBGObject(object + 22, RESPAWN_IMMEDIATELY);
|
||||||
|
|
||||||
|
bool ignoreSpiritGuide = false;
|
||||||
if (IsTower(node))
|
if (IsTower(node))
|
||||||
{
|
{
|
||||||
//spawning/despawning of bigflag+aura
|
//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(BG_AV_OBJECT_AURA_N_FIRSTAID_STATION + 3 * node, RESPAWN_IMMEDIATELY); //neutral aura spawn
|
||||||
SpawnBGObject(static_cast<uint8>(BG_AV_OBJECT_AURA_A_FIRSTAID_STATION) + prevOwnerId + 3 * node, RESPAWN_ONE_DAY); //teeamaura despawn
|
SpawnBGObject(static_cast<uint8>(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
|
SpawnBGObject(object, RESPAWN_ONE_DAY); //delete old banner
|
||||||
|
|||||||
@@ -1621,7 +1621,7 @@ private:
|
|||||||
void DefendNode(BG_AV_Nodes node, TeamId teamId);
|
void DefendNode(BG_AV_Nodes node, TeamId teamId);
|
||||||
|
|
||||||
void PopulateNode(BG_AV_Nodes node);
|
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);
|
BG_AV_Nodes GetNodeThroughObject(uint32 object);
|
||||||
uint32 GetObjectThroughNode(BG_AV_Nodes node);
|
uint32 GetObjectThroughNode(BG_AV_Nodes node);
|
||||||
|
|||||||
@@ -566,78 +566,89 @@ void BattlegroundIC::EventPlayerClickedOnFlag(Player* player, GameObject* gameOb
|
|||||||
// All the node points are iterated to find the clicked one
|
// All the node points are iterated to find the clicked one
|
||||||
for (uint8 i = 0; i < MAX_NODE_TYPES; ++i)
|
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
|
// THIS SHOULD NEEVEER HAPPEN
|
||||||
if (nodePoint[i].faction == player->GetTeamId())
|
if (point.faction == player->GetTeamId())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Prevent capturing of keep if none of gates was destroyed
|
// 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 &&
|
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)
|
||||||
GateStatus[BG_IC_A_WEST] != BG_IC_GATE_DESTROYED &&
|
{
|
||||||
GateStatus[BG_IC_A_EAST] != BG_IC_GATE_DESTROYED)
|
|
||||||
return;
|
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 &&
|
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)
|
||||||
GateStatus[BG_IC_H_WEST] != BG_IC_GATE_DESTROYED &&
|
{
|
||||||
GateStatus[BG_IC_H_EAST] != BG_IC_GATE_DESTROYED)
|
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 nextBanner = GetNextBanner(&nodePoint[i], player->GetTeamId(), false);
|
uint32 nextBanner = GetNextBanner(&point, player->GetTeamId(), false);
|
||||||
|
|
||||||
// we set the new settings of the nodePoint
|
// we set the new settings of the nodePoint
|
||||||
nodePoint[i].faction = player->GetTeamId();
|
point.faction = player->GetTeamId();
|
||||||
nodePoint[i].last_entry = nodePoint[i].gameobject_entry;
|
point.last_entry = point.gameobject_entry;
|
||||||
nodePoint[i].gameobject_entry = nextBanner;
|
point.gameobject_entry = nextBanner;
|
||||||
|
|
||||||
// this is just needed if the next banner is grey
|
// 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)
|
point.timer = BANNER_STATE_CHANGE_TIME; // 1 minute for last change (real faction banner)
|
||||||
nodePoint[i].needChange = true;
|
point.needChange = true;
|
||||||
|
|
||||||
RelocateDeadPlayers(BgCreatures[static_cast<uint16>(BG_IC_NPC_SPIRIT_GUIDE_1) + nodePoint[i].nodeType - 2]);
|
_reviveEvents.AddEventAtOffset([this, point]()
|
||||||
|
{
|
||||||
|
RelocateDeadPlayers(BgCreatures[static_cast<uint16>(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 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 (nodePoint[i].nodeType != NODE_TYPE_REFINERY && nodePoint[i].nodeType != NODE_TYPE_QUARRY)
|
{
|
||||||
if (BgCreatures[static_cast<uint16>(BG_IC_NPC_SPIRIT_GUIDE_1) + (nodePoint[i].nodeType) - 2])
|
if (BgCreatures[static_cast<uint16>(BG_IC_NPC_SPIRIT_GUIDE_1) + (point.nodeType) - 2])
|
||||||
DelCreature(static_cast<uint16>(BG_IC_NPC_SPIRIT_GUIDE_1) + (nodePoint[i].nodeType) - 2);
|
{
|
||||||
|
DelCreature(static_cast<uint16>(BG_IC_NPC_SPIRIT_GUIDE_1) + (point.nodeType) - 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 500ms);
|
||||||
|
|
||||||
UpdatePlayerScore(player, SCORE_BASES_ASSAULTED, 1);
|
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_1, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, point.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));
|
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(&nodePoint[i]);
|
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
|
// if we are going to spawn the definitve faction banner, we dont need the timer anymore
|
||||||
{
|
{
|
||||||
nodePoint[i].timer = BANNER_STATE_CHANGE_TIME;
|
point.timer = BANNER_STATE_CHANGE_TIME;
|
||||||
nodePoint[i].needChange = false;
|
point.needChange = false;
|
||||||
SendMessage2ToAll(LANG_BG_IC_TEAM_DEFENDED_NODE, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, nodePoint[i].string);
|
SendMessage2ToAll(LANG_BG_IC_TEAM_DEFENDED_NODE, CHAT_MSG_BG_SYSTEM_NEUTRAL, player, point.string);
|
||||||
HandleCapturedNodes(&nodePoint[i], true);
|
HandleCapturedNodes(&point, true);
|
||||||
UpdatePlayerScore(player, SCORE_BASES_DEFENDED, 1);
|
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
|
if (!banner) // this should never happen
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() };
|
float cords[4] = {banner->GetPositionX(), banner->GetPositionY(), banner->GetPositionZ(), banner->GetOrientation() };
|
||||||
|
|
||||||
DelObject(nodePoint[i].gameobject_type);
|
DelObject(point.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);
|
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
|
// 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.
|
// If the needChange bool was set true, we will handle the rest in the Update Map function.
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user