Merge remote-tracking branch 'origin/NetHack-3.6.0'
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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);
|
||||
|
||||
12
src/end.c
12
src/end.c
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
18
src/mhitu.c
18
src/mhitu.c
@@ -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;
|
||||
|
||||
56
src/mon.c
56
src/mon.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
19
src/trap.c
19
src/trap.c
@@ -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.");
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user