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)
|
fix some unreachable messages (either make then reachable or remove them)
|
||||||
can quiver coins when GOLDOBJ is defined
|
can quiver coins when GOLDOBJ is defined
|
||||||
grammar, spelling and other typos
|
grammar, spelling and other typos
|
||||||
oracle and rumor regarding priestly donations
|
|
||||||
keep various delayed killers separate to avoid mixed up messages
|
keep various delayed killers separate to avoid mixed up messages
|
||||||
don't place randomly-placed aquatic monsters in lava on special levels
|
don't place randomly-placed aquatic monsters in lava on special levels
|
||||||
hiding monsters don't hide under cockatrice/chickatrice corpses
|
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
|
nurses are affected if player is polymorphed as a cockatrice
|
||||||
getting a particular rotten food result can't make attempting to eat a
|
getting a particular rotten food result can't make attempting to eat a
|
||||||
corpse of one of the Riders be survivable
|
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
|
Platform- and/or Interface-Specific Fixes
|
||||||
@@ -248,6 +248,7 @@ add Malcolm Ryan's Statue Glyphs patch
|
|||||||
lembas and cram never rot unless cursed
|
lembas and cram never rot unless cursed
|
||||||
multiple squeaks for squeaky boards
|
multiple squeaks for squeaky boards
|
||||||
include time, user ID, and play mode in paniclog entries
|
include time, user ID, and play mode in paniclog entries
|
||||||
|
add oracle and rumor regarding priestly donations
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific New Features
|
Platform- and/or Interface-Specific New Features
|
||||||
|
|||||||
@@ -2101,6 +2101,7 @@ E void NDECL(exercise_steed);
|
|||||||
E void NDECL(kick_steed);
|
E void NDECL(kick_steed);
|
||||||
E void FDECL(dismount_steed, (int));
|
E void FDECL(dismount_steed, (int));
|
||||||
E void FDECL(place_monster, (struct monst *,int,int));
|
E void FDECL(place_monster, (struct monst *,int,int));
|
||||||
|
E boolean FDECL(stucksteed, (BOOLEAN_P));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ### teleport.c ### */
|
/* ### teleport.c ### */
|
||||||
|
|||||||
18
src/do.c
18
src/do.c
@@ -755,13 +755,9 @@ dodown()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (u.usteed && !u.usteed->mcanmove) {
|
if (stucksteed(TRUE)) {
|
||||||
pline("%s won't move!", Monnam(u.usteed));
|
return 0;
|
||||||
return(0);
|
}
|
||||||
} else if (u.usteed && u.usteed->meating) {
|
|
||||||
pline("%s is still eating.", Monnam(u.usteed));
|
|
||||||
return(0);
|
|
||||||
} else
|
|
||||||
#endif
|
#endif
|
||||||
if (Levitation) {
|
if (Levitation) {
|
||||||
if ((HLevitation & I_SPECIAL) || (ELevitation & W_ARTI)) {
|
if ((HLevitation & I_SPECIAL) || (ELevitation & W_ARTI)) {
|
||||||
@@ -875,13 +871,9 @@ doup()
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (u.usteed && !u.usteed->mcanmove) {
|
if (stucksteed(TRUE)) {
|
||||||
pline("%s won't move!", Monnam(u.usteed));
|
|
||||||
return(0);
|
return(0);
|
||||||
} else if (u.usteed && u.usteed->meating) {
|
}
|
||||||
pline("%s is still eating.", Monnam(u.usteed));
|
|
||||||
return(0);
|
|
||||||
} else
|
|
||||||
#endif
|
#endif
|
||||||
if(u.ustuck) {
|
if(u.ustuck) {
|
||||||
You("are %s, and cannot go up.",
|
You("are %s, and cannot go up.",
|
||||||
|
|||||||
@@ -1221,11 +1221,10 @@ domove()
|
|||||||
}
|
}
|
||||||
/* not attacking an animal, so we try to move */
|
/* not attacking an animal, so we try to move */
|
||||||
#ifdef STEED
|
#ifdef STEED
|
||||||
if (u.usteed && !u.usteed->mcanmove && (u.dx || u.dy)) {
|
if ((u.dx || u.dy) && stucksteed(FALSE)) {
|
||||||
pline("%s won't move!", upstart(y_monnam(u.usteed)));
|
|
||||||
nomul(0);
|
nomul(0);
|
||||||
return;
|
return;
|
||||||
} else
|
}
|
||||||
#endif
|
#endif
|
||||||
if(!youmonst.data->mmove) {
|
if(!youmonst.data->mmove) {
|
||||||
You("are rooted %s.",
|
You("are rooted %s.",
|
||||||
|
|||||||
@@ -1277,7 +1277,7 @@ int amt, how;
|
|||||||
(how >= 0 && resist(mon, (char)how, 0, NOTELL))) {
|
(how >= 0 && resist(mon, (char)how, 0, NOTELL))) {
|
||||||
shieldeff(mon->mx, mon->my);
|
shieldeff(mon->mx, mon->my);
|
||||||
} else if (mon->mcanmove) {
|
} else if (mon->mcanmove) {
|
||||||
mon->meating = 0; /* terminate any meal-in-progress */
|
finish_meating(mon); /* terminate any meal-in-progress */
|
||||||
amt += (int) mon->mfrozen;
|
amt += (int) mon->mfrozen;
|
||||||
if (amt > 0) { /* sleep for N turns */
|
if (amt > 0) { /* sleep for N turns */
|
||||||
mon->mcanmove = 0;
|
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. */
|
/* Copyright (c) Kevin Hugo, 1998-1999. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* 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 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 */
|
/* caller has decided that hero can't reach something while mounted */
|
||||||
void
|
void
|
||||||
@@ -136,6 +137,9 @@ use_saddle(otmp)
|
|||||||
if (otmp->cursed)
|
if (otmp->cursed)
|
||||||
chance -= 50;
|
chance -= 50;
|
||||||
|
|
||||||
|
/* [intended] steed becomes alert if possible */
|
||||||
|
maybewakesteed(mtmp);
|
||||||
|
|
||||||
/* Make the attempt */
|
/* Make the attempt */
|
||||||
if (rn2(100) < chance) {
|
if (rn2(100) < chance) {
|
||||||
You("put the saddle on %s.", mon_nam(mtmp));
|
You("put the saddle on %s.", mon_nam(mtmp));
|
||||||
@@ -172,16 +176,17 @@ doride()
|
|||||||
{
|
{
|
||||||
boolean forcemount = FALSE;
|
boolean forcemount = FALSE;
|
||||||
|
|
||||||
if (u.usteed)
|
if (u.usteed) {
|
||||||
dismount_steed(DISMOUNT_BYCHOICE);
|
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
|
#ifdef WIZARD
|
||||||
if (wizard && yn("Force the mount to succeed?") == 'y')
|
if (wizard && yn("Force the mount to succeed?") == 'y')
|
||||||
forcemount = TRUE;
|
forcemount = TRUE;
|
||||||
#endif
|
#endif
|
||||||
return (mount_steed(m_at(u.ux+u.dx, u.uy+u.dy), forcemount));
|
return (mount_steed(m_at(u.ux+u.dx, u.uy+u.dy), forcemount));
|
||||||
} else
|
} else {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,10 +334,11 @@ mount_steed(mtmp, force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Success */
|
/* Success */
|
||||||
|
maybewakesteed(mtmp);
|
||||||
if (!force) {
|
if (!force) {
|
||||||
if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
|
if (Levitation && !is_floater(ptr) && !is_flyer(ptr))
|
||||||
/* Must have Lev_at_will at this point */
|
/* Must have Lev_at_will at this point */
|
||||||
pline("%s magically floats up!", Monnam(mtmp));
|
pline("%s magically floats up!", Monnam(mtmp));
|
||||||
You("mount %s.", mon_nam(mtmp));
|
You("mount %s.", mon_nam(mtmp));
|
||||||
}
|
}
|
||||||
/* setuwep handles polearms differently when you're mounted */
|
/* setuwep handles polearms differently when you're mounted */
|
||||||
@@ -620,6 +626,56 @@ dismount_steed(reason)
|
|||||||
return;
|
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
|
void
|
||||||
place_monster(mon, x, y)
|
place_monster(mon, x, y)
|
||||||
struct monst *mon;
|
struct monst *mon;
|
||||||
|
|||||||
Reference in New Issue
Block a user