home *** CD-ROM | disk | FTP | other *** search
/ GameStar Special 2004 August / GSSH0804.iso / Geschicklichkeit / Enigma / Enigma-081.exe / doc / ant_lua.txt next >
Text File  |  2003-10-12  |  85KB  |  2,305 lines

  1. ant.lua documentation
  2. Petr Machata, ant_39@centrum.cz
  3.  
  4. This document describes usage of ant.lua, the collection of helper
  5. functions for Enigma map designers.
  6.  
  7.  
  8. ================================================================================
  9. 0] PREFACE
  10. ================================================================================
  11.  
  12. 0.1 Revision history
  13. --------------------------------------------------------------------------------
  14.  
  15. version 0.1.3: 2003-06-19:
  16.   Proofread, some typos fixed, some sentences changed
  17.   Added chapter 'Puzzle kinds'
  18.  
  19. version 0.1.2: 2003-05-11:
  20.   Added chapter 'Multiple wholes per one target'
  21.   Changes in a chapter 'use_cells'
  22.  
  23. version 0.1.1: 2003-04-25:
  24.   Number of typos fixed
  25.  
  26. version 0.1: 2003-04-13:
  27.   this covers ant.lua for upcoming Enigma 0.8
  28.   first release of document
  29.  
  30.  
  31. 0.2 Table of contents
  32. --------------------------------------------------------------------------------
  33.  
  34. 0] PREFACE
  35.    0.1 Revision history
  36.    0.2 Table of contents
  37.  
  38. 1] INTRODUCTION
  39.    1.1 What is this document
  40.    1.2 How to contact author
  41.    1.3 Distribution policy
  42.    1.4 New versions of this document
  43.    1.5 Bugs
  44.  
  45. 2] ABOUT ant.lua
  46.    2.1 What is ant.lua
  47.    2.2 What is it good for?
  48.    2.3 How to use it
  49.  
  50. 3] VISUAL MAP DESIGN
  51.    3.1 Simple things first
  52.       3.1.1 What is it, how to use it
  53.       3.1.2 Using cell{}
  54.       3.1.3 Parents of cell{}
  55.       3.1.4 Drawing map
  56.    3.2 More complicated then
  57.       3.2.1 Default parents
  58.       3.2.2 Default cell meanings
  59.       3.2.4 use_cells
  60.       3.2.3 Layered maps
  61.       3.2.4 Drawing per partes
  62.       3.2.5 Multichar maps
  63.    3.3 cell{} to depth
  64.       3.3.1 Checker floor
  65.       3.3.2 Random floor
  66.       3.3.3 Curried function construction
  67.  
  68. 4] FUNCTIONAL APPROACH
  69.    4.1 Fills, borders, ...
  70.    4.2 init.lua counterparts - set_, draw_
  71.    4.3 Coordinate mangling
  72.  
  73. 5] OBJECT GROUPS
  74.    5.1 Introduction
  75.    5.2 Common multiples
  76.       5.2.1 Multielement functions
  77.       5.2.2 Group actions
  78.       5.2.3 Rubber bands
  79.    5.3 Generic multielements
  80.       5.3.1 add_multicell
  81.       5.3.2 add_multiobject
  82.       5.3.3 add_multitag
  83.    5.4 Worm holes
  84.       5.4.1 Forewords
  85.       5.4.2 Technical background
  86.       5.4.3 Setting up cell{} functions
  87.       5.4.4 Setting up the map
  88.       5.4.5 Post-execution code
  89.       5.4.6 Multiple wholes per one target
  90.    5.5 Railways
  91.       5.5.1 What are railways
  92.       5.5.2 Technical background
  93.       5.5.3 Setting up cell{} functions
  94.       5.5.4 Binding the train to railway
  95.       5.5.5 Setting up the map
  96.    5.6 Puzzles
  97.       5.6.1 Forewords
  98.       5.6.2 Technical background
  99.       5.6.3 Setting up puzzle
  100.       5.6.4 Fake puzzles
  101.       5.6.5 Puzzle kinds
  102.    5.7 Slopes
  103.       5.7.1 Forewords
  104.       5.7.2 Technical background
  105.       5.7.3 Setting up cell{} functions
  106.       5.7.4 Setting up the map
  107.       5.7.5 Post-execution code
  108.       5.7.6 Mixing several slopes
  109.       5.7.7 Fake slopes
  110.       5.7.8 Invert slopes
  111.    5.8 Afterwords
  112.  
  113. 6] HELPER FUNCTIONS
  114.    6.1 Debugging
  115.       6.1.1 Warnings
  116.       6.1.2 Debugs
  117.    6.2 Clone table
  118.    6.3 Sending messages
  119.  
  120.  
  121. ================================================================================
  122. [1] INTRODUCTION
  123. ================================================================================
  124.  
  125. 1.1 What is this document
  126. --------------------------------------------------------------------------------
  127.  
  128. This document tris to uncover hidden treasures of ant.lua, the library
  129. of helper functions for Enigma level designers. If one level is
  130. created with help of this, I reached my goal.
  131.  
  132. Please, no great expectations. I'm not very experienced in English and
  133. I have never written such a document before. I did my best, but you
  134. know how it is...
  135.  
  136.  
  137. 1.2 How to contact author
  138. --------------------------------------------------------------------------------
  139.  
  140. Any questions, bug reports, misunderstandings, typos, flames and
  141. praises, regarding both this documentation and ant.lua library, please
  142. send to:
  143.  
  144.     my e-mail:        ant_39 at centrum.cz
  145.     enigma-devel ML:  enigma-devel at nongnu.org
  146.  
  147.  
  148. 1.3 Distribution policy
  149. --------------------------------------------------------------------------------
  150.  
  151. This documentation is covered by GNU GPL, v.2 or later. Interpret the
  152. document's source text as the 'program' and adhere to the following
  153. terms:
  154.  
  155.     This program is free software; you can redistribute it and/or
  156.     modify it under the terms of the GNU General Public License as
  157.     published by the Free Software Foundation; either version 2 of the
  158.     License, or (at your option) any later version.
  159.  
  160.     This program is distributed in the hope that it will be useful,
  161.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  162.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  163.     General Public License for more details.
  164.  
  165.     You should have received a copy of the GNU General Public License
  166.     along with this program; if not, write to the Free Software
  167.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  168.     02111-1307 USA
  169.  
  170.  
  171. 1.4 New versions of this document
  172. --------------------------------------------------------------------------------
  173.  
  174. Most probably, any new version will be located directly at Enigma CVS
  175. repository. If it isn't there, ant.lua was probably discarded from
  176. source tree either, and so the documentation is obsolete.
  177.  
  178.  
  179. 1.5 Bugs
  180. --------------------------------------------------------------------------------
  181.  
  182. There are several things missing in the document yet. There could be a
  183. complete reference of ant.lua, though I'm not very sure whether
  184. ant.lua itself is not better source.
  185.  
  186. Not all examples were tested. I often rely on my knowledge, so if
  187. something doesn't work, the bug doesn't have to be in library.
  188.  
  189. Besides this, the document should be completely rewritten by someone
  190. better in English. This is utopia, so we simply have to get enough
  191. with this.
  192.  
  193.  
  194.  
  195. ================================================================================
  196. 2] ABOUT ant.lua
  197. ================================================================================
  198.  
  199. 2.1 What is ant.lua
  200. --------------------------------------------------------------------------------
  201.  
  202. ant.lua is lua module that should help level designers to create their
  203. maps. At this time, graphical level editor is being worked on, or
  204. maybe the works already pushed it to somehow usable stage. In older
  205. times there was nothing alike, so enigma maps were created by manually
  206. placing stones and floor squares to their places in a simple
  207. programming language. This tool made it a way more comfortable to me.
  208.  
  209. It's possible that the editor will make this module useless, so
  210. further development will stop. It will probably stay in enigma source
  211. repository in future, as many maps and also some other libraries
  212. (ralf.lua for example) use it.
  213.  
  214.  
  215. 2.2 What is it good for?
  216. --------------------------------------------------------------------------------
  217.  
  218. Well, for creating enigma maps.
  219.  
  220. Now seriously. Basic idea behind creating maps to enigma is that you
  221. use a function every time you want to place a stone, every time you
  222. place a floor square, etc. You draw the level procedurally, use
  223. functions for filling, distribute items, stones, floors, actors,
  224. etc. There are loops, well known from programming languages (while,
  225. repeat, for, for each), but level creation process is not very simple
  226. even with them.
  227.  
  228. For this reason the level developers tend to use some sort of visual
  229. map creation. You draw the level to a simple string grid, tell to the
  230. library that all #'s are stone walls and all *'s are say puzzle
  231. stones, and then call a function. It reads your definitions, looks to
  232. string map that you have just made, and turns them to ugly LUA code,
  233. that in turn changes to beautiful and precious elements of Enigma
  234. world.
  235.  
  236.  
  237. 2.3 How to use it
  238. --------------------------------------------------------------------------------
  239.  
  240. Let's look at how a simple map can look like, if it's created with
  241. ant.lua. First, how does it look without it:
  242.  
  243.       enigma.ConserveLevel = TRUE
  244.       levelw = 20
  245.       levelh = 13
  246.  
  247.       create_world(levelw, levelh)
  248.       oxyd_default_flavor = "a"       -- Default flavor for oxyd stones.
  249.  
  250.       draw_border("st-brownie")
  251.       fill_floor("fl-hay", 0,0, level_width,level_height)
  252.  
  253.       set_stone("st-fart", levelw-1,0, {name="fart"})
  254.       set_stone("st-timer", 0,0, {action="trigger", target="fart", interval=10})
  255.  
  256.       oxyd(3,3)
  257.       oxyd(level_width-4,level_height-4)
  258.       oxyd(level_width-4, 3)
  259.       oxyd(3,level_height-4)
  260.       oxyd_shuffle()
  261.  
  262.       set_actor("ac-blackball", 10,6.5, {player=0})
  263.  
  264. This is a welcome map for Enigma. First level in Enigma level
  265. package. You have to have a great imagination to create maps in such a
  266. way. You have to use precious coordinates and dozens of commands,
  267. nothing very simple. Great for small levels and fast stings, but
  268. complicated levels are difficult to create this way.
  269.  
  270. Using ant.lua, the code turns to look this way:
  271.  
  272.       Require("levels/ant.lua")
  273.  
  274.       cells={}
  275.       cells[" "]=cell{floor="fl-sand"}
  276.       cells["#"]=cell{stone="st-greenbrown"}
  277.       cells["~"]=cell{stone={"st-timer", {action="trigger", target="fart", interval=10}}}
  278.       cells["*"]=cell{stone={"st-fart", {name="fart"}}}
  279.  
  280.       level = {
  281.          "~##################*",
  282.          "#                  #",
  283.          "#                  #",
  284.          "#  0            0  #",
  285.          "#                  #",
  286.          "#                  #",
  287.          "#         O        #",
  288.          "#                  #",
  289.          "#                  #",
  290.          "#  0            0  #",
  291.          "#                  #",
  292.          "#                  #",
  293.          "####################"
  294.       }
  295.  
  296.       oxyd_default_flavor = "a"
  297.       set_default_parent(cells[" "])
  298.       create_world_by_map(level)
  299.       oxyd_shuffle()
  300.  
  301.  
  302. Generally, you will save no lines of code, but make things look
  303. clear. This will ease maintenance works, debugging (yes, even in lua
  304. maps there can be bugs...) and so on. If other people look to your
  305. code, it will be clear to them what have you meant, where to look for
  306. particular elements, and so on.
  307.  
  308. At the very top of file, you have to include ant.lua with the Require
  309. function. Then you prepare name space of your elements, this time it's
  310. called cells. You may have several maps in your file, each of them
  311. using different name space, so that "#" in one map is stone wall and
  312. in other map it's metal block. This is seldom used, but it's possible.
  313.  
  314. Then, you occupy name space with cell keys. In our example, there are
  315. four keys - "#" for green-brown stone, " " for sand floor, "~" for
  316. timer stone, that triggers fart each 10 seconds, and "*", the fart
  317. stone itself.
  318.  
  319. After cells{}, there is a map itself. It incorporates all of the
  320. declared elements (cell keys), plus element "O" (letter o), which
  321. automatically stands for black marble (if you don't override it), and
  322. element "0" (a zero), which is oxyd stone (again, if you don't change
  323. it).
  324.  
  325. Finally, oxyd flavor is selected (the way oxyd stones will look like),
  326. default parent is set up, map is created, oxyd stones are mixed. All
  327. done.
  328.  
  329. We will look at default parent later on. You should know for now, that
  330. this is a default "base" element for each map cell. The command itself
  331. tells to ant.lua: "let there be sand floor everywhere, if not said
  332. otherwise".
  333.  
  334. Well, this is enough for now. If you are interested, read on, really
  335. interesting things are yet to be said. It you are not, I'm sorry for
  336. bothering you. I really didn't meant to.
  337.  
  338.  
  339. ================================================================================
  340. 3] VISUAL MAP DESIGN
  341. ================================================================================
  342.  
  343. 3.1 Simple things first
  344. --------------------------------------------------------------------------------
  345.  
  346. 3.1.1 What is it, how to use it
  347. ...............................
  348.  
  349. The thing that you have just seen was an example of visual map
  350. design. You draw the map to the string grid, declare which key
  351. produces which element, and let ant.lua draw the thing. The way how
  352. your string map looks like is very near to how the world will look
  353. like once it gets rendered, thus visual.
  354.  
  355. ant.lua has also the features that make your life easier even if you
  356. want to use procedural way of map design. These are not subject of
  357. this chapter and are to be discussed later.
  358.  
  359.  
  360. 3.1.2 Using cell{}
  361. ..................
  362.  
  363. Once more, look at the declaration of cell keys:
  364.  
  365.       cells={}
  366.       cells[" "]=cell{floor="fl-sand"}
  367.       cells["#"]=cell{stone="st-greenbrown"}
  368.       cells["~"]=cell{stone={"st-timer", {action="trigger", target="fart", interval=10}}}
  369.       cells["*"]=cell{stone={"st-fart", {name="fart"}}}
  370.  
  371. First you create table of cell functions. Then you fill it with keys,
  372. and each key bind with its meaning. The core part of this declaration
  373. is function cell(). It's to be seen on each declaration line, and it
  374. can be used to declare any combination of floor, stone, item and
  375. actor. It can also "inherit" from other cell function, which will be
  376. discussed later.
  377.  
  378. Generally, there are four ways how to use cell function:
  379.  
  380.       cells[" "]=cell{floor="fl-sand"}
  381.       cells["#"]=cell{stone="st-rock2"}
  382.       cells["s"]=cell{item= "it-spring2"}
  383.       cells["o"]=cell{actor="ac-whiteball-small"}
  384.  
  385. That is, you can create any part of Enigma world with cell
  386. functions. You can also mix things together, like this:
  387.  
  388.       cells["&"]=cell{floor="fl-water", stone="st-grate1"}
  389.  
  390. Each stone, actor, item and floor may have an attributes. Attributes
  391. of an object affect its behavior. For example, look at switch
  392. stone. This stone can make an action. It can open doors, turn boulders,
  393. turn on lasers etc. Zillion of things. Attributes say what exactly
  394. will it do. Or timer stone (we had one in an example above). Timer
  395. stone does an action in exactly specified intervals. Kind of action and
  396. the interval are driven, surprisingly, by an attributes.
  397.  
  398. Attributes of element are defined this way:
  399.  
  400.       cells["~"]=cell{stone={"st-timer", {action="trigger", target="fart", interval=10}}}
  401.       cells["*"]=cell{stone={"st-fart", {name="fart"}}}
  402.  
  403. Syntax is as follows:
  404.  
  405.       something = cell{stone={"st-something", {attrib1=value1, attrib2=value2, ...}}}
  406.  
  407. And similar for floors and others.
  408.  
  409. Knowledge of attributes is basic for customizing behavior of the
  410. objects. You can get it by looking at a
  411. /enigma-dir/doc/CREATING-LEVELS, or, better, by studying Enigma
  412. sources. Particularly the file /enigma-dir/src/objects.cc and
  413. /enigma-dir/src/items.cc. I believe that a better documentation is
  414. underway.
  415.  
  416.  
  417. 3.1.3 Parents of cell{}
  418. .......................
  419.  
  420. Mechanism of parents provides mechanism that arranges cell keys to
  421. hierarchical trees. Imagine this: you want to have two surfaces in
  422. your map. A grass and a sand. Also you would like to have a grate
  423. stone over each of the surfaces. You can do something like this:
  424.  
  425.       cells[" "]=cell{floor="fl-sand"}
  426.       cells["."]=cell{floor="fl-leaves"}
  427.       cells["x"]=cell{floor="fl-sand",   stone="st-grate1"}
  428.       cells["X"]=cell{floor="fl-leaves", stone="st-grate1"}
  429.  
  430. or, better:
  431.  
  432.       cells[" "]=cell{floor="fl-sand"}   -- sand alone
  433.       cells["."]=cell{floor="fl-leaves"} -- grass alone
  434.       cells["x"]=cell{parent=cells[" "], stone="st-grate1"} -- grate over sand
  435.       cells["X"]=cell{parent=cells["."], stone="st-grate1"} -- grate over leaves
  436.  
  437. This is better, because once you change the surface (let's say you
  438. like fl-rough better) you have to change it in just one place. But
  439. still, it can be improved a bit:
  440.  
  441.       cells[" "]=cell{floor="fl-sand"}   -- sand alone
  442.       cells["."]=cell{floor="fl-leaves"} -- grass alone
  443.       cells["g"]=cell{stone="st-grate1"} -- grate alone
  444.       cells["x"]=cell{parent={cells[" "], cells["g"]}}
  445.       cells["X"]=cell{parent={cells["."], cells["g"]}}
  446.  
  447. And this is perfectly generic. You can replace st-grate1 with
  448. st-grate2 and everything changes by itself. You replace fl-sand with
  449. fl-rough, and sand changes to rough floor everywhere.
  450.  
  451. This is one point where procedural way of creating levels is
  452. better. In map, you have to differ between grate on sand and grate on
  453. leaves, like here:
  454.  
  455.       level = {
  456.          "####################",
  457.          "#....     x    ....#",
  458.          "#XXXXxxxxxx    ....#",
  459.          "#....    xxxxxxXXXX#",
  460.          "#....    x     ....#",
  461.          "####################"
  462.       }
  463.  
  464. Hierarchy:
  465.  
  466.         cells[" "]  \
  467.                      > -> cells["x"]
  468.         cells["g"]  <
  469.                      > -> cells["X"]
  470.         cells["."]  /
  471.  
  472. You can create a way more complicated trees. You may not create
  473. circular inheritance (A has parent B, whereas B has parent A). LUA
  474. won't let you do so, but it wouldn't be very wise to do it either.
  475.  
  476. (In fact, it is possible to workaround it and create such a
  477. circularity, but it brings no extra functionality, except for some
  478. stack overflows)
  479.  
  480. In fact, parent function may be any function that accepts x and y as
  481. it's first two arguments. For example:
  482.  
  483.          function pr(x,y)
  484.             print(x, y)
  485.          end
  486.  
  487.          ... some LUA code ...
  488.  
  489.          cells["w"] = cell{parent={pr, cells["p"]}}
  490.  
  491. This code writes x and y coordinates of element "w" for each place
  492. where element is located. This example itself is good for nothing,
  493. there are better usages of this principle. We will discuss them later,
  494. in a chapter about multiples.
  495.  
  496.  
  497. 3.1.4 Drawing map
  498. .................
  499.  
  500. You already saw an example map at the beginning of this document.
  501. Well, that was exactly how the maps are created. You make up the
  502. string grid, where each char represents one square of Enigma
  503. world. Map may be of any size, but it should be at least 20x13
  504. squares, one screen map.
  505.  
  506. At the end of level file, there is usually located a combo of level
  507. creating commands. Let's look:
  508.  
  509.       oxyd_default_flavor = "a"
  510.       set_default_parent(cells[" "])
  511.       create_world_by_map(level)
  512.       oxyd_shuffle()
  513.  
  514. More about oxyd_default_flavor variable should be said at
  515. /enigma-dir/doc/functions.html. Generally, this variable controls how
  516. do the oxyd stones look like. At the time of writing this, it's
  517. possible to select between "a", "b", "c", and (surprisingly) "d". It's
  518. expectable that next flavor will be "e", should there be any at all.
  519.  
  520. Default parent will be discussed later.
  521.  
  522. Then, there is create_world_by_map. There are several more approaches
  523. available, plus you can select a name space of cells. Full command
  524. looks this way:
  525.  
  526.       create_world_by_map(level, cells)
  527.  
  528. What means, use the map "level". Meaning of chars of this map is
  529. described in a table named "cells". However, you may omit the second
  530. argument. If you do so, ant.lua will automatically pick a table named
  531. "cells". If there is none, a warning will be displayed, and empty
  532. table used instead.
  533.  
  534.  
  535. 3.2 More complicated then
  536. --------------------------------------------------------------------------------
  537.  
  538. 3.2.1 Default parents
  539. .....................
  540.  
  541. Now we get to promised default parent. You already know that each cell
  542. can have a parent. Any function at all can become a parent of some
  543. cell, but it's usual to use another cells as a parents. This makes
  544. level designing somehow better to understand and once written levels
  545. are easier to maintain.
  546.  
  547. This is everything very nice, but imagine a level built up completely
  548. on sand. Every floor square is sand. What happens? Look:
  549.  
  550.       cells[" "] = cell{floor="fl-sand"}
  551.       cells["#"] = cell{parent=cells[" "], stone="st-rock3"}
  552.       cells["D"] = cell{parent=cells[" "], stone="st-death"}
  553.       cells["W"] = cell{parent=cells[" "], stone="st-wood"}
  554.       ...
  555.  
  556. It's boring cut-and-paste. If a single function is automatically
  557. parent of everything, there is no need to declare it this way. You can
  558. simply put down:
  559.  
  560.       set_default_parent(cells[" "])
  561.  
  562. Well, what if there is a grassy field in the middle of all that sand?
  563. No problem. Default parents get executed before any other parents, and
  564. these are in turn executed before any other cell elements. That means,
  565. that common parents always override default parents, and common cell
  566. elements (like stone, floor, ...) always override any parent. So, this
  567. is perfectly legal:
  568.  
  569.       cells[" "] = cell{floor="fl-sand"}
  570.       cells["."] = cell{floor="fl-leaves"}
  571.       cells[":"] = cell{parent=cells["."], floor="fl-himalaya"}
  572.       ...
  573.       set_default_parent(cells[" "])
  574.  
  575. It works as expected: all spaces in map are sand, and it's OK, as sand
  576. is default parent. All dots mean grass, even if default parent is
  577. sand. And all colons are replaced with himalayas stone floor, even if
  578. grass is declared as a parent and sand as a default parent.
  579.  
  580. In fact, this is both power and weakness of the system. Parents are
  581. executed every time. They're all functions, so the engine doesn't know
  582. what exactly they're doing. It's waste of time - all default parents
  583. are executed for each cell every time it gets displayed, and all cell
  584. common parents the same. The engine doesn't know that nine out of ten
  585. parents set floor, and so he sets floor nine times.
  586.  
  587.  
  588. 3.2.2 Default cell meanings
  589. ...........................
  590.  
  591. After first ten levels or so, you note that you use the same symbols
  592. for particular entities. For example letter 'O' for black marble,
  593. number '0' for oxyd stone, '#' for stone wall and 'D' for death
  594. stone. This made me do something like common cell meaning.
  595.  
  596. Default meanings save time and code in case that you use the component
  597. in standard way. You don't have to declare such a component and
  598. ant.lua automatically pick its default meaning. For example, look
  599. again to the welcome.lua example:
  600.  
  601.       cells={}
  602.       cells[" "]=cell{floor="fl-sand"}
  603.       cells["#"]=cell{stone="st-greenbrown"}
  604.       cells["~"]=cell{stone={"st-timer", {action="trigger", target="fart", interval=10}}}
  605.       cells["*"]=cell{stone={"st-fart", {name="fart"}}}
  606.  
  607.       level = {
  608.          "~##################*",
  609.          "#                  #",
  610.          "#                  #",
  611.          "#  0            0  #",
  612.          "#                  #",
  613.          "#                  #",
  614.          "#         O        #",
  615.          "#                  #",
  616.          "#                  #",
  617.          "#  0            0  #",
  618.          "#                  #",
  619.          "#                  #",
  620.          "####################"
  621.       }
  622.  
  623. The cells '0' and 'O' are not declared at all, still they may be used
  624. at a string map. That is because 'O' and '0' are bound to black marble
  625. actor and oxyd stone by default. There are more of a kind:
  626.  
  627.       '.' stands for "fl-abyss"
  628.       'o' stands for "ac-whiteball-small"
  629.       'W' stands for "st-wood"
  630.       'B' stands for "st-block"
  631.       'D' stands for "st-death"
  632.       '=' stands for "st-glass"
  633.       'X' stands for "st-grate"
  634.  
  635. And maybe some more will be declared in future. Look to ant.lua, to
  636. section 'MEANINGS FOR COMMON CELL KEYS'.
  637.  
  638. Besides this, there is a bunch of map moods and modes. These moods and
  639. modes map some other cell meanings, if you turn them on. If you write
  640. this into your level file:
  641.  
  642.       meditation_mode()
  643.  
  644. you turn on meditation mode. In this mode, letter 'O' has a special
  645. meaning of a floor pit (hollow) that has to be occupied by a small
  646. white marble for the level to be finished.
  647.  
  648. Another modes and their bindings:
  649.  
  650.       multiplayer_mode()
  651.         '1' stands for black marble
  652.         '2' stands for white marble
  653.         each of these marbles gets an it-yinyang automatically, so that
  654.         the player can switch between the marbles. Letter 'O' has still
  655.         its meaning of black marble without a yinyang item.
  656.  
  657.       grass_mode()
  658.         '#' stands for "st-rock1"
  659.         ' ' stands for "fl-leaves"
  660.  
  661.       metal_mode()
  662.         '#' stands for "st-rock2"
  663.         ' ' stands for "fl-metal"
  664.  
  665. It's alike that more modes are to come in future.
  666.  
  667. If you want to override the common meaning, no problem. Just declare
  668. the element in your cells table. ant.lua will look for default meaning
  669. only in case it doesn't find it there.
  670.  
  671.  
  672. 3.2.4 use_cells
  673. ...............
  674.  
  675. When you rely on a default cell meanings, you happen to miss many of
  676. default meanings in your cells table. For example, you don't have to
  677. declare cells["#"] in metal_mode, as '#' stands for metal stone
  678. already.
  679.  
  680. Well, but what if you want to use given cell as a parent? What if you
  681. want to place an actor to non-default floor. There is a sand
  682. everywhere in your map, so it's reasonable to use the sand for default
  683. parent. But you need an actor on metal floor. Typical construction
  684. looks like this:
  685.  
  686.       cells = {}
  687.       cells["_"]=cell{floor="fl-metal"}
  688.       cells["*"]=cell{parent={cell["_"], cell["O"]}}
  689.  
  690. Ha! But there is no cell["O"], because you use default meanings. And
  691. who wants to declare cells["O"] - there are default meanings for you
  692. not to have to do this. Well, there is a function that helps you in
  693. such a situations:
  694.  
  695.       cells = {}
  696.       use_cells("O")
  697.       cells["_"]=cell{floor="fl-metal"}
  698.       cells["*"]=cell{parent={cell["_"], cell["O"]}}
  699.  
  700. That's it. Even better, if you have only one actor in your map, you
  701. can override default meaning:
  702.  
  703.       cells = {}
  704.       use_cells("O")
  705.       cells["_"]=cell{floor="fl-metal"}
  706.       cells["O"]=cell{parent={cell["_"], cell["O"]}}
  707.  
  708. The function can also get a cellfuncs-table as an argument. This is
  709. particularly necessary if you have your definitions in a table with
  710. the name different from 'cells'.
  711.  
  712.       cells2 = {}
  713.       use_cells(cells2, "O", "D")
  714.  
  715. It's not very common to use 'use_cells' in map, but it happens once
  716. upon a time.
  717.  
  718.  
  719. 3.2.3 Layered maps
  720. ..................
  721.  
  722. It's also possible to map surfaces, stones and items separately.
  723. Three maps are created then, and you write:
  724.  
  725.       create_world_by_map(floors, fcells)
  726.       draw_map(0, 0, stones, scells)
  727.       draw_map(0, 0, items,  icells)
  728.  
  729. If you have only one table of cell meanings, named 'cells', you may
  730. write this, as 'cells' is being looked for by default:
  731.  
  732.       create_world_by_map(floors)
  733.       draw_map(0, 0, stones)
  734.       draw_map(0, 0, items)
  735.  
  736. The only tricky thing to avoid is default parent - you may not use
  737. default parents in layered maps, or, the default parent may not change
  738. map itself. Imagine sand floor for the default parent. You let ant.lua
  739. draw floors, and it's OK. Then you let draw stones, and all floors are
  740. overridden by default parent. Beware. Or, draw layers in reverse
  741. order.
  742.  
  743.  
  744. 3.2.4 Drawing per partes
  745. ........................
  746.  
  747. Currently, it's possible to draw a map as a whole, by one command, or,
  748. for more precious drawing, draw a part of map, or draw just the
  749. squares you want to be drawn.
  750.  
  751. These functions are participating in drawing process. They're
  752. organized so that the most low-level function is first and the most
  753. high-level last.
  754.  
  755.       function render_key(rx, ry, key, cellfuncs)
  756.       function get_cell_by_xy(mx, my, map)
  757.       function render_map_cell(rx0, ry0, mx, my, map, cellfuncs)
  758.       function draw_map_portion(rx0, ry0, mxy0, mxy1, map, cellfuncs)
  759.       function draw_map(rx0, ry0, map, cellfuncs)
  760.       function prepare_world_by_map(map)
  761.       function create_world_by_map(map, cellfuncs)
  762.  
  763. Now we'll look on those functions briefly.
  764.  
  765.   render_key: render one square of world
  766.     rx, ry: which square to render
  767.     key:    the cell key, like in string map
  768.     cellfuncs: table of cell functions, may be omitted
  769.     *example: render_key(5,15, '#')
  770.               render_key(5,15, ' ', cells)
  771.  
  772.   get_cell_by_xy: get a key at given map location
  773.     mx, my: coordinates of key at map
  774.     map:    string map
  775.  
  776.   render_map_cell: draw given square of map
  777.     rx0, ry0: where should be left top corner of map located in world
  778.     mx, my:   coordinates of the cell in map
  779.     map:      the map
  780.     cellfuncs:table of cell functions, may be omitted
  781.  
  782.   draw_map_portion: draw given part of map
  783.     rx0, ry0: where should be left top corner of map located in world
  784.     mxy0:     {mx0,my0} -> coordinates of left top corner of portion
  785.     mxy1:     {mx1,my1} -> coordinates of right bottom corner
  786.     map:      string map
  787.     cellfuncs:table of cell functions, may be omitted
  788.     *example: draw_map_portion(0,0, {2,5}, {10,7}, level, cells)
  789.  
  790.   draw_map: draw whole map
  791.     rx0, ry0: world coordinates of left top corner of map
  792.     map:      string map to be drawn
  793.     cellfuncs:table of cell functions, may be omitted
  794.  
  795.   prepare_world_by_map: create Enigma world with the size by given map
  796.     map: string map, which the size of the world is taken from
  797.  
  798.   create_world_by_map: create and draw Enigma world
  799.     map:       string map of the world
  800.     cellfuncs: table of cell functions, may be omitted
  801.  
  802.  
  803. 3.2.5 Multichar maps
  804. ....................
  805.  
  806. It could happen that you need to use the map, where each cell is
  807. defined by more than one character. You may simply create the map so
  808. complex, that you run out of chars. You may create the map, where each
  809. key is composed of three chars, first declaring floor type, second
  810. stone, third item or actor. Generally it's not used, but there is a
  811. possibility to do so. Functions in ant.lua can work with such a maps.
  812.  
  813. There is only one thing that you have to do, to let ant.lua know what
  814. key width you are using, that is, how many chars are the keys composed
  815. of. That thing is:
  816.  
  817.       set_cell_key_width(w)
  818.  
  819. where 'w' stands for the width of key. By default it's 1, and you can
  820. use any positive whole number that you want.
  821.  
  822. String maps have to reflect cell key width. If you have got a cell key
  823. width of 2, strings in map simply cannot have lengths like 7 or
  824. 13. Let's convert our example map to multichar:
  825.  
  826.       Require("levels/ant.lua")
  827.  
  828.       cells={}
  829.       cells["  "]=cell{floor="fl-sand"}
  830.       cells["##"]=cell{stone="st-greenbrown"}
  831.       cells["~~"]=cell{stone={"st-timer", {action="trigger", target="fart", interval=10}}}
  832.       cells["**"]=cell{stone={"st-fart", {name="fart"}}}
  833.  
  834.       level = {
  835.          "~~####################################**",
  836.          "##                                    ##",
  837.          "##                                    ##",
  838.          "##    00                        00    ##",
  839.          "##                                    ##",
  840.          "##                                    ##",
  841.          "##                  OO                ##",
  842.          "##                                    ##",
  843.          "##                                    ##",
  844.          "##    00                        00    ##",
  845.          "##                                    ##",
  846.          "##                                    ##",
  847.          "########################################"
  848.       }
  849.  
  850.       oxyd_default_flavor = "a"
  851.       set_cell_key_width(2)
  852.       set_default_parent(cells["  "])
  853.       create_world_by_map(level)
  854.       oxyd_shuffle()
  855.  
  856. How are default cell meanings parsed in case of multichar maps? Well,
  857. there may be some default meanings, but it's not alike. However, the
  858. engine tries. It it doesn't find any meaning among both common cell
  859. functions table and default meanings, it picks first char and tries
  860. again. So '00' becomes oxyd stone, as well as '0$' or anything else
  861. with zero as first char.
  862.  
  863. Behavior of some ant.lua functions may be changed by the fact that the
  864. map is multichar. For example, get_map_width() returns correct map
  865. size, even if strings in map are twice (three times, ...)  longer.
  866. get_cell_by_xy() gives back correct cell key, not the char located at,
  867. say, [7,15], but the string of two (three, ...) chars located at map
  868. position [7,15]. And so on...
  869.  
  870.  
  871. 3.3 cell{} to depth
  872. --------------------------------------------------------------------------------
  873.  
  874. 3.3.1 Checker floor
  875. ...................
  876.  
  877. Sometimes you want to create something as basic as a checkerboard
  878. floor. It's, in my opinion, nice design element. You would expect this
  879. to be no problem, but...
  880.  
  881. Well, it generally is not a problem in procedural way of map design.
  882. But if you have to draw the checkerboard into string map, you soon
  883. find out terrible truth. It's boring and map looks messy.
  884.  
  885. I tried, too. And this experience made me to create a mechanism to
  886. draw checkerboard floors. This mechanism may be happily used also to
  887. create checkerboard stones or anything, but most common it's used for
  888. creating floors, thus its name.
  889.  
  890. Syntax is as follows:
  891.  
  892.       cells={}
  893.       cells[";"]=cell{floor="fl-tigris"}
  894.       cells[","]=cell{floor="fl-sahara"}
  895.       cells[" "]=cell{{{checkerfloor,{cells[","], cells[";"]}}}}
  896.  
  897. It's kinda LISPy, due to special syntax that we will discuss later
  898. on. In fact, this is special case of calling parent. Also, you could
  899. write something like this:
  900.  
  901.       cells[" "]=cell{parent={{checkerfloor, {cells[","], cells[";"]}}}}
  902.  
  903. and it is the same.
  904.  
  905. By default, a grid of 1x1 square is done, checkerboard squares have
  906. the size of one precious Enigma world stone. There are arguments, that
  907. change this:
  908.  
  909.       sahara=     cell{floor="fl-sahara"}
  910.       tigris=     cell{floor="fl-tigris"}
  911.       solidfloor= cell{{{checkerfloor,{sahara,tigris; side=2, offset=1}}}}
  912.  
  913. Argument 'side' changes the size of the square: here each of the
  914. squares takes up area of four stones: 2x2.
  915.  
  916. Argument 'offset' does exactly what it sounds like: it 'shifts' the
  917. grid. By default, left top corner of first square of checkerboard is
  918. aligned with left top corner of world (square coordinates [0,0]).
  919. Offset of 1 moves it to the square [1,1].
  920.  
  921. Also you can create asymmetric constructions. You may specify also
  922. these attributes:
  923.  
  924.       sidex: to specify width of squares
  925.       sidey: to specify height of squares
  926.       offsetx: to shift the grid to right
  927.       offsety: to shift the grit down
  928.  
  929.  
  930. 3.3.2 Random floor
  931. ..................
  932.  
  933. Random floor is a similar case to checkerboards. You need one once
  934. upon a time and creating such a floor by hand is boring and not so
  935. very random as one wishes. That was the reason behind creating random
  936. floor parent.
  937.  
  938. Just like the checker floor, also this parent may be used to construct
  939. anything random. Random stones, random items, you choose.
  940.  
  941. Random floor is constructed like in this example:
  942.  
  943.       normal = cell{floor="fl-rough"}
  944.       invert = cell{floor="fl-inverse"}
  945.       tiles  = cell{{{randomfloor, {normal, invert}}}}
  946.  
  947. You see, the syntax is very similar to that used in checker floor
  948. parent. Soon, you will see this is no coincidence.
  949.  
  950. You can declare as many random elements as you want:
  951.  
  952.       normal = cell{floor="fl-rough"}
  953.       invert = cell{floor="fl-inverse"}
  954.       sahara = cell{floor="fl-sahara"}
  955.       tigris = cell{floor="fl-tigris"}
  956.       tiles  = cell{{{randomfloor, {normal, invert, sahara, tigris}}}}
  957.  
  958. Great, you think. What if I want one item to occur more often? The
  959. answer is item occurrence factor. Each item may be followed by a
  960. number, which declares how often the tile will occur compared to
  961. others. If you omit the number (like in above examples), factor of 1
  962. is default. See the example:
  963.  
  964.  
  965.       tigris = cell{floor="fl-tigris"}
  966.       samba  = cell{floor="fl-samba"}
  967.       stone  = cell{floor="fl-stone"}
  968.       cells[" "] = cell{{{randomfloor, tigris, 3, samba, 1, stone, 20}}}
  969.  
  970. In this case, the floor tiles will be picked in ratio 3:1:20. Most
  971. often, the stone floor will occur, approximately twenty times more
  972. often than samba floor. Tigris floor will occur less often,
  973. approximately three times more than samba.
  974.  
  975. A function 'random' is used to pick random number. Result of the
  976. function may be modified by the function 'randomseed', which initiates
  977. random seed generator:
  978.  
  979.       randomseed(666) -- a truly evil landscape
  980.       randomseed(date"%d%H%M%S") -- 'real' randomness
  981.  
  982.  
  983. 3.3.3 Curried function construction
  984. ...................................
  985.  
  986. Let's look at a parent functions again. Cell parents provide interface
  987. to call another functions. In fact, common cell construction:
  988.  
  989.       tigris = cell{floor="fl-tigris"}
  990.  
  991. just assigns a function to name 'tigris'. Later on, you may write
  992. things like this:
  993.  
  994.       tigris(5, 15)
  995.  
  996. and this means 'place a tigris floor to the square located at
  997. [5,15]'. Just as simple. If you construct a cell function like this:
  998.  
  999.       cells["%"] = cell{parent=tigris, stone="st-glass"}
  1000.  
  1001. you just let the function cells["%"] execute the function tigris
  1002. before everything else. Note, cells["%"] is also function, so you can
  1003. happen to write things like cells["%"](5, 15)!
  1004.  
  1005. The rule is: each function may be used as an parent. If it accepts
  1006. some arguments, first two of them have to be (x,y). Like here, in the
  1007. example we've seen before:
  1008.  
  1009.       function pr(x,y) print(x, y); end
  1010.       cells["w"] = cell{parent=pr}
  1011.  
  1012. If you enclose them to the curly brackets, you can call several
  1013. parents at one run:
  1014.  
  1015.       cells["w"] = cell{parent={pf1, pf2, pf3}}
  1016.  
  1017. Finally, you may omit leading 'parent=' - if ant.lua finds no 'parent'
  1018. assignment, it automatically looks for the first item of the
  1019. table. So, this is perfectly legal:
  1020.  
  1021.       cells["w"] = cell{{pf1, pf2, pf3}}
  1022.  
  1023. Another problem is passing arguments to parent functions. Let's look
  1024. to randomfloor parent example once more:
  1025.  
  1026.       tiles  = cell{{{randomfloor, {normal, invert}}}}
  1027.  
  1028. The same could be written also this way:
  1029.  
  1030.       tiles  = cell{parent={{randomfloor, {normal, invert}}}}
  1031.  
  1032. Let's convert it to syntactical rule:
  1033.  
  1034.       tiles  = cell{parent={{function_name, argument}}}
  1035.  
  1036. And we are done. If you enclose parent to double curly brackets, it
  1037. becomes curry function construction. First element of inner table is
  1038. function name, all other elements are function arguments. If you omit
  1039. leading 'parent=', you'll get to triple-curly-encapsulation, rather
  1040. common in maps with ant.lua:
  1041.  
  1042.       function pr(x,y, greet, name)
  1043.          print(greet..", "..name.." from ["..x..","..y.."]!")
  1044.       end
  1045.  
  1046.       hallo = cell{{{pr, "Hallo", "world"}}}
  1047.  
  1048.       hallo(2,3)
  1049.  
  1050. This code chunk will produce: "Hallo, world from [2,3]!"
  1051.  
  1052. Still not at the end. This construction lets you create so called
  1053. curried constructions. Curried functions are used in some programming
  1054. languages (Haskell for example). What ant.lua provides is far from
  1055. curried functions known from such a languages, but it's somehow
  1056. similar. Look at this to see what's going on:
  1057.  
  1058.       hallo0 = cell{{{pr, "Hallo", "world"}}}
  1059.       hallo1 = cell{{{pr, "Hallo"}}}
  1060.       hallo2 = cell{{{hallo1, "world"}}}
  1061.  
  1062.       hallo0(2,3)
  1063.       hallo1(2,3, "world")
  1064.       hallo2(2,3)
  1065.       pr(2,3, "Hallo", "world")
  1066.  
  1067. Of course, all these function calls produce the same output.
  1068.  
  1069. Curried function calls are rather common in maps that use ant.lua.
  1070. Later on we'll take a look at 'object multiples' - this thing is
  1071. completely build on top of curried function call. And features like
  1072. railway generator, puzzle generator or slope generator stand on object
  1073. groups in turn. It could be said that most features of ant.lua use
  1074. curried call.
  1075.  
  1076.  
  1077. ================================================================================
  1078. 4] FUNCTIONAL APPROACH
  1079. ================================================================================
  1080.  
  1081. 4.1 Fills, borders, ...
  1082. --------------------------------------------------------------------------------
  1083.  
  1084. There are several functions for drawing Enigma maps in init.lua. Most
  1085. of them (if not all) have their counterparts in ant.lua. The difference
  1086. is, that init.lua functions work with stone/floor/item names, but
  1087. ant.lua function works with functions.
  1088.  
  1089. Let's look at how are the basic function, filling the world and
  1090. drawing border, declared:
  1091.  
  1092.       function fill_world_func(fillfunc, x0, y0, w, h)
  1093.       function draw_border_func(fillfunc, x0, y0, w, h)
  1094.       function draw_func_corners(fillfunc, x0, y0, w, h)
  1095.  
  1096. You see, first argument is a function, then there are coordinates of
  1097. area to be filled. The area may actually be omitted completely, and
  1098. then whole world is filled/bordered at once. Function
  1099. 'draw_func_corners' behaves similarly to 'draw_border_func', except
  1100. that it draws only the four corners of given area.
  1101.  
  1102. As to the 'fillfunc', this can be any function at all, but preferably
  1103. it should look something like this:
  1104.  
  1105.       function fill(x,y)
  1106.          do_something(x,y)
  1107.       end
  1108.  
  1109. This function will be executed for each cell at given area (that is
  1110. for the fill_world function), or for each cell of the border of given
  1111. area (that is for draw_border function).
  1112.  
  1113. Note, that also cell{} function have got the form of func(x,y), so you
  1114. can happily use them:
  1115.  
  1116.       floor0 = cell{floor="fl-himalaya"}
  1117.       stone0 = cell{stone="st-rock4"}
  1118.       actor0 = cell{actor={"ac-blackball", {player=0}}}
  1119.  
  1120.       create_world(20, 13)
  1121.       fill_world_func(floor0)
  1122.       draw_border_func(stone0)
  1123.       actor0(5,5)
  1124.  
  1125. And we are done. Note that if you haven't got a string map, you must
  1126. use common function create_world(w,h).
  1127.  
  1128. How to fill/border/cornerify just a given portion of map? Well, use
  1129. x0, y0, x, h arguments of function:
  1130.  
  1131.       fill_world_func(floor0, 39, 1, 19, 11)
  1132.  
  1133. init.lua provides a single function to let you draw a checkerboard of
  1134. selected floor kinds. In ant.lua there is no function alike. It's
  1135. possible to do it this way:
  1136.  
  1137.       normal = cell{floor="fl-normal"}
  1138.       invers = cell{floor="fl-inverse"}
  1139.       checker= cell{{{checkerfloor, {normal, invers}}}}
  1140.       fill_world_func(checker)
  1141.  
  1142. This mechanism is much more generic. You use the same filling function
  1143. as usual, just add the function that generates checker floor. Note
  1144. that creating random floor is a matter of rewriting 'checkerfloor' to
  1145. 'randomfloor', and you can create checkers/randoms from floors,
  1146. stones, items and even an actors.
  1147.  
  1148.  
  1149. 4.2 init.lua counterparts - set_, draw_
  1150. --------------------------------------------------------------------------------
  1151.  
  1152. The library also provides functions similar to set_ and draw_functions
  1153. from init.lua. Group of 'set_' functions in init.lua was aimed to
  1154. place a single item/stone/floor/actor to given position. As usual,
  1155. ant.lua does the same with a single function set_funcs:
  1156.  
  1157.       function set_funcs(fillfunc, poslist)
  1158.  
  1159. Where 'fillfuncs' is a function to be executed on given positions, and
  1160. 'poslist' are those positions. Look at examples:
  1161.  
  1162.       set_funcs(doorA, {{2,1},{2,11},{10,1},{10,11}})
  1163.       set_funcs(fakeoxyd, {{1,1},{1,11}})
  1164.       set_funcs(oxyd, {{18,1},{18,11}})
  1165.  
  1166. Argument 'poslist' is really a list of positions, as you expected. You
  1167. got the idea. It's also possible to execute several functions at once,
  1168. though this is seldom used:
  1169.  
  1170.       set_funcs({abyss, doorA}, {{2,1},{2,11},{10,1},{10,11}})
  1171.  
  1172. Another useful function is draw_funcs. This is similar to draw_floor,
  1173. draw_items and others from init.lua. Draw_funcs executes given
  1174. function at several places in one row:
  1175.  
  1176.       function draw_func(fillfunc, {x0,y0}, {dx,dy}, steps)
  1177.  
  1178. Real life examples follow:
  1179.  
  1180.       draw_func(stone, {3,2}, {0,1}, 11)
  1181.       draw_func(abyss, {13,0}, {0,1}, 13)
  1182.  
  1183. First in list is function to be executed, then starting location
  1184. follows, then increment and finally number of steps to proceed. First
  1185. line of above example says: "take a function 'stone' and call it for
  1186. x,y coordinates beginning at {3,2}, and ending up at {3,12}". So,
  1187. given {dx,dy} is continually added to initial location {x0,y0} exactly
  1188. 'steps' times, and for each location the function is called.
  1189.  
  1190. More general syntax is this:
  1191.  
  1192.       function draw_func(fillfunc, xylist, dxdylist, steps)
  1193.  
  1194. This syntax allows you to use several {x0,y0} locations or several
  1195. {dx,dy} increments. Let's look at examples:
  1196.  
  1197.       draw_func(stone, {{1,1},{5,1}}, {0,1}, 10)
  1198.  
  1199. Two vertical rows of 'stones' are drawn, each consisting of ten stone
  1200. blocks, the first starting at {1,1}, second at {5,1}.
  1201.  
  1202.       draw_func(stone, {0,0}, {{0,1}, {1,0}} 10)
  1203.  
  1204. Two rows of ten stones are drawn, one horizontal and one vertical,
  1205. both starting at {0,0}.
  1206.  
  1207. Also you can use table of functions, if you want to execute several
  1208. function for each cell:
  1209.  
  1210.       draw_func({floor0, stone0}, {0,0}, {0,1}, 10)
  1211.  
  1212. Last function of this sub-chapter is 'ngon' drawing function. It's
  1213. particularly useful for placing several actors to circular/
  1214. triangular/ pentagonal/ any other polygonal settings. Basic syntax
  1215. follows:
  1216.  
  1217.       function ngon_funcs(fillfunc, xylist, radiuslist, count)
  1218.  
  1219. * fillfuncs: this is, as usual, a function or several functions in a table.
  1220. * xylist: this is {x0,y0} coordinates of a polygon center. You may
  1221.   also specify several locations, if you want to create several
  1222.   polygons, like in draw_func.
  1223. * radiuslist: this is a single number, if you want to create a single
  1224.   polygon, or a table of numbers, if you want to create several
  1225.   concentric polygons.
  1226. * count: a number of elements in polygon
  1227.  
  1228. A real-world example:
  1229.  
  1230.       ngon_funcs(actor, {10,10}, 2.25, 3)
  1231.  
  1232. To turn whole polygon by a given angle, include that angle as a last
  1233. function argument:
  1234.  
  1235.       ngon_funcs(actor, {10,10}, 2.25, 3, 60)
  1236.  
  1237. And finally, if you want to place stones, floors and items, you have
  1238. to round their coordinates (you simply cannot place a floor tile to
  1239. {1.63, 7.25}). This is done via 'roundfunc' syntax:
  1240.  
  1241.       function ngon_funcs(fillfunc, xylist, radiuslist, count, alpha0, roundfunc)
  1242.  
  1243. For example:
  1244.  
  1245.       ngon_funcs(actor, {10,10}, 2.25, 3, 60, floor)
  1246.  
  1247. 'floor' is a name of a mathematical function, not a function to draw
  1248. Enigma floor. You could also use for example 'ceil'. To be precious,
  1249. you can use any function, that accepts one argument and results it's
  1250. modified value:
  1251.  
  1252.       function f0(x) return x*x end
  1253.       ngon_funcs(actor, {10,10}, 2.25, 3, 60, f0)
  1254.  
  1255. But I have no idea what would this be good for :)
  1256.  
  1257.  
  1258. 4.3 Coordinate mangling
  1259. --------------------------------------------------------------------------------
  1260.  
  1261. Very impressive feature of whole cell{} function mechanism is, that it
  1262. provides a way to transform a coordinates automatically for you. Maybe
  1263. you know the problem with placing the items to lower and right edges
  1264. of map - one never knows what exactly to subtract from level_width to
  1265. get the right value.
  1266.  
  1267. Look at the piece of code from the welcome-map example:
  1268.  
  1269.       oxyd(3,3)
  1270.       oxyd(level_width-4,level_height-4)
  1271.       oxyd(level_width-4, 3)
  1272.       oxyd(3,level_height-4)
  1273.  
  1274. What this piece actually does, is that it places the four oxyd stones
  1275. to location [3,3] relatively to the four corners of map. Even this
  1276. line of code:
  1277.  
  1278.       oxyd(level_width-4,level_height-4)
  1279.  
  1280. Actually means 'place the oxyd three from bottom and three from
  1281. right', or something alike.
  1282.  
  1283. In ant.lua code, you can simply write:
  1284.  
  1285.       oxyd( 3, 3)
  1286.       oxyd(-3,-3)
  1287.       oxyd(-3, 3)
  1288.       oxyd( 3,-3)
  1289.  
  1290. As we all know that negative coordinates don't exist in Enigma,
  1291. ant.lua converts those so that they become relative to lower/right
  1292. edges of map. Simple as that.
  1293.  
  1294. What is even better? It's possible to use coordinates list:
  1295.  
  1296.       oxyd({{3,3}, {-3,-3}, {-3,3}, {3,-3}})
  1297.  
  1298. This is good enough, but for the cases like this one, where you need
  1299. to place some entity to the four corners of imaginary rectangle, there
  1300. is a function:
  1301.  
  1302.       draw_func_corners(fillfunc, x0, y0, w, h)
  1303.  
  1304. The tricky thing is that the function requires 'w' and 'h'
  1305. arguments. This means that you cannot simply write:
  1306.  
  1307.       draw_func_corners(oxyd, 3, 3, -3, -3)
  1308.  
  1309. as this time, '-3' means 'three squares less than width of the
  1310. map'. Use this instead:
  1311.  
  1312.       draw_func_corners(oxyd, 3, 3, -6, -6)
  1313.  
  1314.  
  1315. ================================================================================
  1316. 5] OBJECT GROUPS
  1317. ================================================================================
  1318.  
  1319. 5.1 Introduction
  1320. --------------------------------------------------------------------------------
  1321.  
  1322. What are object groups? What are they good for? Generally, object
  1323. group is nothing but a table filled with some special data. If those
  1324. data are interpreted correctly, they may happen to become stones,
  1325. actors, floors, coordinates or other meaningful constructions.
  1326.  
  1327. Imagine that you want to build a map. There are four doors, one in
  1328. each level corner. And one switch in a center. Now, how do you get all
  1329. doors open at the same time, after someone switches the button? You
  1330. use object group, so-called multiple. That multiple holds all the
  1331. doors at one table, and it can open/close them upon button switch. The
  1332. advantage is, that you can add as many doors as you want to map, and
  1333. all will open at once.
  1334.  
  1335. Another example: a rubber bands. If you want to connect several
  1336. actors, or actors and stones with rubber bands, you add them to
  1337. multiple and after the level is drawn, you bind them together with one
  1338. command. Let's look at some real-world example:
  1339.  
  1340.       cells["O"]=cell{{{add_multiactor, "ac-blackball", actors, {player=0}, 2}}}
  1341.       cells["%"]=cell{{{add_multistone, "st-rock3", stones}}}
  1342.       ... code,map,stuff ...
  1343.       create_world_by_map(level)
  1344.       add_rubber_bands(actors, stones, -10, 4)
  1345.  
  1346. That's all. No matter how much actors are there, no matter how much
  1347. stones are they to be bound to. We'll talk about rubber bands more
  1348. later. Now, as you got the idea what is it good for, let's move on.
  1349.  
  1350.  
  1351. 5.2 Common multiples
  1352. --------------------------------------------------------------------------------
  1353.  
  1354. 5.2.1 Multielement functions
  1355. ............................
  1356.  
  1357. There are four basic object multiples in ant.lua:
  1358.  
  1359.       add_multistone(x, y, face, group, attribs)
  1360.       add_multifloor(x, y, face, group, attribs)
  1361.       add_multiitem(x, y, face, group, attribs)
  1362.       add_multiactor(x, y, face, group, attribs, actor_mode)
  1363.  
  1364. Basic difference between them is obvious.
  1365.  
  1366. Step one when creating a multiple is to define a group. It's usual to
  1367. store the object to logical groups - doors that should open at once
  1368. have to be in one group, actors to be bound by rubber bands have to be
  1369. in another. To define a group, do this:
  1370.  
  1371.       group = {}
  1372.  
  1373. That's it. This has to be done for each group, so that LUA has a space
  1374. to add objects to. The above example should look like this:
  1375.  
  1376.       actors={}
  1377.       stones={}
  1378.       cells["O"]=cell{{{add_multiactor, "ac-blackball", actors, {player=0}, 2}}}
  1379.       cells["%"]=cell{{{add_multistone, "st-rock3", stones}}}
  1380.  
  1381. This example also shows a step two. You have to create a rule to fill
  1382. a multiple with objects. In above example, the group named 'actors' is
  1383. filled up with the rule add_multiactor ("ac-blackball", the black
  1384. marble) and 'stones' group is filled up with stones "st-rock3".
  1385.  
  1386. It's possible to mix up several kinds of elements in one group. For
  1387. example, it's perfectly reasonable if you store a doors and bridges in
  1388. one group, and then let them all open/close at once.
  1389.  
  1390.       openables={}
  1391.       cells["-"]=cell{{{add_multistone, "st-door", openables, {type="h"}}}}
  1392.       cells["|"]=cell{{{add_multistone, "st-door", openables, {type="v"}}}}
  1393.       cells["T"]=cell{{{add_multifloor, "fl-bridge", openables, {name="bridgeA"}}}}
  1394.  
  1395. Moreover, it's also possible to have one object placed in several
  1396. groups. I've never need such a thing, but it's well possible to do so:
  1397.  
  1398.       openables={}
  1399.       stones={}
  1400.       cells["-(1)"]=cell{{{add_multistone, "st-door", openables, {type="h"}}}}
  1401.       cells["-(2)"]=cell{{{add_multistone, "st-door", stones, {type="h"}}}}
  1402.       cells["-"]=   cell{parent={cells["-(1)"], cells["-(2)"]}}
  1403.       cells["D"]=   cell{{{add_multistone, "st-death", stones}}}
  1404.       cells["T"]=   cell{{{add_multifloor, "fl-bridge", openables, {name="bridgeA"}}}}
  1405.  
  1406. In this example, the element "-" is added both to 'openables' and
  1407. 'stones'. Like I said, this is not very common :)
  1408.  
  1409.  
  1410. 5.2.2 Group actions
  1411. ...................
  1412.  
  1413. Fine, so we know everything about creating a group, yet there was no
  1414. example of real usage. The simplest usage is to send a message to all
  1415. elements in group. In one of above examples, the group 'openables'
  1416. grouped together all the elements that could work with a 'openclose'
  1417. message:
  1418.  
  1419.       send_group_message(openables, "open", nil)
  1420.  
  1421. This function has the same syntax and semantics as a 'send_message'
  1422. from init.lua, it just accepts a group of objects at a first
  1423. place. You can use this on groups of objects only. Since now, there
  1424. were only the object groups, that is, the groups made up of stones,
  1425. floors, items and actors. But this will change soon.
  1426.  
  1427. Sending a message is not the only thing to be done with object
  1428. group. You can also change the attribute of grouped objects. As in the
  1429. above case, you can only do this with game elements - stones, floors,
  1430. you know. This is done this way:
  1431.  
  1432.       set_group_attribs(bolders, {direction=EAST})
  1433.  
  1434. First argument is object group, second the attributes to be changed
  1435. (like in 'set_attribs' from init.lua).
  1436.  
  1437.  
  1438. 5.2.3 Rubber bands
  1439. ..................
  1440.  
  1441. Creating a rubber bands is kinda tricky in a string-map-based
  1442. level. How to mark which objects should be rubber-banded together?
  1443. Answer is object groups.
  1444.  
  1445. Basically, you need two groups for this, one with the objects 'from'
  1446. which the rubber band be made, and another with the object 'to' which
  1447. the rubber band will be made. In fact, you can well use the same group
  1448. for both, and it's often used.
  1449.  
  1450. There are several rubber-banding functions. We'll go through all of
  1451. them.
  1452.  
  1453. First, imagine you want to rubber band each actors with each
  1454. bolder. Actors are in first group, bolders in another. You can do it
  1455. this way:
  1456.  
  1457.       add_rubber_bands(actors, bolders, 5, 0)
  1458.  
  1459. That is, bind each actor with each bolder by rubber band of length 0
  1460. and force 5. In a special case of one bolder in 'bolders' group, all
  1461. actors are bound to a single bolder. In another special case of a
  1462. single actor in a 'actors' group, poor actor is bound to all
  1463. bolders. And finally, if there is a single actor and a single bolder,
  1464. they are simply bound together.
  1465.  
  1466. Another useful construction is to create a rubber band pairs. This
  1467. time, you really need two different groups. First object from first
  1468. group is then bound with first object from second group, second from
  1469. first group with second from second group, and so on:
  1470.  
  1471.       add_rubber_band_pairs(actors, blocks, 10, 0)
  1472.  
  1473. It's really useful to have both the groups populated by same number of
  1474. elements. Above example is picked from a meditation landscape, where
  1475. each of the small white marbles is bound to one stone block.
  1476.  
  1477. Last rubber banding function is 'rubber_band_circle'. This time you
  1478. only need a single group. First object of the group is bound with
  1479. second, the second is bound with third, and so on. Last one is then
  1480. bound with the first:
  1481.  
  1482.       rubber_band_circle(actors, 10, 2)
  1483.  
  1484. In Enigma, you are only allowed to bind the actor and stone or the
  1485. actor and actor. Because of this, the group in this case has to be
  1486. made up of the actors only, or, more exactly, the two neighboring
  1487. elements may not be stone-stone. It's not possible to bind the actor
  1488. to floor or item, so avoid using those object in rubber band
  1489. constructions completely.
  1490.  
  1491.  
  1492. 5.3 Generic multielements
  1493. --------------------------------------------------------------------------------
  1494.  
  1495. Besides multielements that represent Enigma game objects, there are
  1496. several so-called generic multielements. Those usually cannot accept
  1497. multimessages, nor can their attributes be changed by
  1498. change_group_attribs. These multielements are used in special ant.lua
  1499. utilities - train-, wormhole- and slope-generator.
  1500.  
  1501. Everything that was said about common multielements is true for
  1502. generic multielements, too. They are stored in a table, that has to be
  1503. declared, so the basic construction looks like this:
  1504.  
  1505.       group={}
  1506.       cells["!"]=cell{{{add_*, group, ...}}}
  1507.  
  1508. Where add_* stands for the multielement function, group is group which
  1509. the multielement should be given to, and '...' stands for 'another
  1510. arguments'.
  1511.  
  1512. Generic multielement functions are these:
  1513.  
  1514.       function add_multicell(x, y, group, tag)
  1515.       function add_multiobject(x, y, group, func)
  1516.       function add_multitag(x, y, group, tag, func)
  1517.  
  1518. In upcoming chapters, each of them will be talked about a bit.
  1519.  
  1520.  
  1521. 5.3.1 add_multicell
  1522. ...................
  1523.  
  1524. Each multicell element holds three values: two coordinates (x,y) and a
  1525. 'tag' value. For example:
  1526.  
  1527.       slopes={}
  1528.       cells["*"]=cell{{{add_multicell, slopes, -1}}}
  1529.  
  1530. This example will add an element to the 'slopes' table for each
  1531. asterisk in your string map. Every such element will be tagged to -1.
  1532.  
  1533. add_multicell element is the most widely used one.
  1534.  
  1535.  
  1536. 5.3.2 add_multiobject
  1537. .....................
  1538.  
  1539. Another multielement is add_multiobject. This is used rather seldom,
  1540. much much lesser than add_multicell. Multiobject function is similar
  1541. to multicell, except for the tag, which is 'function' this time:
  1542.  
  1543.       function add_multiobject(x, y, group, func)
  1544.  
  1545. Given function gets executed with the (x,y) coordinates, and its
  1546. result is stored to given table. Real-world examples are rather
  1547. obscure constructions like this one:
  1548.  
  1549.       cells = {}
  1550.       use_cells(cells, "O")
  1551.       cells["O"]=cell{{{add_multiobject, actors, cells["O"]}}}
  1552.  
  1553. cells["O"] is a function, we all know. This function has in fact a
  1554. return value. Simply said, cell{} function that places an actor return
  1555. this actor. Cell function that creates a stone return this stone. And
  1556. so on. Because of use_cells(cells, "O") the default meaning for "O"
  1557. will be added to cells[] table. And add_multiobject will thus add its
  1558. return value, that is just created actor, to the 'actors' table.
  1559.  
  1560. In fact, the function can be anything. It doesn't have to result in
  1561. Enigma object, like in above example. It may well return string or
  1562. number, or even the table. It's up to you, the level designer, if you
  1563. find use for this construction.
  1564.  
  1565.  
  1566. 5.3.3 add_multitag
  1567. ..................
  1568.  
  1569. This function is remainder from first implementation of slopes
  1570. generator. Currently it's used in no map at all, due to it's special
  1571. nature.
  1572.  
  1573.       function add_multitag(x, y, group, tag, func)
  1574.  
  1575. add_multitag can store several elements under one tag number (or
  1576. tag-string, if you pass string for a tag). Structure of a constructed
  1577. table may look like this:
  1578.  
  1579.       group={
  1580.         [1]={{5,7},{6,7},{7,7},{9,15}},
  1581.         [2]={{1,3},{9,3},{1,9},{9,9}}
  1582.       }
  1583.  
  1584. So, the idea is to store under each tag number a list of coordinates -
  1585. thus effectively grouping several groups together. As a bonus, each
  1586. element can have a tag number of its own, which may look like this:
  1587.  
  1588.       group={
  1589.         [1]={{5,7,"yet"},{6,7,"another"},{7,7,"boring"},{9,15,"multiple"}}
  1590.       }
  1591.  
  1592. If you do not specify this extra tag number, the tag number of a group
  1593. is taken:
  1594.  
  1595.       group={
  1596.         [1]={{5,7,1},{6,7,1}},
  1597.         [2]={{1,3,2},{9,3,2}}
  1598.       }
  1599.  
  1600. The 'function' argument of add_multitag is processed in a special
  1601. way. If it's a function, it's executed with (x,y) arguments, and its
  1602. result is stored as a tag. Otherwise the value of 'function' itself is
  1603. stored as a tag. If nil is passed (or the argument is omitted
  1604. completely), value of a 'tag' is passed as tag.
  1605.  
  1606. What is this good for? Well... like I said, this is remainder of first
  1607. slope generator implementation, pure feature creep. If you find use
  1608. for this, well. Currently there is none. It's well possible that the
  1609. function will be removed.
  1610.  
  1611.  
  1612. 5.4 Worm holes
  1613. --------------------------------------------------------------------------------
  1614.  
  1615. 5.4.1 Forewords
  1616. ...............
  1617.  
  1618. Worm hole pairs are nice map addition, seen in many maps across all
  1619. Enigma map packages. However if you want to create such a pair by
  1620. traditional resources, you find out that it's far from the comfort of
  1621. moving letters across the string map. You have to change attributes of
  1622. given worm hole directly - by choosing another pair of numbers. And as
  1623. I really am a lazy person, the first thing to do when creating map
  1624. with wormholes, was to add a generator that would just simplify this
  1625. task.
  1626.  
  1627.  
  1628. 5.4.2 Technical background
  1629. ..........................
  1630.  
  1631. Wormholes in Enigma have a simple purpose. If an actor enters
  1632. wormhole, it's moved to arbitrary location in Enigma world. Thus, each
  1633. worm hole has to be fed up with coordinates of target.
  1634.  
  1635. The work of wormhole generator stands on top of object groups. You
  1636. feed the generator with a table of worm hole items and a table of worm
  1637. hole targets, and it puts them into pairs and create appropriate items
  1638. with the right attributes.  Both the worm holes and their targets are
  1639. special table of multicells.
  1640.  
  1641. Basic scheme is this:
  1642.  
  1643. * declare group for wholes and wtargets
  1644. * declare whole symbols and wtarget symbols for cells[]
  1645. * let the map be drawn
  1646. * render worm holes
  1647.  
  1648.  
  1649. 5.4.3 Setting up cell{} functions
  1650. .................................
  1651.  
  1652. At first, you have to declare the groups:
  1653.  
  1654.       holes={}
  1655.       targets={}
  1656.  
  1657. Now add a wormhole pairs. There is function that does this for you,
  1658. called 'worm_hole_pair':
  1659.  
  1660.       worm_hole_pair(cellfuncs, whole_cell, tgt_cell, whole_parent, tgt_parent, whole_grp, tgt_grp, tagnumber)
  1661.  
  1662. * cellfuncs is a table of cell functions (usually cells[])
  1663. * whole_cell is a letter that will stand for worm hole on string map
  1664. * tgt_cell is a letter that will stand for a worm hole target
  1665. * whole_parent is a function to be used as a parent of worm hole cell
  1666. * tgt_parent is a function to be used as a parent of worm hole target
  1667. * whole_grp is a group of worm holes
  1668. * tgt_grp is table of worm hole targets
  1669. * tagnumber is unique number that identifies the wormhole-target pair
  1670.  
  1671. For example, the setting might look this way:
  1672.  
  1673.       worm_hole_pair(cells, "A", "a", cells[" "], cells[" "], holes, targets, 1)
  1674.       worm_hole_pair(cells, "B", "b", cells["_"], cells["_"], holes, targets, 2)
  1675.       worm_hole_pair(cells, "C", "c", cells["_"], cells["_"], holes, targets, 3)
  1676.  
  1677. If you need some special fine-tuning, you can write the same this way
  1678. (in the example, there is a "A"-"a" pair defined):
  1679.  
  1680.       cellfuncs["A"] = cell{{cells["_"], {add_multicell, holes,   1}}}
  1681.       cellfuncs["a"] = cell{{cells[" "], {add_multicell, targets, 1}}}
  1682.  
  1683.  
  1684. 5.4.4 Setting up the map
  1685. ........................
  1686.  
  1687. In map, you simply place the whole-letters and wtarget-letters to
  1688. their places, so that they represent desired actor hyper-jumps.
  1689.  
  1690.       level = {
  1691.          "###################",
  1692.          "#A       #       a#",
  1693.          "#        #        #",
  1694.          "#        #        #",
  1695.          "#b       #       B#",
  1696.          "###################"
  1697.       }
  1698.  
  1699.  
  1700. 5.4.5 Post-execution code
  1701. .........................
  1702.  
  1703. When map is drawn, the mission doesn't end yet. You now have the
  1704. holes{} and targets{} tables filled with reasonable informations. Now,
  1705. the worm hole generator can transform it to worm holes for you:
  1706.  
  1707.       create_world_by_map(level)
  1708.       render_wormholes(holes, targets, {strength=10, range=5})
  1709.  
  1710. And we're done. The important thing is to call generator after the
  1711. world is drawn.
  1712.  
  1713.  
  1714. 5.4.6 Multiple wholes per one target
  1715. ....................................
  1716.  
  1717. If you want several worm holes to move actor to a single location,
  1718. just give them same tag-numbers:
  1719.  
  1720.       wholes={}
  1721.       wtgts={}
  1722.       worm_hole_pair(cells, "A", "b", cells[" "], cells[" "], wholes, wtgts, 2)
  1723.       worm_hole_pair(cells, "B", "d", cells[" "], cells[" "], wholes, wtgts, 4)
  1724.       worm_hole_pair(cells, "C", "b", cells[" "], cells[" "], wholes, wtgts, 2)
  1725.       worm_hole_pair(cells, "D", "a", cells[" "], cells[" "], wholes, wtgts, 1)
  1726.       worm_hole_pair(cells, "E", "c", cells[" "], cells[" "], wholes, wtgts, 3)
  1727.       worm_hole_pair(cells, "F", "d", cells[" "], cells[" "], wholes, wtgts, 4)
  1728.       worm_hole_pair(cells, "G", "c", cells[" "], cells[" "], wholes, wtgts, 3)
  1729.       worm_hole_pair(cells, "H", "a", cells[" "], cells[" "], wholes, wtgts, 1)
  1730.  
  1731. In the example, worm holes "A" and "C" move actor to target denoted by
  1732. "b". Please note that it's tag-numbers what is important, and that tag
  1733. numbers have to match with the letter of target location (all pairs
  1734. tagged with number 2 have the same target letter: "b").
  1735.  
  1736.  
  1737.  
  1738. 5.5 Railways
  1739. --------------------------------------------------------------------------------
  1740.  
  1741. 5.5.1 What are railways
  1742. .......................
  1743.  
  1744. Railways, or trains, are the constructions in Enigma maps, that...
  1745. that actually behave like a train. Train has fixed, predefined
  1746. journey, a rail. On this rail there is arbitrary number of vehicles
  1747. moving, each of them "drawing" Enigma tiles (usually floors). It's
  1748. usual that "train" is composed of two vehicles: one that sets up the
  1749. floor and another that replaces it with abyss, water or other lethal
  1750. surface. Trains are actually incorporated to three of my Enigma maps:
  1751. ant08 (Mourning Palace), ant10 (Circularity) and ant11 (Cannonball).
  1752. Go on and look at them if you want to find out what's going on
  1753. exactly.
  1754.  
  1755.  
  1756. 5.5.2 Technical background
  1757. ..........................
  1758.  
  1759. Each train (that is a vehicle/railway combination) is defined by two
  1760. tables:
  1761.  
  1762. * table of cells that the railway consists of
  1763. * table of engines - path constructors and destructors
  1764.  
  1765. Basic idea is, that in each tick, each of engines is moved on to the
  1766. next cell of the railway.  Each engine marks its rail - every field it
  1767. enters is marked with its tag number, causing that it never can step
  1768. on this field again (this prevents the engine from loosing its
  1769. direction).  So, the engine tagged with '1' can step only to fields,
  1770. that are not marked with '1', and similarly for '0'.
  1771.  
  1772. Engines with tag '1' are called 'constructors', and those are
  1773. 'locomotive' of the train. Engines tagged with '0' are destructors,
  1774. and they are acting as a last wagon of a train. Their mission is to
  1775. erase tagnumber, so that locomotive can move to the field later, when
  1776. it visits it again.
  1777.  
  1778. The path should be circular, and one field thick. In fact, engines are
  1779. always trying to keep their direction, so that they do not turn until
  1780. they have to. Thus it could be possible to create a two-fields thick
  1781. railway. It's not very simple though, and I never tried it. The train
  1782. will fail if it goes into the tight corner - it cannot invert its
  1783. direction.
  1784.  
  1785.  
  1786. 5.5.3 Setting up cell{} functions
  1787. .................................
  1788.  
  1789. To setup a rail, you need four cells. One for train constructor, one
  1790. for train destructor, one for the body of train and one for the
  1791. pathway. Example of a typical construction follows:
  1792.  
  1793.       path = {}
  1794.       loco = {}
  1795.       cells["!"]=cell{parent={cells["."], {add_multicell, path, 0}}}
  1796.       cells["_"]=cell{parent={cells["!"], {add_multicell, path, 1}, cells["'"]}}
  1797.       cells["c"]=cell{parent={cells["_"], {add_multicell, loco, construct}}}
  1798.       cells["d"]=cell{parent={cells["!"], {add_multicell, loco, destruct}}}
  1799.  
  1800. That means:
  1801. * cells marked "!" are part of path and are tagged to zero
  1802. * cells marked "_" are also part of path, but are tagged to 1 instead
  1803. * cells marked "c" are engines, and are tagged by function 'construct'
  1804. * cells marked "d" are also engines, but are tagged by function 'destruct'
  1805.  
  1806. Note that one of parents of cells["!"] function is cells["."],
  1807. denoting that outside the train, there is abyss (or whatever happens
  1808. to be under cells["."]). Similarly, cells["_"] has cells["'"] as a
  1809. parent, and this is how the train body will look like. This is how the
  1810. path and train looks like after startup, after the train starts to
  1811. move, 'construct' and 'destruct' functions drive what will be
  1812. displayed! If you want to simple setup, do this:
  1813.  
  1814.       path = {}
  1815.       loco = {}
  1816.       cells["."]=cell{how does the railway look like}
  1817.       cells["'"]=cell{how does the train look like}
  1818.       cells["!"]=cell{parent={cells["."], {add_multicell, path, 0}}}
  1819.       cells["_"]=cell{parent={cells["!"], {add_multicell, path, 1}, cells["'"]}}
  1820.       cells["c"]=cell{parent={cells["_"], {add_multicell, loco, cells["'"]}}}
  1821.       cells["d"]=cell{parent={cells["!"], {add_multicell, loco, cells["."]}}}
  1822.  
  1823. This is not very wise, as cells[] functions are bloated with
  1824. functionality. Remember all these curried constructions and the like -
  1825. they provide much power, but this drawbacks in rather slow execution
  1826. (up to four times slower than init.lua functions). Both 'construct'
  1827. and 'destruct' functions are called repeatedly each tick, for each
  1828. move the train does. The faster they are, the better. In my opinion,
  1829. it's better to create hard-core functions that do the dirty work fast
  1830. enough:
  1831.  
  1832.       function construct(x, y) set_floor("fl-normal", x, y) end
  1833.       function destruct(x, y)  set_floor("fl-abyss", x, y) end
  1834.  
  1835.       cells["."]=construct
  1836.       cells["'"]=destruct
  1837.       cells["!"]=cell{parent={cells["."], {add_multicell, path, 0}}}
  1838.       cells["_"]=cell{parent={cells["!"], {add_multicell, path, 1}, cells["'"]}}
  1839.       cells["c"]=cell{parent={cells["_"], {add_multicell, loco, construct}}}
  1840.       cells["d"]=cell{parent={cells["!"], {add_multicell, loco, destruct}}}
  1841.  
  1842.  
  1843. 5.5.4 Binding the train to railway
  1844. ..................................
  1845.  
  1846. Now you have the cells declared, but still the train is not ready. You
  1847. have to make up the function that moves engines on the railway each
  1848. time it's called. Don't worry, it is as simple as this:
  1849.  
  1850.       rail = new_rail(loco, path)
  1851.  
  1852. Now, each time the rail() function gets called, it moves all the
  1853. engines ahead, processing 'construct' and 'destruct' functions. To do
  1854. this repeatedly (your train should move on fluently), let the function
  1855. be called by timer stone:
  1856.  
  1857.       cells["~"]=cell{stone={"st-timer", {action="callback", target="rail", interval=0.15}}}
  1858.  
  1859. Ready. Now just draw the map and you are done.
  1860.  
  1861.  
  1862. 5.5.5 Setting up the map
  1863. ........................
  1864.  
  1865. In your string map, the path will be denoted by exclamation marks, the
  1866. train by underscores, locomotives by 'c' and last wagons by 'd'. Don't
  1867. forget to add a timer stone '~' to make your train move!
  1868.  
  1869. Result map could look this way:
  1870.  
  1871.       level = {
  1872.          "####################",
  1873.          "#!!!!!!!  !!c___d!!#",
  1874.          "#!     !!!!       !#",
  1875.          "#!!!!!         !!!!#",
  1876.          "#    !!!!!!!!!!!   #",
  1877.          "###################~"
  1878.       }
  1879.  
  1880. And that is all. Congratulations, your map just got a train.
  1881.  
  1882.  
  1883. 5.6 Puzzles
  1884. --------------------------------------------------------------------------------
  1885.  
  1886. 5.6.1 Forewords
  1887. ...............
  1888.  
  1889. Puzzles are popular map constructions overall. The puzzle consists of
  1890. several 'puzzle stones', that may only be moved together. You can
  1891. create constructions of dozens puzzle stones as well as two or three
  1892. stones big ones.
  1893.  
  1894. Creating puzzles is not complicated at all, it's simply boring. It
  1895. means that you have to declare several cells to become several kinds
  1896. of puzzle stones - one with sockets to left and down, one with up and
  1897. right, one with left, down and right, one with... You got it. But if
  1898. you want to create so called 'complete cluster' (each stone of puzzle
  1899. has all the sockets connected to other stones), it's just a matter of
  1900. dumb work to make up a cluster elements out of the cluster
  1901. layout. This is where ant.lua brings help.
  1902.  
  1903. In fact, it's somehow possible to create also open clusters, but this
  1904. feature is not very strong and generally you better rely on boring
  1905. hard-coding cell functions.
  1906.  
  1907.  
  1908. 5.6.2 Technical background
  1909. ..........................
  1910.  
  1911. The puzzle generator aims at creating complete puzzle clusters. It
  1912. needs a table, in which there are coordinates of a puzzle stones,
  1913. reads this table and places right puzzle elements to Enigma world. In
  1914. the table, there is in fact a 'layout' of a puzzle cluster.
  1915.  
  1916. The step-by-step recipe to create a puzzle cluster is here:
  1917.  
  1918. * declare a layout table
  1919. * declare a cell function that represents cell stone
  1920. * draw a map
  1921. * render puzzles
  1922.  
  1923.  
  1924. 5.6.3 Setting up puzzle
  1925. .......................
  1926.  
  1927. You have to declare a table where LUA will store the layout in. This
  1928. is done in usual way:
  1929.  
  1930.       puzzles = {}
  1931.  
  1932. Next, declare a cell function:
  1933.  
  1934.       cells["*"]=cell{{{add_multicell, puzzles}}}
  1935.  
  1936. Now draw the string map:
  1937.  
  1938.       level = {
  1939.          "####################",
  1940.          "#                  #",
  1941.          "#  ***   ***       #",
  1942.          "#  * ***** *       #",
  1943.          "#***       ***     #",
  1944.          "####################"
  1945.       }
  1946.  
  1947. And draw it:
  1948.  
  1949.       create_world_by_map(level)
  1950.  
  1951. Like in case of wormholes, in this moment the table of puzzles is
  1952. filled with information about layout of puzzle. You just have to pass
  1953. this information to puzzle generator:
  1954.  
  1955.       render_puzzles(puzzles)
  1956.  
  1957. Done!
  1958.  
  1959.  
  1960. 5.6.4 Fake puzzles
  1961. ..................
  1962.  
  1963. There is one more feature of the puzzle generator, that can help you
  1964. in creating incomplete puzzles. You can declare a cell to act as if
  1965. there is a puzzle stone, but in fact no stone is rendered there.
  1966. Effectively this will make neighboring stones to open thir sockets to
  1967. this field.
  1968.  
  1969. To set up this fake puzzle stone, declare the puzzle cell this way:
  1970.  
  1971.       cells["&"]=cell{{{add_multicell, puzzles, 2}}}
  1972.  
  1973. Then the puzzle won't be generated on given map element, but it's
  1974. neighbors will have their sockets opened in this direction like there
  1975. should be one.
  1976.  
  1977.  
  1978. 5.6.5 Puzzle kinds
  1979. ..................
  1980.  
  1981. There are several puzzle kinds in enigma. There is a classic puzzle,
  1982. an Oxyd1 compatible puzzle, plus 'st-bigbrick' stone that is actually
  1983. being constructed like a puzzle (it has nearly the same attributes as
  1984. 'st-puzzle' does).
  1985.  
  1986. To let level designer choose a puzzle kind, it's possible to pass a
  1987. 'kind' argument to a render_puzzles() function. If this argument is
  1988. omitted, ant.lua automatically picks a 'puzzle' kind. If it's
  1989. supplied, it has to be a function with this interface:
  1990.  
  1991.       function some_puzzle(x, y, connections)
  1992.  
  1993. In init.lua, there are currently (at time of writing this) two
  1994. functions with necessary syntax and semantics: puzzle() and puzzle2()
  1995. (for Oxyd1 compatible puzzles). The call then looks this way:
  1996.  
  1997.       render_puzzles(puzzles1)
  1998.       render_puzzles(puzzles2, puzzle2)
  1999.  
  2000. You could declare your own rendering function. For example:
  2001.  
  2002.       function bigbrick(x, y, conn)
  2003.          set_stone("st-bigbrick", x, y, {connections=conn})
  2004.       end
  2005.  
  2006.       render_puzzles(puzzles3, bigbrick)
  2007.  
  2008.  
  2009. 5.7 Slopes
  2010. --------------------------------------------------------------------------------
  2011.  
  2012. 5.7.1 Forewords
  2013. ...............
  2014.  
  2015. Slopes are Enigma construction that pushes the actor to move in one
  2016. direction. It's gradiented floor. Gradients can create really big
  2017. constructions, beveled areas, both sunken and raised.
  2018.  
  2019. With slopes, its very similar to puzzles. Both the fact, that
  2020. declaring cell functions is boring, and the way the slopes are
  2021. generated.
  2022.  
  2023.  
  2024. 5.7.2 Technical background
  2025. ..........................
  2026.  
  2027. Slope generator can create a wide variety of slope settings, but some
  2028. things it's simply unable to do. It has no intelligence, it's just
  2029. automaton that reads input data and based on them it decides what kind
  2030. of slope will be on this or that place.
  2031.  
  2032. It works on a pattern matching basis. Each cell setup is compared with
  2033. a table of patterns, the nearest one is picked up and we hope it's the
  2034. right one. It happens that some complicated settings are just not
  2035. parsed the right way, or there are ambiguities. There is no simple
  2036. remedy for this situation, than to add another pattern to patterns
  2037. database. Most of the time, the patterns match just well and slopes
  2038. are happily (and correctly) generated.
  2039.  
  2040. Next thing is setting up where is the center of desired shape. The
  2041. program needs to know how to shape slopes, whether "up-down" or
  2042. "down-up". The point that declares where is the "upside" of sloped
  2043. shape is called 'pivot'.
  2044.  
  2045. The basic step-by-step recipe follows:
  2046.  
  2047. * create table for slopes and pivots
  2048. * create cell functions for slopes and pivots
  2049. * create map
  2050. * let the pivot be spread
  2051. * render slopes
  2052.  
  2053. Most of work is done by ant.lua for you, but there are some steps that
  2054. may require some skill and experience.
  2055.  
  2056.  
  2057. 5.7.3 Setting up cell{} functions
  2058. .................................
  2059.  
  2060. Tables for cells and pivots are created in common fashion:
  2061.  
  2062.       slopes={}
  2063.       pivots={}
  2064.  
  2065. Into 'slopes', the overall layout of the shape will be placed. This is
  2066. similar table to the one used in puzzle generator. In 'pivots' table,
  2067. the locations of 'central points' are stored.
  2068.  
  2069. Next, cell functions are created:
  2070.  
  2071.       cells["*"]=cell{{{add_multicell, slopes, 1}}}
  2072.       cells["&"]=cell{{{add_multicell, pivots, slopes}, cells[" "]}}
  2073.  
  2074. You see, add_multicell is used once more. Tag '1' has meaning of 'here
  2075. be the slope'. Cell '&' is tagged by the slopes table. This way the
  2076. pivots are bound to slopes, so that it is possible to lay several
  2077. concentric slope shapes.
  2078.  
  2079.  
  2080. 5.7.4 Setting up the map
  2081. ........................
  2082.  
  2083. Now the map is populated with the asterisks, representing the slope
  2084. boundary, and one or more pivot ampersands, placed *INSIDE* that
  2085. boundary.
  2086.  
  2087. Please note that it's really necessary to place a pivot inside a
  2088. closed boundary, otherwise the stack overflows, or others errors
  2089. occur.
  2090.  
  2091.       level = {
  2092.          "####################",
  2093.          "#  **************  #",
  2094.          "#  *&           *  #",
  2095.          "#  *            *  #",
  2096.          "#  **************  #",
  2097.          "####################"
  2098.       }
  2099.  
  2100.  
  2101. 5.7.5 Post-execution code
  2102. .........................
  2103.  
  2104. After the map is drawn, the tables are fed up with information about
  2105. the shape. Now two steps have to be done: the pivot has to be spread,
  2106. so that the whole boundary gets filled, and program can effectively
  2107. differ between "up" and "down". Then, the slope can be rendered.
  2108.  
  2109. Piece of code that processes the thing looks right like this:
  2110.  
  2111.       create_world_by_map(level)
  2112.       spread_tag(pivots)
  2113.       render_slopes(slopes)
  2114.  
  2115. That's it. Slopes got rendered and everyone is happy.
  2116.  
  2117.  
  2118. 5.7.6 Mixing several slopes
  2119. ...........................
  2120.  
  2121. Sometimes you want to create several slopes where one bounds
  2122. another. You could need to create two slopes overlapping. It can
  2123. happen (it happens) that you need to create a slope that the program
  2124. cannot render correctly. In all such cases, you should break your
  2125. slope to several parts, and place each one to separate table:
  2126.  
  2127.       slopes1={}
  2128.       slopes2={}
  2129.       pivots1={}
  2130.       pivots2={}
  2131.  
  2132.       cells["*"]=cell{{{add_multicell, slopes1, 1}}}
  2133.       cells["@"]=cell{{{add_multicell, slopes2, 1}}}
  2134.       cells["&"]=cell{{{add_multicell, pivots1, slopes1}, cells[" "]}}
  2135.       cells["%"]=cell{{{add_multicell, pivots2, slopes2}, cells[" "]}}
  2136.       cells["^"]=cell{parent={cells["*"],cells["@"]}}
  2137.  
  2138. You have to reflect this in your map:
  2139.  
  2140.       level = {
  2141.          "####################",
  2142.          "#  **********      #",
  2143.          "#  *@@@@@@@@^@@@   #",
  2144.          "#  *@&%     *  @   #",
  2145.          "#  *@       *  @   #",
  2146.          "#  *@@@@@@@@^@@@   #",
  2147.          "#  **********      #",
  2148.          "####################"
  2149.       }
  2150.  
  2151. Rendered by Enigma, this doesn't look very nice, as one slope just
  2152. overrides another. Well, at least you got the idea how it works.
  2153.  
  2154.  
  2155. 5.7.7 Fake slopes
  2156. .................
  2157.  
  2158. Like in puzzles, you can create also fake slopes. Fake slope is a
  2159. cell, that behaves like a slope, but it never gets rendered. Fake
  2160. slopes are tagged by the number '2':
  2161.  
  2162.       cells["+"]=cell{{{add_multicell, slopes, 2}}}
  2163.  
  2164.  
  2165. 5.7.8 Invert slopes
  2166. ...................
  2167.  
  2168. If you want to create inverted-slope (southwest instead of northeast
  2169. and so on), tag it with a number -1:
  2170.  
  2171.       cells["+"]=cell{{{add_multicell, slopes, -1}}}
  2172.  
  2173. You can also create a whole boundary invert, by using 'invert'
  2174. argument in 'render_slopes' function:
  2175.  
  2176.       render_slopes(slopes, -1)
  2177.  
  2178. Actually you can pass anything non-nil as invert argument, and whole
  2179. boundary gets inverted. If there are invert cells in boundary, the are
  2180. drawn 'normally' - that is, double inversion results to original
  2181. state, like in De Morgan's.
  2182.  
  2183.  
  2184. 5.8 Afterwords
  2185. --------------------------------------------------------------------------------
  2186.  
  2187. It's perfectly possible to mix up generators of ant.lua in map. Not
  2188. just several instances on one generator, like two trains or two
  2189. slopes. It's of course possible to mix up trains with slopes and
  2190. puzzles. Just remember, that some constructions are static. If you are
  2191. creating engine with slope in center, that would move over the map,
  2192. you don't need the slope generator. It cannot help you, unless you
  2193. want to spread tag and render slopes each round over and over.
  2194.  
  2195. Well, this was the core of ant.lua. There are a few helper functions
  2196. besides this, but in fact ant.lua will provide you no better
  2197. functionality.
  2198.  
  2199.  
  2200. ================================================================================
  2201. 6] HELPER FUNCTIONS
  2202. ================================================================================
  2203.  
  2204. 6.1 Debugging
  2205. --------------------------------------------------------------------------------
  2206.  
  2207. It's a simple fact that even in enigma maps there tend to be errors.
  2208. ant.lua can help you in map designing by providing warning and error
  2209. messages each time some ill argument gets passed or something. If you
  2210. debug, you may use several ant.lua functions that provide warning
  2211. and debug messages.
  2212.  
  2213. The functions follow:
  2214.  
  2215.       function warning(text)
  2216.       function be_pedantic(mode)
  2217.       function debug(text)
  2218.       function debug_mode()
  2219.       function debug_mode_off()
  2220.  
  2221. 6.1.1 Warnings
  2222. ..............
  2223.  
  2224. This function displays a warning message in a following format:
  2225.  
  2226.       warning: [ant.lua]: <text>
  2227.  
  2228. Where <text> is replaced by your text. If you want no warnings to
  2229. occur, that is, if a warning means that the map is broken and there is
  2230. no need to even try if it works, you may turn on pedantic mode:
  2231.  
  2232.       be_pedantic()
  2233.  
  2234. In pedantic mode, each warning turns to error. If an error occurs
  2235. during the map load time, the map never gets loaded.
  2236.  
  2237. Pedantic mode is turned off this way:
  2238.  
  2239.       be_pedantic(0)
  2240.  
  2241.  
  2242. 6.1.2 Debugs
  2243. ............
  2244.  
  2245. ant.lua provides a number of debugging messages. These inform you
  2246. about the code execution and about some checkpoints that were
  2247. passed. If you find yourself in doubt whether a function gets executed
  2248. at all, turn on debug mode:
  2249.  
  2250.       debug_mode()
  2251.  
  2252. In debug mode, the messages like this one:
  2253.  
  2254.       debug: [ant.lua]: creating world [20x13]
  2255.  
  2256. Appear on your terminal every once in a while. You can produce your
  2257. own debug messages, should you want:
  2258.  
  2259.       debug("beer overflow: fridge limit reached (improbable)")
  2260.  
  2261. I use this when creating some really complicated maps with lots of LUA
  2262. experiments in. You can leave the messages in a file even after the
  2263. debug, just remove the debug_mode() line. I remove them though, as I
  2264. like clean code :).
  2265.  
  2266.  
  2267. 6.2 Clone table
  2268. --------------------------------------------------------------------------------
  2269.  
  2270. This function makes a copy of a table. It's just a shallow copy
  2271. though, only the first layer of values is copied, nested tables stay
  2272. intact.
  2273.  
  2274.       cf = clone_table(cellfuncs)
  2275.  
  2276.  
  2277. 6.3 Sending messages
  2278. --------------------------------------------------------------------------------
  2279.  
  2280. Sending messages is a common way how to make one object do the things
  2281. like opening, closing, switching on and off, triggering etc. As long
  2282. as you use the triggers and switches for this purpose, everything is
  2283. OK. If you want to send a message on your own, you have to write
  2284. things like this:
  2285.  
  2286.       enigma.SendMessage(enigma.GetNamedObject("doorA"), "open", nil)
  2287.  
  2288. There is a function that provides this in a simple interface:
  2289.  
  2290.       send_message_named(objname, message, third)
  2291.  
  2292. Well, in fact I do not know what the 'third' argument means, but I
  2293. never saw anyone to pass anything other than 'nil' here. Above example
  2294. changes this way:
  2295.  
  2296.       send_message_named("doorA", "open", nil)
  2297.  
  2298. Much better.
  2299.  
  2300. Besides this, it's possible to send a message to the group of objects.
  2301. This is covered in chapter [5.2.2 Group actions].
  2302.  
  2303. ================================================================================
  2304. ~end of ant_lua,txt~
  2305.