mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 18:51:29 +00:00
[Fix] Zone State Entity Variable Load Pre-Spawn (#4785)
* [Fix] Zone state ent variable pre-spawn * Update zone_save_state.cpp * Update zone_save_state.cpp * Update spawn2.cpp * Update zone_save_state.cpp * Update zone_save_state.cpp
This commit is contained in:
parent
fd6e5f465d
commit
9528c1e7fc
@ -277,6 +277,13 @@ bool Spawn2::Process() {
|
|||||||
|
|
||||||
npcthis = npc;
|
npcthis = npc;
|
||||||
|
|
||||||
|
if (!m_entity_variables.empty()) {
|
||||||
|
for (auto &var : m_entity_variables) {
|
||||||
|
npc->SetEntityVariable(var.first, var.second);
|
||||||
|
}
|
||||||
|
m_entity_variables = {};
|
||||||
|
}
|
||||||
|
|
||||||
npc->SetResumedFromZoneSuspend(m_resumed_from_zone_suspend);
|
npc->SetResumedFromZoneSuspend(m_resumed_from_zone_suspend);
|
||||||
m_resumed_from_zone_suspend = false;
|
m_resumed_from_zone_suspend = false;
|
||||||
|
|
||||||
|
|||||||
@ -77,6 +77,7 @@ public:
|
|||||||
inline NPC *GetNPC() const { return npcthis; }
|
inline NPC *GetNPC() const { return npcthis; }
|
||||||
inline bool IsResumedFromZoneSuspend() const { return m_resumed_from_zone_suspend; }
|
inline bool IsResumedFromZoneSuspend() const { return m_resumed_from_zone_suspend; }
|
||||||
inline void SetResumedFromZoneSuspend(bool resumed) { m_resumed_from_zone_suspend = resumed; }
|
inline void SetResumedFromZoneSuspend(bool resumed) { m_resumed_from_zone_suspend = resumed; }
|
||||||
|
inline void SetEntityVariables(std::map<std::string, std::string> vars) { m_entity_variables = vars; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class Zone;
|
friend class Zone;
|
||||||
@ -104,6 +105,7 @@ private:
|
|||||||
bool IsDespawned;
|
bool IsDespawned;
|
||||||
uint32 killcount;
|
uint32 killcount;
|
||||||
bool m_resumed_from_zone_suspend = false;
|
bool m_resumed_from_zone_suspend = false;
|
||||||
|
std::map<std::string, std::string> m_entity_variables = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpawnCondition {
|
class SpawnCondition {
|
||||||
|
|||||||
@ -204,6 +204,33 @@ inline std::string GetLootSerialized(Corpse *c)
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::map<std::string, std::string> GetVariablesDeserialized(const std::string &entity_variables)
|
||||||
|
{
|
||||||
|
std::map<std::string, std::string> deserialized_map;
|
||||||
|
|
||||||
|
if (entity_variables.empty()) {
|
||||||
|
return deserialized_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Strings::IsValidJson(entity_variables)) {
|
||||||
|
LogZoneState("Invalid JSON data for entity variables");
|
||||||
|
return deserialized_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
std::stringstream ss;
|
||||||
|
{
|
||||||
|
ss << entity_variables;
|
||||||
|
cereal::JSONInputArchive ar(ss);
|
||||||
|
ar(deserialized_map);
|
||||||
|
}
|
||||||
|
} catch (const std::exception &e) {
|
||||||
|
LogZoneState("Failed to load entity variables [{}]", e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
return deserialized_map;
|
||||||
|
}
|
||||||
|
|
||||||
inline void LoadNPCEntityVariables(NPC *n, const std::string &entity_variables)
|
inline void LoadNPCEntityVariables(NPC *n, const std::string &entity_variables)
|
||||||
{
|
{
|
||||||
if (!RuleB(Zone, StateSaveEntityVariables)) {
|
if (!RuleB(Zone, StateSaveEntityVariables)) {
|
||||||
@ -214,25 +241,7 @@ inline void LoadNPCEntityVariables(NPC *n, const std::string &entity_variables)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Strings::IsValidJson(entity_variables)) {
|
for (const auto &[key, value]: GetVariablesDeserialized(entity_variables)) {
|
||||||
LogZoneState("Invalid JSON data for NPC [{}]", n->GetNPCTypeID());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<std::string, std::string> deserialized_map;
|
|
||||||
try {
|
|
||||||
std::istringstream is(entity_variables);
|
|
||||||
{
|
|
||||||
cereal::JSONInputArchive archive(is);
|
|
||||||
archive(deserialized_map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception &e) {
|
|
||||||
LogZoneState("Failed to load entity variables for NPC [{}] [{}]", n->GetNPCTypeID(), e.what());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto &[key, value]: deserialized_map) {
|
|
||||||
n->SetEntityVariable(key, value);
|
n->SetEntityVariable(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -310,6 +319,11 @@ inline std::vector<uint32_t> GetLootdropIds(const std::vector<ZoneStateSpawnsRep
|
|||||||
return lootdrop_ids;
|
return lootdrop_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void LoadNPCStatePreSpawn(Zone *zone, NPC *n, ZoneStateSpawnsRepository::ZoneStateSpawns &s)
|
||||||
|
{
|
||||||
|
LoadNPCEntityVariables(n, s.entity_variables);
|
||||||
|
}
|
||||||
|
|
||||||
inline void LoadNPCState(Zone *zone, NPC *n, ZoneStateSpawnsRepository::ZoneStateSpawns &s)
|
inline void LoadNPCState(Zone *zone, NPC *n, ZoneStateSpawnsRepository::ZoneStateSpawns &s)
|
||||||
{
|
{
|
||||||
if (s.hp > 0) {
|
if (s.hp > 0) {
|
||||||
@ -329,7 +343,6 @@ inline void LoadNPCState(Zone *zone, NPC *n, ZoneStateSpawnsRepository::ZoneStat
|
|||||||
n->SetResumedFromZoneSuspend(false);
|
n->SetResumedFromZoneSuspend(false);
|
||||||
LoadLootStateData(zone, n, s.loot_data);
|
LoadLootStateData(zone, n, s.loot_data);
|
||||||
n->SetResumedFromZoneSuspend(true);
|
n->SetResumedFromZoneSuspend(true);
|
||||||
LoadNPCEntityVariables(n, s.entity_variables);
|
|
||||||
LoadNPCBuffs(n, s.buffs);
|
LoadNPCBuffs(n, s.buffs);
|
||||||
|
|
||||||
if (s.is_corpse) {
|
if (s.is_corpse) {
|
||||||
@ -477,6 +490,7 @@ bool Zone::LoadZoneState(
|
|||||||
if (spawn_time_left == 0) {
|
if (spawn_time_left == 0) {
|
||||||
new_spawn->SetCurrentNPCID(s.npc_id);
|
new_spawn->SetCurrentNPCID(s.npc_id);
|
||||||
new_spawn->SetResumedFromZoneSuspend(true);
|
new_spawn->SetResumedFromZoneSuspend(true);
|
||||||
|
new_spawn->SetEntityVariables(GetVariablesDeserialized(s.entity_variables));
|
||||||
}
|
}
|
||||||
|
|
||||||
spawn2_list.Insert(new_spawn);
|
spawn2_list.Insert(new_spawn);
|
||||||
@ -513,6 +527,8 @@ bool Zone::LoadZoneState(
|
|||||||
npc->SetQueuedToCorpse();
|
npc->SetQueuedToCorpse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoadNPCStatePreSpawn(zone, npc, s);
|
||||||
|
|
||||||
entity_list.AddNPC(npc, true, true);
|
entity_list.AddNPC(npc, true, true);
|
||||||
|
|
||||||
LoadNPCState(zone, npc, s);
|
LoadNPCState(zone, npc, s);
|
||||||
@ -566,7 +582,7 @@ inline void SaveNPCState(NPC *n, ZoneStateSpawnsRepository::ZoneStateSpawns &s)
|
|||||||
auto buffs = n->GetBuffs();
|
auto buffs = n->GetBuffs();
|
||||||
if (buffs) {
|
if (buffs) {
|
||||||
std::vector<Buffs_Struct> valid_buffs;
|
std::vector<Buffs_Struct> valid_buffs;
|
||||||
for (int index = 0; index < n->GetMaxBuffSlots(); index++) {
|
for (int index = 0; index < n->GetMaxBuffSlots(); index++) {
|
||||||
if (buffs[index].spellid != 0 && buffs[index].spellid != 65535) {
|
if (buffs[index].spellid != 0 && buffs[index].spellid != 65535) {
|
||||||
valid_buffs.push_back(buffs[index]);
|
valid_buffs.push_back(buffs[index]);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user