From 8cba2cf7b262b347fd8516c3a8b4eb45d5faaf50 Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Sun, 21 Jan 2024 17:28:16 +0100 Subject: [PATCH] fix(VNpc): implement loading of news --- include/zenkit/vobs/Misc.hh | 31 +++++++++++++++++++++++++++++++ src/vobs/Misc.cc | 32 ++++++++++++++++++++++++-------- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/include/zenkit/vobs/Misc.hh b/include/zenkit/vobs/Misc.hh index 9602b81d..1af70d09 100644 --- a/include/zenkit/vobs/Misc.hh +++ b/include/zenkit/vobs/Misc.hh @@ -476,6 +476,36 @@ namespace zenkit { using slot ZKREM("renamed to Slot") = Slot; + enum class NewsId { + MURDER = 200, + ATTACK = 195, + THEFT = 190, + DEFEAT = 185, + NERVE = 180, + INTERFERE = 175, + HAS_DEFEATED = 170, + }; + + enum class NewsSpread { + DONT_SPREAD = 0, + FRIENDLY_TOWARDS_VICTIM = 1, + FRIENDLY_TOWARDS_WITNESS = 2, + FRIENDLY_TOWARDS_OFFENDER = 3, + SAME_GUILD_VICTIM = 4, + }; + + struct News { + bool told; + float spread_time; + NewsSpread spread_type; + NewsId news_id; + bool gossip; + bool guild_victim; + std::string witness_name; + std::string offender_name; + std::string victim_name; + }; + std::string npc_instance; glm::vec3 model_scale; float model_fatness; @@ -512,6 +542,7 @@ namespace zenkit { bool move_lock; std::string packed[packed_count]; + std::vector> news; std::vector> items; std::vector> slots; diff --git a/src/vobs/Misc.cc b/src/vobs/Misc.cc index b8aa49c4..cdc1fe3c 100644 --- a/src/vobs/Misc.cc +++ b/src/vobs/Misc.cc @@ -332,13 +332,19 @@ namespace zenkit { // unknown. [[maybe_unused]] auto spells = r.read_raw(4); // spells - // TODO: News (I don't have a sample.). auto news_count = r.read_int(); // NumOfEntries - if (news_count != 0) { - ZKLOGE("VOb.Npc", - "!!! IMPORTANT !!! This save-game contains news entries and cannot be loaded currently. Please " - "open an issue at https://github.com/GothicKit/ZenKit providing your save-game as a ZIP file."); - throw ParserError {"VNpc"}; + for (auto i = 0; i < news_count; ++i) { + auto n = std::make_unique(); + n->told = r.read_bool(); // told + n->spread_time = r.read_float(); // spread_time + n->spread_type = static_cast(r.read_int()); // spreadType + n->news_id = static_cast(r.read_int()); // news_id + n->gossip = r.read_bool(); // gossip + n->guild_victim = r.read_bool(); // guildvictim + n->witness_name = r.read_string(); // witnessName + n->offender_name = r.read_string(); // offenderName + n->victim_name = r.read_string(); // victimName + news.push_back(std::move(n)); } carry_vob = std::dynamic_pointer_cast(r.read_object(version)); // [carryVob % 0 0] @@ -492,8 +498,18 @@ namespace zenkit { spells.push_back({}); w.write_raw("spells", spells); - // TODO: News (I don't have a sample.). - w.write_int("NumOfEntries", 0); + w.write_int("NumOfEntries", this->news.size()); + for (auto& n : this->news) { + w.write_bool("told", n->told); + w.write_float("spread_time", n->spread_time); + w.write_int("spreadType", static_cast(n->spread_type)); + w.write_int("news_id", static_cast(n->news_id)); + w.write_bool("gossip", n->gossip); + w.write_bool("guildvictim", n->guild_victim); + w.write_string("witnessName", n->witness_name); + w.write_string("offenderName", n->offender_name); + w.write_string("victimName", n->victim_name); + } w.write_object("carryVob", this->carry_vob, version); w.write_object("enemy", this->enemy, version);