home *** CD-ROM | disk | FTP | other *** search
/ GameStar Special 2004 August / GSSH0804.iso / Geschicklichkeit / Enigma / Enigma-081.exe / data / levels / ant.lua < prev    next >
Text File  |  2003-06-21  |  46KB  |  1,454 lines

  1. ------------------------------------------------------------------------
  2. -- Copyright (C) 2002-2003 Petr Machata
  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: ant.lua,v 1.18 2003/06/21 18:00:57 ant_39 Exp $
  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.txt),
  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
  31. -- 2003-01-11 -- multiples support (groups of doors, bolders etc.)
  32. -- 2003-01-14 -- bugfixes and error reporting, some new map-creating funcs
  33. -- 2003-02-09 --
  34. --   many changes. Fixes of rubberband functions, fixes in multiples support, some interfaces changed
  35. --   These changes require also fixes in several levels, but it's more logic this way. Besides this, it's
  36. --   finally possible to call functions from init.lua or any functions declared like func(x, y, args),
  37. --   for example oxyd(), fakeoxyd(), laser(), ...  and others.
  38. --   While I was rewriting, I finally implemented multichar maps, which I planned since the beginning...
  39. -- 2003-02-11 -- fixes in filling functions
  40. -- 2003-02-12 -- cell() now returns last created object; functional-drawing functions accept table; and fixes
  41. -- 2003-02-20 --
  42. --   major rewrite of cell() function. This require also changes in *all* (~30) levels so far
  43. --   I'll do it now, until there is just a few things to change... Later it could be too late
  44. --   and these changes are really necessary
  45. --   These changes include rewrites in parent function handling, so that it now supports a kind
  46. --   of curried functions from haskell. Also you can use the coordlists instead of simple coords and
  47. --   place several elements at once. And so on...
  48. --   Big changes in interfacing many parent functions, completely rewritten trains and puzzle generators,
  49. --   changes in multiples (there are more kinds, and interfacing changed).
  50. --   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 necessary
  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. -- 2003-03-13 -- several cosmetic changes plus add_multitag, spread_tag, wormholes generator and slope generator
  58. -- 2003-03-21 -- warning may raise error if warning_raises_error is set to 1 (ralf)
  59. -- 2003-03-30 --
  60. --   some comments fixed, be_pedantic() added, add_multitag fix, draw_map and get_map_size
  61. --   were broken up to several parts so that particular tasks may be solved as designer wishes.
  62. --   cell0.tag removed - I'm not sure if it was ever used at all...
  63. --   some improvements in handling default cell key meanings at multichar maps
  64. -- 2003-04-12 -- interface of add_multiobject changed to match interface of other multiples
  65. -- 2003-04-25 -- boolean tables
  66. -- 2003-06-19 -- render_puzzles accepts a 'kind' argument. Thanks to ralf!
  67.  
  68.  
  69. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  70. -- MISCELANEOUS - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  71. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  72. -- for warning messages
  73. function warning(text)
  74.    if (warning_raises_error) then
  75.       error(" [ant.lua]: "..text)
  76.    else
  77.       print("warning: [ant.lua]: "..text)
  78.    end
  79. end
  80.  
  81. -- turn warning messages to errors
  82. -- usage: be_pedantic() -> turn on raising errors instead of warnings
  83. function be_pedantic(mode)
  84.    warning_raises_error = ((mode==nil)or(mode~=0))
  85. end
  86.  
  87. -- for debug messages
  88. local ldm={str="", cnt=0}
  89. function debug(text)
  90.    if (DEBUG_MODE) then
  91.       if (%ldm.str~=text) then
  92.      if (%ldm.cnt>1) then print("debug: [ant.lua]: last message repeated "..%ldm.cnt.." times") end
  93.      if (text~="")   then print("debug: [ant.lua]: "..text) end
  94.      %ldm.str = text;
  95.      %ldm.cnt = 0;
  96.       else
  97.      %ldm.cnt = %ldm.cnt +1;
  98.       end
  99.    end
  100. end
  101.  
  102. -- debug mode
  103. -- in debug mode, ant.lua produces messages that inform you about the execution
  104. DEBUG_MODE = nil
  105. function debug_mode()
  106.    DEBUG_MODE = 1
  107.    debug("debug_mode: debug mode turned on")
  108. end
  109.  
  110. -- turn off debug mode
  111. function debug_mode_off()
  112.    debug("debug_mode_off: turning debug mode off")
  113.    DEBUG_MODE = nil
  114. end
  115.  
  116. -- x,y should be numbers, although chars and strings are generally also the right choice
  117. function getkey(...)
  118.    local key=""
  119.    for i=1,getn(arg) do
  120.       if (i>1) then key=key.."\0" end
  121.       key=key..arg[i]
  122.    end
  123.    return key
  124. end
  125.  
  126. -- todo: deep clone - clone also nested tables
  127. function clone_table(tab)
  128.    local ntab = {}
  129.  
  130.    for key,val in tab do
  131.       ntab[key] = val
  132.    end
  133.  
  134.    return ntab;
  135. end
  136.  
  137. -- each ant.lua function, that accepts coordinates, may be
  138. -- called with negative coordinates as well. That in fact
  139. -- means to place the object relatively to lower right
  140. -- corner.
  141. --  location [-1,-1] means [levelw, levelh]
  142. --  size [0,0] means [levelw, levelh]
  143. function transform_coords(x,y,w,h)
  144.    local x, y = (x or 0), (y or 0)
  145.    local w, h = (w or 0), (h or 0)
  146.    if (x<0) then x = level_width +x-1 end
  147.    if (y<0) then y = level_height+y-1 end
  148.    if (w<=0) then w = level_width +w end
  149.    if (h<=0) then h = level_height+h end
  150.    return x,y,w,h
  151. end
  152.  
  153. -- this couple of functions takes care of converting common tile coordinates to real coordinates of placed
  154. -- actor. It depends on the given actor_mode, which is being declared like this:
  155. -- cells["O"]=cell{parent=cells["+"], actor={face="ac-blackball", attr={player=0}, mode=ACTOR_MODE}}
  156. --
  157. -- the meaning of actor mode is as follows:
  158. -- value || x | y || meaning
  159. -- ------++---+---++--------
  160. --  0    || 0 | 0 || actor is placed to left top corner of tile
  161. --  1    || 1 | 0 || actor is centered horizontally on tile
  162. --  2    || 0 | 1 || actor is centered vertically on tile
  163. --  3    || 1 | 1 || actor is centered in tile
  164. --
  165. function get_actor_x(x, actor_mode)
  166.    if ((actor_mode == 0)or(actor_mode == 2)) then
  167.       return x
  168.    else
  169.       return x + 0.5
  170.    end
  171. end
  172.  
  173. function get_actor_y(y, actor_mode)
  174.    if ((actor_mode == 0)or(actor_mode == 1)) then
  175.       return y
  176.    else
  177.       return y + 0.5
  178.    end
  179. end
  180.  
  181.  
  182.  
  183.  
  184. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  185. -- VISUAL MAP CREATION  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  186. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  187.  
  188. -- width of key in map definition
  189. -- CELL_KEY_WIDTH means how many characters occupy single map cell. In several maps I strongly
  190. -- wanted this functions (cannonball for example), and after all here it is. Usable in maps with
  191. -- wide variety of different surfaces.
  192. CELL_KEY_WIDTH = 1
  193. function set_cell_key_width(w)
  194.    if ( (type(w) == "number") and (w>0) and (floor(w)==w) ) then
  195.       CELL_KEY_WIDTH = w
  196.       debug("set_cell_key_width: CELL_KEY_WIDTH is: "..w)
  197.       return w
  198.    else
  199.       warning("set_cell_key_width: CELL_KEY_WIDTH has to be positive whole number")
  200.       return -1
  201.    end
  202. end
  203.  
  204. -- get a table with cell functions
  205. -- with no argument given, global cells is looked for.
  206. -- if none is present, warning occurs.
  207. function get_cellfuncs(cellfuncs)
  208.    local funcs = cellfuncs or cells;  -- hope for a global cells
  209.  
  210.    if (not(funcs)) then
  211.       warning("get_cellfuncs: no cellfuncs declared and global variable 'cells' is absent.")
  212.       funcs = {};
  213.    else
  214.       debug("get_cellfuncs: ok, found cellfuncs table.")
  215.    end
  216.  
  217.    return funcs;
  218. end
  219.  
  220. -- this function tries to guess the width of key.
  221. -- It does so by looking for the most common width of keys in cells[key]
  222. function guess_cell_key_width(cellfuncs)
  223.    local funcs = get_cellfuncs(cellfuncs)
  224.    local freq_table = {}
  225.  
  226.    for key,_ in funcs do
  227.       local ktype = type(key)
  228.       if (ktype == "string") then
  229.      local n = strlen(key)
  230.      freq_table[n] = (freq_table[n] or 0)+1
  231.       end
  232.    end
  233.  
  234.    local maxw,maxfreq = 0,0
  235.    for w,freq in freq_table do
  236.       if (freq>maxfreq) then
  237.      maxw = w
  238.      maxfreq = freq
  239.       end
  240.    end
  241.  
  242.    debug("guess_cell_key_width: CELL_KEY_WIDTH guessed "..maxw)
  243.    return set_cell_key_width(maxw)
  244. end
  245.  
  246. -- default cell parent is called before any of common cell parents
  247. -- default parent is a table, where each element may be
  248. --  + a function
  249. --  + a string, in which case this is a key in cellfunc table
  250. -- also set_default_parent can be called with a single function
  251. -- or string argument. The table will be built from this.
  252. DEFAULT_CELL_PARENT = nil
  253. function set_default_parent(func)
  254.    if (not(func)) then
  255.       debug("set_default_parent: default parent turned off")
  256.       DEFAULT_CELL_PARENT = nil
  257.       return
  258.    end
  259.  
  260.    if ((type(func)=="function")or(type(func)=="string")) then
  261.       func = {func}
  262.    end
  263.  
  264.    if (type(func)=="table") then
  265.       for key,f in func do
  266.      local ftype = type(f)
  267.      if ((ftype~="function")and(ftype~="string")) then
  268.         warning("set_default_parent: element "..key.." of DEFAULT_CELL_PARENT\n"..
  269.             "has to be function or string, not "..ftype.."!")
  270.         return
  271.      end
  272.       end
  273.       DEFAULT_CELL_PARENT = func
  274.    else
  275.       warning("set_default_parent: default parent has to be\n"..
  276.           "a function, table of functions or string key")
  277.    end
  278. end
  279.  
  280. -- each item:
  281. --  + face - name of stone/floor/item object
  282. --  + attr - set of attributes of given object
  283. function cell_item(it)
  284.    local n_it = {}
  285.    local ittype = type(it)
  286.  
  287.    if (type(it)=="string") then it = {it} end
  288.  
  289.    n_it.face = (it.face or it[1] or "")
  290.    n_it.attr = (it.attr or it[2] or {})
  291.    n_it.mode = (it.mode or it[3] or 3)
  292.  
  293.    return n_it
  294. end
  295.  
  296. -- each cell
  297. --  + stone - if present, the stone shall be added to defined position
  298. --  + floor - the same, but for floor
  299. --  + item  - the same, but for item
  300. --  + actor - the same, but for actor
  301. --    ++ mode - see get_actor_x() and _y() functions
  302. --  + mode - parent arglist handling mode. Defaults to 0 and it means where to put (x,y) couple in arglist
  303. --    ++ mode = -1 => do not place the (x,y) couple to arglist
  304. --    ++ mode = +0 => place it before parent arguments
  305.  
  306. --  ATTENTION: there *has* to be a coordlist even in case of pmode=-1, or NO arguments may be passed:
  307. --    -> func()
  308. --    -> func(x,y)
  309. --    -> func(x,y, arg1, arg2, ...)
  310. --    -> func(arg1, arg2) --> INCORRECT!!
  311.  
  312. function cell(structure)
  313.    local cell0 = {}
  314.  
  315.    cell0.floor = cell_item(structure.floor or {})
  316.    cell0.stone = cell_item(structure.stone or {})
  317.    cell0.item =  cell_item(structure.item or {})
  318.    cell0.actor = cell_item(structure.actor or {})
  319.  
  320.    -- get parent
  321.    -- parent is declared in this form: parent={{func1, arg1, arg2,...},...}
  322.    -- if it's not, convert to this form
  323.    local parent =(structure.parent or structure[1] or {})
  324.  
  325.    if (type(parent)=="function") then
  326.       parent = {parent}
  327.    elseif (type(parent)=="table") then
  328.       -- this is O.K.
  329.    else
  330.       warning("cell{}: parent has to be a function, a table of functions\n"..
  331.           "or a table of curry-functions, not "..type(parent))
  332.       parent={}
  333.    end
  334.  
  335.    for a=1,getn(parent) do
  336.       if (type(parent[a])=="function") then
  337.      parent[a] = {parent[a]}
  338.       elseif (type(parent[a])=="table") then
  339.      if (type(parent[a][1])=="function") then
  340.         -- this is O.K. => a curry function call {func, arg1, arg2, ...}
  341.      else
  342.         warning("cell{}: parent element number "..a.." acts as a curry-function\n"..
  343.             "construction, but it's first element isn't a function, it's "..type(parent[a])..".\n"..
  344.             "Using empty function instead.")
  345.         parent[a]={function() end}
  346.      end
  347.       else
  348.      warning("cell{}: parent element number "..a.." should be a function\n"..
  349.          "or a curry-function construction, not "..type(parent[a])..".\n"..
  350.          "Using empty function instead.")
  351.      parent[a]={function() end}
  352.       end
  353.    end
  354.  
  355.    --+ this functions manages calling various parent functions. Most functions are just func(x,y) or (x,y,something)
  356.    --  but it's also possible to call ({{x1,y1},{x2,y2}}, something1, something2)
  357.    --  This enables compatibility with and wrapping of functions form init.lua.
  358.    --+ At the same moment, it's possible to declare some parametters in cell functions, like this:
  359.    --     cell1 = cell{parent={{func, par1}}}
  360.    --  and then call  --cell1(par2)--  instead of  --func(par1, par2)--
  361.    --  It may be used as a sort of curried functions from haskell, as far as my poor haskell knowledge says...
  362.    return function(...)
  363.          local xylist = tremove(arg, 1) or {}
  364.          local ret = nil
  365.  
  366.          -- first, get rid of cell(x,y) notation and convert it to cell({{x0,y0}}) notation
  367.          local xtp = type(xylist);
  368.          if (xtp=="number") then
  369.         xylist = {{xylist,tremove(arg,1)}}
  370.          elseif ((xtp=="table")and(type(xylist[1])=="number")) then
  371.         xylist = {xylist}
  372.          end
  373.  
  374.          for idx=1,getn(%parent) do
  375.         local tab0 = %parent[idx]
  376.         --+ tab0 is table. first item is function, the rest are the the function arguments
  377.         --+ first extract function from tab0, then include arguments from function call to the
  378.         --  tab, add a place for x,y coordinates and call it. Eventually tab will look like this:
  379.         --    {x, y, pfpar1, pfpar2, ..., arg1, arg2, ...}
  380.         local func = tab0[1]
  381.         local pmode= tab0.mode or %parent.mode or 0
  382.         local tab = ((pmode==0) and {0,0}) or {}
  383.         for a=2,getn(tab0) do tinsert(tab, tab0[a]) end
  384.         for a=1,getn(arg) do tinsert(tab, arg[a]) end
  385.  
  386.         -- and call a function
  387.         if (pmode==0) then
  388.            for i=1,getn(xylist) do
  389.               tab[1],tab[2] = transform_coords(xylist[i][1], xylist[i][2])
  390.               ret =  call(func, tab)
  391.            end
  392.         else
  393.            ret =  call(func, tab)
  394.         end
  395.          end
  396.  
  397.          --process common map elements
  398.          for i=1,getn(xylist) do
  399.         local x,y = transform_coords(xylist[i][1], xylist[i][2])
  400.         if (%structure.stone) then ret = set_stone(%cell0.stone.face, x, y, %cell0.stone.attr) end
  401.         if (%structure.floor) then ret = set_floor(%cell0.floor.face, x, y, %cell0.floor.attr) end
  402.         if (%structure.item ) then ret = set_item (%cell0.item.face , x, y, %cell0.item.attr ) end
  403.         if (%structure.actor) then
  404.            local ax, ay = get_actor_x(x, %cell0.actor.mode), get_actor_y(y, %cell0.actor.mode)
  405.            ret = set_actor(%cell0.actor.face, ax, ay, %cell0.actor.attr)
  406.         end
  407.          end
  408.          return ret
  409.       end
  410. end
  411.  
  412. -- height is just number of lines
  413. function get_map_height(map)
  414.    return getn(map)
  415. end
  416.  
  417. -- width of particular map row
  418. function map_row_length(y, map)
  419.    return floor(strlen(map[y])/CELL_KEY_WIDTH);
  420. end
  421.  
  422. -- width - this is width of the widest row of map
  423. function get_map_width(map)
  424.    local mapw = 0
  425.  
  426.    for y=1,get_map_height(map) do
  427.       local w = map_row_length(y, map)
  428.       if w>mapw then mapw = w end
  429.    end
  430.  
  431.    return mapw
  432. end
  433.  
  434. -- and size combined
  435. function get_map_size(map)
  436.    return get_map_width(map), get_map_height(map)
  437. end
  438.  
  439. -- common map
  440. -- if a key has no meaning declared in given 'cellfuncs', we'll look here
  441. -- whether there is a 'default' meaning
  442. -- look at the bottom of ant.lua to see the map
  443. DEFAULT_KEY_MEANING={}
  444. function map_cell_meaning(key, func)
  445.    DEFAULT_KEY_MEANING[key]=func
  446. end
  447.  
  448. -- use cells from default library in cellfuncs table
  449. -- this function accepts a table of cellfuncs and arbitrary number of string keys as arguments
  450. -- it loads the default keys to given cellfuncs table
  451. function use_cells(funcs, ...)
  452.    for a=1,getn(arg) do
  453.       funcs[arg[a]] = DEFAULT_KEY_MEANING[arg[a]]
  454.    end
  455. end
  456.  
  457. -- function picks a function from table of default cell keys
  458. -- and results it
  459. function default_cell(key)
  460.    return DEFAULT_KEY_MEANING[key]
  461. end
  462.  
  463. -- this function accepts a cell key and cellfuncs table
  464. -- it looks into that table and if there is no func with given key, it returns default
  465. -- value instead and inserts the value to given cellfuncs table
  466. function get_cell_func(key, cellfuncs)
  467.    if (cellfuncs[key]) then
  468.       return cellfuncs[key]
  469.    elseif (DEFAULT_KEY_MEANING[key]) then
  470.       debug("get_cell_func: using DEFAULT_KEY_MEANING of '"..key.."'")
  471.       cellfuncs[key] = DEFAULT_KEY_MEANING[key]
  472.       return DEFAULT_KEY_MEANING[key]
  473.    else
  474.       -- for multichar maps, try by the first char
  475.       if (strlen(key)>1) then
  476.      local ret = get_cell_func(strsub(key, 1, 1), cellfuncs)
  477.      if (ret) then
  478.         debug("get_cell_func: as a meaning of the key '"..key.."'")
  479.         cellfuncs[key] = ret;
  480.         return ret
  481.      end
  482.       end
  483.  
  484.       warning("get_cell_func: no function declared for map key '"..key.."'")
  485.       return nil
  486.    end
  487. end
  488.  
  489.  
  490.  
  491.  
  492. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  493. -- MAP RENDERING FUNCTIONS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  494. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  495.  
  496. -- render a map square by key
  497. -- rx,ry are x,y coordinates of given cell on map
  498. -- key is a cell descriptor
  499. -- func is a table of cellfuncs
  500. function render_key(rx, ry, key, cellfuncs)
  501.    local cellfuncs = cellfuncs or get_cellfuncs(cellfuncs);
  502.  
  503.    -- call default parents
  504.    if (DEFAULT_CELL_PARENT) then
  505.       for _,val in DEFAULT_CELL_PARENT do
  506.      local dpfunc=0
  507.      if (type(val)=="string") then
  508.         dpfunc=get_cell_func(val, cellfuncs)
  509.      else
  510.         dpfunc=val
  511.      end
  512.  
  513.      if (type(dpfunc)=="function") then
  514.         dpfunc(rx, ry)
  515.      else
  516.         warning("render_key: unknown default parent type for the key: '"..val.."'")
  517.      end
  518.       end
  519.    end
  520.  
  521.    -- call common cell function
  522.    local func = get_cell_func(key, cellfuncs)
  523.    local ftype = type(func)
  524.    if (ftype == "function") then
  525.       func(rx, ry)
  526.    elseif (ftype == "nil") then
  527.       warning("render_key: function doesn't exist for map element '"..key.."'.")
  528.    else
  529.       warning("render_key: cell element '"..key.."' is not a function, it's "..ftype..".")
  530.    end
  531. end
  532.  
  533. -- this function returns a cell key by its x,y coordinates
  534. function get_cell_by_xy(mx, my, map)
  535.    return strsub(map[my], (mx-1)*CELL_KEY_WIDTH+1, mx*CELL_KEY_WIDTH)
  536. end
  537.  
  538. -- function renders a given cell of map
  539. -- rx0, ry0 are coordinates of left top square of map
  540. -- mx, my are coordinates of map square to be rendered
  541. function render_map_cell(rx0, ry0, mx, my, map, cellfuncs)
  542.    if (not(map)) then
  543.       warning("render_map_cell: no map given!")
  544.       return
  545.    end
  546.    local cellfuncs = cellfuncs or get_cellfuncs(cellfuncs)
  547.  
  548.    local rx, ry = mx+rx0-1, my+ry0-1
  549.    local key = get_cell_by_xy(mx, my, map)
  550.    render_key(rx, ry, key, cellfuncs)
  551. end
  552.  
  553. -- this draws the map to the position [rx0,ry0]
  554. -- map is array of strings. Each string is one line of result map, each char is one map square.
  555. -- you may omit cellfuncs, default global 'cells' is used instead
  556. function draw_map_portion(rx0, ry0, mxy0, mxy1, map, cellfuncs)
  557.    if (not(map)) then
  558.       warning("draw_map: no map given!")
  559.       return
  560.    end
  561.    local cellfuncs = cellfuncs or get_cellfuncs(cellfuncs);
  562.  
  563.    for my = mxy0[2],mxy1[2] do
  564.       for mx = mxy0[1],mxy1[1] do
  565.      render_map_cell(rx0, ry0, mx, my, map, cellfuncs);
  566.       end
  567.    end
  568. end
  569.  
  570. -- this will draw whole map
  571. -- rx0, ry0 are coordinates of left top map corner
  572. function draw_map(rx0, ry0, map, cellfuncs)
  573.    local mapw, maph = get_map_size(map)
  574.    draw_map_portion(rx0, ry0, {1,1}, {mapw, maph}, map, cellfuncs)
  575. end
  576.  
  577. -- this just prepares the world, but no map is created
  578. function prepare_world_by_map(map)
  579.    local mapw, maph = get_map_size(map)
  580.    local flavor = oxyd_default_flavor
  581.  
  582.    debug("creating world ["..mapw.."x"..maph.."]")
  583.    create_world(mapw, maph)
  584.    oxyd_default_flavor = flavor or oxyd_default_flavor or "b"
  585. end
  586.  
  587. -- this prepares enigma world and draws given map
  588. -- you may omit cellfuncs, default global 'cells' is used instead
  589. function create_world_by_map(map, cellfuncs)
  590.    prepare_world_by_map(map)
  591.    draw_map(0, 0, map, cellfuncs)
  592. end
  593.  
  594.  
  595.  
  596.  
  597.  
  598.  
  599.  
  600. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  601. -- FUNCTIOAL MAP DRAWING - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  602. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  603. -- functions in this section are much like those defined in init.lua. Major difference
  604. -- is that these functions accept a function as an argument. So, it's possible to call
  605. -- given function with several coordinates at once. Just one single prerequisity -
  606. -- the function must require at most two arguments, and they have to be coordinates
  607. --   func(x,y, non_required_arguments)
  608.  
  609. -- fill each square of map with given function
  610. function fill_world_func(fillfunc, x0, y0, w, h)
  611.    local x0,y0,w,h = transform_coords(x0, y0, w, h)
  612.    if (type(fillfunc)=="function") then fillfunc={fillfunc} end
  613.  
  614.    for _,func in fillfunc do
  615.       for x=x0, x0+w-1 do
  616.      for y=y0, y0+h-1 do
  617.         func(x, y)
  618.      end
  619.       end
  620.    end
  621. end
  622.  
  623. -- to draw border of map by given function
  624. function draw_border_func(fillfunc, x0, y0, w, h)
  625.    local x0,y0,w,h = transform_coords(x0, y0, w, h)
  626.    if (type(fillfunc)=="function") then fillfunc={fillfunc} end
  627.  
  628.    for _,func in fillfunc do
  629.       for x=x0,x0+w-1 do
  630.      func(x, y0)
  631.      func(x, y0+h-1)
  632.       end
  633.  
  634.       for y=y0,y0+h-1 do
  635.      func(x0, y)
  636.      func(x0+w-1, y)
  637.       end
  638.    end
  639. end
  640.  
  641. -- draws into corners of given boundary
  642. function draw_func_corners(fillfunc, x0, y0, w, h)
  643.    local x0,y0,w,h = transform_coords(x0, y0, w, h)
  644.    if (type(fillfunc)=="function") then fillfunc={fillfunc} end
  645.  
  646.    for _,func in fillfunc do
  647.       func(x0,y0)
  648.       func(x0,y0+h-1)
  649.       func(x0+w-1,y0)
  650.       func(x0+w-1,y0+h-1)
  651.    end
  652. end
  653.  
  654. -- like set_stones, but calling a function
  655. -- like: set_funcs(oxyd, {{1,2},{3,4},...})
  656. function set_funcs(fillfunc, poslist)
  657.    if (type(fillfunc)=="function") then fillfunc={fillfunc} end
  658.  
  659.    for _,func in fillfunc do
  660.       for i=1,getn(poslist) do
  661.      func(transform_coords(poslist[i][1], poslist[i][2]))
  662.       end
  663.    end
  664. end
  665.  
  666.  
  667. -- draw functions into a row -- like draw_stones, draw_floor and others, but calls a func
  668. -- generator of coordinates
  669. function get_draw_coords(xylist, dxdylist, steps)
  670.    if (type(xylist[1])~="table") then xylist = {xylist} end
  671.    if (type(dxdylist[1])~="table") then dxdylist = {dxdylist} end
  672.    local ret = {}
  673.  
  674.    -- convert
  675.    for i=1,getn(xylist) do
  676.       local x0,y0   = transform_coords(xylist[i][1], xylist[i][2])
  677.  
  678.       tinsert(ret, {x0,y0})
  679.  
  680.       for j=1,getn(dxdylist) do
  681.      local x,y   = x0,y0
  682.      local dx,dy = dxdylist[j][1], dxdylist[j][2]
  683.  
  684.      for i=2,steps do
  685.         x = x+dx
  686.         y = y+dy
  687.         tinsert(ret, {x,y})
  688.      end
  689.       end
  690.    end
  691.    --
  692.    return ret
  693. end
  694.  
  695. -- drawing function
  696. function draw_func(fillfunc, ...)
  697.    if (type(fillfunc)=="function") then fillfunc={fillfunc} end
  698.    local xylist = call(get_draw_coords, arg)
  699.  
  700.    for _,func in fillfunc do
  701.       for i=1,getn(xylist) do
  702.      local x,y = transform_coords(xylist[i][1], xylist[i][2])
  703.      func(x,y)
  704.       end
  705.    end
  706. end
  707.  
  708.  
  709. -- draw a function into a regular n-gon. Particularly usable for
  710. -- setting up arrangements of actors, as they accept real values,
  711. -- but if proper roundfunc is given, also stones etc. may be
  712. -- placed with this function.
  713.  
  714. -- generator of coordinates
  715. function get_ngon_coords(xylist, radiuslist, count, alpha0, roundfunc)
  716.    if (type(xylist[1])~="table") then xylist = {xylist} end
  717.    if (type(radiuslist)~="table") then radiuslist = {radiuslist} end
  718.  
  719.    local astep = 360/count
  720.    local roundfunc = roundfunc or (function(x) return x end)
  721.  
  722.    local ret = {}
  723.  
  724.    for i=1,getn(xylist) do
  725.       local x0, y0 = transform_coords(xylist[i][1], xylist[i][2])
  726.  
  727.       for j=1,getn(radiuslist) do
  728.      local radius = radiuslist[j]
  729.      local alpha = alpha0 or 0
  730.  
  731.      for _=1,count do
  732.         local x00 = roundfunc(x0+radius*sin(alpha))
  733.         local y00 = roundfunc(y0+radius*cos(alpha))
  734.         tinsert(ret, {x00,y00})
  735.         alpha = alpha + astep
  736.      end
  737.       end
  738.    end
  739.  
  740.    return ret
  741. end
  742.  
  743. -- drawing function
  744. function ngon_funcs(fillfunc, ...)
  745.    if (type(fillfunc)=="function") then fillfunc={fillfunc} end
  746.    local xylist = call(get_ngon_coords, arg)
  747.  
  748.    for _,func in fillfunc do
  749.       for i=1,getn(xylist) do
  750.      local x,y = transform_coords(xylist[i][1], xylist[i][2])
  751.      func(x,y)
  752.       end
  753.    end
  754. end
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  762. -- SPECIAL FLOOR TYPES  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  763. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  764. -- see ant.lua documentation for extensive howto
  765. -- (this is yet to be done)
  766.  
  767. -- draws checker floor
  768. -- sidex: horizontal size of checker square
  769. -- sidey: vertical size of checker square
  770. -- count: number of checker textures
  771. -- items: table of checker textures {1,2,3,...}
  772. -- x,y:   coordinates of checker field
  773. function mcheckerfloor(x, y, sidex, sidey, offsetx, offsety, count, items)
  774.    local x0, y0 = floor((x-offsetx+sidex)/sidex), floor((y-offsety+sidey)/sidey)
  775.    local remainder = mod(x0+y0, count)
  776.    items[remainder+1](x,y)
  777. end
  778.  
  779. -- the checkerfloor parent
  780. -- items: checkerfloor textures. Functions generated by cell({structure})
  781. -- eg:
  782. --   cells["."]=cell{floor={face="fl-metal"}}
  783. --   cells[","]=cell{floor={face="fl-normal"}}
  784. --   cells[" "]=cell{parent={{checkerfloor,{cells[","], cells["."]}}}}
  785. -- optionally, at the end of table there may be additional checkerboard generating variables:
  786. --   side - set size of checkerboard square
  787. --   sidex - only set horizontal size (defaults to 1)
  788. --   sidey - only set vertical size (defaults to 1)
  789. --     cells[" "]=cell{parent={{checkerfloor,{cells[","], cells["."]; side=2}}}}
  790. function checkerfloor(x, y, items)
  791.    local count = getn(items)
  792.    local remainder = mod(x+y, count)
  793.    local sidex, sidey = 1, 1
  794.    local offsetx, offsety = 0, 0
  795.  
  796.    if (items.side~=nil) then
  797.       sidex = items.side
  798.       sidey = sidex
  799.    end
  800.  
  801.    if (items.sidex~=nil) then
  802.       sidex = items.sidex
  803.    end
  804.  
  805.    if (items.sidey~=nil) then
  806.       sidey = items.sidey
  807.    end
  808.  
  809.    if (items.offset~=nil) then
  810.       offsetx = items.offset
  811.       offsety = offsetx
  812.    end
  813.  
  814.    if (items.offsetx~=nil) then
  815.       offsetx = items.offsetx
  816.    end
  817.  
  818.    if (items.offsety~=nil) then
  819.       offsety = items.offsety
  820.    end
  821.  
  822.    mcheckerfloor(x, y, sidex, sidey, offsetx, offsety, getn(items), items)
  823. end
  824.  
  825. -- the random floor parent
  826. --  every item may be:
  827. --   texture -- parent function, for example cell[] function
  828. --   occurence -- occurence factor for previous texture. Defaults to 1.
  829. function randomfloor(x, y, ...)
  830.    local count = 0
  831.    local total = 0 --total occurences
  832.  
  833.    local items = {}
  834.    if (getn(arg)==1) then
  835.       if (type(arg[1])=="table") then
  836.      items=arg[1]    -- table is passed
  837.       else
  838.      items={arg[1]}  -- single function passed (hope it's a function)... who could do it?
  839.       end
  840.    else
  841.       items=arg          -- a list of functions and their rarities is not passed in table, but as arguments
  842.    end
  843.  
  844.    local itemlist = {}
  845.  
  846.    for i=1,getn(items) do --_,item in items do
  847.       local item = items[i]
  848.       local titem = type(item)
  849.       if (titem == "function") then
  850.      count = count + 1
  851.      itemlist[count] = {}
  852.      itemlist[count].func = item
  853.      itemlist[count].occf = 1
  854.      total = total + 1
  855.       elseif (titem == "number") then
  856.      itemlist[count].occf = item
  857.      total = total + item-1
  858.       end
  859.    end
  860.  
  861.    local rand = total*random()
  862.    local ctr  = 0
  863.  
  864.    for i=1,count do
  865.       local move = itemlist[i].occf
  866.       if ((rand>=ctr) and (rand<ctr+move)) then
  867.      itemlist[i].func(x,y)
  868.       end
  869.       ctr = ctr + move
  870.    end
  871. end
  872.  
  873.  
  874.  
  875.  
  876.  
  877. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  878. -- OBJECT GROUPS [MULTIPLES]  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  879. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  880. -- see ant.lua documentation for extensive howto
  881.  
  882. -- add a stone to a group
  883. -- face: this is stone face
  884. -- group: object group table
  885. -- attribs: object attributes
  886. function add_multistone(x, y, face, group, attribs)
  887.    local attribs = attribs or {}
  888.    attribs["name"] = attribs.name or (face..(getn(group)+1))
  889.    tinsert(group, set_stone(face, x, y, attribs))
  890. end
  891.  
  892. -- add a floor to a group
  893. -- face: this is floor face
  894. -- group: object group table
  895. -- attribs: object attributes
  896. function add_multifloor(x, y, face, group, attribs)
  897.    local attribs = attribs or {}
  898.    attribs["name"] = attribs.name or (face..(getn(group)+1))
  899.    tinsert(group, set_floor(face, x, y, attribs))
  900. end
  901.  
  902. -- add an item to a group
  903. -- face: this is an item kind
  904. -- group: object group table
  905. -- attribs: object attributes
  906. function add_multiitem(x, y, face, group, attribs)
  907.    local attribs = attribs or {}
  908.    attribs["name"] = attribs.name or (face..(getn(group)+1))
  909.    tinsert(group, set_item(face, x, y, attribs))
  910. end
  911.  
  912. -- add an actor to a group
  913. -- face: this is floor face
  914. -- group: object group table
  915. -- attribs: object attributes
  916. function add_multiactor(x, y, face, group, attribs, actor_mode)
  917.    local attribs = attribs or {}
  918.    local actor_mode = actor_mode or 3
  919.    attribs["name"] = attribs.name or (face..(getn(group)+1))
  920.    tinsert(group, set_actor(face, get_actor_x(x, actor_mode), get_actor_y(y, actor_mode), attribs))
  921. end
  922.  
  923. -- for generic multiples, this only stores cell coordinates and tag information
  924. -- this is usable for example to construct puzzles and trains, see below
  925. function add_multicell(x, y, group, tag)
  926.    local key = getkey(x,y)
  927.    group[key] = {}
  928.    group[key].x = x
  929.    group[key].y = y
  930.    group[key].tag = tag
  931. end
  932.  
  933. -- next generic multiple. Multitag can store several cells under one tagnumber
  934. -- if a function is given, it's result stored.
  935. function add_multitag(x, y, group, tag, func)
  936.    local tab = {x=x, y=y}
  937.  
  938.    if (type(func)=="function") then
  939.       tab.tag = func(x, y)
  940.    elseif (type(func)~="nil") then
  941.       tab.tag = func
  942.    else
  943.       tab.tag = tag
  944.    end
  945.  
  946.    group[tag] = group[tag] or {}
  947.    group[tag][getn(group[tag])+1] = tab
  948. end
  949.  
  950. -- another generic multiple
  951. -- this stores the result of given function(x,y) to table
  952. function add_multiobject(x, y, group, func)
  953.    tinsert(group, func(x, y))
  954. end
  955.  
  956.  
  957.  
  958. -- couple of functions to mark all cells in given area with
  959. -- given tagnumber. Used for rendering gradients. Area must
  960. -- be closed, otherwise stack overflow occurs.
  961. -- usage:
  962. --   slopes={}
  963. --   pivots={}
  964. --   cells["*"]=cell{{{add_multicell, slopes, 1}}}
  965. --   cells["&"]=cell{{{add_multicell, pivots, slopes}}}
  966. -- at the end of levelfile:
  967. --   spread_tag(pivots)
  968. --   render_slopes(slopes)
  969. -- BUGS:
  970. --  stack overflows, if:
  971. --  + the shape is not closed
  972. --  + area is too large (for example very long corridor...)
  973. function spread_tag_depth(x0, y0, tab, tag)
  974.    if tab[getkey(x0, y0)] then return end
  975.  
  976.    add_multicell(x0, y0, tab, tag)
  977.    spread_tag_depth(x0,   y0-1, tab, tag)
  978.    spread_tag_depth(x0+1, y0  , tab, tag)
  979.    spread_tag_depth(x0,   y0+1, tab, tag)
  980.    spread_tag_depth(x0-1, y0  , tab, tag)
  981. end
  982.  
  983. function spread_tag(tab, tag)
  984.    local tag = tag or 2
  985.    for _,val in tab do
  986.       local x0, y0 = val.x, val.y
  987.       local tab0 = val.tag
  988.       spread_tag_depth(x0, y0, tab0, tag)
  989.    end
  990. end
  991.  
  992. -- add the rubber band between all objects in group 1 and all objects in group 2
  993. -- that is, each object from gr1 will be connected with each object from gr2
  994. function add_rubber_bands(gr1, gr2, strength, length)
  995.    for i=1,getn(gr1) do
  996.       for j=1,getn(gr2) do
  997.      AddRubberBand(gr1[i], gr2[j], strength, length)
  998.       end
  999.    end
  1000. end
  1001.  
  1002. -- add pairs: 1st object from gr1 will be connected with 1st from gr2 and so on
  1003. -- requires same sized groups, of course...
  1004. function add_rubber_band_pairs(gr1, gr2, strength, length)
  1005.    for i=1,getn(gr1) do
  1006.       AddRubberBand(gr1[i], gr2[i], strength, length)
  1007.    end
  1008. end
  1009.  
  1010. -- to rubber-band given objects [1,2,3,...,n] like that:
  1011. --  1=2=3=...=n=1
  1012. function rubber_band_circle(gr1, strength, length)
  1013.    local remember = nil
  1014.    local first = nil
  1015.    for a=1,getn(gr1) do
  1016.       local obj1 = gr1[a]
  1017.       if (remember) then
  1018.      AddRubberBand(obj1, remember, strength, length)
  1019.       else
  1020.      first = obj1
  1021.       end
  1022.  
  1023.       remember = obj1
  1024.    end
  1025.  
  1026.    if (first) then
  1027.       AddRubberBand(first, remember, strength, length)
  1028.    end
  1029. end
  1030.  
  1031. -- send message to each object in group
  1032. function send_group_message(group, message, third)
  1033.    for i=1,getn(group) do
  1034.       enigma.SendMessage(group[i], message, third)
  1035.    end
  1036. end
  1037.  
  1038. -- send a message to named object
  1039. function send_message_named(objname, message, third)
  1040.    enigma.SendMessage(enigma.GetNamedObject(objname), message, third)
  1041. end
  1042.  
  1043. -- set attribute to each of the objects in group
  1044. function set_group_attribs(group, attribs)
  1045.    for i=1,getn(group) do
  1046.       set_attribs(group[i], attribs)
  1047.    end
  1048. end
  1049.  
  1050.  
  1051.  
  1052.  
  1053.  
  1054. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1055. -- RAILWAY GENERATOR -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1056. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1057. -- see ant.lua documentation for extensive howto
  1058.  
  1059. function new_rail(engines, path)
  1060.    local func0 = function()
  1061.             for _,engine in %engines do
  1062.                local ekey = getkey(engine.x, engine.y)
  1063.  
  1064.                for _, dir in {engine.dir,{1,0},{0,1},{-1,0},{0,-1}} do
  1065.               local x0, y0 = engine.x+dir[1], engine.y+dir[2]
  1066.               local key = getkey(x0, y0)
  1067.               if ((%path[key]) and (%path[key].tag~=%path[ekey].tag)) then
  1068.                  %path[key].tag = %path[ekey].tag
  1069.                  engine.x, engine.y = x0, y0
  1070.                  engine.dir = dir -- remember direction
  1071.                  engine.tag(x0, y0)
  1072.                  break
  1073.               end
  1074.                end--directions
  1075.             end--engines
  1076.          end--function
  1077.    return func0
  1078. end
  1079.  
  1080.  
  1081.  
  1082.  
  1083. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1084. -- PUZZLE GENERATOR  -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1085. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1086. -- see ant.lua documentation for extensive howto
  1087. function render_puzzles(tab, kind, generatorfunc)
  1088.    for _,val in tab do
  1089.       local kind = kind or puzzle
  1090.       local x,y = val.x, val.y
  1091.  
  1092.       local up   = (tab[getkey(x, y-1)] ~= nil) or 0;
  1093.       local down = (tab[getkey(x, y+1)] ~= nil) or 0;
  1094.       local left = (tab[getkey(x-1, y)] ~= nil) or 0;
  1095.       local right= (tab[getkey(x+1, y)] ~= nil) or 0;
  1096.  
  1097.       if (generatorfunc) then
  1098.      generatorfunc(val);
  1099.       end
  1100.  
  1101.       if ((val.tag~=2) and (kind)) then
  1102.      kind(x, y, getglobal("PUZ_"..up..right..down..left))
  1103.       end
  1104.    end
  1105. end
  1106.  
  1107.  
  1108.  
  1109.  
  1110. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1111. -- BLACK HOLES GENERATOR - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1112. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1113. -- see ant.lua documentation for extensive howto
  1114.  
  1115. function render_wormholes(holes, targets, whole_attribs, actor_mode)
  1116.    local whole_attribs = whole_attribs or {}
  1117.    local actor_mode = actor_mode or 3
  1118.  
  1119.    for _,hval in holes do
  1120.       local target = 0
  1121.       for _,tval in targets do
  1122.      if (tval.tag == hval.tag) then
  1123.         target = tval;
  1124.         break
  1125.      end
  1126.       end
  1127.  
  1128.       if (target ~= 0) then
  1129.      local targetx = get_actor_x(target.x, actor_mode)
  1130.      local targety = get_actor_y(target.y, actor_mode)
  1131.      wormhole(hval.x, hval.y, targetx, targety, whole_attribs)
  1132.       end
  1133.    end
  1134. end
  1135.  
  1136. function worm_hole_pair(cellfuncs, whole_cell, tgt_cell, whole_parent, tgt_parent, whole_grp, tgt_grp, tagnumber)
  1137.    cellfuncs[whole_cell] = cell{{whole_parent, {add_multicell, whole_grp, tagnumber}}}
  1138.    cellfuncs[tgt_cell]   = cell{{tgt_parent,   {add_multicell, tgt_grp,   tagnumber}}}
  1139. end
  1140.  
  1141.  
  1142.  
  1143.  
  1144.  
  1145.  
  1146. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1147. -- SLOPE GENERATOR - -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1148. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1149. -- see ant.lua documentation for extensive howto
  1150.  
  1151. __slopemap = {}
  1152. __slopemap["x0x11x1x"]=SLOPE_N
  1153. __slopemap["x1x01x1x"]=SLOPE_W
  1154. __slopemap["x1x10x1x"]=SLOPE_E
  1155. __slopemap["x1x11x0x"]=SLOPE_S
  1156. __slopemap["x1x00x0x"]=SLOPE_S
  1157. __slopemap["x0x10x0x"]=SLOPE_E
  1158. __slopemap["x0x01x0x"]=SLOPE_W
  1159. __slopemap["x0x00x1x"]=SLOPE_N
  1160.  
  1161. -- soft conditions
  1162. __slopemap["x11x1xxx"]=SLOPE_SMALL_SW
  1163. __slopemap["x1x1111x"]=SLOPE_LARGE_NE
  1164. __slopemap["xxx1x11x"]=SLOPE_SMALL_NE
  1165. __slopemap["x1111x1x"]=SLOPE_LARGE_SW
  1166. __slopemap["xxxx1x11"]=SLOPE_SMALL_NW
  1167. __slopemap["11x11x1x"]=SLOPE_LARGE_SE
  1168. __slopemap["11x1xxxx"]=SLOPE_SMALL_SE
  1169. __slopemap["x1x11x11"]=SLOPE_LARGE_NW
  1170.  
  1171. -- hard conditions -- these don't match always, but help to break ambiguous matches
  1172. __slopemap["x1101x0x"]=SLOPE_SMALL_SW
  1173. __slopemap["x101111x"]=SLOPE_LARGE_NE
  1174. __slopemap["x0x1011x"]=SLOPE_SMALL_NE
  1175. __slopemap["x111101x"]=SLOPE_LARGE_SW
  1176. __slopemap["x0x01x11"]=SLOPE_SMALL_NW
  1177. __slopemap["11x11x10"]=SLOPE_LARGE_SE
  1178. __slopemap["11x10x0x"]=SLOPE_SMALL_SE
  1179. __slopemap["01x11x11"]=SLOPE_LARGE_NW
  1180.  
  1181. --inverses
  1182. __grad_inverse={}
  1183. __grad_inverse[SLOPE_S]=SLOPE_N
  1184. __grad_inverse[SLOPE_N]=SLOPE_S
  1185. __grad_inverse[SLOPE_E]=SLOPE_W
  1186. __grad_inverse[SLOPE_W]=SLOPE_E
  1187. __grad_inverse[SLOPE_LARGE_SE]=SLOPE_SMALL_NW
  1188. __grad_inverse[SLOPE_LARGE_SW]=SLOPE_SMALL_NE
  1189. __grad_inverse[SLOPE_LARGE_NE]=SLOPE_SMALL_SW
  1190. __grad_inverse[SLOPE_LARGE_NW]=SLOPE_SMALL_SE
  1191. __grad_inverse[SLOPE_SMALL_SE]=SLOPE_LARGE_NW
  1192. __grad_inverse[SLOPE_SMALL_NE]=SLOPE_LARGE_SW
  1193. __grad_inverse[SLOPE_SMALL_SW]=SLOPE_LARGE_NE
  1194. __grad_inverse[SLOPE_SMALL_NW]=SLOPE_LARGE_SE
  1195.  
  1196. -- return correct gradient type based on neighbors
  1197. function map_slope(x, y, node)
  1198.    local map = __slopemap;
  1199.    local re  = ""..node[1]..node[2]..node[3]..node[4]..node[5]..node[6]..node[7]..node[8]
  1200.    --
  1201.    local longest=0;
  1202.    local longkey=0;
  1203.    local longval=0;
  1204.    local warns={}
  1205.    --
  1206.    for key,val in map do
  1207.       local okay = 1
  1208.       local count = 0
  1209.       -- okay turns to 0, if any char, that is not 'x', doesn't match
  1210.       for i=1,strlen(key) do
  1211.      local char1 = strsub(key, i, i)
  1212.      local char2 = strsub(re, i, i)
  1213.      --
  1214.      if ((char1~='x')and(char2~='x')and(char1~=char2)) then
  1215.         okay = 0
  1216.         break
  1217.      else
  1218.         if ((char1~='x')and(char2~='x')) then
  1219.            count = count +1
  1220.         end
  1221.      end
  1222.       end
  1223.       --
  1224.       if (okay==1) then
  1225.      if (count>longest) then
  1226.         longest = count;
  1227.         longkey = key;
  1228.         longval = val;
  1229.         warns = {}
  1230.      elseif (count==longest) then
  1231.         tinsert(warns, "map_slope: ambiguous match: '"..longkey.."' vs. '"..key.."' for re '"..re.."'")
  1232.      end
  1233.       end
  1234.    end
  1235.    --
  1236.    for i=1,getn(warns) do
  1237.       debug(warns[i])
  1238.    end
  1239.  
  1240.    if (longest==0) then
  1241.       warning("map_slope: no match for mask '"..re.."' at ["..x..","..y.."].")
  1242.    end
  1243.  
  1244.    return longval;
  1245. end
  1246.  
  1247. function render_slopes(tab, invert)
  1248.    for _,val in tab do
  1249.       local x,y = val.x, val.y
  1250.  
  1251.       local node = {}
  1252.       tinsert(node, (tab[getkey(x-1,y-1)] ~= nil) or 0)
  1253.       tinsert(node, (tab[getkey(x  ,y-1)] ~= nil) or 0)
  1254.       tinsert(node, (tab[getkey(x+1,y-1)] ~= nil) or 0)
  1255.       tinsert(node, (tab[getkey(x-1,y  )] ~= nil) or 0)
  1256.       tinsert(node, (tab[getkey(x+1,y  )] ~= nil) or 0)
  1257.       tinsert(node, (tab[getkey(x-1,y+1)] ~= nil) or 0)
  1258.       tinsert(node, (tab[getkey(x  ,y+1)] ~= nil) or 0)
  1259.       tinsert(node, (tab[getkey(x+1,y+1)] ~= nil) or 0)
  1260.  
  1261.       if (val.tag~=2) then
  1262.      if ((invert~=nil)~=(val.tag==-1)) then   -- this is ((invert) xnor (val.tag==-1))
  1263.         gradient(x, y, __grad_inverse[map_slope(x, y, node)])
  1264.      else
  1265.         gradient(x, y, map_slope(x, y, node))
  1266.      end
  1267.       end
  1268.    end
  1269. end
  1270.  
  1271.  
  1272.  
  1273.  
  1274.  
  1275. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1276. -- BOOLEAN TABLES -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1277. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1278. -- see ant.lua documentation for extensive howto
  1279.  
  1280. -- bool_and tests table for and: all elements have to be '1' to succeed
  1281. function bool_and(tab)
  1282.    return tab.count == tab.value
  1283. end
  1284.  
  1285.  
  1286. -- bool_or tests table for or: at least one element has to be '1' to succeed
  1287. function bool_or(tab)
  1288.    return tab.value > 0
  1289. end
  1290.  
  1291.  
  1292. -- bool_xor tests table for xor: odd number of elements has to be '1' to succeed
  1293. function bool_xor(tab)
  1294.    return mod(tab.value, 2) ~= 0
  1295. end
  1296.  
  1297.  
  1298. -- bool_table initialization
  1299. -- count_tot  is number of cells in table (that is the number of triggers)
  1300. -- count_init is number of cells to init (number of negset triggers)
  1301. -- test_func  is a function to get called each set and negset - a test function
  1302. -- true_func  is a function to be called if test passed
  1303. -- false_func is a function to be called if test failed
  1304. function bool_table(count_tot, count_init, test_func, true_func, false_func)
  1305.    local tab   = {};
  1306.  
  1307.    tab.test    = test_func  or function() return nil end;
  1308.    tab.true    = true_func  or function() return nil end;
  1309.    tab.false   = false_func or function() return nil end;
  1310.    tab.count   = count_tot  or 1;
  1311.    tab.value   = count_init or 0;
  1312.    tab.remember= -1;
  1313.  
  1314.    return tab;
  1315. end
  1316.  
  1317.  
  1318. -- bool val set
  1319. -- this gets called upon every trigger/switcher state change
  1320. -- it changes value of one element of given table
  1321. function bool_set(value, omit, tab)
  1322.    if (value == 0) then
  1323.       tab.value = tab.value -1;
  1324.    else
  1325.       tab.value = tab.value +1;
  1326.    end
  1327.  
  1328.    local res = tab.test(tab);
  1329.    if (tab.remember ~= res) then
  1330.       tab.remember = res;
  1331.  
  1332.       if (res) then
  1333.      debug("bool_set: true")
  1334.      tab.true()
  1335.       else
  1336.      debug("bool_set: false")
  1337.      tab.false()
  1338.       end
  1339.    end
  1340. end
  1341.  
  1342.  
  1343. -- bool val negative set
  1344. -- this is similar to bool_val, except that it sets '1' if triggered off and vice versa
  1345. function bool_negset(value, omit, tab)
  1346.    if (value == 0) then
  1347.       bool_set(1, nil, tab)
  1348.    else
  1349.       bool_set(0, nil, tab)
  1350.    end
  1351. end
  1352.  
  1353.  
  1354.  
  1355.  
  1356.  
  1357. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1358. -- WRAPPED init.lua FUNCTIONS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1359. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1360. -- these functions override common init.lua functions, giving them the power
  1361. -- of ant.lua syntax -- that is, calling with list of coordinates,
  1362. -- using negative coordinates for positions relative to lower-right corner
  1363. -- and maybe also some others that I do not recall now :)
  1364. -- Note, that basic syntax remain intact, so at first glance no changes are visible!
  1365. -- Wrapped functions are a lot slower, empirically nearly 3.5 times. Not a great deal,
  1366. -- as LUA is really fast, and the same for enigma. Tested on rather slow 166MHz AMD,
  1367. -- 80 megs of memory, Win95 - you won't notice extra time spent by loading a level.
  1368.  
  1369. -- stones
  1370. oxyd =     cell{oxyd}
  1371. fakeoxyd = cell{fakeoxyd}
  1372. oneway =   cell{oneway}
  1373. laser =    cell{laser}
  1374. mirrorp =  cell{mirrorp}
  1375. mirror3 =  cell{mirror3}
  1376. puzzle =   cell{puzzle}
  1377. switch =   cell{switch}
  1378.  
  1379. -- floors
  1380. abyss =    cell{abyss}
  1381. hollow =   cell{hollow}
  1382. hill=      cell{item="it-hill"}
  1383.  
  1384. -- items
  1385. Document = cell{Document}
  1386. hammer =   cell{hammer}
  1387. dynamite = cell{dynamite}
  1388. bomb =     cell{bomb}
  1389. shogundot= cell{shogundot}
  1390. keya =     cell{keya}
  1391. keyb =     cell{keyb}
  1392. keyc =     cell{keyc}
  1393. shogundot1=cell{{{shogundot, 1}}}
  1394. shogundot2=cell{{{shogundot, 2}}}
  1395. shogundot3=cell{{{shogundot, 3}}}
  1396. Wormhole = cell{Wormhole}
  1397. doorh =    cell{doorh}
  1398. doorv =    cell{doorv}
  1399. gradient = cell{gradient}
  1400.  
  1401. -- lower case equivalents
  1402. document = Document
  1403. wormhole = Wormhole
  1404.  
  1405.  
  1406.  
  1407.  
  1408. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1409. -- MEANINGS FOR COMMON CELL KEYS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1410. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  1411. -- here are declarations for default cell bindings
  1412.  
  1413. -- bindings based on init.lua functions
  1414. map_cell_meaning(".", abyss)
  1415. map_cell_meaning("0", oxyd)
  1416.  
  1417. -- common constructions
  1418. map_cell_meaning("W", cell{stone="st-wood"})
  1419. map_cell_meaning("B", cell{stone="st-block"})
  1420. map_cell_meaning("D", cell{stone="st-death"})
  1421. map_cell_meaning("=", cell{stone="st-glass"})
  1422. map_cell_meaning("X", cell{stone="st-grate1"})
  1423.  
  1424. -- actors
  1425. map_cell_meaning("o", cell{actor={"ac-whiteball-small", {player=0, mouseforce=1}}})
  1426. map_cell_meaning("O", cell{actor={"ac-blackball", {player=0, mouseforce=1}}})
  1427.  
  1428. -- presets
  1429. function meditation_mode()
  1430.    map_cell_meaning("O", hollow)
  1431. end
  1432.  
  1433. function multiplayer_mode()
  1434.    map_cell_meaning("1", cell{item="it-yinyang", actor={"ac-blackball", {player=0, mouseforce=1}}})
  1435.    map_cell_meaning("2", cell{item="it-yinyang", actor={"ac-whiteball", {player=1, mouseforce=1}}})
  1436. end
  1437.  
  1438. -- level mood
  1439. function grass_mode()
  1440.    map_cell_meaning(" ", cell{floor="fl-leaves"})
  1441.    map_cell_meaning("#", cell{stone="st-rock1"})
  1442. end
  1443.  
  1444. function metal_mode()
  1445.    map_cell_meaning(" ", cell{floor="fl-metal"})
  1446.    map_cell_meaning("#", cell{stone="st-rock2"})
  1447. end
  1448.  
  1449. -- maybe in a future, there will be a possibility to integrate Nat's mazes into maps
  1450. function maze_mode()
  1451.    Require("levels/natmaze.lua")
  1452.    --map_cell_meaning("!", )
  1453. end
  1454.