From d207c2251ffe4693f73e275c8df95bc7127c0010 Mon Sep 17 00:00:00 2001 From: Aussiemon Date: Thu, 3 Jul 2025 11:38:15 -0600 Subject: [PATCH] Fix unneeded runtime errors --- apps/openmw/mwscript/interpretercontext.cpp | 26 ++++++-- components/interpreter/defines.cpp | 70 +++++++++++---------- 2 files changed, 60 insertions(+), 36 deletions(-) diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 15c9100b98..9aeccfc886 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "../mwworld/esmstore.hpp" @@ -300,7 +301,15 @@ namespace MWScript std::string_view InterpreterContext::getNPCFaction() const { - const ESM::NPC* npc = getReferenceImp().get()->mBase; + const MWWorld::Ptr& ptr = getReferenceImp(); + const ESM::RefId& factionId = ptr.getClass().getPrimaryFaction(ptr); + if (factionId.empty()) + { + Log(Debug::Warning) << "getNPCFaction(): NPC is not in a faction"; + return "%"; + } + + const ESM::NPC* npc = ptr.get()->mBase; const ESM::Faction* faction = MWBase::Environment::get().getESMStore()->get().find(npc->mFaction); return faction->mName; } @@ -310,7 +319,10 @@ namespace MWScript const MWWorld::Ptr& ptr = getReferenceImp(); const ESM::RefId& faction = ptr.getClass().getPrimaryFaction(ptr); if (faction.empty()) - throw std::runtime_error("getNPCRank(): NPC is not in a faction"); + { + Log(Debug::Warning) << "getNPCRank(): NPC is not in a faction"; + return "%"; + } int rank = ptr.getClass().getPrimaryFactionRank(ptr); if (rank < 0 || rank > 9) @@ -349,7 +361,10 @@ namespace MWScript const ESM::RefId& factionId = getReferenceImp().getClass().getPrimaryFaction(getReferenceImp()); if (factionId.empty()) - throw std::runtime_error("getPCRank(): NPC is not in a faction"); + { + Log(Debug::Warning) << "getPCRank(): NPC is not in a faction"; + return "%"; + } const auto& ranks = player.getClass().getNpcStats(player).getFactionRanks(); auto it = ranks.find(factionId); @@ -378,7 +393,10 @@ namespace MWScript const ESM::RefId& factionId = getReferenceImp().getClass().getPrimaryFaction(getReferenceImp()); if (factionId.empty()) - throw std::runtime_error("getPCNextRank(): NPC is not in a faction"); + { + Log(Debug::Warning) << "getPCNextRank(): NPC is not in a faction"; + return "%"; + } const auto& ranks = player.getClass().getNpcStats(player).getFactionRanks(); auto it = ranks.find(factionId); diff --git a/components/interpreter/defines.cpp b/components/interpreter/defines.cpp index e7a8e35328..6d51a72cca 100644 --- a/components/interpreter/defines.cpp +++ b/components/interpreter/defines.cpp @@ -26,40 +26,40 @@ namespace std::vector globals; const std::initializer_list> sActionBindings{ - { "actionslideright", "#{sRight}" }, - { "actionreadymagic", "#{sReady_Magic}" }, - { "actionprevweapon", "#{sPrevWeapon}" }, - { "actionnextweapon", "#{sNextWeapon}" }, - { "actiontogglerun", "#{sAuto_Run}" }, - { "actionslideleft", "#{sLeft}" }, - { "actionreadyitem", "#{sReady_Weapon}" }, - { "actionprevspell", "#{sPrevSpell}" }, - { "actionnextspell", "#{sNextSpell}" }, - { "actionrestmenu", "#{sRestKey}" }, - { "actionmenumode", "#{sInventory}" }, - { "actionactivate", "#{sActivate}" }, - { "actionjournal", "#{sJournal}" }, - { "actionforward", "#{sForward}" }, - { "actioncrouch", "#{sCrouch_Sneak}" }, - { "actionjump", "#{sJump}" }, - { "actionback", "#{sBack}" }, - { "actionuse", "#{sUse}" }, - { "actionrun", "#{sRun}" }, + { "ActionSlideRight", "#{sRight}" }, + { "ActionReadyMagic", "#{sReady_Magic}" }, + { "ActionPrevWeapon", "#{sPrevWeapon}" }, + { "ActionNextWeapon", "#{sNextWeapon}" }, + { "ActionToggleRun", "#{sAuto_Run}" }, + { "ActionSlideLeft", "#{sLeft}" }, + { "ActionReadyItem", "#{sReady_Weapon}" }, + { "ActionPrevSpell", "#{sPrevSpell}" }, + { "ActionNextSpell", "#{sNextSpell}" }, + { "ActionRestMenu", "#{sRestKey}" }, + { "ActionMenuMode", "#{sInventory}" }, + { "ActionActivate", "#{sActivate}" }, + { "ActionJournal", "#{sJournal}" }, + { "ActionForward", "#{sForward}" }, + { "ActionCrouch", "#{sCrouch_Sneak}" }, + { "ActionJump", "#{sJump}" }, + { "ActionBack", "#{sBack}" }, + { "ActionUse", "#{sUse}" }, + { "ActionRun", "#{sRun}" }, }; using ContextMethod = std::string_view (Interpreter::Context::*)() const; const std::initializer_list>> sContextMethods{ - { "nextpcrank", { &Interpreter::Context::getPCNextRank, nullptr } }, - { "pcnextrank", { &Interpreter::Context::getPCNextRank, nullptr } }, - { "faction", { &Interpreter::Context::getNPCFaction, nullptr } }, - { "pcclass", { &Interpreter::Context::getPCClass, &Interpreter::Context::getPCClass } }, - { "pcname", { &Interpreter::Context::getPCName, &Interpreter::Context::getPCName } }, - { "pcrace", { &Interpreter::Context::getPCRace, &Interpreter::Context::getPCRace } }, - { "pcrank", { &Interpreter::Context::getPCRank, nullptr } }, - { "class", { &Interpreter::Context::getNPCClass, &Interpreter::Context::getPCClass } }, - { "cell", { &Interpreter::Context::getCurrentCellName, &Interpreter::Context::getCurrentCellName } }, - { "race", { &Interpreter::Context::getNPCRace, &Interpreter::Context::getPCRace } }, - { "rank", { &Interpreter::Context::getNPCRank, nullptr } }, - { "name", { &Interpreter::Context::getActorName, &Interpreter::Context::getPCName } }, + { "NextPCRank", { &Interpreter::Context::getPCNextRank, nullptr } }, + { "PCNextRank", { &Interpreter::Context::getPCNextRank, nullptr } }, + { "Faction", { &Interpreter::Context::getNPCFaction, nullptr } }, + { "PCClass", { &Interpreter::Context::getPCClass, &Interpreter::Context::getPCClass } }, + { "PCName", { &Interpreter::Context::getPCName, &Interpreter::Context::getPCName } }, + { "PCRace", { &Interpreter::Context::getPCRace, &Interpreter::Context::getPCRace } }, + { "PCRank", { &Interpreter::Context::getPCRank, nullptr } }, + { "Class", { &Interpreter::Context::getNPCClass, &Interpreter::Context::getPCClass } }, + { "Cell", { &Interpreter::Context::getCurrentCellName, &Interpreter::Context::getCurrentCellName } }, + { "Race", { &Interpreter::Context::getNPCRace, &Interpreter::Context::getPCRace } }, + { "Rank", { &Interpreter::Context::getNPCRank, nullptr } }, + { "Name", { &Interpreter::Context::getActorName, &Interpreter::Context::getPCName } }, }; bool longerStr(std::string_view a, std::string_view b) @@ -78,7 +78,7 @@ namespace return true; } } - if (check(temp, "pccrimelevel", i, start)) + if (check(temp, "PCCrimeLevel", i, start)) { retval << context.getPCBounty(); return true; @@ -89,7 +89,13 @@ namespace if (check(temp, name, i, start)) { if (method) // Not all variables are available outside of dialogue + { retval << (context.*method)(); + + // Re-add the token if replacement failed without an error + if ((context.*method)() == "%") + retval << name; + } return true; } }