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
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%
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,182275,182276,182277,182301,182302,182303,182304,182305,182306,182307,182308,182297,182298,182299,182300));
+DELETE FROM gameobject WHERE id IN (182267, 182280,182281,182282,182222,182272,182273,182274,182266,182275,182276,182277,182301,182302,182303,182304,182305,182306,182307,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]