Merge branch 'NetHack-3.7' of https://rodney.nethack.org:20040/git/NHsource into NetHack-3.7

This commit is contained in:
Alex Smith
2020-03-18 23:02:04 +00:00
30 changed files with 235 additions and 367 deletions
+5 -11
View File
@@ -90,14 +90,8 @@ des.monster("giant eel", 36, 01)
des.monster("giant eel", 37, 09) des.monster("giant eel", 37, 09)
des.monster("giant eel", 39, 15) des.monster("giant eel", 39, 15)
-- Monsters on siege duty. -- Monsters on siege duty.
des.monster({ id = "ogre", x=40, y=08, peaceful=0 }) local ogrelocs = selection.floodfill(37,7) & selection.area(40,03, 45,20)
des.monster({ id = "ogre", x=41, y=06, peaceful=0 }) for i = 0, 11 do
des.monster({ id = "ogre", x=41, y=07, peaceful=0 }) local x,y = ogrelocs:rndcoord(1);
des.monster({ id = "ogre", x=41, y=08, peaceful=0 }) des.monster({ id = "ogre", coord={x,y}, peaceful=0 })
des.monster({ id = "ogre", x=41, y=09, peaceful=0 }) end
des.monster({ id = "ogre", x=41, y=10, peaceful=0 })
des.monster({ id = "ogre", x=42, y=06, peaceful=0 })
des.monster({ id = "ogre", x=42, y=07, peaceful=0 })
des.monster({ id = "ogre", x=42, y=08, peaceful=0 })
des.monster({ id = "ogre", x=42, y=09, peaceful=0 })
des.monster({ id = "ogre", x=42, y=10, peaceful=0 })
+14 -14
View File
@@ -42,6 +42,8 @@ des.region({ region={24,06, 33,13}, lit=1, type="temple" })
des.replace_terrain({ region={00,00, 10,19}, fromterrain=".", toterrain="T", chance=10 }) des.replace_terrain({ region={00,00, 10,19}, fromterrain=".", toterrain="T", chance=10 })
des.replace_terrain({ region={65,00, 75,19}, fromterrain=".", toterrain="T", chance=10 }) des.replace_terrain({ region={65,00, 75,19}, fromterrain=".", toterrain="T", chance=10 })
local spacelocs = selection.floodfill(05,04);
-- Portal arrival point -- Portal arrival point
des.terrain({05,04}, ".") des.terrain({05,04}, ".")
des.levregion({ region = {05,04,05,04}, type="branch" }) des.levregion({ region = {05,04,05,04}, type="branch" })
@@ -83,22 +85,20 @@ des.monster("abbot", 33, 12)
-- Non diggable walls -- Non diggable walls
des.non_diggable(selection.area(18,03,55,16)) des.non_diggable(selection.area(18,03,55,16))
-- Random traps -- Random traps
des.trap("dart",20,09) for i = 1, 2 do
des.trap("dart",20,10) local x,y = spacelocs:rndcoord(1);
des.trap("dart",x,y)
end
des.trap() des.trap()
des.trap() des.trap()
des.trap() des.trap()
des.trap() des.trap()
-- Monsters on siege duty. -- Monsters on siege duty.
des.monster("earth elemental", 37, 01) for i = 1, 8 do
des.monster("earth elemental", 37, 18) local x,y = spacelocs:rndcoord(1);
des.monster("earth elemental", 03, 03) des.monster("earth elemental", x, y)
des.monster("earth elemental", 65, 04) end
des.monster("earth elemental", 12, 11) for i = 1, 4 do
des.monster("earth elemental", 60, 12) local x,y = spacelocs:rndcoord(1);
des.monster("earth elemental", 14, 08) des.monster("xorn", x, y)
des.monster("earth elemental", 55, 00) end
des.monster("xorn", 18, 18)
des.monster("xorn", 59, 10)
des.monster("xorn", 13, 09)
des.monster("xorn", 01, 17)
+8 -1
View File
@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ $NHDT-Date: 1583926845 2020/03/11 11:40:45 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.137 $ $NHDT-Date: 1584482684 2020/03/17 22:04:44 $
General Fixes and Modified Features General Fixes and Modified Features
----------------------------------- -----------------------------------
@@ -79,6 +79,11 @@ fix priest created inside temple wall
fix vault guard occasionally encasing monsters in stone fix vault guard occasionally encasing monsters in stone
tone down scare monster by excluding humans and uniques tone down scare monster by excluding humans and uniques
lock the castle chest lock the castle chest
revamp amnesia to forget skills instead of objects or maps
when Punished and carrying the iron ball and levitating, hurtling in the
opposite direction of a thrown object didn't bring along the chain
recognize "kirin" as alias for "ki-rin" when asked to create a monster
make unique swallowing monsters (Juiblex) resist magical digging from inside
Fixes to 3.7.0-x Problems that Were Exposed Via git Repository Fixes to 3.7.0-x Problems that Were Exposed Via git Repository
@@ -129,6 +134,8 @@ tty: role and race selection menus weren't filtering out potential choices
which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic which got excluded by OPTIONS=align:!lawful or !neutral or !chaotic
windows: update for new status condition fields windows: update for new status condition fields
X11: substantial overhaul of status display, both 'fancy' and 'tty-style' X11: substantial overhaul of status display, both 'fancy' and 'tty-style'
X11: extend fancy status one-turn inverse video status-change highlighting to
hunger, encumbrance, and conditions
General New Features General New Features
+1 -1
View File
@@ -159,7 +159,7 @@ typedef struct branch {
struct linfo { struct linfo {
unsigned char flags; unsigned char flags;
#define VISITED 0x01 /* hero has visited this level */ #define VISITED 0x01 /* hero has visited this level */
#define FORGOTTEN 0x02 /* hero will forget this level when reached */ /* 0x02 was FORGOTTEN, when amnesia made you forget maps */
#define LFILE_EXISTS 0x04 /* a level file exists for this level */ #define LFILE_EXISTS 0x04 /* a level file exists for this level */
/* Note: VISITED and LFILE_EXISTS are currently almost always /* Note: VISITED and LFILE_EXISTS are currently almost always
* set at the same time. However they _mean_ different things. * set at the same time. However they _mean_ different things.
+4 -6
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1583073988 2020/03/01 14:46:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.809 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1584405113 2020/03/17 00:31:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.814 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -666,7 +666,6 @@ E char *FDECL(get_annotation, (d_level *));
E int NDECL(donamelevel); E int NDECL(donamelevel);
E int NDECL(dooverview); E int NDECL(dooverview);
E void FDECL(show_overview, (int, int)); E void FDECL(show_overview, (int, int));
E void FDECL(forget_mapseen, (int));
E void FDECL(rm_mapseen, (int)); E void FDECL(rm_mapseen, (int));
E void FDECL(init_mapseen, (d_level *)); E void FDECL(init_mapseen, (d_level *));
E void NDECL(recalc_mapseen); E void NDECL(recalc_mapseen);
@@ -907,6 +906,7 @@ E int NDECL(dopickup);
E void NDECL(lookaround); E void NDECL(lookaround);
E boolean FDECL(crawl_destination, (int, int)); E boolean FDECL(crawl_destination, (int, int));
E int NDECL(monster_nearby); E int NDECL(monster_nearby);
E void FDECL(end_running, (BOOLEAN_P));
E void FDECL(nomul, (int)); E void FDECL(nomul, (int));
E void FDECL(unmul, (const char *)); E void FDECL(unmul, (const char *));
E void FDECL(losehp, (int, const char *, BOOLEAN_P)); E void FDECL(losehp, (int, const char *, BOOLEAN_P));
@@ -1509,6 +1509,7 @@ E void NDECL(kill_genocided_monsters);
E void FDECL(golemeffects, (struct monst *, int, int)); E void FDECL(golemeffects, (struct monst *, int, int));
E boolean FDECL(angry_guards, (BOOLEAN_P)); E boolean FDECL(angry_guards, (BOOLEAN_P));
E void NDECL(pacify_guards); E void NDECL(pacify_guards);
E struct monst *FDECL(find_ghost_with_name, (char *));
E void FDECL(decide_to_shapeshift, (struct monst *, int)); E void FDECL(decide_to_shapeshift, (struct monst *, int));
E boolean FDECL(vamp_stone, (struct monst *)); E boolean FDECL(vamp_stone, (struct monst *));
E void NDECL(monst_globals_init); E void NDECL(monst_globals_init);
@@ -2166,10 +2167,6 @@ E char *FDECL(tshirt_text, (struct obj *, char *));
E int NDECL(doread); E int NDECL(doread);
E boolean FDECL(is_chargeable, (struct obj *)); E boolean FDECL(is_chargeable, (struct obj *));
E void FDECL(recharge, (struct obj *, int)); E void FDECL(recharge, (struct obj *, int));
E void FDECL(forget_objects, (int));
E void FDECL(forget_levels, (int));
E void NDECL(forget_traps);
E void FDECL(forget_map, (int));
E int FDECL(seffects, (struct obj *)); E int FDECL(seffects, (struct obj *));
E void FDECL(drop_boulder_on_player, E void FDECL(drop_boulder_on_player,
(BOOLEAN_P, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); (BOOLEAN_P, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
@@ -2956,6 +2953,7 @@ E void FDECL(unrestrict_weapon_skill, (int));
E void FDECL(use_skill, (int, int)); E void FDECL(use_skill, (int, int));
E void FDECL(add_weapon_skill, (int)); E void FDECL(add_weapon_skill, (int));
E void FDECL(lose_weapon_skill, (int)); E void FDECL(lose_weapon_skill, (int));
E void FDECL(drain_weapon_skill, (int));
E int FDECL(weapon_type, (struct obj *)); E int FDECL(weapon_type, (struct obj *));
E int NDECL(uwep_skill_type); E int NDECL(uwep_skill_type);
E int FDECL(weapon_hit_bonus, (struct obj *)); E int FDECL(weapon_hit_bonus, (struct obj *));
+5
View File
@@ -477,6 +477,11 @@ enum bodypart_types {
#define RANDOM_TIN (-2) #define RANDOM_TIN (-2)
#define HEALTHY_TIN (-3) #define HEALTHY_TIN (-3)
/* Corpse aging */
#define TAINT_AGE (50L) /* age when corpses go bad */
#define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */
#define ROT_AGE (250L) /* age when corpses rot away */
/* Some misc definitions */ /* Some misc definitions */
#define POTION_OCCUPANT_CHANCE(n) (13 + 2 * (n)) #define POTION_OCCUPANT_CHANCE(n) (13 + 2 * (n))
#define WAND_BACKFIRE_CHANCE 100 #define WAND_BACKFIRE_CHANCE 100
+4 -8
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 allmain.c $NHDT-Date: 1580044340 2020/01/26 13:12:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */ /* NetHack 3.6 allmain.c $NHDT-Date: 1584405115 2020/03/17 00:31:55 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.143 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -178,6 +178,9 @@ boolean resuming;
g.monstermoves++; /* [obsolete (for a long time...)] */ g.monstermoves++; /* [obsolete (for a long time...)] */
g.moves++; g.moves++;
if (flags.time && !g.context.run)
iflags.time_botl = TRUE; /* 'moves' just changed */
/********************************/ /********************************/
/* once-per-turn things go here */ /* once-per-turn things go here */
/********************************/ /********************************/
@@ -189,8 +192,6 @@ boolean resuming;
if (u.ublesscnt) if (u.ublesscnt)
u.ublesscnt--; u.ublesscnt--;
if (flags.time && !g.context.run)
iflags.time_botl = TRUE;
/* One possible result of prayer is healing. Whether or /* One possible result of prayer is healing. Whether or
* not you get healed depends on your current hit points. * not you get healed depends on your current hit points.
@@ -436,8 +437,6 @@ boolean resuming;
if (!g.multi) { if (!g.multi) {
/* lookaround may clear multi */ /* lookaround may clear multi */
g.context.move = 0; g.context.move = 0;
if (flags.time)
g.context.botl = TRUE;
continue; continue;
} }
if (g.context.mv) { if (g.context.mv) {
@@ -457,9 +456,6 @@ boolean resuming;
} }
if (u.utotype) /* change dungeon level */ if (u.utotype) /* change dungeon level */
deferred_goto(); /* after rhack() */ deferred_goto(); /* after rhack() */
/* !g.context.move here: multiple movement command stopped */
else if (flags.time && (!g.context.move || !g.context.mv))
g.context.botl = TRUE;
if (g.vision_full_recalc) if (g.vision_full_recalc)
vision_recalc(0); /* vision! */ vision_recalc(0); /* vision! */
+5 -4
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1583190980 2020/03/02 23:16:20 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.185 $ */ /* NetHack 3.6 botl.c $NHDT-Date: 1584350350 2020/03/16 09:19:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.186 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */ /*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1117,10 +1117,11 @@ cond_menu(VOID_ARGS)
} while (showmenu); } while (showmenu);
if (res > 0) { if (res > 0) {
for (i = 0; i < CONDITION_COUNT; ++i) { for (i = 0; i < CONDITION_COUNT; ++i)
if (condtests[i].enabled != condtests[i].choice) if (condtests[i].enabled != condtests[i].choice) {
condtests[i].enabled = condtests[i].choice; condtests[i].enabled = condtests[i].choice;
} g.context.botl = TRUE;
}
} }
} }
+7 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 dig.c $NHDT-Date: 1578659784 2020/01/10 12:36:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.135 $ */ /* NetHack 3.6 dig.c $NHDT-Date: 1584350347 2020/03/16 09:19:07 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2012. */ /*-Copyright (c) Michael Allison, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -928,7 +928,7 @@ coord *cc;
case 1: case 1:
You("unearth a corpse."); You("unearth a corpse.");
if ((otmp = mk_tt_object(CORPSE, dig_x, dig_y)) != 0) if ((otmp = mk_tt_object(CORPSE, dig_x, dig_y)) != 0)
otmp->age -= 100; /* this is an *OLD* corpse */ otmp->age -= (TAINT_AGE + 1); /* this is an *OLD* corpse */
break; break;
case 2: case 2:
if (!Blind) if (!Blind)
@@ -1409,7 +1409,10 @@ zap_dig()
if (is_animal(mtmp->data)) if (is_animal(mtmp->data))
You("pierce %s %s wall!", s_suffix(mon_nam(mtmp)), You("pierce %s %s wall!", s_suffix(mon_nam(mtmp)),
mbodypart(mtmp, STOMACH)); mbodypart(mtmp, STOMACH));
mtmp->mhp = 1; /* almost dead */ if (unique_corpstat(mtmp->data))
mtmp->mhp = (mtmp->mhp + 1) / 2;
else
mtmp->mhp = 1; /* almost dead */
expels(mtmp, mtmp->data, !is_animal(mtmp->data)); expels(mtmp, mtmp->data, !is_animal(mtmp->data));
} }
return; return;
@@ -1827,8 +1830,7 @@ boolean *dealloced;
*dealloced = FALSE; *dealloced = FALSE;
if (otmp == uball) { if (otmp == uball) {
unpunish(); unpunish();
u.utrap = rn1(50, 20); set_utrap((unsigned) rn1(50, 20), TT_BURIEDBALL);
u.utraptype = TT_BURIEDBALL;
pline_The("iron ball gets buried!"); pline_The("iron ball gets buried!");
} }
/* after unpunish(), or might get deallocated chain */ /* after unpunish(), or might get deallocated chain */
+4 -9
View File
@@ -1461,12 +1461,14 @@ boolean at_stairs, falling, portal;
if (!(g.level_info[new_ledger].flags & LFILE_EXISTS)) { if (!(g.level_info[new_ledger].flags & LFILE_EXISTS)) {
/* entering this level for first time; make it now */ /* entering this level for first time; make it now */
if (g.level_info[new_ledger].flags & (FORGOTTEN | VISITED)) { if (g.level_info[new_ledger].flags & (VISITED)) {
impossible("goto_level: returning to discarded level?"); impossible("goto_level: returning to discarded level?");
g.level_info[new_ledger].flags &= ~(FORGOTTEN | VISITED); g.level_info[new_ledger].flags &= ~(VISITED);
} }
mklev(); mklev();
new = TRUE; /* made the level */ new = TRUE; /* made the level */
familiar = (find_ghost_with_name(g.plname) != (struct monst *) 0);
} else { } else {
/* returning to previously visited level; reload it */ /* returning to previously visited level; reload it */
nhfp = open_levelfile(new_ledger, whynot); nhfp = open_levelfile(new_ledger, whynot);
@@ -1606,13 +1608,6 @@ boolean at_stairs, falling, portal;
else if (Is_firelevel(&u.uz)) else if (Is_firelevel(&u.uz))
fumaroles(); fumaroles();
if (g.level_info[new_ledger].flags & FORGOTTEN) {
forget_map(ALL_MAP); /* forget the map */
forget_traps(); /* forget all traps too */
familiar = TRUE;
g.level_info[new_ledger].flags &= ~FORGOTTEN;
}
/* Reset the screen. */ /* Reset the screen. */
vision_reset(); /* reset the blockages */ vision_reset(); /* reset the blockages */
g.glyphmap_perlevel_flags = 0L; /* force per-level mapglyph() changes */ g.glyphmap_perlevel_flags = 0L; /* force per-level mapglyph() changes */
+4
View File
@@ -1181,6 +1181,10 @@ int after; /* this is extra fast monster movement */
} }
} }
} }
/* pet moved when attacking */
if (mtmp->mx != omx || mtmp->my != omy)
return 0;
} }
} }
+4 -3
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1583073990 2020/03/01 14:46:30 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.183 $ */ /* NetHack 3.6 dothrow.c $NHDT-Date: 1584398443 2020/03/16 22:40:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.184 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -714,8 +714,9 @@ int x, y;
} }
} }
/* Caller has already determined that dragging the ball is allowed */ /* caller has already determined that dragging the ball is allowed;
if (Punished && uball->where == OBJ_FLOOR) { if ball is carried we might still need to drag the chain */
if (Punished) {
int bc_control; int bc_control;
xchar ballx, bally, chainx, chainy; xchar ballx, bally, chainx, chainy;
boolean cause_delay; boolean cause_delay;
+3 -32
View File
@@ -1958,7 +1958,7 @@ const char *nam;
&& dlev.dnum == valley_level.dnum)) && dlev.dnum == valley_level.dnum))
&& (/* either wizard mode or else seen and not forgotten */ && (/* either wizard mode or else seen and not forgotten */
wizard wizard
|| (g.level_info[idx].flags & (FORGOTTEN | VISITED)) || (g.level_info[idx].flags & (VISITED))
== VISITED)) { == VISITED)) {
lev = depth(&dlev); lev = depth(&dlev);
} }
@@ -1973,9 +1973,9 @@ const char *nam;
idx &= 0x00FF; idx &= 0x00FF;
/* either wizard mode, or else _both_ sides of branch seen */ /* either wizard mode, or else _both_ sides of branch seen */
if (wizard if (wizard
|| (((g.level_info[idx].flags & (FORGOTTEN | VISITED)) || (((g.level_info[idx].flags & (VISITED))
== VISITED) == VISITED)
&& ((g.level_info[idxtoo].flags & (FORGOTTEN | VISITED)) && ((g.level_info[idxtoo].flags & (VISITED))
== VISITED))) { == VISITED))) {
if (ledger_to_dnum(idxtoo) == u.uz.dnum) if (ledger_to_dnum(idxtoo) == u.uz.dnum)
idx = idxtoo; idx = idxtoo;
@@ -2392,35 +2392,6 @@ const char *s;
} }
void
forget_mapseen(ledger_num)
int ledger_num;
{
mapseen *mptr;
struct cemetery *bp;
for (mptr = g.mapseenchn; mptr; mptr = mptr->next)
if (g.dungeons[mptr->lev.dnum].ledger_start + mptr->lev.dlevel
== ledger_num)
break;
/* if not found, then nothing to forget */
if (mptr) {
mptr->flags.forgot = 1;
mptr->br = (branch *) 0;
/* custom names are erased, not just forgotten until revisited */
if (mptr->custom) {
mptr->custom_lth = 0;
free((genericptr_t) mptr->custom);
mptr->custom = (char *) 0;
}
(void) memset((genericptr_t) mptr->msrooms, 0, sizeof mptr->msrooms);
for (bp = mptr->final_resting_place; bp; bp = bp->next)
bp->bonesknown = FALSE;
}
}
void void
rm_mapseen(ledger_num) rm_mapseen(ledger_num)
int ledger_num; int ledger_num;
+11 -13
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 eat.c $NHDT-Date: 1577190688 2019/12/24 12:31:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.222 $ */ /* NetHack 3.6 eat.c $NHDT-Date: 1584405116 2020/03/17 00:31:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.223 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -3056,17 +3056,16 @@ boolean incr;
switch (newhs) { switch (newhs) {
case HUNGRY: case HUNGRY:
if (Hallucination) { if (Hallucination) {
You((!incr) ? "now have a lesser case of the munchies." You(!incr ? "now have a lesser case of the munchies."
: "are getting the munchies."); : "are getting the munchies.");
} else } else
You((!incr) ? "only feel hungry now." You(!incr ? "only feel hungry now."
: (u.uhunger < 145) : (u.uhunger < 145) ? "feel hungry."
? "feel hungry." : "are beginning to feel hungry.");
: "are beginning to feel hungry.");
if (incr && g.occupation if (incr && g.occupation
&& (g.occupation != eatfood && g.occupation != opentin)) && (g.occupation != eatfood && g.occupation != opentin))
stop_occupation(); stop_occupation();
g.context.travel = g.context.travel1 = g.context.mv = g.context.run = 0; end_running(TRUE);
break; break;
case WEAK: case WEAK:
if (Hallucination) if (Hallucination)
@@ -3079,14 +3078,13 @@ boolean incr;
? g.urole.name.m ? g.urole.name.m
: "Elf"); : "Elf");
else else
You((!incr) You(!incr ? "feel weak now."
? "feel weak now." : (u.uhunger < 45) ? "feel weak."
: (u.uhunger < 45) ? "feel weak." : "are beginning to feel weak.");
: "are beginning to feel weak.");
if (incr && g.occupation if (incr && g.occupation
&& (g.occupation != eatfood && g.occupation != opentin)) && (g.occupation != eatfood && g.occupation != opentin))
stop_occupation(); stop_occupation();
g.context.travel = g.context.travel1 = g.context.mv = g.context.run = 0; end_running(TRUE);
break; break;
} }
u.uhs = newhs; u.uhs = newhs;
+35 -11
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 hack.c $NHDT-Date: 1582799171 2020/02/27 10:26:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.249 $ */ /* NetHack 3.6 hack.c $NHDT-Date: 1584405116 2020/03/17 00:31:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.250 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -954,7 +954,7 @@ int mode;
if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && g.context.travel1 if ((mode == TRAVP_TRAVEL || mode == TRAVP_VALID) && g.context.travel1
&& distmin(u.ux, u.uy, u.tx, u.ty) == 1 && distmin(u.ux, u.uy, u.tx, u.ty) == 1
&& !(u.ux != u.tx && u.uy != u.ty && NODIAG(u.umonnum))) { && !(u.ux != u.tx && u.uy != u.ty && NODIAG(u.umonnum))) {
g.context.run = 0; end_running(FALSE);
if (test_move(u.ux, u.uy, u.tx - u.ux, u.ty - u.uy, TEST_MOVE)) { if (test_move(u.ux, u.uy, u.tx - u.ux, u.ty - u.uy, TEST_MOVE)) {
if (mode == TRAVP_TRAVEL) { if (mode == TRAVP_TRAVEL) {
u.dx = u.tx - u.ux; u.dx = u.tx - u.ux;
@@ -1964,10 +1964,14 @@ domove_core()
} }
if (g.context.run && flags.runmode != RUN_TPORT) { if (g.context.run && flags.runmode != RUN_TPORT) {
/* display every step or every 7th step depending upon mode */ /* for tport mode, don't display anything until we've stopped;
for normal (leap) mode, update display every 7th step
(relative to turn counter; ought to be to start of running);
for walk and crawl (visual debugging) modes, update the
display after every step */
if (flags.runmode != RUN_LEAP || !(g.moves % 7L)) { if (flags.runmode != RUN_LEAP || !(g.moves % 7L)) {
if (flags.time) /* moveloop() suppresses time_botl when running */
iflags.time_botl = 1; iflags.time_botl = flags.time;
curs_on_u(); curs_on_u();
delay_output(); delay_output();
if (flags.runmode == RUN_CRAWL) { if (flags.runmode == RUN_CRAWL) {
@@ -2927,6 +2931,21 @@ monster_nearby()
return 0; return 0;
} }
void
end_running(and_travel)
boolean and_travel;
{
/* moveloop() suppresses time_botl when context.run is non-zero; when
running stops, update 'time' even if other botl status is unchanged */
if (flags.time && g.context.run)
iflags.time_botl = TRUE;
g.context.run = 0;
/* 'context.mv' isn't travel but callers who want to end travel
all clear it too */
if (and_travel)
g.context.travel = g.context.travel1 = g.context.mv = 0;
}
void void
nomul(nval) nomul(nval)
int nval; int nval;
@@ -2939,7 +2958,7 @@ int nval;
g.multi = nval; g.multi = nval;
if (nval == 0) if (nval == 0)
g.multi_reason = NULL; g.multi_reason = NULL;
g.context.travel = g.context.travel1 = g.context.mv = g.context.run = 0; end_running(TRUE);
} }
/* called when a non-movement, multi-turn action has completed */ /* called when a non-movement, multi-turn action has completed */
@@ -2947,7 +2966,7 @@ void
unmul(msg_override) unmul(msg_override)
const char *msg_override; const char *msg_override;
{ {
g.context.botl = 1; g.context.botl = TRUE;
g.multi = 0; /* caller will usually have done this already */ g.multi = 0; /* caller will usually have done this already */
if (msg_override) if (msg_override)
g.nomovemsg = msg_override; g.nomovemsg = msg_override;
@@ -3018,11 +3037,19 @@ register int n;
register const char *knam; register const char *knam;
boolean k_format; boolean k_format;
{ {
#if 0 /* code below is prepared to handle negative 'loss' so don't add this
* until we've verified that no callers intentionally rely on that */
if (n <= 0) {
impossible("hero losing %d hit points due to \"%s\"?", n, knam);
return;
}
#endif
g.context.botl = TRUE; /* u.uhp or u.mh is changing */
end_running(TRUE);
if (Upolyd) { if (Upolyd) {
u.mh -= n; u.mh -= n;
if (u.mhmax < u.mh) if (u.mhmax < u.mh)
u.mhmax = u.mh; u.mhmax = u.mh;
g.context.botl = 1;
if (u.mh < 1) if (u.mh < 1)
rehumanize(); rehumanize();
else if (n > 0 && u.mh * 10 < u.mhmax && Unchanging) else if (n > 0 && u.mh * 10 < u.mhmax && Unchanging)
@@ -3033,9 +3060,6 @@ boolean k_format;
u.uhp -= n; u.uhp -= n;
if (u.uhp > u.uhpmax) if (u.uhp > u.uhpmax)
u.uhpmax = u.uhp; /* perhaps n was negative */ u.uhpmax = u.uhp; /* perhaps n was negative */
else
g.context.travel = g.context.travel1 = g.context.mv = g.context.run = 0;
g.context.botl = 1;
if (u.uhp < 1) { if (u.uhp < 1) {
g.killer.format = k_format; g.killer.format = k_format;
if (g.killer.name != knam) /* the thing that killed you */ if (g.killer.name != knam) /* the thing that killed you */
+20
View File
@@ -73,6 +73,7 @@
void strbuf_nl_to_crlf (strbuf_t *) void strbuf_nl_to_crlf (strbuf_t *)
char * nonconst (const char *, char *) char * nonconst (const char *, char *)
int swapbits (int, int, int) int swapbits (int, int, int)
UNUSED void shuffle_int_array (int *, int)
=*/ =*/
#ifdef LINT #ifdef LINT
#define Static /* pacify lint */ #define Static /* pacify lint */
@@ -1301,4 +1302,23 @@ int val, bita, bitb;
return (val ^ ((tmp << bita) | (tmp << bitb))); return (val ^ ((tmp << bita) | (tmp << bitb)));
} }
#if 0
/* randomize the given list of numbers 0 <= i < count */
static void
shuffle_int_array(indices, count)
int *indices;
int count;
{
int i, iswap, temp;
for (i = count - 1; i > 0; i--) {
if ((iswap = rn2(i + 1)) == i)
continue;
temp = indices[i];
indices[i] = indices[iswap];
indices[iswap] = temp;
}
}
#endif
/*hacklib.c*/ /*hacklib.c*/
-2
View File
@@ -1175,8 +1175,6 @@ register struct attack *mattk;
} }
/* adjattrib gives dunce cap message when appropriate */ /* adjattrib gives dunce cap message when appropriate */
(void) adjattrib(A_INT, -rnd(2), FALSE); (void) adjattrib(A_INT, -rnd(2), FALSE);
forget_levels(25); /* lose memory of 25% of levels */
forget_objects(25); /* lose memory of 25% of objects */
break; break;
case AD_PLYS: case AD_PLYS:
hitmsg(mtmp, mattk); hitmsg(mtmp, mattk);
+1 -1
View File
@@ -1543,7 +1543,7 @@ coord *tm;
otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], m.x, m.y, otmp = mkcorpstat(CORPSE, NULL, &mons[victim_mnum], m.x, m.y,
CORPSTAT_INIT); CORPSTAT_INIT);
if (otmp) if (otmp)
otmp->age -= 51; /* died too long ago to eat */ otmp->age -= (TAINT_AGE + 1); /* died too long ago to eat */
} }
} }
-4
View File
@@ -1189,10 +1189,6 @@ struct obj *body;
int rot_adjust; int rot_adjust;
short action; short action;
#define TAINT_AGE (50L) /* age when corpses go bad */
#define TROLL_REVIVE_CHANCE 37 /* 1/37 chance for 50 turns ~ 75% chance */
#define ROT_AGE (250L) /* age when corpses rot away */
/* lizards and lichen don't rot or revive */ /* lizards and lichen don't rot or revive */
if (body->corpsenm == PM_LIZARD || body->corpsenm == PM_LICHEN) if (body->corpsenm == PM_LIZARD || body->corpsenm == PM_LICHEN)
return; return;
+18 -2
View File
@@ -350,7 +350,7 @@ unsigned corpseflags;
num = undead_to_corpse(mndx); num = undead_to_corpse(mndx);
corpstatflags |= CORPSTAT_INIT; corpstatflags |= CORPSTAT_INIT;
obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags); obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
obj->age -= 100; /* this is an *OLD* corpse */ obj->age -= (TAINT_AGE + 1); /* this is an *OLD* corpse */
break; break;
case PM_KOBOLD_MUMMY: case PM_KOBOLD_MUMMY:
case PM_DWARF_MUMMY: case PM_DWARF_MUMMY:
@@ -371,7 +371,7 @@ unsigned corpseflags;
num = undead_to_corpse(mndx); num = undead_to_corpse(mndx);
corpstatflags |= CORPSTAT_INIT; corpstatflags |= CORPSTAT_INIT;
obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags); obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, corpstatflags);
obj->age -= 100; /* this is an *OLD* corpse */ obj->age -= (TAINT_AGE + 1); /* this is an *OLD* corpse */
break; break;
case PM_IRON_GOLEM: case PM_IRON_GOLEM:
num = d(2, 6); num = d(2, 6);
@@ -4170,6 +4170,22 @@ pacify_guards()
} }
} }
struct monst *
find_ghost_with_name(str)
char *str;
{
struct monst *mtmp;
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
if (DEADMONSTER(mtmp)
|| mtmp->data != &mons[PM_GHOST] || !has_mname(mtmp))
continue;
if (!strcmpi(MNAME(mtmp), str))
return mtmp;
}
return (struct monst *) 0;
}
void void
mimic_hit_msg(mtmp, otyp) mimic_hit_msg(mtmp, otyp)
struct monst *mtmp; struct monst *mtmp;
+1
View File
@@ -757,6 +757,7 @@ const char *in_str;
/* Hyphenated names -- it would be nice to handle these via /* Hyphenated names -- it would be nice to handle these via
fuzzymatch() but it isn't able to ignore trailing stuff */ fuzzymatch() but it isn't able to ignore trailing stuff */
{ "ki rin", PM_KI_RIN }, { "ki rin", PM_KI_RIN },
{ "kirin", PM_KI_RIN },
{ "uruk hai", PM_URUK_HAI }, { "uruk hai", PM_URUK_HAI },
{ "orc captain", PM_ORC_CAPTAIN }, { "orc captain", PM_ORC_CAPTAIN },
{ "woodland elf", PM_WOODLAND_ELF }, { "woodland elf", PM_WOODLAND_ELF },
+3 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.7 options.c $NHDT-Date: 1583282760 2020/03/04 00:46:00 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.457 $ */ /* NetHack 3.7 options.c $NHDT-Date: 1584350350 2020/03/16 09:19:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.459 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */ /*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -7568,6 +7568,8 @@ doset() /* changing options via menu by Per Liboriussen */
check_gold_symbol(); check_gold_symbol();
reglyph_darkroom(); reglyph_darkroom();
(void) doredraw(); (void) doredraw();
} else if (g.context.botl || g.context.botlx) {
bot();
} }
return 0; return 0;
} }
+5 -200
View File
@@ -22,11 +22,6 @@ static char *FDECL(apron_text, (struct obj *, char *buf));
static void FDECL(stripspe, (struct obj *)); static void FDECL(stripspe, (struct obj *));
static void FDECL(p_glow1, (struct obj *)); static void FDECL(p_glow1, (struct obj *));
static void FDECL(p_glow2, (struct obj *, const char *)); static void FDECL(p_glow2, (struct obj *, const char *));
static void FDECL(forget_single_object, (int));
#if 0 /* not used */
static void FDECL(forget_objclass, (int));
#endif
static void FDECL(randomize, (int *, int));
static void FDECL(forget, (int)); static void FDECL(forget, (int));
static int FDECL(maybe_tame, (struct monst *, struct obj *)); static int FDECL(maybe_tame, (struct monst *, struct obj *));
static boolean FDECL(get_valid_stinking_cloud_pos, (int, int)); static boolean FDECL(get_valid_stinking_cloud_pos, (int, int));
@@ -711,183 +706,13 @@ int curse_bless;
} }
} }
/* Forget known information about this object type. */
static void
forget_single_object(obj_id)
int obj_id;
{
objects[obj_id].oc_name_known = 0;
objects[obj_id].oc_pre_discovered = 0; /* a discovery when relearned */
if (objects[obj_id].oc_uname) {
free((genericptr_t) objects[obj_id].oc_uname);
objects[obj_id].oc_uname = 0;
}
undiscover_object(obj_id); /* after clearing oc_name_known */
/* clear & free object names from matching inventory items too? */
}
#if 0 /* here if anyone wants it.... */
/* Forget everything known about a particular object class. */
static void
forget_objclass(oclass)
int oclass;
{
int i;
for (i = g.bases[oclass];
i < NUM_OBJECTS && objects[i].oc_class == oclass; i++)
forget_single_object(i);
}
#endif
/* randomize the given list of numbers 0 <= i < count */
static void
randomize(indices, count)
int *indices;
int count;
{
int i, iswap, temp;
for (i = count - 1; i > 0; i--) {
if ((iswap = rn2(i + 1)) == i)
continue;
temp = indices[i];
indices[i] = indices[iswap];
indices[iswap] = temp;
}
}
/* Forget % of known objects. */
void
forget_objects(percent)
int percent;
{
int i, count;
int indices[NUM_OBJECTS];
if (percent == 0)
return;
if (percent <= 0 || percent > 100) {
impossible("forget_objects: bad percent %d", percent);
return;
}
indices[0] = 0; /* lint suppression */
for (count = 0, i = 1; i < NUM_OBJECTS; i++)
if (OBJ_DESCR(objects[i])
&& (objects[i].oc_name_known || objects[i].oc_uname))
indices[count++] = i;
if (count > 0) {
randomize(indices, count);
/* forget first % of randomized indices */
count = ((count * percent) + rn2(100)) / 100;
for (i = 0; i < count; i++)
forget_single_object(indices[i]);
}
}
/* Forget some or all of map (depends on parameters). */
void
forget_map(howmuch)
int howmuch;
{
register int zx, zy;
if (Sokoban)
return;
g.known = TRUE;
for (zx = 0; zx < COLNO; zx++)
for (zy = 0; zy < ROWNO; zy++)
if (howmuch & ALL_MAP || rn2(7)) {
/* Zonk all memory of this location. */
levl[zx][zy].seenv = 0;
levl[zx][zy].waslit = 0;
levl[zx][zy].glyph = GLYPH_UNEXPLORED;
g.lastseentyp[zx][zy] = STONE;
}
/* forget overview data for this level */
forget_mapseen(ledger_no(&u.uz));
}
/* Forget all traps on the level. */
void
forget_traps()
{
register struct trap *trap;
/* forget all traps (except the one the hero is in :-) */
for (trap = g.ftrap; trap; trap = trap->ntrap)
if ((trap->tx != u.ux || trap->ty != u.uy) && (trap->ttyp != HOLE))
trap->tseen = 0;
}
/*
* Forget given % of all levels that the hero has visited and not forgotten,
* except this one.
*/
void
forget_levels(percent)
int percent;
{
int i, count;
xchar maxl, this_lev;
int indices[MAXLINFO];
if (percent == 0)
return;
if (percent <= 0 || percent > 100) {
impossible("forget_levels: bad percent %d", percent);
return;
}
this_lev = ledger_no(&u.uz);
maxl = maxledgerno();
/* count & save indices of non-forgotten visited levels */
/* Sokoban levels are pre-mapped for the player, and should stay
* so, or they become nearly impossible to solve. But try to
* shift the forgetting elsewhere by fiddling with percent
* instead of forgetting fewer levels.
*/
indices[0] = 0; /* lint suppression */
for (count = 0, i = 0; i <= maxl; i++)
if ((g.level_info[i].flags & VISITED)
&& !(g.level_info[i].flags & FORGOTTEN) && i != this_lev) {
if (ledger_to_dnum(i) == sokoban_dnum)
percent += 2;
else
indices[count++] = i;
}
if (percent > 100)
percent = 100;
if (count > 0) {
randomize(indices, count);
/* forget first % of randomized indices */
count = ((count * percent) + 50) / 100;
for (i = 0; i < count; i++) {
g.level_info[indices[i]].flags |= FORGOTTEN;
forget_mapseen(indices[i]);
}
}
}
/* /*
* Forget some things (e.g. after reading a scroll of amnesia). When called, * Forget some things (e.g. after reading a scroll of amnesia). When called,
* the following are always forgotten: * the following are always forgotten:
* - felt ball & chain * - felt ball & chain
* - traps * - skill training
* - part (6 out of 7) of the map
* *
* Other things are subject to flags: * Other things are subject to flags:
* howmuch & ALL_MAP = forget whole map
* howmuch & ALL_SPELLS = forget all spells * howmuch & ALL_SPELLS = forget all spells
*/ */
static void static void
@@ -897,30 +722,11 @@ int howmuch;
if (Punished) if (Punished)
u.bc_felt = 0; /* forget felt ball&chain */ u.bc_felt = 0; /* forget felt ball&chain */
forget_map(howmuch);
forget_traps();
/* 1 in 3 chance of forgetting some levels */
if (!rn2(3))
forget_levels(rn2(25));
/* 1 in 3 chance of forgetting some objects */
if (!rn2(3))
forget_objects(rn2(25));
if (howmuch & ALL_SPELLS) if (howmuch & ALL_SPELLS)
losespells(); losespells();
/*
* Make sure that what was seen is restored correctly. To do this, /* Forget some skills. */
* we need to go blind for an instant --- turn off the display, drain_weapon_skill(rnd(howmuch ? 5 : 3));
* then restart it. All this work is needed to correctly handle
* walls which are stone on one side and wall on the other. Turning
* off the seen bits above will make the wall revert to stone, but
* there are cases where we don't want this to happen. The easiest
* thing to do is to run it through the vision system again, which
* is always correct.
*/
docrt(); /* this correctly will reset vision */
} }
/* monster is hit by scroll of taming's effect */ /* monster is hit by scroll of taming's effect */
@@ -1579,8 +1385,7 @@ struct obj *sobj; /* scroll, or fake spellbook object for scroll-like spell */
break; break;
case SCR_AMNESIA: case SCR_AMNESIA:
g.known = TRUE; g.known = TRUE;
forget((!sblessed ? ALL_SPELLS : 0) forget((!sblessed ? ALL_SPELLS : 0));
| (!confused || scursed ? ALL_MAP : 0));
if (Hallucination) /* Ommmmmm! */ if (Hallucination) /* Ommmmmm! */
Your("mind releases itself from mundane concerns."); Your("mind releases itself from mundane concerns.");
else if (!strncmpi(g.plname, "Maud", 4)) else if (!strncmpi(g.plname, "Maud", 4))
+1 -1
View File
@@ -210,7 +210,7 @@ dosit()
/* Magical voice not affected by deafness */ /* Magical voice not affected by deafness */
pline("A voice echoes:"); pline("A voice echoes:");
verbalize("Thy audience hath been summoned, %s!", verbalize("Thine audience hath been summoned, %s!",
flags.female ? "Dame" : "Sire"); flags.female ? "Dame" : "Sire");
while (cnt--) while (cnt--)
(void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS); (void) makemon(courtmon(), u.ux, u.uy, NO_MM_FLAGS);
+2 -2
View File
@@ -453,8 +453,8 @@ boolean extras;
/* get_level_extends() returns -1,-1 to COLNO,ROWNO at max */ /* get_level_extends() returns -1,-1 to COLNO,ROWNO at max */
if (miny < 0) if (miny < 0)
miny = 0; miny = 0;
if (minx < 0) if (minx < 1)
minx = 0; minx = 1;
if (maxx >= COLNO) if (maxx >= COLNO)
maxx = (COLNO - 1); maxx = (COLNO - 1);
if (maxy >= ROWNO) if (maxy >= ROWNO)
-2
View File
@@ -397,8 +397,6 @@ learn(VOID_ARGS)
book->spestudied++; book->spestudied++;
exercise(A_WIS, TRUE); /* extra study */ exercise(A_WIS, TRUE); /* extra study */
} }
/* make book become known even when spell is already
known, in case amnesia made you forget the book */
makeknown((int) booktype); makeknown((int) booktype);
} else { /* (spellid(i) == NO_SPELL) */ } else { /* (spellid(i) == NO_SPELL) */
/* for a normal book, spestudied will be zero, but for /* for a normal book, spestudied will be zero, but for
+1 -5
View File
@@ -719,11 +719,7 @@ boolean break_the_rules; /* True: wizard mode ^T */
if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12) if (!Teleportation || (u.ulevel < (Role_if(PM_WIZARD) ? 8 : 12)
&& !can_teleport(g.youmonst.data))) { && !can_teleport(g.youmonst.data))) {
/* Try to use teleport away spell. /* Try to use teleport away spell. */
Prior to 3.6.2 this used to require that you know the spellbook
(probably just intended as an optimization to skip the
lookup loop) but it is possible to know and cast a spell
after forgetting its book due to amnesia. */
for (sp_no = 0; sp_no < MAXSPELL; sp_no++) for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
if (g.spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY) if (g.spl_book[sp_no].sp_id == SPE_TELEPORT_AWAY)
break; break;
+3 -5
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1581886869 2020/02/16 21:01:09 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.227 $ */ /* NetHack 3.6 uhitm.c $NHDT-Date: 1584405117 2020/03/17 00:31:57 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.228 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -366,14 +366,12 @@ register struct monst *mtmp;
Strcpy(buf, y_monnam(mtmp)); Strcpy(buf, y_monnam(mtmp));
buf[0] = highc(buf[0]); buf[0] = highc(buf[0]);
You("stop. %s is in the way!", buf); You("stop. %s is in the way!", buf);
g.context.travel = g.context.travel1 = g.context.mv = g.context.run end_running(TRUE);
= 0;
return TRUE; return TRUE;
} else if ((mtmp->mfrozen || (!mtmp->mcanmove) } else if ((mtmp->mfrozen || (!mtmp->mcanmove)
|| (mtmp->data->mmove == 0)) && rn2(6)) { || (mtmp->data->mmove == 0)) && rn2(6)) {
pline("%s doesn't seem to move!", Monnam(mtmp)); pline("%s doesn't seem to move!", Monnam(mtmp));
g.context.travel = g.context.travel1 = g.context.mv = g.context.run end_running(TRUE);
= 0;
return TRUE; return TRUE;
} else } else
return FALSE; return FALSE;
+38
View File
@@ -1373,6 +1373,44 @@ int n; /* number of slots to lose; normally one */
} }
} }
void
drain_weapon_skill(n)
int n; /* number of skills to drain */
{
int skill;
int i;
int tmpskills[P_NUM_SKILLS];
(void) memset((genericptr_t) tmpskills, 0, sizeof(tmpskills));
while (--n >= 0) {
if (u.skills_advanced) {
/* Pick a random skill, deleting it from the list. */
i = rn2(u.skills_advanced);
skill = u.skill_record[i];
tmpskills[skill] = 1;
for (; i < u.skills_advanced - 1; i++) {
u.skill_record[i] = u.skill_record[i + 1];
}
u.skills_advanced--;
if (P_SKILL(skill) <= P_UNSKILLED)
panic("drain_weapon_skill (%d)", skill);
P_SKILL(skill)--; /* drop skill one level */
/* refund slots used for skill */
u.weapon_slots += slots_required(skill);
/* drain a random proportion of skill training */
if (P_ADVANCE(skill))
P_ADVANCE(skill) = rn2(P_ADVANCE(skill));
}
}
for (skill = 0; skill < P_NUM_SKILLS; skill++)
if (tmpskills[skill]) {
You("forget %syour training in %s.",
P_SKILL(skill) >= P_BASIC ? "some of " : "", P_NAME(skill));
}
}
int int
weapon_type(obj) weapon_type(obj)
struct obj *obj; struct obj *obj;
+28 -24
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 winstat.c $NHDT-Date: 1582833042 2020/02/27 19:50:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.24 $ */ /* NetHack 3.6 winstat.c $NHDT-Date: 1584482684 2020/03/17 22:04:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.26 $ */
/* Copyright (c) Dean Luick, 1992 */ /* Copyright (c) Dean Luick, 1992 */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1341,21 +1341,12 @@ static void
hilight_label(w) hilight_label(w)
Widget w; /* label widget */ Widget w; /* label widget */
{ {
Arg args[2];
Pixel fg, bg;
/* /*
* This predates STATUS_HILITES. * This predates STATUS_HILITES.
* It is used to show any changed item in inverse and gets * It is used to show any changed item in inverse and gets
* reset on the next turn. * reset on the next turn.
*/ */
swap_fg_bg(w);
XtSetArg(args[0], XtNforeground, &fg);
XtSetArg(args[1], XtNbackground, &bg);
XtGetValues(w, args, TWO);
XtSetArg(args[0], XtNforeground, bg);
XtSetArg(args[1], XtNbackground, fg);
XtSetValues(w, args, TWO);
} }
static void static void
@@ -1415,14 +1406,17 @@ long new_value;
/* special cases: hunger and encumbrance */ /* special cases: hunger and encumbrance */
if (attr_rec == &shown_stats[F_HUNGER]) { if (attr_rec == &shown_stats[F_HUNGER]) {
XtSetArg(args[0], XtNlabel, hu_stat[new_value]); Strcpy(buf, hu_stat[new_value]);
(void) mungspaces(buf);
} else if (attr_rec == &shown_stats[F_ENCUMBER]) { } else if (attr_rec == &shown_stats[F_ENCUMBER]) {
XtSetArg(args[0], XtNlabel, enc_stat[new_value]); Strcpy(buf, enc_stat[new_value]);
} else if (new_value) { } else if (new_value) {
XtSetArg(args[0], XtNlabel, attr_rec->name); Strcpy(buf, attr_rec->name); /* condition name On */
} else { } else {
XtSetArg(args[0], XtNlabel, ""); *buf = '\0'; /* condition name Off */
} }
XtSetArg(args[0], XtNlabel, buf);
XtSetValues(attr_rec->w, args, ONE); XtSetValues(attr_rec->w, args, ONE);
} else { /* a value pair */ } else { /* a value pair */
@@ -1532,18 +1526,28 @@ long new_value;
} }
/* /*
* Now hilight the changed information. Names, time and score don't * Now highlight the changed information. Don't highlight Time because
* hilight. If first time, don't hilight. If already lit, don't do * it's continually changing. For others, don't highlight if this is
* it again. * the first update. If already highlighted, don't change it unless
* it's being set to blank (where that item should be reset now instead
* of showing highlighted blank until the next expiration check).
*
* 3.7: highlight non-labelled 'name' items (conditions plus hunger
* and encumbrance) when they come On. For all conditions going Off,
* or changing to not-hungry or not-encumbered, there's nothing to
* highlight because the field becomes blank.
*/ */
if (attr_rec->type != SV_NAME && attr_rec != &shown_stats[F_TIME]) { if (attr_rec != &shown_stats[F_TIME]) {
if (attr_rec->after_init) { if (attr_rec->after_init) {
if (!attr_rec->set) { /* toggle if not highlighted and just set to nonblank or if
if (attr_rec->type == SV_LABEL) already highlighted and just set to blank */
if (!attr_rec->set ^ !*buf) {
if (attr_rec->type == SV_LABEL || attr_rec->type == SV_NAME)
hilight_label(attr_rec->w); hilight_label(attr_rec->w);
else else
hilight_value(attr_rec->w); hilight_value(attr_rec->w);
attr_rec->set = TRUE;
attr_rec->set = !attr_rec->set;
} }
attr_rec->turn_count = 0; attr_rec->turn_count = 0;
} else { } else {
@@ -1780,8 +1784,8 @@ check_turn_events()
continue; continue;
if (sv->turn_count++ >= hilight_time) { if (sv->turn_count++ >= hilight_time) {
/* unhighlights by toggling a highlit item back off again */ /* unhighlights by toggling a highlighted item back off again */
if (sv->type == SV_LABEL) if (sv->type == SV_LABEL || sv->type == SV_NAME)
hilight_label(sv->w); hilight_label(sv->w);
else else
hilight_value(sv->w); hilight_value(sv->w);