1 |
-- base methods for ant's enigma maps |
-- base methods for ant's enigma maps |
2 |
-- (c) 2002 Petr Machata/ant_39 |
-- (c) 2002 Petr Machata/ant_39 |
3 |
-- Licensed under GPL v2.0 or above |
-- Licensed under GPL v2.0 or above |
4 |
|
-- |
5 |
|
-- modified 2003-01-07 : special floor types and train support |
6 |
|
|
7 |
|
|
8 |
|
|
9 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
10 |
|
-- EASY MAP DRAWING -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
11 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
12 |
|
|
13 |
TRANSPOSE_MAP = 1 |
TRANSPOSE_MAP = 1 |
14 |
NO_TRANSPOSE_MAP = not(TRANSPOSE_MAP) |
NO_TRANSPOSE_MAP = not(TRANSPOSE_MAP) |
37 |
cell.stone = cell_item(structure.stone or {}) |
cell.stone = cell_item(structure.stone or {}) |
38 |
cell.item = cell_item(structure.item or {}) |
cell.item = cell_item(structure.item or {}) |
39 |
|
|
40 |
|
local parent =structure.parent |
41 |
|
local partype=type(parent) |
42 |
|
|
43 |
return function(x, y) |
return function(x, y) |
44 |
--call parents |
if (%partype=="nil") then |
45 |
if (%structure.parent) then |
-- no parent, do nothing! |
46 |
for i,parfun in %structure.parent do |
elseif (%partype=="function") then |
47 |
parfun(x,y) |
-- parent is single function. let's call it! |
48 |
|
%structure.parent(x,y) |
49 |
|
elseif (%partype=="table") then |
50 |
|
-- parent is table. look closer... |
51 |
|
for _,item in %parent do |
52 |
|
if (type(item)=="function") then |
53 |
|
-- item is function. call it! |
54 |
|
item(x,y) |
55 |
|
elseif (type(item)=="table") then |
56 |
|
-- item is table. let first item be function and second it's parameter |
57 |
|
item[1](item[2], x, y) |
58 |
|
else |
59 |
|
-- item is something else |
60 |
|
print("warning: [ant.lua]: illegal parent item type:", type(item)) |
61 |
|
end |
62 |
end |
end |
63 |
|
else |
64 |
|
-- parent is something else |
65 |
|
print("warning: [ant.lua]: ilegal parent type:", %partype) |
66 |
end |
end |
67 |
|
|
68 |
--map elements |
--map elements |
78 |
end |
end |
79 |
end |
end |
80 |
|
|
81 |
|
-- this returns... voila... the size of map |
82 |
|
function get_map_size(level) |
83 |
|
local levelh = getn(level) |
84 |
|
local levelw = 0 |
85 |
|
|
86 |
|
for _,str in level do |
87 |
|
if strlen(str)>levelw then |
88 |
|
levelw = strlen(str) |
89 |
|
end |
90 |
|
end |
91 |
|
|
92 |
|
return levelw, levelh |
93 |
|
end |
94 |
|
|
95 |
-- this draws the map to the position [x0,y0] |
-- this draws the map to the position [x0,y0] |
96 |
function draw_map(x0, y0, map, swap_coords) |
function draw_map(x0, y0, map, swap_coords) |
97 |
for y,str in map do |
for y,str in map do |
105 |
end |
end |
106 |
end |
end |
107 |
end |
end |
108 |
|
|
109 |
|
-- this prepares enigma world and draws given map |
110 |
|
-- swap_coords is optionaly |
111 |
|
function create_world_by_map(level, swap_coords) |
112 |
|
local levelw, levelh = get_map_size(level) |
113 |
|
create_world(levelw, levelh) |
114 |
|
draw_map(0, 0, level, swap_coords) |
115 |
|
end |
116 |
|
|
117 |
|
|
118 |
|
|
119 |
|
|
120 |
|
|
121 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
122 |
|
-- TRAINS/WORMS/WHATEVER FUNCTIONS -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
123 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
124 |
|
|
125 |
|
pathway_directions = {{ 1, 0}, { 0, 1}, {-1, 0}, { 0,-1}} |
126 |
|
path = {} |
127 |
|
path.constructor = {} |
128 |
|
|
129 |
|
-- globals |
130 |
|
|
131 |
|
function getkey(x,y) return x..","..y end |
132 |
|
|
133 |
|
-- pathworks |
134 |
|
|
135 |
|
function new_path_item(x,y,tag,context) |
136 |
|
local it = {} |
137 |
|
it.x, it.y = x, y |
138 |
|
it.tag = tag |
139 |
|
it.context = context |
140 |
|
|
141 |
|
return it |
142 |
|
end |
143 |
|
|
144 |
|
function add_path_item(x, y, tag, context) |
145 |
|
path[getkey(x,y)]=new_path_item(x,y,tag,context) |
146 |
|
end |
147 |
|
|
148 |
|
function add_path_train(x, y, context) |
149 |
|
add_path_item(x, y, nil, context) |
150 |
|
end |
151 |
|
|
152 |
|
function add_path_empty(x, y, context) |
153 |
|
add_path_item(x, y, not(nil), context) |
154 |
|
end |
155 |
|
|
156 |
|
-- constructors |
157 |
|
|
158 |
|
function add_path_constructor(x, y, await, action, context) |
159 |
|
local cons = {} |
160 |
|
cons.x, cons.y = x, y |
161 |
|
cons.action = action |
162 |
|
cons.await = await |
163 |
|
cons.context = context |
164 |
|
|
165 |
|
path.constructor[getn(path.constructor)+1] = cons |
166 |
|
end |
167 |
|
|
168 |
|
function move_constructor(x0, y0, awaittag, context) |
169 |
|
local found = nil |
170 |
|
|
171 |
|
for i,dir in pathway_directions do |
172 |
|
local x00, y00 = x0+dir[1], y0+dir[2] |
173 |
|
local key = getkey(x00, y00) |
174 |
|
|
175 |
|
if (path[key]) then |
176 |
|
if ((path[key].context==context) and (path[key].tag==awaittag)) then |
177 |
|
path[key].tag = not(path[key].tag) |
178 |
|
found = i |
179 |
|
break |
180 |
|
end |
181 |
|
end |
182 |
|
end |
183 |
|
|
184 |
|
if (found) then |
185 |
|
local x1 = x0 + pathway_directions[found][1] |
186 |
|
local y1 = y0 + pathway_directions[found][2] |
187 |
|
return x1, y1 |
188 |
|
else |
189 |
|
return x0, y0 |
190 |
|
end |
191 |
|
end |
192 |
|
|
193 |
|
function move_constructors() |
194 |
|
local key, cons |
195 |
|
for key,cons in path.constructor do |
196 |
|
cons.x, cons.y = move_constructor(cons.x, cons.y, cons.await, cons.context) |
197 |
|
cons.action(cons.x, cons.y) |
198 |
|
end |
199 |
|
end |
200 |
|
|
201 |
|
|
202 |
|
|
203 |
|
|
204 |
|
|
205 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
206 |
|
-- SPECIAL FLOOR TYPES -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
207 |
|
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- |
208 |
|
|
209 |
|
-- draws checker floor |
210 |
|
-- sidex: horizontal size of checker square |
211 |
|
-- sidey: vertical size of checker square |
212 |
|
-- count: number of checker textures |
213 |
|
-- items: table of checker textures [1,2,3,...] |
214 |
|
-- x,y: coordinates of checker field |
215 |
|
function mcheckerfloor(sidex, sidey, count, items, x, y) |
216 |
|
local x0, y0 = floor(x/sidex), floor(y/sidey) |
217 |
|
local remainder = mod(x0+y0, count) |
218 |
|
items[remainder+1](x,y) |
219 |
|
end |
220 |
|
|
221 |
|
-- the checkerfloor parent |
222 |
|
-- items: checkerfloor textures. Functions generated by cell({structure}) |
223 |
|
-- eg: |
224 |
|
-- cells["."]=cell{floor={face="fl-metal"}} |
225 |
|
-- cells[","]=cell{floor={face="fl-normal"}} |
226 |
|
-- cells[" "]=cell{parent={{checkerfloor,{cells[","], cells["."]}}}} |
227 |
|
-- optionally, at the end of table there may be additional checkerboard generating variables: |
228 |
|
-- side - set size of checkerboard square |
229 |
|
-- sidex - only set horizontal size (defaults to 1) |
230 |
|
-- sidey - only set vertical size (defaults to 1) |
231 |
|
-- cells[" "]=cell{parent={{checkerfloor,{cells[","], cells["."]; side=2}}}} |
232 |
|
function checkerfloor(items, x, y) |
233 |
|
local count = getn(items) |
234 |
|
local remainder = mod(x+y, count) |
235 |
|
local sidex, sidey = 1, 1 |
236 |
|
|
237 |
|
if (items.side~=nil) then |
238 |
|
sidex = items.side |
239 |
|
sidey = sidex |
240 |
|
end |
241 |
|
|
242 |
|
if (items.sidex~=nil) then |
243 |
|
sidex = items.sidex |
244 |
|
end |
245 |
|
|
246 |
|
if (items.sidey~=nil) then |
247 |
|
sidey = items.sidey |
248 |
|
end |
249 |
|
|
250 |
|
mcheckerfloor(sidex, sidey, getn(items), items, x, y) |
251 |
|
end |
252 |
|
|
253 |
|
-- the random floor parent |
254 |
|
-- every item may be: |
255 |
|
-- texture -- parent function to be called if given texture is selected |
256 |
|
-- occurence -- occurence factor for previous texture. Defaults to 1. |
257 |
|
function randomfloor(items, x, y) |
258 |
|
local count = 0 |
259 |
|
local total = 0 --total occurences |
260 |
|
local itemlist = {} |
261 |
|
|
262 |
|
for _,item in items do |
263 |
|
local titem = type(item) |
264 |
|
if (titem == "function") then |
265 |
|
count = count + 1 |
266 |
|
itemlist[count] = {} |
267 |
|
itemlist[count].func = item |
268 |
|
itemlist[count].occf = 1 |
269 |
|
total = total + 1 |
270 |
|
elseif (titem == "number") then |
271 |
|
itemlist[count].occf = item |
272 |
|
total = total + item-1 |
273 |
|
end |
274 |
|
end |
275 |
|
|
276 |
|
local rand = total*random() |
277 |
|
local ctr = 0 |
278 |
|
|
279 |
|
for i=1,count do |
280 |
|
local move = itemlist[i].occf |
281 |
|
if ((rand>=ctr) and (rand<ctr+move)) then |
282 |
|
itemlist[i].func(x,y) |
283 |
|
end |
284 |
|
ctr = ctr + move |
285 |
|
end |
286 |
|
end |
287 |
|
|
288 |
|
-- trains and pathworks support floor parents |
289 |
|
|
290 |
|
-- path_constructor - add a generator of solid floor. This is the head of train. |
291 |
|
-- opts[1] is context. It is number or string. Train only rides on the |
292 |
|
-- paths with same context, as it has |
293 |
|
-- opts[2] is constructing function. Usually it draws floor or something. It can also be one of cells[" "] functions. |
294 |
|
function path_constructor(opts,x,y) |
295 |
|
add_path_constructor(x, y, not(nil), opts[2], opts[1]) |
296 |
|
end |
297 |
|
|
298 |
|
-- path_destructor - add a desintegrator of solid floor. This is train's last wagon. |
299 |
|
-- opts like in path_constructor |
300 |
|
function path_destructor(opts,x,y) |
301 |
|
add_path_constructor(x, y, nil, opts[2], opts[1]) |
302 |
|
end |
303 |
|
|
304 |
|
-- path_train - there already is body of train on this square |
305 |
|
-- opts[1] is context, see path_constructor |
306 |
|
function path_train(opts,x,y) |
307 |
|
add_path_train(x,y,opts[1]) |
308 |
|
end |
309 |
|
|
310 |
|
-- path_empty - there is just path. Train can ride here eventually. |
311 |
|
-- opts[1] is context, see path_constructor |
312 |
|
function path_empty(opts,x,y) |
313 |
|
add_path_empty(x,y,opts[1]) |
314 |
|
end |