From 552647fb36c94bcff68ac8b1900635b42e810b8c Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 10 Oct 2016 16:18:14 +0300 Subject: [PATCH 01/23] Use more enums We're already using enums, so convert some already existing defines. --- include/attrib.h | 16 ++-- include/dungeon.h | 16 ++-- include/flag.h | 40 +++++---- include/hack.h | 202 ++++++++++++++++++++++++--------------------- include/mextra.h | 18 ++-- include/mkroom.h | 57 +++++++------ include/monsym.h | 126 ++++++++++++++-------------- include/objclass.h | 41 ++++----- include/rm.h | 78 ++++++++--------- include/sp_lev.h | 12 +-- include/trap.h | 53 ++++++------ include/wintype.h | 36 ++++---- 12 files changed, 368 insertions(+), 327 deletions(-) diff --git a/include/attrib.h b/include/attrib.h index ed2c5d86c..fe97a9fb2 100644 --- a/include/attrib.h +++ b/include/attrib.h @@ -7,14 +7,16 @@ #ifndef ATTRIB_H #define ATTRIB_H -#define A_STR 0 -#define A_INT 1 -#define A_WIS 2 -#define A_DEX 3 -#define A_CON 4 -#define A_CHA 5 +enum attrib_types { + A_STR = 0, + A_INT, + A_WIS, + A_DEX, + A_CON, + A_CHA, -#define A_MAX 6 /* used in rn2() selection of attrib */ + A_MAX /* used in rn2() selection of attrib */ +}; #define ABASE(x) (u.acurr.a[x]) #define ABON(x) (u.abon.a[x]) diff --git a/include/dungeon.h b/include/dungeon.h index 23965e6ce..43452d908 100644 --- a/include/dungeon.h +++ b/include/dungeon.h @@ -35,13 +35,15 @@ typedef struct stairway { /* basic stairway identifier */ } stairway; /* level region types */ -#define LR_DOWNSTAIR 0 -#define LR_UPSTAIR 1 -#define LR_PORTAL 2 -#define LR_BRANCH 3 -#define LR_TELE 4 -#define LR_UPTELE 5 -#define LR_DOWNTELE 6 +enum level_region_types { + LR_DOWNSTAIR = 0, + LR_UPSTAIR, + LR_PORTAL, + LR_BRANCH, + LR_TELE, + LR_UPTELE, + LR_DOWNTELE +}; typedef struct dest_area { /* non-stairway level change identifier */ xchar lx, ly; /* "lower" left corner (near [0,0]) */ diff --git a/include/flag.h b/include/flag.h index 642c680be..b28b0e673 100644 --- a/include/flag.h +++ b/include/flag.h @@ -378,26 +378,30 @@ extern NEARDATA struct sysflag sysflags; #endif extern NEARDATA struct instance_flags iflags; -/* last_msg values */ -#define PLNMSG_UNKNOWN 0 /* arbitrary */ -#define PLNMSG_ONE_ITEM_HERE 1 /* "you see here" */ -#define PLNMSG_TOWER_OF_FLAME 2 /* scroll of fire */ -#define PLNMSG_CAUGHT_IN_EXPLOSION 3 /* explode() feedback */ -#define PLNMSG_OBJ_GLOWS 4 /* "the glows " */ -#define PLNMSG_OBJNAM_ONLY 5 /* xname/doname only, for #tip */ - /* Usage: - * pline("some message"); - * pline: vsprintf + putstr + iflags.last_msg = PLNMSG_UNKNOWN; - * iflags.last_msg = PLNMSG_some_message; - * and subsequent code can adjust the next message if it is affected - * by some_message. The next message will clear iflags.last_msg. - */ +/* last_msg values + * Usage: + * pline("some message"); + * pline: vsprintf + putstr + iflags.last_msg = PLNMSG_UNKNOWN; + * iflags.last_msg = PLNMSG_some_message; + * and subsequent code can adjust the next message if it is affected + * by some_message. The next message will clear iflags.last_msg. + */ +enum plnmsg_types { + PLNMSG_UNKNOWN = 0, /* arbitrary */ + PLNMSG_ONE_ITEM_HERE, /* "you see here" */ + PLNMSG_TOWER_OF_FLAME, /* scroll of fire */ + PLNMSG_CAUGHT_IN_EXPLOSION, /* explode() feedback */ + PLNMSG_OBJ_GLOWS, /* "the glows " */ + PLNMSG_OBJNAM_ONLY /* xname/doname only, for #tip */ +}; /* runmode options */ -#define RUN_TPORT 0 /* don't update display until movement stops */ -#define RUN_LEAP 1 /* update display every 7 steps */ -#define RUN_STEP 2 /* update display every single step */ -#define RUN_CRAWL 3 /* walk w/ extra delay after each update */ +enum runmode_types { + RUN_TPORT = 0, /* don't update display until movement stops */ + RUN_LEAP, /* update display every 7 steps */ + RUN_STEP, /* update display every single step */ + RUN_CRAWL /* walk w/ extra delay after each update */ +}; /* paranoid confirmation prompting */ /* any yes confirmations also require explicit no (or ESC) to reject */ diff --git a/include/hack.h b/include/hack.h index 45da184a9..cc878942c 100644 --- a/include/hack.h +++ b/include/hack.h @@ -22,24 +22,28 @@ } /* symbolic names for capacity levels */ -#define UNENCUMBERED 0 -#define SLT_ENCUMBER 1 /* Burdened */ -#define MOD_ENCUMBER 2 /* Stressed */ -#define HVY_ENCUMBER 3 /* Strained */ -#define EXT_ENCUMBER 4 /* Overtaxed */ -#define OVERLOADED 5 /* Overloaded */ +enum encumbrance_types { + UNENCUMBERED = 0, + SLT_ENCUMBER, /* Burdened */ + MOD_ENCUMBER, /* Stressed */ + HVY_ENCUMBER, /* Strained */ + EXT_ENCUMBER, /* Overtaxed */ + OVERLOADED /* Overloaded */ +}; /* weight increment of heavy iron ball */ #define IRON_BALL_W_INCR 160 /* hunger states - see hu_stat in eat.c */ -#define SATIATED 0 -#define NOT_HUNGRY 1 -#define HUNGRY 2 -#define WEAK 3 -#define FAINTING 4 -#define FAINTED 5 -#define STARVED 6 +enum hunger_state_types { + SATIATED = 0, + NOT_HUNGRY, + HUNGRY, + WEAK, + FAINTING, + FAINTED, + STARVED +}; /* Macros for how a rumor was delivered in outrumor() */ #define BY_ORACLE 0 @@ -48,13 +52,15 @@ #define BY_OTHER 9 /* Macros for why you are no longer riding */ -#define DISMOUNT_GENERIC 0 -#define DISMOUNT_FELL 1 -#define DISMOUNT_THROWN 2 -#define DISMOUNT_POLY 3 -#define DISMOUNT_ENGULFED 4 -#define DISMOUNT_BONES 5 -#define DISMOUNT_BYCHOICE 6 +enum dismount_types { + DISMOUNT_GENERIC = 0, + DISMOUNT_FELL, + DISMOUNT_THROWN, + DISMOUNT_POLY, + DISMOUNT_ENGULFED, + DISMOUNT_BONES, + DISMOUNT_BYCHOICE +}; /* Special returns from mapglyph() */ #define MG_CORPSE 0x01 @@ -73,25 +79,27 @@ #define SELL_DONTSELL (2) /* alteration types--keep in synch with costly_alteration(mkobj.c) */ -#define COST_CANCEL 0 /* standard cancellation */ -#define COST_DRAIN 1 /* drain life upon an object */ -#define COST_UNCHRG 2 /* cursed charging */ -#define COST_UNBLSS 3 /* unbless (devalues holy water) */ -#define COST_UNCURS 4 /* uncurse (devalues unholy water) */ -#define COST_DECHNT 5 /* disenchant weapons or armor */ -#define COST_DEGRD 6 /* removal of rustproofing, dulling via engraving */ -#define COST_DILUTE 7 /* potion dilution */ -#define COST_ERASE 8 /* scroll or spellbook blanking */ -#define COST_BURN 9 /* dipped into flaming oil */ -#define COST_NUTRLZ 10 /* neutralized via unicorn horn */ -#define COST_DSTROY 11 /* wand breaking (bill first, useup later) */ -#define COST_SPLAT 12 /* cream pie to own face (ditto) */ -#define COST_BITE 13 /* start eating food */ -#define COST_OPEN 14 /* open tin */ -#define COST_BRKLCK 15 /* break box/chest's lock */ -#define COST_RUST 16 /* rust damage */ -#define COST_ROT 17 /* rotting attack */ -#define COST_CORRODE 18 /* acid damage */ +enum cost_alteration_types { + COST_CANCEL = 0, /* standard cancellation */ + COST_DRAIN, /* drain life upon an object */ + COST_UNCHRG, /* cursed charging */ + COST_UNBLSS, /* unbless (devalues holy water) */ + COST_UNCURS, /* uncurse (devalues unholy water) */ + COST_DECHNT, /* disenchant weapons or armor */ + COST_DEGRD, /* removal of rustproofing, dulling via engraving */ + COST_DILUTE, /* potion dilution */ + COST_ERASE, /* scroll or spellbook blanking */ + COST_BURN, /* dipped into flaming oil */ + COST_NUTRLZ, /* neutralized via unicorn horn */ + COST_DSTROY, /* wand breaking (bill first, useup later) */ + COST_SPLAT, /* cream pie to own face (ditto) */ + COST_BITE, /* start eating food */ + COST_OPEN, /* open tin */ + COST_BRKLCK, /* break box/chest's lock */ + COST_RUST, /* rust damage */ + COST_ROT, /* rotting attack */ + COST_CORRODE /* acid damage */ +}; /* bitmask flags for corpse_xname(); PFX_THE takes precedence over ARTICLE, NO_PFX takes precedence over both */ @@ -115,22 +123,24 @@ enum getpos_retval { * in end.c and topten.c will need to be changed. Some parts of the * code assume that PANIC separates the deaths from the non-deaths. */ -#define DIED 0 -#define CHOKING 1 -#define POISONING 2 -#define STARVING 3 -#define DROWNING 4 -#define BURNING 5 -#define DISSOLVED 6 -#define CRUSHING 7 -#define STONING 8 -#define TURNED_SLIME 9 -#define GENOCIDED 10 -#define PANICKED 11 -#define TRICKED 12 -#define QUIT 13 -#define ESCAPED 14 -#define ASCENDED 15 +enum game_end_types { + DIED = 0, + CHOKING, + POISONING, + STARVING, + DROWNING, + BURNING, + DISSOLVED, + CRUSHING, + STONING, + TURNED_SLIME, + GENOCIDED, + PANICKED, + TRICKED, + QUIT, + ESCAPED, + ASCENDED +}; #include "align.h" #include "dungeon.h" @@ -146,18 +156,22 @@ enum getpos_retval { NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ /* types of calls to bhit() */ -#define ZAPPED_WAND 0 -#define THROWN_WEAPON 1 -#define KICKED_WEAPON 2 -#define FLASHED_LIGHT 3 -#define INVIS_BEAM 4 +enum bhit_call_types { + ZAPPED_WAND = 0, + THROWN_WEAPON, + KICKED_WEAPON, + FLASHED_LIGHT, + INVIS_BEAM +}; /* attack mode for hmon() */ -#define HMON_MELEE 0 /* hand-to-hand */ -#define HMON_THROWN 1 /* normal ranged (or spitting while poly'd) */ -#define HMON_KICKED 2 /* alternate ranged */ -#define HMON_APPLIED 3 /* polearm, treated as ranged */ -#define HMON_DRAGGED 4 /* attached iron ball, pulled into mon */ +enum hmon_atkmode_types { + HMON_MELEE = 0, /* hand-to-hand */ + HMON_THROWN, /* normal ranged (or spitting while poly'd) */ + HMON_KICKED, /* alternate ranged */ + HMON_APPLIED, /* polearm, treated as ranged */ + HMON_DRAGGED /* attached iron ball, pulled into mon */ +}; #define MATCH_WARN_OF_MON(mon) \ (Warn_of_mon && ((context.warntype.obj \ @@ -315,14 +329,16 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ #define LAUNCH_KNOWN 0x80 /* the hero caused this by explicit action */ /* Macros for explosion types */ -#define EXPL_DARK 0 -#define EXPL_NOXIOUS 1 -#define EXPL_MUDDY 2 -#define EXPL_WET 3 -#define EXPL_MAGICAL 4 -#define EXPL_FIERY 5 -#define EXPL_FROSTY 6 -#define EXPL_MAX 7 +enum explosion_types { + EXPL_DARK = 0, + EXPL_NOXIOUS, + EXPL_MUDDY, + EXPL_WET, + EXPL_MAGICAL, + EXPL_FIERY, + EXPL_FROSTY, + EXPL_MAX +}; /* enlightenment control flags */ #define BASICENLIGHTENMENT 1 /* show mundane stuff */ @@ -344,25 +360,27 @@ NEARDATA extern coord bhitpos; /* place where throw or zap hits or stops */ #define XKILL_NOCONDUCT 4 /* Macros for messages referring to hands, eyes, feet, etc... */ -#define ARM 0 -#define EYE 1 -#define FACE 2 -#define FINGER 3 -#define FINGERTIP 4 -#define FOOT 5 -#define HAND 6 -#define HANDED 7 -#define HEAD 8 -#define LEG 9 -#define LIGHT_HEADED 10 -#define NECK 11 -#define SPINE 12 -#define TOE 13 -#define HAIR 14 -#define BLOOD 15 -#define LUNG 16 -#define NOSE 17 -#define STOMACH 18 +enum bodypart_types { + ARM = 0, + EYE, + FACE, + FINGER, + FINGERTIP, + FOOT, + HAND, + HANDED, + HEAD, + LEG, + LIGHT_HEADED, + NECK, + SPINE, + TOE, + HAIR, + BLOOD, + LUNG, + NOSE, + STOMACH +}; /* indices for some special tin types */ #define ROTTEN_TIN 0 diff --git a/include/mextra.h b/include/mextra.h index e69d137df..c92a79f4d 100644 --- a/include/mextra.h +++ b/include/mextra.h @@ -144,14 +144,16 @@ struct emin { ** formerly edog.h -- pet extension */ /* various types of pet food, the lower, the better liked */ -#define DOGFOOD 0 -#define CADAVER 1 -#define ACCFOOD 2 -#define MANFOOD 3 -#define APPORT 4 -#define POISON 5 -#define UNDEF 6 -#define TABU 7 +enum dogfood_types { + DOGFOOD = 0, + CADAVER, + ACCFOOD, + MANFOOD, + APPORT, + POISON, + UNDEF, + TABU +}; struct edog { long droptime; /* moment dog dropped object */ diff --git a/include/mkroom.h b/include/mkroom.h index 1141f3616..ef20a1d5d 100644 --- a/include/mkroom.h +++ b/include/mkroom.h @@ -51,33 +51,36 @@ extern struct mkroom *dnstairs_room, *upstairs_room, *sstairs_room; extern NEARDATA coord doors[DOORMAX]; /* values for rtype in the room definition structure */ -#define OROOM 0 /* ordinary room */ -#define COURT 2 /* contains a throne */ -#define SWAMP 3 /* contains pools */ -#define VAULT 4 /* contains piles of gold */ -#define BEEHIVE 5 /* contains killer bees and royal jelly */ -#define MORGUE 6 /* contains corpses, undead and ghosts */ -#define BARRACKS 7 /* contains soldiers and their gear */ -#define ZOO 8 /* floor covered with treasure and monsters */ -#define DELPHI 9 /* contains Oracle and peripherals */ -#define TEMPLE 10 /* contains a shrine */ -#define LEPREHALL 11 /* leprechaun hall (Tom Proudfoot) */ -#define COCKNEST 12 /* cockatrice nest (Tom Proudfoot) */ -#define ANTHOLE 13 /* ants (Tom Proudfoot) */ -#define SHOPBASE 14 /* everything above this is a shop */ -#define ARMORSHOP 15 /* specific shop defines for level compiler */ -#define SCROLLSHOP 16 -#define POTIONSHOP 17 -#define WEAPONSHOP 18 -#define FOODSHOP 19 -#define RINGSHOP 20 -#define WANDSHOP 21 -#define TOOLSHOP 22 -#define BOOKSHOP 23 -#define FODDERSHOP 24 /* health food store */ -#define UNIQUESHOP 25 /* shops here & below not randomly gen'd. */ -#define CANDLESHOP 25 -#define MAXRTYPE 25 /* maximum valid room type */ +enum roomtype_types { + OROOM = 0, /* ordinary room */ + COURT = 2, /* contains a throne */ + SWAMP, /* contains pools */ + VAULT, /* contains piles of gold */ + BEEHIVE, /* contains killer bees and royal jelly */ + MORGUE, /* contains corpses, undead and ghosts */ + BARRACKS, /* contains soldiers and their gear */ + ZOO, /* floor covered with treasure and monsters */ + DELPHI, /* contains Oracle and peripherals */ + TEMPLE, /* contains a shrine */ + LEPREHALL, /* leprechaun hall (Tom Proudfoot) */ + COCKNEST, /* cockatrice nest (Tom Proudfoot) */ + ANTHOLE, /* ants (Tom Proudfoot) */ + SHOPBASE, /* everything above this is a shop */ + ARMORSHOP, /* specific shop defines for level compiler */ + SCROLLSHOP, + POTIONSHOP, + WEAPONSHOP, + FOODSHOP, + RINGSHOP, + WANDSHOP, + TOOLSHOP, + BOOKSHOP, + FODDERSHOP, /* health food store */ + CANDLESHOP +}; + +#define MAXRTYPE (CANDLESHOP) /* maximum valid room type */ +#define UNIQUESHOP (CANDLESHOP) /* shops here & above not randomly gen'd. */ /* Special type for search_special() */ #define ANY_TYPE (-1) diff --git a/include/monsym.h b/include/monsym.h index 9a781012a..4aec7c2a2 100644 --- a/include/monsym.h +++ b/include/monsym.h @@ -10,71 +10,71 @@ * them. Monster class 0 is not used or defined so we can use it as a * NULL character. */ -/* clang-format off */ -#define S_ANT 1 -#define S_BLOB 2 -#define S_COCKATRICE 3 -#define S_DOG 4 -#define S_EYE 5 -#define S_FELINE 6 -#define S_GREMLIN 7 -#define S_HUMANOID 8 -#define S_IMP 9 -#define S_JELLY 10 -#define S_KOBOLD 11 -#define S_LEPRECHAUN 12 -#define S_MIMIC 13 -#define S_NYMPH 14 -#define S_ORC 15 -#define S_PIERCER 16 -#define S_QUADRUPED 17 -#define S_RODENT 18 -#define S_SPIDER 19 -#define S_TRAPPER 20 -#define S_UNICORN 21 -#define S_VORTEX 22 -#define S_WORM 23 -#define S_XAN 24 -#define S_LIGHT 25 -#define S_ZRUTY 26 -#define S_ANGEL 27 -#define S_BAT 28 -#define S_CENTAUR 29 -#define S_DRAGON 30 -#define S_ELEMENTAL 31 -#define S_FUNGUS 32 -#define S_GNOME 33 -#define S_GIANT 34 -#define S_invisible 35 /* non-class present in def_monsyms[] */ -#define S_JABBERWOCK 36 -#define S_KOP 37 -#define S_LICH 38 -#define S_MUMMY 39 -#define S_NAGA 40 -#define S_OGRE 41 -#define S_PUDDING 42 -#define S_QUANTMECH 43 -#define S_RUSTMONST 44 -#define S_SNAKE 45 -#define S_TROLL 46 -#define S_UMBER 47 -#define S_VAMPIRE 48 -#define S_WRAITH 49 -#define S_XORN 50 -#define S_YETI 51 -#define S_ZOMBIE 52 -#define S_HUMAN 53 -#define S_GHOST 54 -#define S_GOLEM 55 -#define S_DEMON 56 -#define S_EEL 57 -#define S_LIZARD 58 +enum mon_class_types { + S_ANT = 1, + S_BLOB, + S_COCKATRICE, + S_DOG, + S_EYE, + S_FELINE, + S_GREMLIN, + S_HUMANOID, + S_IMP, + S_JELLY, + S_KOBOLD, + S_LEPRECHAUN, + S_MIMIC, + S_NYMPH, + S_ORC, + S_PIERCER, + S_QUADRUPED, + S_RODENT, + S_SPIDER, + S_TRAPPER, + S_UNICORN, + S_VORTEX, + S_WORM, + S_XAN, + S_LIGHT, + S_ZRUTY, + S_ANGEL, + S_BAT, + S_CENTAUR, + S_DRAGON, + S_ELEMENTAL, + S_FUNGUS, + S_GNOME, + S_GIANT, + S_invisible, /* non-class present in def_monsyms[] */ + S_JABBERWOCK, + S_KOP, + S_LICH, + S_MUMMY, + S_NAGA, + S_OGRE, + S_PUDDING, + S_QUANTMECH, + S_RUSTMONST, + S_SNAKE, + S_TROLL, + S_UMBER, + S_VAMPIRE, + S_WRAITH, + S_XORN, + S_YETI, + S_ZOMBIE, + S_HUMAN, + S_GHOST, + S_GOLEM, + S_DEMON, + S_EEL, + S_LIZARD, -#define S_WORM_TAIL 59 -#define S_MIMIC_DEF 60 -/* clang-format on */ + S_WORM_TAIL, + S_MIMIC_DEF, -#define MAXMCLASSES 61 /* number of monster classes */ + MAXMCLASSES /* number of monster classes */ +}; /* * Default characters for monsters. These correspond to the monster classes diff --git a/include/objclass.h b/include/objclass.h index b968cd246..3f7218092 100644 --- a/include/objclass.h +++ b/include/objclass.h @@ -131,25 +131,28 @@ extern NEARDATA struct objdescr obj_descr[]; * All objects have a class. Make sure that all classes have a corresponding * symbol below. */ -#define RANDOM_CLASS 0 /* used for generating random objects */ -#define ILLOBJ_CLASS 1 -#define WEAPON_CLASS 2 -#define ARMOR_CLASS 3 -#define RING_CLASS 4 -#define AMULET_CLASS 5 -#define TOOL_CLASS 6 -#define FOOD_CLASS 7 -#define POTION_CLASS 8 -#define SCROLL_CLASS 9 -#define SPBOOK_CLASS 10 /* actually SPELL-book */ -#define WAND_CLASS 11 -#define COIN_CLASS 12 -#define GEM_CLASS 13 -#define ROCK_CLASS 14 -#define BALL_CLASS 15 -#define CHAIN_CLASS 16 -#define VENOM_CLASS 17 -#define MAXOCLASSES 18 +enum obj_class_types { + RANDOM_CLASS = 0, /* used for generating random objects */ + ILLOBJ_CLASS, + WEAPON_CLASS, + ARMOR_CLASS, + RING_CLASS, + AMULET_CLASS, + TOOL_CLASS, + FOOD_CLASS, + POTION_CLASS, + SCROLL_CLASS, + SPBOOK_CLASS, /* actually SPELL-book */ + WAND_CLASS, + COIN_CLASS, + GEM_CLASS, + ROCK_CLASS, + BALL_CLASS, + CHAIN_CLASS, + VENOM_CLASS, + + MAXOCLASSES +}; #define ALLOW_COUNT (MAXOCLASSES + 1) /* Can be used in the object class */ #define ALL_CLASSES (MAXOCLASSES + 2) /* input to getobj(). */ diff --git a/include/rm.h b/include/rm.h index 3e85f2e2d..d7a494196 100644 --- a/include/rm.h +++ b/include/rm.h @@ -34,45 +34,47 @@ defines array type_names[] which contains an entry for each of these, so needs to be kept in sync if any new types are added or existing ones renumbered.] */ -#define STONE 0 -#define VWALL 1 -#define HWALL 2 -#define TLCORNER 3 -#define TRCORNER 4 -#define BLCORNER 5 -#define BRCORNER 6 -#define CROSSWALL 7 /* For pretty mazes and special levels */ -#define TUWALL 8 -#define TDWALL 9 -#define TLWALL 10 -#define TRWALL 11 -#define DBWALL 12 -#define TREE 13 /* KMH */ -#define SDOOR 14 -#define SCORR 15 -#define POOL 16 -#define MOAT 17 /* pool that doesn't boil, adjust messages */ -#define WATER 18 -#define DRAWBRIDGE_UP 19 -#define LAVAPOOL 20 -#define IRONBARS 21 /* KMH */ -#define DOOR 22 -#define CORR 23 -#define ROOM 24 -#define STAIRS 25 -#define LADDER 26 -#define FOUNTAIN 27 -#define THRONE 28 -#define SINK 29 -#define GRAVE 30 -#define ALTAR 31 -#define ICE 32 -#define DRAWBRIDGE_DOWN 33 -#define AIR 34 -#define CLOUD 35 +enum levl_typ_types { + STONE = 0, + VWALL, + HWALL, + TLCORNER, + TRCORNER, + BLCORNER, + BRCORNER, + CROSSWALL, /* For pretty mazes and special levels */ + TUWALL, + TDWALL, + TLWALL, + TRWALL, + DBWALL, + TREE, /* KMH */ + SDOOR, + SCORR, + POOL, + MOAT, /* pool that doesn't boil, adjust messages */ + WATER, + DRAWBRIDGE_UP, + LAVAPOOL, + IRONBARS, /* KMH */ + DOOR, + CORR, + ROOM, + STAIRS, + LADDER, + FOUNTAIN, + THRONE, + SINK, + GRAVE, + ALTAR, + ICE, + DRAWBRIDGE_DOWN, + AIR, + CLOUD, -#define MAX_TYPE 36 -#define INVALID_TYPE 127 + MAX_TYPE, + INVALID_TYPE = 127 +}; /* * Avoid using the level types in inequalities: diff --git a/include/sp_lev.h b/include/sp_lev.h index 78ace02ab..be3e92164 100644 --- a/include/sp_lev.h +++ b/include/sp_lev.h @@ -34,11 +34,13 @@ generate ways to escape from them */ /* different level layout initializers */ -#define LVLINIT_NONE 0 -#define LVLINIT_SOLIDFILL 1 -#define LVLINIT_MAZEGRID 2 -#define LVLINIT_MINES 3 -#define LVLINIT_ROGUE 4 +enum lvlinit_types { + LVLINIT_NONE = 0, + LVLINIT_SOLIDFILL, + LVLINIT_MAZEGRID, + LVLINIT_MINES, + LVLINIT_ROGUE +}; /* max. layers of object containment */ #define MAX_CONTAINMENT 10 diff --git a/include/trap.h b/include/trap.h index 4b83f1996..ce4f4696d 100644 --- a/include/trap.h +++ b/include/trap.h @@ -53,30 +53,33 @@ extern struct trap *ftrap; /* Note: if adding/removing a trap, adjust trap_engravings[] in mklev.c */ /* unconditional traps */ -#define NO_TRAP 0 -#define ARROW_TRAP 1 -#define DART_TRAP 2 -#define ROCKTRAP 3 -#define SQKY_BOARD 4 -#define BEAR_TRAP 5 -#define LANDMINE 6 -#define ROLLING_BOULDER_TRAP 7 -#define SLP_GAS_TRAP 8 -#define RUST_TRAP 9 -#define FIRE_TRAP 10 -#define PIT 11 -#define SPIKED_PIT 12 -#define HOLE 13 -#define TRAPDOOR 14 -#define TELEP_TRAP 15 -#define LEVEL_TELEP 16 -#define MAGIC_PORTAL 17 -#define WEB 18 -#define STATUE_TRAP 19 -#define MAGIC_TRAP 20 -#define ANTI_MAGIC 21 -#define POLY_TRAP 22 -#define VIBRATING_SQUARE 23 -#define TRAPNUM 24 +enum trap_types { + NO_TRAP = 0, + ARROW_TRAP, + DART_TRAP, + ROCKTRAP, + SQKY_BOARD, + BEAR_TRAP, + LANDMINE, + ROLLING_BOULDER_TRAP, + SLP_GAS_TRAP, + RUST_TRAP, + FIRE_TRAP, + PIT, + SPIKED_PIT, + HOLE, + TRAPDOOR, + TELEP_TRAP, + LEVEL_TELEP, + MAGIC_PORTAL, + WEB, + STATUE_TRAP, + MAGIC_TRAP, + ANTI_MAGIC, + POLY_TRAP, + VIBRATING_SQUARE, + + TRAPNUM +}; #endif /* TRAP_H */ diff --git a/include/wintype.h b/include/wintype.h index e15e6725e..3dbcc0500 100644 --- a/include/wintype.h +++ b/include/wintype.h @@ -29,24 +29,24 @@ typedef union any { /* (buggy old Ultrix compiler) */ /* symbolic names for the data types housed in anything */ -/* clang-format off */ -#define ANY_VOID 1 -#define ANY_OBJ 2 /* struct obj */ -#define ANY_MONST 3 /* struct monst (not used) */ -#define ANY_INT 4 /* int */ -#define ANY_CHAR 5 /* char */ -#define ANY_UCHAR 6 /* unsigned char */ -#define ANY_SCHAR 7 /* signed char */ -#define ANY_UINT 8 /* unsigned int */ -#define ANY_LONG 9 /* long */ -#define ANY_ULONG 10 /* unsigned long */ -#define ANY_IPTR 11 /* pointer to int */ -#define ANY_UPTR 12 /* pointer to unsigned int */ -#define ANY_LPTR 13 /* pointer to long */ -#define ANY_ULPTR 14 /* pointer to unsigned long */ -#define ANY_STR 15 /* pointer to null-terminated char string */ -#define ANY_MASK32 16 /* 32-bit mask (stored as unsigned long) */ -/* clang-format on */ +enum any_types { + ANY_VOID = 1, + ANY_OBJ, /* struct obj */ + ANY_MONST, /* struct monst (not used) */ + ANY_INT, /* int */ + ANY_CHAR, /* char */ + ANY_UCHAR, /* unsigned char */ + ANY_SCHAR, /* signed char */ + ANY_UINT, /* unsigned int */ + ANY_LONG, /* long */ + ANY_ULONG, /* unsigned long */ + ANY_IPTR, /* pointer to int */ + ANY_UPTR, /* pointer to unsigned int */ + ANY_LPTR, /* pointer to long */ + ANY_ULPTR, /* pointer to unsigned long */ + ANY_STR, /* pointer to null-terminated char string */ + ANY_MASK32 /* 32-bit mask (stored as unsigned long) */ +}; /* menu return list */ typedef struct mi { From ecf1500b6c4ad0360a5e37f314051c348d96afca Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Mon, 10 Oct 2016 21:55:23 +0300 Subject: [PATCH 02/23] Use even more enums --- include/rm.h | 204 ++++++++++++++++++++++++++------------------------- 1 file changed, 103 insertions(+), 101 deletions(-) diff --git a/include/rm.h b/include/rm.h index d7a494196..abcdd8c08 100644 --- a/include/rm.h +++ b/include/rm.h @@ -111,120 +111,122 @@ enum levl_typ_types { */ /* begin dungeon characters */ - -#define S_stone 0 -#define S_vwall 1 -#define S_hwall 2 -#define S_tlcorn 3 -#define S_trcorn 4 -#define S_blcorn 5 -#define S_brcorn 6 -#define S_crwall 7 -#define S_tuwall 8 -#define S_tdwall 9 -#define S_tlwall 10 -#define S_trwall 11 -#define S_ndoor 12 -#define S_vodoor 13 -#define S_hodoor 14 -#define S_vcdoor 15 /* closed door, vertical wall */ -#define S_hcdoor 16 /* closed door, horizontal wall */ -#define S_bars 17 /* KMH -- iron bars */ -#define S_tree 18 /* KMH */ -#define S_room 19 -#define S_darkroom 20 -#define S_corr 21 -#define S_litcorr 22 -#define S_upstair 23 -#define S_dnstair 24 -#define S_upladder 25 -#define S_dnladder 26 -#define S_altar 27 -#define S_grave 28 -#define S_throne 29 -#define S_sink 30 -#define S_fountain 31 -#define S_pool 32 -#define S_ice 33 -#define S_lava 34 -#define S_vodbridge 35 -#define S_hodbridge 36 -#define S_vcdbridge 37 /* closed drawbridge, vertical wall */ -#define S_hcdbridge 38 /* closed drawbridge, horizontal wall */ -#define S_air 39 -#define S_cloud 40 -#define S_water 41 +enum screen_symbols { + S_stone = 0, + S_vwall, + S_hwall, + S_tlcorn, + S_trcorn, + S_blcorn, + S_brcorn, + S_crwall, + S_tuwall, + S_tdwall, + S_tlwall, + S_trwall, + S_ndoor, + S_vodoor, + S_hodoor, + S_vcdoor, /* closed door, vertical wall */ + S_hcdoor, /* closed door, horizontal wall */ + S_bars, /* KMH -- iron bars */ + S_tree, /* KMH */ + S_room, + S_darkroom, + S_corr, + S_litcorr, + S_upstair, + S_dnstair, + S_upladder, + S_dnladder, + S_altar, + S_grave, + S_throne, + S_sink, + S_fountain, + S_pool, + S_ice, + S_lava, + S_vodbridge, + S_hodbridge, + S_vcdbridge, /* closed drawbridge, vertical wall */ + S_hcdbridge, /* closed drawbridge, horizontal wall */ + S_air, + S_cloud, + S_water, /* end dungeon characters, begin traps */ -#define S_arrow_trap 42 -#define S_dart_trap 43 -#define S_falling_rock_trap 44 -#define S_squeaky_board 45 -#define S_bear_trap 46 -#define S_land_mine 47 -#define S_rolling_boulder_trap 48 -#define S_sleeping_gas_trap 49 -#define S_rust_trap 50 -#define S_fire_trap 51 -#define S_pit 52 -#define S_spiked_pit 53 -#define S_hole 54 -#define S_trap_door 55 -#define S_teleportation_trap 56 -#define S_level_teleporter 57 -#define S_magic_portal 58 -#define S_web 59 -#define S_statue_trap 60 -#define S_magic_trap 61 -#define S_anti_magic_trap 62 -#define S_polymorph_trap 63 -#define S_vibrating_square 64 + S_arrow_trap, + S_dart_trap, + S_falling_rock_trap, + S_squeaky_board, + S_bear_trap, + S_land_mine, + S_rolling_boulder_trap, + S_sleeping_gas_trap, + S_rust_trap, + S_fire_trap, + S_pit, + S_spiked_pit, + S_hole, + S_trap_door, + S_teleportation_trap, + S_level_teleporter, + S_magic_portal, + S_web, + S_statue_trap, + S_magic_trap, + S_anti_magic_trap, + S_polymorph_trap, + S_vibrating_square, /* end traps, begin special effects */ -#define S_vbeam 65 /* The 4 zap beam symbols. Do NOT separate. */ -#define S_hbeam 66 /* To change order or add, see function */ -#define S_lslant 67 /* zapdir_to_glyph() in display.c. */ -#define S_rslant 68 -#define S_digbeam 69 /* dig beam symbol */ -#define S_flashbeam 70 /* camera flash symbol */ -#define S_boomleft 71 /* thrown boomerang, open left, e.g ')' */ -#define S_boomright 72 /* thrown boomerang, open right, e.g. '(' */ -#define S_ss1 73 /* 4 magic shield glyphs */ -#define S_ss2 74 -#define S_ss3 75 -#define S_ss4 76 -#define S_poisoncloud 77 -#define S_goodpos 78 /* valid position for targeting */ + S_vbeam, /* The 4 zap beam symbols. Do NOT separate. */ + S_hbeam, /* To change order or add, see function */ + S_lslant, /* zapdir_to_glyph() in display.c. */ + S_rslant, + S_digbeam, /* dig beam symbol */ + S_flashbeam, /* camera flash symbol */ + S_boomleft, /* thrown boomerang, open left, e.g ')' */ + S_boomright, /* thrown boomerang, open right, e.g. '(' */ + S_ss1, /* 4 magic shield glyphs */ + S_ss2, + S_ss3, + S_ss4, + S_poisoncloud, + S_goodpos, /* valid position for targeting */ /* The 8 swallow symbols. Do NOT separate. To change order or add, see */ /* the function swallow_to_glyph() in display.c. */ -#define S_sw_tl 79 /* swallow top left [1] */ -#define S_sw_tc 80 /* swallow top center [2] Order: */ -#define S_sw_tr 81 /* swallow top right [3] */ -#define S_sw_ml 82 /* swallow middle left [4] 1 2 3 */ -#define S_sw_mr 83 /* swallow middle right [6] 4 5 6 */ -#define S_sw_bl 84 /* swallow bottom left [7] 7 8 9 */ -#define S_sw_bc 85 /* swallow bottom center [8] */ -#define S_sw_br 86 /* swallow bottom right [9] */ + S_sw_tl, /* swallow top left [1] */ + S_sw_tc, /* swallow top center [2] Order: */ + S_sw_tr, /* swallow top right [3] */ + S_sw_ml, /* swallow middle left [4] 1 2 3 */ + S_sw_mr, /* swallow middle right [6] 4 5 6 */ + S_sw_bl, /* swallow bottom left [7] 7 8 9 */ + S_sw_bc, /* swallow bottom center [8] */ + S_sw_br, /* swallow bottom right [9] */ -#define S_explode1 87 /* explosion top left */ -#define S_explode2 88 /* explosion top center */ -#define S_explode3 89 /* explosion top right Ex. */ -#define S_explode4 90 /* explosion middle left */ -#define S_explode5 91 /* explosion middle center /-\ */ -#define S_explode6 92 /* explosion middle right |@| */ -#define S_explode7 93 /* explosion bottom left \-/ */ -#define S_explode8 94 /* explosion bottom center */ -#define S_explode9 95 /* explosion bottom right */ + S_explode1, /* explosion top left */ + S_explode2, /* explosion top center */ + S_explode3, /* explosion top right Ex. */ + S_explode4, /* explosion middle left */ + S_explode5, /* explosion middle center /-\ */ + S_explode6, /* explosion middle right |@| */ + S_explode7, /* explosion bottom left \-/ */ + S_explode8, /* explosion bottom center */ + S_explode9, /* explosion bottom right */ /* end effects */ -#define MAXPCHARS 96 /* maximum number of mapped characters */ -#define MAXDCHARS 42 /* maximum of mapped dungeon characters */ -#define MAXTCHARS 22 /* maximum of mapped trap characters */ -#define MAXECHARS 31 /* maximum of mapped effects characters */ + MAXPCHARS /* maximum number of mapped characters */ +}; + +#define MAXDCHARS (S_water - S_stone + 1) /* maximum of mapped dungeon characters */ +#define MAXTCHARS (S_vibrating_square - S_arrow_trap + 1) /* maximum of mapped trap characters */ +#define MAXECHARS (S_explode9 - S_vbeam + 1) /* maximum of mapped effects characters */ #define MAXEXPCHARS 9 /* number of explosion characters */ #define DARKROOMSYM (Is_rogue_level(&u.uz) ? S_stone : S_darkroom) From 63487e8dbd1ee6598909e4f5003dbeae063ecd19 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 11 Oct 2016 12:45:24 +0300 Subject: [PATCH 03/23] Sometimes create mazes with wide corridors ...and/or thick walls. --- src/mkmaze.c | 121 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 102 insertions(+), 19 deletions(-) diff --git a/src/mkmaze.c b/src/mkmaze.c index 9d4124d2c..bdfb2ca37 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -618,6 +618,96 @@ fixup_special() num_lregions = 0; } +/* Create a maze with specified corridor width and wall thickness + * TODO: rewrite walkfrom so it works on temp space, not levl + */ +void +create_maze(corrwid, wallthick) +int corrwid; +int wallthick; +{ + int x,y; + coord mm; + int tmp_xmax = x_maze_max; + int tmp_ymax = y_maze_max; + int rdx = 0; + int rdy = 0; + int scale; + + if (wallthick < 1) + wallthick = 1; + else if (wallthick > 5) + wallthick = 5; + + if (corrwid < 1) + corrwid = 1; + else if (corrwid > 5) + corrwid = 5; + + scale = corrwid + wallthick; + rdx = (x_maze_max / scale); + rdy = (y_maze_max / scale); + + if (level.flags.corrmaze) + for (x = 2; x < (rdx*2); x++) + for (y = 2; y < (rdy*2); y++) + levl[x][y].typ = STONE; + else + for (x = 2; x <= (rdx*2); x++) + for (y = 2; y <= (rdy*2); y++) + levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL; + + /* set upper bounds for maze0xy and walkfrom */ + x_maze_max = (rdx*2); + y_maze_max = (rdy*2); + + /* create maze */ + maze0xy(&mm); + walkfrom((int) mm.x, (int) mm.y, 0); + + /* restore bounds */ + x_maze_max = tmp_xmax; + y_maze_max = tmp_ymax; + + /* scale maze up if needed */ + if (scale > 2) { + char tmpmap[COLNO][ROWNO]; + int rx = 1,ry = 1; + + /* back up the existing smaller maze */ + for (x = 1; x < x_maze_max; x++) + for (y = 1; y < y_maze_max; y++) { + tmpmap[x][y] = levl[x][y].typ; + } + + /* do the scaling */ + rx = x = 2; + while (rx < x_maze_max) { + int mx = (x % 2) ? corrwid + : ((x == 2 || x == ((rdx*2))) ? 1 : wallthick); + ry = y = 2; + while (ry < y_maze_max) { + int dx = 0, dy = 0; + int my = (y % 2) ? corrwid + : ((y == 2 || y == ((rdy*2))) ? 1 : wallthick); + for (dx = 0; dx < mx; dx++) + for (dy = 0; dy < my; dy++) { + if (rx+dx >= x_maze_max + || ry+dy >= y_maze_max) + break; + levl[rx + dx][ry + dy].typ = tmpmap[x][y]; + } + ry += my; + y++; + } + rx += mx; + x++; + } + + } +} + + void makemaz(s) const char *s; @@ -686,19 +776,12 @@ const char *s; level.flags.is_maze_lev = TRUE; level.flags.corrmaze = !rn2(3); - if (level.flags.corrmaze) - for (x = 2; x < x_maze_max; x++) - for (y = 2; y < y_maze_max; y++) - levl[x][y].typ = STONE; - else - for (x = 2; x <= x_maze_max; x++) - for (y = 2; y <= y_maze_max; y++) - levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL; - - maze0xy(&mm); - walkfrom((int) mm.x, (int) mm.y, 0); - /* put a boulder at the maze center */ - (void) mksobj_at(BOULDER, (int) mm.x, (int) mm.y, TRUE, FALSE); + if (!Invocation_lev(&u.uz) && rn2(2)) { + int corrscale = rnd(4); + create_maze(corrscale,rnd(4)-corrscale); + } else { + create_maze(1,1); + } if (!level.flags.corrmaze) wallification(2, 2, x_maze_max, y_maze_max); @@ -880,8 +963,8 @@ coord *cc; int cpt = 0; do { - cc->x = 3 + 2 * rn2((x_maze_max >> 1) - 1); - cc->y = 3 + 2 * rn2((y_maze_max >> 1) - 1); + cc->x = 1 + rn2(x_maze_max); + cc->y = 1 + rn2(y_maze_max); cpt++; } while (cpt < 100 && levl[cc->x][cc->y].typ @@ -890,10 +973,10 @@ coord *cc; int x, y; /* last try */ - for (x = 0; x < (x_maze_max >> 1) - 1; x++) - for (y = 0; y < (y_maze_max >> 1) - 1; y++) { - cc->x = 3 + 2 * x; - cc->y = 3 + 2 * y; + for (x = 1; x < x_maze_max; x++) + for (y = 1; y < y_maze_max; y++) { + cc->x = x; + cc->y = y; if (levl[cc->x][cc->y].typ == (level.flags.corrmaze ? CORR : ROOM)) return; From 56e51b9b6bdc3f9f4f6b134b729fbf75e7f486da Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 11 Oct 2016 17:26:32 +0300 Subject: [PATCH 04/23] Add wizmode command to recreate current level --- dat/wizhelp | 1 + doc/fixes36.1 | 2 ++ src/cmd.c | 18 ++++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/dat/wizhelp b/dat/wizhelp index 941ad50b2..b85d301ce 100644 --- a/dat/wizhelp +++ b/dat/wizhelp @@ -20,6 +20,7 @@ Debug-Mode Quick Reference: #timeout == look at timeout queue #vision == show vision array #vanquished == disclose counts of dead monsters +#wizmakemap == recreate the current level #wizsmell == smell a monster #wizintrinsic == set selected intrinsic timeouts #wizrumorcheck == validate first and last rumor for true and false set diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 47995a24f..efc7afa1e 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -348,6 +348,7 @@ give quest guardians some equipment hero polyed into ghoul can only eat non-veggy corpses or eggs kicking activates statue traps pets start with apport equal to your charisma +sometimes generate the random mazes with wide corridors or thick walls Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository @@ -502,6 +503,7 @@ random horses have a tiny chance of being generated saddled give feedback just before timed levitation runs out travel accepts 'm' (request menu) prefix pressing a or A when cursor positioning shows menu of "interesting" features +wizard-mode command #wizmakemap to recreate the current level Platform- and/or Interface-Specific New Features diff --git a/src/cmd.c b/src/cmd.c index 8444fbfae..47d072f42 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3,6 +3,7 @@ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" +#include "lev.h" #include "func_tab.h" #ifdef ALTMETA @@ -123,6 +124,7 @@ STATIC_PTR int NDECL(wiz_wish); STATIC_PTR int NDECL(wiz_identify); STATIC_PTR int NDECL(wiz_intrinsic); STATIC_PTR int NDECL(wiz_map); +STATIC_PTR int NDECL(wiz_makemap); STATIC_PTR int NDECL(wiz_genesis); STATIC_PTR int NDECL(wiz_where); STATIC_PTR int NDECL(wiz_detect); @@ -610,6 +612,21 @@ wiz_identify(VOID_ARGS) return 0; } +STATIC_PTR int +wiz_makemap(VOID_ARGS) +{ + if (wizard) { + savelev(-1, ledger_no(&u.uz), FREE_SAVE); + mklev(); + reglyph_darkroom(); + vision_reset(); + vision_full_recalc = 1; + (void) safe_teleds(TRUE); + docrt(); + flush_screen(1); + } +} + /* ^F command - reveal the level map and any traps on it */ STATIC_PTR int wiz_map(VOID_ARGS) @@ -2812,6 +2829,7 @@ struct ext_func_tab extcmdlist[] = { { C('i'), "wizidentify", "identify all items in inventory", wiz_identify, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "wizintrinsic", "set intrinsic", wiz_intrinsic, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { C('v'), "wizlevelport", "teleport to another level", wiz_level_tele, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, + { '\0', "wizmakemap", "recreate the current level", wiz_makemap, IFBURIED|WIZMODECMD }, { C('f'), "wizmap", "map the level", wiz_map, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "wizrumorcheck", "verify rumor boundaries", wiz_rumor_check, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, { '\0', "wizsmell", "smell monster", wiz_smell, IFBURIED|AUTOCOMPLETE|WIZMODECMD }, From 09c517e830b9b4ba2643269b1879c77c4c34e449 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 11 Oct 2016 17:59:35 +0300 Subject: [PATCH 05/23] Fix valgrind complaint --- win/X11/winmisc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/win/X11/winmisc.c b/win/X11/winmisc.c index f9d4a248a..b96902588 100644 --- a/win/X11/winmisc.c +++ b/win/X11/winmisc.c @@ -732,7 +732,7 @@ int ec_indx; /* might be greater than extended_cmd_selected */ float s_min, s_max; Dimension h, hh, wh, vh; /* widget and viewport heights */ Dimension border_width; - int distance; + int distance = 0; boolean force_top = (ec_indx < 0); /* From 23157c48300de19493c0269b116b0f355959f3a5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 11 Oct 2016 18:34:41 +0300 Subject: [PATCH 06/23] Free allocated memory --- src/do_name.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/do_name.c b/src/do_name.c index e55caf1d3..3a98b5662 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -415,6 +415,7 @@ boolean fovonly; gather_locs(&garr, &gcount, fovonly ? GLOC_INTERESTING_FOV : GLOC_INTERESTING); if (gcount < 2) { /* gcount always includes the hero */ + free((genericptr_t) garr); You("cannot %s anything interesting.", fovonly ? "see" : "detect"); return FALSE; } From 9858e46f6419d762f3ffa1445fd12626efe64741 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 11 Oct 2016 23:03:32 +0300 Subject: [PATCH 07/23] Show correct keybind in ext cmd list --- src/cmd.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/cmd.c b/src/cmd.c index 47d072f42..437b1a19e 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -329,8 +329,9 @@ doextcmd(VOID_ARGS) return 0; } if (iflags.menu_requested && !accept_menu_prefix(func)) { - pline("'%s' prefix has no effect for this command.", - visctrl(Cmd.spkeys[NHKF_REQMENU])); + pline("'%s' prefix has no effect for the %s command.", + visctrl(Cmd.spkeys[NHKF_REQMENU]), + extcmdlist[idx].ef_txt); iflags.menu_requested = FALSE; } retval = (*func)(); @@ -346,13 +347,18 @@ doextlist(VOID_ARGS) register const struct ext_func_tab *efp; char buf[BUFSZ]; winid datawin; + char ch = cmd_from_func(doextcmd); datawin = create_nhwindow(NHW_TEXT); putstr(datawin, 0, ""); putstr(datawin, 0, " Extended Commands List"); putstr(datawin, 0, ""); - putstr(datawin, 0, " Press '#', then type:"); - putstr(datawin, 0, ""); + if (ch) { + Sprintf(buf, " Press '%s', then type:", + visctrl(ch)); + putstr(datawin, 0, buf); + putstr(datawin, 0, ""); + } for (efp = extcmdlist; efp->ef_txt; efp++) { if (!wizard && (efp->flags & WIZMODECMD)) From 90ca75d0d9a597e3b195d5610d54c190fdd95b30 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 11 Oct 2016 16:03:45 -0700 Subject: [PATCH 08/23] lint fix --- src/cmd.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/cmd.c b/src/cmd.c index 437b1a19e..4d356edb0 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -631,6 +631,7 @@ wiz_makemap(VOID_ARGS) docrt(); flush_screen(1); } + return 0; } /* ^F command - reveal the level map and any traps on it */ From 4af4fc11431744525ff7fb18e2be00d53d0e80a0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Wed, 12 Oct 2016 18:39:24 +0300 Subject: [PATCH 09/23] Occasionally remove maze dead ends, creating loops --- doc/fixes36.1 | 3 ++- src/mkmaze.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index efc7afa1e..282b8bdd3 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -348,7 +348,8 @@ give quest guardians some equipment hero polyed into ghoul can only eat non-veggy corpses or eggs kicking activates statue traps pets start with apport equal to your charisma -sometimes generate the random mazes with wide corridors or thick walls +sometimes generate the random mazes with wide corridors, thick walls, + or with dead ends changed to loops Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/mkmaze.c b/src/mkmaze.c index bdfb2ca37..9c6d18715 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -618,6 +618,57 @@ fixup_special() num_lregions = 0; } +boolean +maze_inbounds(x,y) +int x,y; +{ + return (x >= 2 && y >= 2 + && x < x_maze_max && y < y_maze_max && isok(x,y)); +} + +void +maze_remove_deadends(typ) +xchar typ; +{ + int x,y, dir; + for (x = 2; x < x_maze_max; x++) + for (y = 2; y < y_maze_max; y++) + if (ACCESSIBLE(levl[x][y].typ) && (x % 2) && (y % 2)) { + char dirok[4]; + int idx = 0; + int idx2 = 0; + for (dir = 0; dir < 4; dir++) { + int dx = x; + int dy = y; + int dx2 = x; + int dy2 = y; + mz_move(dx,dy, dir); + if (!maze_inbounds(dx,dy)) { + idx2++; + continue; + } + mz_move(dx2,dy2, dir); + mz_move(dx2,dy2, dir); + if (!maze_inbounds(dx2,dy2)) { + idx2++; + continue; + } + if (!ACCESSIBLE(levl[dx][dy].typ) + && ACCESSIBLE(levl[dx2][dy2].typ)) { + dirok[idx++] = dir; + idx2++; + } + } + if (idx2 >= 3 && idx > 0) { + dir = dirok[rn2(idx)]; + int dx = x; + int dy = y; + mz_move(dx,dy, dir); + levl[dx][dy].typ = typ; + } + } +} + /* Create a maze with specified corridor width and wall thickness * TODO: rewrite walkfrom so it works on temp space, not levl */ @@ -665,6 +716,9 @@ int wallthick; maze0xy(&mm); walkfrom((int) mm.x, (int) mm.y, 0); + if (!rn2(5)) + maze_remove_deadends((level.flags.corrmaze) ? CORR : ROOM); + /* restore bounds */ x_maze_max = tmp_xmax; y_maze_max = tmp_ymax; From abb4f0fab2e52b9fc4a77ac898dc7a57662ddecf Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Thu, 13 Oct 2016 20:16:21 +0300 Subject: [PATCH 10/23] Allow toggling menu for any travel target list --- doc/Guidebook.mn | 18 +++++- doc/Guidebook.tex | 21 ++++++- include/extern.h | 2 +- include/flag.h | 16 ++++- src/cmd.c | 8 ++- src/do_name.c | 148 +++++++++++++++++++++++++++++----------------- src/options.c | 2 + 7 files changed, 150 insertions(+), 65 deletions(-) diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 171388b6e..cf4d13739 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -2910,6 +2910,14 @@ The option is also used with the `/m', `/M', `/o', and `/O' sub-commands of `/', where the `none' setting is overridden with `map'. +.lp whatis_inview +When getting a location on the map, and using the keys to cycle through +next and previous targets, limit the possible targets to those in view. +(default off) +.lp whatis_menu +When getting a location on the map, and using a key to cycle through +next and previous targets, use a menu instead to pick a target. +(default off) .lp windowtype Select which windowing system to use, such as ``tty'' or ``X11'' (default depends on version). @@ -3201,6 +3209,10 @@ When asked for a direction, the key to target yourself. Default is '.'. When asked for a direction, the key to target yourself. Default is 's'. .lp getpos.autodescribe When asked for a location, the key to toggle autodescribe. Default is '#'. +.lp getpos.all.next +When asked for a location, the key to go to next closest interesting thing. Default is 'a'. +.lp getpos.all.prev +When asked for a location, the key to go to previous closest interesting thing. Default is 'A'. .lp getpos.door.next When asked for a location, the key to go to next closest door or doorway. Default is 'd'. .lp getpos.door.prev @@ -3216,9 +3228,9 @@ When asked for a location, the key to go to next closest object. Default is 'o'. .lp getpos.obj.prev When asked for a location, the key to go to previous closest object. Default is 'O'. .lp getpos.menu -When asked for a location, show a menu of all interesting targets. Default is 'A'. -.lp getpos.menu.cansee -When asked for a location, show a menu of interesting targets in view. Default is 'a'. +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle showing a menu instead. Default is '!'. +.lp getpos.inview +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle limiting possible targets to those in view only. Default is '"'. .lp getpos.pick When asked for a location, the key to choose the location, and possibly ask for more info. Default is '.'. .lp getpos.pick.once diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 5ea6a5679..5bf4fc351 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -3543,6 +3543,15 @@ the `{\tt /m}', `{\tt /M}', `{\tt /o}', and `{\tt /O}' sub-commands of `{\tt /}', where the `{\it none\/}' setting is overridden with `{\it map}'. %.lp +\item[\ib{whatis\verb+_+inview}] +When getting a location on the map, and using the keys to cycle through +next and previous targets, limit the possible targets to those in view. +(default off) +\item[\ib{whatis\verb+_+menu}] +When getting a location on the map, and using a key to cycle through +next and previous targets, use a menu instead to pick a target. +(default off) +%.lp \item[\ib{windowtype}] Select which windowing system to use, such as ``{\tt tty}'' or ``{\tt X11}'' (default depends on version). @@ -3917,6 +3926,12 @@ When asked for a direction, the key to target yourself. Default is ``{\tt s}''. \item{\bb{getpos.autodescribe}} When asked for a location, the key to toggle {\it autodescribe\/}. Default is ``{\tt \#}''. %.lp +\item{\bb{getpos.all.next}} +When asked for a location, the key to go to next closest interesting thing. Default is ``{\tt a}''. +%.lp +\item{\bb{getpos.all.prev}} +When asked for a location, the key to go to previous closest interesting thing. Default is ``{\tt A}''. +%.lp \item{\bb{getpos.door.next}} When asked for a location, the key to go to next closest door or doorway. Default is ``{\tt d}''. %.lp @@ -3939,10 +3954,10 @@ When asked for a location, the key to go to next closest object. Default is ``{\ When asked for a location, the key to go to previous closest object. Default is ``{\tt O}''. %.lp \item{\bb{getpos.menu}} -When asked for a location, show a menu of all interesting targets. Default is '{\tt A}'. +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle showing a menu instead. Default is '{\tt !}'. %.lp -\item{\bb{getpos.menu.cansee}} -When asked for a location, show a menu of interesting targets in view. Default is '{\tt a}'. +\item{\bb{getpos.inview}} +When asked for a location, and using one of the next or previous keys to cycle through targets, toggle limiting possible targets to those in view only. Default is '{\tt "}'. %.lp \item{\bb{getpos.pick}} When asked for a location, the key to choose the location, and possibly ask for more info. Default is ``{\tt .}''. diff --git a/include/extern.h b/include/extern.h index a1cce9f22..0129b888f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -379,7 +379,7 @@ E void NDECL(heal_legs); /* ### do_name.c ### */ E char *FDECL(coord_desc, (int, int, char *, CHAR_P)); -E boolean FDECL(getpos_menu, (coord *, BOOLEAN_P)); +E boolean FDECL(getpos_menu, (coord *, BOOLEAN_P, int)); E int FDECL(getpos, (coord *, BOOLEAN_P, const char *)); E void FDECL(getpos_sethilite, (void (*f)(int))); E void FDECL(new_mname, (struct monst *, int)); diff --git a/include/flag.h b/include/flag.h index b28b0e673..4927cb632 100644 --- a/include/flag.h +++ b/include/flag.h @@ -194,6 +194,8 @@ struct instance_flags { #define TER_MON 0x08 #define TER_DETECT 0x10 /* detect_foo magic rather than #terrain */ boolean getloc_travelmode; + boolean getloc_limitview; + boolean getloc_usemenu; coord travelcc; /* coordinates for travel_cache */ boolean window_inited; /* true if init_nhwindows() completed */ boolean vision_inited; /* true if vision is ready */ @@ -471,13 +473,25 @@ enum nh_keyfunc { NHKF_GETPOS_DOOR_PREV, NHKF_GETPOS_UNEX_NEXT, NHKF_GETPOS_UNEX_PREV, + NHKF_GETPOS_INTERESTING_NEXT, + NHKF_GETPOS_INTERESTING_PREV, NHKF_GETPOS_HELP, NHKF_GETPOS_MENU, - NHKF_GETPOS_MENU_FOV, + NHKF_GETPOS_LIMITVIEW, NUM_NHKF }; +enum gloctypes { + GLOC_MONS = 0, + GLOC_OBJS, + GLOC_DOOR, + GLOC_EXPLORE, + GLOC_INTERESTING, + + NUM_GLOCS +}; + /* commands[] is used to directly access cmdlist[] instead of looping through it to find the entry for a given input character; move_X is the character used for moving one step in direction X; diff --git a/src/cmd.c b/src/cmd.c index 4d356edb0..35ffe9c1f 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -3544,9 +3544,11 @@ struct { { NHKF_GETPOS_DOOR_PREV, 'D', "getpos.door.prev" }, { NHKF_GETPOS_UNEX_NEXT, 'x', "getpos.unexplored.next" }, { NHKF_GETPOS_UNEX_PREV, 'X', "getpos.unexplored.prev" }, + { NHKF_GETPOS_INTERESTING_NEXT, 'a', "getpos.all.next" }, + { NHKF_GETPOS_INTERESTING_PREV, 'A', "getpos.all.prev" }, { NHKF_GETPOS_HELP, '?', "getpos.help" }, - { NHKF_GETPOS_MENU, 'A', "getpos.menu" }, - { NHKF_GETPOS_MENU_FOV, 'a', "getpos.menu.cansee" } + { NHKF_GETPOS_LIMITVIEW, '"', "getpos.inview" }, + { NHKF_GETPOS_MENU, '!', "getpos.menu" } }; boolean @@ -4727,7 +4729,7 @@ dotravel(VOID_ARGS) } iflags.getloc_travelmode = TRUE; if (iflags.menu_requested) { - if (!getpos_menu(&cc, TRUE)) { + if (!getpos_menu(&cc, TRUE, GLOC_INTERESTING)) { iflags.getloc_travelmode = FALSE; return 0; } diff --git a/src/do_name.c b/src/do_name.c index 3a98b5662..6ec045fa8 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -44,6 +44,32 @@ void FDECL((*f), (int)); getpos_hilitefunc = f; } +const char *const gloc_descr[NUM_GLOCS][4] = { + { "any monsters", "monster", "next monster", "monsters" }, + { "any items", "item", "next object", "objects" }, + { "any doors", "door", "next door or doorway", "doors or doorways" }, + { "any unexplored areas", "unexplored area", "unexplored location", "unexplored locations" }, + { "anything interesting", "interesting thing", "anything interesting", "anything interesting" } +}; + + +void +getpos_help_keyxhelp(tmpwin, k1,k2,gloc) +winid tmpwin; +const char *k1; +const char *k2; +int gloc; +{ + char sbuf[BUFSZ]; + Sprintf(sbuf, "Use '%s' or '%s' to %s%s%s.", + k1, k2, + iflags.getloc_usemenu ? "get a menu of " + : "move the cursor to ", + gloc_descr[gloc][2 + iflags.getloc_usemenu], + iflags.getloc_limitview ? " in view" : ""); + putstr(tmpwin, 0, sbuf); +} + /* the response for '?' help request in getpos() */ STATIC_OVL void getpos_help(force, goal) @@ -63,37 +89,39 @@ const char *goal; visctrl(Cmd.spkeys[NHKF_GETPOS_SELF])); putstr(tmpwin, 0, sbuf); if (!iflags.terrainmode || (iflags.terrainmode & TER_MON) != 0) { - Sprintf(sbuf, "Use '%s' or '%s' to move the cursor to next monster.", - visctrl(Cmd.spkeys[NHKF_GETPOS_MON_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_MON_PREV])); - putstr(tmpwin, 0, sbuf); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_MON_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_MON_PREV]), + GLOC_MONS); } if (!iflags.terrainmode || (iflags.terrainmode & TER_OBJ) != 0) { - Sprintf(sbuf, "Use '%s' or '%s' to move the cursor to next object.", - visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_PREV])); - putstr(tmpwin, 0, sbuf); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_OBJ_PREV]), + GLOC_OBJS); } if (!iflags.terrainmode || (iflags.terrainmode & TER_MAP) != 0) { - /* both of these are primarily useful when choosing a travel + /* these are primarily useful when choosing a travel destination for the '_' command */ - Sprintf(sbuf, - "Use '%s' or '%s' to move the cursor to next door or doorway.", - visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_PREV])); - putstr(tmpwin, 0, sbuf); - Sprintf(sbuf, - "Use '%s' or '%s' to move the cursor to unexplored location.", - visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_NEXT]), - visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_PREV])); - putstr(tmpwin, 0, sbuf); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_DOOR_PREV]), + GLOC_DOOR); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_UNEX_PREV]), + GLOC_EXPLORE); + getpos_help_keyxhelp(tmpwin, + visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_NEXT]), + visctrl(Cmd.spkeys[NHKF_GETPOS_INTERESTING_PREV]), + GLOC_INTERESTING); } - Sprintf(sbuf, "Use '%s' for a menu of interesting targets in view.", - visctrl(Cmd.spkeys[NHKF_GETPOS_MENU_FOV])); - putstr(tmpwin, 0, sbuf); - Sprintf(sbuf, "Use '%s' for a menu of all interesting targets.", + Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.", visctrl(Cmd.spkeys[NHKF_GETPOS_MENU])); putstr(tmpwin, 0, sbuf); + Sprintf(sbuf, "Use '%s' to toggle limiting possible targets to in view only.", + visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW])); + putstr(tmpwin, 0, sbuf); if (!iflags.terrainmode) { char kbuf[BUFSZ]; if (getpos_hilitefunc) { @@ -174,19 +202,6 @@ const void *b; return dist_1 - dist_2; } -enum gloctypes { - GLOC_MONS = 0, - GLOC_OBJS, - GLOC_DOOR, - GLOC_EXPLORE, - - NUM_GLOCS, - - GLOC_INTERESTING, - GLOC_INTERESTING_FOV -}; - - #define IS_UNEXPLORED_LOC(x,y) \ (isok((x), (y)) \ && glyph_is_cmap(levl[(x)][(y)].glyph) \ @@ -202,6 +217,9 @@ int x,y, gloc; */ int glyph = glyph_at(x, y); + if (iflags.getloc_limitview && !cansee(x,y)) + return FALSE; + switch (gloc) { default: case GLOC_MONS: @@ -231,9 +249,6 @@ int x,y, gloc; || IS_UNEXPLORED_LOC(x - 1, y) || IS_UNEXPLORED_LOC(x, y + 1) || IS_UNEXPLORED_LOC(x, y - 1))); - case GLOC_INTERESTING_FOV: - if (!cansee(x,y)) - return FALSE; case GLOC_INTERESTING: return gather_locs_interesting(x,y, GLOC_DOOR) || !(glyph_is_cmap(glyph) @@ -400,9 +415,10 @@ int cx, cy; } boolean -getpos_menu(ccp, fovonly) +getpos_menu(ccp, fovonly, gloc) coord *ccp; boolean fovonly; +int gloc; { coord *garr = DUMMY; int gcount = 0; @@ -412,11 +428,12 @@ boolean fovonly; menu_item *picks = (menu_item *) 0; char tmpbuf[BUFSZ]; - gather_locs(&garr, &gcount, - fovonly ? GLOC_INTERESTING_FOV : GLOC_INTERESTING); + gather_locs(&garr, &gcount, gloc); + if (gcount < 2) { /* gcount always includes the hero */ free((genericptr_t) garr); - You("cannot %s anything interesting.", fovonly ? "see" : "detect"); + You("cannot %s %s.", + fovonly ? "see" : "detect", gloc_descr[gloc][0]); return FALSE; } @@ -424,7 +441,8 @@ boolean fovonly; start_menu(tmpwin); any = zeroany; - for (i = 0; i < gcount; i++) { + /* gather_locs returns array[0] == you. skip it. */ + for (i = 1; i < gcount; i++) { char fullbuf[BUFSZ]; coord tmpcc; const char *firstmatch = "unknown"; @@ -440,8 +458,8 @@ boolean fovonly; } } - Sprintf(tmpbuf, "Pick a target%s%s", - fovonly ? " in view" : "", + Sprintf(tmpbuf, "Pick a target %s%s%s", + gloc_descr[gloc][1], fovonly ? " in view" : "", iflags.getloc_travelmode ? " for travel" : ""); end_menu(tmpwin, tmpbuf); pick_cnt = select_menu(tmpwin, PICK_ONE, &picks); @@ -478,10 +496,12 @@ const char *goal; NHKF_GETPOS_DOOR_NEXT, NHKF_GETPOS_DOOR_PREV, NHKF_GETPOS_UNEX_NEXT, - NHKF_GETPOS_UNEX_PREV + NHKF_GETPOS_UNEX_PREV, + NHKF_GETPOS_INTERESTING_NEXT, + NHKF_GETPOS_INTERESTING_PREV }; char pick_chars[6]; - char mMoOdDxX[9]; + char mMoOdDxX[11]; int result = 0; int cx, cy, i, c; int sidx, tx, ty; @@ -618,13 +638,24 @@ const char *goal; show_goal_msg = TRUE; msg_given = TRUE; goto nxtc; - } else if (c == Cmd.spkeys[NHKF_GETPOS_MENU] - || c == Cmd.spkeys[NHKF_GETPOS_MENU_FOV]) { - coord tmpcrd; - if (getpos_menu(&tmpcrd, (c == Cmd.spkeys[NHKF_GETPOS_MENU_FOV]))) { - cx = tmpcrd.x; - cy = tmpcrd.y; + } else if (c == Cmd.spkeys[NHKF_GETPOS_LIMITVIEW]) { + iflags.getloc_limitview = !iflags.getloc_limitview; + for (i = 0; i < NUM_GLOCS; i++) { + if (garr[i]) { + free((genericptr_t) garr[i]); + garr[i] = NULL; + } + gidx[i] = gcount[i] = 0; } + pline("%s possible targets to those in sight only.", + iflags.getloc_limitview ? "Limiting" : "Not limiting"); + msg_given = TRUE; + goto nxtc; + } else if (c == Cmd.spkeys[NHKF_GETPOS_MENU]) { + iflags.getloc_usemenu = !iflags.getloc_usemenu; + pline("%s a menu to show possible targets.", + iflags.getloc_usemenu ? "Using" : "Not using"); + msg_given = TRUE; goto nxtc; } else if (c == Cmd.spkeys[NHKF_GETPOS_SELF]) { /* reset 'm&M', 'o&O', &c; otherwise, there's no way for player @@ -639,6 +670,15 @@ const char *goal; int gtmp = (int) (cp - mMoOdDxX), /* 0..7 */ gloc = gtmp >> 1; /* 0..3 */ + if (iflags.getloc_usemenu) { + coord tmpcrd; + if (getpos_menu(&tmpcrd, iflags.getloc_limitview, gloc)) { + cx = tmpcrd.x; + cy = tmpcrd.y; + } + goto nxtc; + } + if (!garr[gloc]) { gather_locs(&garr[gloc], &gcount[gloc], gloc); gidx[gloc] = 0; /* garr[][0] is hero's spot */ diff --git a/src/options.c b/src/options.c index 2d30ba03a..9b610f3d9 100644 --- a/src/options.c +++ b/src/options.c @@ -230,6 +230,8 @@ static struct Bool_Opt { #else { "vt_tiledata", (boolean *) 0, FALSE, SET_IN_FILE }, #endif + { "whatis_menu", &iflags.getloc_usemenu, FALSE, SET_IN_GAME }, + { "whatis_inview", &iflags.getloc_limitview, FALSE, SET_IN_GAME }, { "wizweight", &iflags.wizweight, FALSE, SET_IN_WIZGAME }, { "wraptext", &iflags.wc2_wraptext, FALSE, SET_IN_GAME }, #ifdef ZEROCOMP From 9f8f22ea4a0089158b6105b2e5198b8dac9a7e3e Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 13 Oct 2016 12:08:06 -0700 Subject: [PATCH 11/23] more lint and formatting Fix a C89/C90 complaint about a declaration following executable code. The rest is formatting (of stuff I saw rather than systematic fixups). --- src/do_name.c | 22 ++++++++++++------- src/mkmaze.c | 59 +++++++++++++++++++++++++++------------------------ 2 files changed, 45 insertions(+), 36 deletions(-) diff --git a/src/do_name.c b/src/do_name.c index 6ec045fa8..d494942ce 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -48,23 +48,26 @@ const char *const gloc_descr[NUM_GLOCS][4] = { { "any monsters", "monster", "next monster", "monsters" }, { "any items", "item", "next object", "objects" }, { "any doors", "door", "next door or doorway", "doors or doorways" }, - { "any unexplored areas", "unexplored area", "unexplored location", "unexplored locations" }, - { "anything interesting", "interesting thing", "anything interesting", "anything interesting" } + { "any unexplored areas", "unexplored area", "unexplored location", + "unexplored locations" }, + { "anything interesting", "interesting thing", "anything interesting", + "anything interesting" } }; void -getpos_help_keyxhelp(tmpwin, k1,k2,gloc) +getpos_help_keyxhelp(tmpwin, k1, k2, gloc) winid tmpwin; const char *k1; const char *k2; int gloc; { char sbuf[BUFSZ]; + Sprintf(sbuf, "Use '%s' or '%s' to %s%s%s.", k1, k2, iflags.getloc_usemenu ? "get a menu of " - : "move the cursor to ", + : "move the cursor to ", gloc_descr[gloc][2 + iflags.getloc_usemenu], iflags.getloc_limitview ? " in view" : ""); putstr(tmpwin, 0, sbuf); @@ -80,10 +83,12 @@ const char *goal; boolean doing_what_is; winid tmpwin = create_nhwindow(NHW_MENU); - Sprintf(sbuf, "Use '%c', '%c', '%c', '%c' to move the cursor to %s.", /* hjkl */ + Sprintf(sbuf, + "Use '%c', '%c', '%c', '%c' to move the cursor to %s.", /* hjkl */ Cmd.move_W, Cmd.move_S, Cmd.move_N, Cmd.move_E, goal); putstr(tmpwin, 0, sbuf); - putstr(tmpwin, 0, "Use 'H', 'J', 'K', 'L' to move the cursor 8 units at a time."); + putstr(tmpwin, 0, + "Use 'H', 'J', 'K', 'L' to move the cursor 8 units at a time."); putstr(tmpwin, 0, "Or enter a background symbol (ex. '<')."); Sprintf(sbuf, "Use '%s' to move the cursor on yourself.", visctrl(Cmd.spkeys[NHKF_GETPOS_SELF])); @@ -119,7 +124,8 @@ const char *goal; Sprintf(sbuf, "Use '%s' to toggle menu listing for possible targets.", visctrl(Cmd.spkeys[NHKF_GETPOS_MENU])); putstr(tmpwin, 0, sbuf); - Sprintf(sbuf, "Use '%s' to toggle limiting possible targets to in view only.", + Sprintf(sbuf, + "Use '%s' to toggle limiting possible targets to in view only.", visctrl(Cmd.spkeys[NHKF_GETPOS_LIMITVIEW])); putstr(tmpwin, 0, sbuf); if (!iflags.terrainmode) { @@ -155,7 +161,7 @@ const char *goal; putstr(tmpwin, 0, sbuf); if (doing_what_is) { Sprintf(sbuf, - " '%s' describe current spot, show 'more info', move to another spot.", + " '%s' describe current spot, show 'more info', move to another spot.", visctrl(Cmd.spkeys[NHKF_GETPOS_PICK_V])); putstr(tmpwin, 0, sbuf); Sprintf(sbuf, diff --git a/src/mkmaze.c b/src/mkmaze.c index 9c6d18715..03d993590 100644 --- a/src/mkmaze.c +++ b/src/mkmaze.c @@ -619,37 +619,38 @@ fixup_special() } boolean -maze_inbounds(x,y) -int x,y; +maze_inbounds(x, y) +int x, y; { return (x >= 2 && y >= 2 - && x < x_maze_max && y < y_maze_max && isok(x,y)); + && x < x_maze_max && y < y_maze_max && isok(x, y)); } void maze_remove_deadends(typ) xchar typ; { - int x,y, dir; + char dirok[4]; + int x, y, dir, idx, idx2, dx, dy, dx2, dy2; + + dirok[0] = 0; /* lint suppression */ for (x = 2; x < x_maze_max; x++) for (y = 2; y < y_maze_max; y++) if (ACCESSIBLE(levl[x][y].typ) && (x % 2) && (y % 2)) { - char dirok[4]; - int idx = 0; - int idx2 = 0; + idx = idx2 = 0; for (dir = 0; dir < 4; dir++) { - int dx = x; - int dy = y; - int dx2 = x; - int dy2 = y; - mz_move(dx,dy, dir); - if (!maze_inbounds(dx,dy)) { + /* note: mz_move() is a macro which modifies + one of its first two parameters */ + dx = dx2 = x; + dy = dy2 = y; + mz_move(dx, dy, dir); + if (!maze_inbounds(dx, dy)) { idx2++; continue; } - mz_move(dx2,dy2, dir); - mz_move(dx2,dy2, dir); - if (!maze_inbounds(dx2,dy2)) { + mz_move(dx2, dy2, dir); + mz_move(dx2, dy2, dir); + if (!maze_inbounds(dx2, dy2)) { idx2++; continue; } @@ -660,10 +661,10 @@ xchar typ; } } if (idx2 >= 3 && idx > 0) { + dx = x; + dy = y; dir = dirok[rn2(idx)]; - int dx = x; - int dy = y; - mz_move(dx,dy, dir); + mz_move(dx, dy, dir); levl[dx][dy].typ = typ; } } @@ -700,17 +701,17 @@ int wallthick; rdy = (y_maze_max / scale); if (level.flags.corrmaze) - for (x = 2; x < (rdx*2); x++) - for (y = 2; y < (rdy*2); y++) + for (x = 2; x < (rdx * 2); x++) + for (y = 2; y < (rdy * 2); y++) levl[x][y].typ = STONE; else - for (x = 2; x <= (rdx*2); x++) - for (y = 2; y <= (rdy*2); y++) + for (x = 2; x <= (rdx * 2); x++) + for (y = 2; y <= (rdy * 2); y++) levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL; /* set upper bounds for maze0xy and walkfrom */ - x_maze_max = (rdx*2); - y_maze_max = (rdy*2); + x_maze_max = (rdx * 2); + y_maze_max = (rdy * 2); /* create maze */ maze0xy(&mm); @@ -726,7 +727,7 @@ int wallthick; /* scale maze up if needed */ if (scale > 2) { char tmpmap[COLNO][ROWNO]; - int rx = 1,ry = 1; + int rx = 1, ry = 1; /* back up the existing smaller maze */ for (x = 1; x < x_maze_max; x++) @@ -738,12 +739,14 @@ int wallthick; rx = x = 2; while (rx < x_maze_max) { int mx = (x % 2) ? corrwid - : ((x == 2 || x == ((rdx*2))) ? 1 : wallthick); + : ((x == 2 || x == (rdx * 2)) ? 1 + : wallthick); ry = y = 2; while (ry < y_maze_max) { int dx = 0, dy = 0; int my = (y % 2) ? corrwid - : ((y == 2 || y == ((rdy*2))) ? 1 : wallthick); + : ((y == 2 || y == (rdy * 2)) ? 1 + : wallthick); for (dx = 0; dx < mx; dx++) for (dy = 0; dy < my; dy++) { if (rx+dx >= x_maze_max From 17e13f1e538dd9fd9dccfe043ec8921d9e47cf6f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Fri, 14 Oct 2016 16:43:49 +0300 Subject: [PATCH 12/23] X11: Handle define-lines in NetHack.ad xrdb can load a X recource file with #define-lines, but NetHack cannot. Substitute the defines in Makefile during compile. Requires grep --- sys/unix/Makefile.dat | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/unix/Makefile.dat b/sys/unix/Makefile.dat index 535e7a808..6327b0c10 100644 --- a/sys/unix/Makefile.dat +++ b/sys/unix/Makefile.dat @@ -50,7 +50,13 @@ nhtiles.bmp: ../util/tile2bmp ../win/share/monsters.txt \ ../util/tile2bmp $@ NetHack.ad: ../win/X11/NetHack.ad - cp ../win/X11/NetHack.ad NetHack.ad +# handle "#define foo bar" -lines + grep ^#define ../win/X11/NetHack.ad | \ + sed -e 's/^#define/s/g' -e 's/ */ /g' \ + -e 's/$$/ g/g' > NetHack.ad.tmp + grep -v ^#define ../win/X11/NetHack.ad | \ + sed -f NetHack.ad.tmp > NetHack.ad + -rm -f NetHack.ad.tmp pet_mark.xbm: ../win/X11/pet_mark.xbm cp ../win/X11/pet_mark.xbm pet_mark.xbm From 35f46a01492f7d282aeda6100755de18d0eafcc0 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 15 Oct 2016 10:26:20 +0300 Subject: [PATCH 13/23] Put throne room gold in the chest --- doc/fixes36.1 | 1 + src/mkroom.c | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 282b8bdd3..9878cf716 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -350,6 +350,7 @@ kicking activates statue traps pets start with apport equal to your charisma sometimes generate the random mazes with wide corridors, thick walls, or with dead ends changed to loops +put throne room gold in the chest Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/mkroom.c b/src/mkroom.c index 49b84f3e1..c76531b52 100644 --- a/src/mkroom.c +++ b/src/mkroom.c @@ -380,12 +380,16 @@ struct mkroom *sroom; } switch (type) { case COURT: { - struct obj *chest; + struct obj *chest, *gold; levl[tx][ty].typ = THRONE; (void) somexy(sroom, &mm); - (void) mkgold((long) rn1(50 * level_difficulty(), 10), mm.x, mm.y); + gold = mksobj(GOLD_PIECE, TRUE, FALSE); + gold->quan = (long) rn1(50 * level_difficulty(), 10); + gold->owt = weight(gold); /* the royal coffers */ chest = mksobj_at(CHEST, mm.x, mm.y, TRUE, FALSE); + add_to_container(chest, gold); + chest->owt = weight(chest); chest->spe = 2; /* so it can be found later */ level.flags.has_court = 1; break; From 14bd550481506798ebf7388f94e960069abfa8af Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Sat, 15 Oct 2016 19:47:04 +0300 Subject: [PATCH 14/23] Wielding Trollsbane prevents trolls from reviving --- doc/fixes36.1 | 1 + include/timeout.h | 29 +++++++++++++++++------------ src/zap.c | 4 +++- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index 9878cf716..b997f6994 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -351,6 +351,7 @@ pets start with apport equal to your charisma sometimes generate the random mazes with wide corridors, thick walls, or with dead ends changed to loops put throne room gold in the chest +wielding Trollsbane prevents trolls from reviving Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/include/timeout.h b/include/timeout.h index e405b5e14..0cb4c706a 100644 --- a/include/timeout.h +++ b/include/timeout.h @@ -9,10 +9,12 @@ typedef void FDECL((*timeout_proc), (ANY_P *, long)); /* kind of timer */ -#define TIMER_LEVEL 0 /* event specific to level */ -#define TIMER_GLOBAL 1 /* event follows current play */ -#define TIMER_OBJECT 2 /* event follows a object */ -#define TIMER_MONSTER 3 /* event follows a monster */ +enum timer_type { + TIMER_LEVEL = 0, /* event specific to level */ + TIMER_GLOBAL, /* event follows current play */ + TIMER_OBJECT, /* event follows a object */ + TIMER_MONSTER /* event follows a monster */ +}; /* save/restore timer ranges */ #define RANGE_LEVEL 0 /* save/restore timers staying on level */ @@ -22,14 +24,17 @@ typedef void FDECL((*timeout_proc), (ANY_P *, long)); * Timeout functions. Add a define here, then put it in the table * in timeout.c. "One more level of indirection will fix everything." */ -#define ROT_ORGANIC 0 /* for buried organics */ -#define ROT_CORPSE 1 -#define REVIVE_MON 2 -#define BURN_OBJECT 3 -#define HATCH_EGG 4 -#define FIG_TRANSFORM 5 -#define MELT_ICE_AWAY 6 -#define NUM_TIME_FUNCS 7 +enum timeout_types { + ROT_ORGANIC = 0, /* for buried organics */ + ROT_CORPSE, + REVIVE_MON, + BURN_OBJECT, + HATCH_EGG, + FIG_TRANSFORM, + MELT_ICE_AWAY, + + NUM_TIME_FUNCS +}; /* used in timeout.c */ typedef struct fe { diff --git a/src/zap.c b/src/zap.c index 927bcb1dc..b2df5212f 100644 --- a/src/zap.c +++ b/src/zap.c @@ -748,7 +748,9 @@ boolean by_hero; x = xy.x, y = xy.y; } - if (mons[montype].mlet == S_EEL && !IS_POOL(levl[x][y].typ)) { + if ((mons[montype].mlet == S_EEL && !IS_POOL(levl[x][y].typ)) + || (mons[montype].mlet == S_TROLL + && uwep && uwep->oartifact == ART_TROLLSBANE)) { if (by_hero && cansee(x,y)) pline("%s twitches feebly.", upstart(corpse_xname(corpse, (const char *) 0, CXN_PFX_THE))); From 8d32f375888c66ebec517330b633917dde4bd2f1 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 17:31:00 +0100 Subject: [PATCH 15/23] Make the Elbereth restrictions more flavour-consistent Elbereth now has to be on a square by itself; it's hard to justify why text before it would prevent it working if text after it fails to prevent it working. --- src/engrave.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/engrave.c b/src/engrave.c index 0c2670af2..04921ca2a 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -257,8 +257,7 @@ xchar x, y; * Ignore headstones, in case the player names herself "Elbereth". * * If strict checking is requested, the word is only considered to be - * present if it is intact and is the first word in the engraving. - * ("Elbereth burrito" matches; "o Elbereth" does not.) + * present if it is intact and is the entire content of the engraving. */ int sengr_at(s, x, y, strict) @@ -269,7 +268,7 @@ boolean strict; register struct engr *ep = engr_at(x, y); if (ep && ep->engr_type != HEADSTONE && ep->engr_time <= moves) { - return strict ? (strncmpi(ep->engr_txt, s, strlen(s)) == 0) + return strict ? (fuzzymatch(ep->engr_txt, s, "", TRUE)) : (strstri(ep->engr_txt, s) != 0); } return FALSE; From 5c12362a98f458d75a372dc7bc658598b8dca76b Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 17:34:08 +0100 Subject: [PATCH 16/23] Fix engrave.c; I used the wrong commit command --- src/engrave.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/engrave.c b/src/engrave.c index 04921ca2a..faa813351 100644 --- a/src/engrave.c +++ b/src/engrave.c @@ -271,6 +271,7 @@ boolean strict; return strict ? (fuzzymatch(ep->engr_txt, s, "", TRUE)) : (strstri(ep->engr_txt, s) != 0); } + return FALSE; } From ee5b4885148d08d390b075a2a11cd4fe8cdcb131 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 18:15:57 +0100 Subject: [PATCH 17/23] Differentiate between monster anger from attacks and from other causes setmangry() and wakeup() were being used for multiple purposes. Add an extra parameter to track which. This fixes several minor bugs (e.g. whether monsters with no eyes were angered by (useless) gaze attacks against them previously depended on the state of a UI option, and the Minetown guards would be annoyed if you used a cursed scroll of tame monster on a shopkeeper). It's also a prerequisite for the Elbereth changes I'm working on. --- include/extern.h | 4 ++-- src/apply.c | 4 ++-- src/dig.c | 2 +- src/dokick.c | 6 +++--- src/dothrow.c | 12 +++++++----- src/explode.c | 2 +- src/mon.c | 18 ++++++++++++++---- src/music.c | 2 +- src/polyself.c | 2 +- src/potion.c | 2 +- src/priest.c | 3 ++- src/read.c | 2 +- src/region.c | 2 +- src/trap.c | 4 ++-- src/uhitm.c | 24 ++++++++++++------------ src/vault.c | 2 +- src/zap.c | 9 +++------ 17 files changed, 55 insertions(+), 45 deletions(-) diff --git a/include/extern.h b/include/extern.h index 0129b888f..300af5e06 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1355,8 +1355,8 @@ E void FDECL(mnexto, (struct monst *)); E void FDECL(maybe_mnexto, (struct monst *)); E boolean FDECL(mnearto, (struct monst *, XCHAR_P, XCHAR_P, BOOLEAN_P)); E void FDECL(m_respond, (struct monst *)); -E void FDECL(setmangry, (struct monst *)); -E void FDECL(wakeup, (struct monst *)); +E void FDECL(setmangry, (struct monst *, boolean)); +E void FDECL(wakeup, (struct monst *, boolean)); E void NDECL(wake_nearby); E void FDECL(wake_nearto, (int, int, int)); E void FDECL(seemimic, (struct monst *)); diff --git a/src/apply.c b/src/apply.c index 8d64620a8..2e1fb0cf1 100644 --- a/src/apply.c +++ b/src/apply.c @@ -2695,7 +2695,7 @@ struct obj *obj; pline1(msg_slipsfree); } if (mtmp) - wakeup(mtmp); + wakeup(mtmp, TRUE); } else pline1(msg_snap); @@ -2789,7 +2789,7 @@ struct obj *obj; } else { pline1(msg_slipsfree); } - wakeup(mtmp); + wakeup(mtmp, TRUE); } else { if (mtmp->m_ap_type && !Protection_from_shape_changers && !sensemon(mtmp)) diff --git a/src/dig.c b/src/dig.c index 5f45e117e..4407c4c15 100644 --- a/src/dig.c +++ b/src/dig.c @@ -2008,7 +2008,7 @@ struct monst *mtmp; } mtmp->mburied = TRUE; - wakeup(mtmp); /* at least give it a chance :-) */ + wakeup(mtmp, FALSE); /* at least give it a chance :-) */ newsym(mtmp->mx, mtmp->my); } diff --git a/src/dokick.c b/src/dokick.c index f1e0dcddf..2cb485472 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -156,7 +156,7 @@ xchar x, y; int i, j; /* anger target even if wild miss will occur */ - setmangry(mon); + setmangry(mon, TRUE); if (Levitation && !rn2(3) && verysmall(mon->data) && !is_flyer(mon->data)) { @@ -298,7 +298,7 @@ register struct obj *gold; if (!likes_gold(mtmp->data) && !mtmp->isshk && !mtmp->ispriest && !mtmp->isgd && !is_mercenary(mtmp->data)) { - wakeup(mtmp); + wakeup(mtmp, TRUE); } else if (!mtmp->mcanmove) { /* too light to do real damage */ if (canseemon(mtmp)) { @@ -312,7 +312,7 @@ register struct obj *gold; mtmp->msleeping = 0; finish_meating(mtmp); if (!mtmp->isgd && !rn2(4)) /* not always pleasing */ - setmangry(mtmp); + setmangry(mtmp, TRUE); /* greedy monsters catch gold */ if (cansee(mtmp->mx, mtmp->my)) pline("%s catches the gold.", Monnam(mtmp)); diff --git a/src/dothrow.c b/src/dothrow.c index 70496ef7a..98d41de9e 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -608,7 +608,8 @@ int x, y; if ((mon = m_at(x, y)) != 0) { You("bump into %s.", a_monnam(mon)); - wakeup(mon); + wakeup(mon, FALSE); + setmangry(mon, FALSE); wake_nearto(x,y, 10); return FALSE; } @@ -1346,7 +1347,7 @@ boolean maybe_wakeup; else miss(missile, mon); if (maybe_wakeup && !rn2(3)) - wakeup(mon); + wakeup(mon, TRUE); return; } @@ -1448,7 +1449,8 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ at leader... (kicked artifact is ok too; HMON_APPLIED could occur if quest artifact polearm or grapnel ever gets added) */ if (hmode != HMON_APPLIED && quest_arti_hits_leader(obj, mon)) { - /* not wakeup(), which angers non-tame monsters */ + /* AIS: changes to wakeup() means that it's now less inappropriate here + than it used to be, but the manual version works just as well */ mon->msleeping = 0; mon->mstrategy &= ~STRAT_WAITMASK; @@ -1562,7 +1564,7 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ } else { tmiss(obj, mon, TRUE); if (hmode == HMON_APPLIED) - wakeup(mon); + wakeup(mon, TRUE); } } else if (otyp == HEAVY_IRON_BALL) { @@ -1610,7 +1612,7 @@ register struct obj *obj; /* thrownobj or kickedobj or uwep */ } } else if (guaranteed_hit) { /* this assumes that guaranteed_hit is due to swallowing */ - wakeup(mon); + wakeup(mon, TRUE); if (obj->otyp == CORPSE && touch_petrifies(&mons[obj->corpsenm])) { if (is_animal(u.ustuck->data)) { minstapetrify(u.ustuck, TRUE); diff --git a/src/explode.c b/src/explode.c index e6f85866b..e26e58d8a 100644 --- a/src/explode.c +++ b/src/explode.c @@ -433,7 +433,7 @@ int expltype; monkilled(mtmp, "", (int) adtyp); } else if (!context.mon_moving) { /* all affected monsters, even if mdef is set */ - setmangry(mtmp); + setmangry(mtmp, TRUE); } } diff --git a/src/mon.c b/src/mon.c index e31ecb27b..d0586b200 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2583,10 +2583,18 @@ struct monst *mtmp; } } +/* Called whenever the player attacks mtmp; also called in other situations + where mtmp gets annoyed at the player. Handles mtmp getting annoyed at the + attack and any ramifications that might have. Useful also in situations where + mtmp was already hostile; it checks for situations where the player shouldn't + be attacking and any ramifications /that/ might have. */ void -setmangry(mtmp) +setmangry(mtmp, via_attack) struct monst *mtmp; +boolean via_attack; { + (void) via_attack; /* AIS: not used yet */ + /* AIS: Should this be in both places, or just in wakeup()? */ mtmp->mstrategy &= ~STRAT_WAITMASK; if (!mtmp->mpeaceful) return; @@ -2681,14 +2689,16 @@ struct monst *mtmp; } -/* wake up a monster, usually making it angry in the process */ +/* wake up a monster, possibly making it angry in the process */ void -wakeup(mtmp) +wakeup(mtmp, via_attack) register struct monst *mtmp; +boolean via_attack; { mtmp->msleeping = 0; finish_meating(mtmp); - setmangry(mtmp); + if (via_attack) + setmangry(mtmp, TRUE); if (mtmp->m_ap_type) { seemimic(mtmp); } else if (context.forcefight && !context.mon_moving diff --git a/src/music.c b/src/music.c index 58cc4b0f0..75ab39d4d 100644 --- a/src/music.c +++ b/src/music.c @@ -263,7 +263,7 @@ int force; for (x = start_x; x <= end_x; x++) for (y = start_y; y <= end_y; y++) { if ((mtmp = m_at(x, y)) != 0) { - wakeup(mtmp); /* peaceful monster will become hostile */ + wakeup(mtmp, TRUE); /* peaceful monster will become hostile */ if (mtmp->mundetected && is_hider(mtmp->data)) { mtmp->mundetected = 0; if (cansee(x, y)) diff --git a/src/polyself.c b/src/polyself.c index 71f9ce8ba..869a37a07 100644 --- a/src/polyself.c +++ b/src/polyself.c @@ -1310,8 +1310,8 @@ dogaze() mon_nam(mtmp)); if (yn(qbuf) != 'y') continue; - setmangry(mtmp); } + setmangry(mtmp, TRUE); if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleeping || !mtmp->mcansee || !haseyes(mtmp->data)) { looked--; diff --git a/src/potion.c b/src/potion.c index b5971dd79..38f5c6553 100644 --- a/src/potion.c +++ b/src/potion.c @@ -1488,7 +1488,7 @@ boolean your_fault; /* target might have been killed */ if (mon->mhp > 0) { if (angermon) - wakeup(mon); + wakeup(mon, TRUE); else mon->msleeping = 0; } diff --git a/src/priest.c b/src/priest.c index ec76c91bb..0cce5cf36 100644 --- a/src/priest.c +++ b/src/priest.c @@ -795,7 +795,8 @@ angry_priest() if ((priest = findpriest(temple_occupied(u.urooms))) != 0) { struct epri *eprip = EPRI(priest); - wakeup(priest); + wakeup(priest, FALSE); + setmangry(priest, FALSE); /* * If the altar has been destroyed or converted, let the * priest run loose. diff --git a/src/read.c b/src/read.c index 12e3cc002..efc36e3cb 100644 --- a/src/read.c +++ b/src/read.c @@ -901,7 +901,7 @@ struct obj *sobj; unsigned was_peaceful = mtmp->mpeaceful; if (sobj->cursed) { - setmangry(mtmp); + setmangry(mtmp, FALSE); if (was_peaceful && !mtmp->mpeaceful) return -1; } else { diff --git a/src/region.c b/src/region.c index 240f7270c..3ab0317b2 100644 --- a/src/region.c +++ b/src/region.c @@ -974,7 +974,7 @@ genericptr_t p2; if (cansee(mtmp->mx, mtmp->my)) pline("%s coughs!", Monnam(mtmp)); if (heros_fault(reg)) - setmangry(mtmp); + setmangry(mtmp, TRUE); if (haseyes(mtmp->data) && mtmp->mcansee) { mtmp->mblinded = 1; mtmp->mcansee = 0; diff --git a/src/trap.c b/src/trap.c index 9e5b2f500..23e26dec3 100644 --- a/src/trap.c +++ b/src/trap.c @@ -2119,7 +2119,7 @@ register struct monst *mtmp; Recognizing who made the trap isn't completely unreasonable; everybody has their own style. */ if (trap->madeby_u && rnl(5)) - setmangry(mtmp); + setmangry(mtmp, TRUE); in_sight = canseemon(mtmp); see_it = cansee(mtmp->mx, mtmp->my); @@ -4541,7 +4541,7 @@ boolean *noticed; /* set to true iff hero notices the effect; */ or if you sense the monster who becomes trapped */ *noticed = cansee(t->tx, t->ty) || canspotmon(mon); /* monster will be angered; mintrap doesn't handle that */ - wakeup(mon); + wakeup(mon, TRUE); ++force_mintrap; result = (mintrap(mon) != 0); --force_mintrap; diff --git a/src/uhitm.c b/src/uhitm.c index 832390694..a4a31cde0 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -145,7 +145,7 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */ if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)) u.ustuck = mtmp; } - wakeup(mtmp); /* always necessary; also un-mimics mimics */ + wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */ return TRUE; } @@ -190,7 +190,7 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */ */ if ((mtmp->mundetected || mtmp->m_ap_type) && sensemon(mtmp)) { mtmp->mundetected = 0; - wakeup(mtmp); + wakeup(mtmp, TRUE); } if (flags.confirm && mtmp->mpeaceful && !Confusion && !Hallucination @@ -573,7 +573,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ unconventional[0] = '\0'; saved_oname[0] = '\0'; - wakeup(mon); + wakeup(mon, TRUE); if (!obj) { /* attack with bare hands */ if (mdat == &mons[PM_SHADE]) tmp = 0; @@ -894,7 +894,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ pline("%s %s over %s!", what, vtense(what, "splash"), whom); } - setmangry(mon); + setmangry(mon, TRUE); mon->mcansee = 0; tmp = rn1(25, 21); if (((int) mon->mblinded + tmp) > 127) @@ -903,7 +903,7 @@ int thrown; /* HMON_xxx (0 => hand-to-hand, other => ranged) */ mon->mblinded += tmp; } else { pline(obj->otyp == CREAM_PIE ? "Splat!" : "Splash!"); - setmangry(mon); + setmangry(mon, TRUE); } if (thrown) obfree(obj, (struct obj *) 0); @@ -2097,7 +2097,7 @@ boolean wouldhavehit; else You("miss it."); if (!mdef->msleeping && mdef->mcanmove) - wakeup(mdef); + wakeup(mdef, TRUE); } /* attack monster as a monster. */ @@ -2178,7 +2178,7 @@ register struct monst *mon; sum[i] = damageum(mon, mattk); break; } - wakeup(mon); + wakeup(mon, TRUE); /* maybe this check should be in damageum()? */ if (mon->data == &mons[PM_SHADE] && !(mattk->aatyp == AT_KICK && uarmf @@ -2212,7 +2212,7 @@ register struct monst *mon; * already grabbed in a previous attack */ dhit = 1; - wakeup(mon); + wakeup(mon, TRUE); if (mon->data == &mons[PM_SHADE]) Your("hug passes harmlessly through %s.", mon_nam(mon)); else if (!sticks(mon->data) && !u.uswallow) { @@ -2230,7 +2230,7 @@ register struct monst *mon; case AT_EXPL: /* automatic hit if next to */ dhit = -1; - wakeup(mon); + wakeup(mon, TRUE); sum[i] = explum(mon, mattk); break; @@ -2238,7 +2238,7 @@ register struct monst *mon; tmp = find_roll_to_hit(mon, mattk->aatyp, (struct obj *) 0, &attknum, &armorpenalty); if ((dhit = (tmp > rnd(20 + i)))) { - wakeup(mon); + wakeup(mon, TRUE); if (mon->data == &mons[PM_SHADE]) Your("attempt to surround %s is harmless.", mon_nam(mon)); else { @@ -2637,7 +2637,7 @@ struct monst *mtmp; if (what) pline(fmt, what); - wakeup(mtmp); /* clears mimicking */ + wakeup(mtmp, FALSE); /* clears mimicking */ /* if hero is blind, wakeup() won't display the monster even though it's no longer concealed */ if (!canspotmon(mtmp) @@ -2695,7 +2695,7 @@ struct obj *otmp; /* source of flash */ } if (mtmp->mhp > 0) { if (!context.mon_moving) - setmangry(mtmp); + setmangry(mtmp, TRUE); if (tmp < 9 && !mtmp->isshk && rn2(4)) monflee(mtmp, rn2(4) ? rnd(100) : 0, FALSE, TRUE); mtmp->mcansee = 0; diff --git a/src/vault.c b/src/vault.c index 909cc3872..f076986f5 100644 --- a/src/vault.c +++ b/src/vault.c @@ -400,7 +400,7 @@ invault() } mongone(guard); } else { - setmangry(guard); + setmangry(guard, FALSE); if (Deaf) { if (!Blind) pline("%s mouths something and looks very angry!", diff --git a/src/zap.c b/src/zap.c index b2df5212f..9cf38e030 100644 --- a/src/zap.c +++ b/src/zap.c @@ -426,7 +426,7 @@ struct obj *otmp; } if (wake) { if (mtmp->mhp > 0) { - wakeup(mtmp); + wakeup(mtmp, TRUE); m_respond(mtmp); if (mtmp->isshk && !*u.ushops) hot_pursuit(mtmp); @@ -4535,12 +4535,9 @@ short exploding_wand_typ; You("%s of smoke.", !Blind ? "see a puff" : "smell a whiff"); } if ((mon = m_at(x, y)) != 0) { - /* Cannot use wakeup() which also angers the monster */ - mon->msleeping = 0; - if (mon->m_ap_type) - seemimic(mon); + wakeup(mon, FALSE); if (type >= 0) { - setmangry(mon); + setmangry(mon, TRUE); if (mon->ispriest && *in_rooms(mon->mx, mon->my, TEMPLE)) ghod_hitsu(mon); if (mon->isshk && !*u.ushops) From 348e54aa32683728304fbd8b2b9e4e78b502c1fc Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 18:26:44 +0100 Subject: [PATCH 18/23] Change the rules for Elbereth erosion If you attack a monster under Elbereth protection, and it wasn't scuffed by the attack itself, then it'll be automatically removed with an alignment penalty. It no longer fades from scaring monsters; only from being abused to attack monsters while protected. --- src/mon.c | 16 +++++++++++++++- src/monmove.c | 6 ------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/mon.c b/src/mon.c index d0586b200..3a70ba3f8 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2593,7 +2593,21 @@ setmangry(mtmp, via_attack) struct monst *mtmp; boolean via_attack; { - (void) via_attack; /* AIS: not used yet */ + if (via_attack && sengr_at("Elbereth", u.ux, u.uy, TRUE)) { + You_feel("like a hypocrite."); + /* AIS: Yes, I know alignment penalties and bonuses aren't balanced at + the moment. This is about correct relative to other "small" + penalties; it should be fairly large, as attacking while standing on + an Elbereth means that you're requesting peace and then violating + your own request. I know 5 isn't actually large, but it's + intentionally larger than the 1s and 2s that are normally given for + this sort of thing. */ + adjalign(-5); + if (!Blind) + pline("The engraving beneath you fades."); + del_engr_at(u.ux, u.uy); + } + /* AIS: Should this be in both places, or just in wakeup()? */ mtmp->mstrategy &= ~STRAT_WAITMASK; if (!mtmp->mpeaceful) diff --git a/src/monmove.c b/src/monmove.c index c032db504..0b60d0c15 100644 --- a/src/monmove.c +++ b/src/monmove.c @@ -320,12 +320,6 @@ int *inrange, *nearby, *scared; || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) { *scared = 1; monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE); - - /* magical protection won't last forever, so there'll be a - * chance of the magic being used up regardless of type */ - if (sawscary) { - wipe_engr_at(seescaryx, seescaryy, 1, TRUE); - } } else *scared = 0; } From d01c0364f1b80b2c7641b8e620e836e64497e710 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Mon, 17 Oct 2016 18:29:09 +0100 Subject: [PATCH 19/23] Ugh, why does NH3's commit process have to differ from NH4's? --- src/mon.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mon.c b/src/mon.c index 3a70ba3f8..35966e381 100644 --- a/src/mon.c +++ b/src/mon.c @@ -2603,6 +2603,7 @@ boolean via_attack; intentionally larger than the 1s and 2s that are normally given for this sort of thing. */ adjalign(-5); + if (!Blind) pline("The engraving beneath you fades."); del_engr_at(u.ux, u.uy); From f106b578a25b49e6d4de8dcde72347af0324caa6 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 18 Oct 2016 18:07:53 +0300 Subject: [PATCH 20/23] Wielding Demonbane prevents demons summoning friends --- doc/fixes36.1 | 1 + src/minion.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index b997f6994..bb74b1308 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -352,6 +352,7 @@ sometimes generate the random mazes with wide corridors, thick walls, or with dead ends changed to loops put throne room gold in the chest wielding Trollsbane prevents trolls from reviving +wielding Demonbane prevents demons summoning friends Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository diff --git a/src/minion.c b/src/minion.c index 1af08f5ea..d0394477b 100644 --- a/src/minion.c +++ b/src/minion.c @@ -57,6 +57,13 @@ struct monst *mon; if (mon) { ptr = mon->data; + + if (uwep && uwep->oartifact == ART_DEMONBANE && is_demon(ptr)) { + if (canseemon(mon)) + pline("%s looks puzzled for a moment.", Monnam(mon)); + return 0; + } + atyp = mon->ispriest ? EPRI(mon)->shralign : mon->isminion ? EMIN(mon)->min_align : (ptr->maligntyp == A_NONE) From 9c5cfc4153897fb06053daaa8a58ef186ac8b145 Mon Sep 17 00:00:00 2001 From: Alex Smith Date: Tue, 18 Oct 2016 16:52:21 +0100 Subject: [PATCH 21/23] Changelog for the Elbereth changes --- doc/fixes36.1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/fixes36.1 b/doc/fixes36.1 index b997f6994..d57a14962 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -352,6 +352,8 @@ sometimes generate the random mazes with wide corridors, thick walls, or with dead ends changed to loops put throne room gold in the chest wielding Trollsbane prevents trolls from reviving +Elbereth must now be on a square by itself to function +Elbereth now erodes based on attacks by the player, not monsters scared Fixes to Post-3.6.0 Problems that Were Exposed Via git Repository From 1506572ea0a70db319a9a376e65bfb3999e593b5 Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 18 Oct 2016 19:42:20 +0300 Subject: [PATCH 22/23] With fragile wands, use snap instead of break --- src/apply.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apply.c b/src/apply.c index 8d64620a8..3486fb1a3 100644 --- a/src/apply.c +++ b/src/apply.c @@ -3210,8 +3210,8 @@ struct obj *obj; You("don't have the strength to break %s!", yname(obj)); return 0; } - pline("Raising %s high above your %s, you break it in two!", yname(obj), - body_part(HEAD)); + pline("Raising %s high above your %s, you %s it in two!", yname(obj), + body_part(HEAD), is_fragile ? "snap" : "break"); /* [ALI] Do this first so that wand is removed from bill. Otherwise, * the freeinv() below also hides it from setpaid() which causes problems. From bf1c81c0b4ec0ef651a4cd2cd137aec6a8fcda3f Mon Sep 17 00:00:00 2001 From: Pasi Kallinen Date: Tue, 18 Oct 2016 23:19:12 +0300 Subject: [PATCH 23/23] Accept custom level annotations at the level teleport prompt via UnNetHack, original implementation by aaxelb --- src/dungeon.c | 59 +++++++++++++++++++++++++++++++++++--------------- src/teleport.c | 4 ++-- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/dungeon.c b/src/dungeon.c index 78dd19d6c..10879fdd4 100644 --- a/src/dungeon.c +++ b/src/dungeon.c @@ -62,6 +62,7 @@ STATIC_DCL void FDECL(print_branch, (winid, int, int, int, BOOLEAN_P, STATIC_DCL mapseen *FDECL(load_mapseen, (int)); STATIC_DCL void FDECL(save_mapseen, (int, mapseen *)); STATIC_DCL mapseen *FDECL(find_mapseen, (d_level *)); +STATIC_DCL mapseen *FDECL(find_mapseen_by_str, (const char *)); STATIC_DCL void FDECL(print_mapseen, (winid, mapseen *, int, int, BOOLEAN_P)); STATIC_DCL boolean FDECL(interest_mapseen, (mapseen *)); STATIC_DCL void FDECL(traverse_mapseenchn, (BOOLEAN_P, winid, @@ -1642,25 +1643,35 @@ const char *nam; const char *p; int idx, idxtoo; char buf[BUFSZ]; + mapseen *mseen; - /* allow strings like "the oracle level" to find "oracle" */ - if (!strncmpi(nam, "the ", 4)) - nam += 4; - if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) { - nam = strcpy(buf, nam); - *(eos(buf) - 6) = '\0'; - } - /* hell is the old name, and wouldn't match; gehennom would match its - branch, yielding the castle level instead of the valley of the dead */ - if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) { - if (In_V_tower(&u.uz)) - nam = " to Vlad's tower"; /* branch to... */ - else - nam = "valley"; + /* look at the player's custom level annotations first */ + if ((mseen = find_mapseen_by_str(nam)) != 0) { + dlev = mseen->lev; + } else { + /* no matching annotation, check whether they used a name we know */ + + /* allow strings like "the oracle level" to find "oracle" */ + if (!strncmpi(nam, "the ", 4)) + nam += 4; + if ((p = strstri(nam, " level")) != 0 && p == eos((char *) nam) - 6) { + nam = strcpy(buf, nam); + *(eos(buf) - 6) = '\0'; + } + /* hell is the old name, and wouldn't match; gehennom would match its + branch, yielding the castle level instead of the valley of the dead */ + if (!strcmpi(nam, "gehennom") || !strcmpi(nam, "hell")) { + if (In_V_tower(&u.uz)) + nam = " to Vlad's tower"; /* branch to... */ + else + nam = "valley"; + } + + if ((slev = find_level(nam)) != 0) + dlev = slev->dlevel; } - if ((slev = find_level(nam)) != 0) { - dlev = slev->dlevel; + if (mseen || slev) { idx = ledger_no(&dlev); if ((dlev.dnum == u.uz.dnum /* within same branch, or else main dungeon <-> gehennom */ @@ -1672,7 +1683,7 @@ const char *nam; wizard || (level_info[idx].flags & (FORGOTTEN | VISITED)) == VISITED)) { - lev = depth(&slev->dlevel); + lev = depth(&dlev); } } else { /* not a specific level; try branch names */ idx = find_branch(nam, (struct proto_dungeon *) 0); @@ -2055,6 +2066,20 @@ d_level *lev; return mptr; } +STATIC_OVL mapseen * +find_mapseen_by_str(s) +const char *s; +{ + mapseen *mptr; + + for (mptr = mapseenchn; mptr; mptr = mptr->next) + if (mptr->custom && !strcmpi(s, mptr->custom)) + break; + + return mptr; +} + + void forget_mapseen(ledger_num) int ledger_num; diff --git a/src/teleport.c b/src/teleport.c index f45abfb5e..5c42151a6 100644 --- a/src/teleport.c +++ b/src/teleport.c @@ -609,9 +609,9 @@ level_tele() do { if (++trycnt == 2) { if (wizard) - Strcat(qbuf, " [type a number or ? for a menu]"); + Strcat(qbuf, " [type a number, name, or ? for a menu]"); else - Strcat(qbuf, " [type a number]"); + Strcat(qbuf, " [type a number or name]"); } getlin(qbuf, buf); if (!strcmp(buf, "\033")) { /* cancelled */