new composite status conditions: weaponstatus,\
armorstatus, and terrainstatus This adds three special status items to show at a glance what the hero is wielding, wearing, and standing on. Each of the three items has its own boolean option rather than try to fix them in with the existing opttional status conditions. After a lot of testing, I think the weapon and armor ones will prove useful but the terrain one probably won't be. Presently it is implemented for tty and curses. When I developed it six years ago, it was also working for X11 but I'm not able to test the resurrection of that part so have left it out.
This commit is contained in:
118
src/hack.c
118
src/hack.c
@@ -3084,6 +3084,93 @@ invocation_message(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* for status: set up iflags.terrain_typ, an index into terrain_descrp[];
|
||||
some types need fixing up */
|
||||
void
|
||||
classify_terrain(void)
|
||||
{
|
||||
struct rm *lev = &levl[u.ux][u.uy];
|
||||
int typ = svl.lastseentyp[u.ux][u.uy]; /* lev->typ */
|
||||
|
||||
/*
|
||||
* If the terrain under the hero is different now from what it
|
||||
* was on the previous check, bring iflags.terrain_typ up to date
|
||||
* and request a status update. Unless hero is running--then the
|
||||
* update request will be suppressed.
|
||||
*/
|
||||
|
||||
if (Underwater) {
|
||||
typ = xSUBMERGED;
|
||||
} else {
|
||||
switch (typ) {
|
||||
case STONE:
|
||||
if (svl.level.flags.arboreal)
|
||||
typ = TREE;
|
||||
break;
|
||||
case CORR:
|
||||
case ROOM:
|
||||
/* this matches surface() but 'floor' is odd in many places */
|
||||
typ = !Is_earthlevel(&u.uz) ? xFLOOR : xGROUND;
|
||||
break;
|
||||
case DOOR:
|
||||
/* defaults to "doorway" (door-less or broken) */
|
||||
if ((lev->doormask & D_ISOPEN) != 0)
|
||||
typ = xOPENDOOR;
|
||||
else if ((lev->doormask & (D_CLOSED | D_LOCKED | D_TRAPPED)) != 0)
|
||||
typ = xSHUTDOOR;
|
||||
break;
|
||||
case DRAWBRIDGE_UP:
|
||||
/* ICE, MOAT, LAVA, or 'STONE' (which ought to be 'room') */
|
||||
typ = db_under_typ(lev->drawbridgemask);
|
||||
if (typ == STONE || typ == ROOM)
|
||||
typ = xGROUND;
|
||||
break;
|
||||
case MOAT:
|
||||
/* moat and swamp handling match waterbody_name()'s result */
|
||||
if (Is_medusa_level(&u.uz))
|
||||
typ = xSEA;
|
||||
else if (Is_juiblex_level(&u.uz))
|
||||
typ = xSWAMP;
|
||||
break;
|
||||
case WATER:
|
||||
if (!Is_waterlevel(&u.uz))
|
||||
typ = xWATERWALL;
|
||||
break;
|
||||
#if 0 /* don't bother -- Passes_walls for hero is rare, moving
|
||||
* from one type of wall to another even rarer, and the
|
||||
* cost of some extra once per move status updates is low */
|
||||
case VWALL:
|
||||
case HWALL:
|
||||
case TLCORNER:
|
||||
case TRCORNER:
|
||||
case BLCORNER:
|
||||
case BRCORNER:
|
||||
case CROSSWALL:
|
||||
case TUWALL:
|
||||
case TDWALL:
|
||||
case TLWALL:
|
||||
case TRWALL:
|
||||
case SDOOR: /* (note: lastseentyp[][] never yields SDOOR) */
|
||||
/* any wall type would do, terrain_descr[] is "Wall" for all;
|
||||
forcing just one avoids false 'changed' detection below if
|
||||
hero with Passes_walls ability moves from one to another */
|
||||
typ = VWALL;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (typ != iflags.terrain_typ) {
|
||||
/* terrain at hero's spot is different */
|
||||
iflags.terrain_typ = typ;
|
||||
/* request a status update unless hero is running */
|
||||
if (flags.terrainstatus && !svc.context.run)
|
||||
disp.botl = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* moving onto different terrain;
|
||||
might be going into solid rock, inhibiting levitation or flight,
|
||||
or coming back out of such, reinstating levitation/flying */
|
||||
@@ -3124,13 +3211,19 @@ switch_terrain(void)
|
||||
}
|
||||
if ((!!Levitation ^ was_levitating) || (!!Flying ^ was_flying))
|
||||
disp.botl = TRUE; /* update Lev/Fly status condition */
|
||||
|
||||
if (flags.terrainstatus)
|
||||
classify_terrain();
|
||||
}
|
||||
|
||||
/* set or clear u.uinwater */
|
||||
void
|
||||
set_uinwater(int in_out)
|
||||
{
|
||||
u.uinwater = in_out ? 1 : 0;
|
||||
if (in_out != u.uinwater) {
|
||||
u.uinwater = in_out ? 1 : 0;
|
||||
switch_terrain();
|
||||
}
|
||||
}
|
||||
|
||||
/* extracted from spoteffects; called by spoteffects to check for entering or
|
||||
@@ -3246,8 +3339,11 @@ spoteffects(boolean pick)
|
||||
spotterrain = levl[u.ux][u.uy].typ;
|
||||
spotloc.x = u.ux, spotloc.y = u.uy;
|
||||
|
||||
/* moving onto different terrain might cause Lev or Fly to toggle */
|
||||
if (spotterrain != levl[u.ux0][u.uy0].typ || !on_level(&u.uz, &u.uz0))
|
||||
/* moving onto different terrain might cause Lev or Fly to toggle;
|
||||
level change sets <ux0,uy0> to <ux,uy>, so this spotterrain
|
||||
check always fails then, but it also sets iflags.terrain_typ */
|
||||
if (spotterrain != levl[u.ux0][u.uy0].typ
|
||||
|| iflags.terrain_typ == MAX_TYPE)
|
||||
switch_terrain();
|
||||
|
||||
if (pooleffects(TRUE))
|
||||
@@ -4035,9 +4131,19 @@ end_running(boolean and_travel)
|
||||
{
|
||||
/* moveloop() suppresses time_botl when context.run is non-zero; when
|
||||
running stops, update 'time' even if other botl status is unchanged */
|
||||
if (flags.time && svc.context.run)
|
||||
disp.time_botl = TRUE;
|
||||
svc.context.run = 0;
|
||||
if (svc.context.run) {
|
||||
svc.context.run = 0;
|
||||
if (flags.time)
|
||||
disp.time_botl = TRUE;
|
||||
/* classify_terrain() suppresses setting disp.botl when
|
||||
running; after that, it can no longer compare current terrain
|
||||
against iflaga.terrain_typ to detect a change, so recompute */
|
||||
if (flags.terrainstatus) {
|
||||
iflags.terrain_typ = MAX_TYPE; /* "none of the above" value */
|
||||
classify_terrain();
|
||||
}
|
||||
}
|
||||
|
||||
/* 'context.mv' isn't travel but callers who want to end travel
|
||||
all clear it too */
|
||||
if (and_travel)
|
||||
|
||||
Reference in New Issue
Block a user