Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
+21
-15
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user