dumplog's saved_plines[]
[aNetHack.git] / include / sp_lev.h
blobbe3e92164ed1e29fb9b1778bd36cd27c7eaf58be
1 /* NetHack 3.6 sp_lev.h $NHDT-Date: 1470212260 2016/08/03 08:17:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.17 $ */
2 /* Copyright (c) 1989 by Jean-Christophe Collet */
3 /* NetHack may be freely redistributed. See license for details. */
5 #ifndef SP_LEV_H
6 #define SP_LEV_H
8 /* wall directions */
9 #define W_NORTH 1
10 #define W_SOUTH 2
11 #define W_EAST 4
12 #define W_WEST 8
13 #define W_ANY (W_NORTH | W_SOUTH | W_EAST | W_WEST)
15 /* MAP limits */
16 #define MAP_X_LIM 76
17 #define MAP_Y_LIM 21
19 /* Per level flags */
20 #define NOTELEPORT 0x00000001L
21 #define HARDFLOOR 0x00000002L
22 #define NOMMAP 0x00000004L
23 #define SHORTSIGHTED 0x00000008L
24 #define ARBOREAL 0x00000010L
25 #define MAZELEVEL 0x00000020L
26 #define PREMAPPED 0x00000040L /* premapped level & sokoban rules */
27 #define SHROUD 0x00000080L
28 #define GRAVEYARD 0x00000100L
29 #define ICEDPOOLS 0x00000200L /* for ice locations: ICED_POOL vs ICED_MOAT \
31 #define SOLIDIFY 0x00000400L /* outer areas are nondiggable & nonpasswall */
32 #define CORRMAZE 0x00000800L /* for maze levels only */
33 #define CHECK_INACCESSIBLES 0x00001000L /* check for inaccessible areas and
34 generate ways to escape from them */
36 /* different level layout initializers */
37 enum lvlinit_types {
38 LVLINIT_NONE = 0,
39 LVLINIT_SOLIDFILL,
40 LVLINIT_MAZEGRID,
41 LVLINIT_MINES,
42 LVLINIT_ROGUE
45 /* max. layers of object containment */
46 #define MAX_CONTAINMENT 10
48 /* max. # of random registers */
49 #define MAX_REGISTERS 10
51 /* max. nested depth of subrooms */
52 #define MAX_NESTED_ROOMS 5
54 /* max. # of opcodes per special level */
55 #define SPCODER_MAX_RUNTIME 65536
57 /* Opcodes for creating the level
58 * If you change these, also change opcodestr[] in util/lev_main.c
60 enum opcode_defs {
61 SPO_NULL = 0,
62 SPO_MESSAGE,
63 SPO_MONSTER,
64 SPO_OBJECT,
65 SPO_ENGRAVING,
66 SPO_ROOM,
67 SPO_SUBROOM,
68 SPO_DOOR,
69 SPO_STAIR,
70 SPO_LADDER,
71 SPO_ALTAR,
72 SPO_FOUNTAIN,
73 SPO_SINK,
74 SPO_POOL,
75 SPO_TRAP,
76 SPO_GOLD,
77 SPO_CORRIDOR,
78 SPO_LEVREGION,
79 SPO_DRAWBRIDGE,
80 SPO_MAZEWALK,
81 SPO_NON_DIGGABLE,
82 SPO_NON_PASSWALL,
83 SPO_WALLIFY,
84 SPO_MAP,
85 SPO_ROOM_DOOR,
86 SPO_REGION,
87 SPO_MINERALIZE,
88 SPO_CMP,
89 SPO_JMP,
90 SPO_JL,
91 SPO_JLE,
92 SPO_JG,
93 SPO_JGE,
94 SPO_JE,
95 SPO_JNE,
96 SPO_TERRAIN,
97 SPO_REPLACETERRAIN,
98 SPO_EXIT,
99 SPO_ENDROOM,
100 SPO_POP_CONTAINER,
101 SPO_PUSH,
102 SPO_POP,
103 SPO_RN2,
104 SPO_DEC,
105 SPO_INC,
106 SPO_MATH_ADD,
107 SPO_MATH_SUB,
108 SPO_MATH_MUL,
109 SPO_MATH_DIV,
110 SPO_MATH_MOD,
111 SPO_MATH_SIGN,
112 SPO_COPY,
113 SPO_END_MONINVENT,
114 SPO_GRAVE,
115 SPO_FRAME_PUSH,
116 SPO_FRAME_POP,
117 SPO_CALL,
118 SPO_RETURN,
119 SPO_INITLEVEL,
120 SPO_LEVEL_FLAGS,
121 SPO_VAR_INIT, /* variable_name data */
122 SPO_SHUFFLE_ARRAY,
123 SPO_DICE,
125 SPO_SEL_ADD,
126 SPO_SEL_POINT,
127 SPO_SEL_RECT,
128 SPO_SEL_FILLRECT,
129 SPO_SEL_LINE,
130 SPO_SEL_RNDLINE,
131 SPO_SEL_GROW,
132 SPO_SEL_FLOOD,
133 SPO_SEL_RNDCOORD,
134 SPO_SEL_ELLIPSE,
135 SPO_SEL_FILTER,
136 SPO_SEL_GRADIENT,
137 SPO_SEL_COMPLEMENT,
139 MAX_SP_OPCODES
142 /* MONSTER and OBJECT can take a variable number of parameters,
143 * they also pop different # of values from the stack. So,
144 * first we pop a value that tells what the _next_ value will
145 * mean.
147 /* MONSTER */
148 #define SP_M_V_PEACEFUL 0
149 #define SP_M_V_ALIGN 1
150 #define SP_M_V_ASLEEP 2
151 #define SP_M_V_APPEAR 3
152 #define SP_M_V_NAME 4
154 #define SP_M_V_FEMALE 5
155 #define SP_M_V_INVIS 6
156 #define SP_M_V_CANCELLED 7
157 #define SP_M_V_REVIVED 8
158 #define SP_M_V_AVENGE 9
159 #define SP_M_V_FLEEING 10
160 #define SP_M_V_BLINDED 11
161 #define SP_M_V_PARALYZED 12
162 #define SP_M_V_STUNNED 13
163 #define SP_M_V_CONFUSED 14
164 #define SP_M_V_SEENTRAPS 15
166 #define SP_M_V_END 16 /* end of variable parameters */
168 /* OBJECT */
169 #define SP_O_V_SPE 0
170 #define SP_O_V_CURSE 1
171 #define SP_O_V_CORPSENM 2
172 #define SP_O_V_NAME 3
173 #define SP_O_V_QUAN 4
174 #define SP_O_V_BURIED 5
175 #define SP_O_V_LIT 6
176 #define SP_O_V_ERODED 7
177 #define SP_O_V_LOCKED 8
178 #define SP_O_V_TRAPPED 9
179 #define SP_O_V_RECHARGED 10
180 #define SP_O_V_INVIS 11
181 #define SP_O_V_GREASED 12
182 #define SP_O_V_BROKEN 13
183 #define SP_O_V_COORD 14
184 #define SP_O_V_END 15 /* end of variable parameters */
186 /* When creating objects, we need to know whether
187 * it's a container and/or contents.
189 #define SP_OBJ_CONTENT 0x1
190 #define SP_OBJ_CONTAINER 0x2
192 /* SPO_FILTER types */
193 #define SPOFILTER_PERCENT 0
194 #define SPOFILTER_SELECTION 1
195 #define SPOFILTER_MAPCHAR 2
197 /* gradient filter types */
198 #define SEL_GRADIENT_RADIAL 0
199 #define SEL_GRADIENT_SQUARE 1
201 /* variable types */
202 #define SPOVAR_NULL 0x00
203 #define SPOVAR_INT 0x01 /* l */
204 #define SPOVAR_STRING 0x02 /* str */
205 #define SPOVAR_VARIABLE 0x03 /* str (contains the variable name) */
206 #define SPOVAR_COORD \
207 0x04 /* coordinate, encoded in l; use SP_COORD_X() and SP_COORD_Y() */
208 #define SPOVAR_REGION 0x05 /* region, encoded in l; use SP_REGION_X1() etc \
210 #define SPOVAR_MAPCHAR 0x06 /* map char, in l */
211 #define SPOVAR_MONST \
212 0x07 /* monster class & specific monster, encoded in l; use SP_MONST_... \
214 #define SPOVAR_OBJ \
215 0x08 /* object class & specific object type, encoded in l; use \
216 SP_OBJ_... */
217 #define SPOVAR_SEL 0x09 /* selection. char[COLNO][ROWNO] in str */
218 #define SPOVAR_ARRAY 0x40 /* used in splev_var & lc_vardefs, not in opvar */
220 #define SP_COORD_IS_RANDOM 0x01000000
221 /* Humidity flags for get_location() and friends, used with
222 * SP_COORD_PACK_RANDOM() */
223 #define DRY 0x01
224 #define WET 0x02
225 #define HOT 0x04
226 #define SOLID 0x08
227 #define ANY_LOC 0x10 /* even outside the level */
228 #define NO_LOC_WARN 0x20 /* no complaints and set x & y to -1, if no loc */
229 #define SPACELOC 0x40 /* like DRY, but accepts furniture too */
231 #define SP_COORD_X(l) (l & 0xff)
232 #define SP_COORD_Y(l) ((l >> 16) & 0xff)
233 #define SP_COORD_PACK(x, y) (((x) & 0xff) + (((y) & 0xff) << 16))
234 #define SP_COORD_PACK_RANDOM(f) (SP_COORD_IS_RANDOM | (f))
236 #define SP_REGION_X1(l) (l & 0xff)
237 #define SP_REGION_Y1(l) ((l >> 8) & 0xff)
238 #define SP_REGION_X2(l) ((l >> 16) & 0xff)
239 #define SP_REGION_Y2(l) ((l >> 24) & 0xff)
240 #define SP_REGION_PACK(x1, y1, x2, y2) \
241 (((x1) & 0xff) + (((y1) & 0xff) << 8) + (((x2) & 0xff) << 16) \
242 + (((y2) & 0xff) << 24))
244 /* permonst index, object index, and lit value might be negative;
245 * add 10 to accept -1 through -9 while forcing non-negative for bit shift
247 #define SP_MONST_CLASS(l) ((l) & 0xff)
248 #define SP_MONST_PM(l) ((((l) >> 8) & 0xffff) - 10)
249 #define SP_MONST_PACK(pm, cls) (((10 + (pm)) << 8) | ((cls) & 0xff))
251 #define SP_OBJ_CLASS(l) ((l) & 0xff)
252 #define SP_OBJ_TYP(l) ((((l) >> 8) & 0xffff) - 10)
253 #define SP_OBJ_PACK(ob, cls) (((10 + (ob)) << 8) | ((cls) & 0xff))
255 #define SP_MAPCHAR_TYP(l) ((l) & 0xff)
256 #define SP_MAPCHAR_LIT(l) ((((l) >> 8) & 0xffff) - 10)
257 #define SP_MAPCHAR_PACK(typ, lit) (((10 + (lit)) << 8) | ((typ) & 0xff))
259 struct opvar {
260 xchar spovartyp; /* one of SPOVAR_foo */
261 union {
262 char *str;
263 long l;
264 } vardata;
267 struct splev_var {
268 struct splev_var *next;
269 char *name;
270 xchar svtyp; /* SPOVAR_foo */
271 union {
272 struct opvar *value;
273 struct opvar **arrayvalues;
274 } data;
275 long array_len;
278 struct splevstack {
279 long depth;
280 long depth_alloc;
281 struct opvar **stackdata;
284 struct sp_frame {
285 struct sp_frame *next;
286 struct splevstack *stack;
287 struct splev_var *variables;
288 long n_opcode;
291 struct sp_coder {
292 struct splevstack *stack;
293 struct sp_frame *frame;
294 int premapped;
295 boolean solidify;
296 struct mkroom *croom;
297 struct mkroom *tmproomlist[MAX_NESTED_ROOMS + 1];
298 boolean failed_room[MAX_NESTED_ROOMS + 1];
299 int n_subroom;
300 boolean exit_script;
301 int lvl_is_joined;
302 boolean check_inaccessibles;
304 int opcode; /* current opcode */
305 struct opvar *opdat; /* current push data (req. opcode == SPO_PUSH) */
308 /* special level coder CPU flags */
309 #define SP_CPUFLAG_LT 1
310 #define SP_CPUFLAG_GT 2
311 #define SP_CPUFLAG_EQ 4
312 #define SP_CPUFLAG_ZERO 8
315 * Structures manipulated by the special levels loader & compiler
318 #define packed_coord long
319 typedef struct {
320 xchar is_random;
321 long getloc_flags;
322 int x, y;
323 } unpacked_coord;
325 typedef struct {
326 int cmp_what;
327 int cmp_val;
328 } opcmp;
330 typedef struct {
331 long jmp_target;
332 } opjmp;
334 typedef union str_or_len {
335 char *str;
336 int len;
337 } Str_or_Len;
339 typedef struct {
340 xchar init_style; /* one of LVLINIT_foo */
341 long flags;
342 schar filling;
343 boolean init_present, padding;
344 char fg, bg;
345 boolean smoothed, joined;
346 xchar lit, walled;
347 boolean icedpools;
348 } lev_init;
350 typedef struct {
351 xchar wall, pos, secret, mask;
352 } room_door;
354 typedef struct {
355 packed_coord coord;
356 xchar x, y, type;
357 } trap;
359 typedef struct {
360 Str_or_Len name, appear_as;
361 short id;
362 aligntyp align;
363 packed_coord coord;
364 xchar x, y, class, appear;
365 schar peaceful, asleep;
366 short female, invis, cancelled, revived, avenge, fleeing, blinded,
367 paralyzed, stunned, confused;
368 long seentraps;
369 short has_invent;
370 } monster;
372 typedef struct {
373 Str_or_Len name;
374 int corpsenm;
375 short id, spe;
376 packed_coord coord;
377 xchar x, y, class, containment;
378 schar curse_state;
379 int quan;
380 short buried;
381 short lit;
382 short eroded, locked, trapped, recharged, invis, greased, broken;
383 } object;
385 typedef struct {
386 packed_coord coord;
387 xchar x, y;
388 aligntyp align;
389 xchar shrine;
390 } altar;
392 typedef struct {
393 xchar x1, y1, x2, y2;
394 xchar rtype, rlit, rirreg;
395 } region;
397 typedef struct {
398 xchar ter, tlit;
399 } terrain;
401 typedef struct {
402 xchar chance;
403 xchar x1, y1, x2, y2;
404 xchar fromter, toter, tolit;
405 } replaceterrain;
407 /* values for rtype are defined in dungeon.h */
408 typedef struct {
409 struct {
410 xchar x1, y1, x2, y2;
411 } inarea;
412 struct {
413 xchar x1, y1, x2, y2;
414 } delarea;
415 boolean in_islev, del_islev;
416 xchar rtype, padding;
417 Str_or_Len rname;
418 } lev_region;
420 typedef struct {
421 struct {
422 xchar room;
423 xchar wall;
424 xchar door;
425 } src, dest;
426 } corridor;
428 typedef struct _room {
429 Str_or_Len name;
430 Str_or_Len parent;
431 xchar x, y, w, h;
432 xchar xalign, yalign;
433 xchar rtype, chance, rlit, filled, joined;
434 } room;
436 typedef struct {
437 schar zaligntyp;
438 schar keep_region;
439 schar halign, valign;
440 char xsize, ysize;
441 char **map;
442 } mazepart;
444 typedef struct {
445 int opcode;
446 struct opvar *opdat;
447 } _opcode;
449 typedef struct {
450 _opcode *opcodes;
451 long n_opcodes;
452 } sp_lev;
454 typedef struct {
455 xchar x, y, direction, count, lit;
456 char typ;
457 } spill;
459 /* only used by lev_comp */
460 struct lc_funcdefs_parm {
461 char *name;
462 char parmtype;
463 struct lc_funcdefs_parm *next;
466 struct lc_funcdefs {
467 struct lc_funcdefs *next;
468 char *name;
469 long addr;
470 sp_lev code;
471 long n_called;
472 struct lc_funcdefs_parm *params;
473 long n_params;
476 struct lc_vardefs {
477 struct lc_vardefs *next;
478 char *name;
479 long var_type; /* SPOVAR_foo */
480 long n_used;
483 struct lc_breakdef {
484 struct lc_breakdef *next;
485 struct opvar *breakpoint;
486 int break_depth;
490 * Quick! Avert your eyes while you still have a chance!
492 #ifdef SPEC_LEV
493 /* compiling lev_comp rather than nethack */
494 #ifdef USE_OLDARGS
495 #undef VA_ARGS
496 #undef VA_DECL
497 #undef VA_DECL2
498 #undef VA_SHIFT
499 #define VA_ARGS \
500 arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, \
501 arg12, arg13, arg14
502 #define VA_DECL(typ1, var1) \
503 (var1, VA_ARGS) typ1 var1; \
504 char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8, *arg9, \
505 *arg10, *arg11, *arg12, *arg13, *arg14; \
507 #define VA_DECL2(typ1, var1, typ2, var2) \
508 (var1, var2, VA_ARGS) typ1 var1; \
509 typ2 var2; \
510 char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6, *arg7, *arg8, *arg9, \
511 *arg10, *arg11, *arg12, *arg13, *arg14; \
513 /* unlike in the core, lev_comp's VA_SHIFT is completely safe,
514 because callers always pass all these arguments */
515 #define VA_SHIFT() \
516 (arg1 = arg2, arg2 = arg3, arg3 = arg4, arg4 = arg5, arg5 = arg6, \
517 arg6 = arg7, arg7 = arg8, arg8 = arg9, arg9 = arg10, arg10 = arg11, \
518 arg11 = arg12, arg12 = arg13, arg13 = arg14, arg14 = 0)
519 /* standard NULL may be either (void *)0 or plain 0, both of
520 which would need to be explicitly cast to (char *) here */
521 typedef char *Va;
522 #define VA_PASS1(a1) \
523 (Va) a1, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, \
524 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
525 #define VA_PASS2(a1, a2) \
526 (Va) a1, (Va) a2, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, \
527 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
528 #define VA_PASS3(a1, a2, a3) \
529 (Va) a1, (Va) a2, (Va) a3, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, \
530 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
531 #define VA_PASS4(a1, a2, a3, a4) \
532 (Va) a1, (Va) a2, (Va) a3, (Va) a4, (Va) 0, (Va) 0, (Va) 0, (Va) 0, \
533 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
534 #define VA_PASS5(a1, a2, a3, a4, a5) \
535 (Va) a1, (Va) a2, (Va) a3, (Va) a4, (Va) a5, (Va) 0, (Va) 0, (Va) 0, \
536 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
537 #define VA_PASS7(a1, a2, a3, a4, a5, a6, a7) \
538 (Va) a1, (Va) a2, (Va) a3, (Va) a4, (Va) a5, (Va) a6, (Va) a7, (Va) 0, \
539 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
540 #define VA_PASS8(a1, a2, a3, a4, a5, a6, a7, a8) \
541 (Va) a1, (Va) a2, (Va) a3, (Va) a4, (Va) a5, (Va) a6, (Va) a7, (Va) a8, \
542 (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
543 #define VA_PASS9(a1, a2, a3, a4, a5, a6, a7, a8, a9) \
544 (Va) a1, (Va) a2, (Va) a3, (Va) a4, (Va) a5, (Va) a6, (Va) a7, (Va) a8, \
545 (Va) a9, (Va) 0, (Va) 0, (Va) 0, (Va) 0, (Va) 0
546 #define VA_PASS14(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, \
547 a14) \
548 (Va) a1, (Va) a2, (Va) a3, (Va) a4, (Va) a5, (Va) a6, (Va) a7, (Va) a8, \
549 (Va) a9, (Va) a10, (Va) a11, (Va) a12, (Va) a13, (Va) a14
550 #else /*!USE_OLDARGS*/
551 /* USE_STDARG and USE_VARARGS don't need to pass dummy arguments
552 or cast real ones */
553 #define VA_PASS1(a1) a1
554 #define VA_PASS2(a1, a2) a1, a2
555 #define VA_PASS3(a1, a2, a3) a1, a2, a3
556 #define VA_PASS4(a1, a2, a3, a4) a1, a2, a3, a4
557 #define VA_PASS5(a1, a2, a3, a4, a5) a1, a2, a3, a4, a5
558 #define VA_PASS7(a1, a2, a3, a4, a5, a6, a7) a1, a2, a3, a4, a5, a6, a7
559 #define VA_PASS8(a1, a2, a3, a4, a5, a6, a7, a8) \
560 a1, a2, a3, a4, a5, a6, a7, a8
561 #define VA_PASS9(a1, a2, a3, a4, a5, a6, a7, a8, a9) \
562 a1, a2, a3, a4, a5, a6, a7, a8, a9
563 #define VA_PASS14(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, \
564 a14) \
565 a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14
566 #endif /*?USE_OLDARGS*/
567 /* You were warned to avert your eyes.... */
568 #endif /*SPEC_LEV*/
570 #endif /* SP_LEV_H */