sleeping steeds (trunk only)
From the newsgroup: it was possible to saddle, mount, and ride on a sleeping jabberwork without it ever waking up. Movement was checking for timed sleep (!mon->mcanmove, set when mon->mfrozen contains a timer count for either sleep or paralysis) but not indefinite sleep (mon->msleeping). This moves the checking into its own routine which handles both types. And it gives monsters a chance to wake up when they get saddled or mounted.
This commit is contained in:
@@ -31,7 +31,6 @@ internals: use Is_box rather than explicitly checking what it checks
|
||||
fix some unreachable messages (either make then reachable or remove them)
|
||||
can quiver coins when GOLDOBJ is defined
|
||||
grammar, spelling and other typos
|
||||
oracle and rumor regarding priestly donations
|
||||
keep various delayed killers separate to avoid mixed up messages
|
||||
don't place randomly-placed aquatic monsters in lava on special levels
|
||||
hiding monsters don't hide under cockatrice/chickatrice corpses
|
||||
@@ -163,7 +162,8 @@ bugles affect all monsters to some extent
|
||||
nurses are affected if player is polymorphed as a cockatrice
|
||||
getting a particular rotten food result can't make attempting to eat a
|
||||
corpse of one of the Riders be survivable
|
||||
pad rumors to improve distribution of delivered rumors
|
||||
pad shortest rumors to improve distribution of delivered rumors
|
||||
wake up sleeping steed when putting on saddle or mounting
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific Fixes
|
||||
@@ -248,6 +248,7 @@ add Malcolm Ryan's Statue Glyphs patch
|
||||
lembas and cram never rot unless cursed
|
||||
multiple squeaks for squeaky boards
|
||||
include time, user ID, and play mode in paniclog entries
|
||||
add oracle and rumor regarding priestly donations
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
@@ -2101,6 +2101,7 @@ E void NDECL(exercise_steed);
|
||||
E void NDECL(kick_steed);
|
||||
E void FDECL(dismount_steed, (int));
|
||||
E void FDECL(place_monster, (struct monst *,int,int));
|
||||
E boolean FDECL(stucksteed, (BOOLEAN_P));
|
||||
#endif
|
||||
|
||||
/* ### teleport.c ### */
|
||||
|
||||
18
src/do.c
18
src/do.c
@@ -755,13 +755,9 @@ dodown()
|
||||
}
|
||||
|
||||
#ifdef STEED
|
||||
if (u.usteed && !u.usteed->mcanmove) {
|
||||
pline("%s won't move!", Monnam(u.usteed));
|
||||
return(0);
|
||||
} else if (u.usteed && u.usteed->meating) {
|
||||
pline("%s is still eating.", Monnam(u.usteed));
|
||||
return(0);
|
||||
} else
|
||||
if (stucksteed(TRUE)) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if (Levitation) {
|
||||
if ((HLevitation & I_SPECIAL) || (ELevitation & W_ARTI)) {
|
||||
@@ -875,13 +871,9 @@ doup()
|
||||
return(0);
|
||||
}
|
||||
#ifdef STEED
|
||||
if (u.usteed && !u.usteed->mcanmove) {
|
||||
pline("%s won't move!", Monnam(u.usteed));
|
||||
if (stucksteed(TRUE)) {
|
||||
return(0);
|
||||
} else if (u.usteed && u.usteed->meating) {
|
||||
pline("%s is still eating.", Monnam(u.usteed));
|
||||
return(0);
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
if(u.ustuck) {
|
||||
You("are %s, and cannot go up.",
|
||||
|
||||
@@ -1221,11 +1221,10 @@ domove()
|
||||
}
|
||||
/* not attacking an animal, so we try to move */
|
||||
#ifdef STEED
|
||||
if (u.usteed && !u.usteed->mcanmove && (u.dx || u.dy)) {
|
||||
pline("%s won't move!", upstart(y_monnam(u.usteed)));
|
||||
if ((u.dx || u.dy) && stucksteed(FALSE)) {
|
||||
nomul(0);
|
||||
return;
|
||||
} else
|
||||
}
|
||||
#endif
|
||||
if(!youmonst.data->mmove) {
|
||||
You("are rooted %s.",
|
||||
|
||||
@@ -1277,7 +1277,7 @@ int amt, how;
|
||||
(how >= 0 && resist(mon, (char)how, 0, NOTELL))) {
|
||||
shieldeff(mon->mx, mon->my);
|
||||
} else if (mon->mcanmove) {
|
||||
mon->meating = 0; /* terminate any meal-in-progress */
|
||||
finish_meating(mon); /* terminate any meal-in-progress */
|
||||
amt += (int) mon->mfrozen;
|
||||
if (amt > 0) { /* sleep for N turns */
|
||||
mon->mcanmove = 0;
|
||||
|
||||
70
src/steed.c
70
src/steed.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)steed.c 3.5 2006/04/14 */
|
||||
/* SCCS Id: @(#)steed.c 3.5 2006/10/11 */
|
||||
/* Copyright (c) Kevin Hugo, 1998-1999. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -13,6 +13,7 @@ static NEARDATA const char steeds[] = {
|
||||
};
|
||||
|
||||
STATIC_DCL boolean FDECL(landing_spot, (coord *, int, int));
|
||||
STATIC_DCL void FDECL(maybewakesteed, (struct monst *));
|
||||
|
||||
/* caller has decided that hero can't reach something while mounted */
|
||||
void
|
||||
@@ -136,6 +137,9 @@ use_saddle(otmp)
|
||||
if (otmp->cursed)
|
||||
chance -= 50;
|
||||
|
||||
/* [intended] steed becomes alert if possible */
|
||||
maybewakesteed(mtmp);
|
||||
|
||||
/* Make the attempt */
|
||||
if (rn2(100) < chance) {
|
||||
You("put the saddle on %s.", mon_nam(mtmp));
|
||||
@@ -172,16 +176,17 @@ doride()
|
||||
{
|
||||
boolean forcemount = FALSE;
|
||||
|
||||
if (u.usteed)
|
||||
if (u.usteed) {
|
||||
dismount_steed(DISMOUNT_BYCHOICE);
|
||||
else if (getdir((char *)0) && isok(u.ux+u.dx, u.uy+u.dy)) {
|
||||
} else if (getdir((char *)0) && isok(u.ux+u.dx, u.uy+u.dy)) {
|
||||
#ifdef WIZARD
|
||||
if (wizard && yn("Force the mount to succeed?") == 'y')
|
||||
if (wizard && yn("Force the mount to succeed?") == 'y')
|
||||
forcemount = TRUE;
|
||||
#endif
|
||||
return (mount_steed(m_at(u.ux+u.dx, u.uy+u.dy), forcemount));
|
||||
} else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -329,10 +334,11 @@ mount_steed(mtmp, force)
|
||||
}
|
||||
|
||||
/* Success */
|
||||
maybewakesteed(mtmp);
|
||||
if (!force) {
|
||||
if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
|
||||
/* Must have Lev_at_will at this point */
|
||||
pline("%s magically floats up!", Monnam(mtmp));
|
||||
/* Must have Lev_at_will at this point */
|
||||
pline("%s magically floats up!", Monnam(mtmp));
|
||||
You("mount %s.", mon_nam(mtmp));
|
||||
}
|
||||
/* setuwep handles polearms differently when you're mounted */
|
||||
@@ -620,6 +626,56 @@ dismount_steed(reason)
|
||||
return;
|
||||
}
|
||||
|
||||
/* when attempting to saddle or mount a sleeping steed, try to wake it up
|
||||
(for the saddling case, it won't be u.usteed yet) */
|
||||
STATIC_OVL void
|
||||
maybewakesteed(steed)
|
||||
struct monst *steed;
|
||||
{
|
||||
int frozen = (int) steed->mfrozen;
|
||||
boolean wasimmobile = steed->msleeping || !steed->mcanmove;
|
||||
|
||||
steed->msleeping = 0;
|
||||
if (frozen) {
|
||||
frozen = (frozen + 1) / 2; /* half */
|
||||
/* might break out of timed sleep or paralysis */
|
||||
if (!rn2(frozen)) {
|
||||
steed->mfrozen = 0;
|
||||
steed->mcanmove = 1;
|
||||
} else {
|
||||
/* didn't awake, but remaining duration is halved */
|
||||
steed->mfrozen = frozen;
|
||||
}
|
||||
}
|
||||
if (wasimmobile && !steed->msleeping && steed->mcanmove)
|
||||
pline("%s wakes up.", Monnam(steed));
|
||||
/* regardless of waking, terminate any meal in progress */
|
||||
finish_meating(steed);
|
||||
}
|
||||
|
||||
/* decide whether hero's steed is able to move;
|
||||
doesn't check for holding traps--those affect the hero directly */
|
||||
boolean
|
||||
stucksteed(checkfeeding)
|
||||
boolean checkfeeding;
|
||||
{
|
||||
struct monst *steed = u.usteed;
|
||||
|
||||
if (steed) {
|
||||
/* check whether steed can move */
|
||||
if (steed->msleeping || !steed->mcanmove) {
|
||||
pline("%s won't move!", upstart(y_monnam(steed)));
|
||||
return TRUE;
|
||||
}
|
||||
/* optionally check whether steed is in the midst of a meal */
|
||||
if (checkfeeding && steed->meating) {
|
||||
pline("%s is still eating.", upstart(y_monnam(steed)));
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
place_monster(mon, x, y)
|
||||
struct monst *mon;
|
||||
|
||||
Reference in New Issue
Block a user