Merge branch 'eventful' into 'master'

[Lua] Some event handlers.

See merge request OpenMW/openmw!4738
This commit is contained in:
Alexei Kotov 2025-07-06 22:20:27 +03:00
commit eb9096baf4
7 changed files with 150 additions and 1 deletions

View File

@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 50)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_LUA_API_REVISION 79)
set(OPENMW_LUA_API_REVISION 80)
set(OPENMW_POSTPROCESSING_API_REVISION 3)
set(OPENMW_VERSION_COMMITHASH "")

View File

@ -41,9 +41,53 @@ Example:
core.sendGlobalEvent('UseItem', {object = potion, actor = player, force = true})
**ModifyStat**
Modify the corresponding stat.
.. code-block:: Lua
-- Consume 10 magicka
actor:sendEvent('ModifyStat', {name = 'magicka', amount = -10})
**AddVfx**
Calls the corresponding method in openmw.animation
.. code-block:: Lua
local eventParams = {
model = 'vfx_default',
options = {
textureOverride = effect.particle,
},
}
actor:sendEvent('AddVfx', eventParams)
**PlaySound3d**
Calls the corresponding function in openw.core on the target. Will use core.sound.playSoundFile3d instead of core.sound.playSound3d if you put `file` instead of `sound` in the event data.
.. code-block:: Lua
actor:sendEvent('PlaySound3d', {sound = 'Open Lock'})
**BreakInvisibility**
Forces the actor to lose all active invisibility effects.
UI events
---------
**ShowMessage**
If sent to a player, shows a message as if a call to ui.showMessage was made.
.. code-block:: Lua
player:sendEvent('ShowMessage', {message = 'Lorem ipsum'})
**UiModeChanged**
Every time UI mode is changed built-in scripts send to player the event ``UiModeChanged`` with arguments ``oldMode, ``newMode`` (same as ``I.UI.getMode()``)
@ -91,3 +135,36 @@ Global events that just call the corresponding function in `openmw.world`.
-- world.setSimulationTimeScale(scale)
core.sendGlobalEvent('SetSimulationTimeScale', scale)
**SpawnVfx, PlaySound3d**
Calls the corresponding function in openw.core. Note that PlaySound3d will call core.sound.playSoundFile3d instead of core.sound.playSound3d if you put `file` instead of `sound` in the event data.
.. code-block:: Lua
core.sendGlobalEvent('SpawnVfx', {position = hitPos, model = 'vfx_destructarea', options = {scale = 10}})
core.sendGlobalEvent('PlaySound3d', {sound = 'Open Lock', position = container.position})
**ConsumeItem**
Reduces stack size of an item by a given amount, removing the item completely if stack size is reduced to 0 or less.
.. code-block:: Lua
core.sendGlobalEvent('ConsumeItem', {item = foobar, amount = 1})
**Lock**
Lock a container or door
.. code-block:: Lua
core.sendGlobalEvent('Lock', {taret = selected, magnitude = 50})
**Unlock**
Unlock a container or door
.. code-block:: Lua
core.sendGlobalEvent('Unlock', {taret = selected})

View File

@ -91,7 +91,9 @@ set(BUILTIN_DATA_FILES
scripts/omw/console/local.lua
scripts/omw/console/player.lua
scripts/omw/console/menu.lua
scripts/omw/mechanics/actorcontroller.lua
scripts/omw/mechanics/animationcontroller.lua
scripts/omw/mechanics/globalcontroller.lua
scripts/omw/mechanics/playercontroller.lua
scripts/omw/settings/menu.lua
scripts/omw/music/actor.lua

View File

@ -23,6 +23,8 @@ PLAYER: scripts/omw/input/actionbindings.lua
PLAYER: scripts/omw/input/smoothmovement.lua
PLAYER: scripts/omw/input/gamepadcontrols.lua
NPC,CREATURE: scripts/omw/ai.lua
GLOBAL: scripts/omw/mechanics/globalcontroller.lua
CREATURE, NPC, PLAYER: scripts/omw/mechanics/actorcontroller.lua
# User interface
PLAYER: scripts/omw/ui.lua

View File

@ -0,0 +1,23 @@
local self = require('openmw.self')
local core = require('openmw.core')
local types = require('openmw.types')
local Actor = types.Actor
return {
eventHandlers = {
ModifyStat = function(data)
local stat = Actor.stats.dynamic[data.stat](self)
stat.current = stat.current + data.amount
end,
PlaySound3d = function(data)
if data.sound then
core.sound.playSound3d(data.sound, self, data.options)
else
core.sound.playSoundFile3d(data.file, self, data.options)
end
end,
BreakInvisibility = function(data)
Actor.activeEffects(self):remove(core.magic.EFFECT_TYPE.Invisibility)
end,
},
}

View File

@ -0,0 +1,39 @@
local types = require('openmw.types')
local Lockable = types.Lockable
local Item = require('openmw.types').Item
local world = require('openmw.world')
local core = require('openmw.core')
local function onConsumeItem(data)
local item = data.item
local amount = data.amount
if amount > item.count then
print('Warning: tried to consume '..tostring(amount)..' '..tostring(item)..'s, but there were only '..tostring(item.count))
amount = item.count
end
item:remove(amount)
end
local function onPlaySound3d(data)
if data.sound then
core.sound.playSound3d(data.sound, data.position, data.options)
elseif data.file then
core.sound.playSoundFile3d(data.file, data.position, data.options)
end
end
return {
eventHandlers = {
SpawnVfx = function(data)
world.vfx.spawn(data.model, data.position, data.options)
end,
PlaySound3d = onPlaySound3d,
ConsumeItem = onConsumeItem,
Lock = function(data)
Lockable.lock(data.target, data.magnitude)
end,
Unlock = function(data)
Lockable.unlock(data.target)
end,
},
}

View File

@ -111,4 +111,10 @@ return {
engineHandlers = {
onUpdate = onUpdate,
},
eventHandlers = {
ShowMessage = function(data)
if data.message then ui.showMessage(data.message) end
end
},
}