displacing pet long worm

Salvage part of an old patch.  Swapping places with any long worm,
even a baby one, always failed with "You stop.  Foo is in the way!"
This lets you swap places with tame baby long worms, and adult ones
if they have no tail (which won't happen unless there are more than
32 long worms on the current level--even if a long worm appears to
be only a head, there is normally a hidden tail segment at the same
location).
This commit is contained in:
PatR
2018-12-14 18:17:42 -08:00
parent 1be3ad0ddc
commit aa5a85f4da

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 uhitm.c $NHDT-Date: 1543892215 2018/12/04 02:56:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.195 $ */ /* NetHack 3.6 uhitm.c $NHDT-Date: 1544840256 2018/12/15 02:17:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.196 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -101,7 +101,7 @@ attack_checks(mtmp, wep)
register struct monst *mtmp; register struct monst *mtmp;
struct obj *wep; /* uwep for attack(), null for kick_monster() */ struct obj *wep; /* uwep for attack(), null for kick_monster() */
{ {
char qbuf[QBUFSZ]; int glyph;
/* if you're close enough to attack, alert any waiting monster */ /* if you're close enough to attack, alert any waiting monster */
mtmp->mstrategy &= ~STRAT_WAITMASK; mtmp->mstrategy &= ~STRAT_WAITMASK;
@@ -124,6 +124,12 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */
return FALSE; return FALSE;
} }
/* cache the shown glyph;
cases which might change it (by placing or removing
'rembered, unseen monster' glyph or revealing a mimic)
always return without further reference to this */
glyph = glyph_at(bhitpos.x, bhitpos.y);
/* Put up an invisible monster marker, but with exceptions for /* Put up an invisible monster marker, but with exceptions for
* monsters that hide and monsters you've been warned about. * monsters that hide and monsters you've been warned about.
* The former already prints a warning message and * The former already prints a warning message and
@@ -132,8 +138,8 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */
* happening two turns in a row. The latter shows a glyph on * happening two turns in a row. The latter shows a glyph on
* the screen, so you know something is there. * the screen, so you know something is there.
*/ */
if (!canspotmon(mtmp) && !glyph_is_warning(glyph_at(bhitpos.x, bhitpos.y)) if (!canspotmon(mtmp)
&& !glyph_is_invisible(levl[bhitpos.x][bhitpos.y].glyph) && !glyph_is_warning(glyph) && !glyph_is_invisible(glyph)
&& !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) { && !(!Blind && mtmp->mundetected && hides_under(mtmp->data))) {
pline("Wait! There's %s there you can't see!", something); pline("Wait! There's %s there you can't see!", something);
map_invisible(bhitpos.x, bhitpos.y); map_invisible(bhitpos.x, bhitpos.y);
@@ -146,17 +152,23 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */
if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK)) if (!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data, AD_STCK))
u.ustuck = mtmp; u.ustuck = mtmp;
} }
/* #H7329 - if hero is on engraved "Elbereth", this will end up
* assessing an alignment penalty and removing the engraving
* even though no attack actually occurs. Since it also angers
* peacefuls, we're operating as if an attack attempt did occur
* and the Elbereth behavior is consistent.
*/
wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */ wakeup(mtmp, TRUE); /* always necessary; also un-mimics mimics */
return TRUE; return TRUE;
} }
if (mtmp->m_ap_type && !Protection_from_shape_changers && !sensemon(mtmp) if (mtmp->m_ap_type && !Protection_from_shape_changers && !sensemon(mtmp)
&& !glyph_is_warning(glyph_at(bhitpos.x, bhitpos.y))) { && !glyph_is_warning(glyph)) {
/* If a hidden mimic was in a square where a player remembers /* If a hidden mimic was in a square where a player remembers
* some (probably different) unseen monster, the player is in * some (probably different) unseen monster, the player is in
* luck--he attacks it even though it's hidden. * luck--he attacks it even though it's hidden.
*/ */
if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) { if (glyph_is_invisible(glyph)) {
seemimic(mtmp); seemimic(mtmp);
return FALSE; return FALSE;
} }
@@ -165,11 +177,11 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */
} }
if (mtmp->mundetected && !canseemon(mtmp) if (mtmp->mundetected && !canseemon(mtmp)
&& !glyph_is_warning(glyph_at(bhitpos.x, bhitpos.y)) && !glyph_is_warning(glyph)
&& (hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) { && (hides_under(mtmp->data) || mtmp->data->mlet == S_EEL)) {
mtmp->mundetected = mtmp->msleeping = 0; mtmp->mundetected = mtmp->msleeping = 0;
newsym(mtmp->mx, mtmp->my); newsym(mtmp->mx, mtmp->my);
if (glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) { if (glyph_is_invisible(glyph)) {
seemimic(mtmp); seemimic(mtmp);
return FALSE; return FALSE;
} }
@@ -197,14 +209,16 @@ struct obj *wep; /* uwep for attack(), null for kick_monster() */
wakeup(mtmp, TRUE); wakeup(mtmp, TRUE);
} }
if (flags.confirm && mtmp->mpeaceful && !Confusion && !Hallucination if (flags.confirm && mtmp->mpeaceful
&& !Stunned) { && !Confusion && !Hallucination && !Stunned) {
/* Intelligent chaotic weapons (Stormbringer) want blood */ /* Intelligent chaotic weapons (Stormbringer) want blood */
if (wep && wep->oartifact == ART_STORMBRINGER) { if (wep && wep->oartifact == ART_STORMBRINGER) {
override_confirmation = TRUE; override_confirmation = TRUE;
return FALSE; return FALSE;
} }
if (canspotmon(mtmp)) { if (canspotmon(mtmp)) {
char qbuf[QBUFSZ];
Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp)); Sprintf(qbuf, "Really attack %s?", mon_nam(mtmp));
if (!paranoid_query(ParanoidHit, qbuf)) { if (!paranoid_query(ParanoidHit, qbuf)) {
context.move = 0; context.move = 0;
@@ -329,23 +343,26 @@ register struct monst *mtmp;
/* Intelligent chaotic weapons (Stormbringer) want blood */ /* Intelligent chaotic weapons (Stormbringer) want blood */
if (is_safepet(mtmp) && !context.forcefight) { if (is_safepet(mtmp) && !context.forcefight) {
if (!uwep || uwep->oartifact != ART_STORMBRINGER) { if (!uwep || uwep->oartifact != ART_STORMBRINGER) {
/* there are some additional considerations: this won't work /* There are some additional considerations: this won't work
* if in a shop or Punished or you miss a random roll or * if in a shop or Punished or you miss a random roll or
* if you can walk thru walls and your pet cannot (KAA) or * if you can walk thru walls and your pet cannot (KAA) or
* if your pet is a long worm (unless someone does better). * if your pet is a long worm with a tail.
* there's also a chance of displacing a "frozen" monster. * There's also a chance of displacing a "frozen" monster:
* sleeping monsters might magically walk in their sleep. * sleeping monsters might magically walk in their sleep.
*/ */
boolean foo = (Punished || !rn2(7) || is_longworm(mtmp->data)), boolean foo = (Punished || !rn2(7)
|| (is_longworm(mtmp->data) && mtmp->wormno)),
inshop = FALSE; inshop = FALSE;
char *p; char *p;
for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++) /* only check for in-shop if don't already have reason to stop */
if (tended_shop(&rooms[*p - ROOMOFFSET])) { if (!foo) {
inshop = TRUE; for (p = in_rooms(mtmp->mx, mtmp->my, SHOPBASE); *p; p++)
break; if (tended_shop(&rooms[*p - ROOMOFFSET])) {
} inshop = TRUE;
break;
}
}
if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ) if (inshop || foo || (IS_ROCK(levl[u.ux][u.uy].typ)
&& !passes_walls(mtmp->data))) { && !passes_walls(mtmp->data))) {
char buf[BUFSZ]; char buf[BUFSZ];
@@ -895,7 +912,7 @@ int dieroll;
if (resists_ston(mon)) if (resists_ston(mon))
break; break;
/* note: hp may be <= 0 even if munstoned==TRUE */ /* note: hp may be <= 0 even if munstoned==TRUE */
return (boolean) (!DEADMONSTER(mon)); return (boolean) !DEADMONSTER(mon);
#if 0 #if 0
} else if (touch_petrifies(mdat)) { } else if (touch_petrifies(mdat)) {
; /* maybe turn the corpse into a statue? */ ; /* maybe turn the corpse into a statue? */