/[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.10 by ant_39, Wed Feb 12 18:53:44 2003 UTC revision 1.11 by ant_39, Fri Feb 21 18:01:59 2003 UTC
# Line 5  Line 5 
5  -- 2003-01-07 -- special floor types and train support  -- 2003-01-07 -- special floor types and train support
6  -- 2003-01-11 -- multiples support (groups of doors, bolders etc.)  -- 2003-01-11 -- multiples support (groups of doors, bolders etc.)
7  -- 2003-01-14 -- bugfixes and error reporting, some new map-creating funcs  -- 2003-01-14 -- bugfixes and error reporting, some new map-creating funcs
8  -- 2003-02-09 --  -- 2003-02-09 --
9  --   many changes. Fixes of rubberband functions, fixes in multiples support, some interfaces changed  --   many changes. Fixes of rubberband functions, fixes in multiples support, some interfaces changed
10  --   These changes require also fixes in several levels, but it's more logic this way. Besides this, it's  --   These changes require also fixes in several levels, but it's more logic this way. Besides this, it's
11  --   finally possible to call functions from init.lua or any functions declared like func(x, y, args),  --   finally possible to call functions from init.lua or any functions declared like func(x, y, args),
# Line 13  Line 13 
13  --   While I was rewriting, I finally implemented multichar maps, which I planned since the beginning...  --   While I was rewriting, I finally implemented multichar maps, which I planned since the beginning...
14  -- 2003-02-11 -- fixes in filling functions  -- 2003-02-11 -- fixes in filling functions
15  -- 2003-02-12 -- cell() now returns last created object; functional-drawing functions accept table; and fixes  -- 2003-02-12 -- cell() now returns last created object; functional-drawing functions accept table; and fixes
16    -- 2003-02-20 --
17    --   major rewrite of cell() function. This require also changes in *all* (~30) levels so far
18    --   I'll do it now, until there is just a few things to change... Later it could be too late
19    --   and these changes are really necessary
20    --   These changes include rewrites in parent function handling, so that it now supports a kind
21    --   of curried functions from haskell. Also you can use the coordlists instead of simple coords and
22    --   place several elements at once. And so on...
23    --   Big changes in interfacing many parent functions, completely rewritten trains and puzzle generators,
24    --   changes in multiples (there are more kinds, and interfacing changed).
25    --   A bug in multichar cell key fixed
26    
27  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
28  -- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
29  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30  -- x,y should be numbers, although chars and strings are generally also the right choice, if you avoid ','  -- x,y should be numbers, although chars and strings are generally also the right choice, if you avoid ','
31  function getkey(x,y)  function getkey(...)
32     return x..","..y     local key=""
33       for i=1,getn(arg) do
34          if (i>1) then key=key.."\0" end
35          key=key..arg[i]
36       end
37       return key
38    end
39    
40    -- each ant.lua function, that accepts coordinates, may be
41    -- called with negative coordinates as well. That in fact
42    -- means to place the object relatively to lower right
43    -- corner.
44    --  location [-1,-1] means [levelw, levelh]
45    --  size [0,0] means [levelw, levelh]
46    function transform_coords(x,y,w,h)
47       local x, y = (x or 0), (y or 0)
48       local w, h = (w or 0), (h or 0)
49       if (x) then if (x<0) then x = level_width +x-1 end end
50       if (y) then if (y<0) then y = level_height+y-1 end end
51       if (w) then if (w<=0) then w = level_width +w end end
52       if (h) then if (h<=0) then h = level_height+h end end
53       return x,y,w,h
54  end  end
55    
56  -- 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
# Line 27  end Line 58  end
58  -- cells["O"]=cell{parent=cells["+"], item={face="ac-blackball", attr={player=0}, actor=ACTOR_MODE}}  -- cells["O"]=cell{parent=cells["+"], item={face="ac-blackball", attr={player=0}, actor=ACTOR_MODE}}
59  --  --
60  -- the meaning of actor mode is as follows:  -- the meaning of actor mode is as follows:
61  -- value || a | x | y || meaning  -- value || x | y || meaning
62  -- ------++---+---+---++--------  -- ------++---+---++--------
63  --  0/nil|| 0 |  any  || this is not actor, but an item  --  0    || 0 | 0 || actor is placed to left top corner of tile
64  --  1    || 1 | 0 | 0 || this is actor, centered in tile  --  1    || 1 | 0 || actor is centered horizontally on tile
65  --  3    || 1 | 1 | 0 || this is actor, centered vertically  --  2    || 0 | 1 || actor is centered vertically on tile
66  --  5    || 1 | 0 | 1 || this is actor, centered horizontally  --  3    || 1 | 1 || actor is centered in tile
 --  7    || 1 | 1 | 1 || this is actor, placed to left top corner of tile  
67  --  --
68  function get_actor_x(x, actor_mode)  function get_actor_x(x, actor_mode)
69     if ((actor_mode == 3)or(actor_mode == 7)) then     if ((actor_mode == 0)or(actor_mode == 2)) then
70        return x        return x
71     else     else
72        return x + 0.5        return x + 0.5
# Line 44  function get_actor_x(x, actor_mode) Line 74  function get_actor_x(x, actor_mode)
74  end  end
75    
76  function get_actor_y(y, actor_mode)  function get_actor_y(y, actor_mode)
77     if ((actor_mode == 5)or(actor_mode == 7)) then     if ((actor_mode == 0)or(actor_mode == 1)) then
78        return y        return y
79     else     else
80        return y + 0.5        return y + 0.5
# Line 57  end Line 87  end
87  -- VISUAL MAP CREATION  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- VISUAL MAP CREATION  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
88  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
89    
 TRANSPOSE_MAP = 1  
 NO_TRANSPOSE_MAP = not(TRANSPOSE_MAP)  
   
90  -- width of key in map definition  -- width of key in map definition
91  -- 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
92  -- 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
93  -- wide variety of different surfaces.  -- wide variety of different surfaces.
94  CELL_KEY_WIDTH = 1  CELL_KEY_WIDTH = 1
95  function cell_key_width(w)  function set_cell_key_width(w)
96     if ( (type(w) == "number") and (w>0) and (floor(w)==w) ) then     if ( (type(w) == "number") and (w>0) and (floor(w)==w) ) then
97        CELL_KEY_WIDTH = w        CELL_KEY_WIDTH = w
98        return w        return w
# Line 99  function guess_cell_key_width(cellfuncs) Line 126  function guess_cell_key_width(cellfuncs)
126        end        end
127     end     end
128    
129     return cell_key_width(maxw)     return set_cell_key_width(maxw)
130    end
131    
132    -- default cell parent is called before any of common cell parents
133    -- it may be a function(x,y) or a table of functions(x,y)
134    DEFAULT_CELL_PARENT = nil
135    function set_default_parent(func)
136       if (type(func)=="function") then func = {func} end
137       if (type(func)=="table") then
138          for key,f in func do
139             local ftype = type(f)
140             if (ftype~="function") then
141                print("warning: [ant.lua]: element "..key.." of DEFAULT_CELL_PARENT has to be function, not "..ftype.."!")
142                return
143             end
144          end
145          DEFAULT_CELL_PARENT = func
146       else print("warning: [ant.lua]: default parent has to be function or table of functions")
147       end
148  end  end
149    
150  -- each item:  -- each item:
# Line 107  end Line 152  end
152  --  + attr - set of attributes of given object  --  + attr - set of attributes of given object
153  function cell_item(it)  function cell_item(it)
154     local n_it = {}     local n_it = {}
155     n_it.face = (it.face or "")     local ittype = type(it)
156     n_it.attr = (it.attr or {})  
157       if (type(it)=="string") then it = {it} end
158    
159       n_it.face = (it.face or it[1] or "")
160       n_it.attr = (it.attr or it[2] or {})
161       n_it.mode = (it.mode or it[3] or 3)
162    
163     return n_it     return n_it
164  end  end
165    
# Line 124  function cell(structure) Line 175  function cell(structure)
175     cell0.floor = cell_item(structure.floor or {})     cell0.floor = cell_item(structure.floor or {})
176     cell0.stone = cell_item(structure.stone or {})     cell0.stone = cell_item(structure.stone or {})
177     cell0.item =  cell_item(structure.item or {})     cell0.item =  cell_item(structure.item or {})
178       cell0.actor = cell_item(structure.actor or {})
179    
180     local parent =structure.parent     -- get parent
181     local partype=type(parent)     -- parent is declared in this form: parent={{func1, arg1, arg2,...},...}
182       -- if it's not, convert to this form
183       local parent =(structure.parent or structure[1] or {})
184       if (type(parent)=="function") then parent = {parent} end
185       for key,_ in parent do if (type(parent[key])=="function") then parent[key] = {parent[key]} end end
186    
187       --+ this functions manages calling various parent functions. Most functions are just func(x,y) or (x,y,something)
188       --  but it's also possible to call ({{x1,y1},{x2,y2}}, something1, something2)
189       --  This enables compatibility with and wrapping of functions form init.lua.
190       --+ At the same moment, it's possible to declare some parametters in cell functions, like this:
191       --     cell1 = cell{parent={{func, par1}}}
192       --  and then call  --cell(par2)--  instead of  --func(par1, par2)--
193       --  It may be used as a sort of curried functions from haskell, as far as my poor haskell knowledge says...
194       return function(...)
195                 local xylist = tremove(arg, 1)
196                 local ret = nil
197    
198     return function(x, y)               -- first, get rid of cell(x,y) notation and convert it to cell({{x0,y0}}) notation
199               if (%partype=="nil") then               if (type(xylist)=="number") then
200                  -- no parent, do nothing!                  xylist = {{xylist,tremove(arg,1)}}
201               elseif (%partype=="function") then               elseif ((type(xylist)=="table")and(type(xylist[1])=="number")) then
202                  -- parent is single function. let's call it!                  xylist = {xylist}
                 %structure.parent(x,y)  
              elseif (%partype=="table") then  
                 -- parent is table. look closer...  
                 for _,item in %parent do  
                    if (type(item)=="function") then  
                       -- item is function. call it!  
                       item(x,y)  
                    elseif (type(item)=="table") then  
                       -- item is table. first item has to be of type "function"  
                       -- the rest are the the function arguments  
                       --  
                       -- first construct global function __tmpfunc0, which calls defined  
                       -- function from item[] and passes coordinates and arguments, like this:  
                       --   item[1](x, y, item[2], item[3], ...)  
                       -- the call it and finally erase it  
                       -- well, it's dirty enough, but it works..  
                       local counter = 0  
                       local funccall = "__tmpfunc0 = function(uitem, ux, uy) "  
                       --  
                       for key,_ in item do  
                          if (counter > 0) then funccall = funccall .. ", " end  
                          funccall = funccall .. "uitem["..key.."]"  
                          if (counter == 0) then funccall = funccall .. "(ux, uy" end  
                          counter = counter + 1  
                       end  
                       funccall = funccall .. ") end"  
                       --  
                       dostring(funccall)  
                       __tmpfunc0(item, x, y)  
                       __tmpfunc0 = nil;  
                    else  
                       -- item is something else  
                       print("warning: [ant.lua]: illegal parent item type:", type(item))  
                    end  
                 end  
              else  
                 -- parent is something else  
                 print("warning: [ant.lua]: ilegal parent type:", %partype)  
203               end               end
204    
205               --map elements               for _,tab0 in %parent do
206               local ret = nil                  --+ item is table. first item is function, the rest are the the function arguments
207                    --+ first extract function from tab, then include arguments from function call to the
208               if (%structure.stone) then ret = set_stone(%cell0.stone.face, x, y, %cell0.stone.attr) end                  --  tab, add a place for x,y coordinates and call it. Eventually tab will look like this:
209               if (%structure.floor) then ret = set_floor(%cell0.floor.face, x, y, %cell0.floor.attr) end                  --    {x, y, pfpar1, pfpar2, ..., arg1, arg2, ...}
210               if (%structure.item) then                  local func = tab0[1]
211                  if ((%structure.item.actor or 0) == 0) then                  local tab = {0,0}
212                     ret = set_item(%cell0.item.face, x, y, %cell0.item.attr)                  for a=2,getn(tab0) do tinsert(tab, tab0[a]) end
213                  else                  for a=1,getn(arg) do tinsert(tab, arg[a]) end
214                     ret = set_actor(%cell0.item.face,  
215                                     get_actor_x(x, %structure.item.actor),                  -- and call a function
216                                     get_actor_y(y, %structure.item.actor),                  for i=1,getn(xylist) do
217                                     %cell0.item.attr)                     tab[1],tab[2] = transform_coords(xylist[i][1], xylist[i][2])
218                       ret = call(func, tab)
219                  end                  end
220               end               end
221    
222                 --process common map elements
223                 for i=1,getn(xylist) do
224                    local x,y = transform_coords(xylist[i][1], xylist[i][2])
225                    if (%structure.stone) then ret = set_stone(%cell0.stone.face, x, y, %cell0.stone.attr) end
226                    if (%structure.floor) then ret = set_floor(%cell0.floor.face, x, y, %cell0.floor.attr) end
227                    if (%structure.item ) then ret = set_item (%cell0.item.face , x, y, %cell0.item.attr ) end
228                    if (%structure.actor) then
229                       local ax, ay = get_actor_x(x, %cell0.actor.mode), get_actor_y(y, %cell0.actor.mode)
230                       ret = set_actor(%cell0.actor.face, ax, ay, %cell0.actor.attr)
231                    end
232                 end
233               return ret               return ret
234            end            end
235  end  end
236    
237  -- these return... voila... the sizes of the map  
238  -- width - this is width of the widest row of map  -- width - this is width of the widest row of map
239  function get_map_width(level)  function get_map_width(level)
240     local levelw = 0     local levelw = 0
# Line 218  function get_map_size(level) Line 259  function get_map_size(level)
259  end  end
260    
261  -- this draws the map to the position [x0,y0]  -- this draws the map to the position [x0,y0]
262  function draw_map(x0, y0, map, cellfuncs, swap_coords)  function draw_map(x0, y0, map, cellfuncs)
263     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.
264    
265     for y,str in map do     for y,str in map do
# Line 228  function draw_map(x0, y0, map, cellfuncs Line 269  function draw_map(x0, y0, map, cellfuncs
269           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)
270           local func = funcs[key]           local func = funcs[key]
271           local ftype = type(func)           local ftype = type(func)
272             local rx, ry = x+x0-1, y+y0-1
273    
274             -- call default parents
275             if (DEFAULT_CELL_PARENT) then
276                for _,dpfunc in DEFAULT_CELL_PARENT do dpfunc(rx, ry) end
277             end
278    
279             -- call common cell function
280           if (ftype == "function") then           if (ftype == "function") then
281              if (swap_coords) then              func(rx, ry)
                func(y+y0-1, x+x0-1)  
             else  
                func(x+x0-1, y+y0-1)  
             end  
282           elseif (ftype == "nil") then           elseif (ftype == "nil") then
283              print("warning: [ant.lua]: function doesn't exist for map element '"..key.."'.")              print("warning: [ant.lua]: function doesn't exist for map element '"..key.."'.")
284           else           else
# Line 245  function draw_map(x0, y0, map, cellfuncs Line 289  function draw_map(x0, y0, map, cellfuncs
289  end  end
290    
291  -- this prepares enigma world and draws given map  -- this prepares enigma world and draws given map
292  -- swap_coords is optional  function create_world_by_map(level, cellfuncs)
 function create_world_by_map(level, cellfuncs, swap_coords)  
293     local flavor = oxyd_default_flavor     local flavor = oxyd_default_flavor
294     local levelw, levelh = get_map_size(level)     local levelw, levelh = get_map_size(level)
295    
    if (swap_coords==TRANSPOSE_MAP) then  
       temp, levelw, levelh = levelw, levelh, temp  
    end  
   
296     create_world(levelw, levelh)     create_world(levelw, levelh)
297     oxyd_default_flavor = flavor or oxyd_default_flavor or "b"     oxyd_default_flavor = flavor or oxyd_default_flavor or "b"
298    
299     draw_map(0, 0, level, cellfuncs, swap_coords)     draw_map(0, 0, level, cellfuncs)
300  end  end
301    
302  -- to fill each square of map with given function  
303    
304    
305    
306    
307    
308    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
309    -- FUNCTIOAL MAP DRAWING - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
310    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
311    -- functions in this section are much like those defined in init.lua. Major difference
312    -- is that these functions accept a function as an argument. So, it's possible to call
313    -- given function with several coordinates at once. Just one single prerequisity -
314    -- the function must require at most two arguments, and they have to be coordinates
315    --   func(x,y, non_required_arguments)
316    
317    -- fill each square of map with given function
318  function fill_world_func(fillfunc, x0, y0, w, h)  function fill_world_func(fillfunc, x0, y0, w, h)
319     local x0, y0 = (x0 or 0), (y0 or 0)     local x0,y0,w,h = transform_coords(x0, y0, w, h)
    local w, h = (w or 0), (h or 0)  
    if w<=0 then w = level_width+w end  
    if h<=0 then h = level_height+h end  
320     if (type(fillfunc)=="function") then fillfunc={fillfunc} end     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
321    
322     for _,func in fillfunc do     for _,func in fillfunc do
# Line 279  end Line 330  end
330    
331  -- to draw border of map by given function  -- to draw border of map by given function
332  function draw_border_func(fillfunc, x0, y0, w, h)  function draw_border_func(fillfunc, x0, y0, w, h)
333     local x0, y0 = (x0 or 0), (y0 or 0)     local x0,y0,w,h = transform_coords(x0, y0, w, h)
    local w, h = (w or 0), (h or 0)  
    if w<=0 then w = level_width+w end  
    if h<=0 then h = level_height+h end  
334     if (type(fillfunc)=="function") then fillfunc={fillfunc} end     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
335    
336     for _,func in fillfunc do     for _,func in fillfunc do
# Line 298  function draw_border_func(fillfunc, x0, Line 346  function draw_border_func(fillfunc, x0,
346     end     end
347  end  end
348    
349  -- like set_stones, but calling a function  -- draws into corners of given boundary
350  -- like: set_funcs(oxyd, {{1,2},{3,4},...})  function draw_func_corners(fillfunc, x0, y0, w, h)
351  function set_funcs(fillfunc, poslist)     local x0,y0,w,h = transform_coords(x0, y0, w, h)
352     if (type(fillfunc)=="function") then fillfunc={fillfunc} end     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
353    
354     for _,func in fillfunc do     for _,func in fillfunc do
355        for i,xy in poslist do        func(x0,y0)
356           func(xy[1], xy[2])        func(x0,y0+h-1)
357        end        func(x0+w-1,y0)
358          func(x0+w-1,y0+h-1)
359     end     end
360  end  end
361    
362  -- like draw_stones, draw_floor and others, but calls a func  -- like set_stones, but calling a function
363  function draw_func(fillfunc, xy0, xystep, n)  -- like: set_funcs(oxyd, {{1,2},{3,4},...})
364    function set_funcs(fillfunc, poslist)
365     if (type(fillfunc)=="function") then fillfunc={fillfunc} end     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
    local x,y = xy0[1], xy0[2]  
366    
367     for _,func in fillfunc do     for _,func in fillfunc do
368        for i=1,n do        for i,xy in poslist do
369           func(x, y)           func(transform_coords(xy[1], xy[2]))
          x = x+xystep[1]  
          y = y+xystep[2]  
370        end        end
371     end     end
372  end  end
373    
374    
375    -- draw functions into a row -- like draw_stones, draw_floor and others, but calls a func
376    -- generator of coordinates
377    function get_draw_coords(xylist, dxdylist, steps)
378       if (type(xylist[1])~="table") then xylist = {xylist} end
379       if (type(dxdylist[1])~="table") then dxdylist = {dxdylist} end
380       local ret = {}
381    
382       -- convert
383       for i=1,getn(xylist) do
384          local x0,y0   = transform_coords(xylist[i][1], xylist[i][2])
385    
386          tinsert(ret, {x0,y0})
387    
388  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --        for j=1,getn(dxdylist) do
389  -- TRAINS/WORMS/WHATEVER FUNCTIONS  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --           local x,y   = x0,y0
390  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --           local dx,dy = dxdylist[j][1], dxdylist[j][2]
   
 pathway_directions = {{ 1, 0}, { 0, 1}, {-1, 0}, { 0,-1}}  
 path = {}  
 path.constructor = {}  
   
 -- pathworks  
   
 -- tag shows whether there is a train or a rail - constructor sets it, destructor unsets it  
 -- context is ID of the track  
 function new_path_item(x, y, tag, context)  
    local it = {}  
    it.x, it.y = x, y  
    it.tag = tag  
    it.context = context  
391    
392     return it           for i=2,steps do
393                x = x+dx
394                y = y+dy
395                tinsert(ret, {x,y})
396             end
397          end
398       end
399       --
400       return ret
401  end  end
402    
403  function add_path_item(x, y, tag, context)  -- drawing function
404     path[getkey(x,y)]=new_path_item(x,y,tag,context)  function draw_func(fillfunc, ...)
405  end     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
406       local xylist = call(get_draw_coords, arg)
407    
408  function add_path_train(x, y, context)     for _,func in fillfunc do
409     add_path_item(x, y, nil, context)        for i=1,getn(xylist) do
410             local x,y = transform_coords(xylist[i][1], xylist[i][2])
411             func(x,y)
412          end
413       end
414  end  end
415    
 function add_path_empty(x, y, context)  
    add_path_item(x, y, not(nil), context)  
 end  
416    
417  -- constructors  -- draw a function into a regular n-gon. Particularly usable for
418    -- setting up arrangements of actors, as they accept real values,
419    -- but if proper roundfunc is given, also stones etc. may be
420    -- placed with this function.
421    
422  function add_path_constructor(x, y, await, action, context)  -- generator of coordinates
423     local cons = {}  function get_ngon_coords(xylist, radiuslist, count, alpha0, roundfunc)
424     cons.x, cons.y = x, y     if (type(xylist[1])~="table") then xylist = {xylist} end
425     cons.action    = action     if (type(radiuslist)~="table") then radiuslist = {radiuslist} end
    cons.await     = await  
    cons.context   = context  
426    
427     path.constructor[getn(path.constructor)+1] = cons     local astep = 360/count
428  end     local roundfunc = roundfunc or (function(x) return x end)
429    
430  function move_constructor(x0, y0, awaittag, context)     local ret = {}
    local found = nil  
431    
432     for i,dir in pathway_directions do     for i=1,getn(xylist) do
433        local x00, y00 = x0+dir[1], y0+dir[2]        local x0, y0 = transform_coords(xylist[i][1], xylist[i][2])
       local key = getkey(x00, y00)  
434    
435        if (path[key]) then        for j=1,getn(radiuslist) do
436           if ((path[key].context==context) and (path[key].tag==awaittag)) then           local radius = radiuslist[j]
437              path[key].tag = not(path[key].tag)           local alpha = alpha0 or 0
438              found = i  
439              break           for _=1,count do
440                local x00 = roundfunc(x0+radius*sin(alpha))
441                local y00 = roundfunc(y0+radius*cos(alpha))
442                tinsert(ret, {x00,y00})
443                alpha = alpha + astep
444           end           end
445        end        end
446     end     end
447    
448     if (found) then     return ret
       local x1 = x0 + pathway_directions[found][1]  
       local y1 = y0 + pathway_directions[found][2]  
       return x1, y1  
    else  
       return x0, y0  
    end  
449  end  end
450    
451  function move_constructors()  -- drawing function
452     local key, cons  function ngon_funcs(fillfunc, ...)
453     for key,cons in path.constructor do     if (type(fillfunc)=="function") then fillfunc={fillfunc} end
454        cons.x, cons.y = move_constructor(cons.x, cons.y, cons.await, cons.context)     local xylist = call(get_ngon_coords, arg)
455        cons.action(cons.x, cons.y)  
456       for _,func in fillfunc do
457          for i=1,getn(xylist) do
458             local x,y = transform_coords(xylist[i][1], xylist[i][2])
459             func(x,y)
460          end
461     end     end
462  end  end
463    
# Line 410  end Line 465  end
465    
466    
467    
468    
469  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
470  -- SPECIAL FLOOR TYPES  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- SPECIAL FLOOR TYPES  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
471  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
472    -- these function are usually used as a parent functions
473    
474  -- draws checker floor  -- draws checker floor
475  -- sidex: horizontal size of checker square  -- sidex: horizontal size of checker square
476  -- sidey: vertical size of checker square  -- sidey: vertical size of checker square
477  -- count: number of checker textures  -- count: number of checker textures
478  -- items: table of checker textures [1,2,3,...]  -- items: table of checker textures {1,2,3,...}
479  -- x,y:   coordinates of checker field  -- x,y:   coordinates of checker field
480  function mcheckerfloor(x, y, sidex, sidey, offsetx, offsety, count, items)  function mcheckerfloor(x, y, sidex, sidey, offsetx, offsety, count, items)
481     local x0, y0 = floor((x-offsetx+sidex)/sidex), floor((y-offsety+sidey)/sidey)     local x0, y0 = floor((x-offsetx+sidex)/sidex), floor((y-offsety+sidey)/sidey)
# Line 476  end Line 533  end
533  --  every item may be:  --  every item may be:
534  --   texture -- parent function, for example cell[] function  --   texture -- parent function, for example cell[] function
535  --   occurence -- occurence factor for previous texture. Defaults to 1.  --   occurence -- occurence factor for previous texture. Defaults to 1.
536  function randomfloor(x, y, items)  function randomfloor(x, y, ...)
537     local count = 0     local count = 0
538     local total = 0 --total occurences     local total = 0 --total occurences
539    
540       local items = {}
541       if (getn(arg)==1) then
542          if (type(arg[1])=="table") then
543             items=arg[1]    -- table is passed
544          else
545             items={arg[1]}  -- single function passed (hope it's a function)... who could do it?
546          end
547       else
548          items=arg          -- a list of functions and their rarities is not passed in table, but as arguments
549       end
550    
551     local itemlist = {}     local itemlist = {}
552    
553     for _,item in items do     for i=1,getn(items) do --_,item in items do
554          local item = items[i]
555        local titem = type(item)        local titem = type(item)
556        if (titem == "function") then        if (titem == "function") then
557           count = count + 1           count = count + 1
# Line 507  function randomfloor(x, y, items) Line 577  function randomfloor(x, y, items)
577     end     end
578  end  end
579    
 -- trains and pathworks support floor parents  
   
 -- path_constructor - add a generator of solid floor. This is the head of train.  
 -- opts[1] is context. It is number or string. Train only rides on the  
 --     paths with same context, as it has  
 -- opts[2] is constructing function. Usually it draws floor or something. It can also be one of cells[" "] functions.  
 function path_constructor(x, y, opts)  
    add_path_constructor(x, y, not(nil), opts[2], opts[1])  
 end  
   
 -- path_destructor - add a desintegrator of solid floor. This is train's last wagon.  
 -- opts like in path_constructor  
 function path_destructor(x, y, opts)  
    add_path_constructor(x, y, nil, opts[2], opts[1])  
 end  
   
 -- path_train - there already is body of train on this square  
 -- opts[1] is context, see path_constructor  
 function path_train(x, y, opts)  
    add_path_train(x, y, opts[1])  
 end  
   
 -- path_empty - there is just path. Train can ride here eventually.  
 -- opts[1] is context, see path_constructor  
 function path_empty(x, y, opts)  
    add_path_empty(x, y, opts[1])  
 end  
   
580    
581    
582    
583    
584  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
585  -- BOLDER/DOOR/ETC GROUPS  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- OBJECT GROUPS [MULTIPLES]  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
586  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
   
587  -- these are common parent function, much like checkerfloor or randomfloor  -- these are common parent function, much like checkerfloor or randomfloor
588  -- usage is as follows in example:  -- usage is as follows in example:
589  -- blocks = {};  -- blocks = {};
590  -- cells["W"] = cell{parent={cells[" "],{add_multistone,{"st-block", blocks}}}}  -- cells[" "] = cell{floor={face="fl-gray"}}
591    -- cells["W"] = cell{parent={cell[" "], {add_multistone, "st-block", blocks}}}
592  --  --
593  -- this cell has two parents:  -- this cell has two parents:
594  --   cells[" "], which probably is some common floor  --   cells[" "], which is some common floor of kind 'fl-gray'
595  --   {add_multistone,{"st-block", blocks}}, which is group parent function  --   {add_multistone, "st-block", blocks}, which is group parent function
596  --    add_multistone : add a stone to map and also to a group  --    add_multistone : add a stone to map and also to a group
597  --    "st-block"     : name of stone object to add  --    "st-block"     : name of stone object to add
598  --    blocks         : LUA table that represents object group  --    blocks         : LUA table that represents object group
# Line 559  end Line 601  end
601  --  send_group_message, add_rubber_bands, ...  --  send_group_message, add_rubber_bands, ...
602    
603  -- add a stone to a group  -- add a stone to a group
604  -- first item in table is stone face  -- face: this is stone face
605  -- second is group table  -- group: object group table
606  -- third is object attributes  -- attribs: object attributes
607  function add_multistone(x, y, args)  function add_multistone(x, y, face, group, attribs)
    local face, group, opts = args[1], args[2], args[3]  
608     local bc = getn(group)+1     local bc = getn(group)+1
609     local bn = face..bc     local bn = face..bc
610    
611     opts = opts or {}     attribs = attribs or {}
612     opts["name"] = bn     attribs["name"] = bn
613    
614       group[bc] = set_stone(face, x, y, attribs)
615    end
616    
617    -- add a floor to a group
618    -- face: this is floor face
619    -- group: object group table
620    -- attribs: object attributes
621    function add_multifloor(x, y, face, group, attribs)
622       local bc = getn(group)+1
623       local bn = face..bc
624    
625       attribs = attribs or {}
626       attribs["name"] = bn
627    
628       group[bc] = set_floor(face, x, y, attribs)
629    end
630    
631     set_stone(face, x, y, opts)  -- add an item to a group
632     local obj = enigma.GetNamedObject(bn)  -- face: this is an item kind
633     group[bc] = obj  -- group: object group table
634    -- attribs: object attributes
635    function add_multiitem(x, y, face, group, attribs)
636       local attribs = attribs or {}
637       attribs["name"] = face..(getn(group)+1)
638       tinsert(group, set_item(face, x, y, attribs))
639  end  end
640    
641  -- add an actor to a group  -- add an actor to a group
642  -- first item in table is actor kind  -- face: this is floor face
643  -- second is group table  -- group: object group table
644  -- third is object attributes  -- attribs: object attributes
645  function add_multiactor(x, y, args)  function add_multiactor(x, y, face, group, opts, actor_mode)
646     local face, group, opts, actor_mode = args[1], args[2], (args[3] or {}), (args[4] or 1)     local actor_mode = actor_mode or 3
647     local bc = getn(group)+1     local bc = getn(group)+1
648     local bn = face..bc     local bn = face..bc
649    
650     opts = opts or {}     opts = opts or {}
651     opts["name"] = bn     opts["name"] = bn
652    
653     set_actor(face, get_actor_x(x, actor_mode or 1), get_actor_y(y, actor_mode), opts)     group[bc] = set_actor(face, get_actor_x(x, actor_mode or 1), get_actor_y(y, actor_mode), opts)
654     local obj = enigma.GetNamedObject(bn)  end
655     group[bc] = obj  
656    -- for generic multiples, this only stores cell coordinates and tag information
657    -- this is usable for example to construct puzzles and trains, see below
658    function add_multicell(x, y, group, tag)
659       local key = getkey(x,y)
660       group[key] = {}
661       group[key].x = x
662       group[key].y = y
663       group[key].tag = tag
664    end
665    
666    -- another generic multiple
667    -- this stores the result of given function(x,y) to table
668    function add_multiobject(x, y, func, group)
669       local bc = getn(group)+1
670       group[bc] = func(x, y)
671  end  end
672    
673  -- 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
# Line 610  function add_rubber_band_pairs(gr1, gr2, Line 688  function add_rubber_band_pairs(gr1, gr2,
688     end     end
689  end  end
690    
691    -- to rubber-band given objects [1,2,3,...,n] like that:
692    --  1=2=3=...=n=1
693    function rubber_band_circle(gr1, strength, length)
694       local remember = nil
695       local first = nil
696       for a=1,getn(gr1) do
697          local obj1 = gr1[a]
698          if (remember) then
699             AddRubberBand(obj1, remember, strength, length)
700          else
701             first = obj1
702          end
703    
704          remember = obj1
705       end
706    
707       if (first) then
708          AddRubberBand(first, remember, strength, length)
709       end
710    end
711    
712  -- send message to each object in group  -- send message to each object in group
713  function send_group_message(group, message, third)  function send_group_message(group, message, third)
714     for _,item in group do     for _,item in group do
# Line 617  function send_group_message(group, messa Line 716  function send_group_message(group, messa
716     end     end
717  end  end
718    
719    -- set attribute to each of the objects in group
720    function set_group_attribs(group, attribs)
721       for _,item in group do
722          set_attribs(item, attribs)
723       end
724    end
725    
726    
727    
728    
729    
730  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
731  -- PUZZLE GENERATORS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- RAILWAY GENERATOR -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
732  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
733    
734  -- use this function right like other parent function, for example checkerfloor or randomfloor  -- creating trains:
735  -- in contrast to common parent functions, its attribute should be a single table variable which  --  each train is defined by two tables:
736  -- holds list of already registered puzzle cells. Usage:  --   +table of cells that the path consists of
737  --   puzzles = {};  --   +table of engines - path constructors and destructors
738  --   cells["*"]=cell{parent={{puzzlecell, puzzles}}}  --
739  function puzzlecell (x, y, tab)  -- basic idea is as follows:
740     tab[getkey(x,y)] = {}  --  in each tick, each of engines is moved to next cell in its path
741     tab[getkey(x,y)].x = x  --  each engine marks its rail - it sets a tag number of a current cell to some value
742     tab[getkey(x,y)].y = y  --  constructors set tag number to 1 destructors to 0
743    --  constructor will only move to such a path cell, that has different tag from its own tag
744    --  that is, constructors will only move to non-1-tagged cells
745    --  and destructors will never move to cells tagged as zero
746    --  and as each move means new tag value, the train keeps going forward
747    --
748    -- how to setup a rail
749    --  generic parent function add_multicell is used to setup both path and engines
750    --  see that example:
751    --
752    --    path = {}
753    --    loco = {}
754    --    cells["!"]=cell{parent={cells["."], {add_multicell, path, 0}}}
755    --    cells["_"]=cell{parent={cells["!"], {add_multicell, path, 1}, cells["'"]}}
756    --    cells["c"]=cell{parent={cells["_"], {add_multicell, loco, construct}}}
757    --    cells["d"]=cell{parent={cells["!"], {add_multicell, loco, destruct}}}
758    --
759    -- that means:
760    --  cells marked "!" are part of path and are tagged to zero
761    --  cells marked "_" are also part of path, but are tagged to 1 instead
762    --  cells marked "c" are part of engine ('loco' in example), and are tagged by function 'construct'
763    --  cells marked "d" are also engines, but are tagged by function 'destruct'
764    --
765    -- you also need to declare tag-functions 'construct' and 'destruct', and also cells["."] and cells["'"] have
766    -- to be defined somewhere. cells["."] is empty cell, if there is no train - abyss, a water or similar
767    -- cells["'"] is a surface of train - fl-normal, fl-wood, you choose.
768    -- path constructor and destructor are simple functions:
769    --
770    --   function construct(x, y) set_floor("fl-normal", x, y) end
771    --   function destruct(x, y)  set_floor("fl-abyss", x, y) end
772    --
773    -- you could also use cells["'"] and cells["."] respective instead, but these functions are
774    -- bloated. Note that construct() and destruct() will be used repeatedly and they have to be
775    -- as fast as possible, no extra functionality necessary.
776    --
777    -- Finally, you bind together engine with its path and let new railway operate:
778    --    rail = new_rail(loco, path)
779    --    cells["~"]=cell{stone={face="st-timer", attr={action="callback", target="rail", interval=0.15}}}
780    
781    function new_rail(engines, path)
782       local func0 = function()
783                        for _,engine in %engines do
784                           local ekey = getkey(engine.x, engine.y)
785    
786                           for _, dir in {engine.dir,{1,0},{0,1},{-1,0},{0,-1}} do
787                              local x0, y0 = engine.x+dir[1], engine.y+dir[2]
788                              local key = getkey(x0, y0)
789                              if ((%path[key]) and (%path[key].tag~=%path[ekey].tag)) then
790                                 %path[key].tag = %path[ekey].tag
791                                 engine.x, engine.y = x0, y0
792                                 engine.dir = dir -- remember direction
793                                 engine.tag(x0, y0)
794                                 break
795                              end
796                           end--directions
797                        end--engines
798                     end--function
799       return func0
800  end  end
801    
802    
803    
804    
805    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
806    -- PUZZLE GENERATOR  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
807    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
808    -- for simple puzzle generating:
809    --  cells["*"] - all puzzle stones are marked as asterisk in level map
810    --
811    --   puzzles = {};  -- create a table of puzzle stones
812    --   cells["*"]=cell{parent={{add_multicell, puzzles}}}  -- use generic multiple to add a cell to table
813    --
814    -- and finally, at the end of the level:
815    --   render_puzzles(puzzles)  -- place information from puzzle table to map
816    
817    
818  -- this functions is called at the end of level file. It accepts  -- this functions is called at the end of level file. It accepts
819  --  tab, which is a list of registered puzzle cells  --  tab, which is a list of registered puzzle cells
820  --  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
# Line 658  function render_puzzles (tab, generatorf Line 837  function render_puzzles (tab, generatorf
837        puzzle(x, y, puz)        puzzle(x, y, puz)
838     end     end
839  end  end
840    
841    
842    
843    
844    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
845    -- WRAPPED init.lua FUNCTIONS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
846    -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
847    -- these functions override common init.lua functions, giving them the power
848    -- of ant.lua syntax -- that is, calling with list of coordinates,
849    -- using negative coordinates for positions relative to lower-right corner
850    -- and maybe also some others that I do not recall now :)
851    -- Note, that basic syntax remain intact, so at first glance no changes are visible!
852    -- Wrapped functions are a lot slower, empirically nearly 3.5 times. Not a great deal,
853    -- as LUA is really fast.
854    
855    -- stones
856    oxyd =     cell{{{oxyd}}}
857    fakeoxyd = cell{{{fakeoxyd}}}
858    oneway =   cell{{{oneway}}}
859    laser =    cell{{{laser}}}
860    mirrorp =  cell{{{mirrorp}}}
861    mirror3 =  cell{{{mirror3}}}
862    puzzle =   cell{{{puzzle}}}
863    switch =   cell{{{switch}}}
864    
865    -- floors
866    abyss =    cell{{{abyss}}}
867    hollow =   cell{{{hollow}}}
868    
869    -- items
870    Document = cell{{{Document}}}
871    hammer =   cell{{{hammer}}}
872    dynamite = cell{{{dynamite}}}
873    bomb =     cell{{{bomb}}}
874    shogundot= cell{{{shogundot}}}
875    keya =     cell{{{keya}}}
876    keyb =     cell{{{keyb}}}
877    keyc =     cell{{{keyc}}}
878    shogundot1=cell{{{shogundot, 1}}}
879    shogundot2=cell{{{shogundot, 2}}}
880    shogundot3=cell{{{shogundot, 3}}}
881    Wormhole = cell{{{Wormhole}}}
882    doorh =    cell{{{doorh}}}
883    doorv =    cell{{{doorv}}}
884    gradient = cell{{{gradient}}}
885    
886    -- lower case equivalents
887    document = Document
888    wormhole = Wormhole

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

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