Core/OutdoorPvP: Refactor OutdoorPvP creation to be linked to host map creation instead of having globally accessible objects
Port From (https://github.com/TrinityCore/TrinityCore/commit/775be0682a794d0a1f62d656f8c6c6dffca8de79)
This commit is contained in:
@@ -1438,7 +1438,7 @@ namespace Game.Entities
|
||||
if (bf != null)
|
||||
return bf;
|
||||
else
|
||||
return Global.OutdoorPvPMgr.GetZoneScript(GetZoneId());
|
||||
return Global.OutdoorPvPMgr.GetOutdoorPvPToZoneId(map, GetZoneId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -765,7 +765,7 @@ namespace Game.Entities
|
||||
}
|
||||
public OutdoorPvP GetOutdoorPvP()
|
||||
{
|
||||
return Global.OutdoorPvPMgr.GetOutdoorPvPToZoneId(GetZoneId());
|
||||
return Global.OutdoorPvPMgr.GetOutdoorPvPToZoneId(GetMap(), GetZoneId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,8 @@ namespace Game.Maps
|
||||
|
||||
_worldStateValues = Global.WorldStateMgr.GetInitialWorldStatesForMap(this);
|
||||
|
||||
Global.OutdoorPvPMgr.CreateOutdoorPvPForMap(this);
|
||||
|
||||
Global.ScriptMgr.OnCreateMap(this);
|
||||
}
|
||||
|
||||
@@ -111,6 +113,8 @@ namespace Game.Maps
|
||||
if (!m_scriptSchedule.Empty())
|
||||
Global.MapMgr.DecreaseScheduledScriptCount((uint)m_scriptSchedule.Count);
|
||||
|
||||
Global.OutdoorPvPMgr.DestroyOutdoorPvPForMap(this);
|
||||
|
||||
if (m_parentMap == this)
|
||||
m_childTerrainMaps = null;
|
||||
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace Game.PvP
|
||||
// base class for specific outdoor pvp handlers
|
||||
public class OutdoorPvP : ZoneScript
|
||||
{
|
||||
public OutdoorPvP()
|
||||
public OutdoorPvP(Map map)
|
||||
{
|
||||
m_TypeId = 0;
|
||||
m_sendUpdate = true;
|
||||
m_map = map;
|
||||
m_players[0] = new List<ObjectGuid>();
|
||||
m_players[1] = new List<ObjectGuid>();
|
||||
}
|
||||
@@ -285,21 +285,10 @@ namespace Game.PvP
|
||||
|
||||
public Map GetMap() { return m_map; }
|
||||
|
||||
// Hack to store map because this code is just shit
|
||||
public void SetMapFromZone(uint zone)
|
||||
{
|
||||
AreaTableRecord areaTable = CliDB.AreaTableStorage.LookupByKey(zone);
|
||||
Cypher.Assert(areaTable != null);
|
||||
Map map = Global.MapMgr.CreateBaseMap(areaTable.ContinentID);
|
||||
Cypher.Assert(!map.Instanceable());
|
||||
m_map = map;
|
||||
}
|
||||
|
||||
// the map of the objectives belonging to this outdoorpvp
|
||||
public Dictionary<ulong, OPvPCapturePoint> m_capturePoints = new();
|
||||
List<ObjectGuid>[] m_players = new List<ObjectGuid>[2];
|
||||
public OutdoorPvPTypes m_TypeId;
|
||||
bool m_sendUpdate;
|
||||
|
||||
Map m_map;
|
||||
}
|
||||
|
||||
@@ -45,34 +45,40 @@ namespace Game.PvP
|
||||
|
||||
do
|
||||
{
|
||||
uint typeId = result.Read<byte>(0);
|
||||
OutdoorPvPTypes typeId = (OutdoorPvPTypes)result.Read<byte>(0);
|
||||
|
||||
if (Global.DisableMgr.IsDisabledFor(DisableType.OutdoorPVP, typeId, null))
|
||||
if (Global.DisableMgr.IsDisabledFor(DisableType.OutdoorPVP, (uint)typeId, null))
|
||||
continue;
|
||||
|
||||
if (typeId >= (int)OutdoorPvPTypes.Max)
|
||||
if (typeId >= OutdoorPvPTypes.Max)
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Invalid OutdoorPvPTypes value {0} in outdoorpvp_template; skipped.", typeId);
|
||||
continue;
|
||||
}
|
||||
|
||||
OutdoorPvPTypes realTypeId = (OutdoorPvPTypes)typeId;
|
||||
OutdoorPvPScriptIds[realTypeId] = Global.ObjectMgr.GetScriptId(result.Read<string>(1));
|
||||
m_OutdoorPvPDatas[typeId] = Global.ObjectMgr.GetScriptId(result.Read<string>(1));
|
||||
|
||||
++count;
|
||||
}
|
||||
while (result.NextRow());
|
||||
|
||||
OutdoorPvP pvp;
|
||||
Log.outInfo(LogFilter.ServerLoading, $"Loaded {count} outdoor PvP definitions in {Time.GetMSTimeDiffToNow(oldMSTime)} ms");
|
||||
}
|
||||
|
||||
public void CreateOutdoorPvPForMap(Map map)
|
||||
{
|
||||
for (OutdoorPvPTypes outdoorPvpType = OutdoorPvPTypes.HellfirePeninsula; outdoorPvpType < OutdoorPvPTypes.Max; ++outdoorPvpType)
|
||||
{
|
||||
if (!OutdoorPvPScriptIds.ContainsKey(outdoorPvpType))
|
||||
if (map.GetId() != m_OutdoorMapIds[(int)outdoorPvpType])
|
||||
continue;
|
||||
|
||||
if (!m_OutdoorPvPDatas.ContainsKey(outdoorPvpType))
|
||||
{
|
||||
Log.outError(LogFilter.Sql, "Could not initialize OutdoorPvP object for type ID {0}; no entry in database.", outdoorPvpType);
|
||||
continue;
|
||||
}
|
||||
|
||||
pvp = Global.ScriptMgr.CreateOutdoorPvP(OutdoorPvPScriptIds[outdoorPvpType]);
|
||||
OutdoorPvP pvp = Global.ScriptMgr.CreateOutdoorPvP(m_OutdoorPvPDatas[outdoorPvpType], map);
|
||||
if (pvp == null)
|
||||
{
|
||||
Log.outError(LogFilter.Outdoorpvp, "Could not initialize OutdoorPvP object for type ID {0}; got NULL pointer from script.", outdoorPvpType);
|
||||
@@ -85,20 +91,23 @@ namespace Game.PvP
|
||||
continue;
|
||||
}
|
||||
|
||||
m_OutdoorPvPSet.Add(pvp);
|
||||
m_OutdoorPvPByMap.Add(map, pvp);
|
||||
}
|
||||
}
|
||||
|
||||
Log.outInfo(LogFilter.ServerLoading, "Loaded {0} outdoor PvP definitions in {1} ms", count, Time.GetMSTimeDiffToNow(oldMSTime));
|
||||
public void DestroyOutdoorPvPForMap(Map map)
|
||||
{
|
||||
m_OutdoorPvPByMap.Remove(map);
|
||||
}
|
||||
|
||||
public void AddZone(uint zoneid, OutdoorPvP handle)
|
||||
{
|
||||
m_OutdoorPvPMap[zoneid] = handle;
|
||||
m_OutdoorPvPMap[(handle.GetMap(), zoneid)] = handle;
|
||||
}
|
||||
|
||||
public void HandlePlayerEnterZone(Player player, uint zoneid)
|
||||
{
|
||||
var outdoor = GetOutdoorPvPToZoneId(zoneid);
|
||||
var outdoor = GetOutdoorPvPToZoneId(player.GetMap(), zoneid);
|
||||
if (outdoor == null)
|
||||
return;
|
||||
|
||||
@@ -111,7 +120,7 @@ namespace Game.PvP
|
||||
|
||||
public void HandlePlayerLeaveZone(Player player, uint zoneid)
|
||||
{
|
||||
var outdoor = GetOutdoorPvPToZoneId(zoneid);
|
||||
var outdoor = GetOutdoorPvPToZoneId(player.GetMap(), zoneid);
|
||||
if (outdoor == null)
|
||||
return;
|
||||
|
||||
@@ -123,15 +132,9 @@ namespace Game.PvP
|
||||
Log.outDebug(LogFilter.Outdoorpvp, "Player {0} left outdoorpvp id {1}", player.GetGUID().ToString(), outdoor.GetTypeId());
|
||||
}
|
||||
|
||||
public OutdoorPvP GetOutdoorPvPToZoneId(uint zoneid)
|
||||
public OutdoorPvP GetOutdoorPvPToZoneId(Map map, uint zoneid)
|
||||
{
|
||||
var outdoor = m_OutdoorPvPMap.LookupByKey(zoneid);
|
||||
if (outdoor == null)
|
||||
{
|
||||
// no handle for this zone, return
|
||||
return null;
|
||||
}
|
||||
return outdoor;
|
||||
return m_OutdoorPvPMap.LookupByKey((map, zoneid));
|
||||
}
|
||||
|
||||
public void Update(uint diff)
|
||||
@@ -139,7 +142,7 @@ namespace Game.PvP
|
||||
m_UpdateTimer += diff;
|
||||
if (m_UpdateTimer > 1000)
|
||||
{
|
||||
foreach (var outdoor in m_OutdoorPvPSet)
|
||||
foreach (var (_, outdoor) in m_OutdoorPvPByMap)
|
||||
outdoor.Update(m_UpdateTimer);
|
||||
m_UpdateTimer = 0;
|
||||
}
|
||||
@@ -147,69 +150,50 @@ namespace Game.PvP
|
||||
|
||||
public bool HandleCustomSpell(Player player, uint spellId, GameObject go)
|
||||
{
|
||||
foreach (var outdoor in m_OutdoorPvPSet)
|
||||
{
|
||||
if (outdoor.HandleCustomSpell(player, spellId, go))
|
||||
return true;
|
||||
}
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null && pvp.HasPlayer(player))
|
||||
return pvp.HandleCustomSpell(player, spellId, go);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public ZoneScript GetZoneScript(uint zoneId)
|
||||
{
|
||||
var outdoor = GetOutdoorPvPToZoneId(zoneId);
|
||||
if (outdoor == null)
|
||||
return null;
|
||||
|
||||
return outdoor;
|
||||
}
|
||||
|
||||
public bool HandleOpenGo(Player player, GameObject go)
|
||||
{
|
||||
foreach (var outdoor in m_OutdoorPvPSet)
|
||||
{
|
||||
if (outdoor.HandleOpenGo(player, go))
|
||||
return true;
|
||||
}
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null && pvp.HasPlayer(player))
|
||||
return pvp.HandleOpenGo(player, go);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void HandleGossipOption(Player player, Creature creature, uint gossipid)
|
||||
{
|
||||
foreach (var outdoor in m_OutdoorPvPSet)
|
||||
{
|
||||
if (outdoor.HandleGossipOption(player, creature, gossipid))
|
||||
return;
|
||||
}
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null && pvp.HasPlayer(player))
|
||||
pvp.HandleGossipOption(player, creature, gossipid);
|
||||
}
|
||||
|
||||
public bool CanTalkTo(Player player, Creature creature, GossipMenuItems gso)
|
||||
{
|
||||
foreach (var outdoor in m_OutdoorPvPSet)
|
||||
{
|
||||
if (outdoor.CanTalkTo(player, creature, gso))
|
||||
return true;
|
||||
}
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null && pvp.HasPlayer(player))
|
||||
return pvp.CanTalkTo(player, creature, gso);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void HandleDropFlag(Player player, uint spellId)
|
||||
{
|
||||
foreach (var outdoor in m_OutdoorPvPSet)
|
||||
{
|
||||
if (outdoor.HandleDropFlag(player, spellId))
|
||||
return;
|
||||
}
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null && pvp.HasPlayer(player))
|
||||
pvp.HandleDropFlag(player, spellId);
|
||||
}
|
||||
|
||||
public void HandlePlayerResurrects(Player player, uint zoneid)
|
||||
{
|
||||
var outdoor = GetOutdoorPvPToZoneId(zoneid);
|
||||
if (outdoor == null)
|
||||
return;
|
||||
|
||||
if (outdoor.HasPlayer(player))
|
||||
outdoor.HandlePlayerResurrects(player, zoneid);
|
||||
OutdoorPvP pvp = player.GetOutdoorPvP();
|
||||
if (pvp != null && pvp.HasPlayer(player))
|
||||
pvp.HandlePlayerResurrects(player, zoneid);
|
||||
}
|
||||
|
||||
public string GetDefenseMessage(uint zoneId, uint id, Locale locale)
|
||||
@@ -224,14 +208,15 @@ namespace Game.PvP
|
||||
|
||||
// contains all initiated outdoor pvp events
|
||||
// used when initing / cleaning up
|
||||
List<OutdoorPvP> m_OutdoorPvPSet = new();
|
||||
MultiMap<Map, OutdoorPvP> m_OutdoorPvPByMap = new();
|
||||
|
||||
// maps the zone ids to an outdoor pvp event
|
||||
// used in player event handling
|
||||
Dictionary<uint, OutdoorPvP> m_OutdoorPvPMap = new();
|
||||
Dictionary<(Map map, uint zoneId), OutdoorPvP> m_OutdoorPvPMap = new();
|
||||
|
||||
// Holds the outdoor PvP templates
|
||||
Dictionary<OutdoorPvPTypes, uint> OutdoorPvPScriptIds = new();
|
||||
uint[] m_OutdoorMapIds = { 0, 530, 530, 530, 530, 1 };
|
||||
Dictionary<OutdoorPvPTypes, uint> m_OutdoorPvPDatas = new();
|
||||
|
||||
// update interval
|
||||
uint m_UpdateTimer;
|
||||
|
||||
@@ -25,7 +25,7 @@ namespace Game.PvP
|
||||
{
|
||||
class HellfirePeninsulaPvP : OutdoorPvP
|
||||
{
|
||||
public HellfirePeninsulaPvP()
|
||||
public HellfirePeninsulaPvP(Map map) : base(map)
|
||||
{
|
||||
m_TypeId = OutdoorPvPTypes.HellfirePeninsula;
|
||||
m_AllianceTowersControlled = 0;
|
||||
@@ -36,7 +36,6 @@ namespace Game.PvP
|
||||
{
|
||||
m_AllianceTowersControlled = 0;
|
||||
m_HordeTowersControlled = 0;
|
||||
SetMapFromZone(HPConst.BuffZones[0]);
|
||||
|
||||
// add the zones affected by the pvp buff
|
||||
for (int i = 0; i < HPConst.BuffZones.Length; ++i)
|
||||
@@ -305,9 +304,9 @@ namespace Game.PvP
|
||||
{
|
||||
public OutdoorPvP_hellfire_peninsula() : base("outdoorpvp_hp") { }
|
||||
|
||||
public override OutdoorPvP GetOutdoorPvP()
|
||||
public override OutdoorPvP GetOutdoorPvP(Map map)
|
||||
{
|
||||
return new HellfirePeninsulaPvP();
|
||||
return new HellfirePeninsulaPvP(map);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -469,7 +469,7 @@ namespace Game.Scripting
|
||||
public override bool IsDatabaseBound() { return true; }
|
||||
|
||||
// Should return a fully valid OutdoorPvP object for the type ID.
|
||||
public virtual OutdoorPvP GetOutdoorPvP() { return null; }
|
||||
public virtual OutdoorPvP GetOutdoorPvP(Map map) { return null; }
|
||||
}
|
||||
|
||||
public class WeatherScript : ScriptObject
|
||||
|
||||
@@ -729,9 +729,9 @@ namespace Game.Scripting
|
||||
}
|
||||
|
||||
// OutdoorPvPScript
|
||||
public OutdoorPvP CreateOutdoorPvP(uint scriptId)
|
||||
public OutdoorPvP CreateOutdoorPvP(uint scriptId, Map map)
|
||||
{
|
||||
return RunScriptRet<OutdoorPvPScript, OutdoorPvP>(p => p.GetOutdoorPvP(), scriptId, null);
|
||||
return RunScriptRet<OutdoorPvPScript, OutdoorPvP>(p => p.GetOutdoorPvP(map), scriptId, null);
|
||||
}
|
||||
|
||||
// WeatherScript
|
||||
|
||||
Reference in New Issue
Block a user