root/trunk/src/game/OutdoorPvPTF.cpp @ 93

Revision 80, 13.9 kB (checked in by yumileroy, 17 years ago)

[svn] Fixed a crash in OutdoorPvP*::BuffTeam?().

Original author: w12x
Date: 2008-10-20 13:34:00-05:00

Line 
1#include "OutdoorPvPTF.h"
2#include "OutdoorPvPMgr.h"
3#include "WorldPacket.h"
4#include "Player.h"
5#include "ObjectMgr.h"
6#include "Language.h"
7#include "World.h"
8
9OutdoorPvPTF::OutdoorPvPTF()
10{
11    m_TypeId = OUTDOOR_PVP_TF;
12}
13
14OutdoorPvPObjectiveTF::OutdoorPvPObjectiveTF(OutdoorPvP *pvp, OutdoorPvPTF_TowerType type)
15: OutdoorPvPObjective(pvp), m_TowerType(type), m_TowerState(TF_TOWERSTATE_N)
16{
17    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);
18}
19
20void OutdoorPvPObjectiveTF::FillInitialWorldStates(WorldPacket &data)
21{
22    data << uint32(TFTowerWorldStates[m_TowerType].n) << uint32(bool(m_TowerState & TF_TOWERSTATE_N));
23    data << uint32(TFTowerWorldStates[m_TowerType].h) << uint32(bool(m_TowerState & TF_TOWERSTATE_H));
24    data << uint32(TFTowerWorldStates[m_TowerType].a) << uint32(bool(m_TowerState & TF_TOWERSTATE_A));
25}
26
27void OutdoorPvPTF::FillInitialWorldStates(WorldPacket &data)
28{
29    data << TF_UI_TOWER_SLIDER_POS << uint32(50);
30    data << TF_UI_TOWER_SLIDER_N << uint32(100);
31    data << TF_UI_TOWER_SLIDER_DISPLAY << uint32(0);
32
33    data << TF_UI_TOWER_COUNT_H << m_HordeTowersControlled;
34    data << TF_UI_TOWER_COUNT_A << m_AllianceTowersControlled;
35    data << TF_UI_TOWERS_CONTROLLED_DISPLAY << uint32(!m_IsLocked);
36
37    data << TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT << first_digit;
38    data << TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT << second_digit;
39    data << TF_UI_LOCKED_TIME_HOURS << hours_left;
40
41    data << TF_UI_LOCKED_DISPLAY_NEUTRAL << uint32(m_IsLocked && !m_HordeTowersControlled && !m_AllianceTowersControlled);
42    data << TF_UI_LOCKED_DISPLAY_HORDE << uint32(m_IsLocked && (m_HordeTowersControlled > m_AllianceTowersControlled));
43    data << TF_UI_LOCKED_DISPLAY_ALLIANCE << uint32(m_IsLocked && (m_HordeTowersControlled < m_AllianceTowersControlled));
44
45    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
46    {
47        (*itr)->FillInitialWorldStates(data);
48    }
49}
50
51void OutdoorPvPTF::SendRemoveWorldStates(Player * plr)
52{
53    plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS,uint32(0));
54    plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_N,uint32(0));
55    plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY,uint32(0));
56
57    plr->SendUpdateWorldState(TF_UI_TOWER_COUNT_H,uint32(0));
58    plr->SendUpdateWorldState(TF_UI_TOWER_COUNT_A,uint32(0));
59    plr->SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY,uint32(0));
60
61    plr->SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT,uint32(0));
62    plr->SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT,uint32(0));
63    plr->SendUpdateWorldState(TF_UI_LOCKED_TIME_HOURS,uint32(0));
64
65    plr->SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
66    plr->SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(0));
67    plr->SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(0));
68
69    for(int i = 0; i < TF_TOWER_NUM; ++i)
70    {
71        plr->SendUpdateWorldState(uint32(TFTowerWorldStates[i].n),uint32(0));
72        plr->SendUpdateWorldState(uint32(TFTowerWorldStates[i].h),uint32(0));
73        plr->SendUpdateWorldState(uint32(TFTowerWorldStates[i].a),uint32(0));
74    }
75}
76
77void OutdoorPvPObjectiveTF::UpdateTowerState()
78{
79    m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].n),uint32(bool(m_TowerState & TF_TOWERSTATE_N)));
80    m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].h),uint32(bool(m_TowerState & TF_TOWERSTATE_H)));
81    m_PvP->SendUpdateWorldState(uint32(TFTowerWorldStates[m_TowerType].a),uint32(bool(m_TowerState & TF_TOWERSTATE_A)));
82}
83
84bool OutdoorPvPObjectiveTF::HandlePlayerEnter(Player *plr)
85{
86    if(OutdoorPvPObjective::HandlePlayerEnter(plr))
87    {
88        plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 1);
89        uint32 phase = (uint32)ceil(( m_ShiftPhase + m_ShiftMaxPhase) / ( 2 * m_ShiftMaxPhase ) * 100.0f);
90        plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS, phase);
91        plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_N, m_NeutralValue);
92        return true;
93    }
94    return false;
95}
96
97void OutdoorPvPObjectiveTF::HandlePlayerLeave(Player *plr)
98{
99    plr->SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 0);
100    OutdoorPvPObjective::HandlePlayerLeave(plr);
101}
102
103bool OutdoorPvPObjectiveTF::HandleCapturePointEvent(Player *plr, uint32 eventId)
104{
105    if(eventId == TFTowerPlayerEnterEvents[m_TowerType])
106    {
107        this->HandlePlayerEnter(plr);
108        return true;
109    }
110    else if (eventId == TFTowerPlayerLeaveEvents[m_TowerType])
111    {
112        this->HandlePlayerLeave(plr);
113        return true;
114    }
115    return false;
116}
117
118void OutdoorPvPTF::BuffTeam(uint32 team)
119{
120    if(team == ALLIANCE)
121    {
122        for(std::set<uint64>::iterator itr = m_PlayerGuids[0].begin(); itr != m_PlayerGuids[0].end(); ++itr)
123        {
124            if(Player * plr = objmgr.GetPlayer(*itr))
125                if(plr->IsInWorld()) plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
126        }
127        for(std::set<uint64>::iterator itr = m_PlayerGuids[1].begin(); itr != m_PlayerGuids[1].end(); ++itr)
128        {
129            if(Player * plr = objmgr.GetPlayer(*itr))
130                if(plr->IsInWorld()) plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
131        }
132    }
133    else if(team == HORDE)
134    {
135        for(std::set<uint64>::iterator itr = m_PlayerGuids[1].begin(); itr != m_PlayerGuids[1].end(); ++itr)
136        {
137            if(Player * plr = objmgr.GetPlayer(*itr))
138                if(plr->IsInWorld()) plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
139        }
140        for(std::set<uint64>::iterator itr = m_PlayerGuids[0].begin(); itr != m_PlayerGuids[0].end(); ++itr)
141        {
142            if(Player * plr = objmgr.GetPlayer(*itr))
143                if(plr->IsInWorld()) plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
144        }
145    }
146    else
147    {
148        for(std::set<uint64>::iterator itr = m_PlayerGuids[0].begin(); itr != m_PlayerGuids[0].end(); ++itr)
149        {
150            if(Player * plr = objmgr.GetPlayer(*itr))
151                if(plr->IsInWorld()) plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
152        }
153        for(std::set<uint64>::iterator itr = m_PlayerGuids[1].begin(); itr != m_PlayerGuids[1].end(); ++itr)
154        {
155            if(Player * plr = objmgr.GetPlayer(*itr))
156                if(plr->IsInWorld()) plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
157        }
158    }
159}
160
161bool OutdoorPvPTF::Update(uint32 diff)
162{
163    bool changed = false;
164
165    if(changed = OutdoorPvP::Update(diff))
166    {
167        if(m_AllianceTowersControlled == TF_TOWER_NUM)
168        {
169            BuffTeam(ALLIANCE);
170            m_IsLocked = true;
171            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
172            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(0));
173            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(1));
174            SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(0));
175        }
176        else if(m_HordeTowersControlled == TF_TOWER_NUM)
177        {
178            BuffTeam(HORDE);
179            m_IsLocked = true;
180            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
181            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(1));
182            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(0));
183            SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(0));
184        }
185        else
186            BuffTeam(NULL);
187        SendUpdateWorldState(TF_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
188        SendUpdateWorldState(TF_UI_TOWER_COUNT_H, m_HordeTowersControlled);
189    }
190    if(m_IsLocked)
191    {
192        // lock timer is down, release lock
193        if(m_LockTimer < diff)
194        {
195            m_LockTimer = TF_LOCK_TIME;
196            m_LockTimerUpdate = 0;
197            m_IsLocked = false;
198            SendUpdateWorldState(TF_UI_TOWERS_CONTROLLED_DISPLAY, uint32(1));
199            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_NEUTRAL,uint32(0));
200            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_HORDE,uint32(0));
201            SendUpdateWorldState(TF_UI_LOCKED_DISPLAY_ALLIANCE,uint32(0));
202        }
203        else
204        {
205            // worldstateui update timer is down, update ui with new time data
206            if(m_LockTimerUpdate < diff)
207            {
208                m_LockTimerUpdate = TF_LOCK_TIME_UPDATE;
209                uint32 minutes_left = m_LockTimer / 60000;
210                hours_left = minutes_left / 60;
211                minutes_left -= hours_left * 60;
212                second_digit = minutes_left % 10;
213                first_digit = minutes_left / 10;
214
215                SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_FIRST_DIGIT,first_digit);
216                SendUpdateWorldState(TF_UI_LOCKED_TIME_MINUTES_SECOND_DIGIT,second_digit);
217                SendUpdateWorldState(TF_UI_LOCKED_TIME_HOURS,hours_left);
218            } else m_LockTimerUpdate -= diff;
219            m_LockTimer -= diff;
220        }
221    }
222    return changed;
223}
224
225void OutdoorPvPTF::HandlePlayerEnterZone(Player * plr, uint32 zone)
226{
227    if(plr->GetTeam() == ALLIANCE)
228    {
229        if(m_AllianceTowersControlled >= TF_TOWER_NUM)
230            plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
231    }
232    else
233    {
234        if(m_HordeTowersControlled >= TF_TOWER_NUM)
235            plr->CastSpell(plr,TF_CAPTURE_BUFF,true);
236    }
237    OutdoorPvP::HandlePlayerEnterZone(plr,zone);
238}
239
240void OutdoorPvPTF::HandlePlayerLeaveZone(Player * plr, uint32 zone)
241{
242    // remove buffs
243    plr->RemoveAurasDueToSpell(TF_CAPTURE_BUFF);
244    OutdoorPvP::HandlePlayerLeaveZone(plr, zone);
245}
246
247bool OutdoorPvPTF::SetupOutdoorPvP()
248{
249    m_AllianceTowersControlled = 0;
250    m_HordeTowersControlled = 0;
251
252    m_IsLocked = false;
253    m_LockTimer = TF_LOCK_TIME;
254    m_LockTimerUpdate = 0; 
255    hours_left = 6;
256    second_digit = 0;
257    first_digit = 0;
258
259    // add the zones affected by the pvp buff
260    for(int i = 0; i < OutdoorPvPTFBuffZonesNum; ++i)
261        sOutdoorPvPMgr.AddZone(OutdoorPvPTFBuffZones[i],this);
262
263    m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_NW));
264    m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_N));
265    m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_NE));
266    m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_SE));
267    m_OutdoorPvPObjectives.insert(new OutdoorPvPObjectiveTF(this,TF_TOWER_S));
268
269    return true;
270}
271
272bool OutdoorPvPObjectiveTF::Update(uint32 diff)
273{
274    // can update even in locked state if gathers the controlling faction
275    bool canupdate = ((((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled > 0) && this->m_AllianceActivePlayerCount > this->m_HordeActivePlayerCount) ||
276            ((((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled > 0) && this->m_AllianceActivePlayerCount < this->m_HordeActivePlayerCount);
277    // if gathers the other faction, then only update if the pvp is unlocked
278    canupdate = canupdate || !((OutdoorPvPTF*)m_PvP)->m_IsLocked;
279    if(canupdate && OutdoorPvPObjective::Update(diff))
280    {
281        if(m_OldState != m_State)
282        {
283            // if changing from controlling alliance to horde
284            if( m_OldState == OBJECTIVESTATE_ALLIANCE )
285            {
286                if(((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled)
287                    ((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled--;
288                sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_LOOSE_A));
289            }
290            // if changing from controlling horde to alliance
291            else if ( m_OldState == OBJECTIVESTATE_HORDE )
292            {
293                if(((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled)
294                    ((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled--;
295                sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_LOOSE_H));
296            }
297
298            uint32 artkit = 21;
299
300            switch(m_State)
301            {
302            case OBJECTIVESTATE_ALLIANCE:
303                m_TowerState = TF_TOWERSTATE_A;
304                artkit = 2;
305                if(((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled<TF_TOWER_NUM)
306                    ((OutdoorPvPTF*)m_PvP)->m_AllianceTowersControlled++;
307                sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_CAPTURE_A));
308                break;
309            case OBJECTIVESTATE_HORDE:
310                m_TowerState = TF_TOWERSTATE_H;
311                artkit = 1;
312                if(((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled<TF_TOWER_NUM)
313                    ((OutdoorPvPTF*)m_PvP)->m_HordeTowersControlled++;
314                sWorld.SendZoneText(OutdoorPvPTFBuffZones[0],objmgr.GetTrinityStringForDBCLocale(LANG_OPVP_TF_CAPTURE_H));
315                break;
316            case OBJECTIVESTATE_NEUTRAL:
317            case OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE:
318            case OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE:
319            case OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE:
320            case OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE:
321                m_TowerState = TF_TOWERSTATE_N;
322                break;
323            }
324
325            GameObject* flag = HashMapHolder<GameObject>::Find(m_CapturePoint);
326            if(flag)
327            {
328                flag->SetGoArtKit(artkit);
329                flag->SendUpdateObjectToAllExcept(NULL);
330            }
331
332            UpdateTowerState();
333        }
334
335        if(m_ShiftPhase != m_OldPhase)
336        {
337            // send this too, sometimes the slider disappears, dunno why :(
338            SendUpdateWorldState(TF_UI_TOWER_SLIDER_DISPLAY, 1);
339            // send these updates to only the ones in this objective
340            uint32 phase = (uint32)ceil(( m_ShiftPhase + m_ShiftMaxPhase) / ( 2 * m_ShiftMaxPhase ) * 100.0f);
341            SendUpdateWorldState(TF_UI_TOWER_SLIDER_POS, phase);
342            // send this too, sometimes it resets :S
343            SendUpdateWorldState(TF_UI_TOWER_SLIDER_N, m_NeutralValue);
344        }
345        return true;
346    }
347    return false;
348}
Note: See TracBrowser for help on using the browser.