Add #wiztelekinesis for testing purposes

For testing mhurtle, which is used for jousting or
bare-handed combat.

Improve mhurtle_step to handle bumping into another monster,
and when the monster gets killed or stuck in a trap.
This commit is contained in:
Pasi Kallinen
2022-02-22 15:54:02 +02:00
parent e5c73d01fe
commit 268022e5de
4 changed files with 54 additions and 3 deletions

View File

@@ -83,7 +83,11 @@ enum trap_types {
};
/* some trap-related function return results */
enum { Trap_Effect_Finished = 0, Trap_Is_Gone = 0, Trap_Killed_Mon = 2 };
enum { Trap_Effect_Finished = 0,
Trap_Is_Gone = 0,
Trap_Caught_Mon = 1,
Trap_Killed_Mon = 2
};
#define is_pit(ttyp) ((ttyp) == PIT || (ttyp) == SPIKED_PIT)
#define is_hole(ttyp) ((ttyp) == HOLE || (ttyp) == TRAPDOOR)

View File

@@ -1221,6 +1221,39 @@ wiz_level_change(void)
return ECMD_OK;
}
/* #wiztelekinesis */
static int
wiz_telekinesis(void)
{
int ans = 0;
coord cc;
struct monst *mtmp = (struct monst *) 0;
cc.x = u.ux;
cc.y = u.uy;
pline("Pick a monster to hurtle.");
do {
if (mtmp && !DEADMONSTER(mtmp) && canseemon(mtmp)) {
cc.x = mtmp->mx;
cc.y = mtmp->my;
}
ans = getpos(&cc, TRUE, "a monster");
if (ans < 0 || cc.x < 0)
return ECMD_CANCEL;
if (((mtmp = m_at(cc.x, cc.y)) != 0) && canseemon(mtmp)) {
if (!getdir("which direction?"))
return ECMD_CANCEL;
mhurtle(mtmp, u.dx, u.dy, 6);
}
} while (TRUE);
return ECMD_OK;
}
/* #panic command - test program's panic handling */
static int
wiz_panic(void)
@@ -2421,6 +2454,8 @@ struct ext_func_tab extcmdlist[] = {
wiz_show_seenv, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL },
{ '\0', "wizsmell", "smell monster",
wiz_smell, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL },
{ '\0', "wiztelekinesis", "telekinesis",
wiz_telekinesis, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL },
{ '\0', "wizwhere", "show locations of special levels",
wiz_where, IFBURIED | AUTOCOMPLETE | WIZMODECMD, NULL },
{ C('w'), "wizwish", "wish for something",

View File

@@ -901,19 +901,30 @@ static boolean
mhurtle_step(genericptr_t arg, int x, int y)
{
struct monst *mon = (struct monst *) arg;
struct monst *mtmp;
/* TODO: Treat walls, doors, iron bars, pools, lava, etc. specially
* rather than just stopping before.
*/
if (goodpos(x, y, mon, 0) && m_in_out_region(mon, x, y)) {
int res;
remove_monster(mon->mx, mon->my);
newsym(mon->mx, mon->my);
place_monster(mon, x, y);
newsym(mon->mx, mon->my);
set_apparxy(mon);
(void) mintrap(mon);
res = mintrap(mon);
if (res == Trap_Killed_Mon || res == Trap_Caught_Mon)
return FALSE;
return TRUE;
}
if ((mtmp = m_at(x, y)) != 0 && (canseemon(mon) || canseemon(mtmp))) {
pline("%s bumps into %s.", Monnam(mon), a_monnam(mtmp));
wakeup(mon, !g.context.mon_moving);
wakeup(mtmp, !g.context.mon_moving);
}
return FALSE;
}

View File

@@ -3139,7 +3139,8 @@ mintrap(register struct monst *mtmp)
trap_result = trapeffect_selector(mtmp, trap, 0);
}
return (trap_result == Trap_Killed_Mon) ? trap_result : mtmp->mtrapped;
return (trap_result == Trap_Killed_Mon) ? trap_result
: mtmp->mtrapped ? Trap_Caught_Mon : Trap_Effect_Finished;
}
/* Combine cockatrice checks into single functions to avoid repeating code. */