root/trunk/src/game/OutdoorPvP.cpp @ 83

Revision 44, 23.4 kB (checked in by yumileroy, 17 years ago)

[svn] * Merge Temp dev SVN with Assembla.
* Changes include:

  • Implementation of w12x's Outdoor PvP and Game Event Systems.
  • Temporary removal of IRC Chat Bot (until infinite loop when disabled is fixed).
  • All mangos -> trinity (to convert your mangos_string table, please run mangos_string_to_trinity_string.sql).
  • Improved Config cleanup.
  • And many more changes.

Original author: Seline
Date: 2008-10-14 11:57:03-05:00

Line 
1#include "OutdoorPvP.h"
2#include "OutdoorPvPMgr.h"
3#include "ObjectAccessor.h"
4#include "ObjectMgr.h"
5#include "Map.h"
6#include "MapManager.h"
7#include "OutdoorPvPObjectiveAI.h"
8#include "Group.h"
9#include "WorldPacket.h"
10
11OutdoorPvPObjective::OutdoorPvPObjective(OutdoorPvP * pvp) 
12: m_PvP(pvp), m_AllianceActivePlayerCount(0), m_HordeActivePlayerCount(0),
13m_ShiftTimer(0), m_ShiftPhase(0), m_ShiftMaxPhase(0), m_OldPhase(0),
14m_State(0), m_OldState(0), m_CapturePoint(0), m_NeutralValue(0), m_ShiftMaxCaptureSpeed(0), m_CapturePointCreature(0)
15{
16}
17
18bool OutdoorPvPObjective::HandlePlayerEnter(Player * plr)
19{
20    // only called if really entered, so no use in the return value anymore
21    // player distance and activity state was checked already in the AI
22    std::set<uint64>::iterator pitr = m_ActivePlayerGuids.find(plr->GetGUID());
23    // if not already counted as active, add player
24    if(pitr == m_ActivePlayerGuids.end())
25    {
26        if(plr->GetTeam() == ALLIANCE)
27            ++m_AllianceActivePlayerCount;
28        else
29            ++m_HordeActivePlayerCount;
30        m_ActivePlayerGuids.insert(plr->GetGUID());
31        sLog.outDebug("player %u entered an outdoorpvpobjective", plr->GetGUIDLow());
32        return true;
33    }
34    return true;
35}
36
37void OutdoorPvPObjective::HandlePlayerLeave(Player * plr)
38{
39    // only decrease the count if the player is in the active list
40    if(m_ActivePlayerGuids.find(plr->GetGUID())!=m_ActivePlayerGuids.end())
41    {
42        if(plr->GetTeam() == ALLIANCE)
43            --m_AllianceActivePlayerCount;
44        else
45            --m_HordeActivePlayerCount;
46        m_ActivePlayerGuids.erase(plr->GetGUID());
47    }
48}
49
50void OutdoorPvPObjective::HandlePlayerActivityChanged(Player * plr)
51{
52    if(m_CapturePointCreature)
53        if(Creature * c = HashMapHolder<Creature>::Find(m_CapturePointCreature))
54            if(c->AI())
55                c->AI()->MoveInLineOfSight(plr);
56}
57
58bool OutdoorPvPObjective::AddObject(uint32 type, uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
59{
60    GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
61    if (!goinfo)
62        return false;
63
64    uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
65
66    GameObjectData& data = objmgr.NewGOData(guid);
67
68    data.id             = entry;
69    data.mapid          = map;
70    data.posX           = x;
71    data.posY           = y;
72    data.posZ           = z;
73    data.orientation    = o;
74    data.rotation0      = rotation0;
75    data.rotation1      = rotation1;
76    data.rotation2      = rotation2;
77    data.rotation3      = rotation3;
78    data.spawntimesecs  = 0;
79    data.animprogress   = 100;
80    data.spawnMask      = 1;
81    data.go_state       = 1;
82
83    objmgr.AddGameobjectToGrid(guid, &data);
84
85    // 2 way registering
86    m_Objects[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT);
87    m_ObjectTypes[m_Objects[type]]=type;
88
89    Map * pMap = MapManager::Instance().FindMap(map);
90    if(!pMap)
91        return true;
92    GameObject * go = new GameObject;
93    if(!go->Create(guid,entry, pMap,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
94    {
95        sLog.outError("Gameobject template %u not found in database.", entry);
96        delete go;
97        return true;
98    }
99
100    go->SetRespawnTime(0);
101    objmgr.SaveGORespawnTime(go->GetDBTableGUIDLow(),0,0);
102    pMap->Add(go);
103
104    return true;
105}
106
107bool OutdoorPvPObjective::AddCreature(uint32 type, uint32 entry, uint32 teamval, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay)
108{
109    CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(entry);
110    if(!cinfo)
111    {
112        return false;
113    }
114
115    uint32 displayId = objmgr.ChooseDisplayId(teamval, cinfo, NULL);
116    CreatureModelInfo const *minfo = objmgr.GetCreatureModelRandomGender(displayId);
117    if (!minfo)
118    {
119        return false;
120    }
121    else
122        displayId = minfo->modelid;                        // it can be different (for another gender)
123
124    uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
125
126    CreatureData& data = objmgr.NewOrExistCreatureData(guid);
127
128    data.id = entry;
129    data.mapid = map;
130    data.displayid = displayId;
131    data.equipmentId = cinfo->equipmentId;
132    data.posX = x;
133    data.posY = y;
134    data.posZ = z;
135    data.orientation = o;
136    data.spawntimesecs = spawntimedelay;
137    data.spawndist = 0;
138    data.currentwaypoint = 0;
139    data.curhealth = cinfo->maxhealth;
140    data.curmana = cinfo->maxmana;
141    data.is_dead = false;
142    data.movementType = cinfo->MovementType;
143    data.spawnMask = 1;
144
145    objmgr.AddCreatureToGrid(guid, &data);
146
147    m_Creatures[type] = MAKE_NEW_GUID(guid, entry, HIGHGUID_UNIT);
148    m_CreatureTypes[m_Creatures[type]] = type;
149
150    Map * pMap = MapManager::Instance().FindMap(map);
151    if(!pMap)
152        return true;
153    Creature* pCreature = new Creature;
154    if (!pCreature->Create(guid, pMap, entry, teamval))
155    {
156        sLog.outError("Can't create creature entry: %u",entry);
157        delete pCreature;
158        return true;
159    }
160
161    pCreature->AIM_Initialize();
162
163    pCreature->Relocate(x, y, z, o);
164
165    if(!pCreature->IsPositionValid())
166    {
167        sLog.outError("ERROR: Creature (guidlow %d, entry %d) not added to opvp. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
168        return false;
169    }
170
171    if(spawntimedelay)
172        pCreature->SetRespawnDelay(spawntimedelay);
173
174    pMap->Add(pCreature);
175
176    return true;
177}
178
179bool OutdoorPvPObjective::AddCapturePoint(uint32 entry, uint32 map, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
180{
181    sLog.outDebug("creating capture point %u and capture point creature",entry);
182
183    // check info existence
184    GameObjectInfo const* goinfo = objmgr.GetGameObjectInfo(entry);
185    if (!goinfo)
186        return false;
187
188    CreatureInfo const *cinfo = objmgr.GetCreatureTemplate(OPVP_TRIGGER_CREATURE_ENTRY);
189    if(!cinfo)
190        return false;
191
192    // create capture point creature
193    uint32 displayId = objmgr.ChooseDisplayId(0, cinfo, NULL);
194
195    uint32 creature_guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
196
197    CreatureData& cdata = objmgr.NewOrExistCreatureData(creature_guid);
198
199    cdata.id = OPVP_TRIGGER_CREATURE_ENTRY;
200    cdata.mapid = map;
201    cdata.displayid = displayId;
202    cdata.equipmentId = cinfo->equipmentId;
203    cdata.posX = x;
204    cdata.posY = y;
205    cdata.posZ = z;
206    cdata.orientation = o;
207    cdata.spawntimesecs = 1;
208    cdata.spawndist = 0;
209    cdata.currentwaypoint = 0;
210    cdata.curhealth = cinfo->maxhealth;
211    cdata.curmana = cinfo->maxmana;
212    cdata.is_dead = false;
213    cdata.movementType = cinfo->MovementType;
214    cdata.spawnMask = 1;
215
216    objmgr.AddCreatureToGrid(creature_guid, &cdata);
217    m_CapturePointCreature = MAKE_NEW_GUID(creature_guid, OPVP_TRIGGER_CREATURE_ENTRY, HIGHGUID_UNIT);
218
219    // create capture point go
220    uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
221
222    GameObjectData& data = objmgr.NewGOData(guid);
223
224    data.id             = entry;
225    data.mapid          = map;
226    data.posX           = x;
227    data.posY           = y;
228    data.posZ           = z;
229    data.orientation    = o;
230    data.rotation0      = rotation0;
231    data.rotation1      = rotation1;
232    data.rotation2      = rotation2;
233    data.rotation3      = rotation3;
234    data.spawntimesecs  = 1;
235    data.animprogress   = 100;
236    data.spawnMask      = 1;
237    data.go_state       = 1;
238
239    objmgr.AddGameobjectToGrid(guid, &data);
240
241    m_CapturePoint = MAKE_NEW_GUID(guid, entry, HIGHGUID_GAMEOBJECT);
242
243    // get the needed values from goinfo
244    m_ShiftMaxPhase = goinfo->raw.data[17];
245    m_ShiftMaxCaptureSpeed = m_ShiftMaxPhase / float(goinfo->raw.data[16]);
246    m_NeutralValue = goinfo->raw.data[12];
247
248    // add to map if map is already loaded
249    Map * pMap = MapManager::Instance().FindMap(map);
250    if(!pMap)
251        return true;
252    // add GO...
253    GameObject * go = new GameObject;
254    if(!go->Create(guid,entry, pMap,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
255    {
256        sLog.outError("Gameobject template %u not found in database.", entry);
257        delete go;
258    }
259    else
260    {
261        go->SetRespawnTime(0);
262        objmgr.SaveGORespawnTime(go->GetDBTableGUIDLow(), 0, 0);
263        pMap->Add(go);
264    }
265    // add creature...
266    Creature* pCreature = new Creature;
267    if (!pCreature->Create(creature_guid, pMap, OPVP_TRIGGER_CREATURE_ENTRY, 0))
268    {
269        sLog.outError("Can't create creature entry: %u",entry);
270        delete pCreature;
271    }
272    else
273    {
274        pCreature->AIM_Initialize();
275
276        pCreature->Relocate(x, y, z, o);
277
278        if(!pCreature->IsPositionValid())
279        {
280            sLog.outError("ERROR: Creature (guidlow %d, entry %d) not added to opvp. Suggested coordinates isn't valid (X: %f Y: %f)",pCreature->GetGUIDLow(),pCreature->GetEntry(),pCreature->GetPositionX(),pCreature->GetPositionY());
281            return false;
282        }
283
284        pMap->Add(pCreature);
285    }
286    return true;
287}
288
289bool OutdoorPvPObjective::DelCreature(uint32 type)
290{
291    if(!m_Creatures[type])
292    {
293        sLog.outDebug("opvp creature type %u was already deleted",type);
294        return false;
295    }
296
297    Creature *cr = HashMapHolder<Creature>::Find(m_Creatures[type]);
298    if(!cr)
299    {
300        // can happen when closing the core
301        m_Creatures[type] = 0;
302        return false;
303    }
304    sLog.outDebug("deleting opvp creature type %u",type);
305    uint32 guid = cr->GetDBTableGUIDLow();
306    // dont save respawn time
307    cr->SetRespawnTime(0);
308    cr->RemoveCorpse();
309    cr->CleanupsBeforeDelete();
310    // explicit removal from map
311    // beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted
312    // so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed
313    if(Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
314        map->Remove(cr,false);
315    // delete respawn time for this creature
316    WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u'", guid);
317    cr->AddObjectToRemoveList();
318    objmgr.DeleteCreatureData(guid);
319    m_CreatureTypes[m_Creatures[type]] = 0;
320    m_Creatures[type] = 0;
321    return true;
322}
323
324bool OutdoorPvPObjective::DelObject(uint32 type)
325{
326    if(!m_Objects[type])
327        return false;
328
329    GameObject *obj = HashMapHolder<GameObject>::Find(m_Objects[type]);
330    if(!obj)
331    {
332        m_Objects[type] = 0;
333        return false;
334    }
335    uint32 guid = obj->GetDBTableGUIDLow();
336    obj->SetRespawnTime(0);                                 // not save respawn time
337    obj->Delete();
338    objmgr.DeleteGOData(guid);
339    m_ObjectTypes[m_Objects[type]] = 0;
340    m_Objects[type] = 0;
341    return true;
342}
343
344bool OutdoorPvPObjective::DelCapturePoint()
345{
346    if(m_CapturePoint)
347    {
348        GameObject *obj = HashMapHolder<GameObject>::Find(m_CapturePoint);
349        if(obj)
350        {
351            uint32 guid = obj->GetDBTableGUIDLow();
352            obj->SetRespawnTime(0);                                 // not save respawn time
353            obj->Delete();
354            objmgr.DeleteGOData(guid);
355        }
356        m_CapturePoint = 0;
357    }
358    if(m_CapturePointCreature)
359    {
360        Creature *cr = HashMapHolder<Creature>::Find(m_CapturePointCreature);
361        if(cr)
362        {
363            uint32 guid = cr->GetDBTableGUIDLow();
364            // dont save respawn time
365            cr->SetRespawnTime(0);
366            cr->RemoveCorpse();
367            cr->CleanupsBeforeDelete();
368            // explicit removal from map
369            // beats me why this is needed, but with the recent removal "cleanup" some creatures stay in the map if "properly" deleted
370            // so this is a big fat workaround, if AddObjectToRemoveList and DoDelayedMovesAndRemoves worked correctly, this wouldn't be needed
371            if(Map * map = MapManager::Instance().FindMap(cr->GetMapId()))
372                map->Remove(cr,false);
373            // delete respawn time for this creature
374            WorldDatabase.PExecute("DELETE FROM creature_respawn WHERE guid = '%u'", guid);
375            cr->AddObjectToRemoveList();
376            objmgr.DeleteCreatureData(guid);
377        }
378        m_CapturePointCreature = 0;
379    }
380    return true;
381}
382
383void OutdoorPvPObjective::DeleteSpawns()
384{
385    for(std::map<uint32,uint64>::iterator i = m_Objects.begin(); i != m_Objects.end(); ++i)
386        DelObject(i->first);
387    for(std::map<uint32,uint64>::iterator i = m_Creatures.begin(); i != m_Creatures.end(); ++i)
388        DelCreature(i->first);
389    DelCapturePoint();
390}
391
392void OutdoorPvP::DeleteSpawns()
393{
394    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
395        (*itr)->DeleteSpawns();
396}
397
398OutdoorPvP::OutdoorPvP()
399{
400}
401
402OutdoorPvP::~OutdoorPvP()
403{
404    DeleteSpawns();
405}
406
407void OutdoorPvP::HandlePlayerEnterZone(Player * plr, uint32 zone)
408{
409    if(plr->GetTeam()==ALLIANCE)
410        m_PlayerGuids[0].insert(plr->GetGUID());
411    else
412        m_PlayerGuids[1].insert(plr->GetGUID());
413}
414
415void OutdoorPvP::HandlePlayerLeaveZone(Player * plr, uint32 zone)
416{
417    // inform the objectives of the leaving
418    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
419        (*itr)->HandlePlayerLeave(plr);
420    // 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)
421    if(zone != plr->GetZoneId())
422        SendRemoveWorldStates(plr);
423    if(plr->GetTeam()==ALLIANCE)
424        m_PlayerGuids[0].erase(plr->GetGUID());
425    else
426        m_PlayerGuids[1].erase(plr->GetGUID());
427    sLog.outDebug("player left an outdoorpvp zone");
428}
429
430bool OutdoorPvP::Update(uint32 diff)
431{
432    bool objective_changed = false;
433    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
434        objective_changed |= (*itr)->Update(diff);
435    return objective_changed;
436}
437
438bool OutdoorPvPObjective::Update(uint32 diff)
439{
440    uint32 Challenger = 0;
441    if(m_ShiftTimer<diff)
442    {
443        m_ShiftTimer = OUTDOORPVP_OBJECTIVE_UPDATE_INTERVAL;
444
445        // get the difference of numbers
446        float fact_diff = (m_AllianceActivePlayerCount - m_HordeActivePlayerCount);
447
448        if(fact_diff<0)
449        {
450            if(fact_diff < - m_ShiftMaxCaptureSpeed)
451                fact_diff = - m_ShiftMaxCaptureSpeed;
452            Challenger = HORDE;
453            // horde is in majority, but it's already horde-controlled -> no change
454            if(m_State == OBJECTIVESTATE_HORDE && m_ShiftPhase == - m_ShiftMaxPhase)
455                return false;
456        }
457        else if(fact_diff>0)
458        {
459            if(fact_diff > m_ShiftMaxCaptureSpeed)
460                fact_diff = m_ShiftMaxCaptureSpeed;
461            Challenger = ALLIANCE;
462            // ally is in majority, but it's already ally-controlled -> no change
463            if(m_State == OBJECTIVESTATE_ALLIANCE && m_ShiftPhase == m_ShiftMaxPhase)
464                return false;
465        }
466        else /*if(fact_diff==0)*/ // no change
467            return false;
468
469        m_OldPhase = m_ShiftPhase;
470
471        m_OldState = m_State;
472
473        m_ShiftPhase += fact_diff;
474
475        // check limits, these are over the grey part
476        if(m_ShiftPhase <= - m_ShiftMaxPhase * (float)(m_NeutralValue) / 100.0f)
477        {
478            if(m_ShiftPhase <= - m_ShiftMaxPhase)
479                m_ShiftPhase = - m_ShiftMaxPhase;
480            m_State = OBJECTIVESTATE_HORDE;
481            return true;
482        }
483        else if(m_ShiftPhase >= m_ShiftMaxPhase * (float)(m_NeutralValue) / 100.0f)
484        {
485            if(m_ShiftPhase >= m_ShiftMaxPhase)
486                m_ShiftPhase = m_ShiftMaxPhase;
487            m_State = OBJECTIVESTATE_ALLIANCE;
488            return true;
489        }
490
491        if(m_OldPhase*m_ShiftPhase <=0)
492        {
493            // gone through neutral
494            // if challenger is ally, then n->a challenge
495            if(Challenger == ALLIANCE)
496                m_State = OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE;
497            // if challenger is horde, then n->h challenge
498            else if(Challenger == HORDE)
499                m_State = OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE;
500        }
501        else
502        {
503            // old phase and current are on the same side, so one team challenges the other
504            if(Challenger == ALLIANCE && (m_OldState == OBJECTIVESTATE_HORDE || m_OldState == OBJECTIVESTATE_NEUTRAL_HORDE_CHALLENGE))
505                m_State = OBJECTIVESTATE_HORDE_ALLIANCE_CHALLENGE;
506            else if(Challenger == HORDE && (m_OldState == OBJECTIVESTATE_ALLIANCE || m_OldState == OBJECTIVESTATE_NEUTRAL_ALLIANCE_CHALLENGE))
507                m_State = OBJECTIVESTATE_ALLIANCE_HORDE_CHALLENGE;
508        }
509
510        return true;
511    } else m_ShiftTimer-=diff;
512
513    return false;
514}
515
516bool OutdoorPvPObjective::HandleCaptureCreaturePlayerMoveInLos(Player * p, Creature * c)
517{
518    // check if guid matches
519    if(c->GetGUID() != m_CapturePointCreature)
520        return false;
521
522    // check if capture point go is spawned
523    GameObject * cp = HashMapHolder<GameObject>::Find(m_CapturePoint);
524    if(!cp)
525        return false;
526
527    // check range and activity
528    if(cp->IsWithinDistInMap(p,cp->GetGOInfo()->raw.data[0]) && p->IsOutdoorPvPActive())
529    {
530        // data[8] will be used for player enter
531        return HandleCapturePointEvent(p, cp->GetGOInfo()->raw.data[8]); //i_objective->HandlePlayerEnter((Player*)u);
532    }
533    else
534    {
535        // data[9] will be used for player leave
536        return HandleCapturePointEvent(p, cp->GetGOInfo()->raw.data[9]); //i_objective->HandlePlayerLeave((Player*)u);
537    }
538}
539
540void OutdoorPvP::SendUpdateWorldState(uint32 field, uint32 value)
541{
542    // send to both factions
543    for(int i = 0; i < 2; ++i)
544    {
545        // send to all players present in the area
546        for(std::set<uint64>::iterator itr = m_PlayerGuids[i].begin(); itr != m_PlayerGuids[i].end(); ++itr)
547        {
548            Player * plr = objmgr.GetPlayer(*itr);
549            if(plr)
550            {
551                plr->SendUpdateWorldState(field,value);
552            }
553        }
554    }
555}
556
557void OutdoorPvPObjective::SendUpdateWorldState(uint32 field, uint32 value)
558{
559    // send to all players present in the area
560    for(std::set<uint64>::iterator itr = m_ActivePlayerGuids.begin(); itr != m_ActivePlayerGuids.end(); ++itr)
561    {
562        Player * plr = objmgr.GetPlayer(*itr);
563        if(plr)
564        {
565            plr->SendUpdateWorldState(field,value);
566        }
567    }
568}
569
570void OutdoorPvPObjective::SendObjectiveComplete(uint32 id,uint64 guid)
571{
572    uint32 controlling_faction;
573    switch(m_State)
574    {
575    case OBJECTIVESTATE_ALLIANCE:
576        controlling_faction = ALLIANCE;
577        break;
578    case OBJECTIVESTATE_HORDE:
579        controlling_faction = HORDE;
580        break;
581    default:
582        return;
583        break;
584    }
585
586    // send to all players present in the area
587    for(std::set<uint64>::iterator itr = m_ActivePlayerGuids.begin(); itr != m_ActivePlayerGuids.end(); ++itr)
588    {
589        Player * plr = objmgr.GetPlayer(*itr);
590        if(plr && plr->GetTeam() == controlling_faction)
591        {
592            plr->KilledMonster(id,guid);
593        }
594    }
595}
596
597void OutdoorPvP::HandlePlayerActivityChanged(Player * plr)
598{
599    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
600        (*itr)->HandlePlayerActivityChanged(plr);
601}
602
603void OutdoorPvP::HandleKill(Player *killer, Unit * killed)
604{
605    if(Group * pGroup = killer->GetGroup())
606    {
607        for(GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
608        {
609            Player *pGroupGuy = itr->getSource();
610
611            if(!pGroupGuy)
612                continue;
613
614            // skip if too far away
615            if(!pGroupGuy->IsAtGroupRewardDistance(killed))
616                continue;
617
618            // creature kills must be notified, even if not inside objective / not outdoor pvp active
619            // player kills only count if active and inside objective
620            if(( pGroupGuy->IsOutdoorPvPActive() && IsInsideObjective(pGroupGuy) ) || killed->GetTypeId() == TYPEID_UNIT)
621            {
622                HandleKillImpl(pGroupGuy, killed);
623            }
624        }
625    }
626    else
627    {
628        // creature kills must be notified, even if not inside objective / not outdoor pvp active
629        if(killer && (( killer->IsOutdoorPvPActive() && IsInsideObjective(killer) ) || killed->GetTypeId() == TYPEID_UNIT))
630        {
631            HandleKillImpl(killer, killed);
632        }
633    }
634}
635
636bool OutdoorPvP::IsInsideObjective(Player *plr)
637{
638    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
639    {
640        if((*itr)->IsInsideObjective(plr))
641            return true;
642    }
643    return false;
644}
645
646bool OutdoorPvPObjective::IsInsideObjective(Player *plr)
647{
648    std::set<uint64>::iterator itr = m_ActivePlayerGuids.find(plr->GetGUID());
649    return itr != m_ActivePlayerGuids.end();
650}
651
652bool OutdoorPvP::HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go)
653{
654    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
655    {
656        if((*itr)->HandleCustomSpell(plr,spellId,go))
657            return true;
658    }
659    return false;
660}
661
662bool OutdoorPvPObjective::HandleCustomSpell(Player *plr, uint32 spellId, GameObject * go)
663{
664    if(!plr->IsOutdoorPvPActive())
665        return false;
666    return false;
667}
668
669bool OutdoorPvP::HandleOpenGo(Player *plr, uint64 guid)
670{
671    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
672    {
673        if((*itr)->HandleOpenGo(plr,guid) >= 0)
674            return true;
675    }
676    return false;
677}
678
679bool OutdoorPvP::HandleCaptureCreaturePlayerMoveInLos(Player * p, Creature * c)
680{
681    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
682    {
683        if((*itr)->HandleCaptureCreaturePlayerMoveInLos(p, c))
684            return true;
685    }
686    return false;
687}
688
689bool OutdoorPvP::HandleGossipOption(Player * plr, uint64 guid, uint32 id)
690{
691    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
692    {
693        if((*itr)->HandleGossipOption(plr, guid, id))
694            return true;
695    }
696    return false;
697}
698
699bool OutdoorPvP::CanTalkTo(Player * plr, Creature * c, GossipOption &gso)
700{
701    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
702    {
703        if((*itr)->CanTalkTo(plr, c, gso))
704            return true;
705    }
706    return false;
707}
708
709bool OutdoorPvP::HandleDropFlag(Player * plr, uint32 id)
710{
711    for(OutdoorPvPObjectiveSet::iterator itr = m_OutdoorPvPObjectives.begin(); itr != m_OutdoorPvPObjectives.end(); ++itr)
712    {
713        if((*itr)->HandleDropFlag(plr, id))
714            return true;
715    }
716    return false;
717}
718
719bool OutdoorPvPObjective::HandleGossipOption(Player * plr, uint64 guid, uint32 id)
720{
721    return false;
722}
723
724bool OutdoorPvPObjective::CanTalkTo(Player * plr, Creature * c, GossipOption &gso)
725{
726    return false;
727}
728
729bool OutdoorPvPObjective::HandleDropFlag(Player * plr, uint32 id)
730{
731    return false;
732}
733
734int32 OutdoorPvPObjective::HandleOpenGo(Player *plr, uint64 guid)
735{
736    std::map<uint64,uint32>::iterator itr = m_ObjectTypes.find(guid);
737    if(itr != m_ObjectTypes.end())
738    {
739        return itr->second;   
740    }
741    return -1;
742}
743
744bool OutdoorPvP::HandleAreaTrigger(Player *plr, uint32 trigger)
745{
746    return false;
747}
Note: See TracBrowser for help on using the browser.