Core/Scripts: Save instance data in JSON format

Port From (https://github.com/TrinityCore/TrinityCore/commit/76be303351ae398b7f9e69e4c472cb5b05fce45e)
This commit is contained in:
hondacrx
2022-10-04 14:04:16 -04:00
parent 66c7047a29
commit 67d6fa48eb
7 changed files with 454 additions and 166 deletions
@@ -116,9 +116,9 @@ namespace Game.Chat
}
[Command("savedata", RBACPermissions.CommandInstanceSavedata)]
static bool HandleInstanceSaveData(CommandHandler handler)
static bool HandleInstanceSaveDataCommand(CommandHandler handler)
{
Player player = handler.GetSession().GetPlayer();
/*Player player = handler.GetSession().GetPlayer();
InstanceMap map = player.GetMap().ToInstanceMap();
if (map == null)
{
@@ -132,7 +132,7 @@ namespace Game.Chat
return false;
}
map.GetInstanceScript().SaveToDB();
map.GetInstanceScript().SaveToDB();*/
return true;
}
@@ -460,13 +460,13 @@ namespace Game.Maps
_sharedData = sharedData;
}
public void SetInstanceId(uint instanceId)
public override void SetInstanceId(uint instanceId)
{
base.SetInstanceId(instanceId);
_sharedData.InstanceId = instanceId;
}
public InstanceLockData GetInstanceInitializationData() { return _sharedData; }
public override InstanceLockData GetInstanceInitializationData() { return _sharedData; }
public SharedInstanceLockData GetSharedData() { return _sharedData; }
}
+109 -93
View File
@@ -44,17 +44,6 @@ namespace Game.Maps
InstanceScenario scenario = instance.GetInstanceScenario();
if (scenario != null)
scenario.SaveToDB();
string data = GetSaveData();
if (string.IsNullOrEmpty(data))
return;
PreparedStatement stmt = DB.Characters.GetPreparedStatement(CharStatements.UPD_INSTANCE_DATA);
stmt.AddValue(0, GetCompletedEncounterMask());
stmt.AddValue(1, data);
stmt.AddValue(2, _entranceId);
stmt.AddValue(3, instance.GetInstanceId());
DB.Characters.Execute(stmt);
}
public virtual bool IsEncounterInProgress()
@@ -104,9 +93,7 @@ namespace Game.Maps
public void SetHeaders(string dataHeaders)
{
foreach (char header in dataHeaders)
if (char.IsLetter(header))
headers.Add(header);
headers = dataHeaders;
}
public void LoadBossBoundaries(BossBoundaryEntry[] data)
@@ -178,7 +165,7 @@ namespace Game.Maps
for (int i = 0; i < MapConst.MaxDungeonEncountersPerBoss; ++i)
bosses[bossId].DungeonEncounters[i] = CliDB.DungeonEncounterStorage.LookupByKey(dungeonEncounterIds[i]);
}
public virtual void UpdateDoorState(GameObject door)
{
var range = doors.LookupByKey(door.GetEntry());
@@ -430,8 +417,8 @@ namespace Game.Maps
bossInfo.state = state;
SaveToDB();
if (state == EncounterState.Done && dungeonEncounter != null)
instance.UpdateInstanceLock(dungeonEncounter, new(id, state));
if (dungeonEncounter != null)
instance.UpdateInstanceLock(new UpdateBossStateSaveDataEvent(dungeonEncounter, id, state));
}
for (uint type = 0; type < (int)DoorType.Max; ++type)
@@ -470,7 +457,7 @@ namespace Game.Maps
UpdateSpawnGroups();
}
public virtual void Load(string data)
public void Load(string data)
{
if (string.IsNullOrEmpty(data))
{
@@ -480,12 +467,11 @@ namespace Game.Maps
OutLoadInstData(data);
var loadStream = new StringArguments(data);
if (ReadSaveDataHeaders(loadStream))
InstanceScriptDataReader reader = new(this);
if (reader.Load(data) == InstanceScriptDataReader.Result.Ok)
{
ReadSaveDataBossStates(loadStream);
ReadSaveDataMore(loadStream);
UpdateSpawnGroups();
AfterDataLoad();
}
else
OutLoadInstDataFail();
@@ -493,84 +479,39 @@ namespace Game.Maps
OutLoadInstDataComplete();
}
bool ReadSaveDataHeaders(StringArguments data)
{
foreach (char header in headers)
{
char buff = data.NextChar();
if (header != buff)
return false;
}
return true;
}
void ReadSaveDataBossStates(StringArguments data)
{
foreach (var pair in bosses)
{
EncounterState buff = (EncounterState)data.NextUInt32();
if (buff == EncounterState.InProgress || buff == EncounterState.Fail || buff == EncounterState.Special)
buff = EncounterState.NotStarted;
if (buff < EncounterState.ToBeDecided)
SetBossState(pair.Key, buff);
}
UpdateSpawnGroups();
}
public virtual string GetSaveData()
public string GetSaveData()
{
OutSaveInstData();
StringBuilder saveStream = new();
InstanceScriptDataWriter writer = new(this);
WriteSaveDataHeaders(saveStream);
WriteSaveDataBossStates(saveStream);
WriteSaveDataMore(saveStream);
writer.FillData();
OutSaveInstDataComplete();
return saveStream.ToString();
return writer.GetString();
}
public string UpdateSaveData(string oldData, UpdateSaveDataEvent saveEvent)
public string UpdateBossStateSaveData(string oldData, UpdateBossStateSaveDataEvent saveEvent)
{
if (!instance.GetMapDifficulty().IsUsingEncounterLocks())
return GetSaveData();
int position = (int)(headers.Count + saveEvent.BossId) * 2;
StringBuilder newData = new(oldData);
if (position >= oldData.Length)
{
// Initialize blank data
StringBuilder saveStream = new();
WriteSaveDataHeaders(saveStream);
for (var i = 0; i < bosses.Count; ++i)
saveStream.Append($"{(uint)EncounterState.NotStarted} ");
WriteSaveDataMore(saveStream);
newData = saveStream;
}
newData.Remove(position, 2);
newData.Insert(position, $"{(uint)saveEvent.NewState}0");
return newData.ToString();
}
void WriteSaveDataHeaders(StringBuilder data)
{
foreach (char header in headers)
data.AppendFormat("{0} ", header);
InstanceScriptDataWriter writer = new(this);
writer.FillDataFrom(oldData);
writer.SetBossState(saveEvent);
return writer.GetString();
}
void WriteSaveDataBossStates(StringBuilder data)
public string UpdateAdditionalSaveData(string oldData, UpdateAdditionalSaveDataEvent saveEvent)
{
foreach (BossInfo bossInfo in bosses.Values)
data.AppendFormat("{0} ", (uint)bossInfo.state);
if (!instance.GetMapDifficulty().IsUsingEncounterLocks())
return GetSaveData();
InstanceScriptDataWriter writer = new(this);
writer.FillDataFrom(oldData);
writer.SetAdditionalData(saveEvent);
return writer.GetString();
}
public void HandleGameObject(ObjectGuid guid, bool open, GameObject go = null)
@@ -763,7 +704,7 @@ namespace Game.Maps
return false;
}
public void SetEntranceLocation(uint worldSafeLocationId)
{
_entranceId = worldSafeLocationId;
@@ -998,6 +939,12 @@ namespace Game.Maps
public byte GetCombatResurrectionCharges() { return _combatResurrectionCharges; }
public void RegisterPersistentScriptValue(PersistentInstanceScriptValueBase value) { _persistentScriptValues.Add(value); }
public string GetHeader() { return headers; }
public List<PersistentInstanceScriptValueBase> GetPersistentScriptValues() { return _persistentScriptValues; }
public void SetBossNumber(uint number)
{
for (uint i = 0; i < number; ++i)
@@ -1010,15 +957,15 @@ namespace Game.Maps
public void OutLoadInstDataComplete() { Log.outDebug(LogFilter.Scripts, "Instance Data Load for Instance {0} (Map {1}, Instance Id: {2}) is complete.", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); }
public void OutLoadInstDataFail() { Log.outDebug(LogFilter.Scripts, "Unable to load Instance Data for Instance {0} (Map {1}, Instance Id: {2}).", instance.GetMapName(), instance.GetId(), instance.GetInstanceId()); }
public virtual void ReadSaveDataMore(StringArguments data) { }
public virtual void WriteSaveDataMore(StringBuilder data) { }
public List<InstanceSpawnGroupInfo> GetInstanceSpawnGroups() { return _instanceSpawnGroups; }
// Override this function to validate all additional data loads
public virtual void AfterDataLoad() { }
public InstanceMap instance;
List<char> headers = new();
string headers;
Dictionary<uint, BossInfo> bosses = new();
List<PersistentInstanceScriptValueBase> _persistentScriptValues = new();
MultiMap<uint, DoorInfo> doors = new();
Dictionary<uint, MinionInfo> minions = new();
Dictionary<uint, uint> _creatureInfo = new();
@@ -1131,15 +1078,84 @@ namespace Game.Maps
public BossInfo bossInfo;
}
public struct UpdateSaveDataEvent
public struct UpdateBossStateSaveDataEvent
{
public DungeonEncounterRecord DungeonEncounter;
public uint BossId;
public EncounterState NewState;
public UpdateSaveDataEvent(uint bossId, EncounterState state)
public UpdateBossStateSaveDataEvent(DungeonEncounterRecord dungeonEncounter, uint bossId, EncounterState state)
{
DungeonEncounter = dungeonEncounter;
BossId = bossId;
NewState = state;
}
}
public struct UpdateAdditionalSaveDataEvent
{
public string Key;
public object Value;
public UpdateAdditionalSaveDataEvent(string key, object value)
{
Key = key;
Value = value;
}
}
public class PersistentInstanceScriptValueBase
{
protected InstanceScript _instance;
protected string _name;
protected object _value;
protected PersistentInstanceScriptValueBase(InstanceScript instance, string name, object value)
{
_instance = instance;
_name = name;
_value = value;
_instance.RegisterPersistentScriptValue(this);
}
public string GetName() { return _name; }
public UpdateAdditionalSaveDataEvent CreateEvent()
{
return new UpdateAdditionalSaveDataEvent(_name, _value);
}
public void LoadValue(long value)
{
_value = value;
}
public void LoadValue(double value)
{
_value = value;
}
}
class PersistentInstanceScriptValue<T> : PersistentInstanceScriptValueBase
{
public PersistentInstanceScriptValue(InstanceScript instance, string name, T value) : base(instance, name, value) { }
public PersistentInstanceScriptValue<T> SetValue(T value)
{
_value = value;
NotifyValueChanged();
return this;
}
void NotifyValueChanged()
{
_instance.instance.UpdateInstanceLock(CreateEvent());
}
void LoadValue(T value)
{
_value = value;
}
}
}
@@ -0,0 +1,279 @@
/*
* Copyright (C) 2012-2020 CypherCore <http://github.com/CypherCore>
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*/
using Framework.Constants;
using Game.DataStorage;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
namespace Game.Maps
{
class InstanceScriptDataReader
{
public enum Result
{
Ok,
MalformedJson,
RootIsNotAnObject,
MissingHeader,
UnexpectedHeader,
MissingBossStates,
BossStatesIsNotAnObject,
UnknownBoss,
BossStateIsNotAnObject,
MissingBossState,
BossStateValueIsNotANumber,
AdditionalDataIsNotAnObject,
AdditionalDataUnexpectedValueType
}
InstanceScript _instance;
JsonDocument _doc;
public InstanceScriptDataReader(InstanceScript instance)
{
_instance = instance;
}
public Result Load(string data)
{
/*
Expected JSON
{
"Header": "HEADER_STRING_SET_BY_SCRIPT",
"BossStates": [0,2,0,...] // indexes are boss ids, values are EncounterState
"AdditionalData: { // optional
"ExtraKey1": 123
"AnotherExtraKey": 2.0
}
}
*/
try
{
_doc = JsonDocument.Parse(data);
}
catch (JsonException ex)
{
Log.outError(LogFilter.Scripts, $"JSON parser error {ex.Message} at {ex.LineNumber} while loading data for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.MalformedJson;
}
if (_doc.RootElement.ValueKind != JsonValueKind.Object)
{
Log.outError(LogFilter.Scripts, $"Root JSON value is not an object for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.RootIsNotAnObject;
}
Result result = ParseHeader();
if (result != Result.Ok)
return result;
result = ParseBossStates();
if (result != Result.Ok)
return result;
result = ParseAdditionalData();
if (result != Result.Ok)
return result;
return Result.Ok;
}
Result ParseHeader()
{
if (!_doc.RootElement.TryGetProperty("Header", out JsonElement header))
{
Log.outError(LogFilter.Scripts, $"Missing data header for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.MissingHeader;
}
if (header.GetString() != _instance.GetHeader())
{
Log.outError(LogFilter.Scripts, $"Incorrect data header for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}], expected \"{_instance.GetHeader()}\" got \"{header.GetString()}\"");
return Result.UnexpectedHeader;
}
return Result.Ok;
}
Result ParseBossStates()
{
if (!_doc.RootElement.TryGetProperty("BossStates", out JsonElement bossStates))
{
Log.outError(LogFilter.Scripts, $"Missing boss states for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.MissingBossStates;
}
if (bossStates.ValueKind != JsonValueKind.Array)
{
Log.outError(LogFilter.Scripts, $"Boss states is not an array for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.BossStatesIsNotAnObject;
}
for (int bossId = 0; bossId < bossStates.GetArrayLength(); ++bossId)
{
if (bossId >= _instance.GetEncounterCount())
{
Log.outError(LogFilter.Scripts, $"Boss states has entry for boss with higher id ({bossId}) than number of bosses ({_instance.GetEncounterCount()}) for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.UnknownBoss;
}
var bossState = bossStates[bossId];
if (bossState.ValueKind != JsonValueKind.Number)
{
Log.outError(LogFilter.Scripts, $"Boss state for boss ({bossId}) is not a number for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.BossStateIsNotAnObject;
}
EncounterState state = (EncounterState)bossState.GetInt32();
if (state == EncounterState.InProgress || state == EncounterState.Fail || state == EncounterState.Special)
state = EncounterState.NotStarted;
if (state < EncounterState.ToBeDecided)
_instance.SetBossState((uint)bossId, state);
}
return Result.Ok;
}
Result ParseAdditionalData()
{
if (!_doc.RootElement.TryGetProperty("AdditionalData", out JsonElement moreData))
return Result.Ok;
if (moreData.ValueKind != JsonValueKind.Object)
{
Log.outError(LogFilter.Scripts, $"Additional data is not an object for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.AdditionalDataIsNotAnObject;
}
foreach (PersistentInstanceScriptValueBase valueBase in _instance.GetPersistentScriptValues())
{
if (moreData.TryGetProperty(valueBase.GetName(), out JsonElement value) && value.ValueKind != JsonValueKind.Null)
{
if (value.ValueKind != JsonValueKind.Number)
{
Log.outError(LogFilter.Scripts, $"Additional data value for key {valueBase.GetName()} is not a number for instance {GetInstanceId()} [{GetMapId()}-{GetMapName()} | {GetDifficultyId()}-{GetDifficultyName()}]");
return Result.AdditionalDataUnexpectedValueType;
}
if (value.TryGetDouble(out double doubleValue))
valueBase.LoadValue(doubleValue);
else
valueBase.LoadValue(value.GetInt64());
}
}
return Result.Ok;
}
uint GetInstanceId() { return _instance.instance.GetInstanceId(); }
uint GetMapId() { return _instance.instance.GetId(); }
string GetMapName() { return _instance.instance.GetMapName(); }
uint GetDifficultyId() { return (uint)_instance.instance.GetDifficultyID(); }
string GetDifficultyName() { return CliDB.DifficultyStorage.LookupByKey(_instance.instance.GetDifficultyID()).Name; }
}
class InstanceScriptDataWriter
{
InstanceScript _instance;
JsonObject _doc = new();
public InstanceScriptDataWriter(InstanceScript instance)
{
_instance = instance;
}
public string GetString()
{
using var stream = new MemoryStream();
using (var writer = new Utf8JsonWriter(stream))
{
_doc.WriteTo(writer);
}
return Encoding.UTF8.GetString(stream.ToArray());
}
public void FillData(bool withValues = true)
{
_doc.Add("Header", _instance.GetHeader());
JsonArray bossStates = new();
for (uint bossId = 0; bossId < _instance.GetEncounterCount(); ++bossId)
bossStates.Add(JsonValue.Create((int)(withValues ? _instance.GetBossState(bossId) : EncounterState.NotStarted)));
_doc.Add("BossStates", bossStates);
if (!_instance.GetPersistentScriptValues().Empty())
{
JsonObject moreData = new();
foreach (PersistentInstanceScriptValueBase additionalValue in _instance.GetPersistentScriptValues())
{
if (withValues)
{
UpdateAdditionalSaveDataEvent data = additionalValue.CreateEvent();
if (data.Value is double)
moreData.Add(data.Key, (double)data.Value);
else
moreData.Add(data.Key, (long)data.Value);
}
else
moreData.Add(additionalValue.GetName(), null);
}
_doc.Add("AdditionalData", moreData);
}
}
public void FillDataFrom(string data)
{
try
{
_doc = JsonNode.Parse(data).AsObject();
}
catch (JsonException ex)
{
FillData(false);
}
}
public void SetBossState(UpdateBossStateSaveDataEvent data)
{
var array = _doc["BossStates"].AsArray();
array[(int)data.BossId] = (int)data.NewState;
}
public void SetAdditionalData(UpdateAdditionalSaveDataEvent data)
{
var jObject = _doc["AdditionalData"].AsObject();
if (data.Value is double)
jObject[data.Key] = (double)data.Value;
else
jObject[data.Key] = (long)data.Value;
}
}
}
+46 -6
View File
@@ -4990,20 +4990,18 @@ namespace Game.Maps
return Global.ObjectMgr.GetScriptName(i_script_id);
}
public void UpdateInstanceLock(DungeonEncounterRecord dungeonEncounter, UpdateSaveDataEvent updateSaveDataEvent)
public void UpdateInstanceLock(UpdateBossStateSaveDataEvent updateSaveDataEvent)
{
if (i_instanceLock != null)
{
uint instanceCompletedEncounters = i_instanceLock.GetData().CompletedEncountersMask;
if (dungeonEncounter != null)
instanceCompletedEncounters |= 1u << dungeonEncounter.Bit;
uint instanceCompletedEncounters = i_instanceLock.GetData().CompletedEncountersMask | (1u << updateSaveDataEvent.DungeonEncounter.Bit);
MapDb2Entries entries = new(GetEntry(), GetMapDifficulty());
SQLTransaction trans = new();
if (entries.IsInstanceIdBound())
Global.InstanceLockMgr.UpdateSharedInstanceLock(trans, new InstanceLockUpdateEvent(GetInstanceId(), i_data.GetSaveData(), instanceCompletedEncounters, dungeonEncounter));
Global.InstanceLockMgr.UpdateSharedInstanceLock(trans, new InstanceLockUpdateEvent(GetInstanceId(), i_data.GetSaveData(), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter));
foreach (var player in GetPlayers())
{
@@ -5018,7 +5016,49 @@ namespace Game.Maps
bool isNewLock = playerLock == null || playerLock.GetData().CompletedEncountersMask == 0 || playerLock.IsExpired();
InstanceLock newLock = Global.InstanceLockMgr.UpdateInstanceLockForPlayer(trans, player.GetGUID(), entries, new InstanceLockUpdateEvent(GetInstanceId(), i_data.UpdateSaveData(oldData, updateSaveDataEvent), instanceCompletedEncounters, dungeonEncounter));
InstanceLock newLock = Global.InstanceLockMgr.UpdateInstanceLockForPlayer(trans, player.GetGUID(), entries, new InstanceLockUpdateEvent(GetInstanceId(), i_data.UpdateBossStateSaveData(oldData, updateSaveDataEvent), instanceCompletedEncounters, updateSaveDataEvent.DungeonEncounter));
if (isNewLock)
{
InstanceSaveCreated data = new();
data.Gm = player.IsGameMaster();
player.SendPacket(data);
player.GetSession().SendCalendarRaidLockoutAdded(newLock);
}
}
DB.Characters.CommitTransaction(trans);
}
}
public void UpdateInstanceLock(UpdateAdditionalSaveDataEvent updateSaveDataEvent)
{
if (i_instanceLock != null)
{
uint instanceCompletedEncounters = i_instanceLock.GetData().CompletedEncountersMask;
MapDb2Entries entries = new(GetEntry(), GetMapDifficulty());
SQLTransaction trans = new();
if (entries.IsInstanceIdBound())
Global.InstanceLockMgr.UpdateSharedInstanceLock(trans, new InstanceLockUpdateEvent(GetInstanceId(), i_data.GetSaveData(), instanceCompletedEncounters, null));
foreach (var player in GetPlayers())
{
// never instance bind GMs with GM mode enabled
if (player.IsGameMaster())
continue;
InstanceLock playerLock = Global.InstanceLockMgr.FindActiveInstanceLock(player.GetGUID(), entries);
string oldData = "";
if (playerLock != null)
oldData = playerLock.GetData().Data;
bool isNewLock = playerLock == null || playerLock.GetData().CompletedEncountersMask == 0 || playerLock.IsExpired();
InstanceLock newLock = Global.InstanceLockMgr.UpdateInstanceLockForPlayer(trans, player.GetGUID(), entries, new InstanceLockUpdateEvent(GetInstanceId(), i_data.UpdateAdditionalSaveData(oldData, updateSaveDataEvent), instanceCompletedEncounters, null));
if (isNewLock)
{
@@ -114,9 +114,6 @@ namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths
class instance_blackrock_depths_InstanceMapScript : InstanceScript
{
uint[] encounter = new uint[MiscConst.MaxEncounter];
string str_data;
ObjectGuid EmperorGUID;
ObjectGuid PhalanxGUID;
ObjectGuid MagmusGUID;
@@ -155,6 +152,7 @@ namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths
public instance_blackrock_depths_InstanceMapScript(InstanceMap map) : base(map)
{
SetHeaders("BRD");
SetBossNumber(MiscConst.MaxEncounter);
BarAleCount = 0;
GhostKillCount = 0;
@@ -238,40 +236,30 @@ namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths
switch (type)
{
case DataTypes.TypeRingOfLaw:
encounter[0] = data;
SetBossState(0, (EncounterState)data);
break;
case DataTypes.TypeVault:
encounter[1] = data;
SetBossState(1, (EncounterState)data);
break;
case DataTypes.TypeBar:
if (data == (uint)EncounterState.Special)
++BarAleCount;
else
encounter[2] = data;
SetBossState(2, (EncounterState)data);
break;
case DataTypes.TypeTombOfSeven:
encounter[3] = data;
SetBossState(3, (EncounterState)data);
break;
case DataTypes.TypeLyceum:
encounter[4] = data;
SetBossState(4, (EncounterState)data);
break;
case DataTypes.TypeIronHall:
encounter[5] = data;
SetBossState(5, (EncounterState)data);
break;
case DataTypes.DataGhostkill:
GhostKillCount += data;
break;
}
if (data == (uint)EncounterState.Done || GhostKillCount >= MiscConst.TombOfSevenBossNum)
{
OutSaveInstData();
str_data = $"{encounter[0]} {encounter[1]} {encounter[2]} {encounter[3]} {encounter[4]} {encounter[5]} {GhostKillCount}";
SaveToDB();
OutSaveInstDataComplete();
}
}
public override uint GetData(uint type)
@@ -279,20 +267,20 @@ namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths
switch (type)
{
case DataTypes.TypeRingOfLaw:
return encounter[0];
return (uint)GetBossState(0);
case DataTypes.TypeVault:
return encounter[1];
return (uint)GetBossState(1);
case DataTypes.TypeBar:
if (encounter[2] == (uint)EncounterState.InProgress && BarAleCount == 3)
if (GetBossState(2) == EncounterState.InProgress && BarAleCount == 3)
return (uint)EncounterState.Special;
else
return encounter[2];
return (uint)GetBossState(2);
case DataTypes.TypeTombOfSeven:
return encounter[3];
return (uint)GetBossState(3);
case DataTypes.TypeLyceum:
return encounter[4];
return (uint)GetBossState(4);
case DataTypes.TypeIronHall:
return encounter[5];
return (uint)GetBossState(5);
case DataTypes.DataGhostkill:
return GhostKillCount;
}
@@ -343,41 +331,6 @@ namespace Scripts.EasternKingdoms.BlackrockMountain.BlackrockDepths
return ObjectGuid.Empty;
}
public override string GetSaveData()
{
return str_data;
}
public override void Load(string str)
{
if (str.IsEmpty())
{
OutLoadInstDataFail();
return;
}
OutLoadInstData(str);
StringArguments loadStream = new(str);
for (var i = 0; i < encounter.Length; ++i)
encounter[i] = loadStream.NextUInt32();
GhostKillCount = loadStream.NextUInt32();
for (byte i = 0; i < encounter.Length; ++i)
if (encounter[i] == (uint)EncounterState.InProgress)
encounter[i] = (uint)EncounterState.NotStarted;
if (GhostKillCount > 0 && GhostKillCount < MiscConst.TombOfSevenBossNum)
GhostKillCount = 0;//reset tomb of seven event
if (GhostKillCount >= MiscConst.TombOfSevenBossNum)
GhostKillCount = MiscConst.TombOfSevenBossNum;
OutLoadInstDataComplete();
}
void TombOfSevenEvent()
{
if (GhostKillCount < MiscConst.TombOfSevenBossNum && !TombBossGUIDs[TombEventCounter].IsEmpty())
@@ -230,7 +230,7 @@ namespace Scripts.EasternKingdoms.BlackrockMountain.MoltenCore
return true;
}
void ReadSaveDataMore(string data)
public override void AfterDataLoad()
{
if (CheckMajordomoExecutus())
_executusSchedule = true;