mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
253 lines
4.0 KiB
Lua
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
|