Core/WorldStates: Add area requirements to world states

Port From (https://github.com/TrinityCore/TrinityCore/commit/70eacebad531af0a4b5b4ac6be6d90ddc56ed5d4)
This commit is contained in:
hondacrx
2022-06-27 16:56:01 -04:00
parent 9cece8cc8a
commit a98ce1eb00
3 changed files with 76 additions and 14 deletions
+7 -7
View File
@@ -2899,21 +2899,21 @@ namespace Game.Entities
SendPacket(worldstate);
}
void SendInitWorldStates(uint zoneid, uint areaid)
void SendInitWorldStates(uint zoneId, uint areaId)
{
// data depends on zoneid/mapid...
Battleground bg = GetBattleground();
uint mapid = GetMapId();
OutdoorPvP pvp = Global.OutdoorPvPMgr.GetOutdoorPvPToZoneId(zoneid);
OutdoorPvP pvp = Global.OutdoorPvPMgr.GetOutdoorPvPToZoneId(zoneId);
InstanceScript instance = GetInstanceScript();
BattleField battlefield = Global.BattleFieldMgr.GetBattlefieldToZoneId(zoneid);
BattleField battlefield = Global.BattleFieldMgr.GetBattlefieldToZoneId(zoneId);
InitWorldStates packet = new();
packet.MapID = mapid;
packet.AreaID = zoneid;
packet.SubareaID = areaid;
packet.AreaID = zoneId;
packet.SubareaID = areaId;
Global.WorldStateMgr.FillInitialWorldStates(packet, GetMap());
Global.WorldStateMgr.FillInitialWorldStates(packet, GetMap(), areaId);
packet.AddState(2264, 0); // SCOURGE_EVENT_WORLDSTATE_EASTERN_PLAGUELANDS
packet.AddState(2263, 0); // SCOURGE_EVENT_WORLDSTATE_TANARIS
@@ -2947,7 +2947,7 @@ namespace Game.Entities
packet.AddState(17043, (uint)(10 + (Global.WorldMgr.GetWarModeDominantFaction() == TeamId.Horde ? Global.WorldMgr.GetWarModeOutnumberedFactionReward() : 0)));
// insert <field> <value>
switch (zoneid)
switch (zoneId)
{
case 1: // Dun Morogh
case 11: // Wetlands
+14 -2
View File
@@ -583,7 +583,7 @@ namespace Game.Maps
}
public Dictionary<int, int> GetWorldStateValues() { return _worldStateValues; }
public void SetWorldStateValue(int worldStateId, int value)
{
int oldValue = _worldStateValues.LookupByKey(worldStateId);
@@ -597,7 +597,19 @@ namespace Game.Maps
UpdateWorldState updateWorldState = new();
updateWorldState.VariableID = (uint)worldStateId;
updateWorldState.Value = value;
SendToPlayers(updateWorldState);
updateWorldState.Write();
foreach (var player in GetPlayers())
{
if (worldStateTemplate != null && !worldStateTemplate.AreaIds.Empty())
{
bool isInAllowedArea = worldStateTemplate.AreaIds.Any(requiredAreaId => Global.DB2Mgr.IsInArea(player.GetAreaId(), requiredAreaId));
if (!isInAllowedArea)
continue;
}
player.SendPacket(updateWorldState);
}
}
void InitializeObject(WorldObject obj)
+55 -5
View File
@@ -16,13 +16,14 @@
*/
using Framework.Collections;
using Framework.Constants;
using Framework.Database;
using Game.DataStorage;
using Game.Maps;
using Game.Networking.Packets;
using System;
using System.Collections.Generic;
using Framework.Constants;
using System.Linq;
namespace Game
{
@@ -38,8 +39,8 @@ namespace Game
{
uint oldMSTime = Time.GetMSTime();
// 0 1 2 3
SQLResult result = DB.World.Query("SELECT ID, DefaultValue, MapIDs, ScriptName FROM world_state");
// 0 1 2 3 4
SQLResult result = DB.World.Query("SELECT ID, DefaultValue, MapIDs, AreaIDs, ScriptName FROM world_state");
if (result.IsEmpty())
return;
@@ -74,7 +75,45 @@ namespace Game
continue;
}
worldState.ScriptId = Global.ObjectMgr.GetScriptId(result.Read<string>(3));
string areaIds = result.Read<string>(3);
if (!worldState.MapIds.Empty())
{
foreach (string areaIdToken in new StringArray(areaIds, ','))
{
if (!uint.TryParse(areaIdToken, out uint areaId))
{
Log.outError(LogFilter.Sql, $"Table `world_state` contains a world state {id} with non-integer AreaID ({areaIdToken}), area ignored");
continue;
}
var areaTableEntry = CliDB.AreaTableStorage.LookupByKey(areaId);
if (areaTableEntry == null)
{
Log.outError(LogFilter.Sql, $"Table `world_state` contains a world state {id} with invalid AreaID ({areaId}), area ignored");
continue;
}
if (!worldState.MapIds.Contains(areaTableEntry.ContinentID))
{
Log.outError(LogFilter.Sql, $"Table `world_state` contains a world state {id} with AreaID ({areaId}) not on any of required maps, area ignored");
continue;
}
worldState.AreaIds.Add(areaId);
}
if (!areaIds.IsEmpty() && worldState.AreaIds.Empty())
{
Log.outError(LogFilter.Sql, $"Table `world_state` contains a world state {id} with nonempty AreaIDs ({areaIds}) but no valid area id was found, ignored");
continue;
}
}
else if (!areaIds.IsEmpty())
{
Log.outError(LogFilter.Sql, $"Table `world_state` contains a world state {id} with nonempty AreaIDs ({areaIds}) but is a realm wide world state, area requirement ignored");
}
worldState.ScriptId = Global.ObjectMgr.GetScriptId(result.Read<string>(4));
if (!worldState.MapIds.Empty())
{
@@ -156,13 +195,23 @@ namespace Game
return new Dictionary<int, int>();
}
public void FillInitialWorldStates(InitWorldStates initWorldStates, Map map)
public void FillInitialWorldStates(InitWorldStates initWorldStates, Map map, uint playerAreaId)
{
foreach (var (worldStateId, value) in _realmWorldStateValues)
initWorldStates.AddState(worldStateId, value);
foreach (var (worldStateId, value) in map.GetWorldStateValues())
{
WorldStateTemplate worldStateTemplate = GetWorldStateTemplate(worldStateId);
if (worldStateTemplate != null && !worldStateTemplate.AreaIds.Empty())
{
bool isInAllowedArea = worldStateTemplate.AreaIds.Any(requiredAreaId => Global.DB2Mgr.IsInArea(playerAreaId, requiredAreaId));
if (!isInAllowedArea)
continue;
}
initWorldStates.AddState(worldStateId, value);
}
}
}
@@ -173,5 +222,6 @@ namespace Game
public uint ScriptId;
public List<uint> MapIds = new();
public List<uint> AreaIds = new();
}
}