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