summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Mikheev <ptmikheev@gmail.com>2022-01-10 21:04:07 +0100
committerPetr Mikheev <ptmikheev@gmail.com>2022-01-10 21:04:07 +0100
commit9fd7630ca056ea122184d395482210b52832d610 (patch)
tree0e045be13a6017de33fd3613ba728c1f97b844ab
parent2d1b1002397f7e7394b18d9e35a658e2f5bcb4ee (diff)
Add calendar.lua
-rw-r--r--docs/source/reference/lua-scripting/api.rst3
-rw-r--r--docs/source/reference/lua-scripting/openmw_aux_calendar.rst5
-rw-r--r--docs/source/reference/lua-scripting/overview.rst6
-rw-r--r--files/builtin_scripts/CMakeLists.txt8
-rw-r--r--files/builtin_scripts/i18n/Calendar/en.lua42
-rw-r--r--files/builtin_scripts/openmw_aux/calendar.lua159
-rw-r--r--files/builtin_scripts/scripts/omw/camera.lua6
7 files changed, 224 insertions, 5 deletions
diff --git a/docs/source/reference/lua-scripting/api.rst b/docs/source/reference/lua-scripting/api.rst
index 635fcfb95e..d6e85389b8 100644
--- a/docs/source/reference/lua-scripting/api.rst
+++ b/docs/source/reference/lua-scripting/api.rst
@@ -18,6 +18,7 @@ Lua API reference
openmw_input
openmw_ui
openmw_camera
+ openmw_aux_calendar
openmw_aux_util
openmw_aux_time
interface_camera
@@ -74,6 +75,8 @@ Sources can be found in ``resources/vfs/openmw_aux``. In theory mods can overrid
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+
| Built-in library | Can be used | Description |
+=========================================================+====================+===============================================================+
+|:ref:`openmw_aux.calendar <Package openmw_aux.calendar>` | everywhere | | Game time calendar |
++---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw_aux.util <Package openmw_aux.util>` | everywhere | | Miscellaneous utils |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw_aux.time <Package openmw_aux.time>` | everywhere | | Timers and game time utils |
diff --git a/docs/source/reference/lua-scripting/openmw_aux_calendar.rst b/docs/source/reference/lua-scripting/openmw_aux_calendar.rst
new file mode 100644
index 0000000000..ea60b62852
--- /dev/null
+++ b/docs/source/reference/lua-scripting/openmw_aux_calendar.rst
@@ -0,0 +1,5 @@
+Package openmw_aux.calendar
+===========================
+
+.. raw:: html
+ :file: generated_html/openmw_aux_calendar.html
diff --git a/docs/source/reference/lua-scripting/overview.rst b/docs/source/reference/lua-scripting/overview.rst
index 103a93c559..eab3fc962a 100644
--- a/docs/source/reference/lua-scripting/overview.rst
+++ b/docs/source/reference/lua-scripting/overview.rst
@@ -365,6 +365,8 @@ Sources can be found in ``resources/vfs/openmw_aux``. In theory mods can overrid
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+
| Built-in library | Can be used | Description |
+=========================================================+====================+===============================================================+
+|:ref:`openmw_aux.calendar <Package openmw_aux.calendar>` | everywhere | | Game time calendar |
++---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw_aux.util <Package openmw_aux.util>` | everywhere | | Miscellaneous utils |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw_aux.time <Package openmw_aux.time>` | everywhere | | Timers and game time utils |
@@ -374,8 +376,8 @@ They can be loaded with ``require`` the same as API packages. For example:
.. code-block:: Lua
- local aux_util = require('openmw_aux.util')
- aux_util.runEveryNSeconds(15, doSomething) -- run `doSomething()` every 15 seconds
+ local time = require('openmw_aux.time')
+ time.runRepeatedly(doSomething, 15 * time.second) -- run `doSomething()` every 15 seconds
Script interfaces
diff --git a/files/builtin_scripts/CMakeLists.txt b/files/builtin_scripts/CMakeLists.txt
index 6f290cc1f7..1ef67a2e15 100644
--- a/files/builtin_scripts/CMakeLists.txt
+++ b/files/builtin_scripts/CMakeLists.txt
@@ -7,8 +7,14 @@ set(SDIR ${CMAKE_CURRENT_SOURCE_DIR})
set(DDIRRELATIVE resources/vfs)
copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_RESOURCES_ROOT} ${DDIRRELATIVE} "builtin.omwscripts")
+set(LUA_AUX_FILES
+ openmw_aux/util.lua
+ openmw_aux/time.lua
+ openmw_aux/calendar.lua
+)
+
set(DDIRRELATIVE resources/vfs/openmw_aux)
-copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_RESOURCES_ROOT} ${DDIRRELATIVE} "openmw_aux/util.lua")
+copy_all_resource_files(${CMAKE_CURRENT_SOURCE_DIR} ${OPENMW_RESOURCES_ROOT} ${DDIRRELATIVE} "${LUA_AUX_FILES}")
set(LUA_SCRIPTS_FILES
scripts/omw/camera.lua
diff --git a/files/builtin_scripts/i18n/Calendar/en.lua b/files/builtin_scripts/i18n/Calendar/en.lua
new file mode 100644
index 0000000000..a4e8183a92
--- /dev/null
+++ b/files/builtin_scripts/i18n/Calendar/en.lua
@@ -0,0 +1,42 @@
+-- source: https://en.uesp.net/wiki/Lore:Calendar
+
+return {
+ month1 = "Morning Star",
+ month2 = "Sun's Dawn",
+ month3 = "First Seed",
+ month4 = "Rain's Hand",
+ month5 = "Second Seed",
+ month6 = "Midyear",
+ month7 = "Sun's Height",
+ month8 = "Last Seed",
+ month9 = "Hearthfire",
+ month10 = "Frostfall",
+ month11 = "Sun's Dusk",
+ month12 = "Evening Star",
+
+ -- The variant of month names in the context "day X of month Y".
+ -- In English it is the same, but some languages require a different form.
+ monthInGenitive1 = "Morning Star",
+ monthInGenitive2 = "Sun's Dawn",
+ monthInGenitive3 = "First Seed",
+ monthInGenitive4 = "Rain's Hand",
+ monthInGenitive5 = "Second Seed",
+ monthInGenitive6 = "Midyear",
+ monthInGenitive7 = "Sun's Height",
+ monthInGenitive8 = "Last Seed",
+ monthInGenitive9 = "Hearthfire",
+ monthInGenitive10 = "Frostfall",
+ monthInGenitive11 = "Sun's Dusk",
+ monthInGenitive12 = "Evening Star",
+
+ dateFormat = "day %{day} of %{monthInGenitive} %{year}",
+
+ weekday1 = "Sundas",
+ weekday2 = "Morndas",
+ weekday3 = "Tirdas",
+ weekday4 = "Middas",
+ weekday5 = "Turdas",
+ weekday6 = "Fredas",
+ weekday7 = "Loredas",
+}
+
diff --git a/files/builtin_scripts/openmw_aux/calendar.lua b/files/builtin_scripts/openmw_aux/calendar.lua
new file mode 100644
index 0000000000..58e7298f1d
--- /dev/null
+++ b/files/builtin_scripts/openmw_aux/calendar.lua
@@ -0,0 +1,159 @@
+---
+-- `openmw_aux.calendar` defines utility functions for formatting game time.
+-- Implementation can be found in `resources/vfs/openmw_aux/calendar.lua`.
+-- @module calendar
+-- @usage local calendar = require('openmw_aux.calendar')
+
+local core = require('openmw.core')
+local time = require('openmw_aux.time')
+local i18n = core.i18n('Calendar')
+
+local monthsDuration = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+local daysInWeek = 7
+local daysInYear = 0
+for _, d in ipairs(monthsDuration) do daysInYear = daysInYear + d end
+
+local startingYear = 427
+local startingYearDay = 227
+local startingWeekDay = 1
+
+local function gameTime(t)
+ if not t then
+ return core.getGameTime()
+ else
+ local days = (t.year or 0) * daysInYear + (t.day or 0)
+ for i = 1, (t.month or 1)-1 do
+ days = days + monthsDuration[i]
+ end
+ return days * time.day + (t.hour or 0) * time.hour +
+ (t.min or 0) * time.minute + (t.sec or 0) * time.second
+ end
+end
+
+local function defaultDateFormat(t)
+ return i18n('dateFormat', {
+ day = t.day,
+ month = i18n('month' .. t.month),
+ monthInGenitive = i18n('monthInGenitive' .. t.month),
+ year = t.year,
+ })
+end
+
+local function formatGameTime(formatStr, timestamp)
+ timestamp = timestamp or core.getGameTime()
+
+ local t = {}
+ local day = math.floor(timestamp / time.day)
+ t.year = math.floor(day / daysInYear) + startingYear
+ t.yday = (day + startingYearDay - 1) % daysInYear + 1
+ t.wday = (day + startingWeekDay - 1) % daysInWeek + 1
+ timestamp = timestamp % time.day
+ t.hour = math.floor(timestamp / time.hour)
+ timestamp = timestamp % time.hour
+ t.min = math.floor(timestamp / time.minute)
+ t.sec = math.floor(timestamp) % time.minute
+
+ t.day = t.yday
+ t.month = 1
+ while t.day > monthsDuration[t.month] do
+ t.day = t.day - monthsDuration[t.month]
+ t.month = t.month + 1
+ end
+
+ if formatStr == '*t' then return t end
+
+ local replFn = function(tag)
+ if tag == '%a' or tag == '%A' then return i18n('weekday' .. t.wday) end
+ if tag == '%b' or tag == '%B' then return i18n('monthInGenitive' .. t.month) end
+ if tag == '%c' then
+ return string.format('%02d:%02d %s', t.hour, t.min, defaultDateFormat(t))
+ end
+ if tag == '%d' then return string.format('%02d', t.day) end
+ if tag == '%e' then return string.format('%2d', t.day) end
+ if tag == '%H' then return string.format('%02d', t.hour) end
+ if tag == '%I' then return string.format('%02d', (t.hour - 1) % 12 + 1) end
+ if tag == '%M' then return string.format('%02d', t.min) end
+ if tag == '%m' then return string.format('%02d', t.month) end
+ if tag == '%p' then
+ if t.hour > 0 and t.hour <= 12 then
+ return 'am'
+ else
+ return 'pm'
+ end
+ end
+ if tag == '%S' then return string.format('%02d', t.sec) end
+ if tag == '%w' then return t.wday - 1 end
+ if tag == '%x' then return defaultDateFormat(t) end
+ if tag == '%X' then return string.format('%02d:%02d', t.hour, t.min) end
+ if tag == '%Y' then return t.year end
+ if tag == '%y' then return string.format('%02d', t.year % 100) end
+ if tag == '%%' then return '%' end
+ error('Unknown tag "'..tag..'"')
+ end
+
+ res, _ = string.gsub(formatStr or '%c', '%%.', replFn)
+ return res
+end
+
+return {
+ --- An equivalent of `os.time` for game time.
+ -- See [https://www.lua.org/pil/22.1.html](https://www.lua.org/pil/22.1.html)
+ -- @function [parent=#calendar] gameTime
+ -- @param #table table a table which describes a date (optional).
+ -- @return #number a timestamp.
+ gameTime = gameTime,
+
+ --- An equivalent of `os.date` for game time.
+ -- See [https://www.lua.org/pil/22.1.html](https://www.lua.org/pil/22.1.html).
+ -- It is a slow function. Please try not to use it in every frame.
+ -- @function [parent=#calendar] formatGameTime
+ -- @param #string format format of date (optional)
+ -- @param #number time time to format (default value is current time)
+ -- @return #string a formatted string representation of `time`.
+ formatGameTime = formatGameTime,
+
+ --- The number of months in a year
+ -- @field [parent=#calendar] #number monthCount
+ monthCount = #monthsDuration,
+
+ --- The number of days in a year
+ -- @field [parent=#calendar] #number daysInYear
+ daysInYear = daysInYear,
+
+ --- The number of days in a week
+ -- @field [parent=#calendar] #number daysInWeek
+ daysInWeek = daysInWeek,
+
+ --- The number of days in a month
+ -- @function [parent=#calendar] daysInMonth
+ -- @param monthIndex
+ -- @return #number
+ daysInMonth = function(m)
+ return monthsDuration[(m-1) % #monthsDuration + 1]
+ end,
+
+ --- The name of a month
+ -- @function [parent=#calendar] monthName
+ -- @param monthIndex
+ -- @return #string
+ monthName = function(m)
+ return i18n('month' .. ((m-1) % #monthsDuration + 1))
+ end,
+
+ --- The name of a month in genitive (for English is the same as `monthName`, but in some languages the form can differ).
+ -- @function [parent=#calendar] monthNameInGenitive
+ -- @param monthIndex
+ -- @return #string
+ monthNameInGenitive = function(m)
+ return i18n('monthInGenitive' .. ((m-1) % #monthsDuration + 1))
+ end,
+
+ --- The name of a weekday
+ -- @function [parent=#calendar] weekdayName
+ -- @param dayIndex
+ -- @return #string
+ weekdayName = function(d)
+ return i18n('weekday' .. ((d-1) % daysInWeek + 1))
+ end,
+}
+
diff --git a/files/builtin_scripts/scripts/omw/camera.lua b/files/builtin_scripts/scripts/omw/camera.lua
index 4025f7eee4..cd4d0dccfb 100644
--- a/files/builtin_scripts/scripts/omw/camera.lua
+++ b/files/builtin_scripts/scripts/omw/camera.lua
@@ -175,10 +175,12 @@ return {
--- @module Camera
-- @usage require('openmw.interfaces').Camera
interface = {
- --- @field [parent=#Camera] #number version Interface version
+ --- Interface version
+ -- @field [parent=#Camera] #number version
version = 0,
- --- @function [parent=#Camera] getPrimaryMode Returns primary mode (MODE.FirstPerson or MODE.ThirdPerson).
+ --- Return primary mode (MODE.FirstPerson or MODE.ThirdPerson).
+ -- @function [parent=#Camera] getPrimaryMode
getPrimaryMode = function() return primaryMode end,
--- @function [parent=#Camera] getBaseThirdPersonDistance
getBaseThirdPersonDistance = function() return third_person.baseDistance end,