aboutsummaryrefslogtreecommitdiff
path: root/src/game/OutdoorPvPTF.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/OutdoorPvPTF.cpp')
-rw-r--r--src/game/OutdoorPvPTF.cpp348
1 files changed, 348 insertions, 0 deletions
diff --git a/src/game/OutdoorPvPTF.cpp b/src/game/OutdoorPvPTF.cpp
new file mode 100644
index 00000000000..7fff6fbdd4f
--- /dev/null
+++ b/src/game/OutdoorPvPTF.cpp
@@ -0,0 +1,348 @@
+#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;
+}
+
+OutdoorPvPObjectiveTF::OutdoorPvPObjectiveTF(OutdoorPvP *pvp, OutdoorPvPTF_TowerType type)
+: OutdoorPvPObjective(pvp), m_TowerType(type), m_TowerState(TF_TOWERSTATE_N)
+{
+ AddCapturePoint(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 OutdoorPvPObjectiveTF::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(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
+ {
+ (*itr)->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 OutdoorPvPObjectiveTF::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 OutdoorPvPObjectiveTF::HandlePlayerEnter(Player *plr)
+{
+ if(OutdoorPvPObjective::HandlePlayerEnter(plr))
+ {
+ plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 1);
+ uint32 phase = (uint32)ceil(( m_ShiftPhase + m_ShiftMaxPhase) / ( 2 * m_ShiftMaxPhase ) * 100.0f);
+ plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS, phase);
+ plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_N, m_NeutralValue);
+ return true;
+ }
+ return false;
+}
+
+void OutdoorPvPObjectiveTF::HandlePlayerLeave(Player *plr)
+{
+ plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 0);
+ OutdoorPvPObjective::HandlePlayerLeave(plr);
+}
+
+bool OutdoorPvPObjectiveTF::HandleCapturePointEvent(Player *plr, uint32 eventId)
+{
+ if(eventId == TFTowerPlayerEnterEvents[m_TowerType])
+ {
+ this->HandlePlayerEnter(plr);
+ return true;
+ }
+ else if (eventId == TFTowerPlayerLeaveEvents[m_TowerType])
+ {
+ this->HandlePlayerLeave(plr);
+ return true;
+ }
+ return false;
+}
+
+void OutdoorPvPTF::BuffTeam(uint32 team)
+{
+ if(team == ALLIANCE)
+ {
+ for(std::set<uint64>::iterator itr = m_PlayerGuids[0].begin(); itr != m_PlayerGuids[0].end(); ++itr)
+ {
+ if(Player * plr = objmgr.GetPlayer(*itr))
+ plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
+ }
+ for(std::set<uint64>::iterator itr = m_PlayerGuids[1].begin(); itr != m_PlayerGuids[1].end(); ++itr)
+ {
+ if(Player * plr = objmgr.GetPlayer(*itr))
+ plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
+ }
+ }
+ else if(team == HORDE)
+ {
+ for(std::set<uint64>::iterator itr = m_PlayerGuids[1].begin(); itr != m_PlayerGuids[1].end(); ++itr)
+ {
+ if(Player * plr = objmgr.GetPlayer(*itr))
+ plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
+ }
+ for(std::set<uint64>::iterator itr = m_PlayerGuids[0].begin(); itr != m_PlayerGuids[0].end(); ++itr)
+ {
+ if(Player * plr = objmgr.GetPlayer(*itr))
+ plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
+ }
+ }
+ else
+ {
+ for(std::set<uint64>::iterator itr = m_PlayerGuids[0].begin(); itr != m_PlayerGuids[0].end(); ++itr)
+ {
+ if(Player * plr = objmgr.GetPlayer(*itr))
+ plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
+ }
+ for(std::set<uint64>::iterator itr = m_PlayerGuids[1].begin(); itr != m_PlayerGuids[1].end(); ++itr)
+ {
+ if(Player * plr = objmgr.GetPlayer(*itr))
+ plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
+ }
+ }
+}
+
+bool OutdoorPvPTF::Update(uint32 diff)
+{
+ bool changed = false;
+
+ if(changed = OutdoorPvP::Update(diff))
+ {
+ if(m_AllianceTowersControlled == TF_TOWER_NUM)
+ {
+ BuffTeam(ALLIANCE);
+ 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)
+ {
+ BuffTeam(HORDE);
+ 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
+ BuffTeam(NULL);
+ 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)
+ sOutdoorPvPMgr.AddZone(OutdoorPvPTFBuffZones[i],this);
+
+ m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_NW));
+ m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_N));
+ m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_NE));
+ m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_SE));
+ m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_S));
+
+ return true;
+}
+
+bool OutdoorPvPObjectiveTF::Update(uint32 diff)
+{
+ // can update even in locked state if gathers the controlling faction
+ bool canupdate = ((((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled > 0) && this->m_AllianceActivePlayerCount > this->m_HordeActivePlayerCount) ||
+ ((((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled > 0) && this->m_AllianceActivePlayerCount < this->m_HordeActivePlayerCount);
+ // if gathers the other faction, then only update if the pvp is unlocked
+ canupdate = canupdate || !((OutdoorPvPTF*)m_PvP)->m_IsLocked;
+ if(canupdate && OutdoorPvPObjective::Update(diff))
+ {
+ if(m_OldState != m_State)
+ {
+ // 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));
+ 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));
+ 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_CapturePoint);
+ if(flag)
+ {
+ flag->SetGoArtKit(artkit);
+ flag->SendUpdateObjectToAllExcept(NULL);
+ }
+
+ UpdateTowerState();
+ }
+
+ if(m_ShiftPhase != m_OldPhase)
+ {
+ // 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_ShiftPhase + m_ShiftMaxPhase) / ( 2 * m_ShiftMaxPhase ) * 100.0f);
+ SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS, phase);
+ // send this too, sometimes it resets :S
+ SendUpdateWorldState(TF_UI_TOWER_SLIDER_N, m_NeutralValue);
+ }
+ return true;
+ }
+ return false;
+}