diff --git a/Source/lua/modules/monsters.cpp b/Source/lua/modules/monsters.cpp index 58d414ae3..35e796afb 100644 --- a/Source/lua/modules/monsters.cpp +++ b/Source/lua/modules/monsters.cpp @@ -21,55 +21,10 @@ void AddMonsterDataFromTsv(const std::string_view path) LoadMonstDatFromFile(dataFile, path); } -void AddUniqueMonsterData(const std::string_view type, const std::string_view name, const std::string_view trn, const uint8_t level, const uint16_t maxHp, const std::string_view ai, const uint8_t intelligence, const uint8_t minDamage, const uint8_t maxDamage, const std::string_view resistance, const std::string_view monsterPack, const std::optional customToHit, const std::optional customArmorClass) +void AddUniqueMonsterDataFromTsv(const std::string_view path) { - UniqueMonsterData monster; - - const auto monsterTypeResult = ParseMonsterId(type); - if (!monsterTypeResult.has_value()) { - DisplayFatalErrorAndExit(_("Adding Unique Monster Failed"), fmt::format(fmt::runtime(_("Failed to parse monster type ID \"{}\": {}")), type, monsterTypeResult.error())); - } - - monster.mtype = monsterTypeResult.value(); - monster.mName = name; - monster.mTrnName = trn; - monster.mlevel = level; - monster.mmaxhp = maxHp; - - const auto monsterAiResult = ParseAiId(ai); - if (!monsterAiResult.has_value()) { - DisplayFatalErrorAndExit(_("Adding Unique Monster Failed"), fmt::format(fmt::runtime(_("Failed to parse monster AI ID \"{}\": {}")), ai, monsterAiResult.error())); - } - - monster.mAi = monsterAiResult.value(); - monster.mint = intelligence; - monster.mMinDamage = minDamage; - monster.mMaxDamage = maxDamage; - - monster.mMagicRes = {}; - - if (!resistance.empty()) { - for (const std::string_view resistancePart : SplitByChar(resistance, ',')) { - const auto monsterResistanceResult = ParseMonsterResistance(resistancePart); - if (!monsterResistanceResult.has_value()) { - DisplayFatalErrorAndExit(_("Adding Unique Monster Failed"), fmt::format(fmt::runtime(_("Failed to parse monster resistance \"{}\": {}")), resistance, monsterResistanceResult.error())); - } - - monster.mMagicRes |= monsterResistanceResult.value(); - } - } - - const auto monsterPackResult = ParseUniqueMonsterPack(monsterPack); - if (!monsterPackResult.has_value()) { - DisplayFatalErrorAndExit(_("Adding Unique Monster Failed"), fmt::format(fmt::runtime(_("Failed to parse unique monster pack \"{}\": {}")), monsterPack, monsterPackResult.error())); - } - - monster.monsterPack = monsterPackResult.value(); - monster.customToHit = customToHit.value_or(0); - monster.customArmorClass = customArmorClass.value_or(0); - monster.mtalkmsg = TEXT_NONE; - - UniqueMonstersData.push_back(std::move(monster)); + DataFile dataFile = DataFile::loadOrDie(path); + LoadUniqueMonstDatFromFile(dataFile, path); } } // namespace @@ -78,7 +33,7 @@ sol::table LuaMonstersModule(sol::state_view &lua) { sol::table table = lua.create_table(); LuaSetDocFn(table, "addMonsterDataFromTsv", "(path: string)", AddMonsterDataFromTsv); - LuaSetDocFn(table, "addUniqueMonsterData", "(type: string, name: string, trn: string, level: number, maxHp: number, ai: string, intelligence: number, minDamage: number, maxDamage: number, resistance: string, monsterPack: string, customToHit: number = nil, customArmorClass: number = nil)", AddUniqueMonsterData); + LuaSetDocFn(table, "addUniqueMonsterDataFromTsv", "(path: string)", AddUniqueMonsterDataFromTsv); return table; } diff --git a/Source/monstdat.cpp b/Source/monstdat.cpp index 7c7bc86e7..3917a73a0 100644 --- a/Source/monstdat.cpp +++ b/Source/monstdat.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -219,8 +220,6 @@ namespace { /** Contains the mapping between monster ID strings and indices, used for parsing additional monster data. */ ankerl::unordered_dense::map AdditionalMonsterIdStringsToIndices; -} // namespace - tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value) { const std::optional<_monster_id> enumValueOpt = magic_enum::enum_cast<_monster_id>(value); @@ -234,8 +233,6 @@ tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value) return tl::make_unexpected("Unknown enum value"); } -namespace { - tl::expected<_monster_id, std::string> ParseMonsterIdIfNotEmpty(std::string_view value) { if (value.empty()) { @@ -253,8 +250,6 @@ tl::expected ParseMonsterAvailability(std::str return tl::make_unexpected("Expected one of: Always, Never, or Retail"); } -} // namespace - tl::expected ParseAiId(std::string_view value) { if (value == "Zombie") return MonsterAIID::Zombie; @@ -300,8 +295,6 @@ tl::expected ParseAiId(std::string_view value) return tl::make_unexpected("Unknown enum value"); } -namespace { - tl::expected ParseMonsterFlag(std::string_view value) { if (value == "HIDDEN") return MFLAG_HIDDEN; @@ -327,8 +320,6 @@ tl::expected ParseMonsterClass(std::string_view value return tl::make_unexpected("Unknown enum value"); } -} // namespace - tl::expected ParseMonsterResistance(std::string_view value) { if (value == "RESIST_MAGIC") return RESIST_MAGIC; @@ -341,8 +332,6 @@ tl::expected ParseMonsterResistance(std::string return tl::make_unexpected("Unknown enum value"); } -namespace { - tl::expected ParseSelectionRegion(std::string_view value) { if (value.empty()) return SelectionRegion::None; @@ -363,8 +352,6 @@ tl::expected ParseMonsterTreasure(std::string_view value) return tl::make_unexpected("Invalid value. NOTE: Parser is incomplete"); } -} // namespace - tl::expected ParseUniqueMonsterPack(std::string_view value) { if (value == "None") return UniqueMonsterPack::None; @@ -373,6 +360,8 @@ tl::expected ParseUniqueMonsterPack(std::string_ return tl::make_unexpected("Unknown enum value"); } +} // namespace + void LoadMonstDatFromFile(DataFile &dataFile, const std::string_view filename) { dataFile.skipHeaderOrDie(filename); @@ -464,14 +453,14 @@ void LoadMonstDat() LuaEvent("MonsterDataLoaded"); } -void LoadUniqueMonstDat() +} // namespace + +void LoadUniqueMonstDatFromFile(DataFile &dataFile, std::string_view filename) { - const std::string_view filename = "txtdata\\monsters\\unique_monstdat.tsv"; - DataFile dataFile = DataFile::loadOrDie(filename); dataFile.skipHeaderOrDie(filename); - UniqueMonstersData.clear(); - UniqueMonstersData.reserve(dataFile.numRecords()); + UniqueMonstersData.reserve(UniqueMonstersData.size() + dataFile.numRecords()); + for (DataFileRecord record : dataFile) { RecordReader reader { record, filename }; UniqueMonsterData &monster = UniqueMonstersData.emplace_back(); @@ -504,6 +493,17 @@ void LoadUniqueMonstDat() } UniqueMonstersData.shrink_to_fit(); +} + +namespace { + +void LoadUniqueMonstDat() +{ + const std::string_view filename = "txtdata\\monsters\\unique_monstdat.tsv"; + DataFile dataFile = DataFile::loadOrDie(filename); + + UniqueMonstersData.clear(); + LoadUniqueMonstDatFromFile(dataFile, filename); LuaEvent("UniqueMonsterDataLoaded"); } diff --git a/Source/monstdat.h b/Source/monstdat.h index 2545a69a7..3d3afd5ba 100644 --- a/Source/monstdat.h +++ b/Source/monstdat.h @@ -10,8 +10,6 @@ #include #include -#include - #include "cursor.h" #include "textdat.h" @@ -339,11 +337,8 @@ extern std::vector MonstersData; extern const _monster_id MonstConvTbl[]; extern std::vector UniqueMonstersData; -tl::expected<_monster_id, std::string> ParseMonsterId(std::string_view value); -tl::expected ParseAiId(std::string_view value); -tl::expected ParseMonsterResistance(std::string_view value); -tl::expected ParseUniqueMonsterPack(std::string_view value); void LoadMonstDatFromFile(DataFile &dataFile, std::string_view filename); +void LoadUniqueMonstDatFromFile(DataFile &dataFile, std::string_view filename); void LoadMonsterData(); /**