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 = FunctionMachinefunction FunctionMachine:_new()local m = { }setmetatable(m, self)self.__index = selfreturn mendfunction FunctionMachine:new(pars)if not pars thenerror("No parameters provided")endif not pars.func thenerror("No function provided")endlocal f = function() endif type(pars.func) ~= type(f) thenerror("Need an actual function")endif not pars.marker_type thenerror("No marker_type specified")endif (pars.marker_type == "random"and not (pars.turns_min and pars.turns_max)) thenerror("marker_type:random, but no turns_min or turns_max specified")endif pars.marker_type == "turns" and not pars.turns thenerror("marker_type:turns, but no turns specified")endlocal m = FunctionMachine:_new()m.func = pars.funcm.marker_type = pars.marker_typem.activated = falsem.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 0m.turns_max = pars.turns_max or pars.turns or 0m.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 * 10m.turns_max = m.turns_max * 10return mendfunction FunctionMachine:do_function(marker)local _x, _y = marker:pos()self.func(marker)endfunction 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)endfunction FunctionMachine:event(marker, ev)local x, y = marker:pos()if ev:type() == dgn.dgn_event_type('turn') thenif self.marker_type == "random" or self.marker_type == "turns" thenself.countdown = self.countdown - ev:ticks()while self.countdown <= 0 doself:do_function(marker)self.activated = trueself.countdown = self.countdown +crawl.random_range(self.turns_min, self.turns_max, 1)endelseif self.marker_type == "in_los" thenif you.see_cell(x, y) thenif not self.activated or self.repeated thenself:do_function(marker)self.activated = trueendendelseif self.marker_type == "player_at" thenyou_x, you_y = you.pos()if you_x == x and you_y == y thenif not self.activated or self.repeated thenself:do_function(marker)self.activated = trueendendendendendfunction 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)endfunction 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 selfendfunction function_machine(pars)return FunctionMachine:new(pars)end