Merge branch 'NetHack-3.6.2'
This commit is contained in:
+3
-4
@@ -599,8 +599,7 @@ drag:
|
||||
|| !is_pool(uball->ox, uball->oy)
|
||||
|| levl[uball->ox][uball->oy].typ == POOL))
|
||||
|| ((t = t_at(uchain->ox, uchain->oy))
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT || t->ttyp == HOLE
|
||||
|| t->ttyp == TRAPDOOR))) {
|
||||
&& (is_pit(t->ttyp) || is_hole(t->ttyp)))) {
|
||||
if (Levitation) {
|
||||
You_feel("a tug from the iron ball.");
|
||||
if (t)
|
||||
@@ -745,8 +744,8 @@ xchar x, y;
|
||||
if (!Levitation && !MON_AT(x, y) && !u.utrap
|
||||
&& (is_pool(x, y)
|
||||
|| ((t = t_at(x, y))
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT
|
||||
|| t->ttyp == TRAPDOOR || t->ttyp == HOLE)))) {
|
||||
&& (is_pit(t->ttyp)
|
||||
|| is_hole(t->ttyp))))) {
|
||||
u.ux = x;
|
||||
u.uy = y;
|
||||
} else {
|
||||
|
||||
@@ -57,6 +57,7 @@ NEARDATA char pl_fruit[PL_FSIZ] = DUMMY;
|
||||
NEARDATA struct fruit *ffruit = (struct fruit *) 0;
|
||||
|
||||
NEARDATA char tune[6] = DUMMY;
|
||||
NEARDATA boolean ransacked = 0;
|
||||
|
||||
const char *occtxt = DUMMY;
|
||||
const char quitchars[] = " \r\n\033";
|
||||
|
||||
@@ -312,8 +312,7 @@ dig(VOID_ARGS)
|
||||
}
|
||||
|
||||
if (context.digging.effort <= 50
|
||||
|| (ttmp && (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == PIT
|
||||
|| ttmp->ttyp == SPIKED_PIT))) {
|
||||
|| (ttmp && (ttmp->ttyp == TRAPDOOR || is_pit(ttmp->ttyp)))) {
|
||||
return 1;
|
||||
} else if (ttmp && (ttmp->ttyp == LANDMINE
|
||||
|| (ttmp->ttyp == BEAR_TRAP && !u.utrap))) {
|
||||
@@ -803,7 +802,7 @@ coord *cc;
|
||||
}
|
||||
|
||||
} else if ((boulder_here = sobj_at(BOULDER, dig_x, dig_y)) != 0) {
|
||||
if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)
|
||||
if (ttmp && is_pit(ttmp->ttyp)
|
||||
&& rn2(2)) {
|
||||
pline_The("boulder settles into the %spit.",
|
||||
(dig_x != u.ux || dig_y != u.uy) ? "adjacent " : "");
|
||||
@@ -1087,7 +1086,7 @@ struct obj *obj;
|
||||
KILLED_BY);
|
||||
} else if (u.utrap && u.utraptype == TT_PIT && trap
|
||||
&& (trap_with_u = t_at(u.ux, u.uy))
|
||||
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
|
||||
&& is_pit(trap->ttyp)
|
||||
&& !conjoined_pits(trap, trap_with_u, FALSE)) {
|
||||
int idx;
|
||||
|
||||
@@ -1462,8 +1461,7 @@ zap_dig()
|
||||
struct trap *adjpit = t_at(zx, zy);
|
||||
if ((diridx < 8) && !conjoined_pits(adjpit, trap_with_u, FALSE)) {
|
||||
digdepth = 0; /* limited to the adjacent location only */
|
||||
if (!(adjpit && (adjpit->ttyp == PIT
|
||||
|| adjpit->ttyp == SPIKED_PIT))) {
|
||||
if (!(adjpit && is_pit(adjpit->ttyp))) {
|
||||
char buf[BUFSZ];
|
||||
cc.x = zx;
|
||||
cc.y = zy;
|
||||
@@ -1477,7 +1475,7 @@ zap_dig()
|
||||
}
|
||||
}
|
||||
if (adjpit
|
||||
&& (adjpit->ttyp == PIT || adjpit->ttyp == SPIKED_PIT)) {
|
||||
&& is_pit(adjpit->ttyp)) {
|
||||
int adjidx = (diridx + 4) % 8;
|
||||
trap_with_u->conjoined |= (1 << diridx);
|
||||
adjpit->conjoined |= (1 << adjidx);
|
||||
@@ -1566,7 +1564,7 @@ zap_dig()
|
||||
|
||||
if (pitflow && isok(flow_x, flow_y)) {
|
||||
struct trap *ttmp = t_at(flow_x, flow_y);
|
||||
if (ttmp && (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT)) {
|
||||
if (ttmp && is_pit(ttmp->ttyp)) {
|
||||
schar filltyp = fillholetyp(ttmp->tx, ttmp->ty, TRUE);
|
||||
if (filltyp != ROOM)
|
||||
pit_flow(ttmp, filltyp);
|
||||
@@ -1681,7 +1679,7 @@ struct trap *trap;
|
||||
schar filltyp;
|
||||
{
|
||||
if (trap && (filltyp != ROOM)
|
||||
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
|
||||
&& is_pit(trap->ttyp)) {
|
||||
struct trap t;
|
||||
int idx;
|
||||
|
||||
|
||||
+1
-1
@@ -783,7 +783,7 @@ register int x, y;
|
||||
|
||||
/* if monster is in a physical trap, you see the trap too
|
||||
*/
|
||||
if (tt == BEAR_TRAP || tt == PIT || tt == SPIKED_PIT
|
||||
if (tt == BEAR_TRAP || is_pit(tt)
|
||||
|| tt == WEB) {
|
||||
trap->tseen = TRUE;
|
||||
}
|
||||
|
||||
@@ -149,8 +149,7 @@ const char *verb;
|
||||
if (obj->otyp == BOULDER && boulder_hits_pool(obj, x, y, FALSE)) {
|
||||
return TRUE;
|
||||
} else if (obj->otyp == BOULDER && (t = t_at(x, y)) != 0
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT
|
||||
|| t->ttyp == TRAPDOOR || t->ttyp == HOLE)) {
|
||||
&& (is_pit(t->ttyp) || is_hole(t->ttyp))) {
|
||||
if (((mtmp = m_at(x, y)) && mtmp->mtrapped)
|
||||
|| (u.utrap && u.ux == x && u.uy == y)) {
|
||||
if (*verb)
|
||||
@@ -956,7 +955,7 @@ dodown()
|
||||
if (trap && uteetering_at_seen_pit(trap)) {
|
||||
dotrap(trap, TOOKPLUNGE);
|
||||
return 1;
|
||||
} else if (!trap || (trap->ttyp != TRAPDOOR && trap->ttyp != HOLE)
|
||||
} else if (!trap || !is_hole(trap->ttyp)
|
||||
|| !Can_fall_thru(&u.uz) || !trap->tseen) {
|
||||
if (flags.autodig && !context.nopick && uwep && is_pick(uwep)) {
|
||||
return use_pick_axe2(uwep);
|
||||
|
||||
+45
-7
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 do_name.c $NHDT-Date: 1519420054 2018/02/23 21:07:34 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.128 $ */
|
||||
/* NetHack 3.6 do_name.c $NHDT-Date: 1537477563 2018/09/20 21:06:03 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.132 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -543,7 +543,7 @@ int cx, cy;
|
||||
|
||||
cc.x = cx;
|
||||
cc.y = cy;
|
||||
if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch)) {
|
||||
if (do_screen_description(cc, TRUE, sym, tmpbuf, &firstmatch, (struct permonst **)0)) {
|
||||
(void) coord_desc(cx, cy, tmpbuf, iflags.getpos_coords);
|
||||
custompline(SUPPRESS_HISTORY,
|
||||
"%s%s%s%s%s", firstmatch, *tmpbuf ? " " : "", tmpbuf,
|
||||
@@ -593,7 +593,8 @@ int gloc;
|
||||
any.a_int = i + 1;
|
||||
tmpcc.x = garr[i].x;
|
||||
tmpcc.y = garr[i].y;
|
||||
if (do_screen_description(tmpcc, TRUE, sym, tmpbuf, &firstmatch)) {
|
||||
if (do_screen_description(tmpcc, TRUE, sym, tmpbuf,
|
||||
&firstmatch, (struct permonst **)0)) {
|
||||
(void) coord_desc(garr[i].x, garr[i].y, tmpbuf,
|
||||
iflags.getpos_coords);
|
||||
Sprintf(fullbuf, "%s%s%s", firstmatch,
|
||||
@@ -1699,10 +1700,7 @@ boolean called;
|
||||
if (do_saddle && (mtmp->misc_worn_check & W_SADDLE) && !Blind
|
||||
&& !Hallucination)
|
||||
Strcat(buf, "saddled ");
|
||||
if (buf[0] != 0)
|
||||
has_adjectives = TRUE;
|
||||
else
|
||||
has_adjectives = FALSE;
|
||||
has_adjectives = (buf[0] != '\0');
|
||||
|
||||
/* Put the actual monster name or type into the buffer now */
|
||||
/* Be sure to remember whether the buffer starts with a name */
|
||||
@@ -2067,6 +2065,46 @@ char *buf;
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *
|
||||
rndorcname(s)
|
||||
char *s;
|
||||
{
|
||||
int i;
|
||||
const char *v[] = {"a", "ai", "og", "u"};
|
||||
const char *snd[] = {"gor", "gris", "un", "bane", "ruk",
|
||||
"oth","ul", "z", "thos","akh","hai"};
|
||||
int vstart = rn2(2);
|
||||
|
||||
if (s) {
|
||||
*s = '\0';
|
||||
for (i = 0; i < rn2(2) + 3; ++i) {
|
||||
vstart = 1 - vstart; /* 0 -> 1, 1 -> 0 */
|
||||
if (!rn2(30) && i > 0)
|
||||
(void) strcat(s, "-");
|
||||
(void) sprintf(eos(s), "%s", vstart ? v[rn2(SIZE(v))] :
|
||||
snd[rn2(SIZE(snd))]);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
struct monst *
|
||||
christen_orc(mtmp, gang)
|
||||
struct monst *mtmp;
|
||||
char *gang;
|
||||
{
|
||||
int sz = 0;
|
||||
char buf[BUFSZ], buf2[BUFSZ], *orcname;
|
||||
|
||||
orcname = rndorcname(buf2);
|
||||
sz = (int) (strlen(gang) + strlen(orcname) + sizeof " of " - sizeof "");
|
||||
if (gang && orcname && sz < BUFSZ) {
|
||||
Sprintf(buf, "%s of %s", upstart(orcname), upstart(gang));
|
||||
mtmp = christen_monst(mtmp, buf);
|
||||
}
|
||||
return mtmp;
|
||||
}
|
||||
|
||||
/* make sure "The Colour of Magic" remains the first entry in here */
|
||||
static const char *const sir_Terry_novels[] = {
|
||||
"The Colour of Magic", "The Light Fantastic", "Equal Rites", "Mort",
|
||||
|
||||
@@ -407,6 +407,12 @@ boolean with_you;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mtmp->mspare1 & MIGR_LEFTOVERS) != 0L) {
|
||||
/* Pick up the rest of the MIGR_TO_SPECIES objects */
|
||||
if (migrating_objs)
|
||||
deliver_obj_to_mon(mtmp, DF_ALL);
|
||||
}
|
||||
|
||||
if (xlocale && wander) {
|
||||
/* monster moved a bit; pick a nearby location */
|
||||
/* mnearto() deals w/stone, et al */
|
||||
|
||||
+48
-3
@@ -495,7 +495,7 @@ xchar x, y;
|
||||
return 0;
|
||||
|
||||
if ((trap = t_at(x, y)) != 0) {
|
||||
if (((trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) && !Passes_walls)
|
||||
if ((is_pit(trap->ttyp) && !Passes_walls)
|
||||
|| trap->ttyp == WEB) {
|
||||
if (!trap->tseen)
|
||||
find_trap(trap);
|
||||
@@ -1515,7 +1515,7 @@ boolean shop_floor_obj;
|
||||
/* boulders never fall through trap doors, but they might knock
|
||||
other things down before plugging the hole */
|
||||
if (otmp->otyp == BOULDER && ((t = t_at(x, y)) != 0)
|
||||
&& (t->ttyp == TRAPDOOR || t->ttyp == HOLE)) {
|
||||
&& is_hole(t->ttyp)) {
|
||||
if (impact)
|
||||
impact_drop(otmp, x, y, 0);
|
||||
return FALSE; /* let caller finish the drop */
|
||||
@@ -1612,6 +1612,9 @@ boolean near_hero;
|
||||
continue;
|
||||
|
||||
where = (int) (otmp->owornmask & 0x7fffL); /* destination code */
|
||||
if ((where & MIGR_TO_SPECIES) != 0)
|
||||
continue;
|
||||
|
||||
nobreak = (where & MIGR_NOBREAK) != 0;
|
||||
noscatter = (where & MIGR_WITH_HERO) != 0;
|
||||
where &= ~(MIGR_NOBREAK | MIGR_NOSCATTER);
|
||||
@@ -1667,6 +1670,48 @@ boolean near_hero;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
deliver_obj_to_mon(mtmp, deliverflags)
|
||||
struct monst *mtmp;
|
||||
unsigned long deliverflags;
|
||||
{
|
||||
struct obj *otmp, *otmp2;
|
||||
int where, cnt = 0, maxobj = 0;
|
||||
|
||||
if (deliverflags & DF_RANDOM3)
|
||||
maxobj = rn2(3) + 1;
|
||||
else if (deliverflags & DF_RANDOM2)
|
||||
maxobj = rn2(2) + 1;
|
||||
else if (deliverflags == DF_NONE)
|
||||
maxobj = 1;
|
||||
|
||||
for (otmp = migrating_objs; otmp; otmp = otmp2) {
|
||||
otmp2 = otmp->nobj;
|
||||
where = (int) (otmp->owornmask & 0x7fffL); /* destination code */
|
||||
if ((where & MIGR_TO_SPECIES) == 0)
|
||||
continue;
|
||||
|
||||
if ((mtmp->data->mflags2 & otmp->corpsenm) != 0) {
|
||||
obj_extract_self(otmp);
|
||||
otmp->owornmask = 0L;
|
||||
otmp->ox = otmp->oy = 0;
|
||||
|
||||
/* special treatment for orcs and their kind */
|
||||
if ((otmp->corpsenm & M2_ORC) != 0 && has_oname(otmp)) {
|
||||
if (!has_mname(mtmp))
|
||||
mtmp = christen_orc(mtmp, ONAME(otmp));
|
||||
free_oname(otmp);
|
||||
}
|
||||
otmp->corpsenm = 0;
|
||||
(void) add_to_minv(mtmp, otmp);
|
||||
cnt++;
|
||||
if (maxobj && cnt >= maxobj)
|
||||
break;
|
||||
/* getting here implies DF_ALL */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
otransit_msg(otmp, nodrop, num)
|
||||
register struct obj *otmp;
|
||||
@@ -1717,7 +1762,7 @@ xchar x, y;
|
||||
}
|
||||
|
||||
if (((ttmp = t_at(x, y)) != 0 && ttmp->tseen)
|
||||
&& (ttmp->ttyp == TRAPDOOR || ttmp->ttyp == HOLE)) {
|
||||
&& is_hole(ttmp->ttyp)) {
|
||||
gate_str = (ttmp->ttyp == TRAPDOOR) ? "through the trap door"
|
||||
: "through the hole";
|
||||
return MIGR_RANDOM;
|
||||
|
||||
+1
-2
@@ -744,8 +744,7 @@ int x, y;
|
||||
dotrap(ttmp, 0); /* doesn't print messages */
|
||||
} else if (ttmp->ttyp == FIRE_TRAP) {
|
||||
dotrap(ttmp, 0);
|
||||
} else if ((ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT
|
||||
|| ttmp->ttyp == HOLE || ttmp->ttyp == TRAPDOOR)
|
||||
} else if ((is_pit(ttmp->ttyp) || is_hole(ttmp->ttyp))
|
||||
&& Sokoban) {
|
||||
/* air currents overcome the recoil in Sokoban;
|
||||
when jumping, caller performs last step and enters trap */
|
||||
|
||||
@@ -1280,7 +1280,7 @@ int how;
|
||||
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;
|
||||
iflags.perm_invent = 0;
|
||||
}
|
||||
display_nhwindow(WIN_MESSAGE, TRUE);
|
||||
destroy_nhwindow(WIN_MAP), WIN_MAP = WIN_ERR;
|
||||
|
||||
+4
-5
@@ -151,8 +151,7 @@ moverock()
|
||||
|
||||
if (mtmp && !noncorporeal(mtmp->data)
|
||||
&& (!mtmp->mtrapped
|
||||
|| !(ttmp && ((ttmp->ttyp == PIT)
|
||||
|| (ttmp->ttyp == SPIKED_PIT))))) {
|
||||
|| !(ttmp && is_pit(ttmp->ttyp)))) {
|
||||
if (Blind)
|
||||
feel_location(sx, sy);
|
||||
if (canspotmon(mtmp)) {
|
||||
@@ -1205,7 +1204,7 @@ struct trap *desttrap; /* nonnull if another trap at <x,y> */
|
||||
break;
|
||||
case TT_PIT:
|
||||
if (desttrap && desttrap->tseen
|
||||
&& (desttrap->ttyp == PIT || desttrap->ttyp == SPIKED_PIT))
|
||||
&& is_pit(desttrap->ttyp))
|
||||
return TRUE; /* move into adjacent pit */
|
||||
/* try to escape; position stays same regardless of success */
|
||||
climb_pit();
|
||||
@@ -1736,7 +1735,7 @@ domove()
|
||||
u.ux = mtmp->mx, u.uy = mtmp->my; /* resume swapping positions */
|
||||
|
||||
if (mtmp->mtrapped && (trap = t_at(mtmp->mx, mtmp->my)) != 0
|
||||
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)
|
||||
&& is_pit(trap->ttyp)
|
||||
&& sobj_at(BOULDER, trap->tx, trap->ty)) {
|
||||
/* can't swap places with pet pinned in a pit by a boulder */
|
||||
u.ux = u.ux0, u.uy = u.uy0; /* didn't move after all */
|
||||
@@ -2100,7 +2099,7 @@ boolean pick;
|
||||
* If not a pit, pickup before triggering trap.
|
||||
* If pit, trigger trap before pickup.
|
||||
*/
|
||||
pit = (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT));
|
||||
pit = (trap && is_pit(trap->ttyp));
|
||||
if (pick && !pit)
|
||||
(void) pickup(1);
|
||||
|
||||
|
||||
+3
-3
@@ -2511,7 +2511,7 @@ long *out_cnt;
|
||||
if (lets && !*lets)
|
||||
lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */
|
||||
|
||||
if (flags.perm_invent && (lets || xtra_choice)) {
|
||||
if (iflags.perm_invent && (lets || xtra_choice)) {
|
||||
/* partial inventory in perm_invent setting; don't operate on
|
||||
full inventory window, use an alternate one instead; create
|
||||
the first time needed and keep it for re-use as needed later */
|
||||
@@ -2536,7 +2536,7 @@ long *out_cnt;
|
||||
* more than 1; for the last one, we don't need a precise number.
|
||||
* For perm_invent update we force 'more than 1'.
|
||||
*/
|
||||
n = (flags.perm_invent && !lets && !want_reply) ? 2
|
||||
n = (iflags.perm_invent && !lets && !want_reply) ? 2
|
||||
: lets ? (int) strlen(lets)
|
||||
: !invent ? 0 : !invent->nobj ? 1 : 2;
|
||||
/* for xtra_choice, there's another 'item' not included in initial 'n';
|
||||
@@ -2670,7 +2670,7 @@ nextclass:
|
||||
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) {
|
||||
if (iflags.perm_invent && !lets && !any.a_char) {
|
||||
any = zeroany;
|
||||
add_menu(win, NO_GLYPH, &any, 0, 0, 0,
|
||||
not_carrying_anything, MENU_UNSELECTED);
|
||||
|
||||
+5
-2
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1495237801 2017/05/19 23:50:01 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.116 $ */
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1537477761 2018/09/20 21:09:21 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.124 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1390,6 +1390,9 @@ int mmflags;
|
||||
mtmp->mstrategy |= STRAT_APPEARMSG;
|
||||
}
|
||||
|
||||
if (allow_minvent && migrating_objs)
|
||||
deliver_obj_to_mon(mtmp, DF_RANDOM2); /* in case there's waiting items */
|
||||
|
||||
if (!in_mklev)
|
||||
newsym(mtmp->mx, mtmp->my); /* make sure the mon shows up */
|
||||
|
||||
@@ -1835,7 +1838,7 @@ struct monst *mtmp, *victim;
|
||||
slightly less sexist if prepared for it...) */
|
||||
: (fem && !mtmp->female) ? "female " : "",
|
||||
ptr->mname);
|
||||
pline("%s %s %s.", Monnam(mtmp),
|
||||
pline("%s %s %s.", upstart(y_monnam(mtmp)),
|
||||
(fem != mtmp->female) ? "changes into"
|
||||
: humanoid(ptr) ? "becomes"
|
||||
: "grows up into",
|
||||
|
||||
@@ -1266,6 +1266,9 @@ register struct attack *mattk;
|
||||
mwepgone(mdef);
|
||||
otmp->owornmask = 0L;
|
||||
update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
|
||||
/* give monster a chance to wear other equipment on its next
|
||||
move instead of waiting until it picks something up */
|
||||
mdef->misc_worn_check |= I_SPECIAL;
|
||||
}
|
||||
/* add_to_minv() might free otmp [if it merges] */
|
||||
if (vis)
|
||||
|
||||
+1
-1
@@ -1744,7 +1744,7 @@ struct attack *mattk;
|
||||
|
||||
if (!engulf_target(mtmp, &youmonst))
|
||||
return 0;
|
||||
if ((t && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)))
|
||||
if ((t && is_pit(t->ttyp))
|
||||
&& sobj_at(BOULDER, u.ux, u.uy))
|
||||
return 0;
|
||||
|
||||
|
||||
+4
-6
@@ -503,8 +503,7 @@ int trap_type;
|
||||
if (trap_type || !rn2(4)) {
|
||||
rm->typ = SCORR;
|
||||
if (trap_type) {
|
||||
if ((trap_type == HOLE || trap_type == TRAPDOOR)
|
||||
&& !Can_fall_thru(&u.uz))
|
||||
if (is_hole(trap_type) && !Can_fall_thru(&u.uz))
|
||||
trap_type = ROCKTRAP;
|
||||
ttmp = maketrap(xx, yy + dy, trap_type);
|
||||
if (ttmp) {
|
||||
@@ -1345,15 +1344,14 @@ coord *tm;
|
||||
} while (kind == NO_TRAP);
|
||||
}
|
||||
|
||||
if ((kind == TRAPDOOR || kind == HOLE) && !Can_fall_thru(&u.uz))
|
||||
if (is_hole(kind) && !Can_fall_thru(&u.uz))
|
||||
kind = ROCKTRAP;
|
||||
|
||||
if (tm) {
|
||||
m = *tm;
|
||||
} else {
|
||||
register int tryct = 0;
|
||||
boolean avoid_boulder = (kind == PIT || kind == SPIKED_PIT
|
||||
|| kind == TRAPDOOR || kind == HOLE);
|
||||
boolean avoid_boulder = (is_pit(kind) || is_hole(kind));
|
||||
|
||||
do {
|
||||
if (++tryct > 200)
|
||||
@@ -1393,7 +1391,7 @@ coord *tm;
|
||||
in a pit and yet not be able to identify that the pit is there. */
|
||||
if (lvl <= (unsigned) rnd(4)
|
||||
&& kind != SQKY_BOARD && kind != RUST_TRAP
|
||||
&& kind != PIT && kind != SPIKED_PIT && kind < HOLE) {
|
||||
&& !is_pit(kind) && kind < HOLE) {
|
||||
/* Object generated by the trap; initially NULL, stays NULL if
|
||||
we fail to generate an object or if the trap doesn't
|
||||
generate objects. */
|
||||
|
||||
+151
-1
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mkmaze.c $NHDT-Date: 1518718417 2018/02/15 18:13:37 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.55 $ */
|
||||
/* NetHack 3.6 mkmaze.c $NHDT-Date: 1537477570 2018/09/20 21:06:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.61 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -30,6 +30,10 @@ STATIC_DCL boolean FDECL(put_lregion_here, (XCHAR_P, XCHAR_P, XCHAR_P,
|
||||
STATIC_DCL void NDECL(baalz_fixup);
|
||||
STATIC_DCL void NDECL(setup_waterlevel);
|
||||
STATIC_DCL void NDECL(unsetup_waterlevel);
|
||||
STATIC_DCL void FDECL(check_ransacked, (char *));
|
||||
STATIC_DCL void FDECL(migr_booty_item, (int, const char *));
|
||||
STATIC_DCL void FDECL(migrate_orc, (struct monst *, unsigned long));
|
||||
STATIC_DCL void NDECL(stolen_booty);
|
||||
|
||||
#ifdef CONWAY
|
||||
STATIC_DCL void NDECL(conway_setup);
|
||||
@@ -619,6 +623,8 @@ fixup_special()
|
||||
} else if (on_level(&u.uz, &baalzebub_level)) {
|
||||
/* custom wallify the "beetle" potion of the level */
|
||||
baalz_fixup();
|
||||
} else if (u.uz.dnum == mines_dnum && ransacked) {
|
||||
stolen_booty();
|
||||
}
|
||||
#ifdef CONWAY
|
||||
if (level.flags.conway) {
|
||||
@@ -631,6 +637,149 @@ fixup_special()
|
||||
num_lregions = 0;
|
||||
}
|
||||
|
||||
void
|
||||
check_ransacked(s)
|
||||
char *s;
|
||||
{
|
||||
/* this kludge only works as long as orctown is minetn-1 */
|
||||
ransacked = (u.uz.dnum == mines_dnum && !strcmp(s, "minetn-1"));
|
||||
}
|
||||
|
||||
#define ORC_LEADER 1
|
||||
|
||||
void
|
||||
migrate_orc(mtmp, mflags)
|
||||
struct monst *mtmp;
|
||||
unsigned long mflags;
|
||||
{
|
||||
int nlev, max_depth, cur_depth;
|
||||
d_level dest;
|
||||
|
||||
cur_depth = (int) depth(&u.uz);
|
||||
max_depth = dunlevs_in_dungeon(&u.uz) +
|
||||
(dungeons[u.uz.dnum].depth_start - 1);
|
||||
if (mflags == ORC_LEADER) {
|
||||
/* Note that the orc leader will take possession of any
|
||||
* remaining stuff not already delivered to other
|
||||
* orcs between here and the bottom of the mines.
|
||||
*/
|
||||
nlev = max_depth;
|
||||
mtmp->mspare1 = MIGR_LEFTOVERS;
|
||||
} else {
|
||||
nlev = rn2(max_depth - cur_depth) + cur_depth + 1;
|
||||
if (nlev == cur_depth)
|
||||
nlev++;
|
||||
if (nlev > max_depth)
|
||||
nlev = max_depth;
|
||||
mtmp->mspare1 = 0L;
|
||||
}
|
||||
get_level(&dest, nlev);
|
||||
migrate_to_level(mtmp, ledger_no(&dest), MIGR_RANDOM, (coord *) 0);
|
||||
}
|
||||
|
||||
void
|
||||
migr_booty_item(otyp, gang)
|
||||
int otyp;
|
||||
const char *gang;
|
||||
{
|
||||
struct obj *otmp;
|
||||
otmp = mksobj_migr_to_species(otyp, (unsigned long) M2_ORC, FALSE, FALSE);
|
||||
if (otmp && gang) {
|
||||
new_oname(otmp, strlen(gang) + 1); /* removes old name if one is present */
|
||||
Strcpy(ONAME(otmp), gang);
|
||||
if (otyp >= TRIPE_RATION && otyp <= TIN)
|
||||
otmp->quan += (long) rn2(3);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stolen_booty(VOID_ARGS)
|
||||
{
|
||||
char *gang, gang_name[BUFSZ];
|
||||
struct monst *mtmp;
|
||||
int cnt, i, otyp;
|
||||
|
||||
/*
|
||||
* --------------------------------------------------------
|
||||
* Mythos:
|
||||
*
|
||||
* A tragic accident has occurred in Frontier Town...
|
||||
* It has been overrun by orcs.
|
||||
*
|
||||
* The booty that the orcs took from the town is now
|
||||
* in the possession of the orcs that did this and
|
||||
* have long since fled the level.
|
||||
* --------------------------------------------------------
|
||||
*/
|
||||
|
||||
gang = rndorcname(gang_name);
|
||||
/* create the leader of the orc gang */
|
||||
mtmp = makemon(&mons[PM_ORC_CAPTAIN], 0, 0, MM_NONAME);
|
||||
if (mtmp) {
|
||||
mtmp = christen_monst(mtmp, upstart(gang));
|
||||
mtmp->mpeaceful = 0;
|
||||
migrate_orc(mtmp, ORC_LEADER);
|
||||
}
|
||||
/* create the stuff that the rest of the gang took */
|
||||
migr_booty_item(rn2(2) ? LONG_SWORD : SILVER_SABER, gang);
|
||||
cnt = rn2(3) + 1;
|
||||
for (i = 0; i < cnt; ++i)
|
||||
migr_booty_item(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE, gang);
|
||||
cnt = rn2(2) + 1;
|
||||
for (i = 0; i < cnt; ++i)
|
||||
migr_booty_item(SKELETON_KEY, gang);
|
||||
otyp = rn2((GAUNTLETS_OF_DEXTERITY - LEATHER_GLOVES) + 1) + LEATHER_GLOVES;
|
||||
migr_booty_item(otyp, gang);
|
||||
cnt = rn2(9) + 1;
|
||||
for (i = 0; i < cnt; ++i) {
|
||||
/* Food items - but no lembas! (or some other weird things) */
|
||||
otyp = rn2((TIN - TRIPE_RATION) + 1) + TRIPE_RATION;
|
||||
if (otyp != LEMBAS_WAFER && otyp != GLOB_OF_GRAY_OOZE &&
|
||||
otyp != GLOB_OF_BROWN_PUDDING && otyp != GLOB_OF_GREEN_SLIME &&
|
||||
otyp != GLOB_OF_BLACK_PUDDING && otyp != MEAT_STICK &&
|
||||
otyp != MEATBALL && otyp != MEAT_STICK && otyp != MEAT_RING &&
|
||||
otyp != HUGE_CHUNK_OF_MEAT && otyp != CORPSE)
|
||||
migr_booty_item(otyp, gang);
|
||||
}
|
||||
/* Make most of the orcs on the level be part of the invading gang */
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp))
|
||||
continue;
|
||||
|
||||
if (is_orc(mtmp->data) && !has_mname(mtmp) && rn2(10)) {
|
||||
/*
|
||||
* We'll consider the orc captain from the level
|
||||
* .des file to be the captain of a rival orc horde
|
||||
* who is there to see what has transpired, and to
|
||||
* contemplate future action.
|
||||
*
|
||||
* Don't christen the orc captain as a subordinate
|
||||
* member of the main orc horde.
|
||||
*/
|
||||
if (mtmp->data != &mons[PM_ORC_CAPTAIN])
|
||||
mtmp = christen_orc(mtmp, upstart(gang));
|
||||
}
|
||||
}
|
||||
/* Lastly, ensure there's several more orcs from the gang along the way.
|
||||
* The mechanics are such that they aren't actually identified as
|
||||
* members of the invading gang until they get their spoils assigned
|
||||
* to the inventory; handled during that assignment.
|
||||
*/
|
||||
cnt = rn2(7) + 5;
|
||||
for (i = 0; i < cnt; ++i) {
|
||||
int mtyp;
|
||||
|
||||
mtyp = rn2((PM_ORC_SHAMAN - PM_ORC) + 1) + PM_ORC;
|
||||
mtmp = makemon(&mons[mtyp], 0, 0, MM_NONAME);
|
||||
if (mtmp)
|
||||
migrate_orc(mtmp, 0UL);
|
||||
}
|
||||
|
||||
ransacked = 0;
|
||||
}
|
||||
|
||||
#undef ORC_LEADER
|
||||
|
||||
boolean
|
||||
maze_inbounds(x, y)
|
||||
int x, y;
|
||||
@@ -833,6 +982,7 @@ const char *s;
|
||||
}
|
||||
|
||||
if (*protofile) {
|
||||
check_ransacked(protofile);
|
||||
Strcat(protofile, LEV_EXT);
|
||||
if (load_special(protofile)) {
|
||||
/* some levels can end up with monsters
|
||||
|
||||
+17
@@ -224,6 +224,23 @@ boolean init, artif;
|
||||
return otmp;
|
||||
}
|
||||
|
||||
struct obj *
|
||||
mksobj_migr_to_species(otyp, mflags2, init, artif)
|
||||
int otyp;
|
||||
unsigned mflags2;
|
||||
boolean init, artif;
|
||||
{
|
||||
struct obj *otmp;
|
||||
|
||||
otmp = mksobj(otyp, init, artif);
|
||||
if (otmp) {
|
||||
add_to_migration(otmp);
|
||||
otmp->owornmask = (long) MIGR_TO_SPECIES;
|
||||
otmp->corpsenm = mflags2;
|
||||
}
|
||||
return otmp;
|
||||
}
|
||||
|
||||
/* mkobj(): select a type of item from a class, use mksobj() to create it */
|
||||
struct obj *
|
||||
mkobj(oclass, artif)
|
||||
|
||||
@@ -731,6 +731,17 @@ movemon()
|
||||
if (minliquid(mtmp))
|
||||
continue;
|
||||
|
||||
/* after losing equipment, try to put on replacement */
|
||||
if (mtmp->misc_worn_check & I_SPECIAL) {
|
||||
long oldworn;
|
||||
|
||||
mtmp->misc_worn_check &= ~I_SPECIAL;
|
||||
oldworn = mtmp->misc_worn_check;
|
||||
m_dowear(mtmp, FALSE);
|
||||
if (mtmp->misc_worn_check != oldworn || !mtmp->mcanmove)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_hider(mtmp->data)) {
|
||||
/* unwatched mimics and piercers may hide again [MRS] */
|
||||
if (restrap(mtmp))
|
||||
@@ -1435,8 +1446,7 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
|
||||
if ((ttmp->ttyp != RUST_TRAP
|
||||
|| mdat == &mons[PM_IRON_GOLEM])
|
||||
&& ttmp->ttyp != STATUE_TRAP
|
||||
&& ((ttmp->ttyp != PIT && ttmp->ttyp != SPIKED_PIT
|
||||
&& ttmp->ttyp != TRAPDOOR && ttmp->ttyp != HOLE)
|
||||
&& ((!is_pit(ttmp->ttyp) && !is_hole(ttmp->ttyp))
|
||||
|| (!is_flyer(mdat) && !is_floater(mdat)
|
||||
&& !is_clinger(mdat)) || Sokoban)
|
||||
&& (ttmp->ttyp != SLP_GAS_TRAP || !resists_sleep(mon))
|
||||
@@ -1796,6 +1806,8 @@ struct monst *mtmp;
|
||||
pline_The("medallion crumbles to dust!");
|
||||
}
|
||||
m_useup(mtmp, lifesave);
|
||||
/* equip replacement amulet, if any, on next move */
|
||||
mtmp->misc_worn_check |= I_SPECIAL;
|
||||
|
||||
surviver = !(mvitals[monsndx(mtmp->data)].mvflags & G_GENOD);
|
||||
mtmp->mcanmove = 1;
|
||||
@@ -1806,13 +1818,14 @@ struct monst *mtmp;
|
||||
if (mtmp->mhpmax <= 0)
|
||||
mtmp->mhpmax = 10;
|
||||
mtmp->mhp = mtmp->mhpmax;
|
||||
if (surviver)
|
||||
return;
|
||||
|
||||
/* genocided monster can't be life-saved */
|
||||
if (cansee(mtmp->mx, mtmp->my))
|
||||
pline("Unfortunately, %s is still genocided...", mon_nam(mtmp));
|
||||
mtmp->mhp = 0;
|
||||
if (!surviver) {
|
||||
/* genocided monster can't be life-saved */
|
||||
if (cansee(mtmp->mx, mtmp->my))
|
||||
pline("Unfortunately, %s is still genocided...",
|
||||
mon_nam(mtmp));
|
||||
mtmp->mhp = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2242,7 +2255,7 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
|
||||
}
|
||||
|
||||
if (mtmp->mtrapped && (t = t_at(x, y)) != 0
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
|
||||
&& is_pit(t->ttyp)) {
|
||||
if (sobj_at(BOULDER, x, y))
|
||||
nocorpse = TRUE; /* Prevent corpses/treasure being created
|
||||
"on top" of boulder that is about to fall in.
|
||||
@@ -2887,7 +2900,8 @@ restartcham()
|
||||
for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
|
||||
if (DEADMONSTER(mtmp))
|
||||
continue;
|
||||
mtmp->cham = pm_to_cham(monsndx(mtmp->data));
|
||||
if (!mtmp->mcan)
|
||||
mtmp->cham = pm_to_cham(monsndx(mtmp->data));
|
||||
if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping
|
||||
&& cansee(mtmp->mx, mtmp->my)) {
|
||||
set_mimic_sym(mtmp);
|
||||
@@ -2929,7 +2943,7 @@ register struct monst *mtmp;
|
||||
|| rn2(3) || mtmp == u.ustuck
|
||||
/* can't hide while trapped except in pits */
|
||||
|| (mtmp->mtrapped && (t = t_at(mtmp->mx, mtmp->my)) != 0
|
||||
&& !(t->ttyp == PIT || t->ttyp == SPIKED_PIT))
|
||||
&& !is_pit(t->ttyp))
|
||||
|| (sensemon(mtmp) && distu(mtmp->mx, mtmp->my) <= 2))
|
||||
return FALSE;
|
||||
|
||||
@@ -2957,7 +2971,7 @@ struct monst *mtmp;
|
||||
; /* can't hide if holding you or held by you */
|
||||
} else if (is_u ? (u.utrap && u.utraptype != TT_PIT)
|
||||
: (mtmp->mtrapped && (t = t_at(x, y)) != 0
|
||||
&& !(t->ttyp == PIT || t->ttyp == SPIKED_PIT))) {
|
||||
&& !is_pit(t->ttyp))) {
|
||||
; /* can't hide while stuck in a non-pit trap */
|
||||
} else if (mtmp->data->mlet == S_EEL) {
|
||||
undetected = (is_pool(x, y) && !Is_waterlevel(&u.uz));
|
||||
@@ -3404,6 +3418,13 @@ boolean msg; /* "The oldmon turns into a newmon!" */
|
||||
anomalous extinction feedback during final disclsoure */
|
||||
if (mbirth_limit(monsndx(olddata)) < MAXMONNO)
|
||||
return 0;
|
||||
/* cancelled shapechangers become uncancelled prior
|
||||
to being given a new shape */
|
||||
if (mtmp->mcan && !Protection_from_shape_changers) {
|
||||
mtmp->cham = pm_to_cham(monsndx(mtmp->data));
|
||||
if (mtmp->cham != NON_PM)
|
||||
mtmp->mcan = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
|
||||
+1
-1
@@ -126,7 +126,7 @@ int x, y;
|
||||
|
||||
if (create && !((mtmp = m_at(x, y)) != 0 && mtmp->mtrapped
|
||||
&& (t = t_at(x, y)) != 0
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT))) {
|
||||
&& is_pit(t->ttyp))) {
|
||||
int objgone = 0;
|
||||
|
||||
if (down_gate(x, y) != -1)
|
||||
|
||||
+2
-2
@@ -439,7 +439,7 @@ struct monst *mtmp;
|
||||
|| onscary(xx, yy, mtmp))
|
||||
continue;
|
||||
/* use trap if it's the correct type */
|
||||
if ((t->ttyp == TRAPDOOR || t->ttyp == HOLE)
|
||||
if (is_hole(t->ttyp)
|
||||
&& !is_floater(mtmp->data)
|
||||
&& !mtmp->isshk && !mtmp->isgd && !mtmp->ispriest
|
||||
&& Can_fall_thru(&u.uz)) {
|
||||
@@ -489,7 +489,7 @@ struct monst *mtmp;
|
||||
|
||||
/* kludge to cut down on trap destruction (particularly portals) */
|
||||
t = t_at(x, y);
|
||||
if (t && (t->ttyp == PIT || t->ttyp == SPIKED_PIT || t->ttyp == WEB
|
||||
if (t && (is_pit(t->ttyp) || t->ttyp == WEB
|
||||
|| t->ttyp == BEAR_TRAP))
|
||||
t = 0; /* ok for monster to dig here */
|
||||
|
||||
|
||||
+1
-1
@@ -249,7 +249,7 @@ int force;
|
||||
unsigned tu_pit = 0;
|
||||
|
||||
if (trap_at_u)
|
||||
tu_pit = (trap_at_u->ttyp == PIT || trap_at_u->ttyp == SPIKED_PIT);
|
||||
tu_pit = is_pit(trap_at_u->ttyp);
|
||||
start_x = u.ux - (force * 2);
|
||||
start_y = u.uy - (force * 2);
|
||||
end_x = u.ux + (force * 2);
|
||||
|
||||
+1
-1
@@ -368,7 +368,7 @@ HELM("helm of telepathy", "visored helmet",
|
||||
* There is code in obj.h, objnam.c, mon.c, read.c that assumes (2).
|
||||
* (1) The dragon scale mails and the dragon scales are together.
|
||||
* (2) That the order of the dragon scale mail and dragon scales
|
||||
* is the the same as order of dragons defined in monst.c.
|
||||
* is the same as order of dragons defined in monst.c.
|
||||
*/
|
||||
#define DRGN_ARMR(name,mgc,power,cost,ac,color) \
|
||||
ARMOR(name, None, 1, mgc, 1, power, 0, 5, 40, \
|
||||
|
||||
+7
-2
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 objnam.c $NHDT-Date: 1533352036 2018/08/04 03:07:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.206 $ */
|
||||
/* NetHack 3.6 objnam.c $NHDT-Date: 1537313446 2018/09/18 23:30:46 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.208 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2011. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -3204,6 +3204,11 @@ struct obj *no_wish;
|
||||
typ = SPE_BLANK_PAPER;
|
||||
goto typfnd;
|
||||
}
|
||||
/* specific food rather than color of gem/potion/spellbook[/scales] */
|
||||
if (!BSTRCMPI(bp, p - 6, "orange") && mntmp == NON_PM) {
|
||||
typ = ORANGE;
|
||||
goto typfnd;
|
||||
}
|
||||
/*
|
||||
* NOTE: Gold pieces are handled as objects nowadays, and therefore
|
||||
* this section should probably be reconsidered as well as the entire
|
||||
@@ -3508,7 +3513,7 @@ wiztrap:
|
||||
if (strncmpi(tname, bp, strlen(tname)))
|
||||
continue;
|
||||
/* found it; avoid stupid mistakes */
|
||||
if ((trap == TRAPDOOR || trap == HOLE) && !Can_fall_thru(&u.uz))
|
||||
if (is_hole(trap) && !Can_fall_thru(&u.uz))
|
||||
trap = ROCKTRAP;
|
||||
if ((t = maketrap(x, y, trap)) != 0) {
|
||||
trap = t->ttyp;
|
||||
|
||||
+2
-1
@@ -173,7 +173,8 @@ static struct Bool_Opt {
|
||||
#else
|
||||
{ "page_wait", (boolean *) 0, FALSE, SET_IN_FILE },
|
||||
#endif
|
||||
{ "perm_invent", &flags.perm_invent, FALSE, SET_IN_GAME },
|
||||
/* 3.6.2: move perm_invent from flags to inflags and out of save file */
|
||||
{ "perm_invent", &iflags.perm_invent, FALSE, SET_IN_GAME },
|
||||
{ "pickup_thrown", &flags.pickup_thrown, TRUE, SET_IN_GAME },
|
||||
{ "popup_dialog", &iflags.wc_popup_dialog, FALSE, SET_IN_GAME }, /*WC*/
|
||||
{ "preload_tiles", &iflags.wc_preload_tiles, TRUE, DISP_IN_GAME }, /*WC*/
|
||||
|
||||
+90
-16
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pager.c $NHDT-Date: 1523142395 2018/04/07 23:06:35 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.123 $ */
|
||||
/* NetHack 3.6 pager.c $NHDT-Date: 1537477571 2018/09/20 21:06:11 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.129 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -16,8 +16,9 @@ STATIC_DCL void FDECL(look_at_monster, (char *, char *,
|
||||
struct monst *, int, int));
|
||||
STATIC_DCL struct permonst *FDECL(lookat, (int, int, char *, char *));
|
||||
STATIC_DCL void FDECL(checkfile, (char *, struct permonst *,
|
||||
BOOLEAN_P, BOOLEAN_P));
|
||||
BOOLEAN_P, BOOLEAN_P, char *));
|
||||
STATIC_DCL void FDECL(look_all, (BOOLEAN_P,BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(do_supplemental_info, (char *, struct permonst *,BOOLEAN_P));
|
||||
STATIC_DCL void NDECL(whatdoes_help);
|
||||
STATIC_DCL void NDECL(docontact);
|
||||
STATIC_DCL void NDECL(dispfile_help);
|
||||
@@ -279,7 +280,7 @@ int x, y;
|
||||
int tt = t ? t->ttyp : NO_TRAP;
|
||||
|
||||
/* newsym lets you know of the trap, so mention it here */
|
||||
if (tt == BEAR_TRAP || tt == PIT || tt == SPIKED_PIT || tt == WEB)
|
||||
if (tt == BEAR_TRAP || is_pit(tt) || tt == WEB)
|
||||
Sprintf(eos(buf), ", trapped in %s",
|
||||
an(defsyms[trap_to_defsym(tt)].explanation));
|
||||
}
|
||||
@@ -509,10 +510,11 @@ char *buf, *monbuf;
|
||||
* Therefore, we create a copy of inp _just_ for data.base lookup.
|
||||
*/
|
||||
STATIC_OVL void
|
||||
checkfile(inp, pm, user_typed_name, without_asking)
|
||||
checkfile(inp, pm, user_typed_name, without_asking, supplemental_name)
|
||||
char *inp;
|
||||
struct permonst *pm;
|
||||
boolean user_typed_name, without_asking;
|
||||
char *supplemental_name;
|
||||
{
|
||||
dlb *fp;
|
||||
char buf[BUFSZ], newstr[BUFSZ], givenname[BUFSZ];
|
||||
@@ -619,7 +621,7 @@ boolean user_typed_name, without_asking;
|
||||
int chk_skip, pass = 1;
|
||||
boolean yes_to_moreinfo, found_in_file, pass1found_in_file,
|
||||
skipping_entry;
|
||||
char *ap, *alt = 0; /* alternate description */
|
||||
char *sp, *ap, *alt = 0; /* alternate description */
|
||||
|
||||
/* adjust the input to remove "named " and "called " */
|
||||
if ((ep = strstri(dbase_str, " named ")) != 0) {
|
||||
@@ -629,6 +631,8 @@ boolean user_typed_name, without_asking;
|
||||
} else if ((ep = strstri(dbase_str, " called ")) != 0) {
|
||||
copynchars(givenname, ep + 8, BUFSZ - 1);
|
||||
alt = givenname;
|
||||
if (supplemental_name && (sp = strstri(inp, " called ")) != 0)
|
||||
copynchars(supplemental_name, sp + 8, BUFSZ - 1);
|
||||
} else
|
||||
ep = strstri(dbase_str, ", ");
|
||||
if (ep && ep > dbase_str)
|
||||
@@ -760,12 +764,13 @@ boolean user_typed_name, without_asking;
|
||||
}
|
||||
|
||||
int
|
||||
do_screen_description(cc, looked, sym, out_str, firstmatch)
|
||||
do_screen_description(cc, looked, sym, out_str, firstmatch, for_supplement)
|
||||
coord cc;
|
||||
boolean looked;
|
||||
int sym;
|
||||
char *out_str;
|
||||
const char **firstmatch;
|
||||
struct permonst **for_supplement;
|
||||
{
|
||||
static const char mon_interior[] = "the interior of a monster",
|
||||
unreconnoitered[] = "unreconnoitered";
|
||||
@@ -1008,11 +1013,15 @@ const char **firstmatch;
|
||||
|
||||
didlook:
|
||||
if (looked) {
|
||||
struct permonst *pm = (struct permonst *)0;
|
||||
|
||||
if (found > 1 || need_to_look) {
|
||||
char monbuf[BUFSZ];
|
||||
char temp_buf[BUFSZ];
|
||||
|
||||
(void) lookat(cc.x, cc.y, look_buf, monbuf);
|
||||
pm = lookat(cc.x, cc.y, look_buf, monbuf);
|
||||
if (pm && for_supplement)
|
||||
*for_supplement = pm;
|
||||
*firstmatch = look_buf;
|
||||
if (*(*firstmatch)) {
|
||||
Sprintf(temp_buf, " (%s)", *firstmatch);
|
||||
@@ -1043,7 +1052,7 @@ coord *click_cc;
|
||||
boolean clicklook = (mode == 2); /* right mouse-click method */
|
||||
char out_str[BUFSZ] = DUMMY;
|
||||
const char *firstmatch = 0;
|
||||
struct permonst *pm = 0;
|
||||
struct permonst *pm = 0, *supplemental_pm = 0;
|
||||
int i = '\0', ans = 0;
|
||||
int sym; /* typed symbol or converted glyph */
|
||||
int found; /* count of matching syms found */
|
||||
@@ -1137,7 +1146,7 @@ coord *click_cc;
|
||||
break;
|
||||
}
|
||||
if (*out_str)
|
||||
checkfile(out_str, pm, TRUE, TRUE);
|
||||
checkfile(out_str, pm, TRUE, TRUE, (char *) 0);
|
||||
return 0;
|
||||
}
|
||||
case '?':
|
||||
@@ -1151,7 +1160,7 @@ coord *click_cc;
|
||||
return 0;
|
||||
|
||||
if (out_str[1]) { /* user typed in a complete string */
|
||||
checkfile(out_str, pm, TRUE, TRUE);
|
||||
checkfile(out_str, pm, TRUE, TRUE, (char *) 0);
|
||||
return 0;
|
||||
}
|
||||
sym = out_str[0];
|
||||
@@ -1204,7 +1213,7 @@ coord *click_cc;
|
||||
}
|
||||
|
||||
found = do_screen_description(cc, (from_screen || clicklook), sym,
|
||||
out_str, &firstmatch);
|
||||
out_str, &firstmatch, &supplemental_pm);
|
||||
|
||||
/* Finally, print out our explanation. */
|
||||
if (found) {
|
||||
@@ -1215,16 +1224,19 @@ coord *click_cc;
|
||||
if (found == 1 && ans != LOOK_QUICK && ans != LOOK_ONCE
|
||||
&& (ans == LOOK_VERBOSE || (flags.help && !quick))
|
||||
&& !clicklook) {
|
||||
char temp_buf[BUFSZ];
|
||||
char temp_buf[BUFSZ], supplemental_name[BUFSZ];
|
||||
|
||||
supplemental_name[0] = '\0';
|
||||
Strcpy(temp_buf, firstmatch);
|
||||
checkfile(temp_buf, pm, FALSE,
|
||||
(boolean) (ans == LOOK_VERBOSE));
|
||||
(boolean) (ans == LOOK_VERBOSE), supplemental_name);
|
||||
if (supplemental_pm)
|
||||
do_supplemental_info(supplemental_name, supplemental_pm,
|
||||
(boolean) (ans == LOOK_VERBOSE));
|
||||
}
|
||||
} else {
|
||||
pline("I've never heard of such things.");
|
||||
}
|
||||
|
||||
} while (from_screen && !quick && ans != LOOK_ONCE && !clicklook);
|
||||
|
||||
flags.verbose = save_verbose;
|
||||
@@ -1319,6 +1331,69 @@ boolean do_mons; /* True => monsters, False => objects */
|
||||
destroy_nhwindow(win);
|
||||
}
|
||||
|
||||
void
|
||||
do_supplemental_info(name, pm, without_asking)
|
||||
char *name;
|
||||
struct permonst *pm;
|
||||
boolean without_asking;
|
||||
{
|
||||
winid datawin = WIN_ERR;
|
||||
char *entrytext = name, *bp;
|
||||
char question[QBUFSZ];
|
||||
boolean yes_to_moreinfo = FALSE;
|
||||
|
||||
/*
|
||||
* Provide some info on some specific things
|
||||
* meant to support in-game mythology, and not
|
||||
* available from data.base or other sources.
|
||||
*/
|
||||
if (name && pm && is_orc(pm) &&
|
||||
(strlen(name) < (BUFSZ - 1)) &&
|
||||
(bp = strstri(name, " of ")) != 0) {
|
||||
char fullname[BUFSZ];
|
||||
|
||||
Strcpy(fullname, name);
|
||||
if (!without_asking) {
|
||||
Strcpy(question, "More info about \"");
|
||||
/* +2 => length of "\"?" */
|
||||
copynchars(eos(question), entrytext,
|
||||
(int) (sizeof question - 1 - (strlen(question) + 2)));
|
||||
Strcat(question, "\"?");
|
||||
if (yn(question) == 'y')
|
||||
yes_to_moreinfo = TRUE;
|
||||
}
|
||||
if (yes_to_moreinfo) {
|
||||
int i, subs = 0;
|
||||
char *gang = bp + 4;
|
||||
static const char *text[] = {
|
||||
"%s is a member of a marauding horde of orcs",
|
||||
"rumored to have brutally attacked and plundered the ordinarily",
|
||||
"sheltered town that is located deep within The Gnomish Mines.",
|
||||
"",
|
||||
"The members of that vicious horde proudly and defiantly acclaim",
|
||||
"their allegiance to their leader %s in their names.",
|
||||
};
|
||||
|
||||
*bp = '\0';
|
||||
datawin = create_nhwindow(NHW_MENU);
|
||||
for (i = 0; i < SIZE(text); i++) {
|
||||
char buf[BUFSZ];
|
||||
const char *txt;
|
||||
|
||||
if (strstri(text[i], "%s") != 0) {
|
||||
Sprintf(buf, text[i],
|
||||
subs++ ? gang : fullname);
|
||||
txt = buf;
|
||||
} else
|
||||
txt = text[i];
|
||||
putstr(datawin, 0, txt);
|
||||
}
|
||||
display_nhwindow(datawin, FALSE);
|
||||
destroy_nhwindow(datawin), datawin = WIN_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* the '/' command */
|
||||
int
|
||||
dowhatis()
|
||||
@@ -1362,8 +1437,7 @@ doidtrap()
|
||||
break;
|
||||
tt = trap->ttyp;
|
||||
if (u.dz) {
|
||||
if (u.dz < 0 ? (tt == TRAPDOOR || tt == HOLE)
|
||||
: tt == ROCKTRAP)
|
||||
if (u.dz < 0 ? is_hole(tt) : tt == ROCKTRAP)
|
||||
break;
|
||||
}
|
||||
tt = what_trap(tt);
|
||||
|
||||
+1
-1
@@ -921,7 +921,7 @@ aligntyp g_align;
|
||||
* - fix all of your problems;
|
||||
* - do you a gratuitous favor.
|
||||
*
|
||||
* If you make it to the the last category, you roll randomly again
|
||||
* If you make it to the last category, you roll randomly again
|
||||
* to see what they do for you.
|
||||
*
|
||||
* If your luck is at least 0, then you are guaranteed rescued from
|
||||
|
||||
+8
-4
@@ -543,9 +543,12 @@ unsigned int *stuckid, *steedid;
|
||||
/* avoid keeping permanent inventory window up to date during restore
|
||||
(setworn() calls update_inventory); attempting to include the cost
|
||||
of unpaid items before shopkeeper's bill is available is a no-no;
|
||||
named fruit names aren't accessible yet either */
|
||||
defer_perm_invent = flags.perm_invent;
|
||||
flags.perm_invent = FALSE;
|
||||
named fruit names aren't accessible yet either
|
||||
[3.6.2: moved perm_invent from flags to iflags to keep it out of
|
||||
save files; retaining the override here is simpler than trying to
|
||||
to figure out where it really belongs now] */
|
||||
defer_perm_invent = iflags.perm_invent;
|
||||
iflags.perm_invent = FALSE;
|
||||
/* wizard and discover are actually flags.debug and flags.explore;
|
||||
player might be overriding the save file values for them;
|
||||
in the discover case, we don't want to set that for a normal
|
||||
@@ -595,6 +598,7 @@ unsigned int *stuckid, *steedid;
|
||||
u.uz.dlevel = 1;
|
||||
/* revert to pre-restore option settings */
|
||||
iflags.deferred_X = FALSE;
|
||||
iflags.perm_invent = defer_perm_invent;
|
||||
flags = newgameflags;
|
||||
#ifdef SYSFLAGS
|
||||
sysflags = newgamesysflags;
|
||||
@@ -672,7 +676,7 @@ unsigned int *stuckid, *steedid;
|
||||
relink_timers(FALSE);
|
||||
relink_light_sources(FALSE);
|
||||
/* inventory display is now viable */
|
||||
flags.perm_invent = defer_perm_invent;
|
||||
iflags.perm_invent = defer_perm_invent;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
+23
-33
@@ -2662,8 +2662,7 @@ fill_empty_maze()
|
||||
maze1xy(&mm, DRY);
|
||||
trytrap = rndtrap();
|
||||
if (sobj_at(BOULDER, mm.x, mm.y))
|
||||
while (trytrap == PIT || trytrap == SPIKED_PIT
|
||||
|| trytrap == TRAPDOOR || trytrap == HOLE)
|
||||
while (is_pit(trytrap) || is_hole(trytrap))
|
||||
trytrap = rndtrap();
|
||||
(void) maketrap(mm.x, mm.y, trytrap);
|
||||
}
|
||||
@@ -3834,7 +3833,7 @@ selection_do_grow(ov, dir)
|
||||
struct opvar *ov;
|
||||
int dir;
|
||||
{
|
||||
int x, y, c;
|
||||
int x, y;
|
||||
char tmp[COLNO][ROWNO];
|
||||
|
||||
if (ov->spovartyp != SPOVAR_SEL)
|
||||
@@ -3842,40 +3841,31 @@ int dir;
|
||||
if (!ov)
|
||||
return;
|
||||
|
||||
(void) memset(tmp, 0, sizeof(tmp));
|
||||
(void) memset(tmp, 0, sizeof tmp);
|
||||
|
||||
for (x = 0; x < COLNO; x++)
|
||||
for (x = 1; x < COLNO; x++)
|
||||
for (y = 0; y < ROWNO; y++) {
|
||||
c = 0;
|
||||
if ((dir & W_WEST) && (x > 0)
|
||||
&& (selection_getpoint(x - 1, y, ov)))
|
||||
c++;
|
||||
if ((dir & (W_WEST | W_NORTH)) && (x > 0) && (y > 0)
|
||||
&& (selection_getpoint(x - 1, y - 1, ov)))
|
||||
c++;
|
||||
if ((dir & W_NORTH) && (y > 0)
|
||||
&& (selection_getpoint(x, y - 1, ov)))
|
||||
c++;
|
||||
if ((dir & (W_NORTH | W_EAST)) && (y > 0) && (x < COLNO - 1)
|
||||
&& (selection_getpoint(x + 1, y - 1, ov)))
|
||||
c++;
|
||||
if ((dir & W_EAST) && (x < COLNO - 1)
|
||||
&& (selection_getpoint(x + 1, y, ov)))
|
||||
c++;
|
||||
if ((dir & (W_EAST | W_SOUTH)) && (x < COLNO - 1)
|
||||
&& (y < ROWNO - 1) && (selection_getpoint(x + 1, y + 1, ov)))
|
||||
c++;
|
||||
if ((dir & W_SOUTH) && (y < ROWNO - 1)
|
||||
&& (selection_getpoint(x, y + 1, ov)))
|
||||
c++;
|
||||
if ((dir & (W_SOUTH | W_WEST)) && (y < ROWNO - 1) && (x > 0)
|
||||
&& (selection_getpoint(x - 1, y + 1, ov)))
|
||||
c++;
|
||||
if (c)
|
||||
/* note: dir is a mask of multiple directions, but the only
|
||||
way to specify diagonals is by including the two adjacent
|
||||
orthogonal directions, which effectively specifies three-
|
||||
way growth [WEST|NORTH => WEST plus WEST|NORTH plus NORTH] */
|
||||
if (((dir & W_WEST) && selection_getpoint(x + 1, y, ov))
|
||||
|| (((dir & (W_WEST | W_NORTH)) == (W_WEST | W_NORTH))
|
||||
&& selection_getpoint(x + 1, y + 1, ov))
|
||||
|| ((dir & W_NORTH) && selection_getpoint(x, y + 1, ov))
|
||||
|| (((dir & (W_NORTH | W_EAST)) == (W_NORTH | W_EAST))
|
||||
&& selection_getpoint(x - 1, y + 1, ov))
|
||||
|| ((dir & W_EAST) && selection_getpoint(x - 1, y, ov))
|
||||
|| (((dir & (W_EAST | W_SOUTH)) == (W_EAST | W_SOUTH))
|
||||
&& selection_getpoint(x - 1, y - 1, ov))
|
||||
|| ((dir & W_SOUTH) && selection_getpoint(x, y - 1, ov))
|
||||
|| (((dir & (W_SOUTH | W_WEST)) == (W_SOUTH | W_WEST))
|
||||
&& selection_getpoint(x + 1, y - 1, ov))) {
|
||||
tmp[x][y] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < COLNO; x++)
|
||||
for (x = 1; x < COLNO; x++)
|
||||
for (y = 0; y < ROWNO; y++)
|
||||
if (tmp[x][y])
|
||||
selection_setpoint(x, y, ov, 1);
|
||||
@@ -4501,7 +4491,7 @@ ensure_way_out()
|
||||
|
||||
while (ttmp) {
|
||||
if ((ttmp->ttyp == MAGIC_PORTAL || ttmp->ttyp == VIBRATING_SQUARE
|
||||
|| ttmp->ttyp == HOLE || ttmp->ttyp == TRAPDOOR)
|
||||
|| is_hole(ttmp->ttyp))
|
||||
&& !selection_getpoint(ttmp->tx, ttmp->ty, ov))
|
||||
selection_floodfill(ov, ttmp->tx, ttmp->ty, TRUE);
|
||||
ttmp = ttmp->ntrap;
|
||||
|
||||
+1
-1
@@ -1159,7 +1159,7 @@ int in_sight;
|
||||
d_level tolevel;
|
||||
int migrate_typ = MIGR_RANDOM;
|
||||
|
||||
if ((tt == HOLE || tt == TRAPDOOR)) {
|
||||
if (is_hole(tt)) {
|
||||
if (Is_stronghold(&u.uz)) {
|
||||
assign_level(&tolevel, &valley_level);
|
||||
} else if (Is_botlevel(&u.uz)) {
|
||||
|
||||
+64
-70
@@ -7,6 +7,15 @@
|
||||
|
||||
extern const char *const destroy_strings[][3]; /* from zap.c */
|
||||
|
||||
STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned, struct obj *,
|
||||
struct obj *));
|
||||
STATIC_DCL struct obj *FDECL(t_missile, (int, struct trap *));
|
||||
STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
|
||||
STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
|
||||
STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
|
||||
STATIC_DCL int FDECL(mkroll_launch, (struct trap *, XCHAR_P, XCHAR_P,
|
||||
SHORT_P, long));
|
||||
STATIC_DCL boolean FDECL(isclearpath, (coord *, int, SCHAR_P, SCHAR_P));
|
||||
STATIC_DCL void FDECL(dofiretrap, (struct obj *));
|
||||
STATIC_DCL void NDECL(domagictrap);
|
||||
STATIC_DCL boolean FDECL(emergency_disrobe, (boolean *));
|
||||
@@ -18,26 +27,16 @@ STATIC_DCL int FDECL(disarm_holdingtrap, (struct trap *));
|
||||
STATIC_DCL int FDECL(disarm_landmine, (struct trap *));
|
||||
STATIC_DCL int FDECL(disarm_squeaky_board, (struct trap *));
|
||||
STATIC_DCL int FDECL(disarm_shooting_trap, (struct trap *, int));
|
||||
STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
|
||||
STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
|
||||
STATIC_DCL int FDECL(try_lift, (struct monst *, struct trap *, int,
|
||||
BOOLEAN_P));
|
||||
STATIC_DCL int FDECL(help_monster_out, (struct monst *, struct trap *));
|
||||
STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
|
||||
BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(launch_drop_spot, (struct obj *, XCHAR_P, XCHAR_P));
|
||||
STATIC_DCL int FDECL(mkroll_launch, (struct trap *, XCHAR_P, XCHAR_P,
|
||||
SHORT_P, long));
|
||||
STATIC_DCL boolean FDECL(isclearpath, (coord *, int, SCHAR_P, SCHAR_P));
|
||||
STATIC_DCL char *FDECL(trapnote, (struct trap *, BOOLEAN_P));
|
||||
#if 0
|
||||
STATIC_DCL void FDECL(join_adjacent_pits, (struct trap *));
|
||||
#endif
|
||||
STATIC_DCL void FDECL(clear_conjoined_pits, (struct trap *));
|
||||
STATIC_DCL boolean FDECL(adj_nonconjoined_pit, (struct trap *));
|
||||
|
||||
STATIC_DCL int FDECL(steedintrap, (struct trap *, struct obj *));
|
||||
STATIC_DCL boolean FDECL(keep_saddle_with_steedcorpse, (unsigned,
|
||||
struct obj *,
|
||||
struct obj *));
|
||||
STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int,
|
||||
BOOLEAN_P));
|
||||
STATIC_DCL void NDECL(maybe_finish_sokoban);
|
||||
|
||||
/* mintrap() should take a flags argument, but for time being we use this */
|
||||
@@ -328,8 +327,7 @@ int x, y, typ;
|
||||
if (u.utrap && x == u.ux && y == u.uy
|
||||
&& ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP)
|
||||
|| (u.utraptype == TT_WEB && typ != WEB)
|
||||
|| (u.utraptype == TT_PIT && typ != PIT
|
||||
&& typ != SPIKED_PIT)))
|
||||
|| (u.utraptype == TT_PIT && !is_pit(typ))))
|
||||
u.utrap = 0;
|
||||
/* old <tx,ty> remain valid */
|
||||
} else if (IS_FURNITURE(lev->typ)
|
||||
@@ -407,8 +405,7 @@ int x, y, typ;
|
||||
case HOLE:
|
||||
case TRAPDOOR:
|
||||
if (*in_rooms(x, y, SHOPBASE)
|
||||
&& (typ == HOLE || typ == TRAPDOOR
|
||||
|| IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
|
||||
&& (is_hole(typ) || IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
|
||||
add_damage(x, y, /* schedule repair */
|
||||
((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
|
||||
&& !context.mon_moving)
|
||||
@@ -841,6 +838,21 @@ struct trap *trap;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* make a single arrow/dart/rock for a trap to shoot or drop */
|
||||
STATIC_OVL struct obj *
|
||||
t_missile(otyp, trap)
|
||||
int otyp;
|
||||
struct trap *trap;
|
||||
{
|
||||
struct obj *otmp = mksobj(otyp, TRUE, FALSE);
|
||||
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp->opoisoned = 0;
|
||||
otmp->ox = trap->tx, otmp->oy = trap->ty;
|
||||
return otmp;
|
||||
}
|
||||
|
||||
void
|
||||
dotrap(trap, trflags)
|
||||
register struct trap *trap;
|
||||
@@ -862,8 +874,7 @@ unsigned trflags;
|
||||
nomul(0);
|
||||
|
||||
/* KMH -- You can't escape the Sokoban level traps */
|
||||
if (Sokoban && (ttype == PIT || ttype == SPIKED_PIT
|
||||
|| ttype == HOLE || ttype == TRAPDOOR)) {
|
||||
if (Sokoban && (is_pit(ttype) || is_hole(ttype))) {
|
||||
/* The "air currents" message is still appropriate -- even when
|
||||
* the hero isn't flying or levitating -- because it conveys the
|
||||
* reason why the player cannot escape the trap with a dexterity
|
||||
@@ -875,7 +886,7 @@ unsigned trflags;
|
||||
/* then proceed to normal trap effect */
|
||||
} else if (already_seen && !forcetrap) {
|
||||
if ((Levitation || (Flying && !plunged))
|
||||
&& (ttype == PIT || ttype == SPIKED_PIT || ttype == HOLE
|
||||
&& (is_pit(ttype) || ttype == HOLE
|
||||
|| ttype == BEAR_TRAP)) {
|
||||
You("%s over %s %s.", Levitation ? "float" : "fly",
|
||||
a_your[trap->madeby_u],
|
||||
@@ -885,7 +896,7 @@ unsigned trflags;
|
||||
if (!Fumbling && ttype != MAGIC_PORTAL && ttype != VIBRATING_SQUARE
|
||||
&& ttype != ANTI_MAGIC && !forcebungle && !plunged
|
||||
&& !conj_pit && !adj_pit
|
||||
&& (!rn2(5) || ((ttype == PIT || ttype == SPIKED_PIT)
|
||||
&& (!rn2(5) || (is_pit(ttype)
|
||||
&& is_clinger(youmonst.data)))) {
|
||||
You("escape %s %s.", (ttype == ARROW_TRAP && !trap->madeby_u)
|
||||
? "an"
|
||||
@@ -914,12 +925,9 @@ unsigned trflags;
|
||||
trap->once = 1;
|
||||
seetrap(trap);
|
||||
pline("An arrow shoots out at you!");
|
||||
otmp = mksobj(ARROW, TRUE, FALSE);
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp->opoisoned = 0;
|
||||
if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
|
||||
;
|
||||
otmp = t_missile(ARROW, trap);
|
||||
if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
|
||||
; /* nothing */
|
||||
} else if (thitu(8, dmgval(otmp, &youmonst), &otmp, "arrow")) {
|
||||
if (otmp)
|
||||
obfree(otmp, (struct obj *) 0);
|
||||
@@ -942,14 +950,12 @@ unsigned trflags;
|
||||
trap->once = 1;
|
||||
seetrap(trap);
|
||||
pline("A little dart shoots out at you!");
|
||||
otmp = mksobj(DART, TRUE, FALSE);
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = t_missile(DART, trap);
|
||||
if (!rn2(6))
|
||||
otmp->opoisoned = 1;
|
||||
oldumort = u.umortality;
|
||||
if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) { /* nothing */
|
||||
;
|
||||
if (u.usteed && !rn2(2) && steedintrap(trap, otmp)) {
|
||||
; /* nothing */
|
||||
} else if (thitu(7, dmgval(otmp, &youmonst), &otmp, "little dart")) {
|
||||
if (otmp) {
|
||||
if (otmp->opoisoned)
|
||||
@@ -979,13 +985,11 @@ unsigned trflags;
|
||||
|
||||
trap->once = 1;
|
||||
feeltrap(trap);
|
||||
otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE, FALSE);
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = t_missile(ROCK, trap);
|
||||
place_object(otmp, u.ux, u.uy);
|
||||
|
||||
pline("A trap door in %s opens and %s falls on your %s!",
|
||||
the(ceiling(u.ux, u.uy)), an(xname(otmp)), body_part(HEAD));
|
||||
|
||||
if (uarmh) {
|
||||
if (is_metallic(uarmh)) {
|
||||
pline("Fortunately, you are wearing a hard helmet.");
|
||||
@@ -994,7 +998,6 @@ unsigned trflags;
|
||||
pline("%s does not protect you.", Yname2(uarmh));
|
||||
}
|
||||
}
|
||||
|
||||
if (!Blind)
|
||||
otmp->dknown = 1;
|
||||
stackobj(otmp);
|
||||
@@ -1642,7 +1645,7 @@ static struct {
|
||||
xchar x, y;
|
||||
} launchplace;
|
||||
|
||||
static void
|
||||
STATIC_OVL void
|
||||
launch_drop_spot(obj, x, y)
|
||||
struct obj *obj;
|
||||
xchar x, y;
|
||||
@@ -2075,8 +2078,8 @@ register struct monst *mtmp;
|
||||
mtmp->mtrapped = 0; /* perhaps teleported? */
|
||||
} else if (mtmp->mtrapped) { /* is currently in the trap */
|
||||
if (!trap->tseen && cansee(mtmp->mx, mtmp->my) && canseemon(mtmp)
|
||||
&& (trap->ttyp == SPIKED_PIT || trap->ttyp == BEAR_TRAP
|
||||
|| trap->ttyp == HOLE || trap->ttyp == PIT
|
||||
&& (is_pit(trap->ttyp) || trap->ttyp == BEAR_TRAP
|
||||
|| trap->ttyp == HOLE
|
||||
|| trap->ttyp == WEB)) {
|
||||
/* If you come upon an obviously trapped monster, then
|
||||
* you must be able to see the trap it's in too.
|
||||
@@ -2086,7 +2089,7 @@ register struct monst *mtmp;
|
||||
|
||||
if (!rn2(40)) {
|
||||
if (sobj_at(BOULDER, mtmp->mx, mtmp->my)
|
||||
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
|
||||
&& is_pit(trap->ttyp)) {
|
||||
if (!rn2(2)) {
|
||||
mtmp->mtrapped = 0;
|
||||
if (canseemon(mtmp))
|
||||
@@ -2150,10 +2153,7 @@ register struct monst *mtmp;
|
||||
break;
|
||||
}
|
||||
trap->once = 1;
|
||||
otmp = mksobj(ARROW, TRUE, FALSE);
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp->opoisoned = 0;
|
||||
otmp = t_missile(ARROW, trap);
|
||||
if (in_sight)
|
||||
seetrap(trap);
|
||||
if (thitm(8, mtmp, otmp, 0, FALSE))
|
||||
@@ -2169,9 +2169,7 @@ register struct monst *mtmp;
|
||||
break;
|
||||
}
|
||||
trap->once = 1;
|
||||
otmp = mksobj(DART, TRUE, FALSE);
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = t_missile(DART, trap);
|
||||
if (!rn2(6))
|
||||
otmp->opoisoned = 1;
|
||||
if (in_sight)
|
||||
@@ -2190,9 +2188,7 @@ register struct monst *mtmp;
|
||||
break;
|
||||
}
|
||||
trap->once = 1;
|
||||
otmp = mksobj(ROCK, TRUE, FALSE);
|
||||
otmp->quan = 1L;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = t_missile(ROCK, trap);
|
||||
if (in_sight)
|
||||
seetrap(trap);
|
||||
if (thitm(0, mtmp, otmp, d(2, 6), FALSE))
|
||||
@@ -2818,7 +2814,7 @@ int x, y;
|
||||
struct obj *otmp;
|
||||
struct trap *t;
|
||||
|
||||
if ((t = t_at(x, y)) && ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT))
|
||||
if ((t = t_at(x, y)) && is_pit(t->ttyp)
|
||||
&& (otmp = sobj_at(BOULDER, x, y))) {
|
||||
obj_extract_self(otmp);
|
||||
(void) flooreffects(otmp, x, y, "settle");
|
||||
@@ -2865,8 +2861,7 @@ long hmask, emask; /* might cancel timeout */
|
||||
if (Punished && !carried(uball)
|
||||
&& (is_pool(uball->ox, uball->oy)
|
||||
|| ((trap = t_at(uball->ox, uball->oy))
|
||||
&& ((trap->ttyp == PIT) || (trap->ttyp == SPIKED_PIT)
|
||||
|| (trap->ttyp == TRAPDOOR) || (trap->ttyp == HOLE))))) {
|
||||
&& (is_pit(trap->ttyp) || is_hole(trap->ttyp))))) {
|
||||
u.ux0 = u.ux;
|
||||
u.uy0 = u.uy;
|
||||
u.ux = uball->ox;
|
||||
@@ -4313,7 +4308,7 @@ boolean force;
|
||||
if (ttmp) {
|
||||
Strcpy(the_trap, the(trapdescr));
|
||||
if (boxcnt) {
|
||||
if (ttmp->ttyp == PIT || ttmp->ttyp == SPIKED_PIT) {
|
||||
if (is_pit(ttmp->ttyp)) {
|
||||
You_cant("do much about %s%s.", the_trap,
|
||||
u.utrap ? " that you're stuck in"
|
||||
: " while standing on the edge of it");
|
||||
@@ -4615,8 +4610,7 @@ boolean *noticed; /* set to true iff hero notices the effect; */
|
||||
/* if no trap here or it's not a falling trap, we're done
|
||||
(note: falling rock traps have a trapdoor in the ceiling) */
|
||||
if (!t || ((t->ttyp != TRAPDOOR && t->ttyp != ROCKTRAP)
|
||||
&& (trapdoor_only || (t->ttyp != HOLE && t->ttyp != PIT
|
||||
&& t->ttyp != SPIKED_PIT))))
|
||||
&& (trapdoor_only || (t->ttyp != HOLE && !is_pit(t->ttyp)))))
|
||||
return FALSE;
|
||||
|
||||
if (ishero) {
|
||||
@@ -4875,8 +4869,8 @@ boolean u_entering_trap2;
|
||||
if (!trap1 || !trap2)
|
||||
return FALSE;
|
||||
if (!isok(trap2->tx, trap2->ty) || !isok(trap1->tx, trap1->ty)
|
||||
|| !(trap2->ttyp == PIT || trap2->ttyp == SPIKED_PIT)
|
||||
|| !(trap1->ttyp == PIT || trap1->ttyp == SPIKED_PIT)
|
||||
|| !is_pit(trap2->ttyp)
|
||||
|| !is_pit(trap1->ttyp)
|
||||
|| (u_entering_trap2 && !(u.utrap && u.utraptype == TT_PIT)))
|
||||
return FALSE;
|
||||
dx = sgn(trap2->tx - trap1->tx);
|
||||
@@ -4894,21 +4888,21 @@ boolean u_entering_trap2;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
STATIC_OVL void
|
||||
clear_conjoined_pits(trap)
|
||||
struct trap *trap;
|
||||
{
|
||||
int diridx, adjidx, x, y;
|
||||
struct trap *t;
|
||||
|
||||
if (trap && (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT)) {
|
||||
if (trap && is_pit(trap->ttyp)) {
|
||||
for (diridx = 0; diridx < 8; ++diridx) {
|
||||
if (trap->conjoined & (1 << diridx)) {
|
||||
x = trap->tx + xdir[diridx];
|
||||
y = trap->ty + ydir[diridx];
|
||||
if (isok(x, y)
|
||||
&& (t = t_at(x, y)) != 0
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
|
||||
&& is_pit(t->ttyp)) {
|
||||
adjidx = (diridx + 4) % 8;
|
||||
t->conjoined &= ~(1 << adjidx);
|
||||
}
|
||||
@@ -4918,15 +4912,15 @@ struct trap *trap;
|
||||
}
|
||||
}
|
||||
|
||||
boolean
|
||||
STATIC_OVL boolean
|
||||
adj_nonconjoined_pit(adjtrap)
|
||||
struct trap *adjtrap;
|
||||
{
|
||||
struct trap *trap_with_u = t_at(u.ux0, u.uy0);
|
||||
|
||||
if (trap_with_u && adjtrap && u.utrap && u.utraptype == TT_PIT &&
|
||||
(trap_with_u->ttyp == PIT || trap_with_u->ttyp == SPIKED_PIT) &&
|
||||
(adjtrap->ttyp == PIT || adjtrap->ttyp == SPIKED_PIT)) {
|
||||
is_pit(trap_with_u->ttyp) &&
|
||||
is_pit(adjtrap->ttyp)) {
|
||||
int idx;
|
||||
for (idx = 0; idx < 8; idx++) {
|
||||
if (xdir[idx] == u.dx && ydir[idx] == u.dy)
|
||||
@@ -4955,7 +4949,7 @@ struct trap *trap;
|
||||
y = trap->ty + ydir[diridx];
|
||||
if (isok(x, y)) {
|
||||
if ((t = t_at(x, y)) != 0
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) {
|
||||
&& is_pit(t->ttyp)) {
|
||||
trap->conjoined |= (1 << diridx);
|
||||
join_adjacent_pits(t);
|
||||
} else
|
||||
@@ -4973,7 +4967,7 @@ uteetering_at_seen_pit(trap)
|
||||
struct trap *trap;
|
||||
{
|
||||
if (trap && trap->tseen && (!u.utrap || u.utraptype != TT_PIT)
|
||||
&& (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT))
|
||||
&& is_pit(trap->ttyp))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
@@ -4987,8 +4981,8 @@ register struct trap *ttmp;
|
||||
/* some of these are arbitrary -dlc */
|
||||
if (ttmp && ((ttmp->ttyp == SQKY_BOARD) || (ttmp->ttyp == BEAR_TRAP)
|
||||
|| (ttmp->ttyp == LANDMINE) || (ttmp->ttyp == FIRE_TRAP)
|
||||
|| (ttmp->ttyp == PIT) || (ttmp->ttyp == SPIKED_PIT)
|
||||
|| (ttmp->ttyp == HOLE) || (ttmp->ttyp == TRAPDOOR)
|
||||
|| is_pit(ttmp->ttyp)
|
||||
|| is_hole(ttmp->ttyp)
|
||||
|| (ttmp->ttyp == TELEP_TRAP) || (ttmp->ttyp == LEVEL_TELEP)
|
||||
|| (ttmp->ttyp == WEB) || (ttmp->ttyp == MAGIC_TRAP)
|
||||
|| (ttmp->ttyp == ANTI_MAGIC))) {
|
||||
|
||||
@@ -1484,6 +1484,9 @@ struct attack *mattk;
|
||||
setmnotwielded(mdef, otmp);
|
||||
otmp->owornmask = 0L;
|
||||
update_mon_intrinsics(mdef, otmp, FALSE, FALSE);
|
||||
/* give monster a chance to wear other equipment on its next
|
||||
move instead of waiting until it picks something up */
|
||||
mdef->misc_worn_check |= I_SPECIAL;
|
||||
|
||||
if (otmp == stealoid) /* special message for final item */
|
||||
pline("%s finishes taking off %s suit.", Monnam(mdef),
|
||||
|
||||
+1
-1
@@ -1916,7 +1916,7 @@ char *limits; /* points at range limit for current row, or NULL */
|
||||
* shadow limit imposed by the far block (right) then use the far
|
||||
* wall as our new far block when we recurse.
|
||||
*
|
||||
* If the limits are the the same, and the far block really exists
|
||||
* If the limits are the same, and the far block really exists
|
||||
* (fb_row >= 0) then do the same as above.
|
||||
*
|
||||
* Normally, the check would be for the far wall being closer OR EQUAL
|
||||
|
||||
+17
-1
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 worn.c $NHDT-Date: 1526728754 2018/05/19 11:19:14 $ $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.51 $ */
|
||||
/* NetHack 3.6 worn.c $NHDT-Date: 1537234121 2018/09/18 01:28:41 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.55 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -710,6 +710,13 @@ clear_bypasses()
|
||||
struct obj *otmp, *nobj;
|
||||
struct monst *mtmp;
|
||||
|
||||
/*
|
||||
* 'Object' bypass is also used for one monster function:
|
||||
* polymorph control of long worms. Activated via setting
|
||||
* context.bypasses even if no specific object has been
|
||||
* bypassed.
|
||||
*/
|
||||
|
||||
for (otmp = fobj; otmp; otmp = nobj) {
|
||||
nobj = otmp->nobj;
|
||||
if (otmp->bypass) {
|
||||
@@ -741,10 +748,19 @@ clear_bypasses()
|
||||
continue;
|
||||
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
|
||||
otmp->bypass = 0;
|
||||
/* long worm created by polymorph has mon->mextra->mcorpsenm set
|
||||
to PM_LONG_WORM to flag it as not being subject to further
|
||||
polymorph (so polymorph zap won't hit monster to transform it
|
||||
into a long worm, then hit that worm's tail and transform it
|
||||
again on same zap); clearing mcorpsenm reverts worm to normal */
|
||||
if (mtmp->data == &mons[PM_LONG_WORM] && has_mcorpsenm(mtmp))
|
||||
MCORPSENM(mtmp) = NON_PM;
|
||||
}
|
||||
for (mtmp = migrating_mons; mtmp; mtmp = mtmp->nmon) {
|
||||
for (otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
|
||||
otmp->bypass = 0;
|
||||
/* no MCORPSENM(mtmp)==PM_LONG_WORM check here; long worms can't
|
||||
be just created by polymorph and migrating at the same time */
|
||||
}
|
||||
/* billobjs and mydogs chains don't matter here */
|
||||
context.bypasses = FALSE;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 zap.c $NHDT-Date: 1525012627 2018/04/29 14:37:07 $ $NHDT-Branch: master $:$NHDT-Revision: 1.277 $ */
|
||||
/* NetHack 3.6 zap.c $NHDT-Date: 1537234123 2018/09/18 01:28:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.287 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -222,7 +222,11 @@ struct obj *otmp;
|
||||
case WAN_POLYMORPH:
|
||||
case SPE_POLYMORPH:
|
||||
case POT_POLYMORPH:
|
||||
if (resists_magm(mtmp)) {
|
||||
if (mtmp->data == &mons[PM_LONG_WORM] && has_mcorpsenm(mtmp)) {
|
||||
/* if a long worm has mcorpsenm set, it was polymophed by
|
||||
the current zap and shouldn't be affected if hit again */
|
||||
;
|
||||
} else if (resists_magm(mtmp)) {
|
||||
/* magic resistance protects from polymorph traps, so make
|
||||
it guard against involuntary polymorph attacks too... */
|
||||
shieldeff(mtmp->mx, mtmp->my);
|
||||
@@ -238,6 +242,7 @@ struct obj *otmp;
|
||||
if (polyspot)
|
||||
for (obj = mtmp->minvent; obj; obj = obj->nobj)
|
||||
bypass_obj(obj);
|
||||
|
||||
/* natural shapechangers aren't affected by system shock
|
||||
(unless protection from shapechangers is interfering
|
||||
with their metabolism...) */
|
||||
@@ -261,6 +266,22 @@ struct obj *otmp;
|
||||
|| (u.uswallow && mtmp == u.ustuck)))
|
||||
learn_it = TRUE;
|
||||
}
|
||||
|
||||
/* do this even if polymorphed failed (otherwise using
|
||||
flags.mon_polycontrol prompting to force mtmp to remain
|
||||
'long worm' would prompt again if zap hit another segment) */
|
||||
if (!DEADMONSTER(mtmp) && mtmp->data == &mons[PM_LONG_WORM]) {
|
||||
if (!has_mcorpsenm(mtmp))
|
||||
newmcorpsenm(mtmp);
|
||||
/* flag to indicate that mtmp became a long worm
|
||||
on current zap, so further hits (on mtmp's new
|
||||
tail) don't do further transforms */
|
||||
MCORPSENM(mtmp) = PM_LONG_WORM;
|
||||
/* flag to indicate that cleanup is needed; object
|
||||
bypass cleanup also clears mon->mextra->mcorpsenm
|
||||
for all long worms on the level */
|
||||
context.bypasses = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WAN_CANCELLATION:
|
||||
@@ -2306,7 +2327,7 @@ boolean ordinary;
|
||||
|
||||
case WAN_CANCELLATION:
|
||||
case SPE_CANCELLATION:
|
||||
(void) cancel_monst(&youmonst, obj, TRUE, FALSE, TRUE);
|
||||
(void) cancel_monst(&youmonst, obj, TRUE, TRUE, TRUE);
|
||||
break;
|
||||
|
||||
case SPE_DRAIN_LIFE:
|
||||
@@ -2675,25 +2696,45 @@ boolean youattack, allow_cancel_kill, self_cancel;
|
||||
|
||||
/* now handle special cases */
|
||||
if (youdefend) {
|
||||
if (Upolyd) {
|
||||
if ((u.umonnum == PM_CLAY_GOLEM) && !Blind)
|
||||
pline(writing_vanishes, your);
|
||||
|
||||
if (Unchanging)
|
||||
if (Upolyd) { /* includes lycanthrope in creature form */
|
||||
/*
|
||||
* Return to normal form unless Unchanging.
|
||||
* Hero in clay golem form dies if Unchanging.
|
||||
* Does not cure lycanthropy or stop timed random polymorph.
|
||||
*/
|
||||
if (u.umonnum == PM_CLAY_GOLEM) {
|
||||
if (!Blind)
|
||||
pline(writing_vanishes, your);
|
||||
else /* note: "dark" rather than "heavy" is intentional... */
|
||||
You_feel("%s headed.", Hallucination ? "dark" : "light");
|
||||
u.mh = 0; /* fatal; death handled by rehumanize() */
|
||||
}
|
||||
if (Unchanging && u.mh > 0)
|
||||
Your("amulet grows hot for a moment, then cools.");
|
||||
else
|
||||
rehumanize();
|
||||
}
|
||||
} else {
|
||||
mdef->mcan = TRUE;
|
||||
|
||||
if (is_were(mdef->data) && mdef->data->mlet != S_HUMAN)
|
||||
mdef->mcan = 1;
|
||||
/* force shapeshifter into its base form */
|
||||
if (mdef->m_ap_type != M_AP_NOTHING)
|
||||
seemimic(mdef);
|
||||
/* [not 'else if'; chameleon might have been hiding as a mimic] */
|
||||
if (mdef->cham >= LOW_PM) {
|
||||
/* note: newcham() uncancels shapechangers (resets m->mcan
|
||||
to 0), but only for shapechangers whose m->cham is already
|
||||
NON_PM and we just verified that it's LOW_PM or higher */
|
||||
newcham(mdef, &mons[mdef->cham], FALSE, FALSE);
|
||||
mdef->cham = NON_PM; /* cancelled shapeshifter can't shift */
|
||||
}
|
||||
if (is_were(mdef->data) && !is_human(mdef->data))
|
||||
were_change(mdef);
|
||||
|
||||
if (mdef->data == &mons[PM_CLAY_GOLEM]) {
|
||||
if (canseemon(mdef))
|
||||
pline(writing_vanishes, s_suffix(mon_nam(mdef)));
|
||||
|
||||
/* !allow_cancel_kill is for Magicbane, where clay golem
|
||||
will be killed somewhere back up the call/return chain... */
|
||||
if (allow_cancel_kill) {
|
||||
if (youattack)
|
||||
killed(mdef);
|
||||
@@ -3373,8 +3414,7 @@ struct obj **pobj; /* object tossed/used, set to NULL
|
||||
The(distant_name(obj, xname))); /* lame */
|
||||
range = 0;
|
||||
} else if (Sokoban && (t = t_at(x, y)) != 0
|
||||
&& (t->ttyp == PIT || t->ttyp == SPIKED_PIT
|
||||
|| t->ttyp == HOLE || t->ttyp == TRAPDOOR)) {
|
||||
&& (is_pit(t->ttyp) || is_hole(t->ttyp))) {
|
||||
/* hero falls into the trap, so ball stops */
|
||||
range = 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user