1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2024-11-21 16:55:06 +00:00
notnotdnethack/include/mondata.h
Ron Nazarov d848fa3230
Make all gnomes start with medium hats and allow wearing them
Including the hat in the mad stuff box.

Any hat can now be worn even if it's one size too large (huge ->
gigantic counts as 3 sizes for the purposes of this calculation).
2024-10-10 19:46:37 +01:00

1581 lines
79 KiB
C

/* SCCS Id: @(#)mondata.h 3.4 2003/01/08 */
/* Copyright (c) 1989 Mike Threepoint */
/* NetHack may be freely redistributed. See license for details. */
#ifndef MONDATA_H
#define MONDATA_H
#define verysmall(ptr) ((ptr)->msize < MZ_SMALL)
#define bigmonst(ptr) ((ptr)->msize >= MZ_LARGE)
#define MON_BAB(mon) ((mon)->data->mflagsf&MF_BAB_FULL ? 1.0 : (mon)->data->mflagsf&MF_BAB_HALF ? .5 : .75)
#define lev_limit_30(ptr) ((ptr)->mflagsf&MF_LEVEL_30)
#define lev_limit_45(ptr) ((ptr)->mflagsf&MF_LEVEL_45)
#define has_phys_scaling(ptr) ((ptr)->mflagsf&MF_PHYS_SCALING)
#define pm_resistance(ptr,typ) (((ptr)->mresists & (typ)) != 0)
#define mon_intrinsic(mon,typ) (((mon)->mintrinsics[((typ)-1)/32] & (0x1L << ((typ)-1)%32)) != 0)
#define mon_extrinsic(mon,typ) (((mon)->mextrinsics[((typ)-1)/32] & (0x1L << ((typ)-1)%32)) != 0)
#define mon_acquired_trinsic(mon,typ) (((mon)->acquired_trinsics[((typ)-1)/32] & (0x1L << ((typ)-1)%32)) != 0)
#define mon_resistance(mon,typ) (mon_intrinsic(mon,typ) || mon_extrinsic(mon,typ) || (typ == SWIMMING && Is_waterlevel(&u.uz)) || \
(typ == TELEPORT && mad_monster_turn(mon, MAD_NON_EUCLID) && !(mon)->mpeaceful) || (typ == TELEPORT_CONTROL && mad_monster_turn(mon, MAD_NON_EUCLID)) || \
(typ == TELEPAT && mon != &youmonst && !mindless((mon)->data) && uarmh && uarmh->oartifact == ART_ENFORCED_MIND && distu((mon)->mx, (mon)->my) <= etele_dist))
#define species_resists_fire(mon) (((mon)->data->mresists & MR_FIRE) != 0)
#define species_resists_cold(mon) (((mon)->data->mresists & MR_COLD) != 0)
#define species_resists_sleep(mon) (((mon)->data->mresists & MR_SLEEP) != 0)
#define species_resists_disint(mon) (((mon)->data->mresists & MR_DISINT) != 0)
#define species_resists_elec(mon) (((mon)->data->mresists & MR_ELEC) != 0)
#define species_resists_poison(mon) (((mon)->data->mresists & MR_POISON) != 0)
#define species_resists_acid(mon) (((mon)->data->mresists & MR_ACID) != 0)
#define species_resists_ston(mon) (((mon)->data->mresists & MR_STONE) != 0)
#define species_resists_drain(mon) (((mon)->data->mresists & MR_DRAIN) != 0)
#define species_resists_sickness(mon) (((mon)->data->mresists & MR_SICK) != 0)
#define species_resists_magic(mon) (((mon)->data->mresists & MR_MAGIC) != 0)
#define species_reflects(mon) (((mon)->data->mresists & MR_REFLECT) != 0)
#define resist_attacks(ptr) ((((ptr)->mflagsg & MG_WRESIST) != 0L))
#define resist_blunt(ptr) ((((ptr)->mflagsg & MG_RBLUNT) != 0L))
#define resist_slash(ptr) ((((ptr)->mflagsg & MG_RSLASH) != 0L))
#define resist_pierce(ptr) ((((ptr)->mflagsg & MG_RPIERCE) != 0L))
#define resists_all(ptr) ((((ptr)->mflagsg & MG_RALL) == MG_RALL))
#define vulnerable_mask(mask) ((!((mask)&SLASH)+!((mask)&PIERCE)+!((mask)&WHACK)) == 1)
#define resists_poly(ptr) (((ptr)->geno&G_UNIQ) \
|| is_weeping(ptr) \
|| (ptr)->mtyp == PM_VERMIURGE \
|| (ptr)->mtyp == PM_TWIN_SIBLING \
|| is_yochlol(ptr))
#define resists_confusion(ptr) (((ptr)->geno&G_UNIQ) || is_weeping(ptr) || is_yochlol(ptr))
#define is_blind(mon) (!((mon)->mcansee) || (darksight((mon)->data) && !(\
(!levl[(mon)->mx][(mon)->my].lit && !(viz_array[(mon)->my][(mon)->mx]&TEMP_LIT1 && !(viz_array[(mon)->my][(mon)->mx]&TEMP_DRK1)))\
|| (levl[(mon)->mx][(mon)->my].lit && (viz_array[(mon)->my][(mon)->mx]&TEMP_DRK1 && !(viz_array[(mon)->my][(mon)->mx]&TEMP_LIT1))))))
#define is_deaf(mon) (!((mon)->mcanhear) ||\
(mon)->mtyp == PM_NUPPERIBO ||\
(mon)->mtyp == PM_APHANACTONAN_ASSESSOR ||\
(mon)->mtyp == PM_ALABASTER_ELF ||\
(mon)->mtyp == PM_ALABASTER_ELF_ELDER)
#define has_template(mon, id) ((mon)->mtemplate == (id))
#define templated(mon) ((mon)->mtemplate != 0)
#define get_template(mon) ((mon)->mtemplate)
#define is_molochan(ptr) ((ptr)->maligntyp == MON_A_NONE)
#define is_voidalign(ptr) ((ptr)->maligntyp == MON_A_VOID)
#define is_lawful(ptr) ((ptr)->maligntyp > A_NEUTRAL && !is_molochan(ptr) && !is_voidalign(ptr))
#define is_lawful_mon(mon) (HAS_EPRI(mon) ? EPRI(mon)->shralign == A_LAWFUL :\
HAS_EMIN(mon) ? EMIN(mon)->min_align == A_LAWFUL :\
is_lawful((mon)->data))
#define is_neutral(ptr) ((ptr)->maligntyp == A_NEUTRAL)
#define is_neutral_mon(mon) (HAS_EPRI(mon) ? EPRI(mon)->shralign == A_NEUTRAL :\
HAS_EMIN(mon) ? EMIN(mon)->min_align == A_NEUTRAL :\
is_neutral((mon)->data))
#define is_chaotic(ptr) ((ptr)->maligntyp < A_NEUTRAL && !is_molochan(ptr) && !is_voidalign(ptr))
#define is_chaotic_mon(mon) (HAS_EPRI(mon) ? EPRI(mon)->shralign == A_CHAOTIC :\
HAS_EMIN(mon) ? EMIN(mon)->min_align == A_CHAOTIC :\
is_chaotic((mon)->data))
#define is_alabaster_mummy(ptr) ((ptr)->mtyp == PM_ALABASTER_MUMMY)
#define is_ent(ptr) ((ptr)->mtyp == PM_ENT)
#define is_ent_species(ptr, species) (is_ent(ptr) && u.ent_species == species)
#define is_ancient_body_ent(ptr, species) (is_ent(ptr) && (species == ENT_ASH || species == ENT_BLUEGUM || species == ENT_ELM \
|| species == ENT_LOCUST || species == ENT_METHUSELAH || species == ENT_REDWOOD))
#define is_ancient_knowledge_ent(ptr, species) (is_ent(ptr) && (species == ENT_ELDER || species == ENT_OAK || species == ENT_WILLOW \
|| species == ENT_YEW))
#define is_beautiful_scent_ent(ptr, species) (is_ent(ptr) && (species == ENT_CHESTNUT || species == ENT_DOGWOOD || species == ENT_MAGNOLIA \
|| species == ENT_POPLAR))
#define is_coniferous_ent(ptr, species) (is_ent(ptr) && (species == ENT_CEDAR || species == ENT_CYPRESS || species == ENT_FIR \
|| species == ENT_METHUSELAH || species == ENT_REDWOOD || species == ENT_YEW))
#define is_decidious_ent(ptr, species) (is_ent(ptr) && (species == ENT_ASH || species == ENT_BEECH || species == ENT_BIRCH \
|| species == ENT_BLUEGUM || species == ENT_CHESTNUT || species == ENT_DOGWOOD || species == ENT_ELDER \
|| species == ENT_ELM || species == ENT_GINKGO || species == ENT_LARCH || species == ENT_LOCUST \
|| species == ENT_MAGNOLIA || species == ENT_MAPLE || species == ENT_MIMOSA || species == ENT_OAK \
|| species == ENT_POPLAR || species == ENT_WILLOW))
#define is_fast_healing_ent(ptr, species) (is_ent(ptr) && (species == ENT_ASH || species == ENT_BEECH || species == ENT_BIRCH \
|| species == ENT_CEDAR || species == ENT_ELDER || species == ENT_ELM || species == ENT_FIR || species == ENT_LARCH \
|| species == ENT_GINKGO || species == ENT_MAPLE || species == ENT_OAK || species == ENT_YEW))
#define is_powerful_build_ent(ptr, species) (is_ent(ptr) && (species == ENT_BLUEGUM || species == ENT_CHESTNUT || species == ENT_GINKGO \
|| species == ENT_LOCUST || species == ENT_MAGNOLIA || species == ENT_OAK || species == ENT_REDWOOD))
#define is_spry_ent(ptr, species) (is_ent(ptr) && (species == ENT_CYPRESS || species == ENT_FIR || species == ENT_POPLAR || species == ENT_SPRUCE || species == ENT_DOGWOOD || species == ENT_ELM))
#define is_lminion(mon) (is_minion((mon)->data) && is_lawful_mon(mon))
#define is_nminion(mon) (is_minion((mon)->data) && is_neutral_mon(mon))
#define is_cminion(mon) (is_minion((mon)->data) && is_chaotic_mon(mon))
#define notonline(ptr) (((ptr)->mflagsm & MM_NOTONL) != 0L)
#define fleetflee(ptr) (((ptr)->mflagsm & MM_FLEETFLEE) != 0L)
#define bold(ptr) (((ptr)->mflagst & MT_BOLD) != 0L)
#define is_clinger(ptr) (((ptr)->mflagsm & MM_CLING) != 0L)
#define species_flies(ptr) (((ptr)->mflagsm & MM_FLY) != 0L)
#define species_displaces(ptr) (((ptr)->mflagsg & MG_DISPLACEMENT) != 0L)
#define species_floats(ptr) (((ptr)->mflagsm & MM_FLOAT) != 0L)
#define species_swims(ptr) (((ptr)->mflagsm & MM_SWIM) != 0L)
#define species_tears_webs(ptr) (((ptr)->mflagsm & MM_WEBRIP) != 0L)
#define species_busts_doors(ptr) (((ptr)->mflagsm & MM_DOORBUST) != 0L)
#define is_suicidal(ptr) (is_fern_spore(ptr) || \
(ptr)->mtyp == PM_FREEZING_SPHERE || \
(ptr)->mtyp == PM_FLAMING_SPHERE || \
(ptr)->mtyp == PM_SHOCKING_SPHERE)
#define breathless(ptr) (((ptr)->mflagsm & MM_BREATHLESS) != 0L)
#define breathless_mon(mon) (breathless((mon)->data) || mon_resistance((mon), MAGICAL_BREATHING))
#define amphibious(ptr) (((ptr)->mflagsm & (MM_AMPHIBIOUS | MM_BREATHLESS)) != 0L)
#define amphibious_mon(mon) (amphibious((mon)->data) || mon_resistance((mon), MAGICAL_BREATHING) || mon_resistance((mon), SWIMMING))
#define species_passes_walls(ptr) (((ptr)->mflagsm & MM_WALLWALK) != 0L)
#define amorphous(ptr) (((ptr)->mflagsm & MM_AMORPHOUS) != 0L)
#define noncorporeal(ptr) ((ptr)->mlet == S_GHOST || (ptr)->mlet == S_SHADE)
#define insubstantial(ptr) (((ptr)->mflagsb & MB_INSUBSTANTIAL) != 0L)
#define tunnels(ptr) (((ptr)->mflagsm & MM_TUNNEL) != 0L)
#define needspick(ptr) (((ptr)->mflagsm & MM_NEEDPICK) != 0L)
#define is_underswimmer(ptr) ((ptr)->mlet == S_EEL || (ptr)->mtyp == PM_CRYSTAL_OOZE)
#define hides_under(ptr) (((ptr)->mflagst & MT_CONCEAL) != 0L)
#define is_hider(ptr) (((ptr)->mflagst & MT_HIDE) != 0L)
#define is_backstabber(ptr) (((ptr)->mflagsg & MG_BACKSTAB) != 0L)
#define is_commander(ptr) (((ptr)->mflagsg & MG_COMMANDER) != 0L)
/*#define haseyes(ptr) (((ptr)->mflagsb & MB_NOEYES) == 0L) when did this get duplicated???*/
#define haseyes(ptr) (((ptr)->mflagsb & MB_NOEYES) == 0L)
#define nomouth(mtyp) (mtyp==PM_NIGHTGAUNT || mtyp==PM_STRANGER || mtyp==PM_SUZERAIN || mtyp==PM_CARCOSAN_COURTIER)
#define goodsmeller(ptr) (((ptr)->mflagsv & MV_SCENT) != 0L)
#define is_tracker(ptr) (((ptr)->mflagsg & MG_TRACKER) != 0L)
#define eyecount(ptr) (!haseyes(ptr) ? 0 : \
((ptr)->mtyp == PM_CYCLOPS || \
(ptr)->mtyp == PM_MONOTON || \
(ptr)->mtyp == PM_FLOATING_EYE) ? 1 : 2)
#define sensitive_ears(ptr) (((ptr)->mflagsv & MV_ECHOLOCATE) != 0L || (ptr)->mtyp == PM_APHANACTONAN_AUDIENT)
#define nohands(ptr) (((ptr)->mflagsb & (MB_NOHANDS|MB_NOLIMBS)) != 0L)
#define nolimbs(ptr) (((ptr)->mflagsb & MB_NOLIMBS) == MB_NOLIMBS)
#define nofeet(ptr) ((ptr)->mflagsb & MB_NOFEET)
#define nogloves(ptr) (nohands(ptr) || ((ptr)->mflagsb & MB_NOGLOVES))
#define nohat(ptr) (!has_head(ptr) || ((ptr)->mflagsb & MB_NOHAT))
#define noshield(ptr) ((nogloves(ptr) && !allow_shield(ptr)) || ptr->mtyp == PM_CARCOSAN_COURTIER)
#define notake(ptr) (((ptr)->mflagst & MT_NOTAKE) != 0L)
#define has_head(ptr) (((ptr)->mflagsb & MB_NOHEAD) == 0L)
#define has_head_mon(mon) ((mon == &youmonst) ? (has_head(youracedata)) : (has_head((mon)->data)))
#define has_horns(ptr) (num_horns(ptr) > 0)
#define is_whirly(ptr) ((ptr)->mlet == S_VORTEX || \
(ptr)->mtyp == PM_AIR_ELEMENTAL ||\
(ptr)->mtyp == PM_ILLURIEN_OF_THE_MYRIAD_GLIMPSES ||\
(ptr)->mtyp == PM_DREADBLOSSOM_SWARM)
#define has_passthrough_displacement(ptr) ((ptr)->mtyp == PM_WRAITHWORM ||\
(ptr)->mtyp == PM_FIRST_WRAITHWORM)
#define flaming(ptr) ((ptr)->mtyp == PM_FIRE_VORTEX || \
(ptr)->mtyp == PM_FLAMING_SPHERE || \
(ptr)->mtyp == PM_FIRE_ELEMENTAL || \
(ptr)->mtyp == PM_FIRE_STORM || \
(ptr)->mtyp == PM_FLAMING_ORB || \
(ptr)->mtyp == PM_HELLFIRE_COLOSSUS || \
(ptr)->mtyp == PM_HELLFIRE_ORB || \
(ptr)->mtyp == PM_DANCING_FLAME || \
(ptr)->mtyp == PM_BALL_OF_GOSSAMER_SUNLIGHT || \
(ptr)->mtyp == PM_ANCIENT_OF_THE_BURNING_WASTES || \
(ptr)->mtyp == PM_FIERNA || \
(ptr)->mtyp == PM_MOLEK || \
(ptr)->mtyp == PM_SALAMANDER)
#define is_gold(ptr) ((ptr)->mtyp == PM_GOLD_GOLEM || \
(ptr)->mtyp == PM_GOLDEN_HEART || \
(ptr)->mtyp == PM_TREASURY_GOLEM || \
(ptr)->mtyp == PM_AURUMACH_RILMANI || \
(ptr)->mtyp == PM_ARA_KAMEREL || \
(ptr)->mtyp == PM_ACERERAK || \
(ptr)->mtyp == PM_RADIANT_PYRAMID)
#define is_iron(ptr) ((ptr)->mtyp == PM_IRON_PIERCER || \
(ptr)->mtyp == PM_IRON_GOLEM || \
(ptr)->mtyp == PM_GREEN_STEEL_GOLEM || \
(ptr)->mtyp == PM_CHAIN_GOLEM || \
(ptr)->mtyp == PM_SCRAP_TITAN || \
(ptr)->mtyp == PM_HELLFIRE_COLOSSUS || \
(ptr)->mtyp == PM_HELLFIRE_ORB || \
(ptr)->mtyp == PM_FERRUMACH_RILMANI)
#define is_iron_mon(mon) (is_iron((mon)->data))
#define is_silver(ptr) ((ptr)->mtyp == PM_ARGENACH_RILMANI || \
(ptr)->mtyp == PM_AMM_KAMEREL || \
(ptr)->mtyp == PM_ARGENTUM_GOLEM)
#define is_silver_mon(mon) (is_silver((mon)->data) || has_template(mon, CONSTELLATION))
#define is_stone(ptr) ((ptr)->mtyp == PM_DUST_VORTEX || \
(ptr)->mtyp == PM_EARTH_ELEMENTAL || \
(ptr)->mtyp == PM_TERRACOTTA_SOLDIER || \
(ptr)->mtyp == PM_STONE_GOLEM || \
(ptr)->mtyp == PM_SHIRO || \
(ptr)->mtyp == PM_SENTINEL_OF_MITHARDIR || \
(ptr)->mtyp == PM_GARGOYLE || \
(ptr)->mtyp == PM_WINGED_GARGOYLE || \
(ptr)->mtyp == PM_XORN)
#define is_anhydrous(ptr) (flaming(ptr) || \
is_clockwork(ptr) || \
is_stone(ptr) || \
is_auton(ptr) || \
(ptr)->mlet == S_KETER || \
(ptr)->mtyp == PM_AOA || \
(ptr)->mtyp == PM_AOA_DROPLET)
#define is_watery(ptr) ((ptr)->mtyp == PM_WATER_ELEMENTAL \
|| (ptr)->mtyp == PM_FORD_ELEMENTAL \
|| (ptr)->mtyp == PM_WATER_DOLPHIN \
|| (ptr)->mtyp == PM_WATERSPOUT \
|| (ptr)->mtyp == PM_UISCERRE_ELADRIN \
|| (ptr)->mtyp == PM_FOG_CLOUD \
|| (ptr)->mtyp == PM_STEAM_VORTEX \
|| (ptr)->mtyp == PM_ANCIENT_TEMPEST \
|| (ptr)->mtyp == PM_MORTAI \
|| (ptr)->mtyp == PM_HUDOR_KAMEREL \
|| (ptr)->mtyp == PM_LETHE_ELEMENTAL \
|| (ptr)->mtyp == PM_DAUGHTER_OF_NAUNET \
)
#define is_uvuudaum(ptr) ((ptr)->mtyp == PM_UVUUDAUM \
|| (ptr)->mtyp == PM_MASKED_QUEEN \
)
#define is_witch_mon(mon) ((mon)->mtyp == PM_APPRENTICE_WITCH \
|| (mon)->mtyp == PM_WITCH \
|| (mon)->mtyp == PM_COVEN_LEADER \
)
#define removed_innards(ptr) (((ptr)->mtyp == PM_HUNGRY_DEAD) || \
((ptr)->mtyp == PM_KOBOLD_MUMMY) || \
((ptr)->mtyp == PM_GNOME_MUMMY) || \
((ptr)->mtyp == PM_ORC_MUMMY) || \
((ptr)->mtyp == PM_DWARF_MUMMY) || \
((ptr)->mtyp == PM_ELF_MUMMY) || \
((ptr)->mtyp == PM_HUMAN_MUMMY) || \
((ptr)->mtyp == PM_HALF_DRAGON_MUMMY) || \
((ptr)->mtyp == PM_ETTIN_MUMMY) || \
((ptr)->mtyp == PM_CHIROPTERAN_MUMMY) || \
((ptr)->mtyp == PM_GIANT_MUMMY) || \
((ptr)->mtyp == PM_SHAMBLING_HORROR && u.shambin == 3) || \
((ptr)->mtyp == PM_STUMBLING_HORROR && u.stumbin == 3) || \
((ptr)->mtyp == PM_WANDERING_HORROR && u.wandein == 3) || \
((ptr)->mtyp == PM_GHOUL_QUEEN_NITOCRIS) || \
((ptr)->mtyp == PM_PHARAOH) \
)
#define skeleton_innards(ptr) (((ptr)->mtyp == PM_SKELETON) || \
((ptr)->mtyp == PM_SKELETAL_PIRATE) \
)
#define no_innards(ptr) ((ptr)->mlet == S_VORTEX || \
(ptr)->mlet == S_LIGHT || \
(ptr)->mlet == S_ELEMENTAL || \
(ptr)->mlet == S_MIMIC || \
((ptr)->mtyp == PM_BALL_OF_LIGHT) || \
((ptr)->mtyp == PM_BALL_OF_RADIANCE) || \
((ptr)->mtyp == PM_BALL_OF_GOSSAMER_SUNLIGHT) || \
((ptr)->mtyp == PM_DAUGHTER_OF_NAUNET) || \
((ptr)->mtyp == PM_SHAMBLING_HORROR && u.shambin == 2) || \
((ptr)->mtyp == PM_STUMBLING_HORROR && u.stumbin == 2) || \
((ptr)->mtyp == PM_WANDERING_HORROR && u.wandein == 2) || \
(ptr)->mlet == S_WRAITH || \
(ptr)->mlet == S_GHOST || \
(ptr)->mlet == S_SHADE || \
(ptr)->mlet == S_GOLEM \
)
#define undiffed_innards(ptr) ((ptr)->mlet == S_BLOB || \
(ptr)->mtyp == PM_FLOATING_EYE || \
(ptr)->mlet == S_JELLY || \
(ptr)->mlet == S_TRAPPER || \
(ptr)->mlet == S_FUNGUS || \
(ptr)->mlet == S_PUDDING || \
((ptr)->mtyp == PM_DROW_MUMMY) || \
((ptr)->mtyp == PM_SHAMBLING_HORROR && u.shambin == 1) || \
((ptr)->mtyp == PM_STUMBLING_HORROR && u.stumbin == 1) || \
((ptr)->mtyp == PM_WANDERING_HORROR && u.wandein == 1) || \
(ptr)->mlet == S_PLANT \
)
#define is_silent(ptr) ((ptr)->msound == MS_SILENT)
#define is_silent_mon(mon) (is_silent((mon)->data))
#define unsolid(ptr) (((ptr)->mflagsb & MB_UNSOLID) != 0L)
#define mindless(ptr) (((ptr)->mflagst & MT_MINDLESS) != 0L || ((ptr)->mflagst & MT_DETACHED) != 0L || on_level(&valley_level, &u.uz))
#define mindless_mon(mon) (mon && mindless((mon)->data))
#define detached_from_purpose(ptr) (((ptr)->mflagst & MT_DETACHED) != 0)
#define detached_from_purpose_mon(mon) (mon && detached_from_purpose((mon)->data))
#define mindless_muse_mon(mon) (mindless_mon(mon) && !(!on_level(&valley_level, &u.uz) && detached_from_purpose_mon(mon)))
#define intelligent_mon(mon) (!mindless_mon(mon) && !is_animal((mon)->data))
#define murderable_mon(mon) ((mon) && ((intelligent_mon(mon) && always_peaceful((mon)->data) && !always_hostile_mon(mon)) || (mon)->isshk || (mon)->isgd || (mon)->ispriest))
#define mortal_race(mon) (intelligent_mon(mon) && !nonliving((mon)->data) && !is_minion((mon)->data) && !is_demon((mon)->data) && !is_primordial((mon)->data) && !is_great_old_one((mon)->data))
#define dark_immune(mon) (is_unalive((mon)->data) || is_primordial((mon)->data))
#define slithy(ptr) ((ptr)->mflagsb & MB_SLITHY)
#define humanoid_torso(ptr) (((ptr)->mflagsb & MB_HUMANOID) != 0)
#define humanoid_upperbody(ptr) (humanoid_torso(ptr) && (((ptr)->mflagsb&(MB_LONGHEAD|MB_LONGNECK)) == 0))
#define humanoid_feet(ptr) (((ptr)->mflagsb & MB_HAS_FEET) != 0)
#define humanoid(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == MB_HUMANOID)
#define animaloid(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == MB_ANIMAL)
#define serpentine(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == MB_SLITHY)
#define centauroid(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == (MB_HUMANOID|MB_ANIMAL))
#define snakemanoid(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == (MB_HUMANOID|MB_SLITHY))
#define leggedserpent(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == (MB_ANIMAL|MB_SLITHY))
#define naoid(ptr) (((ptr)->mflagsb & MB_BODYTYPEMASK) == 0)
#define noanatomy(ptr) (noncorporeal(ptr) || amorphous(ptr) || naoid(ptr))
#define noboots(ptr) ((slithy(ptr) || nolimbs(ptr) || nofeet(ptr)) && !humanoid_feet(ptr))
#define has_wings(ptr) (((ptr)->mflagsb & MB_WINGS) != 0)
#define is_animal(ptr) (((ptr)->mflagst & MT_ANIMAL) != 0L)
#define is_plant(ptr) (((ptr)->mflagsa & MA_PLANT) != 0L)
#define is_insectoid(ptr) (((ptr)->mflagsa & MA_INSECTOID) != 0L)
#define is_arachnid(ptr) (((ptr)->mflagsa & MA_ARACHNID) != 0L)
#define is_aquatic(ptr) (((ptr)->mflagsa & MA_AQUATIC) != 0L)
#define is_wooden(ptr) ((ptr)->mtyp == PM_WOOD_GOLEM || (ptr)->mtyp == PM_LIVING_LECTERN || is_plant(ptr))
#define thick_skinned(ptr) (((ptr)->mflagsb & MB_THICK_HIDE) != 0L)
#define lays_eggs(ptr) (((ptr)->mflagsb & MB_OVIPAROUS) != 0L)
#define species_regenerates(ptr) (((ptr)->mflagsg & MG_REGEN) != 0L)
#define species_perceives(ptr) (((ptr)->mflagsv & MV_SEE_INVIS) != 0L)
#define species_teleports(ptr) (((ptr)->mflagsm & MM_TPORT) != 0L)
#define species_controls_teleports(ptr) (((ptr)->mflagsm & MM_TPORT_CNTRL) != 0L)
#define species_is_telepathic(ptr) (((ptr)->mflagsv & MV_TELEPATHIC) != 0L)
#define species_blind_telepathic(ptr) (!haseyes(ptr) || !((ptr)->mflagsv&(MV_NORMAL|MV_INFRAVISION|MV_DARKSIGHT|MV_LOWLIGHT2|MV_LOWLIGHT3|MV_CATSIGHT|MV_EXTRAMISSION)))
#define is_armed(ptr) (attacktype(ptr, AT_WEAP) || attacktype(ptr, AT_XWEP) || attacktype(ptr, AT_MARI) || attacktype(ptr, AT_DEVA))
#define is_armed_mon(mon) (mon_attacktype(mon, AT_WEAP) || mon_attacktype(mon, AT_XWEP) || mon_attacktype(mon, AT_MARI) || mon_attacktype(mon, AT_DEVA))
#define crpsdanger(ptr) (acidic(ptr) || poisonous(ptr) ||\
freezing(ptr) || burning(ptr))
#define hideablewidegaze(ptr) ((ptr)->mtyp == PM_MEDUSA || \
(ptr)->mtyp == PM_GREAT_CTHULHU || \
(ptr)->mtyp == PM_STAR_SPAWN || \
(ptr)->mtyp == PM_DAGON || \
(ptr)->mtyp == PM_PALE_NIGHT || \
(ptr)->mtyp == PM_OBOX_OB || \
(ptr)->mtyp == PM_UVUUDAUM || \
(ptr)->mtyp == PM_MASKED_QUEEN \
)
#define controlledwidegaze(ptr) (!((ptr)->mtyp == PM_MEDUSA || (ptr)->mtyp == PM_UVUUDAUM || (ptr)->mtyp == PM_GREAT_CTHULHU || (ptr)->mtyp == PM_OBOX_OB || (ptr)->mtyp == PM_DAGON))
#define controlledwidegaze_mon(mon) (controlledwidegaze((mon)->data) || has_template(mon, ILLUMINATED))
#define acidic(ptr) (((ptr)->mflagsb & MB_ACID) != 0L)
#define poisonous(ptr) (((ptr)->mflagsb & MB_POIS) != 0L)
#define freezing(ptr) (((ptr)->mflagsb & MB_CHILL) != 0L)
#define burning(ptr) (((ptr)->mflagsb & MB_TOSTY) != 0L)
#define hallucinogenic(ptr) (((ptr)->mflagsb & MB_HALUC) != 0L)
#define inediate(ptr) (!(carnivorous(ptr) || herbivorous(ptr) || metallivorous(ptr) || magivorous(ptr) || is_vampire(ptr)))
#define carnivorous(ptr) (((ptr)->mflagst & MT_CARNIVORE) != 0L)
#define herbivorous(ptr) (((ptr)->mflagst & MT_HERBIVORE) != 0L)
#define metallivorous(ptr) (((ptr)->mflagst & MT_METALLIVORE) != 0L)
#define magivorous(ptr) (((ptr)->mflagst & MT_MAGIVORE) != 0L)
#define polyok(ptr) ((((ptr)->mflagsg & MG_NOPOLY) == 0L) && (G_C_INST((ptr)->geno) <= u.uinsight) && !((((ptr)->mflagsg&MG_FUTURE_WISH) != 0L) && !Role_if(PM_TOURIST)))
#define is_Rebel(ptr) ((ptr)->mtyp == PM_REBEL_RINGLEADER ||\
(ptr)->mtyp == PM_ADVENTURING_WIZARD ||\
(ptr)->mtyp == PM_MILITANT_CLERIC ||\
(ptr)->mtyp == PM_HALF_ELF_RANGER)
#define is_undead(ptr) (((ptr)->mflagsa & MA_UNDEAD) != 0L)
#define can_undead(ptr) (!nonliving(ptr) && !is_minion(ptr) && ((ptr)->mlet != S_PUDDING) &&\
((ptr)->mlet != S_JELLY) && ((ptr)->mlet != S_BLOB) && !is_elemental(ptr) &&\
!is_plant(ptr) && !is_demon(ptr) && !is_great_old_one(ptr) && !is_primordial(ptr) && !(mvitals[monsndx(ptr)].mvflags&G_NOCORPSE))
#define is_weldproof(ptr) (is_undead(ptr) || is_demon(ptr) || is_were(ptr) || is_great_old_one(ptr) || ptr->mtyp == PM_DAUGHTER_OF_NAUNET || ptr->mtyp == PM_PARASITIC_WALL_HUGGER)
#define is_weldproof_mon(mon) (is_weldproof((mon)->data))
#define is_were(ptr) (((ptr)->mflagsa & MA_WERE) != 0L)
#define is_heladrin(ptr) (\
(ptr)->mtyp == PM_COURE_ELADRIN || \
(ptr)->mtyp == PM_NOVIERE_ELADRIN || \
(ptr)->mtyp == PM_BRALANI_ELADRIN || \
(ptr)->mtyp == PM_FIRRE_ELADRIN || \
(ptr)->mtyp == PM_SHIERE_ELADRIN || \
(ptr)->mtyp == PM_GHAELE_ELADRIN || \
(ptr)->mtyp == PM_TULANI_ELADRIN || \
(ptr)->mtyp == PM_GAE_ELADRIN || \
(ptr)->mtyp == PM_BRIGHID_ELADRIN || \
(ptr)->mtyp == PM_UISCERRE_ELADRIN || \
(ptr)->mtyp == PM_CAILLEA_ELADRIN || \
(ptr)->mtyp == PM_DRACAE_ELADRIN || \
(ptr)->mtyp == PM_LIGHT_ELF || \
(ptr)->mtyp == PM_ALRUNES ||\
(ptr)->mtyp == PM_GWYNHARWYF ||\
(ptr)->mtyp == PM_ASCODEL ||\
(ptr)->mtyp == PM_FAERINAAL ||\
(ptr)->mtyp == PM_QUEEN_MAB ||\
(ptr)->mtyp == PM_QUEEN_OF_STARS ||\
(ptr)->mtyp == PM_KETO \
)
#define is_eeladrin(ptr) (\
(ptr)->mtyp == PM_MOTE_OF_LIGHT || \
(ptr)->mtyp == PM_WATER_DOLPHIN || \
(ptr)->mtyp == PM_SINGING_SAND || \
(ptr)->mtyp == PM_DANCING_FLAME || \
(ptr)->mtyp == PM_BALL_OF_LIGHT || \
(ptr)->mtyp == PM_LUMINOUS_CLOUD || \
(ptr)->mtyp == PM_BALL_OF_RADIANCE || \
(ptr)->mtyp == PM_WARDEN_TREE || \
(ptr)->mtyp == PM_PYROCLASTIC_VORTEX || \
(ptr)->mtyp == PM_WATERSPOUT || \
(ptr)->mtyp == PM_MOONSHADOW || \
(ptr)->mtyp == PM_MOTHERING_MASS || \
(ptr)->mtyp == PM_UNBODIED || \
(ptr)->mtyp == PM_HATEFUL_WHISPERS ||\
(ptr)->mtyp == PM_FURIOUS_WHIRLWIND ||\
(ptr)->mtyp == PM_BLOODY_SUNSET ||\
(ptr)->mtyp == PM_BALL_OF_GOSSAMER_SUNLIGHT ||\
(ptr)->mtyp == PM_COTERIE_OF_MOTES ||\
(ptr)->mtyp == PM_ETERNAL_LIGHT ||\
(ptr)->mtyp == PM_ANCIENT_TEMPEST \
)
#define is_yochlol(ptr) ((ptr)->mtyp == PM_YOCHLOL ||\
(ptr)->mtyp == PM_UNEARTHLY_DROW ||\
(ptr)->mtyp == PM_STINKING_CLOUD ||\
(ptr)->mtyp == PM_DEMONIC_BLACK_WIDOW)
#define is_duergar(ptr) ((ptr)->mtyp == PM_DUERGAR ||\
(ptr)->mtyp == PM_GIANT_DUERGAR ||\
(ptr)->mtyp == PM_DUERGAR_DEEPKING||\
(ptr)->mtyp == PM_GIANT_DEEPKING ||\
(ptr)->mtyp == PM_DUERGAR_STONEGUARD ||\
(ptr)->mtyp == PM_GIANT_STONEGUARD ||\
(ptr)->mtyp == PM_DUERGAR_DEBILITATOR ||\
(ptr)->mtyp == PM_DUERGAR_ANNIHILATOR)
#define is_kuo_toa(ptr) ((ptr)->mtyp == PM_KUO_TOA ||\
(ptr)->mtyp == PM_KUO_TOA_WHIP)
#define is_vampire(ptr) (((ptr)->mflagsa & MA_VAMPIRE) != 0L)
#define is_half_dragon(ptr) attacktype_fordmg(ptr, AT_BREA, AD_HDRG)
#define is_boreal_dragoon(ptr) (attacktype_fordmg(ptr, AT_WEAP, AD_HDRG) || attacktype_fordmg(ptr, AT_XWEP, AD_HDRG))
#define is_elf(ptr) (((ptr)->mflagsa & MA_ELF) != 0L && !is_drow(ptr))
#define is_drow(ptr) (((ptr)->mflagsa & MA_DROW) != 0L)
#define is_myrkalfr(ptr) ((ptr)->mtyp == PM_MYRKALFAR_WARRIOR || (ptr)->mtyp == PM_MYRKALFAR_MATRON || (ptr)->mtyp == PM_MYRKALFR || (ptr)->mtyp == PM_ALIDER)
#define is_dwarf(ptr) (((ptr)->mflagsa & MA_DWARF) != 0L)
#define is_gnome(ptr) (((ptr)->mflagsa & MA_GNOME) != 0L)
#define is_gizmo(ptr) ((ptr)->mlet == S_GNOME && is_clockwork(ptr))
#define is_szcultist(ptr) ((ptr)->mtyp == PM_SHATTERED_ZIGGURAT_CULTIST \
|| (ptr)->mtyp == PM_SHATTERED_ZIGGURAT_KNIGHT \
|| (ptr)->mtyp == PM_SHATTERED_ZIGGURAT_WIZARD)
#define is_orc(ptr) (((ptr)->mflagsa & MA_ORC) != 0L)
#define is_ogre(ptr) ((ptr)->mlet == S_OGRE)
#define is_troll(ptr) ((ptr)->mlet == S_TROLL)
#define is_kobold(ptr) ((ptr)->mlet == S_KOBOLD)
#define is_ettin(ptr) ((ptr)->mtyp == PM_ETTIN)
#define is_human(ptr) (((ptr)->mflagsa & MA_HUMAN) != 0L)
#define is_untamable(ptr) (((ptr)->mflagsg & MG_NOTAME) != 0L)
#define is_unwishable(ptr) ((((ptr)->mflagsg & MG_NOWISH) != 0L) || (G_C_INST((ptr)->geno) > u.uinsight) || ((((ptr)->mflagsg&MG_FUTURE_WISH) != 0L) && !Role_if(PM_TOURIST)))
#define is_fungus(ptr) ((ptr)->mlet == S_FUNGUS)
#define is_migo(ptr) ((ptr)->mtyp == PM_MIGO_WORKER ||\
(ptr)->mtyp == PM_MIGO_SOLDIER ||\
(ptr)->mtyp == PM_MIGO_PHILOSOPHER ||\
(ptr)->mtyp == PM_MIGO_QUEEN)
#define your_race(ptr) (((ptr)->mflagsa & urace.selfmask) != 0L)
#define is_andromaliable(ptr) (is_elf(ptr) || is_drow(ptr) || is_dwarf(ptr) || is_gnome(ptr) || is_orc(ptr) || is_human(ptr) || (ptr)->mtyp == PM_HOBBIT || \
(ptr)->mtyp == PM_MONKEY || (ptr)->mtyp == PM_APE || (ptr)->mtyp == PM_YETI || \
(ptr)->mtyp == PM_CARNIVOROUS_APE || (ptr)->mtyp == PM_SASQUATCH\
)
#define is_bat(ptr) ((ptr)->mtyp == PM_BAT || \
(ptr)->mtyp == PM_GIANT_BAT || \
(ptr)->mtyp == PM_BATTLE_BAT || \
(ptr)->mtyp == PM_WARBAT || \
(ptr)->mtyp == PM_VAMPIRE_BAT)
#define is_metroid(ptr) ((ptr)->mlet == S_TRAPPER && !((ptr)->mtyp == PM_TRAPPER || (ptr)->mtyp == PM_LURKER_ABOVE))
#define is_social_insect(ptr) ((ptr)->mlet == S_ANT && (ptr)->maligntyp > 0)
#define is_spider(ptr) ((ptr)->mlet == S_SPIDER && (\
(ptr)->mtyp == PM_CAVE_SPIDER ||\
(ptr)->mtyp == PM_GIANT_SPIDER ||\
(ptr)->mtyp == PM_MIRKWOOD_SPIDER ||\
(ptr)->mtyp == PM_PHASE_SPIDER ||\
(ptr)->mtyp == PM_MIRKWOOD_ELDER \
))
#define is_rat(ptr) ((ptr)->mlet == S_RODENT && ( \
(ptr)->mtyp == PM_SEWER_RAT || \
(ptr)->mtyp == PM_GIANT_RAT || \
(ptr)->mtyp == PM_RABID_RAT || \
(ptr)->mtyp == PM_ENORMOUS_RAT || \
(ptr)->mtyp == PM_RODENT_OF_UNUSUAL_SIZE))
#define is_basic_worm(ptr) ((ptr)->mlet == S_WORM && (\
(ptr)->mtyp == PM_DARK_WORM ||\
(ptr)->mtyp == PM_BABY_LONG_WORM ||\
(ptr)->mtyp == PM_BABY_PURPLE_WORM ||\
(ptr)->mtyp == PM_LONG_WORM ||\
(ptr)->mtyp == PM_PURPLE_WORM \
))
#define is_wormy_thing(ptr) (((ptr)->mlet == S_EEL && (\
(ptr)->mtyp == PM_GIANT_EEL ||\
(ptr)->mtyp == PM_ELECTRIC_EEL ||\
(ptr)->mtyp == PM_KRAKEN \
)) || ((ptr)->mlet == S_SPIDER && (\
(ptr)->mtyp == PM_CENTIPEDE \
)) || ((ptr)->mlet == S_SNAKE && (\
(ptr)->mtyp == PM_GARTER_SNAKE ||\
(ptr)->mtyp == PM_SNAKE ||\
(ptr)->mtyp == PM_WATER_MOCCASIN ||\
(ptr)->mtyp == PM_PIT_VIPER ||\
(ptr)->mtyp == PM_PYTHON ||\
(ptr)->mtyp == PM_COBRA ||\
(ptr)->mtyp == PM_DAUGHTER_OF_NAUNET \
))\
)
#define is_wormy_dragon(ptr) ((ptr)->mlet == S_DRAGON && (\
(ptr)->mtyp == PM_GRAY_DRAGON ||\
(ptr)->mtyp == PM_SILVER_DRAGON ||\
(ptr)->mtyp == PM_SHIMMERING_DRAGON ||\
(ptr)->mtyp == PM_WHITE_DRAGON ||\
(ptr)->mtyp == PM_ORANGE_DRAGON ||\
(ptr)->mtyp == PM_BLACK_DRAGON ||\
(ptr)->mtyp == PM_BLUE_DRAGON ||\
(ptr)->mtyp == PM_GREEN_DRAGON ||\
(ptr)->mtyp == PM_RED_DRAGON ||\
(ptr)->mtyp == PM_DEEP_DRAGON ||\
(ptr)->mtyp == PM_YELLOW_DRAGON\
))
#define is_dragon(ptr) (((ptr)->mflagsa & MA_DRAGON) != 0L)
#define is_true_adult_dragon(ptr) ((monsndx(ptr) >= PM_GRAY_DRAGON && monsndx(ptr) <= PM_YELLOW_DRAGON) || \
(ptr)->mtyp == PM_EDEN || (ptr)->mtyp == PM_FAFNIR || \
(ptr)->mtyp == PM_PLATINUM_DRAGON || (ptr)->mtyp == PM_CHROMATIC_DRAGON || (ptr)->mtyp == PM_IXOTH || (ptr)->mtyp == PM_SMAUG)
#define is_true_dragon(ptr) ((monsndx(ptr) >= PM_BABY_GRAY_DRAGON && monsndx(ptr) <= PM_BABY_YELLOW_DRAGON) || is_true_adult_dragon(ptr))
#define is_pseudodragon(ptr) (monsndx(ptr) >= PM_TINY_PSEUDODRAGON && monsndx(ptr) <= PM_GIGANTIC_PSEUDODRAGON)
#define is_bird(ptr) (((ptr)->mflagsa & MA_AVIAN) != 0L)
#define is_giant(ptr) (((ptr)->mflagsa & MA_GIANT) != 0L)
#define is_gnoll(ptr) ((ptr)->mtyp == PM_GNOLL || \
(ptr)->mtyp == PM_GNOLL_GHOUL || \
(ptr)->mtyp == PM_ANUBITE || \
(ptr)->mtyp == PM_GNOLL_MATRIARCH || \
(ptr)->mtyp == PM_YEENOGHU)
#define is_minotaur(ptr) ((ptr)->mtyp == PM_MINOTAUR || \
(ptr)->mtyp == PM_MINOTAUR_PRIESTESS || \
(ptr)->mtyp == PM_BAPHOMET)
#define is_pirate(ptr) ((ptr)->mtyp == PM_PIRATE || \
(ptr)->mtyp == PM_PIRATE_BROTHER || \
(ptr)->mtyp == PM_SKELETAL_PIRATE || \
(ptr)->mtyp == PM_DAMNED_PIRATE || \
(ptr)->mtyp == PM_GITHYANKI_PIRATE || \
(ptr)->mtyp == PM_MAYOR_CUMMERBUND)
#define is_golem(ptr) ((ptr)->mlet == S_GOLEM)
#define is_clockwork(ptr) (((ptr)->mflagsa & MA_CLOCK) != 0L)
#define is_domestic(ptr) (((ptr)->mflagst & MT_DOMESTIC) != 0L)
#define is_fey(ptr) (((ptr)->mflagsa & MA_FEY) != 0L)
#define is_snake(ptr) (((ptr)->mflagsa & MA_REPTILIAN) != 0L && (ptr)->mlet == S_SNAKE)
#define is_demon(ptr) (((ptr)->mflagsa & MA_DEMON) != 0L)
#define is_law_demon(ptr) (((ptr)->mflagsa & MA_DEMON) != 0L && is_lawful(ptr))
#define is_cha_demon(ptr) (((ptr)->mflagsa & MA_DEMON) != 0L && is_chaotic(ptr))
#define is_ancient(ptr) (((ptr)->mtyp >= PM_ANCIENT_OF_BLESSINGS\
&& (ptr)->mtyp <= PM_ANCIENT_OF_DEATH) \
|| (ptr)->mtyp == PM_BAALPHEGOR \
)
#define is_tannin(ptr) (((ptr)->mtyp >= PM_AKKABISH_TANNIN \
&& (ptr)->mtyp <= PM_TERAPHIM_TANNAH \
) \
|| (ptr)->mtyp == PM_PALE_NIGHT \
|| (ptr)->mtyp == PM_DAGON \
|| (ptr)->mtyp == PM_OBOX_OB \
)
#define is_primordial(ptr) (((ptr)->mflagsa & MA_PRIMORDIAL) != 0L)
#define is_great_old_one(ptr) (((ptr)->mflagsa & MA_G_O_O) != 0L)
#define is_mask_of_nyarlathotep(ptr) ((ptr)->mtyp == PM_GOOD_NEIGHBOR || (ptr)->mtyp == PM_HMNYW_PHARAOH || (ptr)->mtyp == PM_NITOCRIS)
#define is_alien(ptr) (((ptr)->mflagsa & MA_ET) != 0L)
#define is_keter(ptr) ((ptr)->mlet == S_KETER)
#define is_angel(ptr) ((((ptr)->mflagsa & MA_MINION) != 0L) && ((ptr)->mlet == S_LAW_ANGEL || (ptr)->mlet == S_NEU_ANGEL || (ptr)->mlet == S_CHA_ANGEL))
#define fallen(mx) (has_template(mx, MAD_TEMPLATE) || has_template(mx, FALLEN_TEMPLATE) || mx->mfaction == LAMASHTU_FACTION)
#define normalAngel(mx) ((is_angel(mx->data) && !fallen(mx)) || (is_undead(mx->data) && mx->mfaction == HOLYDEAD_FACTION))
#define fallenAngel(mx) (is_angel(mx->data) && fallen(mx))
#define is_eladrin(ptr) (is_heladrin(ptr) || is_eeladrin(ptr))
#define is_high_caste_eladrin(ptr) (\
(ptr)->mtyp == PM_TULANI_ELADRIN || \
(ptr)->mtyp == PM_GAE_ELADRIN || \
(ptr)->mtyp == PM_BRIGHID_ELADRIN || \
(ptr)->mtyp == PM_UISCERRE_ELADRIN || \
(ptr)->mtyp == PM_CAILLEA_ELADRIN \
)
#define is_archon(ptr) ((ptr)->mlet == S_LAW_ANGEL &&\
!((ptr)->mtyp == PM_COUATL ||\
(ptr)->mtyp == PM_ALEAX ||\
(ptr)->mtyp == PM_KI_RIN ||\
(ptr)->mtyp == PM_GIANT_EAGLE ||\
(ptr)->mtyp == PM_GOD ||\
(ptr)->mtyp == PM_DAMAGED_ARCADIAN_AVENGER ||\
(ptr)->mtyp == PM_ARCADIAN_AVENGER ||\
(ptr)->mtyp == PM_APOLLYON ||\
(ptr)->mtyp == PM_ANGEL))
#define is_auton(ptr) ( (ptr)->mtyp == PM_MONOTON ||\
(ptr)->mtyp == PM_DUTON ||\
(ptr)->mtyp == PM_TRITON ||\
(ptr)->mtyp == PM_QUATON ||\
(ptr)->mtyp == PM_QUINON ||\
(ptr)->mtyp == PM_AXUS\
)
#define is_kamerel(ptr) ( (ptr)->mtyp == PM_AMM_KAMEREL ||\
(ptr)->mtyp == PM_HUDOR_KAMEREL ||\
(ptr)->mtyp == PM_SHARAB_KAMEREL ||\
(ptr)->mtyp == PM_ARA_KAMEREL\
)
#define is_rilmani(ptr) ( (ptr)->mtyp == PM_PLUMACH_RILMANI ||\
(ptr)->mtyp == PM_FERRUMACH_RILMANI ||\
(ptr)->mtyp == PM_CUPRILACH_RILMANI ||\
(ptr)->mtyp == PM_STANNUMACH_RILMANI ||\
(ptr)->mtyp == PM_ARGENACH_RILMANI ||\
(ptr)->mtyp == PM_MERCURIAL_ESSENCE ||\
(ptr)->mtyp == PM_BRIMSTONE_ESSENCE ||\
(ptr)->mtyp == PM_HYDRARGYRUMACH_RILMANI ||\
(ptr)->mtyp == PM_CENTER_OF_ALL ||\
(ptr)->mtyp == PM_ADAMACH ||\
(ptr)->mtyp == PM_AURUMACH_RILMANI\
)
#define is_deva(ptr) ((ptr)->mlet == S_NEU_ANGEL)
#define is_divider(ptr) ( (ptr)->mtyp == PM_BLACK_PUDDING\
|| (ptr)->mtyp == PM_BROWN_PUDDING\
|| (ptr)->mtyp == PM_DARKNESS_GIVEN_HUNGER\
|| (ptr)->mtyp == PM_GREMLIN\
|| (ptr)->mtyp == PM_DUNGEON_FERN_SPORE\
|| (ptr)->mtyp == PM_DUNGEON_FERN_SPROUT\
|| (ptr)->mtyp == PM_BURNING_FERN_SPORE\
|| (ptr)->mtyp == PM_BURNING_FERN_SPROUT\
|| (ptr)->mtyp == PM_SWAMP_FERN_SPORE\
|| (ptr)->mtyp == PM_SWAMP_FERN_SPROUT\
|| (ptr)->mtyp == PM_RAZORVINE\
)
#define is_horror(ptr) ( (ptr)->mtyp == PM_SHAMBLING_HORROR\
|| (ptr)->mtyp == PM_STUMBLING_HORROR\
|| (ptr)->mtyp == PM_WANDERING_HORROR\
|| (ptr)->mtyp == PM_NAMELESS_HORROR\
)
#define is_chuul(ptr) ( (ptr)->mtyp == PM_CHUUL \
|| (ptr)->mtyp == PM_ELDER_CHUUL \
|| (ptr)->mtyp == PM_BLIBDOOLPOOLP_S_MINDGRAVEN_CHAMPION \
|| (ptr)->mtyp == PM_BLIBDOOLPOOLP__GRAVEN_INTO_FLESH \
)
#define is_mercenary(ptr) (((ptr)->mflagsg & MG_MERC) != 0L)
#define is_army_pm(pm) (pm == PM_CAPTAIN || pm == PM_LIEUTENANT || pm == PM_SERGEANT || pm == PM_SOLDIER)
#define is_bardmon(ptr) ((ptr)->mtyp == PM_LILLEND || (ptr)->mtyp == PM_RHYMER || (ptr)->mtyp == PM_BARD)
#define is_male(ptr) (((ptr)->mflagsb & MB_MALE) != 0L)
#define is_female(ptr) (((ptr)->mflagsb & MB_FEMALE) != 0L)
#define is_neuter(ptr) (((ptr)->mflagsb & MB_NEUTER) != 0L)
#define is_wanderer(ptr) (((ptr)->mflagst & MT_WANDER) != 0L)
#define is_goat_tentacle_mtyp(ptr) ((ptr)->mtyp == PM_DARK_YOUNG \
|| (ptr)->mtyp == PM_MOTHERING_MASS \
|| (ptr)->mtyp == PM_BLESSED \
|| (ptr)->mtyp == PM_PARASITIC_WALL_HUGGER \
|| (ptr)->mtyp == PM_SWIRLING_MIST \
|| (ptr)->mtyp == PM_DUST_STORM \
|| (ptr)->mtyp == PM_ICE_STORM \
|| (ptr)->mtyp == PM_THUNDER_STORM \
|| (ptr)->mtyp == PM_FIRE_STORM \
|| (ptr)->mtyp == PM_MOUTH_OF_THE_GOAT)
#define is_goat_tentacle_mon(mon) (is_goat_tentacle_mtyp((mon)->data) || has_template(mon, MISTWEAVER))
#define is_snake_bite_mtyp(ptr) ((ptr)->mtyp == PM_MEDUSA \
|| (ptr)->mtyp == PM_ANCIENT_NAGA)
#define is_snake_bite_mon(mon) (is_snake_bite_mtyp((mon)->data) || has_template(mon, MOLY_TEMPLATE))
#define is_tailslap_mtyp(ptr) (is_true_adult_dragon(ptr) || (ptr)->mtyp == PM_UISCERRE_ELADRIN || (ptr)->mtyp == PM_DISENCHANTER || (ptr)->mtyp == PM_GRAY_DEVOURER)
#define is_tailslap_mon(mon) (is_tailslap_mtyp((mon)->data))
#define is_vines_mon(mon) ((mon)->mtyp == PM_GAE_ELADRIN && (mon)->m_lev >= 20)
#define is_star_blades_mtyp(ptr) ((ptr)->mtyp == PM_COURE_ELADRIN || (ptr)->mtyp == PM_FLAXEN_STARSHADOW || (ptr)->mtyp == PM_MOTE_OF_LIGHT || (ptr)->mtyp == PM_IASOIAN_ARCHON)
#define is_star_blades_mon(mon) (is_star_blades_mtyp((mon)->data) || ((mon)->mtyp == PM_PORO_AULON && (mon)->mhp<(mon)->mhpmax/2))
#define is_storm_mtyp(ptr) ((ptr)->mtyp == PM_DAO_LAO_GUI_MONK)
#define is_level_storm_mtyp(ptr) ((ptr)->mtyp == PM_CAILLEA_ELADRIN || (ptr)->mtyp == PM_MOONSHADOW\
|| (ptr)->mtyp == PM_GHAELE_ELADRIN || (ptr)->mtyp == PM_LUMINOUS_CLOUD\
|| (ptr)->mtyp == PM_PYROCLASTIC_VORTEX)
#define is_storm_mon(mon) ((is_level_storm_mtyp((mon)->data) && (mon)->m_lev >= 20) || is_storm_mtyp((mon)->data))
#define is_dancer(ptr) ((ptr)->mtyp == PM_PORO_AULON || (ptr)->mtyp == PM_SEYLL_AUZKOVYN || (ptr)->mtyp == PM_ANULO_DANCER || (ptr)->mtyp == PM_MYRKALFAR_MATRON)
#define goat_monster(ptr) (In_lost_cities(&u.uz) ? lost_cities_goat_monster(ptr) : always_goat_monster(ptr))
#define always_goat_monster(ptr) (\
(ptr)->mtyp == PM_SMALL_GOAT_SPAWN \
|| (ptr)->mtyp == PM_GOAT_SPAWN \
|| (ptr)->mtyp == PM_GIANT_GOAT_SPAWN \
|| (ptr)->mtyp == PM_MIGO_WORKER \
|| (ptr)->mtyp == PM_MIGO_SOLDIER \
|| (ptr)->mtyp == PM_MIGO_PHILOSOPHER \
|| (ptr)->mtyp == PM_MIGO_QUEEN \
|| (ptr)->mtyp == PM_DARK_YOUNG \
|| (ptr)->mtyp == PM_BLESSED \
|| (ptr)->mtyp == PM_SWIRLING_MIST \
|| (ptr)->mtyp == PM_DUST_STORM \
|| (ptr)->mtyp == PM_ICE_STORM \
|| (ptr)->mtyp == PM_THUNDER_STORM \
|| (ptr)->mtyp == PM_FIRE_STORM \
|| (ptr)->mtyp == PM_MOUTH_OF_THE_GOAT \
)
#define lost_cities_goat_monster(ptr) (\
always_goat_monster(ptr) \
|| (ptr)->mtyp == PM_PLAINS_CENTAUR \
|| (ptr)->mtyp == PM_FOREST_CENTAUR \
|| (ptr)->mtyp == PM_MOUNTAIN_CENTAUR \
|| (ptr)->mtyp == PM_CENTAUR_CHIEFTAIN \
|| (ptr)->mtyp == PM_QUICKLING \
|| (ptr)->mtyp == PM_NAIAD \
|| (ptr)->mtyp == PM_DRYAD \
|| (ptr)->mtyp == PM_OREAD \
|| (ptr)->mtyp == PM_YUKI_ONNA \
|| (ptr)->mtyp == PM_DEMINYMPH \
|| (ptr)->mtyp == PM_WHITE_UNICORN \
|| (ptr)->mtyp == PM_GRAY_UNICORN \
|| (ptr)->mtyp == PM_BLACK_UNICORN \
|| (ptr)->mtyp == PM_NIGHTMARE \
)
#define always_yellow_monster(ptr) (\
(ptr)->mtyp == PM_BYAKHEE \
|| (ptr)->mtyp == PM_COILING_BRAWN \
|| (ptr)->mtyp == PM_FUNGAL_BRAIN \
|| (ptr)->mtyp == PM_STRANGER \
|| (ptr)->mtyp == PM_SUZERAIN \
|| (ptr)->mtyp == PM_FLAXEN_STARSHADOW \
|| (ptr)->mtyp == PM_FLAXEN_STAR_PHANTOM \
|| (ptr)->mtyp == PM_PUPPET_EMPEROR_XELETH \
|| (ptr)->mtyp == PM_PUPPET_EMPRESS_XEDALLI \
)
#define yellow_monster(mon) (\
always_yellow_monster(mon->data) \
|| has_template(mon, YELLOW_TEMPLATE) \
|| has_template(mon, DREAM_LEECH) \
)
#define gates_in_help(ptr) ((is_demon((ptr)) || is_minion((ptr))) \
&& !is_auton(ptr) \
&& (ptr)->mtyp != PM_OONA \
&& (ptr)->mtyp != PM_CHAOS \
&& (ptr)->mtyp != PM_KARY__THE_FIEND_OF_FIRE \
&& (ptr)->mtyp != PM_BALROG \
&& (ptr)->mtyp != PM_DURIN_S_BANE \
&& (ptr)->mtyp != PM_SUCCUBUS \
&& (ptr)->mtyp != PM_INCUBUS \
)
#define template_blocks_gate(magr) (has_template(magr, ZOMBIFIED)\
|| has_template(magr, SKELIFIED)\
|| has_template(magr, CRYSTALFIED)\
|| has_template(magr, TOMB_HERD)\
|| has_template(magr, SLIME_REMNANT)\
)
#define always_one_hand_mtyp(ptr) (ptr->mtyp == PM_THRONE_ARCHON \
|| ptr->mtyp == PM_OCCULTIST \
|| ptr->mtyp == PM_LUNGORTHIN \
|| ptr->mtyp == PM_BASTARD_OF_THE_BOREAL_VALLEY \
|| ptr->mtyp == PM_GUG \
|| ptr->mtyp == PM_Y_CULTIST_MATRON \
|| ptr->mtyp == PM_Y_CULTIST_PATRON \
|| ptr->mtyp == PM_DEMOGORGON \
)
#define always_hostile(ptr) (((ptr)->mflagst & MT_HOSTILE) != 0L)
#define always_hostile_mon(mon) (always_hostile((mon)->data))
#define always_peaceful(ptr) (((ptr)->mflagst & MT_PEACEFUL) != 0L)
#define race_hostile(ptr) (((ptr)->mflagsa & urace.hatemask) != 0L)
#define race_peaceful(ptr) (((ptr)->mflagsa & urace.lovemask) != 0L)
#define extra_nasty(ptr) (((ptr)->mflagsg & MG_NASTY) != 0L)
#define strongmonst(ptr) (((ptr)->mflagsb & MB_STRONG) != 0L)
#define can_breathe(ptr) attacktype(ptr, AT_BREA)
#define taxes_sanity(ptr) (((ptr)->mflagsg & MG_SANLOSS) != 0L)
#define yields_insight(ptr) (((ptr)->mflagsg & MG_INSIGHT) != 0L)
#define is_render(mtyp) (mtyp == PM_SECRET_WHISPERER || mtyp == PM_TRUTH_SEER || mtyp == PM_DREAM_EATER || mtyp == PM_VEIL_RENDER)
#define banish_kill(mtyp) (is_render(mtyp))
#define mon_insane(mtmp) (mtmp->mcrazed \
|| mtmp->mberserk \
|| mtmp->mdisrobe \
|| mtmp->mdoubt \
|| mtmp->msanctity \
|| mtmp->mgluttony \
|| mtmp->mfrigophobia \
|| mtmp->mcannibal \
|| mtmp->mrage \
|| mtmp->margent \
|| mtmp->msuicide \
|| mtmp->mnudist \
|| mtmp->mophidio \
|| mtmp->marachno \
|| mtmp->mentomo \
|| mtmp->mthalasso \
|| mtmp->mhelmintho \
|| mtmp->mparanoid \
|| mtmp->mtalons \
|| mtmp->mdreams \
|| mtmp->msciaphilia \
|| mtmp->mforgetful \
|| mtmp->mapostasy \
|| mtmp->mtoobig \
|| mtmp->mrotting \
|| mtmp->mformication \
|| mtmp->mscorpions)
#define has_sunflask(mtyp) (mtyp == PM_UNDEAD_KNIGHT || mtyp == PM_WARRIOR_OF_SUNLIGHT\
|| mtyp == PM_UNDEAD_MAIDEN || mtyp == PM_KNIGHT_OF_THE_PRINCESS_S_GUARD\
|| mtyp == PM_BLUE_SENTINEL || mtyp == PM_DARKMOON_KNIGHT\
|| mtyp == PM_UNDEAD_REBEL || mtyp == PM_PARDONER || mtyp == PM_OCCULTIST\
|| mtyp == PM_CROW_WINGED_HALF_DRAGON || mtyp == PM_ADVENTURESS_ZARIA \
)
#define triggers_ophidiophobia(mon) (triggers_ophidiophobia_ptr((mon)->data) || has_template(mon, MOLY_TEMPLATE))
#define triggers_ophidiophobia_ptr(ptr) (is_snake((ptr))\
|| (ptr)->mlet == S_NAGA\
|| (ptr)->mtyp == PM_COUATL\
|| (ptr)->mtyp == PM_LILLEND\
|| (ptr)->mtyp == PM_MEDUSA\
|| (ptr)->mtyp == PM_MARILITH\
|| (ptr)->mtyp == PM_MAMMON\
|| (ptr)->mtyp == PM_SHAKTARI\
|| (ptr)->mtyp == PM_DEMOGORGON\
|| (ptr)->mtyp == PM_GIANT_EEL\
|| (ptr)->mtyp == PM_ELECTRIC_EEL\
|| (ptr)->mtyp == PM_KRAKEN\
|| (ptr)->mtyp == PM_SALAMANDER\
|| (ptr)->mtyp == PM_KARY__THE_FIEND_OF_FIRE\
|| (ptr)->mtyp == PM_CATHEZAR)
#define triggers_entomophobia(ptr) (is_insectoid(ptr) || is_arachnid(ptr))
#define triggers_arachnophobia(ptr) (is_spider(ptr)\
|| (ptr)->mtyp == PM_SPROW\
|| (ptr)->mtyp == PM_DRIDER\
|| (ptr)->mtyp == PM_PRIESTESS_OF_GHAUNADAUR\
|| (ptr)->mtyp == PM_AVATAR_OF_LOLTH)
#define triggers_helminthophobia(mon) ((mon)->data->mlet == S_WORM || mon_attacktype((mon), AT_TENT))
#define allow_wield(ptr) (ptr->mtyp == PM_SHOGGOTH \
|| ptr->mtyp == PM_PRIEST_OF_GHAUNADAUR\
|| ptr->mtyp == PM_MOTHERING_MASS\
|| ptr->mtyp == PM_ANCIENT_NUPPERIBO\
|| ptr->mtyp == PM_KOBOLD_SHAMAN\
|| ptr->mtyp == PM_ORC_SHAMAN\
|| ptr->mtyp == PM_MORDOR_SHAMAN\
|| ptr->mtyp == PM_ZETA_METROID\
|| ptr->mtyp == PM_MINOTAUR_PRIESTESS\
|| ptr->mtyp == PM_BLASPHEMOUS_LURKER\
|| ptr->mtyp == PM_DREAD_SERAPH\
|| ptr->mtyp == PM_MAD_SEER\
|| ptr->mtyp == PM_ORACLE\
|| ptr->mtyp == PM_PRIEST_OF_AN_UNKNOWN_GOD\
|| ptr->mtyp == PM_PRIEST_OF_IB\
|| ptr->mtyp == PM_PALE_NIGHT\
|| ptr->mtyp == PM_SARA__THE_LAST_ORACLE\
|| ptr->mtyp == PM_STRANGE_CORPSE\
|| ptr->mtyp == PM_NIMUNE\
|| ptr->mtyp == PM_ELDER_BRAIN\
|| ptr->mtyp == PM_KRAKEN__THE_FIEND_OF_WATER\
|| ptr->mtyp == PM_CHAIN_GOLEM\
|| ptr->mtyp == PM_GOOD_NEIGHBOR\
)
#define allow_shield(ptr) (ptr->mtyp == PM_SCORPION\
|| ptr->mtyp == PM_YURIAN\
|| ptr->mtyp == PM_ZETA_METROID\
|| ptr->mtyp == PM_Y_CULTIST_MATRON\
|| ptr->mtyp == PM_Y_CULTIST_PATRON\
|| ptr->mtyp == PM_DEMOGORGON\
|| ptr->mtyp == PM_CHAIN_GOLEM\
|| ptr->mtyp == PM_SCORPIUS\
|| ptr->mtyp == PM_KRAKEN__THE_FIEND_OF_WATER\
)
#define could_twoweap(ptr) attacktype(ptr, AT_XWEP)
#define could_twoweap_mon(mon) mon_attacktype(mon, AT_XWEP)
// define cantweararm(ptr) (breakarm(ptr) || sliparm(ptr))
#define arm_size_fits(ptr,obj) (Is_dragon_scales(obj) || \
obj->objsize == (ptr)->msize || \
(is_elven_armor(obj) && abs(obj->objsize - (ptr)->msize) <= 1))
#define arm_match(ptr,obj) \
(Is_dragon_scales(obj) || obj->otyp == WAISTCLOTH || \
((obj->otyp == ELVEN_TOGA || obj->otyp == NOBLE_S_DRESS || obj->otyp == GENTLEWOMAN_S_DRESS) && upper_body_match(ptr,obj)) || \
(ptr->mtyp == PM_BLIBDOOLPOOLP_S_MINDGRAVEN_CHAMPION && upper_body_match(ptr,obj)) || \
(ptr->mtyp == PM_OCTOPODE && obj->otyp == LIVING_ARMOR) || \
full_body_match(ptr,obj))
#define full_body_match(ptr,obj) (((ptr->mflagsb&MB_BODYTYPEMASK) != 0) && \
((ptr->mflagsb&MB_BODYTYPEMASK) == (obj->bodytypeflag&MB_BODYTYPEMASK)))
#define boots_size_fits(ptr,obj) (ptr->mtyp == PM_BLIBDOOLPOOLP_S_MINDGRAVEN_CHAMPION ? \
(ptr->msize+1 == obj->objsize) : \
(ptr->msize == obj->objsize))
#define can_wear_gloves(ptr) (!nogloves(ptr) && !nohands(ptr))
#define can_wear_amulet(ptr) (has_head(ptr) || (ptr->mflagsb&MB_CAN_AMULET))
#define can_wear_blindf(ptr) (has_head(ptr))
#define can_wear_boots(ptr) ((humanoid(ptr) || humanoid_feet(ptr)) && !nofeet(ptr) && !nolimbs(ptr))
#define shirt_match(ptr,obj) ((obj->otyp != BODYGLOVE && upper_body_match(ptr,obj)) || \
full_body_match(ptr,obj))
#define upper_body_match(ptr,obj) (((ptr->mflagsb&MB_HUMANOID) && (obj->bodytypeflag&MB_HUMANOID)) || \
(((ptr->mflagsb&MB_BODYTYPEMASK) != 0) && ((ptr->mflagsb&MB_BODYTYPEMASK) == (obj->bodytypeflag&MB_BODYTYPEMASK))))
#define helm_match(ptr,obj) ((!has_horns(ptr) || obj->otyp == find_gcirclet() || is_flimsy(obj)) && !nohat(ptr) && \
(is_hat(obj) || (has_head(ptr) && (ptr->mflagsb&MB_HEADMODIMASK) == (obj->bodytypeflag&MB_HEADMODIMASK))))
/*Note: No-modifier helms are "normal"*/
#define helm_size_fits(ptr,obj) (obj->objsize == ptr->msize || (is_hat(obj) && obj->objsize <= ptr->msize+1))
#define hates_holy_mon(mon) ((mon) == &youmonst ? hates_holy(youracedata) : hates_holy((mon)->data))
#define hates_holy(ptr) (is_demon(ptr) || (is_undead(ptr) && ptr->mtyp != PM_DREAD_SERAPH) || (((ptr)->mflagsg&MG_HATESHOLY) != 0))
#define hates_unholy(ptr) ((ptr->mflagsg&MG_HATESUNHOLY) != 0)
#define hates_unholy_mon(mon) ((mon) == &youmonst ? hates_unholy(youracedata) : hates_unholy((mon)->data))
#define hates_unblessed(ptr) ((ptr->mflagsg&MG_HATESUNBLESSED) != 0)
#define hates_unblessed_mon(mon) ((mon) == &youmonst ? hates_unblessed(youracedata) : hates_unblessed((mon)->data))
#define hates_silver(ptr) ((ptr->mflagsg&MG_HATESSILVER) != 0)
#define hates_iron(ptr) ((ptr->mflagsg&MG_HATESIRON) != 0)
#define hates_lawful(ptr) (is_chaotic(ptr) || (ptr)->mtyp == PM_UVUUDAUM)
#define hates_lawful_mon(mon) ((mon) == &youmonst ? u.ualign.type == A_CHAOTIC : (HAS_EPRI(mon) ? EPRI(mon)->shralign == A_CHAOTIC :\
HAS_EMIN(mon) ? EMIN(mon)->min_align == A_CHAOTIC :\
hates_lawful((mon)->data)))
#define hates_chaos(ptr) (is_lawful(ptr) || (ptr)->mtyp == PM_UVUUDAUM)
#define hates_chaos_mon(mon) ((mon) == &youmonst ? u.ualign.type == A_LAWFUL : (HAS_EPRI(mon) ? EPRI(mon)->shralign == A_LAWFUL :\
HAS_EMIN(mon) ? EMIN(mon)->min_align == A_LAWFUL :\
hates_chaos((mon)->data)))
#define sflm_target(mon) (!is_rider((mon)->data) && (is_angel((mon)->data) || ((mon) == &youmonst ? Displaced : mon_resistance(mon, DISPLACED)) || is_shapechanger((mon)->data) || is_chaotic_mon(mon)))
#define sflm_target_data(ptr) (!is_rider(ptr) && (is_angel(ptr) || ((ptr)->mflagsg&MG_DISPLACEMENT) || is_shapechanger(ptr) || is_chaotic(ptr)))
#define melee_polearms(ptr) ((ptr)->mtyp == PM_VROCK ||\
(ptr)->mtyp == PM_MEPHISTOPHELES ||\
(ptr)->mtyp == PM_BAPHOMET \
)
#define throws_rocks(ptr) (((ptr)->mflagst & MT_ROCKTHROW) != 0L)
#define type_is_pname(ptr) (((ptr)->mflagsg & MG_PNAME) != 0L)
#define is_thief(ptr) ( dmgtype(ptr, AD_SGLD) || dmgtype(ptr, AD_SITM) || dmgtype(ptr, AD_SEDU) )
#define is_magical(ptr) ( attacktype(ptr, AT_MMGC) || attacktype(ptr, AT_MAGC) )
#define nospellcooldowns(ptr) ((((ptr)->mflagsg & MG_NOSPELLCOOLDOWN) != 0L) || ((ptr)->mtyp == PM_TWIN_SIBLING && check_mutation(SHUB_RADIANCE)))
#define nospellcooldowns_mon(mtmp) (nospellcooldowns((mtmp)->data) || (is_alabaster_mummy((mtmp)->data) && (mtmp)->mvar_syllable == SYLLABLE_OF_THOUGHT__NAEN))
#define is_lord(ptr) (((ptr)->mflagsg & MG_LORD) != 0L)
#define is_prince(ptr) (((ptr)->mflagsg & MG_PRINCE) != 0L)
#define is_normal_demon(ptr) (is_demon(ptr) && \
(((ptr)->mflagsg & (MG_LORD|MG_PRINCE)) == 0L))
#define is_dlord(ptr) (is_demon(ptr) && is_lord(ptr))
#define is_dprince(ptr) (is_demon(ptr) && is_prince(ptr))
#define is_dnoble(ptr) (is_demon(ptr) && (is_lord(ptr) || is_prince(ptr)))
#define is_minion(ptr) ((ptr)->mflagsa & MA_MINION)
#define likes_gold(ptr) (((ptr)->mflagst & MT_GREEDY) != 0L)
#define likes_gems(ptr) (((ptr)->mflagst & MT_JEWELS) != 0L)
#define likes_objs(ptr) (((ptr)->mflagst & MT_COLLECT) != 0L || \
(is_armed(ptr) && !mindless(ptr)))
#define likes_magic(ptr) (((ptr)->mflagst & MT_MAGIC) != 0L)
#define webmaker(ptr) ((ptr)->mtyp == PM_CAVE_SPIDER || \
(ptr)->mtyp == PM_GIANT_SPIDER || (ptr)->mtyp == PM_PHASE_SPIDER || \
(ptr)->mtyp == PM_MIRKWOOD_SPIDER || (ptr)->mtyp == PM_MIRKWOOD_ELDER || \
(ptr)->mtyp == PM_SPROW || (ptr)->mtyp == PM_DRIDER || (ptr)->mtyp == PM_ALIDER || \
(ptr)->mtyp == PM_EDDERKOP || (ptr)->mtyp == PM_MISKA || (ptr)->mtyp == PM_CHUPOCLOPS || \
(ptr)->mtyp == PM_MENDICANT_SPROW || (ptr)->mtyp == PM_MENDICANT_DRIDER || \
(ptr)->mtyp == PM_AVATAR_OF_LOLTH || (ptr)->mtyp == PM_DROW_MUMMY)
#define is_unicorn(ptr) ((ptr)->mlet == S_UNICORN && likes_gems(ptr))
#define is_longworm(ptr) (\
((ptr)->mtyp == PM_LONG_WORM) || \
((ptr)->mtyp == PM_LONG_WORM_TAIL) || \
((ptr)->mtyp == PM_HUNTING_HORROR) || \
((ptr)->mtyp == PM_HUNTING_HORROR_TAIL))
#define is_shapechanger(ptr) ((ptr)->mtyp == PM_CHAMELEON\
|| (ptr)->mtyp == PM_DOPPELGANGER\
|| (ptr)->mtyp == PM_SANDESTIN\
|| (ptr)->mtyp == PM_DREAM_QUASIELEMENTAL\
|| is_were(ptr)\
|| (ptr)->mlet == S_MIMIC\
)
#define wants_bell(ptr) ((ptr->mflagst & MT_WANTSBELL))
#define wants_book(ptr) ((ptr->mflagst & MT_WANTSBOOK))
#define wants_cand(ptr) ((ptr->mflagst & MT_WANTSCAND))
#define wants_qart(ptr) ((ptr->mflagst & MT_WANTSARTI))
#define wants_amul(ptr) ((ptr->mflagst & MT_COVETOUS))
#define is_covetous(ptr) ((ptr->mflagst & MT_COVETOUS))
#define quest_faction(mon) ((mon)->mfaction == QUEST_FACTION || (Race_if(PM_DROW) && (mon)->mfaction == u.uhouse))
#define normalvision(ptr) ((ptr->mflagsv & MV_NORMAL))
#define darksight(ptr) ((ptr->mflagsv & MV_DARKSIGHT))
#define catsight(ptr) ((ptr->mflagsv & MV_CATSIGHT))
#define lowlightsight2(ptr) ((ptr->mflagsv & MV_LOWLIGHT2))
#define lowlightsight3(ptr) ((ptr->mflagsv & MV_LOWLIGHT3))
#define echolocation(ptr) ((ptr->mflagsv & MV_ECHOLOCATE))
#define extramission(ptr) ((ptr->mflagsv & MV_EXTRAMISSION))
#define rlyehiansight(ptr) ((ptr->mflagsv & MV_RLYEHIAN))
#define infravision(ptr) ((ptr->mflagsv & MV_INFRAVISION))
#define infravisible(ptr) ((ptr->mflagsg & MG_INFRAVISIBLE))
#define infravisible_mon(mon) (infravisible((mon)->data))
#define bloodsense(ptr) ((ptr->mflagsv & MV_BLOODSENSE))
#define lifesense(ptr) ((ptr->mflagsv & MV_LIFESENSE))
#define earthsense(ptr) ((ptr->mflagsv & MV_EARTHSENSE))
#define senseall(ptr) ((ptr->mflagsv & MV_DETECTION))
#define omnisense(ptr) ((ptr->mflagsv & MV_OMNI))
#define can_betray(ptr) ((ptr->mflagst & MT_TRAITOR))
// #define opaque(ptr) (((ptr)->mflagsg & MG_OPAQUE))
#define opaque(ptr) (FALSE)
#define mteleport(ptr) (((ptr)->mflagsm & MM_TENGTPORT))
#define is_mplayer(ptr) (((ptr)->mtyp >= PM_ARCHEOLOGIST) && \
((ptr)->mtyp <= PM_WIZARD))
#define is_deadly(ptr) ((ptr)->mflagsg & MG_DEADLY)
#define is_rider(ptr) ((ptr)->mflagsg & MG_RIDER)
#define rider_hp(ptr) ((ptr)->mflagsg & MG_RIDER_HP)
#define is_placeholder(ptr) ((ptr)->mtyp == PM_ORC || \
(ptr)->mtyp == PM_GIANT || \
(ptr)->mtyp == PM_ELF || \
(ptr)->mtyp == PM_HUMAN)
/* return TRUE if the monster tends to revive */
#define is_reviver(ptr) (is_rider(ptr) || (ptr)->mlet == S_TROLL || (ptr)->mlet == S_FUNGUS)
#define is_demihuman(ptr) ((ptr->mflagsa & MA_DEMIHUMAN))
/* this returns the light's range, or 0 if none; if we add more light emitting
monsters, we'll likely have to add a new light range field to mons[]
KEEP IN SYNC with MAX_RADIUS, circle_data, and circle_start[].
Maximum allowable lightsource radius is currently 10 (30 after 3x lowlight modifier) */
#define emits_light(ptr) (((ptr)->mlet == S_LIGHT || \
(ptr)->mtyp == PM_BRIGHT_WALKER || \
(ptr)->mtyp == PM_FLAMING_SPHERE || \
(ptr)->mtyp == PM_SHOCKING_SPHERE || \
(ptr)->mtyp == PM_PARASITIZED_DOLL || \
(ptr)->mtyp == PM_MOTE_OF_LIGHT || \
(ptr)->mtyp == PM_BALL_OF_LIGHT || \
(ptr)->mtyp == PM_LIGHT_ELF || \
(ptr)->mtyp == PM_BLOODY_SUNSET || \
(ptr)->mtyp == PM_BALL_OF_GOSSAMER_SUNLIGHT || \
(ptr)->mtyp == PM_LUMINOUS_CLOUD || \
(ptr)->mtyp == PM_HOOLOOVOO || \
(ptr)->mtyp == PM_LIGHTNING_PARAELEMENTAL || \
(ptr)->mtyp == PM_FALLEN_ANGEL || \
(ptr)->mtyp == PM_ANCIENT_OF_THOUGHT || \
(ptr)->mtyp == PM_DARK_WORM || \
(ptr)->mtyp == PM_FIRE_VORTEX) ? 1 : \
((ptr)->mtyp == PM_FIRE_ELEMENTAL ||\
(ptr)->mtyp == PM_FLAMING_ORB || \
(ptr)->mtyp == PM_CANDLE_TREE || \
(ptr)->mtyp == PM_PARASITIZED_KNIGHT || \
(ptr)->mtyp == PM_DANCING_FLAME ||\
(ptr)->mtyp == PM_COTERIE_OF_MOTES ||\
(ptr)->mtyp == PM_BALL_OF_RADIANCE) ? 2 : \
((ptr)->mtyp == PM_THRONE_ARCHON ||\
(ptr)->mtyp == PM_UNBODIED ||\
(ptr)->mtyp == PM_BEAUTEOUS_ONE ||\
(ptr)->mtyp == PM_DAO_LAO_GUI_MONK ||\
(ptr)->mtyp == PM_ASPECT_OF_THE_SILENCE) ? 3 : \
((ptr)->mtyp == PM_BLESSED) ? 4 : \
((ptr)->mtyp == PM_LIGHT_ARCHON|| \
(ptr)->mtyp == PM_GOD ||\
(ptr)->mtyp == PM_LUCIFER) ? 7 : \
((ptr)->mtyp == PM_EDDERKOP) ? 8 : \
((ptr)->mtyp == PM_SURYA_DEVA) ? 9 : \
0)
#define emits_light_mon(mon) (has_template(mon, ILLUMINATED) ? \
max(3, emits_light((mon)->data)) : \
emits_light((mon)->data))
#define Is_darklight_monster(ptr) ((ptr)->mtyp == PM_EDDERKOP\
|| (ptr)->mtyp == PM_DARK_WORM\
|| (ptr)->mtyp == PM_ASPECT_OF_THE_SILENCE\
|| (ptr)->mtyp == PM_DAO_LAO_GUI_MONK\
)
/* [note: the light ranges above were reduced to 1 for performance...] */
#define likes_lava(ptr) ( \
(ptr)->mtyp == PM_FIRE_ELEMENTAL || \
is_salamander(ptr) \
)
#define is_salamander(ptr) ((ptr)->mtyp == PM_FIRE_SNAKE || \
(ptr)->mtyp == PM_SALAMANDER_SLAVE ||\
(ptr)->mtyp == PM_SALAMANDER_PRISONER ||\
(ptr)->mtyp == PM_SALAMANDER_MAGE ||\
(ptr)->mtyp == PM_SALAMANDER)
#define is_efreeti(ptr) ((ptr)->mtyp == PM_EFREET || \
(ptr)->mtyp == PM_EFREET_OVERSEER ||\
(ptr)->mtyp == PM_EFREET_GUARDIAN ||\
(ptr)->mtyp == PM_EFREET_MERCHANT ||\
(ptr)->mtyp == PM_EFREET_SULTAN)
#define pm_invisible(ptr) ( \
(ptr)->mtyp == PM_STALKER || \
(ptr)->mtyp == PM_BLACK_LIGHT ||\
(ptr)->mtyp == PM_PHANTOM_FUNGUS ||\
(ptr)->mtyp == PM_CENTER_OF_ALL ||\
(ptr)->mtyp == PM_DARKNESS_GIVEN_HUNGER ||\
(ptr)->mtyp == PM_ANCIENT_OF_DEATH\
)
/* could probably add more */
#define likes_fire(ptr) ( \
(ptr)->mtyp == PM_FIRE_VORTEX || \
(ptr)->mtyp == PM_FLAMING_SPHERE || \
likes_lava(ptr))
#define touch_petrifies(ptr) ((ptr)->mtyp == PM_COCKATRICE || \
(ptr)->mtyp == PM_CHICKATRICE)
#define mad_no_armor(mon) ((mon)->mdisrobe || (mon)->mnudist)
#define is_weeping(ptr) ((ptr)->mtyp == PM_WEEPING_ANGEL)
#define is_alienist(ptr) (is_mind_flayer(ptr) || \
(ptr)->mlet == S_UMBER ||\
(ptr)->mtyp == PM_DROW_ALIENIST ||\
(ptr)->mtyp == PM_DARUTH_XAXOX ||\
(ptr)->mtyp == PM_EMBRACED_DROWESS\
)
#define has_mind_blast_mon(mon) ((has_mind_blast((mon)->data) \
|| has_template(mon, DREAM_LEECH) \
) && !((mon)->mtyp == PM_MAD_SEER && (mon)->mspec_used)\
&& ((mon)->mnotlaugh)\
&& !((mon)->mcan)\
)
#define has_mind_blast(ptr) (is_mind_flayer(ptr) \
|| (ptr)->mtyp == PM_BRAIN_GOLEM \
|| (ptr)->mtyp == PM_SEMBLANCE \
|| (ptr)->mtyp == PM_FUNGAL_BRAIN \
|| (ptr)->mtyp == PM_LADY_CONSTANCE \
|| (ptr)->mtyp == PM_MADMAN \
|| (ptr)->mtyp == PM_MADWOMAN \
|| (ptr)->mtyp == PM_MAD_SEER \
|| (ptr)->mtyp == PM_CLAIRVOYANT_CHANGED \
|| ((ptr)->mtyp == PM_TWIN_SIBLING && check_mutation(TWIN_DREAMS)) \
)
#define insightful(ptr) (yields_insight(ptr) \
|| is_great_old_one(ptr) \
|| is_primordial(ptr) \
|| has_mind_blast(ptr) \
|| (ptr)->mtyp == PM_JRT_NETJER \
)
#define is_mind_flayer(ptr) ((ptr)->mtyp == PM_MIND_FLAYER || \
(ptr)->mtyp == PM_MASTER_MIND_FLAYER || \
(ptr)->mtyp == PM_ADVERSARY || \
(ptr)->mtyp == PM_VILLITHID || \
(ptr)->mtyp == PM_ULITHARID || \
(ptr)->mtyp == PM_MENZOBERRANZAN || \
(ptr)->mtyp == PM_STAR_SPAWN || \
(ptr)->mtyp == PM_MAD_GRAZI || \
(ptr)->mtyp == PM_PARASITIZED_ANDROID || \
(ptr)->mtyp == PM_PARASITIZED_GYNOID || \
(ptr)->mtyp == PM_PARASITIC_MIND_FLAYER || \
(ptr)->mtyp == PM_PARASITIC_MASTER_MIND_FLAYER || \
(ptr)->mtyp == PM_ALHOON || \
(ptr)->mtyp == PM_ELDER_BRAIN || \
(ptr)->mtyp == PM_LUGRIBOSSK || \
(ptr)->mtyp == PM_MAANZECORIAN || \
(ptr)->mtyp == PM_GREAT_CTHULHU \
)
#define is_extradimensional(ptr) ((ptr)->mtyp == PM_STAR_SPAWN || \
(ptr)->mtyp == PM_GREAT_CTHULHU || \
(ptr)->mtyp == PM_DREAM_EATER || \
(ptr)->mtyp == PM_VEIL_RENDER || \
((ptr)->mtyp == PM_LADY_CONSTANCE && !rn2(2)) || \
mad_monster_turn((ptr), MAD_NON_EUCLID) \
)
#define is_android(ptr) ((ptr)->mtyp == PM_ANDROID || \
(ptr)->mtyp == PM_GYNOID || \
(ptr)->mtyp == PM_OPERATOR || \
(ptr)->mtyp == PM_COMMANDER || \
(ptr)->mtyp == PM_MUMMIFIED_ANDROID || \
(ptr)->mtyp == PM_MUMMIFIED_GYNOID || \
(ptr)->mtyp == PM_FLAYED_ANDROID || \
(ptr)->mtyp == PM_FLAYED_GYNOID || \
(ptr)->mtyp == PM_CRUCIFIED_ANDROID || \
(ptr)->mtyp == PM_CRUCIFIED_GYNOID || \
(ptr)->mtyp == PM_PARASITIZED_ANDROID || \
(ptr)->mtyp == PM_PARASITIZED_GYNOID || \
(ptr)->mtyp == PM_PARASITIZED_OPERATOR || \
(ptr)->mtyp == PM_PARASITIZED_COMMANDER \
)
#define free_android(ptr) ((ptr)->mtyp == PM_ANDROID || \
(ptr)->mtyp == PM_GYNOID || \
(ptr)->mtyp == PM_OPERATOR || \
(ptr)->mtyp == PM_COMMANDER \
)
#define is_dollable(ptr) ((ptr)->mtyp == PM_ANDROID || \
(ptr)->mtyp == PM_GYNOID || \
(ptr)->mtyp == PM_OPERATOR || \
(ptr)->mtyp == PM_COMMANDER || \
(ptr)->mtyp == PM_LIVING_DOLL \
)
#define stuck_in_time(mtmp) (mtmp->mtyp != PM_EDDERKOP\
&& mtmp->mtyp != PM_EMBRACED_DROWESS\
&& mtmp->mtyp != PM_PARASITIZED_EMBRACED_ALIDER\
&& !is_mind_flayer(mtmp)\
&& !has_template(mtmp, M_BLACK_WEB)\
&& !has_template(mtmp, M_GREAT_WEB)\
&& !has_template(mtmp, PSEUDONATURAL)\
&& !has_template(mtmp, FRACTURED)\
&& !is_naturally_unalive(mtmp->data)\
)
#define is_changed_mtyp(mtyp) (mtyp == PM_CHANGED || mtyp == PM_WARRIOR_CHANGED || mtyp == PM_TWITCHING_FOUR_ARMED_CHANGED || mtyp == PM_CLAIRVOYANT_CHANGED)
#define nonliving(ptr) (is_unalive(ptr) || is_undead(ptr) || \
(ptr)->mtyp == PM_MANES \
)
#define is_unalive(ptr) (on_level(&valley_level, &u.uz) || is_naturally_unalive(ptr))
#define is_naturally_unalive(ptr) (((ptr)->mflagsa & MA_UNLIVING))
#define is_indigestible(ptr) (((ptr)->mflagsb&MB_INDIGESTIBLE) != 0)
// #define is_indigestible(ptr) ((ptr)->mtyp == PM_DANCING_BLADE ||\
// (ptr)->mtyp == PM_EARTH_ELEMENTAL ||\
// (ptr)->mtyp == PM_TERRACOTTA_SOLDIER ||\
// (ptr)->mtyp == PM_CLOCKWORK_SOLDIER ||\
// (ptr)->mtyp == PM_CLOCKWORK_DWARF ||\
// (ptr)->mtyp == PM_CLOCKWORK_FACTORY ||\
// (ptr)->mtyp == PM_GOLDEN_HEART ||\
// (ptr)->mtyp == PM_JUGGERNAUT ||\
// (ptr)->mtyp == PM_ID_JUGGERNAUT ||\
// (ptr)->mtyp == PM_SCRAP_TITAN ||\
// (ptr)->mtyp == PM_HELLFIRE_COLOSSUS ||\
// (ptr)->mtyp == PM_HELLFIRE_ORB ||\
// (ptr)->mtyp == PM_CLOCKWORK_AUTOMATON ||\
// (ptr)->mtyp == PM_COLOSSAL_CLOCKWORK_WAR_MACHINE ||\
// (ptr)->mtyp == PM_MALKUTH_SEPHIRAH ||\
// (ptr)->mtyp == PM_YESOD_SEPHIRAH ||\
// (ptr)->mtyp == PM_DAAT_SEPHIRAH ||\
// (ptr)->mtyp == PM_HOD_SEPHIRAH ||\
// (ptr)->mtyp == PM_NETZACH_SEPHIRAH ||\
// (ptr)->mtyp == PM_GEVURAH_SEPHIRAH ||\
// (ptr)->mtyp == PM_BINAH_SEPHIRAH ||\
// (ptr)->mtyp == PM_CHOKHMAH_SEPHIRAH ||\
// (ptr)->mtyp == PM_HALF_STONE_DRAGON ||\
// (ptr)->mtyp == PM_HOOLOOVOO ||\
// (ptr)->mtyp == PM_GOLD_GOLEM ||\
// (ptr)->mtyp == PM_CLAY_GOLEM ||\
// (ptr)->mtyp == PM_TREASURY_GOLEM ||\
// (ptr)->mtyp == PM_SEMBLANCE ||\
// (ptr)->mtyp == PM_STONE_GOLEM ||\
// (ptr)->mtyp == PM_GLASS_GOLEM ||\
// (ptr)->mtyp == PM_IRON_GOLEM ||\
// (ptr)->mtyp == PM_GREEN_STEEL_GOLEM ||\
// (ptr)->mtyp == PM_ARGENTUM_GOLEM ||\
// (ptr)->mtyp == PM_RETRIEVER ||\
// (ptr)->mtyp == PM_LIVING_DOLL ||\
// (ptr)->mtyp == PM_ARA_KAMEREL ||\
// (ptr)->mtyp == PM_ANCIENT_OF_DEATH ||\
// (ptr)->mtyp == PM_PALE_NIGHT ||\
// (ptr)->mtyp == PM_BAALPHEGOR ||\
// (ptr)->mtyp == PM_ARCADIAN_AVENGER ||\
// (ptr)->mtyp == PM_DAMAGED_ARCADIAN_AVENGER ||\
// (ptr)->mtyp == PM_MUMMIFIED_ANDROID ||\
// (ptr)->mtyp == PM_MUMMIFIED_GYNOID ||\
// (ptr)->mtyp == PM_FLAYED_ANDROID ||\
// (ptr)->mtyp == PM_FLAYED_GYNOID ||\
// (ptr)->mtyp == PM_CRUCIFIED_ANDROID ||\
// (ptr)->mtyp == PM_CRUCIFIED_GYNOID ||\
// (ptr)->mtyp == PM_ANDROID ||\
// (ptr)->mtyp == PM_GYNOID ||\
// (ptr)->mtyp == PM_OPERATOR ||\
// (ptr)->mtyp == PM_COMMANDER ||\
// (ptr)->mtyp == PM_SENTINEL_OF_MITHARDIR ||\
// (ptr)->mtyp == PM_CHAIN_GOLEM ||\
// is_uvuudaum(ptr) ||\
// is_rilmani(ptr))
#define is_delouseable(ptr) ((ptr)->mtyp == PM_PARASITIZED_DOLL ||\
(ptr)->mtyp == PM_PARASITIZED_ANDROID ||\
(ptr)->mtyp == PM_PARASITIZED_GYNOID ||\
(ptr)->mtyp == PM_PARASITIZED_OPERATOR ||\
(ptr)->mtyp == PM_PARASITIZED_COMMANDER)
#define is_elemental(ptr) ( (ptr->mflagsa & MA_ELEMENTAL) )
#define mon_archeologist(mon) ((mon)->mtyp == PM_ARCHEOLOGIST || (mon)->mtyp == PM_LORD_CARNARVON || (mon)->mtyp == PM_STUDENT || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_ARCHEOLOGIST)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_ARCHEOLOGIST))
#define mon_anachrononaut(mon) ((mon)->mtyp == PM_ANACHRONONAUT || (mon)->mtyp == PM_TROOPER || is_myrkalfr(mon) || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_ANACHRONONAUT)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_ANACHRONONAUT))
#define mon_barbarian(mon) ((mon)->mtyp == PM_BARBARIAN || (mon)->mtyp == PM_HALF_DRAGON || (mon)->mtyp == PM_ORC_WARCHIEF || \
(mon)->mtyp == PM_CHIEFTAIN || (mon)->mtyp == PM_ORC_WARRIOR || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_BARBARIAN)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_BARBARIAN))
#define mon_bard(mon) ((mon)->mtyp == PM_BARD || (mon)->mtyp == PM_PINDAR || (mon)->mtyp == PM_RHYMER || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_BARD)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_BARD))
#define mon_caveman(mon) ((mon)->mtyp == PM_CAVEMAN || (mon)->mtyp == PM_CAVEWOMAN || (mon)->mtyp == PM_SHAMAN_KARNOV || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_CAVEMAN)) || \
(mon)->mtyp == PM_NEANDERTHAL || ((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_CAVEMAN))
#define mon_convict(mon) ((mon)->mtyp == PM_CONVICT || (mon)->mtyp == PM_ROBERT_THE_LIFER || (mon)->mtyp == PM_INMATE || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_CONVICT)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_CONVICT))
#define mon_healer(mon) ((mon)->mtyp == PM_HEALER || (mon)->mtyp == PM_HIPPOCRATES || (mon)->mtyp == PM_ATTENDANT || \
(mon)->mtyp == PM_SISTER_T_EIRASTRA || (mon)->mtyp == PM_PEN_A_MENDICANT || (mon)->mtyp == PM_MENDICANT_DRIDER || \
(mon)->mtyp == PM_MENDICANT_SPROW || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_HEALER)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_HEALER))
#define mon_undead_hunter(mon) (((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_HUNTER))
#define mon_knight(mon) ((mon)->mtyp == PM_KNIGHT || (mon)->mtyp == PM_KING_ARTHUR || (mon)->mtyp == PM_SIR_GARLAND || \
(mon)->mtyp == PM_GARLAND || (mon)->mtyp == PM_CELEBORN || (mon)->mtyp == PM_DANTRAG || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_KNIGHT)) || \
(mon)->mtyp == PM_PAGE || ((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_KNIGHT))
#define mon_turn_undead(mon) ((mon)->mtyp == PM_KNIGHT || (mon)->mtyp == PM_KING_ARTHUR || \
(mon)->mtyp == PM_BRIGHID_ELADRIN || \
(mon)->mtyp == PM_DRACAE_ELADRIN || \
(mon)->mtyp == PM_LIGHT_ELF || (mon)->mtyp == PM_UNBODIED || \
(mon)->mtyp == PM_KUKER || (mon)->mtyp == PM_SHIELD_ARCHON || \
(mon)->mtyp == PM_MONADIC_DEVA || \
(mon)->mtyp == PM_ALRUNES || (mon)->mtyp == PM_HATEFUL_WHISPERS || \
(mon)->mtyp == PM_ELF_LORD || (mon)->mtyp == PM_ELVENKING || \
(mon)->mtyp == PM_CELEBORN || (mon)->mtyp == PM_DANTRAG || \
(mon)->mtyp == PM_ARIANNA || (mon)->mtyp == PM_BLIBDOOLPOOLP_S_MINDGRAVEN_CHAMPION || \
(mon)->mtyp == PM_REBEL_RINGLEADER || (mon)->mtyp == PM_RADIANT_PYRAMID || \
(mon)->mtyp == PM_SIR_ALJANOR || (mon)->mtyp == PM_ALLIANCE_VANGUARD || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_KNIGHT)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_KNIGHT))
#define mon_healing_turn(mon) ((mon)->mtyp == PM_DRACAE_ELADRIN || (mon)->mtyp == PM_UNBODIED)
#define mon_monk(mon) ((mon)->mtyp == PM_MONK || (mon)->mtyp == PM_GRAND_MASTER || (mon)->mtyp == PM_ABBOT || \
(mon)->mtyp == PM_ITINERANT_PRIESTESS || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_MONK)) || \
(mon)->mtyp == PM_XUENU_MONK || ((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_MONK))
#define mon_madman(mon) ((mon)->mtyp == PM_MADMAN || (mon)->mtyp == PM_MADWOMAN || (mon)->mtyp == PM_CASSILDA_THE_IRON_MAIDEN || \
(mon)->mtyp == PM_PATIENT || (mon)->mtyp == PM_CONTAMINATED_PATIENT || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_MADMAN)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_MADMAN))
#define mon_pirate(mon) ((mon)->mtyp == PM_PIRATE || (mon)->mtyp == PM_MAYOR_CUMMERBUND || (mon)->mtyp == PM_BLACKBEARD_S_GHOST || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_PIRATE)) || \
(mon)->mtyp == PM_PIRATE_BROTHER || ((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_PIRATE))
#define mon_priest(mon) ((mon)->mtyp == PM_PRIEST || (mon)->mtyp == PM_PRIESTESS || (mon)->mtyp == PM_ITINERANT_PRIESTESS ||\
(mon)->mtyp == PM_ECLAVDRA || (mon)->mtyp == PM_GALADRIEL || (mon)->mtyp == PM_MOTHER ||\
(mon)->mtyp == PM_DROW_NOVICE || (mon)->mtyp == PM_ARCH_PRIEST || (mon)->mtyp == PM_SEYLL_AUZKOVYN || \
(mon)->mtyp == PM_A_SALOM || (mon)->mtyp == PM_DROW_MATRON_MOTHER || (mon)->mtyp == PM_HIGH_ELF || \
(mon)->mtyp == PM_STJARNA_ALFR || (mon)->mtyp == PM_SISTER || (mon)->mtyp == PM_ACOLYTE || \
(mon)->mtyp == PM_PRIEST_OF_GHAUNADAUR || (mon)->mtyp == PM_DWARF_CLERIC || (mon)->mtyp == PM_DWARF_QUEEN || \
(mon)->mtyp == PM_ELVENKING || (mon)->mtyp == PM_ELVENQUEEN || (mon)->mtyp == PM_MILITANT_CLERIC || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_PRIEST)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_PRIEST))
#define mon_ranger(mon) ((mon)->mtyp == PM_RANGER || (mon)->mtyp == PM_ORION || (mon)->mtyp == PM_HALF_ELF_RANGER || (mon)->mtyp == PM_HUNTER || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_RANGER)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_RANGER))
#define mon_rogue(mon) ((mon)->mtyp == PM_ROGUE || (mon)->mtyp == PM_MASTER_OF_THIEVES || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_ROGUE)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_ROGUE))
#define mon_samurai(mon) ((mon)->mtyp == PM_SAMURAI || (mon)->mtyp == PM_LORD_SATO || (mon)->mtyp == PM_ASHIKAGA_TAKAUJI || (mon)->mtyp == PM_ROSHI || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_SAMURAI)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_SAMURAI))
#define mon_tourist(mon) ((mon)->mtyp == PM_TOURIST || (mon)->mtyp == PM_TWOFLOWER || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_TOURIST)) || \
((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_TOURIST))
#define mon_valkyrie(mon) ((mon)->mtyp == PM_VALKYRIE || (mon)->mtyp == PM_AWAKENED_VALKYRIE || (mon)->mtyp == PM_TRANSCENDENT_VALKYRIE || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_VALKYRIE)) || \
(mon)->mtyp == PM_WARRIOR || ((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_VALKYRIE))
#define mon_wizard(mon) ((mon)->mtyp == PM_WIZARD || (mon)->mtyp == PM_WORM_THAT_WALKS || (mon)->mtyp == PM_INCANTIFIER || \
(mon)->mtyp == PM_NEFERET_THE_GREEN || (mon)->mtyp == PM_NIMUNE || (mon)->mtyp == PM_ADVENTURING_WIZARD || \
(mon)->mtyp == PM_HEDROW_MASTER_WIZARD || (mon)->mtyp == PM_GROMPH || (mon)->mtyp == PM_GUIDE || \
((mon)->mtyp == PM_HOD_SEPHIRAH && Role_if(PM_WIZARD)) || \
(mon)->mtyp == PM_APPRENTICE || ((mon)->mtyp == PM_DEMINYMPH && (mon)->mvar_deminymph_role == PM_WIZARD))
#define is_vectored_mtyp(mtyp) (is_random_vectored_mtyp(mtyp) || is_guided_vectored_mtyp(mtyp))
#define is_random_vectored_mtyp(mtyp) ((mtyp) == PM_CLOCKWORK_SOLDIER || (mtyp) == PM_CLOCKWORK_DWARF || \
(mtyp) == PM_FABERGE_SPHERE || (mtyp) == PM_FIREWORK_CART)
#define is_guided_vectored_mtyp(mtyp) ((mtyp) == PM_JUGGERNAUT || (mtyp) == PM_ID_JUGGERNAUT)
#define is_smith_mtyp(mtyp) ((mtyp) == PM_OONA || (mtyp) == PM_DRACAE_ELADRIN || (mtyp) == PM_GOBLIN_SMITH || (mtyp) == PM_DWARF_SMITH\
|| (mtyp) == PM_MITHRIL_SMITH || (mtyp) == PM_SHADOWSMITH || (mtyp) == PM_HUMAN_SMITH || (mtyp) == PM_TREESINGER)
#define needs_forge_mon(mon) (!(ESMT(mon)->smith_mtyp == PM_OONA || ESMT(mon)->smith_mtyp == PM_DRACAE_ELADRIN || ESMT(mon)->smith_mtyp == PM_SHADOWSMITH))
#define likes_swamp(ptr) ((ptr)->mlet == S_PUDDING || \
(ptr)->mlet == S_FUNGUS || \
(ptr)->mtyp == PM_OCHRE_JELLY)
#define stationary_mon(mon) (stationary((mon)->data) || \
((mon)->mtyp == PM_ETHEREAL_FILCHER && (mon)->mcan) || \
((mon) != &youmonst ? (which_armor((mon), W_ARMF) && which_armor((mon), W_ARMF)->otyp == SHACKLES && which_armor((mon), W_ARMF)->cursed) :\
(uarmf && uarmf->otyp == SHACKLES && uarmf->cursed)))
#define stationary(ptr) ((ptr)->mflagsm & MM_STATIONARY)
#define sessile(ptr) ((ptr)->mmove == 0)
#define straitjacketed_mon(mon) (mon->entangled_oid || shackled_arms_mon(mon) || (which_armor(mon, W_ARM) && which_armor(mon, W_ARM)->otyp == STRAITJACKET && which_armor(mon, W_ARM)->cursed))
#define shackled_arms_mon(mon) (which_armor(mon, W_ARMG) && which_armor(mon, W_ARMG)->otyp == SHACKLES && which_armor(mon, W_ARMG)->cursed)
#define covered_face_mon(mon) ((which_armor(mon, W_ARMH) && FacelessHelm(which_armor(mon, W_ARMH))) || \
(which_armor(mon, W_ARMC) && FacelessCloak(which_armor(mon, W_ARMC))) \
)
/* Used for conduct with corpses, tins, and digestion attacks */
/* G_NOCORPSE monsters might still be swallowed as a purple worm */
/* Maybe someday this could be in mflags... */
/** Shogooths are vegan :-/ **/
#define vegan(ptr) (((ptr)->mlet == S_BLOB \
&& (ptr)->mtyp != PM_BLOB_OF_PRESERVED_ORGANS\
&& (ptr)->mtyp != PM_BLOOD_BLOATER\
&& (ptr)->mtyp != PM_COILING_BRAWN\
) || \
(ptr)->mlet == S_JELLY || \
((ptr)->mlet == S_FUNGUS && \
!is_migo(ptr)) || \
(ptr)->mlet == S_VORTEX || \
(ptr)->mlet == S_LIGHT || \
(ptr)->mlet == S_PLANT || \
is_fern_spore(ptr) || \
(ptr)->mtyp == PM_GAS_SPORE || \
is_elemental_sphere(ptr) || \
is_gizmo(ptr) || \
(is_clockwork(ptr) && \
is_naturally_unalive(ptr)) || \
((ptr)->mlet == S_ELEMENTAL && \
(ptr)->mtyp != PM_STALKER) || \
((ptr)->mlet == S_GOLEM && \
(ptr)->mtyp != PM_FLESH_GOLEM && \
(ptr)->mtyp != PM_LEATHER_GOLEM) || \
(ptr)->mtyp == PM_WOOD_TROLL || \
noncorporeal(ptr))
#define is_burnable(ptr) ((ptr)->mlet == S_PLANT || \
((ptr)->mlet == S_FUNGUS && !is_migo(ptr)) || \
is_fern_spore(ptr) || \
(ptr)->mtyp == PM_WOOD_TROLL)
#define vegetarian(ptr) (vegan(ptr) || \
((ptr)->mlet == S_PUDDING && \
(ptr)->mtyp != PM_BLACK_PUDDING && \
(ptr)->mtyp != PM_DARKNESS_GIVEN_HUNGER))
/* For vampires */
#define has_blood(ptr) (!vegetarian(ptr) && \
(ptr)->mlet != S_GOLEM && \
(ptr)->mlet != S_KETER && \
(ptr)->mlet != S_MIMIC && \
(ptr)->mtyp != PM_WEEPING_ANGEL && \
(ptr)->mtyp != PM_GREAT_CTHULHU && \
(ptr)->mtyp != PM_STAR_SPAWN && \
!is_clockwork(ptr) && \
(!nonliving(ptr) || is_vampire(ptr)))
#define has_blood_mon(mon) (has_blood((mon)->data))
/* Keep track of ferns, fern sprouts, fern spores, and other plants */
#define is_fern_sprout(ptr) ((ptr)->mtyp == PM_DUNGEON_FERN_SPROUT || \
(ptr)->mtyp == PM_SWAMP_FERN_SPROUT || \
(ptr)->mtyp == PM_BURNING_FERN_SPROUT)
#define is_fern_spore(ptr) ((ptr)->mtyp == PM_DUNGEON_FERN_SPORE || \
(ptr)->mtyp == PM_SWAMP_FERN_SPORE || \
(ptr)->mtyp == PM_BURNING_FERN_SPORE)
#define is_fern(ptr) (is_fern_sprout(ptr) || \
(ptr)->mtyp == PM_DUNGEON_FERN || \
(ptr)->mtyp == PM_SWAMP_FERN || \
(ptr)->mtyp == PM_BURNING_FERN)
#define is_elemental_sphere(ptr) ((ptr)->mtyp == PM_FREEZING_SPHERE || \
(ptr)->mtyp == PM_FLAMING_SPHERE || \
(ptr)->mtyp == PM_SHOCKING_SPHERE || \
(ptr)->mtyp == PM_VEXING_ORB || \
(ptr)->mtyp == PM_FLAMING_ORB)
#define is_vegetation(ptr) ((ptr)->mlet == S_PLANT || is_fern(ptr))
#define befriend_with_obj(ptr, obj) (((obj)->oclass == FOOD_CLASS ||\
(obj)->otyp == SHEAF_OF_HAY) && \
(is_domestic(ptr) || (is_rat(ptr) && Role_if(PM_CONVICT))))
#define can_see_hurtnss_of_mon(mon) \
((u.sealsActive&SEAL_MOTHER && !is_undead((mon)->data)) || \
(Role_if(PM_HEALER) && (!nonliving((mon)->data) || has_blood_mon(mon))) || \
(ublindf && ublindf->otyp == ANDROID_VISOR))
#define standardUnwardable(mtmp) (mtmp->isshk || mtmp->iswiz || is_rider(mtmp->data))
#define catWardInactive ( (mvitals[PM_KITTEN].mvflags & G_GENOD || mvitals[PM_KITTEN].died >= 120) && \
(mvitals[PM_HOUSECAT].mvflags & G_GENOD || mvitals[PM_HOUSECAT].died >= 120) && \
(mvitals[PM_LARGE_CAT].mvflags & G_GENOD || mvitals[PM_LARGE_CAT].died >= 120) \
)
#define wingWarded(data) (data->mlet == S_COCKATRICE \
|| data->mlet == S_RODENT \
|| data->mlet == S_NAGA \
|| data->mlet == S_SNAKE \
|| data->mlet == S_LIZARD \
|| data->mtyp == PM_TOVE \
|| data->mtyp == PM_KRAKEN \
)
#define catWarded(data) (is_bird(data) \
|| is_bat(data) \
|| data->mlet == S_RODENT \
|| data->mlet == S_SNAKE \
|| data->mlet == S_SPIDER \
|| data->mlet == S_EEL \
|| data->mlet == S_LIZARD \
|| data->mtyp == PM_TOVE \
)
#define touWarded(data) (data->mlet == S_DOG || data->mlet == S_FELINE)
#define dreWarded(data) (is_bird(data)\
|| is_bat(data) \
|| data->mlet == S_QUADRUPED \
|| data->mlet == S_UNICORN \
)
#define veiWarded(data) (data->mlet == S_EEL)
#define thjWarded(data) (data->mlet == S_LEPRECHAUN \
|| data->mlet == S_NYMPH \
|| is_thief(data) \
)
#define queenWarded(data) (data->mlet == S_ANT \
|| data->mlet == S_XAN \
|| data->mlet == S_SPIDER \
|| data->mlet == S_RUSTMONST \
)
#define eeyeWarded(data) ( \
jsjk;sfdlksakslakldskkflskals \
)
#define hamWarded(data) (is_auton(data) \
|| data->mtyp == PM_FLOATING_EYE \
|| data->mtyp == PM_BEHOLDER \
|| data->mtyp == PM_APHANACTONAN_ASSESSOR \
|| data->mtyp == PM_EYE_OF_DOOM \
|| data->mtyp == PM_MANY_EYED_SEEKER \
|| data->mtyp == PM_GROTESQUE_PEEPER \
|| data->mtyp == PM_JRT_NETJER \
|| data->mtyp == PM_YOCHLOL \
|| data->mtyp == PM_TRUTH_SEER \
|| data->mtyp == PM_DREAM_EATER \
|| data->mtyp == PM_PARASITIZED_DOLL \
)
#define hexWarded(data) ((is_minion(data) \
|| data->mtyp == PM_HELL_HOUND \
|| data->mtyp == PM_HELL_HOUND_PUP \
|| data->mtyp == PM_EYE_OF_DOOM \
|| data->mtyp == PM_SON_OF_TYPHON \
|| is_golem(data) \
|| is_angel(data) \
|| is_keter(data) \
|| data->mlet == S_QUANTMECH \
|| data->mlet == S_IMP \
|| is_demon(data) \
) && !( \
(data->mtyp == PM_CHOKHMAH_SEPHIRAH) || \
(data->mtyp == PM_ELDER_PRIEST) || \
(data->mtyp == PM_GREAT_CTHULHU) \
))
#define pentWarded(data) ((is_demon(data) \
|| data->mtyp == PM_HELL_HOUND \
|| data->mtyp == PM_HELL_HOUND_PUP \
|| data->mtyp == PM_GARGOYLE \
|| data->mtyp == PM_WINGED_GARGOYLE \
|| data->mtyp == PM_DJINNI \
|| data->mtyp == PM_SANDESTIN \
|| data->mtyp == PM_SALAMANDER \
|| data->mlet == S_ELEMENTAL \
|| data->mlet == S_IMP \
) && !( \
(data->mtyp == PM_CHOKHMAH_SEPHIRAH) || \
(data->mtyp == PM_ELDER_PRIEST) || \
(data->mtyp == PM_GREAT_CTHULHU) \
))
#define circleWarded(data) ((data->mtyp == PM_CERBERUS || is_undead(data)) \
&& !(mtmp->mtyp == PM_MAANZECORIAN))
#define gorgUnwardable(mtmp) (standardUnwardable(mtmp) || is_lminion(mtmp) || mtmp->mtyp == PM_ANGEL)
#define gorgWarded(data) (!mindless(data) \
&& !is_great_old_one(data) \
&& (data->mtyp != PM_CHOKHMAH_SEPHIRAH) \
&& (data->mtyp != PM_ELDER_PRIEST) \
&& (data->mtyp != PM_LUGRIBOSSK) \
&& (data->mtyp != PM_MAANZECORIAN) \
)
#define heptUnwardable(mtmp) (standardUnwardable(mtmp) || mtmp->isgd || is_lminion(mtmp) || mtmp->mtyp == PM_ANGEL || mtmp->mpeaceful)
#define heptWarded(data) (( !(is_human(data) || is_elf(data) \
|| is_drow(data) || is_dwarf(data) \
|| is_gnome(data) || is_orc(data)) \
|| is_undead(data) || is_were(data) \
) && !( \
data->mtyp == PM_CHOKHMAH_SEPHIRAH \
))
#define yellowUnwardable(mtmp) (standardUnwardable(mtmp) || mtmp->mpeaceful || (mtmp->mtyp == PM_STRANGER) || (mtmp->mtyp == PM_SUZERAIN) || (mtmp->mtyp == PM_ELDER_PRIEST) || (has_template(mtmp, YELLOW_TEMPLATE)))
#define yellowWarded(data) (!heptWarded(data) && !is_undead(data) && !is_were(data) && !is_primordial(data) )
#endif /* MONDATA_H */