setting at third person over the shoulder in combat mode

Support for running, installing or compiling OpenMW

Before you submit a bug report for the first time, please read: Bug reporting guidelines
Post Reply
Alyen91
Posts: 7
Joined: 20 Mar 2021, 22:47

setting at third person over the shoulder in combat mode

Post by Alyen91 »

as the title suggests, I would like the camera to be always positioned to the in towards the shoulder this is already set when I'm not fighting. but when I draw the bow the camera returns to the center making it difficult for me to aim in some situations.

Imagecarica immagini online
my elf will thank you for any help...

sorrry in not english and use google traslate :)
Last edited by Alyen91 on 26 Mar 2021, 15:07, edited 1 time in total.
User avatar
psi29a
Posts: 5360
Joined: 29 Sep 2011, 10:13
Location: Belgium
Gitlab profile: https://gitlab.com/psi29a/
Contact:

Re: first pass at third person over the shoulder in combat mode

Post by psi29a »

:shock:

Every time you edit your post, it has to go through the moderation queue for all new users. This check goes away after you've been here awhile.

Isn't there a setting in the launcher that allows this?
Alyen91
Posts: 7
Joined: 20 Mar 2021, 22:47

Re: first pass at third person over the shoulder in combat mode

Post by Alyen91 »

ahahaha ... but you didn't tell me how ... isn't there a setting on openmw that allows me to always keep the camera right over my shoulder even in fights?
Notaro
Posts: 9
Joined: 26 Mar 2021, 19:36

Re: setting at third person over the shoulder in combat mode

Post by Notaro »

I second that. Atm camera switches when you enter/exit combat mode, and that's annoying.
User avatar
victr
Posts: 1
Joined: 11 Mar 2022, 10:36

Re: setting at third person over the shoulder in combat mode

Post by victr »

I was able to keep the camera over the shoulders even in combat by commenting some lines in "resources/vfs/scripts/omw/third_person.lua".
Below is the code already edited, just replace all the code inside and save.

Code: Select all

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 MODE = camera.MODE
local STATE = { RightShoulder = 0, LeftShoulder = 1, Combat = 2, Swimming = 3 }

local M = {
    baseDistance = settings._getFloatFromSettingsCfg('Camera', 'third person camera distance'),
    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 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 combatOffset = util.vector2(0, 15)

local state = defaultShoulder

local rayOptions = {collisionType = nearby.COLLISION_TYPE.Default - nearby.COLLISION_TYPE.Actor}
local function ray(from, angle, limit)
    local to = from + util.transform.rotateZ(angle) * util.vector3(0, limit, 0)
    local res = nearby.castRay(from, to, rayOptions)
    if res.hit then
        return (res.hitPos - from):length()
    else
        return limit
    end
end

local function trySwitchShoulder()
    local limitToSwitch = 120  -- switch to other shoulder if wall is closer than this limit
    local limitToSwitchBack = 300  -- switch back to default shoulder if there is no walls at this distance

    local pos = camera.getTrackedPosition()
    local rayRight = ray(pos, camera.getYaw() + math.rad(90), limitToSwitchBack + 1)
    local rayLeft = ray(pos, camera.getYaw() - math.rad(90), limitToSwitchBack + 1)
    local rayRightForward = ray(pos, camera.getYaw() + math.rad(30), limitToSwitchBack + 1)
    local rayLeftForward = ray(pos, camera.getYaw() - math.rad(30), limitToSwitchBack + 1)

    local distRight = math.min(rayRight, rayRightForward)
    local distLeft = math.min(rayLeft, rayLeftForward)

    if distLeft < limitToSwitch and distRight > limitToSwitchBack then
        state = STATE.RightShoulder
    elseif distRight < limitToSwitch and distLeft > limitToSwitchBack then
        state = STATE.LeftShoulder
    elseif distRight > limitToSwitchBack and distLeft > limitToSwitchBack then
        state = defaultShoulder
    end
end

local function calculateDistance(smoothedSpeed)
    local smoothedSpeedSqr = smoothedSpeed * smoothedSpeed
    return (M.baseDistance + math.max(camera.getPitch(), 0) * 50
            + smoothedSpeedSqr / (smoothedSpeedSqr + 300*300) * zoomOutWhenMoveCoef)
end

local noThirdPersonLastFrame = true

local function updateState()
    local mode = camera.getMode()
    local oldState = state
    -- if (self:isInWeaponStance() or self:isInMagicStance()) and mode == MODE.ThirdPerson then
        -- state = STATE.Combat
    -- else
    if self:isSwimming() then
        state = STATE.Swimming
    elseif oldState == STATE.Swimming then
    -- elseif oldState == STATE.Combat or oldState == STATE.Swimming then
        state = defaultShoulder
    end
    if autoSwitchShoulder and (mode == MODE.ThirdPerson or state ~= oldState or noThirdPersonLastFrame)
       and (state == STATE.LeftShoulder or state == STATE.RightShoulder) then
        trySwitchShoulder()
    end
    if oldState ~= state or noThirdPersonLastFrame then
        -- State was changed, start focal point transition.
        if mode == MODE.Vanity then
            -- Player doesn't touch controls for a long time. Transition should be very slow.
            camera.setFocalTransitionSpeed(0.2)
        -- elseif (oldState == STATE.Combat or state == STATE.Combat) and
            --    (mode ~= MODE.Preview or M.standingPreview) then
            -- Transition to/from combat mode and we are not in preview mode. Should be fast.
            -- camera.setFocalTransitionSpeed(5.0)
        else
            camera.setFocalTransitionSpeed(1.0)  -- Default transition speed.
        end

        if state == STATE.RightShoulder then
            camera.setFocalPreferredOffset(rightShoulderOffset)
        elseif state == STATE.LeftShoulder then
            camera.setFocalPreferredOffset(leftShoulderOffset)
        else
            camera.setFocalPreferredOffset(combatOffset)
        end
    end
end

function M.update(dt, smoothedSpeed)
    local mode = camera.getMode()
    if mode == MODE.FirstPerson or mode == MODE.Static then
        noThirdPersonLastFrame = true
        return
    end
    if not viewOverShoulder then
        M.preferredDistance = M.baseDistance
        camera.setPreferredThirdPersonDistance(M.baseDistance)
        noThirdPersonLastFrame = false
        return
    end

    if M.noOffsetControl == 0 then
        updateState()
    else
        state = nil
    end

    M.preferredDistance = calculateDistance(smoothedSpeed)
    if noThirdPersonLastFrame then  -- just switched to third person view
        camera.setPreferredThirdPersonDistance(M.preferredDistance)
        camera.instantTransition()
        noThirdPersonLastFrame = false
    else
        local maxIncrease = dt * (100 + M.baseDistance)
        camera.setPreferredThirdPersonDistance(math.min(
            M.preferredDistance, camera.getThirdPersonDistance() + maxIncrease))
    end
end

return M
Post Reply