1 //
2 //  RogueMain.h
3 //  Brogue
4 //
5 //  Created by Brian Walker on 12/26/08.
6 //  Copyright 2012. All rights reserved.
7 //
8 //  This file is part of Brogue.
9 //
10 //  This program is free software: you can redistribute it and/or modify
11 //  it under the terms of the GNU Affero General Public License as
12 //  published by the Free Software Foundation, either version 3 of the
13 //  License, or (at your option) any later version.
14 //
15 //  This program is distributed in the hope that it will be useful,
16 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 //  GNU Affero General Public License for more details.
19 //
20 //  You should have received a copy of the GNU Affero General Public License
21 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 //
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdint.h>
28 #include <time.h>
29 #include "PlatformDefines.h"
30 
31 #ifndef BROGUE_EXTRA_VERSION
32 #error "The BROGUE_EXTRA_VERSION macro is undefined."
33 #endif
34 
35 // unicode: comment this line to revert to ASCII
36 #define USE_UNICODE
37 
38 // Brogue version number
39 #define BROGUE_MAJOR 1
40 #define BROGUE_MINOR 10
41 #define BROGUE_PATCH 1
42 
43 // Expanding a macro as a string constant requires two levels of macros
44 #define _str(x) #x
45 #define STRINGIFY(x) _str(x)
46 
47 // Brogue version: what the user sees in the menu and title
48 #define BROGUE_VERSION_STRING "CE " STRINGIFY(BROGUE_MAJOR) "." STRINGIFY(BROGUE_MINOR) "." STRINGIFY(BROGUE_PATCH) BROGUE_EXTRA_VERSION
49 
50 // Recording version. Saved into recordings and save files made by this version.
51 // Cannot be longer than 16 chars
52 #define BROGUE_RECORDING_VERSION_STRING "CE " STRINGIFY(BROGUE_MAJOR) "." STRINGIFY(BROGUE_MINOR) "." STRINGIFY(BROGUE_PATCH)
53 
54 /* Patch pattern. A scanf format string which matches an unsigned short. If this
55 matches against a recording version string, it defines a "patch version." During
56 normal play, rogue.patchVersion is set to the match of the game's recording
57 version above, or 0 if it doesn't match.
58 
59 The game will only load a recording/save if either a) it has a patch version
60 which is equal or less than the patch version of the current game
61 (rogue.patchLevel is set to the recording's); or b) it doesn't match the version
62 strings, but they are equal (rogue.patchLevel is set to 0).
63 */
64 #define BROGUE_PATCH_VERSION_PATTERN "CE " STRINGIFY(BROGUE_MAJOR) "." STRINGIFY(BROGUE_MINOR) ".%hu"
65 
66 // Dungeon version. Used in seed catalog output.
67 #define BROGUE_DUNGEON_VERSION_STRING "CE 1.9"
68 
69 // Macro to compare BROGUE_MAJOR.BROGUE_MINOR.patchVersion to a.b.c
70 #define BROGUE_VERSION_ATLEAST(a,b,c) (BROGUE_MAJOR != (a) ? BROGUE_MAJOR > (a) : BROGUE_MINOR != (b) ? BROGUE_MINOR > (b) : rogue.patchVersion >= (c))
71 
72 #define DEBUG                           if (rogue.wizard)
73 #define MONSTERS_ENABLED                (!rogue.wizard || 1) // Quest room monsters can be generated regardless.
74 #define ITEMS_ENABLED                   (!rogue.wizard || 1)
75 
76 #define D_BULLET_TIME                   (rogue.wizard && 0)
77 #define D_WORMHOLING                    (rogue.wizard && 1)
78 #define D_IMMORTAL                      (rogue.wizard && 1)
79 
80 #define D_SAFETY_VISION                 (rogue.wizard && 0)
81 #define D_SCENT_VISION                  (rogue.wizard && 0)
82 #define D_DISABLE_BACKGROUND_COLORS     (rogue.wizard && 0)
83 
84 #define D_INSPECT_LEVELGEN              (rogue.wizard && 0)
85 #define D_INSPECT_MACHINES              (rogue.wizard && 0)
86 
87 #define D_MESSAGE_ITEM_GENERATION       (rogue.wizard && 0)
88 #define D_MESSAGE_MACHINE_GENERATION    (rogue.wizard && 0)
89 
90 // set to false to allow multiple loads from the same saved file:
91 #define DELETE_SAVE_FILE_AFTER_LOADING  true
92 
93 // set to false to disable references to keystrokes (e.g. for a tablet port)
94 #define KEYBOARD_LABELS true
95 
96 //#define BROGUE_ASSERTS        // introduces several assert()s -- useful to find certain array overruns and other bugs
97 //#define AUDIT_RNG             // VERY slow, but sometimes necessary to debug out-of-sync recording errors
98 //#define GENERATE_FONT_FILES   // Displays font in grid upon startup, which can be screen-captured into font files for PC.
99 
100 #ifdef BROGUE_ASSERTS
101 #include <assert.h>
102 #define brogueAssert(x)         assert(x)
103 #else
104 #define brogueAssert(x)
105 #endif
106 
107 #define boolean                 char
108 
109 #define false                   0
110 #define true                    1
111 
112 #define Fl(N)                   ((unsigned long) 1 << (N))
113 
114 typedef long long fixpt;
115 #define FP_BASE 16 // Don't change this without recalculating all of the power tables throughout the code!
116 #define FP_FACTOR (1LL << FP_BASE)
117 #define FP_MUL(x, y)  ((x) * (y) / FP_FACTOR)
118 #define FP_DIV(x, y)  ((x) * FP_FACTOR / (y))
119 
120 // recording and save filenames
121 #define LAST_GAME_PATH          "LastGame.broguesave"
122 #define LAST_GAME_NAME          "LastGame"
123 #define LAST_RECORDING_NAME     "LastRecording"
124 #define RECORDING_SUFFIX        ".broguerec"
125 #define GAME_SUFFIX             ".broguesave"
126 #define ANNOTATION_SUFFIX       ".txt"
127 #define RNG_LOG                 "RNGLog.txt"
128 #define SCREENSHOT_SUFFIX       ".png"
129 
130 #define BROGUE_FILENAME_MAX     (min(1024*4, FILENAME_MAX))
131 
132 // Date format used when listing recordings and high scores
133 #define DATE_FORMAT             "%Y-%m-%d" // see strftime() documentation
134 
135 #define MESSAGE_LINES           3
136 #define MESSAGE_ARCHIVE_VIEW_LINES ROWS
137 #define MESSAGE_ARCHIVE_LINES   (MESSAGE_ARCHIVE_VIEW_LINES*10)
138 #define MESSAGE_ARCHIVE_ENTRIES (MESSAGE_ARCHIVE_LINES*4)
139 #define MAX_MESSAGE_REPEATS     100
140 
141 // Size of the entire terminal window. These need to be hard-coded here and in Viewport.h
142 #define COLS                    100
143 #define ROWS                    (31 + MESSAGE_LINES)
144 
145 // Size of the portion of the terminal window devoted to displaying the dungeon:
146 #define DCOLS                   (COLS - STAT_BAR_WIDTH - 1) // n columns on the left for the sidebar;
147                                                             // one column to separate the sidebar from the map.
148 #define DROWS                   (ROWS - MESSAGE_LINES - 2)  // n lines at the top for messages;
149                                                             // one line at the bottom for flavor text;
150                                                             // another line at the bottom for the menu bar.
151 
152 #define STAT_BAR_WIDTH          20          // number of characters in the stats bar to the left of the map
153 
154 #define LOS_SLOPE_GRANULARITY   32768       // how finely we divide up the squares when calculating slope;
155                                             // higher numbers mean fewer artifacts but more memory and processing
156 #define INTERFACE_OPACITY       95
157 
158 #define LIGHT_SMOOTHING_THRESHOLD 150       // light components higher than this magnitude will be toned down a little
159 
160 #define MAX_BOLT_LENGTH         DCOLS*10
161 
162 #define VISIBILITY_THRESHOLD    50          // how bright cumulative light has to be before the cell is marked visible
163 
164 #define AMULET_LEVEL            26          // how deep before the amulet appears
165 #define DEEPEST_LEVEL           40          // how deep the universe goes
166 
167 #define MACHINES_FACTOR         FP_FACTOR   // use this to adjust machine frequency
168 
169 #define MACHINES_BUFFER_LENGTH  200
170 
171 #define WEAPON_KILLS_TO_AUTO_ID 20
172 #define ARMOR_DELAY_TO_AUTO_ID  1000
173 #define RING_DELAY_TO_AUTO_ID   1500
174 
175 #define FALL_DAMAGE_MIN         8
176 #define FALL_DAMAGE_MAX         10
177 
178 #define INPUT_RECORD_BUFFER     1000        // how many bytes of input data to keep in memory before saving it to disk
179 #define DEFAULT_PLAYBACK_DELAY  50
180 
181 #define HIGH_SCORES_COUNT       30
182 
183 // color escapes
184 #define COLOR_ESCAPE            25
185 #define COLOR_VALUE_INTERCEPT   25
186 
187 // display characters:
188 
189 enum displayGlyph {
190     G_UP_ARROW = 128,
191     G_DOWN_ARROW,
192     G_POTION,
193     G_GRASS,
194     G_WALL,
195     G_DEMON,
196     G_OPEN_DOOR,
197     G_GOLD,
198     G_CLOSED_DOOR,
199     G_RUBBLE,
200     G_KEY,
201     G_BOG,
202     G_CHAIN_TOP_LEFT,
203     G_CHAIN_BOTTOM_RIGHT,
204     G_CHAIN_TOP_RIGHT,
205     G_CHAIN_BOTTOM_LEFT,
206     G_CHAIN_TOP,
207     G_CHAIN_BOTTOM,
208     G_CHAIN_LEFT,
209     G_CHAIN_RIGHT,
210     G_FOOD,
211     G_UP_STAIRS,
212     G_VENT,
213     G_DOWN_STAIRS,
214     G_PLAYER,
215     G_BOG_MONSTER,
216     G_CENTAUR,
217     G_DRAGON,
218     G_FLAMEDANCER,
219     G_GOLEM,
220     G_TENTACLE_HORROR,
221     G_IFRIT,
222     G_JELLY,
223     G_KRAKEN,
224     G_LICH,
225     G_NAGA,
226     G_OGRE,
227     G_PHANTOM,
228     G_REVENANT,
229     G_SALAMANDER,
230     G_TROLL,
231     G_UNDERWORM,
232     G_VAMPIRE,
233     G_WRAITH,
234     G_ZOMBIE,
235     G_ARMOR,
236     G_STAFF,
237     G_WEB,
238     G_MOUND,
239     G_BLOAT,
240     G_CENTIPEDE,
241     G_DAR_BLADEMASTER,
242     G_EEL,
243     G_FURY,
244     G_GOBLIN,
245     G_IMP,
246     G_JACKAL,
247     G_KOBOLD,
248     G_MONKEY,
249     G_PIXIE,
250     G_RAT,
251     G_SPIDER,
252     G_TOAD,
253     G_BAT,
254     G_WISP,
255     G_PHOENIX,
256     G_ALTAR,
257     G_LIQUID,
258     G_FLOOR,
259     G_CHASM,
260     G_TRAP,
261     G_FIRE,
262     G_FOLIAGE,
263     G_AMULET,
264     G_SCROLL,
265     G_RING,
266     G_WEAPON,
267     G_TURRET,
268     G_TOTEM,
269     G_GOOD_MAGIC,
270     G_BAD_MAGIC,
271     G_DOORWAY,
272     G_CHARM,
273     G_WALL_TOP,
274     G_DAR_PRIESTESS,
275     G_DAR_BATTLEMAGE,
276     G_GOBLIN_MAGIC,
277     G_GOBLIN_CHIEFTAN,
278     G_OGRE_MAGIC,
279     G_GUARDIAN,
280     G_WINGED_GUARDIAN,
281     G_EGG,
282     G_WARDEN,
283     G_DEWAR,
284     G_ANCIENT_SPIRIT,
285     G_LEVER,
286     G_LEVER_PULLED,
287     G_BLOODWORT_STALK,
288     G_FLOOR_ALT,
289     G_UNICORN,
290     G_GEM,
291     G_WAND,
292     G_GRANITE,
293     G_CARPET,
294     G_CLOSED_IRON_DOOR,
295     G_OPEN_IRON_DOOR,
296     G_TORCH,
297     G_CRYSTAL,
298     G_PORTCULLIS,
299     G_BARRICADE,
300     G_STATUE,
301     G_CRACKED_STATUE,
302     G_CLOSED_CAGE,
303     G_OPEN_CAGE,
304     G_PEDESTAL,
305     G_CLOSED_COFFIN,
306     G_OPEN_COFFIN,
307     G_MAGIC_GLYPH,
308     G_BRIDGE,
309     G_BONES,
310     G_ELECTRIC_CRYSTAL,
311     G_ASHES,
312     G_BEDROLL,
313     G_BLOODWORT_POD,
314     G_VINE,
315     G_NET,
316     G_LICHEN,
317     G_PIPES,
318     G_SAC_ALTAR,
319     G_ORB_ALTAR
320 };
321 
322 enum graphicsModes {
323     TEXT_GRAPHICS,
324     TILES_GRAPHICS,
325     HYBRID_GRAPHICS, // text for items and creatures, tiles for environment
326 };
327 
328 enum eventTypes {
329     KEYSTROKE,
330     MOUSE_UP,
331     MOUSE_DOWN,
332     RIGHT_MOUSE_DOWN,
333     RIGHT_MOUSE_UP,
334     MOUSE_ENTERED_CELL,
335     RNG_CHECK,
336     SAVED_GAME_LOADED,
337     END_OF_RECORDING,
338     EVENT_ERROR,
339     NUMBER_OF_EVENT_TYPES, // unused
340 };
341 
342 enum notificationEventTypes {
343 	GAMEOVER_QUIT,
344 	GAMEOVER_DEATH,
345 	GAMEOVER_VICTORY,
346 	GAMEOVER_SUPERVICTORY,
347 	GAMEOVER_RECORDING
348 };
349 
350 typedef struct rogueEvent {
351     enum eventTypes eventType;
352     signed long param1;
353     signed long param2;
354     boolean controlKey;
355     boolean shiftKey;
356 } rogueEvent;
357 
358 typedef struct rogueHighScoresEntry {
359     signed long score;
360     char date[100];
361     char description[DCOLS];
362 } rogueHighScoresEntry;
363 
364 typedef struct fileEntry {
365     char *path;
366     struct tm date;
367 } fileEntry;
368 
369 enum RNGs {
370     RNG_SUBSTANTIVE,
371     RNG_COSMETIC,
372     NUMBER_OF_RNGS,
373 };
374 
375 enum displayDetailValues {
376     DV_UNLIT = 0,
377     DV_LIT,
378     DV_DARK,
379 };
380 
381 enum directions {
382     NO_DIRECTION    = -1,
383     // Cardinal directions; must be 0-3:
384     UP              = 0,
385     DOWN            = 1,
386     LEFT            = 2,
387     RIGHT           = 3,
388     // Secondary directions; must be 4-7:
389     UPLEFT          = 4,
390     DOWNLEFT        = 5,
391     UPRIGHT         = 6,
392     DOWNRIGHT       = 7,
393 
394     DIRECTION_COUNT = 8,
395 };
396 
397 enum textEntryTypes {
398     TEXT_INPUT_NORMAL = 0,
399     TEXT_INPUT_FILENAME,
400     TEXT_INPUT_NUMBERS,
401     TEXT_INPUT_TYPES,
402 };
403 
404 #define NUMBER_DYNAMIC_COLORS   6
405 
406 enum tileType {
407     NOTHING = 0,
408     GRANITE,
409     FLOOR,
410     FLOOR_FLOODABLE,
411     CARPET,
412     MARBLE_FLOOR,
413     WALL,
414     DOOR,
415     OPEN_DOOR,
416     SECRET_DOOR,
417     LOCKED_DOOR,
418     OPEN_IRON_DOOR_INERT,
419     DOWN_STAIRS,
420     UP_STAIRS,
421     DUNGEON_EXIT,
422     DUNGEON_PORTAL,
423     TORCH_WALL, // wall lit with a torch
424     CRYSTAL_WALL,
425     PORTCULLIS_CLOSED,
426     PORTCULLIS_DORMANT,
427     WOODEN_BARRICADE,
428     PILOT_LIGHT_DORMANT,
429     PILOT_LIGHT,
430     HAUNTED_TORCH_DORMANT,
431     HAUNTED_TORCH_TRANSITIONING,
432     HAUNTED_TORCH,
433     WALL_LEVER_HIDDEN,
434     WALL_LEVER,
435     WALL_LEVER_PULLED,
436     WALL_LEVER_HIDDEN_DORMANT,
437     STATUE_INERT,
438     STATUE_DORMANT,
439     STATUE_CRACKING,
440     STATUE_INSTACRACK,
441     PORTAL,
442     TURRET_DORMANT,
443     WALL_MONSTER_DORMANT,
444     DARK_FLOOR_DORMANT,
445     DARK_FLOOR_DARKENING,
446     DARK_FLOOR,
447     MACHINE_TRIGGER_FLOOR,
448     ALTAR_INERT,
449     ALTAR_KEYHOLE,
450     ALTAR_CAGE_OPEN,
451     ALTAR_CAGE_CLOSED,
452     ALTAR_SWITCH,
453     ALTAR_SWITCH_RETRACTING,
454     ALTAR_CAGE_RETRACTABLE,
455     PEDESTAL,
456     MONSTER_CAGE_OPEN,
457     MONSTER_CAGE_CLOSED,
458     COFFIN_CLOSED,
459     COFFIN_OPEN,
460 
461     GAS_TRAP_POISON_HIDDEN,
462     GAS_TRAP_POISON,
463     TRAP_DOOR_HIDDEN,
464     TRAP_DOOR,
465     GAS_TRAP_PARALYSIS_HIDDEN,
466     GAS_TRAP_PARALYSIS,
467     MACHINE_PARALYSIS_VENT_HIDDEN,
468     MACHINE_PARALYSIS_VENT,
469     GAS_TRAP_CONFUSION_HIDDEN,
470     GAS_TRAP_CONFUSION,
471     FLAMETHROWER_HIDDEN,
472     FLAMETHROWER,
473     FLOOD_TRAP_HIDDEN,
474     FLOOD_TRAP,
475     NET_TRAP_HIDDEN,
476     NET_TRAP,
477     ALARM_TRAP_HIDDEN,
478     ALARM_TRAP,
479     MACHINE_POISON_GAS_VENT_HIDDEN,
480     MACHINE_POISON_GAS_VENT_DORMANT,
481     MACHINE_POISON_GAS_VENT,
482     MACHINE_METHANE_VENT_HIDDEN,
483     MACHINE_METHANE_VENT_DORMANT,
484     MACHINE_METHANE_VENT,
485     STEAM_VENT,
486     MACHINE_PRESSURE_PLATE,
487     MACHINE_PRESSURE_PLATE_USED,
488     MACHINE_GLYPH,
489     MACHINE_GLYPH_INACTIVE,
490     DEWAR_CAUSTIC_GAS,
491     DEWAR_CONFUSION_GAS,
492     DEWAR_PARALYSIS_GAS,
493     DEWAR_METHANE_GAS,
494 
495     DEEP_WATER,
496     SHALLOW_WATER,
497     MUD,
498     CHASM,
499     CHASM_EDGE,
500     MACHINE_COLLAPSE_EDGE_DORMANT,
501     MACHINE_COLLAPSE_EDGE_SPREADING,
502     LAVA,
503     LAVA_RETRACTABLE,
504     LAVA_RETRACTING,
505     SUNLIGHT_POOL,
506     DARKNESS_PATCH,
507     ACTIVE_BRIMSTONE,
508     INERT_BRIMSTONE,
509     OBSIDIAN,
510     BRIDGE,
511     BRIDGE_FALLING,
512     BRIDGE_EDGE,
513     STONE_BRIDGE,
514     MACHINE_FLOOD_WATER_DORMANT,
515     MACHINE_FLOOD_WATER_SPREADING,
516     MACHINE_MUD_DORMANT,
517     ICE_DEEP,
518     ICE_DEEP_MELT,
519     ICE_SHALLOW,
520     ICE_SHALLOW_MELT,
521 
522     HOLE,
523     HOLE_GLOW,
524     HOLE_EDGE,
525     FLOOD_WATER_DEEP,
526     FLOOD_WATER_SHALLOW,
527     GRASS,
528     DEAD_GRASS,
529     GRAY_FUNGUS,
530     LUMINESCENT_FUNGUS,
531     LICHEN,
532     HAY,
533     RED_BLOOD,
534     GREEN_BLOOD,
535     PURPLE_BLOOD,
536     ACID_SPLATTER,
537     VOMIT,
538     URINE,
539     UNICORN_POOP,
540     WORM_BLOOD,
541     ASH,
542     BURNED_CARPET,
543     PUDDLE,
544     BONES,
545     RUBBLE,
546     JUNK,
547     BROKEN_GLASS,
548     ECTOPLASM,
549     EMBERS,
550     SPIDERWEB,
551     NETTING,
552     FOLIAGE,
553     DEAD_FOLIAGE,
554     TRAMPLED_FOLIAGE,
555     FUNGUS_FOREST,
556     TRAMPLED_FUNGUS_FOREST,
557     FORCEFIELD,
558     FORCEFIELD_MELT,
559     SACRED_GLYPH,
560     MANACLE_TL,
561     MANACLE_BR,
562     MANACLE_TR,
563     MANACLE_BL,
564     MANACLE_T,
565     MANACLE_B,
566     MANACLE_L,
567     MANACLE_R,
568     PORTAL_LIGHT,
569     GUARDIAN_GLOW,
570 
571     PLAIN_FIRE,
572     BRIMSTONE_FIRE,
573     FLAMEDANCER_FIRE,
574     GAS_FIRE,
575     GAS_EXPLOSION,
576     DART_EXPLOSION,
577     ITEM_FIRE,
578     CREATURE_FIRE,
579 
580     POISON_GAS,
581     CONFUSION_GAS,
582     ROT_GAS,
583     STENCH_SMOKE_GAS,
584     PARALYSIS_GAS,
585     METHANE_GAS,
586     STEAM,
587     DARKNESS_CLOUD,
588     HEALING_CLOUD,
589 
590     BLOODFLOWER_STALK,
591     BLOODFLOWER_POD,
592 
593     HAVEN_BEDROLL,
594 
595     DEEP_WATER_ALGAE_WELL,
596     DEEP_WATER_ALGAE_1,
597     DEEP_WATER_ALGAE_2,
598 
599     ANCIENT_SPIRIT_VINES,
600     ANCIENT_SPIRIT_GRASS,
601 
602     AMULET_SWITCH,
603 
604     COMMUTATION_ALTAR,
605     COMMUTATION_ALTAR_INERT,
606     PIPE_GLOWING,
607     PIPE_INERT,
608 
609     RESURRECTION_ALTAR,
610     RESURRECTION_ALTAR_INERT,
611     MACHINE_TRIGGER_FLOOR_REPEATING,
612 
613     SACRIFICE_ALTAR_DORMANT,
614     SACRIFICE_ALTAR,
615     SACRIFICE_LAVA,
616     SACRIFICE_CAGE_DORMANT,
617     DEMONIC_STATUE,
618 
619     STATUE_INERT_DOORWAY,
620     STATUE_DORMANT_DOORWAY,
621 
622     CHASM_WITH_HIDDEN_BRIDGE,
623     CHASM_WITH_HIDDEN_BRIDGE_ACTIVE,
624     MACHINE_CHASM_EDGE,
625 
626     RAT_TRAP_WALL_DORMANT,
627     RAT_TRAP_WALL_CRACKING,
628 
629     ELECTRIC_CRYSTAL_OFF,
630     ELECTRIC_CRYSTAL_ON,
631     TURRET_LEVER,
632 
633     WORM_TUNNEL_MARKER_DORMANT,
634     WORM_TUNNEL_MARKER_ACTIVE,
635     WORM_TUNNEL_OUTER_WALL,
636 
637     BRAZIER,
638 
639     MUD_FLOOR,
640     MUD_WALL,
641     MUD_DOORWAY,
642 
643     NUMBER_TILETYPES,
644 };
645 
646 enum lightType {
647     NO_LIGHT,
648     MINERS_LIGHT,
649     BURNING_CREATURE_LIGHT,
650     WISP_LIGHT,
651     SALAMANDER_LIGHT,
652     IMP_LIGHT,
653     PIXIE_LIGHT,
654     LICH_LIGHT,
655     FLAMEDANCER_LIGHT,
656     SENTINEL_LIGHT,
657     UNICORN_LIGHT,
658     IFRIT_LIGHT,
659     PHOENIX_LIGHT,
660     PHOENIX_EGG_LIGHT,
661     YENDOR_LIGHT,
662     SPECTRAL_BLADE_LIGHT,
663     SPECTRAL_IMAGE_LIGHT,
664     SPARK_TURRET_LIGHT,
665     EXPLOSIVE_BLOAT_LIGHT,
666     BOLT_LIGHT_SOURCE,
667     TELEPATHY_LIGHT,
668     SACRIFICE_MARK_LIGHT,
669 
670     SCROLL_PROTECTION_LIGHT,
671     SCROLL_ENCHANTMENT_LIGHT,
672     POTION_STRENGTH_LIGHT,
673     EMPOWERMENT_LIGHT,
674     GENERIC_FLASH_LIGHT,
675     FALLEN_TORCH_FLASH_LIGHT,
676     SUMMONING_FLASH_LIGHT,
677     EXPLOSION_FLARE_LIGHT,
678     QUIETUS_FLARE_LIGHT,
679     SLAYING_FLARE_LIGHT,
680     CHARGE_FLASH_LIGHT,
681 
682     TORCH_LIGHT,
683     LAVA_LIGHT,
684     SUN_LIGHT,
685     DARKNESS_PATCH_LIGHT,
686     FUNGUS_LIGHT,
687     FUNGUS_FOREST_LIGHT,
688     LUMINESCENT_ALGAE_BLUE_LIGHT,
689     LUMINESCENT_ALGAE_GREEN_LIGHT,
690     ECTOPLASM_LIGHT,
691     UNICORN_POOP_LIGHT,
692     EMBER_LIGHT,
693     FIRE_LIGHT,
694     BRIMSTONE_FIRE_LIGHT,
695     EXPLOSION_LIGHT,
696     INCENDIARY_DART_LIGHT,
697     PORTAL_ACTIVATE_LIGHT,
698     CONFUSION_GAS_LIGHT,
699     DARKNESS_CLOUD_LIGHT,
700     FORCEFIELD_LIGHT,
701     CRYSTAL_WALL_LIGHT,
702     CANDLE_LIGHT,
703     HAUNTED_TORCH_LIGHT,
704     GLYPH_LIGHT_DIM,
705     GLYPH_LIGHT_BRIGHT,
706     SACRED_GLYPH_LIGHT,
707     DESCENT_LIGHT,
708     DEMONIC_STATUE_LIGHT,
709     NUMBER_LIGHT_KINDS
710 };
711 
712 #define NUMBER_ITEM_CATEGORIES  13
713 
714 // Item categories
715 enum itemCategory {
716     FOOD                = Fl(0),
717     WEAPON              = Fl(1),
718     ARMOR               = Fl(2),
719     POTION              = Fl(3),
720     SCROLL              = Fl(4),
721     STAFF               = Fl(5),
722     WAND                = Fl(6),
723     RING                = Fl(7),
724     CHARM               = Fl(8),
725     GOLD                = Fl(9),
726     AMULET              = Fl(10),
727     GEM                 = Fl(11),
728     KEY                 = Fl(12),
729 
730     CAN_BE_DETECTED     = (WEAPON | ARMOR | POTION | SCROLL | RING | CHARM | WAND | STAFF | AMULET),
731     PRENAMED_CATEGORY   = (FOOD | GOLD | AMULET | GEM | KEY),
732     NEVER_IDENTIFIABLE  = (FOOD | CHARM | GOLD | AMULET | GEM | KEY),
733     CAN_BE_SWAPPED      = (WEAPON | ARMOR | STAFF | CHARM | RING),
734     ALL_ITEMS           = (FOOD|POTION|WEAPON|ARMOR|STAFF|WAND|SCROLL|RING|CHARM|GOLD|AMULET|GEM|KEY),
735 };
736 
737 enum keyKind {
738     KEY_DOOR,
739     KEY_CAGE,
740     KEY_PORTAL,
741     NUMBER_KEY_TYPES
742 };
743 
744 enum foodKind {
745     RATION,
746     FRUIT,
747     NUMBER_FOOD_KINDS
748 };
749 
750 enum potionKind {
751     POTION_LIFE,
752     POTION_STRENGTH,
753     POTION_TELEPATHY,
754     POTION_LEVITATION,
755     POTION_DETECT_MAGIC,
756     POTION_HASTE_SELF,
757     POTION_FIRE_IMMUNITY,
758     POTION_INVISIBILITY,
759     POTION_POISON,
760     POTION_PARALYSIS,
761     POTION_HALLUCINATION,
762     POTION_CONFUSION,
763     POTION_INCINERATION,
764     POTION_DARKNESS,
765     POTION_DESCENT,
766     POTION_LICHEN,
767     NUMBER_POTION_KINDS
768 };
769 
770 enum weaponKind {
771     DAGGER,
772     SWORD,
773     BROADSWORD,
774 
775     WHIP,
776     RAPIER,
777     FLAIL,
778 
779     MACE,
780     HAMMER,
781 
782     SPEAR,
783     PIKE,
784 
785     AXE,
786     WAR_AXE,
787 
788     DART,
789     INCENDIARY_DART,
790     JAVELIN,
791     NUMBER_WEAPON_KINDS
792 };
793 
794 enum weaponEnchants {
795     W_SPEED,
796     W_QUIETUS,
797     W_PARALYSIS,
798     W_MULTIPLICITY,
799     W_SLOWING,
800     W_CONFUSION,
801     W_FORCE,
802     W_SLAYING,
803     W_MERCY,
804     NUMBER_GOOD_WEAPON_ENCHANT_KINDS = W_MERCY,
805     W_PLENTY,
806     NUMBER_WEAPON_RUNIC_KINDS
807 };
808 
809 enum armorKind {
810     LEATHER_ARMOR,
811     SCALE_MAIL,
812     CHAIN_MAIL,
813     BANDED_MAIL,
814     SPLINT_MAIL,
815     PLATE_MAIL,
816     NUMBER_ARMOR_KINDS
817 };
818 
819 enum armorEnchants {
820     A_MULTIPLICITY,
821     A_MUTUALITY,
822     A_ABSORPTION,
823     A_REPRISAL,
824     A_IMMUNITY,
825     A_REFLECTION,
826     A_RESPIRATION,
827     A_DAMPENING,
828     A_BURDEN,
829     NUMBER_GOOD_ARMOR_ENCHANT_KINDS = A_BURDEN,
830     A_VULNERABILITY,
831     A_IMMOLATION,
832     NUMBER_ARMOR_ENCHANT_KINDS,
833 };
834 
835 enum wandKind {
836     WAND_TELEPORT,
837     WAND_SLOW,
838     WAND_POLYMORPH,
839     WAND_NEGATION,
840     WAND_DOMINATION,
841     WAND_BECKONING,
842     WAND_PLENTY,
843     WAND_INVISIBILITY,
844     WAND_EMPOWERMENT,
845     NUMBER_WAND_KINDS
846 };
847 
848 enum staffKind {
849     STAFF_LIGHTNING,
850     STAFF_FIRE,
851     STAFF_POISON,
852     STAFF_TUNNELING,
853     STAFF_BLINKING,
854     STAFF_ENTRANCEMENT,
855     STAFF_OBSTRUCTION,
856     STAFF_DISCORD,
857     STAFF_CONJURATION,
858     STAFF_HEALING,
859     STAFF_HASTE,
860     STAFF_PROTECTION,
861     NUMBER_STAFF_KINDS
862 };
863 
864 // these must be wand bolts, in order, and then staff bolts, in order:
865 enum boltType {
866     BOLT_NONE = 0,
867     BOLT_TELEPORT,
868     BOLT_SLOW,
869     BOLT_POLYMORPH,
870     BOLT_NEGATION,
871     BOLT_DOMINATION,
872     BOLT_BECKONING,
873     BOLT_PLENTY,
874     BOLT_INVISIBILITY,
875     BOLT_EMPOWERMENT,
876     BOLT_LIGHTNING,
877     BOLT_FIRE,
878     BOLT_POISON,
879     BOLT_TUNNELING,
880     BOLT_BLINKING,
881     BOLT_ENTRANCEMENT,
882     BOLT_OBSTRUCTION,
883     BOLT_DISCORD,
884     BOLT_CONJURATION,
885     BOLT_HEALING,
886     BOLT_HASTE,
887     BOLT_SLOW_2,
888     BOLT_SHIELDING,
889     BOLT_SPIDERWEB,
890     BOLT_SPARK,
891     BOLT_DRAGONFIRE,
892     BOLT_DISTANCE_ATTACK,
893     BOLT_POISON_DART,
894     BOLT_ANCIENT_SPIRIT_VINES,
895     BOLT_WHIP,
896     NUMBER_BOLT_KINDS
897 };
898 
899 enum ringKind {
900     RING_CLAIRVOYANCE,
901     RING_STEALTH,
902     RING_REGENERATION,
903     RING_TRANSFERENCE,
904     RING_LIGHT,
905     RING_AWARENESS,
906     RING_WISDOM,
907     RING_REAPING,
908     NUMBER_RING_KINDS
909 };
910 
911 enum charmKind {
912     CHARM_HEALTH,
913     CHARM_PROTECTION,
914     CHARM_HASTE,
915     CHARM_FIRE_IMMUNITY,
916     CHARM_INVISIBILITY,
917     CHARM_TELEPATHY,
918     CHARM_LEVITATION,
919     CHARM_SHATTERING,
920     CHARM_GUARDIAN,
921     CHARM_TELEPORTATION,
922     CHARM_RECHARGING,
923     CHARM_NEGATION,
924     NUMBER_CHARM_KINDS
925 };
926 
927 enum scrollKind {
928     SCROLL_ENCHANTING,
929     SCROLL_IDENTIFY,
930     SCROLL_TELEPORT,
931     SCROLL_REMOVE_CURSE,
932     SCROLL_RECHARGING,
933     SCROLL_PROTECT_ARMOR,
934     SCROLL_PROTECT_WEAPON,
935     SCROLL_SANCTUARY,
936     SCROLL_MAGIC_MAPPING,
937     SCROLL_NEGATION,
938     SCROLL_SHATTERING,
939     SCROLL_DISCORD,
940     SCROLL_AGGRAVATE_MONSTER,
941     SCROLL_SUMMON_MONSTER,
942     NUMBER_SCROLL_KINDS
943 };
944 
945 #define MAX_PACK_ITEMS              26
946 
947 enum monsterTypes {
948     MK_YOU,
949     MK_RAT,
950     MK_KOBOLD,
951     MK_JACKAL,
952     MK_EEL,
953     MK_MONKEY,
954     MK_BLOAT,
955     MK_PIT_BLOAT,
956     MK_GOBLIN,
957     MK_GOBLIN_CONJURER,
958     MK_GOBLIN_MYSTIC,
959     MK_GOBLIN_TOTEM,
960     MK_PINK_JELLY,
961     MK_TOAD,
962     MK_VAMPIRE_BAT,
963     MK_ARROW_TURRET,
964     MK_ACID_MOUND,
965     MK_CENTIPEDE,
966     MK_OGRE,
967     MK_BOG_MONSTER,
968     MK_OGRE_TOTEM,
969     MK_SPIDER,
970     MK_SPARK_TURRET,
971     MK_WILL_O_THE_WISP,
972     MK_WRAITH,
973     MK_ZOMBIE,
974     MK_TROLL,
975     MK_OGRE_SHAMAN,
976     MK_NAGA,
977     MK_SALAMANDER,
978     MK_EXPLOSIVE_BLOAT,
979     MK_DAR_BLADEMASTER,
980     MK_DAR_PRIESTESS,
981     MK_DAR_BATTLEMAGE,
982     MK_ACID_JELLY,
983     MK_CENTAUR,
984     MK_UNDERWORM,
985     MK_SENTINEL,
986     MK_DART_TURRET,
987     MK_KRAKEN,
988     MK_LICH,
989     MK_PHYLACTERY,
990     MK_PIXIE,
991     MK_PHANTOM,
992     MK_FLAME_TURRET,
993     MK_IMP,
994     MK_FURY,
995     MK_REVENANT,
996     MK_TENTACLE_HORROR,
997     MK_GOLEM,
998     MK_DRAGON,
999 
1000     MK_GOBLIN_CHIEFTAN,
1001     MK_BLACK_JELLY,
1002     MK_VAMPIRE,
1003     MK_FLAMEDANCER,
1004 
1005     MK_SPECTRAL_BLADE,
1006     MK_SPECTRAL_IMAGE,
1007     MK_GUARDIAN,
1008     MK_WINGED_GUARDIAN,
1009     MK_CHARM_GUARDIAN,
1010     MK_WARDEN_OF_YENDOR,
1011     MK_ELDRITCH_TOTEM,
1012     MK_MIRRORED_TOTEM,
1013 
1014     MK_UNICORN,
1015     MK_IFRIT,
1016     MK_PHOENIX,
1017     MK_PHOENIX_EGG,
1018     MK_ANCIENT_SPIRIT,
1019 
1020     NUMBER_MONSTER_KINDS
1021 };
1022 
1023 #define NUMBER_MUTATORS             8
1024 
1025 #define NUMBER_HORDES               177
1026 
1027 #define MONSTER_CLASS_COUNT         15
1028 
1029 // flavors
1030 
1031 #define NUMBER_ITEM_COLORS          21
1032 #define NUMBER_TITLE_PHONEMES       21
1033 #define NUMBER_ITEM_WOODS           21
1034 #define NUMBER_POTION_DESCRIPTIONS  18
1035 #define NUMBER_ITEM_METALS          12
1036 #define NUMBER_ITEM_GEMS            18
1037 
1038 // Dungeon flags
1039 enum tileFlags {
1040     DISCOVERED                  = Fl(0),
1041     VISIBLE                     = Fl(1),    // cell has sufficient light and is in field of view, ready to draw.
1042     HAS_PLAYER                  = Fl(2),
1043     HAS_MONSTER                 = Fl(3),
1044     HAS_DORMANT_MONSTER         = Fl(4),    // hidden monster on the square
1045     HAS_ITEM                    = Fl(5),
1046     IN_FIELD_OF_VIEW            = Fl(6),    // player has unobstructed line of sight whether or not there is enough light
1047     WAS_VISIBLE                 = Fl(7),
1048     HAS_STAIRS                  = Fl(8),
1049     SEARCHED_FROM_HERE          = Fl(9),    // player already auto-searched here; can't auto-search here again
1050     IS_IN_SHADOW                = Fl(10),   // so that a player gains an automatic stealth bonus
1051     MAGIC_MAPPED                = Fl(11),
1052     ITEM_DETECTED               = Fl(12),
1053     CLAIRVOYANT_VISIBLE         = Fl(13),
1054     WAS_CLAIRVOYANT_VISIBLE     = Fl(14),
1055     CLAIRVOYANT_DARKENED        = Fl(15),   // magical blindness from a cursed ring of clairvoyance
1056     CAUGHT_FIRE_THIS_TURN       = Fl(16),   // so that fire does not spread asymmetrically
1057     PRESSURE_PLATE_DEPRESSED    = Fl(17),   // so that traps do not trigger repeatedly while you stand on them
1058     STABLE_MEMORY               = Fl(18),   // redraws will be pulled from the memory array, not recalculated
1059     KNOWN_TO_BE_TRAP_FREE       = Fl(19),   // keep track of where the player has stepped or watched monsters step as he knows no traps are there
1060     IS_IN_PATH                  = Fl(20),   // the yellow trail leading to the cursor
1061     IN_LOOP                     = Fl(21),   // this cell is part of a terrain loop
1062     IS_CHOKEPOINT               = Fl(22),   // if this cell is blocked, part of the map will be rendered inaccessible
1063     IS_GATE_SITE                = Fl(23),   // consider placing a locked door here
1064     IS_IN_ROOM_MACHINE          = Fl(24),
1065     IS_IN_AREA_MACHINE          = Fl(25),
1066     IS_POWERED                  = Fl(26),   // has been activated by machine power this turn (flag can probably be eliminated if needed)
1067     IMPREGNABLE                 = Fl(27),   // no tunneling allowed!
1068     TERRAIN_COLORS_DANCING      = Fl(28),   // colors here will sparkle when the game is idle
1069     TELEPATHIC_VISIBLE          = Fl(29),   // potions of telepathy let you see through other creatures' eyes
1070     WAS_TELEPATHIC_VISIBLE      = Fl(30),   // potions of telepathy let you see through other creatures' eyes
1071 
1072     IS_IN_MACHINE               = (IS_IN_ROOM_MACHINE | IS_IN_AREA_MACHINE),    // sacred ground; don't generate items here, or teleport randomly to it
1073 
1074     PERMANENT_TILE_FLAGS = (DISCOVERED | MAGIC_MAPPED | ITEM_DETECTED | HAS_ITEM | HAS_DORMANT_MONSTER
1075                             | HAS_MONSTER | HAS_STAIRS | SEARCHED_FROM_HERE | PRESSURE_PLATE_DEPRESSED
1076                             | STABLE_MEMORY | KNOWN_TO_BE_TRAP_FREE | IN_LOOP
1077                             | IS_CHOKEPOINT | IS_GATE_SITE | IS_IN_MACHINE | IMPREGNABLE),
1078 
1079     ANY_KIND_OF_VISIBLE         = (VISIBLE | CLAIRVOYANT_VISIBLE | TELEPATHIC_VISIBLE),
1080 };
1081 
1082 #define TURNS_FOR_FULL_REGEN                300
1083 #define STOMACH_SIZE                        2150
1084 #define HUNGER_THRESHOLD                    (STOMACH_SIZE - 1800)
1085 #define WEAK_THRESHOLD                      150
1086 #define FAINT_THRESHOLD                     50
1087 #define MAX_EXP_LEVEL                       20
1088 #define MAX_EXP                             100000000L
1089 
1090 #define XPXP_NEEDED_FOR_TELEPATHIC_BOND     1400 // XPXP required to enable telepathic awareness with the ally
1091 
1092 #define ROOM_MIN_WIDTH                      4
1093 #define ROOM_MAX_WIDTH                      20
1094 #define ROOM_MIN_HEIGHT                     3
1095 #define ROOM_MAX_HEIGHT                     7
1096 #define HORIZONTAL_CORRIDOR_MIN_LENGTH      5
1097 #define HORIZONTAL_CORRIDOR_MAX_LENGTH      15
1098 #define VERTICAL_CORRIDOR_MIN_LENGTH        2
1099 #define VERTICAL_CORRIDOR_MAX_LENGTH        9
1100 #define CROSS_ROOM_MIN_WIDTH                3
1101 #define CROSS_ROOM_MAX_WIDTH                12
1102 #define CROSS_ROOM_MIN_HEIGHT               2
1103 #define CROSS_ROOM_MAX_HEIGHT               5
1104 #define MIN_SCALED_ROOM_DIMENSION           2
1105 
1106 #define ROOM_TYPE_COUNT                     8
1107 
1108 #define CORRIDOR_WIDTH                      1
1109 
1110 #define WAYPOINT_SIGHT_RADIUS               10
1111 #define MAX_WAYPOINT_COUNT                  40
1112 
1113 #define MAX_ITEMS_IN_MONSTER_ITEMS_HOPPER   100
1114 
1115 // Making these larger means cave generation will take more trials; set them too high and the program will hang.
1116 #define CAVE_MIN_WIDTH                      50
1117 #define CAVE_MIN_HEIGHT                     20
1118 
1119 // Keyboard commands:
1120 #define UP_KEY              'k'
1121 #define DOWN_KEY            'j'
1122 #define LEFT_KEY            'h'
1123 #define RIGHT_KEY           'l'
1124 #define UP_ARROW            63232
1125 #define LEFT_ARROW          63234
1126 #define DOWN_ARROW          63233
1127 #define RIGHT_ARROW         63235
1128 #define UPLEFT_KEY          'y'
1129 #define UPRIGHT_KEY         'u'
1130 #define DOWNLEFT_KEY        'b'
1131 #define DOWNRIGHT_KEY       'n'
1132 #define DESCEND_KEY         '>'
1133 #define ASCEND_KEY          '<'
1134 #define REST_KEY            'z'
1135 #define AUTO_REST_KEY       'Z'
1136 #define SEARCH_KEY          's'
1137 #define INVENTORY_KEY       'i'
1138 #define ACKNOWLEDGE_KEY     ' '
1139 #define EQUIP_KEY           'e'
1140 #define UNEQUIP_KEY         'r'
1141 #define APPLY_KEY           'a'
1142 #define THROW_KEY           't'
1143 #define RETHROW_KEY         'T'
1144 #define RELABEL_KEY         'R'
1145 #define SWAP_KEY            'w'
1146 #define TRUE_COLORS_KEY     '\\'
1147 #define AGGRO_DISPLAY_KEY   ']'
1148 #define DROP_KEY            'd'
1149 #define CALL_KEY            'c'
1150 #define QUIT_KEY            'Q'
1151 #define MESSAGE_ARCHIVE_KEY 'M'
1152 #define BROGUE_HELP_KEY     '?'
1153 #define DISCOVERIES_KEY     'D'
1154 #define EXPLORE_KEY         'x'
1155 #define AUTOPLAY_KEY        'A'
1156 #define SEED_KEY            '~'
1157 #define EASY_MODE_KEY       '&'
1158 #define ESCAPE_KEY          '\033'
1159 #define RETURN_KEY          '\012'
1160 #define DELETE_KEY          '\177'
1161 #define TAB_KEY             '\t'
1162 #define SHIFT_TAB_KEY       25 // Cocoa reports shift-tab this way for some reason.
1163 #define PERIOD_KEY          '.'
1164 #define VIEW_RECORDING_KEY  'V'
1165 #define LOAD_SAVED_GAME_KEY 'O'
1166 #define SAVE_GAME_KEY       'S'
1167 #define NEW_GAME_KEY        'N'
1168 #define GRAPHICS_KEY        'G'
1169 #define SWITCH_TO_PLAYING_KEY 'P'
1170 #define NUMPAD_0            48
1171 #define NUMPAD_1            49
1172 #define NUMPAD_2            50
1173 #define NUMPAD_3            51
1174 #define NUMPAD_4            52
1175 #define NUMPAD_5            53
1176 #define NUMPAD_6            54
1177 #define NUMPAD_7            55
1178 #define NUMPAD_8            56
1179 #define NUMPAD_9            57
1180 #define PAGE_UP_KEY         63276
1181 #define PAGE_DOWN_KEY       63277
1182 #define PRINTSCREEN_KEY     '\054'
1183 
1184 #define UNKNOWN_KEY         (128+19)
1185 
1186 #define min(x, y)       (((x) < (y)) ? (x) : (y))
1187 #define max(x, y)       (((x) > (y)) ? (x) : (y))
1188 #define clamp(x, low, hi)   (min(hi, max(x, low))) // pins x to the [y, z] interval
1189 
1190 #define terrainFlags(x, y)                  (tileCatalog[pmap[x][y].layers[DUNGEON]].flags \
1191                                             | tileCatalog[pmap[x][y].layers[LIQUID]].flags \
1192                                             | tileCatalog[pmap[x][y].layers[SURFACE]].flags \
1193                                             | tileCatalog[pmap[x][y].layers[GAS]].flags)
1194 
1195 #define terrainMechFlags(x, y)              (tileCatalog[pmap[x][y].layers[DUNGEON]].mechFlags \
1196                                             | tileCatalog[pmap[x][y].layers[LIQUID]].mechFlags \
1197                                             | tileCatalog[pmap[x][y].layers[SURFACE]].mechFlags \
1198                                             | tileCatalog[pmap[x][y].layers[GAS]].mechFlags)
1199 
1200 #ifdef BROGUE_ASSERTS
1201 boolean cellHasTerrainFlag(short x, short y, unsigned long flagMask);
1202 #else
1203 #define cellHasTerrainFlag(x, y, flagMask)  ((flagMask) & terrainFlags((x), (y)) ? true : false)
1204 #endif
1205 #define cellHasTMFlag(x, y, flagMask)       ((flagMask) & terrainMechFlags((x), (y)) ? true : false)
1206 
1207 #define cellHasTerrainType(x, y, terrain)   ((pmap[x][y].layers[DUNGEON] == (terrain) \
1208                                             || pmap[x][y].layers[LIQUID] == (terrain) \
1209                                             || pmap[x][y].layers[SURFACE] == (terrain) \
1210                                             || pmap[x][y].layers[GAS] == (terrain)) ? true : false)
1211 
1212 #define cellHasKnownTerrainFlag(x, y, flagMask) ((flagMask) & pmap[(x)][(y)].rememberedTerrainFlags ? true : false)
1213 
1214 #define cellIsPassableOrDoor(x, y)          (!cellHasTerrainFlag((x), (y), T_PATHING_BLOCKER) \
1215                                             || (cellHasTMFlag((x), (y), (TM_IS_SECRET | TM_PROMOTES_WITH_KEY | TM_CONNECTS_LEVEL)) \
1216                                                 && cellHasTerrainFlag((x), (y), T_OBSTRUCTS_PASSABILITY)))
1217 
1218 #define coordinatesAreInMap(x, y)           ((x) >= 0 && (x) < DCOLS    && (y) >= 0 && (y) < DROWS)
1219 #define coordinatesAreInWindow(x, y)        ((x) >= 0 && (x) < COLS     && (y) >= 0 && (y) < ROWS)
1220 #define mapToWindowX(x)                     ((x) + STAT_BAR_WIDTH + 1)
1221 #define mapToWindowY(y)                     ((y) + MESSAGE_LINES)
1222 #define windowToMapX(x)                     ((x) - STAT_BAR_WIDTH - 1)
1223 #define windowToMapY(y)                     ((y) - MESSAGE_LINES)
1224 
1225 #define playerCanDirectlySee(x, y)          (pmap[x][y].flags & VISIBLE)
1226 #define playerCanSee(x, y)                  (pmap[x][y].flags & ANY_KIND_OF_VISIBLE)
1227 #define playerCanSeeOrSense(x, y)           ((pmap[x][y].flags & ANY_KIND_OF_VISIBLE) \
1228                                             || (rogue.playbackOmniscience \
1229                                                 && (pmap[x][y].layers[DUNGEON] != GRANITE || (pmap[x][y].flags & DISCOVERED))))
1230 
1231 #define assureCosmeticRNG                   short oldRNG = rogue.RNG; rogue.RNG = RNG_COSMETIC;
1232 #define restoreRNG                          rogue.RNG = oldRNG;
1233 
1234 #define MIN_COLOR_DIFF          600
1235 // weighted sum of the squares of the component differences. Weights are according to color perception.
1236 #define COLOR_DIFF(f, b)         (((f).red - (b).red) * ((f).red - (b).red) * 0.2126 \
1237 + ((f).green - (b).green) * ((f).green - (b).green) * 0.7152 \
1238 + ((f).blue - (b).blue) * ((f).blue - (b).blue) * 0.0722)
1239 
1240 // structs
1241 
1242 enum dungeonLayers {
1243     NO_LAYER = -1,
1244     DUNGEON = 0,        // dungeon-level tile   (e.g. walls)
1245     LIQUID,             // liquid-level tile    (e.g. lava)
1246     GAS,                // gas-level tile       (e.g. fire, smoke, swamp gas)
1247     SURFACE,            // surface-level tile   (e.g. grass)
1248     NUMBER_TERRAIN_LAYERS
1249 };
1250 
1251 // keeps track of graphics so we only redraw if the cell has changed:
1252 typedef struct cellDisplayBuffer {
1253     enum displayGlyph character;
1254     char foreColorComponents[3];
1255     char backColorComponents[3];
1256     char opacity;
1257 } cellDisplayBuffer;
1258 
1259 typedef struct pcell {                              // permanent cell; have to remember this stuff to save levels
1260     enum tileType layers[NUMBER_TERRAIN_LAYERS];    // terrain
1261     unsigned long flags;                            // non-terrain cell flags
1262     unsigned short volume;                          // quantity of gas in cell
1263     unsigned char machineNumber;
1264     cellDisplayBuffer rememberedAppearance;         // how the player remembers the cell to look
1265     enum itemCategory rememberedItemCategory;       // what category of item the player remembers lying there
1266     short rememberedItemKind;                       // what kind of item the player remembers lying there
1267     short rememberedItemQuantity;                   // how many of the item the player remembers lying there
1268     short rememberedItemOriginDepth;                // the origin depth of the item the player remembers lying there
1269     enum tileType rememberedTerrain;                // what the player remembers as the terrain (i.e. highest priority terrain upon last seeing)
1270     unsigned long rememberedCellFlags;              // map cell flags the player remembers from that spot
1271     unsigned long rememberedTerrainFlags;           // terrain flags the player remembers from that spot
1272     unsigned long rememberedTMFlags;                // TM flags the player remembers from that spot
1273     short exposedToFire;                            // number of times the tile has been exposed to fire since the last environment update
1274 } pcell;
1275 
1276 typedef struct tcell {          // transient cell; stuff we don't need to remember between levels
1277     short light[3];             // RGB components of lighting
1278     short oldLight[3];          // compare with subsequent lighting to determine whether to refresh cell
1279 } tcell;
1280 
1281 typedef struct randomRange {
1282     short lowerBound;
1283     short upperBound;
1284     short clumpFactor;
1285 } randomRange;
1286 
1287 typedef struct color {
1288     // base RGB components:
1289     short red;
1290     short green;
1291     short blue;
1292 
1293     // random RGB components to add to base components:
1294     short redRand;
1295     short greenRand;
1296     short blueRand;
1297 
1298     // random scalar to add to all components:
1299     short rand;
1300 
1301     // Flag: this color "dances" with every refresh:
1302     boolean colorDances;
1303 } color;
1304 
1305 enum itemFlags {
1306     ITEM_IDENTIFIED         = Fl(0),
1307     ITEM_EQUIPPED           = Fl(1),
1308     ITEM_CURSED             = Fl(2),
1309     ITEM_PROTECTED          = Fl(3),
1310     // unused               = Fl(4),
1311     ITEM_RUNIC              = Fl(5),
1312     ITEM_RUNIC_HINTED       = Fl(6),
1313     ITEM_RUNIC_IDENTIFIED   = Fl(7),
1314     ITEM_CAN_BE_IDENTIFIED  = Fl(8),
1315     ITEM_PREPLACED          = Fl(9),
1316     ITEM_FLAMMABLE          = Fl(10),
1317     ITEM_MAGIC_DETECTED     = Fl(11),
1318     ITEM_MAX_CHARGES_KNOWN  = Fl(12),
1319     ITEM_IS_KEY             = Fl(13),
1320 
1321     ITEM_ATTACKS_STAGGER    = Fl(14),   // mace, hammer
1322     ITEM_ATTACKS_EXTEND     = Fl(15),   // whip
1323     ITEM_ATTACKS_QUICKLY    = Fl(16),   // rapier
1324     ITEM_ATTACKS_PENETRATE  = Fl(17),   // spear, pike
1325     ITEM_ATTACKS_ALL_ADJACENT=Fl(18),   // axe, war axe
1326     ITEM_LUNGE_ATTACKS      = Fl(19),   // rapier
1327     ITEM_SNEAK_ATTACK_BONUS = Fl(20),   // dagger
1328     ITEM_PASS_ATTACKS       = Fl(21),   // flail
1329 
1330     ITEM_KIND_AUTO_ID       = Fl(22),   // the item type will become known when the item is picked up.
1331     ITEM_PLAYER_AVOIDS      = Fl(23),   // explore and travel will try to avoid picking the item up
1332 };
1333 
1334 #define KEY_ID_MAXIMUM  20
1335 
1336 typedef struct keyLocationProfile {
1337     short x;
1338     short y;
1339     short machine;
1340     boolean disposableHere;
1341 } keyLocationProfile;
1342 
1343 typedef struct item {
1344     unsigned short category;
1345     short kind;
1346     unsigned long flags;
1347     randomRange damage;
1348     short armor;
1349     short charges;
1350     short enchant1;
1351     short enchant2;
1352     short timesEnchanted;
1353     enum monsterTypes vorpalEnemy;
1354     short strengthRequired;
1355     unsigned short quiverNumber;
1356     enum displayGlyph displayChar;
1357     color *foreColor;
1358     color *inventoryColor;
1359     short quantity;
1360     char inventoryLetter;
1361     char inscription[DCOLS];
1362     short xLoc;
1363     short yLoc;
1364     keyLocationProfile keyLoc[KEY_ID_MAXIMUM];
1365     short originDepth;
1366     unsigned long spawnTurnNumber;
1367     unsigned long lastUsed[3];         // Absolute turns last applied
1368     struct item *nextItem;
1369 } item;
1370 
1371 typedef struct itemTable {
1372     char *name;
1373     char *flavor;
1374     char callTitle[30];
1375     short frequency;
1376     short marketValue;
1377     short strengthRequired;
1378     randomRange range;
1379     boolean identified;
1380     boolean called;
1381     char description[1500];
1382 } itemTable;
1383 
1384 enum dungeonFeatureTypes {
1385     DF_GRANITE_COLUMN = 1,
1386     DF_CRYSTAL_WALL,
1387     DF_LUMINESCENT_FUNGUS,
1388     DF_GRASS,
1389     DF_DEAD_GRASS,
1390     DF_BONES,
1391     DF_RUBBLE,
1392     DF_FOLIAGE,
1393     DF_FUNGUS_FOREST,
1394     DF_DEAD_FOLIAGE,
1395 
1396     DF_SUNLIGHT,
1397     DF_DARKNESS,
1398 
1399     DF_SHOW_DOOR,
1400     DF_SHOW_POISON_GAS_TRAP,
1401     DF_SHOW_PARALYSIS_GAS_TRAP,
1402     DF_SHOW_TRAPDOOR_HALO,
1403     DF_SHOW_TRAPDOOR,
1404     DF_SHOW_CONFUSION_GAS_TRAP,
1405     DF_SHOW_FLAMETHROWER_TRAP,
1406     DF_SHOW_FLOOD_TRAP,
1407     DF_SHOW_NET_TRAP,
1408     DF_SHOW_ALARM_TRAP,
1409 
1410     DF_RED_BLOOD,
1411     DF_GREEN_BLOOD,
1412     DF_PURPLE_BLOOD,
1413     DF_WORM_BLOOD,
1414     DF_ACID_BLOOD,
1415     DF_ASH_BLOOD,
1416     DF_EMBER_BLOOD,
1417     DF_ECTOPLASM_BLOOD,
1418     DF_RUBBLE_BLOOD,
1419     DF_ROT_GAS_BLOOD,
1420 
1421     DF_VOMIT,
1422     DF_BLOAT_DEATH,
1423     DF_BLOAT_EXPLOSION,
1424     DF_BLOOD_EXPLOSION,
1425     DF_FLAMEDANCER_CORONA,
1426 
1427     DF_MUTATION_EXPLOSION,
1428     DF_MUTATION_LICHEN,
1429 
1430     DF_REPEL_CREATURES,
1431     DF_ROT_GAS_PUFF,
1432     DF_STEAM_PUFF,
1433     DF_STEAM_ACCUMULATION,
1434     DF_METHANE_GAS_PUFF,
1435     DF_SALAMANDER_FLAME,
1436     DF_URINE,
1437     DF_UNICORN_POOP,
1438     DF_PUDDLE,
1439     DF_ASH,
1440     DF_ECTOPLASM_DROPLET,
1441     DF_FORCEFIELD,
1442     DF_FORCEFIELD_MELT,
1443     DF_SACRED_GLYPHS,
1444     DF_LICHEN_GROW,
1445     DF_TUNNELIZE,
1446     DF_SHATTERING_SPELL,
1447 
1448     // spiderwebs
1449     DF_WEB_SMALL,
1450     DF_WEB_LARGE,
1451 
1452     // ancient spirit
1453     DF_ANCIENT_SPIRIT_VINES,
1454     DF_ANCIENT_SPIRIT_GRASS,
1455 
1456     // foliage
1457     DF_TRAMPLED_FOLIAGE,
1458     DF_SMALL_DEAD_GRASS,
1459     DF_FOLIAGE_REGROW,
1460     DF_TRAMPLED_FUNGUS_FOREST,
1461     DF_FUNGUS_FOREST_REGROW,
1462 
1463     // brimstone
1464     DF_ACTIVE_BRIMSTONE,
1465     DF_INERT_BRIMSTONE,
1466 
1467     // bloodwort
1468     DF_BLOODFLOWER_PODS_GROW_INITIAL,
1469     DF_BLOODFLOWER_PODS_GROW,
1470     DF_BLOODFLOWER_POD_BURST,
1471 
1472     // dewars
1473     DF_DEWAR_CAUSTIC,
1474     DF_DEWAR_CONFUSION,
1475     DF_DEWAR_PARALYSIS,
1476     DF_DEWAR_METHANE,
1477     DF_DEWAR_GLASS,
1478     DF_CARPET_AREA,
1479 
1480     // algae
1481     DF_BUILD_ALGAE_WELL,
1482     DF_ALGAE_1,
1483     DF_ALGAE_2,
1484     DF_ALGAE_REVERT,
1485 
1486     DF_OPEN_DOOR,
1487     DF_CLOSED_DOOR,
1488     DF_OPEN_IRON_DOOR_INERT,
1489     DF_ITEM_CAGE_OPEN,
1490     DF_ITEM_CAGE_CLOSE,
1491     DF_ALTAR_INERT,
1492     DF_ALTAR_RETRACT,
1493     DF_PORTAL_ACTIVATE,
1494     DF_INACTIVE_GLYPH,
1495     DF_ACTIVE_GLYPH,
1496     DF_SILENT_GLYPH_GLOW,
1497     DF_GUARDIAN_STEP,
1498     DF_MIRROR_TOTEM_STEP,
1499     DF_GLYPH_CIRCLE,
1500     DF_REVEAL_LEVER,
1501     DF_PULL_LEVER,
1502     DF_CREATE_LEVER,
1503 
1504     DF_BRIDGE_FALL_PREP,
1505     DF_BRIDGE_FALL,
1506 
1507     DF_PLAIN_FIRE,
1508     DF_GAS_FIRE,
1509     DF_EXPLOSION_FIRE,
1510     DF_DART_EXPLOSION,
1511     DF_BRIMSTONE_FIRE,
1512     DF_BRIDGE_FIRE,
1513     DF_FLAMETHROWER,
1514     DF_EMBERS,
1515     DF_EMBERS_PATCH,
1516     DF_OBSIDIAN,
1517     DF_ITEM_FIRE,
1518     DF_CREATURE_FIRE,
1519 
1520     DF_FLOOD,
1521     DF_FLOOD_2,
1522     DF_FLOOD_DRAIN,
1523     DF_HOLE_2,
1524     DF_HOLE_DRAIN,
1525 
1526     DF_DEEP_WATER_FREEZE,
1527     DF_ALGAE_1_FREEZE,
1528     DF_ALGAE_2_FREEZE,
1529     DF_DEEP_WATER_MELTING,
1530     DF_DEEP_WATER_THAW,
1531     DF_SHALLOW_WATER_FREEZE,
1532     DF_SHALLOW_WATER_MELTING,
1533     DF_SHALLOW_WATER_THAW,
1534 
1535     DF_POISON_GAS_CLOUD,
1536     DF_CONFUSION_GAS_TRAP_CLOUD,
1537     DF_NET,
1538     DF_AGGRAVATE_TRAP,
1539     DF_METHANE_GAS_ARMAGEDDON,
1540 
1541     // potions
1542     DF_POISON_GAS_CLOUD_POTION,
1543     DF_PARALYSIS_GAS_CLOUD_POTION,
1544     DF_CONFUSION_GAS_CLOUD_POTION,
1545     DF_INCINERATION_POTION,
1546     DF_DARKNESS_POTION,
1547     DF_HOLE_POTION,
1548     DF_LICHEN_PLANTED,
1549 
1550     // other items
1551     DF_ARMOR_IMMOLATION,
1552     DF_STAFF_HOLE,
1553     DF_STAFF_HOLE_EDGE,
1554 
1555     // commutation altar
1556     DF_ALTAR_COMMUTE,
1557     DF_MAGIC_PIPING,
1558     DF_INERT_PIPE,
1559 
1560     // resurrection altar
1561     DF_ALTAR_RESURRECT,
1562     DF_MACHINE_FLOOR_TRIGGER_REPEATING,
1563 
1564     // sacrifice altar
1565     DF_SACRIFICE_ALTAR,
1566     DF_SACRIFICE_COMPLETE,
1567     DF_SACRIFICE_CAGE_ACTIVE,
1568 
1569     // vampire in coffin
1570     DF_COFFIN_BURSTS,
1571     DF_COFFIN_BURNS,
1572     DF_TRIGGER_AREA,
1573 
1574     // throwing tutorial -- button in chasm
1575     DF_CAGE_DISAPPEARS,
1576     DF_MEDIUM_HOLE,
1577     DF_MEDIUM_LAVA_POND,
1578     DF_MACHINE_PRESSURE_PLATE_USED,
1579 
1580     // rat trap
1581     DF_WALL_CRACK,
1582 
1583     // wooden barricade at entrance
1584     DF_WOODEN_BARRICADE_BURN,
1585 
1586     // wooden barricade around altar, dead grass all around
1587     DF_SURROUND_WOODEN_BARRICADE,
1588 
1589     // pools of water that, when triggered, slowly expand to fill the room
1590     DF_SPREADABLE_WATER,
1591     DF_SHALLOW_WATER,
1592     DF_WATER_SPREADS,
1593     DF_SPREADABLE_WATER_POOL,
1594     DF_SPREADABLE_DEEP_WATER_POOL,
1595 
1596     // when triggered, the ground gradually turns into chasm:
1597     DF_SPREADABLE_COLLAPSE,
1598     DF_COLLAPSE,
1599     DF_COLLAPSE_SPREADS,
1600     DF_ADD_MACHINE_COLLAPSE_EDGE_DORMANT,
1601 
1602     // when triggered, a bridge appears:
1603     DF_BRIDGE_ACTIVATE,
1604     DF_BRIDGE_ACTIVATE_ANNOUNCE,
1605     DF_BRIDGE_APPEARS,
1606     DF_ADD_DORMANT_CHASM_HALO,
1607 
1608     // when triggered, the lava retracts:
1609     DF_LAVA_RETRACTABLE,
1610     DF_RETRACTING_LAVA,
1611     DF_OBSIDIAN_WITH_STEAM,
1612 
1613     // when triggered, the door seals and caustic gas fills the room
1614     DF_SHOW_POISON_GAS_VENT,
1615     DF_POISON_GAS_VENT_OPEN,
1616     DF_ACTIVATE_PORTCULLIS,
1617     DF_OPEN_PORTCULLIS,
1618     DF_VENT_SPEW_POISON_GAS,
1619 
1620     // when triggered, pilot light ignites and explosive gas fills the room
1621     DF_SHOW_METHANE_VENT,
1622     DF_METHANE_VENT_OPEN,
1623     DF_VENT_SPEW_METHANE,
1624     DF_PILOT_LIGHT,
1625 
1626     // paralysis trap: trigger plate with gas vents nearby
1627     DF_DISCOVER_PARALYSIS_VENT,
1628     DF_PARALYSIS_VENT_SPEW,
1629     DF_REVEAL_PARALYSIS_VENT_SILENTLY,
1630 
1631     // thematic dungeon
1632     DF_AMBIENT_BLOOD,
1633 
1634     // statues crack for a few turns and then shatter, revealing the monster inside
1635     DF_CRACKING_STATUE,
1636     DF_STATUE_SHATTER,
1637 
1638     // a turret appears:
1639     DF_TURRET_EMERGE,
1640 
1641     // an elaborate worm catacomb opens up
1642     DF_WORM_TUNNEL_MARKER_DORMANT,
1643     DF_WORM_TUNNEL_MARKER_ACTIVE,
1644     DF_GRANITE_CRUMBLES,
1645     DF_WALL_OPEN,
1646 
1647     // the room gradually darkens
1648     DF_DARKENING_FLOOR,
1649     DF_DARK_FLOOR,
1650     DF_HAUNTED_TORCH_TRANSITION,
1651     DF_HAUNTED_TORCH,
1652 
1653     // bubbles rise from the mud and bog monsters spawn
1654     DF_MUD_DORMANT,
1655     DF_MUD_ACTIVATE,
1656 
1657     // crystals charge when hit by lightning
1658     DF_ELECTRIC_CRYSTAL_ON,
1659     DF_TURRET_LEVER,
1660 
1661     // idyll:
1662     DF_SHALLOW_WATER_POOL,
1663     DF_DEEP_WATER_POOL,
1664 
1665     // swamp:
1666     DF_SWAMP_WATER,
1667     DF_SWAMP,
1668     DF_SWAMP_MUD,
1669 
1670     // camp:
1671     DF_HAY,
1672     DF_JUNK,
1673 
1674     // remnants:
1675     DF_REMNANT,
1676     DF_REMNANT_ASH,
1677 
1678     // chasm catwalk:
1679     DF_CHASM_HOLE,
1680     DF_CATWALK_BRIDGE,
1681 
1682     // lake catwalk:
1683     DF_LAKE_CELL,
1684     DF_LAKE_HALO,
1685 
1686     // worm den:
1687     DF_WALL_SHATTER,
1688 
1689     // monster cages open:
1690     DF_MONSTER_CAGE_OPENS,
1691 
1692     // goblin warren:
1693     DF_STENCH_BURN,
1694     DF_STENCH_SMOLDER,
1695 
1696     NUMBER_DUNGEON_FEATURES,
1697 };
1698 
1699 enum dungeonProfileTypes {
1700     DP_BASIC,
1701     DP_BASIC_FIRST_ROOM,
1702 
1703     DP_GOBLIN_WARREN,
1704     DP_SENTINEL_SANCTUARY,
1705 
1706     NUMBER_DUNGEON_PROFILES,
1707 };
1708 
1709 typedef struct lightSource {
1710     const color *lightColor;
1711     randomRange lightRadius;
1712     short radialFadeToPercent;
1713     boolean passThroughCreatures; // generally no, but miner light does
1714 } lightSource;
1715 
1716 typedef struct flare {
1717     lightSource *light;                 // Flare light
1718     short coeffChangeAmount;            // The constant amount by which the coefficient changes per frame, e.g. -25 means it gets 25% dimmer per frame.
1719     short coeffLimit;                   // Flare ends if the coefficient passes this percentage (whether going up or down).
1720     short xLoc, yLoc;                   // Current flare location.
1721     long coeff;                         // Current flare coefficient; always starts at 100.
1722     unsigned long turnNumber;           // So we can eliminate those that fired one or more turns ago.
1723 } flare;
1724 
1725 enum DFFlags {
1726     DFF_EVACUATE_CREATURES_FIRST    = Fl(0),    // Creatures in the DF area get moved outside of it
1727     DFF_SUBSEQ_EVERYWHERE           = Fl(1),    // Subsequent DF spawns in every cell that this DF spawns in, instead of only the origin
1728     DFF_TREAT_AS_BLOCKING           = Fl(2),    // If filling the footprint of this DF with walls would disrupt level connectivity, then abort.
1729     DFF_PERMIT_BLOCKING             = Fl(3),    // Generate this DF without regard to level connectivity.
1730     DFF_ACTIVATE_DORMANT_MONSTER    = Fl(4),    // Dormant monsters on this tile will appear -- e.g. when a statue bursts to reveal a monster.
1731     DFF_CLEAR_OTHER_TERRAIN         = Fl(5),    // Erase other terrain in the footprint of this DF.
1732     DFF_BLOCKED_BY_OTHER_LAYERS     = Fl(6),    // Will not propagate into a cell if any layer in that cell has a superior priority.
1733     DFF_SUPERPRIORITY               = Fl(7),    // Will overwrite terrain of a superior priority.
1734     DFF_AGGRAVATES_MONSTERS         = Fl(8),    // Will act as though an aggravate monster scroll of effectRadius radius had been read at that point.
1735     DFF_RESURRECT_ALLY              = Fl(9),    // Will bring back to life your most recently deceased ally.
1736 };
1737 
1738 enum boltEffects {
1739     BE_NONE,
1740     BE_ATTACK,
1741     BE_TELEPORT,
1742     BE_SLOW,
1743     BE_POLYMORPH,
1744     BE_NEGATION,
1745     BE_DOMINATION,
1746     BE_BECKONING,
1747     BE_PLENTY,
1748     BE_INVISIBILITY,
1749     BE_EMPOWERMENT,
1750     BE_DAMAGE,
1751     BE_POISON,
1752     BE_TUNNELING,
1753     BE_BLINKING,
1754     BE_ENTRANCEMENT,
1755     BE_OBSTRUCTION,
1756     BE_DISCORD,
1757     BE_CONJURATION,
1758     BE_HEALING,
1759     BE_HASTE,
1760     BE_SHIELDING,
1761 };
1762 
1763 enum boltFlags {
1764     BF_PASSES_THRU_CREATURES        = Fl(0),    // Bolt continues through creatures (e.g. lightning and tunneling)
1765     BF_HALTS_BEFORE_OBSTRUCTION     = Fl(1),    // Bolt takes effect the space before it terminates (e.g. conjuration, obstruction, blinking)
1766     BF_TARGET_ALLIES                = Fl(2),    // Staffs/wands/creatures that shoot this bolt will auto-target allies.
1767     BF_TARGET_ENEMIES               = Fl(3),    // Staffs/wands/creatures that shoot this bolt will auto-target enemies.
1768     BF_FIERY                        = Fl(4),    // Bolt will light flammable terrain on fire as it passes, and will ignite monsters hit.
1769     BF_NEVER_REFLECTS               = Fl(6),    // Bolt will never reflect (e.g. spiderweb, arrows).
1770     BF_NOT_LEARNABLE                = Fl(7),    // This technique cannot be absorbed by empowered allies.
1771     BF_NOT_NEGATABLE                = Fl(8),    // Won't be erased by negation.
1772     BF_ELECTRIC                     = Fl(9),    // Activates terrain that has TM_PROMOTES_ON_ELECTRICITY
1773     BF_DISPLAY_CHAR_ALONG_LENGTH    = Fl(10),   // Display the character along the entire length of the bolt instead of just at the front.
1774 };
1775 
1776 typedef struct bolt {
1777     char name[DCOLS];
1778     char description[COLS];
1779     char abilityDescription[COLS*2];
1780     enum displayGlyph theChar;
1781     const color *foreColor;
1782     const color *backColor;
1783     short boltEffect;
1784     short magnitude;
1785     short pathDF;
1786     short targetDF;
1787     unsigned long forbiddenMonsterFlags;
1788     unsigned long flags;
1789 } bolt;
1790 
1791 // Level profiles, affecting what rooms get chosen and how they're connected:
1792 typedef struct dungeonProfile {
1793     // Room type weights (in the natural dungeon, these are also adjusted based on depth):
1794     short roomFrequencies[ROOM_TYPE_COUNT];
1795 
1796     short corridorChance;
1797 } dungeonProfile;
1798 
1799 // Dungeon features, spawned from Architect.c:
1800 typedef struct dungeonFeature {
1801     // tile info:
1802     enum tileType tile;
1803     enum dungeonLayers layer;
1804 
1805     // spawning pattern:
1806     short startProbability;
1807     short probabilityDecrement;
1808     unsigned long flags;
1809     char description[DCOLS];
1810     enum lightType lightFlare;
1811     const color *flashColor;
1812     short effectRadius;
1813     enum tileType propagationTerrain;
1814     enum dungeonFeatureTypes subsequentDF;
1815     boolean messageDisplayed;
1816 } dungeonFeature;
1817 
1818 // Terrain types:
1819 typedef struct floorTileType {
1820     // appearance:
1821     enum displayGlyph displayChar;
1822     const color *foreColor;
1823     const color *backColor;
1824     short drawPriority;                     // priority (lower number means higher priority); governs drawing as well as tile replacement comparisons.
1825     char chanceToIgnite;                    // chance to burn if a flame terrain is on one of the four cardinal neighbors
1826     enum dungeonFeatureTypes fireType;      // spawn this DF when the terrain ignites (or, if it's T_IS_DF_TRAP, when the pressure plate clicks)
1827     enum dungeonFeatureTypes discoverType;  // spawn this DF when successfully searched if T_IS_SECRET is set
1828     enum dungeonFeatureTypes promoteType;   // creates this dungeon spawn type when it promotes for some other reason (random promotion or promotion through machine activation)
1829     short promoteChance;                    // percent chance per turn to spawn the promotion type; will also vanish upon doing so if T_VANISHES_UPON_PROMOTION is set
1830     short glowLight;                        // if it glows, this is the ID of the light type
1831     unsigned long flags;
1832     unsigned long mechFlags;
1833     char description[COLS];
1834     char flavorText[COLS];
1835 } floorTileType;
1836 
1837 enum terrainFlagCatalog {
1838     T_OBSTRUCTS_PASSABILITY         = Fl(0),        // cannot be walked through
1839     T_OBSTRUCTS_VISION              = Fl(1),        // blocks line of sight
1840     T_OBSTRUCTS_ITEMS               = Fl(2),        // items can't be on this tile
1841     T_OBSTRUCTS_SURFACE_EFFECTS     = Fl(3),        // grass, blood, etc. cannot exist on this tile
1842     T_OBSTRUCTS_GAS                 = Fl(4),        // blocks the permeation of gas
1843     T_OBSTRUCTS_DIAGONAL_MOVEMENT   = Fl(5),        // can't step diagonally around this tile
1844     T_SPONTANEOUSLY_IGNITES         = Fl(6),        // monsters avoid unless chasing player or immune to fire
1845     T_AUTO_DESCENT                  = Fl(7),        // automatically drops creatures down a depth level and does some damage (2d6)
1846     T_LAVA_INSTA_DEATH              = Fl(8),        // kills any non-levitating non-fire-immune creature instantly
1847     T_CAUSES_POISON                 = Fl(9),        // any non-levitating creature gets 10 poison
1848     T_IS_FLAMMABLE                  = Fl(10),       // terrain can catch fire
1849     T_IS_FIRE                       = Fl(11),       // terrain is a type of fire; ignites neighboring flammable cells
1850     T_ENTANGLES                     = Fl(12),       // entangles players and monsters like a spiderweb
1851     T_IS_DEEP_WATER                 = Fl(13),       // steals items 50% of the time and moves them around randomly
1852     T_CAUSES_DAMAGE                 = Fl(14),       // anything on the tile takes max(1-2, 10%) damage per turn
1853     T_CAUSES_NAUSEA                 = Fl(15),       // any creature on the tile becomes nauseous
1854     T_CAUSES_PARALYSIS              = Fl(16),       // anything caught on this tile is paralyzed
1855     T_CAUSES_CONFUSION              = Fl(17),       // causes creatures on this tile to become confused
1856     T_CAUSES_HEALING                = Fl(18),       // heals 20% max HP per turn for any player or non-inanimate monsters
1857     T_IS_DF_TRAP                    = Fl(19),       // spews gas of type specified in fireType when stepped on
1858     T_CAUSES_EXPLOSIVE_DAMAGE       = Fl(20),       // is an explosion; deals higher of 15-20 or 50% damage instantly, but not again for five turns
1859     T_SACRED                        = Fl(21),       // monsters that aren't allies of the player will avoid stepping here
1860 
1861     T_OBSTRUCTS_SCENT               = (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION | T_AUTO_DESCENT | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES),
1862     T_PATHING_BLOCKER               = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_IS_FIRE | T_SPONTANEOUSLY_IGNITES),
1863     T_DIVIDES_LEVEL                 = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER),
1864     T_LAKE_PATHING_BLOCKER          = (T_AUTO_DESCENT | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES),
1865     T_WAYPOINT_BLOCKER              = (T_OBSTRUCTS_PASSABILITY | T_AUTO_DESCENT | T_IS_DF_TRAP | T_LAVA_INSTA_DEATH | T_IS_DEEP_WATER | T_SPONTANEOUSLY_IGNITES),
1866     T_MOVES_ITEMS                   = (T_IS_DEEP_WATER | T_LAVA_INSTA_DEATH),
1867     T_CAN_BE_BRIDGED                = (T_AUTO_DESCENT),
1868     T_OBSTRUCTS_EVERYTHING          = (T_OBSTRUCTS_PASSABILITY | T_OBSTRUCTS_VISION | T_OBSTRUCTS_ITEMS | T_OBSTRUCTS_GAS | T_OBSTRUCTS_SURFACE_EFFECTS | T_OBSTRUCTS_DIAGONAL_MOVEMENT),
1869     T_HARMFUL_TERRAIN               = (T_CAUSES_POISON | T_IS_FIRE | T_CAUSES_DAMAGE | T_CAUSES_PARALYSIS | T_CAUSES_CONFUSION | T_CAUSES_EXPLOSIVE_DAMAGE),
1870     T_RESPIRATION_IMMUNITIES        = (T_CAUSES_DAMAGE | T_CAUSES_CONFUSION | T_CAUSES_PARALYSIS | T_CAUSES_NAUSEA),
1871 };
1872 
1873 enum terrainMechanicalFlagCatalog {
1874     TM_IS_SECRET                    = Fl(0),        // successful search or being stepped on while visible transforms it into discoverType
1875     TM_PROMOTES_WITH_KEY            = Fl(1),        // promotes if the key is present on the tile (in your pack, carried by monster, or lying on the ground)
1876     TM_PROMOTES_WITHOUT_KEY         = Fl(2),        // promotes if the key is NOT present on the tile (in your pack, carried by monster, or lying on the ground)
1877     TM_PROMOTES_ON_CREATURE         = Fl(3),        // promotes when a creature or player is on the tile (whether or not levitating)
1878     TM_PROMOTES_ON_ITEM             = Fl(4),        // promotes when an item is on the tile
1879     TM_PROMOTES_ON_ITEM_PICKUP      = Fl(5),        // promotes when an item is lifted from the tile (primarily for altars)
1880     TM_PROMOTES_ON_PLAYER_ENTRY     = Fl(6),        // promotes when the player enters the tile (whether or not levitating)
1881     TM_PROMOTES_ON_SACRIFICE_ENTRY  = Fl(7),        // promotes when the sacrifice target enters the tile (whether or not levitating)
1882     TM_PROMOTES_ON_ELECTRICITY      = Fl(8),        // promotes when hit by a lightning bolt
1883     TM_ALLOWS_SUBMERGING            = Fl(9),        // allows submersible monsters to submerge in this terrain
1884     TM_IS_WIRED                     = Fl(10),        // if wired, promotes when powered, and sends power when promoting
1885     TM_IS_CIRCUIT_BREAKER           = Fl(11),       // prevents power from circulating in its machine
1886     TM_GAS_DISSIPATES               = Fl(12),       // does not just hang in the air forever
1887     TM_GAS_DISSIPATES_QUICKLY       = Fl(13),       // dissipates quickly
1888     TM_EXTINGUISHES_FIRE            = Fl(14),       // extinguishes burning terrain or creatures
1889     TM_VANISHES_UPON_PROMOTION      = Fl(15),       // vanishes when creating promotion dungeon feature, even if the replacement terrain priority doesn't require it
1890     TM_REFLECTS_BOLTS               = Fl(16),       // magic bolts reflect off of its surface randomly (similar to pmap flag IMPREGNABLE)
1891     TM_STAND_IN_TILE                = Fl(17),       // earthbound creatures will be said to stand "in" the tile, not on it
1892     TM_LIST_IN_SIDEBAR              = Fl(18),       // terrain will be listed in the sidebar with a description of the terrain type
1893     TM_VISUALLY_DISTINCT            = Fl(19),       // terrain will be color-adjusted if necessary so the character stands out from the background
1894     TM_BRIGHT_MEMORY                = Fl(20),       // no blue fade when this tile is out of sight
1895     TM_EXPLOSIVE_PROMOTE            = Fl(21),       // when burned, will promote to promoteType instead of burningType if surrounded by tiles with T_IS_FIRE or TM_EXPLOSIVE_PROMOTE
1896     TM_CONNECTS_LEVEL               = Fl(22),       // will be treated as passable for purposes of calculating level connectedness, irrespective of other aspects of this terrain layer
1897     TM_INTERRUPT_EXPLORATION_WHEN_SEEN = Fl(23),    // will generate a message when discovered during exploration to interrupt exploration
1898     TM_INVERT_WHEN_HIGHLIGHTED      = Fl(24),       // will flip fore and back colors when highlighted with pathing
1899     TM_SWAP_ENCHANTS_ACTIVATION     = Fl(25),       // in machine, swap item enchantments when two suitable items are on this terrain, and activate the machine when that happens
1900 
1901     TM_PROMOTES_ON_STEP             = (TM_PROMOTES_ON_CREATURE | TM_PROMOTES_ON_ITEM),
1902 };
1903 
1904 enum statusEffects {
1905     STATUS_SEARCHING = 0,
1906     STATUS_DONNING,
1907     STATUS_WEAKENED,
1908     STATUS_TELEPATHIC,
1909     STATUS_HALLUCINATING,
1910     STATUS_LEVITATING,
1911     STATUS_SLOWED,
1912     STATUS_HASTED,
1913     STATUS_CONFUSED,
1914     STATUS_BURNING,
1915     STATUS_PARALYZED,
1916     STATUS_POISONED,
1917     STATUS_STUCK,
1918     STATUS_NAUSEOUS,
1919     STATUS_DISCORDANT,
1920     STATUS_IMMUNE_TO_FIRE,
1921     STATUS_EXPLOSION_IMMUNITY,
1922     STATUS_NUTRITION,
1923     STATUS_ENTERS_LEVEL_IN,
1924     STATUS_ENRAGED, // temporarily ignores normal MA_AVOID_CORRIDORS behavior
1925     STATUS_MAGICAL_FEAR,
1926     STATUS_ENTRANCED,
1927     STATUS_DARKNESS,
1928     STATUS_LIFESPAN_REMAINING,
1929     STATUS_SHIELDED,
1930     STATUS_INVISIBLE,
1931     STATUS_AGGRAVATING,
1932     NUMBER_OF_STATUS_EFFECTS,
1933 };
1934 
1935 enum hordeFlags {
1936     HORDE_DIES_ON_LEADER_DEATH      = Fl(0),    // if the leader dies, the horde will die instead of electing new leader
1937     HORDE_IS_SUMMONED               = Fl(1),    // minions summoned when any creature is the same species as the leader and casts summon
1938     HORDE_SUMMONED_AT_DISTANCE      = Fl(2),    // summons will appear across the level, and will naturally path back to the leader
1939     HORDE_LEADER_CAPTIVE            = Fl(3),    // the leader is in chains and the followers are guards
1940     HORDE_NO_PERIODIC_SPAWN         = Fl(4),    // can spawn only when the level begins -- not afterwards
1941     HORDE_ALLIED_WITH_PLAYER        = Fl(5),
1942 
1943     HORDE_MACHINE_BOSS              = Fl(6),    // used in machines for a boss challenge
1944     HORDE_MACHINE_WATER_MONSTER     = Fl(7),    // used in machines where the room floods with shallow water
1945     HORDE_MACHINE_CAPTIVE           = Fl(8),    // powerful captive monsters without any captors
1946     HORDE_MACHINE_STATUE            = Fl(9),    // the kinds of monsters that make sense in a statue
1947     HORDE_MACHINE_TURRET            = Fl(10),   // turrets, for hiding in walls
1948     HORDE_MACHINE_MUD               = Fl(11),   // bog monsters, for hiding in mud
1949     HORDE_MACHINE_KENNEL            = Fl(12),   // monsters that can appear in cages in kennels
1950     HORDE_VAMPIRE_FODDER            = Fl(13),   // monsters that are prone to capture and farming by vampires
1951     HORDE_MACHINE_LEGENDARY_ALLY    = Fl(14),   // legendary allies
1952     HORDE_NEVER_OOD                 = Fl(15),   // Horde cannot be generated out of depth
1953     HORDE_MACHINE_THIEF             = Fl(16),   // monsters that can be generated in the key thief area machines
1954     HORDE_MACHINE_GOBLIN_WARREN     = Fl(17),   // can spawn in goblin warrens
1955     HORDE_SACRIFICE_TARGET          = Fl(18),   // can be the target of an assassination challenge; leader will get scary light.
1956 
1957     HORDE_MACHINE_ONLY              = (HORDE_MACHINE_BOSS | HORDE_MACHINE_WATER_MONSTER
1958                                        | HORDE_MACHINE_CAPTIVE | HORDE_MACHINE_STATUE
1959                                        | HORDE_MACHINE_TURRET | HORDE_MACHINE_MUD
1960                                        | HORDE_MACHINE_KENNEL | HORDE_VAMPIRE_FODDER
1961                                        | HORDE_MACHINE_LEGENDARY_ALLY | HORDE_MACHINE_THIEF
1962                                        | HORDE_MACHINE_GOBLIN_WARREN
1963                                        | HORDE_SACRIFICE_TARGET),
1964 };
1965 
1966 enum monsterBehaviorFlags {
1967     MONST_INVISIBLE                 = Fl(0),    // monster is invisible
1968     MONST_INANIMATE                 = Fl(1),    // monster has abbreviated stat bar display and is immune to many things
1969     MONST_IMMOBILE                  = Fl(2),    // monster won't move or perform melee attacks
1970     MONST_CARRY_ITEM_100            = Fl(3),    // monster carries an item 100% of the time
1971     MONST_CARRY_ITEM_25             = Fl(4),    // monster carries an item 25% of the time
1972     MONST_ALWAYS_HUNTING            = Fl(5),    // monster is never asleep or in wandering mode
1973     MONST_FLEES_NEAR_DEATH          = Fl(6),    // monster flees when under 25% health and re-engages when over 75%
1974     MONST_ATTACKABLE_THRU_WALLS     = Fl(7),    // can be attacked when embedded in a wall
1975     MONST_DEFEND_DEGRADE_WEAPON     = Fl(8),    // hitting the monster damages the weapon
1976     MONST_IMMUNE_TO_WEAPONS         = Fl(9),    // weapons ineffective
1977     MONST_FLIES                     = Fl(10),   // permanent levitation
1978     MONST_FLITS                     = Fl(11),   // moves randomly a third of the time
1979     MONST_IMMUNE_TO_FIRE            = Fl(12),   // won't burn, won't die in lava
1980     MONST_CAST_SPELLS_SLOWLY        = Fl(13),   // takes twice the attack duration to cast a spell
1981     MONST_IMMUNE_TO_WEBS            = Fl(14),   // monster passes freely through webs
1982     MONST_REFLECT_4                 = Fl(15),   // monster reflects projectiles as though wearing +4 armor of reflection
1983     MONST_NEVER_SLEEPS              = Fl(16),   // monster is always awake
1984     MONST_FIERY                     = Fl(17),   // monster carries an aura of flame (but no automatic fire light)
1985     MONST_INVULNERABLE              = Fl(18),   // monster is immune to absolutely everything
1986     MONST_IMMUNE_TO_WATER           = Fl(19),   // monster moves at full speed in deep water and (if player) doesn't drop items
1987     MONST_RESTRICTED_TO_LIQUID      = Fl(20),   // monster can move only on tiles that allow submersion
1988     MONST_SUBMERGES                 = Fl(21),   // monster can submerge in appropriate terrain
1989     MONST_MAINTAINS_DISTANCE        = Fl(22),   // monster tries to keep a distance of 3 tiles between it and player
1990     MONST_WILL_NOT_USE_STAIRS       = Fl(23),   // monster won't chase the player between levels
1991     MONST_DIES_IF_NEGATED           = Fl(24),   // monster will die if exposed to negation magic
1992     MONST_MALE                      = Fl(25),   // monster is male (or 50% likely to be male if also has MONST_FEMALE)
1993     MONST_FEMALE                    = Fl(26),   // monster is female (or 50% likely to be female if also has MONST_MALE)
1994     MONST_NOT_LISTED_IN_SIDEBAR     = Fl(27),   // monster doesn't show up in the sidebar
1995     MONST_GETS_TURN_ON_ACTIVATION   = Fl(28),   // monster never gets a turn, except when its machine is activated
1996     MONST_ALWAYS_USE_ABILITY        = Fl(29),   // monster will never fail to use special ability if eligible (no random factor)
1997     MONST_NO_POLYMORPH              = Fl(30),   // monster cannot result from a polymorph spell (liches, phoenixes and Warden of Yendor)
1998 
1999     NEGATABLE_TRAITS                = (MONST_INVISIBLE | MONST_DEFEND_DEGRADE_WEAPON | MONST_IMMUNE_TO_WEAPONS | MONST_FLIES
2000                                        | MONST_FLITS | MONST_IMMUNE_TO_FIRE | MONST_REFLECT_4 | MONST_FIERY | MONST_MAINTAINS_DISTANCE),
2001     MONST_TURRET                    = (MONST_IMMUNE_TO_WEBS | MONST_NEVER_SLEEPS | MONST_IMMOBILE | MONST_INANIMATE |
2002                                        MONST_ATTACKABLE_THRU_WALLS | MONST_WILL_NOT_USE_STAIRS),
2003     LEARNABLE_BEHAVIORS             = (MONST_INVISIBLE | MONST_FLIES | MONST_IMMUNE_TO_FIRE | MONST_REFLECT_4),
2004     MONST_NEVER_VORPAL_ENEMY        = (MONST_INANIMATE | MONST_INVULNERABLE | MONST_IMMOBILE | MONST_RESTRICTED_TO_LIQUID | MONST_GETS_TURN_ON_ACTIVATION | MONST_MAINTAINS_DISTANCE),
2005     MONST_NEVER_MUTATED             = (MONST_INVISIBLE | MONST_INANIMATE | MONST_IMMOBILE | MONST_INVULNERABLE),
2006 };
2007 
2008 enum monsterAbilityFlags {
2009     MA_HIT_HALLUCINATE              = Fl(0),    // monster can hit to cause hallucinations
2010     MA_HIT_STEAL_FLEE               = Fl(1),    // monster can steal an item and then run away
2011     MA_HIT_BURN                     = Fl(2),    // monster can hit to set you on fire
2012     MA_ENTER_SUMMONS                = Fl(3),    // monster will "become" its summoned leader, reappearing when that leader is defeated
2013     MA_HIT_DEGRADE_ARMOR            = Fl(4),    // monster damages armor
2014     MA_CAST_SUMMON                  = Fl(5),    // requires that there be one or more summon hordes with this monster type as the leader
2015     MA_SEIZES                       = Fl(6),    // monster seizes enemies before attacking
2016     MA_POISONS                      = Fl(7),    // monster's damage is dealt in the form of poison
2017     MA_DF_ON_DEATH                  = Fl(8),    // monster spawns its DF when it dies
2018     MA_CLONE_SELF_ON_DEFEND         = Fl(9),    // monster splits in two when struck
2019     MA_KAMIKAZE                     = Fl(10),   // monster dies instead of attacking
2020     MA_TRANSFERENCE                 = Fl(11),   // monster recovers 40 or 90% of the damage that it inflicts as health
2021     MA_CAUSES_WEAKNESS              = Fl(12),   // monster attacks cause weakness status in target
2022     MA_ATTACKS_PENETRATE            = Fl(13),   // monster attacks all adjacent enemies, like an axe
2023     MA_ATTACKS_ALL_ADJACENT         = Fl(14),   // monster attacks penetrate one layer of enemies, like a spear
2024     MA_ATTACKS_EXTEND               = Fl(15),   // monster attacks from a distance in a cardinal direction, like a whip
2025     MA_ATTACKS_STAGGER              = Fl(16),   // monster attacks will push the player backward by one space if there is room
2026     MA_AVOID_CORRIDORS              = Fl(17),   // monster will avoid corridors when hunting
2027 
2028     SPECIAL_HIT                     = (MA_HIT_HALLUCINATE | MA_HIT_STEAL_FLEE | MA_HIT_DEGRADE_ARMOR | MA_POISONS
2029                                        | MA_TRANSFERENCE | MA_CAUSES_WEAKNESS | MA_HIT_BURN | MA_ATTACKS_STAGGER),
2030     LEARNABLE_ABILITIES             = (MA_TRANSFERENCE | MA_CAUSES_WEAKNESS),
2031 
2032     MA_NON_NEGATABLE_ABILITIES      = (MA_ATTACKS_PENETRATE | MA_ATTACKS_ALL_ADJACENT | MA_ATTACKS_EXTEND | MA_ATTACKS_STAGGER),
2033     MA_NEVER_VORPAL_ENEMY           = (MA_KAMIKAZE),
2034     MA_NEVER_MUTATED                = (MA_KAMIKAZE),
2035 };
2036 
2037 enum monsterBookkeepingFlags {
2038     MB_WAS_VISIBLE              = Fl(0),    // monster was visible to player last turn
2039     MB_TELEPATHICALLY_REVEALED  = Fl(1),    // player can magically see monster and adjacent cells
2040     MB_PREPLACED                = Fl(2),    // monster dropped onto the level and requires post-processing
2041     MB_APPROACHING_UPSTAIRS     = Fl(3),    // following the player up the stairs
2042     MB_APPROACHING_DOWNSTAIRS   = Fl(4),    // following the player down the stairs
2043     MB_APPROACHING_PIT          = Fl(5),    // following the player down a pit
2044     MB_LEADER                   = Fl(6),    // monster is the leader of a horde
2045     MB_FOLLOWER                 = Fl(7),    // monster is a member of a horde
2046     MB_CAPTIVE                  = Fl(8),    // monster is all tied up
2047     MB_SEIZED                   = Fl(9),    // monster is being held
2048     MB_SEIZING                  = Fl(10),   // monster is holding another creature immobile
2049     MB_SUBMERGED                = Fl(11),   // monster is currently submerged and hence invisible until it attacks
2050     MB_JUST_SUMMONED            = Fl(12),   // used to mark summons so they can be post-processed
2051     MB_WILL_FLASH               = Fl(13),   // this monster will flash as soon as control is returned to the player
2052     MB_BOUND_TO_LEADER          = Fl(14),   // monster will die if the leader dies or becomes separated from the leader
2053     MB_MARKED_FOR_SACRIFICE     = Fl(15),   // scary glow, monster can be sacrificed in the appropriate machine
2054     MB_ABSORBING                = Fl(16),   // currently learning a skill by absorbing an enemy corpse
2055     MB_DOES_NOT_TRACK_LEADER    = Fl(17),   // monster will not follow its leader around
2056     MB_IS_FALLING               = Fl(18),   // monster is plunging downward at the end of the turn
2057     MB_IS_DYING                 = Fl(19),   // monster has already been killed and is awaiting the end-of-turn graveyard sweep (or in purgatory)
2058     MB_GIVEN_UP_ON_SCENT        = Fl(20),   // to help the monster remember that the scent map is a dead end
2059     MB_IS_DORMANT               = Fl(21),   // lurking, waiting to burst out
2060     MB_HAS_SOUL                 = Fl(22),   // slaying the monster will count toward weapon auto-ID
2061     MB_ALREADY_SEEN             = Fl(23),   // seeing this monster won't interrupt exploration
2062     MB_HAS_ENTRANCED_MOVED      = Fl(24)    // has already moved while entranced and should not move again
2063 };
2064 
2065 // Defines all creatures, which include monsters and the player:
2066 typedef struct creatureType {
2067     enum monsterTypes monsterID; // index number for the monsterCatalog
2068     char monsterName[COLS];
2069     enum displayGlyph displayChar;
2070     const color *foreColor;
2071     short maxHP;
2072     short defense;
2073     short accuracy;
2074     randomRange damage;
2075     long turnsBetweenRegen;     // turns to wait before regaining 1 HP
2076     short movementSpeed;
2077     short attackSpeed;
2078     enum dungeonFeatureTypes bloodType;
2079     enum lightType intrinsicLightType;
2080     boolean isLarge;    // used for size of psychic emanation
2081     short DFChance;                     // percent chance to spawn the dungeon feature per awake turn
2082     enum dungeonFeatureTypes DFType;    // kind of dungeon feature
2083     enum boltType bolts[20];
2084     unsigned long flags;
2085     unsigned long abilityFlags;
2086 } creatureType;
2087 
2088 typedef struct monsterWords {
2089     char flavorText[COLS*5];
2090     char absorbing[40];
2091     char absorbStatus[40];
2092     char attack[5][30];
2093     char DFMessage[DCOLS * 2];
2094     char summonMessage[DCOLS * 2];
2095 } monsterWords;
2096 
2097 enum creatureStates {
2098     MONSTER_SLEEPING,
2099     MONSTER_TRACKING_SCENT,
2100     MONSTER_WANDERING,
2101     MONSTER_FLEEING,
2102     MONSTER_ALLY,
2103 };
2104 
2105 enum creatureModes {
2106     MODE_NORMAL,
2107     MODE_PERM_FLEEING
2108 };
2109 
2110 typedef struct mutation {
2111     char title[100];
2112     const color *textColor;
2113     short healthFactor;
2114     short moveSpeedFactor;
2115     short attackSpeedFactor;
2116     short defenseFactor;
2117     short damageFactor;
2118     short DFChance;
2119     enum dungeonFeatureTypes DFType;
2120     enum lightType light;
2121     unsigned long monsterFlags;
2122     unsigned long monsterAbilityFlags;
2123     unsigned long forbiddenFlags;
2124     unsigned long forbiddenAbilityFlags;
2125     char description[1000];
2126     boolean canBeNegated;
2127 } mutation;
2128 
2129 typedef struct hordeType {
2130     enum monsterTypes leaderType;
2131 
2132     // membership information
2133     short numberOfMemberTypes;
2134     enum monsterTypes memberType[5];
2135     randomRange memberCount[5];
2136 
2137     // spawning information
2138     short minLevel;
2139     short maxLevel;
2140     short frequency;
2141     enum tileType spawnsIn;
2142     short machine;
2143 
2144     enum hordeFlags flags;
2145 } hordeType;
2146 
2147 typedef struct monsterClass {
2148     char name[30];
2149     short frequency;
2150     short maxDepth;
2151     enum monsterTypes memberList[15];
2152 } monsterClass;
2153 
2154 typedef struct creature {
2155     creatureType info;
2156     short xLoc;
2157     short yLoc;
2158     short depth;
2159     short currentHP;
2160     long turnsUntilRegen;
2161     short regenPerTurn;                 // number of HP to regenerate every single turn
2162     short weaknessAmount;               // number of points of weakness that are inflicted by the weakness status
2163     short poisonAmount;                 // number of points of damage per turn from poison
2164     enum creatureStates creatureState;  // current behavioral state
2165     enum creatureModes creatureMode;    // current behavioral mode (higher-level than state)
2166 
2167     short mutationIndex;                // what mutation the monster has (or -1 for none)
2168     boolean wasNegated;                 // the monster has lost abilities due to negation
2169 
2170     // Waypoints:
2171     short targetWaypointIndex;          // the index number of the waypoint we're pathing toward
2172     boolean waypointAlreadyVisited[MAX_WAYPOINT_COUNT]; // checklist of waypoints
2173     short lastSeenPlayerAt[2];          // last location at which the monster hunted the player
2174 
2175     short targetCorpseLoc[2];           // location of the corpse that the monster is approaching to gain its abilities
2176     char targetCorpseName[30];          // name of the deceased monster that we're approaching to gain its abilities
2177     unsigned long absorptionFlags;      // ability/behavior flags that the monster will gain when absorption is complete
2178     boolean absorbBehavior;             // above flag is behavior instead of ability (ignored if absorptionBolt is set)
2179     short absorptionBolt;               // bolt index that the monster will learn to cast when absorption is complete
2180     short corpseAbsorptionCounter;      // used to measure both the time until the monster stops being interested in the corpse,
2181                                         // and, later, the time until the monster finishes absorbing the corpse.
2182     short **mapToMe;                    // if a pack leader, this is a periodically updated pathing map to get to the leader
2183     short **safetyMap;                  // fleeing monsters store their own safety map when out of player FOV to avoid omniscience
2184     short ticksUntilTurn;               // how long before the creature gets its next move
2185 
2186     // Locally cached statistics that may be temporarily modified:
2187     short movementSpeed;
2188     short attackSpeed;
2189 
2190     short previousHealthPoints;         // remembers what your health proportion was at the start of the turn
2191     short turnsSpentStationary;         // how many (subjective) turns it's been since the creature moved between tiles
2192     short flashStrength;                // monster will flash soon; this indicates the percent strength of flash
2193     color flashColor;                   // the color that the monster will flash
2194     short status[NUMBER_OF_STATUS_EFFECTS];
2195     short maxStatus[NUMBER_OF_STATUS_EFFECTS]; // used to set the max point on the status bars
2196     unsigned long bookkeepingFlags;
2197     short spawnDepth;                   // keep track of the depth of the machine to which they relate (for activation monsters)
2198     short machineHome;                  // monsters that spawn in a machine keep track of the machine number here (for activation monsters)
2199     short xpxp;                         // exploration experience (used to time telepathic bonding for allies)
2200     short newPowerCount;                // how many more times this monster can absorb a fallen monster
2201     short totalPowerCount;              // how many times has the monster been empowered? Used to recover abilities when negated.
2202 
2203     struct creature *leader;                 // only if monster is a follower
2204     struct creature *carriedMonster; // when vampires turn into bats, one of the bats restores the vampire when it dies
2205     struct item *carriedItem;                // only used for monsters
2206 } creature;
2207 
2208 typedef struct creatureListNode {
2209     creature *creature;
2210     // A list node is just a creature that also knows who comes next.
2211     struct creatureListNode *nextCreature;
2212 } creatureListNode;
2213 
2214 typedef struct creatureList {
2215     creatureListNode* head;
2216 } creatureList;
2217 
2218 typedef struct creatureIterator {
2219     creatureList *list; // used for restarting
2220     creatureListNode *next;
2221 } creatureIterator;
2222 
2223 enum NGCommands {
2224     NG_NOTHING = 0,
2225     NG_NEW_GAME,
2226     NG_NEW_GAME_WITH_SEED,
2227     NG_OPEN_GAME,
2228     NG_VIEW_RECORDING,
2229     NG_HIGH_SCORES,
2230     NG_QUIT,
2231 };
2232 
2233 enum featTypes {
2234     FEAT_PURE_MAGE = 0,
2235     FEAT_PURE_WARRIOR,
2236     FEAT_PACIFIST,
2237     FEAT_ARCHIVIST,
2238     FEAT_COMPANION,
2239     FEAT_SPECIALIST,
2240     FEAT_JELLYMANCER,
2241     FEAT_INDOMITABLE,
2242     FEAT_ASCETIC,
2243     FEAT_DRAGONSLAYER,
2244     FEAT_PALADIN,
2245     FEAT_TONE,
2246 
2247     FEAT_COUNT,
2248 };
2249 
2250 // these are basically global variables pertaining to the game state and player's unique variables:
2251 typedef struct playerCharacter {
2252     boolean wizard;                     // in wizard mode
2253 
2254     short depthLevel;                   // which dungeon level are we on
2255     short deepestLevel;
2256     boolean disturbed;                  // player should stop auto-acting
2257     boolean gameInProgress;             // the game is in progress (the player has not died, won or quit yet)
2258     boolean gameHasEnded;               // stop everything and go to death screen
2259     boolean highScoreSaved;             // so that it saves the high score only once
2260     boolean blockCombatText;            // busy auto-fighting
2261     boolean autoPlayingLevel;           // seriously, don't interrupt
2262     boolean automationActive;           // cut some corners during redraws to speed things up
2263     boolean justRested;                 // previous turn was a rest -- used in stealth
2264     boolean justSearched;               // previous turn was a search -- used in manual searches
2265     boolean cautiousMode;               // used to prevent careless deaths caused by holding down a key
2266     boolean receivedLevitationWarning;  // only warn you once when you're hovering dangerously over liquid
2267     boolean updatedSafetyMapThisTurn;   // so it's updated no more than once per turn
2268     boolean updatedAllySafetyMapThisTurn;   // so it's updated no more than once per turn
2269     boolean updatedMapToSafeTerrainThisTurn;// so it's updated no more than once per turn
2270     boolean updatedMapToShoreThisTurn;      // so it's updated no more than once per turn
2271     boolean easyMode;                   // enables easy mode
2272     boolean inWater;                    // helps with the blue water filter effect
2273     boolean heardCombatThisTurn;        // so you get only one "you hear combat in the distance" per turn
2274     boolean creaturesWillFlashThisTurn; // there are creatures out there that need to flash before the turn ends
2275     boolean staleLoopMap;               // recalculate the loop map at the end of the turn
2276     boolean alreadyFell;                // so the player can fall only one depth per turn
2277     boolean eligibleToUseStairs;        // so the player uses stairs only when he steps onto them
2278     boolean trueColorMode;              // whether lighting effects are disabled
2279     boolean displayAggroRangeMode;      // whether your stealth range is displayed
2280     boolean quit;                       // to skip the typical end-game theatrics when the player quits
2281     uint64_t seed;                      // the master seed for generating the entire dungeon
2282     short RNG;                          // which RNG are we currently using?
2283     unsigned long gold;                 // how much gold we have
2284     unsigned long goldGenerated;        // how much gold has been generated on the levels, not counting gold held by monsters
2285     short strength;
2286     unsigned short monsterSpawnFuse;    // how much longer till a random monster spawns
2287 
2288     item *weapon;
2289     item *armor;
2290     item *ringLeft;
2291     item *ringRight;
2292     item *swappedIn;
2293     item *swappedOut;
2294 
2295     flare **flares;
2296     short flareCount;
2297     short flareCapacity;
2298 
2299     creature *yendorWarden;
2300 
2301     lightSource minersLight;
2302     fixpt minersLightRadius;
2303     short ticksTillUpdateEnvironment;   // so that some periodic things happen in objective time
2304     unsigned short scentTurnNumber;     // helps make scent-casting work
2305     unsigned long playerTurnNumber;     // number of input turns in recording. Does not increment during paralysis.
2306     unsigned long absoluteTurnNumber;   // number of turns since the beginning of time. Always increments.
2307     signed long milliseconds;           // milliseconds since launch, to decide whether to engage cautious mode
2308     short xpxpThisTurn;                 // how many squares the player explored this turn
2309     short aggroRange;                   // distance from which monsters will notice you
2310 
2311     short previousPoisonPercent;        // and your poison proportion, to display percentage alerts for each.
2312 
2313     short upLoc[2];                     // upstairs location this level
2314     short downLoc[2];                   // downstairs location this level
2315 
2316     short cursorLoc[2];                 // used for the return key functionality
2317     creature *lastTarget;               // to keep track of the last monster the player has thrown at or zapped
2318     item *lastItemThrown;
2319     short rewardRoomsGenerated;         // to meter the number of reward machines
2320     short machineNumber;                // so each machine on a level gets a unique number
2321     short sidebarLocationList[ROWS*2][2];   // to keep track of which location each line of the sidebar references
2322 
2323     // maps
2324     short **mapToShore;                 // how many steps to get back to shore
2325     short **mapToSafeTerrain;           // so monsters can get to safety
2326 
2327     // recording info
2328     boolean recording;                  // whether we are recording the game
2329     boolean playbackMode;               // whether we're viewing a recording instead of playing
2330     unsigned short patchVersion;        // what patch version of the game this was recorded on
2331     char versionString[16];             // the version string saved into the recording file
2332     unsigned long currentTurnNumber;    // how many turns have elapsed
2333     unsigned long howManyTurns;         // how many turns are in this recording
2334     short howManyDepthChanges;          // how many times the player changes depths
2335     short playbackDelayPerTurn;         // base playback speed; modified per turn by events
2336     short playbackDelayThisTurn;        // playback speed as modified
2337     boolean playbackPaused;
2338     boolean playbackFastForward;        // for loading saved games and such -- disables drawing and prevents pauses
2339     boolean playbackOOS;                // playback out of sync -- no unpausing allowed
2340     boolean playbackOmniscience;        // whether to reveal all the map during playback
2341     boolean playbackBetweenTurns;       // i.e. waiting for a top-level input -- iff, permit playback commands
2342     unsigned long nextAnnotationTurn;   // the turn number during which to display the next annotation
2343     char nextAnnotation[5000];          // the next annotation
2344     unsigned long locationInAnnotationFile; // how far we've read in the annotations file
2345 
2346     // metered items
2347     long long foodSpawned;                    // amount of nutrition units spawned so far this game
2348     short lifePotionFrequency;
2349     short lifePotionsSpawned;
2350     short strengthPotionFrequency;
2351     short enchantScrollFrequency;
2352 
2353     // ring bonuses:
2354     short clairvoyance;
2355     short stealthBonus;
2356     short regenerationBonus;
2357     short lightMultiplier;
2358     short awarenessBonus;
2359     short transference;
2360     short wisdomBonus;
2361     short reaping;
2362 
2363     // feats:
2364     boolean featRecord[FEAT_COUNT];
2365 
2366     // waypoints:
2367     short **wpDistance[MAX_WAYPOINT_COUNT];
2368     short wpCount;
2369     short wpCoordinates[MAX_WAYPOINT_COUNT][2];
2370     short wpRefreshTicker;
2371 
2372     // cursor trail:
2373     short cursorPathIntensity;
2374     boolean cursorMode;
2375 
2376     // What do you want to do, player -- play, play with seed, resume, recording, high scores or quit?
2377     enum NGCommands nextGame;
2378     char nextGamePath[BROGUE_FILENAME_MAX];
2379     uint64_t nextGameSeed;
2380 } playerCharacter;
2381 
2382 // Stores the necessary info about a level so it can be regenerated:
2383 typedef struct levelData {
2384     boolean visited;
2385     pcell mapStorage[DCOLS][DROWS];
2386     struct item *items;
2387     struct creatureList monsters;
2388     struct creatureList dormantMonsters;
2389     short **scentMap;
2390     uint64_t levelSeed;
2391     short upStairsLoc[2];
2392     short downStairsLoc[2];
2393     short playerExitedVia[2];
2394     unsigned long awaySince;
2395 } levelData;
2396 
2397 enum machineFeatureFlags {
2398     MF_GENERATE_ITEM                = Fl(0),    // feature entails generating an item (overridden if the machine is adopting an item)
2399     MF_OUTSOURCE_ITEM_TO_MACHINE    = Fl(1),    // item must be adopted by another machine
2400     MF_BUILD_VESTIBULE              = Fl(2),    // call this at the origin of a door room to create a new door guard machine there
2401     MF_ADOPT_ITEM                   = Fl(3),    // this feature will take the adopted item (be it from another machine or a previous feature)
2402     MF_NO_THROWING_WEAPONS          = Fl(4),    // the generated item cannot be a throwing weapon
2403     MF_GENERATE_HORDE               = Fl(5),    // generate a monster horde that has all of the horde flags
2404     MF_BUILD_AT_ORIGIN              = Fl(6),    // generate this feature at the room entrance
2405     // unused                       = Fl(7),    //
2406     MF_PERMIT_BLOCKING              = Fl(8),    // permit the feature to block the map's passability (e.g. to add a locked door)
2407     MF_TREAT_AS_BLOCKING            = Fl(9),    // treat this terrain as though it blocks, for purposes of deciding whether it can be placed there
2408     MF_NEAR_ORIGIN                  = Fl(10),   // feature must spawn in the rough quarter of tiles closest to the origin
2409     MF_FAR_FROM_ORIGIN              = Fl(11),   // feature must spawn in the rough quarter of tiles farthest from the origin
2410     MF_MONSTER_TAKE_ITEM            = Fl(12),   // the item associated with this feature (including if adopted) will be in possession of the horde leader that's generated
2411     MF_MONSTER_SLEEPING             = Fl(13),   // the monsters should be asleep when generated
2412     MF_MONSTER_FLEEING              = Fl(14),   // the monsters should be permanently fleeing when generated
2413     MF_EVERYWHERE                   = Fl(15),   // generate the feature on every tile of the machine (e.g. carpeting)
2414     MF_ALTERNATIVE                  = Fl(16),   // build only one feature that has this flag per machine; the rest are skipped
2415     MF_ALTERNATIVE_2                = Fl(17),   // same as MF_ALTERNATIVE, but provides for a second set of alternatives of which only one will be chosen
2416     MF_REQUIRE_GOOD_RUNIC           = Fl(18),   // generated item must be uncursed runic
2417     MF_MONSTERS_DORMANT             = Fl(19),   // monsters are dormant, and appear when a dungeon feature with DFF_ACTIVATE_DORMANT_MONSTER spawns on their tile
2418     // unused                       = Fl(20),   //
2419     MF_BUILD_IN_WALLS               = Fl(21),   // build in an impassable tile that is adjacent to the interior
2420     MF_BUILD_ANYWHERE_ON_LEVEL      = Fl(22),   // build anywhere on the level that is not inside the machine
2421     MF_REPEAT_UNTIL_NO_PROGRESS     = Fl(23),   // keep trying to build this feature set until no changes are made
2422     MF_IMPREGNABLE                  = Fl(24),   // this feature's location will be immune to tunneling
2423     MF_IN_VIEW_OF_ORIGIN            = Fl(25),   // this feature must be in view of the origin
2424     MF_IN_PASSABLE_VIEW_OF_ORIGIN   = Fl(26),   // this feature must be in view of the origin, where "view" is blocked by pathing blockers
2425     MF_NOT_IN_HALLWAY               = Fl(27),   // the feature location must have a passableArcCount of <= 1
2426     MF_NOT_ON_LEVEL_PERIMETER       = Fl(28),   // don't build it in the outermost walls of the level
2427     MF_SKELETON_KEY                 = Fl(29),   // if a key is generated or adopted by this feature, it will open all locks in this machine.
2428     MF_KEY_DISPOSABLE               = Fl(30),   // if a key is generated or adopted, it will self-destruct after being used at this current location.
2429 };
2430 
2431 typedef struct machineFeature {
2432     // terrain
2433     enum dungeonFeatureTypes featureDF; // generate this DF at the feature location (0 for none)
2434     enum tileType terrain;              // generate this terrain tile at the feature location (0 for none)
2435     enum dungeonLayers layer;           // generate the terrain tile in this layer
2436 
2437     short instanceCountRange[2];        // generate this range of instances of this feature
2438     short minimumInstanceCount;         // abort if fewer than this
2439 
2440     // items: these will be ignored if the feature is adopting an item
2441     short itemCategory;                 // generate this category of item (or -1 for random)
2442     short itemKind;                     // generate this kind of item (or -1 for random)
2443 
2444     short monsterID;                    // generate a monster of this kind if MF_GENERATE_MONSTER is set
2445 
2446     short personalSpace;                // subsequent features must be generated more than this many tiles away from this feature
2447     unsigned long hordeFlags;           // choose a monster horde based on this
2448     unsigned long itemFlags;            // assign these flags to the item
2449     unsigned long flags;                // feature flags
2450 } machineFeature;
2451 
2452 enum blueprintFlags {
2453     BP_ADOPT_ITEM                   = Fl(0),    // the machine must adopt an item (e.g. a door key)
2454     BP_VESTIBULE                    = Fl(1),    // spawns in a doorway (location must be given) and expands outward, to guard the room
2455     BP_PURGE_PATHING_BLOCKERS       = Fl(2),    // clean out traps and other T_PATHING_BLOCKERs
2456     BP_PURGE_INTERIOR               = Fl(3),    // clean out all of the terrain in the interior before generating the machine
2457     BP_PURGE_LIQUIDS                = Fl(4),    // clean out all of the liquids in the interior before generating the machine
2458     BP_SURROUND_WITH_WALLS          = Fl(5),    // fill in any impassable gaps in the perimeter (e.g. water, lava, brimstone, traps) with wall
2459     BP_IMPREGNABLE                  = Fl(6),    // impassable perimeter and interior tiles are locked; tunneling bolts will bounce off harmlessly
2460     BP_REWARD                       = Fl(7),    // metered reward machines
2461     BP_OPEN_INTERIOR                = Fl(8),    // clear out walls in the interior, widen the interior until convex or bumps into surrounding areas
2462     BP_MAXIMIZE_INTERIOR            = Fl(9),    // same as BP_OPEN_INTERIOR but expands the room as far as it can go, potentially surrounding the whole level.
2463     BP_ROOM                         = Fl(10),   // spawns in a dead-end room that is dominated by a chokepoint of the given size (as opposed to a random place of the given size)
2464     BP_TREAT_AS_BLOCKING            = Fl(11),   // abort the machine if, were it filled with wall tiles, it would disrupt the level connectivity
2465     BP_REQUIRE_BLOCKING             = Fl(12),   // abort the machine unless, were it filled with wall tiles, it would disrupt the level connectivity
2466     BP_NO_INTERIOR_FLAG             = Fl(13),   // don't flag the area as being part of a machine
2467     BP_REDESIGN_INTERIOR            = Fl(14),   // nuke and pave -- delete all terrain in the interior and build entirely new rooms within the bounds
2468 };
2469 
2470 typedef struct blueprint {
2471     short depthRange[2];                // machine must be built between these dungeon depths
2472     short roomSize[2];                  // machine must be generated in a room of this size
2473     short frequency;                    // frequency (number of tickets this blueprint enters in the blueprint selection raffle)
2474     short featureCount;                 // how many different types of features follow (max of 20)
2475     short dungeonProfileType;           // if BP_REDESIGN_INTERIOR is set, which dungeon profile do we use?
2476     unsigned long flags;                // blueprint flags
2477     machineFeature feature[20];         // the features themselves
2478 } blueprint;
2479 
2480 enum machineTypes {
2481     // Reward rooms:
2482     MT_REWARD_MULTI_LIBRARY = 1,
2483     MT_REWARD_MONO_LIBRARY,
2484     MT_REWARD_CONSUMABLES,
2485     MT_REWARD_PEDESTALS_PERMANENT,
2486     MT_REWARD_PEDESTALS_CONSUMABLE,
2487     MT_REWARD_COMMUTATION_ALTARS,
2488     MT_REWARD_RESURRECTION_ALTAR,
2489     MT_REWARD_ADOPTED_ITEM,
2490     MT_REWARD_DUNGEON,
2491     MT_REWARD_KENNEL,
2492     MT_REWARD_VAMPIRE_LAIR,
2493     MT_REWARD_ASTRAL_PORTAL,
2494     MT_REWARD_GOBLIN_WARREN,
2495     MT_REWARD_SENTINEL_SANCTUARY,
2496 
2497     // Amulet holder:
2498     MT_AMULET_AREA,
2499 
2500     // Door guard machines:
2501     MT_LOCKED_DOOR_VESTIBULE,
2502     MT_SECRET_DOOR_VESTIBULE,
2503     MT_SECRET_LEVER_VESTIBULE,
2504     MT_FLAMMABLE_BARRICADE_VESTIBULE,
2505     MT_STATUE_SHATTERING_VESTIBULE,
2506     MT_STATUE_MONSTER_VESTIBULE,
2507     MT_THROWING_TUTORIAL_VESTIBULE,
2508     MT_PIT_TRAPS_VESTIBULE,
2509     MT_BECKONING_OBSTACLE_VESTIBULE,
2510     MT_GUARDIAN_VESTIBULE,
2511 
2512     // Key guard machines:
2513     MT_KEY_REWARD_LIBRARY,
2514     MT_KEY_SECRET_ROOM,
2515     MT_KEY_THROWING_TUTORIAL_AREA,
2516     MT_KEY_RAT_TRAP_ROOM,
2517     MT_KEY_FIRE_TRANSPORTATION_ROOM,
2518     MT_KEY_FLOOD_TRAP_ROOM,
2519     MT_KEY_FIRE_TRAP_ROOM,
2520     MT_KEY_THIEF_AREA,
2521     MT_KEY_COLLAPSING_FLOOR_AREA,
2522     MT_KEY_PIT_TRAP_ROOM,
2523     MT_KEY_LEVITATION_ROOM,
2524     MT_KEY_WEB_CLIMBING_ROOM,
2525     MT_KEY_LAVA_MOAT_ROOM,
2526     MT_KEY_LAVA_MOAT_AREA,
2527     MT_KEY_POISON_GAS_TRAP_ROOM,
2528     MT_KEY_EXPLOSIVE_TRAP_ROOM,
2529     MT_KEY_BURNING_TRAP_ROOM,
2530     MT_KEY_STATUARY_TRAP_AREA,
2531     MT_KEY_GUARDIAN_WATER_PUZZLE_ROOM,
2532     MT_KEY_GUARDIAN_GAUNTLET_ROOM,
2533     MT_KEY_GUARDIAN_CORRIDOR_ROOM,
2534     MT_KEY_SACRIFICE_ROOM,
2535     MT_KEY_SUMMONING_CIRCLE_ROOM,
2536     MT_KEY_BECKONING_OBSTACLE_ROOM,
2537     MT_KEY_WORM_TRAP_AREA,
2538     MT_KEY_MUD_TRAP_ROOM,
2539     MT_KEY_ELECTRIC_CRYSTALS_ROOM,
2540     MT_KEY_ZOMBIE_TRAP_ROOM,
2541     MT_KEY_PHANTOM_TRAP_ROOM,
2542     MT_KEY_WORM_TUNNEL_ROOM,
2543     MT_KEY_TURRET_TRAP_ROOM,
2544     MT_KEY_BOSS_ROOM,
2545 
2546     // Thematic machines:
2547     MT_BLOODFLOWER_AREA,
2548     MT_SHRINE_AREA,
2549     MT_IDYLL_AREA,
2550     MT_SWAMP_AREA,
2551     MT_CAMP_AREA,
2552     MT_REMNANT_AREA,
2553     MT_DISMAL_AREA,
2554     MT_BRIDGE_TURRET_AREA,
2555     MT_LAKE_PATH_TURRET_AREA,
2556     MT_PARALYSIS_TRAP_AREA,
2557     MT_PARALYSIS_TRAP_HIDDEN_AREA,
2558     MT_TRICK_STATUE_AREA,
2559     MT_WORM_AREA,
2560     MT_SENTINEL_AREA,
2561 
2562     NUMBER_BLUEPRINTS,
2563 };
2564 
2565 typedef struct autoGenerator {
2566     // What spawns:
2567     enum tileType terrain;
2568     enum dungeonLayers layer;
2569 
2570     enum dungeonFeatureTypes DFType;
2571 
2572     enum machineTypes machine; // Machine placement also respects BP_ placement flags in the machine blueprint
2573 
2574     // Parameters governing when and where it spawns:
2575     enum tileType requiredDungeonFoundationType;
2576     enum tileType requiredLiquidFoundationType;
2577     short minDepth;
2578     short maxDepth;
2579     short frequency;
2580     short minNumberIntercept; // actually intercept * 100
2581     short minNumberSlope; // actually slope * 100
2582     short maxNumber;
2583 } autoGenerator;
2584 
2585 #define NUMBER_AUTOGENERATORS 49
2586 
2587 typedef struct feat {
2588     char name[100];
2589     char description[200];
2590     boolean initialValue;
2591 } feat;
2592 
2593 #define PDS_FORBIDDEN   -1
2594 #define PDS_OBSTRUCTION -2
2595 #define PDS_CELL(map, x, y) ((map)->links + ((x) + DCOLS * (y)))
2596 
2597 typedef struct brogueButton {
2598     char text[COLS*3];          // button label; can include color escapes
2599     short x;                    // button's leftmost cell will be drawn at (x, y)
2600     short y;
2601     signed long hotkey[10];     // up to 10 hotkeys to trigger the button
2602     color buttonColor;          // background of the button; further gradient-ized when displayed
2603     short opacity;              // further reduced by 50% if not enabled
2604     enum displayGlyph symbol[COLS];         // Automatically replace the nth asterisk in the button label text with
2605                                 // the nth character supplied here, if one is given.
2606                                 // (Primarily to display magic character and item symbols in the inventory display.)
2607     unsigned long flags;
2608 } brogueButton;
2609 
2610 enum buttonDrawStates {
2611     BUTTON_NORMAL = 0,
2612     BUTTON_HOVER,
2613     BUTTON_PRESSED,
2614 };
2615 
2616 enum BUTTON_FLAGS {
2617     B_DRAW                  = Fl(0),
2618     B_ENABLED               = Fl(1),
2619     B_GRADIENT              = Fl(2),
2620     B_HOVER_ENABLED         = Fl(3),
2621     B_WIDE_CLICK_AREA       = Fl(4),
2622     B_KEYPRESS_HIGHLIGHT    = Fl(5),
2623 };
2624 
2625 typedef struct buttonState {
2626     // Indices of the buttons that are doing stuff:
2627     short buttonFocused;
2628     short buttonDepressed;
2629 
2630     // Index of the selected button:
2631     short buttonChosen;
2632 
2633     // The buttons themselves:
2634     short buttonCount;
2635     brogueButton buttons[50];
2636 
2637     // The window location, to determine whether a click is a cancelation:
2638     short winX;
2639     short winY;
2640     short winWidth;
2641     short winHeight;
2642 
2643     // Graphical buffers:
2644     cellDisplayBuffer dbuf[COLS][ROWS]; // Where buttons are drawn.
2645     cellDisplayBuffer rbuf[COLS][ROWS]; // Reversion screen state.
2646 } buttonState;
2647 
2648 enum messageFlags {
2649     REQUIRE_ACKNOWLEDGMENT        = Fl(0),
2650     REFRESH_SIDEBAR               = Fl(1),
2651     FOLDABLE                      = Fl(2),
2652 };
2653 
2654 typedef struct archivedMessage {
2655     char message[COLS*2];
2656     unsigned char count;          // how many times this message appears
2657     unsigned long turn;           // player turn of the first occurrence
2658     enum messageFlags flags;
2659 } archivedMessage;
2660 
2661 extern boolean serverMode;
2662 extern boolean hasGraphics;
2663 extern enum graphicsModes graphicsMode;
2664 
2665 #if defined __cplusplus
2666 extern "C" {
2667 #endif
2668 
2669     // Utilities.c - String functions
2670     boolean endswith(const char *str, const char *ending);
2671     void append(char *str, char *ending, int bufsize);
2672 
2673     void rogueMain();
2674     void executeEvent(rogueEvent *theEvent);
2675     boolean fileExists(const char *pathname);
2676     boolean chooseFile(char *path, char *prompt, char *defaultName, char *suffix);
2677     boolean openFile(const char *path);
2678     void initializeRogue(uint64_t seed);
2679     void gameOver(char *killedBy, boolean useCustomPhrasing);
2680     void victory(boolean superVictory);
2681     void enableEasyMode();
2682     boolean tryParseUint64(char *str, uint64_t *num);
2683     uint64_t rand_64bits();
2684     long rand_range(long lowerBound, long upperBound);
2685     uint64_t seedRandomGenerator(uint64_t seed);
2686     short randClumpedRange(short lowerBound, short upperBound, short clumpFactor);
2687     short randClump(randomRange theRange);
2688     boolean rand_percent(short percent);
2689     void shuffleList(short *list, short listLength);
2690     void fillSequentialList(short *list, short listLength);
2691     fixpt fp_round(fixpt x);
2692     fixpt fp_pow(fixpt base, int expn);
2693     fixpt fp_sqrt(fixpt val);
2694     short unflag(unsigned long flag);
2695     void considerCautiousMode();
2696     void refreshScreen();
2697     void displayLevel();
2698     void storeColorComponents(char components[3], const color *theColor);
2699     boolean separateColors(color *fore, color *back);
2700     void bakeColor(color *theColor);
2701     void shuffleTerrainColors(short percentOfCells, boolean refreshCells);
2702     void normColor(color *baseColor, const short aggregateMultiplier, const short colorTranslation);
2703     void getCellAppearance(short x, short y, enum displayGlyph *returnChar, color *returnForeColor, color *returnBackColor);
2704     void logBuffer(char array[DCOLS][DROWS]);
2705     //void logBuffer(short **array);
2706     boolean search(short searchStrength);
2707     boolean proposeOrConfirmLocation(short x, short y, char *failureMessage);
2708     boolean useStairs(short stairDirection);
2709     short passableArcCount(short x, short y);
2710     void analyzeMap(boolean calculateChokeMap);
2711     boolean buildAMachine(enum machineTypes bp,
2712                           short originX, short originY,
2713                           unsigned long requiredMachineFlags,
2714                           item *adoptiveItem,
2715                           item *parentSpawnedItems[50],
2716                           creature *parentSpawnedMonsters[50]);
2717     void attachRooms(short **grid, const dungeonProfile *theDP, short attempts, short maxRoomCount);
2718     void digDungeon();
2719     void updateMapToShore();
2720     short levelIsDisconnectedWithBlockingMap(char blockingMap[DCOLS][DROWS], boolean countRegionSize);
2721     void resetDFMessageEligibility();
2722     boolean fillSpawnMap(enum dungeonLayers layer,
2723                          enum tileType surfaceTileType,
2724                          char spawnMap[DCOLS][DROWS],
2725                          boolean blockedByOtherLayers,
2726                          boolean refresh,
2727                          boolean superpriority);
2728     boolean spawnDungeonFeature(short x, short y, dungeonFeature *feat, boolean refreshCell, boolean abortIfBlocking);
2729     void restoreMonster(creature *monst, short **mapToStairs, short **mapToPit);
2730     void restoreItem(item *theItem);
2731     void refreshWaypoint(short wpIndex);
2732     void setUpWaypoints();
2733     void zeroOutGrid(char grid[DCOLS][DROWS]);
2734     short oppositeDirection(short theDir);
2735 
2736     void plotChar(enum displayGlyph inputChar,
2737                   short xLoc, short yLoc,
2738                   short backRed, short backGreen, short backBlue,
2739                   short foreRed, short foreGreen, short foreBlue);
2740     boolean pauseForMilliseconds(short milliseconds);
2741     boolean isApplicationActive();
2742     void nextKeyOrMouseEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance);
2743     void notifyEvent(short eventId, int data1, int data2, const char *str1, const char *str2);
2744     boolean takeScreenshot();
2745     enum graphicsModes setGraphicsMode(enum graphicsModes mode);
2746     boolean controlKeyIsDown();
2747     boolean shiftKeyIsDown();
2748     short getHighScoresList(rogueHighScoresEntry returnList[HIGH_SCORES_COUNT]);
2749     boolean saveHighScore(rogueHighScoresEntry theEntry);
2750     fileEntry *listFiles(short *fileCount, char **dynamicMemoryBuffer);
2751     void initializeLaunchArguments(enum NGCommands *command, char *path, uint64_t *seed);
2752 
2753     char nextKeyPress(boolean textInput);
2754     void refreshSideBar(short focusX, short focusY, boolean focusedEntityMustGoFirst);
2755     void printHelpScreen();
2756     void printDiscoveriesScreen();
2757     void printHighScores(boolean hiliteMostRecent);
2758     void displayGrid(short **map);
2759     void printSeed();
2760     void printProgressBar(short x, short y, const char barLabel[COLS], long amtFilled, long amtMax, color *fillColor, boolean dim);
2761     short printMonsterInfo(creature *monst, short y, boolean dim, boolean highlight);
2762     void describeHallucinatedItem(char *buf);
2763     short printItemInfo(item *theItem, short y, boolean dim, boolean highlight);
2764     short printTerrainInfo(short x, short y, short py, const char *description, boolean dim, boolean highlight);
2765     void rectangularShading(short x, short y, short width, short height,
2766                             const color *backColor, short opacity, cellDisplayBuffer dbuf[COLS][ROWS]);
2767     short printTextBox(char *textBuf, short x, short y, short width,
2768                        color *foreColor, color *backColor,
2769                        cellDisplayBuffer rbuf[COLS][ROWS],
2770                        brogueButton *buttons, short buttonCount);
2771     void printMonsterDetails(creature *monst, cellDisplayBuffer rbuf[COLS][ROWS]);
2772     void printFloorItemDetails(item *theItem, cellDisplayBuffer rbuf[COLS][ROWS]);
2773     unsigned long printCarriedItemDetails(item *theItem,
2774                                           short x, short y, short width,
2775                                           boolean includeButtons,
2776                                           cellDisplayBuffer rbuf[COLS][ROWS]);
2777     void funkyFade(cellDisplayBuffer displayBuf[COLS][ROWS], const color *colorStart, const color *colorEnd, short stepCount, short x, short y, boolean invert);
2778     void displayCenteredAlert(char *message);
2779     void flashMessage(char *message, short x, short y, int time, color *fColor, color *bColor);
2780     void flashTemporaryAlert(char *message, int time);
2781     void waitForAcknowledgment();
2782     void waitForKeystrokeOrMouseClick();
2783     boolean confirm(char *prompt, boolean alsoDuringPlayback);
2784     void refreshDungeonCell(short x, short y);
2785     void applyColorMultiplier(color *baseColor, const color *multiplierColor);
2786     void applyColorAverage(color *baseColor, const color *newColor, short averageWeight);
2787     void applyColorAugment(color *baseColor, const color *augmentingColor, short augmentWeight);
2788     void applyColorScalar(color *baseColor, short scalar);
2789     void applyColorBounds(color *baseColor, short lowerBound, short upperBound);
2790     void desaturate(color *baseColor, short weight);
2791     void randomizeColor(color *baseColor, short randomizePercent);
2792     void swapColors(color *color1, color *color2);
2793     void irisFadeBetweenBuffers(cellDisplayBuffer fromBuf[COLS][ROWS],
2794                                 cellDisplayBuffer toBuf[COLS][ROWS],
2795                                 short x, short y,
2796                                 short frameCount,
2797                                 boolean outsideIn);
2798     void colorBlendCell(short x, short y, color *hiliteColor, short hiliteStrength);
2799     void hiliteCell(short x, short y, const color *hiliteColor, short hiliteStrength, boolean distinctColors);
2800     void colorMultiplierFromDungeonLight(short x, short y, color *editColor);
2801     void plotCharWithColor(enum displayGlyph inputChar, short xLoc, short yLoc, const color *cellForeColor, const color *cellBackColor);
2802     void plotCharToBuffer(enum displayGlyph inputChar, short x, short y, color *foreColor, color *backColor, cellDisplayBuffer dbuf[COLS][ROWS]);
2803     void plotForegroundChar(enum displayGlyph inputChar, short x, short y, color *foreColor, boolean affectedByLighting);
2804     void commitDraws();
2805     void dumpLevelToScreen();
2806     void hiliteCharGrid(char hiliteCharGrid[DCOLS][DROWS], color *hiliteColor, short hiliteStrength);
2807     void blackOutScreen();
2808     void colorOverDungeon(const color *color);
2809     void copyDisplayBuffer(cellDisplayBuffer toBuf[COLS][ROWS], cellDisplayBuffer fromBuf[COLS][ROWS]);
2810     void clearDisplayBuffer(cellDisplayBuffer dbuf[COLS][ROWS]);
2811     color colorFromComponents(char rgb[3]);
2812     void overlayDisplayBuffer(cellDisplayBuffer overBuf[COLS][ROWS], cellDisplayBuffer previousBuf[COLS][ROWS]);
2813     void flashForeground(short *x, short *y, color **flashColor, short *flashStrength, short count, short frames);
2814     void flashCell(color *theColor, short frames, short x, short y);
2815     void colorFlash(const color *theColor, unsigned long reqTerrainFlags, unsigned long reqTileFlags, short frames, short maxRadius, short x, short y);
2816     void printString(const char *theString, short x, short y, color *foreColor, color*backColor, cellDisplayBuffer dbuf[COLS][ROWS]);
2817     short wrapText(char *to, const char *sourceText, short width);
2818     short printStringWithWrapping(char *theString, short x, short y, short width, color *foreColor,
2819                                   color*backColor, cellDisplayBuffer dbuf[COLS][ROWS]);
2820     boolean getInputTextString(char *inputText,
2821                                const char *prompt,
2822                                short maxLength,
2823                                const char *defaultEntry,
2824                                const char *promptSuffix,
2825                                short textEntryType,
2826                                boolean useDialogBox);
2827     void displayChokeMap();
2828     void displayLoops();
2829     boolean pauseBrogue(short milliseconds);
2830     void nextBrogueEvent(rogueEvent *returnEvent, boolean textInput, boolean colorsDance, boolean realInputEvenInPlayback);
2831     void executeMouseClick(rogueEvent *theEvent);
2832     void executeKeystroke(signed long keystroke, boolean controlKey, boolean shiftKey);
2833     void initializeLevel();
2834     void startLevel (short oldLevelNumber, short stairDirection);
2835     void updateMinersLightRadius();
2836     void freeCreature(creature *monst);
2837     void freeCreatureList(creatureList *list);
2838     void emptyGraveyard();
2839     void freeEverything();
2840     boolean randomMatchingLocation(short *x, short *y, short dungeonType, short liquidType, short terrainType);
2841     enum dungeonLayers highestPriorityLayer(short x, short y, boolean skipGas);
2842     enum dungeonLayers layerWithTMFlag(short x, short y, unsigned long flag);
2843     enum dungeonLayers layerWithFlag(short x, short y, unsigned long flag);
2844     char *tileFlavor(short x, short y);
2845     char *tileText(short x, short y);
2846     void describedItemBasedOnParameters(short theCategory, short theKind, short theQuantity, short theItemOriginDepth, char *buf);
2847     void describeLocation(char buf[DCOLS], short x, short y);
2848     void printLocationDescription(short x, short y);
2849     void useKeyAt(item *theItem, short x, short y);
2850     void playerRuns(short direction);
2851     void exposeCreatureToFire(creature *monst);
2852     void updateFlavorText();
2853     void updatePlayerUnderwaterness();
2854     boolean monsterShouldFall(creature *monst);
2855     void applyInstantTileEffectsToCreature(creature *monst);
2856     void vomit(creature *monst);
2857     void becomeAllyWith(creature *monst);
2858     void freeCaptive(creature *monst);
2859     boolean freeCaptivesEmbeddedAt(short x, short y);
2860     boolean handleWhipAttacks(creature *attacker, enum directions dir, boolean *aborted);
2861     boolean handleSpearAttacks(creature *attacker, enum directions dir, boolean *aborted);
2862     boolean diagonalBlocked(const short x1, const short y1, const short x2, const short y2, const boolean limitToPlayerKnowledge);
2863     boolean playerMoves(short direction);
2864     void calculateDistances(short **distanceMap,
2865                             short destinationX, short destinationY,
2866                             unsigned long blockingTerrainFlags,
2867                             creature *traveler,
2868                             boolean canUseSecretDoors,
2869                             boolean eightWays);
2870     short pathingDistance(short x1, short y1, short x2, short y2, unsigned long blockingTerrainFlags);
2871     short nextStep(short **distanceMap, short x, short y, creature *monst, boolean reverseDirections);
2872     void travelRoute(short path[1000][2], short steps);
2873     void travel(short x, short y, boolean autoConfirm);
2874     void populateGenericCostMap(short **costMap);
2875     void getLocationFlags(const short x, const short y,
2876                           unsigned long *tFlags, unsigned long *TMFlags, unsigned long *cellFlags,
2877                           const boolean limitToPlayerKnowledge);
2878     void populateCreatureCostMap(short **costMap, creature *monst);
2879     enum directions adjacentFightingDir();
2880     void getExploreMap(short **map, boolean headingToStairs);
2881     boolean explore(short frameDelay);
2882     short getPlayerPathOnMap(short path[1000][2], short **map, short originX, short originY);
2883     void reversePath(short path[1000][2], short steps);
2884     void hilitePath(short path[1000][2], short steps, boolean unhilite);
2885     void clearCursorPath();
2886     void hideCursor();
2887     void showCursor();
2888     void mainInputLoop();
2889     boolean isDisturbed(short x, short y);
2890     void discover(short x, short y);
2891     short randValidDirectionFrom(creature *monst, short x, short y, boolean respectAvoidancePreferences);
2892     boolean exposeTileToElectricity(short x, short y);
2893     boolean exposeTileToFire(short x, short y, boolean alwaysIgnite);
2894     boolean cellCanHoldGas(short x, short y);
2895     void monstersFall();
2896     void updateEnvironment();
2897     void updateAllySafetyMap();
2898     void updateSafetyMap();
2899     void updateSafeTerrainMap();
2900     short staffChargeDuration(const item *theItem);
2901     void rechargeItemsIncrementally(short multiplier);
2902     void extinguishFireOnCreature(creature *monst);
2903     void autoRest();
2904     void manualSearch();
2905     boolean startFighting(enum directions dir, boolean tillDeath);
2906     void autoFight(boolean tillDeath);
2907     void synchronizePlayerTimeState();
2908     void playerRecoversFromAttacking(boolean anAttackHit);
2909     void playerTurnEnded();
2910     void resetScentTurnNumber();
2911     void displayMonsterFlashes(boolean flashingEnabled);
2912     void clearMessageArchive();
2913     void formatRecentMessages(char buf[][COLS*2], size_t height, short *linesFormatted, short *latestMessageLines);
2914     void displayRecentMessages();
2915     void displayMessageArchive();
2916     void temporaryMessage(const char *msg1, enum messageFlags flags);
2917     void messageWithColor(char *msg, color *theColor, enum messageFlags flags);
2918     void flavorMessage(char *msg);
2919     void message(const char *msg, enum messageFlags flags);
2920     void displayMoreSignWithoutWaitingForAcknowledgment();
2921     void displayMoreSign();
2922     short encodeMessageColor(char *msg, short i, const color *theColor);
2923     short decodeMessageColor(const char *msg, short i, color *returnColor);
2924     color *messageColorFromVictim(creature *monst);
2925     void upperCase(char *theChar);
2926     void updateMessageDisplay();
2927     void deleteMessages();
2928     void confirmMessages();
2929     void stripShiftFromMovementKeystroke(signed long *keystroke);
2930 
2931     void storeMemories(const short x, const short y);
2932     void updateFieldOfViewDisplay(boolean updateDancingTerrain, boolean refreshDisplay);
2933     void updateFieldOfView(short xLoc, short yLoc, short radius, boolean paintScent,
2934                            boolean passThroughCreatures, boolean setFieldOfView, short theColor[3], short fadeToPercent);
2935     void betweenOctant1andN(short *x, short *y, short x0, short y0, short n);
2936 
2937     void getFOVMask(char grid[DCOLS][DROWS], short xLoc, short yLoc, fixpt maxRadius,
2938                     unsigned long forbiddenTerrain, unsigned long forbiddenFlags, boolean cautiousOnWalls);
2939     void scanOctantFOV(char grid[DCOLS][DROWS], short xLoc, short yLoc, short octant, fixpt maxRadius,
2940                        short columnsRightFromOrigin, long startSlope, long endSlope, unsigned long forbiddenTerrain,
2941                        unsigned long forbiddenFlags, boolean cautiousOnWalls);
2942 
2943     creature *generateMonster(short monsterID, boolean itemPossible, boolean mutationPossible);
2944     short chooseMonster(short forLevel);
2945     creature *spawnHorde(short hordeID, short x, short y, unsigned long forbiddenFlags, unsigned long requiredFlags);
2946     void fadeInMonster(creature *monst);
2947 
2948     creatureList createCreatureList();
2949     creatureIterator iterateCreatures(creatureList *list);
2950     boolean hasNextCreature(creatureIterator iter);
2951     creature *nextCreature(creatureIterator *iter);
2952     void restartIterator(creatureIterator *iter);
2953     void prependCreature(creatureList *list, creature *add);
2954     boolean removeCreature(creatureList *list, creature *remove);
2955     creature *firstCreature(creatureList *list);
2956 
2957     boolean monsterWillAttackTarget(const creature *attacker, const creature *defender);
2958     boolean monstersAreTeammates(const creature *monst1, const creature *monst2);
2959     boolean monstersAreEnemies(const creature *monst1, const creature *monst2);
2960     void initializeGender(creature *monst);
2961     boolean stringsMatch(const char *str1, const char *str2);
2962     void resolvePronounEscapes(char *text, creature *monst);
2963     short pickHordeType(short depth, enum monsterTypes summonerType, unsigned long forbiddenFlags, unsigned long requiredFlags);
2964     creature *cloneMonster(creature *monst, boolean announce, boolean placeClone);
2965     void empowerMonster(creature *monst);
2966     unsigned long forbiddenFlagsForMonster(creatureType *monsterType);
2967     unsigned long avoidedFlagsForMonster(creatureType *monsterType);
2968     boolean monsterCanSubmergeNow(creature *monst);
2969     void populateMonsters();
2970     void updateMonsterState(creature *monst);
2971     void decrementMonsterStatus(creature *monst);
2972     boolean specifiedPathBetween(short x1, short y1, short x2, short y2,
2973                                  unsigned long blockingTerrain, unsigned long blockingFlags);
2974     boolean traversiblePathBetween(creature *monst, short x2, short y2);
2975     boolean openPathBetween(short x1, short y1, short x2, short y2);
2976     creature *monsterAtLoc(short x, short y);
2977     creature *dormantMonsterAtLoc(short x, short y);
2978     void perimeterCoords(short returnCoords[2], short n);
2979     boolean monsterBlinkToPreferenceMap(creature *monst, short **preferenceMap, boolean blinkUphill);
2980     boolean monsterSummons(creature *monst, boolean alwaysUse);
2981     boolean resurrectAlly(const short x, const short y);
2982     void unAlly(creature *monst);
2983     boolean monsterFleesFrom(creature *monst, creature *defender);
2984     void monstersTurn(creature *monst);
2985     boolean getRandomMonsterSpawnLocation(short *x, short *y);
2986     void spawnPeriodicHorde();
2987     void clearStatus(creature *monst);
2988     void moralAttack(creature *attacker, creature *defender);
2989     short runicWeaponChance(item *theItem, boolean customEnchantLevel, fixpt enchantLevel);
2990     void magicWeaponHit(creature *defender, item *theItem, boolean backstabbed);
2991     void disentangle(creature *monst);
2992     void teleport(creature *monst, short x, short y, boolean respectTerrainAvoidancePreferences);
2993     void chooseNewWanderDestination(creature *monst);
2994     boolean canPass(creature *mover, creature *blocker);
2995     boolean isPassableOrSecretDoor(short x, short y);
2996     boolean knownToPlayerAsPassableOrSecretDoor(short x, short y);
2997     void setMonsterLocation(creature *monst, short newX, short newY);
2998     boolean moveMonster(creature *monst, short dx, short dy);
2999     unsigned long burnedTerrainFlagsAtLoc(short x, short y);
3000     unsigned long discoveredTerrainFlagsAtLoc(short x, short y);
3001     boolean monsterAvoids(creature *monst, short x, short y);
3002     short distanceBetween(short x1, short y1, short x2, short y2);
3003     void alertMonster(creature *monst);
3004     void wakeUp(creature *monst);
3005     boolean monsterRevealed(creature *monst);
3006     boolean monsterHiddenBySubmersion(const creature *monst, const creature *observer);
3007     boolean monsterIsHidden(const creature *monst, const creature *observer);
3008     boolean canSeeMonster(creature *monst);
3009     boolean canDirectlySeeMonster(creature *monst);
3010     void monsterName(char *buf, creature *monst, boolean includeArticle);
3011     boolean monsterIsInClass(const creature *monst, const short monsterClass);
3012     fixpt strengthModifier(item *theItem);
3013     fixpt netEnchant(item *theItem);
3014     short hitProbability(creature *attacker, creature *defender);
3015     boolean attackHit(creature *attacker, creature *defender);
3016     void applyArmorRunicEffect(char returnString[DCOLS], creature *attacker, short *damage, boolean melee);
3017     void processStaggerHit(creature *attacker, creature *defender);
3018     boolean attack(creature *attacker, creature *defender, boolean lungeAttack);
3019     void inflictLethalDamage(creature *attacker, creature *defender);
3020     boolean inflictDamage(creature *attacker, creature *defender,
3021                           short damage, const color *flashColor, boolean ignoresProtectionShield);
3022     void addPoison(creature *monst, short totalDamage, short concentrationIncrement);
3023     void killCreature(creature *decedent, boolean administrativeDeath);
3024     void buildHitList(creature **hitList, const creature *attacker, creature *defender, const boolean sweep);
3025     void addScentToCell(short x, short y, short distance);
3026     void populateItems(short upstairsX, short upstairsY);
3027     item *placeItem(item *theItem, short x, short y);
3028     void removeItemFrom(short x, short y);
3029     void pickUpItemAt(short x, short y);
3030     item *addItemToPack(item *theItem);
3031     void aggravateMonsters(short distance, short x, short y, const color *flashColor);
3032     short getLineCoordinates(short listOfCoordinates[][2], const short originLoc[2], const short targetLoc[2], const bolt *theBolt);
3033     void getImpactLoc(short returnLoc[2], const short originLoc[2], const short targetLoc[2],
3034                       const short maxDistance, const boolean returnLastEmptySpace, const bolt *theBolt);
3035     boolean negate(creature *monst);
3036     short monsterAccuracyAdjusted(const creature *monst);
3037     fixpt monsterDamageAdjustmentAmount(const creature *monst);
3038     short monsterDefenseAdjusted(const creature *monst);
3039     void weaken(creature *monst, short maxDuration);
3040     void slow(creature *monst, short turns);
3041     void haste(creature *monst, short turns);
3042     void heal(creature *monst, short percent, boolean panacea);
3043     boolean projectileReflects(creature *attacker, creature *defender);
3044     short reflectBolt(short targetX, short targetY, short listOfCoordinates[][2], short kinkCell, boolean retracePath);
3045     void checkForMissingKeys(short x, short y);
3046     enum boltEffects boltEffectForItem(item *theItem);
3047     enum boltType boltForItem(item *theItem);
3048     boolean zap(short originLoc[2], short targetLoc[2], bolt *theBolt, boolean hideDetails);
3049     boolean nextTargetAfter(short *returnX,
3050                             short *returnY,
3051                             short targetX,
3052                             short targetY,
3053                             boolean targetEnemies,
3054                             boolean targetAllies,
3055                             boolean targetItems,
3056                             boolean targetTerrain,
3057                             boolean requireOpenPath,
3058                             boolean reverseDirection);
3059     boolean moveCursor(boolean *targetConfirmed,
3060                        boolean *canceled,
3061                        boolean *tabKey,
3062                        short targetLoc[2],
3063                        rogueEvent *event,
3064                        buttonState *state,
3065                        boolean colorsDance,
3066                        boolean keysMoveCursor,
3067                        boolean targetCanLeaveMap);
3068     void identifyItemKind(item *theItem);
3069     void autoIdentify(item *theItem);
3070     short numberOfItemsInPack();
3071     char nextAvailableInventoryCharacter();
3072     void checkForDisenchantment(item *theItem);
3073     void updateFloorItems();
3074     void itemKindName(item *theItem, char *kindName);
3075     void itemRunicName(item *theItem, char *runicName);
3076     void itemName(item *theItem, char *root, boolean includeDetails, boolean includeArticle, color *baseColor);
3077     char displayInventory(unsigned short categoryMask,
3078                           unsigned long requiredFlags,
3079                           unsigned long forbiddenFlags,
3080                           boolean waitForAcknowledge,
3081                           boolean includeButtons);
3082     short numberOfMatchingPackItems(unsigned short categoryMask,
3083                                     unsigned long requiredFlags, unsigned long forbiddenFlags,
3084                                     boolean displayErrors);
3085     void clearInventory(char keystroke);
3086     item *initializeItem();
3087     item *generateItem(unsigned short theCategory, short theKind);
3088     short chooseKind(itemTable *theTable, short numKinds);
3089     item *makeItemInto(item *theItem, unsigned long itemCategory, short itemKind);
3090     void updateEncumbrance();
3091     short displayedArmorValue();
3092     void strengthCheck(item *theItem, boolean noisy);
3093     void recalculateEquipmentBonuses();
3094     boolean equipItem(item *theItem, boolean force, item *unequipHint);
3095     void equip(item *theItem);
3096     item *keyInPackFor(short x, short y);
3097     item *keyOnTileAt(short x, short y);
3098     void unequip(item *theItem);
3099     void drop(item *theItem);
3100     void findAlternativeHomeFor(creature *monst, short *x, short *y, boolean chooseRandomly);
3101     boolean getQualifyingLocNear(short loc[2],
3102                                  short x, short y,
3103                                  boolean hallwaysAllowed,
3104                                  char blockingMap[DCOLS][DROWS],
3105                                  unsigned long forbiddenTerrainFlags,
3106                                  unsigned long forbiddenMapFlags,
3107                                  boolean forbidLiquid,
3108                                  boolean deterministic);
3109     boolean getQualifyingGridLocNear(short loc[2],
3110                                      short x, short y,
3111                                      boolean grid[DCOLS][DROWS],
3112                                      boolean deterministic);
3113 
3114     // Grid operations
3115     short **allocGrid();
3116     void freeGrid(short **array);
3117     void copyGrid(short **to, short **from);
3118     void fillGrid(short **grid, short fillValue);
3119     void hiliteGrid(short **grid, color *hiliteColor, short hiliteStrength);
3120     void findReplaceGrid(short **grid, short findValueMin, short findValueMax, short fillValue);
3121     short floodFillGrid(short **grid, short x, short y, short eligibleValueMin, short eligibleValueMax, short fillValue);
3122     void drawRectangleOnGrid(short **grid, short x, short y, short width, short height, short value);
3123     void drawCircleOnGrid(short **grid, short x, short y, short radius, short value);
3124     void getTerrainGrid(short **grid, short value, unsigned long terrainFlags, unsigned long mapFlags);
3125     void getTMGrid(short **grid, short value, unsigned long TMflags);
3126     short validLocationCount(short **grid, short validValue);
3127     void randomLocationInGrid(short **grid, short *x, short *y, short validValue);
3128     boolean getQualifyingPathLocNear(short *retValX, short *retValY,
3129                                      short x, short y,
3130                                      boolean hallwaysAllowed,
3131                                      unsigned long blockingTerrainFlags,
3132                                      unsigned long blockingMapFlags,
3133                                      unsigned long forbiddenTerrainFlags,
3134                                      unsigned long forbiddenMapFlags,
3135                                      boolean deterministic);
3136     void createBlobOnGrid(short **grid,
3137                           short *retMinX, short *retMinY, short *retWidth, short *retHeight,
3138                           short roundCount,
3139                           short minBlobWidth, short minBlobHeight,
3140                           short maxBlobWidth, short maxBlobHeight, short percentSeeded,
3141                           char birthParameters[9], char survivalParameters[9]);
3142 
3143     void checkForContinuedLeadership(creature *monst);
3144     void demoteMonsterFromLeadership(creature *monst);
3145     void toggleMonsterDormancy(creature *monst);
3146     void monsterDetails(char buf[], creature *monst);
3147     void makeMonsterDropItem(creature *monst);
3148     void throwCommand(item *theItem, boolean autoThrow);
3149     void relabel(item *theItem);
3150     void swapLastEquipment();
3151     void apply(item *theItem, boolean recordCommands);
3152     boolean itemCanBeCalled(item *theItem);
3153     void call(item *theItem);
3154     short chooseVorpalEnemy();
3155     void describeMonsterClass(char *buf, const short classID, boolean conjunctionAnd);
3156     void identify(item *theItem);
3157     void updateIdentifiableItem(item *theItem);
3158     void updateIdentifiableItems();
3159     void readScroll(item *theItem);
3160     void updateRingBonuses();
3161     void updatePlayerRegenerationDelay();
3162     boolean removeItemFromChain(item *theItem, item *theChain);
3163     void addItemToChain(item *theItem, item *theChain);
3164     void drinkPotion(item *theItem);
3165     item *promptForItemOfType(unsigned short category,
3166                               unsigned long requiredFlags,
3167                               unsigned long forbiddenFlags,
3168                               char *prompt,
3169                               boolean allowInventoryActions);
3170     item *itemOfPackLetter(char letter);
3171     boolean unequipItem(item *theItem, boolean force);
3172     short magicCharDiscoverySuffix(short category, short kind);
3173     int itemMagicPolarity(item *theItem);
3174     item *itemAtLoc(short x, short y);
3175     item *dropItem(item *theItem);
3176     itemTable *tableForItemCategory(enum itemCategory theCat, short *kindCount);
3177     boolean isVowelish(char *theChar);
3178     short charmEffectDuration(short charmKind, short enchant);
3179     short charmRechargeDelay(short charmKind, short enchant);
3180     boolean itemIsCarried(item *theItem);
3181     void itemDetails(char *buf, item *theItem);
3182     void deleteItem(item *theItem);
3183     void shuffleFlavors();
3184     unsigned long itemValue(item *theItem);
3185     short strLenWithoutEscapes(const char *str);
3186     void combatMessage(char *theMsg, color *theColor);
3187     void displayCombatText();
3188     void flashMonster(creature *monst, const color *theColor, short strength);
3189 
3190     boolean paintLight(lightSource *theLight, short x, short y, boolean isMinersLight, boolean maintainShadows);
3191     void backUpLighting(short lights[DCOLS][DROWS][3]);
3192     void restoreLighting(short lights[DCOLS][DROWS][3]);
3193     void updateLighting();
3194     boolean playerInDarkness();
3195     flare *newFlare(lightSource *light, short x, short y, short changePerFrame, short limit);
3196     void createFlare(short x, short y, enum lightType lightIndex);
3197     void animateFlares(flare **flares, short count);
3198     void deleteAllFlares();
3199     void demoteVisibility();
3200     void discoverCell(const short x, const short y);
3201     void updateVision(boolean refreshDisplay);
3202     void burnItem(item *theItem);
3203     void activateMachine(short machineNumber);
3204     boolean circuitBreakersPreventActivation(short machineNumber);
3205     void promoteTile(short x, short y, enum dungeonLayers layer, boolean useFireDF);
3206     void autoPlayLevel(boolean fastForward);
3207     void updateClairvoyance();
3208     short scentDistance(short x1, short y1, short x2, short y2);
3209     short armorAggroAdjustment(item *theArmor);
3210     short currentAggroValue();
3211 
3212     void initRecording();
3213     void flushBufferToFile();
3214     void fillBufferFromFile();
3215     void recordEvent(rogueEvent *event);
3216     void recallEvent(rogueEvent *event);
3217     void pausePlayback();
3218     void displayAnnotation();
3219     boolean loadSavedGame();
3220     void switchToPlaying();
3221     void recordKeystroke(int keystroke, boolean controlKey, boolean shiftKey);
3222     void cancelKeystroke();
3223     void recordKeystrokeSequence(unsigned char *commandSequence);
3224     void recordMouseClick(short x, short y, boolean controlKey, boolean shiftKey);
3225     void OOSCheck(unsigned long x, short numberOfBytes);
3226     void RNGCheck();
3227     boolean executePlaybackInput(rogueEvent *recordingInput);
3228     void getAvailableFilePath(char *filePath, const char *defaultPath, const char *suffix);
3229     boolean characterForbiddenInFilename(const char theChar);
3230     void saveGame();
3231     void saveGameNoPrompt();
3232     void saveRecording(char *filePath);
3233     void saveRecordingNoPrompt(char *filePath);
3234     void parseFile();
3235     void RNGLog(char *message);
3236 
3237     short wandDominate(creature *monst);
3238     short staffDamageLow(fixpt enchant);
3239     short staffDamageHigh(fixpt enchant);
3240     short staffDamage(fixpt enchant);
3241     int staffPoison(fixpt enchant);
3242     short staffBlinkDistance(fixpt enchant);
3243     short staffHasteDuration(fixpt enchant);
3244     short staffBladeCount(fixpt enchant);
3245     short staffDiscordDuration(fixpt enchant);
3246     int staffProtection(fixpt enchant);
3247     short staffEntrancementDuration(fixpt enchant);
3248     fixpt ringWisdomMultiplier(fixpt enchant);
3249     short charmHealing(fixpt enchant);
3250     int charmProtection(fixpt enchant);
3251     short charmShattering(fixpt enchant);
3252     short charmGuardianLifespan(fixpt enchant);
3253     short charmNegationRadius(fixpt enchant);
3254     short weaponParalysisDuration(fixpt enchant);
3255     short weaponConfusionDuration(fixpt enchant);
3256     short weaponForceDistance(fixpt enchant);
3257     short weaponSlowDuration(fixpt enchant);
3258     short weaponImageCount(fixpt enchant);
3259     short weaponImageDuration(fixpt enchant);
3260     short armorReprisalPercent(fixpt enchant);
3261     short armorAbsorptionMax(fixpt enchant);
3262     short armorImageCount(fixpt enchant);
3263     short reflectionChance(fixpt enchant);
3264     long turnsForFullRegenInThousandths(fixpt bonus);
3265     fixpt damageFraction(fixpt netEnchant);
3266     fixpt accuracyFraction(fixpt netEnchant);
3267     fixpt defenseFraction(fixpt netDefense);
3268 
3269     void checkForDungeonErrors();
3270 
3271     boolean dialogChooseFile(char *path, const char *suffix, const char *prompt);
3272     void quitImmediately();
3273     void dialogAlert(char *message);
3274     void mainBrogueJunction();
3275     void printSeedCatalog(uint64_t startingSeed, uint64_t numberOfSeedsToScan, unsigned int scanThroughDepth, boolean isCsvFormat);
3276 
3277     void initializeButton(brogueButton *button);
3278     void drawButtonsInState(buttonState *state);
3279     void initializeButtonState(buttonState *state,
3280                                brogueButton *buttons,
3281                                short buttonCount,
3282                                short winX,
3283                                short winY,
3284                                short winWidth,
3285                                short winHeight);
3286     short processButtonInput(buttonState *state, boolean *canceled, rogueEvent *event);
3287     short smoothHiliteGradient(const short currentXValue, const short maxXValue);
3288     void drawButton(brogueButton *button, enum buttonDrawStates highlight, cellDisplayBuffer dbuf[COLS][ROWS]);
3289     short buttonInputLoop(brogueButton *buttons,
3290                           short buttonCount,
3291                           short winX,
3292                           short winY,
3293                           short winWidth,
3294                           short winHeight,
3295                           rogueEvent *returnEvent);
3296 
3297     void dijkstraScan(short **distanceMap, short **costMap, boolean useDiagonals);
3298 
3299 #if defined __cplusplus
3300 }
3301 #endif
3302