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

This commit is contained in:
keni
2016-12-09 17:47:54 -05:00
21 changed files with 145 additions and 65 deletions

View File

@@ -132,14 +132,13 @@ boolean resuming;
moveamt = youmonst.data->mmove;
if (Very_fast) { /* speed boots or potion */
/* average movement is 1.67 times normal */
moveamt += NORMAL_SPEED / 2;
if (rn2(3) == 0)
moveamt += NORMAL_SPEED / 2;
} else if (Fast) {
/* average movement is 1.33 times normal */
/* gain a free action on 2/3 of turns */
if (rn2(3) != 0)
moveamt += NORMAL_SPEED / 2;
moveamt += NORMAL_SPEED;
} else if (Fast) {
/* gain a free action on 1/3 of turns */
if (rn2(3) == 0)
moveamt += NORMAL_SPEED;
}
}

View File

@@ -272,6 +272,7 @@ boolean thrown_weapon; /* thrown weapons are less deadly */
if (i == 0 && typ != A_CHA) {
/* instant kill */
u.uhp = -1;
context.botl = TRUE;
pline_The("poison was deadly...");
} else if (i > 5) {
/* HP damage; more likely--but less severe--with missiles */
@@ -1002,6 +1003,9 @@ int x;
&& (youmonst.data->mlet == S_NYMPH || u.umonnum == PM_SUCCUBUS
|| u.umonnum == PM_INCUBUS))
return (schar) 18;
} else if (x == A_CON) {
if (uwep && uwep->oartifact == ART_OGRESMASHER)
return (schar) 25;
} else if (x == A_INT || x == A_WIS) {
/* yes, this may raise int/wis if player is sufficiently
* stupid. there are lower levels of cognition than "dunce".
@@ -1047,6 +1051,9 @@ int attrindx;
/* lower limit for Str can also be 25 */
if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER)
lolimit = hilimit;
} else if (attrindx == A_CON) {
if (uwep && uwep->oartifact == ART_OGRESMASHER)
lolimit = hilimit;
}
/* this exception is hypothetical; the only other worn item affecting
Int or Wis is another helmet so can't be in use at the same time */

View File

@@ -1638,6 +1638,8 @@ int mode, final, attrindx;
break;
case A_CON:
attrname = "constitution";
if (uwep && uwep->oartifact == ART_OGRESMASHER && uwep->cursed)
hide_innate_value = TRUE;
break;
case A_INT:
attrname = "intelligence";

View File

@@ -430,9 +430,10 @@ boolean with_you;
mtmp->mx = 0; /*(already is 0)*/
mtmp->my = xyflags;
if (xlocale)
(void) mnearto(mtmp, xlocale, ylocale, FALSE);
else {
if (xlocale) {
if (!mnearto(mtmp, xlocale, ylocale, FALSE))
goto fail_mon_placement;
} else {
if (!rloc(mtmp, TRUE)) {
/*
* Failed to place migrating monster,
@@ -440,6 +441,7 @@ boolean with_you;
* Dump the monster's cargo and leave the monster dead.
*/
struct obj *obj;
fail_mon_placement:
while ((obj = mtmp->minvent) != 0) {
obj_extract_self(obj);
obj_no_longer_held(obj);

View File

@@ -922,6 +922,18 @@ int how;
return;
}
}
if (program_state.panicking
#ifdef HANGUPHANDLING
|| program_state.done_hup
#endif
) {
/* skip status update if panicking or disconnected */
context.botl = context.botlx = FALSE;
} else {
/* otherwise force full status update */
context.botlx = TRUE;
bot();
}
if (how == ASCENDED || (!killer.name[0] && how == GENOCIDED))
killer.format = NO_KILLER_PREFIX;

View File

@@ -742,6 +742,7 @@ register struct attack *mattk;
if (cansee(dx, dy))
pline("%s is regurgitated!", Monnam(mdef));
remove_monster(dx,dy);
place_monster(magr, ax, ay);
place_monster(mdef, dx, dy);
newsym(ax, ay);

View File

@@ -5,7 +5,7 @@
#include "hack.h"
#include "artifact.h"
STATIC_VAR NEARDATA struct obj *otmp;
STATIC_VAR NEARDATA struct obj *mon_currwep = (struct obj *) 0;
STATIC_DCL boolean FDECL(u_slip_free, (struct monst *, struct attack *));
STATIC_DCL int FDECL(passiveum, (struct permonst *, struct monst *,
@@ -646,6 +646,7 @@ register struct monst *mtmp;
for (i = 0; i < NATTK; i++) {
sum[i] = 0;
mon_currwep = (struct obj *)0;
mattk = getmattk(mtmp, &youmonst, i, sum, &alt_attk);
if ((u.uswallow && mattk->aatyp != AT_ENGL)
|| (skipnonmagc && mattk->aatyp != AT_MAGC))
@@ -747,18 +748,18 @@ register struct monst *mtmp;
break;
}
if (foundyou) {
otmp = MON_WEP(mtmp);
if (otmp) {
hittmp = hitval(otmp, &youmonst);
mon_currwep = MON_WEP(mtmp);
if (mon_currwep) {
hittmp = hitval(mon_currwep, &youmonst);
tmp += hittmp;
mswings(mtmp, otmp);
mswings(mtmp, mon_currwep);
}
if (tmp > (j = dieroll = rnd(20 + i)))
sum[i] = hitmu(mtmp, mattk);
else
missmu(mtmp, (tmp == j), mattk);
/* KMH -- Don't accumulate to-hit bonuses */
if (otmp)
if (mon_currwep)
tmp -= hittmp;
} else {
wildmiss(mtmp, mattk);
@@ -968,6 +969,7 @@ register struct attack *mattk;
: "crushed");
}
} else { /* hand to hand weapon */
struct obj *otmp = mon_currwep;
if (mattk->aatyp == AT_WEAP && otmp) {
int tmp;
@@ -2710,10 +2712,10 @@ register struct attack *mattk;
return 1;
}
case AD_ENCH: /* KMH -- remove enchantment (disenchanter) */
if (otmp) {
if (mon_currwep) {
/* by_you==True: passive counterattack to hero's action
is hero's fault */
(void) drain_item(otmp, TRUE);
(void) drain_item(mon_currwep, TRUE);
/* No message */
}
return 1;

View File

@@ -582,6 +582,7 @@ mcalcmove(mon)
struct monst *mon;
{
int mmove = mon->data->mmove;
int mmove_adj;
/* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0;
* MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op;
@@ -592,21 +593,24 @@ struct monst *mon;
else if (mon->mspeed == MFAST)
mmove = (4 * mmove + 2) / 3;
if (mon == u.usteed) {
if (u.ugallop && context.mv) {
/* average movement is 1.50 times normal */
mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
}
} else if (mmove) {
/* vary movement points allocated to slightly reduce predictability;
random increment (avg +2) exceeds random decrement (avg +1) by
a small amount; normal speed monsters will occasionally get an
extra move and slow ones won't be quite as slow */
mmove += rn2(5) - rn2(3); /* + 0..4 - 0..2, average net +1 */
if (mmove < 1)
mmove = 1;
if (mon == u.usteed && u.ugallop && context.mv) {
/* increase movement by a factor of 1.5; also increase variance of
movement speed (if it's naturally 24, we don't want it to always
become 36) */
mmove = ((rn2(2) ? 4 : 5) * mmove) / 3;
}
/* Randomly round the monster's speed to a multiple of NORMAL_SPEED. This
makes it impossible for the player to predict when they'll get a free
turn (thus preventing exploits like "melee kiting"), while retaining
guarantees about shopkeepers not being outsped by a normal-speed player,
normal-speed players being unable to open up a gap when fleeing a
normal-speed monster, etc.*/
mmove_adj = mmove % NORMAL_SPEED;
mmove -= mmove_adj;
if (rn2(NORMAL_SPEED) < mmove_adj)
mmove += NORMAL_SPEED;
return mmove;
}
@@ -2025,6 +2029,8 @@ struct monst *mdef;
/* hero is thrown from his steed when it disappears */
if (mdef == u.usteed)
dismount_steed(DISMOUNT_GENERIC);
/* stuck to you? release */
unstuck(mdef);
/* drop special items like the Amulet so that a dismissed Kop or nurse
can't remove them from the game */
mdrop_special_objs(mdef);
@@ -2445,6 +2451,16 @@ struct monst *mtmp;
return TRUE;
}
/* drop monster into "limbo" - that is, migrate to the current level */
void
m_into_limbo(mtmp)
struct monst *mtmp;
{
unstuck(mtmp);
mdrop_special_objs(mtmp);
migrate_to_level(mtmp, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
}
/* make monster mtmp next to you (if possible);
might place monst on far side of a wall or boulder */
void
@@ -2461,7 +2477,11 @@ struct monst *mtmp;
return;
}
if (!enexto(&mm, u.ux, u.uy, mtmp->data))
if (!enexto(&mm, u.ux, u.uy, mtmp->data)) {
m_into_limbo(mtmp);
return;
}
if (!isok(mm.x, mm.y))
return;
rloc_to(mtmp, mm.x, mm.y);
if (!in_mklev && (mtmp->mstrategy & STRAT_APPEARMSG)) {
@@ -2530,6 +2550,8 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
*/
if (!enexto(&mm, newx, newy, mtmp->data))
return FALSE;
if (!isok(mm.x,mm.y))
return FALSE;
newx = mm.x;
newy = mm.y;
}
@@ -2541,12 +2563,10 @@ boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */
othermon->mx = othermon->my = 0;
(void) mnearto(othermon, x, y, FALSE);
if (othermon->mx == 0 && othermon->my == 0) {
/* reloc failed, dump monster into "limbo"
(aka migrate to current level) */
/* reloc failed */
othermon->mx = oldx;
othermon->my = oldy;
mdrop_special_objs(othermon);
migrate_to_level(othermon, ledger_no(&u.uz), MIGR_APPROX_XY, NULL);
m_into_limbo(othermon);
}
}

View File

@@ -268,7 +268,7 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
register struct objclass *ocl = &objects[typ];
int nn = ocl->oc_name_known, omndx = obj->corpsenm;
const char *actualn = OBJ_NAME(*ocl);
const char *dn = OBJ_DESCR(*ocl);
const char *dn = OBJ_DESCR(*ocl) ? OBJ_DESCR(*ocl) : actualn;
const char *un = ocl->oc_uname;
boolean pluralize = (obj->quan != 1L) && !(cxn_flags & CXN_SINGULAR);
boolean known, dknown, bknown;
@@ -327,15 +327,15 @@ unsigned cxn_flags; /* bitmask of CXN_xxx values */
Strcpy(buf, (obj->spe < 3) ? "moist " : "wet ");
if (!dknown)
Strcat(buf, dn ? dn : actualn);
Strcat(buf, dn);
else if (nn)
Strcat(buf, actualn);
else if (un) {
Strcat(buf, dn ? dn : actualn);
Strcat(buf, dn);
Strcat(buf, " called ");
Strcat(buf, un);
} else
Strcat(buf, dn ? dn : actualn);
Strcat(buf, dn);
/* If we use an() here we'd have to remember never to use */
/* it whenever calling doname() or xname(). */
if (typ == FIGURINE && omndx != NON_PM) {

View File

@@ -113,7 +113,7 @@ dosit()
}
} else {
You("sit down.");
dotrap(trap, 0);
dotrap(trap, VIASITTING);
}
} else if (Underwater || Is_waterlevel(&u.uz)) {
if (Is_waterlevel(&u.uz))

View File

@@ -872,12 +872,20 @@ struct trap *trap;
}
void
level_tele_trap(trap)
level_tele_trap(trap, trflags)
struct trap *trap;
unsigned trflags;
{
You("%s onto a level teleport trap!",
Levitation ? (const char *) "float"
: locomotion(youmonst.data, "step"));
char verbbuf[BUFSZ];
if ((trflags & VIASITTING) != 0)
Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
else
Sprintf(verbbuf, "%s onto",
Levitation ? (const char *) "float"
: locomotion(youmonst.data, "step"));
You("%s a level teleport trap!", verbbuf);
if (Antimagic) {
shieldeff(u.ux, u.uy);
}

View File

@@ -850,6 +850,7 @@ unsigned trflags;
webmsgok = (trflags & NOWEBMSG) == 0,
forcebungle = (trflags & FORCEBUNGLE) != 0,
plunged = (trflags & TOOKPLUNGE) != 0,
viasitting = (trflags & VIASITTING) != 0,
adj_pit = conjoined_pits(trap, t_at(u.ux0, u.uy0), TRUE);
int oldumort;
int steed_article = ARTICLE_THE;
@@ -1237,7 +1238,7 @@ unsigned trflags;
case LEVEL_TELEP:
seetrap(trap);
level_tele_trap(trap);
level_tele_trap(trap, trflags);
break;
case WEB: /* Our luckless player has stumbled into a web. */
@@ -1253,7 +1254,7 @@ unsigned trflags;
if (webmsgok) {
char verbbuf[BUFSZ];
if (forcetrap) {
if (forcetrap || viasitting) {
Strcpy(verbbuf, "are caught by");
} else if (u.usteed) {
Sprintf(verbbuf, "lead %s into",
@@ -1382,15 +1383,17 @@ unsigned trflags;
char verbbuf[BUFSZ];
seetrap(trap);
if (u.usteed)
Sprintf(verbbuf, "lead %s",
if (viasitting)
Strcpy(verbbuf, "trigger"); /* follows "You sit down." */
else if (u.usteed)
Sprintf(verbbuf, "lead %s onto",
x_monnam(u.usteed, steed_article, (char *) 0,
SUPPRESS_SADDLE, FALSE));
else
Sprintf(verbbuf, "%s", Levitation
? (const char *) "float"
: locomotion(youmonst.data, "step"));
You("%s onto a polymorph trap!", verbbuf);
Sprintf(verbbuf, "%s onto",
Levitation ? (const char *) "float"
: locomotion(youmonst.data, "step"));
You("%s a polymorph trap!", verbbuf);
if (Antimagic || Unchanging) {
shieldeff(u.ux, u.uy);
You_feel("momentarily different.");

View File

@@ -96,6 +96,10 @@ register struct obj *obj;
if (!Blind)
pline("%s shining.", Tobjnam(olduwep, "stop"));
}
if (uwep == obj
&& ((uwep && uwep->oartifact == ART_OGRESMASHER)
|| (olduwep && olduwep->oartifact == ART_OGRESMASHER)))
context.botl = 1;
/* Note: Explicitly wielding a pick-axe will not give a "bashing"
* message. Wielding one via 'a'pplying it will.
* 3.2.2: Wielding arbitrary objects will give bashing message too.

View File

@@ -380,7 +380,10 @@ register struct monst *mtmp;
if (!rn2(3 + mtmp->mhp / 10))
(void) rloc(mtmp, TRUE);
} else if (sx && (mtmp->mx != sx || mtmp->my != sy)) {
(void) mnearto(mtmp, sx, sy, TRUE);
if (!mnearto(mtmp, sx, sy, TRUE)) {
m_into_limbo(mtmp);
return 0;
}
}
/* if you're not around, cast healing spells */
if (distu(mtmp->mx, mtmp->my) > (BOLT_LIM * BOLT_LIM))
@@ -433,7 +436,8 @@ register struct monst *mtmp;
return 0;
}
} else { /* a monster has it - 'port beside it. */
(void) mnearto(mtmp, tx, ty, FALSE);
if (!mnearto(mtmp, tx, ty, FALSE))
m_into_limbo(mtmp);
return 0;
}
}