diff --git a/mods/CORE/mcl_events/init.lua b/mods/CORE/mcl_events/init.lua new file mode 100644 index 0000000000..164dfdaa1c --- /dev/null +++ b/mods/CORE/mcl_events/init.lua @@ -0,0 +1,127 @@ +mcl_events = {} +mcl_events.registered_events = {} +local active_events = {} + +local tpl_eventdef = { + stage = 1, + max_stage = 1, + --pos = vector.zero(), + --time_start = 0, + 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 +} + +function mcl_events.register_event(name,def) + mcl_events.registered_events[name] = {} + --setmetatable(mcl_events.registered_events[name],tpl_eventdef) + mcl_events.registered_events[name] = def + mcl_events.registered_events[name].name = name +end + +local function start_event(p,e) + minetest.log("event started: "..e.name.." at "..minetest.pos_to_string(p)) + local idx = #active_events + 1 + active_events[idx] = table.copy(e) + setmetatable(active_events[idx],e) + active_events[idx].pos = vector.copy(p) + active_events[idx].stage = 1 + active_events[idx].time_start = os.time() + active_events[idx]:on_start(p) +end + +local function finish_event(self,idx) + minetest.log("event finished: "..self.name.." at "..minetest.pos_to_string(self.pos)) + if self.on_complete then self:on_complete() end + table.remove(active_events,idx) +end + +local etime = 0 +function check_events(dtime) + for idx,ae in pairs(active_events) do + if ae.cond_complete and ae:cond_complete() then + finish_event(ae,idx) + elseif ae.max_stage and ae.max_stage < ae.stage then + finish_event(ae,idx) + elseif ae.cond_progress then + local p = ae:cond_progress() + if p == true then + ae.stage = ae.stage + 1 + minetest.log("event progressed to stage "..ae.stage) + ae:on_stage_begin() + elseif tonumber(p) then + ae.stage = tonumber(p) or ae.stage + 1 + minetest.log("event progressed to stage "..ae.stage) + ae:on_stage_begin() + end + + elseif ae.on_step then + ae:on_step() + end + end + 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 + for _,p in pairs(pp) do + start_event(p,e) + end + end + end +end + +minetest.register_globalstep(check_events) + +mcl_events.register_event("infestation",{ + max_stage = 5, + cond_start = function(self) + local r = {} + for _,p in pairs(minetest.get_connected_players()) do + if p:get_meta():get_string("infestation-omen") == "yes" then + p:get_meta():set_string("infestation-omen","") + table.insert(r,p:get_pos()) + end + end + if #r > 0 then return r end + end, + on_start = function(self) + self.mobs = {} + minetest.log("inf") + end, + cond_progress = function(self) + local m = {} + for k,o in pairs(self.mobs) do + if o and o:get_pos() then table.insert(m,o) end + end + if #m < 1 then + minetest.log("INFESTATION stage "..self.stage.." completed") + return true end + self.mobs = m + end, + on_stage_begin = function(self) + minetest.log("event "..self.name.." stage "..self.stage.." begin...") + for i=1,5 * self.stage do + local m = mcl_mobs.spawn(vector.add(self.pos,vector.new(math.random(20)-10,0,math.random(20)-10)),"mobs_mc:silverfish") + if m then + table.insert(self.mobs,m) + end + end + end, + on_complete = function(self) + minetest.log("INFESTATION complete") + end, +}) + +minetest.register_chatcommand("infest",{ + privs = {debug = true}, + func = function(n,param) + local p = minetest.get_player_by_name(n) + p:get_meta():set_string("infestation-omen","yes") + end, +}) diff --git a/mods/CORE/mcl_events/mod.conf b/mods/CORE/mcl_events/mod.conf new file mode 100644 index 0000000000..a69f0a303b --- /dev/null +++ b/mods/CORE/mcl_events/mod.conf @@ -0,0 +1,3 @@ +name = mcl_events +author = cora +depends = mcl_mobs