Needs merge with lm_trig.lua.
Signed-off-by: Darshan Shaligram <dshaligram@users.sourceforge.net>
QP5NJZGX7NQ5IUD3NC4MOZVVMFEDURLPRCZRRH3F67TM4LHE2Y7QC
------------------------------------------------------------------------------
-- lm_func.lua:
-- Function execution.
--
-- Calls a specific Lua function when activated; activation of the
-- function can occur when certain conditions are met. See the
-- marker_type parameter as listed below.
--
-- Marker parameters:
-- func: The function to be called.
-- marker_type: Can be one of the following:
-- * "random": Call the function randomly, takes the following parameters
-- "turns_min", "turns_max", and will call every random(min, max) turns.
-- * "turns": Call the function regularly, takes the parameter "turns", and
-- will call the function every "turns".
-- * "in_los": Calls the function whenever the marker is in the
-- player's line of sight. Takes the parameter "repeated", which
-- is "false" by default, meaning that the function is only
-- called once. Passing true means that the function is called
-- every turn that the marker is in LOS.
-- * "player_at": Calls the function whenever the player is at the
-- same position as the marker. Takes the same "repeated"
-- parameter as "in_los".
--
-- Specific markers take specific parameters, as listed under marker_type.
--
-- The function will be called with the "marker" object as its only parameter.
--
------------------------------------------------------------------------------
FunctionMachine = { CLASS = "FunctionMachine" }
FunctionMachine.__index = FunctionMachine
function FunctionMachine:_new()
local m = { }
setmetatable(m, self)
self.__index = self
return m
end
function FunctionMachine:new(pars)
if not pars then
error("No parameters provided")
end
if not pars.func then
error("No function provided")
end
local f = function() end
if type(pars.func) ~= type(f) then
error("Need an actual function")
end
if not pars.marker_type then
error("No marker_type specified")
end
if (pars.marker_type == "random"
and not (pars.turns_min and pars.turns_max)) then
error("marker_type:random, but no turns_min or turns_max specified")
end
if pars.marker_type == "turns" and not pars.turns then
error("marker_type:turns, but no turns specified")
end
local m = FunctionMachine:_new()
m.func = pars.func
m.marker_type = pars.marker_type
m.activated = false
m.countdown = 0
-- Setting turns is basically the same as setting turns_min and
-- turns_max to the same value; there's no point duplicating
-- functionality later.
m.turns_min = pars.turns_min or pars.turns or 0
m.turns_max = pars.turns_max or pars.turns or 0
m.repeated = pars.repeated or false
-- Some arithmetic to make these make sense in terms of actual turns
-- versus ticks.
m.turns_min = m.turns_min * 10
m.turns_max = m.turns_max * 10
return m
end
function FunctionMachine:do_function(marker)
local _x, _y = marker:pos()
self.func(marker)
end
function FunctionMachine:activate(marker, verbose)
local _x, _y = marker:pos()
dgn.register_listener(dgn.dgn_event_type('turn'), marker)
dgn.register_listener(dgn.dgn_event_type('entered_level'), marker)
end
function FunctionMachine:event(marker, ev)
local x, y = marker:pos()
if ev:type() == dgn.dgn_event_type('turn') then
if self.marker_type == "random" or self.marker_type == "turns" then
self.countdown = self.countdown - ev:ticks()
while self.countdown <= 0 do
self:do_function(marker)
self.activated = true
self.countdown = self.countdown +
crawl.random_range(self.turns_min, self.turns_max, 1)
end
elseif self.marker_type == "in_los" then
if you.see_cell(x, y) then
if not self.activated or self.repeated then
self:do_function(marker)
self.activated = true
end
end
elseif self.marker_type == "player_at" then
you_x, you_y = you.pos()
if you_x == x and you_y == y then
if not self.activated or self.repeated then
self:do_function(marker)
self.activated = true
end
end
end
end
end
function FunctionMachine:write(marker, th)
file.marshall_meta(th, self.func)
file.marshall_meta(th, self.marker_type)
file.marshall_meta(th, self.activated)
file.marshall_meta(th, self.countdown)
file.marshall_meta(th, self.turns_min)
file.marshall_meta(th, self.turns_max)
file.marshall_meta(th, self.repeated)
end
function FunctionMachine:read(marker, th)
self.func = file.unmarshall_meta(th)
self.marker_type = file.unmarshall_meta(th)
self.activated = file.unmarshall_meta(th)
self.countdown = file.unmarshall_meta(th)
self.turns_min = file.unmarshall_meta(th)
self.turns_max = file.unmarshall_meta(th)
self.repeated = file.unmarshall_meta(th)
setmetatable(self, FunctionMachine)
return self
end
function function_machine(pars)
return FunctionMachine:new(pars)
end