Merge remote-tracking branch 'origin/NetHack-3.6.0'

This commit is contained in:
keni
2017-11-04 16:31:11 -04:00
43 changed files with 1481 additions and 1008 deletions
+21 -15
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 bones.c $NHDT-Date: 1503309019 2017/08/21 09:50:19 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */
/* NetHack 3.6 bones.c $NHDT-Date: 1508827591 2017/10/24 06:46:31 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.71 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985,1993. */
/* NetHack may be freely redistributed. See license for details. */
@@ -127,7 +127,7 @@ boolean restore;
otmp->spe = 1;
#endif
} else if (otmp->otyp == EGG) {
otmp->spe = 0;
otmp->spe = 0; /* not "laid by you" in next game */
} else if (otmp->otyp == TIN) {
/* make tins of unique monster's meat be empty */
if (otmp->corpsenm >= LOW_PM
@@ -136,24 +136,30 @@ boolean restore;
} else if (otmp->otyp == CORPSE || otmp->otyp == STATUE) {
int mnum = otmp->corpsenm;
/* Discard incarnation details of unique
monsters (by passing null instead of otmp
for object), shopkeepers (by passing false
for revival flag), temple priests, and
vault guards in order to prevent corpse
revival or statue reanimation. */
/* Discard incarnation details of unique monsters
(by passing null instead of otmp for object),
shopkeepers (by passing false for revival flag),
temple priests, and vault guards in order to
prevent corpse revival or statue reanimation. */
if (has_omonst(otmp)
&& cant_revive(&mnum, FALSE, (struct obj *) 0)) {
free_omonst(otmp);
/* mnum is now either human_zombie or
doppelganger; for corpses of uniques,
we need to force the transformation
now rather than wait until a revival
attempt, otherwise eating this corpse
/* mnum is now either human_zombie or doppelganger;
for corpses of uniques, we need to force the
transformation now rather than wait until a
revival attempt, otherwise eating this corpse
would behave as if it remains unique */
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 (otmp->otyp == AMULET_OF_YENDOR) {
/* no longer the real Amulet */
otmp->otyp = FAKE_AMULET_OF_YENDOR;
@@ -186,8 +192,8 @@ sanitize_name(namebuf)
char *namebuf;
{
int c;
boolean strip_8th_bit =
!strcmp(windowprocs.name, "tty") && !iflags.wc_eight_bit_input;
boolean strip_8th_bit = (!strcmp(windowprocs.name, "tty")
&& !iflags.wc_eight_bit_input);
/* it's tempting to skip this for single-user platforms, since
only the current player could have left these bones--except
+7 -5
View File
@@ -1794,7 +1794,7 @@ boolean from_configfile;
numeric = TRUE;
tmp = tmpbuf;
if (strlen(tmp) > 0) {
dt = blstats[0][fld].anytype;
dt = initblstats[fld].anytype;
if (percent)
dt = ANY_INT;
(void) s_to_anything(&hilite.value, tmp, dt);
@@ -2593,7 +2593,7 @@ int fld;
nopts++;
}
if (fld != BL_CAP && (at == ANY_INT || at == ANY_LONG || at == ANY_UINT)) {
if (fld != BL_CAP && fld != BL_HUNGER && (at == ANY_INT || at == ANY_LONG || at == ANY_UINT)) {
any = zeroany;
any.a_int = onlybeh = BL_TH_VAL_ABSOLUTE;
add_menu(tmpwin, NO_GLYPH, &any, 'n', 0, ATR_NONE,
@@ -2609,7 +2609,7 @@ int fld;
nopts++;
}
if (initblstats[fld].anytype == ANY_STR || fld == BL_CAP) {
if (initblstats[fld].anytype == ANY_STR || fld == BL_CAP || fld == BL_HUNGER) {
any = zeroany;
any.a_int = onlybeh = BL_TH_TEXTMATCH;
Sprintf(buf, "%s text match", initblstats[fld].fldname);
@@ -2878,7 +2878,7 @@ choose_value:
hilite.rel = TXT_VALUE;
Strcpy(hilite.textmatch, aligntxt[rv]);
} else if (fld == BL_HUNGER) {
const char *hutxt[] = {"Satiated", "", "Hungry", "Weak",
const char *hutxt[] = {"Satiated", (char *)0, "Hungry", "Weak",
"Fainting", "Fainted", "Starved"};
int rv = query_arrayvalue(qry_buf,
hutxt,
@@ -3163,7 +3163,9 @@ status_hilites_viewall()
datawin = create_nhwindow(NHW_TEXT);
while (hlstr) {
Sprintf(buf, "OPTIONS=hilite_status: %s", hlstr->str);
Sprintf(buf, "OPTIONS=hilite_status: %.*s",
(int)(BUFSZ - sizeof "OPTIONS=hilite_status: " - 1),
hlstr->str);
putstr(datawin, 0, buf);
hlstr = hlstr->next;
}
+2 -2
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1494985492 2017/05/17 01:44:52 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.258 $ */
/* NetHack 3.6 cmd.c $NHDT-Date: 1508880573 2017/10/24 21:29:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.275 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -3005,7 +3005,7 @@ struct ext_func_tab extcmdlist[] = {
{ '\0', "terrain", "show map without obstructions",
doterrain, IFBURIED | AUTOCOMPLETE },
{ '\0', "therecmdmenu",
"show menu of commands you can do from here to adjacent spot",
"menu of commands you can do from here to adjacent spot",
dotherecmdmenu },
{ 't', "throw", "throw something", dothrow },
{ '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
+6
View File
@@ -501,6 +501,12 @@ register struct obj *obj;
pline_The("sink backs up, leaving %s.", doname(obj));
obj->in_use = FALSE;
dropx(obj);
} else if (!rn2(5)) {
freeinv(obj);
obj->in_use = FALSE;
obj->ox = u.ux;
obj->oy = u.uy;
add_to_buried(obj);
} else
useup(obj);
}
+12 -5
View File
@@ -1086,11 +1086,18 @@ int after; /* this is extra fast monster movement */
continue;
/* lessen the chance of backtracking to previous position(s) */
k = has_edog ? uncursedcnt : cnt;
for (j = 0; j < MTSZ && j < k - 1; j++)
if (nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
if (rn2(MTSZ * (k - j)))
goto nxti;
/* This causes unintended issues for pets trying to follow
the hero. Thus, only run it if not leashed and >5 tiles
away. */
if (!mtmp->mleashed &&
distmin(mtmp->mx, mtmp->my, u.ux, u.uy) > 5) {
k = has_edog ? uncursedcnt : cnt;
for (j = 0; j < MTSZ && j < k - 1; j++)
if (nx == mtmp->mtrack[j].x &&
ny == mtmp->mtrack[j].y)
if (rn2(MTSZ * (k - j)))
goto nxti;
}
j = ((ndist = GDIST(nx, ny)) - nidist) * appr;
if ((j == 0 && !rn2(++chcnt)) || j < 0
+6 -2
View File
@@ -1274,8 +1274,11 @@ int how;
if (have_windows) {
wait_synch();
free_pickinv_cache(); /* extra persistent window if perm_invent */
if (WIN_INVEN != WIN_ERR)
if (WIN_INVEN != WIN_ERR) {
destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR;
/* precaution in case any late update_inventory() calls occur */
flags.perm_invent = 0;
}
display_nhwindow(WIN_MESSAGE, TRUE);
destroy_nhwindow(WIN_MAP), WIN_MAP = WIN_ERR;
#ifndef STATUS_HILITES
@@ -1315,7 +1318,7 @@ int how;
? (const char *) ((flags.female && urole.name.f)
? urole.name.f
: urole.name.m)
: (const char *) (flags.female ? "Demigoddess" : "Demigod"));
: (const char *) (flags.female ? "Demigoddess" : "Demigod"));
dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
dump_forward_putstr(endwin, 0, "", done_stopprint);
@@ -1350,6 +1353,7 @@ int how;
Schroedingers_cat = odds_and_ends(invent, CAT_CHECK);
if (Schroedingers_cat) {
int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]);
mhp = d(m_lev, 8);
nowrap_add(u.urexp, mhp);
Strcat(eos(pbuf), " and Schroedinger's cat");
+85 -1
View File
@@ -61,6 +61,11 @@
boolean friday_13th (void)
int night (void)
int midnight (void)
void strbuf_init (strbuf *, const char *)
void strbuf_append (strbuf *, const char *)
void strbuf_reserve (strbuf *, int)
void strbuf_empty (strbuf *)
void strbuf_nl_to_crlf (strbuf_t *)
=*/
#ifdef LINT
#define Static /* pacify lint */
@@ -183,7 +188,7 @@ char *
strip_newline(str)
char *str;
{
char *p = index(str, '\n');
char *p = rindex(str, '\n');
if (p) {
if (p > str && *(p - 1) == '\r')
@@ -1101,4 +1106,83 @@ midnight()
return (getlt()->tm_hour == 0);
}
/* strbuf_init() initializes strbuf state for use */
void
strbuf_init(strbuf)
strbuf_t *strbuf;
{
strbuf->str = NULL;
strbuf->len = 0;
}
/* strbuf_append() appends given str to strbuf->str */
void
strbuf_append(strbuf, str)
strbuf_t *strbuf;
const char *str;
{
int len = (int) strlen(str) + 1;
strbuf_reserve(strbuf,
len + (strbuf->str ? (int) strlen(strbuf->str) : 0));
Strcat(strbuf->str, str);
}
/* strbuf_reserve() ensure strbuf->str has storage for len characters */
void
strbuf_reserve(strbuf, len)
strbuf_t *strbuf;
int len;
{
if (strbuf->str == NULL) {
strbuf->str = strbuf->buf;
strbuf->str[0] = '\0';
strbuf->len = (int) sizeof strbuf->buf;
}
if (len > strbuf->len) {
char *oldbuf = strbuf->str;
strbuf->len = len + (int) sizeof strbuf->buf;
strbuf->str = (char *) alloc(strbuf->len);
Strcpy(strbuf->str, oldbuf);
if (oldbuf != strbuf->buf)
free((genericptr_t) oldbuf);
}
}
/* strbuf_empty() frees allocated memory and set strbuf to initial state */
void
strbuf_empty(strbuf)
strbuf_t *strbuf;
{
if (strbuf->str != NULL && strbuf->str != strbuf->buf)
free((genericptr_t) strbuf->str);
strbuf_init(strbuf);
}
/* strbuf_nl_to_crlf() converts all occurences of \n to \r\n */
void
strbuf_nl_to_crlf(strbuf)
strbuf_t *strbuf;
{
if (strbuf->str) {
int len = (int) strlen(strbuf->str);
int count = 0;
char *cp = strbuf->str;
while (*cp)
if (*cp++ == '\n')
count++;
if (count) {
strbuf_reserve(strbuf, len + count + 1);
for (cp = strbuf->str + len + count; count; --cp)
if ((*cp = cp[-count]) == '\n') {
*--cp = '\r';
--count;
}
}
}
}
/*hacklib.c*/
+30 -10
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1498078873 2017/06/21 21:01:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.214 $ */
/* NetHack 3.6 invent.c $NHDT-Date: 1508827592 2017/10/24 06:46:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.220 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -504,12 +504,21 @@ struct obj *obj;
}
set_artifact_intrinsic(obj, 1, W_ART);
}
if (is_mines_prize(obj) && obj->record_achieve_special) {
/* "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) */
if (is_mines_prize(obj)) {
u.uachieve.mines_luckstone = 1;
obj->record_achieve_special = 0;
} else if (is_soko_prize(obj) && obj->record_achieve_special) {
obj->record_achieve_special = NON_PM;
} else if (is_soko_prize(obj)) {
u.uachieve.finish_sokoban = 1;
obj->record_achieve_special = 0;
obj->record_achieve_special = NON_PM;
}
}
@@ -2171,6 +2180,7 @@ const char *query;
boolean want_reply;
long *out_cnt;
{
static const char not_carrying_anything[] = "Not carrying anything";
struct obj *otmp;
char ilet, ret;
char *invlet = flags.inv_order;
@@ -2217,7 +2227,7 @@ long *out_cnt;
++n;
if (n == 0) {
pline("Not carrying anything.");
pline("%s.", not_carrying_anything);
return 0;
}
@@ -2305,14 +2315,24 @@ nextclass:
goto nextclass;
}
}
if (iflags.force_invmenu && lets && want_reply) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, "Special", MENU_UNSELECTED);
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
"Special", MENU_UNSELECTED);
any.a_char = '*';
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE, "(list everything)", MENU_UNSELECTED);
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE,
"(list everything)", MENU_UNSELECTED);
}
/* for permanent inventory where we intend to show everything but
nothing has been listed (because there isn't anyhing to list;
recognized via any.a_char still being zero; the n==0 case above
gets skipped for perm_invent), put something into the menu */
if (flags.perm_invent && !lets && !any.a_char) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, 0,
not_carrying_anything, MENU_UNSELECTED);
want_reply = FALSE;
}
end_menu(win, query && *query ? query : (char *) 0);
n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected);
+2 -1
View File
@@ -279,7 +279,8 @@ register struct monst *mtmp;
if ((offer = bribe(mtmp)) >= demand) {
pline("%s vanishes, laughing about cowardly mortals.",
Amonnam(mtmp));
} else if (offer > 0L && (long) rnd(40) > (demand - offer)) {
} else if (offer > 0L
&& (long) rnd(5 * ACURR(A_CHA)) > (demand - offer)) {
pline("%s scowls at you menacingly, then vanishes.",
Amonnam(mtmp));
} else {
+31 -23
View File
@@ -223,6 +223,7 @@ boolean init, artif;
return otmp;
}
/* mkobj(): select a type of item from a class, use mksobj() to create it */
struct obj *
mkobj(oclass, artif)
char oclass;
@@ -265,10 +266,10 @@ struct obj *box;
n = 20;
break;
case CHEST:
n = 5;
n = box->olocked ? 7 : 5;
break;
case LARGE_BOX:
n = 3;
n = box->olocked ? 5 : 3;
break;
case SACK:
case OILSKIN_SACK:
@@ -277,7 +278,7 @@ struct obj *box;
n = 0;
break;
}
/*else FALLTHRU*/
/*else FALLTHRU*/
case BAG_OF_HOLDING:
n = 1;
break;
@@ -712,6 +713,7 @@ static const char dknowns[] = { WAND_CLASS, RING_CLASS, POTION_CLASS,
SCROLL_CLASS, GEM_CLASS, SPBOOK_CLASS,
WEAPON_CLASS, TOOL_CLASS, 0 };
/* mksobj(): create a specific type of object */
struct obj *
mksobj(otyp, init, artif)
int otyp;
@@ -743,7 +745,7 @@ boolean artif;
otmp->cknown = 0;
otmp->corpsenm = NON_PM;
if (init)
if (init) {
switch (let) {
case WEAPON_CLASS:
otmp->quan = is_multigen(otmp) ? (long) rn1(6, 6) : 1L;
@@ -773,9 +775,8 @@ boolean artif;
&& (--tryct > 0));
if (tryct == 0) {
/* perhaps rndmonnum() only wants to make G_NOCORPSE
monsters on
this level; let's create an adventurer's corpse
instead, then */
monsters on this level; create an adventurer's
corpse instead, then */
otmp->corpsenm = PM_HUMAN;
}
/* timer set below */
@@ -889,14 +890,13 @@ boolean artif;
case BAG_OF_TRICKS:
otmp->spe = rnd(20);
break;
case FIGURINE: {
int tryct2 = 0;
case FIGURINE:
tryct = 0;
do
otmp->corpsenm = rndmonnum();
while (is_human(&mons[otmp->corpsenm]) && tryct2++ < 30);
while (is_human(&mons[otmp->corpsenm]) && tryct++ < 30);
blessorcurse(otmp, 4);
break;
}
case BELL_OF_OPENING:
otmp->spe = 3;
break;
@@ -918,15 +918,12 @@ boolean artif;
curse(otmp);
} else
blessorcurse(otmp, 10);
break;
case VENOM_CLASS:
case CHAIN_CLASS:
case BALL_CLASS:
break;
case POTION_CLASS:
otmp->fromsink = 0;
if (otmp->otyp == POT_OIL)
otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
/* fall through */
case POTION_CLASS: /* note: potions get some additional init below */
case SCROLL_CLASS:
#ifdef MAIL
if (otmp->otyp != SCR_MAIL)
@@ -1012,27 +1009,36 @@ boolean artif;
objects[otmp->otyp].oc_class);
return (struct obj *) 0;
}
}
/* some things must get done (corpsenm, timers) even if init = 0 */
switch (otmp->otyp) {
switch ((otmp->oclass == POTION_CLASS && otmp->otyp != POT_OIL)
? POT_WATER
: otmp->otyp) {
case CORPSE:
if (otmp->corpsenm == NON_PM) {
otmp->corpsenm = undead_to_corpse(rndmonnum());
if (mvitals[otmp->corpsenm].mvflags & (G_NOCORPSE | G_GONE))
otmp->corpsenm = urole.malenum;
}
/*FALLTHRU*/
/*FALLTHRU*/
case STATUE:
case FIGURINE:
if (otmp->corpsenm == NON_PM)
otmp->corpsenm = rndmonnum();
/*FALLTHRU*/
/*FALLTHRU*/
case EGG:
/* case TIN: */
/* case TIN: */
set_corpsenm(otmp, otmp->corpsenm);
break;
case POT_OIL:
otmp->age = MAX_OIL_IN_FLASK; /* amount of oil */
/*FALLTHRU*/
case POT_WATER: /* POTION_CLASS */
otmp->fromsink = 0; /* overloads corpsenm, which was set to NON_PM */
break;
case LEASH:
otmp->leashmon = 0;
otmp->leashmon = 0; /* overloads corpsenm, which was set to NON_PM */
break;
case SPE_NOVEL:
otmp->novelidx = -1; /* "none of the above"; will be changed */
@@ -1412,8 +1418,10 @@ int x, y;
{
register struct obj *gold = g_at(x, y);
if (amount <= 0L)
amount = (long) (1 + rnd(level_difficulty() + 2) * rnd(30));
if (amount <= 0L) {
long mul = rnd(30 / max(12-depth(&u.uz), 2));
amount = (long) (1 + rnd(level_difficulty() + 2) * mul);
}
if (gold) {
gold->quan += amount;
} else {
+7 -2
View File
@@ -2787,8 +2787,13 @@ wake_nearby()
mtmp->msleeping = 0;
if (!unique_corpstat(mtmp->data))
mtmp->mstrategy &= ~STRAT_WAITMASK;
if (mtmp->mtame && !mtmp->isminion)
EDOG(mtmp)->whistletime = moves;
if (mtmp->mtame) {
if (!mtmp->isminion)
EDOG(mtmp)->whistletime = moves;
/* Clear mtrack. This is to fix up a pet who is
stuck "fleeing" its master. */
memset(mtmp->mtrack, 0, sizeof(mtmp->mtrack));
}
}
}
}
+2 -2
View File
@@ -1878,9 +1878,9 @@ struct permonst _mons2[] = {
| M2_MALE | M2_MAGIC | M2_SHAPESHIFTER,
M3_INFRAVISIBLE, HI_ZAP),
#endif
MON("Vlad the Impaler", S_VAMPIRE, LVL(14, 18, -3, 80, -10),
MON("Vlad the Impaler", S_VAMPIRE, LVL(28, 26, -6, 80, -10),
(G_NOGEN | G_NOCORPSE | G_UNIQ),
A(ATTK(AT_WEAP, AD_PHYS, 1, 10), ATTK(AT_BITE, AD_DRLI, 1, 10),
A(ATTK(AT_WEAP, AD_PHYS, 2, 10), ATTK(AT_BITE, AD_DRLI, 1, 12),
NO_ATTK, NO_ATTK, NO_ATTK, NO_ATTK),
SIZ(WT_HUMAN, 400, MS_VAMPIRE, MZ_HUMAN), MR_SLEEP | MR_POISON, 0,
M1_FLY | M1_BREATHLESS | M1_HUMANOID | M1_POIS | M1_REGEN,
+8 -1
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1507846854 2017/10/12 22:20:54 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.315 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1508827592 2017/10/24 06:46:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.316 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
@@ -724,6 +724,12 @@ initoptions_init()
iflags.travelcc.x = iflags.travelcc.y = -1;
/* 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;
/* assert( sizeof flags.inv_order == sizeof def_inv_order ); */
(void) memcpy((genericptr_t) flags.inv_order,
(genericptr_t) def_inv_order, sizeof flags.inv_order);
@@ -5108,6 +5114,7 @@ boolean setinitial, setfromfile;
assign_graphics(ROGUESET);
} else if (!rogueflag)
assign_graphics(PRIMARY);
preference_update("symset");
need_redraw = TRUE;
return TRUE;
+1 -1
View File
@@ -195,7 +195,7 @@ struct obj **obj_p;
glyph among floor and buried objects; when !Blind, any buried
object's glyph will have been replaced by whatever is present
on the surface as soon as we moved next to its spot */
&& otmp->where == OBJ_FLOOR /* not buried */
&& (fakeobj || otmp->where == OBJ_FLOOR) /* not buried */
/* terrain mode views what's already known, doesn't learn new stuff */
&& !iflags.terrainmode) /* so don't set dknown when in terrain mode */
otmp->dknown = 1; /* if a pile, clearly see the top item only */
+2 -2
View File
@@ -1714,7 +1714,7 @@ plnamesuffix()
do {
if (!*plname)
askname(); /* fill plname[] if necessary */
askname(); /* fill plname[] if necessary, or set defer_plname */
/* Look for tokens delimited by '-' */
if ((eptr = index(plname, '-')) != (char *) 0)
@@ -1735,7 +1735,7 @@ plnamesuffix()
else if ((i = str2align(sptr)) != ROLE_NONE)
flags.initalign = i;
}
} while (!*plname);
} while (!*plname && !iflags.defer_plname);
/* commas in the plname confuse the record file, convert to spaces */
for (sptr = plname; *sptr; sptr++) {
+46 -13
View File
@@ -1,4 +1,4 @@
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1449269920 2015/12/04 22:58:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.77 $ */
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1508879840 2017/10/24 21:17:20 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.90 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -198,13 +198,14 @@ static NEARDATA char xsize, ysize;
char *lev_message = 0;
lev_region *lregions = 0;
int num_lregions = 0;
boolean splev_init_present = FALSE;
boolean icedpools = FALSE;
struct obj *container_obj[MAX_CONTAINMENT];
int container_idx = 0;
static boolean splev_init_present = FALSE;
static boolean icedpools = FALSE;
static int mines_prize_count = 0, soko_prize_count = 0; /* achievements */
struct monst *invent_carrying_monster = NULL;
static struct obj *container_obj[MAX_CONTAINMENT];
static int container_idx = 0;
static struct monst *invent_carrying_monster = NULL;
#define SPLEV_STACK_RESERVE 128
@@ -1881,6 +1882,7 @@ struct mkroom *croom;
}
} else {
struct obj *cobj = container_obj[container_idx - 1];
remove_object(otmp);
if (cobj) {
(void) add_to_container(cobj, otmp);
@@ -1941,12 +1943,31 @@ struct mkroom *croom;
}
}
/* Nasty hack here: try to determine if this is the Mines or Sokoban
* "prize" and then set record_achieve_special (maps to corpsenm)
* for the object. That field will later be checked to find out if
* the player obtained the prize. */
if (is_mines_prize(otmp) || is_soko_prize(otmp)) {
otmp->record_achieve_special = 1;
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) {
otmp->record_achieve_special = MINES_PRIZE;
if (++mines_prize_count > 1)
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;
if (++soko_prize_count > 1)
impossible(prize_warning, "sokoban end");
} else if (otmp->otyp == iflags.soko_prize_type2) {
otmp->record_achieve_special = SOKO_PRIZE2;
if (++soko_prize_count > 1)
impossible(prize_warning, "sokoban end");
}
}
}
stackobj(otmp);
@@ -4176,6 +4197,13 @@ genericptr_t arg;
if (typ < D_CLOSED)
typ = D_CLOSED;
}
if (((isok(x-1,y) && IS_DOORJOIN(levl[x-1][y].typ)) || !isok(x-1,y))
|| (isok(x+1,y) && IS_DOORJOIN(levl[x+1][y].typ)) || !isok(x+1,y))
levl[x][y].horizontal = 1;
else
levl[x][y].horizontal = 0;
levl[x][y].doormask = typ;
SpLev_Map[x][y] = 1;
}
@@ -5186,7 +5214,7 @@ sp_lev *lvl;
long room_stack = 0;
unsigned long max_execution = SPCODER_MAX_RUNTIME;
struct sp_coder *coder =
(struct sp_coder *) alloc(sizeof(struct sp_coder));
(struct sp_coder *) alloc(sizeof (struct sp_coder));
coder->frame = frame_new(0);
coder->stack = NULL;
@@ -5200,9 +5228,14 @@ sp_lev *lvl;
splev_init_present = FALSE;
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 */
mines_prize_count = soko_prize_count = 0;
if (wizard) {
char *met = nh_getenv("SPCODER_MAX_RUNTIME");
if (met && met[0] == '1')
max_execution = (1 << 30) - 1;
}