Merge branch 'NetHack-3.7' into NetHack-3.7-Jan2020
This commit is contained in:
+8
-3
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 attrib.c $NHDT-Date: 1575245050 2019/12/02 00:04:10 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.66 $ */
|
||||
/* NetHack 3.6 attrib.c $NHDT-Date: 1579655026 2020/01/22 01:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.74 $ */
|
||||
/* Copyright 1988, 1989, 1990, 1992, M. Stephenson */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -277,11 +277,12 @@ int typ, fatal; /* if fatal is 0, limit damage to adjattrib */
|
||||
boolean thrown_weapon; /* thrown weapons are less deadly */
|
||||
{
|
||||
int i, loss, kprefix = KILLED_BY_AN;
|
||||
boolean blast = !strcmp(reason, "blast");
|
||||
|
||||
/* inform player about being poisoned unless that's already been done;
|
||||
"blast" has given a "blast of poison gas" message; "poison arrow",
|
||||
"poison dart", etc have implicitly given poison messages too... */
|
||||
if (strcmp(reason, "blast") && !strstri(reason, "poison")) {
|
||||
if (!blast && !strstri(reason, "poison")) {
|
||||
boolean plural = (reason[strlen(reason) - 1] == 's') ? 1 : 0;
|
||||
|
||||
/* avoid "The" Orcus's sting was poisoned... */
|
||||
@@ -290,7 +291,7 @@ boolean thrown_weapon; /* thrown weapons are less deadly */
|
||||
plural ? "were" : "was");
|
||||
}
|
||||
if (Poison_resistance) {
|
||||
if (!strcmp(reason, "blast"))
|
||||
if (blast)
|
||||
shieldeff(u.ux, u.uy);
|
||||
pline_The("poison doesn't seem to affect you.");
|
||||
return;
|
||||
@@ -315,8 +316,12 @@ boolean thrown_weapon; /* thrown weapons are less deadly */
|
||||
g.context.botl = TRUE;
|
||||
pline_The("poison was deadly...");
|
||||
} else if (i > 5) {
|
||||
boolean cloud = !strcmp(reason, "gas cloud");
|
||||
|
||||
/* HP damage; more likely--but less severe--with missiles */
|
||||
loss = thrown_weapon ? rnd(6) : rn1(10, 6);
|
||||
if ((blast || cloud) && Half_gas_damage) /* worn towel */
|
||||
loss = (loss + 1) / 2;
|
||||
losehp(loss, pkiller, kprefix); /* poison damage */
|
||||
} else {
|
||||
/* attribute loss; if typ is A_STR, reduction in current and
|
||||
|
||||
+4
-8
@@ -165,14 +165,10 @@ boolean restore;
|
||||
if (mnum == PM_DOPPELGANGER && otmp->otyp == CORPSE)
|
||||
set_corpsenm(otmp, mnum);
|
||||
}
|
||||
} else if ((otmp->otyp == iflags.mines_prize_type
|
||||
&& !Is_mineend_level(&u.uz))
|
||||
|| ((otmp->otyp == iflags.soko_prize_type1
|
||||
|| otmp->otyp == iflags.soko_prize_type2)
|
||||
&& !Is_sokoend_level(&u.uz))) {
|
||||
/* "special prize" in this game becomes ordinary object
|
||||
if loaded into another game */
|
||||
otmp->record_achieve_special = NON_PM;
|
||||
} else if (is_mines_prize(otmp) || is_soko_prize(otmp)) {
|
||||
/* achievement tracking; in case prize was moved off its
|
||||
original level (which is always a no-bones level) */
|
||||
otmp->nomerge = 0;
|
||||
} else if (otmp->otyp == AMULET_OF_YENDOR) {
|
||||
/* no longer the real Amulet */
|
||||
otmp->otyp = FAKE_AMULET_OF_YENDOR;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1578764033 2020/01/11 17:33:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.391 $ */
|
||||
/* NetHack 3.6 cmd.c $NHDT-Date: 1579655026 2020/01/22 01:03:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.392 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -806,6 +806,24 @@ boolean pre, wiztower;
|
||||
continue;
|
||||
if (mtmp->isshk)
|
||||
setpaid(mtmp);
|
||||
/* achievement tracking */
|
||||
{
|
||||
static const char Unachieve[] = "%s achievement revoked.";
|
||||
|
||||
if (Is_mineend_level(&u.uz)) {
|
||||
if (u.uachieve.mines_luckstone) {
|
||||
pline(Unachieve, "Mine's end");
|
||||
u.uachieve.mines_luckstone = 0;
|
||||
}
|
||||
g.context.achieveo.mines_prize_oid = 0;
|
||||
} else if (Is_sokoend_level(&u.uz)) {
|
||||
if (u.uachieve.finish_sokoban) {
|
||||
pline(Unachieve, "Sokoban end");
|
||||
u.uachieve.finish_sokoban = 0;
|
||||
}
|
||||
g.context.achieveo.soko_prize_oid = 0;
|
||||
}
|
||||
}
|
||||
/* TODO?
|
||||
* Reduce 'born' tally for each monster about to be discarded
|
||||
* by savelev(), otherwise replacing heavily populated levels
|
||||
@@ -877,6 +895,7 @@ wiz_makemap(VOID_ARGS)
|
||||
{
|
||||
if (wizard) {
|
||||
boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz);
|
||||
|
||||
makemap_prepost(TRUE, was_in_W_tower);
|
||||
/* create a new level; various things like bestowing a guardian
|
||||
angel on Astral or setting off alarm on Ft.Ludios are handled
|
||||
@@ -2984,6 +3003,8 @@ int final;
|
||||
enlght_halfdmg(HALF_PHDAM, final);
|
||||
if (Half_spell_damage)
|
||||
enlght_halfdmg(HALF_SPDAM, final);
|
||||
if (Half_gas_damage)
|
||||
enl_msg(You_, "take", "took", " reduced poison gas damage", "");
|
||||
/* polymorph and other shape change */
|
||||
if (Protection_from_shape_changers)
|
||||
you_are("protected from shape changers",
|
||||
|
||||
@@ -638,8 +638,6 @@ const struct instance_globals g_init = {
|
||||
UNDEFINED_VALUE, /* ysize */
|
||||
FALSE, /* splev_init_present */
|
||||
FALSE, /* icedpools */
|
||||
0, /* mines_prize_count */
|
||||
0, /* soki_prize_count */
|
||||
{ UNDEFINED_PTR }, /* container_obj */
|
||||
0, /* container_idx */
|
||||
NULL, /* invent_carrying_monster */
|
||||
|
||||
+22
-4
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 do_wear.c $NHDT-Date: 1575768410 2019/12/08 01:26:50 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.126 $ */
|
||||
/* NetHack 3.6 do_wear.c $NHDT-Date: 1579649788 2020/01/21 23:36:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.127 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1159,15 +1159,19 @@ void
|
||||
Blindf_off(otmp)
|
||||
struct obj *otmp;
|
||||
{
|
||||
boolean was_blind = Blind, changed = FALSE;
|
||||
boolean was_blind = Blind, changed = FALSE,
|
||||
nooffmsg = !otmp;
|
||||
|
||||
if (!otmp)
|
||||
otmp = ublindf;
|
||||
if (!otmp) {
|
||||
impossible("Blindf_off without otmp");
|
||||
impossible("Blindf_off without eyewear?");
|
||||
return;
|
||||
}
|
||||
g.context.takeoff.mask &= ~W_TOOL;
|
||||
setworn((struct obj *) 0, otmp->owornmask);
|
||||
off_msg(otmp);
|
||||
if (!nooffmsg)
|
||||
off_msg(otmp);
|
||||
|
||||
if (Blind) {
|
||||
if (was_blind) {
|
||||
@@ -1895,6 +1899,15 @@ struct obj *obj;
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* FIXME:
|
||||
* except for the rings/nolimbs case, this allows you to put on
|
||||
* accessories without having any hands to manipulate them, and
|
||||
* to put them on when poly'd into a tiny or huge form where
|
||||
* they shouldn't fit. [If the latter situation changes, make
|
||||
* comparable change to break_armor(polyself.c).]
|
||||
*/
|
||||
|
||||
/* accessory */
|
||||
if (ring) {
|
||||
char answer, qbuf[QBUFSZ];
|
||||
@@ -1965,6 +1978,11 @@ struct obj *obj;
|
||||
return 0;
|
||||
}
|
||||
} else if (eyewear) {
|
||||
if (!has_head(g.youmonst.data)) {
|
||||
You("have no head to wear %s on.", ansimpleoname(obj));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ublindf) {
|
||||
if (ublindf->otyp == TOWEL)
|
||||
Your("%s is already covered by a towel.",
|
||||
|
||||
+3
-2
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 dothrow.c $NHDT-Date: 1573688688 2019/11/13 23:44:48 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.164 $ */
|
||||
/* NetHack 3.6 dothrow.c $NHDT-Date: 1579655027 2020/01/22 01:03:47 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.181 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1977,7 +1977,8 @@ boolean from_invent;
|
||||
explode_oil(obj, x, y);
|
||||
} else if (distu(x, y) <= 2) {
|
||||
if (!breathless(g.youmonst.data) || haseyes(g.youmonst.data)) {
|
||||
if (obj->otyp != POT_WATER) {
|
||||
/* wet towel protects both eyes and breathing */
|
||||
if (obj->otyp != POT_WATER && !Half_gas_damage) {
|
||||
if (!breathless(g.youmonst.data)) {
|
||||
/* [what about "familiar odor" when known?] */
|
||||
You("smell a peculiar odor...");
|
||||
|
||||
+14
-15
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 hack.c $NHDT-Date: 1578916008 2020/01/13 11:46:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.243 $ */
|
||||
/* NetHack 3.6 hack.c $NHDT-Date: 1579261288 2020/01/17 11:41:28 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.245 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -750,7 +750,7 @@ int mode;
|
||||
return FALSE;
|
||||
}
|
||||
if (!(Passes_walls || passes_bars(g.youmonst.data))) {
|
||||
if (mode == DO_MOVE && iflags.mention_walls)
|
||||
if (mode == DO_MOVE && flags.mention_walls)
|
||||
You("cannot pass through the bars.");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -772,7 +772,7 @@ int mode;
|
||||
else if (Passes_walls && !may_passwall(x, y)
|
||||
&& In_sokoban(&u.uz))
|
||||
pline_The("Sokoban walls resist your ability.");
|
||||
else if (iflags.mention_walls)
|
||||
else if (flags.mention_walls)
|
||||
pline("It's %s.",
|
||||
(IS_WALL(tmpr->typ) || tmpr->typ == SDOOR) ? "a wall"
|
||||
: IS_TREE(tmpr->typ) ? "a tree"
|
||||
@@ -842,7 +842,7 @@ int mode;
|
||||
if (mode == DO_MOVE) {
|
||||
if (Blind)
|
||||
feel_location(x, y);
|
||||
if (Underwater || iflags.mention_walls)
|
||||
if (Underwater || flags.mention_walls)
|
||||
You_cant("move diagonally into an intact doorway.");
|
||||
}
|
||||
return FALSE;
|
||||
@@ -896,7 +896,7 @@ int mode;
|
||||
if (dx && dy && !Passes_walls && IS_DOOR(ust->typ)
|
||||
&& (!doorless_door(ux, uy) || block_entry(x, y))) {
|
||||
/* Can't move at a diagonal out of a doorway with door. */
|
||||
if (mode == DO_MOVE && iflags.mention_walls)
|
||||
if (mode == DO_MOVE && flags.mention_walls)
|
||||
You_cant("move diagonally out of an intact doorway.");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -904,7 +904,7 @@ int mode;
|
||||
if (sobj_at(BOULDER, x, y) && (Sokoban || !Passes_walls)) {
|
||||
if (!(Blind || Hallucination) && (g.context.run >= 2)
|
||||
&& mode != TEST_TRAV) {
|
||||
if (mode == DO_MOVE && iflags.mention_walls)
|
||||
if (mode == DO_MOVE && flags.mention_walls)
|
||||
pline("A boulder blocks your path.");
|
||||
return FALSE;
|
||||
}
|
||||
@@ -1495,7 +1495,7 @@ domove_core()
|
||||
}
|
||||
}
|
||||
if (!isok(x, y)) {
|
||||
if (iflags.mention_walls) {
|
||||
if (flags.mention_walls) {
|
||||
int dx = u.dx, dy = u.dy;
|
||||
|
||||
if (dx && dy) { /* diagonal */
|
||||
@@ -1511,13 +1511,14 @@ domove_core()
|
||||
directionname(xytod(dx, dy)));
|
||||
}
|
||||
nomul(0);
|
||||
g.context.move = 0;
|
||||
return;
|
||||
}
|
||||
if (((trap = t_at(x, y)) && trap->tseen)
|
||||
|| (Blind && !Levitation && !Flying && !is_clinger(g.youmonst.data)
|
||||
&& is_pool_or_lava(x, y) && levl[x][y].seenv)) {
|
||||
if (g.context.run >= 2) {
|
||||
if (iflags.mention_walls) {
|
||||
if (flags.mention_walls) {
|
||||
if (trap && trap->tseen) {
|
||||
You("stop in front of %s.",
|
||||
an(trapname(trap->ttyp, FALSE)));
|
||||
@@ -2728,7 +2729,7 @@ lookaround()
|
||||
if ((g.context.run != 1 && !mtmp->mtame)
|
||||
|| (x == u.ux + u.dx && y == u.uy + u.dy
|
||||
&& !g.context.travel)) {
|
||||
if (iflags.mention_walls)
|
||||
if (flags.mention_walls)
|
||||
pline("%s blocks your path.", upstart(a_monnam(mtmp)));
|
||||
goto stop;
|
||||
}
|
||||
@@ -2746,7 +2747,7 @@ lookaround()
|
||||
if (x != u.ux && y != u.uy)
|
||||
continue;
|
||||
if (g.context.run != 1) {
|
||||
if (iflags.mention_walls)
|
||||
if (flags.mention_walls)
|
||||
You("stop in front of the door.");
|
||||
goto stop;
|
||||
}
|
||||
@@ -2775,11 +2776,9 @@ lookaround()
|
||||
if (g.context.run == 1)
|
||||
goto bcorr; /* if you must */
|
||||
if (x == u.ux + u.dx && y == u.uy + u.dy) {
|
||||
if (iflags.mention_walls) {
|
||||
|
||||
if (flags.mention_walls)
|
||||
You("stop in front of %s.",
|
||||
an(trapname(trap->ttyp, FALSE)));
|
||||
}
|
||||
goto stop;
|
||||
}
|
||||
continue;
|
||||
@@ -2793,7 +2792,7 @@ lookaround()
|
||||
* to test boots by trying to SHIFT-direction
|
||||
* into a pool and seeing if the game allowed it
|
||||
*/
|
||||
if (iflags.mention_walls)
|
||||
if (flags.mention_walls)
|
||||
You("stop at the edge of the %s.",
|
||||
hliquid(is_pool(x,y) ? "water" : "lava"));
|
||||
goto stop;
|
||||
@@ -2816,7 +2815,7 @@ lookaround()
|
||||
} /* end for loops */
|
||||
|
||||
if (corrct > 1 && g.context.run == 2) {
|
||||
if (iflags.mention_walls)
|
||||
if (flags.mention_walls)
|
||||
pline_The("corridor widens here.");
|
||||
goto stop;
|
||||
}
|
||||
|
||||
+3
-9
@@ -835,20 +835,14 @@ struct obj *obj;
|
||||
}
|
||||
|
||||
/* "special achievements" aren't discoverable during play, they
|
||||
end up being recorded in XLOGFILE at end of game, nowhere else;
|
||||
record_achieve_special overloads corpsenm which is ordinarily
|
||||
initialized to NON_PM (-1) rather than to 0; any special prize
|
||||
must never be a corpse, egg, tin, figurine, or statue because
|
||||
their use of obj->corpsenm for monster type would conflict,
|
||||
nor be a leash (corpsenm overloaded for m_id of leashed
|
||||
monster) or a novel (corpsenm overloaded for novel index) */
|
||||
end up being recorded in XLOGFILE at end of game, nowhere else */
|
||||
if (is_mines_prize(obj)) {
|
||||
u.uachieve.mines_luckstone = 1;
|
||||
obj->record_achieve_special = NON_PM;
|
||||
g.context.achieveo.mines_prize_oid = 0;
|
||||
obj->nomerge = 0;
|
||||
} else if (is_soko_prize(obj)) {
|
||||
u.uachieve.finish_sokoban = 1;
|
||||
obj->record_achieve_special = NON_PM;
|
||||
g.context.achieveo.soko_prize_oid = 0;
|
||||
obj->nomerge = 0;
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 monmove.c $NHDT-Date: 1575245074 2019/12/02 00:04:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.116 $ */
|
||||
/* NetHack 3.6 monmove.c $NHDT-Date: 1579616424 2020/01/21 14:20:24 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.128 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2006. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1286,20 +1286,27 @@ register int after;
|
||||
if (!m_in_out_region(mtmp, nix, niy))
|
||||
return 3;
|
||||
|
||||
/* move a normal monster; for a long worm, remove_monster() and
|
||||
place_monster() only manipulate the head; they leave tail as-is */
|
||||
remove_monster(omx, omy);
|
||||
place_monster(mtmp, nix, niy);
|
||||
/* for a long worm, insert a new segment to reconnect the head
|
||||
with the tail; worm_move() keeps the end of the tail if worm
|
||||
is scheduled to grow, removes that for move-without-growing */
|
||||
if (mtmp->wormno)
|
||||
worm_move(mtmp);
|
||||
|
||||
for (j = MTSZ - 1; j > 0; j--)
|
||||
mtmp->mtrack[j] = mtmp->mtrack[j - 1];
|
||||
mtmp->mtrack[0].x = omx;
|
||||
mtmp->mtrack[0].y = omy;
|
||||
/* Place a segment at the old position. */
|
||||
if (mtmp->wormno)
|
||||
worm_move(mtmp);
|
||||
} else {
|
||||
if (is_unicorn(ptr) && rn2(2) && !tele_restrict(mtmp)) {
|
||||
(void) rloc(mtmp, TRUE);
|
||||
return 1;
|
||||
}
|
||||
/* for a long worm, shrink it (by discarding end of tail) when
|
||||
it has failed to move */
|
||||
if (mtmp->wormno)
|
||||
worm_nomove(mtmp);
|
||||
}
|
||||
|
||||
+124
-15
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 nhlua.c $NHDT-Date: 1575246766 2019/12/02 00:32:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.16 $ */
|
||||
/* NetHack 3.7 nhlua.c $NHDT-Date: 1579901146 2020/01/24 21:25:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.29 $ */
|
||||
/* Copyright (c) 2018 by Pasi Kallinen */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -44,8 +44,16 @@ const char *msg;
|
||||
|
||||
lua_getstack(L, 1, &ar);
|
||||
lua_getinfo(L, "lS", &ar);
|
||||
Sprintf(buf, "%s (line %i%s)", msg, ar.currentline, ar.source);
|
||||
Sprintf(buf, "%s (line %d ", msg, ar.currentline);
|
||||
Sprintf(eos(buf), "%.*s)",
|
||||
/* (max length of ar.short_src is actually LUA_IDSIZE
|
||||
so this is overkill for it, but crucial for ar.source) */
|
||||
(int) (sizeof buf - (strlen(buf) + sizeof ")")),
|
||||
ar.short_src); /* (used to be 'ar.source' here) */
|
||||
lua_pushstring(L, buf);
|
||||
#if 0 /* defined(PANICTRACE) && !defined(NO_SIGNALS) */
|
||||
panictrace_setsignals(FALSE);
|
||||
#endif
|
||||
(void) lua_error(L);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
@@ -923,16 +931,21 @@ lua_State *L;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* read lua code/data from a dlb module or an external file, insert the
|
||||
file name as new first record so that we aren't at the mercy of whoever
|
||||
edits it to maintain that, and since we're forced to muck with messy
|
||||
details, replace comments with empty lines so that Lua won't need to */
|
||||
boolean
|
||||
nhl_loadlua(L, fname)
|
||||
lua_State *L;
|
||||
const char *fname;
|
||||
{
|
||||
boolean ret = TRUE;
|
||||
#define LOADCHUNKSIZE (1L << 13) /* 8K */
|
||||
boolean ret = TRUE, is_comment;
|
||||
dlb *fh;
|
||||
char *buf = (char *) 0;
|
||||
long buflen;
|
||||
int cnt, llret;
|
||||
char *buf = (char *) 0, *bufin, *bufout, *p, *nl;
|
||||
long buflen, ct, cnt, fnamesiz;
|
||||
int llret, first = 0, spanlines = 0;
|
||||
|
||||
fh = dlb_fopen(fname, "r");
|
||||
if (!fh) {
|
||||
@@ -941,20 +954,117 @@ const char *fname;
|
||||
goto give_up;
|
||||
}
|
||||
|
||||
fnamesiz = strlen(fname) + 7L; /* 7: "--{" + "}--\n" (no '\0') */
|
||||
dlb_fseek(fh, 0L, SEEK_END);
|
||||
buflen = dlb_ftell(fh);
|
||||
buf = (char *) alloc(buflen + 1);
|
||||
dlb_fseek(fh, 0L, SEEK_SET);
|
||||
|
||||
if ((cnt = dlb_fread(buf, 1, buflen, fh)) != buflen) {
|
||||
impossible("nhl_loadlua: Error loading %s, got %i/%li bytes",
|
||||
fname, cnt, buflen);
|
||||
ret = FALSE;
|
||||
goto give_up;
|
||||
/* extra +1: room to add final '\n' if missing */
|
||||
buf = bufout = (char *) alloc(fnamesiz + buflen + 1 + 1);
|
||||
/* insert file name as first record so nhl_error() can report it;
|
||||
leading dashes make it be a comment, trailing ones are for
|
||||
symmetry; delimit file name with braces instead of spaces to
|
||||
avoid an undesireable line split during error feedback */
|
||||
Sprintf(bufout, "--{%s}--\n", fname);
|
||||
bufin = bufout = eos(buf);
|
||||
|
||||
ct = 0L;
|
||||
while (buflen > 0 || ct) {
|
||||
/*
|
||||
* Semi-arbitrarily limit reads to 8K at a time. That's big
|
||||
* enough to cover the majority of our Lua files in one bite
|
||||
* but small enough to fully exercise the partial record
|
||||
* handling (when processing the castle's level description).
|
||||
*
|
||||
* [For an external file (non-DLB), VMS may only be able to
|
||||
* read at most 32K-1 at a time depending on the file format
|
||||
* in use, and fseek(SEEK_END) only yields an upper bound on
|
||||
* the actual amount of data in that situation.]
|
||||
*/
|
||||
if ((cnt = dlb_fread(bufin, 1, min(buflen, LOADCHUNKSIZE), fh)) < 0L)
|
||||
break;
|
||||
buflen -= cnt; /* set up for next iteration, if any */
|
||||
if (cnt == 0L) {
|
||||
*bufin = '\n'; /* very last line is unterminated? */
|
||||
cnt = 1;
|
||||
}
|
||||
bufin[cnt] = '\0'; /* fread() doesn't do this */
|
||||
|
||||
/* in case partial line was leftover from previous fread */
|
||||
bufin -= ct, cnt += ct, ct = 0;
|
||||
|
||||
while (cnt > 0) {
|
||||
if ((nl = index(bufin, '\n')) != 0) {
|
||||
/* normal case, newline is present */
|
||||
ct = (long) (nl - bufin + 1L); /* +1: keep the newline */
|
||||
for (p = bufin; *p == ' '; ++p)
|
||||
continue;
|
||||
is_comment = (p[0] == '-' && p[1] == '-' && !spanlines);
|
||||
if (spanlines && index("])}", *p))
|
||||
--spanlines;
|
||||
if (!first++ && (*p == '\n' || is_comment)) {
|
||||
/* if first line is blank or a comment, omit it so that
|
||||
our "--{fname}--\n" line doesn't make the line count
|
||||
be out of sync; note: when first line is code, line
|
||||
number reported in error messages will be off by one */
|
||||
bufin = nl + 1;
|
||||
} else if (is_comment) {
|
||||
/* discard comment to shorten the string Lua will deal
|
||||
with but keep the line to maintain Lua line counter */
|
||||
#if 0
|
||||
Strcpy(bufout, "--\n"), bufout += 3;
|
||||
#else
|
||||
Strcpy(bufout, "\n"), bufout += 1;
|
||||
#endif
|
||||
bufin += ct;
|
||||
} else {
|
||||
/* normal case; some text terminated by newline */
|
||||
for (p = bufin; p <= nl; ++p)
|
||||
*bufout++ = *bufin++;
|
||||
for (p = &bufout[-2]; *p == ' '; --p) /* [-1] is '\n' */
|
||||
continue;
|
||||
if (index("[({", *p))
|
||||
++spanlines;
|
||||
}
|
||||
if (*bufin == '\r')
|
||||
++bufin, ++ct;
|
||||
/* update for next loop iteration */
|
||||
cnt -= ct;
|
||||
ct = 0;
|
||||
} else {
|
||||
/* no newline => partial record; move unprocessed chars
|
||||
to front of input buffer (bufin portion of buf[]) */
|
||||
ct = cnt = (long) (eos(bufin) - bufin);
|
||||
for (p = bufout; cnt > 0; --cnt)
|
||||
*p++ = *bufin++;
|
||||
*p = '\0';
|
||||
bufin = p; /* next fread() populates buf[] starting here */
|
||||
/* cnt==0 so inner loop will terminate */
|
||||
}
|
||||
}
|
||||
}
|
||||
buf[buflen] = '\0';
|
||||
*bufout = '\0';
|
||||
(void) dlb_fclose(fh);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (explicitdebug("loadlua")) {
|
||||
FILE *fp;
|
||||
char oname[QBUFSZ];
|
||||
|
||||
(void) strsubst(strcpy(oname, fname), ".lua", ".txt");
|
||||
if ((fp = fopen(oname, "w")) != 0) {
|
||||
for (buflen = strlen(buf), p = buf;
|
||||
buflen > 0;
|
||||
buflen -= cnt, p += cnt) {
|
||||
cnt = min(buflen, LOADCHUNKSIZE);
|
||||
if ((long) fwrite(p, 1, cnt, fp) < cnt)
|
||||
break;
|
||||
}
|
||||
(void) fclose(fp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
llret = luaL_loadstring(L, buf);
|
||||
if (llret != LUA_OK) {
|
||||
impossible("luaL_loadstring: Error loading %s (errcode %i)",
|
||||
@@ -973,8 +1083,7 @@ const char *fname;
|
||||
|
||||
give_up:
|
||||
if (buf) {
|
||||
free(buf);
|
||||
buf = (char *) 0;
|
||||
free((genericptr_t) buf);
|
||||
buflen = 0;
|
||||
}
|
||||
return ret;
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1578896203 2020/01/13 06:16:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.287 $ */
|
||||
/* NetHack 3.7 objnam.c $NHDT-Date: 1579261291 2020/01/17 11:41:31 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.288 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -998,7 +998,7 @@ unsigned doname_flags;
|
||||
Strcat(prefix, "cursed ");
|
||||
else if (obj->blessed)
|
||||
Strcat(prefix, "blessed ");
|
||||
else if (!iflags.implicit_uncursed
|
||||
else if (!flags.implicit_uncursed
|
||||
/* For most items with charges or +/-, if you know how many
|
||||
* charges are left or what the +/- is, then you must have
|
||||
* totally identified the item, so "uncursed" is unnecessary,
|
||||
|
||||
+7
-7
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 options.c $NHDT-Date: 1578996303 2020/01/14 10:05:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.396 $ */
|
||||
/* NetHack 3.7 options.c $NHDT-Date: 1579261293 2020/01/17 11:41:33 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.428 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2008. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -148,7 +148,7 @@ static const struct Bool_Opt {
|
||||
#else
|
||||
{ "ignintr", (boolean *) 0, FALSE, SET_IN_FILE },
|
||||
#endif
|
||||
{ "implicit_uncursed", &iflags.implicit_uncursed, TRUE, SET_IN_GAME },
|
||||
{ "implicit_uncursed", &flags.implicit_uncursed, TRUE, SET_IN_GAME },
|
||||
{ "large_font", &iflags.obsolete, FALSE, SET_IN_FILE }, /* OBSOLETE */
|
||||
{ "legacy", &flags.legacy, TRUE, DISP_IN_GAME },
|
||||
{ "lit_corridor", &flags.lit_corridor, FALSE, SET_IN_GAME },
|
||||
@@ -158,7 +158,7 @@ static const struct Bool_Opt {
|
||||
#else
|
||||
{ "mail", (boolean *) 0, TRUE, SET_IN_FILE },
|
||||
#endif
|
||||
{ "mention_walls", &iflags.mention_walls, FALSE, SET_IN_GAME },
|
||||
{ "mention_walls", &flags.mention_walls, FALSE, SET_IN_GAME },
|
||||
{ "menucolors", &iflags.use_menu_color, FALSE, SET_IN_GAME },
|
||||
/* for menu debugging only*/
|
||||
{ "menu_tab_sep", &iflags.menu_tab_sep, FALSE, SET_IN_WIZGAME },
|
||||
@@ -739,9 +739,9 @@ initoptions_init()
|
||||
|
||||
/* for "special achievement" tracking (see obj.h,
|
||||
create_object(sp_lev.c), addinv_core1(invent.c) */
|
||||
iflags.mines_prize_type = LUCKSTONE;
|
||||
iflags.soko_prize_type1 = BAG_OF_HOLDING;
|
||||
iflags.soko_prize_type2 = AMULET_OF_REFLECTION;
|
||||
g.context.achieveo.mines_prize_type = LUCKSTONE;
|
||||
g.context.achieveo.soko_prize_typ1 = BAG_OF_HOLDING;
|
||||
g.context.achieveo.soko_prize_typ2 = AMULET_OF_REFLECTION;
|
||||
|
||||
/* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
|
||||
(void) memcpy((genericptr_t) flags.inv_order,
|
||||
@@ -4086,7 +4086,7 @@ boolean tinitial, tfrom_file;
|
||||
g.context.botl = TRUE;
|
||||
} else if (boolopt[i].addr == &flags.invlet_constant
|
||||
|| boolopt[i].addr == &flags.sortpack
|
||||
|| boolopt[i].addr == &iflags.implicit_uncursed) {
|
||||
|| boolopt[i].addr == &flags.implicit_uncursed) {
|
||||
if (!flags.invlet_constant)
|
||||
reassign();
|
||||
update_inventory();
|
||||
|
||||
+25
-5
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 polyself.c $NHDT-Date: 1573290419 2019/11/09 09:06:59 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.135 $ */
|
||||
/* NetHack 3.6 polyself.c $NHDT-Date: 1579660157 2020/01/22 02:29:17 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.149 $ */
|
||||
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -462,14 +462,19 @@ int psflags;
|
||||
pline("I've never heard of such monsters.");
|
||||
else
|
||||
You_cant("polymorph into any of those.");
|
||||
} else if (wizard && Upolyd && mntmp == u.umonster) {
|
||||
/* in wizard mode, picking own role while poly'd reverts to
|
||||
normal without newman()'s chance of level or sex change */
|
||||
rehumanize();
|
||||
goto made_change;
|
||||
} else if (iswere && (were_beastie(mntmp) == u.ulycn
|
||||
|| mntmp == counter_were(u.ulycn)
|
||||
|| (Upolyd && mntmp == PM_HUMAN))) {
|
||||
goto do_shift;
|
||||
/* Note: humans are illegal as monsters, but an
|
||||
* illegal monster forces newman(), which is what we
|
||||
* want if they specified a human.... */
|
||||
} else if (!polyok(&mons[mntmp])
|
||||
/* Note: humans are illegal as monsters, but an
|
||||
illegal monster forces newman(), which is what
|
||||
we want if they specified a human.... */
|
||||
&& !(mntmp == PM_HUMAN || your_race(&mons[mntmp])
|
||||
|| mntmp == g.urole.malenum
|
||||
|| mntmp == g.urole.femalenum)) {
|
||||
@@ -934,7 +939,7 @@ break_armor()
|
||||
useup(uarmu);
|
||||
}
|
||||
} else if (sliparm(g.youmonst.data)) {
|
||||
if (((otmp = uarm) != 0) && (racial_exception(&g.youmonst, otmp) < 1)) {
|
||||
if ((otmp = uarm) != 0 && racial_exception(&g.youmonst, otmp) < 1) {
|
||||
if (donning(otmp))
|
||||
cancel_don();
|
||||
Your("armor falls around you!");
|
||||
@@ -1016,6 +1021,21 @@ break_armor()
|
||||
dropp(otmp);
|
||||
}
|
||||
}
|
||||
/* not armor, but eyewear shouldn't stay worn without a head to wear
|
||||
it/them on (should also come off if head is too tiny or too huge,
|
||||
but putting accessories on doesn't reject those cases [yet?]);
|
||||
amulet stays worn */
|
||||
if ((otmp = ublindf) != 0 && !has_head(g.youmonst.data)) {
|
||||
int l;
|
||||
const char *eyewear = simpleonames(otmp); /* blindfold|towel|lenses */
|
||||
|
||||
if (!strncmp(eyewear, "pair of ", l = 8)) /* lenses */
|
||||
eyewear += l;
|
||||
Your("%s %s off!", eyewear, vtense(eyewear, "fall"));
|
||||
(void) Blindf_off((struct obj *) 0); /* Null: skip usual off mesg */
|
||||
dropp(otmp);
|
||||
}
|
||||
/* rings stay worn even when no hands */
|
||||
}
|
||||
|
||||
static void
|
||||
|
||||
+10
-4
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 potion.c $NHDT-Date: 1573848199 2019/11/15 20:03:19 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.167 $ */
|
||||
/* NetHack 3.6 potion.c $NHDT-Date: 1579655028 2020/01/22 01:03:48 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.179 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1627,13 +1627,19 @@ register struct obj *obj;
|
||||
remains in inventory where our caller expects it to be */
|
||||
obj->in_use = 1;
|
||||
|
||||
switch (obj->otyp) {
|
||||
/* wearing a wet towel protects both eyes and breathing, even when
|
||||
the breath effect might be beneficial; we still pass down to the
|
||||
naming opportunity in case potion was thrown at hero by a monster */
|
||||
switch (Half_gas_damage ? TOWEL : obj->otyp) {
|
||||
case TOWEL:
|
||||
pline("Some vapor passes harmlessly around you.");
|
||||
break;
|
||||
case POT_RESTORE_ABILITY:
|
||||
case POT_GAIN_ABILITY:
|
||||
if (obj->cursed) {
|
||||
if (!breathless(g.youmonst.data))
|
||||
if (!breathless(g.youmonst.data)) {
|
||||
pline("Ulch! That potion smells terrible!");
|
||||
else if (haseyes(g.youmonst.data)) {
|
||||
} else if (haseyes(g.youmonst.data)) {
|
||||
const char *eyes = body_part(EYE);
|
||||
|
||||
if (eyecount(g.youmonst.data) != 1)
|
||||
|
||||
+8
-6
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pray.c $NHDT-Date: 1578895347 2020/01/13 06:02:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.138 $ */
|
||||
/* NetHack 3.6 pray.c $NHDT-Date: 1579401997 2020/01/19 02:46:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.139 $ */
|
||||
/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -484,7 +484,7 @@ int trouble;
|
||||
what = rightglow;
|
||||
else if (otmp == uleft)
|
||||
what = leftglow;
|
||||
decurse:
|
||||
decurse:
|
||||
if (!otmp) {
|
||||
impossible("fix_worst_trouble: nothing to uncurse.");
|
||||
return;
|
||||
@@ -1496,7 +1496,7 @@ dosacrifice()
|
||||
|
||||
if (otmp->otyp == AMULET_OF_YENDOR) {
|
||||
if (!highaltar) {
|
||||
too_soon:
|
||||
too_soon:
|
||||
if (altaralign == A_NONE && Inhell)
|
||||
/* hero has left Moloch's Sanctum so is in the process
|
||||
of getting away with the Amulet (outside of Gehennom,
|
||||
@@ -1526,7 +1526,8 @@ dosacrifice()
|
||||
/* Moloch's high altar */
|
||||
if (u.ualign.record > -99)
|
||||
u.ualign.record = -99;
|
||||
pline("An invisible choir chants in Latin, and you are bathed in darkness...");
|
||||
pline(
|
||||
"An invisible choir chants, and you are bathed in darkness...");
|
||||
/*[apparently shrug/snarl can be sensed without being seen]*/
|
||||
pline("%s shrugs and retains dominion over %s,", Moloch,
|
||||
u_gname());
|
||||
@@ -1593,7 +1594,7 @@ dosacrifice()
|
||||
}
|
||||
|
||||
if (altaralign != u.ualign.type && highaltar) {
|
||||
desecrate_high_altar:
|
||||
desecrate_high_altar:
|
||||
/*
|
||||
* REAL BAD NEWS!!! High altars cannot be converted. Even an attempt
|
||||
* gets the god who owns it truly pissed off.
|
||||
@@ -1830,7 +1831,8 @@ boolean praying; /* false means no messages should be given */
|
||||
}
|
||||
|
||||
if (is_undead(g.youmonst.data) && !Inhell
|
||||
&& (g.p_aligntyp == A_LAWFUL || (g.p_aligntyp == A_NEUTRAL && !rn2(10))))
|
||||
&& (g.p_aligntyp == A_LAWFUL
|
||||
|| (g.p_aligntyp == A_NEUTRAL && !rn2(10))))
|
||||
g.p_type = -1;
|
||||
/* Note: when !praying, the random factor for neutrals makes the
|
||||
return value a non-deterministic approximation for enlightenment.
|
||||
|
||||
+36
-11
@@ -432,9 +432,10 @@ boolean common UNUSED;
|
||||
}
|
||||
|
||||
boolean
|
||||
com_pager_core(section, msgid)
|
||||
com_pager_core(section, msgid, showerror)
|
||||
const char *section;
|
||||
const char *msgid;
|
||||
boolean showerror;
|
||||
{
|
||||
const char *const howtoput[] = { "pline", "window", "text", "menu", "default", NULL };
|
||||
const int howtoput2i[] = { 1, 2, 2, 3, 0, 0 };
|
||||
@@ -442,6 +443,7 @@ const char *msgid;
|
||||
lua_State *L;
|
||||
char *synopsis;
|
||||
char *text;
|
||||
char *fallback_msgid = NULL;
|
||||
|
||||
if (skip_pager(TRUE))
|
||||
return FALSE;
|
||||
@@ -449,7 +451,8 @@ const char *msgid;
|
||||
L = nhl_init();
|
||||
|
||||
if (!nhl_loadlua(L, QTEXT_FILE)) {
|
||||
impossible("com_pager: %s not found.", QTEXT_FILE);
|
||||
if (showerror)
|
||||
impossible("com_pager: %s not found.", QTEXT_FILE);
|
||||
lua_close(L);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -457,21 +460,40 @@ const char *msgid;
|
||||
lua_settop(L, 0);
|
||||
lua_getglobal(L, "questtext");
|
||||
if (!lua_istable(L, -1)) {
|
||||
impossible("com_pager: questtext in %s is not a lua table", QTEXT_FILE);
|
||||
if (showerror)
|
||||
impossible("com_pager: questtext in %s is not a lua table",
|
||||
QTEXT_FILE);
|
||||
lua_close(L);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lua_getfield(L, -1, section);
|
||||
if (!lua_istable(L, -1)) {
|
||||
impossible("com_pager: questtext[%s] in %s is not a lua table", section, QTEXT_FILE);
|
||||
if (showerror)
|
||||
impossible("com_pager: questtext[%s] in %s is not a lua table",
|
||||
section, QTEXT_FILE);
|
||||
lua_close(L);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
lua_getfield(L, -1, msgid);
|
||||
tryagain:
|
||||
lua_getfield(L, -1, fallback_msgid ? fallback_msgid : msgid);
|
||||
if (!lua_istable(L, -1)) {
|
||||
impossible("com_pager: questtext[%s][%s] in %s is not a lua table", section, msgid, QTEXT_FILE);
|
||||
if (!fallback_msgid) {
|
||||
/* Do we have questtxt[msg_fallbacks][<msgid>]? */
|
||||
lua_getfield(L, -3, "msg_fallbacks");
|
||||
if (lua_istable(L, -1)) {
|
||||
fallback_msgid = get_table_str_opt(L, msgid, NULL);
|
||||
lua_pop(L, 2);
|
||||
if (fallback_msgid)
|
||||
goto tryagain;
|
||||
}
|
||||
}
|
||||
|
||||
if (showerror)
|
||||
impossible("com_pager: questtext[%s][%s] in %s is not a lua table",
|
||||
section, msgid, QTEXT_FILE);
|
||||
free(fallback_msgid);
|
||||
lua_close(L);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -487,9 +509,11 @@ const char *msgid;
|
||||
nelems = (int) lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (nelems < 2) {
|
||||
impossible(
|
||||
"com_pager: questtext[%s][%s] in %s in not an array of strings",
|
||||
if (showerror)
|
||||
impossible(
|
||||
"com_pager: questtext[%s][%s] in %s in not an array of strings",
|
||||
section, msgid, QTEXT_FILE);
|
||||
free(fallback_msgid);
|
||||
lua_close(L);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -518,6 +542,7 @@ const char *msgid;
|
||||
free(synopsis);
|
||||
}
|
||||
|
||||
free(fallback_msgid);
|
||||
free(text);
|
||||
lua_close(L);
|
||||
return TRUE;
|
||||
@@ -527,15 +552,15 @@ void
|
||||
com_pager(msgid)
|
||||
const char *msgid;
|
||||
{
|
||||
com_pager_core("common", msgid);
|
||||
com_pager_core("common", msgid, TRUE);
|
||||
}
|
||||
|
||||
void
|
||||
qt_pager(msgid)
|
||||
const char *msgid;
|
||||
{
|
||||
if (!com_pager_core(g.urole.filecode, msgid))
|
||||
com_pager_core("common", msgid);
|
||||
if (!com_pager_core(g.urole.filecode, msgid, FALSE))
|
||||
com_pager_core("common", msgid, TRUE);
|
||||
}
|
||||
|
||||
struct permonst *
|
||||
|
||||
+5
-2
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 region.c $NHDT-Date: 1573957877 2019/11/17 02:31:17 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.45 $ */
|
||||
/* NetHack 3.6 region.c $NHDT-Date: 1579655029 2020/01/22 01:03:49 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.60 $ */
|
||||
/* Copyright (c) 1996 by Jean-Christophe Collet */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1024,7 +1024,10 @@ genericptr_t p2;
|
||||
pline("%s is burning your %s!", Something,
|
||||
makeplural(body_part(LUNG)));
|
||||
You("cough and spit blood!");
|
||||
losehp(Maybe_Half_Phys(rnd(dam) + 5), "gas cloud", KILLED_BY_AN);
|
||||
dam = Maybe_Half_Phys(rnd(dam) + 5);
|
||||
if (Half_gas_damage) /* worn towel */
|
||||
dam = (dam + 1) / 2;
|
||||
losehp(dam, "gas cloud", KILLED_BY_AN);
|
||||
return FALSE;
|
||||
} else {
|
||||
You("cough!");
|
||||
|
||||
+9
-5
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 role.c $NHDT-Date: 1574648943 2019/11/25 02:29:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.65 $ */
|
||||
/* NetHack 3.6 role.c $NHDT-Date: 1578947634 2020/01/13 20:33:54 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.68 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985-1999. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1047,8 +1047,8 @@ int racenum, gendnum, alignnum, pickhow;
|
||||
gendnum, alignnum)
|
||||
&& ok_gend(i, racenum,
|
||||
(gendnum >= 0) ? gendnum : ROLE_RANDOM, alignnum)
|
||||
&& ok_race(i, racenum,
|
||||
gendnum, (alignnum >= 0) ? alignnum : ROLE_RANDOM))
|
||||
&& ok_align(i, racenum,
|
||||
gendnum, (alignnum >= 0) ? alignnum : ROLE_RANDOM))
|
||||
set[roles_ok++] = i;
|
||||
}
|
||||
if (roles_ok == 0 || (roles_ok > 1 && pickhow == PICK_RIGID))
|
||||
@@ -1221,7 +1221,7 @@ int alignnum;
|
||||
/* random; check whether any selection is possible */
|
||||
for (i = 0; i < ROLE_ALIGNS; i++) {
|
||||
if (g.rfilter.mask & aligns[i].allow)
|
||||
return FALSE;
|
||||
continue;
|
||||
allow = aligns[i].allow;
|
||||
if (rolenum >= 0 && rolenum < SIZE(roles) - 1
|
||||
&& !(allow & roles[rolenum].allow & ROLE_ALIGNMASK))
|
||||
@@ -1909,9 +1909,13 @@ boolean preselect;
|
||||
add_menu(where, NO_GLYPH, &any, RS_menu_let[which], 0, ATR_NONE, buf,
|
||||
MENU_ITEMFLAGS_NONE);
|
||||
} else if (which == RS_filter) {
|
||||
char setfiltering[40];
|
||||
|
||||
any.a_int = RS_menu_arg(RS_filter);
|
||||
Sprintf(setfiltering, "%s role/race/&c filtering",
|
||||
gotrolefilter() ? "Reset" : "Set");
|
||||
add_menu(where, NO_GLYPH, &any, '~', 0, ATR_NONE,
|
||||
"Reset role/race/&c filtering", MENU_ITEMFLAGS_NONE);
|
||||
setfiltering, MENU_ITEMFLAGS_NONE);
|
||||
} else if (which == ROLE_RANDOM) {
|
||||
any.a_int = ROLE_RANDOM;
|
||||
add_menu(where, NO_GLYPH, &any, '*', 0, ATR_NONE, "Random",
|
||||
|
||||
+40
-30
@@ -1569,32 +1569,34 @@ struct mkroom *croom;
|
||||
if (o->id != -1) {
|
||||
static const char prize_warning[] = "multiple prizes on %s level";
|
||||
|
||||
/* if this is a specific item of the right type and it is being
|
||||
created on the right level, flag it as the designated item
|
||||
used to detect a special achievement (to whit, reaching and
|
||||
exploring the target level, although the exploration part
|
||||
might be short-circuited if a monster brings object to hero) */
|
||||
if (Is_mineend_level(&u.uz)) {
|
||||
if (otmp->otyp == iflags.mines_prize_type) {
|
||||
if (!g.mines_prize_count++) {
|
||||
/* Note: the first luckstone on lev will become the prize
|
||||
even if its not the explicit one, but random */
|
||||
otmp->record_achieve_special = MINES_PRIZE;
|
||||
/* prevent stacking; cleared when achievement is recorded */
|
||||
otmp->nomerge = 1;
|
||||
}
|
||||
/*
|
||||
* If this is a specific item of the right type and it is being
|
||||
* created on the right level, flag it as the designated item
|
||||
* used to detect a special achievement (to whit, reaching and
|
||||
* exploring the target level, although the exploration part
|
||||
* might be short-circuited if a monster brings object to hero).
|
||||
*
|
||||
* Random items of the appropriate type won't trigger a false
|
||||
* match--they'll fail the (id != -1) test above--but the level
|
||||
* definition should not include a second instance of any prize.
|
||||
*/
|
||||
if (Is_mineend_level(&u.uz)
|
||||
&& otmp->otyp == g.context.achieveo.mines_prize_type) {
|
||||
if (!g.context.achieveo.mines_prize_oid) {
|
||||
g.context.achieveo.mines_prize_oid = otmp->o_id;
|
||||
/* prevent stacking; cleared when achievement is recorded */
|
||||
otmp->nomerge = 1;
|
||||
} else {
|
||||
impossible(prize_warning, "mines end");
|
||||
}
|
||||
} else if (Is_sokoend_level(&u.uz)) {
|
||||
if (otmp->otyp == iflags.soko_prize_type1) {
|
||||
otmp->record_achieve_special = SOKO_PRIZE1;
|
||||
} else if (Is_sokoend_level(&u.uz)
|
||||
&& (otmp->otyp == g.context.achieveo.soko_prize_typ1
|
||||
|| otmp->otyp == g.context.achieveo.soko_prize_typ2)) {
|
||||
if (!g.context.achieveo.soko_prize_oid) {
|
||||
g.context.achieveo.soko_prize_oid = otmp->o_id;
|
||||
otmp->nomerge = 1; /* redundant; Sokoban prizes don't stack */
|
||||
if (++g.soko_prize_count > 1)
|
||||
impossible(prize_warning, "sokoban end");
|
||||
} else if (otmp->otyp == iflags.soko_prize_type2) {
|
||||
otmp->record_achieve_special = SOKO_PRIZE2;
|
||||
otmp->nomerge = 1; /* redundant; Sokoban prizes don't stack */
|
||||
if (++g.soko_prize_count > 1)
|
||||
impossible(prize_warning, "sokoban end");
|
||||
} else {
|
||||
impossible(prize_warning, "sokoban end");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2590,14 +2592,26 @@ const char *s;
|
||||
|
||||
/* find by object name */
|
||||
for (i = 0; i < NUM_OBJECTS; i++) {
|
||||
objname = obj_descr[i].oc_name;
|
||||
objname = OBJ_NAME(objects[i]);
|
||||
if (objname && !strcmpi(s, objname))
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME:
|
||||
* If the file specifies "orange potion", the actual object
|
||||
* description is just "orange" and won't match. [There's a
|
||||
* reason that wish handling is insanely complicated.] And
|
||||
* even if that gets fixed, if the file specifies "gray stone"
|
||||
* it will start matching but would always pick the first one.
|
||||
*
|
||||
* "orange potion" is an unlikely thing to have in a special
|
||||
* level description but "gray stone" is not....
|
||||
*/
|
||||
|
||||
/* find by object description */
|
||||
for (i = 0; i < NUM_OBJECTS; i++) {
|
||||
objname = obj_descr[i].oc_descr;
|
||||
objname = OBJ_DESCR(objects[i]);
|
||||
if (objname && !strcmpi(s, objname))
|
||||
return i;
|
||||
}
|
||||
@@ -5419,10 +5433,6 @@ sp_level_coder_init()
|
||||
|
||||
g.splev_init_present = FALSE;
|
||||
g.icedpools = FALSE;
|
||||
/* achievement tracking; static init would suffice except we need to
|
||||
reset if #wizmakemap is used to recreate mines' end or sokoban end;
|
||||
once either level is created, these values can be forgotten */
|
||||
g.mines_prize_count = g.soko_prize_count = 0;
|
||||
|
||||
for (tmpi = 0; tmpi <= MAX_NESTED_ROOMS; tmpi++) {
|
||||
coder->tmproomlist[tmpi] = (struct mkroom *) 0;
|
||||
|
||||
+10
-6
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 weapon.c $NHDT-Date: 1559998716 2019/06/08 12:58:36 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.70 $ */
|
||||
/* NetHack 3.6 weapon.c $NHDT-Date: 1579648295 2020/01/21 23:11:35 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.82 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -95,13 +95,17 @@ struct obj *obj;
|
||||
switch (skill) {
|
||||
case P_NONE:
|
||||
/* not a weapon or weptool: use item class name;
|
||||
override class name "food" for corpses, tins, and eggs,
|
||||
"large rock" for statues and boulders, and "tool" for towels */
|
||||
override class name for things where it sounds strange and
|
||||
for things that aren't unexpected to find being wielded:
|
||||
corpses, tins, eggs, and globs avoid "food",
|
||||
statues and boulders avoid "large rock",
|
||||
and towels and tin openers avoid "tool" */
|
||||
descr = (obj->otyp == CORPSE || obj->otyp == TIN || obj->otyp == EGG
|
||||
|| obj->otyp == STATUE || obj->otyp == BOULDER
|
||||
|| obj->otyp == TOWEL)
|
||||
? OBJ_NAME(objects[obj->otyp])
|
||||
: def_oc_syms[(int) obj->oclass].name;
|
||||
|| obj->otyp == TOWEL || obj->otyp == TIN_OPENER)
|
||||
? OBJ_NAME(objects[obj->otyp])
|
||||
: obj->globby ? "glob"
|
||||
: def_oc_syms[(int) obj->oclass].name;
|
||||
break;
|
||||
case P_SLING:
|
||||
if (is_ammo(obj))
|
||||
|
||||
+8
-1
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 worm.c $NHDT-Date: 1561340880 2019/06/24 01:48:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.30 $ */
|
||||
/* NetHack 3.6 worm.c $NHDT-Date: 1579616437 2020/01/21 14:20:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.40 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2009. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -218,6 +218,13 @@ struct monst *worm;
|
||||
seg->nseg = new_seg; /* attach it to the end of the list */
|
||||
wheads[wnum] = new_seg; /* move the end pointer */
|
||||
|
||||
/*
|
||||
* [maybe] FIXME?
|
||||
* scheduling wgrowtime[] seems to be based on normal movement
|
||||
* speed (12) but long worms move at 1/4 of that (3), so they'll
|
||||
* reach the scheduled 'moves' more quickly (in terms of their
|
||||
* actual movement) and grow faster than was probably intended.
|
||||
*/
|
||||
if (wgrowtime[wnum] <= g.moves) {
|
||||
if (!wgrowtime[wnum])
|
||||
wgrowtime[wnum] = g.moves + rnd(5);
|
||||
|
||||
Reference in New Issue
Block a user