1 /*	SCCS Id: @(#)sp_lev.h	3.4	1996/05/08	*/
2 /* Copyright (c) 1989 by Jean-Christophe Collet			  */
3 /* NetHack may be freely redistributed.  See license for details. */
4 
5 #ifndef SP_LEV_H
6 #define SP_LEV_H
7 
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)
14 
15     /* MAP limits */
16 #define MAP_X_LIM	76
17 #define MAP_Y_LIM	21
18 
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 NOFLIPX		0x00000020L
26 #define NOFLIPY		0x00000040L
27 #define MAZELEVEL	0x00000080L
28 #define PREMAPPED	0x00000100L
29 #define SHROUD		0x00000200L
30 #define STORMY		0x00000400L
31 #define GRAVEYARD	0x00000800L
32 #define SKYMAP		0x00001000L
33 #define SHEOL_LEV	0x00002000L
34 #define FLAG_RNDVAULT	0x00004000L
35 
36 
37 /* different level layout initializers */
38 #define LVLINIT_NONE		0
39 #define LVLINIT_SOLIDFILL	1
40 #define LVLINIT_MAZEGRID	2
41 #define LVLINIT_MINES		3
42 #define LVLINIT_SHEOL		4
43 #define LVLINIT_ROGUE		5
44 
45 /* max. layers of object containment */
46 #define MAX_CONTAINMENT 10
47 
48 /* max. # of random registers */
49 #define MAX_REGISTERS	10
50 
51 /* max. nested depth of subrooms */
52 #define MAX_NESTED_ROOMS 5
53 
54 /* max. # of opcodes per special level */
55 #define SPCODER_MAX_RUNTIME	65536
56 
57 /* Opcodes for creating the level
58  * If you change these, also change opcodestr[] in util/lev_main.c
59  */
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_SPILL,
97     SPO_TERRAIN,
98     SPO_REPLACETERRAIN,
99     SPO_EXIT,
100     SPO_ENDROOM,
101     SPO_POP_CONTAINER,
102     SPO_PUSH,
103     SPO_POP,
104     SPO_RN2,
105     SPO_DEC,
106     SPO_INC,
107     SPO_MATH_ADD,
108     SPO_MATH_SUB,
109     SPO_MATH_MUL,
110     SPO_MATH_DIV,
111     SPO_MATH_MOD,
112     SPO_MATH_SIGN,
113     SPO_COPY,
114     SPO_MON_GENERATION,
115     SPO_END_MONINVENT,
116     SPO_GRAVE,
117     SPO_FRAME_PUSH,
118     SPO_FRAME_POP,
119     SPO_CALL,
120     SPO_RETURN,
121     SPO_INITLEVEL,
122     SPO_LEVEL_FLAGS,
123     SPO_LEVEL_SOUNDS,
124     SPO_WALLWALK,
125     SPO_VAR_INIT, /* variable_name data */
126     SPO_SHUFFLE_ARRAY,
127     SPO_DICE,
128     SPO_COREFUNC,
129 
130     SPO_SEL_ADD,
131     SPO_SEL_POINT,
132     SPO_SEL_RECT,
133     SPO_SEL_FILLRECT,
134     SPO_SEL_LINE,
135     SPO_SEL_RNDLINE,
136     SPO_SEL_GROW,
137     SPO_SEL_FLOOD,
138     SPO_SEL_RNDCOORD,
139     SPO_SEL_ELLIPSE,
140     SPO_SEL_FILTER,
141     SPO_SEL_GRADIENT,
142     SPO_SEL_COMPLEMENT,
143 
144     MAX_SP_OPCODES
145 };
146 
147 /* "Functions" exposed from the core to the level compiler.
148  * Function handling is in spo_corefunc() in sp_lev.c
149  * See also core_vars[] in util/lev_main.c for their public
150  * names and what parameters they take and return.
151  */
152 enum corefuncs {
153     COREFUNC_NONE = 0,
154     COREFUNC_LEVEL_DIFFICULTY,
155     COREFUNC_LEVEL_DEPTH,
156     COREFUNC_DISCORDIAN_HOLIDAY,
157     COREFUNC_PIRATEDAY,
158     COREFUNC_APRILFOOLSDAY,
159     COREFUNC_PIDAY,
160     COREFUNC_TOWELDAY,
161     COREFUNC_MIDNIGHT,
162     COREFUNC_NIGHT,
163     COREFUNC_FRIDAY_13TH,
164     COREFUNC_POM,
165     COREFUNC_YYYYMMDD,
166     COREFUNC_PLNAME,
167     COREFUNC_TOSTRING,
168     COREFUNC_TOINT,
169     COREFUNC_TOCOORD,
170     COREFUNC_TOREGION,
171     COREFUNC_RN2,
172     COREFUNC_SOBJ_AT,
173     COREFUNC_MON_AT,
174     COREFUNC_CARRYING,
175     COREFUNC_ROLE,
176     COREFUNC_RACE,
177 
178     COREFUNC_ROOM_WID,
179     COREFUNC_ROOM_HEI,
180     COREFUNC_ROOM_X,
181     COREFUNC_ROOM_Y,
182 
183     /* variable methods */
184     COREFUNC_COORD_X,
185     COREFUNC_COORD_Y,
186     COREFUNC_ARRAY_LEN,
187 
188     NUM_COREFUNCS
189 };
190 
191 /* MONSTER and OBJECT can take a variable number of parameters,
192  * they also pop different # of values from the stack. So,
193  * first we pop a value that tells what the _next_ value will
194  * mean.
195  */
196 /* MONSTER */
197 #define SP_M_V_PEACEFUL         0
198 #define SP_M_V_ALIGN            1
199 #define SP_M_V_ASLEEP           2
200 #define SP_M_V_APPEAR           3
201 #define SP_M_V_NAME             4
202 
203 #define SP_M_V_FEMALE		5
204 #define SP_M_V_INVIS		6
205 #define SP_M_V_CANCELLED	7
206 #define SP_M_V_REVIVED		8
207 #define SP_M_V_AVENGE		9
208 #define SP_M_V_FLEEING		10
209 #define SP_M_V_BLINDED		11
210 #define SP_M_V_PARALYZED	12
211 #define SP_M_V_STUNNED		13
212 #define SP_M_V_CONFUSED		14
213 #define SP_M_V_SEENTRAPS	15
214 
215 #define SP_M_V_END              16 /* end of variable parameters */
216 
217 /* OBJECT */
218 #define SP_O_V_SPE              0
219 #define SP_O_V_CURSE            1
220 #define SP_O_V_CORPSENM         2
221 #define SP_O_V_NAME             3
222 #define SP_O_V_QUAN		4
223 #define SP_O_V_BURIED		5
224 #define SP_O_V_LIT		6
225 #define SP_O_V_ERODED		7
226 #define SP_O_V_LOCKED		8
227 #define SP_O_V_TRAPPED		9
228 #define SP_O_V_RECHARGED	10
229 #define SP_O_V_INVIS		11
230 #define SP_O_V_GREASED		12
231 #define SP_O_V_BROKEN		13
232 #define SP_O_V_COORD		14
233 #define SP_O_V_END              15 /* end of variable parameters */
234 
235 
236 /* When creating objects, we need to know whether
237  * it's a container and/or contents.
238  */
239 #define SP_OBJ_CONTENT		0x1
240 #define SP_OBJ_CONTAINER	0x2
241 
242 
243 /* SPO_FILTER types */
244 #define SPOFILTER_PERCENT	0
245 #define SPOFILTER_SELECTION	1
246 #define SPOFILTER_MAPCHAR	2
247 
248 /* gradient filter types */
249 #define SEL_GRADIENT_RADIAL	0
250 #define SEL_GRADIENT_SQUARE	1
251 
252 
253 #define SPOVAR_NULL	0x00
254 #define SPOVAR_INT	0x01 /* l */
255 #define SPOVAR_STRING	0x02 /* str */
256 #define SPOVAR_VARIABLE	0x03 /* str (contains the variable name) */
257 #define SPOVAR_COORD	0x04 /* coordinate, encoded in l; use SP_COORD_X() and SP_COORD_Y() */
258 #define SPOVAR_REGION	0x05 /* region, encoded in l; use SP_REGION_X1() etc */
259 #define SPOVAR_MAPCHAR	0x06 /* map char, in l */
260 #define SPOVAR_MONST	0x07 /* monster class & specific monster, encoded in l; use SP_MONST_... */
261 #define SPOVAR_OBJ	0x08 /* object class & specific object type, encoded in l; use SP_OBJ_... */
262 #define SPOVAR_SEL	0x09 /* selection. char[COLNO][ROWNO] in str */
263 #define SPOVAR_ARRAY	0x40 /* used in splev_var & lc_vardefs, not in opvar */
264 
265 #define SP_COORD_IS_RANDOM 0x01000000
266 /* Humidity flags for get_location() and friends, used with SP_COORD_PACK_RANDOM() */
267 #define DRY	0x1
268 #define WET	0x2
269 #define HOT	0x4
270 #define SOLID	0x8
271 #define ANY_LOC 0x10 /* even outside the level */
272 #define NO_LOC_WARN 0x20 /* no complaints and set x & y to -1, if no loc */
273 
274 #define SP_COORD_X(l)	(l & 0xff)
275 #define SP_COORD_Y(l)	((l >> 16) & 0xff)
276 #define SP_COORD_PACK(x,y) ((( x ) & 0xff) + ((( y ) & 0xff) << 16))
277 #define SP_COORD_PACK_RANDOM(f) (SP_COORD_IS_RANDOM | (f))
278 
279 #define SP_REGION_X1(l)	(l & 0xff)
280 #define SP_REGION_Y1(l)	((l >> 8) & 0xff)
281 #define SP_REGION_X2(l)	((l >> 16) & 0xff)
282 #define SP_REGION_Y2(l)	((l >> 24) & 0xff)
283 #define SP_REGION_PACK(x1,y1,x2,y2) ((( x1 ) & 0xff) + ((( y1 ) & 0xff) << 8) + ((( x2 ) & 0xff) << 16) + ((( y2 ) & 0xff) << 24))
284 
285 #define SP_MONST_CLASS(l) (l & 0xff)
286 #define SP_MONST_PM(l)	  ((l >> 8) & 0xffff)
287 #define SP_MONST_PACK(m,c) ((( m ) << 8) + ((char)( c )))
288 
289 #define SP_OBJ_CLASS(l)	  (l & 0xff)
290 #define SP_OBJ_TYP(l)	  ((l >> 8) & 0xffff)
291 #define SP_OBJ_PACK(o,c)  ((( o ) << 8) + ((char)( c )))
292 
293 #define SP_MAPCHAR_TYP(l) (l & 0xff)
294 #define SP_MAPCHAR_LIT(l) ((l >> 8) & 0xff)
295 #define SP_MAPCHAR_PACK(typ,lit) ((( lit ) << 8) + ((char)( typ )))
296 
297 struct opvar {
298     xchar spovartyp; /* one of SPOVAR_foo */
299     union {
300 	char *str;
301 	long l;
302     } vardata;
303 };
304 
305 struct splev_var {
306     struct splev_var *next;
307     char *name;
308     xchar svtyp; /* SPOVAR_foo */
309     union {
310 	struct opvar *value;
311 	struct opvar **arrayvalues;
312     } data;
313     long array_len;
314 };
315 
316 struct splevstack {
317     long depth;
318     long depth_alloc;
319     struct opvar **stackdata;
320 };
321 
322 
323 struct sp_frame {
324     struct sp_frame *next;
325     struct splevstack *stack;
326     struct splev_var *variables;
327     long n_opcode;
328 };
329 
330 
331 struct sp_coder {
332     struct splevstack *stack;
333     struct sp_frame *frame;
334     int allow_flips;
335     int premapped;
336     struct mkroom *croom;
337     struct mkroom *tmproomlist[MAX_NESTED_ROOMS+1];
338     boolean failed_room[MAX_NESTED_ROOMS+1];
339     int n_subroom;
340     boolean exit_script;
341     int  lvl_is_joined;
342 
343     int opcode;  /* current opcode */
344     struct opvar *opdat; /* current push data (req. opcode == SPO_PUSH) */
345 };
346 
347 /* special level coder CPU flags */
348 #define SP_CPUFLAG_LT	1
349 #define SP_CPUFLAG_GT	2
350 #define SP_CPUFLAG_EQ	4
351 #define SP_CPUFLAG_ZERO	8
352 
353 /*
354  * Structures manipulated by the special levels loader & compiler
355  */
356 
357 #define packed_coord long
358 typedef struct {
359     xchar is_random;
360     long getloc_flags;
361     int x, y;
362 } unpacked_coord;
363 
364 typedef struct {
365 	int cmp_what;
366 	int cmp_val;
367 } opcmp;
368 
369 typedef struct {
370 	long jmp_target;
371 } opjmp;
372 
373 typedef union str_or_len {
374 	char *str;
375 	int   len;
376 } Str_or_Len;
377 
378 typedef struct {
379 	xchar   init_style; /* one of LVLINIT_foo */
380 	char	fg, bg;
381 	boolean smoothed, joined;
382 	xchar	lit, walled;
383 	long	flags;
384 	schar	filling;
385 } lev_init;
386 
387 typedef struct {
388 	xchar wall, pos, secret, mask;
389 } room_door;
390 
391 typedef struct {
392     packed_coord coord;
393 	xchar x, y, type;
394 } trap;
395 
396 typedef struct {
397 	Str_or_Len name, appear_as;
398 	short id;
399 	aligntyp align;
400     packed_coord coord;
401 	xchar x, y, class, appear;
402 	schar peaceful, asleep;
403         short female, invis, cancelled, revived, avenge, fleeing, blinded, paralyzed, stunned, confused;
404         long seentraps;
405 	short has_invent;
406 } monster;
407 
408 typedef struct {
409 	Str_or_Len name;
410 	int   corpsenm;
411 	short id, spe;
412     packed_coord coord;
413 	xchar x, y, class, containment;
414 	schar curse_state;
415 	int   quan;
416 	short buried;
417 	short lit;
418         short eroded, locked, trapped, recharged, invis, greased, broken;
419 } object;
420 
421 typedef struct {
422     packed_coord coord;
423 	xchar		x, y;
424 	aligntyp	align;
425 	xchar		shrine;
426 } altar;
427 
428 typedef struct {
429 	xchar x1, y1, x2, y2;
430 	xchar rtype, rlit, rirreg;
431 } region;
432 
433 typedef struct {
434     xchar ter, tlit;
435 } terrain;
436 
437 typedef struct {
438     xchar chance;
439     xchar x1,y1,x2,y2;
440     xchar fromter, toter, tolit;
441 } replaceterrain;
442 
443 /* values for rtype are defined in dungeon.h */
444 typedef struct {
445 	struct { xchar x1, y1, x2, y2; } inarea;
446 	struct { xchar x1, y1, x2, y2; } delarea;
447 	boolean in_islev, del_islev;
448 	xchar rtype, padding;
449 	Str_or_Len rname;
450 } lev_region;
451 
452 typedef struct _room {
453 	Str_or_Len name;
454 	Str_or_Len parent;
455 	xchar x, y, w, h;
456 	xchar xalign, yalign;
457 	xchar rtype, chance, rlit, filled, joined;
458 } room;
459 
460 typedef struct {
461 	schar zaligntyp;
462 	schar keep_region;
463 	schar halign, valign;
464 	char xsize, ysize;
465 	char **map;
466 } mazepart;
467 
468 typedef struct {
469 	struct {
470 		xchar room;
471 		xchar wall;
472 		xchar door;
473 	} src, dest;
474 } corridor;
475 
476 typedef struct {
477     int opcode;
478     struct opvar *opdat;
479 } _opcode;
480 
481 typedef struct {
482     _opcode  *opcodes;
483     long     n_opcodes;
484 } sp_lev;
485 
486 typedef struct {
487 	xchar x, y, direction, count, lit;
488 	char typ;
489 } spill;
490 
491 
492 /* only used by lev_comp */
493 struct lc_funcdefs_parm {
494     char *name;
495     char parmtype;
496     struct lc_funcdefs_parm *next;
497 };
498 
499 struct lc_funcdefs {
500     struct lc_funcdefs *next;
501     char *name;
502     long addr;
503     sp_lev code;
504     long n_called;
505     struct lc_funcdefs_parm *params;
506     long n_params;
507 };
508 
509 struct lc_vardefs {
510     struct lc_vardefs *next;
511     char *name;
512     long var_type; /* SPOVAR_foo */
513     long n_used;
514 };
515 
516 struct lc_breakdef {
517     struct lc_breakdef *next;
518     struct opvar *breakpoint;
519     int break_depth;
520 };
521 
522 #endif /* SP_LEV_H */
523