[Working]OutdoorPvP r10408+
Bonjour à tous,

Tous le monde le sait MaNGOS ne supporte pas l'outdoorPvP sans ce système dites adieu au joug d'hivers par exemple, hors mis si, comme moi, vous savez vous servir de vos dix doigts Heureux

Donc j'ouvre un nouveau sujet, en working, concernant l'implémentation de l'OutdoorPvP Système, lorsque j'ai débuter se travail je m'étais appuyé sur les quelques scripts de Xfurry / ManGOS Community. Je tiens à dire que le système est implémenté au core mais n'est pas encore destiné à un royaume en production :

Code :
>> Loaded 13 battlegrounds

Starting Outdoor PvP System
Map (Id: 530) for AddObject Can not Be initialized.
Map (Id: 530) for AddObject Can not Be initialized.
Map (Id: 530) for AddObject Can not Be initialized.

OutdoorPvP: HP Successfully Initiated.

OutdoorPvP: NA Successfully Initiated.

OutdoorPvP: TF Successfully Initiated.
Map (Id: 530) for AddObject Can not Be initialized.

OutdoorPvP: ZM Successfully Initiated.

OutdoorPvP: IF Successfully Initiated.
Map (Id: 0) Can not Be for AddObject initialized.
Map (Id: 0) Can not Be for AddObject initialized.
Map (Id: 0) Can not Be for AddObject initialized.
Map (Id: 0) Can not Be for AddObject initialized.

OutdoorPvP: EP Successfully Initiated.

OutdoorPvP: Successfully Initiated !

Loading ... Transport
[************************************************* *] 100%

Heureux

Je posterai au fur et a mesure de l'avancement.

DB Support
[code=SQL]diff --git a/sql/Outdoor/OutdoorPvP_mangos.sql b/sql/additions/OutdoorPvP_mangos.sql
new file mode 100644
index 0000000..5bbccfc
--- /dev/null
+++ b/sql/OutDoorPvP/OutdoorPvP_mangos.sql
@@ -0,0 +1,114 @@
+DELETE FROM gameobject_respawn WHERE guid IN (SELECT guid FROM gameobject WHERE id IN (182267, 182280,182281,182282,182222,182272,182273,182274,182266,1822​75,182276,182277,182301,182302,182303,182304,182305,182306,1​82307,182308,182297,182298,182299,182300));
+DELETE FROM gameobject WHERE id IN (182267, 182280,182281,182282,182222,182272,182273,182274,182266,1822​75,182276,182277,182301,182302,182303,182304,182305,182306,1​82307,182308,182297,182298,182299,182300);
+
+DELETE FROM creature_addon WHERE guid IN (select guid from creature WHERE id IN (18816,18821,21474,21484,21483,18192,18817,18822,21485,21487​,21488,18256));
+DELETE FROM creature_respawn WHERE guid IN (select guid from creature WHERE id IN (18816,18821,21474,21484,21483,18192,18817,18822,21485,21487​,21488,18256));
+DELETE FROM creature WHERE id IN (18816,18821,21474,21484,21483,18192,18817,18822,21485,21487​,21488,18256);
+
+UPDATE creature_template SET RegenHealth = 0 WHERE entry IN (18192,18256);
+--
+UPDATE creature_template SET faction_A = 1630, faction_H = 1630, ScriptName = 'mob_eventai' WHERE entry = 18225;
+
+-- Implémentation Flag PvP
+UPDATE creature_template SET unit_flags = unit_flags | 0x1000 WHERE entry IN (18816,18821,21474,21484,21483,18192,18817,18822,21485,21487​,21488,18256);
+
+UPDATE gameobject_template SET faction = 84, flags = 0 WHERE entry IN (182266,182267,182275,182276,182277,182280,182281,182282);
+UPDATE gameobject_template SET faction = 83, flags = 0 WHERE entry IN (182297, 182298, 182299, 182300, 182301, 182302, 182303, 182304);
+
+UPDATE gameobject_template SET faction = 83, flags = 0 WHERE entry IN (182222, 182272, 182273, 182274);
+UPDATE gameobject_template SET faction = 84, flags = 0 WHERE entry IN (182305, 182306, 182307, 182308);
+
+UPDATE gameobject_template SET data0 = 0 WHERE entry IN (181598, 181597);
+UPDATE gameobject_template SET data0 = 0 WHERE entry = 181682;
+
+DELETE from gameobject WHERE id = 181682; -- DELETE
+
+
+DELETE from creature WHERE id = 17209; -- DELETE
+
+UPDATE creature_template SET faction_a = 83, faction_h = 83 WHERE entry = 17995; --gardes de la horde
+UPDATE creature_template SET faction_a = 83, faction_h = 83 WHERE entry = 17996;
+UPDATE creature_template SET faction_a = 84, faction_h = 84 WHERE entry = 17635; -- gardes de l'alliance
+UPDATE creature_template SET faction_a = 84, faction_h = 84 WHERE entry = 17647;
+UPDATE creature_template SET faction_a = 84, faction_h = 83 WHERE entry = 17209; -- maître de vol
+UPDATE creature_template SET AIName = 'OutdoorPvPObjectiveAI', ScriptName = '' WHERE entry = 12999;
+UPDATE creature_template SET npcflag = npcflag | 536870912 WHERE entry IN (18564, 18581);
+
+DELETE FROM game_graveyard_zone WHERE id IN (969, 927, 993); -- suppression des cimetières
+
+UPDATE quest_template SET ReqSpellCast1 = 0, ReqSpellCast2 = 0, ReqSpellCast3 = 0, ReqSpellCast4 = 0 WHERE entry IN (9665, 9664);
+
+
+UPDATE quest_template SET reqspellcast1 = 0, reqspellcast2 = 0, reqspellcast3 = 0, reqspellcast4 = 0 WHERE entry in(9664,9665);
+
+
+DELETE FROM gameobject WHERE id IN (181899, 182096, 182097, 182173, 182174, 182175, 182210, 182522, 182523, 183104, 183411, 183412, 183413, 183414, 182098);
+
+DELETE FROM creature WHERE id IN (18564, 18581);
+
+DELETE FROM npc_option WHERE id = 51;
+INSERT INTO npc_option(id, gossip_id, npcflag, icon, action, option_text) VALUES (51,0,536870912,0,18,"UNIT_NPC_FLAG_OUTDOORPVP");
+
+
+DELETE FROM `mangos_string` WHERE `entry` BETWEEN 10001 AND 10050;
+INSERT INTO `mangos_string` (`entry`, `content_default`) VALUES
+-- péninsule
+(10001, 'La Horde a pris le surplomb! "),
+ (10002, 'L'Alliance a prisle surplomb! "),
+ (10003, 'La Horde a pris le stade! "),
+ (10004, 'L'Alliance a pris le stade! "),
+ (10005, 'La Horde a pris la Colline brisée!),
+ (10006, 'L'Alliance a pris la Colline brisée!),
+ (10007, 'La Horde perdue le surplomb!'),
+ (10008, 'L'Alliance a perdu le surplomb!'),
+ (10009, 'La Horde a perdu le stade! "),
+ (10010, 'L'Alliance a perdu le stade! "),
+ (10011, 'La Horde perdue la Colline brisée!),
+ (10012, 'L'Alliance a perdu la Colline brisée!'),
+ - Marécage de Zangar
+ (10013, 'La Horde a pris la balise Ouest!'),
+ (10014, 'L'Alliance a pris la balise Ouest!'),
+ (10015, 'La Horde a pris la balise Est! "),
+ (10016, 'L'Alliance a pris la balise Est! "),
+ (10017, 'La Horde a capturé le Cimetière Spire jumeaux!'),
+ (10018, 'L'Alliance a capturé le Cimetière Spire jumeaux!'),
+ (10019, 'La Horde a perdu la balise Ouest!'),
+ (10020, 'L'Alliance a perdu la balise Ouest!'),
+ (10021, 'La Horde a perdu la balise Est! "),
+ (10022, 'L'Alliance a perdu la balise Est! "),
+ (10023, 'La Horde perdue le Cimetière des esprits jumeaux!'),
+ (10024, 'L'Alliance a perdu le Cimetière des esprits jumeaux!'),
+ - Nagrand
+ (10025, 'La Horde a capturé Halaa!'),
+ (10026, 'L'Alliance a capturé Halaa!'),
+ (10027, 'La Horde perdue Halaa!'),
+ (10028, 'L'Alliance a perdu Halaa!'),
+ - Forêt de Terokkar
+ (10029, 'La Horde a pris un tour Esprit!'),
+ (10030, 'L'Alliance a pris un tour Esprit!'),
+ (10031, 'La Horde perdu un tour Esprit!'),
+ (10032, 'L'Alliance a perdu une tour Esprit!'),
+ - Maleterres de l'est
+ (10033, 'La Horde a pris la Tour du nord!'),
+ (10034, 'L'Alliance a pris la Tour du nord!'),
+ (10035, 'La Horde a pris la Tour du mur d'est!'),
+ (10036, 'L'Alliance a pris la Tour du mur d'est!'),
+ (10037, 'La Horde a pris la Tour de la Couronne de la Garde! "),
+ (10038, 'L'Alliance a pris la Tour de la Couronne de la Garde! "),
+ (10039, 'La Horde a pris la Tourde pestebois!'),
+ (10040, 'L'Alliance a pris la Tour de pestebois!'),
+ (10041, 'La Horde a perdu le Tour du nord!'),
+ (10042, 'L'Alliance a perdu le Tour du nord!'),
+ (10043, 'La Horde a perdu le Tour du mur d'est!'),
+ (10044, 'L'Alliance a perdu le Tourdu mur d'esl!'),
+ (10045, 'La Horde a perdu le Tour de garde de la couronne!),
+ (10046, 'L'Alliance a perdu le Tour de garde de la couronne!),
+ (10047, 'La Horde a perdu le Tour de pestebois!'),
+ (10048, 'L'Alliance a perdu le Tour de pestebois!'),
+ - Silithus
+ (10049, 'La Horde a recueilli 200 silithyste!'),
+ (10050, 'L'Alliance a collecté 200 silithyste!');
\ No newline at end of file[/code]

Core Support
[code=CPP]
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index c63a58b..dd49f28 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -38,6 +38,7 @@
#include "WaypointMovementGenerator.h"
#include "InstanceData.h"
#include "BattleGroundMgr.h"
+#include "OutdoorPvPMgr.h"
#include "Spell.h"
#include "Util.h"
#include "GridNotifiers.h"
@@ -154,7 +155,12 @@ void Creature::AddToWorld()
{
///- Register the creature for guid lookup
if(!IsInWorld() && GetObjectGuid().GetHigh() == HIGHGUID_UNIT)
+ {
+ if(m_zoneScript)
+ m_zoneScript->OnCreatureCreate(this, true);
+
GetMap()->GetObjectsStore().insert<Creature>(GetGUID(), (Creature*)this);
+ }

Unit::AddToWorld();
}
@@ -163,7 +169,12 @@ void Creature::RemoveFromWorld()
{
///- Remove the creature from the accessor
if(IsInWorld() && GetObjectGuid().GetHigh() == HIGHGUID_UNIT)
+ {
+ if(m_zoneScript)
+ m_zoneScript->OnCreatureCreate(this, false);
+
GetMap()->GetObjectsStore().erase<Creature>(GetGUID(), (Creature*)NULL);
+ }

Unit::RemoveFromWorld();
}
@@ -1173,6 +1184,14 @@ float Creature::GetSpellDamageMod(int32 Rank)

bool Creature::CreateFromProto(uint32 guidlow, uint32 Entry, uint32 team, const CreatureData *data)
{
+ SetZoneScript();
+ if(m_zoneScript && data)
+ {
+ Entry = m_zoneScript->GetCreatureEntry(guidlow, data);
+ if(!Entry)
+ return false;
+ }
+
CreatureInfo const *cinfo = ObjectMgr::GetCreatureTemplate(Entry);
if(!cinfo)
{
diff --git a/src/game/Creature.h b/src/game/Creature.h
index 69d57e4..7688f45 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -187,6 +187,7 @@ struct EquipmentInfo
// from `creature` table
struct CreatureData
{
+ explicit CreatureData() : dbData(true) {}
uint32 id; // entry in creature_template
uint16 mapid;
uint16 phaseMask;
@@ -204,6 +205,7 @@ struct CreatureData
bool is_dead;
uint8 movementType;
uint8 spawnMask;
+ bool dbData;
};

struct CreatureDataAddonAura
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index 344837c..1031e12 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -35,10 +35,11 @@
#include "InstanceData.h"
#include "BattleGround.h"
#include "BattleGroundAV.h"
+#include "OutdoorPvPMgr.h"
#include "Util.h"
#include "ScriptCalls.h"

-GameObject::GameObject() : WorldObject()
+GameObject::GameObject() : WorldObject(), m_goValue(new GameObjectValue)
{
m_objectType |= TYPEMASK_GAMEOBJECT;
m_objectTypeId = TYPEID_GAMEOBJECT;
@@ -54,6 +55,7 @@ GameObject::GameObject() : WorldObject()
m_spellId = 0;
m_cooldownTime = 0;
m_goInfo = NULL;
+ m_goData = NULL;

m_DBTableGuid = 0;
m_rotation = 0;
@@ -61,13 +63,19 @@ GameObject::GameObject() : WorldObject()

GameObject::~GameObject()
{
+ delete m_goValue;
}

void GameObject::AddToWorld()
{
///- Register the gameobject for guid lookup
if(!IsInWorld())
+ {
+ if(m_zoneScript)
+ m_zoneScript->OnGameObjectCreate(this, true);
+
GetMap()->GetObjectsStore().insert<GameObject>(GetGUID(), (GameObject*)this);
+ }

Object::AddToWorld();
}
@@ -77,6 +85,9 @@ void GameObject::RemoveFromWorld()
///- Remove the gameobject from the accessor
if(IsInWorld())
{
+ if(m_zoneScript)
+ m_zoneScript->OnGameObjectCreate(this, false);
+
// Remove GO from owner
ObjectGuid owner_guid = GetOwnerGUID();
if (!owner_guid.IsEmpty())
@@ -96,7 +107,7 @@ void GameObject::RemoveFromWorld()
Object::RemoveFromWorld();
}

-bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state)
+bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit)
{
ASSERT(map);
Relocate(x,y,z,ang);
@@ -146,13 +157,19 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
SetGoArtKit(0); // unknown what this is
SetGoAnimProgress(animprogress);

+ SetByteValue(GAMEOBJECT_BYTES_1, 2, artKit);
+
+ if (goinfo->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+ m_goValue->destructibleBuilding.health = goinfo->destructibleBuilding.intactNumHits + goinfo->destructibleBuilding.damagedNumHits;
+
//Notify the map's instance data.
//Only works if you create the object in it, not if it is moves to that map.
//Normally non-players do not teleport to other maps.
if(map->IsDungeon() && ((InstanceMap*)map)->GetInstanceData())
- {
+
((InstanceMap*)map)->GetInstanceData()->OnObjectCreate(this);
- }
+
+ SetZoneScript();

return true;
}
@@ -610,6 +627,8 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
}
}

+ m_goData = data;
+
return true;
}

@@ -622,11 +641,6 @@ void GameObject::DeleteFromDB()
WorldDatabase.PExecuteLog("DELETE FROM gameobject_battleground WHERE guid = '%u'", m_DBTableGuid);
}

-GameObjectInfo const *GameObject::GetGOInfo() const
-{
- return m_goInfo;
-}
-
/*********************************************************/
/*** QUEST SYSTEM ***/
/*********************************************************/
@@ -667,7 +681,7 @@ Unit* GameObject::GetOwner() const

void GameObject::SaveRespawnTime()
{
- if(m_respawnTime > time(NULL) && m_spawnedByDefault)
+ if(m_goData && m_goData->dbData && m_respawnTime > time(NULL) && m_spawnedByDefault)
sObjectMgr.SaveGORespawnTime(m_DBTableGuid,GetInstanceId(),m​_respawnTime);
}

@@ -839,6 +853,29 @@ void GameObject::UseDoorOrButton(uint32 time_to_restore, bool alternative /* = f
m_cooldownTime = time(NULL) + time_to_restore;
}

+void GameObject::SetGoArtKit(uint8 kit)
+{
+ SetByteValue(GAMEOBJECT_BYTES_1, 2, kit);
+ GameObjectData *data = const_cast<GameObjectData*>(sObjectMgr.GetGOData(m_DBTableGuid));
+ if(data)
+ data->artKit = kit;
+}
+
+void GameObject::SetGoArtKit(uint8 artkit, GameObject *go, uint32 lowguid)
+{
+ const GameObjectData *data = NULL;
+ if(go)
+ {
+ go->SetGoArtKit(artkit);
+ data = go->GetGOData();
+ }
+ else if(lowguid)
+ data = sObjectMgr.GetGOData(lowguid);
+
+ if(data)
+ const_cast<GameObjectData*>(data)->artKit = artkit;
+}
+
void GameObject::SwitchDoorOrButton(bool activate, bool alternative /* = false */)
{
if(activate)
@@ -1414,7 +1451,10 @@ void GameObject::Use(Unit* user)
SpellEntry const *spellInfo = sSpellStore.LookupEntry( spellId );
if (!spellInfo)
{
- sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType());
+ if(user->GetTypeId() != TYPEID_PLAYER || !sOutdoorPvPMgr.HandleCustomSpell((Player*)user,spellId,this​))
+ sLog.outError("WORLD: unknown spell id %u at use action for gameobject (Entry: %u GoType: %u )", spellId,GetEntry(),GetGoType());
+ else
+ sLog.outDebug("WORLD: %u non-dbc spell was handled by OutdoorPvP", spellId);
return;
}

diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index 08e0796..32fc759 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -516,6 +516,15 @@ struct GameObjectInfo
}
};

+union GameObjectValue
+{
+ //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
+ struct
+ {
+ uint32 health;
+ }destructibleBuilding;
+};
+
// GCC have alternative #pragma pack() syntax and old gcc version not support pack(pop), also any gcc version not support it at some platform
#if defined( __GNUC__ )
#pragma pack()
@@ -542,6 +551,7 @@ enum GOState
// from `gameobject`
struct GameObjectData
{
+ explicit GameObjectData() : dbData(true) {}
uint32 id; // entry in gamobject_template
uint16 mapid;
uint16 phaseMask;
@@ -557,6 +567,8 @@ struct GameObjectData
uint32 animprogress;
GOState go_state;
uint8 spawnMask;
+ uint8 artKit;
+ bool dbData;
};

// For containers: [GO_NOT_READY]->GO_READY (close)->GO_ACTIVATED (open) ->GO_JUST_DEACTIVATED->GO_READY -> ...
@@ -585,9 +597,11 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
void AddToWorld();
void RemoveFromWorld();

- bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state);
+ bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, GOState go_state, uint32 artKit = 0);
void Update(uint32 p_time);
- GameObjectInfo const* GetGOInfo() const;
+ GameObjectInfo const* GetGOInfo() const { return m_goInfo; }
+ GameObjectData const* GetGOData() const { return m_goData; }
+ GameObjectValue * GetGOValue() const { return m_goValue; }

bool IsTransport() const;

@@ -656,7 +670,9 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
GOState GetGoState() const { return GOState(GetByteValue(GAMEOBJECT_BYTES_1, 0)); }
void SetGoState(GOState state) { SetByteValue(GAMEOBJECT_BYTES_1, 0, state); }
uint8 GetGoArtKit() const { return GetByteValue(GAMEOBJECT_BYTES_1, 2); }
- void SetGoArtKit(uint8 artkit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, artkit); }
+ //void SetGoArtKit(uint8 artkit) { SetByteValue(GAMEOBJECT_BYTES_1, 2, artkit); }
+ void SetGoArtKit(uint8 artkit);
+ static void SetGoArtKit(uint8 artkit, GameObject *go, uint32 lowguid = 0);
uint8 GetGoAnimProgress() const { return GetByteValue(GAMEOBJECT_BYTES_1, 3); }
void SetGoAnimProgress(uint8 animprogress) { SetByteValue(GAMEOBJECT_BYTES_1, 3, animprogress); }

@@ -729,6 +745,8 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject

uint32 m_DBTableGuid; ///< For new or temporary gameobjects is 0 for saved it is lowguid
GameObjectInfo const* m_goInfo;
+ GameObjectData const* m_goData;
+ GameObjectValue * const m_goValue;
uint64 m_rotation;
private:
void SwitchDoorOrButton(bool activate, bool alternative = false);
diff --git a/src/game/GossipDef.h b/src/game/GossipDef.h
index 60b98bc..5fe9f05 100644
--- a/src/game/GossipDef.h
+++ b/src/game/GossipDef.h
@@ -48,6 +48,8 @@ enum Gossip_Option
GOSSIP_OPTION_ARMORER = 15, //UNIT_NPC_FLAG_ARMORER (4096)
GOSSIP_OPTION_UNLEARNTALENTS = 16, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
GOSSIP_OPTION_UNLEARNPETSKILLS = 17, //UNIT_NPC_FLAG_TRAINER (16) (bonus option for GOSSIP_OPTION_TRAINER)
+ GOSSIP_OPTION_LEARNDUALSPEC = 18, //UNIT_NPC_FLAG_TRAINER (bonus option for GOSSIP_OPTION_TRAINER)
+ GOSSIP_OPTION_OUTDOORPVP = 19, //added by code (option for outdoor pvp creatures)
GOSSIP_OPTION_MAX
};

diff --git a/src/game/Language.h b/src/game/Language.h
index 32c6dc3..cb79a4b 100644
--- a/src/game/Language.h
+++ b/src/game/Language.h
@@ -900,6 +900,86 @@ enum MangosStrings

// Use for not-in-offcial-sources patches
// 10000-10999
+ // opvp hp
+ LANG_OPVP_HP_CAPTURE_OVERLOOK_H = 10001,
+ LANG_OPVP_HP_CAPTURE_OVERLOOK_A = 10002,
+ LANG_OPVP_HP_CAPTURE_STADIUM_H = 10003,
+ LANG_OPVP_HP_CAPTURE_STADIUM_A = 10004,
+ LANG_OPVP_HP_CAPTURE_BROKENHILL_H = 10005,
+ LANG_OPVP_HP_CAPTURE_BROKENHILL_A = 10006,
+ LANG_OPVP_HP_LOOSE_OVERLOOK_H = 10007,
+ LANG_OPVP_HP_LOOSE_OVERLOOK_A = 10008,
+ LANG_OPVP_HP_LOOSE_STADIUM_H = 10009,
+ LANG_OPVP_HP_LOOSE_STADIUM_A = 10010,
+ LANG_OPVP_HP_LOOSE_BROKENHILL_H = 10011,
+ LANG_OPVP_HP_LOOSE_BROKENHILL_A = 10012,
+ // opvp zm
+ LANG_OPVP_ZM_CAPTURE_WEST_H = 10013,
+ LANG_OPVP_ZM_CAPTURE_WEST_A = 10014,
+ LANG_OPVP_ZM_CAPTURE_EAST_H = 10015,
+ LANG_OPVP_ZM_CAPTURE_EAST_A = 10016,
+ LANG_OPVP_ZM_CAPTURE_GY_H = 10017,
+ LANG_OPVP_ZM_CAPTURE_GY_A = 10018,
+ LANG_OPVP_ZM_LOOSE_WEST_H = 10019,
+ LANG_OPVP_ZM_LOOSE_WEST_A = 10020,
+ LANG_OPVP_ZM_LOOSE_EAST_H = 10021,
+ LANG_OPVP_ZM_LOOSE_EAST_A = 10022,
+ LANG_OPVP_ZM_LOOSE_GY_H = 10023,
+ LANG_OPVP_ZM_LOOSE_GY_A = 10024,
+ // opvp na
+ LANG_OPVP_NA_CAPTURE_H = 10025,
+ LANG_OPVP_NA_CAPTURE_A = 10026,
+ LANG_OPVP_NA_LOOSE_H = 10027,
+ LANG_OPVP_NA_LOOSE_A = 10028,
+ // opvp tf
+ LANG_OPVP_TF_CAPTURE_H = 10029,
+ LANG_OPVP_TF_CAPTURE_A = 10030,
+ LANG_OPVP_TF_LOOSE_H = 10031,
+ LANG_OPVP_TF_LOOSE_A = 10032,
+ // opvp ep
+ LANG_OPVP_EP_CAPTURE_NPT_H = 10033,
+ LANG_OPVP_EP_CAPTURE_NPT_A = 10034,
+ LANG_OPVP_EP_CAPTURE_EWT_H = 10035,
+ LANG_OPVP_EP_CAPTURE_EWT_A = 10036,
+ LANG_OPVP_EP_CAPTURE_CGT_H = 10037,
+ LANG_OPVP_EP_CAPTURE_CGT_A = 10038,
+ LANG_OPVP_EP_CAPTURE_PWT_H = 10039,
+ LANG_OPVP_EP_CAPTURE_PWT_A = 10040,
+ LANG_OPVP_EP_LOOSE_NPT_H = 10041,
+ LANG_OPVP_EP_LOOSE_NPT_A = 10042,
+ LANG_OPVP_EP_LOOSE_EWT_H = 10043,
+ LANG_OPVP_EP_LOOSE_EWT_A = 10044,
+ LANG_OPVP_EP_LOOSE_CGT_H = 10045,
+ LANG_OPVP_EP_LOOSE_CGT_A = 10046,
+ LANG_OPVP_EP_LOOSE_PWT_H = 10047,
+ LANG_OPVP_EP_LOOSE_PWT_A = 10048,
+ // opvp si
+ LANG_OPVP_SI_CAPTURE_H = 10049,
+ LANG_OPVP_SI_CAPTURE_A = 10050,
+ // opvp gossips
+ LANG_OPVP_EP_FLIGHT_NPT = 10051,
+ LANG_OPVP_EP_FLIGHT_EWT = 10052,
+ LANG_OPVP_EP_FLIGHT_CGT = 10053,
+ LANG_OPVP_ZM_GOSSIP_ALLIANCE = 10054,
+ LANG_OPVP_ZM_GOSSIP_HORDE = 10055,
+
+ LANG_BG_WG_BATTLE_STARTS = 10100,
+ LANG_BG_WG_DEFENDED = 10101,
+ LANG_BG_WG_CAPTURED = 10102,
+ LANG_BG_WG_WORKSHOP_DAMAGED = 10103,
+ LANG_BG_WG_WORKSHOP_DESTROYED = 10104,
+ LANG_BG_WG_TOWER_DAMAGED = 10105,
+ LANG_BG_WG_TOWER_DESTROYED = 10106,
+ LANG_BG_WG_FORTRESS_UNDER_ATTACK = 10107,
+ LANG_BG_WG_SWITCH_FACTION = 10108,
+ LANG_BG_WG_CHANGE_TIMER = 10109,
+ LANG_BG_WG_BATTLE_FORCE_START = 10110,
+ LANG_BG_WG_BATTLE_FORCE_STOP = 10111,
+ LANG_BG_WG_STATUS = 10112,
+ LANG_BG_WG_DISABLE = 10113,
+ LANG_BG_WG_ENABLE = 10114,
+ LANG_BG_WG_RANK1 = 10115,
+ LANG_BG_WG_RANK2 = 10116,

// Use for custom patches 11000-11999

diff --git a/src/game/Makefile.am b/src/game/Makefile.am
index 1008833..7c2cf47 100644
--- a/src/game/Makefile.am
+++ b/src/game/Makefile.am
@@ -209,6 +209,23 @@ libmangosgame_a_SOURCES = \
ObjectPosSelector.h \
Opcodes.cpp \
Opcodes.h \
+ OutdoorPvP.cpp \
+ OutdoorPvP.h \
+ OutdoorPvPEP.cpp \
+ OutdoorPvPEP.h \
+ OutdoorPvPHP.cpp \
+ OutdoorPvPHP.h \
+ OutdoorPvPImpl.h \
+ OutdoorPvPMgr.cpp \
+ OutdoorPvPMgr.h \
+ OutdoorPvPNA.cpp \
+ OutdoorPvPNA.h \
+ OutdoorPvPSI.cpp \
+ OutdoorPvPSI.h \
+ OutdoorPvPTF.cpp \
+ OutdoorPvPTF.h \
+ OutdoorPvPZM.cpp \
+ OutdoorPvPZM.h \
Path.h \
PetAI.cpp \
PetAI.h \
@@ -299,7 +316,8 @@ libmangosgame_a_SOURCES = \
FollowerRefManager.h \
GroupReference.cpp \
GroupReference.h \
- GroupRefManager.h
+ GroupRefManager.h \
+ ZoneScript.h

## Additional files to include when running 'make dist'
# Precompiled Headers for WIN
diff --git a/src/game/MiscHandler.cpp b/src/game/MiscHandler.cpp
index 6f7e3e5..bd631f8 100644
--- a/src/game/MiscHandler.cpp
+++ b/src/game/MiscHandler.cpp
@@ -37,6 +37,7 @@
#include "ObjectAccessor.h"
#include "Object.h"
#include "BattleGround.h"
+#include "OutdoorPvP.h"
#include "Pet.h"
#include "SocialMgr.h"
#include "DBCEnums.h"
@@ -739,6 +740,12 @@ void WorldSession::HandleAreaTriggerOpcode(WorldPacket & recv_data)
return;
}

+ if(OutdoorPvP * pvp = GetPlayer()->GetOutdoorPvP())
+ {
+ if(pvp->HandleAreaTrigger(_player, Trigger_ID))
+ return;
+ }
+
// NULL if all values default (non teleport trigger)
AreaTrigger const* at = sObjectMgr.GetAreaTrigger(Trigger_ID);
if(!at)
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 22e6517..6e160e9 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -44,6 +44,7 @@
#include "ObjectPosSelector.h"

#include "TemporarySummon.h"
+#include "OutdoorPvPMgr.h"

uint32 GuidHigh2TypeId(uint32 guid_hi)
{
@@ -598,7 +599,7 @@ void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *
if( index == UNIT_NPC_FLAGS )
{
// remove custom flag before sending
- uint32 appendValue = m_uint32Values[ index ] & ~UNIT_NPC_FLAG_GUARD;
+ uint32 appendValue = m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP);

if (GetTypeId() == TYPEID_UNIT)
{
@@ -1090,7 +1091,7 @@ void Object::BuildUpdateData( UpdateDataMapType& /*update_players */)

WorldObject::WorldObject()
: m_isActiveObject(false), m_currMap(NULL), m_mapId(0), m_InstanceId(0), m_phaseMask(PHASEMASK_NORMAL),
- m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
+ m_zoneScript(NULL),m_positionX(0.0f), m_positionY(0.0f), m_positionZ(0.0f), m_orientation(0.0f)
{
}

@@ -1628,6 +1629,16 @@ void WorldObject::AddObjectToRemoveList()
GetMap()->AddObjectToRemoveList(this);
}

+void WorldObject::SetZoneScript()
+{
+ if(Map *map = GetMap())
+ {
+ if(!map->IsBattleGroundOrArena() && !map->IsDungeon())
+ m_zoneScript = sOutdoorPvPMgr.GetZoneScript(GetZoneId());
+ }
+}
+
+
Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, float ang,TempSummonType spwtype,uint32 despwtime)
{
TemporarySummon* pCreature = new TemporarySummon(GetObjectGuid());
diff --git a/src/game/Object.h b/src/game/Object.h
index c900e4d..6c0a403 100644
--- a/src/game/Object.h
+++ b/src/game/Object.h
@@ -71,6 +71,8 @@ class Unit;
class Map;
class UpdateMask;
class InstanceData;
+class ZoneScript;
+class Vehicle;

typedef UNORDERED_MAP<Player*, UpdateData> UpdateDataMapType;

@@ -481,6 +483,9 @@ class MANGOS_DLL_SPEC WorldObject : public Object
//this function should be removed in nearest time...
Map const* GetBaseMap() const;

+ void SetZoneScript();
+ ZoneScript * GetZoneScript() const { return m_zoneScript; }
+
void AddToClientUpdateList();
void RemoveFromClientUpdateList();
void BuildUpdateData(UpdateDataMapType &);
@@ -499,6 +504,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SetLocationMapId(uint32 _mapId) { m_mapId = _mapId; }
void SetLocationInstanceId(uint32 _instanceId) { m_InstanceId = _instanceId; }

+ ZoneScript *m_zoneScript;
std::string m_name;

bool m_isActiveObject;
diff --git a/src/game/ObjectMgr.cpp b/src/game/ObjectMgr.cpp
index 676d432..e1427dd 100644
--- a/src/game/ObjectMgr.cpp
+++ b/src/game/ObjectMgr.cpp
@@ -1377,6 +1377,111 @@ void ObjectMgr::RemoveCreatureFromGrid(uint32 guid, CreatureData const* data)
}
}

+uint32 ObjectMgr::AddGOData(uint32 entry, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay, float rotation0, float rotation1, float rotation2, float rotation3)
+{
+ GameObjectInfo const* goinfo = GetGameObjectInfo(entry);
+ if (!goinfo)
+ return 0;
+
+ //Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(mapId));
+ Map * map = const_cast<Map*>(sMapMgr.CreateBaseMap(mapId));
+ if(!map)
+ return 0;
+
+ uint32 guid = GenerateLowGuid(HIGHGUID_GAMEOBJECT);
+ GameObjectData& data = NewGOData(guid);
+ data.id = entry;
+ data.mapid = mapId;
+ data.posX = x;
+ data.posY = y;
+ data.posZ = z;
+ data.orientation = o;
+ data.rotation0 = rotation0;
+ data.rotation1 = rotation1;
+ data.rotation2 = rotation2;
+ data.rotation3 = rotation3;
+ data.spawntimesecs = spawntimedelay;
+ data.animprogress = 100;
+ data.spawnMask = 1;
+ data.go_state = GO_STATE_READY;
+ data.phaseMask = PHASEMASK_NORMAL;
+ data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
+ data.dbData = false;
+
+ AddGameobjectToGrid(guid, &data);
+
+ // Spawn if necessary (loaded grids only)
+ // We use spawn coords to spawn
+ if(!map->Instanceable() && map->IsLoaded(x, y))
+ {
+ GameObject *go = new GameObject;
+ if (!go->LoadFromDB(guid, map))
+ {
+ sLog.outError("AddGOData: cannot add gameobject entry %u to map", entry);
+ delete go;
+ return 0;
+ }
+ map->Add(go);
+ }
+
+ sLog.outDebug("AddGOData: dbguid %u entry %u map %u x %f y %f z %f o %f", guid, entry, mapId, x, y, z, o);
+
+ return guid;
+}
+
+uint32 ObjectMgr::AddCreData(uint32 entry, uint32 team, uint32 mapId, float x, float y, float z, float o, uint32 spawntimedelay)
+{
+ CreatureInfo const *cInfo = GetCreatureTemplate(entry);
+ if(!cInfo)
+ return 0;
+
+ uint32 level = cInfo->minlevel == cInfo->maxlevel ? cInfo->minlevel : urand(cInfo->minlevel, cInfo->maxlevel); // Only used for extracting creature base stats
+ //CreatureBaseStats const* stats = objmgr.GetCreatureBaseStats(level, cInfo->unit_class);
+
+ uint32 guid = GenerateLowGuid(HIGHGUID_UNIT);
+ CreatureData& data = NewOrExistCreatureData(guid);
+ data.id = entry;
+ data.mapid = mapId;
+ data.displayid = 0;
+ data.equipmentId = cInfo->equipmentId;
+ data.posX = x;
+ data.posY = y;
+ data.posZ = z;
+ data.orientation = o;
+ data.spawntimesecs = spawntimedelay;
+ data.spawndist = 0;
+ data.currentwaypoint = 0;
+ data.curhealth = 1;
+ data.curmana = 1;
+ data.is_dead = false;
+ data.movementType = cInfo->MovementType;
+ data.spawnMask = 1;
+ data.phaseMask = PHASEMASK_NORMAL;
+ data.dbData = false;
+
+ AddCreatureToGrid(guid, &data);
+
+ // Spawn if necessary (loaded grids only)
+ //if(Map* map = const_cast<Map*>(MapManager::Instance().CreateBaseMap(mapId)))
+ if(Map * map = const_cast<Map*>(sMapMgr.CreateBaseMap(mapId)))
+ {
+ // We use spawn coords to spawn
+ if(!map->Instanceable() && !map->IsRemovalGrid(x, y))
+ {
+ Creature* creature = new Creature;
+ if(!creature->LoadFromDB(guid, map))
+ {
+ sLog.outError("AddCreature: cannot add creature entry %u to map", entry);
+ delete creature;
+ return 0;
+ }
+ map->Add(creature);
+ }
+ }
+
+ return guid;
+}
+
void ObjectMgr::LoadGameobjects()
{
uint32 count = 0;
@@ -1464,8 +1569,8 @@ void ObjectMgr::LoadGameobjects()
continue;
}

- if (data.spawnMask & ~spawnMasks[data.mapid])
- sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid);
+ /*if (data.spawnMask & ~spawnMasks[data.mapid])
+ sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) that have wrong spawn mask %u including not supported difficulty modes for map (Id: %u), skip", guid, data.id, data.spawnMask, data.mapid);*/

if (data.spawntimesecs == 0 && gInfo->IsDespawnAtAction())
{
@@ -5775,6 +5880,53 @@ bool ObjectMgr::AddGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inD
return true;
}

+void ObjectMgr::RemoveGraveYardLink(uint32 id, uint32 zoneId, uint32 team, bool inDB)
+{
+ GraveYardMap::iterator graveLow = mGraveYardMap.lower_bound(zoneId);
+ GraveYardMap::iterator graveUp = mGraveYardMap.upper_bound(zoneId);
+ if(graveLow==graveUp)
+ {
+ //sLog.outErrorDb("Table `game_graveyard_zone` incomplete: Zone %u Team %u does not have a linked graveyard.",zoneId,team);
+ return;
+ }
+
+ bool found = false;
+
+ GraveYardMap::iterator itr;
+
+ for (itr = graveLow; itr != graveUp; ++itr)
+ {
+ GraveYardData & data = itr->second;
+
+ // skip not matching safezone id
+ if(data.safeLocId != id)
+ continue;
+
+ // skip enemy faction graveyard at same map (normal area, city, or battleground)
+ // team == 0 case can be at call from .neargrave
+ if(data.team != 0 && team != 0 && data.team != team)
+ continue;
+
+ found = true;
+ break;
+ }
+
+ // no match, return
+ if(!found)
+ return;
+
+ // remove from links
+ mGraveYardMap.erase(itr);
+
+ // remove link from DB
+ if(inDB)
+ {
+ WorldDatabase.PExecute("DELETE FROM game_graveyard_zone WHERE id = '%u' AND ghost_zone = '%u' AND faction = '%u'",id,zoneId,team);
+ }
+
+ return;
+}
+
void ObjectMgr::LoadAreaTriggerTeleports()
{
mAreaTriggers.clear(); // need for reload case
diff --git a/src/game/ObjectMgr.h b/src/game/ObjectMgr.h
index fc0a7b3..4c871a0 100644
--- a/src/game/ObjectMgr.h
+++ b/src/game/ObjectMgr.h
@@ -596,6 +596,7 @@ class ObjectMgr

WorldSafeLocsEntry const *GetClosestGraveYard(float x, float y, float z, uint32 MapId, uint32 team);
bool AddGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = true);
+ void RemoveGraveYardLink(uint32 id, uint32 zone, uint32 team, bool inDB = false);
void LoadGraveyardZones();
GraveYardData const* FindGraveYardData(uint32 id, uint32 zone);

@@ -924,6 +925,8 @@ class ObjectMgr
void RemoveCreatureFromGrid(uint32 guid, CreatureData const* data);
void AddGameobjectToGrid(uint32 guid, GameObjectData const* data);
void RemoveGameobjectFromGrid(uint32 guid, GameObjectData const* data);
+ uint32 AddGOData(uint32 entry, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0, float rotation0 = 0, float rotation1 = 0, float rotation2 = 0, float rotation3 = 0);
+ uint32 AddCreData(uint32 entry, uint32 team, uint32 map, float x, float y, float z, float o, uint32 spawntimedelay = 0);[/code]
Pour le joug il faudrait récupérer la classe battlefield qui a été crée pour ça et Tol Barad
Ajout du système Outdoor adapté à la dernière révision mangos.

ChangeLogs:
  • Correction du crash aléatoire du royaume lors de la prise de flag
  • Les joueurs ne sont plus déconnectés du royaume lors de la prise du Surpomb à la Péninsule
  • Correction des segfault intempestives lors des tentatives de la prise de Halaa ?? (need more test Heureux)
  • Fix des warning à la compilation (need more fix -DDEBUG=1 Clin )
  • More cleanup Clin

OutdoorPvP.cpp

[code=cpp]diff --git a/src/game/OutdoorPvP.cpp b/src/game/OutdoorPvP.cpp
new file mode 100644
index 0000000..a8018c6
--- /dev/null
+++ b/src/game/OutdoorPvP.cpp
@@ -0,0 +1,683 @@
+/*
+ * Copyright © 2008-2010 MaNGOS <http://www.MaNGOScore.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"
+
+#include "Database/DatabaseEnv.h"
+#include "World.h"
+#include "Player.h"
+#include "Opcodes.h"
+#include "Chat.h"
+#include "ObjectAccessor.h"
+#include "Language.h"
+#include "AccountMgr.h"
+#include "SystemConfig.h"
+#include "revision.h"
+#include "revision_nr.h"
+#include "Util.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 Triste
+ 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 Erf
+ SendUpdateWorldState(m_capturePoint->GetGOInfo()->capturePoint.worldstate3, m_neutralValuePct);
+}
+
+void OPvPCapturePoint::AddGO(uint32 type, uint32 guid, uint32 entry)
+{
+ if(!entry)
+ {
+ const GameObjectData *data = sObjectMgr.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 = sObjectMgr.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 mapId, float x, float y, float z, float o, float rotation0, float rotation1, float rotation2, float rotation3)
+{
+ GameObjectInfo const* goinfo = sObjectMgr.GetGameObjectInfo(entry);
+ if (!goinfo)
+ return 0;
+
+ uint32 guid = sObjectMgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
+ GameObjectData& data = sObjectMgr.NewGOData(guid);
+ data.id = entry;
+ data.mapid = mapId;
+ data.posX = x;
+ data.posY = y;
+ data.posZ = z;
+ data.orientation = o;
+ data.rotation0 = rotation0;
+ data.rotation1 = rotation1;
+ data.rotation2 = rotation2;
+ data.rotation3 = rotation3;
+ data.spawntimesecs = 0;
+ data.animprogress = 100;
+ data.spawnMask = 1;
+ data.go_state = GO_STATE_READY;
+ data.phaseMask = PHASEMASK_NORMAL;
+ data.artKit = goinfo->type == GAMEOBJECT_TYPE_CAPTURE_POINT ? 21 : 0;
+ data.dbData = false;
+
+ Map * map = const_cast<Map*>(sMapMgr.CreateBaseMap(mapId));
+ if(!map)
+ {
+ sLog.outError("Map (Id: %i) for AddObject cannot be initialized.", mapId);
+ return false;
+ }
+
+ //SetMap(newMap);
+
+ sObjectMgr.AddGameobjectToGrid(guid, &data);
+
+ // Spawn if necessary (loaded grids only)
+ // We use spawn coords to spawn
+ if(!map->Instanceable() && map->IsLoaded(x, y))
+ {
+ GameObject *go = new GameObject;
+ if (!go->LoadFromDB(guid, map))
+ {
+ sLog.outError("AddGOData: cannot add gameobject entry %u to map", entry);
+ delete go;
+ return 0;
+ }
+ map->Add(go);
+ }
+
+ sLog.outDebug("AddGOData: dbguid %u entry %u map %u x %f y %f z %f o %f", guid, entry, mapId, x, y, z, o);
+
+ //return guid;
+ // if(uint32 guid = sObjectMgr.AddGOData(entry, map, x, y, z, o, 0, rotation0, rotation1, rotation2, rotation3))
+ if(guid)
+ {
+ 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 = sObjectMgr.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 = sObjectMgr.GetGameObjectInfo(entry);
+ if(!goinfo || goinfo->type != GAMEOBJECT_TYPE_CAPTURE_POINT)
+ {
+ sLog.outError("OutdoorPvP: GO %u is not capture point!", entry);
+ return false;
+ }
+
+ m_capturePointGUID = sObjectMgr.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 = ObjectAccessor::GetCreatureInWorld(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();
+ sObjectMgr.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 = ObjectAccessor::GetGameObjectInWorld(m_Objects[type]);
+ if(!obj)
+ {
+ m_Objects[type] = 0;
+ return false;
+ }
+ uint32 guid = obj->GetDBTableGUIDLow();
+ obj->SetRespawnTime(0); // not save respawn time
+ obj->Delete();
+ sObjectMgr.DeleteGOData(guid);
+ m_ObjectTypes[m_Objects[type]] = 0;
+ m_Objects[type] = 0;
+ return true;
+}
+
+bool OPvPCapturePoint::DelCapturePoint()
+{
+ sObjectMgr.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()Clin
+ {
+ Player *player = *itr;
+ ++itr;
+ if(!m_capturePoint->IsWithinDistInMap(player, radius) || !player->IsOutdoorPvPActive())
+ HandlePlayerLeave(player);
+ }
+ }
+
+ std::list<Player*> players;
+ std::list<Unit *> targets;
+
+ CellPair p(MaNGOS::ComputeCellPair(m_capturePoint->GetPositionX(), m_capturePoint->GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+ cell.SetNoCreate();
+
+ {
+ MaNGOS::AnyUnitInObjectRangeCheck u_check(m_capturePoint, radius);
+ MaNGOS::UnitListSearcher<MaNGOS::AnyUnitInObjectRangeCheck> searcher( m_capturePoint, targets, u_check);
+
+ TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
+ TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
+
+ cell.Visit(p, world_unit_searcher, *m_capturePoint->GetMap());
+ cell.Visit(p, grid_unit_searcher, *m_capturePoint->GetMap());
+ }
+
+ for( std::list<Unit *>::iterator itr = targets.begin(); itr != targets.end(); ++itr )
+ if( (*itr)->GetTypeId() == TYPEID_PLAYER )
+ players.push_back((Player*)(*itr));
+
+ 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)->RemoveAurasDueToSpell((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;
+}
+\ No newline at end of file[/code]

OutdoorPvP.h

[code=cpp]
diff --git a/src/game/OutdoorPvP.h b/src/game/OutdoorPvP.h
new file mode 100644
index 0000000..431761b
--- /dev/null
+++ b/src/game/OutdoorPvP.h
@@ -0,0 +1,262 @@
+/*
+ * Copyright © 2008-2010 MaNGOS <http://www.MaNGOScore.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"
+#include "Map.h"
+#include "ByteBuffer.h"
+#include "BattleGround.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*/, uint32& /*count*/) {}
+
+ // 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*/, uint32& /*count*/) {}
+ // 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);
+}
+\ No newline at end of file
;[/code]


Édition :
Suite..

OutdoorPvPEP.cpp
[code=cpp]
diff --git a/src/game/OutdoorPvPEP.cpp b/src/game/OutdoorPvPEP.cpp
new file mode 100644
index 0000000..90ccdc4
--- /dev/null
+++ b/src/game/OutdoorPvPEP.cpp
@@ -0,0 +1,764 @@
+
+#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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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 = ObjectAccessor::GetGameObjectInWorld(m_capturePointGUID);
+ GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(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 Triste
+ 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 Erf
+ SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
+}
+
+void OPvPCapturePointEP_EWT::FillInitialWorldStates(WorldPacket& data, uint32& count)
+{
+ FillInitialWorldState(data, count, EP_EWT_A, bool(m_TowerState & EP_TS_A));
+ FillInitialWorldState(data, count, EP_EWT_H, bool(m_TowerState & EP_TS_H));
+ FillInitialWorldState(data, count, EP_EWT_A_P, bool(m_TowerState & EP_TS_A_P));
+ FillInitialWorldState(data, count, EP_EWT_H_P, bool(m_TowerState & EP_TS_H_P));
+ FillInitialWorldState(data, count, EP_EWT_N_A, bool(m_TowerState & EP_TS_N_A));
+ FillInitialWorldState(data, count, EP_EWT_N_H, bool(m_TowerState & EP_TS_N_H));
+ FillInitialWorldState(data, count, EP_EWT_N, 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(ui​nt32 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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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 = ObjectAccessor::GetGameObjectInWorld(m_capturePointGUID);
+ GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(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 Triste
+ 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 Erf
+ SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
+}
+
+void OPvPCapturePointEP_NPT::FillInitialWorldStates(WorldPacket& data, uint32& count)
+{
+ FillInitialWorldState(data, count, EP_NPT_A, bool(m_TowerState & EP_TS_A));
+ FillInitialWorldState(data, count, EP_NPT_H, bool(m_TowerState & EP_TS_H));
+ FillInitialWorldState(data, count, EP_NPT_A_P, bool(m_TowerState & EP_TS_A_P));
+ FillInitialWorldState(data, count, EP_NPT_H_P, bool(m_TowerState & EP_TS_H_P));
+ FillInitialWorldState(data, count, EP_NPT_N_A, bool(m_TowerState & EP_TS_N_A));
+ FillInitialWorldState(data, count, EP_NPT_N_H, bool(m_TowerState & EP_TS_N_H));
+ FillInitialWorldState(data, count, EP_NPT_N, 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_Lo​rdaeronShrine.map,EP_NPT_LordaeronShrine.x,EP_NPT_LordaeronS​hrine.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 = ObjectAccessor::GetGameObjectInWorld(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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 = ObjectAccessor::GetGameObjectInWorld(m_capturePointGUID);
+ GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(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 Triste
+ 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 Erf
+ SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
+}
+
+void OPvPCapturePointEP_CGT::FillInitialWorldStates(WorldPacket& data, uint32& count)
+{
+ FillInitialWorldState(data, count, EP_CGT_A, bool(m_TowerState & EP_TS_A));
+ FillInitialWorldState(data, count, EP_CGT_H, bool(m_TowerState & EP_TS_H));
+ FillInitialWorldState(data, count, EP_CGT_A_P, bool(m_TowerState & EP_TS_A_P));
+ FillInitialWorldState(data, count, EP_CGT_H_P, bool(m_TowerState & EP_TS_H_P));
+ FillInitialWorldState(data, count, EP_CGT_N_A, bool(m_TowerState & EP_TS_N_A));
+ FillInitialWorldState(data, count, EP_CGT_N_H, bool(m_TowerState & EP_TS_N_H));
+ FillInitialWorldState(data, count, EP_CGT_N, 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;
+ sObjectMgr.RemoveGraveYardLink(EP_GraveYardId,EP_GraveYardZo​ne,team,false);
+ sObjectMgr.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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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,sObjectMgr.GetMangosStr​ingForDBCLocale(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 = ObjectAccessor::GetGameObjectInWorld(m_capturePointGUID);
+ GameObject * flag2 = ObjectAccessor::GetGameObjectInWorld(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 Triste
+ 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 Erf
+ SendUpdateWorldState(EP_UI_TOWER_SLIDER_N, m_neutralValuePct);
+}
+
+void OPvPCapturePointEP_PWT::FillInitialWorldStates(WorldPacket& data, uint32& count)
+{
+ FillInitialWorldState(data, count, EP_PWT_A, bool(m_TowerState & EP_TS_A));
+ FillInitialWorldState(data, count, EP_PWT_H, bool(m_TowerState & EP_TS_H));
+ FillInitialWorldState(data, count, EP_PWT_A_P, bool(m_TowerState & EP_TS_A_P));
+ FillInitialWorldState(data, count, EP_PWT_H_P, bool(m_TowerState & EP_TS_H_P));
+ FillInitialWorldState(data, count, EP_PWT_N_A, bool(m_TowerState & EP_TS_N_A));
+ FillInitialWorldState(data, count, EP_PWT_N_H, bool(m_TowerState & EP_TS_N_H));
+ FillInitialWorldState(data, count, EP_PWT_N, 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,te​am,EP_PWT_FlightMaster.map,EP_PWT_FlightMaster.x,EP_PWT_Flig​htMaster.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_AllianceTowersCon​trolled);
+ SendUpdateWorldState(EP_UI_TOWER_COUNT_H,m_HordeTowersContro​lled);
+ 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, uint32& count)
+{
+ FillInitialWorldState(data, count, EP_UI_TOWER_COUNT_A, m_AllianceTowersControlled);
+ FillInitialWorldState(data, count, EP_UI_TOWER_COUNT_H, m_HordeTowersControlled);
+ FillInitialWorldState(data, count, EP_UI_TOWER_SLIDER_DISPLAY, 0);
+ FillInitialWorldState(data, count, EP_UI_TOWER_SLIDER_POS, 50);
+ FillInitialWorldState(data, count, EP_UI_TOWER_SLIDER_N, 100);
+ for (OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
+ {
+ itr->second->FillInitialWorldStates(data, count);
+ }
+}
+
+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);
+}[/code]

Le poste le .h dès que j'ai 5 min.

Je suis bloquer pour le script de Halaa a nagrand. Quand on essaye de prendre la ville sa provoque presque systématiquement une segfault que je n'arrive pas encore à résoudre si quelqu'un a un fix à partager se sera avec plaisir
Je continue sur ma série :
Pour le code SQL :
Citation :INDEX 0000000..5bbccfc
Valeur propre à chaque diff, donc il n'existe pas 2 même valeurs :
Si je cherche ça sur google je trouve ça : PasteBin
Pour le code C++ :
Citation :index c63a58b..dd49f28 100644
Si je re-recherche sur google je trouve ça : PasteBin

A la fin du pastebin :
Citation :OutdoorPvP patch for MaNGOS 10408.

D'où le tire du topic "r10408+"

Voilà je crois que j'ai tout dis

Retourner en haut Accueil