[Zone] Implement Zone State Saving on Shutdown (#4715)

* Save spawns

* Update base_zone_state_spawns_repository.h

* Zone state save work

* Code cleanup

* More cleanup

* Database migration

* Update database_update_manifest.cpp

* Revert decay at storage model

* Code cleanup

* More cleanup

* More cleanup

* More cleanup

* Entity variables

* Add entity variables to the schema

* Post rebase

* Checkpoint

* Serialize / deserialize buffs

* Current hp / mana / end save / load

* Save / load current_waypoint

* Add zone spawn protection

* Finishing touches

* Cleanup

* Update zone_save_state.cpp

* Cleanup

* Update zone_save_state.cpp

* Update npc.cpp

* Update npc.cpp

* More

* Update perl_npc.cpp

* Update zone_loot.cpp
This commit is contained in:
Chris Miles
2025-02-28 15:31:06 -06:00
committed by GitHub
parent 425d24c1f4
commit 2f7ca2cdc8
26 changed files with 1637 additions and 59 deletions
+18 -7
View File
@@ -16,6 +16,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <cereal/archives/json.hpp>
#include "../common/global_define.h"
#include "../common/strings.h"
@@ -33,6 +34,7 @@
#include "../common/repositories/spawn2_repository.h"
#include "../common/repositories/spawn2_disabled_repository.h"
#include "../common/repositories/respawn_times_repository.h"
#include "../common/repositories/zone_state_spawns_repository.h"
extern EntityList entity_list;
extern Zone* zone;
@@ -85,9 +87,9 @@ Spawn2::Spawn2(uint32 in_spawn2_id, uint32 spawngroup_id,
x = in_x;
y = in_y;
z = in_z;
heading = in_heading;
respawn_ = respawn;
variance_ = variance;
heading = in_heading;
m_respawn_time = respawn;
variance_ = variance;
grid_ = grid;
path_when_zone_idle = in_path_when_zone_idle;
condition_id = in_cond_id;
@@ -95,6 +97,7 @@ Spawn2::Spawn2(uint32 in_spawn2_id, uint32 spawngroup_id,
npcthis = nullptr;
enabled = in_enabled;
this->anim = anim;
currentnpcid = 0;
if(timeleft == 0xFFFFFFFF) {
//special disable timeleft
@@ -115,7 +118,7 @@ Spawn2::~Spawn2()
uint32 Spawn2::resetTimer()
{
uint32 rspawn = respawn_ * 1000;
uint32 rspawn = m_respawn_time * 1000;
if (variance_ != 0) {
int var_over_2 = (variance_ * 1000) / 2;
@@ -150,12 +153,12 @@ uint32 Spawn2::despawnTimer(uint32 despawn_timer)
bool Spawn2::Process() {
IsDespawned = false;
if (!Enabled())
if (!Enabled()) {
return true;
}
//grab our spawn group
SpawnGroup *spawn_group = zone->spawn_group_list.GetSpawnGroup(spawngroup_id_);
if (NPCPointerValid() && (spawn_group && spawn_group->despawn == 0 || condition_id != 0)) {
return true;
}
@@ -195,7 +198,7 @@ bool Spawn2::Process() {
}
//have the spawn group pick an NPC for us
uint32 npcid = spawn_group->GetNPCType(condition_value);
uint32 npcid = currentnpcid && currentnpcid > 0 ? currentnpcid : spawn_group->GetNPCType(condition_value);
if (npcid == 0) {
LogSpawns("Spawn2 [{}]: Spawn group [{}] did not yeild an NPC! not spawning", spawn2_id, spawngroup_id_);
@@ -267,10 +270,12 @@ bool Spawn2::Process() {
NPC *npc = new NPC(tmp, this, glm::vec4(x, y, z, heading), GravityBehavior::Water);
npcthis = npc;
npc->AddLootTable();
if (npc->DropsGlobalLoot()) {
npc->CheckGlobalLootTables();
}
npc->SetSpawnGroupId(spawngroup_id_);
npc->SaveGuardPointAnim(anim);
npc->SetAppearance((EmuAppearance) anim);
@@ -500,6 +505,12 @@ bool ZoneDatabase::PopulateZoneSpawnList(uint32 zoneid, LinkedList<Spawn2*> &spa
NPC::SpawnZoneController();
if (RuleB(Zone, StateSavingOnShutdown) && zone->LoadZoneState(spawn_times, disabled_spawns)) {
LogZoneState("Loaded zone state for zone [{}] instance_id [{}]", zone_name, zone->GetInstanceID());
return true;
}
// normal spawn2 loading
for (auto &s: spawns) {
uint32 spawn_time_left = 0;
if (spawn_times.count(s.id) != 0) {