1 /* NetHack 3.7	hack.h	$NHDT-Date: 1601595709 2020/10/01 23:41:49 $  $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.141 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Pasi Kallinen, 2017. */
4 /* NetHack may be freely redistributed.  See license for details. */
5 
6 #ifndef HACK_H
7 #define HACK_H
8 
9 #ifndef CONFIG_H
10 #include "config.h"
11 #endif
12 #include "lint.h"
13 
14 #define TELL 1
15 #define NOTELL 0
16 #define ON 1
17 #define OFF 0
18 #define BOLT_LIM 8        /* from this distance ranged attacks will be made */
19 #define MAX_CARR_CAP 1000 /* so that boulders can be heavier */
20 #define DUMMY { 0 }       /* array initializer, letting [1..N-1] default */
21 #define DEF_NOTHING ' '   /* default symbol for NOTHING and UNEXPLORED  */
22 
23 /* The UNDEFINED macros are used to initialize variables whose
24    initialized value is not relied upon.
25    UNDEFINED_VALUE: used to initialize any scalar type except pointers.
26    UNDEFINED_VALUES: used to initialize any non scalar type without pointers.
27    UNDEFINED_PTR: can be used only on pointer types. */
28 #define UNDEFINED_VALUE 0
29 #define UNDEFINED_VALUES { 0 }
30 #define UNDEFINED_PTR NULL
31 
32 /* symbolic names for capacity levels */
33 enum encumbrance_types {
34     UNENCUMBERED = 0,
35     SLT_ENCUMBER = 1, /* Burdened */
36     MOD_ENCUMBER = 2, /* Stressed */
37     HVY_ENCUMBER = 3, /* Strained */
38     EXT_ENCUMBER = 4, /* Overtaxed */
39     OVERLOADED   = 5  /* Overloaded */
40 };
41 
42 /* weight increment of heavy iron ball */
43 #define IRON_BALL_W_INCR 160
44 
45 /* number of turns it takes for vault guard to show up */
46 #define VAULT_GUARD_TIME 30
47 
48 #define SHOP_DOOR_COST 400L /* cost of a destroyed shop door */
49 #define SHOP_BARS_COST 300L /* cost of iron bars */
50 #define SHOP_HOLE_COST 200L /* cost of making hole/trapdoor */
51 #define SHOP_WALL_COST 200L /* cost of destroying a wall */
52 #define SHOP_WALL_DMG  (10L * ACURRSTR) /* damaging a wall */
53 #define SHOP_WEB_COST   30L /* cost of removing a web */
54 
55 /* hunger states - see hu_stat in eat.c */
56 enum hunger_state_types {
57     SATIATED   = 0,
58     NOT_HUNGRY = 1,
59     HUNGRY     = 2,
60     WEAK       = 3,
61     FAINTING   = 4,
62     FAINTED    = 5,
63     STARVED    = 6
64 };
65 
66 /* Macros for how a rumor was delivered in outrumor() */
67 #define BY_ORACLE 0
68 #define BY_COOKIE 1
69 #define BY_PAPER 2
70 #define BY_OTHER 9
71 
72 /* Macros for why you are no longer riding */
73 enum dismount_types {
74     DISMOUNT_GENERIC  = 0,
75     DISMOUNT_FELL     = 1,
76     DISMOUNT_THROWN   = 2,
77     DISMOUNT_POLY     = 3,
78     DISMOUNT_ENGULFED = 4,
79     DISMOUNT_BONES    = 5,
80     DISMOUNT_BYCHOICE = 6
81 };
82 
83 /* sellobj_state() states */
84 #define SELL_NORMAL (0)
85 #define SELL_DELIBERATE (1)
86 #define SELL_DONTSELL (2)
87 
88 /* alteration types--keep in synch with costly_alteration(mkobj.c) */
89 enum cost_alteration_types {
90     COST_CANCEL  =  0, /* standard cancellation */
91     COST_DRAIN   =  1, /* drain life upon an object */
92     COST_UNCHRG  =  2, /* cursed charging */
93     COST_UNBLSS  =  3, /* unbless (devalues holy water) */
94     COST_UNCURS  =  4, /* uncurse (devalues unholy water) */
95     COST_DECHNT  =  5, /* disenchant weapons or armor */
96     COST_DEGRD   =  6, /* removal of rustproofing, dulling via engraving */
97     COST_DILUTE  =  7, /* potion dilution */
98     COST_ERASE   =  8, /* scroll or spellbook blanking */
99     COST_BURN    =  9, /* dipped into flaming oil */
100     COST_NUTRLZ  = 10, /* neutralized via unicorn horn */
101     COST_DSTROY  = 11, /* wand breaking (bill first, useup later) */
102     COST_SPLAT   = 12, /* cream pie to own face (ditto) */
103     COST_BITE    = 13, /* start eating food */
104     COST_OPEN    = 14, /* open tin */
105     COST_BRKLCK  = 15, /* break box/chest's lock */
106     COST_RUST    = 16, /* rust damage */
107     COST_ROT     = 17, /* rotting attack */
108     COST_CORRODE = 18, /* acid damage */
109     COST_FERMENT = 19  /* fermentation of potion into new potion */
110 };
111 
112 /* bitmask flags for corpse_xname();
113    PFX_THE takes precedence over ARTICLE, NO_PFX takes precedence over both */
114 #define CXN_NORMAL 0    /* no special handling */
115 #define CXN_SINGULAR 1  /* override quantity if greather than 1 */
116 #define CXN_NO_PFX 2    /* suppress "the" from "the Unique Monst */
117 #define CXN_PFX_THE 4   /* prefix with "the " (unless pname) */
118 #define CXN_ARTICLE 8   /* include a/an/the prefix */
119 #define CXN_NOCORPSE 16 /* suppress " corpse" suffix */
120 
121 /* flags for look_here() */
122 #define LOOKHERE_PICKED_SOME   1
123 #define LOOKHERE_SKIP_DFEATURE 2
124 
125 /* getpos() return values */
126 enum getpos_retval {
127     LOOK_TRADITIONAL = 0, /* '.' -- ask about "more info?" */
128     LOOK_QUICK       = 1, /* ',' -- skip "more info?" */
129     LOOK_ONCE        = 2, /* ';' -- skip and stop looping */
130     LOOK_VERBOSE     = 3  /* ':' -- show more info w/o asking */
131 };
132 
133 /*
134  * This is the way the game ends.  If these are rearranged, the arrays
135  * in end.c and topten.c will need to be changed.  Some parts of the
136  * code assume that PANIC separates the deaths from the non-deaths.
137  */
138 enum game_end_types {
139     DIED         =  0,
140     CHOKING      =  1,
141     POISONING    =  2,
142     STARVING     =  3,
143     DROWNING     =  4,
144     BURNING      =  5,
145     DISSOLVED    =  6,
146     CRUSHING     =  7,
147     STONING      =  8,
148     TURNED_SLIME =  9,
149     GENOCIDED    = 10,
150     PANICKED     = 11,
151     TRICKED      = 12,
152     QUIT         = 13,
153     ESCAPED      = 14,
154     ASCENDED     = 15
155 };
156 
157 typedef struct strbuf {
158     int    len;
159     char * str;
160     char   buf[256];
161 } strbuf_t;
162 
163 /* str_or_len from sp_lev.h */
164 typedef union str_or_len {
165     char *str;
166     int len;
167 } Str_or_Len;
168 
169 /* values for rtype are defined in dungeon.h */
170 /* lev_region from sp_lev.h */
171 typedef struct {
172     struct {
173         xchar x1, y1, x2, y2;
174     } inarea;
175     struct {
176         xchar x1, y1, x2, y2;
177     } delarea;
178     boolean in_islev, del_islev;
179     xchar rtype, padding;
180     Str_or_Len rname;
181 } lev_region;
182 
183 
184 #include "align.h"
185 #include "dungeon.h"
186 #include "monsym.h"
187 #include "mkroom.h"
188 #include "objclass.h"
189 #include "youprop.h"
190 #include "wintype.h"
191 #include "context.h"
192 #include "rm.h"
193 #include "botl.h"
194 
195 /* Symbol offsets */
196 #define SYM_OFF_P (0)
197 #define SYM_OFF_O (SYM_OFF_P + MAXPCHARS)   /* MAXPCHARS from rm.h */
198 #define SYM_OFF_M (SYM_OFF_O + MAXOCLASSES) /* MAXOCLASSES from objclass.h */
199 #define SYM_OFF_W (SYM_OFF_M + MAXMCLASSES) /* MAXMCLASSES from monsym.h*/
200 #define SYM_OFF_X (SYM_OFF_W + WARNCOUNT)
201 #define SYM_MAX (SYM_OFF_X + MAXOTHER)
202 
203 /* glyphmod entries */
204 enum { GM_FLAGS, GM_TTYCHAR, GM_COLOR, NUM_GLYPHMOD };
205 
206 #include "rect.h"
207 #include "region.h"
208 #include "decl.h"
209 #include "timeout.h"
210 
211 /* types of calls to bhit() */
212 enum bhit_call_types {
213     ZAPPED_WAND   = 0,
214     THROWN_WEAPON = 1,
215     THROWN_TETHERED_WEAPON = 2,
216     KICKED_WEAPON = 3,
217     FLASHED_LIGHT = 4,
218     INVIS_BEAM    = 5
219 };
220 
221 /* attack mode for hmon() */
222 enum hmon_atkmode_types {
223     HMON_MELEE   = 0, /* hand-to-hand */
224     HMON_THROWN  = 1, /* normal ranged (or spitting while poly'd) */
225     HMON_KICKED  = 2, /* alternate ranged */
226     HMON_APPLIED = 3, /* polearm, treated as ranged */
227     HMON_DRAGGED = 4  /* attached iron ball, pulled into mon */
228 };
229 
230 enum saveformats {
231     invalid = 0,
232     historical = 1,     /* entire struct, binary, as-is */
233     lendian = 2,        /* each field, binary, little-endian */
234     ascii = 3           /* each field, ascii text (just proof of concept) */
235 };
236 
237 /* sortloot() return type; needed before extern.h */
238 struct sortloot_item {
239     struct obj *obj;
240     char *str; /* result of loot_xname(obj) in some cases, otherwise null */
241     int indx; /* signed int, because sortloot()'s qsort comparison routine
242                  assumes (a->indx - b->indx) might yield a negative result */
243     xchar orderclass; /* order rather than object class; 0 => not yet init'd */
244     xchar subclass; /* subclass for some classes */
245     xchar disco; /* discovery status */
246 };
247 typedef struct sortloot_item Loot;
248 
249 #define MATCH_WARN_OF_MON(mon)                                               \
250     (Warn_of_mon                                                             \
251      && ((g.context.warntype.obj & (mon)->data->mflags2) != 0                \
252          || (g.context.warntype.obj_mlet                                     \
253              == (unsigned int) (mon)->data->mlet)                            \
254          || (g.context.warntype.polyd & (mon)->data->mflags2) != 0           \
255          || (g.context.warntype.species                                      \
256              && (g.context.warntype.species == (mon)->data))))
257 
258 #include "trap.h"
259 #include "flag.h"
260 #include "vision.h"
261 #include "display.h"
262 #include "engrave.h"
263 
264 #include "extern.h"
265 #include "winprocs.h"
266 #include "sys.h"
267 
268 /* flags to control makemon(); goodpos() uses some plus has some of its own*/
269 #define NO_MM_FLAGS 0x000000L /* use this rather than plain 0 */
270 #define NO_MINVENT  0x000001L /* suppress minvent when creating mon */
271 #define MM_NOWAIT   0x000002L /* don't set STRAT_WAITMASK flags */
272 #define MM_NOCOUNTBIRTH 0x0004L /* don't increment born count (for revival) */
273 #define MM_IGNOREWATER  0x0008L /* ignore water when positioning */
274 #define MM_ADJACENTOK   0x0010L /* acceptable to use adjacent coordinates */
275 #define MM_ANGRY    0x000020L /* monster is created angry */
276 #define MM_NONAME   0x000040L /* monster is not christened */
277 #define MM_EGD      0x000100L /* add egd structure */
278 #define MM_EPRI     0x000200L /* add epri structure */
279 #define MM_ESHK     0x000400L /* add eshk structure */
280 #define MM_EMIN     0x000800L /* add emin structure */
281 #define MM_EDOG     0x001000L /* add edog structure */
282 #define MM_ASLEEP   0x002000L /* monsters should be generated asleep */
283 #define MM_NOGRP    0x004000L /* suppress creation of monster groups */
284 #define MM_NOTAIL   0x008000L /* if a long worm, don't give it a tail */
285 #define MM_MALE     0x010000L /* male variation */
286 #define MM_FEMALE   0x020000L /* female variation */
287 /* if more MM_ flag masks are added, skip or renumber the GP_ one(s) */
288 #define GP_ALLOW_XY 0x040000L /* [actually used by enexto() to decide whether
289                                * to make an extra call to goodpos()]        */
290 #define GP_ALLOW_U  0x080000L /* don't reject hero's location */
291 
292 /* flags for make_corpse() and mkcorpstat() */
293 #define CORPSTAT_NONE 0x00
294 #define CORPSTAT_INIT 0x01   /* pass init flag to mkcorpstat */
295 #define CORPSTAT_BURIED 0x02 /* bury the corpse or statue */
296 #define CORPSTAT_ZOMBIE 0x04 /* mark corpse as zombie-revivable */
297 
298 /* flags for decide_to_shift() */
299 #define SHIFT_SEENMSG 0x01 /* put out a message if in sight */
300 #define SHIFT_MSG 0x02     /* always put out a message */
301 
302 /* m_poisongas_ok() return values */
303 #define M_POISONGAS_BAD   0 /* poison gas is bad */
304 #define M_POISONGAS_MINOR 1 /* poison gas is ok, maybe causes coughing */
305 #define M_POISONGAS_OK    2 /* ignores poison gas completely */
306 
307 /* flags for deliver_obj_to_mon */
308 #define DF_NONE     0x00
309 #define DF_RANDOM   0x01
310 #define DF_ALL      0x04
311 
312 /* special mhpmax value when loading bones monster to flag as extinct or
313  * genocided */
314 #define DEFUNCT_MONSTER (-100)
315 
316 /* macro form of adjustments of physical damage based on Half_physical_damage.
317  * Can be used on-the-fly with the 1st parameter to losehp() if you don't
318  * need to retain the dmg value beyond that call scope.
319  * Take care to ensure it doesn't get used more than once in other instances.
320  */
321 #define Maybe_Half_Phys(dmg) \
322     ((Half_physical_damage) ? (((dmg) + 1) / 2) : (dmg))
323 
324 /* flags for special ggetobj status returns */
325 #define ALL_FINISHED 0x01 /* called routine already finished the job */
326 
327 /* flags to control query_objlist() */
328 #define BY_NEXTHERE       0x0001 /* follow objlist by nexthere field */
329 #define INCLUDE_VENOM     0x0002 /* include venom objects if present */
330 #define AUTOSELECT_SINGLE 0x0004 /* if only 1 object, don't ask */
331 #define USE_INVLET        0x0008 /* use object's invlet */
332 #define INVORDER_SORT     0x0010 /* sort objects by packorder */
333 #define SIGNAL_NOMENU     0x0020 /* return -1 rather than 0 if none allowed */
334 #define SIGNAL_ESCAPE     0x0040 /* return -2 rather than 0 for ESC */
335 #define FEEL_COCKATRICE   0x0080 /* engage cockatrice checks and react */
336 #define INCLUDE_HERO      0x0100 /* show hero among engulfer's inventory */
337 #define HIDE_DISCOURAGED  0x0200 /* only show objects where allow() returns 2 */
338 #define INCLUDE_FEATURE   0x0400 /* include dungeon features */
339 
340 /* Flags to control query_category() */
341 /* BY_NEXTHERE and INCLUDE_VENOM are used by query_category() too, so
342    skip 0x0001 and 0x0002 */
343 #define UNPAID_TYPES      0x0004
344 #define GOLD_TYPES        0x0008
345 #define WORN_TYPES        0x0010
346 #define ALL_TYPES         0x0020
347 #define BILLED_TYPES      0x0040
348 #define CHOOSE_ALL        0x0080
349 #define BUC_BLESSED       0x0100
350 #define BUC_CURSED        0x0200
351 #define BUC_UNCURSED      0x0400
352 #define BUC_UNKNOWN       0x0800
353 #define BUC_ALLBKNOWN (BUC_BLESSED | BUC_CURSED | BUC_UNCURSED)
354 #define BUCX_TYPES (BUC_ALLBKNOWN | BUC_UNKNOWN)
355 #define ALL_TYPES_SELECTED -2
356 
357 /* Flags to control find_mid() */
358 #define FM_FMON 0x01    /* search the fmon chain */
359 #define FM_MIGRATE 0x02 /* search the migrating monster chain */
360 #define FM_MYDOGS 0x04  /* search g.mydogs */
361 #define FM_EVERYWHERE (FM_FMON | FM_MIGRATE | FM_MYDOGS)
362 
363 /* Flags to control pick_[race,role,gend,align] routines in role.c */
364 #define PICK_RANDOM 0
365 #define PICK_RIGID 1
366 
367 /* Flags to control dotrap() in trap.c */
368 #define FORCETRAP 0x01     /* triggering not left to chance */
369 #define NOWEBMSG 0x02      /* suppress stumble into web message */
370 #define FORCEBUNGLE 0x04   /* adjustments appropriate for bungling */
371 #define RECURSIVETRAP 0x08 /* trap changed into another type this same turn */
372 #define TOOKPLUNGE 0x10    /* used '>' to enter pit below you */
373 #define VIASITTING 0x20    /* #sit while at trap location (affects message) */
374 #define FAILEDUNTRAP 0x40  /* trap activated by failed untrap attempt */
375 
376 /* Flags to control test_move in hack.c */
377 #define DO_MOVE 0   /* really doing the move */
378 #define TEST_MOVE 1 /* test a normal move (move there next) */
379 #define TEST_TRAV 2 /* test a future travel location */
380 #define TEST_TRAP 3 /* check if a future travel loc is a trap */
381 
382 /*** some utility macros ***/
383 #define yn(query) yn_function(query, ynchars, 'n')
384 #define ynq(query) yn_function(query, ynqchars, 'q')
385 #define ynaq(query) yn_function(query, ynaqchars, 'y')
386 #define nyaq(query) yn_function(query, ynaqchars, 'n')
387 #define nyNaq(query) yn_function(query, ynNaqchars, 'n')
388 #define ynNaq(query) yn_function(query, ynNaqchars, 'y')
389 
390 /* Macros for scatter */
391 #define VIS_EFFECTS 0x01 /* display visual effects */
392 #define MAY_HITMON 0x02  /* objects may hit monsters */
393 #define MAY_HITYOU 0x04  /* objects may hit you */
394 #define MAY_HIT (MAY_HITMON | MAY_HITYOU)
395 #define MAY_DESTROY 0x08  /* objects may be destroyed at random */
396 #define MAY_FRACTURE 0x10 /* boulders & statues may fracture */
397 
398 /* Macros for launching objects */
399 #define ROLL 0x01          /* the object is rolling */
400 #define FLING 0x02         /* the object is flying thru the air */
401 #define LAUNCH_UNSEEN 0x40 /* hero neither caused nor saw it */
402 #define LAUNCH_KNOWN 0x80  /* the hero caused this by explicit action */
403 
404 /* enlightenment control flags */
405 #define BASICENLIGHTENMENT 1 /* show mundane stuff */
406 #define MAGICENLIGHTENMENT 2 /* show intrinsics and such */
407 #define ENL_GAMEINPROGRESS 0
408 #define ENL_GAMEOVERALIVE  1 /* ascension, escape, quit, trickery */
409 #define ENL_GAMEOVERDEAD   2
410 
411 /* control flags for sortloot() */
412 #define SORTLOOT_PACK   0x01
413 #define SORTLOOT_INVLET 0x02
414 #define SORTLOOT_LOOT   0x04
415 #define SORTLOOT_PETRIFY 0x20 /* override filter func for c-trice corpses */
416 
417 /* flags for xkilled() [note: meaning of first bit used to be reversed,
418    1 to give message and 0 to suppress] */
419 #define XKILL_GIVEMSG   0
420 #define XKILL_NOMSG     1
421 #define XKILL_NOCORPSE  2
422 #define XKILL_NOCONDUCT 4
423 
424 /* pline_flags; mask values for custompline()'s first argument */
425 /* #define PLINE_ORDINARY 0 */
426 #define PLINE_NOREPEAT   1
427 #define OVERRIDE_MSGTYPE 2
428 #define SUPPRESS_HISTORY 4
429 #define URGENT_MESSAGE   8
430 
431 /* Macros for messages referring to hands, eyes, feet, etc... */
432 enum bodypart_types {
433     NO_PART   =  0,
434     ARM       =  1,
435     EYE       =  2,
436     FACE      =  3,
437     FINGER    =  4,
438     FINGERTIP =  5,
439     FOOT      =  6,
440     HAND      =  7,
441     HANDED    =  8,
442     HEAD      =  9,
443     LEG       = 10,
444     LIGHT_HEADED = 11,
445     NECK      = 12,
446     SPINE     = 13,
447     TOE       = 14,
448     HAIR      = 15,
449     BLOOD     = 16,
450     LUNG      = 17,
451     NOSE      = 18,
452     STOMACH   = 19,
453     TORSO     = 20
454 };
455 
456 /* indices for some special tin types */
457 #define ROTTEN_TIN 0
458 #define HOMEMADE_TIN 1
459 #define SPINACH_TIN (-1)
460 #define RANDOM_TIN (-2)
461 #define HEALTHY_TIN (-3)
462 
463 /* Corpse aging */
464 #define TAINT_AGE (50L)          /* age when corpses go bad */
465 #define TROLL_REVIVE_CHANCE 37   /* 1/37 chance for 50 turns ~ 75% chance */
466 #define ZOMBIE_REVIVE_CHANCE 275 /* 1/275 chance for 250 turns ~ 60% chance */
467 #define MOLDY_CHANCE 3900        /* 1/3900 chance for 200 turns ~ 5% chance */
468 #define ROT_AGE (250L)           /* age when corpses rot away */
469 
470 /* Some misc definitions */
471 #define POTION_OCCUPANT_CHANCE(n) (13 + 2 * (n))
472 #define WAND_BACKFIRE_CHANCE 100
473 #define BALL_IN_MON (u.uswallow && uball && uball->where == OBJ_FREE)
474 #define CHAIN_IN_MON (u.uswallow && uchain && uchain->where == OBJ_FREE)
475 #define NODIAG(monnum) ((monnum) == PM_GRID_BUG)
476 
477 /* Flags to control menus */
478 #define MENUTYPELEN sizeof("traditional ")
479 #define MENU_TRADITIONAL 0
480 #define MENU_COMBINATION 1
481 #define MENU_FULL 2
482 #define MENU_PARTIAL 3
483 
484 /* flags to control teleds() */
485 #define TELEDS_NO_FLAGS   0x0
486 #define TELEDS_ALLOW_DRAG 0x1
487 #define TELEDS_TELEPORT   0x2
488 
489 /* Flags to control polymon() message printing */
490 #define POLYMON_NO_MSGS       0x00
491 #define POLYMON_TRANSFORM_MSG 0x01 /* "You become a [monster]!" etc. */
492 #define POLYMON_STATUS_MSG    0x02 /* "You no longer feel sick." etc. */
493 #define POLYMON_GEAR_MSG      0x04 /* "Your cloak tears apart!" etc. */
494 #define POLYMON_INFO_MSG      0x08 /* "Use #monster to do..." */
495 #define POLYMON_ENCUMBER_MSG  0x10 /* whether to call encumber_msg() */
496 #define POLYMON_ALL_MSGS      0x1F
497 
498 /* Flags used in the return from artifact_hit()
499  * note that anywhere that returns INSTAKILLMSG should probably also return
500  * GAVEMSG since INSTAKILLMSG implies a message was given.
501  * message is by definition a specially printed message. */
502 #define ARTIFACTHIT_NOMSG        0x0
503 #define ARTIFACTHIT_GAVEMSG      0x1 /* printed any special message at all,
504                                         incl. things like "miss wildly" */
505 #define ARTIFACTHIT_INSTAKILLMSG 0x2 /* "Vorpal Blade decapitates foo!" &c */
506 
507 /* Return values from current_holidays(). */
508 #define HOLIDAY_NEW_YEARS      0x00001
509 #define HOLIDAY_VALENTINES_DAY 0x00002
510 #define HOLIDAY_PI_DAY         0x00004
511 #define HOLIDAY_APRIL_FOOLS    0x00008
512 #define HOLIDAY_EASTER         0x00010
513 #define HOLIDAY_CANADA_DAY     0x00020
514 #define HOLIDAY_HALLOWEEN      0x00040
515 #define HOLIDAY_THANKSGIVING   0x00080
516 #define HOLIDAY_RAMADAN        0x00100
517 #define HOLIDAY_EID_AL_FITR    0x00200
518 #define HOLIDAY_ROSH_HASHANAH  0x00400
519 #define HOLIDAY_YOM_KIPPUR     0x00800
520 #define HOLIDAY_PASSOVER       0x01000
521 #define HOLIDAY_HANUKKAH       0x02000
522 #define HOLIDAY_CHRISTMAS      0x04000
523 #define HOLIDAY_LOS_MUERTOS    0x08000
524 #define HOLIDAY_MARDI_GRAS     0x10000
525 
526 /* constant passed to explode() for gas spores because gas spores are weird
527  * Specifically, this is an exception to the whole "explode() uses dobuzz types"
528  * system (the range -1 to -9 isn't used by it, for some reason), where this is
529  * effectively an extra dobuzz type, and some zap.c code needs to be aware of
530  * it.  */
531 #define PHYS_EXPL_TYPE -1
532 
533 /* message flags for dump_container() */
534 #define DUMPCONT_NORMAL 0x0
535 #define DUMPCONT_QUIET  0x1 /* suppress most messages */
536 #define DUMPCONT_BYPOLY 0x2 /* "Objects spill out as [cont] polymorphs" */
537 
538 /* psuedo types for intrinsics gained by eating corpses that aren't actually
539  * intrinsics listed in prop.h; these should be nonzero so that zero can
540  * represent "no intrinsic given" */
541 enum psuedo_intrinsics {
542     INTRINSIC_GAIN_STR = -1, /* strength from e.g. giants */
543     INTRINSIC_GAIN_EN  = -2, /* current/max energy from e.g. newts */
544     FIRST_FAKE_PROP    = -2, /* for ++ iteration */
545 };
546 
547 /* to-hit penalty for wearing body armor as a Monk; used to be a 'spelarmr'
548  * stat in the role struct but it wasn't used for any other roles and probably
549  * was never going to be, so it's now a constant. */
550 #define CUMBERSOME_ARMOR_PENALTY 20
551 
552 enum do_stinking_cloud_returns {
553     SCLOUD_CANCELED = 0,
554     SCLOUD_INVALID  = 1,
555     SCLOUD_CREATED  = 2
556 };
557 
558 /* values for g.zombify; 0 is assumed to be "off" and not in zombify mode */
559 enum zombify_values {
560     ZOMBIFY_HOSTILE = 1, /* zombie will revive hostile */
561     ZOMBIFY_TAME    = 2, /* zombie will revive tame */
562 };
563 
564 /* values for 'msgflag' input to adjattrib() and its return value */
565 enum adjattrib_msgflag {
566     AA_CONDMSG = -1, /* print msg conditionally (only if there is a change) */
567     AA_YESMSG  =  0, /* always print msg */
568     AA_NOMSG   =  1  /* never print msg */
569 };
570 enum adjattrib_return {
571     AA_NOCHNG   = 0, /* nothing at all changed */
572     AA_BASECHNG = 1, /* base value changed but current didn't (e.g. gained
573                         strength wearing gauntlets of power) */
574     AA_CURRCHNG = 2  /* current value changed */
575 };
576 
577 /* flags for mktrap() */
578 #define MKTRAP_NOFLAGS       0x0
579 #define MKTRAP_MAZEFLAG      0x1
580 #define MKTRAP_NOSPIDERONWEB 0x2
581 
582 #define MON_POLE_DIST 5 /* How far monsters can use pole-weapons */
583 #define PET_MISSILE_RANGE2 36 /* Square of distance within which pets shoot */
584 
585 /* flags passed to getobj() to control how it responds to player input */
586 #define GETOBJ_NOFLAGS  0x0
587 #define GETOBJ_ALLOWCNT 0x1 /* is a count allowed with this command? */
588 #define GETOBJ_PROMPT   0x2 /* should it force a prompt for input? (prevents it
589                                exiting early with "You don't have anything to
590                                foo" if nothing in inventory is valid) */
591 
592 /* values returned from getobj() callback functions */
593 enum getobj_callback_returns {
594     /* generally invalid - can't be used for this purpose. will give a "silly
595      * thing" message if the player tries to pick it, unless a more specific
596      * failure message is in getobj itself - e.g. "You cannot foo gold". */
597     GETOBJ_EXCLUDE = -2,
598     /* invalid because it is an inaccessible or unwanted piece of gear, but
599      * psuedo-valid for the purposes of allowing the player to select it and
600      * getobj to return it if there is a prompt instead of getting "silly
601      * thing", in order for the getobj caller to present a specific failure
602      * message. Other than that, the only thing this does differently from
603      * GETOBJ_EXCLUDE is that it inserts an "else" in "You don't have anything
604      * else to foo". */
605     GETOBJ_EXCLUDE_INACCESS = -1,
606     /* invalid for purposes of not showing a prompt if nothing is valid but
607      * psuedo-valid for selecting - identical to GETOBJ_EXCLUDE_INACCESS but
608      * without the "else" in "You don't have anything else to foo". */
609     GETOBJ_EXCLUDE_SELECTABLE = 0,
610     /* valid - invlet not presented in the summary or the ? menu as a
611      * recommendation, but is selectable if the player enters it anyway.
612      * Used for objects that are actually valid but unimportantly so, such
613      * as shirts for reading. */
614     GETOBJ_DOWNPLAY = 1,
615     /* valid - will be shown in summary and ? menu */
616     GETOBJ_SUGGEST  = 2,
617 };
618 
619 /*
620  * option setting restrictions
621  */
622 
623 enum optset_restrictions {
624     set_in_sysconf = 0, /* system config file option only */
625     set_in_config  = 1, /* config file option only */
626     set_viaprog    = 2, /* may be set via extern program, not seen in game */
627     set_gameview   = 3, /* may be set via extern program, displayed in game */
628     set_in_game    = 4, /* may be set via extern program or set in the game */
629     set_wizonly    = 5, /* may be set set in the game if wizmode */
630     set_hidden     = 6  /* placeholder for prefixed entries, never show it  */
631 };
632 #define SET__IS_VALUE_VALID(s) ((s < set_in_sysconf) || (s > set_wizonly))
633 
634 #define FEATURE_NOTICE_VER(major, minor, patch)                    \
635     (((unsigned long) major << 24) | ((unsigned long) minor << 16) \
636      | ((unsigned long) patch << 8) | ((unsigned long) 0))
637 
638 #define FEATURE_NOTICE_VER_MAJ (flags.suppress_alert >> 24)
639 #define FEATURE_NOTICE_VER_MIN \
640     (((unsigned long) (0x0000000000FF0000L & flags.suppress_alert)) >> 16)
641 #define FEATURE_NOTICE_VER_PATCH \
642     (((unsigned long) (0x000000000000FF00L & flags.suppress_alert)) >> 8)
643 
644 #ifndef max
645 #define max(a, b) ((a) > (b) ? (a) : (b))
646 #endif
647 #ifndef min
648 #define min(x, y) ((x) < (y) ? (x) : (y))
649 #endif
650 #define plur(x) (((x) == 1) ? "" : "s")
651 
652 #define makeknown(x) discover_object((x), TRUE, TRUE)
653 #define distu(xx, yy) dist2((int)(xx), (int)(yy), (int) u.ux, (int) u.uy)
654 #define onlineu(xx, yy) online2((int)(xx), (int)(yy), (int) u.ux, (int) u.uy)
655 
656 #define rn1(x, y) (rn2(x) + (y))
657 
658 /* negative armor class is randomly weakened to prevent invulnerability */
659 #define AC_VALUE(AC) ((AC) >= 0 ? (AC) : -rnd(-(AC)))
660 
661 #if defined(MICRO) && !defined(__DJGPP__)
662 #define getuid() 1
663 #define getlogin() ((char *) 0)
664 #endif /* MICRO */
665 
666 /* The function argument to qsort() requires a particular
667  * calling convention under WINCE which is not the default
668  * in that environment.
669  */
670 #if defined(WIN_CE)
671 #define QSORTCALLBACK __cdecl
672 #else
673 #define QSORTCALLBACK
674 #endif
675 
676 #define DEVTEAM_EMAIL "aosdict@gmail.com"
677 #define DEVTEAM_URL "https://github.com/copperwater/xNetHack"
678 
679 #endif /* HACK_H */
680