mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-22 12:53:52 +00:00
150 lines
No EOL
4.1 KiB
Lua
150 lines
No EOL
4.1 KiB
Lua
local prequire = function(path)
|
|
local status, result = pcall(function()
|
|
return require(path)
|
|
end)
|
|
return status and result or nil
|
|
end
|
|
|
|
local core = require('openmw.core')
|
|
local types = require('openmw.types')
|
|
local storage = require('openmw.storage')
|
|
local self = prequire('openmw.self')
|
|
local world = prequire('openmw.world')
|
|
|
|
local isPlayerScript = self and true or false
|
|
local isGlobalScript = world and true or false
|
|
|
|
local EVENTS = {
|
|
SettingChanged = 'omwSettingsChanged',
|
|
SettingSet = 'omwSettingsGlobalSet',
|
|
GroupRegistered = 'omwSettingsGroupRegistered',
|
|
}
|
|
|
|
local SCOPE = {
|
|
Global = 'Global',
|
|
Player = 'Player',
|
|
SaveGlobal = 'SaveGlobal',
|
|
SavePlayer = 'SavePlayer',
|
|
}
|
|
|
|
local groups = storage.globalSection('OMW_Settings_Groups')
|
|
local saveGlobalSection = storage.globalSection('OMW_Settings_SaveGlobal')
|
|
|
|
if isGlobalScript then
|
|
groups:removeOnExit()
|
|
saveGlobalSection:removeOnExit()
|
|
end
|
|
|
|
local savePlayerSection = nil
|
|
if isPlayerScript then
|
|
savePlayerSection = storage.playerSection('OMW_Setting_SavePlayer')
|
|
savePlayerSection:removeOnExit()
|
|
end
|
|
|
|
local scopes = {
|
|
[SCOPE.Global] = storage.globalSection('OMW_Setting_Global'),
|
|
[SCOPE.Player] = isPlayerScript and storage.playerSection('OMW_Setting_Player'),
|
|
[SCOPE.SaveGlobal] = saveGlobalSection,
|
|
[SCOPE.SavePlayer] = savePlayerSection,
|
|
}
|
|
|
|
local function isGlobalScope(scope)
|
|
return scope == SCOPE.Global or scope == SCOPE.SaveGlobal
|
|
end
|
|
|
|
local function getSetting(groupKey, settingKey)
|
|
local group = groups:get(groupKey)
|
|
if not group then
|
|
error('Unknown group')
|
|
end
|
|
local setting = group[settingKey]
|
|
if not setting then
|
|
error('Unknown setting')
|
|
end
|
|
return setting
|
|
end
|
|
|
|
local function getSettingValue(groupKey, settingKey)
|
|
local setting = getSetting(groupKey, settingKey)
|
|
local scopeSection = scopes[setting.scope]
|
|
if not scopeSection then
|
|
error(('Setting %s is not available in this context'):format(setting.key))
|
|
end
|
|
if not scopeSection:get(groupKey) then
|
|
scopeSection:set(groupKey, {})
|
|
end
|
|
return scopeSection:get(groupKey)[setting.key] or setting.default
|
|
end
|
|
|
|
local function notifySettingChange(scope, event)
|
|
if isGlobalScope(scope) then
|
|
core.sendGlobalEvent(EVENTS.SettingChanged, event)
|
|
for _, a in ipairs(world.activeActors) do
|
|
if a.type == types.Player then
|
|
a:sendEvent(EVENTS.SettingChanged, event)
|
|
end
|
|
end
|
|
else
|
|
self:sendEvent(EVENTS.SettingChanged, event)
|
|
end
|
|
end
|
|
|
|
local function setSettingValue(groupKey, settingKey, value)
|
|
local setting = getSetting(groupKey, settingKey)
|
|
local event = {
|
|
groupName = groupKey,
|
|
settingName = setting.key,
|
|
value = value,
|
|
}
|
|
if isPlayerScript and isGlobalScope(setting.scope) then
|
|
core.sendGlobalEvent(EVENTS.SettingSet, event)
|
|
return
|
|
end
|
|
|
|
local scopeSection = scopes[setting.scope]
|
|
if not scopeSection:get(groupKey) then
|
|
scopeSection:set(groupKey, {})
|
|
end
|
|
local copy = scopeSection:getCopy(groupKey)
|
|
copy[setting.key] = value
|
|
scopeSection:set(groupKey, copy)
|
|
|
|
notifySettingChange(setting.scope, event)
|
|
end
|
|
|
|
local groupMeta = {
|
|
__index = {
|
|
get = function(self, settingKey)
|
|
return getSettingValue(self.key, settingKey)
|
|
end,
|
|
set = function(self, settingKey, value)
|
|
setSettingValue(self.key, settingKey, value)
|
|
end,
|
|
onChange = function(self, callback)
|
|
table.insert(self.__callbacks, callback)
|
|
end,
|
|
__changed = function(self, settingKey, value)
|
|
for _, callback in ipairs(self.__callbacks) do
|
|
callback(settingKey, value)
|
|
end
|
|
end,
|
|
},
|
|
}
|
|
local cachedGroups = {}
|
|
local function getGroup(groupKey)
|
|
if not cachedGroups[groupKey] then
|
|
cachedGroups[groupKey] = setmetatable({
|
|
key = groupKey,
|
|
__callbacks = {},
|
|
}, groupMeta)
|
|
end
|
|
return cachedGroups[groupKey]
|
|
end
|
|
|
|
return {
|
|
EVENTS = EVENTS,
|
|
SCOPE = SCOPE,
|
|
scopes = scopes,
|
|
groups = groups,
|
|
getGroup = getGroup,
|
|
} |