summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/dat
diff options
context:
space:
mode:
authorDarshan Shaligram <dshaligram@users.sourceforge.net>2009-10-30 15:46:55 +0530
committerDarshan Shaligram <dshaligram@users.sourceforge.net>2009-10-31 22:16:46 +0530
commitad11744e5d49d226fc9c77ed48c3dd8b97921350 (patch)
treec4334fd1e6b4b052ac93593f9021f12c9f10baac /crawl-ref/source/dat
parent23f8631266eac1a7b4b4727b26a5fc088a6f0184 (diff)
downloadcrawl-ref-ad11744e5d49d226fc9c77ed48c3dd8b97921350.tar.gz
crawl-ref-ad11744e5d49d226fc9c77ed48c3dd8b97921350.zip
lmark.synchronized_markers(): apply one marker's effects to multiple points simultaneously.
synchronized_markers() takes a marker, and a list of method names to override, and returns a set of markers that fire simultaneously, to allow, say, fog machines that fire at random intervals, but always fire in unison. lm_mslav.lua has details. volcano.des has an example volcano entry vault that uses this. Allow fetching a list of Lua markers/marker positions by property value. Renamed dgn.find_marker_prop -> dgn.find_marker_position_by_prop. s/helper/listener/ for fog machine listeners.
Diffstat (limited to 'crawl-ref/source/dat')
-rw-r--r--crawl-ref/source/dat/clua/lm_fog.lua172
-rw-r--r--crawl-ref/source/dat/clua/lm_func.lua33
-rw-r--r--crawl-ref/source/dat/clua/lm_mslav.lua157
-rw-r--r--crawl-ref/source/dat/clua/luamark.lua3
-rw-r--r--crawl-ref/source/dat/clua/point.lua4
-rw-r--r--crawl-ref/source/dat/clua/util.lua8
-rw-r--r--crawl-ref/source/dat/clua/ziggurat.lua2
-rw-r--r--crawl-ref/source/dat/volcano.des51
8 files changed, 334 insertions, 96 deletions
diff --git a/crawl-ref/source/dat/clua/lm_fog.lua b/crawl-ref/source/dat/clua/lm_fog.lua
index d893a150d2..97bc5750c4 100644
--- a/crawl-ref/source/dat/clua/lm_fog.lua
+++ b/crawl-ref/source/dat/clua/lm_fog.lua
@@ -48,11 +48,13 @@
-- start_clouds: The number of clouds to lay when the level containing
-- the cloud machine is entered. This is necessary since clouds
-- are cleared when the player leaves a level.
--- helper: A FunctionMachine helper marker. Will be called whenever the countdown
--- is activated, and whenever the fog machine is reset. It will be called
--- with the FogMachine's marker, a string containing the event ("decrement",
--- "trigger"), the actual event object, and a copy of the FogMachine itself.
--- See the section "Messages for fog machines" at the end of the file.
+-- listener: A FunctionMachine listener marker. Will be called
+-- whenever the countdown is activated, and whenever the fog
+-- machine is reset. It will be called with the FogMachine's
+-- marker, a string containing the event ("decrement", "trigger"),
+-- the actual event object, and a copy of the FogMachine itself.
+-- See the section "Messages for fog machines" at the end of the
+-- file.
--
------------------------------------------------------------------------------
@@ -96,7 +98,7 @@ function FogMachine:new(pars)
m.size_max = pars.size_max or pars.size
m.spread_rate = pars.spread_rate or -1
m.start_clouds = pars.start_clouds or 1
- m.helper = pars.helper or nil
+ m.listener = pars.listener or nil
m.size_buildup_amnt = pars.size_buildup_amnt or 0
m.size_buildup_time = pars.size_buildup_time or 1
@@ -109,10 +111,16 @@ function FogMachine:new(pars)
return m
end
-function FogMachine:do_fog(marker)
- local x, y = marker:pos()
+function FogMachine:apply_cloud(point, pow_min, pow_max, pow_rolls,
+ size, cloud_type, kill_cat, spread)
+ dgn.apply_area_cloud(point.x, point.y, pow_min, pow_max, pow_rolls, size,
+ cloud_type, kill_cat, spread)
+end
+
+function FogMachine:do_fog(point)
+ local p = point
if self.walk_dist > 0 then
- x, y = dgn.random_walk(x, y, self.walk_dist)
+ p = dgn.point(dgn.random_walk(p.x, p.y, self.walk_dist))
end
local buildup_turns = self.buildup_turns
@@ -142,9 +150,9 @@ function FogMachine:do_fog(marker)
local spread = self.spread_rate + (self.spread_buildup_amnt * buildup_turns /
self.spread_buildup_time)
- dgn.apply_area_cloud(x, y, self.pow_min, self.pow_max, self.pow_rolls,
- crawl.random_range(size_min, size_max, 1),
- self.cloud_type, self.kill_cat, spread)
+ self:apply_cloud(p, self.pow_min, self.pow_max, self.pow_rolls,
+ crawl.random_range(size_min, size_max, 1),
+ self.cloud_type, self.kill_cat, spread)
end
function FogMachine:activate(marker, verbose)
@@ -153,6 +161,12 @@ function FogMachine:activate(marker, verbose)
dgn.register_listener(dgn.dgn_event_type('entered_level'), marker)
end
+function FogMachine:notify_listener(point, event, evobj)
+ if self.listener then
+ return self.listener:do_function(point, event, ev, self)
+ end
+end
+
function FogMachine:event(marker, ev)
local _x, _y = marker:pos()
if ev:type() == dgn.dgn_event_type('turn') then
@@ -164,23 +178,21 @@ function FogMachine:event(marker, ev)
self.buildup_turns = self.size_buildup_time
end
- if self.helper ~= nil and self.countdown > 0 then
- self.helper:do_function(marker, "decrement", ev, self)
- elseif self.helper ~= nil and self.countdown <= 0 then
- self.helper:do_function(marker, "trigger", ev, self)
+ if self.countdown > 0 then
+ self:notify_listener(dgn.point(marker:pos()), "decrement", ev)
+ elseif self.countdown <= 0 then
+ self:notify_listener(dgn.point(marker:pos()), "trigger", ev)
end
while self.countdown <= 0 do
- self:do_fog(marker)
- self.countdown = self.countdown +
+ self:do_fog(dgn.point(marker:pos()))
+ self.countdown = self.countdown +
crawl.random_range(self.delay_min, self.delay_max, 1)
end
elseif ev:type() == dgn.dgn_event_type('entered_level') then
for i = 1, self.start_clouds do
- self:do_fog(marker)
- if self.helper ~= nil then
- self.helper:do_function(marker, "trigger", ev, self)
- end
+ self:do_fog(dgn.point(marker:pos()))
+ self:notify_listener(dgn.point(marker:pos()), "trigger", ev)
self.countdown = crawl.random_range(self.delay_min, self.delay_max, 1)
self.buildup_turns = 0
end
@@ -206,9 +218,9 @@ function FogMachine:write(marker, th)
file.marshall(th, self.spread_buildup_time)
file.marshall(th, self.buildup_turns)
file.marshall(th, self.countdown)
- if self.helper ~= nil then
+ if self.listener then
file.marshall_meta(th, true)
- self.helper:write(marker, th)
+ self.listener:write(marker, th)
else
file.marshall_meta(th, false)
end
@@ -233,12 +245,15 @@ function FogMachine:read(marker, th)
self.spread_buildup_time = file.unmarshall_number(th)
self.buildup_turns = file.unmarshall_number(th)
self.countdown = file.unmarshall_number(th)
- got_helper = file.unmarshall_meta(th)
- if got_helper == true then
- self.helper = function_machine ({marker_type = "helper", func = (function() end)})
- self.helper:read(marker, th)
+ got_listener = file.unmarshall_meta(th)
+ if got_listener == true then
+ self.listener = function_machine {
+ marker_type = "listener",
+ func = (function() end)
+ }
+ self.listener:read(marker, th)
else
- self.helper = nil
+ self.listener = nil
end
setmetatable(self, FogMachine)
@@ -280,41 +295,46 @@ end
-------------------------------------------------------------------------------
-- Messages for fog machines.
--
--- * warning_machine: Takes three parameters: turns, cantsee_message, and,
--- optionally, see_message. Turns is the value of player turns before to
--- trigger the message before the fog machine is fired. If only see_message
--- is provided, the message will only be printed if the player can see the
--- fog machine. If only cantsee_mesage is provided, the message will be
--- displayed regardless. In combination, the message will be different
--- depending on whether or not the player can see the marker. By default, the
--- message will be displaying using the "warning" channel.
+-- * warning_machine: Takes three parameters: turns, cantsee_message,
+-- and, optionally, see_message. Turns is the value of player
+-- turns before to trigger the message before the fog machine is
+-- fired. If only see_message is provided, the message will only
+-- be printed if the player can see the fog machine. If only
+-- cantsee_mesage is provided, the message will be displayed
+-- regardless. In combination, the message will be different
+-- depending on whether or not the player can see the marker. By
+-- default, the message will be displaying using the "warning"
+-- channel.
--
--- * trigger_machine: Takes three parameters: cantsee_message, see_message, and,
--- optionally, channel. The functionality is identical to a warning_machine,
--- only the message is instead displayed (or not displayed) when the fog machine
--- is triggered. The message channel can be provided.
+-- * trigger_machine: Takes three parameters: cantsee_message,
+-- see_message, and, optionally, channel. The functionality is
+-- identical to a warning_machine, only the message is instead
+-- displayed (or not displayed) when the fog machine is
+-- triggered. The message channel can be provided.
--
--- * tw_machine: Combines the above two message machines, providing warning messages
--- as well as messages when triggered. Takes the parameters: warn_turns,
--- warning_cantsee_message, trigger_cantsee_message, trigger_channel,
--- trigger_see_message, warning_see_message. Parameters work as described above.
+-- * tw_machine: Combines the above two message machines, providing
+-- warning messages as well as messages when triggered. Takes the
+-- parameters: warn_turns, warning_cantsee_message,
+-- trigger_cantsee_message, trigger_channel, trigger_see_message,
+-- warning_see_message. Parameters work as described above.
--
--- In all instances, the "cantsee" form of the message parameter cannot be null,
--- and for warning and dual trigger/warning machines, the turns parameter cannot
--- be null. All other parameters are considered optional.
+-- In all instances, the "cantsee" form of the message parameter
+-- cannot be null, and for warning and dual trigger/warning machines,
+-- the turns parameter cannot be null. All other parameters are
+-- considered optional.
function warning_machine (trns, cantsee_mesg, see_mesg)
if trns == nil or (see_mesg == nil and cantsee_mesg == nil) then
error("WarningMachine requires turns and message!")
end
- local function warning_func (marker, mtable, m2, event_name, event, fm)
+ local function warning_func (point, mtable, event_name, event, fm)
local countdown = fm.countdown
if event_name == "decrement" and countdown <= mtable.turns then
- if mtable.warning_done ~= true then
- if mtable.see_message ~= nil and you.see_cell(marker:pos()) then
- crawl.mpr(mtable.see_message, "warning")
- elseif mtable.cantsee_message ~= nil then
- crawl.mpr(mtable.cantsee_message, "warning")
+ if not mtable.warning_done then
+ if mtable.see_message and you.see_cell(point.x, point.y) then
+ crawl.mpr(mtable.see_message, "warning")
+ elseif mtable.cantsee_message then
+ crawl.mpr(mtable.cantsee_message, "warning")
end
mtable.warning_done = true
end
@@ -322,7 +342,7 @@ function warning_machine (trns, cantsee_mesg, see_mesg)
mtable.warning_done = false
end
end
- pars = {marker_type = "helper"}
+ pars = {marker_type = "listener"}
pars.marker_params = {see_message = see_mesg, cantsee_message = cantsee_mesg,
turns = trns * 10, warning_done = false}
pars.func = warning_func
@@ -333,34 +353,40 @@ function trigger_machine (cantsee_mesg, see_mesg, chan)
if see_mesg == nil and cantsee_mesg == nil then
error("Triggermachine requires a message!")
end
- local function trigger_func (marker, mtable, m2, event_name, event, fm)
+ local function trigger_func (point, mtable, event_name, event, fm)
local countdown = fm.countdown
if event_name == "trigger" then
channel = mtable.channel or ""
- if mtable.see_message ~= nil and you.see_cell(marker:pos()) then
+ if mtable.see_message ~= nil and you.see_cell(point.x, point.y) then
crawl.mpr(mtable.see_message, channel)
elseif mtable.cantsee_message ~= nil then
crawl.mpr(mtable.cantsee_message, channel)
end
end
end
- pars = {marker_type = "helper"}
- pars.marker_params = {channel = chan or nil, see_message = see_mesg, cantsee_message = cantsee_mesg}
+ pars = {marker_type = "listener"}
+ pars.marker_params = {
+ channel = chan or nil,
+ see_message = see_mesg,
+ cantsee_message = cantsee_mesg
+ }
pars.func = trigger_func
return FunctionMachine:new(pars)
end
-function tw_machine (warn_turns, warn_cantsee_message, trig_cantsee_message, trig_channel,
+function tw_machine (warn_turns, warn_cantsee_message,
+ trig_cantsee_message, trig_channel,
trig_see_message, warn_see_message)
- if warn_turns == nil or (warn_see_message == nil and warn_cantsee_message == nil)
- or (trig_see_message == nil and trig_cantsee_message == nil) then
- error("TWMachine needs warning turns, warning message and triggeing message.")
+ if (not warn_turns or (not warn_see_message and not warn_cantsee_message)
+ or (not trig_see_message and not trig_cantsee_message)) then
+ error("TWMachine needs warning turns, warning message and "
+ .. "triggering message.")
end
- local function tw_func (marker, mtable, m2, event_name, event, fm)
+ local function tw_func (point, mtable, event_name, event, fm)
local countdown = fm.countdown
if event_name == "decrement" and countdown <= mtable.warning_turns then
if mtable.warning_done ~= true then
- if mtable.warning_see_message ~= nil and you.see_cell(marker:pos()) then
+ if mtable.warning_see_message and you.see_cell(point.x, point.y) then
crawl.mpr(mtable.warning_see_message, "warning")
elseif mtable.warning_cantsee_message ~= nil then
crawl.mpr(mtable.warning_cantsee_message, "warning")
@@ -370,17 +396,23 @@ function tw_machine (warn_turns, warn_cantsee_message, trig_cantsee_message, tri
elseif event_name == "trigger" then
mtable.warning_done = false
channel = mtable.trigger_channel or ""
- if mtable.trigger_see_message ~= nil and you.see_cell(marker:pos()) then
+ if mtable.trigger_see_message and you.see_cell(point.x, point.y) then
crawl.mpr(mtable.trigger_see_message, channel)
elseif mtable.trigger_cantsee_message ~= nil then
crawl.mpr(mtable.trigger_cantsee_message, channel)
end
end
end
- pars = {marker_type = "helper"}
- pars.marker_params = {warning_see_message = warn_see_message, warning_cantsee_message = warn_cantsee_message,
- warning_turns = warn_turns * 10, warning_done = false, trigger_see_message = trig_see_message,
- trigger_cantsee_message = trig_cantsee_message, trigger_channel = trig_channel or nil}
+ pars = {marker_type = "listener"}
+ pars.marker_params = {
+ warning_see_message = warn_see_message,
+ warning_cantsee_message = warn_cantsee_message,
+ warning_turns = warn_turns * 10,
+ warning_done = false,
+ trigger_see_message = trig_see_message,
+ trigger_cantsee_message = trig_cantsee_message,
+ trigger_channel = trig_channel or nil
+ }
pars.func = tw_func
return FunctionMachine:new(pars)
end
diff --git a/crawl-ref/source/dat/clua/lm_func.lua b/crawl-ref/source/dat/clua/lm_func.lua
index b76d6cdc9a..cd83cf61a3 100644
--- a/crawl-ref/source/dat/clua/lm_func.lua
+++ b/crawl-ref/source/dat/clua/lm_func.lua
@@ -21,12 +21,14 @@
-- * "player_at": Calls the function whenever the player is at the
-- same position as the marker. Takes the same "repeated"
-- parameter as "in_los".
--- * "helper": A function machine that can be linked into other lua markers
--- and machines. It is not triggered independantly, but called by the "parent"
--- marker, though always with the same marker_table parameter as other
--- machines. May take further parameters, see the parent's documentation.
+-- * "helper": A function machine that can be linked into other lua
+-- markers and machines. It is not triggered independantly, but
+-- called by the "parent" marker, though always with the same
+-- marker_table parameter as other machines. May take further
+-- parameters, see the parent's documentation.
--
--- marker_table: Table to be passed to the function when called. Defaults to {}.
+-- marker_table: Table to be passed to the function when called.
+-- Defaults to {}.
--
-- Specific markers take specific parameters, as listed under marker_type.
--
@@ -95,13 +97,12 @@ function FunctionMachine:new(pars)
return m
end
-function FunctionMachine:do_function(...)
- marker = arg[1]
- local _x, _y = marker:pos()
- if #arg == 1 then
- self.func(marker, self.marker_params)
+function FunctionMachine:do_function(position, ...)
+ local largs = { ... }
+ if #largs == 0 then
+ self.func(position, self.marker_params)
else
- self.func(marker, self.marker_params, unpack(arg))
+ self.func(position, self.marker_params, unpack(largs))
end
end
@@ -121,7 +122,7 @@ function FunctionMachine:event(marker, ev)
self.countdown = self.countdown - ev:ticks()
while self.countdown <= 0 do
- self:do_function(marker)
+ self:do_function(dgn.point(marker:pos()))
self.activated = true
self.countdown = self.countdown +
crawl.random_range(self.turns_min, self.turns_max, 1)
@@ -129,7 +130,7 @@ function FunctionMachine:event(marker, ev)
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:do_function(dgn.point(marker:pos()))
self.activated = true
end
end
@@ -137,7 +138,7 @@ function FunctionMachine:event(marker, ev)
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:do_function(dgn.point(marker:pos()))
self.activated = true
end
end
@@ -178,7 +179,9 @@ end
function message_machine (pars)
local channel = pars.channel or false
local mtable = {message = pars.message, channel = pars.channel}
- pars.func = (function(marker, mtable) crawl.mpr(mtable.message, mtable.channel) end)
+ pars.func = function (position, mtable)
+ crawl.mpr(mtable.message, mtable.channel)
+ end
pars.marker_params = mtable
return FunctionMachine:new(pars)
end
diff --git a/crawl-ref/source/dat/clua/lm_mslav.lua b/crawl-ref/source/dat/clua/lm_mslav.lua
new file mode 100644
index 0000000000..141dea7521
--- /dev/null
+++ b/crawl-ref/source/dat/clua/lm_mslav.lua
@@ -0,0 +1,157 @@
+----------------------------------------------------------------------------
+-- lm_mslav.lua
+--
+-- Wraps a marker to act as a master firing synchronized events to its
+-- own position, and to any number of (or zero) slave markers'
+-- positions.
+--
+-- API: lmark.synchronized_markers(<marker>, <trigger-function-names>)
+--
+-- Usage:
+-- ------
+--
+-- You can use synchronized_markers() if you have a marker that
+-- performs an activity at random intervals, and you want to apply
+-- this marker's effects to multiple locations at the same time.
+--
+-- As an example, take a fog machine:
+-- 1) Create the fog machine as you would normally:
+-- local fog = fog_machine {
+-- cloud_type = 'flame',
+-- size = 3, pow_min=2,
+-- pow_max = 5, delay_min = 22, delay_max = 120,
+-- }
+--
+-- 2) Apply it as a Lua marker to one or more locations, wrapping it
+-- with synchronized_markers():
+-- lua_marker('m', lmark.synchronized_markers(fog, 'do_fog'))
+-- Where 'do_fog' is the name of the trigger method on the
+-- underlying marker (here the fog machine) that performs the
+-- activity of interest (generating fog at some point). The first
+-- parameter of this overridden method must be a dgn.point that
+-- specifies where the effect occurs. The method may also take any
+-- number of additional parameters.
+--
+-- You may override multiple methods on the base marker:
+-- lmark.synchronized_markers(fog, 'do_fog', 'notify_listener')
+-- The only requirement for an overridden method is that it take a
+-- dgn.point as its first parameter.
+--
+-- Internals:
+-- ---------
+-- synchronized_markers() takes one marker instance, and creates one
+-- master marker (which is based on the given marker instance) and
+-- multiple slave markers (which are simple PortalDescriptor markers).
+-- The only purpose of the slave markers is to be discoverable by
+-- dgn.find_marker_positions_by_prop, given a unique, autogenerated
+-- slave id.
+--
+-- The master marker operates normally, but calls to any of the trigger
+-- methods (say 'do_fog') are intercepted. Every trigger call is performed
+-- on the master's position, and then on all the slaves' positions.
+----------------------------------------------------------------------------
+
+util.namespace('lmark')
+
+lmark.slave_cookie = 0
+
+function lmark.next_slave_id()
+ local slave_id = "marker_slave" .. lmark.slave_cookie
+ lmark.slave_cookie = lmark.slave_cookie + 1
+ return slave_id
+end
+
+function lmark.saveable_slave_table(slave)
+ local saveable = {
+ slave_id = slave.slave_id,
+ triggers = slave.triggers,
+ old_read = slave.old_read
+ }
+ return saveable
+end
+
+function lmark:master_trigger_fn(trigger_name, point, ...)
+ local old_trigger = self.slave_table.old_triggers[trigger_name]
+ -- Pull the trigger on the master first.
+ old_trigger(self, point, ...)
+
+ local slave_points =
+ dgn.find_marker_positions_by_prop("slave_id", self.slave_table.slave_id)
+ for _, slave_pos in ipairs(slave_points) do
+ old_trigger(self, slave_pos, ...)
+ end
+end
+
+function lmark:master_write(marker, th)
+ -- Save the slave table first.
+ lmark.marshall_table(th, lmark.saveable_slave_table(self.slave_table))
+ self.slave_table.old_write(self, marker, th)
+end
+
+
+function lmark:master_read(marker, th)
+ -- Load the slave table.
+ local slave_table = lmark.unmarshall_table(th)
+
+ local cookie_number = string.match(slave_table.slave_id, "marker_slave(%d+)")
+ -- [ds] Try to avoid reusing the same cookie as one we've reloaded.
+ -- This is only necessary to avoid collisions with cookies generated
+ -- for future vaults placed on this level (such as by the Trowel
+ -- card).
+ if cookie_number then
+ cookie_number = tonumber(cookie_number)
+ if lmark.slave_cookie <= cookie_number then
+ lmark.slave_cookie = cookie_number + 1
+ end
+ end
+
+ -- Call the old read function.
+ local newself = slave_table.old_read(self, marker, th)
+ -- And redecorate the marker as a master marker.
+ return lmark.make_master(newself, slave_table.slave_id,
+ slave_table.triggers)
+end
+
+function lmark.make_master(lmarker, slave_id, triggers)
+ local old_trigger_map = { }
+ for _, trigger_name in ipairs(triggers) do
+ old_trigger_map[trigger_name] = lmarker[trigger_name]
+ lmarker[trigger_name] =
+ function (self, ...)
+ return lmark.master_trigger_fn(self, trigger_name, ...)
+ end
+ end
+
+ lmarker.slave_table = {
+ slave_id = slave_id,
+ triggers = triggers,
+ old_write = lmarker.write,
+ old_triggers = old_trigger_map,
+ old_read = lmarker.read
+ }
+
+ lmarker.write = lmark.master_write
+ lmarker.read = lmark.master_read
+
+ return lmarker
+end
+
+function lmark.make_slave(slave_id)
+ return portal_desc { slave_id = slave_id }
+end
+
+function lmark.synchronized_markers(master, ...)
+ local first = true
+ local slave_id = lmark.next_slave_id()
+ local triggers = { ... }
+ assert(#triggers > 0,
+ "Please provide one or more trigger functions on the master marker")
+ return function ()
+ if first then
+ first = false
+ return lmark.make_master(master, slave_id, triggers)
+ else
+ return lmark.make_slave(slave_id)
+ end
+ end
+end \ No newline at end of file
diff --git a/crawl-ref/source/dat/clua/luamark.lua b/crawl-ref/source/dat/clua/luamark.lua
index 86b125a53c..10eb05945c 100644
--- a/crawl-ref/source/dat/clua/luamark.lua
+++ b/crawl-ref/source/dat/clua/luamark.lua
@@ -13,6 +13,7 @@ require('clua/lm_fog.lua')
require('clua/lm_props.lua')
require('clua/lm_monst.lua')
require('clua/lm_func.lua')
+require('clua/lm_mslav.lua')
function dlua_marker_function(table, name)
return table[name]
@@ -28,7 +29,7 @@ function dlua_marker_read(fn, marker, th)
return fn({ }, marker, th)
end
-lmark = { }
+util.namespace('lmark')
-- Marshalls a table comprising of keys that are strings or numbers only,
-- and values that are strings, numbers, functions, or tables only. The table
diff --git a/crawl-ref/source/dat/clua/point.lua b/crawl-ref/source/dat/clua/point.lua
index b750372197..f186dc62f5 100644
--- a/crawl-ref/source/dat/clua/point.lua
+++ b/crawl-ref/source/dat/clua/point.lua
@@ -22,6 +22,10 @@ local function sgn(x)
end
end
+function point_metatable:xy()
+ return self.x, self.y
+end
+
point_metatable.sgn = function (p)
return dgn.point(sgn(p.x), sgn(p.y))
end
diff --git a/crawl-ref/source/dat/clua/util.lua b/crawl-ref/source/dat/clua/util.lua
index 1ed3670172..5ef063d9fb 100644
--- a/crawl-ref/source/dat/clua/util.lua
+++ b/crawl-ref/source/dat/clua/util.lua
@@ -326,3 +326,11 @@ function util.copy_table(object)
return _copy(object)
end
+-- Initialises a namespace that has functions spread across multiple files.
+-- If the namespace table does not exist, it is created. If it already exists,
+-- it is not modified.
+function util.namespace(table_name)
+ if _G[table_name] == nil then
+ _G[table_name] = { }
+ end
+end \ No newline at end of file
diff --git a/crawl-ref/source/dat/clua/ziggurat.lua b/crawl-ref/source/dat/clua/ziggurat.lua
index ba35595d70..8ac89bc460 100644
--- a/crawl-ref/source/dat/clua/ziggurat.lua
+++ b/crawl-ref/source/dat/clua/ziggurat.lua
@@ -600,7 +600,7 @@ local function ziggurat_create_loot_vault(entry, exit)
return exit
else
-- Find the square to drop the loot.
- local lootx, looty = dgn.find_marker_prop("ziggurat_loot")
+ local lootx, looty = dgn.find_marker_position_by_prop("ziggurat_loot")
if lootx and looty then
return dgn.point(lootx, looty)
diff --git a/crawl-ref/source/dat/volcano.des b/crawl-ref/source/dat/volcano.des
index fdfd592fe9..1b248e11ed 100644
--- a/crawl-ref/source/dat/volcano.des
+++ b/crawl-ref/source/dat/volcano.des
@@ -156,28 +156,28 @@ function place_large_volcano(e)
e.kfeat("V = l")
e.lua_marker('V', fog_machine { cloud_type = "flame", walk_dist=15, pow_max=6,
delay = 300, size = 10000, spread_rate = 30,
- helper = large_warning})
+ listener = large_warning})
end
function place_medium_volcano(e)
e.kfeat("V = l")
e.lua_marker('V', fog_machine { cloud_type = "flame", walk_dist=15, pow_max=6,
delay = 300, size = 3000, spread_rate = 30,
- helper = small_warning})
+ listener = small_warning})
end
function place_small_volcano(e)
e.kfeat("V = l")
e.lua_marker('V', fog_machine { cloud_type = "flame", walk_dist=15, pow_max=6,
delay = 300, size = 800, spread_rate = 30,
- helper = small_warning})
+ listener = small_warning})
end
function place_tiny_volcano(e)
e.kfeat("V = l")
e.lua_marker('V', fog_machine { cloud_type = "flame", walk_dist=10, pow_max=6,
delay = 800, size = 80, spread_rate = 10,
- helper = large_warning})
+ listener = large_warning})
end
function place_medium_flame_cloud (e, glyph, nolava)
@@ -389,6 +389,33 @@ default-depth: Lair:1-8, Orc:1-4, Hive:1
###############################################################################
# Entries:
+
+# [ds] A dummy entry that's a proof-of-concept for synchronized fog machines
+# that trigger at multiple places at the same instant, but still have a random
+# delay.
+NAME: enter_volcano_snarktest101
+TAGS: uniq_volcano
+ORIENT: float
+WEIGHT: 0
+{{
+ local fog = fog_machine { cloud_type = 'flame',
+ size = 3, pow_min=2,
+ pow_max = 5, delay_min = 22, delay_max = 120,
+ }
+ lua_marker('m', lmark.synchronized_markers(fog, 'do_fog'))
+}}
+SUBST: m = .
+: volcano_portal(_G)
+MAP
+.......
+...m...
+.......
+.m.O.m.
+.......
+...m...
+.......
+ENDMAP
+
NAME: enter_volcano_1
TAGS: uniq_volcano
ORIENT: float
@@ -841,8 +868,8 @@ LFLAGS: no_tele_control
{{
local mytable = { total_doorways=8, total_collapsed=0, ac = {} }
-local function collapse_doorways (marker, mytable)
- local x, y = marker:pos()
+local function collapse_doorways (point, mytable)
+ local x, y = point:xy()
local you_x, you_y = you.pos()
if mytable.total_collapsed == mytable.total_doorways then
return
@@ -856,7 +883,7 @@ local function collapse_doorways (marker, mytable)
local ack = x .. "/" .. y
if mytable.ac[ack] ~= true then
mytable.ac[ack] = true
- if you.see_cell(marker:pos()) then
+ if you.see_cell(x, y) then
crawl.mpr("The volcano erupts! Nearby, a roof collapses.", "warning")
else
crawl.mpr("There is a rumble as the volcano erupts. The roof shakes.",
@@ -868,8 +895,14 @@ local function collapse_doorways (marker, mytable)
end
end
-local collapse_marker = function_machine ( {marker_type = "random", turns_min=30,
- turns_max=40, func=collapse_doorways, marker_params=mytable } )
+local collapse_marker = function_machine {
+ marker_type = "random",
+ turns_min=30,
+ turns_max=40,
+ func=collapse_doorways,
+ marker_params=mytable
+}
+
}}
KPROP: RXZ12< = no_rtele_into
SUBST: X = .