mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Core/GameObject: Implement ControlZone gameobject type (#29320)
This commit is contained in:
@@ -62,9 +62,6 @@ Battlefield::Battlefield(Map* map)
|
||||
|
||||
Battlefield::~Battlefield()
|
||||
{
|
||||
for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
delete itr->second;
|
||||
|
||||
for (GraveyardVect::const_iterator itr = m_GraveyardList.begin(); itr != m_GraveyardList.end(); ++itr)
|
||||
delete *itr;
|
||||
}
|
||||
@@ -114,9 +111,6 @@ void Battlefield::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/)
|
||||
}
|
||||
}
|
||||
|
||||
for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
itr->second->HandlePlayerLeave(player);
|
||||
|
||||
m_InvitedPlayers[player->GetTeamId()].erase(player->GetGUID());
|
||||
m_PlayersWillBeKick[player->GetTeamId()].erase(player->GetGUID());
|
||||
m_players[player->GetTeamId()].erase(player->GetGUID());
|
||||
@@ -145,7 +139,6 @@ bool Battlefield::Update(uint32 diff)
|
||||
OnStartGrouping();
|
||||
}
|
||||
|
||||
bool objective_changed = false;
|
||||
if (IsWarTime())
|
||||
{
|
||||
if (m_uiKickAfkPlayersTimer <= diff)
|
||||
@@ -175,13 +168,9 @@ bool Battlefield::Update(uint32 diff)
|
||||
}
|
||||
else
|
||||
m_uiKickDontAcceptTimer -= diff;
|
||||
|
||||
for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
if (itr->second->Update(diff))
|
||||
objective_changed = true;
|
||||
}
|
||||
|
||||
return objective_changed;
|
||||
return false;
|
||||
}
|
||||
|
||||
void Battlefield::InvitePlayersInZoneToQueue()
|
||||
@@ -285,6 +274,42 @@ void Battlefield::InitStalker(uint32 entry, Position const& pos)
|
||||
TC_LOG_ERROR("bg.battlefield", "Battlefield::InitStalker: Could not spawn Stalker (Creature entry {}), zone messages will be unavailable!", entry);
|
||||
}
|
||||
|
||||
void Battlefield::ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker)
|
||||
{
|
||||
ZoneScript::ProcessEvent(target, eventId, invoker);
|
||||
|
||||
if (invoker)
|
||||
{
|
||||
if (GameObject* gameobject = invoker->ToGameObject())
|
||||
{
|
||||
if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
{
|
||||
if (!ControlZoneHandlers.contains(gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
auto controlzone = gameobject->GetGOInfo()->controlZone;
|
||||
BattlefieldControlZoneHandler& handler = *ControlZoneHandlers[invoker->GetEntry()];
|
||||
if (eventId == controlzone.CaptureEventAlliance)
|
||||
handler.HandleCaptureEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.CaptureEventHorde)
|
||||
handler.HandleCaptureEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ContestedEventAlliance)
|
||||
handler.HandleContestedEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ContestedEventHorde)
|
||||
handler.HandleContestedEventHorde(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventAlliance)
|
||||
handler.HandleNeutralEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventHorde)
|
||||
handler.HandleNeutralEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventAlliance)
|
||||
handler.HandleProgressEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventHorde)
|
||||
handler.HandleProgressEventHorde(gameobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Battlefield::KickAfkPlayers()
|
||||
{
|
||||
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
||||
@@ -435,25 +460,6 @@ void Battlefield::SendWarning(uint8 id, WorldObject const* target /*= nullptr*/)
|
||||
sCreatureTextMgr->SendChat(stalker, id, target);
|
||||
}
|
||||
|
||||
void Battlefield::AddCapturePoint(BfCapturePoint* cp)
|
||||
{
|
||||
Battlefield::BfCapturePointMap::iterator i = m_capturePoints.find(cp->GetCapturePointEntry());
|
||||
if (i != m_capturePoints.end())
|
||||
{
|
||||
TC_LOG_ERROR("bg.battlefield", "Battlefield::AddCapturePoint: CapturePoint {} already exists!", cp->GetCapturePointEntry());
|
||||
delete i->second;
|
||||
}
|
||||
m_capturePoints[cp->GetCapturePointEntry()] = cp;
|
||||
}
|
||||
|
||||
BfCapturePoint* Battlefield::GetCapturePoint(uint32 entry) const
|
||||
{
|
||||
Battlefield::BfCapturePointMap::const_iterator itr = m_capturePoints.find(entry);
|
||||
if (itr != m_capturePoints.end())
|
||||
return itr->second;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Battlefield::RegisterZone(uint32 zoneId)
|
||||
{
|
||||
sBattlefieldMgr->AddZone(zoneId, this);
|
||||
@@ -722,275 +728,11 @@ GameObject* Battlefield::GetGameObject(ObjectGuid guid)
|
||||
// ******************* CapturePoint **********************
|
||||
// *******************************************************
|
||||
|
||||
BfCapturePoint::BfCapturePoint(Battlefield* battlefield) : m_Bf(battlefield), m_capturePointGUID()
|
||||
BattlefieldControlZoneHandler::BattlefieldControlZoneHandler(Battlefield* bf) : _battlefield(bf)
|
||||
{
|
||||
m_team = TEAM_NEUTRAL;
|
||||
m_value = 0;
|
||||
m_minValue = 0.0f;
|
||||
m_maxValue = 0.0f;
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL;
|
||||
m_OldState = BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL;
|
||||
m_capturePointEntry = 0;
|
||||
m_neutralValuePct = 0;
|
||||
m_maxSpeed = 0;
|
||||
}
|
||||
|
||||
bool BfCapturePoint::HandlePlayerEnter(Player* player)
|
||||
Battlefield* BattlefieldControlZoneHandler::GetBattlefield()
|
||||
{
|
||||
if (!m_capturePointGUID.IsEmpty())
|
||||
{
|
||||
if (GameObject* capturePoint = m_Bf->GetGameObject(m_capturePointGUID))
|
||||
{
|
||||
player->SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldState1, 1);
|
||||
player->SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldstate2, uint32(ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f)));
|
||||
player->SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldstate3, m_neutralValuePct);
|
||||
}
|
||||
}
|
||||
|
||||
return m_activePlayers[player->GetTeamId()].insert(player->GetGUID()).second;
|
||||
}
|
||||
|
||||
GuidSet::iterator BfCapturePoint::HandlePlayerLeave(Player* player)
|
||||
{
|
||||
if (!m_capturePointGUID.IsEmpty())
|
||||
if (GameObject* capturePoint = m_Bf->GetGameObject(m_capturePointGUID))
|
||||
player->SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldState1, 0);
|
||||
|
||||
GuidSet::iterator current = m_activePlayers[player->GetTeamId()].find(player->GetGUID());
|
||||
|
||||
if (current == m_activePlayers[player->GetTeamId()].end())
|
||||
return current; // return end()
|
||||
|
||||
m_activePlayers[player->GetTeamId()].erase(current++);
|
||||
return current;
|
||||
}
|
||||
|
||||
void BfCapturePoint::SendChangePhase()
|
||||
{
|
||||
if (!m_capturePointGUID)
|
||||
return;
|
||||
|
||||
if (GameObject* capturePoint = m_Bf->GetGameObject(m_capturePointGUID))
|
||||
{
|
||||
// send this too, sometimes the slider disappears, dunno why :(
|
||||
SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldState1, 1);
|
||||
// send these updates to only the ones in this objective
|
||||
SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldstate2, (uint32)std::ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f));
|
||||
// send this too, sometimes it resets :S
|
||||
SendUpdateWorldState(capturePoint->GetGOInfo()->controlZone.worldstate3, m_neutralValuePct);
|
||||
}
|
||||
}
|
||||
|
||||
bool BfCapturePoint::SetCapturePointData(GameObject* capturePoint)
|
||||
{
|
||||
ASSERT(capturePoint);
|
||||
|
||||
TC_LOG_DEBUG("bg.battlefield", "Creating capture point {}", capturePoint->GetEntry());
|
||||
|
||||
m_capturePointGUID = capturePoint->GetGUID();
|
||||
m_capturePointEntry = capturePoint->GetEntry();
|
||||
|
||||
// check info existence
|
||||
GameObjectTemplate const* goinfo = capturePoint->GetGOInfo();
|
||||
if (goinfo->type != GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
{
|
||||
TC_LOG_ERROR("misc", "OutdoorPvP: GO {} is not a capture point!", capturePoint->GetEntry());
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the needed values from goinfo
|
||||
m_maxValue = goinfo->controlZone.maxTime;
|
||||
m_maxSpeed = m_maxValue / (goinfo->controlZone.minTime ? goinfo->controlZone.minTime : 60);
|
||||
m_neutralValuePct = goinfo->controlZone.neutralPercent;
|
||||
m_minValue = m_maxValue * goinfo->controlZone.neutralPercent / 100;
|
||||
|
||||
if (m_team == TEAM_ALLIANCE)
|
||||
{
|
||||
m_value = m_maxValue;
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_value = -m_maxValue;
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
GameObject* BfCapturePoint::GetCapturePointGo()
|
||||
{
|
||||
return m_Bf->GetGameObject(m_capturePointGUID);
|
||||
}
|
||||
|
||||
bool BfCapturePoint::DelCapturePoint()
|
||||
{
|
||||
if (!m_capturePointGUID.IsEmpty())
|
||||
{
|
||||
if (GameObject* capturePoint = m_Bf->GetGameObject(m_capturePointGUID))
|
||||
{
|
||||
capturePoint->SetRespawnTime(0); // not save respawn time
|
||||
capturePoint->Delete();
|
||||
capturePoint = nullptr;
|
||||
}
|
||||
m_capturePointGUID.Clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BfCapturePoint::Update(uint32 diff)
|
||||
{
|
||||
if (!m_capturePointGUID)
|
||||
return false;
|
||||
|
||||
if (GameObject* capturePoint = m_Bf->GetGameObject(m_capturePointGUID))
|
||||
{
|
||||
float radius = capturePoint->GetGOInfo()->controlZone.radius;
|
||||
|
||||
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
||||
{
|
||||
for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end();)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
||||
{
|
||||
if (!capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive())
|
||||
itr = HandlePlayerLeave(player);
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
else
|
||||
++itr;
|
||||
}
|
||||
}
|
||||
|
||||
std::list<Player*> players;
|
||||
Trinity::AnyPlayerInObjectRangeCheck checker(capturePoint, radius);
|
||||
Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(capturePoint, players, checker);
|
||||
Cell::VisitWorldObjects(capturePoint, searcher, radius);
|
||||
|
||||
for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
if ((*itr)->IsOutdoorPvPActive())
|
||||
if (m_activePlayers[(*itr)->GetTeamId()].insert((*itr)->GetGUID()).second)
|
||||
HandlePlayerEnter(*itr);
|
||||
}
|
||||
|
||||
// get the difference of numbers
|
||||
float fact_diff = ((float) m_activePlayers[TEAM_ALLIANCE].size() - (float) m_activePlayers[TEAM_HORDE].size()) * diff / float(BATTLEFIELD_OBJECTIVE_UPDATE_INTERVAL);
|
||||
if (G3D::fuzzyEq(fact_diff, 0.0f))
|
||||
return false;
|
||||
|
||||
uint32 Challenger = 0;
|
||||
float maxDiff = m_maxSpeed * diff;
|
||||
|
||||
if (fact_diff < 0)
|
||||
{
|
||||
// horde is in majority, but it's already horde-controlled -> no change
|
||||
if (m_State == BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE && m_value <= -m_maxValue)
|
||||
return false;
|
||||
|
||||
if (fact_diff < -maxDiff)
|
||||
fact_diff = -maxDiff;
|
||||
|
||||
Challenger = HORDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ally is in majority, but it's already ally-controlled -> no change
|
||||
if (m_State == BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE && m_value >= m_maxValue)
|
||||
return false;
|
||||
|
||||
if (fact_diff > maxDiff)
|
||||
fact_diff = maxDiff;
|
||||
|
||||
Challenger = ALLIANCE;
|
||||
}
|
||||
|
||||
float oldValue = m_value;
|
||||
TeamId oldTeam = m_team;
|
||||
|
||||
m_OldState = m_State;
|
||||
|
||||
m_value += fact_diff;
|
||||
|
||||
if (m_value < -m_minValue) // red
|
||||
{
|
||||
if (m_value < -m_maxValue)
|
||||
m_value = -m_maxValue;
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE;
|
||||
m_team = TEAM_HORDE;
|
||||
}
|
||||
else if (m_value > m_minValue) // blue
|
||||
{
|
||||
if (m_value > m_maxValue)
|
||||
m_value = m_maxValue;
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE;
|
||||
m_team = TEAM_ALLIANCE;
|
||||
}
|
||||
else if (oldValue * m_value <= 0) // grey, go through mid point
|
||||
{
|
||||
// if challenger is ally, then n->a challenge
|
||||
if (Challenger == ALLIANCE)
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE;
|
||||
// if challenger is horde, then n->h challenge
|
||||
else if (Challenger == HORDE)
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE;
|
||||
m_team = TEAM_NEUTRAL;
|
||||
}
|
||||
else // grey, did not go through mid point
|
||||
{
|
||||
// old phase and current are on the same side, so one team challenges the other
|
||||
if (Challenger == ALLIANCE && (m_OldState == BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE || m_OldState == BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE))
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE;
|
||||
else if (Challenger == HORDE && (m_OldState == BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE || m_OldState == BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE))
|
||||
m_State = BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE;
|
||||
m_team = TEAM_NEUTRAL;
|
||||
}
|
||||
|
||||
if (G3D::fuzzyNe(m_value, oldValue))
|
||||
SendChangePhase();
|
||||
|
||||
if (m_OldState != m_State)
|
||||
{
|
||||
//TC_LOG_ERROR("bg.battlefield", "{}->{}", m_OldState, m_State);
|
||||
if (oldTeam != m_team)
|
||||
ChangeTeam(oldTeam);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BfCapturePoint::SendUpdateWorldState(uint32 field, uint32 value)
|
||||
{
|
||||
for (uint8 team = 0; team < PVP_TEAMS_COUNT; ++team)
|
||||
for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr) // send to all players present in the area
|
||||
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
||||
player->SendUpdateWorldState(field, value);
|
||||
}
|
||||
|
||||
void BfCapturePoint::SendObjectiveComplete(uint32 id, ObjectGuid guid)
|
||||
{
|
||||
uint8 team;
|
||||
switch (m_State)
|
||||
{
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
|
||||
team = TEAM_ALLIANCE;
|
||||
break;
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
|
||||
team = TEAM_HORDE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// send to all players present in the area
|
||||
for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
||||
player->KilledMonsterCredit(id, guid);
|
||||
}
|
||||
|
||||
bool BfCapturePoint::IsInsideObjective(Player* player) const
|
||||
{
|
||||
return m_activePlayers[player->GetTeamId()].find(player->GetGUID()) != m_activePlayers[player->GetTeamId()].end();
|
||||
return _battlefield;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "SharedDefines.h"
|
||||
#include "ZoneScript.h"
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
||||
enum BattlefieldTypes
|
||||
{
|
||||
@@ -92,70 +93,16 @@ namespace WorldPackets
|
||||
typedef std::vector<BfGraveyard*> GraveyardVect;
|
||||
typedef std::map<ObjectGuid, time_t> PlayerTimerMap;
|
||||
|
||||
class TC_GAME_API BfCapturePoint
|
||||
class TC_GAME_API BattlefieldControlZoneHandler : public ControlZoneHandler
|
||||
{
|
||||
public:
|
||||
BfCapturePoint(Battlefield* bf);
|
||||
public:
|
||||
explicit BattlefieldControlZoneHandler(Battlefield* bf);
|
||||
virtual ~BattlefieldControlZoneHandler() = default;
|
||||
|
||||
virtual ~BfCapturePoint() { }
|
||||
|
||||
// Send world state update to all players present
|
||||
void SendUpdateWorldState(uint32 field, uint32 value);
|
||||
|
||||
// Send kill notify to players in the controlling faction
|
||||
void SendObjectiveComplete(uint32 id, ObjectGuid guid);
|
||||
|
||||
// Used when player is activated/inactivated in the area
|
||||
virtual bool HandlePlayerEnter(Player* player);
|
||||
virtual GuidSet::iterator HandlePlayerLeave(Player* player);
|
||||
//virtual void HandlePlayerActivityChanged(Player* player);
|
||||
|
||||
// Checks if player is in range of a capture credit marker
|
||||
bool IsInsideObjective(Player* player) const;
|
||||
|
||||
// Returns true if the state of the objective has changed, in this case, the OutdoorPvP must send a world state ui update.
|
||||
virtual bool Update(uint32 diff);
|
||||
virtual void ChangeTeam(TeamId /*oldTeam*/) { }
|
||||
virtual void SendChangePhase();
|
||||
|
||||
bool SetCapturePointData(GameObject* capturePoint);
|
||||
bool DelCapturePoint();
|
||||
GameObject* GetCapturePointGo();
|
||||
uint32 GetCapturePointEntry() const { return m_capturePointEntry; }
|
||||
|
||||
TeamId GetTeamId() const { return m_team; }
|
||||
BattlefieldObjectiveStates GetObjectiveState() const { return m_State; }
|
||||
|
||||
protected:
|
||||
// active Players in the area of the objective, 0 - alliance, 1 - horde
|
||||
GuidSet m_activePlayers[PVP_TEAMS_COUNT];
|
||||
|
||||
// Total shift needed to capture the objective
|
||||
float m_maxValue;
|
||||
float m_minValue;
|
||||
|
||||
// Maximum speed of capture
|
||||
float m_maxSpeed;
|
||||
|
||||
// The status of the objective
|
||||
float m_value;
|
||||
TeamId m_team;
|
||||
|
||||
// Objective states
|
||||
BattlefieldObjectiveStates m_OldState;
|
||||
BattlefieldObjectiveStates m_State;
|
||||
|
||||
// Neutral value on capture bar
|
||||
uint32 m_neutralValuePct;
|
||||
|
||||
// Pointer to the Battlefield this objective belongs to
|
||||
Battlefield* m_Bf;
|
||||
|
||||
// Capture point entry
|
||||
uint32 m_capturePointEntry;
|
||||
|
||||
// Gameobject related to that capture point
|
||||
ObjectGuid m_capturePointGUID;
|
||||
protected:
|
||||
Battlefield* GetBattlefield();
|
||||
private:
|
||||
Battlefield* _battlefield;
|
||||
};
|
||||
|
||||
class TC_GAME_API BfGraveyard
|
||||
@@ -205,7 +152,8 @@ class TC_GAME_API Battlefield : public ZoneScript
|
||||
virtual ~Battlefield();
|
||||
|
||||
/// typedef of map witch store capturepoint and the associate gameobject entry
|
||||
typedef std::map<uint32 /*lowguid */, BfCapturePoint*> BfCapturePointMap;
|
||||
|
||||
typedef std::unordered_map<uint32 /*control zone entry*/, std::unique_ptr<BattlefieldControlZoneHandler>> ControlZoneHandlerMap;
|
||||
|
||||
/// Call this to init the Battlefield
|
||||
virtual bool SetupBattlefield() { return true; }
|
||||
@@ -346,6 +294,7 @@ class TC_GAME_API Battlefield : public ZoneScript
|
||||
|
||||
void InitStalker(uint32 entry, Position const& pos);
|
||||
|
||||
void ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker) override;
|
||||
protected:
|
||||
ObjectGuid StalkerGuid;
|
||||
uint32 m_Timer; // Global timer for event
|
||||
@@ -354,7 +303,7 @@ class TC_GAME_API Battlefield : public ZoneScript
|
||||
TeamId m_DefenderTeam;
|
||||
|
||||
// Map of the objectives belonging to this OutdoorPvP
|
||||
BfCapturePointMap m_capturePoints;
|
||||
ControlZoneHandlerMap ControlZoneHandlers;
|
||||
|
||||
// Players info maps
|
||||
GuidUnorderedSet m_players[PVP_TEAMS_COUNT]; // Players in zone
|
||||
@@ -402,10 +351,6 @@ class TC_GAME_API Battlefield : public ZoneScript
|
||||
void BroadcastPacketToQueue(WorldPacket const* data) const;
|
||||
void BroadcastPacketToWar(WorldPacket const* data) const;
|
||||
|
||||
// CapturePoint system
|
||||
void AddCapturePoint(BfCapturePoint* cp);
|
||||
BfCapturePoint* GetCapturePoint(uint32 entry) const;
|
||||
|
||||
void RegisterZone(uint32 zoneid);
|
||||
bool HasPlayer(Player* player) const;
|
||||
void TeamCastSpell(TeamId team, int32 spellId);
|
||||
|
||||
@@ -91,20 +91,6 @@ void BattlegroundEY::PostUpdateImpl(uint32 diff)
|
||||
RespawnFlagAfterDrop();
|
||||
}
|
||||
}
|
||||
|
||||
m_TowerCapCheckTimer -= diff;
|
||||
if (m_TowerCapCheckTimer <= 0)
|
||||
{
|
||||
//check if player joined point
|
||||
/*I used this order of calls, because although we will check if one player is in gameobject's distance 2 times
|
||||
but we can count of players on current point in CheckSomeoneLeftPoint
|
||||
*/
|
||||
CheckSomeoneJoinedPoint();
|
||||
//check if player left point
|
||||
CheckSomeoneLeftPoint();
|
||||
UpdatePointStatuses();
|
||||
m_TowerCapCheckTimer = BG_EY_FPOINTS_TICK_TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,149 +150,6 @@ BattlegroundPointCaptureStatus BattlegroundEY::GetPointCaptureStatus(uint32 poin
|
||||
: BattlegroundPointCaptureStatus::HordeCapturing;
|
||||
}
|
||||
|
||||
void BattlegroundEY::CheckSomeoneJoinedPoint()
|
||||
{
|
||||
GameObject* obj = nullptr;
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]);
|
||||
if (obj)
|
||||
{
|
||||
uint8 j = 0;
|
||||
while (j < m_PlayersNearPoint[EY_POINTS_MAX].size())
|
||||
{
|
||||
Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[EY_POINTS_MAX][j]);
|
||||
if (!player)
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "BattlegroundEY:CheckSomeoneJoinedPoint: Player ({}) could not be found!", m_PlayersNearPoint[EY_POINTS_MAX][j].ToString());
|
||||
++j;
|
||||
continue;
|
||||
}
|
||||
if (player->CanCaptureTowerPoint() && player->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
{
|
||||
//player joined point!
|
||||
//show progress bar
|
||||
player->SendUpdateWorldState(PROGRESS_BAR_PERCENT_GREY, BG_EY_PROGRESS_BAR_PERCENT_GREY);
|
||||
player->SendUpdateWorldState(PROGRESS_BAR_STATUS, m_PointBarStatus[i]);
|
||||
player->SendUpdateWorldState(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_SHOW);
|
||||
//add player to point
|
||||
m_PlayersNearPoint[i].push_back(m_PlayersNearPoint[EY_POINTS_MAX][j]);
|
||||
//remove player from "free space"
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].erase(m_PlayersNearPoint[EY_POINTS_MAX].begin() + j);
|
||||
}
|
||||
else
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::CheckSomeoneLeftPoint()
|
||||
{
|
||||
//reset current point counts
|
||||
for (uint8 i = 0; i < 2*EY_POINTS_MAX; ++i)
|
||||
m_CurrentPointPlayersCount[i] = 0;
|
||||
GameObject* obj = nullptr;
|
||||
for (uint8 i = 0; i < EY_POINTS_MAX; ++i)
|
||||
{
|
||||
obj = GetBgMap()->GetGameObject(BgObjects[BG_EY_OBJECT_TOWER_CAP_FEL_REAVER + i]);
|
||||
if (obj)
|
||||
{
|
||||
uint8 j = 0;
|
||||
while (j < m_PlayersNearPoint[i].size())
|
||||
{
|
||||
Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[i][j]);
|
||||
if (!player)
|
||||
{
|
||||
TC_LOG_ERROR("bg.battleground", "BattlegroundEY:CheckSomeoneLeftPoint Player ({}) could not be found!", m_PlayersNearPoint[i][j].ToString());
|
||||
//move non-existing players to "free space" - this will cause many errors showing in log, but it is a very important bug
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
|
||||
m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
|
||||
continue;
|
||||
}
|
||||
if (!player->CanCaptureTowerPoint() || !player->IsWithinDistInMap(obj, BG_EY_POINT_RADIUS))
|
||||
//move player out of point (add him to players that are out of points
|
||||
{
|
||||
m_PlayersNearPoint[EY_POINTS_MAX].push_back(m_PlayersNearPoint[i][j]);
|
||||
m_PlayersNearPoint[i].erase(m_PlayersNearPoint[i].begin() + j);
|
||||
player->SendUpdateWorldState(PROGRESS_BAR_SHOW, BG_EY_PROGRESS_BAR_DONT_SHOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
//player is neat flag, so update count:
|
||||
m_CurrentPointPlayersCount[2 * i + GetTeamIndexByTeamId(GetPlayerTeam(player->GetGUID()))]++;
|
||||
++j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::UpdatePointStatuses()
|
||||
{
|
||||
for (uint8 point = 0; point < EY_POINTS_MAX; ++point)
|
||||
{
|
||||
if (!m_PlayersNearPoint[point].empty())
|
||||
{
|
||||
//count new point bar status:
|
||||
int32 pointDelta = int32(m_CurrentPointPlayersCount[2 * point]) - int32(m_CurrentPointPlayersCount[2 * point + 1]);
|
||||
RoundToInterval<int32>(pointDelta, -BG_EY_POINT_MAX_CAPTURERS_COUNT, BG_EY_POINT_MAX_CAPTURERS_COUNT);
|
||||
m_PointBarStatus[point] += pointDelta;
|
||||
|
||||
if (m_PointBarStatus[point] > BG_EY_PROGRESS_BAR_ALI_CONTROLLED)
|
||||
//point is fully alliance's
|
||||
m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_ALI_CONTROLLED;
|
||||
if (m_PointBarStatus[point] < BG_EY_PROGRESS_BAR_HORDE_CONTROLLED)
|
||||
//point is fully horde's
|
||||
m_PointBarStatus[point] = BG_EY_PROGRESS_BAR_HORDE_CONTROLLED;
|
||||
|
||||
uint32 pointOwnerTeamId = 0;
|
||||
//find which team should own this point
|
||||
if (m_PointBarStatus[point] <= BG_EY_PROGRESS_BAR_NEUTRAL_LOW)
|
||||
pointOwnerTeamId = HORDE;
|
||||
else if (m_PointBarStatus[point] >= BG_EY_PROGRESS_BAR_NEUTRAL_HIGH)
|
||||
pointOwnerTeamId = ALLIANCE;
|
||||
else
|
||||
pointOwnerTeamId = EY_POINT_NO_OWNER;
|
||||
|
||||
for (uint8 i = 0; i < m_PlayersNearPoint[point].size(); ++i)
|
||||
{
|
||||
Player* player = ObjectAccessor::FindPlayer(m_PlayersNearPoint[point][i]);
|
||||
if (player)
|
||||
{
|
||||
player->SendUpdateWorldState(PROGRESS_BAR_STATUS, m_PointBarStatus[point]);
|
||||
uint32 team = GetPlayerTeam(player->GetGUID());
|
||||
//if point owner changed we must evoke event!
|
||||
if (pointOwnerTeamId != m_PointOwnedByTeam[point])
|
||||
{
|
||||
//point was uncontrolled and player is from team which captured point
|
||||
if (m_PointState[point] == EY_POINT_STATE_UNCONTROLLED && team == pointOwnerTeamId)
|
||||
this->EventTeamCapturedPoint(player, point);
|
||||
|
||||
//point was under control and player isn't from team which controlled it
|
||||
if (m_PointState[point] == EY_POINT_UNDER_CONTROL && team != m_PointOwnedByTeam[point])
|
||||
this->EventTeamLostPoint(player, point);
|
||||
}
|
||||
|
||||
/// @workaround The original AreaTrigger is covered by a bigger one and not triggered on client side.
|
||||
if (point == FEL_REAVER && m_PointOwnedByTeam[point] == team)
|
||||
if (m_FlagState && GetFlagPickerGUID() == player->GetGUID())
|
||||
if (player->GetDistance(2044.0f, 1729.729f, 1190.03f) < 3.0f)
|
||||
EventPlayerCapturedFlag(player, BG_EY_OBJECT_FLAG_FEL_REAVER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BattlegroundPointCaptureStatus captureStatus = GetPointCaptureStatus(point);
|
||||
if (m_LastPointCaptureStatus[point] != captureStatus)
|
||||
{
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateAllianceStatusBarIcon, captureStatus == BattlegroundPointCaptureStatus::AllianceControlled ? 2 : (captureStatus == BattlegroundPointCaptureStatus::AllianceCapturing ? 1 : 0));
|
||||
UpdateWorldState(m_PointsIconStruct[point].WorldStateHordeStatusBarIcon, captureStatus == BattlegroundPointCaptureStatus::HordeControlled ? 2 : (captureStatus == BattlegroundPointCaptureStatus::HordeCapturing ? 1 : 0));
|
||||
m_LastPointCaptureStatus[point] = captureStatus;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BattlegroundEY::UpdateTeamScore(uint32 Team)
|
||||
{
|
||||
uint32 score = GetTeamScore(Team);
|
||||
@@ -541,6 +384,11 @@ bool BattlegroundEY::SetupBattleground()
|
||||
|
||||
UpdateWorldState(EY_MAX_RESOURCES, BG_EY_MAX_TEAM_SCORE);
|
||||
|
||||
ControlZoneHandlers[BG_OBJECT_FR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, FEL_REAVER);
|
||||
ControlZoneHandlers[BG_OBJECT_BE_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, BLOOD_ELF);
|
||||
ControlZoneHandlers[BG_OBJECT_DR_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, DRAENEI_RUINS);
|
||||
ControlZoneHandlers[BG_OBJECT_HU_TOWER_CAP_EY_ENTRY] = std::make_unique<BattlegroundEYControlZoneHandler>(this, MAGE_TOWER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -684,112 +532,109 @@ void BattlegroundEY::EventPlayerClickedOnFlag(Player* player, GameObject* target
|
||||
SendBroadcastText(BG_EY_TEXT_TAKEN_FLAG, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventTeamLostPoint(Player* player, uint32 Point)
|
||||
void BattlegroundEY::EventTeamLostPoint(Team team, uint32 point, WorldObject* controlZone)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
//Natural point
|
||||
uint32 Team = m_PointOwnedByTeam[Point];
|
||||
|
||||
if (!Team)
|
||||
if (!team)
|
||||
return;
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
m_TeamPointsCount[TEAM_ALLIANCE]--;
|
||||
SpawnBGObject(m_LosingPointTypes[Point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[Point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[Point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeAlliance, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeAlliance + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeAlliance + 2, RESPAWN_ONE_DAY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TeamPointsCount[TEAM_HORDE]--;
|
||||
SpawnBGObject(m_LosingPointTypes[Point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[Point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[Point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeHorde, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeHorde + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].DespawnObjectTypeHorde + 2, RESPAWN_ONE_DAY);
|
||||
}
|
||||
|
||||
SpawnBGObject(m_LosingPointTypes[Point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[Point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[Point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].SpawnNeutralObjectType, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].SpawnNeutralObjectType + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_LosingPointTypes[point].SpawnNeutralObjectType + 2, RESPAWN_IMMEDIATELY);
|
||||
|
||||
//buff isn't despawned
|
||||
|
||||
m_PointOwnedByTeam[Point] = EY_POINT_NO_OWNER;
|
||||
m_PointState[Point] = EY_POINT_NO_OWNER;
|
||||
m_PointOwnedByTeam[point] = EY_POINT_NO_OWNER;
|
||||
m_PointState[point] = EY_POINT_NO_OWNER;
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
SendBroadcastText(m_LosingPointTypes[Point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
if (team == ALLIANCE)
|
||||
SendBroadcastText(m_LosingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
|
||||
else
|
||||
SendBroadcastText(m_LosingPointTypes[Point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
SendBroadcastText(m_LosingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
|
||||
|
||||
UpdatePointsIcons(Team, Point);
|
||||
UpdatePointsCount(Team);
|
||||
UpdatePointsIcons(team, point);
|
||||
UpdatePointsCount(team);
|
||||
|
||||
//remove bonus honor aura trigger creature when node is lost
|
||||
DelCreature(Point + 6);//NULL checks are in DelCreature! 0-5 spirit guides
|
||||
DelCreature(point + 6);//NULL checks are in DelCreature! 0-5 spirit guides
|
||||
}
|
||||
|
||||
void BattlegroundEY::EventTeamCapturedPoint(Player* player, uint32 Point)
|
||||
void BattlegroundEY::EventTeamCapturedPoint(Team team, uint32 point, WorldObject* controlZone)
|
||||
{
|
||||
if (GetStatus() != STATUS_IN_PROGRESS)
|
||||
return;
|
||||
|
||||
uint32 Team = GetPlayerTeam(player->GetGUID());
|
||||
SpawnBGObject(m_CapturingPointTypes[point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY);
|
||||
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 1, RESPAWN_ONE_DAY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].DespawnNeutralObjectType + 2, RESPAWN_ONE_DAY);
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
m_TeamPointsCount[TEAM_ALLIANCE]++;
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeAlliance, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeAlliance + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeAlliance + 2, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_TeamPointsCount[TEAM_HORDE]++;
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[Point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeHorde, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeHorde + 1, RESPAWN_IMMEDIATELY);
|
||||
SpawnBGObject(m_CapturingPointTypes[point].SpawnObjectTypeHorde + 2, RESPAWN_IMMEDIATELY);
|
||||
}
|
||||
|
||||
//buff isn't respawned
|
||||
|
||||
m_PointOwnedByTeam[Point] = Team;
|
||||
m_PointState[Point] = EY_POINT_UNDER_CONTROL;
|
||||
m_PointOwnedByTeam[point] = team;
|
||||
m_PointState[point] = EY_POINT_UNDER_CONTROL;
|
||||
|
||||
if (Team == ALLIANCE)
|
||||
SendBroadcastText(m_CapturingPointTypes[Point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, player);
|
||||
if (team == ALLIANCE)
|
||||
SendBroadcastText(m_CapturingPointTypes[point].MessageIdAlliance, CHAT_MSG_BG_SYSTEM_ALLIANCE, controlZone);
|
||||
else
|
||||
SendBroadcastText(m_CapturingPointTypes[Point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, player);
|
||||
SendBroadcastText(m_CapturingPointTypes[point].MessageIdHorde, CHAT_MSG_BG_SYSTEM_HORDE, controlZone);
|
||||
|
||||
if (!BgCreatures[Point].IsEmpty())
|
||||
DelCreature(Point);
|
||||
if (!BgCreatures[point].IsEmpty())
|
||||
DelCreature(point);
|
||||
|
||||
WorldSafeLocsEntry const* sg = sObjectMgr->GetWorldSafeLoc(m_CapturingPointTypes[Point].GraveyardId);
|
||||
if (!sg || !AddSpiritGuide(Point, sg->Loc.GetPositionX(), sg->Loc.GetPositionY(), sg->Loc.GetPositionZ(), 3.124139f, GetTeamIndexByTeamId(Team)))
|
||||
WorldSafeLocsEntry const* sg = sObjectMgr->GetWorldSafeLoc(m_CapturingPointTypes[point].GraveyardId);
|
||||
if (!sg || !AddSpiritGuide(point, sg->Loc.GetPositionX(), sg->Loc.GetPositionY(), sg->Loc.GetPositionZ(), 3.124139f, GetTeamIndexByTeamId(team)))
|
||||
TC_LOG_ERROR("bg.battleground", "BatteGroundEY: Failed to spawn spirit guide. point: {}, team: {}, graveyard_id: {}",
|
||||
Point, Team, m_CapturingPointTypes[Point].GraveyardId);
|
||||
point, team, m_CapturingPointTypes[point].GraveyardId);
|
||||
|
||||
// SpawnBGCreature(Point, RESPAWN_IMMEDIATELY);
|
||||
|
||||
UpdatePointsIcons(Team, Point);
|
||||
UpdatePointsCount(Team);
|
||||
UpdatePointsIcons(team, point);
|
||||
UpdatePointsCount(team);
|
||||
|
||||
Creature* trigger = GetBGCreature(Point + 6, false);//0-5 spirit guides
|
||||
Creature* trigger = GetBGCreature(point + 6, false);//0-5 spirit guides
|
||||
if (!trigger)
|
||||
trigger = AddCreature(WORLD_TRIGGER, Point+6, BG_EY_TriggerPositions[Point], GetTeamIndexByTeamId(Team));
|
||||
trigger = AddCreature(WORLD_TRIGGER, point+6, BG_EY_TriggerPositions[point], GetTeamIndexByTeamId(team));
|
||||
|
||||
//add bonus honor aura trigger creature when node is accupied
|
||||
//cast bonus aura (+50% honor in 25yards)
|
||||
//aura should only apply to players who have accupied the node, set correct faction for trigger
|
||||
if (trigger)
|
||||
{
|
||||
trigger->SetFaction(Team == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC);
|
||||
trigger->SetFaction(team == ALLIANCE ? FACTION_ALLIANCE_GENERIC : FACTION_HORDE_GENERIC);
|
||||
trigger->CastSpell(trigger, SPELL_HONORABLE_DEFENDER_25Y, false);
|
||||
}
|
||||
}
|
||||
@@ -920,3 +765,64 @@ uint32 BattlegroundEY::GetPrematureWinner()
|
||||
|
||||
return Battleground::GetPrematureWinner();
|
||||
}
|
||||
|
||||
void BattlegroundEY::ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker)
|
||||
{
|
||||
Battleground::ProcessEvent(target, eventId, invoker);
|
||||
|
||||
if (invoker)
|
||||
{
|
||||
if (GameObject* gameobject = invoker->ToGameObject())
|
||||
{
|
||||
if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
{
|
||||
if (!ControlZoneHandlers.contains(gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
auto controlzone = gameobject->GetGOInfo()->controlZone;
|
||||
BattlegroundEYControlZoneHandler& handler = *ControlZoneHandlers[invoker->GetEntry()];
|
||||
if (eventId == controlzone.CaptureEventAlliance)
|
||||
handler.HandleCaptureEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.CaptureEventHorde)
|
||||
handler.HandleCaptureEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ContestedEventAlliance)
|
||||
handler.HandleContestedEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ContestedEventHorde)
|
||||
handler.HandleContestedEventHorde(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventAlliance)
|
||||
handler.HandleNeutralEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventHorde)
|
||||
handler.HandleNeutralEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventAlliance)
|
||||
handler.HandleProgressEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventHorde)
|
||||
handler.HandleProgressEventHorde(gameobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BattlegroundEYControlZoneHandler::BattlegroundEYControlZoneHandler(BattlegroundEY* bg, uint32 point) : ControlZoneHandler(),
|
||||
_battleground(bg), _point(point)
|
||||
{
|
||||
}
|
||||
|
||||
void BattlegroundEYControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
|
||||
{
|
||||
_battleground->EventTeamCapturedPoint(HORDE, _point, controlZone);
|
||||
}
|
||||
|
||||
void BattlegroundEYControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
_battleground->EventTeamCapturedPoint(ALLIANCE, _point, controlZone);
|
||||
}
|
||||
|
||||
void BattlegroundEYControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
|
||||
{
|
||||
_battleground->EventTeamLostPoint(HORDE, _point, controlZone);
|
||||
}
|
||||
|
||||
void BattlegroundEYControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
_battleground->EventTeamLostPoint(ALLIANCE, _point, controlZone);
|
||||
}
|
||||
|
||||
@@ -355,6 +355,23 @@ struct BattlegroundEYCapturingPointStruct
|
||||
uint32 GraveyardId;
|
||||
};
|
||||
|
||||
class BattlegroundEY;
|
||||
|
||||
class BattlegroundEYControlZoneHandler : public ControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit BattlegroundEYControlZoneHandler(BattlegroundEY* bg, uint32 point);
|
||||
|
||||
void HandleProgressEventHorde(GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance(GameObject* controlZone) override;
|
||||
void HandleNeutralEventHorde(GameObject* controlZone) override;
|
||||
void HandleNeutralEventAlliance(GameObject* controlZone) override;
|
||||
|
||||
private:
|
||||
BattlegroundEY* _battleground;
|
||||
uint32 _point;
|
||||
};
|
||||
|
||||
const uint8 BG_EY_TickPoints[EY_POINTS_MAX] = {1, 2, 5, 10};
|
||||
const uint32 BG_EY_FlagPoints[EY_POINTS_MAX] = {75, 85, 100, 500};
|
||||
|
||||
@@ -450,21 +467,17 @@ class BattlegroundEY : public Battleground
|
||||
void EventPlayerDroppedFlag(Player* Source) override;
|
||||
|
||||
uint32 GetPrematureWinner() override;
|
||||
protected:
|
||||
|
||||
void ProcessEvent(WorldObject* target, uint32 eventId, WorldObject* invoker) override;
|
||||
void PostUpdateImpl(uint32 diff) override;
|
||||
|
||||
void EventPlayerCapturedFlag(Player* Source, uint32 BgObjectType);
|
||||
void EventTeamCapturedPoint(Player* Source, uint32 Point);
|
||||
void EventTeamLostPoint(Player* Source, uint32 Point);
|
||||
void EventTeamCapturedPoint(Team team, uint32 point, WorldObject* controlZone);
|
||||
void EventTeamLostPoint(Team team, uint32 point, WorldObject* controlZone);
|
||||
void UpdatePointsCount(uint32 Team);
|
||||
void UpdatePointsIcons(uint32 Team, uint32 Point);
|
||||
|
||||
private:
|
||||
/* Point status updating procedures */
|
||||
void CheckSomeoneLeftPoint();
|
||||
void CheckSomeoneJoinedPoint();
|
||||
void UpdatePointStatuses();
|
||||
|
||||
/* Scorekeeping */
|
||||
void AddPoints(uint32 Team, uint32 Points);
|
||||
|
||||
@@ -493,5 +506,7 @@ protected:
|
||||
|
||||
int32 m_PointAddingTimer;
|
||||
uint32 m_HonorTics;
|
||||
|
||||
std::unordered_map<uint32, std::unique_ptr<BattlegroundEYControlZoneHandler>> ControlZoneHandlers;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "PhasingHandler.h"
|
||||
#include "PoolMgr.h"
|
||||
#include "QueryPackets.h"
|
||||
#include "Util.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellMgr.h"
|
||||
#include "Transport.h"
|
||||
@@ -507,7 +508,7 @@ void SetTransportAutoCycleBetweenStopFrames::Execute(GameObjectTypeBase& type) c
|
||||
class NewFlag : public GameObjectTypeBase
|
||||
{
|
||||
public:
|
||||
explicit NewFlag(GameObject& owner) : GameObjectTypeBase(owner), _state(FlagState::InBase), _respawnTime(0), _takenFromBaseTime(0){ }
|
||||
explicit NewFlag(GameObject& owner) : GameObjectTypeBase(owner), _state(FlagState::InBase), _respawnTime(0), _takenFromBaseTime(0) { }
|
||||
|
||||
void SetState(FlagState newState, Player* player)
|
||||
{
|
||||
@@ -569,6 +570,244 @@ void SetNewFlagState::Execute(GameObjectTypeBase& type) const
|
||||
if (NewFlag* newFlag = dynamic_cast<NewFlag*>(&type))
|
||||
newFlag->SetState(_state, _player);
|
||||
}
|
||||
|
||||
class ControlZone : public GameObjectTypeBase
|
||||
{
|
||||
public:
|
||||
explicit ControlZone(GameObject& owner) : GameObjectTypeBase(owner), _value(static_cast<float>(owner.GetGOInfo()->controlZone.startingValue))
|
||||
{
|
||||
if (owner.GetMap()->Instanceable())
|
||||
_heartbeatRate = 1s;
|
||||
else if (owner.GetGOInfo()->controlZone.FrequentHeartbeat)
|
||||
_heartbeatRate = 2500ms;
|
||||
else
|
||||
_heartbeatRate = 5s;
|
||||
|
||||
_heartbeatTracker.Reset(_heartbeatRate);
|
||||
_previousTeamId = GetControllingTeam();
|
||||
_contestedTriggered = false;
|
||||
}
|
||||
|
||||
void Update(uint32 diff) override
|
||||
{
|
||||
if (_owner.HasFlag(GO_FLAG_NOT_SELECTABLE))
|
||||
return;
|
||||
|
||||
_heartbeatTracker.Update(diff);
|
||||
if (_heartbeatTracker.Passed())
|
||||
{
|
||||
_heartbeatTracker.Reset(_heartbeatRate);
|
||||
HandleHeartbeat();
|
||||
}
|
||||
}
|
||||
|
||||
TeamId GetControllingTeam() const
|
||||
{
|
||||
if (_value < GetMaxHordeValue())
|
||||
return TEAM_HORDE;
|
||||
|
||||
if (_value > GetMinAllianceValue())
|
||||
return TEAM_ALLIANCE;
|
||||
|
||||
return TEAM_NEUTRAL;
|
||||
}
|
||||
|
||||
GuidUnorderedSet const* GetInsidePlayers() const { return &_insidePlayers; }
|
||||
|
||||
void ActivateObject(GameObjectActions action, int32 /*param*/, WorldObject* /*spellCaster*/, uint32 /*spellId*/, int32 /*effectIndex*/) override
|
||||
{
|
||||
switch (action)
|
||||
{
|
||||
case GameObjectActions::MakeInert:
|
||||
for (ObjectGuid const& guid : _insidePlayers)
|
||||
if (Player* player = ObjectAccessor::GetPlayer(_owner, guid))
|
||||
player->SendUpdateWorldState(_owner.GetGOInfo()->controlZone.worldState1, 0);
|
||||
|
||||
_insidePlayers.clear();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetValue(float value)
|
||||
{
|
||||
_value = RoundToInterval<float>(value, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
void HandleHeartbeat()
|
||||
{
|
||||
// update player list inside control zone
|
||||
std::vector<Player*> targetList;
|
||||
SearchTargets(targetList);
|
||||
|
||||
TeamId oldControllingTeam = GetControllingTeam();
|
||||
float pointsGained = CalculatePointsPerSecond(targetList) * _heartbeatRate.count() / 1000.0f;
|
||||
if (pointsGained == 0)
|
||||
return;
|
||||
|
||||
int32 oldRoundedValue = static_cast<int32>(_value);
|
||||
SetValue(_value + pointsGained);
|
||||
int32 roundedValue = static_cast<int32>(_value);
|
||||
if (oldRoundedValue == roundedValue)
|
||||
return;
|
||||
|
||||
TeamId newControllingTeam = GetControllingTeam();
|
||||
TeamId assaultingTeam = pointsGained > 0 ? TEAM_ALLIANCE : TEAM_HORDE;
|
||||
|
||||
if (oldControllingTeam != newControllingTeam)
|
||||
_contestedTriggered = false;
|
||||
|
||||
if (oldControllingTeam != TEAM_ALLIANCE && newControllingTeam == TEAM_ALLIANCE)
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.ProgressEventAlliance);
|
||||
else if (oldControllingTeam != TEAM_HORDE && newControllingTeam == TEAM_HORDE)
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.ProgressEventHorde);
|
||||
else if (oldControllingTeam == TEAM_HORDE && newControllingTeam == TEAM_NEUTRAL)
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.NeutralEventHorde);
|
||||
else if (oldControllingTeam == TEAM_ALLIANCE && newControllingTeam == TEAM_NEUTRAL)
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.NeutralEventAlliance);
|
||||
|
||||
if (roundedValue == 100 && newControllingTeam == TEAM_ALLIANCE && assaultingTeam == TEAM_ALLIANCE)
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.CaptureEventAlliance);
|
||||
else if (roundedValue == 0 && newControllingTeam == TEAM_HORDE && assaultingTeam == TEAM_HORDE)
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.CaptureEventHorde);
|
||||
|
||||
if (oldRoundedValue == 100 && assaultingTeam == TEAM_HORDE && !_contestedTriggered)
|
||||
{
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.ContestedEventHorde);
|
||||
_contestedTriggered = true;
|
||||
}
|
||||
else if (oldRoundedValue == 0 && assaultingTeam == TEAM_ALLIANCE && !_contestedTriggered)
|
||||
{
|
||||
TriggerEvent(_owner.GetGOInfo()->controlZone.ContestedEventAlliance);
|
||||
_contestedTriggered = true;
|
||||
}
|
||||
|
||||
for (Player* player : targetList)
|
||||
player->SendUpdateWorldState(_owner.GetGOInfo()->controlZone.worldstate2, roundedValue);
|
||||
}
|
||||
|
||||
void SearchTargets(std::vector<Player*>& targetList)
|
||||
{
|
||||
Trinity::AnyUnitInObjectRangeCheck check(&_owner, _owner.GetGOInfo()->controlZone.radius, true);
|
||||
Trinity::PlayerListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(&_owner, targetList, check);
|
||||
Cell::VisitWorldObjects(&_owner, searcher, _owner.GetGOInfo()->controlZone.radius);
|
||||
HandleUnitEnterExit(targetList);
|
||||
}
|
||||
|
||||
float CalculatePointsPerSecond(std::vector<Player*> const& targetList)
|
||||
{
|
||||
int32 delta = 0;
|
||||
|
||||
for (Player* player : targetList)
|
||||
{
|
||||
if (!player->IsOutdoorPvPActive())
|
||||
continue;
|
||||
|
||||
if (player->GetTeamId() == TEAM_HORDE)
|
||||
delta--;
|
||||
else
|
||||
delta++;
|
||||
}
|
||||
|
||||
uint32 minTime = _owner.GetGOInfo()->controlZone.minTime;
|
||||
uint32 maxTime = _owner.GetGOInfo()->controlZone.maxTime;
|
||||
uint32 minSuperiority = _owner.GetGOInfo()->controlZone.minSuperiority;
|
||||
uint32 maxSuperiority = _owner.GetGOInfo()->controlZone.maxSuperiority;
|
||||
|
||||
if (static_cast<uint32>(std::abs(delta)) < minSuperiority)
|
||||
return 0;
|
||||
|
||||
float slope = (static_cast<float>(minTime) - maxTime) / (maxSuperiority - minSuperiority);
|
||||
float intercept = maxTime - slope * minSuperiority;
|
||||
float timeNeeded = slope * std::abs(delta) + intercept;
|
||||
float percentageIncrease = 100.0f / timeNeeded;
|
||||
|
||||
if (delta < 0)
|
||||
percentageIncrease *= -1;
|
||||
|
||||
return percentageIncrease;
|
||||
}
|
||||
|
||||
void HandleUnitEnterExit(std::vector<Player*> const& newTargetList)
|
||||
{
|
||||
GuidUnorderedSet exitPlayers(std::move(_insidePlayers));
|
||||
|
||||
std::vector<Player*> enteringPlayers;
|
||||
|
||||
for (Player* unit : newTargetList)
|
||||
{
|
||||
if (exitPlayers.erase(unit->GetGUID()) == 0) // erase(key_type) returns number of elements erased
|
||||
enteringPlayers.push_back(unit);
|
||||
|
||||
_insidePlayers.insert(unit->GetGUID());
|
||||
}
|
||||
|
||||
for (Player* player : enteringPlayers)
|
||||
{
|
||||
player->SendUpdateWorldState(_owner.GetGOInfo()->controlZone.worldState1, 1);
|
||||
player->SendUpdateWorldState(_owner.GetGOInfo()->controlZone.worldstate2, static_cast<int32>(_value));
|
||||
player->SendUpdateWorldState(_owner.GetGOInfo()->controlZone.worldstate3, _owner.GetGOInfo()->controlZone.neutralPercent);
|
||||
}
|
||||
|
||||
for (ObjectGuid const& exitPlayerGuid : exitPlayers)
|
||||
{
|
||||
if (Player* player = ObjectAccessor::GetPlayer(_owner, exitPlayerGuid))
|
||||
{
|
||||
player->SendUpdateWorldState(_owner.GetGOInfo()->controlZone.worldState1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float GetMaxHordeValue() const
|
||||
{
|
||||
// ex: if neutralPercent is 40; then 0 - 30 is Horde Controlled
|
||||
return 50.0f - _owner.GetGOInfo()->controlZone.neutralPercent / 2.0f;
|
||||
}
|
||||
|
||||
float GetMinAllianceValue() const
|
||||
{
|
||||
// ex: if neutralPercent is 40; then 70 - 100 is Alliance Controlled
|
||||
return 50.0f + _owner.GetGOInfo()->controlZone.neutralPercent / 2.0f;
|
||||
}
|
||||
|
||||
void TriggerEvent(uint32 eventId) const
|
||||
{
|
||||
if (eventId <= 0)
|
||||
return;
|
||||
|
||||
GameEvents::Trigger(eventId, &_owner, nullptr);
|
||||
}
|
||||
|
||||
uint32 GetStartingValue() const
|
||||
{
|
||||
return _owner.GetGOInfo()->controlZone.startingValue;
|
||||
}
|
||||
|
||||
private:
|
||||
Milliseconds _heartbeatRate;
|
||||
TimeTracker _heartbeatTracker;
|
||||
GuidUnorderedSet _insidePlayers;
|
||||
TeamId _previousTeamId;
|
||||
float _value;
|
||||
bool _contestedTriggered;
|
||||
};
|
||||
|
||||
SetControlZoneValue::SetControlZoneValue(Optional<uint32> value /*= { }*/) : _value(value)
|
||||
{
|
||||
}
|
||||
|
||||
void SetControlZoneValue::Execute(GameObjectTypeBase& type) const
|
||||
{
|
||||
if (ControlZone* controlZone = dynamic_cast<ControlZone*>(&type))
|
||||
{
|
||||
uint32 value = controlZone->GetStartingValue();
|
||||
if (_value.has_value())
|
||||
value = *_value;
|
||||
|
||||
controlZone->SetValue(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GameObject::GameObject() : WorldObject(false), MapObject(),
|
||||
@@ -863,6 +1102,10 @@ bool GameObject::Create(uint32 entry, Map* map, Position const& pos, QuaternionD
|
||||
m_invisibility.AddValue(INVISIBILITY_TRAP, 300);
|
||||
}
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_CONTROL_ZONE:
|
||||
m_goTypeImpl = std::make_unique<GameObjectType::ControlZone>(*this);
|
||||
setActive(true);
|
||||
break;
|
||||
case GAMEOBJECT_TYPE_NEW_FLAG:
|
||||
m_goTypeImpl = std::make_unique<GameObjectType::NewFlag>(*this);
|
||||
if (map->Instanceable())
|
||||
@@ -2216,6 +2459,10 @@ void GameObject::ActivateObject(GameObjectActions action, int32 param, WorldObje
|
||||
TC_LOG_ERROR("spell", "Spell {} has unhandled action {} in effect {}", spellId, int32(action), effectIndex);
|
||||
break;
|
||||
}
|
||||
|
||||
// Apply side effects of type
|
||||
if (m_goTypeImpl)
|
||||
m_goTypeImpl->ActivateObject(action, param, spellCaster, spellId, effectIndex);
|
||||
}
|
||||
|
||||
void GameObject::SetGoArtKit(uint32 kit)
|
||||
@@ -4118,6 +4365,14 @@ time_t GameObject::GetFlagTakenFromBaseTime() const
|
||||
return newFlag->GetTakenFromBaseTime();
|
||||
}
|
||||
|
||||
GuidUnorderedSet const* GameObject::GetInsidePlayers() const
|
||||
{
|
||||
if (GameObjectType::ControlZone const* controlZone = dynamic_cast<GameObjectType::ControlZone const*>(m_goTypeImpl.get()))
|
||||
return controlZone->GetInsidePlayers();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool GameObject::MeetsInteractCondition(Player const* user) const
|
||||
{
|
||||
if (!m_goInfo->GetConditionID1())
|
||||
|
||||
@@ -71,6 +71,7 @@ public:
|
||||
virtual void OnStateChanged([[maybe_unused]] GOState oldState, [[maybe_unused]] GOState newState) { }
|
||||
virtual void OnRelocated() { }
|
||||
virtual bool IsNeverVisibleFor([[maybe_unused]] WorldObject const* seer, [[maybe_unused]] bool allowServersideObjects) const { return false; }
|
||||
virtual void ActivateObject([[maybe_unused]] GameObjectActions action, [[maybe_unused]] int32 param, [[maybe_unused]] WorldObject* spellCaster = nullptr, [[maybe_unused]] uint32 spellId = 0, [[maybe_unused]] int32 effectIndex = -1) { }
|
||||
|
||||
protected:
|
||||
GameObject& _owner;
|
||||
@@ -100,6 +101,18 @@ private:
|
||||
FlagState _state;
|
||||
Player* _player;
|
||||
};
|
||||
|
||||
class TC_GAME_API SetControlZoneValue : public GameObjectTypeBase::CustomCommand
|
||||
{
|
||||
public:
|
||||
explicit SetControlZoneValue(Optional<uint32> value = { });
|
||||
|
||||
void Execute(GameObjectTypeBase& type) const override;
|
||||
|
||||
private:
|
||||
Optional<uint32> _value;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
union GameObjectValue
|
||||
@@ -413,6 +426,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
ObjectGuid const& GetFlagCarrierGUID() const;
|
||||
time_t GetFlagTakenFromBaseTime() const;
|
||||
|
||||
GuidUnorderedSet const* GetInsidePlayers() const;
|
||||
|
||||
bool MeetsInteractCondition(Player const* user) const;
|
||||
|
||||
void AIM_Destroy();
|
||||
|
||||
@@ -38,6 +38,23 @@ enum class EncounterType : uint8
|
||||
MythicPlusRun
|
||||
};
|
||||
|
||||
class TC_GAME_API ControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit ControlZoneHandler() = default;
|
||||
virtual ~ControlZoneHandler() = default;
|
||||
|
||||
virtual void HandleCaptureEventHorde([[maybe_unused]] GameObject* controlZone) { }
|
||||
virtual void HandleCaptureEventAlliance([[maybe_unused]] GameObject* controlZone) { }
|
||||
virtual void HandleContestedEventHorde([[maybe_unused]] GameObject* controlZone) { }
|
||||
virtual void HandleContestedEventAlliance([[maybe_unused]] GameObject* controlZone) { }
|
||||
virtual void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) { }
|
||||
virtual void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) { }
|
||||
virtual void HandleNeutralEventHorde([[maybe_unused]] GameObject* controlZone) { HandleNeutralEvent(controlZone); }
|
||||
virtual void HandleNeutralEventAlliance([[maybe_unused]] GameObject* controlZone) { HandleNeutralEvent(controlZone); }
|
||||
virtual void HandleNeutralEvent([[maybe_unused]] GameObject* controlZone) { }
|
||||
};
|
||||
|
||||
class TC_GAME_API ZoneScript
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -53,62 +53,10 @@ class DefenseMessageBuilder
|
||||
};
|
||||
|
||||
OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP* pvp):
|
||||
m_capturePointSpawnId(), m_capturePoint(nullptr), m_maxValue(0.0f), m_minValue(0.0f), m_maxSpeed(0),
|
||||
m_value(0), m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL),
|
||||
m_State(OBJECTIVESTATE_NEUTRAL), m_neutralValuePct(0), m_PvP(pvp)
|
||||
m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL),
|
||||
m_State(OBJECTIVESTATE_NEUTRAL), m_PvP(pvp)
|
||||
{ }
|
||||
|
||||
bool OPvPCapturePoint::HandlePlayerEnter(Player* player)
|
||||
{
|
||||
if (m_capturePoint)
|
||||
{
|
||||
player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldState1, 1);
|
||||
player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldstate2, (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f));
|
||||
player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldstate3, m_neutralValuePct);
|
||||
}
|
||||
return m_activePlayers[player->GetTeamId()].insert(player->GetGUID()).second;
|
||||
}
|
||||
|
||||
void OPvPCapturePoint::HandlePlayerLeave(Player* player)
|
||||
{
|
||||
if (m_capturePoint)
|
||||
player->SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldState1, 0);
|
||||
m_activePlayers[player->GetTeamId()].erase(player->GetGUID());
|
||||
}
|
||||
|
||||
void OPvPCapturePoint::SendChangePhase()
|
||||
{
|
||||
if (!m_capturePoint)
|
||||
return;
|
||||
|
||||
// send this too, sometimes the slider disappears, dunno why :(
|
||||
SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldState1, 1);
|
||||
// send these updates to only the ones in this objective
|
||||
SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldstate2, (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f));
|
||||
// send this too, sometimes it resets :S
|
||||
SendUpdateWorldState(m_capturePoint->GetGOInfo()->controlZone.worldstate3, m_neutralValuePct);
|
||||
}
|
||||
|
||||
bool OPvPCapturePoint::SetCapturePointData(uint32 entry)
|
||||
{
|
||||
TC_LOG_DEBUG("outdoorpvp", "Creating capture point {}", entry);
|
||||
|
||||
// check info existence
|
||||
GameObjectTemplate const* goinfo = sObjectMgr->GetGameObjectTemplate(entry);
|
||||
if (!goinfo || goinfo->type != GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
{
|
||||
TC_LOG_ERROR("outdoorpvp", "OutdoorPvP: GO {} is not capture point!", entry);
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the needed values from goinfo
|
||||
m_maxValue = (float)goinfo->controlZone.maxTime;
|
||||
m_maxSpeed = m_maxValue / (goinfo->controlZone.minTime ? goinfo->controlZone.minTime : 60);
|
||||
m_neutralValuePct = goinfo->controlZone.neutralPercent;
|
||||
m_minValue = CalculatePct(m_maxValue, m_neutralValuePct);
|
||||
return true;
|
||||
}
|
||||
|
||||
OutdoorPvP::OutdoorPvP(Map* map) : m_TypeId(0), m_map(map) { }
|
||||
|
||||
OutdoorPvP::~OutdoorPvP() = default;
|
||||
@@ -120,9 +68,6 @@ void OutdoorPvP::HandlePlayerEnterZone(Player* player, uint32 /*zone*/)
|
||||
|
||||
void OutdoorPvP::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/)
|
||||
{
|
||||
// inform the objectives of the leaving
|
||||
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
itr->second->HandlePlayerLeave(player);
|
||||
// remove the world state information from the player (we can't keep everyone up to date, so leave out those who are not in the concerning zones)
|
||||
if (!player->GetSession()->PlayerLogout())
|
||||
SendRemoveWorldStates(player);
|
||||
@@ -132,137 +77,10 @@ void OutdoorPvP::HandlePlayerLeaveZone(Player* player, uint32 /*zone*/)
|
||||
|
||||
void OutdoorPvP::HandlePlayerResurrects(Player* /*player*/, uint32 /*zone*/) { }
|
||||
|
||||
bool OutdoorPvP::Update(uint32 diff)
|
||||
void OutdoorPvP::Update(uint32 diff)
|
||||
{
|
||||
bool objective_changed = false;
|
||||
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
{
|
||||
if (itr->second->Update(diff))
|
||||
objective_changed = true;
|
||||
}
|
||||
return objective_changed;
|
||||
}
|
||||
|
||||
bool OPvPCapturePoint::Update(uint32 diff)
|
||||
{
|
||||
if (!m_capturePoint)
|
||||
return false;
|
||||
|
||||
float radius = (float)m_capturePoint->GetGOInfo()->controlZone.radius;
|
||||
|
||||
for (uint32 team = 0; team < 2; ++team)
|
||||
{
|
||||
for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end();)
|
||||
{
|
||||
ObjectGuid playerGuid = *itr;
|
||||
++itr;
|
||||
|
||||
if (Player* player = ObjectAccessor::FindPlayer(playerGuid))
|
||||
if (!m_capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive())
|
||||
HandlePlayerLeave(player);
|
||||
}
|
||||
}
|
||||
|
||||
std::list<Player*> players;
|
||||
Trinity::AnyPlayerInObjectRangeCheck checker(m_capturePoint, radius);
|
||||
Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(m_capturePoint, players, checker);
|
||||
Cell::VisitWorldObjects(m_capturePoint, searcher, radius);
|
||||
|
||||
for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
{
|
||||
Player* const player = *itr;
|
||||
if (player->IsOutdoorPvPActive())
|
||||
{
|
||||
if (m_activePlayers[player->GetTeamId()].insert(player->GetGUID()).second)
|
||||
HandlePlayerEnter(*itr);
|
||||
}
|
||||
}
|
||||
|
||||
// get the difference of numbers
|
||||
float fact_diff = ((float)m_activePlayers[0].size() - (float)m_activePlayers[1].size()) * diff / OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL;
|
||||
if (!fact_diff)
|
||||
return false;
|
||||
|
||||
uint32 Challenger = 0;
|
||||
float maxDiff = m_maxSpeed * diff;
|
||||
|
||||
if (fact_diff < 0)
|
||||
{
|
||||
// horde is in majority, but it's already horde-controlled -> no change
|
||||
if (m_State == OBJECTIVESTATE_HORDE && m_value <= -m_maxValue)
|
||||
return false;
|
||||
|
||||
if (fact_diff < -maxDiff)
|
||||
fact_diff = -maxDiff;
|
||||
|
||||
Challenger = HORDE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ally is in majority, but it's already ally-controlled -> no change
|
||||
if (m_State == OBJECTIVESTATE_ALLIANCE && m_value >= m_maxValue)
|
||||
return false;
|
||||
|
||||
if (fact_diff > maxDiff)
|
||||
fact_diff = maxDiff;
|
||||
|
||||
Challenger = ALLIANCE;
|
||||
}
|
||||
|
||||
float oldValue = m_value;
|
||||
TeamId oldTeam = m_team;
|
||||
|
||||
m_OldState = m_State;
|
||||
|
||||
m_value += fact_diff;
|
||||
|
||||
if (m_value < -m_minValue) // red
|
||||
{
|
||||
if (m_value < -m_maxValue)
|
||||
m_value = -m_maxValue;
|
||||
m_State = OBJECTIVESTATE_HORDE;
|
||||
m_team = TEAM_HORDE;
|
||||
}
|
||||
else if (m_value > m_minValue) // blue
|
||||
{
|
||||
if (m_value > m_maxValue)
|
||||
m_value = m_maxValue;
|
||||
m_State = OBJECTIVESTATE_ALLIANCE;
|
||||
m_team = TEAM_ALLIANCE;
|
||||
}
|
||||
else if (oldValue * m_value <= 0) // grey, go through mid point
|
||||
{
|
||||
// if challenger is ally, then n->a challenge
|
||||
if (Challenger == ALLIANCE)
|
||||
m_State = OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE;
|
||||
// if challenger is horde, then n->h challenge
|
||||
else if (Challenger == HORDE)
|
||||
m_State = OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE;
|
||||
m_team = TEAM_NEUTRAL;
|
||||
}
|
||||
else // grey, did not go through mid point
|
||||
{
|
||||
// old phase and current are on the same side, so one team challenges the other
|
||||
if (Challenger == ALLIANCE && (m_OldState == OBJECTIVESTATE_HORDE || m_OldState == OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE))
|
||||
m_State = OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE;
|
||||
else if (Challenger == HORDE && (m_OldState == OBJECTIVESTATE_ALLIANCE || m_OldState == OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE))
|
||||
m_State = OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE;
|
||||
m_team = TEAM_NEUTRAL;
|
||||
}
|
||||
|
||||
if (m_value != oldValue)
|
||||
SendChangePhase();
|
||||
|
||||
if (m_OldState != m_State)
|
||||
{
|
||||
//TC_LOG_ERROR("outdoorpvp", "{}->{}", m_OldState, m_State);
|
||||
if (oldTeam != m_team)
|
||||
ChangeTeam(oldTeam);
|
||||
ChangeState();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
itr->second->Update(diff);
|
||||
}
|
||||
|
||||
int32 OutdoorPvP::GetWorldState(int32 worldStateId) const
|
||||
@@ -275,38 +93,6 @@ void OutdoorPvP::SetWorldState(int32 worldStateId, int32 value)
|
||||
sWorldStateMgr->SetValue(worldStateId, value, false, m_map);
|
||||
}
|
||||
|
||||
void OPvPCapturePoint::SendUpdateWorldState(uint32 field, uint32 value)
|
||||
{
|
||||
for (uint32 team = 0; team < 2; ++team)
|
||||
{
|
||||
// send to all players present in the area
|
||||
for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr)
|
||||
if (Player* const player = ObjectAccessor::FindPlayer(*itr))
|
||||
player->SendUpdateWorldState(field, value);
|
||||
}
|
||||
}
|
||||
|
||||
void OPvPCapturePoint::SendObjectiveComplete(uint32 id, ObjectGuid guid)
|
||||
{
|
||||
uint32 team;
|
||||
switch (m_State)
|
||||
{
|
||||
case OBJECTIVESTATE_ALLIANCE:
|
||||
team = 0;
|
||||
break;
|
||||
case OBJECTIVESTATE_HORDE:
|
||||
team = 1;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
// send to all players present in the area
|
||||
for (GuidSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr)
|
||||
if (Player* const player = ObjectAccessor::FindPlayer(*itr))
|
||||
player->KilledMonsterCredit(id, guid);
|
||||
}
|
||||
|
||||
void OutdoorPvP::HandleKill(Player* killer, Unit* killed)
|
||||
{
|
||||
if (Group* group = killer->GetGroup())
|
||||
@@ -324,33 +110,18 @@ void OutdoorPvP::HandleKill(Player* killer, Unit* killed)
|
||||
|
||||
// creature kills must be notified, even if not inside objective / not outdoor pvp active
|
||||
// player kills only count if active and inside objective
|
||||
if ((groupGuy->IsOutdoorPvPActive() && IsInsideObjective(groupGuy)) || killed->GetTypeId() == TYPEID_UNIT)
|
||||
if ((groupGuy->IsOutdoorPvPActive()) || killed->GetTypeId() == TYPEID_UNIT)
|
||||
HandleKillImpl(groupGuy, killed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// creature kills must be notified, even if not inside objective / not outdoor pvp active
|
||||
if ((killer->IsOutdoorPvPActive() && IsInsideObjective(killer)) || killed->GetTypeId() == TYPEID_UNIT)
|
||||
if ((killer->IsOutdoorPvPActive()) || killed->GetTypeId() == TYPEID_UNIT)
|
||||
HandleKillImpl(killer, killed);
|
||||
}
|
||||
}
|
||||
|
||||
bool OutdoorPvP::IsInsideObjective(Player* player) const
|
||||
{
|
||||
for (OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
if (itr->second->IsInsideObjective(player))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OPvPCapturePoint::IsInsideObjective(Player* player) const
|
||||
{
|
||||
GuidSet const& plSet = m_activePlayers[player->GetTeamId()];
|
||||
return plSet.find(player->GetGUID()) != plSet.end();
|
||||
}
|
||||
|
||||
bool OutdoorPvP::HandleCustomSpell(Player* player, uint32 spellId, GameObject* go)
|
||||
{
|
||||
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
@@ -399,26 +170,6 @@ void OutdoorPvP::BroadcastPacket(WorldPacket const* data) const
|
||||
player->SendDirectMessage(data);
|
||||
}
|
||||
|
||||
void OutdoorPvP::AddCapturePoint(OPvPCapturePoint* cp)
|
||||
{
|
||||
OPvPCapturePointMap::iterator i = m_capturePoints.find(cp->m_capturePointSpawnId);
|
||||
if (i != m_capturePoints.end())
|
||||
{
|
||||
TC_LOG_ERROR("outdoorpvp", "OutdoorPvP::AddCapturePoint: CapturePoint {} already exists!", cp->m_capturePointSpawnId);
|
||||
if (i->second.get() == cp)
|
||||
return;
|
||||
}
|
||||
m_capturePoints[cp->m_capturePointSpawnId].reset(cp);
|
||||
}
|
||||
|
||||
OPvPCapturePoint* OutdoorPvP::GetCapturePoint(ObjectGuid::LowType guid) const
|
||||
{
|
||||
OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.find(guid);
|
||||
if (itr != m_capturePoints.end())
|
||||
return itr->second.get();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OutdoorPvP::RegisterZone(uint32 zoneId)
|
||||
{
|
||||
sOutdoorPvPMgr->AddZone(zoneId, this);
|
||||
@@ -452,24 +203,6 @@ void OutdoorPvP::TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2)
|
||||
TeamCastSpell(OTHER_TEAM(team), spellId2 ? -(int32)spellId2 : -(int32)spellId);
|
||||
}
|
||||
|
||||
void OutdoorPvP::OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
if (go->GetGoType() != GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
return;
|
||||
|
||||
if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId()))
|
||||
cp->m_capturePoint = go;
|
||||
}
|
||||
|
||||
void OutdoorPvP::OnGameObjectRemove(GameObject* go)
|
||||
{
|
||||
if (go->GetGoType() != GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
return;
|
||||
|
||||
if (OPvPCapturePoint *cp = GetCapturePoint(go->GetSpawnId()))
|
||||
cp->m_capturePoint = nullptr;
|
||||
}
|
||||
|
||||
void OutdoorPvP::SendDefenseMessage(uint32 zoneId, uint32 id)
|
||||
{
|
||||
DefenseMessageBuilder builder(zoneId, id);
|
||||
@@ -477,6 +210,40 @@ void OutdoorPvP::SendDefenseMessage(uint32 zoneId, uint32 id)
|
||||
BroadcastWorker(localizer, zoneId);
|
||||
}
|
||||
|
||||
void OutdoorPvP::ProcessEvent([[maybe_unused]] WorldObject * target, [[maybe_unused]] uint32 eventId, [[maybe_unused]] WorldObject * invoker)
|
||||
{
|
||||
if (invoker)
|
||||
{
|
||||
if (GameObject* gameobject = invoker->ToGameObject())
|
||||
{
|
||||
if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
{
|
||||
if (!ControlZoneHandlers.contains(gameobject->GetEntry()))
|
||||
return;
|
||||
|
||||
auto controlzone = gameobject->GetGOInfo()->controlZone;
|
||||
OutdoorPvPControlZoneHandler& handler = *ControlZoneHandlers[invoker->GetEntry()];
|
||||
if (eventId == controlzone.CaptureEventAlliance)
|
||||
handler.HandleCaptureEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.CaptureEventHorde)
|
||||
handler.HandleCaptureEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ContestedEventAlliance)
|
||||
handler.HandleContestedEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ContestedEventHorde)
|
||||
handler.HandleContestedEventHorde(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventAlliance)
|
||||
handler.HandleNeutralEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.NeutralEventHorde)
|
||||
handler.HandleNeutralEventHorde(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventAlliance)
|
||||
handler.HandleProgressEventAlliance(gameobject);
|
||||
else if (eventId == controlzone.ProgressEventHorde)
|
||||
handler.HandleProgressEventHorde(gameobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class Worker>
|
||||
void OutdoorPvP::BroadcastWorker(Worker& _worker, uint32 zoneId)
|
||||
{
|
||||
|
||||
@@ -88,68 +88,41 @@ class TC_GAME_API OPvPCapturePoint
|
||||
OPvPCapturePoint& operator=(OPvPCapturePoint const& right) = delete;
|
||||
OPvPCapturePoint& operator=(OPvPCapturePoint&& right) = delete;
|
||||
|
||||
// send world state update to all players present
|
||||
void SendUpdateWorldState(uint32 field, uint32 value);
|
||||
|
||||
// send kill notify to players in the controlling faction
|
||||
void SendObjectiveComplete(uint32 id, ObjectGuid guid);
|
||||
|
||||
// used when player is activated/inactivated in the area
|
||||
virtual bool HandlePlayerEnter(Player* player);
|
||||
virtual void HandlePlayerLeave(Player* player);
|
||||
|
||||
// checks if player is in range of a capture credit marker
|
||||
bool IsInsideObjective(Player* player) const;
|
||||
virtual void Update([[maybe_unused]] uint32 diff) { }
|
||||
|
||||
virtual bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go);
|
||||
|
||||
virtual int32 HandleOpenGo(Player* player, GameObject* go);
|
||||
|
||||
// returns true if the state of the objective has changed, in this case, the OutdoorPvP must send a world state ui update.
|
||||
virtual bool Update(uint32 diff);
|
||||
|
||||
virtual void ChangeState() = 0;
|
||||
|
||||
virtual void ChangeTeam(TeamId /*oldTeam*/) { }
|
||||
|
||||
virtual void SendChangePhase();
|
||||
|
||||
virtual bool HandleDropFlag(Player* /*player*/, uint32 /*spellId*/) { return false; }
|
||||
|
||||
ObjectGuid::LowType m_capturePointSpawnId;
|
||||
|
||||
GameObject* m_capturePoint;
|
||||
|
||||
bool SetCapturePointData(uint32 entry);
|
||||
|
||||
protected:
|
||||
|
||||
// active players in the area of the objective, 0 - alliance, 1 - horde
|
||||
GuidSet m_activePlayers[2];
|
||||
|
||||
// total shift needed to capture the objective
|
||||
float m_maxValue;
|
||||
float m_minValue;
|
||||
|
||||
// maximum speed of capture
|
||||
float m_maxSpeed;
|
||||
|
||||
// the status of the objective
|
||||
float m_value;
|
||||
|
||||
TeamId m_team;
|
||||
|
||||
// objective states
|
||||
ObjectiveStates m_OldState;
|
||||
ObjectiveStates m_State;
|
||||
|
||||
// neutral value on capture bar
|
||||
uint32 m_neutralValuePct;
|
||||
|
||||
// pointer to the OutdoorPvP this objective belongs to
|
||||
OutdoorPvP* m_PvP;
|
||||
};
|
||||
|
||||
class TC_GAME_API OutdoorPvPControlZoneHandler : public ControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit OutdoorPvPControlZoneHandler(OutdoorPvP* pvp) : _pvp(pvp) { }
|
||||
virtual ~OutdoorPvPControlZoneHandler() = default;
|
||||
|
||||
OutdoorPvP* GetOutdoorPvP() const { return _pvp; }
|
||||
private:
|
||||
OutdoorPvP* _pvp;
|
||||
};
|
||||
|
||||
// base class for specific outdoor pvp handlers
|
||||
class TC_GAME_API OutdoorPvP : public ZoneScript
|
||||
{
|
||||
@@ -168,6 +141,7 @@ class TC_GAME_API OutdoorPvP : public ZoneScript
|
||||
virtual ~OutdoorPvP();
|
||||
|
||||
typedef std::map<ObjectGuid::LowType/*spawnId*/, std::unique_ptr<OPvPCapturePoint>> OPvPCapturePointMap;
|
||||
typedef std::unordered_map<uint32 /*control zone entry*/, std::unique_ptr<OutdoorPvPControlZoneHandler>> ControlZoneHandlerMap;
|
||||
|
||||
// called when a player triggers an areatrigger
|
||||
virtual bool HandleAreaTrigger(Player* /*player*/, uint32 /*trigger*/, bool /*entered*/) { return false; }
|
||||
@@ -181,24 +155,19 @@ class TC_GAME_API OutdoorPvP : public ZoneScript
|
||||
// setup stuff
|
||||
virtual bool SetupOutdoorPvP() {return true;}
|
||||
|
||||
void OnGameObjectCreate(GameObject* go) override;
|
||||
void OnGameObjectRemove(GameObject* go) override;
|
||||
void OnCreatureCreate(Creature*) override { }
|
||||
|
||||
// send world state update to all players present
|
||||
int32 GetWorldState(int32 worldStateId) const;
|
||||
void SetWorldState(int32 worldStateId, int32 value);
|
||||
|
||||
// called by OutdoorPvPMgr, updates the objectives and if needed, sends new worldstateui information
|
||||
virtual bool Update(uint32 diff);
|
||||
// called by OutdoorPvPMgr
|
||||
virtual void Update(uint32 diff);
|
||||
|
||||
// handle npc/player kill
|
||||
virtual void HandleKill(Player* killer, Unit* killed);
|
||||
virtual void HandleKillImpl(Player* /*killer*/, Unit* /*killed*/) { }
|
||||
|
||||
// checks if player is in range of a capture credit marker
|
||||
bool IsInsideObjective(Player* player) const;
|
||||
|
||||
// awards rewards for player kill
|
||||
virtual void AwardKillBonus(Player* /*player*/) { }
|
||||
|
||||
@@ -225,11 +194,15 @@ class TC_GAME_API OutdoorPvP : public ZoneScript
|
||||
|
||||
Map* GetMap() const { return m_map; }
|
||||
|
||||
void ProcessEvent([[maybe_unused]] WorldObject* target, [[maybe_unused]] uint32 eventId, [[maybe_unused]] WorldObject* invoker) override;
|
||||
|
||||
protected:
|
||||
|
||||
// the map of the objectives belonging to this outdoorpvp
|
||||
OPvPCapturePointMap m_capturePoints;
|
||||
|
||||
ControlZoneHandlerMap ControlZoneHandlers;
|
||||
|
||||
GuidSet m_players[2];
|
||||
|
||||
uint32 m_TypeId;
|
||||
@@ -244,10 +217,6 @@ class TC_GAME_API OutdoorPvP : public ZoneScript
|
||||
|
||||
virtual void HandlePlayerResurrects(Player* player, uint32 zone);
|
||||
|
||||
void AddCapturePoint(OPvPCapturePoint* cp);
|
||||
|
||||
OPvPCapturePoint* GetCapturePoint(ObjectGuid::LowType guid) const;
|
||||
|
||||
void RegisterZone(uint32 zoneid);
|
||||
|
||||
bool HasPlayer(Player const* player) const;
|
||||
|
||||
@@ -100,15 +100,25 @@ bool BattlefieldTB::SetupBattlefield()
|
||||
// Create capture points
|
||||
for (uint8 i = 0; i < TB_BASE_COUNT; i++)
|
||||
{
|
||||
TolBaradCapturePoint* capturePoint = new TolBaradCapturePoint(this, GetDefenderTeam());
|
||||
|
||||
//Spawn flag pole
|
||||
if (GameObject* go = SpawnGameObject(TBCapturePoints[i].entryFlagPole[GetDefenderTeam()], TBCapturePoints[i].pos, QuaternionData::fromEulerAnglesZYX(TBCapturePoints[i].pos.GetOrientation(), 0.0f, 0.0f)))
|
||||
{
|
||||
go->SetGoArtKit(GetDefenderTeam() == TEAM_ALLIANCE ? TB_GO_ARTKIT_FLAG_ALLIANCE : TB_GO_ARTKIT_FLAG_HORDE);
|
||||
capturePoint->SetCapturePointData(go);
|
||||
std::unique_ptr<TolBaradCapturePoint> controlZone = std::make_unique<TolBaradCapturePoint>(this, TBCapturePoints[i]);
|
||||
if (GetDefenderTeam() == TEAM_ALLIANCE)
|
||||
{
|
||||
sWorldStateMgr->SetValue(controlZone->GetWorldStateAllianceControlled(), 1, false, GetMap());
|
||||
go->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue(100));
|
||||
go->SetGoArtKit(TB_GO_ARTKIT_FLAG_ALLIANCE);
|
||||
}
|
||||
else if (GetDefenderTeam() == TEAM_HORDE)
|
||||
{
|
||||
sWorldStateMgr->SetValue(controlZone->GetWorldStateHordeControlled(), 1, false, GetMap());
|
||||
go->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue(0));
|
||||
go->SetGoArtKit(TB_GO_ARTKIT_FLAG_HORDE);
|
||||
}
|
||||
|
||||
ControlZoneHandlers[go->GetEntry()] = std::move(controlZone);
|
||||
}
|
||||
AddCapturePoint(capturePoint);
|
||||
}
|
||||
|
||||
// Spawn towers
|
||||
@@ -379,23 +389,29 @@ void BattlefieldTB::UpdateNPCsAndGameObjects()
|
||||
if (GetState() == BATTLEFIELD_INACTIVE)
|
||||
{
|
||||
// Delete capture points
|
||||
for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
itr->second->DelCapturePoint();
|
||||
m_capturePoints.clear();
|
||||
ControlZoneHandlers.clear();
|
||||
|
||||
// Create capture points
|
||||
for (uint8 i = 0; i < TB_BASE_COUNT; i++)
|
||||
{
|
||||
TolBaradCapturePoint* capturePoint = new TolBaradCapturePoint(this, GetDefenderTeam());
|
||||
|
||||
//Spawn flag pole
|
||||
if (GameObject* go = SpawnGameObject(TBCapturePoints[i].entryFlagPole[GetDefenderTeam()], TBCapturePoints[i].pos, QuaternionData::fromEulerAnglesZYX(TBCapturePoints[i].pos.GetOrientation(), 0.0f, 0.0f)))
|
||||
{
|
||||
go->SetGoArtKit(GetDefenderTeam() == TEAM_ALLIANCE ? TB_GO_ARTKIT_FLAG_ALLIANCE : TB_GO_ARTKIT_FLAG_HORDE);
|
||||
capturePoint->SetCapturePointData(go);
|
||||
}
|
||||
std::unique_ptr<TolBaradCapturePoint> controlZone = std::make_unique<TolBaradCapturePoint>(this, TBCapturePoints[i]);
|
||||
if (GetDefenderTeam() == TEAM_ALLIANCE)
|
||||
{
|
||||
sWorldStateMgr->SetValue(controlZone->GetWorldStateAllianceControlled(), 1, false, GetMap());
|
||||
go->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue(100));
|
||||
go->SetGoArtKit(TB_GO_ARTKIT_FLAG_ALLIANCE);
|
||||
}
|
||||
else if (GetDefenderTeam() == TEAM_HORDE)
|
||||
{
|
||||
sWorldStateMgr->SetValue(controlZone->GetWorldStateHordeControlled(), 1, false, GetMap());
|
||||
go->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue(0));
|
||||
go->SetGoArtKit(TB_GO_ARTKIT_FLAG_HORDE);
|
||||
}
|
||||
|
||||
AddCapturePoint(capturePoint);
|
||||
ControlZoneHandlers[go->GetEntry()] = std::move(controlZone);
|
||||
}
|
||||
}
|
||||
|
||||
for (ObjectGuid guid : BattleInactiveNPCs)
|
||||
@@ -558,8 +574,9 @@ void BattlefieldTB::OnGameObjectCreate(GameObject* go)
|
||||
}
|
||||
}
|
||||
|
||||
void BattlefieldTB::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* /*invoker*/)
|
||||
void BattlefieldTB::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker)
|
||||
{
|
||||
Battlefield::ProcessEvent(obj, eventId, invoker);
|
||||
if (!IsWarTime())
|
||||
return;
|
||||
|
||||
@@ -644,9 +661,19 @@ void BattlefieldTB::UpdateCapturedBaseCount()
|
||||
{
|
||||
uint32 numCapturedBases = 0; // How many bases attacker has captured
|
||||
|
||||
for (BfCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||
if (itr->second->GetTeamId() == GetAttackerTeam())
|
||||
numCapturedBases += 1;
|
||||
// these world states are either 0 or 1
|
||||
if (GetAttackerTeam() == TEAM_ALLIANCE)
|
||||
{
|
||||
numCapturedBases += sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_GARRISON_ALLIANCE_CONTROLLED, GetMap());
|
||||
numCapturedBases += sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_VIGIL_ALLIANCE_CONTROLLED, GetMap());
|
||||
numCapturedBases += sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_SLAGWORKS_ALLIANCE_CONTROLLED, GetMap());
|
||||
}
|
||||
else if (GetAttackerTeam() == TEAM_HORDE)
|
||||
{
|
||||
numCapturedBases += sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_GARRISON_HORDE_CONTROLLED, GetMap());
|
||||
numCapturedBases += sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_VIGIL_HORDE_CONTROLLED, GetMap());
|
||||
numCapturedBases += sWorldStateMgr->GetValue(WS_BATTLEFIELD_TB_SLAGWORKS_HORDE_CONTROLLED, GetMap());
|
||||
}
|
||||
|
||||
sWorldStateMgr->SetValue(WS_BATTLEFIELD_TB_BUILDINGS_CAPTURED, numCapturedBases, false, m_Map);
|
||||
|
||||
@@ -676,76 +703,65 @@ void BattlefieldTB::PromotePlayer(Player* killer)
|
||||
killer->CastSpell(killer, SPELL_TB_VETERAN, true);
|
||||
}
|
||||
|
||||
TolBaradCapturePoint::TolBaradCapturePoint(BattlefieldTB* battlefield, TeamId teamInControl) : BfCapturePoint(battlefield)
|
||||
TolBaradCapturePoint::TolBaradCapturePoint(BattlefieldTB* battlefield, TBCapturePointSpawnData const& data) : BattlefieldControlZoneHandler(battlefield),
|
||||
_textIdHordeCaptured(data.textGained[TEAM_HORDE]), _textIdAllianceCaptured(data.textGained[TEAM_ALLIANCE]),
|
||||
_textIdHordeLost(data.textLost[TEAM_HORDE]), _textIdAllianceLost(data.textLost[TEAM_ALLIANCE]),
|
||||
_worldstateHordeControlled(data.wsControlled[TEAM_HORDE]), _worldstateAllianceControlled(data.wsControlled[TEAM_ALLIANCE]),
|
||||
_worldstateHordeCapturing(data.wsCapturing[TEAM_HORDE]), _worldstateAllianceCapturing(data.wsCapturing[TEAM_ALLIANCE]),
|
||||
_worldstateNeutral(data.wsNeutral)
|
||||
{
|
||||
m_Bf = battlefield;
|
||||
m_team = teamInControl;
|
||||
m_value = teamInControl == TEAM_ALLIANCE ? m_maxValue : -m_maxValue;
|
||||
m_State = teamInControl == TEAM_ALLIANCE ? BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE : BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE;
|
||||
}
|
||||
|
||||
void TolBaradCapturePoint::SendChangePhase()
|
||||
void TolBaradCapturePoint::HandleContestedEventHorde(GameObject* controlZone)
|
||||
{
|
||||
if (m_OldState == m_State)
|
||||
return;
|
||||
BattlefieldControlZoneHandler::HandleContestedEventHorde(controlZone);
|
||||
}
|
||||
|
||||
// Find out index
|
||||
uint8 iBase = TB_BASE_COUNT;
|
||||
for (uint8 i = 0; i < TB_BASE_COUNT; i++)
|
||||
if (GetCapturePointEntry() == TBCapturePoints[i].entryFlagPole[m_Bf->GetDefenderTeam()])
|
||||
iBase = i;
|
||||
void TolBaradCapturePoint::HandleContestedEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
BattlefieldControlZoneHandler::HandleContestedEventAlliance(controlZone);
|
||||
}
|
||||
|
||||
if (iBase == TB_BASE_COUNT)
|
||||
return;
|
||||
void TolBaradCapturePoint::HandleProgressEventHorde(GameObject* controlZone)
|
||||
{
|
||||
BattlefieldControlZoneHandler::HandleProgressEventHorde(controlZone);
|
||||
GetBattlefield()->SendWarning(_textIdHordeCaptured);
|
||||
controlZone->SetGoArtKit(TB_GO_ARTKIT_FLAG_HORDE);
|
||||
sWorldStateMgr->SetValue(_worldstateHordeControlled, 1, false, controlZone->GetMap());
|
||||
sWorldStateMgr->SetValue(_worldstateHordeCapturing, 0, false, controlZone->GetMap());
|
||||
GetBattlefield()->ProcessEvent(nullptr, EVENT_COUNT_CAPTURED_BASE, nullptr);
|
||||
}
|
||||
|
||||
// Turn off previous world state icon
|
||||
switch (m_OldState)
|
||||
{
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
|
||||
sWorldStateMgr->SetValue(TBCapturePoints[iBase].wsControlled[GetTeamId()], 0, false, m_Bf->GetMap());
|
||||
break;
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
sWorldStateMgr->SetValue(TBCapturePoints[iBase].wsCapturing[TEAM_ALLIANCE], 0, false, m_Bf->GetMap());
|
||||
break;
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
sWorldStateMgr->SetValue(TBCapturePoints[iBase].wsCapturing[TEAM_HORDE], 0, false, m_Bf->GetMap());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
void TolBaradCapturePoint::HandleProgressEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
BattlefieldControlZoneHandler::HandleProgressEventAlliance(controlZone);
|
||||
GetBattlefield()->SendWarning(_textIdAllianceCaptured);
|
||||
controlZone->SetGoArtKit(TB_GO_ARTKIT_FLAG_ALLIANCE);
|
||||
sWorldStateMgr->SetValue(_worldstateAllianceControlled, 1, false, controlZone->GetMap());
|
||||
sWorldStateMgr->SetValue(_worldstateAllianceCapturing, 0, false, controlZone->GetMap());
|
||||
GetBattlefield()->ProcessEvent(nullptr, EVENT_COUNT_CAPTURED_BASE, nullptr);
|
||||
}
|
||||
|
||||
// Turn on new world state icon and send warning
|
||||
switch (m_State)
|
||||
{
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE:
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE:
|
||||
m_Bf->SendWarning(TBCapturePoints[iBase].textGained[GetTeamId()]);
|
||||
sWorldStateMgr->SetValue(TBCapturePoints[iBase].wsControlled[GetTeamId()], 1, false, m_Bf->GetMap());
|
||||
GetCapturePointGo()->SetGoArtKit(GetTeamId() == TEAM_ALLIANCE ? TB_GO_ARTKIT_FLAG_ALLIANCE : TB_GO_ARTKIT_FLAG_HORDE);
|
||||
break;
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
m_Bf->SendWarning(TBCapturePoints[iBase].textLost[TEAM_HORDE]);
|
||||
[[fallthrough]];
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
sWorldStateMgr->SetValue(TBCapturePoints[iBase].wsCapturing[TEAM_ALLIANCE], 1, false, m_Bf->GetMap());
|
||||
GetCapturePointGo()->SetGoArtKit(TB_GO_ARTKIT_FLAG_NONE);
|
||||
break;
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
m_Bf->SendWarning(TBCapturePoints[iBase].textLost[TEAM_ALLIANCE]);
|
||||
[[fallthrough]];
|
||||
case BF_CAPTUREPOINT_OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
sWorldStateMgr->SetValue(TBCapturePoints[iBase].wsCapturing[TEAM_HORDE], 1, false, m_Bf->GetMap());
|
||||
GetCapturePointGo()->SetGoArtKit(TB_GO_ARTKIT_FLAG_NONE);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
void TolBaradCapturePoint::HandleNeutralEventHorde(GameObject* controlZone)
|
||||
{
|
||||
GetBattlefield()->SendWarning(_textIdHordeLost);
|
||||
sWorldStateMgr->SetValue(_worldstateHordeControlled, 0, false, controlZone->GetMap());
|
||||
sWorldStateMgr->SetValue(_worldstateAllianceCapturing, 1, false, controlZone->GetMap());
|
||||
BattlefieldControlZoneHandler::HandleNeutralEventHorde(controlZone);
|
||||
}
|
||||
|
||||
// Update counter
|
||||
m_Bf->ProcessEvent(nullptr, EVENT_COUNT_CAPTURED_BASE, nullptr);
|
||||
void TolBaradCapturePoint::HandleNeutralEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
GetBattlefield()->SendWarning(_textIdAllianceLost);
|
||||
sWorldStateMgr->SetValue(_worldstateAllianceControlled, 0, false, controlZone->GetMap());
|
||||
sWorldStateMgr->SetValue(_worldstateHordeCapturing, 1, false, controlZone->GetMap());
|
||||
BattlefieldControlZoneHandler::HandleNeutralEventAlliance(controlZone);
|
||||
}
|
||||
|
||||
void TolBaradCapturePoint::HandleNeutralEvent(GameObject* controlZone)
|
||||
{
|
||||
BattlefieldControlZoneHandler::HandleNeutralEvent(controlZone);
|
||||
controlZone->SetGoArtKit(TB_GO_ARTKIT_FLAG_NONE);
|
||||
}
|
||||
|
||||
class Battlefield_tol_barad : public BattlefieldScript
|
||||
|
||||
@@ -533,12 +533,32 @@ TBGraveyardInfo const TBGraveyards[BATTLEFIELD_TB_GRAVEYARD_MAX] =
|
||||
* Tol Barad capture point *
|
||||
* ####################### */
|
||||
|
||||
class TolBaradCapturePoint : public BfCapturePoint
|
||||
class TolBaradCapturePoint : public BattlefieldControlZoneHandler
|
||||
{
|
||||
public:
|
||||
TolBaradCapturePoint(BattlefieldTB* battlefield, TeamId teamInControl);
|
||||
TolBaradCapturePoint(BattlefieldTB* battlefield, TBCapturePointSpawnData const& data);
|
||||
|
||||
void SendChangePhase() override;
|
||||
void HandleContestedEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleContestedEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEvent([[maybe_unused]] GameObject* controlZone) override;
|
||||
|
||||
uint32 GetWorldStateHordeControlled() const { return _worldstateHordeControlled; }
|
||||
uint32 GetWorldStateAllianceControlled() const { return _worldstateAllianceControlled; }
|
||||
|
||||
private:
|
||||
uint32 _textIdHordeCaptured;
|
||||
uint32 _textIdAllianceCaptured;
|
||||
uint32 _textIdHordeLost;
|
||||
uint32 _textIdAllianceLost;
|
||||
uint32 _worldstateHordeControlled;
|
||||
uint32 _worldstateAllianceControlled;
|
||||
uint32 _worldstateHordeCapturing;
|
||||
uint32 _worldstateAllianceCapturing;
|
||||
uint32 _worldstateNeutral;
|
||||
};
|
||||
|
||||
/* ##################### *
|
||||
|
||||
@@ -928,11 +928,18 @@ void BattlefieldWG::OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
if (workshop->GetId() == workshopId)
|
||||
{
|
||||
WintergraspCapturePoint* capturePoint = new WintergraspCapturePoint(this, GetAttackerTeam());
|
||||
ControlZoneHandlers[go->GetEntry()] = std::make_unique<WintergraspCapturePoint>(this, workshop);
|
||||
if (GetAttackerTeam() == TEAM_ALLIANCE)
|
||||
{
|
||||
//go->SetGoArtKit(); // todo set art kit
|
||||
go->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue(100));
|
||||
}
|
||||
else if (GetAttackerTeam() == TEAM_HORDE)
|
||||
{
|
||||
//go->SetGoArtKit(); // todo set art kit
|
||||
go->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue(0));
|
||||
}
|
||||
|
||||
capturePoint->SetCapturePointData(go);
|
||||
capturePoint->LinkToWorkshop(workshop);
|
||||
AddCapturePoint(capturePoint);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1185,8 +1192,9 @@ void BattlefieldWG::UpdatedDestroyedTowerCount(TeamId team)
|
||||
}
|
||||
}
|
||||
|
||||
void BattlefieldWG::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* /*invoker*/)
|
||||
void BattlefieldWG::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker)
|
||||
{
|
||||
Battlefield::ProcessEvent(obj, eventId, invoker);
|
||||
if (!obj || !IsWarTime())
|
||||
return;
|
||||
|
||||
@@ -1311,17 +1319,34 @@ void BattlefieldWG::UpdateTenacity()
|
||||
m_tenacityTeam = TEAM_NEUTRAL;
|
||||
}
|
||||
|
||||
WintergraspCapturePoint::WintergraspCapturePoint(BattlefieldWG* battlefield, TeamId teamInControl) : BfCapturePoint(battlefield)
|
||||
WintergraspCapturePoint::WintergraspCapturePoint(BattlefieldWG* battlefield, WintergraspWorkshop* workshop) : BattlefieldControlZoneHandler(battlefield), m_Workshop(workshop)
|
||||
{
|
||||
m_Bf = battlefield;
|
||||
m_team = teamInControl;
|
||||
m_Workshop = nullptr;
|
||||
}
|
||||
|
||||
void WintergraspCapturePoint::ChangeTeam(TeamId /*oldTeam*/)
|
||||
void WintergraspCapturePoint::HandleContestedEventHorde(GameObject* controlZone)
|
||||
{
|
||||
ASSERT(m_Workshop);
|
||||
m_Workshop->GiveControlTo(m_team);
|
||||
BattlefieldControlZoneHandler::HandleContestedEventHorde(controlZone);
|
||||
m_Workshop->GiveControlTo(TEAM_NEUTRAL);
|
||||
}
|
||||
|
||||
void WintergraspCapturePoint::HandleContestedEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
ASSERT(m_Workshop);
|
||||
BattlefieldControlZoneHandler::HandleContestedEventAlliance(controlZone);
|
||||
m_Workshop->GiveControlTo(TEAM_NEUTRAL);
|
||||
}
|
||||
|
||||
void WintergraspCapturePoint::HandleProgressEventHorde(GameObject* /*controlZone*/)
|
||||
{
|
||||
ASSERT(m_Workshop);
|
||||
m_Workshop->GiveControlTo(TEAM_HORDE);
|
||||
}
|
||||
|
||||
void WintergraspCapturePoint::HandleProgressEventAlliance(GameObject* /*controlZone*/)
|
||||
{
|
||||
ASSERT(m_Workshop);
|
||||
m_Workshop->GiveControlTo(TEAM_ALLIANCE);
|
||||
}
|
||||
|
||||
BfGraveyardWG::BfGraveyardWG(BattlefieldWG* battlefield) : BfGraveyard(battlefield)
|
||||
|
||||
@@ -179,15 +179,15 @@ enum WintergraspNpcs
|
||||
* WintergraspCapturePoint *
|
||||
* ######################### */
|
||||
|
||||
class WintergraspCapturePoint : public BfCapturePoint
|
||||
class WintergraspCapturePoint : public BattlefieldControlZoneHandler
|
||||
{
|
||||
public:
|
||||
WintergraspCapturePoint(BattlefieldWG* battlefield, TeamId teamInControl);
|
||||
WintergraspCapturePoint(BattlefieldWG* battlefield, WintergraspWorkshop* workshop);
|
||||
|
||||
void LinkToWorkshop(WintergraspWorkshop* workshop) { m_Workshop = workshop; }
|
||||
|
||||
void ChangeTeam(TeamId oldteam) override;
|
||||
TeamId GetTeam() const { return m_team; }
|
||||
void HandleContestedEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleContestedEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
|
||||
protected:
|
||||
WintergraspWorkshop* m_Workshop;
|
||||
|
||||
@@ -18,38 +18,52 @@
|
||||
#include "OutdoorPvPHP.h"
|
||||
#include "GameObject.h"
|
||||
#include "Map.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptMgr.h"
|
||||
#include "WorldStatePackets.h"
|
||||
|
||||
uint32 const OutdoorPvPHPBuffZonesNum = 6;
|
||||
uint32 const OutdoorPvPHPBuffZones[OutdoorPvPHPBuffZonesNum] = { 3483, 3563, 3562, 3713, 3714, 3836 }; // HP, citadel, ramparts, blood furnace, shattered halls, mag's lair
|
||||
uint32 const HP_CREDITMARKER[HP_TOWER_NUM] = { 19032, 19028, 19029 };
|
||||
//uint32 const HP_CapturePointEvent_Enter[HP_TOWER_NUM] = { 11404, 11396, 11388 };
|
||||
//uint32 const HP_CapturePointEvent_Leave[HP_TOWER_NUM] = { 11403, 11395, 11387 };
|
||||
uint32 const HP_MAP_N[HP_TOWER_NUM] = { 2485, 2482, 2472 };
|
||||
uint32 const HP_MAP_A[HP_TOWER_NUM] = { 2483, 2480, 2471 };
|
||||
uint32 const HP_MAP_H[HP_TOWER_NUM] = { 2484, 2481, 2470 };
|
||||
uint32 const HP_TowerArtKit_A[HP_TOWER_NUM] = { 65, 62, 67 };
|
||||
uint32 const HP_TowerArtKit_H[HP_TOWER_NUM] = { 64, 61, 68 };
|
||||
uint32 const HP_TowerArtKit_N[HP_TOWER_NUM] = { 66, 63, 69 };
|
||||
|
||||
uint32 const HP_LANG_CAPTURE_A[HP_TOWER_NUM] = { TEXT_BROKEN_HILL_TAKEN_ALLIANCE, TEXT_OVERLOOK_TAKEN_ALLIANCE, TEXT_STADIUM_TAKEN_ALLIANCE };
|
||||
uint32 const HP_LANG_CAPTURE_H[HP_TOWER_NUM] = { TEXT_BROKEN_HILL_TAKEN_HORDE, TEXT_OVERLOOK_TAKEN_HORDE, TEXT_STADIUM_TAKEN_HORDE };
|
||||
|
||||
OPvPCapturePointHP::OPvPCapturePointHP(OutdoorPvP* pvp, OutdoorPvPHPTowerType type, GameObject* go, ObjectGuid::LowType const& flagSpawnId)
|
||||
: OPvPCapturePoint(pvp), m_TowerType(type), m_flagSpawnId(flagSpawnId)
|
||||
{
|
||||
m_capturePointSpawnId = go->GetSpawnId();
|
||||
m_capturePoint = go;
|
||||
SetCapturePointData(go->GetEntry());
|
||||
}
|
||||
|
||||
OutdoorPvPHP::OutdoorPvPHP(Map* map) : OutdoorPvP(map), m_towerFlagSpawnIds()
|
||||
OutdoorPvPHP::OutdoorPvPHP(Map* map) : OutdoorPvP(map)
|
||||
{
|
||||
m_TypeId = OUTDOOR_PVP_HP;
|
||||
m_AllianceTowersControlled = 0;
|
||||
m_HordeTowersControlled = 0;
|
||||
|
||||
ControlZoneHandlers[HP_GO_ENTRY_TOWER_S] = std::make_unique<HPControlZoneHandler>(this);
|
||||
GetControlZoneTowerSouthHandler().SetFlagArtKitAlliance(65);
|
||||
GetControlZoneTowerSouthHandler().SetFlagArtKitHorde(64);
|
||||
GetControlZoneTowerSouthHandler().SetFlagArtKitNeutral(66);
|
||||
GetControlZoneTowerSouthHandler().SetTextCaptureAlliance(TEXT_BROKEN_HILL_TAKEN_ALLIANCE);
|
||||
GetControlZoneTowerSouthHandler().SetTextCaptureHorde(TEXT_BROKEN_HILL_TAKEN_HORDE);
|
||||
GetControlZoneTowerSouthHandler().SetWorldstateAlliance(HP_UI_TOWER_S_A);
|
||||
GetControlZoneTowerSouthHandler().SetWorldstateHorde(HP_UI_TOWER_S_H);
|
||||
GetControlZoneTowerSouthHandler().SetWorldstateNeutral(HP_UI_TOWER_S_N);
|
||||
GetControlZoneTowerSouthHandler().SetKillCredit(HP_KILL_CREDIT_TOWER_S);
|
||||
|
||||
ControlZoneHandlers[HP_GO_ENTRY_TOWER_N] = std::make_unique<HPControlZoneHandler>(this);
|
||||
GetControlZoneTowerNorthHandler().SetFlagArtKitAlliance(62);
|
||||
GetControlZoneTowerNorthHandler().SetFlagArtKitHorde(61);
|
||||
GetControlZoneTowerNorthHandler().SetFlagArtKitNeutral(63);
|
||||
GetControlZoneTowerNorthHandler().SetTextCaptureAlliance(TEXT_OVERLOOK_TAKEN_ALLIANCE);
|
||||
GetControlZoneTowerNorthHandler().SetTextCaptureHorde(TEXT_OVERLOOK_TAKEN_HORDE);
|
||||
GetControlZoneTowerNorthHandler().SetWorldstateAlliance(HP_UI_TOWER_N_A);
|
||||
GetControlZoneTowerNorthHandler().SetWorldstateHorde(HP_UI_TOWER_N_H);
|
||||
GetControlZoneTowerNorthHandler().SetWorldstateNeutral(HP_UI_TOWER_N_N);
|
||||
GetControlZoneTowerNorthHandler().SetKillCredit(HP_KILL_CREDIT_TOWER_N);
|
||||
|
||||
ControlZoneHandlers[HP_GO_ENTRY_TOWER_W] = std::make_unique<HPControlZoneHandler>(this);
|
||||
GetControlZoneTowerWestHandler().SetFlagArtKitAlliance(67);
|
||||
GetControlZoneTowerWestHandler().SetFlagArtKitHorde(68);
|
||||
GetControlZoneTowerWestHandler().SetFlagArtKitNeutral(69);
|
||||
GetControlZoneTowerWestHandler().SetTextCaptureAlliance(TEXT_STADIUM_TAKEN_ALLIANCE);
|
||||
GetControlZoneTowerWestHandler().SetTextCaptureHorde(TEXT_STADIUM_TAKEN_HORDE);
|
||||
GetControlZoneTowerWestHandler().SetWorldstateAlliance(HP_UI_TOWER_W_A);
|
||||
GetControlZoneTowerWestHandler().SetWorldstateHorde(HP_UI_TOWER_W_H);
|
||||
GetControlZoneTowerWestHandler().SetWorldstateNeutral(HP_UI_TOWER_W_N);
|
||||
GetControlZoneTowerWestHandler().SetKillCredit(HP_KILL_CREDIT_TOWER_W);
|
||||
}
|
||||
|
||||
bool OutdoorPvPHP::SetupOutdoorPvP()
|
||||
@@ -66,25 +80,19 @@ bool OutdoorPvPHP::SetupOutdoorPvP()
|
||||
|
||||
void OutdoorPvPHP::OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
if (go->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
|
||||
_controlZoneGUIDs.insert(go->GetGUID());
|
||||
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case 182175:
|
||||
AddCapturePoint(new OPvPCapturePointHP(this, HP_TOWER_BROKEN_HILL, go, m_towerFlagSpawnIds[HP_TOWER_BROKEN_HILL]));
|
||||
break;
|
||||
case 182174:
|
||||
AddCapturePoint(new OPvPCapturePointHP(this, HP_TOWER_OVERLOOK, go, m_towerFlagSpawnIds[HP_TOWER_OVERLOOK]));
|
||||
break;
|
||||
case 182173:
|
||||
AddCapturePoint(new OPvPCapturePointHP(this, HP_TOWER_STADIUM, go, m_towerFlagSpawnIds[HP_TOWER_STADIUM]));
|
||||
break;
|
||||
case 183514:
|
||||
m_towerFlagSpawnIds[HP_TOWER_BROKEN_HILL] = go->GetSpawnId();
|
||||
GetControlZoneTowerSouthHandler().SetFlagGuid(go->GetGUID());
|
||||
break;
|
||||
case 182525:
|
||||
m_towerFlagSpawnIds[HP_TOWER_OVERLOOK] = go->GetSpawnId();
|
||||
GetControlZoneTowerNorthHandler().SetFlagGuid(go->GetGUID());
|
||||
break;
|
||||
case 183515:
|
||||
m_towerFlagSpawnIds[HP_TOWER_STADIUM] = go->GetSpawnId();
|
||||
GetControlZoneTowerWestHandler().SetFlagGuid(go->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -123,24 +131,20 @@ void OutdoorPvPHP::HandlePlayerLeaveZone(Player* player, uint32 zone)
|
||||
OutdoorPvP::HandlePlayerLeaveZone(player, zone);
|
||||
}
|
||||
|
||||
bool OutdoorPvPHP::Update(uint32 diff)
|
||||
void OutdoorPvPHP::Update(uint32 diff)
|
||||
{
|
||||
bool changed = OutdoorPvP::Update(diff);
|
||||
if (changed)
|
||||
OutdoorPvP::Update(diff);
|
||||
if (m_AllianceTowersControlled == 3)
|
||||
TeamApplyBuff(TEAM_ALLIANCE, AllianceBuff, HordeBuff);
|
||||
else if (m_HordeTowersControlled == 3)
|
||||
TeamApplyBuff(TEAM_HORDE, HordeBuff, AllianceBuff);
|
||||
else
|
||||
{
|
||||
if (m_AllianceTowersControlled == 3)
|
||||
TeamApplyBuff(TEAM_ALLIANCE, AllianceBuff, HordeBuff);
|
||||
else if (m_HordeTowersControlled == 3)
|
||||
TeamApplyBuff(TEAM_HORDE, HordeBuff, AllianceBuff);
|
||||
else
|
||||
{
|
||||
TeamCastSpell(TEAM_ALLIANCE, -AllianceBuff);
|
||||
TeamCastSpell(TEAM_HORDE, -HordeBuff);
|
||||
}
|
||||
SetWorldState(HP_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
|
||||
SetWorldState(HP_UI_TOWER_COUNT_H, m_HordeTowersControlled);
|
||||
TeamCastSpell(TEAM_ALLIANCE, -AllianceBuff);
|
||||
TeamCastSpell(TEAM_HORDE, -HordeBuff);
|
||||
}
|
||||
return changed;
|
||||
SetWorldState(HP_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
|
||||
SetWorldState(HP_UI_TOWER_COUNT_H, m_HordeTowersControlled);
|
||||
}
|
||||
|
||||
void OutdoorPvPHP::SendRemoveWorldStates(Player* player)
|
||||
@@ -154,128 +158,46 @@ void OutdoorPvPHP::SendRemoveWorldStates(Player* player)
|
||||
initWorldStates.Worldstates.emplace_back(HP_UI_TOWER_COUNT_H, 0);
|
||||
initWorldStates.Worldstates.emplace_back(HP_UI_TOWER_COUNT_A, 0);
|
||||
|
||||
for (size_t i = 0; i < HP_TOWER_NUM; ++i)
|
||||
for (auto& itr : ControlZoneHandlers)
|
||||
{
|
||||
initWorldStates.Worldstates.emplace_back(HP_MAP_N[i], 0);
|
||||
initWorldStates.Worldstates.emplace_back(HP_MAP_A[i], 0);
|
||||
initWorldStates.Worldstates.emplace_back(HP_MAP_H[i], 0);
|
||||
HPControlZoneHandler* handler = static_cast<HPControlZoneHandler*>(itr.second.get());
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateNeutral(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateHorde(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateAlliance(), 0);
|
||||
}
|
||||
|
||||
player->SendDirectMessage(initWorldStates.Write());
|
||||
}
|
||||
|
||||
void OPvPCapturePointHP::ChangeState()
|
||||
{
|
||||
uint32 field = 0;
|
||||
switch (m_OldState)
|
||||
{
|
||||
case OBJECTIVESTATE_NEUTRAL:
|
||||
field = HP_MAP_N[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_ALLIANCE:
|
||||
field = HP_MAP_A[m_TowerType];
|
||||
if (uint32 alliance_towers = ((OutdoorPvPHP*)m_PvP)->GetAllianceTowersControlled())
|
||||
((OutdoorPvPHP*)m_PvP)->SetAllianceTowersControlled(--alliance_towers);
|
||||
break;
|
||||
case OBJECTIVESTATE_HORDE:
|
||||
field = HP_MAP_H[m_TowerType];
|
||||
if (uint32 horde_towers = ((OutdoorPvPHP*)m_PvP)->GetHordeTowersControlled())
|
||||
((OutdoorPvPHP*)m_PvP)->SetHordeTowersControlled(--horde_towers);
|
||||
break;
|
||||
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
field = HP_MAP_N[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
field = HP_MAP_N[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
field = HP_MAP_A[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
field = HP_MAP_H[m_TowerType];
|
||||
break;
|
||||
}
|
||||
|
||||
// send world state update
|
||||
if (field)
|
||||
{
|
||||
m_PvP->SetWorldState(field, 0);
|
||||
field = 0;
|
||||
}
|
||||
uint32 artkit = 21;
|
||||
uint32 artkit2 = HP_TowerArtKit_N[m_TowerType];
|
||||
switch (m_State)
|
||||
{
|
||||
case OBJECTIVESTATE_NEUTRAL:
|
||||
field = HP_MAP_N[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_ALLIANCE:
|
||||
{
|
||||
field = HP_MAP_A[m_TowerType];
|
||||
artkit = 2;
|
||||
artkit2 = HP_TowerArtKit_A[m_TowerType];
|
||||
uint32 alliance_towers = ((OutdoorPvPHP*)m_PvP)->GetAllianceTowersControlled();
|
||||
if (alliance_towers < 3)
|
||||
((OutdoorPvPHP*)m_PvP)->SetAllianceTowersControlled(++alliance_towers);
|
||||
m_PvP->SendDefenseMessage(OutdoorPvPHPBuffZones[0], HP_LANG_CAPTURE_A[m_TowerType]);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVESTATE_HORDE:
|
||||
{
|
||||
field = HP_MAP_H[m_TowerType];
|
||||
artkit = 1;
|
||||
artkit2 = HP_TowerArtKit_H[m_TowerType];
|
||||
uint32 horde_towers = ((OutdoorPvPHP*)m_PvP)->GetHordeTowersControlled();
|
||||
if (horde_towers < 3)
|
||||
((OutdoorPvPHP*)m_PvP)->SetHordeTowersControlled(++horde_towers);
|
||||
m_PvP->SendDefenseMessage(OutdoorPvPHPBuffZones[0], HP_LANG_CAPTURE_H[m_TowerType]);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
field = HP_MAP_N[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
field = HP_MAP_N[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
field = HP_MAP_A[m_TowerType];
|
||||
artkit = 2;
|
||||
artkit2 = HP_TowerArtKit_A[m_TowerType];
|
||||
break;
|
||||
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
field = HP_MAP_H[m_TowerType];
|
||||
artkit = 1;
|
||||
artkit2 = HP_TowerArtKit_H[m_TowerType];
|
||||
break;
|
||||
}
|
||||
|
||||
Map* map = m_PvP->GetMap();
|
||||
auto bounds = map->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId);
|
||||
for (auto itr = bounds.first; itr != bounds.second; ++itr)
|
||||
itr->second->SetGoArtKit(artkit);
|
||||
|
||||
bounds = map->GetGameObjectBySpawnIdStore().equal_range(m_flagSpawnId);
|
||||
for (auto itr = bounds.first; itr != bounds.second; ++itr)
|
||||
itr->second->SetGoArtKit(artkit2);
|
||||
|
||||
// send world state update
|
||||
if (field)
|
||||
m_PvP->SetWorldState(field, 1);
|
||||
|
||||
// complete quest objective
|
||||
if (m_State == OBJECTIVESTATE_ALLIANCE || m_State == OBJECTIVESTATE_HORDE)
|
||||
SendObjectiveComplete(HP_CREDITMARKER[m_TowerType], ObjectGuid::Empty);
|
||||
}
|
||||
|
||||
void OutdoorPvPHP::HandleKillImpl(Player* player, Unit* killed)
|
||||
{
|
||||
if (killed->GetTypeId() != TYPEID_PLAYER)
|
||||
return;
|
||||
|
||||
if (player->GetTeam() == ALLIANCE && killed->ToPlayer()->GetTeam() != ALLIANCE)
|
||||
player->CastSpell(player, AlliancePlayerKillReward, true);
|
||||
else if (player->GetTeam() == HORDE && killed->ToPlayer()->GetTeam() != HORDE)
|
||||
player->CastSpell(player, HordePlayerKillReward, true);
|
||||
// need to check if player is inside an capture zone
|
||||
bool isInsideCaptureZone = false;
|
||||
for (ObjectGuid const& guid : _controlZoneGUIDs)
|
||||
{
|
||||
if (GameObject* gameObject = GetMap()->GetGameObject(guid))
|
||||
{
|
||||
if (GuidUnorderedSet const* insidePlayerGuids = gameObject->GetInsidePlayers())
|
||||
{
|
||||
if (insidePlayerGuids->contains(player->GetGUID()))
|
||||
{
|
||||
isInsideCaptureZone = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isInsideCaptureZone)
|
||||
{
|
||||
if (player->GetTeam() == ALLIANCE && killed->ToPlayer()->GetTeam() != ALLIANCE)
|
||||
player->CastSpell(player, AlliancePlayerKillReward, true);
|
||||
else if (player->GetTeam() == HORDE && killed->ToPlayer()->GetTeam() != HORDE)
|
||||
player->CastSpell(player, HordePlayerKillReward, true);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 OutdoorPvPHP::GetAllianceTowersControlled() const
|
||||
@@ -298,6 +220,88 @@ void OutdoorPvPHP::SetHordeTowersControlled(uint32 count)
|
||||
m_HordeTowersControlled = count;
|
||||
}
|
||||
|
||||
HPControlZoneHandler::HPControlZoneHandler(OutdoorPvPHP* pvp) : OutdoorPvPControlZoneHandler(pvp),
|
||||
_flagGuid(ObjectGuid::Empty), _textCaptureAlliance(0), _textCaptureHorde(0),
|
||||
_flagArtKitNeutral(0), _flagArtKitHorde(0), _flagArtKitAlliance(0),
|
||||
_worldstateNeutral(0), _worldstateHorde(0), _worldstateAlliance(0),
|
||||
_killCredit(0)
|
||||
{
|
||||
}
|
||||
|
||||
void HPControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
|
||||
{
|
||||
ControlZoneHandler::HandleProgressEventHorde(controlZone);
|
||||
|
||||
controlZone->SetGoArtKit(1);
|
||||
controlZone->SendCustomAnim(0);
|
||||
if (GameObject* flag = controlZone->GetMap()->GetGameObject(_flagGuid))
|
||||
flag->SetGoArtKit(_flagArtKitHorde);
|
||||
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 1, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 0, false);
|
||||
|
||||
GetOutdoorPvPHP()->SendDefenseMessage(OutdoorPvPHPBuffZones[0], _textCaptureHorde);
|
||||
|
||||
if (GuidUnorderedSet const* guidSet = controlZone->GetInsidePlayers())
|
||||
for (ObjectGuid const& guid : *guidSet)
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*controlZone, guid))
|
||||
if (player->GetTeam() == TEAM_HORDE)
|
||||
player->KilledMonsterCredit(_killCredit);
|
||||
}
|
||||
|
||||
void HPControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
ControlZoneHandler::HandleProgressEventAlliance(controlZone);
|
||||
|
||||
controlZone->SetGoArtKit(2);
|
||||
controlZone->SendCustomAnim(1);
|
||||
if (GameObject* flag = controlZone->GetMap()->GetGameObject(_flagGuid))
|
||||
flag->SetGoArtKit(_flagArtKitAlliance);
|
||||
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 1, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 0, false);
|
||||
|
||||
GetOutdoorPvPHP()->SendDefenseMessage(OutdoorPvPHPBuffZones[0], _textCaptureAlliance);
|
||||
|
||||
if (GuidUnorderedSet const* guidSet = controlZone->GetInsidePlayers())
|
||||
for (ObjectGuid const& guid : *guidSet)
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*controlZone, guid))
|
||||
if (player->GetTeam() == TEAM_ALLIANCE)
|
||||
player->KilledMonsterCredit(_killCredit);
|
||||
}
|
||||
|
||||
void HPControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
|
||||
{
|
||||
ControlZoneHandler::HandleNeutralEventHorde(controlZone);
|
||||
GetOutdoorPvPHP()->SetHordeTowersControlled(GetOutdoorPvPHP()->GetHordeTowersControlled() - 1);
|
||||
}
|
||||
|
||||
void HPControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
ControlZoneHandler::HandleNeutralEventAlliance(controlZone);
|
||||
GetOutdoorPvPHP()->SetAllianceTowersControlled(GetOutdoorPvPHP()->GetAllianceTowersControlled() - 1);
|
||||
}
|
||||
|
||||
void HPControlZoneHandler::HandleNeutralEvent(GameObject* controlZone)
|
||||
{
|
||||
ControlZoneHandler::HandleNeutralEvent(controlZone);
|
||||
controlZone->SetGoArtKit(21);
|
||||
controlZone->SendCustomAnim(2);
|
||||
if (GameObject* flag = controlZone->GetMap()->GetGameObject(_flagGuid))
|
||||
flag->SetGoArtKit(_flagArtKitNeutral);
|
||||
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 1, false);
|
||||
}
|
||||
|
||||
OutdoorPvPHP* HPControlZoneHandler::GetOutdoorPvPHP() const
|
||||
{
|
||||
return static_cast<OutdoorPvPHP*>(OutdoorPvPControlZoneHandler::GetOutdoorPvP());
|
||||
}
|
||||
|
||||
class OutdoorPvP_hellfire_peninsula : public OutdoorPvPScript
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -53,19 +53,94 @@ enum OutdoorPvPHPWorldStates
|
||||
HP_UI_TOWER_DISPLAY_H = 0x9b9,
|
||||
|
||||
HP_UI_TOWER_COUNT_H = 0x9ae,
|
||||
HP_UI_TOWER_COUNT_A = 0x9ac
|
||||
HP_UI_TOWER_COUNT_A = 0x9ac,
|
||||
|
||||
HP_UI_TOWER_S_A = 2483,
|
||||
HP_UI_TOWER_S_H = 2484,
|
||||
HP_UI_TOWER_S_N = 2485,
|
||||
|
||||
HP_UI_TOWER_N_A = 2480,
|
||||
HP_UI_TOWER_N_H = 2481,
|
||||
HP_UI_TOWER_N_N = 2482,
|
||||
|
||||
HP_UI_TOWER_W_A = 2471,
|
||||
HP_UI_TOWER_W_H = 2470,
|
||||
HP_UI_TOWER_W_N = 2472
|
||||
};
|
||||
|
||||
class OPvPCapturePointHP : public OPvPCapturePoint
|
||||
enum OutdoorPvPHPEvents
|
||||
{
|
||||
public:
|
||||
OPvPCapturePointHP(OutdoorPvP* pvp, OutdoorPvPHPTowerType type, GameObject* go, ObjectGuid::LowType const& flagSpawnId);
|
||||
HP_EVENT_TOWER_W_PROGRESS_HORDE = 11383,
|
||||
HP_EVENT_TOWER_W_PROGRESS_ALLIANCE = 11387,
|
||||
HP_EVENT_TOWER_W_NEUTRAL_HORDE = 11386,
|
||||
HP_EVENT_TOWER_W_NEUTRAL_ALLIANCE = 11385,
|
||||
|
||||
void ChangeState() override;
|
||||
HP_EVENT_TOWER_N_PROGRESS_HORDE = 11396,
|
||||
HP_EVENT_TOWER_N_PROGRESS_ALLIANCE = 11395,
|
||||
HP_EVENT_TOWER_N_NEUTRAL_HORDE = 11394,
|
||||
HP_EVENT_TOWER_N_NEUTRAL_ALLIANCE = 11393,
|
||||
|
||||
private:
|
||||
OutdoorPvPHPTowerType m_TowerType;
|
||||
ObjectGuid::LowType const& m_flagSpawnId;
|
||||
HP_EVENT_TOWER_S_PROGRESS_HORDE = 11404,
|
||||
HP_EVENT_TOWER_S_PROGRESS_ALLIANCE = 11403,
|
||||
HP_EVENT_TOWER_S_NEUTRAL_HORDE = 11402,
|
||||
HP_EVENT_TOWER_S_NEUTRAL_ALLIANCE = 11401
|
||||
};
|
||||
|
||||
enum OutdoorPvPHPGameObjectEntries
|
||||
{
|
||||
HP_GO_ENTRY_TOWER_W = 182173,
|
||||
HP_GO_ENTRY_TOWER_N = 182174,
|
||||
HP_GO_ENTRY_TOWER_S = 182175
|
||||
};
|
||||
|
||||
enum OutdoorPvPHPCredit
|
||||
{
|
||||
HP_KILL_CREDIT_TOWER_S = 19032,
|
||||
HP_KILL_CREDIT_TOWER_N = 19028,
|
||||
HP_KILL_CREDIT_TOWER_W = 19029
|
||||
};
|
||||
|
||||
class OutdoorPvPHP;
|
||||
|
||||
class HPControlZoneHandler : public OutdoorPvPControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit HPControlZoneHandler(OutdoorPvPHP* pvp);
|
||||
|
||||
void SetFlagGuid(ObjectGuid const& guid) { _flagGuid = guid; }
|
||||
void SetTextCaptureHorde(uint32 text) { _textCaptureHorde = text; }
|
||||
void SetTextCaptureAlliance(uint32 text) { _textCaptureAlliance = text; }
|
||||
void SetFlagArtKitNeutral(uint32 artKit) { _flagArtKitNeutral = artKit; }
|
||||
void SetFlagArtKitHorde(uint32 artKit) { _flagArtKitHorde = artKit; }
|
||||
void SetFlagArtKitAlliance(uint32 artKit) { _flagArtKitAlliance = artKit; }
|
||||
void SetWorldstateNeutral(uint32 id) { _worldstateNeutral = id; }
|
||||
void SetWorldstateHorde(uint32 id) { _worldstateHorde = id; }
|
||||
void SetWorldstateAlliance(uint32 id) { _worldstateAlliance = id; }
|
||||
void SetKillCredit(uint32 credit) { _killCredit = credit; }
|
||||
|
||||
void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEvent([[maybe_unused]] GameObject* controlZone) override;
|
||||
|
||||
uint32 GetWorldStateNeutral() { return _worldstateNeutral; }
|
||||
uint32 GetWorldStateHorde() { return _worldstateHorde; }
|
||||
uint32 GetWorldStateAlliance() { return _worldstateAlliance; }
|
||||
|
||||
OutdoorPvPHP* GetOutdoorPvPHP() const;
|
||||
|
||||
private:
|
||||
ObjectGuid _flagGuid;
|
||||
uint32 _textCaptureAlliance;
|
||||
uint32 _textCaptureHorde;
|
||||
uint32 _flagArtKitNeutral;
|
||||
uint32 _flagArtKitHorde;
|
||||
uint32 _flagArtKitAlliance;
|
||||
uint32 _worldstateNeutral;
|
||||
uint32 _worldstateHorde;
|
||||
uint32 _worldstateAlliance;
|
||||
uint32 _killCredit;
|
||||
};
|
||||
|
||||
class OutdoorPvPHP : public OutdoorPvP
|
||||
@@ -80,7 +155,7 @@ class OutdoorPvPHP : public OutdoorPvP
|
||||
void HandlePlayerEnterZone(Player* player, uint32 zone) override;
|
||||
void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
|
||||
|
||||
bool Update(uint32 diff) override;
|
||||
void Update(uint32 diff) override;
|
||||
void SendRemoveWorldStates(Player* player) override;
|
||||
void HandleKillImpl(Player* player, Unit* killed) override;
|
||||
|
||||
@@ -92,7 +167,12 @@ class OutdoorPvPHP : public OutdoorPvP
|
||||
private:
|
||||
uint32 m_AllianceTowersControlled; // how many towers are controlled
|
||||
uint32 m_HordeTowersControlled;
|
||||
std::array<ObjectGuid::LowType, HP_TOWER_NUM> m_towerFlagSpawnIds;
|
||||
|
||||
GuidUnorderedSet _controlZoneGUIDs;
|
||||
|
||||
HPControlZoneHandler& GetControlZoneTowerNorthHandler() { return *static_cast<HPControlZoneHandler*>(ControlZoneHandlers[HP_GO_ENTRY_TOWER_N].get()); }
|
||||
HPControlZoneHandler& GetControlZoneTowerSouthHandler() { return *static_cast<HPControlZoneHandler*>(ControlZoneHandlers[HP_GO_ENTRY_TOWER_S].get()); }
|
||||
HPControlZoneHandler& GetControlZoneTowerWestHandler() { return *static_cast<HPControlZoneHandler*>(ControlZoneHandlers[HP_GO_ENTRY_TOWER_W].get()); }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -40,6 +40,7 @@ OutdoorPvPNA::OutdoorPvPNA(Map* map) : OutdoorPvP(map)
|
||||
{
|
||||
m_TypeId = OUTDOOR_PVP_NA;
|
||||
m_obj = nullptr;
|
||||
ControlZoneHandlers[182210] = std::make_unique<NAControlZoneHandler>(this);
|
||||
}
|
||||
|
||||
void OutdoorPvPNA::OnGameObjectCreate(GameObject* go)
|
||||
@@ -47,8 +48,7 @@ void OutdoorPvPNA::OnGameObjectCreate(GameObject* go)
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case 182210:
|
||||
m_obj->m_capturePointSpawnId = go->GetSpawnId();
|
||||
AddCapturePoint(m_obj);
|
||||
m_obj->SetControlZoneGUID(go->GetGUID());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -67,6 +67,91 @@ void OutdoorPvPNA::HandleKillImpl(Player* player, Unit* killed)
|
||||
}
|
||||
}
|
||||
|
||||
NAControlZoneHandler::NAControlZoneHandler(OutdoorPvPNA* pvp) : OutdoorPvPControlZoneHandler(pvp)
|
||||
{
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleCaptureEventHorde(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleCaptureEventHorde(controlZone);
|
||||
|
||||
if (GetOutdoorPvPNA()->GetCapturePoint()->GetControllingFaction() != HORDE)
|
||||
{
|
||||
GetOutdoorPvPNA()->SendMapWorldStates(0, 0, 0, 1, 0);
|
||||
GetOutdoorPvPNA()->GetCapturePoint()->FactionTakeOver(HORDE);
|
||||
}
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleCaptureEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleCaptureEventAlliance(controlZone);
|
||||
|
||||
if (GetOutdoorPvPNA()->GetCapturePoint()->GetControllingFaction() != ALLIANCE)
|
||||
{
|
||||
GetOutdoorPvPNA()->SendMapWorldStates(0, 0, 0, 0, 1);
|
||||
GetOutdoorPvPNA()->GetCapturePoint()->FactionTakeOver(ALLIANCE);
|
||||
}
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleContestedEventHorde(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleContestedEventHorde(controlZone);
|
||||
|
||||
GetOutdoorPvPNA()->SendMapWorldStates(0, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleContestedEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleContestedEventAlliance(controlZone);
|
||||
|
||||
GetOutdoorPvPNA()->SendMapWorldStates(0, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleProgressEventHorde(controlZone);
|
||||
|
||||
controlZone->SetGoArtKit(1);
|
||||
GetOutdoorPvPNA()->SendMapWorldStates(0, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleProgressEventAlliance(controlZone);
|
||||
|
||||
controlZone->SetGoArtKit(2);
|
||||
GetOutdoorPvPNA()->SendMapWorldStates(0, 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEventHorde(controlZone);
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEventAlliance(controlZone);
|
||||
}
|
||||
|
||||
void NAControlZoneHandler::HandleNeutralEvent(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEvent(controlZone);
|
||||
}
|
||||
|
||||
OutdoorPvPNA* NAControlZoneHandler::GetOutdoorPvPNA() const
|
||||
{
|
||||
return static_cast<OutdoorPvPNA*>(OutdoorPvPControlZoneHandler::GetOutdoorPvP());
|
||||
}
|
||||
|
||||
void OutdoorPvPNA::SendMapWorldStates(int32 neutral, int32 progressHorde, int32 progressAlliance, int32 capturedHorde, int32 captureAlliance)
|
||||
{
|
||||
SetWorldState(NA_MAP_HALAA_NEUTRAL, neutral);
|
||||
SetWorldState(NA_MAP_HALAA_NEU_H, progressHorde);
|
||||
SetWorldState(NA_MAP_HALAA_NEU_A, progressAlliance);
|
||||
SetWorldState(NA_MAP_HALAA_HORDE, capturedHorde);
|
||||
SetWorldState(NA_MAP_HALAA_ALLIANCE, captureAlliance);
|
||||
}
|
||||
|
||||
uint32 OPvPCapturePointNA::GetAliveGuardsCount() const
|
||||
{
|
||||
Position searchCenter = { -1572.57f, 7945.3f, -22.475f, 2.05949f };
|
||||
@@ -89,7 +174,9 @@ void OPvPCapturePointNA::FactionTakeOver(uint32 team)
|
||||
m_ControllingFaction = team;
|
||||
m_GuardsAlive = NA_GUARDS_MAX;
|
||||
m_capturable = false;
|
||||
UpdateHalaaWorldState();
|
||||
if (GameObject* gameObject = m_PvP->GetMap()->GetGameObject(_controlZoneGUID))
|
||||
gameObject->ActivateObject(GameObjectActions::MakeInert, 0);
|
||||
|
||||
if (team == ALLIANCE)
|
||||
{
|
||||
m_WyvernStateSouth = WYVERN_NEU_HORDE;
|
||||
@@ -121,9 +208,9 @@ void OPvPCapturePointNA::FactionTakeOver(uint32 team)
|
||||
}
|
||||
|
||||
OPvPCapturePointNA::OPvPCapturePointNA(OutdoorPvP* pvp) : OPvPCapturePoint(pvp), m_capturable(true), m_GuardsAlive(0), m_ControllingFaction(0), m_WyvernStateNorth(0), m_WyvernStateSouth(0), m_WyvernStateEast(0),
|
||||
m_WyvernStateWest(0), m_HalaaState(HALAA_N), m_RespawnTimer(NA_RESPAWN_TIME), m_GuardCheckTimer(NA_GUARD_CHECK_TIME)
|
||||
m_WyvernStateWest(0), m_RespawnTimer(NA_RESPAWN_TIME), m_GuardCheckTimer(NA_GUARD_CHECK_TIME)
|
||||
{
|
||||
SetCapturePointData(182210);
|
||||
|
||||
}
|
||||
|
||||
bool OutdoorPvPNA::SetupOutdoorPvP()
|
||||
@@ -187,9 +274,9 @@ void OutdoorPvPNA::SendRemoveWorldStates(Player* player)
|
||||
player->SendDirectMessage(initWorldStates.Write());
|
||||
}
|
||||
|
||||
bool OutdoorPvPNA::Update(uint32 diff)
|
||||
void OutdoorPvPNA::Update(uint32 diff)
|
||||
{
|
||||
return m_obj->Update(diff);
|
||||
m_obj->Update(diff);
|
||||
}
|
||||
|
||||
bool OPvPCapturePointNA::HandleCustomSpell(Player* player, uint32 spellId, GameObject* /*go*/)
|
||||
@@ -342,15 +429,8 @@ int32 OPvPCapturePointNA::HandleOpenGo(Player* player, GameObject* go)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool OPvPCapturePointNA::Update(uint32 diff)
|
||||
void OPvPCapturePointNA::Update(uint32 diff)
|
||||
{
|
||||
// let the controlling faction advance in phase
|
||||
bool capturable = false;
|
||||
if (m_ControllingFaction == ALLIANCE && m_activePlayers[0].size() > m_activePlayers[1].size())
|
||||
capturable = true;
|
||||
else if (m_ControllingFaction == HORDE && m_activePlayers[0].size() < m_activePlayers[1].size())
|
||||
capturable = true;
|
||||
|
||||
if (m_GuardCheckTimer < diff)
|
||||
{
|
||||
m_GuardCheckTimer = NA_GUARD_CHECK_TIME;
|
||||
@@ -359,7 +439,11 @@ bool OPvPCapturePointNA::Update(uint32 diff)
|
||||
{
|
||||
m_capturable = true;
|
||||
m_RespawnTimer = NA_RESPAWN_TIME;
|
||||
if (GameObject* gameObject = m_PvP->GetMap()->GetGameObject(_controlZoneGUID))
|
||||
gameObject->ActivateObject(GameObjectActions::MakeActive, 0);
|
||||
}
|
||||
else if (GameObject* gameObject = m_PvP->GetMap()->GetGameObject(_controlZoneGUID))
|
||||
gameObject->ActivateObject(GameObjectActions::MakeInert, 0);
|
||||
// update the guard count for the players in zone
|
||||
m_PvP->SetWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
|
||||
}
|
||||
@@ -382,60 +466,8 @@ bool OPvPCapturePointNA::Update(uint32 diff)
|
||||
m_RespawnTimer -= diff;
|
||||
}
|
||||
|
||||
if (m_capturable || capturable)
|
||||
return OPvPCapturePoint::Update(diff);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OPvPCapturePointNA::ChangeState()
|
||||
{
|
||||
uint32 artkit = 21;
|
||||
switch (m_State)
|
||||
{
|
||||
case OBJECTIVESTATE_NEUTRAL:
|
||||
m_HalaaState = HALAA_N;
|
||||
break;
|
||||
case OBJECTIVESTATE_ALLIANCE:
|
||||
m_HalaaState = HALAA_A;
|
||||
FactionTakeOver(ALLIANCE);
|
||||
artkit = 2;
|
||||
break;
|
||||
case OBJECTIVESTATE_HORDE:
|
||||
m_HalaaState = HALAA_H;
|
||||
FactionTakeOver(HORDE);
|
||||
artkit = 1;
|
||||
break;
|
||||
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
m_HalaaState = HALAA_N_A;
|
||||
break;
|
||||
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
m_HalaaState = HALAA_N_H;
|
||||
break;
|
||||
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
m_HalaaState = HALAA_N_A;
|
||||
artkit = 2;
|
||||
break;
|
||||
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
m_HalaaState = HALAA_N_H;
|
||||
artkit = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
auto bounds = m_PvP->GetMap()->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId);
|
||||
for (auto itr = bounds.first; itr != bounds.second; ++itr)
|
||||
itr->second->SetGoArtKit(artkit);
|
||||
|
||||
UpdateHalaaWorldState();
|
||||
}
|
||||
|
||||
void OPvPCapturePointNA::UpdateHalaaWorldState()
|
||||
{
|
||||
m_PvP->SetWorldState(NA_MAP_HALAA_NEUTRAL, uint32((m_HalaaState & HALAA_N) != 0));
|
||||
m_PvP->SetWorldState(NA_MAP_HALAA_NEU_A, uint32((m_HalaaState & HALAA_N_A) != 0));
|
||||
m_PvP->SetWorldState(NA_MAP_HALAA_NEU_H, uint32((m_HalaaState & HALAA_N_H) != 0));
|
||||
m_PvP->SetWorldState(NA_MAP_HALAA_HORDE, uint32((m_HalaaState & HALAA_H) != 0));
|
||||
m_PvP->SetWorldState(NA_MAP_HALAA_ALLIANCE, uint32((m_HalaaState & HALAA_A) != 0));
|
||||
if (m_capturable)
|
||||
OPvPCapturePoint::Update(diff);
|
||||
}
|
||||
|
||||
void OPvPCapturePointNA::UpdateWyvernRoostWorldState(uint32 roost)
|
||||
|
||||
@@ -113,16 +113,47 @@ enum HalaaStates
|
||||
HALAA_H = 16
|
||||
};
|
||||
|
||||
enum HalaaEvents
|
||||
{
|
||||
HALAA_EVENT_CAPTURE_HORDE = 11504,
|
||||
HALAA_EVENT_CAPTURE_ALLIANCE = 11503,
|
||||
HALAA_EVENT_CONTESTED_HORDE = 11559,
|
||||
HALAA_EVENT_CONTESTED_ALLIANCE = 11558,
|
||||
HALAA_EVENT_PROGRESS_HORDE = 11821,
|
||||
HALAA_EVENT_PROGRESS_ALLIANCE = 11822
|
||||
};
|
||||
|
||||
class Unit;
|
||||
class Creature;
|
||||
class WorldObject;
|
||||
|
||||
class OutdoorPvPNA;
|
||||
|
||||
class NAControlZoneHandler : public OutdoorPvPControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit NAControlZoneHandler(OutdoorPvPNA* pvp);
|
||||
|
||||
void HandleCaptureEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleCaptureEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleContestedEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleContestedEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEvent([[maybe_unused]] GameObject* controlZone) override;
|
||||
|
||||
OutdoorPvPNA* GetOutdoorPvPNA() const;
|
||||
};
|
||||
|
||||
class OPvPCapturePointNA : public OPvPCapturePoint
|
||||
{
|
||||
public:
|
||||
OPvPCapturePointNA(OutdoorPvP* pvp);
|
||||
|
||||
bool Update(uint32 diff) override;
|
||||
void ChangeState() override;
|
||||
void Update(uint32 diff) override;
|
||||
void ChangeState() override { } // todo remove?
|
||||
bool HandleCustomSpell(Player* player, uint32 spellId, GameObject* go) override;
|
||||
int32 HandleOpenGo(Player* player, GameObject* go) override;
|
||||
|
||||
@@ -130,8 +161,8 @@ class OPvPCapturePointNA : public OPvPCapturePoint
|
||||
uint32 GetControllingFaction() const;
|
||||
void FactionTakeOver(uint32 team); // called when a faction takes control
|
||||
void UpdateWyvernRoostWorldState(uint32 roost);
|
||||
void UpdateHalaaWorldState();
|
||||
|
||||
void SetControlZoneGUID(ObjectGuid guid) { _controlZoneGUID = guid; }
|
||||
private:
|
||||
bool m_capturable;
|
||||
uint32 m_GuardsAlive;
|
||||
@@ -140,9 +171,9 @@ class OPvPCapturePointNA : public OPvPCapturePoint
|
||||
uint32 m_WyvernStateSouth;
|
||||
uint32 m_WyvernStateEast;
|
||||
uint32 m_WyvernStateWest;
|
||||
uint32 m_HalaaState;
|
||||
uint32 m_RespawnTimer;
|
||||
uint32 m_GuardCheckTimer;
|
||||
ObjectGuid _controlZoneGUID;
|
||||
};
|
||||
|
||||
class OutdoorPvPNA : public OutdoorPvP
|
||||
@@ -155,10 +186,11 @@ class OutdoorPvPNA : public OutdoorPvP
|
||||
bool SetupOutdoorPvP() override;
|
||||
void HandlePlayerEnterZone(Player* player, uint32 zone) override;
|
||||
void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
|
||||
bool Update(uint32 diff) override;
|
||||
void Update(uint32 diff) override;
|
||||
void SendRemoveWorldStates(Player* player) override;
|
||||
void HandleKillImpl(Player* player, Unit* killed) override;
|
||||
|
||||
void SendMapWorldStates(int32 neutral, int32 progressHorde, int32 progressAlliance, int32 capturedHorde, int32 captureAlliance);
|
||||
OPvPCapturePointNA* GetCapturePoint() const { return m_obj; }
|
||||
private:
|
||||
OPvPCapturePointNA* m_obj;
|
||||
};
|
||||
|
||||
@@ -66,9 +66,8 @@ bool OutdoorPvPSI::SetupOutdoorPvP()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OutdoorPvPSI::Update(uint32 /*diff*/)
|
||||
void OutdoorPvPSI::Update(uint32 /*diff*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void OutdoorPvPSI::HandlePlayerEnterZone(Player* player, uint32 zone)
|
||||
|
||||
@@ -43,7 +43,7 @@ class OutdoorPvPSI : public OutdoorPvP
|
||||
bool SetupOutdoorPvP() override;
|
||||
void HandlePlayerEnterZone(Player* player, uint32 zone) override;
|
||||
void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
|
||||
bool Update(uint32 diff) override;
|
||||
void Update(uint32 diff) override;
|
||||
void SendRemoveWorldStates(Player* player) override;
|
||||
bool HandleAreaTrigger(Player* player, uint32 trigger, bool entered) override;
|
||||
bool HandleDropFlag(Player* player, uint32 spellId) override;
|
||||
|
||||
@@ -45,42 +45,6 @@ int32 const TF_CAPTURE_BUFF = 33377;
|
||||
uint32 const TF_ALLY_QUEST = 11505;
|
||||
uint32 const TF_HORDE_QUEST = 11506;
|
||||
|
||||
struct tf_tower_world_state
|
||||
{
|
||||
int32 n;
|
||||
int32 h;
|
||||
int32 a;
|
||||
};
|
||||
|
||||
tf_tower_world_state const TFTowerWorldStates[TF_TOWER_NUM] =
|
||||
{
|
||||
{ 2681, 2682, 2683 },
|
||||
{ 2686, 2685, 2684 },
|
||||
{ 2690, 2689, 2688 },
|
||||
{ 2696, 2695, 2694 },
|
||||
{ 2693, 2692, 2691 }
|
||||
};
|
||||
|
||||
/*
|
||||
uint32 const TFTowerPlayerEnterEvents[TF_TOWER_NUM] =
|
||||
{
|
||||
12226,
|
||||
12497,
|
||||
12486,
|
||||
12499,
|
||||
12501
|
||||
};
|
||||
|
||||
uint32 const TFTowerPlayerLeaveEvents[TF_TOWER_NUM] =
|
||||
{
|
||||
12225,
|
||||
12496,
|
||||
12487,
|
||||
12498,
|
||||
12500
|
||||
};
|
||||
*/
|
||||
|
||||
OutdoorPvPTF::OutdoorPvPTF(Map* map) : OutdoorPvP(map)
|
||||
{
|
||||
m_TypeId = OUTDOOR_PVP_TF;
|
||||
@@ -92,13 +56,12 @@ OutdoorPvPTF::OutdoorPvPTF(Map* map) : OutdoorPvP(map)
|
||||
hours_left = 6;
|
||||
second_digit = 0;
|
||||
first_digit = 0;
|
||||
}
|
||||
|
||||
OPvPCapturePointTF::OPvPCapturePointTF(OutdoorPvP* pvp, OutdoorPvPTF_TowerType type, GameObject* go) : OPvPCapturePoint(pvp), m_TowerType(type), m_TowerState(TF_TOWERSTATE_N)
|
||||
{
|
||||
m_capturePointSpawnId = go->GetSpawnId();
|
||||
m_capturePoint = go;
|
||||
SetCapturePointData(go->GetEntry());
|
||||
ControlZoneHandlers[TF_ENTRY_TOWER_NW] = std::make_unique<TFControlZoneHandler>(this, 2682, 2683, 2681);
|
||||
ControlZoneHandlers[TF_ENTRY_TOWER_N] = std::make_unique<TFControlZoneHandler>(this, 2685, 2684, 2686);
|
||||
ControlZoneHandlers[TF_ENTRY_TOWER_NE] = std::make_unique<TFControlZoneHandler>(this, 2689, 2688, 2690);
|
||||
ControlZoneHandlers[TF_ENTRY_TOWER_SE] = std::make_unique<TFControlZoneHandler>(this, 2695, 2694, 2696);
|
||||
ControlZoneHandlers[TF_ENTRY_TOWER_S] = std::make_unique<TFControlZoneHandler>(this, 2692, 2691, 2693);
|
||||
}
|
||||
|
||||
void OutdoorPvPTF::SendRemoveWorldStates(Player* player)
|
||||
@@ -119,55 +82,21 @@ void OutdoorPvPTF::SendRemoveWorldStates(Player* player)
|
||||
initWorldStates.Worldstates.emplace_back(TF_UI_LOCKED_DISPLAY_HORDE, 0);
|
||||
initWorldStates.Worldstates.emplace_back(TF_UI_LOCKED_DISPLAY_ALLIANCE, 0);
|
||||
|
||||
for (tf_tower_world_state const& towerWorldStates : TFTowerWorldStates)
|
||||
for (auto& itr : ControlZoneHandlers)
|
||||
{
|
||||
initWorldStates.Worldstates.emplace_back(towerWorldStates.n, 0);
|
||||
initWorldStates.Worldstates.emplace_back(towerWorldStates.h, 0);
|
||||
initWorldStates.Worldstates.emplace_back(towerWorldStates.a, 0);
|
||||
TFControlZoneHandler* handler = static_cast<TFControlZoneHandler*>(itr.second.get());
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateNeutral(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateHorde(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateAlliance(), 0);
|
||||
}
|
||||
|
||||
player->SendDirectMessage(initWorldStates.Write());
|
||||
}
|
||||
|
||||
void OPvPCapturePointTF::UpdateTowerState()
|
||||
void OutdoorPvPTF::Update(uint32 diff)
|
||||
{
|
||||
m_PvP->SetWorldState(TFTowerWorldStates[m_TowerType].n, int32((m_TowerState & TF_TOWERSTATE_N) != 0));
|
||||
m_PvP->SetWorldState(TFTowerWorldStates[m_TowerType].h, int32((m_TowerState & TF_TOWERSTATE_H) != 0));
|
||||
m_PvP->SetWorldState(TFTowerWorldStates[m_TowerType].a, int32((m_TowerState & TF_TOWERSTATE_A) != 0));
|
||||
}
|
||||
OutdoorPvP::Update(diff);
|
||||
|
||||
bool OutdoorPvPTF::Update(uint32 diff)
|
||||
{
|
||||
bool changed = OutdoorPvP::Update(diff);
|
||||
|
||||
if (changed)
|
||||
{
|
||||
if (m_AllianceTowersControlled == TF_TOWER_NUM)
|
||||
{
|
||||
TeamApplyBuff(TEAM_ALLIANCE, TF_CAPTURE_BUFF);
|
||||
m_IsLocked = true;
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, 0);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_HORDE, 0);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE, 1);
|
||||
SetWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, 0);
|
||||
}
|
||||
else if (m_HordeTowersControlled == TF_TOWER_NUM)
|
||||
{
|
||||
TeamApplyBuff(TEAM_HORDE, TF_CAPTURE_BUFF);
|
||||
m_IsLocked = true;
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, 0);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_HORDE, 1);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE, 0);
|
||||
SetWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
TeamCastSpell(TEAM_ALLIANCE, -TF_CAPTURE_BUFF);
|
||||
TeamCastSpell(TEAM_HORDE, -TF_CAPTURE_BUFF);
|
||||
}
|
||||
SetWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
|
||||
SetWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
|
||||
}
|
||||
if (m_IsLocked)
|
||||
{
|
||||
// lock timer is down, release lock
|
||||
@@ -176,6 +105,16 @@ bool OutdoorPvPTF::Update(uint32 diff)
|
||||
m_LockTimer = TF_LOCK_TIME;
|
||||
m_LockTimerUpdate = 0;
|
||||
m_IsLocked = false;
|
||||
|
||||
for (ObjectGuid const& controlZoneGUID : _controlZoneGUIDs)
|
||||
{
|
||||
if (GameObject* gameObject = GetMap()->GetGameObject(controlZoneGUID))
|
||||
{
|
||||
gameObject->HandleCustomTypeCommand(GameObjectType::SetControlZoneValue());
|
||||
gameObject->ActivateObject(GameObjectActions::MakeActive, 0);
|
||||
}
|
||||
}
|
||||
|
||||
SetWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, 1);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, 0);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_HORDE, 0);
|
||||
@@ -200,7 +139,6 @@ bool OutdoorPvPTF::Update(uint32 diff)
|
||||
m_LockTimer -= diff;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
void OutdoorPvPTF::HandlePlayerEnterZone(Player* player, uint32 zone)
|
||||
@@ -250,6 +188,40 @@ bool OutdoorPvPTF::IsLocked() const
|
||||
return m_IsLocked;
|
||||
}
|
||||
|
||||
void OutdoorPvPTF::ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker)
|
||||
{
|
||||
OutdoorPvP::ProcessEvent(obj, eventId, invoker);
|
||||
|
||||
SetWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
|
||||
SetWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
|
||||
|
||||
// now check if everything is capped
|
||||
if (m_HordeTowersControlled == TF_TOWER_NUM)
|
||||
HandleCapture(TEAM_HORDE);
|
||||
else if (m_AllianceTowersControlled == TF_TOWER_NUM)
|
||||
HandleCapture(TEAM_ALLIANCE);
|
||||
else
|
||||
{
|
||||
TeamCastSpell(TEAM_ALLIANCE, -TF_CAPTURE_BUFF);
|
||||
TeamCastSpell(TEAM_HORDE, -TF_CAPTURE_BUFF);
|
||||
}
|
||||
}
|
||||
|
||||
void OutdoorPvPTF::HandleCapture(TeamId team)
|
||||
{
|
||||
m_IsLocked = true;
|
||||
|
||||
for (ObjectGuid const& controlZoneGUID : _controlZoneGUIDs)
|
||||
if (GameObject* gameObject = GetMap()->GetGameObject(controlZoneGUID))
|
||||
gameObject->ActivateObject(GameObjectActions::MakeInert, 0);
|
||||
|
||||
TeamApplyBuff(team, TF_CAPTURE_BUFF);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL, 0);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_HORDE, team == TEAM_HORDE ? 1 : 0);
|
||||
SetWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE, team == TEAM_ALLIANCE ? 1 : 0);
|
||||
SetWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, 0);
|
||||
}
|
||||
|
||||
bool OutdoorPvPTF::SetupOutdoorPvP()
|
||||
{
|
||||
m_AllianceTowersControlled = 0;
|
||||
@@ -273,20 +245,12 @@ void OutdoorPvPTF::OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case 183104:
|
||||
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_NW, go));
|
||||
break;
|
||||
case 183411:
|
||||
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_N, go));
|
||||
break;
|
||||
case 183412:
|
||||
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_NE, go));
|
||||
break;
|
||||
case 183413:
|
||||
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_SE, go));
|
||||
break;
|
||||
case 183414:
|
||||
AddCapturePoint(new OPvPCapturePointTF(this, TF_TOWER_S, go));
|
||||
case TF_ENTRY_TOWER_NW:
|
||||
case TF_ENTRY_TOWER_N:
|
||||
case TF_ENTRY_TOWER_NE:
|
||||
case TF_ENTRY_TOWER_SE:
|
||||
case TF_ENTRY_TOWER_S:
|
||||
_controlZoneGUIDs.insert(go->GetGUID());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -295,81 +259,73 @@ void OutdoorPvPTF::OnGameObjectCreate(GameObject* go)
|
||||
OutdoorPvP::OnGameObjectCreate(go);
|
||||
}
|
||||
|
||||
bool OPvPCapturePointTF::Update(uint32 diff)
|
||||
TFControlZoneHandler::TFControlZoneHandler(OutdoorPvPTF* pvp, uint32 worldstateHorde, uint32 worldstateAlliance, uint32 worldstateNeutral) : OutdoorPvPControlZoneHandler(pvp),
|
||||
_worldstateHorde(worldstateHorde), _worldstateAlliance(worldstateAlliance), _worldstateNeutral(worldstateNeutral)
|
||||
{
|
||||
// can update even in locked state if gathers the controlling faction
|
||||
bool canupdate = ((((OutdoorPvPTF*)m_PvP)->GetAllianceTowersControlled() > 0) && m_activePlayers[0].size() > m_activePlayers[1].size()) ||
|
||||
((((OutdoorPvPTF*)m_PvP)->GetHordeTowersControlled() > 0) && m_activePlayers[0].size() < m_activePlayers[1].size());
|
||||
// if gathers the other faction, then only update if the pvp is unlocked
|
||||
canupdate = canupdate || !((OutdoorPvPTF*)m_PvP)->IsLocked();
|
||||
return canupdate && OPvPCapturePoint::Update(diff);
|
||||
}
|
||||
|
||||
void OPvPCapturePointTF::ChangeState()
|
||||
void TFControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
|
||||
{
|
||||
// if changing from controlling alliance to horde
|
||||
if (m_OldState == OBJECTIVESTATE_ALLIANCE)
|
||||
{
|
||||
if (uint32 alliance_towers = ((OutdoorPvPTF*)m_PvP)->GetAllianceTowersControlled())
|
||||
((OutdoorPvPTF*)m_PvP)->SetAllianceTowersControlled(--alliance_towers);
|
||||
m_PvP->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_LOSE_ALLIANCE);
|
||||
}
|
||||
// if changing from controlling horde to alliance
|
||||
else if (m_OldState == OBJECTIVESTATE_HORDE)
|
||||
{
|
||||
if (uint32 horde_towers = ((OutdoorPvPTF*)m_PvP)->GetHordeTowersControlled())
|
||||
((OutdoorPvPTF*)m_PvP)->SetHordeTowersControlled(--horde_towers);
|
||||
m_PvP->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_LOSE_HORDE);
|
||||
}
|
||||
controlZone->SetGoArtKit(1);
|
||||
GetOutdoorPvPTF()->SetHordeTowersControlled(GetOutdoorPvPTF()->GetHordeTowersControlled() + 1);
|
||||
GetOutdoorPvP()->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_TAKEN_HORDE);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 1, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 0, false);
|
||||
|
||||
uint32 artkit = 21;
|
||||
|
||||
switch (m_State)
|
||||
{
|
||||
case OBJECTIVESTATE_ALLIANCE:
|
||||
{
|
||||
m_TowerState = TF_TOWERSTATE_A;
|
||||
artkit = 2;
|
||||
uint32 alliance_towers = ((OutdoorPvPTF*)m_PvP)->GetAllianceTowersControlled();
|
||||
if (alliance_towers < TF_TOWER_NUM)
|
||||
((OutdoorPvPTF*)m_PvP)->SetAllianceTowersControlled(++alliance_towers);
|
||||
|
||||
m_PvP->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_TAKEN_ALLIANCE);
|
||||
|
||||
for (GuidSet::iterator itr = m_activePlayers[0].begin(); itr != m_activePlayers[0].end(); ++itr)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
||||
player->AreaExploredOrEventHappens(TF_ALLY_QUEST);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVESTATE_HORDE:
|
||||
{
|
||||
m_TowerState = TF_TOWERSTATE_H;
|
||||
artkit = 1;
|
||||
uint32 horde_towers = ((OutdoorPvPTF*)m_PvP)->GetHordeTowersControlled();
|
||||
if (horde_towers < TF_TOWER_NUM)
|
||||
((OutdoorPvPTF*)m_PvP)->SetHordeTowersControlled(++horde_towers);
|
||||
|
||||
m_PvP->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_TAKEN_HORDE);
|
||||
|
||||
for (GuidSet::iterator itr = m_activePlayers[1].begin(); itr != m_activePlayers[1].end(); ++itr)
|
||||
if (Player* player = ObjectAccessor::FindPlayer(*itr))
|
||||
if (GuidUnorderedSet const* guidSet = controlZone->GetInsidePlayers())
|
||||
for (ObjectGuid const& guid : *guidSet)
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*controlZone, guid))
|
||||
if (player->GetTeam() == TEAM_HORDE)
|
||||
player->AreaExploredOrEventHappens(TF_HORDE_QUEST);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVESTATE_NEUTRAL:
|
||||
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
m_TowerState = TF_TOWERSTATE_N;
|
||||
break;
|
||||
}
|
||||
|
||||
auto bounds = m_PvP->GetMap()->GetGameObjectBySpawnIdStore().equal_range(m_capturePointSpawnId);
|
||||
for (auto itr = bounds.first; itr != bounds.second; ++itr)
|
||||
itr->second->SetGoArtKit(artkit);
|
||||
OutdoorPvPControlZoneHandler::HandleProgressEventHorde(controlZone);
|
||||
}
|
||||
|
||||
UpdateTowerState();
|
||||
void TFControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
controlZone->SetGoArtKit(2);
|
||||
GetOutdoorPvPTF()->SetAllianceTowersControlled(GetOutdoorPvPTF()->GetAllianceTowersControlled() + 1);
|
||||
GetOutdoorPvP()->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_TAKEN_ALLIANCE);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 1, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 0, false);
|
||||
|
||||
if (GuidUnorderedSet const* guidSet = controlZone->GetInsidePlayers())
|
||||
for (ObjectGuid const& guid : *guidSet)
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*controlZone, guid))
|
||||
if (player->GetTeam() == TEAM_ALLIANCE)
|
||||
player->AreaExploredOrEventHappens(TF_ALLY_QUEST);
|
||||
|
||||
OutdoorPvPControlZoneHandler::HandleProgressEventAlliance(controlZone);
|
||||
}
|
||||
|
||||
void TFControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
|
||||
{
|
||||
GetOutdoorPvPTF()->SetHordeTowersControlled(GetOutdoorPvPTF()->GetHordeTowersControlled() - 1);
|
||||
GetOutdoorPvP()->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_LOSE_HORDE);
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEventHorde(controlZone);
|
||||
}
|
||||
|
||||
void TFControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
GetOutdoorPvPTF()->SetAllianceTowersControlled(GetOutdoorPvPTF()->GetAllianceTowersControlled() - 1);
|
||||
GetOutdoorPvP()->SendDefenseMessage(OutdoorPvPTFBuffZones[0], TEXT_SPIRIT_TOWER_LOSE_ALLIANCE);
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEventAlliance(controlZone);
|
||||
}
|
||||
|
||||
void TFControlZoneHandler::HandleNeutralEvent(GameObject* controlZone)
|
||||
{
|
||||
controlZone->SetGoArtKit(21);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateHorde, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateAlliance, 0, false);
|
||||
controlZone->GetMap()->SetWorldStateValue(_worldstateNeutral, 1, false);
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEvent(controlZone);
|
||||
}
|
||||
|
||||
OutdoorPvPTF* TFControlZoneHandler::GetOutdoorPvPTF() const
|
||||
{
|
||||
return static_cast<OutdoorPvPTF*>(OutdoorPvPControlZoneHandler::GetOutdoorPvP());
|
||||
}
|
||||
|
||||
class OutdoorPvP_terokkar_forest : public OutdoorPvPScript
|
||||
|
||||
@@ -54,26 +54,66 @@ enum TFWorldStates
|
||||
TF_UI_LOCKED_DISPLAY_ALLIANCE = 2767
|
||||
};
|
||||
|
||||
enum TFTowerStates
|
||||
enum TFGameEvents
|
||||
{
|
||||
TF_TOWERSTATE_N = 1,
|
||||
TF_TOWERSTATE_H = 2,
|
||||
TF_TOWERSTATE_A = 4
|
||||
TF_EVENT_TOWER_NW_ALLIANCE_PROGRESS = 12225,
|
||||
TF_EVENT_TOWER_NW_HORDE_PROGRESS = 12226,
|
||||
TF_EVENT_TOWER_NW_NEUTRAL_ALLIANCE = 12227,
|
||||
TF_EVENT_TOWER_NW_NEUTRAL_HORDE = 12228,
|
||||
|
||||
TF_EVENT_TOWER_NE_HORDE_PROGRESS = 12486,
|
||||
TF_EVENT_TOWER_NE_ALLIANCE_PROGRESS = 12487,
|
||||
TF_EVENT_TOWER_NE_NEUTRAL_HORDE = 12488,
|
||||
TF_EVENT_TOWER_NE_NEUTRAL_ALLIANCE = 12489,
|
||||
|
||||
TF_EVENT_TOWER_N_NEUTRAL_HORDE = 12490,
|
||||
TF_EVENT_TOWER_N_NEUTRAL_ALLIANCE = 12491,
|
||||
TF_EVENT_TOWER_N_ALLIANCE_PROGRESS = 12496,
|
||||
TF_EVENT_TOWER_N_HORDE_PROGRESS = 12497,
|
||||
|
||||
TF_EVENT_TOWER_SE_NEUTRAL_HORDE = 12492,
|
||||
TF_EVENT_TOWER_SE_NEUTRAL_ALLIANCE = 12493,
|
||||
TF_EVENT_TOWER_SE_ALLIANCE_PROGRESS = 12498,
|
||||
TF_EVENT_TOWER_SE_HORDE_PROGRESS = 12499,
|
||||
|
||||
TF_EVENT_TOWER_S_NEUTRAL_HORDE = 12494,
|
||||
TF_EVENT_TOWER_S_NEUTRAL_ALLIANCE = 12495,
|
||||
TF_EVENT_TOWER_S_ALLIANCE_PROGRESS = 12500,
|
||||
TF_EVENT_TOWER_S_HORDE_PROGRESS = 12501
|
||||
};
|
||||
|
||||
class OPvPCapturePointTF : public OPvPCapturePoint
|
||||
enum TFGameObjects
|
||||
{
|
||||
public:
|
||||
OPvPCapturePointTF(OutdoorPvP* pvp, OutdoorPvPTF_TowerType type, GameObject* go);
|
||||
TF_ENTRY_TOWER_NW = 183104,
|
||||
TF_ENTRY_TOWER_N = 183411,
|
||||
TF_ENTRY_TOWER_NE = 183412,
|
||||
TF_ENTRY_TOWER_SE = 183413,
|
||||
TF_ENTRY_TOWER_S = 183414
|
||||
};
|
||||
|
||||
bool Update(uint32 diff) override;
|
||||
void ChangeState() override;
|
||||
class OutdoorPvPTF;
|
||||
|
||||
void UpdateTowerState();
|
||||
class TFControlZoneHandler : public OutdoorPvPControlZoneHandler
|
||||
{
|
||||
public:
|
||||
explicit TFControlZoneHandler(OutdoorPvPTF* pvp, uint32 worldstateHorde, uint32 worldstateAlliance, uint32 worldstateNeutral);
|
||||
|
||||
protected:
|
||||
OutdoorPvPTF_TowerType m_TowerType;
|
||||
uint32 m_TowerState;
|
||||
void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEvent([[maybe_unused]] GameObject* controlZone) override;
|
||||
|
||||
uint32 GetWorldStateHorde() { return _worldstateHorde; }
|
||||
uint32 GetWorldStateAlliance() { return _worldstateAlliance; }
|
||||
uint32 GetWorldStateNeutral() { return _worldstateNeutral; }
|
||||
|
||||
OutdoorPvPTF* GetOutdoorPvPTF() const;
|
||||
|
||||
private:
|
||||
uint32 _worldstateHorde;
|
||||
uint32 _worldstateAlliance;
|
||||
uint32 _worldstateNeutral;
|
||||
};
|
||||
|
||||
class OutdoorPvPTF : public OutdoorPvP
|
||||
@@ -85,7 +125,7 @@ class OutdoorPvPTF : public OutdoorPvP
|
||||
void OnGameObjectCreate(GameObject* go) override;
|
||||
void HandlePlayerEnterZone(Player* player, uint32 zone) override;
|
||||
void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
|
||||
bool Update(uint32 diff) override;
|
||||
void Update(uint32 diff) override;
|
||||
void SendRemoveWorldStates(Player* player) override;
|
||||
|
||||
uint32 GetAllianceTowersControlled() const;
|
||||
@@ -94,6 +134,8 @@ class OutdoorPvPTF : public OutdoorPvP
|
||||
void SetHordeTowersControlled(uint32 count);
|
||||
bool IsLocked() const;
|
||||
|
||||
void ProcessEvent(WorldObject* obj, uint32 eventId, WorldObject* invoker) override;
|
||||
void HandleCapture(TeamId team);
|
||||
private:
|
||||
bool m_IsLocked;
|
||||
uint32 m_LockTimer;
|
||||
@@ -101,6 +143,8 @@ class OutdoorPvPTF : public OutdoorPvP
|
||||
uint32 m_AllianceTowersControlled;
|
||||
uint32 m_HordeTowersControlled;
|
||||
uint32 hours_left, second_digit, first_digit;
|
||||
GuidUnorderedSet _controlZoneGUIDs;
|
||||
std::unordered_map<uint32 /*control zone entry*/, std::unique_ptr<TFControlZoneHandler>> _controlZoneHandlers;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -36,113 +36,80 @@ uint32 const OutdoorPvPZMBuffZones[OutdoorPvPZMBuffZonesNum] = { 3521, 3607, 371
|
||||
// linked when the central tower is controlled
|
||||
uint32 const ZM_GRAVEYARD_ZONE = 3521;
|
||||
|
||||
struct zm_beacon
|
||||
ZMControlZoneHandler::ZMControlZoneHandler(OutdoorPvPZM* pvp, uint32 textBeaconTakenHorde, uint32 textBeaconTakenAlliance, uint32 worldstateNeutralUi, uint32 worldstateNeutralMap, uint32 worldstateHordeUi, uint32 worldstateHordeMap, uint32 worldstateAllianceUi, uint32 worldstateAllianceMap)
|
||||
: OutdoorPvPControlZoneHandler(pvp), _textBeaconTakenHorde(textBeaconTakenHorde), _textBeaconTakenAlliance(textBeaconTakenAlliance), _worldstateNeutralUi(worldstateNeutralUi), _worldstateNeutralMap(worldstateNeutralMap),
|
||||
_worldstateHordeUi(worldstateHordeUi), _worldstateHordeMap(worldstateHordeMap), _worldstateAllianceUi(worldstateAllianceUi), _worldstateAllianceMap(worldstateAllianceMap)
|
||||
{
|
||||
int32 ui_tower_n;
|
||||
int32 ui_tower_h;
|
||||
int32 ui_tower_a;
|
||||
int32 map_tower_n;
|
||||
int32 map_tower_h;
|
||||
int32 map_tower_a;
|
||||
uint32 event_enter;
|
||||
uint32 event_leave;
|
||||
};
|
||||
|
||||
zm_beacon const ZMBeaconInfo[ZM_NUM_BEACONS] =
|
||||
{
|
||||
{ ZM_UI_TOWER_EAST_N, ZM_UI_TOWER_EAST_H, ZM_UI_TOWER_EAST_A, ZM_MAP_TOWER_EAST_N, ZM_MAP_TOWER_EAST_H, ZM_MAP_TOWER_EAST_A, 11807, 11806 },
|
||||
{ ZM_UI_TOWER_WEST_N, ZM_UI_TOWER_WEST_H, ZM_UI_TOWER_WEST_A, ZM_MAP_TOWER_WEST_N, ZM_MAP_TOWER_WEST_H, ZM_MAP_TOWER_WEST_A, 11805, 11804 }
|
||||
};
|
||||
|
||||
uint32 const ZMBeaconCaptureA[ZM_NUM_BEACONS] =
|
||||
{
|
||||
TEXT_EAST_BEACON_TAKEN_ALLIANCE,
|
||||
TEXT_WEST_BEACON_TAKEN_ALLIANCE
|
||||
};
|
||||
|
||||
uint32 const ZMBeaconCaptureH[ZM_NUM_BEACONS] =
|
||||
{
|
||||
TEXT_EAST_BEACON_TAKEN_HORDE,
|
||||
TEXT_WEST_BEACON_TAKEN_HORDE
|
||||
};
|
||||
|
||||
OPvPCapturePointZM_Beacon::OPvPCapturePointZM_Beacon(OutdoorPvP* pvp, ZM_BeaconType type, GameObject* go) : OPvPCapturePoint(pvp), m_TowerType(type), m_TowerState(ZM_TOWERSTATE_N)
|
||||
{
|
||||
m_capturePointSpawnId = go->GetSpawnId();
|
||||
m_capturePoint = go;
|
||||
SetCapturePointData(go->GetEntry());
|
||||
}
|
||||
|
||||
void OPvPCapturePointZM_Beacon::UpdateTowerState()
|
||||
void ZMControlZoneHandler::HandleProgressEventHorde(GameObject* controlZone)
|
||||
{
|
||||
m_PvP->SetWorldState(ZMBeaconInfo[m_TowerType].ui_tower_n, int32((m_TowerState & ZM_TOWERSTATE_N) != 0));
|
||||
m_PvP->SetWorldState(ZMBeaconInfo[m_TowerType].map_tower_n, int32((m_TowerState & ZM_TOWERSTATE_N) != 0));
|
||||
m_PvP->SetWorldState(ZMBeaconInfo[m_TowerType].ui_tower_a, int32((m_TowerState & ZM_TOWERSTATE_A) != 0));
|
||||
m_PvP->SetWorldState(ZMBeaconInfo[m_TowerType].map_tower_a, int32((m_TowerState & ZM_TOWERSTATE_A) != 0));
|
||||
m_PvP->SetWorldState(ZMBeaconInfo[m_TowerType].ui_tower_h, int32((m_TowerState & ZM_TOWERSTATE_H) != 0));
|
||||
m_PvP->SetWorldState(ZMBeaconInfo[m_TowerType].map_tower_h, int32((m_TowerState & ZM_TOWERSTATE_H) != 0));
|
||||
OutdoorPvPControlZoneHandler::HandleProgressEventHorde(controlZone);
|
||||
GetOutdoorPvpZM()->SetHordeTowersControlled(GetOutdoorPvpZM()->GetHordeTowersControlled() + 1);
|
||||
GetOutdoorPvpZM()->SendDefenseMessage(ZM_GRAVEYARD_ZONE, _textBeaconTakenHorde);
|
||||
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateAllianceMap, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateAllianceUi, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateNeutralMap, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateNeutralUi, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateHordeMap, 1);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateHordeUi, 1);
|
||||
}
|
||||
|
||||
void OPvPCapturePointZM_Beacon::ChangeState()
|
||||
void ZMControlZoneHandler::HandleProgressEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
// if changing from controlling alliance to horde
|
||||
if (m_OldState == OBJECTIVESTATE_ALLIANCE)
|
||||
{
|
||||
if (uint32 alliance_towers = ((OutdoorPvPZM*)m_PvP)->GetAllianceTowersControlled())
|
||||
((OutdoorPvPZM*)m_PvP)->SetAllianceTowersControlled(--alliance_towers);
|
||||
}
|
||||
// if changing from controlling horde to alliance
|
||||
else if (m_OldState == OBJECTIVESTATE_HORDE)
|
||||
{
|
||||
if (uint32 horde_towers = ((OutdoorPvPZM*)m_PvP)->GetHordeTowersControlled())
|
||||
((OutdoorPvPZM*)m_PvP)->SetHordeTowersControlled(--horde_towers);
|
||||
}
|
||||
OutdoorPvPControlZoneHandler::HandleProgressEventAlliance(controlZone);
|
||||
GetOutdoorPvpZM()->SetAllianceTowersControlled(GetOutdoorPvpZM()->GetAllianceTowersControlled() + 1);
|
||||
GetOutdoorPvpZM()->SendDefenseMessage(ZM_GRAVEYARD_ZONE, _textBeaconTakenAlliance);
|
||||
|
||||
switch (m_State)
|
||||
{
|
||||
case OBJECTIVESTATE_ALLIANCE:
|
||||
{
|
||||
m_TowerState = ZM_TOWERSTATE_A;
|
||||
uint32 alliance_towers = ((OutdoorPvPZM*)m_PvP)->GetAllianceTowersControlled();
|
||||
if (alliance_towers < ZM_NUM_BEACONS)
|
||||
((OutdoorPvPZM*)m_PvP)->SetAllianceTowersControlled(++alliance_towers);
|
||||
m_PvP->SendDefenseMessage(ZM_GRAVEYARD_ZONE, ZMBeaconCaptureA[m_TowerType]);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVESTATE_HORDE:
|
||||
{
|
||||
m_TowerState = ZM_TOWERSTATE_H;
|
||||
uint32 horde_towers = ((OutdoorPvPZM*)m_PvP)->GetHordeTowersControlled();
|
||||
if (horde_towers < ZM_NUM_BEACONS)
|
||||
((OutdoorPvPZM*)m_PvP)->SetHordeTowersControlled(++horde_towers);
|
||||
m_PvP->SendDefenseMessage(ZM_GRAVEYARD_ZONE, ZMBeaconCaptureH[m_TowerType]);
|
||||
break;
|
||||
}
|
||||
case OBJECTIVESTATE_NEUTRAL:
|
||||
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
|
||||
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
|
||||
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
|
||||
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
|
||||
m_TowerState = ZM_TOWERSTATE_N;
|
||||
break;
|
||||
}
|
||||
|
||||
UpdateTowerState();
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateAllianceMap, 1);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateAllianceUi, 1);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateNeutralMap, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateNeutralUi, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateHordeMap, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateHordeUi, 0);
|
||||
}
|
||||
|
||||
bool OutdoorPvPZM::Update(uint32 diff)
|
||||
void ZMControlZoneHandler::HandleNeutralEventHorde(GameObject* controlZone)
|
||||
{
|
||||
bool changed = OutdoorPvP::Update(diff);
|
||||
if (changed)
|
||||
{
|
||||
if (m_AllianceTowersControlled == ZM_NUM_BEACONS)
|
||||
m_Graveyard->SetBeaconState(ALLIANCE);
|
||||
else if (m_HordeTowersControlled == ZM_NUM_BEACONS)
|
||||
m_Graveyard->SetBeaconState(HORDE);
|
||||
else
|
||||
m_Graveyard->SetBeaconState(0);
|
||||
}
|
||||
return changed;
|
||||
GetOutdoorPvpZM()->SetHordeTowersControlled(GetOutdoorPvpZM()->GetHordeTowersControlled() - 1);
|
||||
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEventHorde(controlZone);
|
||||
}
|
||||
|
||||
void ZMControlZoneHandler::HandleNeutralEventAlliance(GameObject* controlZone)
|
||||
{
|
||||
GetOutdoorPvpZM()->SetAllianceTowersControlled(GetOutdoorPvpZM()->GetAllianceTowersControlled() - 1);
|
||||
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEventAlliance(controlZone);
|
||||
}
|
||||
|
||||
void ZMControlZoneHandler::HandleNeutralEvent(GameObject* controlZone)
|
||||
{
|
||||
OutdoorPvPControlZoneHandler::HandleNeutralEvent(controlZone);
|
||||
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateAllianceMap, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateAllianceUi, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateNeutralMap, 1);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateNeutralUi, 1);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateHordeMap, 0);
|
||||
GetOutdoorPvpZM()->SetWorldState(_worldstateHordeUi, 0);
|
||||
}
|
||||
|
||||
OutdoorPvPZM* ZMControlZoneHandler::GetOutdoorPvpZM()
|
||||
{
|
||||
return static_cast<OutdoorPvPZM*>(OutdoorPvPControlZoneHandler::GetOutdoorPvP());
|
||||
}
|
||||
|
||||
void OutdoorPvPZM::Update(uint32 diff)
|
||||
{
|
||||
OutdoorPvP::Update(diff);
|
||||
if (m_AllianceTowersControlled == ZM_NUM_BEACONS)
|
||||
m_Graveyard->SetBeaconState(ALLIANCE);
|
||||
else if (m_HordeTowersControlled == ZM_NUM_BEACONS)
|
||||
m_Graveyard->SetBeaconState(HORDE);
|
||||
else
|
||||
m_Graveyard->SetBeaconState(0);
|
||||
}
|
||||
|
||||
void OutdoorPvPZM::HandlePlayerEnterZone(Player* player, uint32 zone)
|
||||
@@ -176,6 +143,30 @@ OutdoorPvPZM::OutdoorPvPZM(Map* map) : OutdoorPvP(map)
|
||||
m_Graveyard = nullptr;
|
||||
m_AllianceTowersControlled = 0;
|
||||
m_HordeTowersControlled = 0;
|
||||
|
||||
ControlZoneHandlers[ZM_GO_ENTRY_BEACON_EAST] = std::make_unique<ZMControlZoneHandler>(
|
||||
this,
|
||||
TEXT_EAST_BEACON_TAKEN_HORDE,
|
||||
TEXT_EAST_BEACON_TAKEN_ALLIANCE,
|
||||
ZM_UI_TOWER_EAST_N,
|
||||
ZM_MAP_TOWER_EAST_N,
|
||||
ZM_UI_TOWER_EAST_H,
|
||||
ZM_MAP_TOWER_EAST_H,
|
||||
ZM_UI_TOWER_EAST_A,
|
||||
ZM_MAP_TOWER_EAST_A
|
||||
);
|
||||
|
||||
ControlZoneHandlers[ZM_GO_ENTRY_BEACON_WEST] = std::make_unique<ZMControlZoneHandler>(
|
||||
this,
|
||||
TEXT_WEST_BEACON_TAKEN_HORDE,
|
||||
TEXT_WEST_BEACON_TAKEN_ALLIANCE,
|
||||
ZM_UI_TOWER_WEST_N,
|
||||
ZM_MAP_TOWER_WEST_N,
|
||||
ZM_UI_TOWER_WEST_H,
|
||||
ZM_MAP_TOWER_WEST_H,
|
||||
ZM_UI_TOWER_WEST_A,
|
||||
ZM_MAP_TOWER_WEST_A
|
||||
);
|
||||
}
|
||||
|
||||
bool OutdoorPvPZM::SetupOutdoorPvP()
|
||||
@@ -188,28 +179,10 @@ bool OutdoorPvPZM::SetupOutdoorPvP()
|
||||
RegisterZone(OutdoorPvPZMBuffZones[i]);
|
||||
|
||||
m_Graveyard = new OPvPCapturePointZM_Graveyard(this);
|
||||
AddCapturePoint(m_Graveyard); // though the update function isn't used, the handleusego is!
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OutdoorPvPZM::OnGameObjectCreate(GameObject* go)
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case 182523:
|
||||
AddCapturePoint(new OPvPCapturePointZM_Beacon(this, ZM_BEACON_EAST, go));
|
||||
break;
|
||||
case 182522:
|
||||
AddCapturePoint(new OPvPCapturePointZM_Beacon(this, ZM_BEACON_WEST, go));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
OutdoorPvP::OnGameObjectCreate(go);
|
||||
}
|
||||
|
||||
void OutdoorPvPZM::HandleKillImpl(Player* player, Unit* killed)
|
||||
{
|
||||
if (killed->GetTypeId() != TYPEID_PLAYER)
|
||||
@@ -221,11 +194,9 @@ void OutdoorPvPZM::HandleKillImpl(Player* player, Unit* killed)
|
||||
player->CastSpell(player, ZM_HordePlayerKillReward, true);
|
||||
}
|
||||
|
||||
bool OPvPCapturePointZM_Graveyard::Update(uint32 /*diff*/)
|
||||
void OPvPCapturePointZM_Graveyard::Update(uint32 /*diff*/)
|
||||
{
|
||||
bool retval = m_State != m_OldState;
|
||||
m_State = m_OldState;
|
||||
return retval;
|
||||
}
|
||||
|
||||
int32 OPvPCapturePointZM_Graveyard::HandleOpenGo(Player* player, GameObject* go)
|
||||
@@ -368,21 +339,20 @@ void OutdoorPvPZM::SendRemoveWorldStates(Player* player)
|
||||
initWorldStates.MapID = player->GetMapId();
|
||||
initWorldStates.AreaID = player->GetZoneId();
|
||||
initWorldStates.SubareaID = player->GetAreaId();
|
||||
initWorldStates.Worldstates.emplace_back(ZM_UI_TOWER_EAST_N, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_UI_TOWER_EAST_H, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_UI_TOWER_EAST_A, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_UI_TOWER_WEST_N, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_UI_TOWER_WEST_H, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_UI_TOWER_WEST_A, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_TOWER_EAST_N, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_TOWER_EAST_H, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_TOWER_EAST_A, 0);
|
||||
|
||||
for (auto& itr : ControlZoneHandlers)
|
||||
{
|
||||
ZMControlZoneHandler* handler = static_cast<ZMControlZoneHandler*>(itr.second.get());
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateNeutralUI(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateNeutralMap(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateHordeUI(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateHordeMap(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateAllianceUI(), 0);
|
||||
initWorldStates.Worldstates.emplace_back(handler->GetWorldStateAllianceMap(), 0);
|
||||
}
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_GRAVEYARD_H, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_GRAVEYARD_A, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_GRAVEYARD_N, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_TOWER_WEST_N, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_TOWER_WEST_H, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_TOWER_WEST_A, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_HORDE_FLAG_READY, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_HORDE_FLAG_NOT_READY, 0);
|
||||
initWorldStates.Worldstates.emplace_back(ZM_MAP_ALLIANCE_FLAG_NOT_READY, 0);
|
||||
|
||||
@@ -93,18 +93,17 @@ enum ZM_TowerStateMask
|
||||
ZM_TOWERSTATE_H = 4
|
||||
};
|
||||
|
||||
class OPvPCapturePointZM_Beacon : public OPvPCapturePoint
|
||||
enum ZM_WorldEvents
|
||||
{
|
||||
public:
|
||||
OPvPCapturePointZM_Beacon(OutdoorPvP* pvp, ZM_BeaconType type, GameObject* go);
|
||||
ZM_EVENT_BEACON_EAST_PROGRESS_HORDE = 11807,
|
||||
ZM_EVENT_BEACON_EAST_PROGRESS_ALLIANCE = 11806,
|
||||
ZM_EVENT_BEACON_EAST_NEUTRAL_HORDE = 11814,
|
||||
ZM_EVENT_BEACON_EAST_NEUTRAL_ALLIANCE = 11815,
|
||||
|
||||
void ChangeState() override;
|
||||
|
||||
void UpdateTowerState();
|
||||
|
||||
protected:
|
||||
ZM_BeaconType m_TowerType;
|
||||
uint32 m_TowerState;
|
||||
ZM_EVENT_BEACON_WEST_PROGRESS_HORDE = 11805,
|
||||
ZM_EVENT_BEACON_WEST_PROGRESS_ALLIANCE = 11804,
|
||||
ZM_EVENT_BEACON_WEST_NEUTRAL_HORDE = 11808,
|
||||
ZM_EVENT_BEACON_WEST_NEUTRAL_ALLIANCE = 11809
|
||||
};
|
||||
|
||||
enum ZM_GraveyardState
|
||||
@@ -114,12 +113,51 @@ enum ZM_GraveyardState
|
||||
ZM_GRAVEYARD_H = 4
|
||||
};
|
||||
|
||||
enum ZM_GameObjectEntries
|
||||
{
|
||||
ZM_GO_ENTRY_BEACON_WEST = 182522,
|
||||
ZM_GO_ENTRY_BEACON_EAST = 182523
|
||||
};
|
||||
|
||||
class OutdoorPvPZM;
|
||||
|
||||
class ZMControlZoneHandler : public OutdoorPvPControlZoneHandler
|
||||
{
|
||||
public:
|
||||
ZMControlZoneHandler(OutdoorPvPZM* pvp, uint32 textBeaconTakenHorde, uint32 textBeaconTakenAlliance, uint32 worldstateNeutralUi, uint32 worldstateNeutralMap, uint32 worldstateHordeUi, uint32 worldstateHordeMap, uint32 worldstateAllianceUi, uint32 worldstateAllianceMap);
|
||||
|
||||
void HandleProgressEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleProgressEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventHorde([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEventAlliance([[maybe_unused]] GameObject* controlZone) override;
|
||||
void HandleNeutralEvent([[maybe_unused]] GameObject* controlZone) override;
|
||||
|
||||
uint32 GetWorldStateNeutralUI() { return _worldstateNeutralUi; }
|
||||
uint32 GetWorldStateNeutralMap() { return _worldstateNeutralMap; }
|
||||
uint32 GetWorldStateHordeUI() { return _worldstateHordeUi; }
|
||||
uint32 GetWorldStateHordeMap() { return _worldstateHordeMap; }
|
||||
uint32 GetWorldStateAllianceUI() { return _worldstateAllianceUi; }
|
||||
uint32 GetWorldStateAllianceMap() { return _worldstateAllianceMap; }
|
||||
|
||||
OutdoorPvPZM* GetOutdoorPvpZM();
|
||||
|
||||
private:
|
||||
uint32 _textBeaconTakenHorde;
|
||||
uint32 _textBeaconTakenAlliance;
|
||||
uint32 _worldstateNeutralUi;
|
||||
uint32 _worldstateNeutralMap;
|
||||
uint32 _worldstateHordeUi;
|
||||
uint32 _worldstateHordeMap;
|
||||
uint32 _worldstateAllianceUi;
|
||||
uint32 _worldstateAllianceMap;
|
||||
};
|
||||
|
||||
class OPvPCapturePointZM_Graveyard : public OPvPCapturePoint
|
||||
{
|
||||
public:
|
||||
OPvPCapturePointZM_Graveyard(OutdoorPvP* pvp);
|
||||
|
||||
bool Update(uint32 diff) override;
|
||||
void Update(uint32 diff) override;
|
||||
void ChangeState() override { }
|
||||
int32 HandleOpenGo(Player* player, GameObject* go) override;
|
||||
bool HandleDropFlag(Player* player, uint32 spellId) override;
|
||||
@@ -144,10 +182,9 @@ class OutdoorPvPZM : public OutdoorPvP
|
||||
OutdoorPvPZM(Map* map);
|
||||
|
||||
bool SetupOutdoorPvP() override;
|
||||
void OnGameObjectCreate(GameObject* go) override;
|
||||
void HandlePlayerEnterZone(Player* player, uint32 zone) override;
|
||||
void HandlePlayerLeaveZone(Player* player, uint32 zone) override;
|
||||
bool Update(uint32 diff) override;
|
||||
void Update(uint32 diff) override;
|
||||
void SendRemoveWorldStates(Player* player) override;
|
||||
void HandleKillImpl(Player* player, Unit* killed) override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user