TrinityCore
OutdoorPvP.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "OutdoorPvP.h"
19#include "CellImpl.h"
20#include "ChatPackets.h"
21#include "DatabaseEnv.h"
22#include "GridNotifiersImpl.h"
23#include "Group.h"
24#include "Log.h"
25#include "Map.h"
26#include "ObjectAccessor.h"
27#include "ObjectMgr.h"
28#include "OutdoorPvPMgr.h"
29#include "WorldPacket.h"
30#include "WorldSession.h"
31#include "WorldStateMgr.h"
32
34{
35 public:
37 : _zoneId(zoneId), _id(id) { }
38
40 {
41 std::string text = sOutdoorPvPMgr->GetDefenseMessage(_zoneId, _id, locale);
42
44 defenseMessage->Data.ZoneID = _zoneId;
45 defenseMessage->Data.MessageText = text;
46 defenseMessage->Data.Write();
47 return defenseMessage;
48 }
49
50 private:
53};
54
56 m_team(TEAM_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL),
57 m_State(OBJECTIVESTATE_NEUTRAL), m_PvP(pvp)
58{ }
59
60OutdoorPvP::OutdoorPvP(Map* map) : m_TypeId(0), m_map(map) { }
61
62OutdoorPvP::~OutdoorPvP() = default;
63
65{
66 m_players[player->GetTeamId()].insert(player->GetGUID());
67}
68
70{
71 // 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)
72 if (!player->GetSession()->PlayerLogout())
74 m_players[player->GetTeamId()].erase(player->GetGUID());
75 TC_LOG_DEBUG("outdoorpvp", "Player {} left an outdoorpvp zone", player->GetName());
76}
77
78void OutdoorPvP::HandlePlayerResurrects(Player* /*player*/, uint32 /*zone*/) { }
79
81{
82 for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
83 itr->second->Update(diff);
84}
85
87{
88 return sWorldStateMgr->GetValue(worldStateId, m_map);
89}
90
91void OutdoorPvP::SetWorldState(int32 worldStateId, int32 value)
92{
93 sWorldStateMgr->SetValue(worldStateId, value, false, m_map);
94}
95
96void OutdoorPvP::HandleKill(Player* killer, Unit* killed)
97{
98 if (Group* group = killer->GetGroup())
99 {
100 for (GroupReference* itr = group->GetFirstMember(); itr != nullptr; itr = itr->next())
101 {
102 Player* groupGuy = itr->GetSource();
103
104 if (!groupGuy)
105 continue;
106
107 // skip if too far away
108 if (!groupGuy->IsAtGroupRewardDistance(killed))
109 continue;
110
111 // creature kills must be notified, even if not inside objective / not outdoor pvp active
112 // player kills only count if active and inside objective
113 if ((groupGuy->IsOutdoorPvPActive()) || killed->GetTypeId() == TYPEID_UNIT)
114 HandleKillImpl(groupGuy, killed);
115 }
116 }
117 else
118 {
119 // creature kills must be notified, even if not inside objective / not outdoor pvp active
120 if ((killer->IsOutdoorPvPActive()) || killed->GetTypeId() == TYPEID_UNIT)
121 HandleKillImpl(killer, killed);
122 }
123}
124
126{
127 for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
128 if (itr->second->HandleCustomSpell(player, spellId, go))
129 return true;
130
131 return false;
132}
133
135{
136 if (!player->IsOutdoorPvPActive())
137 return false;
138 return true;
139}
140
142{
143 for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
144 if (itr->second->HandleOpenGo(player, go) >= 0)
145 return true;
146
147 return false;
148}
149
151{
152 for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
153 if (itr->second->HandleDropFlag(player, id))
154 return true;
155
156 return false;
157}
158
160{
161 return -1;
162}
163
165{
166 // This is faster than sWorld->SendZoneMessage
167 for (uint32 team = 0; team < PVP_TEAMS_COUNT; ++team)
168 for (GuidSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
169 if (Player* const player = ObjectAccessor::FindPlayer(*itr))
170 player->SendDirectMessage(data);
171}
172
174{
175 sOutdoorPvPMgr->AddZone(zoneId, this);
176}
177
178bool OutdoorPvP::HasPlayer(Player const* player) const
179{
180 GuidSet const& plSet = m_players[player->GetTeamId()];
181 return plSet.find(player->GetGUID()) != plSet.end();
182}
183
185{
186 if (spellId > 0)
187 {
188 for (GuidSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
189 if (Player* const player = ObjectAccessor::FindPlayer(*itr))
190 player->CastSpell(player, (uint32)spellId, true);
191 }
192 else
193 {
194 for (GuidSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
195 if (Player* const player = ObjectAccessor::FindPlayer(*itr))
196 player->RemoveAura((uint32)-spellId); // by stack?
197 }
198}
199
200void OutdoorPvP::TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2)
201{
202 TeamCastSpell(team, spellId);
203 TeamCastSpell(OTHER_TEAM(team), spellId2 ? -(int32)spellId2 : -(int32)spellId);
204}
205
207{
208 DefenseMessageBuilder builder(zoneId, id);
210 BroadcastWorker(localizer, zoneId);
211}
212
213void OutdoorPvP::ProcessEvent([[maybe_unused]] WorldObject * target, [[maybe_unused]] uint32 eventId, [[maybe_unused]] WorldObject * invoker)
214{
215 if (invoker)
216 {
217 if (GameObject* gameobject = invoker->ToGameObject())
218 {
219 if (gameobject->GetGoType() == GAMEOBJECT_TYPE_CONTROL_ZONE)
220 {
221 if (!ControlZoneHandlers.contains(gameobject->GetEntry()))
222 return;
223
224 auto controlzone = gameobject->GetGOInfo()->controlZone;
225 OutdoorPvPControlZoneHandler& handler = *ControlZoneHandlers[invoker->GetEntry()];
226 if (eventId == controlzone.CaptureEventAlliance)
227 handler.HandleCaptureEventAlliance(gameobject);
228 else if (eventId == controlzone.CaptureEventHorde)
229 handler.HandleCaptureEventHorde(gameobject);
230 else if (eventId == controlzone.ContestedEventAlliance)
231 handler.HandleContestedEventAlliance(gameobject);
232 else if (eventId == controlzone.ContestedEventHorde)
233 handler.HandleContestedEventHorde(gameobject);
234 else if (eventId == controlzone.NeutralEventAlliance)
235 handler.HandleNeutralEventAlliance(gameobject);
236 else if (eventId == controlzone.NeutralEventHorde)
237 handler.HandleNeutralEventHorde(gameobject);
238 else if (eventId == controlzone.ProgressEventAlliance)
239 handler.HandleProgressEventAlliance(gameobject);
240 else if (eventId == controlzone.ProgressEventHorde)
241 handler.HandleProgressEventHorde(gameobject);
242 }
243 }
244 }
245}
246
247template<class Worker>
248void OutdoorPvP::BroadcastWorker(Worker& _worker, uint32 zoneId)
249{
250 for (uint32 i = 0; i < PVP_TEAMS_COUNT; ++i)
251 for (GuidSet::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
252 if (Player* player = ObjectAccessor::FindPlayer(*itr))
253 if (player->GetZoneId() == zoneId)
254 _worker(player);
255}
LocaleConstant
Definition: Common.h:48
int32_t int32
Definition: Define.h:138
uint32_t uint32
Definition: Define.h:142
#define TC_LOG_DEBUG(filterType__,...)
Definition: Log.h:156
@ TYPEID_UNIT
Definition: ObjectGuid.h:40
std::set< ObjectGuid > GuidSet
Definition: ObjectGuid.h:393
#define sOutdoorPvPMgr
@ OBJECTIVESTATE_NEUTRAL
Definition: OutdoorPvP.h:41
#define OTHER_TEAM(a)
Definition: OutdoorPvP.h:50
@ GAMEOBJECT_TYPE_CONTROL_ZONE
TeamId
@ TEAM_NEUTRAL
uint8 constexpr PVP_TEAMS_COUNT
#define sWorldStateMgr
Definition: WorldStateMgr.h:50
virtual void HandleNeutralEventHorde(GameObject *controlZone)
Definition: ZoneScript.h:53
virtual void HandleProgressEventAlliance(GameObject *controlZone)
Definition: ZoneScript.h:52
virtual void HandleContestedEventAlliance(GameObject *controlZone)
Definition: ZoneScript.h:50
virtual void HandleNeutralEventAlliance(GameObject *controlZone)
Definition: ZoneScript.h:54
virtual void HandleCaptureEventHorde(GameObject *controlZone)
Definition: ZoneScript.h:47
virtual void HandleProgressEventHorde(GameObject *controlZone)
Definition: ZoneScript.h:51
virtual void HandleContestedEventHorde(GameObject *controlZone)
Definition: ZoneScript.h:49
virtual void HandleCaptureEventAlliance(GameObject *controlZone)
Definition: ZoneScript.h:48
uint32 _zoneId
ZoneId.
Definition: OutdoorPvP.cpp:51
Trinity::PacketSenderOwning< WorldPackets::Chat::DefenseMessage > * operator()(LocaleConstant locale) const
Definition: OutdoorPvP.cpp:39
DefenseMessageBuilder(uint32 zoneId, uint32 id)
Definition: OutdoorPvP.cpp:36
uint32 _id
BroadcastTextId.
Definition: OutdoorPvP.cpp:52
GroupReference * next()
Definition: Group.h:197
Definition: Map.h:189
OPvPCapturePoint(OutdoorPvP *pvp)
Definition: OutdoorPvP.cpp:55
virtual bool HandleCustomSpell(Player *player, uint32 spellId, GameObject *go)
Definition: OutdoorPvP.cpp:134
virtual int32 HandleOpenGo(Player *player, GameObject *go)
Definition: OutdoorPvP.cpp:159
static GameObject * ToGameObject(Object *o)
Definition: Object.h:231
TypeID GetTypeId() const
Definition: Object.h:173
static ObjectGuid GetGUID(Object const *o)
Definition: Object.h:159
virtual void HandlePlayerEnterZone(Player *player, uint32 zone)
Definition: OutdoorPvP.cpp:64
OPvPCapturePointMap m_capturePoints
Definition: OutdoorPvP.h:202
bool HasPlayer(Player const *player) const
Definition: OutdoorPvP.cpp:178
GuidSet m_players[2]
Definition: OutdoorPvP.h:206
virtual void Update(uint32 diff)
Definition: OutdoorPvP.cpp:80
virtual ~OutdoorPvP()
int32 GetWorldState(int32 worldStateId) const
Definition: OutdoorPvP.cpp:86
void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2=0)
Definition: OutdoorPvP.cpp:200
void RegisterZone(uint32 zoneid)
Definition: OutdoorPvP.cpp:173
virtual void SendRemoveWorldStates(Player *)
Definition: OutdoorPvP.h:211
void SetWorldState(int32 worldStateId, int32 value)
Definition: OutdoorPvP.cpp:91
virtual bool HandleCustomSpell(Player *player, uint32 spellId, GameObject *go)
Definition: OutdoorPvP.cpp:125
virtual void HandlePlayerLeaveZone(Player *player, uint32 zone)
Definition: OutdoorPvP.cpp:69
virtual bool HandleOpenGo(Player *player, GameObject *go)
Definition: OutdoorPvP.cpp:141
void TeamCastSpell(TeamId team, int32 spellId)
Definition: OutdoorPvP.cpp:184
virtual void HandlePlayerResurrects(Player *player, uint32 zone)
Definition: OutdoorPvP.cpp:78
ControlZoneHandlerMap ControlZoneHandlers
Definition: OutdoorPvP.h:204
virtual void HandleKillImpl(Player *, Unit *)
Definition: OutdoorPvP.h:169
void ProcessEvent(WorldObject *target, uint32 eventId, WorldObject *invoker) override
Definition: OutdoorPvP.cpp:213
void BroadcastWorker(Worker &_worker, uint32 zoneId)
Definition: OutdoorPvP.cpp:248
void SendDefenseMessage(uint32 zoneId, uint32 id)
Definition: OutdoorPvP.cpp:206
virtual void HandleKill(Player *killer, Unit *killed)
Definition: OutdoorPvP.cpp:96
virtual bool HandleDropFlag(Player *player, uint32 spellId)
Definition: OutdoorPvP.cpp:150
void BroadcastPacket(WorldPacket const *data) const
Definition: OutdoorPvP.cpp:164
OutdoorPvP(Map *map)
Definition: OutdoorPvP.cpp:60
Map * m_map
Definition: OutdoorPvP.h:229
bool IsAtGroupRewardDistance(WorldObject const *pRewardSource) const
Definition: Player.cpp:25673
WorldSession * GetSession() const
Definition: Player.h:2101
TeamId GetTeamId() const
Definition: Player.h:2236
Group * GetGroup(Optional< uint8 > partyIndex)
Definition: Player.h:2606
bool IsOutdoorPvPActive() const
Definition: Player.cpp:7736
Definition: Unit.h:627
std::string const & GetName() const
Definition: Object.h:555
bool PlayerLogout() const
Definition: WorldSession.h:970
TC_GAME_API Player * FindPlayer(ObjectGuid const &)