[Zone] Zone State Improvements (Continued) (#4768)

* [Zone] Zone State Improvements (Continued)

* Ignore a few events when we resume from suspend

* Add is_zone field

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update database_update_manifest.cpp

* Update zone_save_state.cpp

* Update zone_save_state.cpp

* Add Zone Variables

* Update methods

* Update zone_save_state.cpp

* Update zone_save_state.cpp

---------

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
This commit is contained in:
Chris Miles
2025-03-11 01:14:09 -05:00
committed by GitHub
parent 051ce3736f
commit 30c39194a3
10 changed files with 377 additions and 103 deletions
+71 -4
View File
@@ -291,6 +291,55 @@ inline void LoadNPCState(Zone *zone, NPC *n, ZoneStateSpawnsRepository::ZoneStat
n->SetResumedFromZoneSuspend(true);
}
inline std::string GetZoneVariablesSerialized(Zone *z)
{
std::map<std::string, std::string> variables;
for (const auto &k: z->GetVariables()) {
variables[k] = z->GetVariable(k);
}
try {
std::ostringstream os;
{
cereal::JSONOutputArchiveSingleLine archive(os);
archive(variables);
}
return os.str();
}
catch (const std::exception &e) {
LogZoneState("Failed to serialize variables for zone [{}]", e.what());
return "";
}
return "";
}
inline void LoadZoneVariables(Zone *z, const std::string &variables)
{
if (!Strings::IsValidJson(variables)) {
LogZoneState("Invalid JSON data for zone [{}]", variables);
return;
}
std::map<std::string, std::string> deserialized_map;
try {
std::istringstream is(variables);
{
cereal::JSONInputArchive archive(is);
archive(deserialized_map);
}
}
catch (const std::exception &e) {
LogZoneState("Failed to load zone variables [{}]", e.what());
return;
}
for (const auto &[key, value]: deserialized_map) {
z->SetVariable(key, value);
}
}
bool Zone::LoadZoneState(
std::unordered_map<uint32, uint32> spawn_times,
std::vector<Spawn2DisabledRepository::Spawn2Disabled> disabled_spawns
@@ -315,11 +364,12 @@ bool Zone::LoadZoneState(
zone->Process();
for (auto &s: spawn_states) {
if (s.spawngroup_id == 0) {
if (s.is_zone) {
LoadZoneVariables(zone, s.entity_variables);
continue;
}
if (s.is_corpse) {
if (s.spawngroup_id == 0 || s.is_corpse || s.is_zone) {
continue;
}
@@ -374,7 +424,7 @@ bool Zone::LoadZoneState(
// dynamic spawns, quest spawns, triggers etc.
for (auto &s: spawn_states) {
if (s.spawngroup_id > 0) {
if (s.spawngroup_id > 0 || s.is_zone) {
continue;
}
@@ -524,7 +574,13 @@ void Zone::SaveZoneState()
bool ignore_npcs =
n.second->GetSpawnGroupId() > 0 ||
n.second->GetNPCTypeID() < 100 ||
n.second->HasOwner();
n.second->GetNPCTypeID() == 500 || // Trap::CreateHiddenTrigger
n.second->IsAura() ||
n.second->IsBot() ||
n.second->IsMerc() ||
n.second->IsTrap() ||
n.second->GetSwarmOwner() ||
n.second->IsPet();
if (ignore_npcs) {
continue;
}
@@ -560,6 +616,17 @@ void Zone::SaveZoneState()
spawns.emplace_back(s);
}
// zone state variables
if (!GetVariables().empty()) {
ZoneStateSpawnsRepository::ZoneStateSpawns z{};
z.zone_id = GetZoneID();
z.instance_id = GetInstanceID();
z.is_zone = 1;
z.entity_variables = GetZoneVariablesSerialized(this);
spawns.emplace_back(z);
}
ZoneStateSpawnsRepository::DeleteWhere(
database,
fmt::format(