From ae7861abe4b56cba4bf2f113c188236f8eaf34bb Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Thu, 23 May 2024 11:23:58 +0300 Subject: [PATCH 1/2] Move paralysis god mode checks to CreatureStats --- apps/openmw/mwclass/npc.cpp | 6 ++---- apps/openmw/mwgui/inventorywindow.cpp | 6 ++---- apps/openmw/mwgui/quickkeysmenu.cpp | 3 +-- apps/openmw/mwgui/spellwindow.cpp | 3 +-- apps/openmw/mwmechanics/actors.cpp | 4 +--- apps/openmw/mwmechanics/creaturestats.cpp | 5 +++++ apps/openmw/mwworld/player.cpp | 3 +-- 7 files changed, 13 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 023e9ad768..9d3d2f344e 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -984,8 +984,7 @@ namespace MWClass // TODO: This function is called several times per frame for each NPC. // It would be better to calculate it only once per frame for each NPC and save the result in CreatureStats. const MWMechanics::NpcStats& stats = getNpcStats(ptr); - bool godmode = ptr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); - if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead()) + if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) return 0.f; const MWBase::World* world = MWBase::Environment::get().getWorld(); @@ -1034,8 +1033,7 @@ namespace MWClass return 0.f; const MWMechanics::NpcStats& stats = getNpcStats(ptr); - bool godmode = ptr == MWMechanics::getPlayer() && MWBase::Environment::get().getWorld()->getGodModeState(); - if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead()) + if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead()) return 0.f; const GMST& gmst = getGmst(); diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 4805f7f3cb..e2072e229f 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -749,8 +749,7 @@ namespace MWGui // Player must not be paralyzed, knocked down, or dead to pick up an item. const MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats(player); - bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); - if ((!godmode && playerStats.isParalyzed()) || playerStats.getKnockedDown() || playerStats.isDead()) + if (playerStats.isParalyzed() || playerStats.getKnockedDown() || playerStats.isDead()) return; MWBase::Environment::get().getMechanicsManager()->itemTaken(player, object, MWWorld::Ptr(), count); @@ -789,8 +788,7 @@ namespace MWGui return; const MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); - bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); - if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) + if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) return; ItemModel::ModelIndex selected = -1; diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index df7236242f..93b0ef071f 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -353,8 +353,7 @@ namespace MWGui bool isDelayNeeded = MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player) || playerStats.getKnockedDown() || playerStats.getHitRecovery(); - bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); - bool isReturnNeeded = (!godmode && playerStats.isParalyzed()) || playerStats.isDead(); + bool isReturnNeeded = playerStats.isParalyzed() || playerStats.isDead(); if (isReturnNeeded) { diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index b136a3cad1..10a83f2b2d 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -236,9 +236,8 @@ namespace MWGui if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(player)) return; - bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); const MWMechanics::CreatureStats& stats = player.getClass().getCreatureStats(player); - if ((!godmode && stats.isParalyzed()) || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) + if (stats.isParalyzed() || stats.getKnockedDown() || stats.isDead() || stats.getHitRecovery()) return; mSpellView->setModel(new SpellModel(MWMechanics::getPlayer())); diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index db69f716dd..525044d55c 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1482,7 +1482,6 @@ namespace MWMechanics if (!playerHitAttemptActor.isInCell()) player.getClass().getCreatureStats(player).setHitAttemptActorId(-1); } - const bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); const int actorsProcessingRange = Settings::game().mActorsProcessingRange; // AI and magic effects update @@ -1634,8 +1633,7 @@ namespace MWMechanics world->setActorActive(actor.getPtr(), true); const bool isDead = actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isDead(); - if (!isDead && (!godmode || !isPlayer) - && actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isParalyzed()) + if (!isDead && actor.getPtr().getClass().getCreatureStats(actor.getPtr()).isParalyzed()) ctrl.skipAnim(); // Handle player last, in case a cell transition occurs by casting a teleportation spell diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index e20045791c..98bfa59c89 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -241,6 +241,11 @@ namespace MWMechanics bool CreatureStats::isParalyzed() const { + MWBase::World* world = MWBase::Environment::get().getWorld(); + const MWWorld::Ptr player = world->getPlayerPtr(); + if (world->getGodModeState() && this == &player.getClass().getCreatureStats(player)) + return false; + return mMagicEffects.getOrDefault(ESM::MagicEffect::Paralyze).getMagnitude() > 0; } diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 7849ba1458..29d298a33e 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -183,8 +183,7 @@ namespace MWWorld MWWorld::Ptr player = getPlayer(); const MWMechanics::NpcStats& playerStats = player.getClass().getNpcStats(player); - bool godmode = MWBase::Environment::get().getWorld()->getGodModeState(); - if ((!godmode && playerStats.isParalyzed()) || playerStats.getKnockedDown() || playerStats.isDead()) + if (playerStats.isParalyzed() || playerStats.getKnockedDown() || playerStats.isDead()) return; MWWorld::Ptr toActivate = MWBase::Environment::get().getWorld()->getFacedObject(); From 462818c30468189de5e64259f16dbc905e56da94 Mon Sep 17 00:00:00 2001 From: Alexei Kotov Date: Thu, 23 May 2024 12:21:29 +0300 Subject: [PATCH 2/2] Make paralysis cancel camera mode changes (#7997) --- CHANGELOG.md | 1 + files/data/scripts/omw/camera/camera.lua | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e40974322..4ea7f5a224 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -176,6 +176,7 @@ Bug #7943: Using "addSoulGem" and "dropSoulGem" commands to creatures works only with "Weapon & Shield" flagged ones Bug #7970: Difference of GetPCSleep (?) behavior between vanilla and OpenMW Bug #7980: Paralyzed NPCs' lips move + Bug #7997: Can toggle perspective when paralyzed Feature #1415: Infinite fall failsafe Feature #2566: Handle NAM9 records for manual cell references Feature #3537: Shader-based water ripples diff --git a/files/data/scripts/omw/camera/camera.lua b/files/data/scripts/omw/camera/camera.lua index f5848970dd..5cd04239f7 100644 --- a/files/data/scripts/omw/camera/camera.lua +++ b/files/data/scripts/omw/camera/camera.lua @@ -1,5 +1,6 @@ local camera = require('openmw.camera') local core = require('openmw.core') +local debug = require('openmw.debug') local input = require('openmw.input') local util = require('openmw.util') local self = require('openmw.self') @@ -207,7 +208,9 @@ local function onFrame(dt) primaryMode = mode end if mode ~= MODE.Static then - if not next(noModeControl) then + local paralysis = Actor.activeEffects(self):getEffect(core.magic.EFFECT_TYPE.Paralyze) + local paralyzed = not debug.isGodMode() and paralysis.magnitude > 0 + if not next(noModeControl) and not paralyzed then updatePOV(dt) updateVanity(dt) end