int domindblast (void) { struct monst *mtmp, *nmon; if (u.uen < 10) { You("concentrate but lack the energy to maintain doing so."); return(0); } u.uen -= 10; You("concentrate."); pline("A wave of psychic energy pours out."); for(mtmp=fmon; mtmp; mtmp = nmon) { int u_sen; nmon = mtmp->nmon; if (DEADMONSTER(mtmp)) continue; if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) continue; if (mtmp->mpeaceful) continue; u_sen = telepathic(mtmp->data) && !mtmp->mcansee; if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) { You("lock in on %s %s.", "TODO: s_suffix(mon_nam(mtmp))", u_sen ? "telepathy" : telepathic(mtmp->data) ? "latent telepathy" : "mind"); mtmp->mhp -= rnd(15); if (mtmp->mhp <= 0) killed(mtmp); } } return 1; }
/* Returns an object slot mask giving all the reasons why the given player/monster might have the given property, limited by "reasons", an object slot mask (W_EQUIP, INTRINSIC, and ANY_PROPERTY are the most likely values here, but you can specify slots individually if you like). */ unsigned m_has_property(const struct monst *mon, enum youprop property, unsigned reasons, boolean even_if_blocked) { unsigned rv = 0; struct obj *otmp; /* The general case for equipment */ rv |= mworn_extrinsic(mon, property); if (mon == &youmonst) { /* Intrinsics */ if (u.uintrinsic[property] & TIMEOUT) rv |= W_MASK(os_timeout); rv |= u.uintrinsic[property] & (INTRINSIC | I_SPECIAL); /* Birth options */ if (property == BLINDED && flags.permablind) rv |= W_MASK(os_birthopt); if (property == HALLUC && flags.permahallu) rv |= W_MASK(os_birthopt); if (property == UNCHANGING && flags.polyinit_mnum != -1) rv |= W_MASK(os_birthopt); } else { /* Monster tempraries are boolean flags. TODO: Monsters with no eyes are not considered blind. This doesn't make much sense. However, changing it would be a major balance change (due to Elbereth), and so it has been left alone for now. */ if (property == BLINDED && (!mon->mcansee || mon->mblinded)) rv |= W_MASK(os_timeout); if (property == FAST && mon->mspeed == MFAST) rv |= (mon->permspeed == FAST ? W_MASK(os_polyform) : W_MASK(os_outside)); if (property == INVIS && mon->perminvis && !pm_invisible(mon->data)) rv |= W_MASK(os_outside); if (property == STUNNED && mon->mstun) rv |= W_MASK(os_timeout); if (property == CONFUSION && mon->mconf) rv |= W_MASK(os_timeout); } /* Polyform / monster intrinsic */ /* TODO: Change the monster data code into something that doesn't require a giant switch statement or ternary chain to get useful information from it. We use a ternary chain here because it cuts down on repetitive code and so is easier to read. */ if (property == FIRE_RES ? resists_fire(mon) : property == COLD_RES ? resists_cold(mon) : property == SLEEP_RES ? resists_sleep(mon) : property == DISINT_RES ? resists_disint(mon) : property == SHOCK_RES ? resists_elec(mon) : property == POISON_RES ? resists_poison(mon) : property == DRAIN_RES ? resists_drli(mon) : property == SICK_RES ? mon->data->mlet == S_FUNGUS || mon->data == &mons[PM_GHOUL] : property == ANTIMAGIC ? resists_magm(mon) : property == ACID_RES ? resists_acid(mon) : property == STONE_RES ? resists_ston(mon) : property == STUNNED ? u.umonnum == PM_STALKER || mon->data->mlet == S_BAT : property == BLINDED ? !haseyes(mon->data) : property == HALLUC ? Upolyd && dmgtype(mon->data, AD_HALU) : property == SEE_INVIS ? perceives(mon->data) : property == TELEPAT ? telepathic(mon->data) : property == INFRAVISION ? infravision(mon->data) : /* Note: This one assumes that there's no way to permanently turn visible when you're in stalker form (i.e. mummy wrappings only). */ property == INVIS ? pm_invisible(mon->data) : property == TELEPORT ? can_teleport(mon->data) : property == LEVITATION ? is_floater(mon->data) : property == FLYING ? is_flyer(mon->data) : property == SWIMMING ? is_swimmer(mon->data) : property == PASSES_WALLS ? passes_walls(mon->data) : property == REGENERATION ? regenerates(mon->data) : property == REFLECTING ? mon->data == &mons[PM_SILVER_DRAGON] : property == TELEPORT_CONTROL ? control_teleport(mon->data) : property == MAGICAL_BREATHING ? amphibious(mon->data) : 0) rv |= W_MASK(os_polyform); if (mon == &youmonst) { /* External circumstances */ if (property == BLINDED && u_helpless(hm_unconscious)) rv |= W_MASK(os_circumstance); /* Riding */ if (property == FLYING && u.usteed && is_flyer(u.usteed->data)) rv |= W_MASK(os_saddle); if (property == SWIMMING && u.usteed && is_swimmer(u.usteed->data)) rv |= W_MASK(os_saddle); } /* Overrides */ if (!even_if_blocked) { if (property == BLINDED) { for (otmp = m_minvent(mon); otmp; otmp = otmp->nobj) if (otmp->oartifact == ART_EYES_OF_THE_OVERWORLD && otmp->owornmask & W_MASK(os_tool)) rv &= (unsigned)(W_MASK(os_circumstance) | W_MASK(os_birthopt)); } if (property == WWALKING && Is_waterlevel(m_mz(mon))) rv &= (unsigned)(W_MASK(os_birthopt)); if (mworn_blocked(mon, property)) rv &= (unsigned)(W_MASK(os_birthopt)); } return rv & reasons; }