[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
+89
View File
@@ -300,3 +300,92 @@ std::vector<LootdropEntriesRepository::LootdropEntries> Zone::GetLootdropEntries
return entries;
}
void Zone::LoadLootDrops(const std::vector<uint32> in_lootdrop_ids)
{
BenchTimer timer;
// copy lootdrop_ids
std::vector<uint32> lootdrop_ids = in_lootdrop_ids;
// check if lootdrop is already loaded
std::vector<uint32> loaded_drops = {};
for (const auto &e: lootdrop_ids) {
for (const auto &f: m_lootdrops) {
if (e == f.id) {
LogLootDetail("Lootdrop [{}] already loaded", e);
loaded_drops.push_back(e);
}
}
}
// remove loaded drops from lootdrop_ids
for (const auto &e: loaded_drops) {
lootdrop_ids.erase(
std::remove(
lootdrop_ids.begin(),
lootdrop_ids.end(),
e
),
lootdrop_ids.end()
);
}
if (lootdrop_ids.empty()) {
LogLootDetail("No lootdrops to load");
return;
}
auto lootdrops = LootdropRepository::GetWhere(
content_db,
fmt::format(
"id IN ({})",
Strings::Join(lootdrop_ids, ",")
)
);
auto lootdrop_entries = LootdropEntriesRepository::GetWhere(
content_db,
fmt::format(
"lootdrop_id IN ({})",
Strings::Join(lootdrop_ids, ",")
)
);
// emplace back drops to m_lootdrops if not exists
for (const auto &e: lootdrops) {
bool has_drop = false;
for (const auto &l: m_lootdrops) {
if (e.id == l.id) {
has_drop = true;
break;
}
}
bool has_entry = false;
if (!has_drop) {
// add lootdrop
m_lootdrops.emplace_back(e);
// add lootdrop entries
for (const auto &f: lootdrop_entries) {
if (e.id == f.lootdrop_id) {
// check if lootdrop entry already exists in memory
has_entry = false;
for (const auto &g: m_lootdrop_entries) {
if (f.lootdrop_id == g.lootdrop_id && f.item_id == g.item_id && f.multiplier == g.multiplier) {
has_entry = true;
break;
}
}
}
}
}
}
if (!lootdrop_ids.empty()) {
LogInfo("Loaded [{}] lootdrops ({}s)", m_lootdrops.size(), std::to_string(timer.elapsed()));
}
}