diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/beam.cc | 3 | ||||
-rw-r--r-- | crawl-ref/source/debug.cc | 8 | ||||
-rw-r--r-- | crawl-ref/source/delay.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/dungeon.cc | 5 | ||||
-rw-r--r-- | crawl-ref/source/effects.cc | 4 | ||||
-rw-r--r-- | crawl-ref/source/fight.cc | 2 | ||||
-rw-r--r-- | crawl-ref/source/mon-data.h | 88 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.cc | 101 | ||||
-rw-r--r-- | crawl-ref/source/mon-util.h | 30 | ||||
-rw-r--r-- | crawl-ref/source/monplace.cc | 47 | ||||
-rw-r--r-- | crawl-ref/source/monstuff.cc | 14 |
11 files changed, 178 insertions, 128 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 0d577edc56..0e1f9e7ef0 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -1507,8 +1507,7 @@ static bool _affect_mon_in_wall(bolt &pbolt, item_def *item, && (grd(where) == DNGN_METAL_WALL || pbolt.flavour != BEAM_ELECTRICITY))) { - monsters *mon = &menv[mid]; - if (!mons_is_wall_shielded(mon->type)) + if (!mons_wall_shielded(&menv[mid])) return (true); } diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index e38d6233d9..09e2a5e45e 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -1839,14 +1839,16 @@ void debug_stethoscope(int mon) mons.number, mons.flags ); // Print habitat and behaviour information. - const habitat_type hab = mons_habitat( &mons ); + const habitat_type hab = mons_habitat(&mons); mprf(MSGCH_DIAGNOSTICS, "hab=%s beh=%s(%d) foe=%s(%d) mem=%d target=(%d,%d) god=%s", - ((hab == HT_WATER) ? "water" : + ((hab == HT_LAND) ? "land" : + (hab == HT_LAND_AMPHIBIOUS) ? "land (amphibious)" : + (hab == HT_WATER_AMPHIBIOUS) ? "water (amphibious)" : + (hab == HT_WATER) ? "water" : (hab == HT_LAVA) ? "lava" : (hab == HT_ROCK) ? "rock" : - (hab == HT_LAND) ? "floor" : "unknown"), (mons_is_sleeping(&mons) ? "sleep" : mons_is_wandering(&mons) ? "wander" : diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index eea7f5820a..7f4d7d0612 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -1681,9 +1681,9 @@ inline static void _monster_warning(activity_interrupt_type ai, else if (at.context.find("bursts forth") != std::string::npos) { text += " bursts forth from the "; - if (mons_habitat(mon) == HT_LAVA) + if (mons_primary_habitat(mon) == HT_LAVA) text += "lava"; - else if (mons_habitat(mon) == HT_WATER) + else if (mons_primary_habitat(mon) == HT_WATER) text += "water"; else text += "realm of bugdom"; diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index fc35399d36..cc9f37b7bd 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -4654,10 +4654,11 @@ bool dgn_place_monster(mons_spec &mspec, const int montype = mons_class_is_zombified(mid) ? mspec.monbase : mid; - const habitat_type habitat = mons_habitat_by_type(montype); + const habitat_type habitat = mons_class_primary_habitat(montype); if (habitat != HT_LAND - && (habitat != HT_WATER || !mons_class_amphibious(montype))) + && (habitat != HT_WATER || !mons_class_amphibious(montype)) + && (habitat != HT_ROCK || !mons_class_wall_shielded(montype))) { grd(where) = habitat2grid(habitat); } diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 07538c1c81..1519bcdb09 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -2644,9 +2644,9 @@ static void _catchup_monster_moves(monsters *mon, int turns) return; // Don't move non-land or stationary monsters around. - if (mons_habitat(mon) != HT_LAND + if (mons_primary_habitat(mon) != HT_LAND || mons_is_zombified(mon) - && mons_habitat_by_type(mon->base_monster) != HT_LAND + && mons_class_primary_habitat(mon->base_monster) != HT_LAND || mons_is_stationary(mon)) { return; diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 6ad428c609..6518045d02 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -554,7 +554,7 @@ bool melee_attack::attack() // Defending monster protects itself from attacks using the // wall it's in. if (defender->atype() == ACT_MONSTER && grid_is_solid(def->pos()) - && mons_is_wall_shielded(def->type)) + && mons_wall_shielded(def)) { std::string feat_name = raw_feature_description(grd(def->pos())); diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index d4bd6d269f..175165f7bc 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -802,24 +802,24 @@ static monsterentry mondata[] = { { MONS_GIANT_SLUG, 'j', GREEN, "giant slug", - M_NO_SKELETON | M_AMPHIBIOUS, + M_NO_SKELETON, MR_NO_FLAGS, 700, 10, MONS_GIANT_SLUG, MONS_GIANT_SLUG, MH_NATURAL, -3, { {AT_BITE, AF_PLAIN, 23}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 10, 5, 3, 0 }, 0, 2, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - HT_LAND, 6, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE + HT_AMPHIBIOUS_LAND, 6, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE }, { MONS_GIANT_SNAIL, 'j', LIGHTGREEN, "giant snail", - M_NO_SKELETON | M_AMPHIBIOUS, + M_NO_SKELETON, MR_NO_FLAGS, 900, 10, MONS_GIANT_SLUG, MONS_GIANT_SNAIL, MH_NATURAL, -3, { {AT_BITE, AF_PLAIN, 18}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 14, 5, 3, 0 }, 7, 2, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - HT_LAND, 4, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE + HT_AMPHIBIOUS_LAND, 4, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LARGE }, // killer bees 'k' @@ -848,13 +848,13 @@ static monsterentry mondata[] = { // lizards 'l' { MONS_GIANT_NEWT, 'l', GREEN, "giant newt", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_NO_FLAGS, 150, 10, MONS_GIANT_LIZARD, MONS_GIANT_NEWT, MH_NATURAL, -3, { {AT_BITE, AF_PLAIN, 3}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 1, 1, 2, 0 }, 0, 15, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_TINY + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_TINY }, { @@ -904,13 +904,13 @@ static monsterentry mondata[] = { { MONS_KOMODO_DRAGON, 'l', LIGHTRED, "komodo dragon", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_NO_FLAGS, 800, 10, MONS_GIANT_LIZARD, MONS_KOMODO_DRAGON, MH_NATURAL, -3, { {AT_BITE, AF_DISEASE, 30}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 3, 5, 0 }, 7, 8, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_HISS, I_INSECT, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM }, // drakes (also 'l', but dragon type) @@ -967,24 +967,24 @@ static monsterentry mondata[] = { // merfolk ('m') { MONS_MERFOLK, 'm', LIGHTBLUE, "merfolk", - M_WARM_BLOOD | M_AMPHIBIOUS | M_SPEAKS, + M_WARM_BLOOD | M_SPEAKS, MR_RES_POISON | MR_RES_COLD, 500, 10, MONS_MERFOLK, MONS_MERFOLK, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 14}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 2, 4, 0 }, 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - HT_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM + HT_AMPHIBIOUS_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM }, { MONS_MERMAID, 'm', LIGHTCYAN, "mermaid", - M_SPELLCASTER | M_WARM_BLOOD | M_AMPHIBIOUS | M_SPEAKS, + M_SPELLCASTER | M_WARM_BLOOD | M_SPEAKS, MR_RES_POISON | MR_RES_COLD, 500, 10, MONS_MERMAID, MONS_MERMAID, MH_NATURAL, -5, { {AT_HIT, AF_PLAIN, 10}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 2, 4, 0 }, 4, 12, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - HT_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM + HT_AMPHIBIOUS_WATER, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM }, // rotting monsters ('n') @@ -1311,24 +1311,24 @@ static monsterentry mondata[] = { // ugly things ('u') { MONS_UGLY_THING, 'u', BROWN, "ugly thing", - M_WARM_BLOOD | M_AMPHIBIOUS, + M_WARM_BLOOD, mrd(MR_RES_COLD, 2), 600, 10, MONS_UGLY_THING, MONS_UGLY_THING, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 12}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 3, 5, 0 }, 3, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_ANIMAL, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_MEDIUM + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_MEDIUM }, { MONS_VERY_UGLY_THING, 'u', RED, "very ugly thing", - M_WARM_BLOOD | M_AMPHIBIOUS, + M_WARM_BLOOD, mrd(MR_RES_COLD, 2), 750, 10, MONS_UGLY_THING, MONS_VERY_UGLY_THING, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 17}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 12, 3, 5, 0 }, 4, 8, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_BIG, S_ROAR, I_ANIMAL, - HT_LAND, 8, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_LARGE + HT_AMPHIBIOUS_LAND, 8, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_LARGE }, // vortices ('v') @@ -1390,13 +1390,13 @@ static monsterentry mondata[] = { { MONS_WATER_ELEMENTAL, '{', LIGHTBLUE, "water elemental", - M_FLIES | M_AMPHIBIOUS, + M_FLIES, MR_RES_POISON | MR_VUL_FIRE | MR_RES_ELEC, 0, 10, MONS_EARTH_ELEMENTAL, MONS_WATER_ELEMENTAL, MH_NONLIVING, MAG_IMMUNE, { {AT_HIT, AF_PLAIN, 25}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 6, 5, 3, 0 }, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - HT_WATER, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG + HT_AMPHIBIOUS_WATER, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG }, // worms and larvae ('w') @@ -1793,13 +1793,13 @@ static monsterentry mondata[] = { { MONS_HYDRA, 'D', LIGHTGREEN, "hydra", - M_AMPHIBIOUS | M_WARM_BLOOD, // because it likes the swamp -- bwr + M_WARM_BLOOD, MR_RES_POISON, 1800, 11, MONS_HYDRA, MONS_HYDRA, MH_NATURAL, -3, { {AT_BITE, AF_PLAIN, 18}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 13, 3, 5, 0 }, 0, 5, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_ROAR, I_INSECT, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG }, { @@ -1946,46 +1946,46 @@ static monsterentry mondata[] = { // frogs ('F') { MONS_GIANT_FROG, 'F', GREEN, "giant frog", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_NO_FLAGS, 500, 10, MONS_GIANT_FROG, MONS_GIANT_FROG, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 9}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 4, 3, 5, 0 }, 0, 12, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, - HT_LAND, 15, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL + HT_AMPHIBIOUS_LAND, 15, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL }, { MONS_GIANT_BROWN_FROG, 'F', BROWN, "giant brown frog", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_NO_FLAGS, 890, 10, MONS_GIANT_FROG, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 14}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 8, 3, 5, 0 }, 2, 11, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_CROAK, I_ANIMAL, - HT_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM + HT_AMPHIBIOUS_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM }, { MONS_SPINY_FROG, 'F', YELLOW, "spiny frog", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_RES_POISON, 1000, 10, MONS_GIANT_FROG, MONS_SPINY_FROG, MH_NATURAL, -3, { {AT_STING, AF_POISON_MEDIUM, 26}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 7, 3, 5, 0 }, 6, 9, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_CROAK, I_ANIMAL, - HT_LAND, 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL + HT_AMPHIBIOUS_LAND, 12, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL }, { MONS_BLINK_FROG, 'F', LIGHTGREEN, "blink frog", - M_COLD_BLOOD | M_AMPHIBIOUS | M_SPECIAL_ABILITY, + M_COLD_BLOOD | M_SPECIAL_ABILITY, MR_NO_FLAGS, 800, 12, MONS_GIANT_FROG, MONS_BLINK_FROG, MH_NATURAL, -5, { {AT_HIT, AF_BLINK, 20}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 6, 3, 5, 0 }, 3, 12, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, - HT_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE + HT_AMPHIBIOUS_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE }, // eyes and spores ('G') @@ -2143,24 +2143,24 @@ static monsterentry mondata[] = { { MONS_JELLY, 'J', LIGHTRED, "jelly", - M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS | M_ACID_SPLASH, + M_SEE_INVIS | M_SPLITS | M_ACID_SPLASH, MR_RES_POISON | MR_RES_ASPHYX | mrd(MR_RES_ACID, 3), 0, 13, MONS_JELLY, MONS_JELLY, MH_NATURAL, -3, { {AT_HIT, AF_ACID, 8}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 3, 5, 5, 0 }, 0, 2, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - HT_LAND, 9, DEFAULT_ENERGY, MONUSE_EATS_ITEMS, SIZE_MEDIUM + HT_AMPHIBIOUS_LAND, 9, DEFAULT_ENERGY, MONUSE_EATS_ITEMS, SIZE_MEDIUM }, { MONS_SLIME_CREATURE, 'J', GREEN, "slime creature", - M_AMPHIBIOUS, + M_NO_FLAGS, MR_RES_POISON, 0, 5, MONS_SLIME_CREATURE, MONS_SLIME_CREATURE, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 22}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 11, 3, 5, 0 }, 1, 4, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL }, { @@ -2176,13 +2176,13 @@ static monsterentry mondata[] = { { MONS_GIANT_AMOEBA, 'J', BLUE, "giant amoeba", - M_NO_SKELETON | M_SENSE_INVIS | M_AMPHIBIOUS, + M_NO_SKELETON | M_SENSE_INVIS, MR_RES_POISON, 1000, 10, MONS_GIANT_AMOEBA, MONS_GIANT_AMOEBA, MH_NATURAL, -3, { {AT_HIT, AF_PLAIN, 25}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 12, 3, 5, 0 }, 0, 4, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_LITTLE }, { @@ -2523,24 +2523,24 @@ static monsterentry mondata[] = { { MONS_SNAKE, 'S', LIGHTGREEN, "snake", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_NO_FLAGS, 200, 10, MONS_SNAKE, MONS_SNAKE, MH_NATURAL, -3, { {AT_BITE, AF_POISON, 5}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 2, 3, 5, 0 }, 1, 15, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, - HT_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL + HT_AMPHIBIOUS_LAND, 13, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_SMALL }, { MONS_BROWN_SNAKE, 'S', BROWN, "brown snake", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD, MR_RES_POISON, 300, 10, MONS_SNAKE, MONS_BROWN_SNAKE, MH_NATURAL, -3, { {AT_BITE, AF_POISON_MEDIUM, 10}, AT_NO_ATK, AT_NO_ATK, AT_NO_ATK }, { 4, 3, 5, 0 }, 2, 15, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_INSECT, - HT_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM + HT_AMPHIBIOUS_LAND, 14, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_MEDIUM }, { @@ -2652,14 +2652,14 @@ static monsterentry mondata[] = { { MONS_POLAR_BEAR, 'U', WHITE, "polar bear", - M_WARM_BLOOD | M_AMPHIBIOUS, + M_WARM_BLOOD, MR_RES_COLD, 2500, 10, MONS_BEAR, MONS_POLAR_BEAR, MH_NATURAL, -3, { {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 5}, {AT_CLAW, AF_PLAIN, 5}, AT_NO_ATK }, { 7, 5, 3, 0 }, 7, 8, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_NOTHING, SIZE_BIG }, { @@ -2793,13 +2793,13 @@ static monsterentry mondata[] = { { MONS_TENTACLED_MONSTROSITY, 'X', GREEN, "tentacled monstrosity", - M_SEE_INVIS | M_AMPHIBIOUS | M_EVIL, + M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_TENTACLED_MONSTROSITY, MONS_TENTACLED_MONSTROSITY, MH_DEMONIC, -5, { {AT_HIT, AF_PLAIN, 22}, {AT_HIT, AF_PLAIN, 17}, {AT_HIT, AF_PLAIN, 13} }, { 25, 3, 5, 0 }, 5, 5, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - HT_LAND, 9, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_GIANT, + HT_AMPHIBIOUS_LAND, 9, DEFAULT_ENERGY, MONUSE_OPEN_DOORS, SIZE_GIANT }, { @@ -3887,13 +3887,13 @@ static monsterentry mondata[] = { // Antaeus is now demonic so that he'll resist torment. -- bwr { MONS_ANTAEUS, 'C', LIGHTCYAN, "Antaeus", - M_FIGHTER | M_SPELLCASTER | M_EVIL | M_SPEAKS | M_UNIQUE | M_AMPHIBIOUS, + M_FIGHTER | M_SPELLCASTER | M_EVIL | M_SPEAKS | M_UNIQUE, MR_RES_ELEC | MR_VUL_FIRE | mrd(MR_RES_COLD, 2), 0, 15, MONS_HILL_GIANT, MONS_ANTAEUS, MH_DEMONIC, -9, { {AT_HIT, AF_COLD, 75}, {AT_HIT, AF_COLD, 30}, AT_NO_ATK, AT_NO_ATK }, { 22, 0, 0, 700 }, 28, 4, MST_ANTAEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - HT_LAND, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT + HT_AMPHIBIOUS_LAND, 10, DEFAULT_ENERGY, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT }, { diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index e1394d70ca..16dfa071c6 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -107,6 +107,7 @@ dungeon_feature_type habitat2grid(habitat_type ht) { switch (ht) { + case HT_AMPHIBIOUS_WATER: case HT_WATER: return (DNGN_DEEP_WATER); case HT_LAVA: @@ -114,6 +115,7 @@ dungeon_feature_type habitat2grid(habitat_type ht) case HT_ROCK: return (DNGN_ROCK_WALL); case HT_LAND: + case HT_AMPHIBIOUS_LAND: default: return (DNGN_FLOOR); } @@ -387,11 +389,6 @@ bool mons_class_is_slowable(int mc) return (smc->resist_magic < MAG_IMMUNE); } -bool mons_is_wall_shielded(int mc) -{ - return (mons_habitat_by_type(mc) == HT_ROCK); -} - bool mons_class_is_stationary(int mc) { return mons_class_flag(mc, M_STATIONARY); @@ -1274,10 +1271,10 @@ flight_type mons_flies(const monsters *mon) return (mon->ghost->fly); } - const int type = mons_is_zombified(mon) ? mons_zombie_base(mon) - : mon->type; + const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type; - const flight_type ret = mons_class_flies( type ); + const flight_type ret = mons_class_flies(montype); return (ret ? ret : (_scan_mon_inv_randarts(mon, RAP_LEVITATE) > 0) ? FL_LEVITATE : FL_NONE); @@ -1285,15 +1282,27 @@ flight_type mons_flies(const monsters *mon) bool mons_class_amphibious(int mc) { - return mons_class_flag(mc, M_AMPHIBIOUS); + habitat_type ht = mons_class_habitat(mc); + return (ht == HT_AMPHIBIOUS_LAND || ht == HT_AMPHIBIOUS_WATER); } bool mons_amphibious(const monsters *mon) { - const int type = mons_is_zombified(mon) ? mons_zombie_base(mon) - : mon->type; + const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type; + return (mons_class_amphibious(montype)); +} + +bool mons_class_wall_shielded(int mc) +{ + return (mons_class_habitat(mc) == HT_ROCK); +} - return (mons_class_amphibious(type)); +bool mons_wall_shielded(const monsters *mon) +{ + const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type; + return (mons_class_wall_shielded(montype)); } // This nice routine we keep in exactly the way it was. @@ -2007,22 +2016,53 @@ mon_intel_type mons_intel(int mc) return (smc->intel); } -habitat_type mons_habitat_by_type(int mc) +habitat_type mons_class_habitat(int mc) { const monsterentry *me = get_monster_data(mc); return (me ? me->habitat : HT_LAND); } -habitat_type mons_habitat(const monsters *m) +habitat_type mons_habitat(const monsters *mon) +{ + return mons_class_habitat(mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type); +} + +habitat_type mons_class_primary_habitat(int mc) { - return mons_habitat_by_type( mons_is_zombified(m) ? mons_zombie_base(m) - : m->type ); + habitat_type ht = mons_class_habitat(mc); + if (ht == HT_AMPHIBIOUS_LAND) + ht = HT_LAND; + else if (ht == HT_AMPHIBIOUS_WATER) + ht = HT_WATER; + return (ht); } -bool intelligent_ally(const monsters *monster) +habitat_type mons_primary_habitat(const monsters *mon) { - return (monster->attitude == ATT_FRIENDLY - && mons_intel(monster->type) >= I_NORMAL); + return mons_class_primary_habitat(mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type); +} + +habitat_type mons_class_secondary_habitat(int mc) +{ + habitat_type ht = mons_class_habitat(mc); + if (ht == HT_AMPHIBIOUS_LAND) + ht = HT_WATER; + else if (ht == HT_AMPHIBIOUS_WATER || ht == HT_ROCK) + ht = HT_LAND; + return (ht); +} + +habitat_type mons_secondary_habitat(const monsters *mon) +{ + return mons_class_secondary_habitat(mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type); +} + +bool intelligent_ally(const monsters *mon) +{ + return (mon->attitude == ATT_FRIENDLY && mons_intel(mon->type) >= I_NORMAL); } int mons_power(int mc) @@ -2984,7 +3024,7 @@ void monsters::init_with(const monsters &mon) bool monsters::swimming() const { const dungeon_feature_type grid = grd(pos()); - return (grid_is_watery(grid) && mons_habitat(this) == HT_WATER); + return (grid_is_watery(grid) && mons_primary_habitat(this) == HT_WATER); } bool monsters::wants_submerge() const @@ -3030,15 +3070,15 @@ bool monsters::floundering() const return (grid_is_water(grid) // Can't use monster_habitable_grid because that'll return true // for non-water monsters in shallow water. - && mons_habitat(this) != HT_WATER + && mons_primary_habitat(this) != HT_WATER && !mons_amphibious(this) && !mons_flies(this) && !extra_balanced()); } -bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid) +bool mons_class_can_pass(int mc, const dungeon_feature_type grid) { - if (mons_is_wall_shielded(mclass)) + if (mons_class_wall_shielded(mc)) { // Permanent walls can't be passed through. return (!grid_is_solid(grid) @@ -3048,9 +3088,16 @@ bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid) return !grid_is_solid(grid); } +bool mons_can_pass(const monsters *mon, dungeon_feature_type grid) +{ + const int montype = mons_is_zombified(mon) ? mons_zombie_base(mon) + : mon->type; + return mons_class_can_pass(montype, grid); +} + bool monsters::can_pass_through_feat(dungeon_feature_type grid) const { - return mons_class_can_pass(type, grid); + return mons_can_pass(this, grid); } bool monsters::can_drown() const @@ -6679,9 +6726,9 @@ int monsters::action_energy(energy_use_type et) const // [ds] Amphibious monsters get a significant speed boost // when swimming, as discussed with dpeg. We do not // distinguish between amphibians that favour land - // (HT_LAND, such as hydras) and those that favour water - // (HT_WATER, such as merfolk), but that's something we - // can think about. + // (HT_AMPHIBIOUS_LAND, such as hydras) and those that + // favour water (HT_AMPHIBIOUS_WATER, such as merfolk), but + // that's something we can think about. if (mons_class_amphibious(type)) return div_rand_round(mu.swim * 7, 10); else diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 07c83658e5..e4f6a510b7 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -99,7 +99,7 @@ enum mons_class_flags M_CONFUSED = (1<<10), // monster is perma-confused, M_BATTY = (1<<11), // monster is batty M_SPLITS = (1<<12), // monster can split - M_AMPHIBIOUS = (1<<13), // monster can swim in water + M_STATIONARY = (1<<14), // monster is stationary M_BLOOD_SCENT = (1<<15), // monster can smell blood M_COLD_BLOOD = (1<<16), // susceptible to cold, @@ -150,10 +150,12 @@ enum mon_intel_type // Must be in increasing intelligence order enum habitat_type { // Flying monsters will appear in all categories except rock walls - HT_LAND = 0, // Land critters - HT_WATER, // Water critters - HT_LAVA, // Lava critters - HT_ROCK, // Rock critters + HT_LAND = 0, // Land critters + HT_AMPHIBIOUS_LAND, // Amphibious land-preferring critters + HT_AMPHIBIOUS_WATER, // Amphibious water-preferring critters + HT_WATER, // Water critters + HT_LAVA, // Lava critters + HT_ROCK, // Rock critters NUM_HABITATS }; @@ -444,6 +446,8 @@ flight_type mons_flies(const monsters *mon); bool mons_class_amphibious(int mc); bool mons_amphibious(const monsters *mon); +bool mons_class_wall_shielded(int mc); +bool mons_wall_shielded(const monsters *mon); // last updated XXmay2000 {dlb} /* *********************************************************************** @@ -543,10 +547,14 @@ bool mons_is_shapeshifter(const monsters *m); * *********************************************************************** */ mon_intel_type mons_intel(int mc); -// Use mons_habitat(const monster *) wherever possible since the other -// variant does not handle zombies correctly. -habitat_type mons_habitat(const monsters *m); -habitat_type mons_habitat_by_type(int mc); +// Use mons_habitat() and mons_primary_habitat() wherever possible, +// since the class variants do not handle zombies correctly. +habitat_type mons_class_habitat(int mc); +habitat_type mons_habitat(const monsters *mon); +habitat_type mons_class_primary_habitat(int mc); +habitat_type mons_primary_habitat(const monsters *mon); +habitat_type mons_class_secondary_habitat(int mc); +habitat_type mons_secondary_habitat(const monsters *mon); bool intelligent_ally(const monsters *mon); @@ -730,7 +738,6 @@ bool mons_class_is_confusable(int mc); bool mons_class_is_slowable(int mc); bool mons_class_is_stationary(int mc); bool mons_is_stationary(const monsters *mon); -bool mons_is_wall_shielded(int mc); bool mons_is_insubstantial(int mc); bool mons_has_blood(int mc); bool mons_is_submerged(const monsters *m); @@ -793,7 +800,8 @@ std::string get_mon_shape_str(const monsters *mon); std::string get_mon_shape_str(const int type); std::string get_mon_shape_str(const mon_body_shape shape); -bool mons_class_can_pass(const int mclass, const dungeon_feature_type grid); +bool mons_class_can_pass(int mc, const dungeon_feature_type grid); +bool mons_can_pass(const monsters *mon, dungeon_feature_type grid); mon_inv_type equip_slot_to_mslot(equipment_type eq); diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 5070f80348..f61fab8780 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -116,10 +116,16 @@ bool monster_habitable_grid(int monster_class, int flies, bool paralysed) { const dungeon_feature_type preferred_habitat = - habitat2grid( mons_habitat_by_type(monster_class) ); + habitat2grid(mons_class_primary_habitat(monster_class)); + const dungeon_feature_type nonpreferred_habitat = + habitat2grid(mons_class_secondary_habitat(monster_class)); - if (grid_compatible(preferred_habitat, actual_grid)) + if (grid_compatible(preferred_habitat, actual_grid) + || (nonpreferred_habitat != preferred_habitat + && grid_compatible(nonpreferred_habitat, actual_grid))) + { return (true); + } // [dshaligram] Flying creatures are all DNGN_FLOOR, so we // only have to check for the additional valid grids of deep @@ -130,24 +136,6 @@ bool monster_habitable_grid(int monster_class, return (true); } - // Amphibious critters are happy in water or on land. - if (mons_class_amphibious(monster_class) - && (preferred_habitat == DNGN_FLOOR - && grid_compatible(DNGN_DEEP_WATER, actual_grid) - || preferred_habitat == DNGN_DEEP_WATER - && grid_compatible(DNGN_FLOOR, actual_grid))) - { - return (true); - } - - // Rock wall critters are native to walls but are happy on - // the floor as well. - if (preferred_habitat == DNGN_ROCK_WALL - && grid_compatible(DNGN_FLOOR, actual_grid)) - { - return (true); - } - return (false); } @@ -158,11 +146,11 @@ bool monster_can_submerge(const monsters *mons, dungeon_feature_type grid) return (!find_trap(mons->pos())); // Zombies of watery critters can not submerge. - switch (mons_habitat(mons)) + switch (mons_primary_habitat(mons)) { case HT_WATER: // Monsters can submerge in shallow water - this is intentional. - return grid_is_watery(grid); + return (grid_is_watery(grid)); case HT_LAVA: return (grid == DNGN_LAVA); @@ -552,8 +540,10 @@ static bool _valid_monster_location(const mgen_data &mg, { const int montype = (mons_class_is_zombified(mg.cls) ? mg.base_type : mg.cls); - dungeon_feature_type grid_wanted = - habitat2grid(mons_habitat_by_type(montype)); + const dungeon_feature_type grid_preferred = + habitat2grid(mons_class_primary_habitat(montype)); + const dungeon_feature_type grid_nonpreferred = + habitat2grid(mons_class_secondary_habitat(montype)); if (!in_bounds(mg_pos)) return (false); @@ -563,8 +553,12 @@ static bool _valid_monster_location(const mgen_data &mg, return (false); // Is the monster happy where we want to put it? - if (!grid_compatible(grid_wanted, grd(mg_pos), !force_location)) + if (!grid_compatible(grid_preferred, grd(mg_pos), !force_location) + && (grid_nonpreferred == grid_preferred + || !grid_compatible(grid_nonpreferred, grd(mg_pos), !force_location))) + { return (false); + } if (mg.behaviour != BEH_FRIENDLY && is_sanctuary(mg_pos)) return (false); @@ -1954,8 +1948,7 @@ static dungeon_feature_type _monster_habitat_feature(int mtype) { if (mtype == RANDOM_MONSTER) return DNGN_FLOOR; - - return habitat2grid( mons_habitat_by_type(mtype) ); + return habitat2grid(mons_class_primary_habitat(mtype)); } class newmons_square_find : public travel_pathfind diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 53c2c9dd5c..0380716a15 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -2204,7 +2204,7 @@ static bool _choose_random_patrol_target_grid(monsters *mon) return (false); const bool patrol_seen = mon->mon_see_grid(mon->patrol_point, - habitat2grid(mons_habitat(mon))); + habitat2grid(mons_primary_habitat(mon))); if (intel == I_PLANT && !patrol_seen) { @@ -2351,7 +2351,7 @@ static void _mark_neighbours_target_unreachable(monsters *mon) const bool flies = mons_flies(mon); const bool amphibious = mons_amphibious(mon); - const habitat_type habit = mons_habitat(mon); + const habitat_type habit = mons_primary_habitat(mon); for (radius_iterator ri(mon->pos(), 2, true, false); ri; ++ri) { @@ -2374,7 +2374,7 @@ static void _mark_neighbours_target_unreachable(monsters *mon) continue; // Monsters of differing habitats might prefer different routes. - if (mons_habitat(m) != habit) + if (mons_primary_habitat(m) != habit) continue; // A flying monster has an advantage over a non-flying one. @@ -2824,7 +2824,7 @@ static void _handle_behaviour(monsters *mon) || !mons_has_ranged_spell(mon) && !mons_has_ranged_attack(mon))) { - const habitat_type habit = mons_habitat(mon); + const habitat_type habit = mons_primary_habitat(mon); if (you.lava_in_sight > 0 && habit != HT_LAVA || you.water_in_sight > 0 && habit != HT_WATER && can_move != DNGN_DEEP_WATER) @@ -5442,7 +5442,7 @@ static void _monster_regenerate(monsters *monster) } // Non-land creatures out of their element cannot regenerate. - if (mons_habitat(monster) != HT_LAND + if (mons_primary_habitat(monster) != HT_LAND && !monster_habitable_grid(monster, grd(monster->pos()))) { return; @@ -6649,7 +6649,7 @@ static bool _mon_can_move_to_pos(const monsters *monster, } const dungeon_feature_type target_grid = grd(targ); - const habitat_type habitat = mons_habitat(monster); + const habitat_type habitat = mons_primary_habitat(monster); // Effectively slows down monster movement across water. // Fire elementals can't cross at all. @@ -6846,7 +6846,7 @@ static bool _monster_move(monsters *monster) FixedArray < bool, 3, 3 > good_move; int count_x, count_y, count; - const habitat_type habitat = mons_habitat(monster); + const habitat_type habitat = mons_primary_habitat(monster); bool deep_water_available = false; if (monster->type == MONS_TRAPDOOR_SPIDER) |