156 lines
4.9 KiB
Lua
156 lines
4.9 KiB
Lua
mcl_events = {}
|
|
mcl_events.registered_events = {}
|
|
local disabled_events = minetest.settings:get("mcl_disabled_events")
|
|
if disabled_events then disabled_events = disabled_events:split(",")
|
|
else disabled_events = {} end
|
|
local DBG = minetest.settings:get_bool("mcl_logging_event_api",false)
|
|
local active_events = {}
|
|
|
|
local event_tpl = {
|
|
stage = 0,
|
|
max_stage = 1,
|
|
percent = 100,
|
|
bars = {},
|
|
completed = false,
|
|
cond_start = function(event) end, --return table of positions
|
|
on_step = function(event) end,
|
|
on_start = function(event) end,
|
|
on_stage_begin = function(event) end,
|
|
cond_progress = function(event) end, --return next stage
|
|
cond_complete = function(event) end, --return success
|
|
}
|
|
|
|
local function mcl_log(m,l)
|
|
if DBG then
|
|
if not l then l = "action" end
|
|
minetest.log(l,"[mcl_events] "..m)
|
|
end
|
|
end
|
|
|
|
function mcl_events.register_event(name,def)
|
|
if table.indexof(disabled_events,name) ~= -1 then return end
|
|
mcl_events.registered_events[name] = def
|
|
mcl_events.registered_events[name].name = name
|
|
end
|
|
|
|
local function addbars(self)
|
|
if not self.enable_bossbar then return end
|
|
for _,player in pairs(minetest.get_connected_players()) do
|
|
if vector.distance(self.pos,player:get_pos()) < 64 then
|
|
local bar = mcl_bossbars.add_bar(player, {color = "red", text = self.readable_name .. ": Wave "..self.stage.." / "..self.max_stage, percentage = self.percent }, true,1)
|
|
table.insert(self.bars,bar)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function start_event(p,e)
|
|
mcl_log("[mcl_events] Event started: "..e.readable_name.." at "..minetest.pos_to_string(vector.round(p.pos)))
|
|
local idx = #active_events + 1
|
|
active_events[idx] = table.copy(e)
|
|
setmetatable(active_events[idx],{__index = event_tpl})
|
|
for k,v in pairs(p) do active_events[idx][k] = v end
|
|
active_events[idx].stage = 0
|
|
active_events[idx].percent = 100
|
|
active_events[idx].bars = {}
|
|
active_events[idx].time_start = os.time()
|
|
if active_events[idx].on_start then
|
|
active_events[idx]:on_start(p.pos)
|
|
end
|
|
addbars(active_events[idx])
|
|
end
|
|
|
|
local function finish_event(self,idx)
|
|
mcl_log("[mcl_events] Finished: "..self.readable_name.." at "..minetest.pos_to_string(vector.round(self.pos)))
|
|
if self.on_complete then self:on_complete() end
|
|
for _,b in pairs(self.bars) do
|
|
mcl_bossbars.remove_bar(b)
|
|
end
|
|
table.remove(active_events,idx)
|
|
end
|
|
|
|
local etime = 0
|
|
function check_events(dtime)
|
|
--process active events
|
|
for idx,ae in pairs(active_events) do
|
|
if ae.cond_complete and ae:cond_complete() then
|
|
ae.finished = true
|
|
finish_event(ae,idx)
|
|
elseif not ae.cond_complete and ae.max_stage and ae.max_stage <= ae.stage then
|
|
ae.finished = true
|
|
finish_event(ae,idx)
|
|
elseif not ae.finished and ae.cond_progress then
|
|
local p = ae:cond_progress()
|
|
if p == true then
|
|
ae.stage = ae.stage + 1
|
|
if ae:on_stage_begin() == true then
|
|
mcl_log("[mcl_events] Event "..ae.readable_name.." at "..minetest.pos_to_string(vector.round(ae.pos)).." failed at stage_begin of stage "..ae.stage )
|
|
active_events[idx] = nil
|
|
end
|
|
elseif tonumber(p) then
|
|
ae.stage = tonumber(p) or ae.stage + 1
|
|
ae:on_stage_begin()
|
|
end
|
|
elseif not ae.finished and ae.on_step then
|
|
ae:on_step(dtime)
|
|
end
|
|
addbars(ae)
|
|
end
|
|
-- check if a new event should be started
|
|
etime = etime - dtime
|
|
if etime > 0 then return end
|
|
etime = 10
|
|
for _,e in pairs(mcl_events.registered_events) do
|
|
local pp = e.cond_start()
|
|
if pp then
|
|
--minetest.log("It's gonna start the raid maybe")
|
|
for _,p in pairs(pp) do
|
|
local start = true
|
|
if e.exclusive_to_area then
|
|
for _,ae in pairs(active_events) do
|
|
if e.name == ae.name and vector.distance(p.pos,ae.pos) < e.exclusive_to_area then start = false end
|
|
end
|
|
end
|
|
if start then
|
|
--minetest.log("It's gonna start the raid definitely")
|
|
start_event(p,e)
|
|
elseif DBG then
|
|
mcl_log("[mcl_events] Event "..e.readable_name.." already active at "..minetest.pos_to_string(vector.round(p.pos)))
|
|
end
|
|
end
|
|
else
|
|
--minetest.log("Do not start this raid")
|
|
end
|
|
end
|
|
for idx,ae in pairs(active_events) do
|
|
local player_near = false
|
|
for _,pl in pairs(minetest.get_connected_players()) do
|
|
if ae.pos and vector.distance(pl:get_pos(),ae.pos) < 64 then player_near = true end
|
|
end
|
|
if ae.pos and not player_near then
|
|
mcl_log("[mcl_events] Event "..ae.readable_name.." at "..minetest.pos_to_string(vector.round(ae.pos)).." aborted - no players near." )
|
|
active_events[idx] = nil
|
|
end
|
|
end
|
|
end
|
|
|
|
minetest.register_globalstep(check_events)
|
|
|
|
mcl_info.register_debug_field("Active Events",{
|
|
level = 4,
|
|
func = function(pl,pos)
|
|
return tostring(#active_events)
|
|
end
|
|
})
|
|
|
|
minetest.register_chatcommand("event_start",{
|
|
privs = {debug = true},
|
|
description = "Debug command to start events",
|
|
func = function(pname,param)
|
|
local p = minetest.get_player_by_name(pname)
|
|
local evdef = mcl_events.registered_events[param]
|
|
if not evdef then return false,"Event "..param.." doesn't exist.'" end
|
|
start_event({pos=p:get_pos(),player=pname,factor=1},evdef)
|
|
return true,"Started event "..param
|
|
end,
|
|
})
|