/[enigma]/enigma/data/levels/ant.lua
ViewVC logotype

Diff of /enigma/data/levels/ant.lua

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.11 by ant_39, Fri Feb 21 18:01:59 2003 UTC revision 1.12 by ant_39, Sat Mar 8 20:17:06 2003 UTC
# Line 1  Line 1 
1  -- base methods for ant's enigma maps  ------------------------------------------------------------------------
2  -- (c) 2002-2003 Petr Machata/ant_39  -- Copyright (C) 2002-2003 Petr Machata
 -- Licensed under GPL v2.0 or above  
3  --  --
4    -- This program is free software; you can redistribute it and/or
5    -- modify it under the terms of the GNU General Public License
6    -- as published by the Free Software Foundation; either version 2
7    -- of the License, or (at your option) any later version.
8    --  
9    -- This program is distributed in the hope that it will be useful,
10    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
11    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    -- GNU General Public License for more details.
13    --  
14    -- You should have received a copy of the GNU General Public License along
15    -- with this program; if not, write to the Free Software Foundation, Inc.,
16    -- 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
17    --
18    -- $Id$
19    ------------------------------------------------------------------------
20    --
21    -- This module contains a support functions for designing enigma maps.
22    -- There is a documentation available, please read it if you want
23    -- to find out how to use this (see <enigma-dir>/doc/ant_lua.html),
24    -- or look at how miscelaneous ant??.lua maps are done.
25    -- Any questions, bug reports or anything related to this module please send to:
26    --   my e-mail:              ant_39 at centrum.cz
27    --   enigma-devel ML:  enigma-devel at nongnu.org
28    --
29    -- revision history:
30  -- 2003-01-07 -- special floor types and train support  -- 2003-01-07 -- special floor types and train support
31  -- 2003-01-11 -- multiples support (groups of doors, bolders etc.)  -- 2003-01-11 -- multiples support (groups of doors, bolders etc.)
32  -- 2003-01-14 -- bugfixes and error reporting, some new map-creating funcs  -- 2003-01-14 -- bugfixes and error reporting, some new map-creating funcs
# Line 23  Line 48 
48  --   Big changes in interfacing many parent functions, completely rewritten trains and puzzle generators,  --   Big changes in interfacing many parent functions, completely rewritten trains and puzzle generators,
49  --   changes in multiples (there are more kinds, and interfacing changed).  --   changes in multiples (there are more kinds, and interfacing changed).
50  --   A bug in multichar cell key fixed  --   A bug in multichar cell key fixed
51    -- 2003-02-25 --
52    --   add_multi* now uses tinsert/tremove, functions that work with multiples adapted where neccessary
53    --   some comments fixed, few minor fixes across the source. warning().
54    -- 2003-03-08 --
55    --   support for parents that do not accept coordinates, default cell key meanings, updates in default
56    --   parent handling, debug mode
57    
58  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
59  -- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
61  -- x,y should be numbers, although chars and strings are generally also the right choice, if you avoid ','  -- for warning messages
62    function warning(text)
63       print("warning: [ant.lua]: "..text)
64    end
65    
66    -- for debug messages
67    local ldm={str="", cnt=0}
68    function debug(text)
69       if (DEBUG_MODE) then
70          if (%ldm.str~=text) then
71             if (%ldm.cnt>1) then print("debug: [ant.lua]: last message repeated "..%ldm.cnt.." times") end
72             if (text~="")   then print("debug: [ant.lua]: "..text) end
73             %ldm.str = text;
74             %ldm.cnt = 0;
75          else
76             %ldm.cnt = %ldm.cnt +1;
77          end
78       end
79    end
80    
81    -- x,y should be numbers, although chars and strings are generally also the right choice
82  function getkey(...)  function getkey(...)
83     local key=""     local key=""
84     for i=1,getn(arg) do     for i=1,getn(arg) do
# Line 46  end Line 97  end
97  function transform_coords(x,y,w,h)  function transform_coords(x,y,w,h)
98     local x, y = (x or 0), (y or 0)     local x, y = (x or 0), (y or 0)
99     local w, h = (w or 0), (h or 0)     local w, h = (w or 0), (h or 0)
100     if (x) then if (x<0) then x = level_width +x-1 end end     if (x<0) then x = level_width +x-1 end
101     if (y) then if (y<0) then y = level_height+y-1 end end     if (y<0) then y = level_height+y-1 end
102     if (w) then if (w<=0) then w = level_width +w end end     if (w<=0) then w = level_width +w end
103     if (h) then if (h<=0) then h = level_height+h end end     if (h<=0) then h = level_height+h end
104     return x,y,w,h     return x,y,w,h
105  end  end
106    
107  -- this couple of functions takes care of converting common tile coordinates to real coordinates of placed  -- this couple of functions takes care of converting common tile coordinates to real coordinates of placed
108  -- actor. It depends on the given actor_mode, which is being declared like this:  -- actor. It depends on the given actor_mode, which is being declared like this:
109  -- cells["O"]=cell{parent=cells["+"], item={face="ac-blackball", attr={player=0}, actor=ACTOR_MODE}}  -- cells["O"]=cell{parent=cells["+"], actor={face="ac-blackball", attr={player=0}, mode=ACTOR_MODE}}
110  --  --
111  -- the meaning of actor mode is as follows:  -- the meaning of actor mode is as follows:
112  -- value || x | y || meaning  -- value || x | y || meaning
# Line 87  end Line 138  end
138  -- VISUAL MAP CREATION  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- VISUAL MAP CREATION  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
139  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
140    
141    -- debug mode
142    -- in debug mode, ant.lua produces messages that inform you about the execution
143    DEBUG_MODE = nil
144    function debug_mode()
145       DEBUG_MODE = 1
146       debug("debug mode turned on")
147    end
148    function debug_mode_off()
149       debug("")
150       DEBUG_MODE = nil
151       warning("debug mode turned off")
152    end
153    
154  -- width of key in map definition  -- width of key in map definition
155  -- CELL_KEY_WIDTH means how many characters occupy single map cell. In several maps I strongly  -- CELL_KEY_WIDTH means how many characters occupy single map cell. In several maps I strongly
156  -- wanted this functions (cannonball for example), and after all here it is. Usable in maps with  -- wanted this functions (cannonball for example), and after all here it is. Usable in maps with
# Line 95  CELL_KEY_WIDTH = 1 Line 159  CELL_KEY_WIDTH = 1
159  function set_cell_key_width(w)  function set_cell_key_width(w)
160     if ( (type(w) == "number") and (w>0) and (floor(w)==w) ) then     if ( (type(w) == "number") and (w>0) and (floor(w)==w) ) then
161        CELL_KEY_WIDTH = w        CELL_KEY_WIDTH = w
162          debug("CELL_KEY_WIDTH is: "..w)
163        return w        return w
164     else     else
165        print("warning: [ant.lua]: CELL_KEY_WIDTH has to be positive whole number")        warning("CELL_KEY_WIDTH has to be positive whole number")
166        return -1        return -1
167     end     end
168  end  end
# Line 126  function guess_cell_key_width(cellfuncs) Line 191  function guess_cell_key_width(cellfuncs)
191        end        end
192     end     end
193    
194       debug("CELL_KEY_WIDTH guessed "..maxw)
195     return set_cell_key_width(maxw)     return set_cell_key_width(maxw)
196  end  end
197    
198  -- default cell parent is called before any of common cell parents  -- default cell parent is called before any of common cell parents
199  -- it may be a function(x,y) or a table of functions(x,y)  -- default parent is a table, where each element may be
200    --  + a function
201    --  + a string, in which case this is a key in cellfunc table
202    -- also set_default_parent can be called with a single function
203    -- or string argument. The table will be built from this.
204  DEFAULT_CELL_PARENT = nil  DEFAULT_CELL_PARENT = nil
205  function set_default_parent(func)  function set_default_parent(func)
206     if (type(func)=="function") then func = {func} end     if ((type(func)=="function")or(type(func)=="string")) then
207          func = {func}
208       end
209    
210     if (type(func)=="table") then     if (type(func)=="table") then
211        for key,f in func do        for key,f in func do
212           local ftype = type(f)           local ftype = type(f)
213           if (ftype~="function") then           if ((ftype~="function")and(ftype~="string")) then
214              print("warning: [ant.lua]: element "..key.." of DEFAULT_CELL_PARENT has to be function, not "..ftype.."!")              warning("element "..key.." of DEFAULT_CELL_PARENT has to be function or string, not "..ftype.."!")
215              return              return
216           end           end
217        end        end
218        DEFAULT_CELL_PARENT = func        DEFAULT_CELL_PARENT = func
219     else print("warning: [ant.lua]: default parent has to be function or table of functions")     else
220          warning("default parent has to be function, table of functions or string key")
221     end     end
222  end  end
223    
# Line 167  end Line 241  end
241  --  + stone - if present, the stone shall be added to defined position  --  + stone - if present, the stone shall be added to defined position
242  --  + floor - the same, but for floor  --  + floor - the same, but for floor
243  --  + item  - the same, but for item  --  + item  - the same, but for item
244  --   ++ actor - if item.actor~=0 is set, set_actor will be called instead of set_item.  --  + actor - the same, but for actor
245    --    ++ mode - see get_actor_x() and _y() functions
246    --  + pmode - parent arglist handling mode. Defaults to 0 and it means where to put (x,y) couple in arglist
247    --    ++ pmode = -1 => do not place the (x,y) couple to arglist
248    --    ++ pmode = +0 => place it before parent arguments
249  function cell(structure)  function cell(structure)
250     local cell0 = {}     local cell0 = {}
251    
# Line 181  function cell(structure) Line 259  function cell(structure)
259     -- parent is declared in this form: parent={{func1, arg1, arg2,...},...}     -- parent is declared in this form: parent={{func1, arg1, arg2,...},...}
260     -- if it's not, convert to this form     -- if it's not, convert to this form
261     local parent =(structure.parent or structure[1] or {})     local parent =(structure.parent or structure[1] or {})
262     if (type(parent)=="function") then parent = {parent} end  
263     for key,_ in parent do if (type(parent[key])=="function") then parent[key] = {parent[key]} end end     if (type(parent)=="function") then
264          parent = {parent}
265       elseif (type(parent)=="table") then
266          -- this is O.K.
267       else
268          warning("illegal: parent has to be a function, a table of functions")
269          warning("or a table of curry-functions, not "..type(parent))
270          parent={}
271       end
272    
273       for a=1,getn(parent) do
274          if (type(parent[a])=="function") then
275             parent[a] = {parent[a]}
276          elseif (type(parent[a])=="table") then
277             -- this is O.K. => a curry function call {func, arg1, arg2, ...}
278          else
279             warning("illegal: parent element id "..a.." should be a function or")
280             warning("a curry-function construction, not "..type(parent[a]))
281             parent[a]={function() end}
282          end
283       end
284    
285     --+ this functions manages calling various parent functions. Most functions are just func(x,y) or (x,y,something)     --+ this functions manages calling various parent functions. Most functions are just func(x,y) or (x,y,something)
286     --  but it's also possible to call ({{x1,y1},{x2,y2}}, something1, something2)     --  but it's also possible to call ({{x1,y1},{x2,y2}}, something1, something2)
287     --  This enables compatibility with and wrapping of functions form init.lua.     --  This enables compatibility with and wrapping of functions form init.lua.
288     --+ At the same moment, it's possible to declare some parametters in cell functions, like this:     --+ At the same moment, it's possible to declare some parametters in cell functions, like this:
289     --     cell1 = cell{parent={{func, par1}}}     --     cell1 = cell{parent={{func, par1}}}
290     --  and then call  --cell(par2)--  instead of  --func(par1, par2)--     --  and then call  --cell1(par2)--  instead of  --func(par1, par2)--
291     --  It may be used as a sort of curried functions from haskell, as far as my poor haskell knowledge says...     --  It may be used as a sort of curried functions from haskell, as far as my poor haskell knowledge says...
292     return function(...)     return function(...)
293               local xylist = tremove(arg, 1)               local xylist = tremove(arg, 1) or {}
294               local ret = nil               local ret = nil
295    
296               -- first, get rid of cell(x,y) notation and convert it to cell({{x0,y0}}) notation               -- first, get rid of cell(x,y) notation and convert it to cell({{x0,y0}}) notation
297               if (type(xylist)=="number") then               local xtp = type(xylist);
298                 if (xtp=="number") then
299                  xylist = {{xylist,tremove(arg,1)}}                  xylist = {{xylist,tremove(arg,1)}}
300               elseif ((type(xylist)=="table")and(type(xylist[1])=="number")) then               elseif ((xtp=="table")and(type(xylist[1])=="number")) then
301                  xylist = {xylist}                  xylist = {xylist}
302               end               end
303    
304               for _,tab0 in %parent do               for idx=1,getn(%parent) do
305                  --+ item is table. first item is function, the rest are the the function arguments                  local tab0 = %parent[idx]
306                  --+ first extract function from tab, then include arguments from function call to the                  --+ tab0 is table. first item is function, the rest are the the function arguments
307                    --+ first extract function from tab0, then include arguments from function call to the
308                  --  tab, add a place for x,y coordinates and call it. Eventually tab will look like this:                  --  tab, add a place for x,y coordinates and call it. Eventually tab will look like this:
309                  --    {x, y, pfpar1, pfpar2, ..., arg1, arg2, ...}                  --    {x, y, pfpar1, pfpar2, ..., arg1, arg2, ...}
310                  local func = tab0[1]                  local func = tab0[1]
311                  local tab = {0,0}                  local pmode= tab0.mode or %parent.mode or 0
312                    local tab = ((pmode==0) and {0,0}) or {}
313                  for a=2,getn(tab0) do tinsert(tab, tab0[a]) end                  for a=2,getn(tab0) do tinsert(tab, tab0[a]) end
314                  for a=1,getn(arg) do tinsert(tab, arg[a]) end                  for a=1,getn(arg) do tinsert(tab, arg[a]) end
315    
316                  -- and call a function                  -- and call a function
317                  for i=1,getn(xylist) do                  if (pmode==0) then
318                     tab[1],tab[2] = transform_coords(xylist[i][1], xylist[i][2])                     for i=1,getn(xylist) do
319                     ret = call(func, tab)                        tab[1],tab[2] = transform_coords(xylist[i][1], xylist[i][2])
320                          ret =  call(func, tab)
321                       end
322                    else
323                       ret =  call(func, tab)
324                  end                  end
325               end               end
326    
# Line 234  function cell(structure) Line 339  function cell(structure)
339            end            end
340  end  end
341    
   
342  -- width - this is width of the widest row of map  -- width - this is width of the widest row of map
343  function get_map_width(level)  function get_map_width(level)
344     local levelw = 0     local levelw = 0
# Line 258  function get_map_size(level) Line 362  function get_map_size(level)
362     return get_map_width(level), get_map_height(level)     return get_map_width(level), get_map_height(level)
363  end  end
364    
365    -- common map
366    -- if a key has no meaning declared in given 'cellfuncs', we'll look here
367    -- whether there is no 'default' meaning
368    -- look at the bottom of ant.lua to see the map
369    DEFAULT_KEY_MEANING={}
370    function map_cell_meaning(key, func)
371       DEFAULT_KEY_MEANING[key]=func
372    end
373    
374    -- use cells from default library in cellfuncs table
375    -- this function accepts a table of cellfuncs and arbitrary number of string keys as arguments
376    -- it loads the default keys to given cellfuncs table
377    function use_cells(funcs, ...)
378       for a=1,getn(arg) do
379          funcs[arg[a]] = DEFAULT_KEY_MEANING[arg[a]]
380       end
381    end
382    
383    -- this function accepts a cell key and cellfuncs table
384    -- it looks into that table and if there is no func with given key, it returns default value instead
385    function get_cell_func(key, funcs)
386       if (funcs[key]) then
387          return funcs[key]
388       elseif (DEFAULT_KEY_MEANING[key]) then
389          debug("using DEFAULT_KEY_MEANING of '"..key.."'")
390          return DEFAULT_KEY_MEANING[key]
391       else
392          warning("no default meaning found for map key '"..key.."'")
393          return nil
394       end
395    end
396    
397  -- this draws the map to the position [x0,y0]  -- this draws the map to the position [x0,y0]
398    -- map is array of strings. Each string is one line of result map, each char is one map square.
399  function draw_map(x0, y0, map, cellfuncs)  function draw_map(x0, y0, map, cellfuncs)
400     local funcs = cellfuncs or cells or {}; --we hope that if nil is passed, global cells is defined.     local funcs = cellfuncs or cells or {}; --we hope that if nil is passed, global cells is defined.
401       local map = map or {};                  --but we have no default variable for a map itself
402    
403     for y,str in map do     for y,str in map do
404        local width = floor(strlen(str)/CELL_KEY_WIDTH);        local width = floor(strlen(str)/CELL_KEY_WIDTH)
405    
406        for x = 1,width do        for x = 1,width do
407           local key = strsub(str, (x-1)*CELL_KEY_WIDTH+1, x*CELL_KEY_WIDTH)           local key = strsub(str, (x-1)*CELL_KEY_WIDTH+1, x*CELL_KEY_WIDTH)
          local func = funcs[key]  
          local ftype = type(func)  
408           local rx, ry = x+x0-1, y+y0-1           local rx, ry = x+x0-1, y+y0-1
409    
410           -- call default parents           -- call default parents
411           if (DEFAULT_CELL_PARENT) then           if (DEFAULT_CELL_PARENT) then
412              for _,dpfunc in DEFAULT_CELL_PARENT do dpfunc(rx, ry) end              for _,val in DEFAULT_CELL_PARENT do
413                   local dpfunc=0
414                   if (type(val)=="string") then
415                      dpfunc=get_cell_func(val, funcs)
416                   else
417                      dpfunc=val
418                   end
419    
420                   if (type(dpfunc)=="function") then
421                      dpfunc(rx, ry)
422                   else
423                      warning("unknown default parent for this key:")
424                      warning(val)
425                   end
426                end
427           end           end
428    
429           -- call common cell function           -- call common cell function
430             local func = get_cell_func(key, funcs)
431             local ftype = type(func)
432           if (ftype == "function") then           if (ftype == "function") then
433              func(rx, ry)              func(rx, ry)
434           elseif (ftype == "nil") then           elseif (ftype == "nil") then
435              print("warning: [ant.lua]: function doesn't exist for map element '"..key.."'.")              warning("function doesn't exist for map element '"..key.."'.")
436           else           else
437              print("warning: [ant.lua]: cell element '"..key.."' is not a function, it's "..ftype..".")              warning("cell element '"..key.."' is not a function, it's "..ftype..".")
438           end           end
439        end        end
440     end     end
# Line 293  function create_world_by_map(level, cell Line 445  function create_world_by_map(level, cell
445     local flavor = oxyd_default_flavor     local flavor = oxyd_default_flavor
446     local levelw, levelh = get_map_size(level)     local levelw, levelh = get_map_size(level)
447    
448       debug("creating world ["..levelw.."x"..levelh.."]")
449     create_world(levelw, levelh)     create_world(levelw, levelh)
450     oxyd_default_flavor = flavor or oxyd_default_flavor or "b"     oxyd_default_flavor = flavor or oxyd_default_flavor or "b"
451    
# Line 365  function set_funcs(fillfunc, poslist) Line 518  function set_funcs(fillfunc, poslist)
518     if (type(fillfunc)=="function") then fillfunc={fillfunc} end     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
519    
520     for _,func in fillfunc do     for _,func in fillfunc do
521        for i,xy in poslist do        for i=1,getn(poslist) do
522           func(transform_coords(xy[1], xy[2]))           func(transform_coords(poslist[i][1], poslist[i][2]))
523        end        end
524     end     end
525  end  end
# Line 605  end Line 758  end
758  -- group: object group table  -- group: object group table
759  -- attribs: object attributes  -- attribs: object attributes
760  function add_multistone(x, y, face, group, attribs)  function add_multistone(x, y, face, group, attribs)
761     local bc = getn(group)+1     local attribs = attribs or {}
762     local bn = face..bc     attribs["name"] = attribs.name or (face..(getn(group)+1))
763       tinsert(group, set_stone(face, x, y, attribs))
    attribs = attribs or {}  
    attribs["name"] = bn  
   
    group[bc] = set_stone(face, x, y, attribs)  
764  end  end
765    
766  -- add a floor to a group  -- add a floor to a group
# Line 619  end Line 768  end
768  -- group: object group table  -- group: object group table
769  -- attribs: object attributes  -- attribs: object attributes
770  function add_multifloor(x, y, face, group, attribs)  function add_multifloor(x, y, face, group, attribs)
771     local bc = getn(group)+1     local attribs = attribs or {}
772     local bn = face..bc     attribs["name"] = attribs.name or (face..(getn(group)+1))
773       tinsert(group, set_floor(face, x, y, attribs))
    attribs = attribs or {}  
    attribs["name"] = bn  
   
    group[bc] = set_floor(face, x, y, attribs)  
774  end  end
775    
776  -- add an item to a group  -- add an item to a group
# Line 634  end Line 779  end
779  -- attribs: object attributes  -- attribs: object attributes
780  function add_multiitem(x, y, face, group, attribs)  function add_multiitem(x, y, face, group, attribs)
781     local attribs = attribs or {}     local attribs = attribs or {}
782     attribs["name"] = face..(getn(group)+1)     attribs["name"] = attribs.name or (face..(getn(group)+1))
783     tinsert(group, set_item(face, x, y, attribs))     tinsert(group, set_item(face, x, y, attribs))
784  end  end
785    
# Line 642  end Line 787  end
787  -- face: this is floor face  -- face: this is floor face
788  -- group: object group table  -- group: object group table
789  -- attribs: object attributes  -- attribs: object attributes
790  function add_multiactor(x, y, face, group, opts, actor_mode)  function add_multiactor(x, y, face, group, attribs, actor_mode)
791       local attribs = attribs or {}
792     local actor_mode = actor_mode or 3     local actor_mode = actor_mode or 3
793     local bc = getn(group)+1     attribs["name"] = attribs.name or (face..(getn(group)+1))
794     local bn = face..bc     tinsert(group, set_actor(face, get_actor_x(x, actor_mode), get_actor_y(y, actor_mode), attribs))
   
    opts = opts or {}  
    opts["name"] = bn  
   
    group[bc] = set_actor(face, get_actor_x(x, actor_mode or 1), get_actor_y(y, actor_mode), opts)  
795  end  end
796    
797  -- for generic multiples, this only stores cell coordinates and tag information  -- for generic multiples, this only stores cell coordinates and tag information
# Line 666  end Line 807  end
807  -- another generic multiple  -- another generic multiple
808  -- this stores the result of given function(x,y) to table  -- this stores the result of given function(x,y) to table
809  function add_multiobject(x, y, func, group)  function add_multiobject(x, y, func, group)
810     local bc = getn(group)+1     tinsert(group, func(x, y))
    group[bc] = func(x, y)  
811  end  end
812    
813  -- add the rubber band between all objects in group 1 and all objects in group 2  -- add the rubber band between all objects in group 1 and all objects in group 2
814  -- that is, each object from gr1 will be connected with each object from gr2  -- that is, each object from gr1 will be connected with each object from gr2
815  function add_rubber_bands(gr1, gr2, strength, length)  function add_rubber_bands(gr1, gr2, strength, length)
816     for _,obj1 in gr1 do     for i=1,getn(gr1) do
817        for _,obj2 in gr2 do        for j=1,getn(gr2) do
818           AddRubberBand(obj1, obj2, strength, length)           AddRubberBand(gr1[i], gr2[j], strength, length)
819        end        end
820     end     end
821  end  end
# Line 683  end Line 823  end
823  -- add pairs: 1st object from gr1 will be connected with 1st from gr2 and so on  -- add pairs: 1st object from gr1 will be connected with 1st from gr2 and so on
824  -- requires same sized groups, of course...  -- requires same sized groups, of course...
825  function add_rubber_band_pairs(gr1, gr2, strength, length)  function add_rubber_band_pairs(gr1, gr2, strength, length)
826     for key1,obj1 in gr1 do     for i=1,getn(gr1) do
827        AddRubberBand(obj1, gr2[key1], strength, length)        AddRubberBand(gr1[i], gr2[i], strength, length)
828     end     end
829  end  end
830    
# Line 711  end Line 851  end
851    
852  -- send message to each object in group  -- send message to each object in group
853  function send_group_message(group, message, third)  function send_group_message(group, message, third)
854     for _,item in group do     for i=1,getn(group) do
855        enigma.SendMessage(item, message, third)        enigma.SendMessage(group[i], message, third)
856     end     end
857  end  end
858    
859    -- send a message to named object
860    function send_message_named(objname, message, third)
861       enigma.SendMessage(enigma.GetNamedObject(objname), message, third)
862    end
863    
864  -- set attribute to each of the objects in group  -- set attribute to each of the objects in group
865  function set_group_attribs(group, attribs)  function set_group_attribs(group, attribs)
866     for _,item in group do     for i=1,getn(group) do
867        set_attribs(item, attribs)        set_attribs(group[i], attribs)
868     end     end
869  end  end
870    
# Line 732  end Line 877  end
877  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
878    
879  -- creating trains:  -- creating trains:
880  --  each train is defined by two tables:  --  each train is defined by two tables:
881  --   +table of cells that the path consists of  --   +table of cells that the path consists of
882  --   +table of engines - path constructors and destructors  --   +table of engines - path constructors and destructors
883  --  --
884  -- basic idea is as follows:  -- basic idea is as follows:
885  --  in each tick, each of engines is moved to next cell in its path  --  in each tick, each of engines is moved to next cell on its path
886  --  each engine marks its rail - it sets a tag number of a current cell to some value  --  each engine marks its rail - it sets a tag number of a current cell to some value
887  --  constructors set tag number to 1 destructors to 0  --  constructors set tag number to 1, destructors to 0
888  --  constructor will only move to such a path cell, that has different tag from its own tag  --  constructor will only move to such a path cell, that has different tag from its own tag
889  --  that is, constructors will only move to non-1-tagged cells  --  that is, constructors will only move to non-1-tagged cells
890  --  and destructors will never move to cells tagged as zero  --  and destructors will never move to cells tagged to zero
891  --  and as each move means new tag value, the train keeps going forward  --  and as each move means new tag value, the train keeps going forward
892  --  --
893  -- how to setup a rail  -- how to setup a rail
# Line 756  end Line 901  end
901  --    cells["c"]=cell{parent={cells["_"], {add_multicell, loco, construct}}}  --    cells["c"]=cell{parent={cells["_"], {add_multicell, loco, construct}}}
902  --    cells["d"]=cell{parent={cells["!"], {add_multicell, loco, destruct}}}  --    cells["d"]=cell{parent={cells["!"], {add_multicell, loco, destruct}}}
903  --  --
904  -- that means:  -- that means:
905  --  cells marked "!" are part of path and are tagged to zero  --  cells marked "!" are part of path and are tagged to zero
906  --  cells marked "_" are also part of path, but are tagged to 1 instead  --  cells marked "_" are also part of path, but are tagged to 1 instead
907  --  cells marked "c" are part of engine ('loco' in example), and are tagged by function 'construct'  --  cells marked "c" are part of engine ('loco' in example), and are tagged by function 'construct'
908  --  cells marked "d" are also engines, but are tagged by function 'destruct'  --  cells marked "d" are also engines, but are tagged by function 'destruct'
909  --  --
910  -- you also need to declare tag-functions 'construct' and 'destruct', and also cells["."] and cells["'"] have  -- you also need to declare tag-functions 'construct' and 'destruct', and also cells["."] and cells["'"] have
911  -- to be defined somewhere. cells["."] is empty cell, if there is no train - abyss, a water or similar  -- to be defined somewhere. cells["."] is empty cell, if there is no train - abyss, a water or similar
912  -- cells["'"] is a surface of train - fl-normal, fl-wood, you choose.  -- cells["'"] is a surface of train - fl-normal, fl-wood, you choose.
# Line 809  end Line 954  end
954  --  cells["*"] - all puzzle stones are marked as asterisk in level map  --  cells["*"] - all puzzle stones are marked as asterisk in level map
955  --  --
956  --   puzzles = {};  -- create a table of puzzle stones  --   puzzles = {};  -- create a table of puzzle stones
957  --   cells["*"]=cell{parent={{add_multicell, puzzles}}}  -- use generic multiple to add a cell to table  --   cells["*"]=cell{{{add_multicell, puzzles}}}  -- use generic multiple to add a cell to table
958  --  --
959  -- and finally, at the end of the level:  -- and finally, at the end of the level:
960  --   render_puzzles(puzzles)  -- place information from puzzle table to map  --   render_puzzles(puzzles)  -- place information from puzzle table to level
961    --
962    -- if a puzzle cell is marked with tag=2:
963    --   cells["#"]=cell{{{add_multicell, puzzles, 2}}}
964    -- then the puzzle won't be generated on given map element, but it's neighbors will have their sockets
965    -- opened in this direction like there should be one.
966    
967    
968  -- this functions is called at the end of level file. It accepts  -- this functions is called at the end of level file. It accepts
969  --  tab, which is a list of registered puzzle cells  --  tab, which is a list of registered puzzle cells
970  --  generatorfunc, which is a cell[] function to add the floor or items to each registered cell  --  generatorfunc, which is a cell[] function to add the floor or items to each registered cell
971  -- the function goes through all registered cells, observing their neighbors  -- the function goes through all registered cells, observing their neighbors
972  -- and adding right puzzle stones to right places  -- and adding right puzzle stones to right places
973  function render_puzzles (tab, generatorfunc)  function render_puzzles (tab, generatorfunc)
974     for _,val in tab do     for _,val in tab do
# Line 834  function render_puzzles (tab, generatorf Line 984  function render_puzzles (tab, generatorf
984        end        end
985    
986        dostring("puz = PUZ_"..up..right..down..left)        dostring("puz = PUZ_"..up..right..down..left)
987        puzzle(x, y, puz)        if (val.tag~=2) then
988             puzzle(x, y, puz)
989          end
990     end     end
991  end  end
992    
# Line 850  end Line 1002  end
1002  -- and maybe also some others that I do not recall now :)  -- and maybe also some others that I do not recall now :)
1003  -- Note, that basic syntax remain intact, so at first glance no changes are visible!  -- Note, that basic syntax remain intact, so at first glance no changes are visible!
1004  -- Wrapped functions are a lot slower, empirically nearly 3.5 times. Not a great deal,  -- Wrapped functions are a lot slower, empirically nearly 3.5 times. Not a great deal,
1005  -- as LUA is really fast.  -- as LUA is really fast, and the same for enigma. Tested on rather slow 166MHz AMD,
1006    -- 80 megs of memory, Win95 - you won't notice extra time spent by loading a level.
1007    
1008  -- stones  -- stones
1009  oxyd =     cell{{{oxyd}}}  oxyd =     cell{oxyd}
1010  fakeoxyd = cell{{{fakeoxyd}}}  fakeoxyd = cell{fakeoxyd}
1011  oneway =   cell{{{oneway}}}  oneway =   cell{oneway}
1012  laser =    cell{{{laser}}}  laser =    cell{laser}
1013  mirrorp =  cell{{{mirrorp}}}  mirrorp =  cell{mirrorp}
1014  mirror3 =  cell{{{mirror3}}}  mirror3 =  cell{mirror3}
1015  puzzle =   cell{{{puzzle}}}  puzzle =   cell{puzzle}
1016  switch =   cell{{{switch}}}  switch =   cell{switch}
1017    
1018  -- floors  -- floors
1019  abyss =    cell{{{abyss}}}  abyss =    cell{abyss}
1020  hollow =   cell{{{hollow}}}  hollow =   cell{hollow}
1021    hill=      cell{item="it-hill"}
1022    
1023  -- items  -- items
1024  Document = cell{{{Document}}}  Document = cell{Document}
1025  hammer =   cell{{{hammer}}}  hammer =   cell{hammer}
1026  dynamite = cell{{{dynamite}}}  dynamite = cell{dynamite}
1027  bomb =     cell{{{bomb}}}  bomb =     cell{bomb}
1028  shogundot= cell{{{shogundot}}}  shogundot= cell{shogundot}
1029  keya =     cell{{{keya}}}  keya =     cell{keya}
1030  keyb =     cell{{{keyb}}}  keyb =     cell{keyb}
1031  keyc =     cell{{{keyc}}}  keyc =     cell{keyc}
1032  shogundot1=cell{{{shogundot, 1}}}  shogundot1=cell{{{shogundot, 1}}}
1033  shogundot2=cell{{{shogundot, 2}}}  shogundot2=cell{{{shogundot, 2}}}
1034  shogundot3=cell{{{shogundot, 3}}}  shogundot3=cell{{{shogundot, 3}}}
1035  Wormhole = cell{{{Wormhole}}}  Wormhole = cell{Wormhole}
1036  doorh =    cell{{{doorh}}}  doorh =    cell{doorh}
1037  doorv =    cell{{{doorv}}}  doorv =    cell{doorv}
1038  gradient = cell{{{gradient}}}  gradient = cell{gradient}
1039    
1040  -- lower case equivalents  -- lower case equivalents
1041  document = Document  document = Document
1042  wormhole = Wormhole  wormhole = Wormhole
1043    
1044    
1045    
1046    
1047    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1048    -- MEANINGS FOR COMMON CELL KEYS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1049    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
1050    -- here are declarations for default cell bindings
1051    
1052    -- bindings based on init.lua functions
1053    map_cell_meaning(".", abyss)
1054    map_cell_meaning("0", oxyd)
1055    
1056    -- common constructions
1057    map_cell_meaning("W", cell{stone="st-wood"})
1058    map_cell_meaning("=", cell{stone="st-glass"})
1059    map_cell_meaning("X", cell{stone="st-grate1"})
1060    map_cell_meaning("~", cell{stone="st-timer"})
1061    map_cell_meaning("o", cell{actor={"ac-whiteball-small", {player=0, mouseforce=1}}})
1062    map_cell_meaning("O", cell{actor={"ac-blackball", {player=0, mouseforce=1}}})
1063    
1064    -- presets
1065    function meditation_mode()
1066       map_cell_meaning("O", hollow)
1067    end
1068    
1069    function grass_mode()
1070       map_cell_meaning(" ", cell{floor="fl-leaves"})
1071       map_cell_meaning("#", cell{stone="st-rock1"})
1072    end
1073    
1074    -- maybe in a future, there will be a possibility to integrate Nat's mazes into maps
1075    function maze_mode()
1076       Require("levels/natmaze.lua")
1077       --map_cell_meaning("!", )
1078    end

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.12

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26