Index: src/game/OutdoorPvP.cpp =================================================================== --- src/game/OutdoorPvP.cpp (revision 0) +++ src/game/OutdoorPvP.cpp (revision 0) @@ -0,0 +1,8 @@ +#include "OutdoorPvP.h" +#include "OutdoorPvPMgr.h" + +void OutdoorPvP::HandlePlayerLeaveZone(Player * plr, uint32 zone) +{ + for(OutdoorPvPObjectiveMap::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr) + itr->second.HandlePlayerLeave(plr); +} \ No newline at end of file Index: src/game/OutdoorPvP.h =================================================================== --- src/game/OutdoorPvP.h (revision 0) +++ src/game/OutdoorPvP.h (revision 0) @@ -0,0 +1,63 @@ +#ifndef OUTDOOR_PVP_H_ +#define OUTDOOR_PVP_H_ + +#include "Util.h" + +#include +#include + +// some class predefs +class Player; +class GameObject; + +class OutdoorPvPObjective +{ +public: + // when a team takes over an objective area, spawn / despawn gos and creatures accordingly + virtual void SpawnNPCsForTeam(uint32 team) {} + virtual void SpawnGOsForTeam(uint32 team) {} + virtual void DeSpawnNPCsForTeam(uint32 team) {} + virtual void DeSpawnGOsForTeam(uint32 team) {} + + virtual void HandlePlayerEnter(Player * plr) {} + virtual void HandlePlayerLeave(Player * plr) {} +protected: + // players in the area of the objective + // 0 for ally, 1 for horde + std::set m_PlayerGuids[2]; +}; + +// base class for specific outdoor pvp handlers +class OutdoorPvP +{ +public: + // ctor + OutdoorPvP() {} + // dtor + ~OutdoorPvP() {} + + typedef std::map OutdoorPvPObjectiveMap; + + // called from Player::UpdateArea and when stealth status changes + virtual void HandlePlayerEnterAreaFlag(Player * plr, uint32 areaflag) {} + virtual void HandlePlayerLeaveAreaFlag(Player * plr, uint32 areaflag) {} + // called from Player::UpdateZone to add / remove buffs given by outdoor pvp events + virtual void HandlePlayerEnterZone(Player * plr, uint32 zone) {} + virtual void HandlePlayerLeaveZone(Player * plr, uint32 zone); + // called when a player triggers an areatrigger + virtual void HandleAreaTrigger(Player * plr, uint32 trigger) {} + // called on go use + virtual void HandleGOUse(Player * plr, GameObject * go) {} + + // setup stuff + virtual bool SetupOutdoorPvP() {return true;} + + // + virtual void TeamTakeOverArea() {} + + virtual void Update(uint32 diff) {} +protected: + OutdoorPvPObjectiveMap m_OutdoorPvPObjectives; +}; + +#endif /*OUTDOOR_PVP_H_*/ \ No newline at end of file Index: src/game/OutdoorPvPEPL.cpp =================================================================== --- src/game/OutdoorPvPEPL.cpp (revision 0) +++ src/game/OutdoorPvPEPL.cpp (revision 0) @@ -0,0 +1,10 @@ +#include "OutdoorPvPEPL.h" +#include "OutdoorPvP.h" +#include "OutdoorPvPMgr.h" + +bool OutdoorPvPEPL::SetupOutdoorPvP() +{ + for(int i = 0; i < OutdoorPvPEPLBuffZonesNum; ++i) + sOutdoorPvPMgr.AddZone(OutdoorPvPEPLBuffZones[i],this); + return true; +} \ No newline at end of file Index: src/game/OutdoorPvPEPL.h =================================================================== --- src/game/OutdoorPvPEPL.h (revision 0) +++ src/game/OutdoorPvPEPL.h (revision 0) @@ -0,0 +1,37 @@ +#ifndef OUTDOOR_PVP_EPL_ +#define OUTDOOR_PVP_EPL_ + +#include "OutdoorPvP.h" + +#define OutdoorPvPEPLBuffZonesNum 3 + // EPL Stratholme Scholomance +const uint32 OutdoorPvPEPLBuffZones[OutdoorPvPEPLBuffZonesNum] = { 139, 2017, 2057 }; + +// crown guard tower +class OutdoorPvPObjectiveEPL_CGT : public OutdoorPvPObjective +{ + +}; + +// eastwall tower +class OutdoorPvPObjectiveEPL_EWT : public OutdoorPvPObjective +{ +}; + +// northpass tower +class OutdoorPvPObjectiveEPL_NPT : public OutdoorPvPObjective +{ +}; + +// plaguewood tower +class OutdoorPvPObjectiveEPL_PWT : public OutdoorPvPObjective +{ +}; + +class OutdoorPvPEPL : public OutdoorPvP +{ +public: + virtual bool SetupOutdoorPvP(); +}; + +#endif \ No newline at end of file Index: src/game/OutdoorPvPMgr.cpp =================================================================== --- src/game/OutdoorPvPMgr.cpp (revision 0) +++ src/game/OutdoorPvPMgr.cpp (revision 0) @@ -0,0 +1,66 @@ +#include "OutdoorPvPMgr.h" +#include "OutdoorPvPEPL.h" +#include "Player.h" +#include "Policies/SingletonImp.h" + +INSTANTIATE_SINGLETON_1( OutdoorPvPMgr ); + +OutdoorPvPMgr::OutdoorPvPMgr() +{ +} + +OutdoorPvPMgr::~OutdoorPvPMgr() +{ +} + +void OutdoorPvPMgr::InitOutdoorPvP() +{ + OutdoorPvP * pOP = new OutdoorPvPEPL; + if(!pOP->SetupOutdoorPvP()) + delete pOP; + else + m_OutdoorPvPSet.insert(pOP); +} + +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()) + { + // no handle for this zone, return + return; + } + plr->SetInOutdoorPvPArea(true); + // add possibly beneficial buffs to plr for zone + itr->second->HandlePlayerEnterZone(plr, zoneid); +} + +void OutdoorPvPMgr::HandlePlayerLeaveZone(Player *plr, uint32 zoneid) +{ + OutdoorPvPMap::iterator itr = m_OutdoorPvPMap.find(zoneid); + if(itr == m_OutdoorPvPMap.end()) + { + // no handle for this zone, return + return; + } + plr->SetInOutdoorPvPArea(false); + // inform the OutdoorPvP class of the leaving, it should remove the player from all objectives + itr->second->HandlePlayerLeaveZone(plr, zoneid); +} + +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; +} \ No newline at end of file Index: src/game/OutdoorPvPMgr.h =================================================================== --- src/game/OutdoorPvPMgr.h (revision 0) +++ src/game/OutdoorPvPMgr.h (revision 0) @@ -0,0 +1,40 @@ +#ifndef OUTDOOR_PVP_MGR_H_ +#define OUTDOOR_PVP_MGR_H_ + +#include "OutdoorPvP.h" +#include "Policies/Singleton.h" + +// 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); + // return assigned outdoor pvp + OutdoorPvP * GetOutdoorPvPToZoneId(uint32 zoneid); + + void AddZone(uint32 zoneid, OutdoorPvP * handle); + + typedef std::set OutdoorPvPSet; + typedef std::map 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; +}; + +#define sOutdoorPvPMgr MaNGOS::Singleton::Instance() + +#endif /*OUTDOOR_PVP_MGR_H_*/ \ No newline at end of file Index: src/game/Player.cpp =================================================================== --- src/game/Player.cpp (revision 5157) +++ src/game/Player.cpp (working copy) @@ -53,6 +53,8 @@ #include "BattleGround.h" #include "BattleGroundMgr.h" #include "BattleGroundAB.h" +#include "OutdoorPvP.h" +#include "OutdoorPvPMgr.h" #include "ArenaTeam.h" #include "Chat.h" #include "Database/DatabaseImpl.h" @@ -118,6 +120,11 @@ m_dismountCost = 0; + m_areaFlagUpdateId = 0; + m_areaFlagUpdateTimer = 0; + + m_InOutdoorPvPArea = false; + m_nextSave = sWorld.getConfig(CONFIG_INTERVAL_SAVE); // randomize first save time in range [CONFIG_INTERVAL_SAVE] around [CONFIG_INTERVAL_SAVE] @@ -949,6 +956,20 @@ m_zoneUpdateTimer -= p_time; } + if (m_areaFlagUpdateTimer > 0) + { + if(p_time >= m_areaFlagUpdateTimer) + { + uint32 newareaflag = GetAreaFlag(); + if( m_areaFlagUpdateId != newareaflag ) + UpdateAreaFlag(newareaflag); + else + m_areaFlagUpdateTimer = ZONE_UPDATE_INTERVAL; + } + else + m_areaFlagUpdateTimer -= p_time; + } + if (isAlive()) { RegenerateAll(); @@ -4958,6 +4979,11 @@ GetSession()->SendPacket(data); } +uint32 Player::GetAreaFlag() +{ + return MapManager::Instance().GetBaseMap(GetMapId())->GetAreaFlag(GetPositionX(),GetPositionY()); +} + void Player::CheckExploreSystem() { if (!isAlive()) @@ -5707,8 +5733,56 @@ return zone; } +void Player::UpdateAreaFlag(uint32 newAreaFlag) +{ + m_areaFlagUpdateTimer = ZONE_UPDATE_INTERVAL; + + AreaTableEntry const* oldarea = GetAreaEntryByAreaFlag(m_areaFlagUpdateId); + AreaTableEntry const* newarea = GetAreaEntryByAreaFlag(newAreaFlag); + + // return if either area not found + if(!oldarea || !newarea) + { + m_areaFlagUpdateId = newAreaFlag; + return; + } + + // notify of leaving old areaflag if in outdoor pvp + if(oldarea->flags & 0x8000) + { + if(InOutdoorPvPArea()) + { + OutdoorPvP * pvp = sOutdoorPvPMgr.GetOutdoorPvPToZoneId(GetZoneId()); + if(pvp) + { + pvp->HandlePlayerLeaveAreaFlag(this, m_areaFlagUpdateId); + } + } + } + + // change after calling the leave () stuff + m_areaFlagUpdateId = newAreaFlag; + + // notify of entering if on outdoor pvp + if(newarea->flags & 0x8000) + { + if(InOutdoorPvPArea()) + { + OutdoorPvP * pvp = sOutdoorPvPMgr.GetOutdoorPvPToZoneId(GetZoneId()); + if(pvp) + { + pvp->HandlePlayerEnterAreaFlag(this, m_areaFlagUpdateId); + } + } + } +} + void Player::UpdateZone(uint32 newZone) { + AreaTableEntry const* oldzone = GetAreaEntryByAreaID(newZone); + if(oldzone && oldzone->flags & 0x8000) + sOutdoorPvPMgr.HandlePlayerLeaveZone(this, oldzone->ID); + m_zoneUpdateId = newZone; m_zoneUpdateTimer = ZONE_UPDATE_INTERVAL; @@ -5716,6 +5790,13 @@ if(!zone) return; + if(zone->flags & 0x8000) + sOutdoorPvPMgr.HandlePlayerEnterZone(this, zone->ID); + + uint32 areaFlag = GetAreaFlag(); + if(m_areaFlagUpdateId != areaFlag) + UpdateAreaFlag(areaFlag); + if (sWorld.getConfig(CONFIG_WEATHER)) { Weather *wth = sWorld.FindWeather(zone->ID); @@ -16159,3 +16240,8 @@ item->SendTimeUpdate(this); } } + +OutdoorPvP * Player::GetOutdoorPvP() const +{ + return sOutdoorPvPMgr.GetOutdoorPvPToZoneId(GetZoneId()); +} Index: src/game/Player.h =================================================================== --- src/game/Player.h (revision 5157) +++ src/game/Player.h (working copy) @@ -45,6 +45,7 @@ class PlayerMenu; class Transport; class UpdateMask; +class OutdoorPvP; typedef std::deque PlayerMails; @@ -1532,6 +1533,9 @@ void SetDontMove(bool dontMove); bool GetDontMove() const { return m_dontMove; } + uint32 GetAreaFlag(); + void UpdateAreaFlag(uint32 areaFlag); + void CheckExploreSystem(void); static uint32 TeamForRace(uint8 race); @@ -1713,6 +1717,14 @@ bool GetBGAccessByLevel(uint32 bgTypeId) const; /*********************************************************/ + /*** OUTDOOR PVP SYSTEM ***/ + /*********************************************************/ + + bool InOutdoorPvPArea() { return m_InOutdoorPvPArea; } + void SetInOutdoorPvPArea(bool in) { m_InOutdoorPvPArea = in; } + OutdoorPvP * GetOutdoorPvP() const; + + /*********************************************************/ /*** REST SYSTEM ***/ /*********************************************************/ @@ -2014,6 +2026,11 @@ uint32 m_deathTimer; time_t m_resurrectingSicknessExpire; + uint32 m_areaFlagUpdateId; + uint32 m_areaFlagUpdateTimer; + + bool m_InOutdoorPvPArea; + uint32 m_restTime; uint32 m_WeaponProficiency; Index: win/VC90/game.vcproj =================================================================== --- win/VC90/game.vcproj (revision 5157) +++ win/VC90/game.vcproj (working copy) @@ -467,6 +467,30 @@ > + + + + + + + + + + + +