From 860d5899c4075d5917dfc974cf610ad9475dc3a9 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 14 May 2022 13:37:32 +0200 Subject: [PATCH 1/7] Control camera settings in-game --- docs/source/generate_luadoc.sh | 2 +- .../lua-scripting/interface_camera.rst | 2 +- files/data/CMakeLists.txt | 8 +- files/data/builtin.omwscripts | 8 +- files/data/l10n/OMWCamera/en.yaml | 59 ++++++++++++ .../data/scripts/omw/{ => camera}/camera.lua | 34 +++++-- .../scripts/omw/{ => camera}/head_bobbing.lua | 24 +++-- files/data/scripts/omw/camera/settings.lua | 95 +++++++++++++++++++ .../scripts/omw/{ => camera}/third_person.lua | 50 +++++++--- 9 files changed, 241 insertions(+), 41 deletions(-) create mode 100644 files/data/l10n/OMWCamera/en.yaml rename files/data/scripts/omw/{ => camera}/camera.lua (89%) rename files/data/scripts/omw/{ => camera}/head_bobbing.lua (79%) create mode 100644 files/data/scripts/omw/camera/settings.lua rename files/data/scripts/omw/{ => camera}/third_person.lua (77%) diff --git a/docs/source/generate_luadoc.sh b/docs/source/generate_luadoc.sh index f518c96202..f71e3110cb 100755 --- a/docs/source/generate_luadoc.sh +++ b/docs/source/generate_luadoc.sh @@ -66,6 +66,6 @@ $DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR openmw/*lua cd $FILES_DIR/data $DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR openmw_aux/*lua $DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR scripts/omw/ai.lua -$DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR scripts/omw/camera.lua +$DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR scripts/omw/camera/camera.lua $DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR scripts/omw/mwui/init.lua $DOCUMENTOR_PATH -f doc -d $OUTPUT_DIR scripts/omw/settings/player.lua diff --git a/docs/source/reference/lua-scripting/interface_camera.rst b/docs/source/reference/lua-scripting/interface_camera.rst index c2db83b721..6a0f19d47b 100644 --- a/docs/source/reference/lua-scripting/interface_camera.rst +++ b/docs/source/reference/lua-scripting/interface_camera.rst @@ -2,5 +2,5 @@ Interface Camera ================ .. raw:: html - :file: generated_html/scripts_omw_camera.html + :file: generated_html/scripts_omw_camera_camera.html diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index 4705355d30..a7d6cf320f 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -12,6 +12,7 @@ set(BUILTIN_DATA_FILES l10n/Calendar/en.yaml l10n/Interface/en.yaml + l10n/OMWCamera/en.yaml openmw_aux/util.lua openmw_aux/time.lua @@ -21,9 +22,10 @@ set(BUILTIN_DATA_FILES builtin.omwscripts scripts/omw/ai.lua - scripts/omw/camera.lua - scripts/omw/head_bobbing.lua - scripts/omw/third_person.lua + scripts/omw/camera/camera.lua + scripts/omw/camera/head_bobbing.lua + scripts/omw/camera/third_person.lua + scripts/omw/camera/settings.lua scripts/omw/console/player.lua scripts/omw/console/global.lua scripts/omw/console/local.lua diff --git a/files/data/builtin.omwscripts b/files/data/builtin.omwscripts index 989575ee1a..8c88045ad7 100644 --- a/files/data/builtin.omwscripts +++ b/files/data/builtin.omwscripts @@ -1,8 +1,8 @@ -PLAYER: scripts/omw/camera.lua +PLAYER: scripts/omw/mwui/init.lua +GLOBAL: scripts/omw/settings/global.lua +PLAYER: scripts/omw/settings/player.lua +PLAYER: scripts/omw/camera/camera.lua NPC,CREATURE: scripts/omw/ai.lua PLAYER: scripts/omw/console/player.lua GLOBAL: scripts/omw/console/global.lua CUSTOM: scripts/omw/console/local.lua -PLAYER: scripts/omw/mwui/init.lua -GLOBAL: scripts/omw/settings/global.lua -PLAYER: scripts/omw/settings/player.lua diff --git a/files/data/l10n/OMWCamera/en.yaml b/files/data/l10n/OMWCamera/en.yaml new file mode 100644 index 0000000000..9d5e7ac7ee --- /dev/null +++ b/files/data/l10n/OMWCamera/en.yaml @@ -0,0 +1,59 @@ +Camera: "Camera" +settingsPageDescription: "OpenMW camera settings" + +thirdPersonSettings: "Third person mode" + +viewOverShoulder: "View over the shoulder" +viewOverShoulderDescription: | + Controls third person view mode. + No: view is centered on the character's head. Crosshair is hidden. + Yes: in non-combat mode camera is positioned behind the character's shoulder, crosshair is always visible. + +shoulderOffsetX: "Shoulder view horizontal offset" +shoulderOffsetXDescription: > + Horizontal offset of the camera in the view-over-the-shoulder mode. + For the left shoulder use a negative value. + +shoulderOffsetY: "Shoulder view vertical offset" +shoulderOffsetYDescription: > + Vertical offset of the camera in the view-over-the-shoulder mode. + +autoSwitchShoulder: "Auto switch shoulder" +autoSwitchShoulderDescription: > + When player is close to an obstacle, automatically switches camera + to the shoulder that is farther away from the obstacle. + +zoomOutWhenMoveCoef: "Zoom out when move coef" +zoomOutWhenMoveCoefDescription: > + Slightly pulls camera away (or closer in case of a negative value) when the character moves. + Works only if "view over the shoulder" is enabled. To disable set it to zero (default: 20.0). + +previewIfStandStill: "Preview if stand still" +previewIfStandStillDescription: > + If enabled then the character rotation is not synchonized with the camera rotation + while the character doesn't move and not in combat mode. + +deferredPreviewRotation: "Deferred preview rotation" +deferredPreviewRotationDescription: | + If enabled then the character smoothly rotates to the view direction after exiting preview or vanity mode. + If disabled then the camera rotates rather than the character. + +ignoreNC: "Ignore 'No Collision' flag" +ignoreNCDescription: > + Prevents camera from clipping through the objects with the NC (No Collision) NIF flag. + + +headBobbingSettings: "Head bobbing in first person view" + +headBobbing_enabled: "Enabled" +headBobbing_enabledDescription: "" + +headBobbing_step: "Base step length" +headBobbing_stepDescription: "The length of each step (default: 90.0)." + +headBobbing_height: "Step height" +headBobbing_heightDescription: "The amplitude of the head bobbing (default: 3.0)." + +headBobbing_roll: "Max roll angle" +headBobbing_rollDescription: "The maximum roll angle in degrees (default: 0.2)." + diff --git a/files/data/scripts/omw/camera.lua b/files/data/scripts/omw/camera/camera.lua similarity index 89% rename from files/data/scripts/omw/camera.lua rename to files/data/scripts/omw/camera/camera.lua index 8a614c9ac3..26dcfc036c 100644 --- a/files/data/scripts/omw/camera.lua +++ b/files/data/scripts/omw/camera/camera.lua @@ -1,20 +1,33 @@ local camera = require('openmw.camera') local core = require('openmw.core') local input = require('openmw.input') -local settings = require('openmw.settings') local util = require('openmw.util') local self = require('openmw.self') local nearby = require('openmw.nearby') +local async = require('openmw.async') local Actor = require('openmw.types').Actor -local head_bobbing = require('scripts.omw.head_bobbing') -local third_person = require('scripts.omw.third_person') +local settings = require('scripts.omw.camera.settings').thirdPerson +local head_bobbing = require('scripts.omw.camera.head_bobbing') +local third_person = require('scripts.omw.camera.third_person') local MODE = camera.MODE -local previewIfStandSill = settings._getBoolFromSettingsCfg('Camera', 'preview if stand still') -local showCrosshairInThirdPerson = settings._getBoolFromSettingsCfg('Camera', 'view over shoulder') +local previewIfStandStill = false +local showCrosshairInThirdPerson = false + +local function updateSettings() + previewIfStandStill = settings:get('previewIfStandStill') + showCrosshairInThirdPerson = settings:get('viewOverShoulder') + camera.allowCharacterDeferredRotation(settings:get('deferredPreviewRotation')) + local collisionType = util.bitAnd(nearby.COLLISION_TYPE.Default, util.bitNot(nearby.COLLISION_TYPE.Actor)) + collisionType = util.bitOr(collisionType, nearby.COLLISION_TYPE.Camera) + if settings:get('ignoreNC') then + collisionType = util.bitOr(collisionType, nearby.COLLISION_TYPE.VisualOnly) + end + camera.setCollisionType(collisionType) +end local primaryMode @@ -24,17 +37,18 @@ local noHeadBobbing = 0 local noZoom = 0 local function init() - camera.setCollisionType(util.bitOr(util.bitAnd(nearby.COLLISION_TYPE.Default, util.bitNot(nearby.COLLISION_TYPE.Actor)), nearby.COLLISION_TYPE.Camera)) camera.setFieldOfView(camera.getBaseFieldOfView()) - camera.allowCharacterDeferredRotation(settings._getBoolFromSettingsCfg('Camera', 'deferred preview rotation')) if camera.getMode() == MODE.FirstPerson then primaryMode = MODE.FirstPerson else primaryMode = MODE.ThirdPerson camera.setMode(MODE.ThirdPerson) end + updateSettings() end +settings:subscribe(async:callback(updateSettings)) + local smoothedSpeed = 0 local previewTimer = 0 @@ -60,7 +74,7 @@ local function updatePOV(dt) end local idleTimer = 0 -local vanityDelay = settings.getGMST('fVanityDelay') +local vanityDelay = core.getGMST('fVanityDelay') local function updateVanity(dt) if input.isIdle() then @@ -126,7 +140,7 @@ end local function updateStandingPreview() local mode = camera.getMode() - if not previewIfStandSill or noStandingPreview > 0 + if not previewIfStandStill or noStandingPreview > 0 or mode == MODE.FirstPerson or mode == MODE.Static or mode == MODE.Vanity then third_person.standingPreview = false return @@ -204,7 +218,7 @@ return { enableModeControl = function() noModeControl = math.max(0, noModeControl - 1) end, --- @function [parent=#Camera] isStandingPreviewEnabled - isStandingPreviewEnabled = function() return previewIfStandSill and noStandingPreview == 0 end, + isStandingPreviewEnabled = function() return previewIfStandStill and noStandingPreview == 0 end, --- @function [parent=#Camera] disableStandingPreview disableStandingPreview = function() noStandingPreview = noStandingPreview + 1 end, --- @function [parent=#Camera] enableStandingPreview diff --git a/files/data/scripts/omw/head_bobbing.lua b/files/data/scripts/omw/camera/head_bobbing.lua similarity index 79% rename from files/data/scripts/omw/head_bobbing.lua rename to files/data/scripts/omw/camera/head_bobbing.lua index b3d96a7eba..5b48c94fed 100644 --- a/files/data/scripts/omw/head_bobbing.lua +++ b/files/data/scripts/omw/camera/head_bobbing.lua @@ -1,21 +1,29 @@ local camera = require('openmw.camera') local self = require('openmw.self') -local settings = require('openmw.settings') local util = require('openmw.util') +local async = require('openmw.async') local Actor = require('openmw.types').Actor -local doubleStepLength = settings._getFloatFromSettingsCfg('Camera', 'head bobbing step') * 2 -local stepHeight = settings._getFloatFromSettingsCfg('Camera', 'head bobbing height') -local maxRoll = math.rad(settings._getFloatFromSettingsCfg('Camera', 'head bobbing roll')) +local M = {} + +local settings = require('scripts.omw.camera.settings').headBobbing + +local doubleStepLength, stepHeight, maxRoll + +local function updateSettings() + M.enabled = settings:get('enabled') + doubleStepLength = settings:get('step') * 2 + stepHeight = settings:get('height') + maxRoll = math.rad(settings:get('roll')) +end + +updateSettings() +settings:subscribe(async:callback(updateSettings)) local effectWeight = 0 local totalMovement = 0 -local M = { - enabled = settings._getBoolFromSettingsCfg('Camera', 'head bobbing') -} - -- Trajectory of each step is a scaled arc of 60 degrees. local halfArc = math.rad(30) local sampleArc = function(x) return 1 - math.cos(x * halfArc) end diff --git a/files/data/scripts/omw/camera/settings.lua b/files/data/scripts/omw/camera/settings.lua new file mode 100644 index 0000000000..ec7f8a9c07 --- /dev/null +++ b/files/data/scripts/omw/camera/settings.lua @@ -0,0 +1,95 @@ +local storage = require('openmw.storage') +local async = require('openmw.async') +local I = require('openmw.interfaces') + +I.Settings.registerPage({ + key = 'OMWCamera', + l10n = 'OMWCamera', + name = 'Camera', + description = 'settingsPageDescription', +}) + +local thirdPersonGroup = 'SettingsOMWCameraThirdPerson' +local headBobbingGroup = 'SettingsOMWCameraHeadBobbing' + +local function boolSetting(prefix, key, default) + return { + key = key, + renderer = 'checkbox', + name = prefix..key, + description = prefix..key..'Description', + default = default, + } +end + +local function floatSetting(prefix, key, default) + return { + key = key, + renderer = 'number', + name = prefix..key, + description = prefix..key..'Description', + default = default, + } +end + +I.Settings.registerGroup({ + key = thirdPersonGroup, + page = 'OMWCamera', + l10n = 'OMWCamera', + name = 'thirdPersonSettings', + permanentStorage = true, + order = 0, + settings = { + boolSetting('', 'viewOverShoulder', true), + floatSetting('', 'shoulderOffsetX', 30), + floatSetting('', 'shoulderOffsetY', -10), + boolSetting('', 'autoSwitchShoulder', true), + floatSetting('', 'zoomOutWhenMoveCoef', 20), + boolSetting('', 'previewIfStandStill', true), + boolSetting('', 'deferredPreviewRotation', true), + boolSetting('', 'ignoreNC', true), + }, +}) + +I.Settings.registerGroup({ + key = headBobbingGroup, + page = 'OMWCamera', + l10n = 'OMWCamera', + name = 'headBobbingSettings', + permanentStorage = true, + order = 1, + settings = { + boolSetting('headBobbing_', 'enabled', true), + floatSetting('headBobbing_', 'step', 90), + floatSetting('headBobbing_', 'height', 3), + floatSetting('headBobbing_', 'roll', 0.2), + }, +}) + +local settings = { + thirdPerson = storage.playerSection(thirdPersonGroup), + headBobbing = storage.playerSection(headBobbingGroup), +} + +local function updateViewOverShoulderDisabled() + local disabled = not settings.thirdPerson:get('viewOverShoulder') + I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetX', {disabled = disabled}) + I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetY', {disabled = disabled}) + I.Settings.updateRendererArgument(thirdPersonGroup, 'autoSwitchShoulder', {disabled = disabled}) + I.Settings.updateRendererArgument(thirdPersonGroup, 'zoomOutWhenMoveCoef', {disabled = disabled}) +end + +local function updateHeadBobbingDisabled() + local disabled = not settings.headBobbing:get('enabled') + I.Settings.updateRendererArgument(headBobbingGroup, 'step', {disabled = disabled, min = 1}) + I.Settings.updateRendererArgument(headBobbingGroup, 'height', {disabled = disabled}) + I.Settings.updateRendererArgument(headBobbingGroup, 'roll', {disabled = disabled, min = 0, max = 90}) +end + +updateViewOverShoulderDisabled() +updateHeadBobbingDisabled() + +settings.thirdPerson:subscribe(async:callback(updateViewOverShoulderDisabled)) +settings.headBobbing:subscribe(async:callback(updateHeadBobbingDisabled)) + +return settings diff --git a/files/data/scripts/omw/third_person.lua b/files/data/scripts/omw/camera/third_person.lua similarity index 77% rename from files/data/scripts/omw/third_person.lua rename to files/data/scripts/omw/camera/third_person.lua index 311dbde48b..c28cbe2a4f 100644 --- a/files/data/scripts/omw/third_person.lua +++ b/files/data/scripts/omw/camera/third_person.lua @@ -1,31 +1,47 @@ local camera = require('openmw.camera') -local settings = require('openmw.settings') local util = require('openmw.util') local self = require('openmw.self') local nearby = require('openmw.nearby') +local async = require('openmw.async') local Actor = require('openmw.types').Actor +local settings = require('scripts.omw.camera.settings').thirdPerson + local MODE = camera.MODE local STATE = { RightShoulder = 0, LeftShoulder = 1, Combat = 2, Swimming = 3 } local M = { - baseDistance = settings._getFloatFromSettingsCfg('Camera', 'third person camera distance'), + baseDistance = 192, preferredDistance = 0, standingPreview = false, noOffsetControl = 0, } -local viewOverShoulder = settings._getBoolFromSettingsCfg('Camera', 'view over shoulder') -local autoSwitchShoulder = settings._getBoolFromSettingsCfg('Camera', 'auto switch shoulder') -local shoulderOffset = settings._getVector2FromSettingsCfg('Camera', 'view over shoulder offset') -local zoomOutWhenMoveCoef = settings._getFloatFromSettingsCfg('Camera', 'zoom out when move coef') +local viewOverShoulder, autoSwitchShoulder +local shoulderOffset +local zoomOutWhenMoveCoef -local defaultShoulder = (shoulderOffset.x > 0 and STATE.RightShoulder) or STATE.LeftShoulder -local rightShoulderOffset = util.vector2(math.abs(shoulderOffset.x), shoulderOffset.y) -local leftShoulderOffset = util.vector2(-math.abs(shoulderOffset.x), shoulderOffset.y) +local defaultShoulder, rightShoulderOffset, leftShoulderOffset local combatOffset = util.vector2(0, 15) +local noThirdPersonLastFrame = true + +local function updateSettings() + viewOverShoulder = settings:get('viewOverShoulder') + autoSwitchShoulder = settings:get('autoSwitchShoulder') + shoulderOffset = util.vector2(settings:get('shoulderOffsetX'), + settings:get('shoulderOffsetY')) + zoomOutWhenMoveCoef = settings:get('zoomOutWhenMoveCoef') + + defaultShoulder = (shoulderOffset.x > 0 and STATE.RightShoulder) or STATE.LeftShoulder + rightShoulderOffset = util.vector2(math.abs(shoulderOffset.x), shoulderOffset.y) + leftShoulderOffset = util.vector2(-math.abs(shoulderOffset.x), shoulderOffset.y) + noThirdPersonLastFrame = true +end +updateSettings() +settings:subscribe(async:callback(updateSettings)) + local state = defaultShoulder local function ray(from, angle, limit) @@ -66,8 +82,6 @@ local function calculateDistance(smoothedSpeed) + smoothedSpeedSqr / (smoothedSpeedSqr + 300*300) * zoomOutWhenMoveCoef) end -local noThirdPersonLastFrame = true - local function updateState() local mode = camera.getMode() local oldState = state @@ -80,9 +94,13 @@ local function updateState() elseif not state then state = defaultShoulder end - if autoSwitchShoulder and (mode == MODE.ThirdPerson or state ~= oldState or noThirdPersonLastFrame) + if (mode == MODE.ThirdPerson or Actor.currentSpeed(self) > 0 or state ~= oldState or noThirdPersonLastFrame) and (state == STATE.LeftShoulder or state == STATE.RightShoulder) then - trySwitchShoulder() + if autoSwitchShoulder then + trySwitchShoulder() + else + state = defaultShoulder + end end if oldState ~= state or noThirdPersonLastFrame then -- State was changed, start focal point transition. @@ -116,7 +134,11 @@ function M.update(dt, smoothedSpeed) if not viewOverShoulder then M.preferredDistance = M.baseDistance camera.setPreferredThirdPersonDistance(M.baseDistance) - noThirdPersonLastFrame = false + if noThirdPersonLastFrame then + camera.setFocalPreferredOffset(util.vector2(0, 0)) + camera.instantTransition() + noThirdPersonLastFrame = false + end return end From c548708a27b3a2fe47d192b22dae9eed32683d77 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 21 May 2022 19:23:40 +0200 Subject: [PATCH 2/7] Remove Lua package openmw.settings --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/mwlua/luabindings.hpp | 4 -- apps/openmw/mwlua/luamanagerimp.cpp | 5 -- apps/openmw/mwlua/luamanagerimp.hpp | 2 - apps/openmw/mwlua/settingsbindings.cpp | 71 -------------------------- 5 files changed, 1 insertion(+), 83 deletions(-) delete mode 100644 apps/openmw/mwlua/settingsbindings.cpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index c166b11ae3..24152d59ab 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -60,7 +60,7 @@ add_openmw_dir (mwscript add_openmw_dir (mwlua luamanagerimp object worldview userdataserializer eventqueue - luabindings localscripts playerscripts objectbindings cellbindings asyncbindings settingsbindings + luabindings localscripts playerscripts objectbindings cellbindings asyncbindings camerabindings uibindings inputbindings nearbybindings postprocessingbindings stats debugbindings types/types types/door types/actor types/container types/weapon types/npc types/creature types/activator types/book types/lockpick types/probe types/apparatus types/potion types/misc types/repair ) diff --git a/apps/openmw/mwlua/luabindings.hpp b/apps/openmw/mwlua/luabindings.hpp index af41199ad9..5760a383ec 100644 --- a/apps/openmw/mwlua/luabindings.hpp +++ b/apps/openmw/mwlua/luabindings.hpp @@ -56,10 +56,6 @@ namespace MWLua // Implemented in inputbindings.cpp sol::table initInputPackage(const Context&); - // Implemented in settingsbindings.cpp - sol::table initGlobalSettingsPackage(const Context&); - sol::table initPlayerSettingsPackage(const Context&); - // openmw.self package is implemented in localscripts.cpp } diff --git a/apps/openmw/mwlua/luamanagerimp.cpp b/apps/openmw/mwlua/luamanagerimp.cpp index c3dff4f04c..b71f5919c3 100644 --- a/apps/openmw/mwlua/luamanagerimp.cpp +++ b/apps/openmw/mwlua/luamanagerimp.cpp @@ -88,15 +88,12 @@ namespace MWLua mLua.addCommonPackage("openmw.core", initCorePackage(context)); mLua.addCommonPackage("openmw.types", initTypesPackage(context)); mGlobalScripts.addPackage("openmw.world", initWorldPackage(context)); - mGlobalScripts.addPackage("openmw.settings", initGlobalSettingsPackage(context)); mGlobalScripts.addPackage("openmw.storage", initGlobalStoragePackage(context, &mGlobalStorage)); mCameraPackage = initCameraPackage(localContext); mUserInterfacePackage = initUserInterfacePackage(localContext); mInputPackage = initInputPackage(localContext); mNearbyPackage = initNearbyPackage(localContext); - mLocalSettingsPackage = initGlobalSettingsPackage(localContext); - mPlayerSettingsPackage = initPlayerSettingsPackage(localContext); mLocalStoragePackage = initLocalStoragePackage(localContext, &mGlobalStorage); mPlayerStoragePackage = initPlayerStoragePackage(localContext, &mGlobalStorage, &mPlayerStorage); mPostprocessingPackage = initPostprocessingPackage(localContext); @@ -423,7 +420,6 @@ namespace MWLua scripts->addPackage("openmw.ui", mUserInterfacePackage); scripts->addPackage("openmw.camera", mCameraPackage); scripts->addPackage("openmw.input", mInputPackage); - scripts->addPackage("openmw.settings", mPlayerSettingsPackage); scripts->addPackage("openmw.storage", mPlayerStoragePackage); scripts->addPackage("openmw.postprocessing", mPostprocessingPackage); scripts->addPackage("openmw.debug", mDebugPackage); @@ -434,7 +430,6 @@ namespace MWLua if (!autoStartConf.has_value()) autoStartConf = mConfiguration.getLocalConf(type, ptr.getCellRef().getRefId(), getId(ptr)); scripts->setAutoStartConf(std::move(*autoStartConf)); - scripts->addPackage("openmw.settings", mLocalSettingsPackage); scripts->addPackage("openmw.storage", mLocalStoragePackage); } scripts->addPackage("openmw.nearby", mNearbyPackage); diff --git a/apps/openmw/mwlua/luamanagerimp.hpp b/apps/openmw/mwlua/luamanagerimp.hpp index e1eaac9ff8..41eb076783 100644 --- a/apps/openmw/mwlua/luamanagerimp.hpp +++ b/apps/openmw/mwlua/luamanagerimp.hpp @@ -137,8 +137,6 @@ namespace MWLua sol::table mUserInterfacePackage; sol::table mCameraPackage; sol::table mInputPackage; - sol::table mLocalSettingsPackage; - sol::table mPlayerSettingsPackage; sol::table mLocalStoragePackage; sol::table mPlayerStoragePackage; sol::table mPostprocessingPackage; diff --git a/apps/openmw/mwlua/settingsbindings.cpp b/apps/openmw/mwlua/settingsbindings.cpp deleted file mode 100644 index afd852b1a0..0000000000 --- a/apps/openmw/mwlua/settingsbindings.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "luabindings.hpp" - -#include - -#include "../mwworld/esmstore.hpp" -#include "../mwworld/store.hpp" - -namespace MWLua -{ - - static sol::table initSettingsPackage(const Context& context, bool player) - { - LuaUtil::LuaState* lua = context.mLua; - sol::table config(lua->sol(), sol::create); - - // Access to settings.cfg. Temporary, will be removed at some point. - auto checkRead = [player](std::string_view category) - { - if ((category == "Camera" || category == "GUI" || category == "Hud" || - category == "Windows" || category == "Input") && !player) - throw std::runtime_error("This setting is only available in player scripts"); - }; - config["_getBoolFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) - { - checkRead(category); - return Settings::Manager::getBool(setting, category); - }; - config["_getIntFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) - { - checkRead(category); - return Settings::Manager::getInt(setting, category); - }; - config["_getFloatFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) - { - checkRead(category); - return Settings::Manager::getFloat(setting, category); - }; - config["_getStringFromSettingsCfg"] = [=](const std::string& category, const std::string& setting) - { - checkRead(category); - return Settings::Manager::getString(setting, category); - }; - config["_getVector2FromSettingsCfg"] = [=](const std::string& category, const std::string& setting) - { - checkRead(category); - return Settings::Manager::getVector2(setting, category); - }; - config["_getVector3FromSettingsCfg"] = [=](const std::string& category, const std::string& setting) - { - checkRead(category); - return Settings::Manager::getVector3(setting, category); - }; - - const MWWorld::Store* gmst = &MWBase::Environment::get().getWorld()->getStore().get(); - config["getGMST"] = [lua, gmst](const std::string setting) -> sol::object - { - const ESM::Variant& value = gmst->find(setting)->mValue; - if (value.getType() == ESM::VT_String) - return sol::make_object(lua->sol(), value.getString()); - else if (value.getType() == ESM::VT_Int) - return sol::make_object(lua->sol(), value.getInteger()); - else - return sol::make_object(lua->sol(), value.getFloat()); - }; - return LuaUtil::makeReadOnly(config); - } - - sol::table initGlobalSettingsPackage(const Context& context) { return initSettingsPackage(context, false); } - sol::table initPlayerSettingsPackage(const Context& context) { return initSettingsPackage(context, true); } - -} From 65efd6f1c27d647786df3c24f2ec4ce0d0991b51 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sat, 21 May 2022 19:49:05 +0200 Subject: [PATCH 3/7] Remove from settings.cfg camera settings that are controlled from Lua --- apps/launcher/advancedpage.cpp | 38 ----- apps/launcher/advancedpage.hpp | 1 - .../reference/modding/settings/camera.rst | 135 +---------------- files/settings-default.cfg | 33 ---- files/ui/advancedpage.ui | 141 ------------------ 5 files changed, 3 insertions(+), 345 deletions(-) diff --git a/apps/launcher/advancedpage.cpp b/apps/launcher/advancedpage.cpp index a5a7cab8d4..6566bd8d51 100644 --- a/apps/launcher/advancedpage.cpp +++ b/apps/launcher/advancedpage.cpp @@ -180,20 +180,6 @@ bool Launcher::AdvancedPage::loadSettings() } } - - // Camera - { - loadSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); - connect(viewOverShoulderCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotViewOverShoulderToggled(bool))); - viewOverShoulderVerticalLayout->setEnabled(viewOverShoulderCheckBox->checkState()); - loadSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); - loadSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); - loadSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); - loadSettingBool(headBobbingCheckBox, "head bobbing", "Camera"); - defaultShoulderComboBox->setCurrentIndex( - Settings::Manager::getVector2("view over shoulder offset", "Camera").x() >= 0 ? 0 : 1); - } - // Interface Changes { loadSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); @@ -350,25 +336,6 @@ void Launcher::AdvancedPage::saveSettings() } } - // Camera - { - saveSettingBool(viewOverShoulderCheckBox, "view over shoulder", "Camera"); - saveSettingBool(autoSwitchShoulderCheckBox, "auto switch shoulder", "Camera"); - saveSettingBool(previewIfStandStillCheckBox, "preview if stand still", "Camera"); - saveSettingBool(deferredPreviewRotationCheckBox, "deferred preview rotation", "Camera"); - saveSettingBool(headBobbingCheckBox, "head bobbing", "Camera"); - - osg::Vec2f shoulderOffset = Settings::Manager::getVector2("view over shoulder offset", "Camera"); - if (defaultShoulderComboBox->currentIndex() != (shoulderOffset.x() >= 0 ? 0 : 1)) - { - if (defaultShoulderComboBox->currentIndex() == 0) - shoulderOffset.x() = std::abs(shoulderOffset.x()); - else - shoulderOffset.x() = -std::abs(shoulderOffset.x()); - Settings::Manager::setVector2("view over shoulder offset", "Camera", shoulderOffset); - } - } - // Interface Changes { saveSettingBool(showEffectDurationCheckBox, "show effect duration", "Game"); @@ -479,11 +446,6 @@ void Launcher::AdvancedPage::slotAnimSourcesToggled(bool checked) } } -void Launcher::AdvancedPage::slotViewOverShoulderToggled(bool checked) -{ - viewOverShoulderVerticalLayout->setEnabled(viewOverShoulderCheckBox->checkState()); -} - void Launcher::AdvancedPage::slotPostProcessToggled(bool checked) { postprocessLiveReloadCheckBox->setEnabled(checked); diff --git a/apps/launcher/advancedpage.hpp b/apps/launcher/advancedpage.hpp index 6a3f8319d2..20b44ff9da 100644 --- a/apps/launcher/advancedpage.hpp +++ b/apps/launcher/advancedpage.hpp @@ -29,7 +29,6 @@ namespace Launcher void on_skipMenuCheckBox_stateChanged(int state); void on_runScriptAfterStartupBrowseButton_clicked(); void slotAnimSourcesToggled(bool checked); - void slotViewOverShoulderToggled(bool checked); void slotPostProcessToggled(bool checked); private: diff --git a/docs/source/reference/modding/settings/camera.rst b/docs/source/reference/modding/settings/camera.rst index fe6217b22b..5011885919 100644 --- a/docs/source/reference/modding/settings/camera.rst +++ b/docs/source/reference/modding/settings/camera.rst @@ -1,6 +1,9 @@ Camera Settings ############### +.. note:: + Some camera settings are available only in the in-game settings menu. See the tab "Scripts/OpenMW Camera". + near clip --------- @@ -103,138 +106,6 @@ while small values can result in the hands not being visible. This setting can only be configured by editing the settings configuration file. -third person camera distance ----------------------------- - -:Type: floating point -:Range: 30-800 -:Default: 192.0 - -Distance from the camera to the character in third person mode. - -This setting can be changed in game using "Zoom In" / "Zoom Out" controls. - -view over shoulder ------------------- - -:Type: boolean -:Range: True/False -:Default: False - -This setting controls third person view mode. -False: View is centered on the character's head. Crosshair is hidden. -True: In non-combat mode camera is positioned behind the character's shoulder. Crosshair is visible in third person mode as well. - -This setting can be controlled in Advanced tab of the launcher. - -view over shoulder offset -------------------------- - -:Type: 2D vector floating point -:Range: Any -:Default: 30 -10 - -This setting makes sense only if 'view over shoulder' is enabled. Controls horizontal (first number) and vertical (second number) offset of the camera in third person mode. -Recommened values: 30 -10 for the right shoulder, -30 -10 for the left shoulder. - -This setting can only be configured by editing the settings configuration file. - -auto switch shoulder --------------------- - -:Type: boolean -:Range: True/False -:Default: True - -This setting makes difference only in third person mode if 'view over shoulder' is enabled. -When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle. - -This setting can be controlled in Advanced tab of the launcher. - -zoom out when move coef ------------------------ - -:Type: floating point -:Range: Any -:Default: 20 - -This setting makes difference only in third person mode if 'view over shoulder' is enabled. -Slightly pulls camera away (or closer in case of negative value) when the character moves. To disable set it to zero. - -This setting can only be configured by editing the settings configuration file. - -preview if stand still ----------------------- - -:Type: boolean -:Range: True/False -:Default: False - -Makes difference only in third person mode. -If enabled then the character rotation is not synchonized with the camera rotation while the character doesn't move and not in combat mode. - -This setting can be controlled in Advanced tab of the launcher. - -deferred preview rotation -------------------------- - -:Type: boolean -:Range: True/False -:Default: True - -Makes difference only in third person mode. -If enabled then the character smoothly rotates to the view direction after exiting preview or vanity mode. -If disabled then the camera rotates rather than the character. - -This setting can be controlled in Advanced tab of the launcher. - -head bobbing ------------- - -:Type: boolean -:Range: True/False -:Default: False - -Enables head bobbing when move in first person mode. - -This setting can be controlled in Advanced tab of the launcher. - -head bobbing step ------------------ - -:Type: floating point -:Range: >0 -:Default: 90.0 - -Makes diffence only in first person mode if 'head bobbing' is enabled. -Length of each step. - -This setting can only be configured by editing the settings configuration file. - -head bobbing height -------------------- - -:Type: floating point -:Range: Any -:Default: 3.0 - -Makes diffence only in first person mode if 'head bobbing' is enabled. -Amplitude of the head bobbing. - -This setting can only be configured by editing the settings configuration file. - -head bobbing roll ------------------ - -:Type: floating point -:Range: 0-90 -:Default: 0.2 - -Makes diffence only in first person mode if 'head bobbing' is enabled. -Maximum roll angle in degrees. - -This setting can only be configured by editing the settings configuration file. - reverse z --------- diff --git a/files/settings-default.cfg b/files/settings-default.cfg index da50ca5fc7..3f4446535e 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -26,39 +26,6 @@ field of view = 60.0 # Best to leave this at the default since vanilla assets are not complete enough to adapt to high FoV's. Too low FoV would clip the hands off screen. first person field of view = 60.0 -# Distance from the camera to the character in third person mode. -third person camera distance = 192 - -# If enabled then third person camera is positioned above character's shoulder and crosshair is visible. -view over shoulder = false - -# Makes sense only if 'view over shoulder' is true. First number is horizontal offset (negative value means offset to the left), second number is vertical offset. -view over shoulder offset = 30 -10 - -# Switch shoulder automatically when player is close to an obstacle. -auto switch shoulder = true - -# Slightly pulls camera away when the character moves. Works only in 'view over shoulder' mode. Set to 0 to disable. -zoom out when move coef = 20 - -# Automatically enable preview mode when player doesn't move. -preview if stand still = false - -# Rotate the character to the view direction after exiting preview mode. -deferred preview rotation = true - -# Enables head bobbing in first person mode -head bobbing = false - -# Length of each step -head bobbing step = 90.0 - -# Amplitude of the bobbing effect -head bobbing height = 3.0 - -# Maximum camera roll angle (degrees) -head bobbing roll = 0.2 - # Reverse the depth range, reduces z-fighting of distant objects and terrain reverse z = true diff --git a/files/ui/advancedpage.ui b/files/ui/advancedpage.ui index 520b089965..66ebd90a80 100644 --- a/files/ui/advancedpage.ui +++ b/files/ui/advancedpage.ui @@ -827,147 +827,6 @@ - - - Camera - - - - - - <html><head/><body><p>This setting controls third person view mode.</p><p>False: View is centered on the character's head. Crosshair is hidden. -True: In non-combat mode camera is positioned behind the character's shoulder. Crosshair is visible in third person mode as well. -</p></body></html> - - - View over the shoulder - - - - - - - <html><head/><body><p>When player is close to an obstacle, automatically switches camera to the shoulder that is farther away from the obstacle.</p></body></html> - - - Auto switch shoulder - - - - - - - 20 - - - 0 - - - 0 - - - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Default shoulder: - - - - - - - 0 - - - - Right - - - - - Left - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - - <html><head/><body><p>If enabled then the character rotation is not synchonized with the camera rotation while the character doesn't move and not in combat mode.</p></body></html> - - - Preview if stand still - - - - - - - <html><head/><body><p>If enabled then the character smoothly rotates to the view direction after exiting preview or vanity mode. If disabled then the camera rotates rather than the character.</p></body></html> - - - Deferred preview rotation - - - - - - - <html><head/><body><p>Enables head bobbing when move in first person mode.</p></body></html> - - - Head bobbing in 1st person mode - - - - - - - Qt::Vertical - - - - 0 - 0 - - - - - - Interface From 3fb470dcce410bbfb5a06b1cf1d5eaa3ca145da5 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Tue, 7 Jun 2022 00:36:44 +0200 Subject: [PATCH 4/7] Increase the size of the settings menu; reduce the size of Lua settings "number" in order to make camera settings look good with the default size of the settings menu. --- docs/source/reference/modding/settings/windows.rst | 8 ++++---- files/data/scripts/omw/settings/renderers.lua | 3 ++- files/mygui/openmw_settings_window.layout | 6 +++--- files/settings-default.cfg | 8 ++++---- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/source/reference/modding/settings/windows.rst b/docs/source/reference/modding/settings/windows.rst index 6426802ab9..dd6bb3aee5 100644 --- a/docs/source/reference/modding/settings/windows.rst +++ b/docs/source/reference/modding/settings/windows.rst @@ -249,13 +249,13 @@ settings -------- :Default: - x = 0.33 + x = 0.1 - y = 0.18 + y = 0.1 - w = 0.33 + w = 0.8 - h = 0.66 + h = 0.8 The settings window. Activated by clicking Options in the main menu. diff --git a/files/data/scripts/omw/settings/renderers.lua b/files/data/scripts/omw/settings/renderers.lua index 2b1739e5a3..3c187740e6 100644 --- a/files/data/scripts/omw/settings/renderers.lua +++ b/files/data/scripts/omw/settings/renderers.lua @@ -112,6 +112,7 @@ return function(registerRenderer) template = I.MWUI.templates.textEditLine, props = { text = tostring(value), + size = util.vector2(80, 0), }, events = { textChanged = async:callback(function(text) @@ -262,4 +263,4 @@ return function(registerRenderer) }) end) end -end \ No newline at end of file +end diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index cfc80b1368..71890fec27 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -1,7 +1,7 @@  - + @@ -302,7 +302,7 @@ - + @@ -317,7 +317,7 @@ - + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 3f4446535e..fd9826104a 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -794,10 +794,10 @@ companion maximized h = 0.875 companion maximized = false # Settings menu -settings x = 0.33 -settings y = 0.18 -settings w = 0.33 -settings h = 0.67 +settings x = 0.1 +settings y = 0.1 +settings w = 0.8 +settings h = 0.8 settings maximized x = 0.015 settings maximized y = 0.02 settings maximized w = 0.97 From 1ca0a3a555902ad6fa36edf8098aa3f9ba8d920f Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Wed, 8 Jun 2022 23:34:34 +0200 Subject: [PATCH 5/7] Addition camera features: move360, pov_auto_switch, slow_view_change --- files/data/CMakeLists.txt | 2 + files/data/l10n/OMWCamera/en.yaml | 17 ++++- files/data/scripts/omw/camera/camera.lua | 16 +++- .../omw/camera/first_person_auto_switch.lua | 52 +++++++++++++ files/data/scripts/omw/camera/move360.lua | 73 +++++++++++++++++++ files/data/scripts/omw/camera/settings.lua | 17 +++-- 6 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 files/data/scripts/omw/camera/first_person_auto_switch.lua create mode 100644 files/data/scripts/omw/camera/move360.lua diff --git a/files/data/CMakeLists.txt b/files/data/CMakeLists.txt index a7d6cf320f..40c5456f8a 100644 --- a/files/data/CMakeLists.txt +++ b/files/data/CMakeLists.txt @@ -26,6 +26,8 @@ set(BUILTIN_DATA_FILES scripts/omw/camera/head_bobbing.lua scripts/omw/camera/third_person.lua scripts/omw/camera/settings.lua + scripts/omw/camera/move360.lua + scripts/omw/camera/first_person_auto_switch.lua scripts/omw/console/player.lua scripts/omw/console/global.lua scripts/omw/console/local.lua diff --git a/files/data/l10n/OMWCamera/en.yaml b/files/data/l10n/OMWCamera/en.yaml index 9d5e7ac7ee..eefc192960 100644 --- a/files/data/l10n/OMWCamera/en.yaml +++ b/files/data/l10n/OMWCamera/en.yaml @@ -1,5 +1,5 @@ -Camera: "Camera" -settingsPageDescription: "OpenMW camera settings" +Camera: "OpenMW Camera" +settingsPageDescription: "OpenMW Camera settings" thirdPersonSettings: "Third person mode" @@ -42,6 +42,19 @@ ignoreNC: "Ignore 'No Collision' flag" ignoreNCDescription: > Prevents camera from clipping through the objects with the NC (No Collision) NIF flag. +move360: "Move 360" +move360Description: > + When without weapon in hands the character rotates to the direction of movement. I.e. looks to the camera when run backwards. + +move360TurnSpeed: "Move 360 turning speed" +move360TurnSpeedDescription: A multiplier for the turning speed (5.0 by default) + +slowViewChange: "Smooth view change" +slowViewChangeDescription: "Makes switching from 1st person to 3rd person view not instant." + +povAutoSwitch: "First person auto switch" +povAutoSwitchDescription: "Auto switch to 1st person view if there is an obstacle right behind the player." + headBobbingSettings: "Head bobbing in first person view" diff --git a/files/data/scripts/omw/camera/camera.lua b/files/data/scripts/omw/camera/camera.lua index 26dcfc036c..ce1bd2d48b 100644 --- a/files/data/scripts/omw/camera/camera.lua +++ b/files/data/scripts/omw/camera/camera.lua @@ -11,11 +11,14 @@ local Actor = require('openmw.types').Actor local settings = require('scripts.omw.camera.settings').thirdPerson local head_bobbing = require('scripts.omw.camera.head_bobbing') local third_person = require('scripts.omw.camera.third_person') +local pov_auto_switch = require('scripts.omw.camera.first_person_auto_switch') +local move360 = require('scripts.omw.camera.move360') local MODE = camera.MODE local previewIfStandStill = false local showCrosshairInThirdPerson = false +local slowViewChange = false local function updateSettings() previewIfStandStill = settings:get('previewIfStandStill') @@ -27,6 +30,10 @@ local function updateSettings() collisionType = util.bitOr(collisionType, nearby.COLLISION_TYPE.VisualOnly) end camera.setCollisionType(collisionType) + move360.enabled = settings:get('move360') + move360.turnSpeed = settings:get('move360TurnSpeed') + pov_auto_switch.enabled = settings:get('povAutoSwitch') + slowViewChange = settings:get('slowViewChange') end local primaryMode @@ -167,6 +174,7 @@ local function onUpdate(dt) camera.setExtraRoll(0) camera.setFirstPersonOffset(util.vector3(0, 0, 0)) updateSmoothedSpeed(dt) + pov_auto_switch.onUpdate(dt) end local function onFrame(dt) @@ -188,6 +196,12 @@ local function onFrame(dt) applyControllerZoom(dt) third_person.update(dt, smoothedSpeed) if noHeadBobbing == 0 then head_bobbing.update(dt, smoothedSpeed) end + if slowViewChange then + local maxIncrease = dt * (100 + third_person.baseDistance) + camera.setPreferredThirdPersonDistance( + math.min(camera.getThirdPersonDistance() + maxIncrease, third_person.preferredDistance)) + end + move360.onFrame(dt) end return { @@ -255,6 +269,7 @@ return { elseif action == input.ACTION.ZoomOut then zoom(-10) end + move360.onInputAction(action) end, onActive = init, onLoad = function(data) @@ -265,4 +280,3 @@ return { end, }, } - diff --git a/files/data/scripts/omw/camera/first_person_auto_switch.lua b/files/data/scripts/omw/camera/first_person_auto_switch.lua new file mode 100644 index 0000000000..a1c0b863c9 --- /dev/null +++ b/files/data/scripts/omw/camera/first_person_auto_switch.lua @@ -0,0 +1,52 @@ +local camera = require('openmw.camera') +local util = require('openmw.util') +local nearby = require('openmw.nearby') +local self = require('openmw.self') + +local forcedFirstPerson = false +local limitSwitch = 40 +local limitReturn = 65 + +local rayOptions = {collisionType = nearby.COLLISION_TYPE.Default - nearby.COLLISION_TYPE.Actor} +local function castRayBackward() + local from = camera.getTrackedPosition() + local orient = util.transform.rotateZ(camera.getYaw()) * util.transform.rotateX(camera.getPitch()) + local resLeft = nearby.castRay(from, from + orient * util.vector3(-30, -limitReturn, 0), rayOptions) + local resRight = nearby.castRay(from, from + orient * util.vector3(30, -limitReturn, 0), rayOptions) + local distLeft = limitReturn + 1 + local distRight = limitReturn + 1 + if resLeft.hit then distLeft = (resLeft.hitPos - from):length() end + if resRight.hit then distRight = (resRight.hitPos - from):length() end + return math.min(distLeft, distRight) +end + +local M = { + enabled = false, +} + +function M.onUpdate(dt) + if camera.getMode() ~= camera.MODE.FirstPerson then forcedFirstPerson = false end + if not M.enabled then + if forcedFirstPerson then + camera.setMode(camera.MODE.ThirdPerson, false) + forcedFirstPerson = false + end + return + end + if camera.getMode() == camera.MODE.ThirdPerson and camera.getThirdPersonDistance() < limitSwitch + and math.abs(util.normalizeAngle(camera.getYaw() - self.rotation.z)) < math.rad(10) then + if castRayBackward() <= limitSwitch then + camera.setMode(camera.MODE.FirstPerson, true) + forcedFirstPerson = true + end + return + end + if forcedFirstPerson then + if castRayBackward() > limitReturn then + camera.setMode(camera.MODE.ThirdPerson, false) + forcedFirstPerson = false + end + end +end + +return M diff --git a/files/data/scripts/omw/camera/move360.lua b/files/data/scripts/omw/camera/move360.lua new file mode 100644 index 0000000000..5247c03a30 --- /dev/null +++ b/files/data/scripts/omw/camera/move360.lua @@ -0,0 +1,73 @@ +local core = require('openmw.core') +local camera = require('openmw.camera') +local input = require('openmw.input') +local self = require('openmw.self') +local util = require('openmw.util') +local I = require('openmw.interfaces') + +local Actor = require('openmw.types').Actor + +local MODE = camera.MODE + +local active = false + +local M = { + enabled = false, + turnSpeed = 5, +} + +local function turnOn() + I.Camera.disableStandingPreview() + active = true +end + +local function turnOff() + I.Camera.enableStandingPreview() + active = false + if camera.getMode() == MODE.Preview then + camera.setMode(MODE.ThirdPerson) + end +end + +function M.onFrame(dt) + if core.isWorldPaused() then return end + local newActive = M.enabled and Actor.stance(self) == Actor.STANCE.Nothing + if newActive and not active then + turnOn() + elseif not newActive and active then + turnOff() + end + if not active then return end + if camera.getMode() == MODE.Static then return end + if camera.getMode() == MODE.ThirdPerson then camera.setMode(MODE.Preview) end + if camera.getMode() == MODE.Preview and not input.isActionPressed(input.ACTION.TogglePOV) then + camera.showCrosshair(camera.getFocalPreferredOffset():length() > 5) + local move = util.vector2(self.controls.sideMovement, self.controls.movement) + local yawDelta = camera.getYaw() - self.rotation.z + move = move:rotate(-yawDelta) + self.controls.sideMovement = move.x + self.controls.movement = move.y + self.controls.pitchChange = camera.getPitch() * math.cos(yawDelta) - self.rotation.x + if move:length() > 0.05 then + local delta = math.atan2(move.x, move.y) + local maxDelta = math.max(delta, 1) * M.turnSpeed * dt + self.controls.yawChange = util.clamp(delta, -maxDelta, maxDelta) + else + self.controls.yawChange = 0 + end + end +end + +function M.onInputAction(action) + if not active or core.isWorldPaused() then return end + if action == input.ACTION.ZoomIn and camera.getMode() == MODE.Preview + and I.Camera.getBaseThirdPersonDistance() == 30 then + self.controls.yawChange = camera.getYaw() - self.rotation.z + camera.setMode(MODE.FirstPerson) + elseif action == input.ACTION.ZoomOut and camera.getMode() == MODE.FirstPerson then + camera.setMode(MODE.Preview) + I.Camera.setBaseThirdPersonDistance(30) + end +end + +return M diff --git a/files/data/scripts/omw/camera/settings.lua b/files/data/scripts/omw/camera/settings.lua index ec7f8a9c07..06cbbfc6f0 100644 --- a/files/data/scripts/omw/camera/settings.lua +++ b/files/data/scripts/omw/camera/settings.lua @@ -48,6 +48,10 @@ I.Settings.registerGroup({ boolSetting('', 'previewIfStandStill', true), boolSetting('', 'deferredPreviewRotation', true), boolSetting('', 'ignoreNC', true), + boolSetting('', 'move360', false), + floatSetting('', 'move360TurnSpeed', 5), + boolSetting('', 'slowViewChange', false), + boolSetting('', 'povAutoSwitch', false), }, }) @@ -72,11 +76,14 @@ local settings = { } local function updateViewOverShoulderDisabled() - local disabled = not settings.thirdPerson:get('viewOverShoulder') - I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetX', {disabled = disabled}) - I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetY', {disabled = disabled}) - I.Settings.updateRendererArgument(thirdPersonGroup, 'autoSwitchShoulder', {disabled = disabled}) - I.Settings.updateRendererArgument(thirdPersonGroup, 'zoomOutWhenMoveCoef', {disabled = disabled}) + local shoulderDisabled = not settings.thirdPerson:get('viewOverShoulder') + I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetX', {disabled = shoulderDisabled}) + I.Settings.updateRendererArgument(thirdPersonGroup, 'shoulderOffsetY', {disabled = shoulderDisabled}) + I.Settings.updateRendererArgument(thirdPersonGroup, 'autoSwitchShoulder', {disabled = shoulderDisabled}) + I.Settings.updateRendererArgument(thirdPersonGroup, 'zoomOutWhenMoveCoef', {disabled = shoulderDisabled}) + + local move360Disabled = not settings.thirdPerson:get('move360') + I.Settings.updateRendererArgument(thirdPersonGroup, 'move360TurnSpeed', {disabled = move360Disabled}) end local function updateHeadBobbingDisabled() From 5f0a7c2b169788099f2985b20b0cd5313c5a9cfe Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Wed, 8 Jun 2022 21:23:20 +0200 Subject: [PATCH 6/7] Fix jumping when using move360 with a controller --- apps/openmw/mwinput/controllermanager.cpp | 2 +- files/data/scripts/omw/camera/camera.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 1160b3a0b3..4db9fad595 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -277,7 +277,7 @@ namespace MWInput { gamepadToGuiControl(arg); } - else if (MWBase::Environment::get().getWorld()->isPreviewModeEnabled() && + else if (mBindingsManager->actionIsActive(A_TogglePOV) && (arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT || arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)) { // Preview Mode Gamepad Zooming; do not propagate to mBindingsManager diff --git a/files/data/scripts/omw/camera/camera.lua b/files/data/scripts/omw/camera/camera.lua index ce1bd2d48b..46fa732247 100644 --- a/files/data/scripts/omw/camera/camera.lua +++ b/files/data/scripts/omw/camera/camera.lua @@ -135,7 +135,7 @@ local function zoom(delta) end local function applyControllerZoom(dt) - if camera.getMode() == MODE.Preview then + if input.isActionPressed(input.ACTION.TogglePOV) then local triggerLeft = input.getAxisValue(input.CONTROLLER_AXIS.TriggerLeft) local triggerRight = input.getAxisValue(input.CONTROLLER_AXIS.TriggerRight) local controllerZoom = (triggerRight - triggerLeft) * 100 * dt From 73eda27e7f2e8029d72f23798af436c3b0fe54f9 Mon Sep 17 00:00:00 2001 From: Petr Mikheev Date: Sun, 12 Jun 2022 00:59:03 +0200 Subject: [PATCH 7/7] Update l10n/OMWCamera/en.yaml --- files/data/l10n/OMWCamera/en.yaml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/files/data/l10n/OMWCamera/en.yaml b/files/data/l10n/OMWCamera/en.yaml index eefc192960..d030bd22ec 100644 --- a/files/data/l10n/OMWCamera/en.yaml +++ b/files/data/l10n/OMWCamera/en.yaml @@ -7,31 +7,30 @@ viewOverShoulder: "View over the shoulder" viewOverShoulderDescription: | Controls third person view mode. No: view is centered on the character's head. Crosshair is hidden. - Yes: in non-combat mode camera is positioned behind the character's shoulder, crosshair is always visible. + Yes: while weapon sheathed the camera is positioned behind the character's shoulder, crosshair is always visible. shoulderOffsetX: "Shoulder view horizontal offset" shoulderOffsetXDescription: > - Horizontal offset of the camera in the view-over-the-shoulder mode. + Horizontal offset of the over-the-shoulder view. For the left shoulder use a negative value. shoulderOffsetY: "Shoulder view vertical offset" shoulderOffsetYDescription: > - Vertical offset of the camera in the view-over-the-shoulder mode. + Vertical offset of the over-the-shoulder view. autoSwitchShoulder: "Auto switch shoulder" autoSwitchShoulderDescription: > - When player is close to an obstacle, automatically switches camera - to the shoulder that is farther away from the obstacle. + When there are obstacles that would push the camera close to the player character, + this setting makes the camera automatically switch to the shoulder farther away from the obstacles. zoomOutWhenMoveCoef: "Zoom out when move coef" zoomOutWhenMoveCoefDescription: > - Slightly pulls camera away (or closer in case of a negative value) when the character moves. - Works only if "view over the shoulder" is enabled. To disable set it to zero (default: 20.0). + Moves the camera away (positive value) or towards (negative value) the player character while the character is moving. + Works only if "view over the shoulder" is enabled. Set this to zero to disable (default: 20.0). previewIfStandStill: "Preview if stand still" previewIfStandStillDescription: > - If enabled then the character rotation is not synchonized with the camera rotation - while the character doesn't move and not in combat mode. + Prevents the player character from turning towards the camera direction while they're idle and have their weapon sheathed. deferredPreviewRotation: "Deferred preview rotation" deferredPreviewRotationDescription: | @@ -40,20 +39,21 @@ deferredPreviewRotationDescription: | ignoreNC: "Ignore 'No Collision' flag" ignoreNCDescription: > - Prevents camera from clipping through the objects with the NC (No Collision) NIF flag. + Prevents the camera from clipping through objects that have NC (No Collision) flag turned on in the NIF model. move360: "Move 360" move360Description: > - When without weapon in hands the character rotates to the direction of movement. I.e. looks to the camera when run backwards. + Makes the movement direction independent from the camera direction while the player character's weapon + is sheathed. For example, the player character will look at the camera while running backwards. move360TurnSpeed: "Move 360 turning speed" -move360TurnSpeedDescription: A multiplier for the turning speed (5.0 by default) +move360TurnSpeedDescription: "Turning speed multiplier (default: 5.0)." slowViewChange: "Smooth view change" -slowViewChangeDescription: "Makes switching from 1st person to 3rd person view not instant." +slowViewChangeDescription: "Makes the transition from 1st person to 3rd person view non-instantaneous." povAutoSwitch: "First person auto switch" -povAutoSwitchDescription: "Auto switch to 1st person view if there is an obstacle right behind the player." +povAutoSwitchDescription: "Auto switch to the first person view if there is an obstacle right behind the player." headBobbingSettings: "Head bobbing in first person view"