315 lines
7.5 KiB
Lua

--[[ tModule is something like this
tModule = {
id = 'moduleID', -- Unique module identifier. (String) {IDs beginning with '__' are reserved}
title = 'Module Name', -- Title to show on toggle formspec. (String)
updateWhenHidden = false, -- run update() even if hidden (but main HUD is on)
value = '---', -- current/default valuestring to display if onUpdate is not a function. (String)
onClear = nil, -- function to clear/reset or nil. When set, adds a button
-- to formspec. This hook is called when button is pressed.
onDealoc = nil, -- function to run on shutdown or nil. E.g. to save data.
onHide = nil, -- function or nil. Called when module is deactivated in formspec
onInit = nil, -- function to run on startup or nil.
-- E.g. to read values from datastore.
-- Can be called multiple times per session.
-- Check tmi.modules[index].bInitDone field to detect repeated call
-- or manipulate it in another hook to request a re-init
onReveal = nil, -- function or nil. Called when module is activated in formspec
onUpdate = nil, -- function to, update and return value, Is called at interval
-- or nil --> value field is used
}) --]]
-- your module script needs to call this at load to register in the order
-- you want the info snippets to show up in
function tmi.addModule(tModule)
-- no id, no registration
if not tModule.id then return false end
-- already got a module with that id
if tmi.moduleLookup[tModule.id] then return false end
tModule.index = #tmi.modules + 1
tmi.modules[tModule.index] = tModule
tmi.moduleLookup[tModule.id] = tModule.index
return tModule.index
end -- addModule
function tmi.formInput(formname, fields)
if tmi.formname ~= formname then return false end
local index, m
for k, v in pairs(fields) do
index = tonumber(k)
if index then
tmi.toggleModule(index)
elseif 'b_' == k:sub(1, 2) then
-- a button was pressed
index = tonumber(k:sub(3, -1))
if index then
m = tmi.modules[index]
if m and 'function' == type(m.onClear) then
m.onClear(index)
end
end
elseif 'quit' == k then
--return true
else
print(dump(fields))
end
end -- loop all fields. With our formspec there should only be one
return true
end -- formInput
function tmi.formShow()
local iMax = #tmi.modules
if 0 == iMax then return end
local iX = .5
local iY = .25
local sOut = 'size[5,' .. tostring(iMax * .5 + 1.5) .. ']'
.. 'checkbox[' .. tostring(iX) .. ',' .. tostring(iY) .. ';'
.. '0;Main;' .. tostring(tmi.isOn('__tmi__')) .. ']'
local index, m
for index = 1, iMax do
iY = iY + .5
m = tmi.modules[index]
if 'function' == type(m.onClear) then
-- add clear button
sOut = sOut .. 'button[0,' .. tostring(iY) .. ';.5,1;'
.. 'b_' .. tostring(index) .. ';X]'
end
sOut = sOut .. 'checkbox[' .. tostring(iX) .. ',' .. tostring(iY) .. ';'
.. tostring(index) .. ';' .. m.title .. ';' .. tostring(tmi.isOn(m.id)) .. ']'
end -- loop modules
core.show_formspec(tmi.formname, sOut)
end -- formShow
function tmi.init()
-- don't do anything else if there is already a hud id stored
if tmi.hudID then return end
local bMain = tmi.isOn('__tmi__')
if bMain then
local tHud = {
hud_elem_type = 'text',
name = 'tmiHUD',
number = tmi.conf.colour,
position = { x = 0.002, y = 0.77 },
offset = { x = 8, y = -8 },
text = 'Too Much Info HUD',
scale = { x = 200, y = 60 },
alignment = { x = 1, y = -1 },
}
tmi.hudID = tmi.player:hud_add(tHud)
end
local iMax = #tmi.modules
if 0 == iMax then return end
local index, m
for index = 1, iMax do
m = tmi.modules[index]
if (not m.bInitDone) and ('function' == type(m.onInit)) then
m.onInit(index)
-- modules can change it to request another init when main is turned on
m.bInitDone = true
end
-- TODO: onReveal should be called here, no?
-- not always. If game is launched with TMI-HUD hidden then module isn't
-- being revealed
end -- loop modules
print('[TMI modules initialized]')
end -- init
-- query CSM-datastore for toggle setting of module
function tmi.isOn(id) return '' == tmi.store:get_string(id .. '_disabled') end -- isOn
-- clumsy name for a clumsy way of inserting grouping characters
function tmi.niceNaturalString(iN)
local sOut = tostring(iN)
if 3 < #sOut then
sOut = sOut:sub(1, -4) .. "'" .. sOut:sub(-3, -1)
end
if 7 < #sOut then
sOut = sOut:sub(1, -8) .. "'" .. sOut:sub(-7, -1)
end
if 11 < #sOut then
sOut = sOut:sub(1, -12) .. "'" .. sOut:sub(-11, -1)
end
return sOut
end -- niceNaturalString
function tmi.removeHUD()
-- no hud yet?
if not tmi.hudID then return end
tmi.player:hud_remove(tmi.hudID)
tmi.hudID = nil
end -- removeHUD
-- called when logging off
function tmi.shutdown()
local iMax = #tmi.modules
if 0 == iMax then return end
local index, m
for index = 1, iMax do
m = tmi.modules[index]
if 'function' == type(m.onDealoc) then m.onDealoc(index) end
end -- loop modules
print('[TMI shutdown]')
end -- shutdown
function tmi.startupLoop()
tmi.player = core.localplayer
if tmi.player then
core.after(1, tmi.init)
core.after(2, tmi.update)
else
core.after(1, tmi.startupLoop)
end
end -- startupLoop
-- to toggle visibility of a module by index
function tmi.toggleModule(index)
local id, m
-- main switch is inexistant index 0
local bIsMain = 0 == index
if bIsMain then
id = '__tmi__'
-- kinda check if index could be out of range
--elseif #tmi.modules < index then
-- return
-- better check that also checks if an id is actually set
elseif tmi.modules[index] and tmi.modules[index].id then
m = tmi.modules[index]
id = m.id
else
-- abbort
return
end
-- get new value by inverting current value
local bIsTurningOn = not tmi.isOn(id)
local sNew = bIsTurningOn and '' or '-'
tmi.store:set_string(id .. '_disabled', sNew)
-- if m then
if not bIsMain then
if bIsTurningOn then
if 'function' == type(m.onReveal) then
m.onReveal(index)
end
else
if 'function' == type(m.onHide) then
m.onHide(index)
end
end
return
end -- if a submodule was toggled
-- main module toggeled, need to destroy or remake HUD
-- turn on?
if bIsTurningOn then
-- some modules might get init() called
tmi.update()
end
-- call module hooks for reveal and hide
-- we recycle index variable as we know it is 0 and don't need it anymore
for index = 1, #tmi.modules do
m = tmi.modules[index]
if bIsTurningOn then
if 'function' == type(m.onReveal) then
m.onReveal(index)
end
else
if 'function' == type(m.onHide) then
m.onHide(index)
end
end -- if turning on or off
end -- loop all modules
-- turnig off, need to remove HUD
if not bIsTurningOn then
tmi.removeHUD()
end
end -- toggleModule
function tmi.twoDigitNumberString(iN) return string.format('%02i', iN) end -- twoDigitNumberString
function tmi.update()
local bMain = tmi.isOn('__tmi__')
core.after(tmi.conf.interval, tmi.update)
-- if main switch is on but no HUD-ID, then we need to init HUD and
-- possibly re-run module's init-hook
if bMain and not tmi.hudID then return tmi.init() end
local sOut = ''
local iMax = #tmi.modules
if 0 == iMax then return end
local b, index, m, s
for index = 1, iMax do
s = ''
m = tmi.modules[index]
b = tmi.isOn(m.id)
if b or m.updateWhenHidden then
if 'function' == type(m.onUpdate) then
s = m.onUpdate(index)
else
s = m.value or ''
end
end
if b and '' ~= s then sOut = sOut .. s .. '\n' end
end -- loop modules
--if not bMain then return end
if not tmi.hudID then return end
tmi.player:hud_change(tmi.hudID, 'text', sOut)
end -- update
--print('loaded functions.lua')