rearranged core files

--HG--
branch : trunk
This commit is contained in:
Rat
2010-06-05 23:40:08 +02:00
parent 6a9357b13d
commit 75b80d9f5b
332 changed files with 0 additions and 0 deletions
+598
View File
@@ -0,0 +1,598 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvP.h"
#include "OutdoorPvPImpl.h"
#include "OutdoorPvPMgr.h"
#include "ObjectAccessor.h"
#include "ObjectMgr.h"
#include "Map.h"
#include "MapManager.h"
#include "Group.h"
#include "WorldPacket.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "GridNotifiers.h"
#include "GridNotifiersImpl.h"
#include "CellImpl.h"
OPvPCapturePoint::OPvPCapturePoint(OutdoorPvP * pvp)
: m_PvP(pvp), m_value(0), m_maxValue(0), m_team(TEAM_NEUTRAL),
m_State(OBJECTIVESTATE_NEUTRAL), m_OldState(OBJECTIVESTATE_NEUTRAL), m_capturePointGUID(0), m_neutralValuePct(0),
m_maxSpeed(0), m_capturePoint(NULL)
{
}
bool OPvPCapturePoint::HandlePlayerEnter(Player * plr)
{
if (m_capturePoint)
{
plr->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldState1, 1);
plr->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate2, (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f));
plr->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate3, m_neutralValuePct);
}
return m_activePlayers[plr->GetTeamId()].insert(plr).second;
}
void OPvPCapturePoint::HandlePlayerLeave(Player * plr)
{
if (m_capturePoint)
plr->SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldState1, 0);
m_activePlayers[plr->GetTeamId()].erase(plr);
}
void OPvPCapturePoint::SendChangePhase()
{
if (!m_capturePoint)
return;
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldState1, 1);
// send these updates to only the ones in this objective
SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate2, (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f));
// send this too, sometimes it resets :S
SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate3, m_neutralValuePct);
}
void OPvPCapturePoint::AddGO(uint32 type, uint32 guid, uint32 entry)
{
if (!entry)
{
const GameObjectData *data = objmgr.GetGOData(guid);
if (!data)
return;
entry = data->id;
}
m_Objects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT);
m_ObjectTypes[m_Objects[type]]=type;
}
void OPvPCapturePoint::AddCre(uint32 type, uint32 guid, uint32 entry)
{
if (!entry)
{
const CreatureData *data = objmgr.GetCreatureData(guid);
if (!data)
return;
entry = data->id;
}
m_Creatures[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_UNIT);
m_CreatureTypes[m_Creatures[type]] = type;
}
bool OPvPCapturePoint::AddObject(uint32 type, uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
{
if (uint32 guid = objmgr.AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3))
{
AddGO(type, guid, entry);
return true;
}
return false;
}
bool OPvPCapturePoint::AddCreature(uint32 type, uint32 entry, uint32 team, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay)
{
if (uint32 guid = objmgr.AddCreData(entry, team, map, x, y, z, o, spawntimedelay))
{
AddCre(type, guid, entry);
return true;
}
return false;
}
bool OPvPCapturePoint::SetCapturePointData(uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
{
sLog.outDebug("Creating capture point %u", entry);
// check info existence
GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
if (!goinfo || goinfo->type != GAMEOBJECT_TYPE_CAPTURE_POINT)
{
sLog.outError("OutdoorPvP: GO %u is not capture point!", entry);
return false;
}
m_capturePointGUID = objmgr.AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3);
if (!m_capturePointGUID)
return false;
// get the needed values from goinfo
m_maxValue = goinfo->capturePoint.maxTime;
m_maxSpeed = m_maxValue / (goinfo->capturePoint.minTime ? goinfo->capturePoint.minTime : 60);
m_neutralValuePct = goinfo->capturePoint.neutralPercent;
m_minValue = m_maxValue * goinfo->capturePoint.neutralPercent / 100;
return true;
}
bool OPvPCapturePoint::DelCreature(uint32 type)
{
if (!m_Creatures[type])
{
sLog.outDebug("opvp creature type %u was already deleted",type);
return false;
}
Creature *cr = HashMapHolder<Creature>::Find(m_Creatures[type]);
if (!cr)
{
// can happen when closing the core
m_Creatures[type] = 0;
return false;
}
sLog.outDebug("deleting opvp creature type %u",type);
uint32 guid = cr->GetDBTableGUIDLow();
// Don't save respawn time
cr->SetRespawnTime(0);
cr->RemoveCorpse();
// explicit removal from map
// beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted
// so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed
//if (Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
// map->Remove(cr,false);
// delete respawn time for this creature
WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u'", guid);
cr->AddObjectToRemoveList();
objmgr.DeleteCreatureData(guid);
m_CreatureTypes[m_Creatures[type]] = 0;
m_Creatures[type] = 0;
return true;
}
bool OPvPCapturePoint::DelObject(uint32 type)
{
if (!m_Objects[type])
return false;
GameObject *obj = HashMapHolder<GameObject>::Find(m_Objects[type]);
if (!obj)
{
m_Objects[type] = 0;
return false;
}
uint32 guid = obj->GetDBTableGUIDLow();
obj->SetRespawnTime(0); // not save respawn time
obj->Delete();
objmgr.DeleteGOData(guid);
m_ObjectTypes[m_Objects[type]] = 0;
m_Objects[type] = 0;
return true;
}
bool OPvPCapturePoint::DelCapturePoint()
{
objmgr.DeleteGOData(m_capturePointGUID);
m_capturePointGUID = 0;
if (m_capturePoint)
{
m_capturePoint->SetRespawnTime(0); // not save respawn time
m_capturePoint->Delete();
}
return true;
}
void OPvPCapturePoint::DeleteSpawns()
{
for (std::map<uint32,uint64>::iterator i = m_Objects.begin(); i != m_Objects.end(); ++i)
DelObject(i->first);
for (std::map<uint32,uint64>::iterator i = m_Creatures.begin(); i != m_Creatures.end(); ++i)
DelCreature(i->first);
DelCapturePoint();
}
void OutdoorPvP::DeleteSpawns()
{
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
itr->second->DeleteSpawns();
}
OutdoorPvP::OutdoorPvP() : m_sendUpdate(true)
{
}
OutdoorPvP::~OutdoorPvP()
{
DeleteSpawns();
}
void OutdoorPvP::HandlePlayerEnterZone(Player * plr, uint32 /*zone*/)
{
m_players[plr->GetTeamId()].insert(plr);
}
void OutdoorPvP::HandlePlayerLeaveZone(Player * plr, uint32 /*zone*/)
{
// inform the objectives of the leaving
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
itr->second->HandlePlayerLeave(plr);
// 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 (!plr->GetSession()->PlayerLogout())
SendRemoveWorldStates(plr);
m_players[plr->GetTeamId()].erase(plr);
sLog.outDebug("Player %s left an outdoorpvp zone", plr->GetName());
}
void OutdoorPvP::HandlePlayerResurrects(Player * /*plr*/, uint32 /*zone*/)
{
}
bool 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 = m_capturePoint->GetGOInfo()->capturePoint.radius;
for (uint32 team = 0; team < 2; ++team)
{
for (PlayerSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end();)
{
Player *player = *itr;
++itr;
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);
m_capturePoint->VisitNearbyWorldObject(radius, searcher);
for (std::list<Player*>::iterator itr = players.begin(); itr != players.end(); ++itr)
{
if ((*itr)->IsOutdoorPvPActive())
{
if (m_activePlayers[(*itr)->GetTeamId()].insert(*itr).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)
{
//sLog.outError("%u->%u", m_OldState, m_State);
if (oldTeam != m_team)
ChangeTeam(oldTeam);
ChangeState();
return true;
}
return false;
}
void OutdoorPvP::SendUpdateWorldState(uint32 field, uint32 value)
{
if (m_sendUpdate)
for (int i = 0; i < 2; ++i)
for (PlayerSet::iterator itr = m_players[i].begin(); itr != m_players[i].end(); ++itr)
(*itr)->SendUpdateWorldState(field, value);
}
void OPvPCapturePoint::SendUpdateWorldState(uint32 field, uint32 value)
{
for (uint32 team = 0; team < 2; ++team)
{
// send to all players present in the area
for (PlayerSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr)
{
(*itr)->SendUpdateWorldState(field,value);
}
}
}
void OPvPCapturePoint::SendObjectiveComplete(uint32 id,uint64 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 (PlayerSet::iterator itr = m_activePlayers[team].begin(); itr != m_activePlayers[team].end(); ++itr)
(*itr)->KilledMonsterCredit(id, guid);
}
void OutdoorPvP::HandleKill(Player *killer, Unit * killed)
{
if (Group * pGroup = killer->GetGroup())
{
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
{
Player *pGroupGuy = itr->getSource();
if (!pGroupGuy)
continue;
// skip if too far away
if (!pGroupGuy->IsAtGroupRewardDistance(killed))
continue;
// creature kills must be notified, even if not inside objective / not outdoor pvp active
// player kills only count if active and inside objective
if ((pGroupGuy->IsOutdoorPvPActive() && IsInsideObjective(pGroupGuy)) || killed->GetTypeId() == TYPEID_UNIT)
{
HandleKillImpl(pGroupGuy, killed);
}
}
}
else
{
// creature kills must be notified, even if not inside objective / not outdoor pvp active
if (killer && ((killer->IsOutdoorPvPActive() && IsInsideObjective(killer)) || killed->GetTypeId() == TYPEID_UNIT))
{
HandleKillImpl(killer, killed);
}
}
}
bool OutdoorPvP::IsInsideObjective(Player *plr) const
{
for (OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if (itr->second->IsInsideObjective(plr))
return true;
return false;
}
bool OPvPCapturePoint::IsInsideObjective(Player *plr) const
{
return m_activePlayers[plr->GetTeamId()].find(plr) != m_activePlayers[plr->GetTeamId()].end();
}
bool OutdoorPvP::HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go)
{
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if (itr->second->HandleCustomSpell(plr,spellId,go))
return true;
return false;
}
bool OPvPCapturePoint::HandleCustomSpell(Player *plr, uint32 /*spellId*/, GameObject * /*go*/)
{
if (!plr->IsOutdoorPvPActive())
return false;
return false;
}
bool OutdoorPvP::HandleOpenGo(Player *plr, uint64 guid)
{
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if (itr->second->HandleOpenGo(plr,guid) >= 0)
return true;
return false;
}
bool OutdoorPvP::HandleGossipOption(Player * plr, uint64 guid, uint32 id)
{
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if (itr->second->HandleGossipOption(plr, guid, id))
return true;
return false;
}
bool OutdoorPvP::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
{
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if (itr->second->CanTalkTo(plr, c, gso))
return true;
return false;
}
bool OutdoorPvP::HandleDropFlag(Player * plr, uint32 id)
{
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if (itr->second->HandleDropFlag(plr, id))
return true;
return false;
}
bool OPvPCapturePoint::HandleGossipOption(Player * /*plr*/, uint64 /*guid*/, uint32 /*id*/)
{
return false;
}
bool OPvPCapturePoint::CanTalkTo(Player * /*plr*/, Creature * /*c*/, GossipMenuItems /*gso*/)
{
return false;
}
bool OPvPCapturePoint::HandleDropFlag(Player * /*plr*/, uint32 /*id*/)
{
return false;
}
int32 OPvPCapturePoint::HandleOpenGo(Player * /*plr*/, uint64 guid)
{
std::map<uint64,uint32>::iterator itr = m_ObjectTypes.find(guid);
if (itr != m_ObjectTypes.end())
{
return itr->second;
}
return -1;
}
bool OutdoorPvP::HandleAreaTrigger(Player * /*plr*/, uint32 /*trigger*/)
{
return false;
}
void OutdoorPvP::BroadcastPacket(WorldPacket &data) const
{
// This is faster than sWorld.SendZoneMessage
for (uint32 team = 0; team < 2; ++team)
for (PlayerSet::const_iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
(*itr)->GetSession()->SendPacket(&data);
}
void OutdoorPvP::RegisterZone(uint32 zoneId)
{
sOutdoorPvPMgr.AddZone(zoneId, this);
}
bool OutdoorPvP::HasPlayer(Player *plr) const
{
return m_players[plr->GetTeamId()].find(plr) != m_players[plr->GetTeamId()].end();
}
void OutdoorPvP::TeamCastSpell(TeamId team, int32 spellId)
{
if (spellId > 0)
for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
(*itr)->CastSpell(*itr, (uint32)spellId, true);
else
for (PlayerSet::iterator itr = m_players[team].begin(); itr != m_players[team].end(); ++itr)
(*itr)->RemoveAura((uint32)-spellId); // by stack?
}
void OutdoorPvP::TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2)
{
TeamCastSpell(team, spellId);
TeamCastSpell(OTHER_TEAM(team), spellId2 ? -(int32)spellId2 : -(int32)spellId);
}
void OutdoorPvP::OnGameObjectCreate(GameObject *go, bool add)
{
if (go->GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT)
return;
if (OPvPCapturePoint *cp = GetCapturePoint(go->GetDBTableGUIDLow()))
cp->m_capturePoint = add ? go : NULL;
}
+260
View File
@@ -0,0 +1,260 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_H_
#define OUTDOOR_PVP_H_
#include "Util.h"
#include "SharedDefines.h"
#include "ZoneScript.h"
class GameObject;
enum OutdoorPvPTypes
{
OUTDOOR_PVP_HP = 1,
OUTDOOR_PVP_NA,
OUTDOOR_PVP_TF,
OUTDOOR_PVP_ZM,
OUTDOOR_PVP_SI,
OUTDOOR_PVP_EP,
OUTDOOR_PVP_WG,
OUTDOOR_PVP_NR,
};
const uint8 CapturePointArtKit[3] = {2, 1, 21};
enum ObjectiveStates
{
OBJECTIVESTATE_NEUTRAL = 0,
OBJECTIVESTATE_ALLIANCE,
OBJECTIVESTATE_HORDE,
OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE,
OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE,
OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE,
OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE,
};
// struct for go spawning
struct go_type{
uint32 entry;
uint32 map;
float x;
float y;
float z;
float o;
float rot0;
float rot1;
float rot2;
float rot3;
};
// struct for creature spawning
struct creature_type{
uint32 entry;
uint32 teamval;
uint32 map;
float x;
float y;
float z;
float o;
};
// some class predefs
class Player;
class GameObject;
class WorldPacket;
class Creature;
class Unit;
struct GossipMenuItems;
typedef std::set<Player*> PlayerSet;
class OutdoorPvP;
class OPvPCapturePoint
{
public:
OPvPCapturePoint(OutdoorPvP * pvp);
virtual void FillInitialWorldStates(WorldPacket & /*data*/) {}
// 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, uint64 guid);
// used when player is activated/inactivated in the area
virtual bool HandlePlayerEnter(Player * plr);
virtual void HandlePlayerLeave(Player * plr);
//virtual void HandlePlayerActivityChanged(Player * plr);
// checks if player is in range of a capture credit marker
bool IsInsideObjective(Player * plr) const;
virtual bool HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go);
virtual int32 HandleOpenGo(Player *plr, uint64 guid);
// 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 HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid);
virtual bool CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso);
virtual bool HandleDropFlag(Player * plr, uint32 spellId);
virtual void DeleteSpawns();
uint32 m_capturePointGUID;
GameObject *m_capturePoint;
void AddGO(uint32 type, uint32 guid, uint32 entry = 0);
void AddCre(uint32 type, uint32 guid, uint32 entry = 0);
bool SetCapturePointData(uint32 entry, uint32 map, float x, float y, float z, float o = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0);
protected:
bool AddObject(uint32 type, uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3);
bool AddCreature(uint32 type, uint32 entry, uint32 teamval, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0);
bool DelCreature(uint32 type);
bool DelObject(uint32 type);
bool DelCapturePoint();
protected:
// active players in the area of the objective, 0 - alliance, 1 - horde
PlayerSet 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;
// map to store the various gameobjects and creatures spawned by the objective
// type , guid
std::map<uint32,uint64> m_Objects;
std::map<uint32,uint64> m_Creatures;
std::map<uint64,uint32> m_ObjectTypes;
std::map<uint64,uint32> m_CreatureTypes;
};
// base class for specific outdoor pvp handlers
class OutdoorPvP : public ZoneScript
{
friend class OutdoorPvPMgr;
public:
// ctor
OutdoorPvP();
// dtor
~OutdoorPvP();
// deletes all gos/creatures spawned by the pvp
void DeleteSpawns();
typedef std::map<uint32/*lowguid*/, OPvPCapturePoint*> OPvPCapturePointMap;
virtual void FillInitialWorldStates(WorldPacket & /*data*/) {}
// called when a player triggers an areatrigger
virtual bool HandleAreaTrigger(Player * plr, uint32 trigger);
// called on custom spell
virtual bool HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go);
// called on go use
virtual bool HandleOpenGo(Player *plr, uint64 guid);
// setup stuff
virtual bool SetupOutdoorPvP() {return true;}
void OnGameObjectCreate(GameObject *go, bool add);
void OnCreatureCreate(Creature *, bool /*add*/) {}
// send world state update to all players present
void SendUpdateWorldState(uint32 field, uint32 value);
// called by OutdoorPvPMgr, updates the objectives and if needed, sends new worldstateui information
virtual bool 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 * plr) const;
// awards rewards for player kill
virtual void AwardKillBonus(Player * /*plr*/) {}
uint32 GetTypeId() {return m_TypeId;}
virtual bool HandleDropFlag(Player * plr, uint32 spellId);
virtual bool HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid);
virtual bool CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso);
void TeamApplyBuff(TeamId team, uint32 spellId, uint32 spellId2 = 0);
protected:
// the map of the objectives belonging to this outdoorpvp
OPvPCapturePointMap m_capturePoints;
PlayerSet m_players[2];
uint32 m_TypeId;
bool m_sendUpdate;
// world state stuff
virtual void SendRemoveWorldStates(Player * /*plr*/) {}
void BroadcastPacket(WorldPacket & data) const;
virtual void HandlePlayerEnterZone(Player * plr, uint32 zone);
virtual void HandlePlayerLeaveZone(Player * plr, uint32 zone);
virtual void HandlePlayerResurrects(Player * plr, uint32 zone);
void AddCapturePoint(OPvPCapturePoint* cp)
{
m_capturePoints[cp->m_capturePointGUID] = cp;
}
OPvPCapturePoint * GetCapturePoint(uint32 lowguid) const
{
OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.find(lowguid);
if (itr != m_capturePoints.end())
return itr->second;
return NULL;
}
void RegisterZone(uint32 zoneid);
bool HasPlayer(Player *plr) const;
void TeamCastSpell(TeamId team, int32 spellId);
};
#endif /*OUTDOOR_PVP_H_*/
+765
View File
@@ -0,0 +1,765 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPEP.h"
#include "WorldPacket.h"
#include "Player.h"
#include "GameObject.h"
#include "ObjectMgr.h"
#include "ObjectAccessor.h"
#include "OutdoorPvPMgr.h"
#include "Creature.h"
#include "Language.h"
#include "World.h"
#include "GossipDef.h"
OPvPCapturePointEP_EWT::OPvPCapturePointEP_EWT(OutdoorPvP *pvp)
: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_UnitsSummonedSide(0)
{
SetCapturePointData(EPCapturePoints[EP_EWT].entry,EPCapturePoints[EP_EWT].map,EPCapturePoints[EP_EWT].x,EPCapturePoints[EP_EWT].y,EPCapturePoints[EP_EWT].z,EPCapturePoints[EP_EWT].o,EPCapturePoints[EP_EWT].rot0,EPCapturePoints[EP_EWT].rot1,EPCapturePoints[EP_EWT].rot2,EPCapturePoints[EP_EWT].rot3);
AddObject(EP_EWT_FLAGS,EPTowerFlags[EP_EWT].entry,EPTowerFlags[EP_EWT].map,EPTowerFlags[EP_EWT].x,EPTowerFlags[EP_EWT].y,EPTowerFlags[EP_EWT].z,EPTowerFlags[EP_EWT].o,EPTowerFlags[EP_EWT].rot0,EPTowerFlags[EP_EWT].rot1,EPTowerFlags[EP_EWT].rot2,EPTowerFlags[EP_EWT].rot3);
}
void OPvPCapturePointEP_EWT::ChangeState()
{
if (fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out!
{
// if changing from controlling alliance to horde or vice versa
if (m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_EWT_A));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = 0;
}
else if (m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_EWT_H));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = 0;
}
uint32 artkit = 21;
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
if (m_value == m_maxValue)
m_TowerState = EP_TS_A;
else
m_TowerState = EP_TS_A_P;
artkit = 2;
SummonSupportUnitAtNorthpassTower(ALLIANCE);
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = ALLIANCE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_A));
break;
case OBJECTIVESTATE_HORDE:
if (m_value == -m_maxValue)
m_TowerState = EP_TS_H;
else
m_TowerState = EP_TS_H_P;
artkit = 1;
SummonSupportUnitAtNorthpassTower(HORDE);
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_EWT] = HORDE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_EWT_H));
break;
case OBJECTIVESTATE_NEUTRAL:
m_TowerState = EP_TS_N;
break;
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
m_TowerState = EP_TS_N_A;
break;
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
m_TowerState = EP_TS_N_H;
break;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_EWT_FLAGS]);
if (flag)
{
flag->SetGoArtKit(artkit);
}
if (flag2)
{
flag2->SetGoArtKit(artkit);
}
UpdateTowerState();
// complete quest objective
if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
SendObjectiveComplete(EP_EWT_CM, 0);
}
}
void OPvPCapturePointEP_EWT::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
// send this too, sometimes it resets :S
SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
}
void OPvPCapturePointEP_EWT::FillInitialWorldStates(WorldPacket &data)
{
data << EP_EWT_A << uint32(bool(m_TowerState & EP_TS_A));
data << EP_EWT_H << uint32(bool(m_TowerState & EP_TS_H));
data << EP_EWT_A_P << uint32(bool(m_TowerState & EP_TS_A_P));
data << EP_EWT_H_P << uint32(bool(m_TowerState & EP_TS_H_P));
data << EP_EWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
data << EP_EWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
data << EP_EWT_N << uint32(bool(m_TowerState & EP_TS_N));
}
void OPvPCapturePointEP_EWT::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(EP_EWT_A , bool(m_TowerState & EP_TS_A));
m_PvP->SendUpdateWorldState(EP_EWT_H , bool(m_TowerState & EP_TS_H));
m_PvP->SendUpdateWorldState(EP_EWT_A_P , bool(m_TowerState & EP_TS_A_P));
m_PvP->SendUpdateWorldState(EP_EWT_H_P , bool(m_TowerState & EP_TS_H_P));
m_PvP->SendUpdateWorldState(EP_EWT_N_A , bool(m_TowerState & EP_TS_N_A));
m_PvP->SendUpdateWorldState(EP_EWT_N_H , bool(m_TowerState & EP_TS_N_H));
m_PvP->SendUpdateWorldState(EP_EWT_N , bool(m_TowerState & EP_TS_N));
}
bool OPvPCapturePointEP_EWT::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointEP_EWT::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
void OPvPCapturePointEP_EWT::SummonSupportUnitAtNorthpassTower(uint32 team)
{
if (m_UnitsSummonedSide != team)
{
m_UnitsSummonedSide = team;
const creature_type * ct = NULL;
if (team == ALLIANCE)
ct=EP_EWT_Summons_A;
else
ct=EP_EWT_Summons_H;
for (int i = 0; i < EP_EWT_NUM_CREATURES; ++i)
{
DelCreature(i);
AddCreature(i,ct[i].entry,ct[i].teamval,ct[i].map,ct[i].x,ct[i].y,ct[i].z,ct[i].o,1000000);
}
}
}
// NPT
OPvPCapturePointEP_NPT::OPvPCapturePointEP_NPT(OutdoorPvP *pvp)
: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_SummonedGOSide(0)
{
SetCapturePointData(EPCapturePoints[EP_NPT].entry,EPCapturePoints[EP_NPT].map,EPCapturePoints[EP_NPT].x,EPCapturePoints[EP_NPT].y,EPCapturePoints[EP_NPT].z,EPCapturePoints[EP_NPT].o,EPCapturePoints[EP_NPT].rot0,EPCapturePoints[EP_NPT].rot1,EPCapturePoints[EP_NPT].rot2,EPCapturePoints[EP_NPT].rot3);
AddObject(EP_NPT_FLAGS,EPTowerFlags[EP_NPT].entry,EPTowerFlags[EP_NPT].map,EPTowerFlags[EP_NPT].x,EPTowerFlags[EP_NPT].y,EPTowerFlags[EP_NPT].z,EPTowerFlags[EP_NPT].o,EPTowerFlags[EP_NPT].rot0,EPTowerFlags[EP_NPT].rot1,EPTowerFlags[EP_NPT].rot2,EPTowerFlags[EP_NPT].rot3);
}
void OPvPCapturePointEP_NPT::ChangeState()
{
if (fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out!
{
// if changing from controlling alliance to horde or vice versa
if (m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_NPT_A));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = 0;
}
else if (m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_NPT_H));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = 0;
}
uint32 artkit = 21;
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
if (m_value == m_maxValue)
m_TowerState = EP_TS_A;
else
m_TowerState = EP_TS_A_P;
artkit = 2;
SummonGO(ALLIANCE);
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = ALLIANCE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_A));
break;
case OBJECTIVESTATE_HORDE:
if (m_value == -m_maxValue)
m_TowerState = EP_TS_H;
else
m_TowerState = EP_TS_H_P;
artkit = 1;
SummonGO(HORDE);
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_NPT] = HORDE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_NPT_H));
break;
case OBJECTIVESTATE_NEUTRAL:
m_TowerState = EP_TS_N;
m_SummonedGOSide = 0;
DelObject(EP_NPT_BUFF);
break;
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
m_TowerState = EP_TS_N_A;
break;
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
m_TowerState = EP_TS_N_H;
break;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_FLAGS]);
if (flag)
{
flag->SetGoArtKit(artkit);
}
if (flag2)
{
flag2->SetGoArtKit(artkit);
}
UpdateTowerState();
// complete quest objective
if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
SendObjectiveComplete(EP_NPT_CM, 0);
}
}
void OPvPCapturePointEP_NPT::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
// send this too, sometimes it resets :S
SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
}
void OPvPCapturePointEP_NPT::FillInitialWorldStates(WorldPacket &data)
{
data << EP_NPT_A << uint32(bool(m_TowerState & EP_TS_A));
data << EP_NPT_H << uint32(bool(m_TowerState & EP_TS_H));
data << EP_NPT_A_P << uint32(bool(m_TowerState & EP_TS_A_P));
data << EP_NPT_H_P << uint32(bool(m_TowerState & EP_TS_H_P));
data << EP_NPT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
data << EP_NPT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
data << EP_NPT_N << uint32(bool(m_TowerState & EP_TS_N));
}
void OPvPCapturePointEP_NPT::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(EP_NPT_A , bool(m_TowerState & EP_TS_A));
m_PvP->SendUpdateWorldState(EP_NPT_H , bool(m_TowerState & EP_TS_H));
m_PvP->SendUpdateWorldState(EP_NPT_A_P , bool(m_TowerState & EP_TS_A_P));
m_PvP->SendUpdateWorldState(EP_NPT_H_P , bool(m_TowerState & EP_TS_H_P));
m_PvP->SendUpdateWorldState(EP_NPT_N_A , bool(m_TowerState & EP_TS_N_A));
m_PvP->SendUpdateWorldState(EP_NPT_N_H , bool(m_TowerState & EP_TS_N_H));
m_PvP->SendUpdateWorldState(EP_NPT_N , bool(m_TowerState & EP_TS_N));
}
bool OPvPCapturePointEP_NPT::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointEP_NPT::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
void OPvPCapturePointEP_NPT::SummonGO(uint32 team)
{
if (m_SummonedGOSide != team)
{
m_SummonedGOSide = team;
DelObject(EP_NPT_BUFF);
AddObject(EP_NPT_BUFF,EP_NPT_LordaeronShrine.entry,EP_NPT_LordaeronShrine.map,EP_NPT_LordaeronShrine.x,EP_NPT_LordaeronShrine.y,EP_NPT_LordaeronShrine.z,EP_NPT_LordaeronShrine.o,EP_NPT_LordaeronShrine.rot0,EP_NPT_LordaeronShrine.rot1,EP_NPT_LordaeronShrine.rot2,EP_NPT_LordaeronShrine.rot3);
GameObject * go = HashMapHolder<GameObject>::Find(m_Objects[EP_NPT_BUFF]);
if (go)
go->SetUInt32Value(GAMEOBJECT_FACTION,(team == ALLIANCE ? 84 : 83));
}
}
// CGT
OPvPCapturePointEP_CGT::OPvPCapturePointEP_CGT(OutdoorPvP *pvp)
: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_GraveyardSide(0)
{
SetCapturePointData(EPCapturePoints[EP_CGT].entry,EPCapturePoints[EP_CGT].map,EPCapturePoints[EP_CGT].x,EPCapturePoints[EP_CGT].y,EPCapturePoints[EP_CGT].z,EPCapturePoints[EP_CGT].o,EPCapturePoints[EP_CGT].rot0,EPCapturePoints[EP_CGT].rot1,EPCapturePoints[EP_CGT].rot2,EPCapturePoints[EP_CGT].rot3);
AddObject(EP_CGT_FLAGS,EPTowerFlags[EP_CGT].entry,EPTowerFlags[EP_CGT].map,EPTowerFlags[EP_CGT].x,EPTowerFlags[EP_CGT].y,EPTowerFlags[EP_CGT].z,EPTowerFlags[EP_CGT].o,EPTowerFlags[EP_CGT].rot0,EPTowerFlags[EP_CGT].rot1,EPTowerFlags[EP_CGT].rot2,EPTowerFlags[EP_CGT].rot3);
}
void OPvPCapturePointEP_CGT::ChangeState()
{
if (fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out!
{
// if changing from controlling alliance to horde or vice versa
if (m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_CGT_A));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = 0;
}
else if (m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_CGT_H));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = 0;
}
uint32 artkit = 21;
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
if (m_value == m_maxValue)
m_TowerState = EP_TS_A;
else
m_TowerState = EP_TS_A_P;
artkit = 2;
LinkGraveYard(ALLIANCE);
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = ALLIANCE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_A));
break;
case OBJECTIVESTATE_HORDE:
if (m_value == -m_maxValue)
m_TowerState = EP_TS_H;
else
m_TowerState = EP_TS_H_P;
artkit = 1;
LinkGraveYard(HORDE);
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_CGT] = HORDE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_CGT_H));
break;
case OBJECTIVESTATE_NEUTRAL:
m_TowerState = EP_TS_N;
break;
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
m_TowerState = EP_TS_N_A;
break;
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
m_TowerState = EP_TS_N_H;
break;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_CGT_FLAGS]);
if (flag)
{
flag->SetGoArtKit(artkit);
}
if (flag2)
{
flag2->SetGoArtKit(artkit);
}
UpdateTowerState();
// complete quest objective
if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
SendObjectiveComplete(EP_CGT_CM, 0);
}
}
void OPvPCapturePointEP_CGT::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
// send this too, sometimes it resets :S
SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
}
void OPvPCapturePointEP_CGT::FillInitialWorldStates(WorldPacket &data)
{
data << EP_CGT_A << uint32(bool(m_TowerState & EP_TS_A));
data << EP_CGT_H << uint32(bool(m_TowerState & EP_TS_H));
data << EP_CGT_A_P << uint32(bool(m_TowerState & EP_TS_A_P));
data << EP_CGT_H_P << uint32(bool(m_TowerState & EP_TS_H_P));
data << EP_CGT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
data << EP_CGT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
data << EP_CGT_N << uint32(bool(m_TowerState & EP_TS_N));
}
void OPvPCapturePointEP_CGT::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(EP_CGT_A , bool(m_TowerState & EP_TS_A));
m_PvP->SendUpdateWorldState(EP_CGT_H , bool(m_TowerState & EP_TS_H));
m_PvP->SendUpdateWorldState(EP_CGT_A_P , bool(m_TowerState & EP_TS_A_P));
m_PvP->SendUpdateWorldState(EP_CGT_H_P , bool(m_TowerState & EP_TS_H_P));
m_PvP->SendUpdateWorldState(EP_CGT_N_A , bool(m_TowerState & EP_TS_N_A));
m_PvP->SendUpdateWorldState(EP_CGT_N_H , bool(m_TowerState & EP_TS_N_H));
m_PvP->SendUpdateWorldState(EP_CGT_N , bool(m_TowerState & EP_TS_N));
}
bool OPvPCapturePointEP_CGT::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointEP_CGT::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
void OPvPCapturePointEP_CGT::LinkGraveYard(uint32 team)
{
if (m_GraveyardSide != team)
{
m_GraveyardSide = team;
objmgr.RemoveGraveYardLink(EP_GraveYardId,EP_GraveYardZone,team,false);
objmgr.AddGraveYardLink(EP_GraveYardId,EP_GraveYardZone,team,false);
}
}
// PWT
OPvPCapturePointEP_PWT::OPvPCapturePointEP_PWT(OutdoorPvP *pvp)
: OPvPCapturePoint(pvp), m_TowerState(EP_TS_N), m_FlightMasterSpawned(0)
{
SetCapturePointData(EPCapturePoints[EP_PWT].entry,EPCapturePoints[EP_PWT].map,EPCapturePoints[EP_PWT].x,EPCapturePoints[EP_PWT].y,EPCapturePoints[EP_PWT].z,EPCapturePoints[EP_PWT].o,EPCapturePoints[EP_PWT].rot0,EPCapturePoints[EP_PWT].rot1,EPCapturePoints[EP_PWT].rot2,EPCapturePoints[EP_PWT].rot3);
AddObject(EP_PWT_FLAGS,EPTowerFlags[EP_PWT].entry,EPTowerFlags[EP_PWT].map,EPTowerFlags[EP_PWT].x,EPTowerFlags[EP_PWT].y,EPTowerFlags[EP_PWT].z,EPTowerFlags[EP_PWT].o,EPTowerFlags[EP_PWT].rot0,EPTowerFlags[EP_PWT].rot1,EPTowerFlags[EP_PWT].rot2,EPTowerFlags[EP_PWT].rot3);
}
void OPvPCapturePointEP_PWT::ChangeState()
{
if (fabs(m_value) == m_maxValue) // state won't change, only phase when maxed out!
{
// if changing from controlling alliance to horde or vice versa
if (m_OldState == OBJECTIVESTATE_ALLIANCE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_PWT_A));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = 0;
}
else if (m_OldState == OBJECTIVESTATE_HORDE && m_OldState != m_State)
{
sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_LOOSE_PWT_H));
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = 0;
}
uint32 artkit = 21;
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
if (m_value == m_maxValue)
m_TowerState = EP_TS_A;
else
m_TowerState = EP_TS_A_P;
SummonFlightMaster(ALLIANCE);
artkit = 2;
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = ALLIANCE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_A));
break;
case OBJECTIVESTATE_HORDE:
if (m_value == -m_maxValue)
m_TowerState = EP_TS_H;
else
m_TowerState = EP_TS_H_P;
SummonFlightMaster(HORDE);
artkit = 1;
((OutdoorPvPEP*)m_PvP)->EP_Controls[EP_PWT] = HORDE;
if (m_OldState != m_State) sWorld.SendZoneText(EP_GraveYardZone,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_EP_CAPTURE_PWT_H));
break;
case OBJECTIVESTATE_NEUTRAL:
m_TowerState = EP_TS_N;
DelCreature(EP_PWT_FLIGHTMASTER);
m_FlightMasterSpawned = 0;
break;
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
m_TowerState = EP_TS_N_A;
break;
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
m_TowerState = EP_TS_N_H;
break;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[EP_PWT_FLAGS]);
if (flag)
{
flag->SetGoArtKit(artkit);
}
if (flag2)
{
flag2->SetGoArtKit(artkit);
}
UpdateTowerState();
// complete quest objective
if (m_TowerState == EP_TS_A || m_TowerState == EP_TS_H)
SendObjectiveComplete(EP_PWT_CM, 0);
}
}
void OPvPCapturePointEP_PWT::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
// send this too, sometimes it resets :S
SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
}
void OPvPCapturePointEP_PWT::FillInitialWorldStates(WorldPacket &data)
{
data << EP_PWT_A << uint32(bool(m_TowerState & EP_TS_A));
data << EP_PWT_H << uint32(bool(m_TowerState & EP_TS_H));
data << EP_PWT_A_P << uint32(bool(m_TowerState & EP_TS_A_P));
data << EP_PWT_H_P << uint32(bool(m_TowerState & EP_TS_H_P));
data << EP_PWT_N_A << uint32(bool(m_TowerState & EP_TS_N_A));
data << EP_PWT_N_H << uint32(bool(m_TowerState & EP_TS_N_H));
data << EP_PWT_N << uint32(bool(m_TowerState & EP_TS_N));
}
void OPvPCapturePointEP_PWT::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(EP_PWT_A , bool(m_TowerState & EP_TS_A));
m_PvP->SendUpdateWorldState(EP_PWT_H , bool(m_TowerState & EP_TS_H));
m_PvP->SendUpdateWorldState(EP_PWT_A_P , bool(m_TowerState & EP_TS_A_P));
m_PvP->SendUpdateWorldState(EP_PWT_H_P , bool(m_TowerState & EP_TS_H_P));
m_PvP->SendUpdateWorldState(EP_PWT_N_A , bool(m_TowerState & EP_TS_N_A));
m_PvP->SendUpdateWorldState(EP_PWT_N_H , bool(m_TowerState & EP_TS_N_H));
m_PvP->SendUpdateWorldState(EP_PWT_N , bool(m_TowerState & EP_TS_N));
}
bool OPvPCapturePointEP_PWT::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointEP_PWT::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
void OPvPCapturePointEP_PWT::SummonFlightMaster(uint32 team)
{
if (m_FlightMasterSpawned != team)
{
m_FlightMasterSpawned = team;
DelCreature(EP_PWT_FLIGHTMASTER);
AddCreature(EP_PWT_FLIGHTMASTER,EP_PWT_FlightMaster.entry,team,EP_PWT_FlightMaster.map,EP_PWT_FlightMaster.x,EP_PWT_FlightMaster.y,EP_PWT_FlightMaster.z,EP_PWT_FlightMaster.o);
}
}
// ep
OutdoorPvPEP::OutdoorPvPEP()
{
m_TypeId = OUTDOOR_PVP_EP;
memset(EP_Controls,0,sizeof(EP_Controls));
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
}
bool OutdoorPvPEP::SetupOutdoorPvP()
{
for (int i = 0; i < EPBuffZonesNum; ++i)
RegisterZone(EPBuffZones[i]);
AddCapturePoint(new OPvPCapturePointEP_EWT(this));
AddCapturePoint(new OPvPCapturePointEP_PWT(this));
AddCapturePoint(new OPvPCapturePointEP_CGT(this));
AddCapturePoint(new OPvPCapturePointEP_NPT(this));
return true;
}
bool OutdoorPvPEP::Update(uint32 diff)
{
if (OutdoorPvP::Update(diff))
{
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
for (int i = 0; i < EP_TOWER_NUM; ++i)
{
if (EP_Controls[i] == ALLIANCE)
++m_AllianceTowersControlled;
else if (EP_Controls[i] == HORDE)
++m_HordeTowersControlled;
SendUpdateWorldState(EP_UI_TOWER_COUNT_A,m_AllianceTowersControlled);
SendUpdateWorldState(EP_UI_TOWER_COUNT_H,m_HordeTowersControlled);
BuffTeams();
}
return true;
}
return false;
}
void OutdoorPvPEP::HandlePlayerEnterZone(Player * plr, uint32 zone)
{
// add buffs
if (plr->GetTeam() == ALLIANCE)
{
if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5)
plr->CastSpell(plr,EP_AllianceBuffs[m_AllianceTowersControlled-1],true);
}
else
{
if (m_HordeTowersControlled && m_HordeTowersControlled < 5)
plr->CastSpell(plr,EP_HordeBuffs[m_HordeTowersControlled-1],true);
}
OutdoorPvP::HandlePlayerEnterZone(plr,zone);
}
void OutdoorPvPEP::HandlePlayerLeaveZone(Player * plr, uint32 zone)
{
// remove buffs
if (plr->GetTeam() == ALLIANCE)
{
for (int i = 0; i < 4; ++i)
plr->RemoveAurasDueToSpell(EP_AllianceBuffs[i]);
}
else
{
for (int i = 0; i < 4; ++i)
plr->RemoveAurasDueToSpell(EP_HordeBuffs[i]);
}
OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
}
void OutdoorPvPEP::BuffTeams()
{
for (PlayerSet::iterator itr = m_players[0].begin(); itr != m_players[0].end(); ++itr)
{
Player * plr = *itr;
{
for (int i = 0; i < 4; ++i)
plr->RemoveAurasDueToSpell(EP_AllianceBuffs[i]);
if (m_AllianceTowersControlled && m_AllianceTowersControlled < 5)
plr->CastSpell(plr,EP_AllianceBuffs[m_AllianceTowersControlled-1],true);
}
}
for (PlayerSet::iterator itr = m_players[1].begin(); itr != m_players[1].end(); ++itr)
{
Player * plr = *itr;
{
for (int i = 0; i < 4; ++i)
plr->RemoveAurasDueToSpell(EP_HordeBuffs[i]);
if (m_HordeTowersControlled && m_HordeTowersControlled < 5)
plr->CastSpell(plr,EP_HordeBuffs[m_HordeTowersControlled-1],true);
}
}
}
void OutdoorPvPEP::FillInitialWorldStates(WorldPacket & data)
{
data << EP_UI_TOWER_COUNT_A << m_AllianceTowersControlled;
data << EP_UI_TOWER_COUNT_H << m_HordeTowersControlled;
data << EP_UI_TOWER_SLIDER_DISPLAY << uint32(0);
data << EP_UI_TOWER_SLIDER_POS << uint32(50);
data << EP_UI_TOWER_SLIDER_N << uint32(100);
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
{
itr->second->FillInitialWorldStates(data);
}
}
void OutdoorPvPEP::SendRemoveWorldStates(Player *plr)
{
plr->SendUpdateWorldState(EP_UI_TOWER_COUNT_A,0);
plr->SendUpdateWorldState(EP_UI_TOWER_COUNT_H,0);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_DISPLAY,0);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_POS,0);
plr->SendUpdateWorldState(EP_UI_TOWER_SLIDER_N,0);
plr->SendUpdateWorldState(EP_EWT_A,0);
plr->SendUpdateWorldState(EP_EWT_H,0);
plr->SendUpdateWorldState(EP_EWT_N,0);
plr->SendUpdateWorldState(EP_EWT_A_P,0);
plr->SendUpdateWorldState(EP_EWT_H_P,0);
plr->SendUpdateWorldState(EP_EWT_N_A,0);
plr->SendUpdateWorldState(EP_EWT_N_H,0);
plr->SendUpdateWorldState(EP_PWT_A,0);
plr->SendUpdateWorldState(EP_PWT_H,0);
plr->SendUpdateWorldState(EP_PWT_N,0);
plr->SendUpdateWorldState(EP_PWT_A_P,0);
plr->SendUpdateWorldState(EP_PWT_H_P,0);
plr->SendUpdateWorldState(EP_PWT_N_A,0);
plr->SendUpdateWorldState(EP_PWT_N_H,0);
plr->SendUpdateWorldState(EP_NPT_A,0);
plr->SendUpdateWorldState(EP_NPT_H,0);
plr->SendUpdateWorldState(EP_NPT_N,0);
plr->SendUpdateWorldState(EP_NPT_A_P,0);
plr->SendUpdateWorldState(EP_NPT_H_P,0);
plr->SendUpdateWorldState(EP_NPT_N_A,0);
plr->SendUpdateWorldState(EP_NPT_N_H,0);
plr->SendUpdateWorldState(EP_CGT_A,0);
plr->SendUpdateWorldState(EP_CGT_H,0);
plr->SendUpdateWorldState(EP_CGT_N,0);
plr->SendUpdateWorldState(EP_CGT_A_P,0);
plr->SendUpdateWorldState(EP_CGT_H_P,0);
plr->SendUpdateWorldState(EP_CGT_N_A,0);
plr->SendUpdateWorldState(EP_CGT_N_H,0);
}
+280
View File
@@ -0,0 +1,280 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_EP_
#define OUTDOOR_PVP_EP_
#include "OutdoorPvPImpl.h"
#include "DBCStructure.h"
const uint32 EP_AllianceBuffs[4] = {11413, 11414, 11415, 1386};
const uint32 EP_HordeBuffs[4] = {30880, 30683, 30682, 29520};
const uint32 EP_GraveYardZone = 139;
const uint32 EP_GraveYardId = 927;
const uint32 EPBuffZonesNum = 3;
const uint32 EP_EWT_CM = 17690;
const uint32 EP_CGT_CM = 17689;
const uint32 EP_NPT_CM = 17696;
const uint32 EP_PWT_CM = 17698;
const uint32 EPBuffZones[EPBuffZonesNum] = {139, 2017, 2057};
enum EP_TaxiNodes {
EP_CGT_Taxi = 87,
EP_EWT_Taxi = 86,
EP_NPT_Taxi = 85,
EP_PWT_Taxi = 84
};
enum EP_EastwallTowerWorldStates {
EP_EWT_A = 2354,
EP_EWT_H = 2356,
EP_EWT_A_P = 2357, // ally progressing
EP_EWT_H_P = 2358,
EP_EWT_N_A = 2359, // ally conquested
EP_EWT_N_H = 2360,
EP_EWT_N = 2361
};
enum EP_NorthpassTowerWorldStates {
EP_NPT_N = 2352,
EP_NPT_N_A = 2362,
EP_NPT_N_H = 2363,
EP_NPT_A_P = 2364,
EP_NPT_H_P = 2365,
EP_NPT_A = 2372,
EP_NPT_H = 2373
};
enum EP_PlagewoodTowerWorldStates {
EP_PWT_N_A = 2366,
EP_PWT_N_H = 2353, //2367 not present! use neutral!
EP_PWT_A_P = 2368,
EP_PWT_H_P = 2369,
EP_PWT_A = 2370,
EP_PWT_H = 2371,
EP_PWT_N = 2353
};
enum EP_CrownGuardTowerWorldStates {
EP_CGT_N_A = 2374,
EP_CGT_N_H = 2375,
EP_CGT_A_P = 2376,
EP_CGT_H_P = 2377,
EP_CGT_A = 2378,
EP_CGT_H = 2379,
EP_CGT_N = 2355
};
enum EP_WorldStates {
EP_UI_TOWER_SLIDER_DISPLAY = 2426,
EP_UI_TOWER_SLIDER_POS = 2427,
EP_UI_TOWER_SLIDER_N = 2428,
EP_UI_TOWER_COUNT_A = 2327,
EP_UI_TOWER_COUNT_H = 2328
};
enum EP_Summons {
EP_EWT_COMMANDER = 0,
EP_EWT_SOLDIER1,
EP_EWT_SOLDIER2,
EP_EWT_SOLDIER3,
EP_EWT_SOLDIER4,
EP_PWT_FLIGHTMASTER,
};
enum EP_GoSummons {
EP_NPT_BUFF = 0,
EP_NPT_FLAGS,
EP_EWT_FLAGS,
EP_CGT_FLAGS,
EP_PWT_FLAGS
};
enum EP_Towers {
EP_EWT = 0, // plaguelands 03
EP_NPT,// plaguelands 01
EP_PWT,// plaguelands 04
EP_CGT,// plaguelands 02
EP_TOWER_NUM
};
const go_type EPCapturePoints[EP_TOWER_NUM] = {
{182097,0,2574.51,-4794.89,144.704,-1.45003,-0.097056,0.095578,-0.656229,0.742165},
{181899,0,3181.08,-4379.36,174.123,-2.03472,-0.065392,0.119494,-0.842275,0.521553},
{182098,0,2962.71,-3042.31,154.789,2.08426,-0.074807,-0.113837,0.855928,0.49883},
{182096,0,1860.85,-3731.23,196.716,-2.53214,0.033967,-0.131914,0.944741,-0.298177}
};
const go_type EPTowerFlags[EP_TOWER_NUM] = {
{182106,0,2569.60,-4772.93,115.399,2.72271,0,0,0.978148,0.207912},
{182106,0,3148.17,-4365.51,145.029,1.53589,0,0,0.694658,0.71934},
{182106,0,2992.63,-3022.95,125.593,3.03687,0,0,0.99863,0.052336},
{182106,0,1838.42,-3703.56,167.713,0.890118,0,0,0.430511,0.902585}
};
const uint32 EPTowerPlayerEnterEvents[EP_TOWER_NUM] = {10691,10699,10701,10705};
const uint32 EPTowerPlayerLeaveEvents[EP_TOWER_NUM] = {10692,10698,10700,10704};
const uint32 EP_NUM_CREATURES = 6;
const uint32 EP_EWT_NUM_CREATURES = 5;
// one lordaeron commander, 4 soldiers
// should be spawned at EWT and follow a path, but trans-grid pathing isn't safe, so summon them directly at NPT
const creature_type EP_EWT_Summons_A[EP_EWT_NUM_CREATURES] = {
{17635,469,0, 3167.61,-4352.09,138.20,4.5811},
{17647,469,0, 3172.74,-4352.99,139.14,4.9873},
{17647,469,0, 3165.89,-4354.46,138.67,3.7244},
{17647,469,0, 3164.65,-4350.26,138.22,2.4794},
{17647,469,0, 3169.91,-4349.68,138.37,0.7444}
};
const creature_type EP_EWT_Summons_H[EP_EWT_NUM_CREATURES] = {
{17995,67,0, 3167.61,-4352.09,138.20,4.5811},
{17996,67,0, 3172.74,-4352.99,139.14,4.9873},
{17996,67,0, 3165.89,-4354.46,138.67,3.7244},
{17996,67,0, 3164.65,-4350.26,138.22,2.4794},
{17996,67,0, 3169.91,-4349.68,138.37,0.7444}
};
enum EP_TowerStates {
EP_TS_N = 1,
EP_TS_N_A = 2,
EP_TS_N_H = 4,
EP_TS_A_P = 8,
EP_TS_H_P = 16,
EP_TS_A = 32,
EP_TS_H = 64
};
// when spawning, pay attention at setting the faction manually!
const creature_type EP_PWT_FlightMaster = {17209,0,0,2987.5,-3049.11,120.126,5.75959};
// after spawning, modify the faction so that only the controller will be able to use it with SetUInt32Value(GAMEOBJECT_FACTION, faction_id);
const go_type EP_NPT_LordaeronShrine = {181682,0,3167.72,-4355.91,138.785,1.69297,0,0,0.748956,0.66262};
class OutdoorPvPEP;
class OPvPCapturePointEP_EWT : public OPvPCapturePoint
{
friend class OutdoorPvPEP;
public:
OPvPCapturePointEP_EWT(OutdoorPvP * pvp);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
protected:
void SummonSupportUnitAtNorthpassTower(uint32 team);
void UpdateTowerState();
protected:
uint32 m_TowerState;
uint32 m_UnitsSummonedSide;
};
class OPvPCapturePointEP_NPT : public OPvPCapturePoint
{
friend class OutdoorPvPEP;
public:
OPvPCapturePointEP_NPT(OutdoorPvP * pvp);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
protected:
void SummonGO(uint32 team);
void UpdateTowerState();
protected:
uint32 m_TowerState;
uint32 m_SummonedGOSide;
};
class OPvPCapturePointEP_CGT : public OPvPCapturePoint
{
friend class OutdoorPvPEP;
public:
OPvPCapturePointEP_CGT(OutdoorPvP * pvp);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
protected:
void LinkGraveYard(uint32 team);
void UpdateTowerState();
protected:
uint32 m_TowerState;
uint32 m_GraveyardSide;
};
class OPvPCapturePointEP_PWT : public OPvPCapturePoint
{
friend class OutdoorPvPEP;
public:
OPvPCapturePointEP_PWT(OutdoorPvP * pvp);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
protected:
void SummonFlightMaster(uint32 team);
void UpdateTowerState();
protected:
uint32 m_FlightMasterSpawned;
uint32 m_TowerState;
};
class OutdoorPvPEP : public OutdoorPvP
{
friend class OPvPCapturePointEP_EWT;
friend class OPvPCapturePointEP_NPT;
friend class OPvPCapturePointEP_PWT;
friend class OPvPCapturePointEP_CGT;
public:
OutdoorPvPEP();
bool SetupOutdoorPvP();
void HandlePlayerEnterZone(Player *plr, uint32 zone);
void HandlePlayerLeaveZone(Player *plr, uint32 zone);
bool Update(uint32 diff);
void FillInitialWorldStates(WorldPacket &data);
void SendRemoveWorldStates(Player * plr);
void BuffTeams();
private:
// how many towers are controlled
uint32 EP_Controls[EP_TOWER_NUM];
uint32 m_AllianceTowersControlled;
uint32 m_HordeTowersControlled;
};
#endif
+332
View File
@@ -0,0 +1,332 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPHP.h"
#include "OutdoorPvP.h"
#include "OutdoorPvPMgr.h"
#include "Player.h"
#include "WorldPacket.h"
#include "World.h"
#include "ObjectMgr.h"
#include "Language.h"
const uint32 HP_LANG_LOOSE_A[HP_TOWER_NUM] = {LANG_OPVP_HP_LOOSE_BROKENHILL_A,LANG_OPVP_HP_LOOSE_OVERLOOK_A,LANG_OPVP_HP_LOOSE_STADIUM_A};
const uint32 HP_LANG_LOOSE_H[HP_TOWER_NUM] = {LANG_OPVP_HP_LOOSE_BROKENHILL_H,LANG_OPVP_HP_LOOSE_OVERLOOK_H,LANG_OPVP_HP_LOOSE_STADIUM_H};
const uint32 HP_LANG_CAPTURE_A[HP_TOWER_NUM] = {LANG_OPVP_HP_CAPTURE_BROKENHILL_A,LANG_OPVP_HP_CAPTURE_OVERLOOK_A,LANG_OPVP_HP_CAPTURE_STADIUM_A};
const uint32 HP_LANG_CAPTURE_H[HP_TOWER_NUM] = {LANG_OPVP_HP_CAPTURE_BROKENHILL_H,LANG_OPVP_HP_CAPTURE_OVERLOOK_H,LANG_OPVP_HP_CAPTURE_STADIUM_H};
OPvPCapturePointHP::OPvPCapturePointHP(OutdoorPvP *pvp,OutdoorPvPHPTowerType type)
: OPvPCapturePoint(pvp), m_TowerType(type)
{
SetCapturePointData(HPCapturePoints[type].entry,
HPCapturePoints[type].map,
HPCapturePoints[type].x,
HPCapturePoints[type].y,
HPCapturePoints[type].z,
HPCapturePoints[type].o,
HPCapturePoints[type].rot0,
HPCapturePoints[type].rot1,
HPCapturePoints[type].rot2,
HPCapturePoints[type].rot3);
AddObject(type,
HPTowerFlags[type].entry,
HPTowerFlags[type].map,
HPTowerFlags[type].x,
HPTowerFlags[type].y,
HPTowerFlags[type].z,
HPTowerFlags[type].o,
HPTowerFlags[type].rot0,
HPTowerFlags[type].rot1,
HPTowerFlags[type].rot2,
HPTowerFlags[type].rot3);
}
OutdoorPvPHP::OutdoorPvPHP()
{
m_TypeId = OUTDOOR_PVP_HP;
}
bool OutdoorPvPHP::SetupOutdoorPvP()
{
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
// add the zones affected by the pvp buff
for (int i = 0; i < OutdoorPvPHPBuffZonesNum; ++i)
RegisterZone(OutdoorPvPHPBuffZones[i]);
AddCapturePoint(new OPvPCapturePointHP(this,HP_TOWER_BROKEN_HILL));
AddCapturePoint(new OPvPCapturePointHP(this,HP_TOWER_OVERLOOK));
AddCapturePoint(new OPvPCapturePointHP(this,HP_TOWER_STADIUM));
return true;
}
void OutdoorPvPHP::HandlePlayerEnterZone(Player * plr, uint32 zone)
{
// add buffs
if (plr->GetTeam() == ALLIANCE)
{
if (m_AllianceTowersControlled >=3)
plr->CastSpell(plr,AllianceBuff,true);
}
else
{
if (m_HordeTowersControlled >=3)
plr->CastSpell(plr,HordeBuff,true);
}
OutdoorPvP::HandlePlayerEnterZone(plr,zone);
}
void OutdoorPvPHP::HandlePlayerLeaveZone(Player * plr, uint32 zone)
{
// remove buffs
if (plr->GetTeam() == ALLIANCE)
{
plr->RemoveAurasDueToSpell(AllianceBuff);
}
else
{
plr->RemoveAurasDueToSpell(HordeBuff);
}
OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
}
bool OutdoorPvPHP::Update(uint32 diff)
{
bool changed = OutdoorPvP::Update(diff);
if (changed)
{
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);
}
SendUpdateWorldState(HP_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
SendUpdateWorldState(HP_UI_TOWER_COUNT_H, m_HordeTowersControlled);
}
return changed;
}
void OutdoorPvPHP::SendRemoveWorldStates(Player *plr)
{
plr->SendUpdateWorldState(HP_UI_TOWER_DISPLAY_A,0);
plr->SendUpdateWorldState(HP_UI_TOWER_DISPLAY_H,0);
plr->SendUpdateWorldState(HP_UI_TOWER_COUNT_H,0);
plr->SendUpdateWorldState(HP_UI_TOWER_COUNT_A,0);
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_N,0);
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_POS,0);
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY,0);
for (int i = 0; i < HP_TOWER_NUM; ++i)
{
plr->SendUpdateWorldState(HP_MAP_N[i],0);
plr->SendUpdateWorldState(HP_MAP_A[i],0);
plr->SendUpdateWorldState(HP_MAP_H[i],0);
}
}
void OutdoorPvPHP::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(HP_UI_TOWER_DISPLAY_A) << uint32(1);
data << uint32(HP_UI_TOWER_DISPLAY_H) << uint32(1);
data << uint32(HP_UI_TOWER_COUNT_A) << uint32(m_AllianceTowersControlled);
data << uint32(HP_UI_TOWER_COUNT_H) << uint32(m_HordeTowersControlled);
data << uint32(HP_UI_TOWER_SLIDER_DISPLAY) << uint32(0);
data << uint32(HP_UI_TOWER_SLIDER_POS) << uint32(50);
data << uint32(HP_UI_TOWER_SLIDER_N) << uint32(100);
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
{
itr->second->FillInitialWorldStates(data);
}
}
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 (((OutdoorPvPHP*)m_PvP)->m_AllianceTowersControlled)
((OutdoorPvPHP*)m_PvP)->m_AllianceTowersControlled--;
sWorld.SendZoneText(OutdoorPvPHPBuffZones[0],objmgr.GetTrinityStringForDBCLocale(HP_LANG_LOOSE_A[m_TowerType]));
break;
case OBJECTIVESTATE_HORDE:
field = HP_MAP_H[m_TowerType];
if (((OutdoorPvPHP*)m_PvP)->m_HordeTowersControlled)
((OutdoorPvPHP*)m_PvP)->m_HordeTowersControlled--;
sWorld.SendZoneText(OutdoorPvPHPBuffZones[0],objmgr.GetTrinityStringForDBCLocale(HP_LANG_LOOSE_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];
break;
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
field = HP_MAP_H[m_TowerType];
break;
}
// send world state update
if (field)
{
m_PvP->SendUpdateWorldState(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];
if (((OutdoorPvPHP*)m_PvP)->m_AllianceTowersControlled<3)
((OutdoorPvPHP*)m_PvP)->m_AllianceTowersControlled++;
sWorld.SendZoneText(OutdoorPvPHPBuffZones[0],objmgr.GetTrinityStringForDBCLocale(HP_LANG_CAPTURE_A[m_TowerType]));
break;
case OBJECTIVESTATE_HORDE:
field = HP_MAP_H[m_TowerType];
artkit = 1;
artkit2 = HP_TowerArtKit_H[m_TowerType];
if (((OutdoorPvPHP*)m_PvP)->m_HordeTowersControlled<3)
((OutdoorPvPHP*)m_PvP)->m_HordeTowersControlled++;
sWorld.SendZoneText(OutdoorPvPHPBuffZones[0],objmgr.GetTrinityStringForDBCLocale(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;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
GameObject* flag2 = HashMapHolder<GameObject>::Find(m_Objects[m_TowerType]);
if (flag)
{
flag->SetGoArtKit(artkit);
}
if (flag2)
{
flag2->SetGoArtKit(artkit2);
}
// send world state update
if (field)
m_PvP->SendUpdateWorldState(field, 1);
// complete quest objective
if (m_State == OBJECTIVESTATE_ALLIANCE || m_State == OBJECTIVESTATE_HORDE)
SendObjectiveComplete(HP_CREDITMARKER[m_TowerType], 0);
}
void OPvPCapturePointHP::SendChangePhase()
{
SendUpdateWorldState(HP_UI_TOWER_SLIDER_N, m_neutralValuePct);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(HP_UI_TOWER_SLIDER_POS, phase);
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 1);
}
void OPvPCapturePointHP::FillInitialWorldStates(WorldPacket &data)
{
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
data << uint32(HP_MAP_N[m_TowerType]) << uint32(0);
data << uint32(HP_MAP_A[m_TowerType]) << uint32(1);
data << uint32(HP_MAP_H[m_TowerType]) << uint32(0);
break;
case OBJECTIVESTATE_HORDE:
case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
data << uint32(HP_MAP_N[m_TowerType]) << uint32(0);
data << uint32(HP_MAP_A[m_TowerType]) << uint32(0);
data << uint32(HP_MAP_H[m_TowerType]) << uint32(1);
break;
case OBJECTIVESTATE_NEUTRAL:
case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
default:
data << uint32(HP_MAP_N[m_TowerType]) << uint32(1);
data << uint32(HP_MAP_A[m_TowerType]) << uint32(0);
data << uint32(HP_MAP_H[m_TowerType]) << uint32(0);
break;
}
}
bool OPvPCapturePointHP::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointHP::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(HP_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
void OutdoorPvPHP::HandleKillImpl(Player *plr, Unit * killed)
{
if (killed->GetTypeId() != TYPEID_PLAYER)
return;
if (plr->GetTeam() == ALLIANCE && killed->ToPlayer()->GetTeam() != ALLIANCE)
plr->CastSpell(plr,AlliancePlayerKillReward,true);
else if (plr->GetTeam() == HORDE && killed->ToPlayer()->GetTeam() != HORDE)
plr->CastSpell(plr,HordePlayerKillReward,true);
}
+118
View File
@@ -0,0 +1,118 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_HP_
#define OUTDOOR_PVP_HP_
#include "OutdoorPvPImpl.h"
#define OutdoorPvPHPBuffZonesNum 6
// HP, citadel, ramparts, blood furnace, shattered halls, mag's lair
const uint32 OutdoorPvPHPBuffZones[OutdoorPvPHPBuffZonesNum] = { 3483, 3563, 3562, 3713, 3714, 3836 };
enum OutdoorPvPHPSpells
{
AlliancePlayerKillReward = 32155,
HordePlayerKillReward = 32158,
AllianceBuff = 32071,
HordeBuff = 32049
};
enum OutdoorPvPHPTowerType{
HP_TOWER_BROKEN_HILL = 0,
HP_TOWER_OVERLOOK = 1,
HP_TOWER_STADIUM = 2,
HP_TOWER_NUM = 3
};
const uint32 HP_CREDITMARKER[HP_TOWER_NUM] = {19032,19028,19029};
const uint32 HP_CapturePointEvent_Enter[HP_TOWER_NUM] = {11404,11396,11388};
const uint32 HP_CapturePointEvent_Leave[HP_TOWER_NUM] = {11403,11395,11387};
enum OutdoorPvPHPWorldStates{
HP_UI_TOWER_DISPLAY_A = 0x9ba,
HP_UI_TOWER_DISPLAY_H = 0x9b9,
HP_UI_TOWER_COUNT_H = 0x9ae,
HP_UI_TOWER_COUNT_A = 0x9ac,
HP_UI_TOWER_SLIDER_N = 2475,
HP_UI_TOWER_SLIDER_POS = 2474,
HP_UI_TOWER_SLIDER_DISPLAY = 2473
};
const uint32 HP_MAP_N[HP_TOWER_NUM] = {0x9b5,0x9b2,0x9a8};
const uint32 HP_MAP_A[HP_TOWER_NUM] = {0x9b3,0x9b0,0x9a7};
const uint32 HP_MAP_H[HP_TOWER_NUM] = {0x9b4,0x9b1,0x9a6};
const uint32 HP_TowerArtKit_A[HP_TOWER_NUM] = {65,62,67};
const uint32 HP_TowerArtKit_H[HP_TOWER_NUM] = {64,61,68};
const uint32 HP_TowerArtKit_N[HP_TOWER_NUM] = {66,63,69};
const go_type HPCapturePoints[HP_TOWER_NUM] = {
{182175,530,-471.462,3451.09,34.6432,0.174533,0,0,0.087156,0.996195}, // 0 - Broken Hill
{182174,530,-184.889,3476.93,38.205,-0.017453,0,0,0.008727,-0.999962}, // 1 - Overlook
{182173,530,-290.016,3702.42,56.6729,0.034907,0,0,0.017452,0.999848} // 2 - Stadium
};
const go_type HPTowerFlags[HP_TOWER_NUM] = {
{183514,530,-467.078,3528.17,64.7121,3.14159,0,0,1,0}, // 0 broken hill
{182525,530,-187.887,3459.38,60.0403,-3.12414,0,0,0.999962,-0.008727}, // 1 overlook
{183515,530,-289.610,3696.83,75.9447,3.12414,0,0,0.999962,0.008727} // 2 stadium
};
class OPvPCapturePointHP : public OPvPCapturePoint
{
public:
OPvPCapturePointHP(OutdoorPvP * pvp, OutdoorPvPHPTowerType type);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
private:
OutdoorPvPHPTowerType m_TowerType;
};
class OutdoorPvPHP : public OutdoorPvP
{
friend class OPvPCapturePointHP;
public:
OutdoorPvPHP();
bool SetupOutdoorPvP();
void HandlePlayerEnterZone(Player *plr, uint32 zone);
void HandlePlayerLeaveZone(Player *plr, uint32 zone);
bool Update(uint32 diff);
void FillInitialWorldStates(WorldPacket &data);
void SendRemoveWorldStates(Player * plr);
void HandleKillImpl(Player * plr, Unit * killed);
private:
// how many towers are controlled
uint32 m_AllianceTowersControlled;
uint32 m_HordeTowersControlled;
};
#endif
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOORPVP_IMPL_H
#define OUTDOORPVP_IMPL_H
#include "SharedDefines.h"
#include "OutdoorPvP.h"
#include "Player.h"
#include "WorldPacket.h"
#define OTHER_TEAM(a) (a == TEAM_ALLIANCE ? TEAM_HORDE : TEAM_ALLIANCE)
#endif
@@ -0,0 +1,249 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPMgr.h"
#include "OutdoorPvPHP.h"
#include "OutdoorPvPNA.h"
#include "OutdoorPvPTF.h"
#include "OutdoorPvPZM.h"
#include "OutdoorPvPSI.h"
#include "OutdoorPvPEP.h"
#include "ObjectMgr.h"
#include "Player.h"
#include "Policies/SingletonImp.h"
INSTANTIATE_SINGLETON_1(OutdoorPvPMgr);
OutdoorPvPMgr::OutdoorPvPMgr()
{
m_UpdateTimer = 0;
//sLog.outDebug("Instantiating OutdoorPvPMgr");
}
OutdoorPvPMgr::~OutdoorPvPMgr()
{
//sLog.outDebug("Deleting OutdoorPvPMgr");
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
{
(*itr)->DeleteSpawns();
delete *itr;
}
}
void OutdoorPvPMgr::InitOutdoorPvP()
{
// create new opvp
OutdoorPvP * pOP = new OutdoorPvPHP;
// respawn, init variables
if (!pOP->SetupOutdoorPvP())
{
sLog.outDebug("OutdoorPvP : HP init failed.");
delete pOP;
}
else
{
m_OutdoorPvPSet.push_back(pOP);
sLog.outDebug("OutdoorPvP : HP successfully initiated.");
}
pOP = new OutdoorPvPNA;
// respawn, init variables
if (!pOP->SetupOutdoorPvP())
{
sLog.outDebug("OutdoorPvP : NA init failed.");
delete pOP;
}
else
{
m_OutdoorPvPSet.push_back(pOP);
sLog.outDebug("OutdoorPvP : NA successfully initiated.");
}
pOP = new OutdoorPvPTF;
// respawn, init variables
if (!pOP->SetupOutdoorPvP())
{
sLog.outDebug("OutdoorPvP : TF init failed.");
delete pOP;
}
else
{
m_OutdoorPvPSet.push_back(pOP);
sLog.outDebug("OutdoorPvP : TF successfully initiated.");
}
pOP = new OutdoorPvPZM;
// respawn, init variables
if (!pOP->SetupOutdoorPvP())
{
sLog.outDebug("OutdoorPvP : ZM init failed.");
delete pOP;
}
else
{
m_OutdoorPvPSet.push_back(pOP);
sLog.outDebug("OutdoorPvP : ZM successfully initiated.");
}
pOP = new OutdoorPvPSI;
// respawn, init variables
if (!pOP->SetupOutdoorPvP())
{
sLog.outDebug("OutdoorPvP : SI init failed.");
delete pOP;
}
else
{
m_OutdoorPvPSet.push_back(pOP);
sLog.outDebug("OutdoorPvP : SI successfully initiated.");
}
pOP = new OutdoorPvPEP;
// respawn, init variables
if (!pOP->SetupOutdoorPvP())
{
sLog.outDebug("OutdoorPvP : EP init failed.");
delete pOP;
}
else
{
m_OutdoorPvPSet.push_back(pOP);
sLog.outDebug("OutdoorPvP : EP successfully initiated.");
}
}
void OutdoorPvPMgr::AddZone(uint32 zoneid, OutdoorPvP *handle)
{
m_OutdoorPvPMap[zoneid] = handle;
}
void OutdoorPvPMgr::HandlePlayerEnterZone(Player *plr, uint32 zoneid)
{
OutdoorPvPMap::iterator itr = m_OutdoorPvPMap.find(zoneid);
if (itr == m_OutdoorPvPMap.end())
return;
if (itr->second->HasPlayer(plr))
return;
itr->second->HandlePlayerEnterZone(plr, zoneid);
sLog.outDebug("Player %u entered outdoorpvp id %u", plr->GetGUIDLow(), itr->second->GetTypeId());
}
void OutdoorPvPMgr::HandlePlayerLeaveZone(Player *plr, uint32 zoneid)
{
OutdoorPvPMap::iterator itr = m_OutdoorPvPMap.find(zoneid);
if (itr == m_OutdoorPvPMap.end())
return;
// teleport: remove once in removefromworld, once in updatezone
if (!itr->second->HasPlayer(plr))
return;
itr->second->HandlePlayerLeaveZone(plr, zoneid);
sLog.outDebug("Player %u left outdoorpvp id %u",plr->GetGUIDLow(), itr->second->GetTypeId());
}
OutdoorPvP * OutdoorPvPMgr::GetOutdoorPvPToZoneId(uint32 zoneid)
{
OutdoorPvPMap::iterator itr = m_OutdoorPvPMap.find(zoneid);
if (itr == m_OutdoorPvPMap.end())
{
// no handle for this zone, return
return NULL;
}
return itr->second;
}
void OutdoorPvPMgr::Update(uint32 diff)
{
m_UpdateTimer += diff;
if (m_UpdateTimer > OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL)
{
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
(*itr)->Update(m_UpdateTimer);
m_UpdateTimer = 0;
}
}
bool OutdoorPvPMgr::HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go)
{
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
{
if ((*itr)->HandleCustomSpell(plr,spellId,go))
return true;
}
return false;
}
ZoneScript * OutdoorPvPMgr::GetZoneScript(uint32 zoneId)
{
OutdoorPvPMap::iterator itr = m_OutdoorPvPMap.find(zoneId);
if (itr != m_OutdoorPvPMap.end())
return itr->second;
else
return NULL;
}
bool OutdoorPvPMgr::HandleOpenGo(Player *plr, uint64 guid)
{
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
{
if ((*itr)->HandleOpenGo(plr,guid))
return true;
}
return false;
}
void OutdoorPvPMgr::HandleGossipOption(Player *plr, uint64 guid, uint32 gossipid)
{
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
{
if ((*itr)->HandleGossipOption(plr,guid,gossipid))
return;
}
}
bool OutdoorPvPMgr::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
{
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
{
if ((*itr)->CanTalkTo(plr,c,gso))
return true;
}
return false;
}
void OutdoorPvPMgr::HandleDropFlag(Player *plr, uint32 spellId)
{
for (OutdoorPvPSet::iterator itr = m_OutdoorPvPSet.begin(); itr != m_OutdoorPvPSet.end(); ++itr)
{
if ((*itr)->HandleDropFlag(plr,spellId))
return;
}
}
void OutdoorPvPMgr::HandlePlayerResurrects(Player *plr, uint32 zoneid)
{
OutdoorPvPMap::iterator itr = m_OutdoorPvPMap.find(zoneid);
if (itr == m_OutdoorPvPMap.end())
return;
if (itr->second->HasPlayer(plr))
itr->second->HandlePlayerResurrects(plr, zoneid);
}
@@ -0,0 +1,85 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_MGR_H_
#define OUTDOOR_PVP_MGR_H_
#define OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL 1000
#include "OutdoorPvP.h"
#include "Policies/Singleton.h"
class Player;
class GameObject;
class Creature;
class ZoneScript;
struct GossipMenuItems;
// class to handle player enter / leave / areatrigger / GO use events
class OutdoorPvPMgr
{
public:
// ctor
OutdoorPvPMgr();
// dtor
~OutdoorPvPMgr();
// create outdoor pvp events
void InitOutdoorPvP();
// called when a player enters an outdoor pvp area
void HandlePlayerEnterZone(Player * plr, uint32 areaflag);
// called when player leaves an outdoor pvp area
void HandlePlayerLeaveZone(Player * plr, uint32 areaflag);
// called when player resurrects
void HandlePlayerResurrects(Player * plr, uint32 areaflag);
// return assigned outdoor pvp
OutdoorPvP * GetOutdoorPvPToZoneId(uint32 zoneid);
// handle custom (non-exist in dbc) spell if registered
bool HandleCustomSpell(Player * plr, uint32 spellId, GameObject* go);
// handle custom go if registered
bool HandleOpenGo(Player * plr, uint64 guid);
ZoneScript * GetZoneScript(uint32 zoneId);
void AddZone(uint32 zoneid, OutdoorPvP * handle);
void Update(uint32 diff);
void HandleGossipOption(Player * player, uint64 guid, uint32 gossipid);
bool CanTalkTo(Player * player, Creature * creature, GossipMenuItems gso);
void HandleDropFlag(Player * plr, uint32 spellId);
typedef std::vector<OutdoorPvP*> OutdoorPvPSet;
typedef std::map<uint32 /* zoneid */, OutdoorPvP*> OutdoorPvPMap;
private:
// contains all initiated outdoor pvp events
// used when initing / cleaning up
OutdoorPvPSet m_OutdoorPvPSet;
// maps the zone ids to an outdoor pvp event
// used in player event handling
OutdoorPvPMap m_OutdoorPvPMap;
// update interval
uint32 m_UpdateTimer;
};
#define sOutdoorPvPMgr Trinity::Singleton<OutdoorPvPMgr>::Instance()
#endif /*OUTDOOR_PVP_MGR_H_*/
+664
View File
@@ -0,0 +1,664 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPNA.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "OutdoorPvPMgr.h"
#include "WorldPacket.h"
#include "Language.h"
#include "World.h"
OutdoorPvPNA::OutdoorPvPNA()
{
m_TypeId = OUTDOOR_PVP_NA;
}
void OutdoorPvPNA::HandleKillImpl(Player *plr, Unit * killed)
{
if (killed->GetTypeId() == TYPEID_PLAYER && plr->GetTeam() != killed->ToPlayer()->GetTeam())
{
plr->KilledMonsterCredit(NA_CREDIT_MARKER,0); // 0 guid, btw it isn't even used in killedmonster function :S
if (plr->GetTeam() == ALLIANCE)
plr->CastSpell(plr,NA_KILL_TOKEN_ALLIANCE,true);
else
plr->CastSpell(plr,NA_KILL_TOKEN_HORDE,true);
}
}
uint32 OPvPCapturePointNA::GetAliveGuardsCount()
{
uint32 cnt = 0;
for (std::map<uint32, uint64>::iterator itr = m_Creatures.begin(); itr != m_Creatures.end(); ++itr)
{
switch(itr->first)
{
case NA_NPC_GUARD_01:
case NA_NPC_GUARD_02:
case NA_NPC_GUARD_03:
case NA_NPC_GUARD_04:
case NA_NPC_GUARD_05:
case NA_NPC_GUARD_06:
case NA_NPC_GUARD_07:
case NA_NPC_GUARD_08:
case NA_NPC_GUARD_09:
case NA_NPC_GUARD_10:
case NA_NPC_GUARD_11:
case NA_NPC_GUARD_12:
case NA_NPC_GUARD_13:
case NA_NPC_GUARD_14:
case NA_NPC_GUARD_15:
{
if (Creature * cr = HashMapHolder<Creature>::Find(itr->second))
{
if (cr->isAlive())
++cnt;
}
else if (CreatureData const * cd = objmgr.GetCreatureData(GUID_LOPART(itr->second)))
{
if (!cd->is_dead)
++cnt;
}
}
break;
default:
break;
}
}
return cnt;
}
void OPvPCapturePointNA::SpawnNPCsForTeam(uint32 team)
{
const creature_type * creatures = NULL;
if (team == ALLIANCE)
creatures=AllianceControlNPCs;
else if (team == HORDE)
creatures=HordeControlNPCs;
else
return;
for (int i = 0; i < NA_CONTROL_NPC_NUM; ++i)
AddCreature(i,creatures[i].entry,creatures[i].teamval,creatures[i].map,creatures[i].x,creatures[i].y,creatures[i].z,creatures[i].o,1000000);
}
void OPvPCapturePointNA::DeSpawnNPCs()
{
for (int i = 0; i < NA_CONTROL_NPC_NUM; ++i)
DelCreature(i);
}
void OPvPCapturePointNA::SpawnGOsForTeam(uint32 team)
{
const go_type * gos = NULL;
if (team == ALLIANCE)
gos=AllianceControlGOs;
else if (team == HORDE)
gos=HordeControlGOs;
else
return;
for (int i = 0; i < NA_CONTROL_GO_NUM; ++i)
{
if (i == NA_ROOST_S ||
i == NA_ROOST_W ||
i == NA_ROOST_N ||
i == NA_ROOST_E ||
i == NA_BOMB_WAGON_S ||
i == NA_BOMB_WAGON_W ||
i == NA_BOMB_WAGON_N ||
i == NA_BOMB_WAGON_E)
continue; // roosts and bomb wagons are spawned when someone uses the matching destroyed roost
AddObject(i,gos[i].entry,gos[i].map,gos[i].x,gos[i].y,gos[i].z,gos[i].o,gos[i].rot0,gos[i].rot1,gos[i].rot2,gos[i].rot3);
}
}
void OPvPCapturePointNA::DeSpawnGOs()
{
for (int i = 0; i < NA_CONTROL_GO_NUM; ++i)
{
DelObject(i);
}
}
void OPvPCapturePointNA::FactionTakeOver(uint32 team)
{
if (m_ControllingFaction)
objmgr.RemoveGraveYardLink(NA_HALAA_GRAVEYARD,NA_HALAA_GRAVEYARD_ZONE,m_ControllingFaction,false);
if (m_ControllingFaction == ALLIANCE)
sWorld.SendZoneText(NA_HALAA_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_NA_LOOSE_A));
else if (m_ControllingFaction == HORDE)
sWorld.SendZoneText(NA_HALAA_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_NA_LOOSE_H));
m_ControllingFaction = team;
if (m_ControllingFaction)
objmgr.AddGraveYardLink(NA_HALAA_GRAVEYARD,NA_HALAA_GRAVEYARD_ZONE,m_ControllingFaction,false);
DeSpawnGOs();
DeSpawnNPCs();
SpawnGOsForTeam(team);
SpawnNPCsForTeam(team);
m_GuardsAlive = NA_GUARDS_MAX;
m_capturable = false;
this->UpdateHalaaWorldState();
if (team == ALLIANCE)
{
m_WyvernStateSouth = WYVERN_NEU_HORDE;
m_WyvernStateNorth = WYVERN_NEU_HORDE;
m_WyvernStateEast = WYVERN_NEU_HORDE;
m_WyvernStateWest = WYVERN_NEU_HORDE;
m_PvP->TeamApplyBuff(TEAM_ALLIANCE, NA_CAPTURE_BUFF);
m_PvP->SendUpdateWorldState(NA_UI_HORDE_GUARDS_SHOW, 0);
m_PvP->SendUpdateWorldState(NA_UI_ALLIANCE_GUARDS_SHOW, 1);
m_PvP->SendUpdateWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
sWorld.SendZoneText(NA_HALAA_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_NA_CAPTURE_A));
}
else
{
m_WyvernStateSouth = WYVERN_NEU_ALLIANCE;
m_WyvernStateNorth = WYVERN_NEU_ALLIANCE;
m_WyvernStateEast = WYVERN_NEU_ALLIANCE;
m_WyvernStateWest = WYVERN_NEU_ALLIANCE;
m_PvP->TeamApplyBuff(TEAM_HORDE, NA_CAPTURE_BUFF);
m_PvP->SendUpdateWorldState(NA_UI_HORDE_GUARDS_SHOW, 1);
m_PvP->SendUpdateWorldState(NA_UI_ALLIANCE_GUARDS_SHOW, 0);
m_PvP->SendUpdateWorldState(NA_UI_GUARDS_LEFT, m_GuardsAlive);
sWorld.SendZoneText(NA_HALAA_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_NA_CAPTURE_H));
}
UpdateWyvernRoostWorldState(NA_ROOST_S);
UpdateWyvernRoostWorldState(NA_ROOST_N);
UpdateWyvernRoostWorldState(NA_ROOST_W);
UpdateWyvernRoostWorldState(NA_ROOST_E);
}
bool OPvPCapturePointNA::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointNA::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
OPvPCapturePointNA::OPvPCapturePointNA(OutdoorPvP *pvp) :
OPvPCapturePoint(pvp), m_capturable(true), m_GuardsAlive(0), m_ControllingFaction(0),
m_HalaaState(HALAA_N), m_WyvernStateSouth(0), m_WyvernStateNorth(0), m_WyvernStateWest(0),
m_WyvernStateEast(0), m_RespawnTimer(NA_RESPAWN_TIME), m_GuardCheckTimer(NA_GUARD_CHECK_TIME)
{
SetCapturePointData(182210,530,-1572.57,7945.3,-22.475,2.05949,0,0,0.857167,0.515038);
}
bool OutdoorPvPNA::SetupOutdoorPvP()
{
// m_TypeId = OUTDOOR_PVP_NA; _MUST_ be set in ctor, because of spawns cleanup
// add the zones affected by the pvp buff
RegisterZone(NA_BUFF_ZONE);
// halaa
m_obj = new OPvPCapturePointNA(this);
if (!m_obj)
return false;
AddCapturePoint(m_obj);
return true;
}
void OutdoorPvPNA::HandlePlayerEnterZone(Player * plr, uint32 zone)
{
// add buffs
if (plr->GetTeam() == m_obj->m_ControllingFaction)
plr->CastSpell(plr,NA_CAPTURE_BUFF,true);
OutdoorPvP::HandlePlayerEnterZone(plr,zone);
}
void OutdoorPvPNA::HandlePlayerLeaveZone(Player * plr, uint32 zone)
{
// remove buffs
plr->RemoveAurasDueToSpell(NA_CAPTURE_BUFF);
OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
}
void OutdoorPvPNA::FillInitialWorldStates(WorldPacket &data)
{
m_obj->FillInitialWorldStates(data);
}
void OPvPCapturePointNA::FillInitialWorldStates(WorldPacket &data)
{
if (m_ControllingFaction == ALLIANCE)
{
data << NA_UI_HORDE_GUARDS_SHOW << uint32(0);
data << NA_UI_ALLIANCE_GUARDS_SHOW << uint32(1);
}
else if (m_ControllingFaction == HORDE)
{
data << NA_UI_HORDE_GUARDS_SHOW << uint32(1);
data << NA_UI_ALLIANCE_GUARDS_SHOW << uint32(0);
}
else
{
data << NA_UI_HORDE_GUARDS_SHOW << uint32(0);
data << NA_UI_ALLIANCE_GUARDS_SHOW << uint32(0);
}
data << NA_UI_GUARDS_MAX << NA_GUARDS_MAX;
data << NA_UI_GUARDS_LEFT << uint32(m_GuardsAlive);
data << NA_UI_TOWER_SLIDER_DISPLAY << uint32(0);
data << NA_UI_TOWER_SLIDER_POS << uint32(50);
data << NA_UI_TOWER_SLIDER_N << uint32(100);
data << NA_MAP_WYVERN_NORTH_NEU_H << uint32(bool(m_WyvernStateNorth & WYVERN_NEU_HORDE));
data << NA_MAP_WYVERN_NORTH_NEU_A << uint32(bool(m_WyvernStateNorth & WYVERN_NEU_ALLIANCE));
data << NA_MAP_WYVERN_NORTH_H << uint32(bool(m_WyvernStateNorth & WYVERN_HORDE));
data << NA_MAP_WYVERN_NORTH_A << uint32(bool(m_WyvernStateNorth & WYVERN_ALLIANCE));
data << NA_MAP_WYVERN_SOUTH_NEU_H << uint32(bool(m_WyvernStateSouth & WYVERN_NEU_HORDE));
data << NA_MAP_WYVERN_SOUTH_NEU_A << uint32(bool(m_WyvernStateSouth & WYVERN_NEU_ALLIANCE));
data << NA_MAP_WYVERN_SOUTH_H << uint32(bool(m_WyvernStateSouth & WYVERN_HORDE));
data << NA_MAP_WYVERN_SOUTH_A << uint32(bool(m_WyvernStateSouth & WYVERN_ALLIANCE));
data << NA_MAP_WYVERN_WEST_NEU_H << uint32(bool(m_WyvernStateWest & WYVERN_NEU_HORDE));
data << NA_MAP_WYVERN_WEST_NEU_A << uint32(bool(m_WyvernStateWest & WYVERN_NEU_ALLIANCE));
data << NA_MAP_WYVERN_WEST_H << uint32(bool(m_WyvernStateWest & WYVERN_HORDE));
data << NA_MAP_WYVERN_WEST_A << uint32(bool(m_WyvernStateWest & WYVERN_ALLIANCE));
data << NA_MAP_WYVERN_EAST_NEU_H << uint32(bool(m_WyvernStateEast & WYVERN_NEU_HORDE));
data << NA_MAP_WYVERN_EAST_NEU_A << uint32(bool(m_WyvernStateEast & WYVERN_NEU_ALLIANCE));
data << NA_MAP_WYVERN_EAST_H << uint32(bool(m_WyvernStateEast & WYVERN_HORDE));
data << NA_MAP_WYVERN_EAST_A << uint32(bool(m_WyvernStateEast & WYVERN_ALLIANCE));
data << NA_MAP_HALAA_NEUTRAL << uint32(bool(m_HalaaState & HALAA_N));
data << NA_MAP_HALAA_NEU_A << uint32(bool(m_HalaaState & HALAA_N_A));
data << NA_MAP_HALAA_NEU_H << uint32(bool(m_HalaaState & HALAA_N_H));
data << NA_MAP_HALAA_HORDE << uint32(bool(m_HalaaState & HALAA_H));
data << NA_MAP_HALAA_ALLIANCE << uint32(bool(m_HalaaState & HALAA_A));
}
void OutdoorPvPNA::SendRemoveWorldStates(Player *plr)
{
plr->SendUpdateWorldState(NA_UI_HORDE_GUARDS_SHOW,0);
plr->SendUpdateWorldState(NA_UI_ALLIANCE_GUARDS_SHOW,0);
plr->SendUpdateWorldState(NA_UI_GUARDS_MAX,0);
plr->SendUpdateWorldState(NA_UI_GUARDS_LEFT,0);
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY,0);
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_POS,0);
plr->SendUpdateWorldState(NA_UI_TOWER_SLIDER_N,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_WEST_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_A,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_H,0);
plr->SendUpdateWorldState(NA_MAP_WYVERN_EAST_A,0);
plr->SendUpdateWorldState(NA_MAP_HALAA_NEUTRAL,0);
plr->SendUpdateWorldState(NA_MAP_HALAA_NEU_A,0);
plr->SendUpdateWorldState(NA_MAP_HALAA_NEU_H,0);
plr->SendUpdateWorldState(NA_MAP_HALAA_HORDE,0);
plr->SendUpdateWorldState(NA_MAP_HALAA_ALLIANCE,0);
}
bool OutdoorPvPNA::Update(uint32 diff)
{
return m_obj->Update(diff);
}
bool OPvPCapturePointNA::HandleCustomSpell(Player * plr, uint32 spellId, GameObject * /*go*/)
{
std::vector<uint32> nodes;
nodes.resize(2);
bool retval = false;
switch(spellId)
{
case NA_SPELL_FLY_NORTH:
nodes[0] = FlightPathStartNodes[NA_ROOST_N];
nodes[1] = FlightPathEndNodes[NA_ROOST_N];
plr->ActivateTaxiPathTo(nodes);
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
plr->UpdatePvP(true,true);
retval = true;
break;
case NA_SPELL_FLY_SOUTH:
nodes[0] = FlightPathStartNodes[NA_ROOST_S];
nodes[1] = FlightPathEndNodes[NA_ROOST_S];
plr->ActivateTaxiPathTo(nodes);
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
plr->UpdatePvP(true,true);
retval = true;
break;
case NA_SPELL_FLY_WEST:
nodes[0] = FlightPathStartNodes[NA_ROOST_W];
nodes[1] = FlightPathEndNodes[NA_ROOST_W];
plr->ActivateTaxiPathTo(nodes);
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
plr->UpdatePvP(true,true);
retval = true;
break;
case NA_SPELL_FLY_EAST:
nodes[0] = FlightPathStartNodes[NA_ROOST_E];
nodes[1] = FlightPathEndNodes[NA_ROOST_E];
plr->ActivateTaxiPathTo(nodes);
plr->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_IN_PVP);
plr->UpdatePvP(true,true);
retval = true;
break;
default:
break;
}
if (retval)
{
//Adding items
uint32 noSpaceForCount = 0;
// check space and find places
ItemPosCountVec dest;
int32 count = 10;
uint32 itemid = 24538;
// bomb id count
uint8 msg = plr->CanStoreNewItem(NULL_BAG, NULL_SLOT, dest, itemid, count, &noSpaceForCount);
if (msg != EQUIP_ERR_OK) // convert to possible store amount
count -= noSpaceForCount;
if (count == 0 || dest.empty()) // can't add any
{
return true;
}
Item* item = plr->StoreNewItem(dest, itemid, true);
if (count > 0 && item)
{
plr->SendNewItem(item,count,true,false);
}
return true;
}
return false;
}
int32 OPvPCapturePointNA::HandleOpenGo(Player *plr, uint64 guid)
{
uint32 retval = OPvPCapturePoint::HandleOpenGo(plr, guid);
if (retval >= 0)
{
const go_type * gos = NULL;
if (m_ControllingFaction == ALLIANCE)
gos=AllianceControlGOs;
else if (m_ControllingFaction == HORDE)
gos=HordeControlGOs;
else
return -1;
int32 del = -1;
int32 del2 = -1;
int32 add = -1;
int32 add2 = -1;
switch(retval)
{
case NA_DESTROYED_ROOST_S:
del = NA_DESTROYED_ROOST_S;
add = NA_ROOST_S;
add2 = NA_BOMB_WAGON_S;
if (m_ControllingFaction == HORDE)
m_WyvernStateSouth = WYVERN_ALLIANCE;
else
m_WyvernStateSouth = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_S);
break;
case NA_DESTROYED_ROOST_N:
del = NA_DESTROYED_ROOST_N;
add = NA_ROOST_N;
add2 = NA_BOMB_WAGON_N;
if (m_ControllingFaction == HORDE)
m_WyvernStateNorth = WYVERN_ALLIANCE;
else
m_WyvernStateNorth = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_N);
break;
case NA_DESTROYED_ROOST_W:
del = NA_DESTROYED_ROOST_W;
add = NA_ROOST_W;
add2 = NA_BOMB_WAGON_W;
if (m_ControllingFaction == HORDE)
m_WyvernStateWest = WYVERN_ALLIANCE;
else
m_WyvernStateWest = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_W);
break;
case NA_DESTROYED_ROOST_E:
del = NA_DESTROYED_ROOST_E;
add = NA_ROOST_E;
add2 = NA_BOMB_WAGON_E;
if (m_ControllingFaction == HORDE)
m_WyvernStateEast = WYVERN_ALLIANCE;
else
m_WyvernStateEast = WYVERN_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_E);
break;
case NA_BOMB_WAGON_S:
del = NA_BOMB_WAGON_S;
del2 = NA_ROOST_S;
add = NA_DESTROYED_ROOST_S;
if (m_ControllingFaction == HORDE)
m_WyvernStateSouth = WYVERN_NEU_ALLIANCE;
else
m_WyvernStateSouth = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_S);
break;
case NA_BOMB_WAGON_N:
del = NA_BOMB_WAGON_N;
del2 = NA_ROOST_N;
add = NA_DESTROYED_ROOST_N;
if (m_ControllingFaction == HORDE)
m_WyvernStateNorth = WYVERN_NEU_ALLIANCE;
else
m_WyvernStateNorth = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_N);
break;
case NA_BOMB_WAGON_W:
del = NA_BOMB_WAGON_W;
del2 = NA_ROOST_W;
add = NA_DESTROYED_ROOST_W;
if (m_ControllingFaction == HORDE)
m_WyvernStateWest = WYVERN_NEU_ALLIANCE;
else
m_WyvernStateWest = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_W);
break;
case NA_BOMB_WAGON_E:
del = NA_BOMB_WAGON_E;
del2 = NA_ROOST_E;
add = NA_DESTROYED_ROOST_E;
if (m_ControllingFaction == HORDE)
m_WyvernStateEast = WYVERN_NEU_ALLIANCE;
else
m_WyvernStateEast = WYVERN_NEU_HORDE;
UpdateWyvernRoostWorldState(NA_ROOST_E);
break;
default:
return -1;
break;
}
if (del>-1)
DelObject(del);
if (del2>-1)
DelObject(del2);
if (add>-1)
AddObject(add,gos[add].entry,gos[add].map,gos[add].x,gos[add].y,gos[add].z,gos[add].o,gos[add].rot0,gos[add].rot1,gos[add].rot2,gos[add].rot3);
if (add2>-1)
AddObject(add2,gos[add2].entry,gos[add2].map,gos[add2].x,gos[add2].y,gos[add2].z,gos[add2].o,gos[add2].rot0,gos[add2].rot1,gos[add2].rot2,gos[add2].rot3);
return retval;
}
return -1;
}
bool 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;
uint32 cnt = GetAliveGuardsCount();
if (cnt != m_GuardsAlive)
{
m_GuardsAlive = cnt;
if (m_GuardsAlive == 0)
m_capturable = true;
// update the guard count for the players in zone
m_PvP->SendUpdateWorldState(NA_UI_GUARDS_LEFT,m_GuardsAlive);
}
} else m_GuardCheckTimer -= diff;
if (m_capturable || capturable)
{
if (m_RespawnTimer < diff)
{
// if the guards have been killed, then the challenger has one hour to take over halaa.
// in case they fail to do it, the guards are respawned, and they have to start again.
if (m_ControllingFaction)
FactionTakeOver(m_ControllingFaction);
m_RespawnTimer = NA_RESPAWN_TIME;
} else m_RespawnTimer -= diff;
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;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
if (flag)
{
flag->SetGoArtKit(artkit);
}
UpdateHalaaWorldState();
}
void OPvPCapturePointNA::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(NA_UI_TOWER_SLIDER_DISPLAY, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(NA_UI_TOWER_SLIDER_POS, phase);
SendUpdateWorldState(NA_UI_TOWER_SLIDER_N, m_neutralValuePct);
}
void OPvPCapturePointNA::UpdateHalaaWorldState()
{
m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEUTRAL ,uint32(bool(m_HalaaState & HALAA_N)));
m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_A ,uint32(bool(m_HalaaState & HALAA_N_A)));
m_PvP->SendUpdateWorldState(NA_MAP_HALAA_NEU_H ,uint32(bool(m_HalaaState & HALAA_N_H)));
m_PvP->SendUpdateWorldState(NA_MAP_HALAA_HORDE ,uint32(bool(m_HalaaState & HALAA_H)));
m_PvP->SendUpdateWorldState(NA_MAP_HALAA_ALLIANCE ,uint32(bool(m_HalaaState & HALAA_A)));
}
void OPvPCapturePointNA::UpdateWyvernRoostWorldState(uint32 roost)
{
switch(roost)
{
case NA_ROOST_S:
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_H,uint32(bool(m_WyvernStateSouth & WYVERN_NEU_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_NEU_A,uint32(bool(m_WyvernStateSouth & WYVERN_NEU_ALLIANCE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_H,uint32(bool(m_WyvernStateSouth & WYVERN_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_SOUTH_A,uint32(bool(m_WyvernStateSouth & WYVERN_ALLIANCE)));
break;
case NA_ROOST_N:
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_H,uint32(bool(m_WyvernStateNorth & WYVERN_NEU_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_NEU_A,uint32(bool(m_WyvernStateNorth & WYVERN_NEU_ALLIANCE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_H,uint32(bool(m_WyvernStateNorth & WYVERN_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_NORTH_A,uint32(bool(m_WyvernStateNorth & WYVERN_ALLIANCE)));
break;
case NA_ROOST_W:
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_H,uint32(bool(m_WyvernStateWest & WYVERN_NEU_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_NEU_A,uint32(bool(m_WyvernStateWest & WYVERN_NEU_ALLIANCE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_H,uint32(bool(m_WyvernStateWest & WYVERN_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_WEST_A,uint32(bool(m_WyvernStateWest & WYVERN_ALLIANCE)));
break;
case NA_ROOST_E:
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_H,uint32(bool(m_WyvernStateEast & WYVERN_NEU_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_NEU_A,uint32(bool(m_WyvernStateEast & WYVERN_NEU_ALLIANCE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_H,uint32(bool(m_WyvernStateEast & WYVERN_HORDE)));
m_PvP->SendUpdateWorldState(NA_MAP_WYVERN_EAST_A,uint32(bool(m_WyvernStateEast & WYVERN_ALLIANCE)));
break;
}
}
+297
View File
@@ -0,0 +1,297 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_NA_
#define OUTDOOR_PVP_NA_
// TODO: "sometimes" set to neutral
#include "OutdoorPvPImpl.h"
enum OutdoorPvPNASpells
{
NA_KILL_TOKEN_ALLIANCE = 33005,
NA_KILL_TOKEN_HORDE = 33004,
NA_CAPTURE_BUFF = 33795 // strength of the halaani
};
// kill credit for pks
const uint32 NA_CREDIT_MARKER = 24867;
const uint32 NA_GUARDS_MAX = 15;
const uint32 NA_BUFF_ZONE = 3518;
const uint32 NA_HALAA_GRAVEYARD = 993;
const uint32 NA_HALAA_GRAVEYARD_ZONE = 3518; // need to add zone id, not area id
const uint32 NA_RESPAWN_TIME = 3600000; // one hour to capture after defeating all guards
const uint32 NA_GUARD_CHECK_TIME = 500; // every half second
enum OutdoorPvPNAWorldStates{
NA_UI_HORDE_GUARDS_SHOW = 2503,
NA_UI_ALLIANCE_GUARDS_SHOW = 2502,
NA_UI_GUARDS_MAX = 2493,
NA_UI_GUARDS_LEFT = 2491,
NA_UI_TOWER_SLIDER_DISPLAY = 2495,
NA_UI_TOWER_SLIDER_POS = 2494,
NA_UI_TOWER_SLIDER_N = 2497,
NA_MAP_WYVERN_NORTH_NEU_H = 2762,
NA_MAP_WYVERN_NORTH_NEU_A = 2662,
NA_MAP_WYVERN_NORTH_H = 2663,
NA_MAP_WYVERN_NORTH_A = 2664,
NA_MAP_WYVERN_SOUTH_NEU_H = 2760,
NA_MAP_WYVERN_SOUTH_NEU_A = 2670,
NA_MAP_WYVERN_SOUTH_H = 2668,
NA_MAP_WYVERN_SOUTH_A = 2669,
NA_MAP_WYVERN_WEST_NEU_H = 2761,
NA_MAP_WYVERN_WEST_NEU_A = 2667,
NA_MAP_WYVERN_WEST_H = 2665,
NA_MAP_WYVERN_WEST_A = 2666,
NA_MAP_WYVERN_EAST_NEU_H = 2763,
NA_MAP_WYVERN_EAST_NEU_A = 2659,
NA_MAP_WYVERN_EAST_H = 2660,
NA_MAP_WYVERN_EAST_A = 2661,
NA_MAP_HALAA_NEUTRAL = 2671,
NA_MAP_HALAA_NEU_A = 2676,
NA_MAP_HALAA_NEU_H = 2677,
NA_MAP_HALAA_HORDE = 2672,
NA_MAP_HALAA_ALLIANCE = 2673
};
const uint32 FLIGHT_NODES_NUM = 4;
// used to access the elements of Horde/AllyControlGOs
enum ControlGOTypes{
NA_ROOST_S = 0,
NA_ROOST_W = 1,
NA_ROOST_N = 2,
NA_ROOST_E = 3,
NA_BOMB_WAGON_S = 4,
NA_BOMB_WAGON_W = 5,
NA_BOMB_WAGON_N = 6,
NA_BOMB_WAGON_E = 7,
NA_DESTROYED_ROOST_S = 8,
NA_DESTROYED_ROOST_W = 9,
NA_DESTROYED_ROOST_N = 10,
NA_DESTROYED_ROOST_E = 11,
NA_CONTROL_GO_NUM = 12
};
const uint32 FlightPathStartNodes[FLIGHT_NODES_NUM] = {103,105,107,109};
const uint32 FlightPathEndNodes[FLIGHT_NODES_NUM] = {104,106,108,110};
enum FlightSpellsNA{
NA_SPELL_FLY_SOUTH = 32059,
NA_SPELL_FLY_WEST = 32068,
NA_SPELL_FLY_NORTH = 32075,
NA_SPELL_FLY_EAST = 32081
};
// spawned when the alliance is attacking, horde is in control
const go_type HordeControlGOs[NA_CONTROL_GO_NUM] = {
{182267,530,-1815.8,8036.51,-26.2354,-2.89725,0,0,0.992546,-0.121869}, //ALLY_ROOST_SOUTH
{182280,530,-1507.95,8132.1,-19.5585,-1.3439,0,0,0.622515,-0.782608}, //ALLY_ROOST_WEST
{182281,530,-1384.52,7779.33,-11.1663,-0.575959,0,0,0.284015,-0.95882}, //ALLY_ROOST_NORTH
{182282,530,-1650.11,7732.56,-15.4505,-2.80998,0,0,0.986286,-0.165048}, //ALLY_ROOST_EAST
{182222,530,-1825.4022,8039.2602,-26.08,-2.89725,0,0,0.992546,-0.121869}, //HORDE_BOMB_WAGON_SOUTH
{182272,530,-1515.37,8136.91,-20.42,-1.3439,0,0,0.622515,-0.782608}, //HORDE_BOMB_WAGON_WEST
{182273,530,-1377.95,7773.44,-10.31,-0.575959,0,0,0.284015,-0.95882}, //HORDE_BOMB_WAGON_NORTH
{182274,530,-1659.87,7733.15,-15.75,-2.80998,0,0,0.986286,-0.165048}, //HORDE_BOMB_WAGON_EAST
{182266,530,-1815.8,8036.51,-26.2354,-2.89725,0,0,0.992546,-0.121869}, //DESTROYED_ALLY_ROOST_SOUTH
{182275,530,-1507.95,8132.1,-19.5585,-1.3439,0,0,0.622515,-0.782608}, //DESTROYED_ALLY_ROOST_WEST
{182276,530,-1384.52,7779.33,-11.1663,-0.575959,0,0,0.284015,-0.95882}, //DESTROYED_ALLY_ROOST_NORTH
{182277,530,-1650.11,7732.56,-15.4505,-2.80998,0,0,0.986286,-0.165048} //DESTROYED_ALLY_ROOST_EAST
};
// spawned when the horde is attacking, alliance is in control
const go_type AllianceControlGOs[NA_CONTROL_GO_NUM] = {
{182301,530,-1815.8,8036.51,-26.2354,-2.89725,0,0,0.992546,-0.121869}, //HORDE_ROOST_SOUTH
{182302,530,-1507.95,8132.1,-19.5585,-1.3439,0,0,0.622515,-0.782608}, //HORDE_ROOST_WEST
{182303,530,-1384.52,7779.33,-11.1663,-0.575959,0,0,0.284015,-0.95882}, //HORDE_ROOST_NORTH
{182304,530,-1650.11,7732.56,-15.4505,-2.80998,0,0,0.986286,-0.165048}, //HORDE_ROOST_EAST
{182305,530,-1825.4022,8039.2602,-26.08,-2.89725,0,0,0.992546,-0.121869}, //ALLY_BOMB_WAGON_SOUTH
{182306,530,-1515.37,8136.91,-20.42,-1.3439,0,0,0.622515,-0.782608}, //ALLY_BOMB_WAGON_WEST
{182307,530,-1377.95,7773.44,-10.31,-0.575959,0,0,0.284015,-0.95882}, //ALLY_BOMB_WAGON_NORTH
{182308,530,-1659.87,7733.15,-15.75,-2.80998,0,0,0.986286,-0.165048}, //ALLY_BOMB_WAGON_EAST
{182297,530,-1815.8,8036.51,-26.2354,-2.89725,0,0,0.992546,-0.121869}, //DESTROYED_HORDE_ROOST_SOUTH
{182298,530,-1507.95,8132.1,-19.5585,-1.3439,0,0,0.622515,-0.782608}, //DESTROYED_HORDE_ROOST_WEST
{182299,530,-1384.52,7779.33,-11.1663,-0.575959,0,0,0.284015,-0.95882}, //DESTROYED_HORDE_ROOST_NORTH
{182300,530,-1650.11,7732.56,-15.4505,-2.80998,0,0,0.986286,-0.165048} //DESTROYED_HORDE_ROOST_EAST
};
enum ControlNPCTypes{
NA_NPC_RESEARCHER = 0,
NA_NPC_QUARTERMASTER,
NA_NPC_BLADE_MERCHANT,
NA_NPC_FOOD_MERCHANT,
NA_NPC_AMMO,
NA_NPC_GUARD_01,
NA_NPC_GUARD_02,
NA_NPC_GUARD_03,
NA_NPC_GUARD_04,
NA_NPC_GUARD_05,
NA_NPC_GUARD_06,
NA_NPC_GUARD_07,
NA_NPC_GUARD_08,
NA_NPC_GUARD_09,
NA_NPC_GUARD_10,
NA_NPC_GUARD_11,
NA_NPC_GUARD_12,
NA_NPC_GUARD_13,
NA_NPC_GUARD_14,
NA_NPC_GUARD_15,
NA_CONTROL_NPC_NUM
};
const creature_type HordeControlNPCs[NA_CONTROL_NPC_NUM] = {
{18816,67,530,-1523.92,7951.76,-17.6942,3.51172},
{18821,67,530,-1527.75,7952.46,-17.6948,3.99317},
{21474,67,530,-1520.14,7927.11,-20.2527,3.39389},
{21484,67,530,-1524.84,7930.34,-20.182,3.6405},
{21483,67,530,-1570.01,7993.8,-22.4505,5.02655},
{18192,67,530,-1654.06,8000.46,-26.59,3.37},
{18192,67,530,-1487.18,7899.1,-19.53,0.954},
{18192,67,530,-1480.88,7908.79,-19.19,4.485},
{18192,67,530,-1540.56,7995.44,-20.45,0.947},
{18192,67,530,-1546.95,8000.85,-20.72,6.035},
{18192,67,530,-1595.31,7860.53,-21.51,3.747},
{18192,67,530,-1642.31,7995.59,-25.8,3.317},
{18192,67,530,-1545.46,7995.35,-20.63,1.094},
{18192,67,530,-1487.58,7907.99,-19.27,5.567},
{18192,67,530,-1651.54,7988.56,-26.5289,2.98451},
{18192,67,530,-1602.46,7866.43,-22.1177,4.74729},
{18192,67,530,-1591.22,7875.29,-22.3536,4.34587},
{18192,67,530,-1550.6,7944.45,-21.63,3.559},
{18192,67,530,-1545.57,7935.83,-21.13,3.448},
{18192,67,530,-1550.86,7937.56,-21.7,3.801}
};
const creature_type AllianceControlNPCs[NA_CONTROL_NPC_NUM] = {
{18817,469,530,-1591.18,8020.39,-22.2042,4.59022},
{18822,469,530,-1588.0,8019.0,-22.2042,4.06662},
{21485,469,530,-1521.93,7927.37,-20.2299,3.24631},
{21487,469,530,-1540.33,7971.95,-20.7186,3.07178},
{21488,469,530,-1570.01,7993.8,-22.4505,5.02655},
{18256,469,530,-1654.06,8000.46,-26.59,3.37},
{18256,469,530,-1487.18,7899.1,-19.53,0.954},
{18256,469,530,-1480.88,7908.79,-19.19,4.485},
{18256,469,530,-1540.56,7995.44,-20.45,0.947},
{18256,469,530,-1546.95,8000.85,-20.72,6.035},
{18256,469,530,-1595.31,7860.53,-21.51,3.747},
{18256,469,530,-1642.31,7995.59,-25.8,3.317},
{18256,469,530,-1545.46,7995.35,-20.63,1.094},
{18256,469,530,-1487.58,7907.99,-19.27,5.567},
{18256,469,530,-1651.54,7988.56,-26.5289,2.98451},
{18256,469,530,-1602.46,7866.43,-22.1177,4.74729},
{18256,469,530,-1591.22,7875.29,-22.3536,4.34587},
{18256,469,530,-1603.75,8000.36,-24.18,4.516},
{18256,469,530,-1585.73,7994.68,-23.29,4.439},
{18256,469,530,-1595.5,7991.27,-23.53,4.738}
};
enum WyvernStates{
WYVERN_NEU_HORDE = 1,
WYVERN_NEU_ALLIANCE = 2,
WYVERN_HORDE = 4,
WYVERN_ALLIANCE = 8
};
enum HalaaStates{
HALAA_N = 1,
HALAA_N_A = 2,
HALAA_A = 4,
HALAA_N_H = 8,
HALAA_H = 16
};
class Unit;
class Creature;
class OutdoorPvPNA;
class OPvPCapturePointNA : public OPvPCapturePoint
{
friend class OutdoorPvPNA;
public:
OPvPCapturePointNA(OutdoorPvP * pvp);
bool Update(uint32 diff);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
bool HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go);
int32 HandleOpenGo(Player *plr, uint64 guid);
uint32 GetAliveGuardsCount();
protected:
// called when a faction takes control
void FactionTakeOver(uint32 team);
void DeSpawnNPCs();
void DeSpawnGOs();
void SpawnNPCsForTeam(uint32 team);
void SpawnGOsForTeam(uint32 team);
void UpdateWyvernRoostWorldState(uint32 roost);
void UpdateHalaaWorldState();
private:
bool m_capturable;
uint32 m_GuardsAlive;
uint32 m_ControllingFaction;
uint32 m_WyvernStateNorth;
uint32 m_WyvernStateSouth;
uint32 m_WyvernStateEast;
uint32 m_WyvernStateWest;
uint32 m_HalaaState;
uint32 m_RespawnTimer;
uint32 m_GuardCheckTimer;
};
class OutdoorPvPNA : public OutdoorPvP
{
friend class OPvPCapturePointNA;
public:
OutdoorPvPNA();
bool SetupOutdoorPvP();
void HandlePlayerEnterZone(Player *plr, uint32 zone);
void HandlePlayerLeaveZone(Player *plr, uint32 zone);
bool Update(uint32 diff);
void FillInitialWorldStates(WorldPacket &data);
void SendRemoveWorldStates(Player * plr);
void HandleKillImpl(Player * plr, Unit * killed);
private:
OPvPCapturePointNA * m_obj;
};
#endif
+227
View File
@@ -0,0 +1,227 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPSI.h"
#include "WorldPacket.h"
#include "Player.h"
#include "GameObject.h"
#include "MapManager.h"
#include "ObjectMgr.h"
#include "OutdoorPvPMgr.h"
#include "Language.h"
#include "World.h"
OutdoorPvPSI::OutdoorPvPSI()
{
m_TypeId = OUTDOOR_PVP_SI;
m_Gathered_A = 0;
m_Gathered_H = 0;
m_LastController = 0;
}
void OutdoorPvPSI::FillInitialWorldStates(WorldPacket &data)
{
data << SI_GATHERED_A << m_Gathered_A;
data << SI_GATHERED_H << m_Gathered_H;
data << SI_SILITHYST_MAX << SI_MAX_RESOURCES;
}
void OutdoorPvPSI::SendRemoveWorldStates(Player *plr)
{
plr->SendUpdateWorldState(SI_GATHERED_A,0);
plr->SendUpdateWorldState(SI_GATHERED_H,0);
plr->SendUpdateWorldState(SI_SILITHYST_MAX,0);
}
void OutdoorPvPSI::UpdateWorldState()
{
SendUpdateWorldState(SI_GATHERED_A,m_Gathered_A);
SendUpdateWorldState(SI_GATHERED_H,m_Gathered_H);
SendUpdateWorldState(SI_SILITHYST_MAX,SI_MAX_RESOURCES);
}
bool OutdoorPvPSI::SetupOutdoorPvP()
{
for (int i = 0; i < OutdoorPvPSIBuffZonesNum; ++i)
RegisterZone(OutdoorPvPSIBuffZones[i]);
return true;
}
bool OutdoorPvPSI::Update(uint32 /*diff*/)
{
return false;
}
void OutdoorPvPSI::HandlePlayerEnterZone(Player * plr, uint32 zone)
{
if (plr->GetTeam() == m_LastController)
plr->CastSpell(plr,SI_CENARION_FAVOR,true);
OutdoorPvP::HandlePlayerEnterZone(plr,zone);
}
void OutdoorPvPSI::HandlePlayerLeaveZone(Player * plr, uint32 zone)
{
// remove buffs
plr->RemoveAurasDueToSpell(SI_CENARION_FAVOR);
OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
}
bool OutdoorPvPSI::HandleAreaTrigger(Player *plr, uint32 trigger)
{
switch(trigger)
{
case SI_AREATRIGGER_A:
if (plr->GetTeam() == ALLIANCE && plr->HasAura(SI_SILITHYST_FLAG))
{
// remove aura
plr->RemoveAurasDueToSpell(SI_SILITHYST_FLAG);
++ m_Gathered_A;
if (m_Gathered_A >= SI_MAX_RESOURCES)
{
TeamApplyBuff(TEAM_ALLIANCE, SI_CENARION_FAVOR);
sWorld.SendZoneText(OutdoorPvPSIBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_SI_CAPTURE_A));
m_LastController = ALLIANCE;
m_Gathered_A = 0;
m_Gathered_H = 0;
}
UpdateWorldState();
// reward player
plr->CastSpell(plr,SI_TRACES_OF_SILITHYST,true);
// add 19 honor
plr->RewardHonor(NULL,1,19);
// add 20 cenarion circle repu
plr->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(609),20);
// complete quest
plr->KilledMonsterCredit(SI_TURNIN_QUEST_CM_A,0);
}
return true;
case SI_AREATRIGGER_H:
if (plr->GetTeam() == HORDE && plr->HasAura(SI_SILITHYST_FLAG))
{
// remove aura
plr->RemoveAurasDueToSpell(SI_SILITHYST_FLAG);
++ m_Gathered_H;
if (m_Gathered_H >= SI_MAX_RESOURCES)
{
TeamApplyBuff(TEAM_HORDE, SI_CENARION_FAVOR);
sWorld.SendZoneText(OutdoorPvPSIBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_SI_CAPTURE_H));
m_LastController = HORDE;
m_Gathered_A = 0;
m_Gathered_H = 0;
}
UpdateWorldState();
// reward player
plr->CastSpell(plr,SI_TRACES_OF_SILITHYST,true);
// add 19 honor
plr->RewardHonor(NULL,1,19);
// add 20 cenarion circle repu
plr->GetReputationMgr().ModifyReputation(sFactionStore.LookupEntry(609),20);
// complete quest
plr->KilledMonsterCredit(SI_TURNIN_QUEST_CM_H,0);
}
return true;
}
return false;
}
bool OutdoorPvPSI::HandleDropFlag(Player *plr, uint32 spellId)
{
if (spellId == SI_SILITHYST_FLAG)
{
// if it was dropped away from the player's turn-in point, then create a silithyst mound, if it was dropped near the areatrigger, then it was dispelled by the outdoorpvp, so do nothing
switch(plr->GetTeam())
{
case ALLIANCE:
{
AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(SI_AREATRIGGER_A);
if (atEntry)
{
// 5.0f is safe-distance
if (plr->GetDistance(atEntry->x,atEntry->y,atEntry->z) > 5.0f + atEntry->radius)
{
// he dropped it further, summon mound
GameObject * go = new GameObject;
Map * map = plr->GetMap();
if (!map)
{
delete go;
return true;
}
if (!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map, plr->GetPhaseMask(), plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,GO_STATE_READY))
{
delete go;
}
else
{
go->SetRespawnTime(0);
map->Add(go);
}
}
}
}
break;
case HORDE:
{
AreaTriggerEntry const* atEntry = sAreaTriggerStore.LookupEntry(SI_AREATRIGGER_H);
if (atEntry)
{
// 5.0f is safe-distance
if (plr->GetDistance(atEntry->x,atEntry->y,atEntry->z) > 5.0f + atEntry->radius)
{
// he dropped it further, summon mound
GameObject * go = new GameObject;
Map * map = plr->GetMap();
if (!map)
{
delete go;
return true;
}
if (!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),SI_SILITHYST_MOUND, map, plr->GetPhaseMask() ,plr->GetPositionX(),plr->GetPositionY(),plr->GetPositionZ(),plr->GetOrientation(),0,0,0,0,100,GO_STATE_READY))
{
delete go;
}
else
{
go->SetRespawnTime(0);
map->Add(go);
}
}
}
}
break;
}
return true;
}
return false;
}
bool OutdoorPvPSI::HandleCustomSpell(Player *plr, uint32 spellId, GameObject *go)
{
if (!go || spellId != SI_SILITHYST_FLAG_GO_SPELL)
return false;
plr->CastSpell(plr,SI_SILITHYST_FLAG,true);
if (go->GetGOInfo()->id == SI_SILITHYST_MOUND)
{
// despawn go
go->SetRespawnTime(0);
go->Delete();
}
return true;
}
+75
View File
@@ -0,0 +1,75 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_SI_
#define OUTDOOR_PVP_SI_
#include "OutdoorPvPImpl.h"
enum OutdoorPvPSISpells
{
SI_SILITHYST_FLAG_GO_SPELL = 29518,
SI_SILITHYST_FLAG = 29519,
SI_TRACES_OF_SILITHYST = 29534,
SI_CENARION_FAVOR = 30754
};
const uint32 SI_MAX_RESOURCES = 200;
const uint32 OutdoorPvPSIBuffZonesNum = 3;
const uint32 OutdoorPvPSIBuffZones[OutdoorPvPSIBuffZonesNum] = { 1377, 3428, 3429 };
const uint32 SI_AREATRIGGER_H = 4168;
const uint32 SI_AREATRIGGER_A = 4162;
const uint32 SI_TURNIN_QUEST_CM_A = 17090;
const uint32 SI_TURNIN_QUEST_CM_H = 18199;
const uint32 SI_SILITHYST_MOUND = 181597;
enum SI_WorldStates{
SI_GATHERED_A = 2313,
SI_GATHERED_H = 2314,
SI_SILITHYST_MAX = 2317
};
class OutdoorPvPSI : public OutdoorPvP
{
public:
OutdoorPvPSI();
bool SetupOutdoorPvP();
void HandlePlayerEnterZone(Player *plr, uint32 zone);
void HandlePlayerLeaveZone(Player *plr, uint32 zone);
bool Update(uint32 diff);
void FillInitialWorldStates(WorldPacket &data);
void SendRemoveWorldStates(Player * plr);
bool HandleAreaTrigger(Player * plr, uint32 trigger);
bool HandleDropFlag(Player * plr, uint32 spellId);
bool HandleCustomSpell(Player * plr, uint32 spellId, GameObject *go);
void UpdateWorldState();
private:
uint32 m_Gathered_A;
uint32 m_Gathered_H;
uint32 m_LastController;
};
#endif
+310
View File
@@ -0,0 +1,310 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPTF.h"
#include "OutdoorPvPMgr.h"
#include "WorldPacket.h"
#include "Player.h"
#include "ObjectMgr.h"
#include "Language.h"
#include "World.h"
OutdoorPvPTF::OutdoorPvPTF()
{
m_TypeId = OUTDOOR_PVP_TF;
}
OPvPCapturePointTF::OPvPCapturePointTF(OutdoorPvP *pvp, OutdoorPvPTF_TowerType type)
: OPvPCapturePoint(pvp), m_TowerType(type), m_TowerState(TF_TOWERSTATE_N)
{
SetCapturePointData(TFCapturePoints[type].entry,TFCapturePoints[type].map,TFCapturePoints[type].x,TFCapturePoints[type].y,TFCapturePoints[type].z,TFCapturePoints[type].o,TFCapturePoints[type].rot0,TFCapturePoints[type].rot1,TFCapturePoints[type].rot2,TFCapturePoints[type].rot3);
}
void OPvPCapturePointTF::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(TFTowerWorldStates[m_TowerType].n) << uint32(bool(m_TowerState & TF_TOWERSTATE_N));
data << uint32(TFTowerWorldStates[m_TowerType].h) << uint32(bool(m_TowerState & TF_TOWERSTATE_H));
data << uint32(TFTowerWorldStates[m_TowerType].a) << uint32(bool(m_TowerState & TF_TOWERSTATE_A));
}
void OutdoorPvPTF::FillInitialWorldStates(WorldPacket &data)
{
data << TF_UI_TOWER_SLIDER_POS << uint32(50);
data << TF_UI_TOWER_SLIDER_N << uint32(100);
data << TF_UI_TOWER_SLIDER_DISPLAY << uint32(0);
data << TF_UI_TOWER_COUNT_H << m_HordeTowersControlled;
data << TF_UI_TOWER_COUNT_A << m_AllianceTowersControlled;
data << TF_UI_TOWERS_CONTROLLED_DISPLAY << uint32(!m_IsLocked);
data << TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT << first_digit;
data << TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT << second_digit;
data << TF_UI_LOCKED_TIME_HOURS << hours_left;
data << TF_UI_LOCKED_DISPLAY_NEUTRAL << uint32(m_IsLocked && !m_HordeTowersControlled && !m_AllianceTowersControlled);
data << TF_UI_LOCKED_DISPLAY_HORDE << uint32(m_IsLocked && (m_HordeTowersControlled > m_AllianceTowersControlled));
data << TF_UI_LOCKED_DISPLAY_ALLIANCE << uint32(m_IsLocked && (m_HordeTowersControlled < m_AllianceTowersControlled));
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
{
itr->second->FillInitialWorldStates(data);
}
}
void OutdoorPvPTF::SendRemoveWorldStates(Player * plr)
{
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS,uint32(0));
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_N,uint32(0));
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY,uint32(0));
plr->SendUpdateWorldState(TF_UI_TOWER_COUNT_H,uint32(0));
plr->SendUpdateWorldState(TF_UI_TOWER_COUNT_A,uint32(0));
plr->SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY,uint32(0));
plr->SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT,uint32(0));
plr->SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT,uint32(0));
plr->SendUpdateWorldState(TF_UI_LOCKED_TIME_HOURS,uint32(0));
plr->SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
plr->SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(0));
plr->SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(0));
for (int i = 0; i < TF_TOWER_NUM; ++i)
{
plr->SendUpdateWorldState(uint32(TFTowerWorldStates[i].n),uint32(0));
plr->SendUpdateWorldState(uint32(TFTowerWorldStates[i].h),uint32(0));
plr->SendUpdateWorldState(uint32(TFTowerWorldStates[i].a),uint32(0));
}
}
void OPvPCapturePointTF::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].n),uint32(bool(m_TowerState & TF_TOWERSTATE_N)));
m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].h),uint32(bool(m_TowerState & TF_TOWERSTATE_H)));
m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].a),uint32(bool(m_TowerState & TF_TOWERSTATE_A)));
}
bool OPvPCapturePointTF::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS, phase);
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_N, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointTF::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
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;
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(1));
SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(0));
}
else if (m_HordeTowersControlled == TF_TOWER_NUM)
{
TeamApplyBuff(TEAM_HORDE, TF_CAPTURE_BUFF);
m_IsLocked = true;
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(1));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(0));
SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(0));
}
else
{
TeamCastSpell(TEAM_ALLIANCE, -TF_CAPTURE_BUFF);
TeamCastSpell(TEAM_HORDE, -TF_CAPTURE_BUFF);
}
SendUpdateWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
SendUpdateWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
}
if (m_IsLocked)
{
// lock timer is down, release lock
if (m_LockTimer < diff)
{
m_LockTimer = TF_LOCK_TIME;
m_LockTimerUpdate = 0;
m_IsLocked = false;
SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(1));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(0));
SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(0));
}
else
{
// worldstateui update timer is down, update ui with new time data
if (m_LockTimerUpdate < diff)
{
m_LockTimerUpdate = TF_LOCK_TIME_UPDATE;
uint32 minutes_left = m_LockTimer / 60000;
hours_left = minutes_left / 60;
minutes_left -= hours_left * 60;
second_digit = minutes_left % 10;
first_digit = minutes_left / 10;
SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT,first_digit);
SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT,second_digit);
SendUpdateWorldState(TF_UI_LOCKED_TIME_HOURS,hours_left);
} else m_LockTimerUpdate -= diff;
m_LockTimer -= diff;
}
}
return changed;
}
void OutdoorPvPTF::HandlePlayerEnterZone(Player * plr, uint32 zone)
{
if (plr->GetTeam() == ALLIANCE)
{
if (m_AllianceTowersControlled >= TF_TOWER_NUM)
plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
}
else
{
if (m_HordeTowersControlled >= TF_TOWER_NUM)
plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
}
OutdoorPvP::HandlePlayerEnterZone(plr,zone);
}
void OutdoorPvPTF::HandlePlayerLeaveZone(Player * plr, uint32 zone)
{
// remove buffs
plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
}
bool OutdoorPvPTF::SetupOutdoorPvP()
{
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
m_IsLocked = false;
m_LockTimer = TF_LOCK_TIME;
m_LockTimerUpdate = 0;
hours_left = 6;
second_digit = 0;
first_digit = 0;
// add the zones affected by the pvp buff
for (int i = 0; i < OutdoorPvPTFBuffZonesNum; ++i)
RegisterZone(OutdoorPvPTFBuffZones[i]);
AddCapturePoint(new OPvPCapturePointTF(this,TF_TOWER_NW));
AddCapturePoint(new OPvPCapturePointTF(this,TF_TOWER_N));
AddCapturePoint(new OPvPCapturePointTF(this,TF_TOWER_NE));
AddCapturePoint(new OPvPCapturePointTF(this,TF_TOWER_SE));
AddCapturePoint(new OPvPCapturePointTF(this,TF_TOWER_S));
return true;
}
bool OPvPCapturePointTF::Update(uint32 diff)
{
// can update even in locked state if gathers the controlling faction
bool canupdate = ((((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled > 0) && m_activePlayers[0].size() > m_activePlayers[1].size()) ||
((((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled > 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)->m_IsLocked;
return canupdate && OPvPCapturePoint::Update(diff);
}
void OPvPCapturePointTF::ChangeState()
{
// if changing from controlling alliance to horde
if (m_OldState == OBJECTIVESTATE_ALLIANCE)
{
if (((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled)
((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled--;
sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_LOOSE_A));
}
// if changing from controlling horde to alliance
else if (m_OldState == OBJECTIVESTATE_HORDE)
{
if (((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled)
((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled--;
sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_LOOSE_H));
}
uint32 artkit = 21;
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
m_TowerState = TF_TOWERSTATE_A;
artkit = 2;
if (((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled<TF_TOWER_NUM)
((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled++;
sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_CAPTURE_A));
for (PlayerSet::iterator itr = m_activePlayers[0].begin(); itr != m_activePlayers[0].end(); ++itr)
(*itr)->AreaExploredOrEventHappens(TF_ALLY_QUEST);
break;
case OBJECTIVESTATE_HORDE:
m_TowerState = TF_TOWERSTATE_H;
artkit = 1;
if (((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled<TF_TOWER_NUM)
((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled++;
sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_CAPTURE_H));
for (PlayerSet::iterator itr = m_activePlayers[1].begin(); itr != m_activePlayers[1].end(); ++itr)
(*itr)->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;
}
GameObject* flag = HashMapHolder<GameObject>::Find(m_capturePointGUID);
if (flag)
flag->SetGoArtKit(artkit);
UpdateTowerState();
}
void OPvPCapturePointTF::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS, phase);
// send this too, sometimes it resets :S
SendUpdateWorldState(TF_UI_TOWER_SLIDER_N, m_neutralValuePct);
}
+117
View File
@@ -0,0 +1,117 @@
#ifndef OUTDOOR_PVP_TF_
#define OUTDOOR_PVP_TF_
#include "OutdoorPvPImpl.h"
const uint32 OutdoorPvPTFBuffZonesNum = 5;
const uint32 OutdoorPvPTFBuffZones[OutdoorPvPTFBuffZonesNum] = { 3519 /*Terokkar Forest*/, 3791 /*Sethekk Halls*/, 3789 /*Shadow Labyrinth*/, 3792 /*Mana-Tombs*/, 3790 /*Auchenai Crypts*/ };
// locked for 6 hours after capture
const uint32 TF_LOCK_TIME = 3600 * 6 * 1000;
// update lock timer every 1/4 minute (overkill, but this way it's sure the timer won't "jump" 2 minutes at once.)
const uint32 TF_LOCK_TIME_UPDATE = 15000;
// blessing of auchindoun
#define TF_CAPTURE_BUFF 33377
const uint32 TF_ALLY_QUEST = 11505;
const uint32 TF_HORDE_QUEST = 11506;
enum OutdoorPvPTF_TowerType{
TF_TOWER_NW = 0,
TF_TOWER_N,
TF_TOWER_NE,
TF_TOWER_SE,
TF_TOWER_S,
TF_TOWER_NUM
};
const go_type TFCapturePoints[TF_TOWER_NUM] = {
{183104,530,-3081.65,5335.03,17.1853,-2.14675,0,0,0.878817,-0.477159},
{183411,530,-2939.9,4788.73,18.987,2.77507,0,0,0.983255,0.182236},
{183412,530,-3174.94,4440.97,16.2281,1.86750,0,0.803857,0.594823},
{183413,530,-3603.31,4529.15,20.9077,0.994838,0,0,0.477159,0.878817},
{183414,530,-3812.37,4899.3,17.7249,0.087266,0,0,0.043619,0.999048}
};
struct tf_tower_world_state{
uint32 n;
uint32 h;
uint32 a;
};
const tf_tower_world_state TFTowerWorldStates[TF_TOWER_NUM] = {
{0xa79,0xa7a,0xa7b},
{0xa7e,0xa7d,0xa7c},
{0xa82,0xa81,0xa80},
{0xa88,0xa87,0xa86},
{0xa85,0xa84,0xa83}
};
const uint32 TFTowerPlayerEnterEvents[TF_TOWER_NUM] = {12226, 12497, 12486, 12499, 12501};
const uint32 TFTowerPlayerLeaveEvents[TF_TOWER_NUM] = {12225, 12496, 12487, 12498, 12500};
enum TFWorldStates{
TF_UI_TOWER_SLIDER_POS = 0xa41,
TF_UI_TOWER_SLIDER_N = 0xa40,
TF_UI_TOWER_SLIDER_DISPLAY = 0xa3f,
TF_UI_TOWER_COUNT_H = 0xa3e,
TF_UI_TOWER_COUNT_A = 0xa3d,
TF_UI_TOWERS_CONTROLLED_DISPLAY = 0xa3c,
TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT = 0x9d0,
TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT = 0x9ce,
TF_UI_LOCKED_TIME_HOURS = 0x9cd,
TF_UI_LOCKED_DISPLAY_NEUTRAL = 0x9cc,
TF_UI_LOCKED_DISPLAY_HORDE = 0xad0,
TF_UI_LOCKED_DISPLAY_ALLIANCE = 0xacf
};
enum TFTowerStates {
TF_TOWERSTATE_N = 1,
TF_TOWERSTATE_H = 2,
TF_TOWERSTATE_A = 4
};
class OPvPCapturePointTF : public OPvPCapturePoint
{
public:
OPvPCapturePointTF(OutdoorPvP * pvp, OutdoorPvPTF_TowerType type);
bool Update(uint32 diff);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
void UpdateTowerState();
protected:
OutdoorPvPTF_TowerType m_TowerType;
uint32 m_TowerState;
};
class OutdoorPvPTF : public OutdoorPvP
{
friend class OPvPCapturePointTF;
public:
OutdoorPvPTF();
bool SetupOutdoorPvP();
void HandlePlayerEnterZone(Player *plr, uint32 zone);
void HandlePlayerLeaveZone(Player *plr, uint32 zone);
bool Update(uint32 diff);
void FillInitialWorldStates(WorldPacket &data);
void SendRemoveWorldStates(Player * plr);
private:
bool m_IsLocked;
uint32 m_LockTimer;
uint32 m_LockTimerUpdate;
uint32 m_AllianceTowersControlled;
uint32 m_HordeTowersControlled;
uint32 hours_left, second_digit, first_digit;
};
#endif
+423
View File
@@ -0,0 +1,423 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "OutdoorPvPZM.h"
#include "ObjectMgr.h"
#include "OutdoorPvPMgr.h"
#include "Player.h"
#include "Creature.h"
#include "ObjectAccessor.h"
#include "WorldPacket.h"
#include "GossipDef.h"
#include "World.h"
OPvPCapturePointZM_Beacon::OPvPCapturePointZM_Beacon(OutdoorPvP *pvp, ZM_BeaconType type)
: OPvPCapturePoint(pvp), m_TowerType(type), m_TowerState(ZM_TOWERSTATE_N)
{
SetCapturePointData(ZMCapturePoints[type].entry,ZMCapturePoints[type].map,ZMCapturePoints[type].x,ZMCapturePoints[type].y,ZMCapturePoints[type].z,ZMCapturePoints[type].o,ZMCapturePoints[type].rot0,ZMCapturePoints[type].rot1,ZMCapturePoints[type].rot2,ZMCapturePoints[type].rot3);
}
void OPvPCapturePointZM_Beacon::FillInitialWorldStates(WorldPacket &data)
{
data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_n) << uint32(bool(m_TowerState & ZM_TOWERSTATE_N));
data << uint32(ZMBeaconInfo[m_TowerType].map_tower_n) << uint32(bool(m_TowerState & ZM_TOWERSTATE_N));
data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_a) << uint32(bool(m_TowerState & ZM_TOWERSTATE_A));
data << uint32(ZMBeaconInfo[m_TowerType].map_tower_a) << uint32(bool(m_TowerState & ZM_TOWERSTATE_A));
data << uint32(ZMBeaconInfo[m_TowerType].ui_tower_h) << uint32(bool(m_TowerState & ZM_TOWERSTATE_H));
data << uint32(ZMBeaconInfo[m_TowerType].map_tower_h) << uint32(bool(m_TowerState & ZM_TOWERSTATE_H));
}
void OPvPCapturePointZM_Beacon::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_n),uint32(bool(m_TowerState & ZM_TOWERSTATE_N)));
m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_n),uint32(bool(m_TowerState & ZM_TOWERSTATE_N)));
m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_a),uint32(bool(m_TowerState & ZM_TOWERSTATE_A)));
m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_a),uint32(bool(m_TowerState & ZM_TOWERSTATE_A)));
m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].ui_tower_h),uint32(bool(m_TowerState & ZM_TOWERSTATE_H)));
m_PvP->SendUpdateWorldState(uint32(ZMBeaconInfo[m_TowerType].map_tower_h),uint32(bool(m_TowerState & ZM_TOWERSTATE_H)));
}
bool OPvPCapturePointZM_Beacon::HandlePlayerEnter(Player *plr)
{
if (OPvPCapturePoint::HandlePlayerEnter(plr))
{
plr->SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_disp, 1);
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
plr->SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_pos, phase);
plr->SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_n, m_neutralValuePct);
return true;
}
return false;
}
void OPvPCapturePointZM_Beacon::HandlePlayerLeave(Player *plr)
{
plr->SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_disp, 0);
OPvPCapturePoint::HandlePlayerLeave(plr);
}
void OPvPCapturePointZM_Beacon::ChangeState()
{
// if changing from controlling alliance to horde
if (m_OldState == OBJECTIVESTATE_ALLIANCE)
{
if (((OutdoorPvPZM*)m_PvP)->m_AllianceTowersControlled)
((OutdoorPvPZM*)m_PvP)->m_AllianceTowersControlled--;
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(ZMBeaconLooseA[m_TowerType]));
}
// if changing from controlling horde to alliance
else if (m_OldState == OBJECTIVESTATE_HORDE)
{
if (((OutdoorPvPZM*)m_PvP)->m_HordeTowersControlled)
((OutdoorPvPZM*)m_PvP)->m_HordeTowersControlled--;
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(ZMBeaconLooseH[m_TowerType]));
}
switch(m_State)
{
case OBJECTIVESTATE_ALLIANCE:
m_TowerState = ZM_TOWERSTATE_A;
if (((OutdoorPvPZM*)m_PvP)->m_AllianceTowersControlled<ZM_NUM_BEACONS)
((OutdoorPvPZM*)m_PvP)->m_AllianceTowersControlled++;
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(ZMBeaconCaptureA[m_TowerType]));
break;
case OBJECTIVESTATE_HORDE:
m_TowerState = ZM_TOWERSTATE_H;
if (((OutdoorPvPZM*)m_PvP)->m_HordeTowersControlled<ZM_NUM_BEACONS)
((OutdoorPvPZM*)m_PvP)->m_HordeTowersControlled++;
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(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();
}
void OPvPCapturePointZM_Beacon::SendChangePhase()
{
// send this too, sometimes the slider disappears, dunno why :(
SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_disp, 1);
// send these updates to only the ones in this objective
uint32 phase = (uint32)ceil((m_value + m_maxValue) / (2 * m_maxValue) * 100.0f);
SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_pos, phase);
SendUpdateWorldState(ZMBeaconInfo[m_TowerType].slider_n, m_neutralValuePct);
}
bool OutdoorPvPZM::Update(uint32 diff)
{
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;
}
void OutdoorPvPZM::HandlePlayerEnterZone(Player * plr, uint32 zone)
{
if (plr->GetTeam() == ALLIANCE)
{
if (m_GraveYard->m_GraveYardState & ZM_GRAVEYARD_A)
plr->CastSpell(plr,ZM_CAPTURE_BUFF,true);
}
else
{
if (m_GraveYard->m_GraveYardState & ZM_GRAVEYARD_H)
plr->CastSpell(plr,ZM_CAPTURE_BUFF,true);
}
OutdoorPvP::HandlePlayerEnterZone(plr,zone);
}
void OutdoorPvPZM::HandlePlayerLeaveZone(Player * plr, uint32 zone)
{
// remove buffs
plr->RemoveAurasDueToSpell(ZM_CAPTURE_BUFF);
// remove flag
plr->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_A);
plr->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_H);
OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
}
OutdoorPvPZM::OutdoorPvPZM()
{
m_TypeId = OUTDOOR_PVP_ZM;
m_GraveYard = NULL;
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
}
bool OutdoorPvPZM::SetupOutdoorPvP()
{
m_AllianceTowersControlled = 0;
m_HordeTowersControlled = 0;
// add the zones affected by the pvp buff
for (int i = 0; i < OutdoorPvPZMBuffZonesNum; ++i)
RegisterZone(OutdoorPvPZMBuffZones[i]);
AddCapturePoint(new OPvPCapturePointZM_Beacon(this,ZM_BEACON_WEST));
AddCapturePoint(new OPvPCapturePointZM_Beacon(this,ZM_BEACON_EAST));
m_GraveYard = new OPvPCapturePointZM_GraveYard(this);
AddCapturePoint(m_GraveYard); // though the update function isn't used, the handleusego is!
return true;
}
void OutdoorPvPZM::HandleKillImpl(Player *plr, Unit * killed)
{
if (killed->GetTypeId() != TYPEID_PLAYER)
return;
if (plr->GetTeam() == ALLIANCE && killed->ToPlayer()->GetTeam() != ALLIANCE)
plr->CastSpell(plr,ZM_AlliancePlayerKillReward,true);
else if (plr->GetTeam() == HORDE && killed->ToPlayer()->GetTeam() != HORDE)
plr->CastSpell(plr,ZM_HordePlayerKillReward,true);
}
bool OPvPCapturePointZM_GraveYard::Update(uint32 /*diff*/)
{
bool retval = m_State != m_OldState;
m_State = m_OldState;
return retval;
}
int32 OPvPCapturePointZM_GraveYard::HandleOpenGo(Player *plr, uint64 guid)
{
uint32 retval = OPvPCapturePoint::HandleOpenGo(plr, guid);
if (retval >= 0)
{
if (plr->HasAura(ZM_BATTLE_STANDARD_A) && m_GraveYardState != ZM_GRAVEYARD_A)
{
if (m_GraveYardState == ZM_GRAVEYARD_H)
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_LOOSE_GY_H));
m_GraveYardState = ZM_GRAVEYARD_A;
DelObject(0); // only one gotype is used in the whole outdoor pvp, no need to call it a constant
AddObject(0,ZM_Banner_A.entry,ZM_Banner_A.map,ZM_Banner_A.x,ZM_Banner_A.y,ZM_Banner_A.z,ZM_Banner_A.o,ZM_Banner_A.rot0,ZM_Banner_A.rot1,ZM_Banner_A.rot2,ZM_Banner_A.rot3);
objmgr.RemoveGraveYardLink(ZM_GRAVEYARD_ID, ZM_GRAVEYARD_ZONE, HORDE); // rem gy
objmgr.AddGraveYardLink(ZM_GRAVEYARD_ID, ZM_GRAVEYARD_ZONE, ALLIANCE, false); // add gy
m_PvP->TeamApplyBuff(TEAM_ALLIANCE, ZM_CAPTURE_BUFF);
plr->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_A);
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_CAPTURE_GY_A));
}
else if (plr->HasAura(ZM_BATTLE_STANDARD_H) && m_GraveYardState != ZM_GRAVEYARD_H)
{
if (m_GraveYardState == ZM_GRAVEYARD_A)
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_LOOSE_GY_A));
m_GraveYardState = ZM_GRAVEYARD_H;
DelObject(0); // only one gotype is used in the whole outdoor pvp, no need to call it a constant
AddObject(0,ZM_Banner_H.entry,ZM_Banner_H.map,ZM_Banner_H.x,ZM_Banner_H.y,ZM_Banner_H.z,ZM_Banner_H.o,ZM_Banner_H.rot0,ZM_Banner_H.rot1,ZM_Banner_H.rot2,ZM_Banner_H.rot3);
objmgr.RemoveGraveYardLink(ZM_GRAVEYARD_ID, ZM_GRAVEYARD_ZONE, ALLIANCE); // rem gy
objmgr.AddGraveYardLink(ZM_GRAVEYARD_ID, ZM_GRAVEYARD_ZONE, HORDE, false); // add gy
m_PvP->TeamApplyBuff(TEAM_HORDE, ZM_CAPTURE_BUFF);
plr->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_H);
sWorld.SendZoneText(ZM_GRAVEYARD_ZONE,objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_ZM_CAPTURE_GY_H));
}
UpdateTowerState();
}
return retval;
}
OPvPCapturePointZM_GraveYard::OPvPCapturePointZM_GraveYard(OutdoorPvP *pvp)
: OPvPCapturePoint(pvp)
{
m_BothControllingFaction = 0;
m_GraveYardState = ZM_GRAVEYARD_N;
m_FlagCarrierGUID = 0;
// add field scouts here
AddCreature(ZM_ALLIANCE_FIELD_SCOUT,ZM_AllianceFieldScout.entry,ZM_AllianceFieldScout.teamval,ZM_AllianceFieldScout.map,ZM_AllianceFieldScout.x,ZM_AllianceFieldScout.y,ZM_AllianceFieldScout.z,ZM_AllianceFieldScout.o);
AddCreature(ZM_HORDE_FIELD_SCOUT,ZM_HordeFieldScout.entry,ZM_HordeFieldScout.teamval,ZM_HordeFieldScout.map,ZM_HordeFieldScout.x,ZM_HordeFieldScout.y,ZM_HordeFieldScout.z,ZM_HordeFieldScout.o);
// add neutral banner
AddObject(0,ZM_Banner_N.entry,ZM_Banner_N.map,ZM_Banner_N.x,ZM_Banner_N.y,ZM_Banner_N.z,ZM_Banner_N.o,ZM_Banner_N.rot0,ZM_Banner_N.rot1,ZM_Banner_N.rot2,ZM_Banner_N.rot3);
}
void OPvPCapturePointZM_GraveYard::UpdateTowerState()
{
m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_N,uint32(bool(m_GraveYardState & ZM_GRAVEYARD_N)));
m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_H,uint32(bool(m_GraveYardState & ZM_GRAVEYARD_H)));
m_PvP->SendUpdateWorldState(ZM_MAP_GRAVEYARD_A,uint32(bool(m_GraveYardState & ZM_GRAVEYARD_A)));
m_PvP->SendUpdateWorldState(ZM_MAP_ALLIANCE_FLAG_READY,uint32(m_BothControllingFaction == ALLIANCE));
m_PvP->SendUpdateWorldState(ZM_MAP_ALLIANCE_FLAG_NOT_READY,uint32(m_BothControllingFaction != ALLIANCE));
m_PvP->SendUpdateWorldState(ZM_MAP_HORDE_FLAG_READY,uint32(m_BothControllingFaction == HORDE));
m_PvP->SendUpdateWorldState(ZM_MAP_HORDE_FLAG_NOT_READY,uint32(m_BothControllingFaction != HORDE));
}
void OPvPCapturePointZM_GraveYard::FillInitialWorldStates(WorldPacket &data)
{
data << ZM_MAP_GRAVEYARD_N << uint32(bool(m_GraveYardState & ZM_GRAVEYARD_N));
data << ZM_MAP_GRAVEYARD_H << uint32(bool(m_GraveYardState & ZM_GRAVEYARD_H));
data << ZM_MAP_GRAVEYARD_A << uint32(bool(m_GraveYardState & ZM_GRAVEYARD_A));
data << ZM_MAP_ALLIANCE_FLAG_READY << uint32(m_BothControllingFaction == ALLIANCE);
data << ZM_MAP_ALLIANCE_FLAG_NOT_READY << uint32(m_BothControllingFaction != ALLIANCE);
data << ZM_MAP_HORDE_FLAG_READY << uint32(m_BothControllingFaction == HORDE);
data << ZM_MAP_HORDE_FLAG_NOT_READY << uint32(m_BothControllingFaction != HORDE);
}
void OPvPCapturePointZM_GraveYard::SetBeaconState(uint32 controlling_faction)
{
// nothing to do here
if (m_BothControllingFaction == controlling_faction)
return;
m_BothControllingFaction = controlling_faction;
switch(controlling_faction)
{
case ALLIANCE:
// if ally already controls the gy and taken back both beacons, return, nothing to do for us
if (m_GraveYardState & ZM_GRAVEYARD_A)
return;
// ally doesn't control the gy, but controls the side beacons -> add gossip option, add neutral banner
break;
case HORDE:
// if horde already controls the gy and taken back both beacons, return, nothing to do for us
if (m_GraveYardState & ZM_GRAVEYARD_H)
return;
// horde doesn't control the gy, but controls the side beacons -> add gossip option, add neutral banner
break;
default:
// if the graveyard is not neutral, then leave it that way
// if the graveyard is neutral, then we have to dispel the buff from the flag carrier
if (m_GraveYardState & ZM_GRAVEYARD_N)
{
// gy was neutral, thus neutral banner was spawned, it is possible that someone was taking the flag to the gy
if (m_FlagCarrierGUID)
{
// remove flag from carrier, reset flag carrier guid
Player * p = objmgr.GetPlayer(m_FlagCarrierGUID);
if (p)
{
p->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_A);
p->RemoveAurasDueToSpell(ZM_BATTLE_STANDARD_H);
}
m_FlagCarrierGUID = 0;
}
}
break;
}
// send worldstateupdate
UpdateTowerState();
}
bool OPvPCapturePointZM_GraveYard::CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso)
{
uint64 guid = c->GetGUID();
std::map<uint64,uint32>::iterator itr = m_CreatureTypes.find(guid);
if (itr != m_CreatureTypes.end())
{
if (itr->second == ZM_ALLIANCE_FIELD_SCOUT && plr->GetTeam() == ALLIANCE && m_BothControllingFaction == ALLIANCE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_A)
return true;
else if (itr->second == ZM_HORDE_FIELD_SCOUT && plr->GetTeam() == HORDE && m_BothControllingFaction == HORDE && !m_FlagCarrierGUID && m_GraveYardState != ZM_GRAVEYARD_H)
return true;
}
return false;
}
bool OPvPCapturePointZM_GraveYard::HandleGossipOption(Player *plr, uint64 guid, uint32 /*gossipid*/)
{
std::map<uint64,uint32>::iterator itr = m_CreatureTypes.find(guid);
if (itr != m_CreatureTypes.end())
{
Creature * cr = HashMapHolder<Creature>::Find(guid);
if (!cr)
return true;
// if the flag is already taken, then return
if (m_FlagCarrierGUID)
return true;
if (itr->second == ZM_ALLIANCE_FIELD_SCOUT)
{
cr->CastSpell(plr,ZM_BATTLE_STANDARD_A,true);
m_FlagCarrierGUID = plr->GetGUID();
}
else if (itr->second == ZM_HORDE_FIELD_SCOUT)
{
cr->CastSpell(plr,ZM_BATTLE_STANDARD_H,true);
m_FlagCarrierGUID = plr->GetGUID();
}
UpdateTowerState();
plr->PlayerTalkClass->CloseGossip();
return true;
}
return false;
}
bool OPvPCapturePointZM_GraveYard::HandleDropFlag(Player * /*plr*/, uint32 spellId)
{
switch(spellId)
{
case ZM_BATTLE_STANDARD_A:
m_FlagCarrierGUID = 0;
return true;
case ZM_BATTLE_STANDARD_H:
m_FlagCarrierGUID = 0;
return true;
}
return false;
}
void OutdoorPvPZM::FillInitialWorldStates(WorldPacket &data)
{
data << ZM_WORLDSTATE_UNK_1 << uint32(1);
for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
{
itr->second->FillInitialWorldStates(data);
}
}
void OutdoorPvPZM::SendRemoveWorldStates(Player *plr)
{
plr->SendUpdateWorldState(ZM_UI_TOWER_SLIDER_N_W,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_SLIDER_POS_W,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_SLIDER_DISPLAY_W,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_SLIDER_N_E,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_SLIDER_POS_E,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_SLIDER_DISPLAY_E,0);
plr->SendUpdateWorldState(ZM_WORLDSTATE_UNK_1,1);
plr->SendUpdateWorldState(ZM_UI_TOWER_EAST_N,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_EAST_H,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_EAST_A,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_WEST_N,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_WEST_H,0);
plr->SendUpdateWorldState(ZM_UI_TOWER_WEST_A,0);
plr->SendUpdateWorldState(ZM_MAP_TOWER_EAST_N,0);
plr->SendUpdateWorldState(ZM_MAP_TOWER_EAST_H,0);
plr->SendUpdateWorldState(ZM_MAP_TOWER_EAST_A,0);
plr->SendUpdateWorldState(ZM_MAP_GRAVEYARD_H,0);
plr->SendUpdateWorldState(ZM_MAP_GRAVEYARD_A,0);
plr->SendUpdateWorldState(ZM_MAP_GRAVEYARD_N,0);
plr->SendUpdateWorldState(ZM_MAP_TOWER_WEST_N,0);
plr->SendUpdateWorldState(ZM_MAP_TOWER_WEST_H,0);
plr->SendUpdateWorldState(ZM_MAP_TOWER_WEST_A,0);
plr->SendUpdateWorldState(ZM_MAP_HORDE_FLAG_READY,0);
plr->SendUpdateWorldState(ZM_MAP_HORDE_FLAG_NOT_READY,0);
plr->SendUpdateWorldState(ZM_MAP_ALLIANCE_FLAG_NOT_READY,0);
plr->SendUpdateWorldState(ZM_MAP_ALLIANCE_FLAG_READY,0);
}
+219
View File
@@ -0,0 +1,219 @@
/*
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef OUTDOOR_PVP_ZM_
#define OUTDOOR_PVP_ZM_
#include "OutdoorPvPImpl.h"
#include "Language.h"
const uint32 OutdoorPvPZMBuffZonesNum = 5;
// the buff is cast in these zones
const uint32 OutdoorPvPZMBuffZones[OutdoorPvPZMBuffZonesNum] = {3521,3607,3717,3715,3716};
// linked when the central tower is controlled
const uint32 ZM_GRAVEYARD_ZONE = 3521;
// linked when the central tower is controlled
const uint32 ZM_GRAVEYARD_ID = 969;
enum OutdoorPvPZMSpells
{
// cast on the players of the controlling faction
ZM_CAPTURE_BUFF = 33779, // twin spire blessing
// spell that the field scout casts on the player to carry the flag
ZM_BATTLE_STANDARD_A = 32430,
// spell that the field scout casts on the player to carry the flag
ZM_BATTLE_STANDARD_H = 32431,
// token create spell
ZM_AlliancePlayerKillReward = 32155,
// token create spell
ZM_HordePlayerKillReward = 32158
};
// banners 182527, 182528, 182529, gotta check them ingame
const go_type ZM_Banner_A = { 182527,530,253.54,7083.81,36.7728,-0.017453,0,0,0.008727,-0.999962 };
const go_type ZM_Banner_H = { 182528,530,253.54,7083.81,36.7728,-0.017453,0,0,0.008727,-0.999962 };
const go_type ZM_Banner_N = { 182529,530,253.54,7083.81,36.7728,-0.017453,0,0,0.008727,-0.999962 };
// horde field scout spawn data
const creature_type ZM_HordeFieldScout = {18564,67,530,296.625,7818.4,42.6294,5.18363};
// alliance field scout spawn data
const creature_type ZM_AllianceFieldScout = {18581,469,530,374.395,6230.08,22.8351,0.593412};
enum ZMCreatureTypes{
ZM_ALLIANCE_FIELD_SCOUT = 0,
ZM_HORDE_FIELD_SCOUT,
ZM_CREATURE_NUM
};
struct zm_beacon {
uint32 slider_disp;
uint32 slider_n;
uint32 slider_pos;
uint32 ui_tower_n;
uint32 ui_tower_h;
uint32 ui_tower_a;
uint32 map_tower_n;
uint32 map_tower_h;
uint32 map_tower_a;
uint32 event_enter;
uint32 event_leave;
};
enum ZM_BeaconType{
ZM_BEACON_EAST = 0,
ZM_BEACON_WEST,
ZM_NUM_BEACONS
};
const zm_beacon ZMBeaconInfo[ZM_NUM_BEACONS] = {
{2533,2535,2534,2560,2559,2558,2652,2651,2650,11807,11806},
{2527,2529,2528,2557,2556,2555,2646,2645,2644,11805,11804}
};
const uint32 ZMBeaconCaptureA[ZM_NUM_BEACONS] = {
LANG_OPVP_ZM_CAPTURE_EAST_A,
LANG_OPVP_ZM_CAPTURE_WEST_A
};
const uint32 ZMBeaconCaptureH[ZM_NUM_BEACONS] = {
LANG_OPVP_ZM_CAPTURE_EAST_H,
LANG_OPVP_ZM_CAPTURE_WEST_H
};
const uint32 ZMBeaconLooseA[ZM_NUM_BEACONS] = {
LANG_OPVP_ZM_LOOSE_EAST_A,
LANG_OPVP_ZM_LOOSE_WEST_A
};
const uint32 ZMBeaconLooseH[ZM_NUM_BEACONS] = {
LANG_OPVP_ZM_LOOSE_EAST_H,
LANG_OPVP_ZM_LOOSE_WEST_H
};
const go_type ZMCapturePoints[ZM_NUM_BEACONS] = {
{182523,530,303.243,6841.36,40.1245,-1.58825,0,0,0.71325,-0.700909},
{182522,530,336.466,7340.26,41.4984,-1.58825,0,0,0.71325,-0.700909}
};
enum OutdoorPvPZMWorldStates
{
ZM_UI_TOWER_SLIDER_N_W = 2529,
ZM_UI_TOWER_SLIDER_POS_W = 2528,
ZM_UI_TOWER_SLIDER_DISPLAY_W = 2527,
ZM_UI_TOWER_SLIDER_N_E = 2535,
ZM_UI_TOWER_SLIDER_POS_E = 2534,
ZM_UI_TOWER_SLIDER_DISPLAY_E = 2533,
ZM_WORLDSTATE_UNK_1 = 2653,
ZM_UI_TOWER_EAST_N = 2560,
ZM_UI_TOWER_EAST_H = 2559,
ZM_UI_TOWER_EAST_A = 2558,
ZM_UI_TOWER_WEST_N = 2557,
ZM_UI_TOWER_WEST_H = 2556,
ZM_UI_TOWER_WEST_A = 2555,
ZM_MAP_TOWER_EAST_N = 2652,
ZM_MAP_TOWER_EAST_H = 2651,
ZM_MAP_TOWER_EAST_A = 2650,
ZM_MAP_GRAVEYARD_H = 2649,
ZM_MAP_GRAVEYARD_A = 2648,
ZM_MAP_GRAVEYARD_N = 2647,
ZM_MAP_TOWER_WEST_N = 2646,
ZM_MAP_TOWER_WEST_H = 2645,
ZM_MAP_TOWER_WEST_A = 2644,
ZM_MAP_HORDE_FLAG_READY = 2658,
ZM_MAP_HORDE_FLAG_NOT_READY = 2657,
ZM_MAP_ALLIANCE_FLAG_NOT_READY = 2656,
ZM_MAP_ALLIANCE_FLAG_READY = 2655
};
enum ZM_TowerStateMask{
ZM_TOWERSTATE_N = 1,
ZM_TOWERSTATE_A = 2,
ZM_TOWERSTATE_H = 4
};
class OutdoorPvPZM;
class OPvPCapturePointZM_Beacon : public OPvPCapturePoint
{
friend class OutdoorPvPZM;
public:
OPvPCapturePointZM_Beacon(OutdoorPvP * pvp, ZM_BeaconType type);
void ChangeState();
void SendChangePhase();
void FillInitialWorldStates(WorldPacket & data);
// used when player is activated/inactivated in the area
bool HandlePlayerEnter(Player * plr);
void HandlePlayerLeave(Player * plr);
void UpdateTowerState();
protected:
ZM_BeaconType m_TowerType;
uint32 m_TowerState;
};
enum ZM_GraveYardState{
ZM_GRAVEYARD_N = 1,
ZM_GRAVEYARD_A = 2,
ZM_GRAVEYARD_H = 4
};
class OPvPCapturePointZM_GraveYard : public OPvPCapturePoint
{
friend class OutdoorPvPZM;
public:
OPvPCapturePointZM_GraveYard(OutdoorPvP * pvp);
bool Update(uint32 diff);
void ChangeState() {}
void FillInitialWorldStates(WorldPacket & data);
void UpdateTowerState();
int32 HandleOpenGo(Player *plr, uint64 guid);
void SetBeaconState(uint32 controlling_team); // not good atm
bool HandleGossipOption(Player * plr, uint64 guid, uint32 gossipid);
bool HandleDropFlag(Player * plr, uint32 spellId);
bool CanTalkTo(Player * plr, Creature * c, GossipMenuItems gso);
private:
uint32 m_GraveYardState;
protected:
uint32 m_BothControllingFaction;
uint64 m_FlagCarrierGUID;
};
class OutdoorPvPZM : public OutdoorPvP
{
friend class OPvPCapturePointZM_Beacon;
public:
OutdoorPvPZM();
bool SetupOutdoorPvP();
void HandlePlayerEnterZone(Player *plr, uint32 zone);
void HandlePlayerLeaveZone(Player *plr, uint32 zone);
bool Update(uint32 diff);
void FillInitialWorldStates(WorldPacket &data);
void SendRemoveWorldStates(Player * plr);
void HandleKillImpl(Player * plr, Unit * killed);
private:
OPvPCapturePointZM_GraveYard * m_GraveYard;
uint32 m_AllianceTowersControlled;
uint32 m_HordeTowersControlled;
};
// todo: flag carrier death/leave/mount/activitychange should give back the gossip options
#endif