Monster known traps bit twiddling

This commit is contained in:
Pasi Kallinen
2022-08-21 11:36:39 +03:00
parent 96e9534289
commit 953d43f5ac
10 changed files with 47 additions and 18 deletions

View File

@@ -1651,6 +1651,8 @@ extern boolean olfaction(struct permonst *);
unsigned long cvt_adtyp_to_mseenres(uchar);
extern void monstseesu(unsigned long);
extern boolean resist_conflict(struct monst *);
extern boolean mon_knows_traps(struct monst *, int);
extern void mon_learns_traps(struct monst *, int);
/* ### monmove.c ### */

View File

@@ -54,6 +54,7 @@ struct trap {
/* unconditional traps */
enum trap_types {
ALL_TRAPS = -1, /* mon_knows_traps(), mon_learns_traps() */
NO_TRAP = 0,
ARROW_TRAP = 1,
DART_TRAP = 2,

View File

@@ -1252,13 +1252,15 @@ makemon(
else
mtmp->female = femaleok ? rn2(2) : 0;
if (In_sokoban(&u.uz) && !mindless(ptr)) /* know about traps here */
mtmp->mtrapseen = (1L << (PIT - 1)) | (1L << (HOLE - 1));
if (In_sokoban(&u.uz) && !mindless(ptr)) { /* know about traps here */
mon_learns_traps(mtmp, PIT);
mon_learns_traps(mtmp, HOLE);
}
if (Is_stronghold(&u.uz) && !mindless(ptr)) /* know about the trap doors */
mtmp->mtrapseen = (1L << (TRAPDOOR - 1));
mon_learns_traps(mtmp, TRAPDOOR);
/* quest leader and nemesis both know about all trap types */
if (ptr->msound == MS_LEADER || ptr->msound == MS_NEMESIS)
mtmp->mtrapseen = ~0;
mon_learns_traps(mtmp, ALL_TRAPS);
place_monster(mtmp, x, y);
mtmp->mcansee = mtmp->mcanmove = TRUE;

View File

@@ -2075,7 +2075,7 @@ mfndpos(
&& !is_whirly(mdat) && !unsolid(mdat)))
&& (ttmp->ttyp != ANTI_MAGIC || !resists_magm(mon))) {
if (!(flag & ALLOW_TRAPS)) {
if (mon->mtrapseen & (1L << (ttmp->ttyp - 1)))
if (mon_knows_traps(mon, ttmp->ttyp))
continue;
}
info[cnt] |= ALLOW_TRAPS;

View File

@@ -1372,4 +1372,28 @@ resist_conflict(struct monst* mtmp)
return (rnd(20) > resist_chance);
}
/* does monster mtmp know traps of type ttyp */
boolean
mon_knows_traps(struct monst *mtmp, int ttyp)
{
if (ttyp == ALL_TRAPS)
return (boolean)(mtmp->mtrapseen);
else if (ttyp == NO_TRAP)
return !(boolean)(mtmp->mtrapseen);
else
return ((mtmp->mtrapseen & (1L << (ttyp - 1))) != 0);
}
/* monster mtmp learns all traps of type ttyp */
void
mon_learns_traps(struct monst *mtmp, int ttyp)
{
if (ttyp == ALL_TRAPS)
mtmp->mtrapseen = ~0L;
else if (ttyp == NO_TRAP)
mtmp->mtrapseen = 0L;
else
mtmp->mtrapseen |= (1L << (ttyp - 1));
}
/*mondata.c*/

View File

@@ -45,7 +45,7 @@ mb_trapped(struct monst *mtmp, boolean canseeit)
return TRUE;
/* will get here if lifesaved */
}
mtmp->mtrapseen |= (1 << (TRAPPED_DOOR - 1));
mon_learns_traps(mtmp, TRAPPED_DOOR);
return FALSE;
}
@@ -1945,7 +1945,7 @@ undesirable_disp(
/* Monsters avoid a trap if they've seen that type before */
} else if (trap && rn2(40)
&& (mtmp->mtrapseen & (1 << (trap->ttyp - 1))) != 0) {
&& mon_knows_traps(mtmp, trap->ttyp)) {
return TRUE;
}

View File

@@ -595,7 +595,7 @@ find_defensive(struct monst* mtmp, boolean tryescape)
* about teleport traps.
*/
if (!noteleport_level(mtmp)
|| !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
|| !mon_knows_traps(mtmp, TELEP_TRAP)) {
g.m.defensive = obj;
g.m.has_defense = (mon_has_amulet(mtmp))
? MUSE_WAN_TELEPORTATION
@@ -609,7 +609,7 @@ find_defensive(struct monst* mtmp, boolean tryescape)
&& !mtmp->isgd && !mtmp->ispriest))) {
/* see WAN_TELEPORTATION case above */
if (!noteleport_level(mtmp)
|| !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1)))) {
|| !mon_knows_traps(mtmp, TELEP_TRAP)) {
g.m.defensive = obj;
g.m.has_defense = MUSE_SCR_TELEPORTATION;
}
@@ -722,7 +722,7 @@ use_defensive(struct monst* mtmp)
makeknown(how);
/* monster learns that teleportation isn't useful here */
if (noteleport_level(mtmp))
mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
mon_learns_traps(mtmp, TELEP_TRAP);
return 2;
}
if ((mon_has_amulet(mtmp) || On_W_tower_level(&u.uz)) && !rn2(3)) {
@@ -741,7 +741,7 @@ use_defensive(struct monst* mtmp)
mbhit(mtmp, rn1(8, 6), mbhitm, bhito, otmp);
/* monster learns that teleportation isn't useful here */
if (noteleport_level(mtmp))
mtmp->mtrapseen |= (1 << (TELEP_TRAP - 1));
mon_learns_traps(mtmp, TELEP_TRAP);
g.m_using = FALSE;
return 2;
case MUSE_SCR_TELEPORTATION: {
@@ -1350,7 +1350,7 @@ find_offensive(struct monst* mtmp)
&& !Teleport_control
/* same hack as MUSE_WAN_TELEPORTATION_SELF */
&& (!noteleport_level(mtmp)
|| !(mtmp->mtrapseen & (1 << (TELEP_TRAP - 1))))
|| !mon_knows_traps(mtmp, TELEP_TRAP))
/* do try to move hero to a more vulnerable spot */
&& (onscary(u.ux, u.uy, mtmp)
|| (hero_behind_chokepoint(mtmp) && mon_has_friends(mtmp))

View File

@@ -245,7 +245,7 @@ priestini(
EPRI(priest)->shrpos.x = sx;
EPRI(priest)->shrpos.y = sy;
assign_level(&(EPRI(priest)->shrlevel), lvl);
priest->mtrapseen = ~0; /* traps are known */
mon_learns_traps(priest, ALL_TRAPS); /* traps are known */
priest->mpeaceful = 1;
priest->ispriest = 1;
priest->isminion = 0;
@@ -691,7 +691,7 @@ mk_roamer(struct permonst *ptr, aligntyp alignment, coordxy x, coordxy y,
EMIN(roamer)->renegade = (coaligned && !peaceful);
roamer->ispriest = 0;
roamer->isminion = 1;
roamer->mtrapseen = ~0; /* traps are known */
mon_learns_traps(roamer, ALL_TRAPS); /* traps are known */
roamer->mpeaceful = peaceful;
roamer->msleeping = 0;
set_malign(roamer); /* peaceful may have changed */

View File

@@ -641,7 +641,7 @@ shkinit(const struct shclass* shp, struct mkroom* sroom)
shk->isshk = shk->mpeaceful = 1;
set_malign(shk);
shk->msleeping = 0;
shk->mtrapseen = ~0; /* we know all the traps already */
mon_learns_traps(shk, ALL_TRAPS); /* we know all the traps already */
eshkp->shoproom = (schar) ((sroom - g.rooms) + ROOMOFFSET);
sroom->resident = shk;
eshkp->shoptype = sroom->rtype;

View File

@@ -2552,7 +2552,7 @@ dotrap(struct trap *trap, unsigned trflags)
}
if (u.usteed)
u.usteed->mtrapseen |= (1 << (ttype - 1));
mon_learns_traps(u.usteed, ttype);
/*
* Note:
@@ -3255,7 +3255,7 @@ mintrap(struct monst *mtmp, unsigned mintrapflags)
boolean forcetrap = ((mintrapflags & FORCETRAP) != 0);
boolean forcebungle = (mintrapflags & FORCEBUNGLE) != 0;
/* monster has seen such a trap before */
boolean already_seen = ((mtmp->mtrapseen & (1 << (tt - 1))) != 0
boolean already_seen = (mon_knows_traps(mtmp, tt)
|| (tt == HOLE && !mindless(mptr)));
if (mtmp == u.usteed) {
@@ -3270,7 +3270,7 @@ mintrap(struct monst *mtmp, unsigned mintrapflags)
return Trap_Effect_Finished;
}
mtmp->mtrapseen |= (1 << (tt - 1));
mon_learns_traps(mtmp, tt);
/* Monster is aggravated by being trapped by you.
Recognizing who made the trap isn't completely