1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-30 08:57:00 +02:00
vcmi/scripts/lib/erm.lua
2021-02-16 13:32:18 +03:00

253 lines
4.0 KiB
Lua

DATA = DATA or {}
local DATA = DATA
local GAME = GAME
local TurnStarted = require("events.TurnStarted")
DATA.ERM = DATA.ERM or {}
local ERM_D = DATA.ERM
ERM_D.F = ERM_D.F or {}
ERM_D.MDATA = ERM_D.MDATA or {}
ERM_D.Q = ERM_D.Q or {}
ERM_D.v = ERM_D.v or {}
ERM_D.z = ERM_D.z or {}
local INT_MT =
{
__index = function(t, key)
return rawget(t, key) or 0
end
}
local STR_MT =
{
__index = function(t, key)
return rawget(t, key) or ""
end
}
setmetatable(DATA.ERM.Q, INT_MT)
setmetatable(DATA.ERM.v, INT_MT)
setmetatable(DATA.ERM.z, STR_MT)
local ERM =
{
w = {},
M = {},
subs = {}
}
local ERM_MT =
{
__index = DATA.ERM
}
setmetatable(ERM, ERM_MT)
local MACROS_MT =
{
__index = function(M, key)
address = rawget(ERM.MDATA, key)
assert(address, "Macro "..key.." is not defined")
return ERM[address.name][address.index]
end,
__newindex = function(M, key, value)
address = rawget(ERM.MDATA, key)
assert(address, "Macro "..key.." is not defined")
ERM[address.name][address.index] = value
end
}
setmetatable(ERM.M, MACROS_MT)
function ERM:addMacro(name, varName, varIndex)
assert(varName == "v" or varName == "z", "Macro for "..varName.. "[...] is not allowed")
rawset(self.MDATA, name, {name = varName, index = varIndex})
end
function ERM:getZVar(p1)
if type(p1) == "number" then
return self.z[tostring(p1)]
else
return p1
end
end
local HERO_VAR_MT =
{
__index = function(t, key)
ERM_D.WDATA = ERM_D.WDATA or {}
local wKey = ERM_D.wKey
if not wKey then
error("Hero variable set is not selected")
end
ERM_D.WDATA[wKey] = ERM_D.WDATA[wKey] or {}
return ERM_D.WDATA[wKey][key] or 0
end,
__newindex = function(t, key, value)
ERM_D.WDATA = ERM_D.WDATA or {}
local wKey = ERM_D.wKey
if not wKey then
error("Hero variable set is not selected")
end
ERM_D.WDATA[wKey] = ERM_D.WDATA[wKey] or {}
ERM_D.WDATA[wKey][key] = value
end
}
setmetatable(ERM.w, HERO_VAR_MT)
local function dailyUpdate(event)
ERM.Q.c = GAME:getDate(0)
end
table.insert(ERM.subs, TurnStarted.subscribeAfter(EVENT_BUS, dailyUpdate))
local Receivers = {}
local function createReceiverLoader(name)
local loader = function(...)
Receivers[name] = Receivers[name] or require("core:erm."..name)
return Receivers[name]:new(ERM, ...)
end
return loader
end
--[[
AR
BA
BF
BG
BH
CA
CD
CE
CM
DL
CO
EA
EX
GE
HL
HO
HT
LE
MO
MR
MW
OB
PM
PO
QW
SS
TL
TR
]]
local supportedReceivers = {"BM", "BU", "DO", "FU", "HE", "IF", "DO", "MA", "MF", "OW", "TM", "UN", "VR"}
for _, v in pairs(supportedReceivers) do ERM[v] = createReceiverLoader(v) end
local Triggers = {}
local function createTriggerLoader(name)
local loader = function(id_list, id_key)
local t = Triggers[id_key]
if not t then
local p = require("core:erm."..name.."_T")
t = p:new{ERM=ERM, id=id_list}
Triggers[id_key] = t
end
return t
end
return loader
end
--[[
!?AE
!?BA
!?BF
!?BG
!?BR
!?CM client only?
!?CO
!?DL client only?
!?GE
!?HE
!?HL
!?HM
!?LE (!$LE)
!?MG
!?MM client only?
!?MR
!?MW
!?OB (!$OB)
!?SN client only?
!?SN (ERA)
!?TH client only?
!?TL client only? depends on time limit feature
]]
local supportedTriggers = {"PI", "FU", "GM", "MF", "OB", "TM"}
local TriggerLoaders = {}
for _, v in pairs(supportedTriggers) do TriggerLoaders[v] = createTriggerLoader(v) end
local function makeIdKey(name, id_list)
if id_list == nil then
id_list = {}
elseif type(id_list) ~= "table" then
id_list = {id_list}
end
return name .. table.concat(id_list, "|")
end
function ERM:addTrigger(t)
local name = t.name
local fn = t.fn
local id_list = t.id or {}
local id_key = makeIdKey(name, id_list)
local trigger = TriggerLoaders[name](id_list, id_key)
trigger:addHandler(fn)
end
function ERM:callFunction(id, x)
local id_key = makeIdKey("FU", id)
local t = Triggers[id_key]
if t then
t:call({}, x)
end
end
function ERM:callInstructions(cb)
if not DATA.ERM.instructionsCalled then
cb()
local id_key = makeIdKey("PI")
local pi = Triggers[id_key]
if pi then
pi:call()
end
DATA.ERM.instructionsCalled = true
end
end
return ERM