Skip to content

Commit

Permalink
Merge branch 'camera_script' into 'master'
Browse files Browse the repository at this point in the history
[Lua] Support tags in I.Camera.disable*, I.Camera.enable* in the same way as in world.pause

Closes #6652

See merge request OpenMW/openmw!3419
  • Loading branch information
psi29a committed Oct 5, 2023
2 parents d9f8757 + 54cc1f2 commit 68684d3
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 49 deletions.
128 changes: 83 additions & 45 deletions files/data/scripts/omw/camera/camera.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ end

local primaryMode

local noModeControl = 0
local noStandingPreview = 0
local noHeadBobbing = 0
local noZoom = 0
local noModeControl = {}
local noStandingPreview = {}
local noHeadBobbing = {}
local noZoom = {}

local function init()
camera.setFieldOfView(camera.getBaseFieldOfView())
Expand Down Expand Up @@ -117,19 +117,19 @@ local maxDistance = 800
local function zoom(delta)
if not input.getControlSwitch(input.CONTROL_SWITCH.ViewMode) or
not input.getControlSwitch(input.CONTROL_SWITCH.Controls) or
camera.getMode() == MODE.Static or noZoom > 0 then
camera.getMode() == MODE.Static or next(noZoom) then
return
end
if camera.getMode() ~= MODE.FirstPerson then
local obstacleDelta = third_person.preferredDistance - camera.getThirdPersonDistance()
if delta > 0 and third_person.baseDistance == minDistance and
(camera.getMode() ~= MODE.Preview or third_person.standingPreview) and noModeControl == 0 then
(camera.getMode() ~= MODE.Preview or third_person.standingPreview) and not next(noModeControl) then
primaryMode = MODE.FirstPerson
camera.setMode(primaryMode)
elseif delta > 0 or obstacleDelta < -delta then
third_person.baseDistance = util.clamp(third_person.baseDistance - delta - obstacleDelta, minDistance, maxDistance)
end
elseif delta < 0 and noModeControl == 0 then
elseif delta < 0 and not next(noModeControl) then
primaryMode = MODE.ThirdPerson
camera.setMode(primaryMode)
third_person.baseDistance = minDistance
Expand All @@ -149,7 +149,7 @@ end

local function updateStandingPreview()
local mode = camera.getMode()
if not previewIfStandStill or noStandingPreview > 0
if not previewIfStandStill or next(noStandingPreview)
or mode == MODE.FirstPerson or mode == MODE.Static or mode == MODE.Vanity then
third_person.standingPreview = false
return
Expand Down Expand Up @@ -197,7 +197,7 @@ local function onFrame(dt)
primaryMode = mode
end
if mode ~= MODE.Static then
if noModeControl == 0 then
if not next(noModeControl) then
updatePOV(dt)
updateVanity(dt)
end
Expand All @@ -206,7 +206,7 @@ local function onFrame(dt)
end
applyControllerZoom(dt)
third_person.update(dt, smoothedSpeed)
if noHeadBobbing == 0 then head_bobbing.update(dt, smoothedSpeed) end
if not next(noHeadBobbing) then head_bobbing.update(dt, smoothedSpeed) end
if slowViewChange then
local maxIncrease = dt * (100 + third_person.baseDistance)
camera.setPreferredThirdPersonDistance(
Expand All @@ -221,54 +221,92 @@ return {
-- @module Camera
-- @usage require('openmw.interfaces').Camera
interface = {
--- Interface version
--- Interface version is 1
-- @field [parent=#Camera] #number version
version = 0,
version = 1,

--- Return primary mode (MODE.FirstPerson or MODE.ThirdPerson).
-- @function [parent=#Camera] getPrimaryMode
-- @return #number @{openmw.camera#MODE}
getPrimaryMode = function() return primaryMode end,
--- @function [parent=#Camera] getBaseThirdPersonDistance

--- Get base third person distance (without applying angle and speed modifiers).
-- @function [parent=#Camera] getBaseThirdPersonDistance
-- @return #number
getBaseThirdPersonDistance = function() return third_person.baseDistance end,
--- @function [parent=#Camera] setBaseThirdPersonDistance
--- Set base third person distance
-- @function [parent=#Camera] setBaseThirdPersonDistance
-- @param #number value
setBaseThirdPersonDistance = function(v) third_person.baseDistance = v end,
--- @function [parent=#Camera] getTargetThirdPersonDistance
--- Get the desired third person distance if there would be no obstacles (with angle and speed modifiers)
-- @function [parent=#Camera] getTargetThirdPersonDistance
-- @return #number
getTargetThirdPersonDistance = function() return third_person.preferredDistance end,

--- @function [parent=#Camera] isModeControlEnabled
isModeControlEnabled = function() return noModeControl == 0 end,
--- @function [parent=#Camera] disableModeControl
disableModeControl = function() noModeControl = noModeControl + 1 end,
--- @function [parent=#Camera] enableModeControl
enableModeControl = function() noModeControl = math.max(0, noModeControl - 1) end,
--- Whether the built-in mode control logic is enabled.
-- @function [parent=#Camera] isModeControlEnabled
-- @return #boolean
isModeControlEnabled = function() return not next(noModeControl) end,
--- Disable with (optional) tag until the corresponding enable function is called with the same tag.
-- @function [parent=#Camera] disableModeControl
-- @param #string tag (optional, empty string by default) Will be disabled until the enabling function is called with the same tag
disableModeControl = function(tag) noModeControl[tag or ''] = true end,
--- Undo disableModeControl
-- @function [parent=#Camera] enableModeControl
-- @param #string tag (optional, empty string by default)
enableModeControl = function(tag) noModeControl[tag or ''] = nil end,

--- @function [parent=#Camera] isStandingPreviewEnabled
isStandingPreviewEnabled = function() return previewIfStandStill and noStandingPreview == 0 end,
--- @function [parent=#Camera] disableStandingPreview
disableStandingPreview = function() noStandingPreview = noStandingPreview + 1 end,
--- @function [parent=#Camera] enableStandingPreview
enableStandingPreview = function() noStandingPreview = math.max(0, noStandingPreview - 1) end,
--- Whether the built-in standing preview logic is enabled.
-- @function [parent=#Camera] isStandingPreviewEnabled
-- @return #boolean
isStandingPreviewEnabled = function() return previewIfStandStill and not next(noStandingPreview) end,
--- Disable with (optional) tag until the corresponding enable function is called with the same tag.
-- @function [parent=#Camera] disableStandingPreview
-- @param #string tag (optional, empty string by default) Will be disabled until the enabling function is called with the same tag
disableStandingPreview = function(tag) noStandingPreview[tag or ''] = true end,
--- Undo disableStandingPreview
-- @function [parent=#Camera] enableStandingPreview
-- @param #string tag (optional, empty string by default)
enableStandingPreview = function(tag) noStandingPreview[tag or ''] = nil end,

--- @function [parent=#Camera] isHeadBobbingEnabled
isHeadBobbingEnabled = function() return head_bobbing.enabled and noHeadBobbing == 0 end,
--- @function [parent=#Camera] disableHeadBobbing
disableHeadBobbing = function() noHeadBobbing = noHeadBobbing + 1 end,
--- @function [parent=#Camera] enableHeadBobbing
enableHeadBobbing = function() noHeadBobbing = math.max(0, noHeadBobbing - 1) end,
--- Whether head bobbing is enabled.
-- @function [parent=#Camera] isHeadBobbingEnabled
-- @return #boolean
isHeadBobbingEnabled = function() return head_bobbing.enabled and not next(noHeadBobbing) end,
--- Disable with (optional) tag until the corresponding enable function is called with the same tag.
-- @function [parent=#Camera] disableHeadBobbing
-- @param #string tag (optional, empty string by default) Will be disabled until the enabling function is called with the same tag
disableHeadBobbing = function(tag) noHeadBobbing[tag or ''] = true end,
--- Undo disableHeadBobbing
-- @function [parent=#Camera] enableHeadBobbing
-- @param #string tag (optional, empty string by default)
enableHeadBobbing = function(tag) noHeadBobbing[tag or ''] = nil end,

--- @function [parent=#Camera] isZoomEnabled
isZoomEnabled = function() return noZoom == 0 end,
--- @function [parent=#Camera] disableZoom
disableZoom = function() noZoom = noZoom + 1 end,
--- @function [parent=#Camera] enableZoom
enableZoom = function() noZoom = math.max(0, noZoom - 1) end,
--- Whether the built-in zooming is enabled.
-- @function [parent=#Camera] isZoomEnabled
-- @return #boolean
isZoomEnabled = function() return not next(noZoom) end,
--- Disable with (optional) tag until the corresponding enable function is called with the same tag.
-- @function [parent=#Camera] disableZoom
-- @param #string tag (optional, empty string by default) Will be disabled until the enabling function is called with the same tag
disableZoom = function(tag) noZoom[tag or ''] = true end,
--- Undo disableZoom
-- @function [parent=#Camera] enableZoom
-- @param #string tag (optional, empty string by default)
enableZoom = function(tag) noZoom[tag or ''] = nil end,

--- @function [parent=#Camera] isThirdPersonOffsetControlEnabled
isThirdPersonOffsetControlEnabled = function() return third_person.noOffsetControl == 0 end,
--- @function [parent=#Camera] disableThirdPersonOffsetControl
disableThirdPersonOffsetControl = function() third_person.noOffsetControl = third_person.noOffsetControl + 1 end,
--- @function [parent=#Camera] enableThirdPersonOffsetControl
enableThirdPersonOffsetControl = function() third_person.noOffsetControl = math.max(0, third_person.noOffsetControl - 1) end,
--- Whether the the third person offset can be changed by the built-in camera script.
-- @function [parent=#Camera] isThirdPersonOffsetControlEnabled
-- @return #boolean
isThirdPersonOffsetControlEnabled = function() return not next(third_person.noOffsetControl) end,
--- Disable with (optional) tag until the corresponding enable function is called with the same tag.
-- @function [parent=#Camera] disableThirdPersonOffsetControl
-- @param #string tag (optional, empty string by default) Will be disabled until the enabling function is called with the same tag
disableThirdPersonOffsetControl = function(tag) third_person.noOffsetControl[tag or ''] = true end,
--- Undo disableThirdPersonOffsetControl
-- @function [parent=#Camera] enableThirdPersonOffsetControl
-- @param #string tag (optional, empty string by default)
enableThirdPersonOffsetControl = function(tag) third_person.noOffsetControl[tag or ''] = nil end,
},
engineHandlers = {
onUpdate = onUpdate,
Expand Down
4 changes: 2 additions & 2 deletions files/data/scripts/omw/camera/third_person.lua
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ local M = {
baseDistance = 192,
preferredDistance = 0,
standingPreview = false,
noOffsetControl = 0,
noOffsetControl = {},
}

local viewOverShoulder, autoSwitchShoulder
Expand Down Expand Up @@ -142,7 +142,7 @@ function M.update(dt, smoothedSpeed)
return
end

if M.noOffsetControl == 0 then
if not next(M.noOffsetControl) then
updateState()
else
state = nil
Expand Down
4 changes: 2 additions & 2 deletions files/lua_api/openmw/world.lua
Original file line number Diff line number Diff line change
Expand Up @@ -109,12 +109,12 @@
---
-- Pause the game starting from the next frame.
-- @function [parent=#world] pause
-- @param #string tag (optional) The game will be paused until `unpause` is called with the same tag.
-- @param #string tag (optional, empty string by default) The game will be paused until `unpause` is called with the same tag.

---
-- Remove given tag from the list of pause tags. Resume the game starting from the next frame if the list became empty.
-- @function [parent=#world] unpause
-- @param #string tag (optional) Needed to undo `pause` called with this tag.
-- @param #string tag (optional, empty string by default) Needed to undo `pause` called with this tag.

---
-- The tags that are currently pausing the game.
Expand Down

0 comments on commit 68684d3

Please sign in to comment.