From fcef92e3ea74b46754f3f4ec4e55730fb34d1e46 Mon Sep 17 00:00:00 2001 From: Alexei Dobrohotov Date: Sat, 20 Nov 2021 02:59:57 +0300 Subject: [PATCH] Make AiExtensions less toxic (bug #6429) --- CHANGELOG.md | 1 + apps/openmw/mwscript/aiextensions.cpp | 76 ++++++++++++++++++++------- 2 files changed, 58 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be789859ea..d5f157d81a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ Bug #6386: Artifacts in water reflection due to imprecise screen-space coordinate computation Bug #6396: Inputting certain Unicode characters triggers an assertion Bug #6416: Morphs are applied to the wrong target + Bug #6429: Wyrmhaven: Can't add AI packages to player Feature #890: OpenMW-CS: Column filtering Feature #2554: Modifying an object triggers the instances table to scroll to the corresponding record Feature #2780: A way to see current OpenMW version in the console diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 33f16aea3f..d1adffc9fa 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -14,6 +14,7 @@ #include "../mwworld/class.hpp" #include "../mwworld/esmstore.hpp" +#include "../mwmechanics/actorutil.hpp" #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/aiactivate.hpp" #include "../mwmechanics/aiescort.hpp" @@ -50,6 +51,9 @@ namespace MWScript // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; i(duration), x, y, z); ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr); @@ -148,10 +158,14 @@ namespace MWScript // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; igetStore().get().find(cellID); + if (!MWBase::Environment::get().getWorld()->getStore().get().search(cellID)) + return; MWMechanics::AiEscort escortPackage(actorID, cellID, static_cast(duration), x, y, z); ptr.getClass().getCreatureStats (ptr).getAiSequence().stack(escortPackage, ptr); @@ -169,9 +183,11 @@ namespace MWScript { MWWorld::Ptr ptr = R()(runtime); - Interpreter::Type_Integer value = ptr.getClass().getCreatureStats (ptr).getAiSequence().isPackageDone(); + bool done = false; + if (ptr.getClass().isActor()) + done = ptr.getClass().getCreatureStats(ptr).getAiSequence().isPackageDone(); - runtime.push (value); + runtime.push(done); } }; @@ -224,6 +240,9 @@ namespace MWScript // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; i @@ -256,6 +278,9 @@ namespace MWScript Interpreter::Type_Integer value = runtime[0].mInteger; runtime.pop(); + if (!ptr.getClass().isActor()) + return; + int modified = ptr.getClass().getCreatureStats (ptr).getAiSetting (mIndex).getBase() + value; ptr.getClass().getCreatureStats (ptr).setAiSetting (mIndex, modified); @@ -309,6 +334,9 @@ namespace MWScript // discard additional arguments (reset), because we have no idea what they mean. for (unsigned int i=0; igetGreetingState(actor) == MWMechanics::Greet_InProgress; - bool sayActive = MWBase::Environment::get().getSoundManager()->sayActive(actor); - targetsAreEqual = (greeting && sayActive) || mechMgr->isTurningToPlayer(actor); + const MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); + MWWorld::Ptr targetPtr; + if (creatureStats.getAiSequence().getCombatTarget(targetPtr)) + { + if (!targetPtr.isEmpty() && targetPtr.getCellRef().getRefId() == testedTargetId) + targetsAreEqual = true; + } + else if (testedTargetId == "player") // Currently the player ID is hardcoded + { + MWBase::MechanicsManager* mechMgr = MWBase::Environment::get().getMechanicsManager(); + bool greeting = mechMgr->getGreetingState(actor) == MWMechanics::Greet_InProgress; + bool sayActive = MWBase::Environment::get().getSoundManager()->sayActive(actor); + targetsAreEqual = (greeting && sayActive) || mechMgr->isTurningToPlayer(actor); + } } - runtime.push(int(targetsAreEqual)); + runtime.push(targetsAreEqual); } }; @@ -474,6 +507,8 @@ namespace MWScript void execute (Interpreter::Runtime& runtime) override { MWWorld::Ptr actor = R()(runtime); + if (!actor.getClass().isActor()) + return; MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor); creatureStats.getAiSequence().stopCombat(); } @@ -505,6 +540,9 @@ namespace MWScript Interpreter::Type_Float y = runtime[0].mFloat; runtime.pop(); + if (!actor.getClass().isActor() || actor == MWMechanics::getPlayer()) + return; + MWMechanics::AiFace facePackage(x, y); actor.getClass().getCreatureStats(actor).getAiSequence().stack(facePackage, actor); }