diff options
author | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-19 14:24:03 +0000 |
---|---|---|
committer | dshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573> | 2006-08-19 14:24:03 +0000 |
commit | f49a7e537b416bd6fe65959607a5304dbb401849 (patch) | |
tree | d37cbf0b72171dfea565472b4b3ad81a1d5878a5 | |
parent | e36f2c8cdfe62621f6490e40d3a3e18dd93d9de7 (diff) | |
download | crawl-ref-f49a7e537b416bd6fe65959607a5304dbb401849.tar.gz crawl-ref-f49a7e537b416bd6fe65959607a5304dbb401849.zip |
r41@ODIN: dshaligram | 2006-08-19 18:51:17 +051800
The march towards 4.1-ness continues:
- Monsters can displace other (related) monsters. For instance, orc warriors
can push past vanilla orcs.
- Missile launchers are eligible for acquirement.
- Boosted damage for fire/frost launchers.
- Launchers now support the vorpalise brand (aka "of velocity").
- Throwing skill is now called Ranged Combat.
- Added monster draconians, death drakes. Moved drakes from 'd' to 'l'.
- Shining One: Cleansing flame replaces Thunderbolt.
- Added lajatang, lochaber axe, and longbow.
- Set save major version back to 0, so that stone_soup will refuse to load
Crawl 4.0 savegames, instead of dying horribly.
- Centaur and naga bardings are no longer classified as boots.
- Monsters can cast poison arrow.
- Nagas now do more respectable melee damage.
- Added jelly pits.
- Added itemprop.cc as the central file specifying item properties. Integration
is far from complete though. wpn-misc.cc, food.cc, etc. still have defined
many item properties in code.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/branches/stone_soup@21 c06c8d41-db1a-0410-9941-cceddc491573
71 files changed, 6284 insertions, 3404 deletions
diff --git a/crawl-ref/source/Kills.cc b/crawl-ref/source/Kills.cc index 4a1eaa0ebf..06f465bb70 100644 --- a/crawl-ref/source/Kills.cc +++ b/crawl-ref/source/Kills.cc @@ -52,7 +52,7 @@ const char *kill_category_names[] = "others", }; -const char *KillMaster::category_name(KillCategory kc) const +const char *KillMaster::category_name(kill_category kc) const { if (kc >= KC_YOU && kc < KC_NCATEGORIES) return (kill_category_names[kc]); @@ -95,7 +95,7 @@ void KillMaster::load(FILE *file) void KillMaster::record_kill(const monsters *mon, int killer, bool ispet) { - KillCategory kc = + kill_category kc = (killer == KILL_YOU || killer == KILL_YOU_MISSILE)? KC_YOU : (ispet)? KC_FRIENDLY : KC_OTHER; @@ -134,7 +134,7 @@ std::string KillMaster::kill_info() const kills, count, i == KC_YOU? NULL : - category_name((KillCategory) i), + category_name((kill_category) i), needseparator ); needseparator = true; } @@ -907,7 +907,7 @@ static int kill_lualc_holiness(lua_State *ls) } else { - switch (mons_holiness(ke->monnum)) + switch (mons_class_holiness(ke->monnum)) { case MH_HOLY: verdict = "holy"; break; case MH_NATURAL: verdict = "natural"; break; diff --git a/crawl-ref/source/Kills.h b/crawl-ref/source/Kills.h index 28c30a88c8..074ea79a6d 100644 --- a/crawl-ref/source/Kills.h +++ b/crawl-ref/source/Kills.h @@ -160,7 +160,7 @@ public: std::string kill_info() const; private: - const char *category_name(KillCategory kc) const; + const char *category_name(kill_category kc) const; Kills categorized_kills[KC_NCATEGORIES]; private: diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index dc992da89a..ae7c89fa59 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -110,7 +110,7 @@ static const struct ability_def Ability_List[] = { ABIL_FLY, "Fly", 3, 0, 100, 0, ABFLAG_NONE }, { ABIL_SUMMON_MINOR_DEMON, "Summon Minor Demon", 3, 3, 75, 0, ABFLAG_NONE }, - { ABIL_SUMMON_DEMON, "Summon Demon", 5, 5, 150, 0, ABFLAG_NONE }, + { ABIL_SUMMON_DEMONS, "Summon Demons", 5, 5, 150, 0, ABFLAG_NONE }, { ABIL_HELLFIRE, "Hellfire", 8, 8, 200, 0, ABFLAG_NONE }, { ABIL_TORMENT, "Torment", 9, 0, 250, 0, ABFLAG_PAIN }, { ABIL_RAISE_DEAD, "Raise Dead", 5, 5, 150, 0, ABFLAG_NONE }, @@ -160,7 +160,7 @@ static const struct ability_def Ability_List[] = { ABIL_TSO_REPEL_UNDEAD, "Repel Undead", 1, 0, 100, 0, ABFLAG_NONE }, { ABIL_TSO_SMITING, "Smiting", 3, 0, 50, 2, ABFLAG_NONE }, { ABIL_TSO_ANNIHILATE_UNDEAD, "Annihilate Undead", 3, 0, 50, 2, ABFLAG_NONE }, - { ABIL_TSO_THUNDERBOLT, "Thunderbolt", 5, 0, 100, 2, ABFLAG_NONE }, + { ABIL_TSO_CLEANSING_FLAME, "Cleansing Flame", 5, 0, 100, 2, ABFLAG_NONE }, { ABIL_TSO_SUMMON_DAEVA, "Summon Daeva", 8, 0, 150, 4, ABFLAG_NONE }, // Kikubaaqudgha @@ -211,7 +211,6 @@ static const struct ability_def Ability_List[] = { ABIL_ROTTING, "Rotting", 4, 4, 0, 2, ABFLAG_NONE }, { ABIL_TORMENT_II, "Call Torment", 9, 0, 0, 3, ABFLAG_PAIN }, - { ABIL_SHUGGOTH_SEED, "Sow Shuggoth Seed", 12, 8, 0, 6, ABFLAG_NONE }, { ABIL_RENOUNCE_RELIGION, "Renounce Religion", 0, 0, 0, 0, ABFLAG_NONE }, }; @@ -710,7 +709,7 @@ bool activate_ability(void) summon_any_demon(DEMON_LESSER) ); break; - case ABIL_SUMMON_DEMON: + case ABIL_SUMMON_DEMONS: summon_ice_beast_etc( you.experience_level * 4, summon_any_demon(DEMON_COMMON) ); break; @@ -873,14 +872,14 @@ bool activate_ability(void) exercise(SK_INVOCATIONS, 2 + random2(4)); break; - case ABIL_TSO_THUNDERBOLT: + case ABIL_TSO_CLEANSING_FLAME: if (spell_direction(spd, beam) == -1) { canned_msg(MSG_OK); return (false); } - zapping(ZAP_LIGHTNING, you.skills[SK_INVOCATIONS] * 6, beam); + zapping(ZAP_CLEANSING_FLAME, 20 + you.skills[SK_INVOCATIONS] * 6, beam); exercise(SK_INVOCATIONS, 3 + random2(6)); break; @@ -1035,7 +1034,7 @@ bool activate_ability(void) beam.thrower = KILL_YOU; beam.aux_source = "Makhleb's lightning strike"; beam.ex_size = 1 + you.skills[SK_INVOCATIONS] / 8; - beam.isTracer = false; + beam.is_tracer = false; // ... and fire! explosion(beam); @@ -1158,20 +1157,6 @@ bool activate_ability(void) exercise(SK_INVOCATIONS, 2 + random2(4)); break; - case ABIL_SHUGGOTH_SEED: - if (you.duration[DUR_SHUGGOTH_SEED_RELOAD]) - { - canned_msg(MSG_CANNOT_DO_YET); - return (false); - } - - cast_shuggoth_seed( you.experience_level * 2 - + you.skills[SK_INVOCATIONS] * 3 ); - - you.duration[DUR_SHUGGOTH_SEED_RELOAD] = 10 + random2avg(39, 2); - exercise(SK_INVOCATIONS, 2 + random2(4)); - break; - case ABIL_RENOUNCE_RELIGION: if (yesno("Really renounce your faith, foregoing its fabulous benefits?") && yesno( "Are you sure you won't change your mind later?" )) @@ -1469,7 +1454,7 @@ bool generate_abilities( void ) insert_ability( ABIL_SUMMON_MINOR_DEMON ); if (you.mutation[MUT_SUMMON_DEMONS]) - insert_ability( ABIL_SUMMON_DEMON ); + insert_ability( ABIL_SUMMON_DEMONS ); if (you.mutation[MUT_HURL_HELLFIRE]) insert_ability( ABIL_HELLFIRE ); @@ -1533,7 +1518,7 @@ bool generate_abilities( void ) if (you.piety >= 75) insert_ability( ABIL_TSO_ANNIHILATE_UNDEAD ); if (you.piety >= 100) - insert_ability( ABIL_TSO_THUNDERBOLT ); + insert_ability( ABIL_TSO_CLEANSING_FLAME ); if (you.piety >= 120) insert_ability( ABIL_TSO_SUMMON_DAEVA ); break; @@ -1974,7 +1959,7 @@ static bool insert_ability( int which_ability ) failure = 35 - you.experience_level; break; - case ABIL_SUMMON_DEMON: + case ABIL_SUMMON_DEMONS: failure = 40 - you.experience_level; break; @@ -2114,7 +2099,7 @@ static bool insert_ability( int which_ability ) break; case ABIL_ZIN_HOLY_WORD: - case ABIL_TSO_THUNDERBOLT: + case ABIL_TSO_CLEANSING_FLAME: case ABIL_ELYVILON_RESTORATION: case ABIL_YRED_CONTROL_UNDEAD: case ABIL_OKAWARU_HASTE: @@ -2152,11 +2137,6 @@ static bool insert_ability( int which_ability ) failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4); break; - case ABIL_SHUGGOTH_SEED: - invoc = true; - failure = 85 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 3); - break; - case ABIL_RENOUNCE_RELIGION: invoc = true; perfect = true; diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 5c582e52e9..669b72315a 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -97,6 +97,7 @@ #include "it_use2.h" #include "it_use3.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "lev-pand.h" #include "macro.h" @@ -168,14 +169,6 @@ static const struct coord_def Compass[8] = void (*viewwindow) (char, bool); -/* these are all defined in view.cc: */ -extern unsigned char (*mapch) (unsigned char); -extern unsigned char (*mapch2) (unsigned char); -unsigned char mapchar(unsigned char ldfk); -unsigned char mapchar2(unsigned char ldfk); -unsigned char mapchar3(unsigned char ldfk); -unsigned char mapchar4(unsigned char ldfk); - /* Function pointers are used to make switching between Unix and DOS char sets possible as a runtime option (command-line -c) @@ -201,15 +194,9 @@ static void open_door(char move_x, char move_y); int main( int argc, char *argv[] ) { #ifdef USE_ASCII_CHARACTERS - // Default to the non-ibm set when it makes sense. - viewwindow = &viewwindow3; - mapch = &mapchar3; - mapch2 = &mapchar4; + apply_ascii_display(true); #else - // Use the standard ibm default - viewwindow = &viewwindow2; - mapch = &mapchar; - mapch2 = &mapchar2; + apply_ascii_display(false); #endif // Load in the system environment variables @@ -1894,16 +1881,11 @@ static void input(void) switch (temp_effect) { case SPWPN_VORPAL: - if (damage_type(you.inv[you.equip[EQ_WEAPON]].base_type, - you.inv[you.equip[EQ_WEAPON]].sub_type) != DVORP_CRUSHING) - { + if (get_vorpal_type(you.inv[you.equip[EQ_WEAPON]]) + == DVORP_SLICING) strcat(info, " seems blunter."); - } else - { - //jmf: for Maxwell's Silver Hammer strcat(info, " feels lighter."); - } break; case SPWPN_FLAMING: @@ -1994,7 +1976,7 @@ static void input(void) you.duration[DUR_STONEMAIL]--; if (you.duration[DUR_STONEMAIL] == 6) { - mpr("Your scaley stone armour is starting to flake away.", MSGCH_DURATION); + mpr("Your scaly stone armour is starting to flake away.", MSGCH_DURATION); you.redraw_armour_class = 1; if (coinflip()) you.duration[DUR_STONEMAIL]--; @@ -2002,7 +1984,7 @@ static void input(void) } else if (you.duration[DUR_STONEMAIL] == 1) { - mpr("Your scaley stone armour disappears.", MSGCH_DURATION); + mpr("Your scaly stone armour disappears.", MSGCH_DURATION); you.duration[DUR_STONEMAIL] = 0; you.redraw_armour_class = 1; burden_change(); @@ -2034,7 +2016,8 @@ static void input(void) { you.duration[DUR_CONDENSATION_SHIELD]--; - scrolls_burn( 1, OBJ_POTIONS ); + // [dshaligram] Makes this spell useless + // scrolls_burn( 1, OBJ_POTIONS ); if (player_res_cold() < 0) { @@ -2125,20 +2108,6 @@ static void input(void) you.duration[DUR_DEATH_CHANNEL] = 0; } - if (you.duration[DUR_SHUGGOTH_SEED_RELOAD] > 0) //jmf: added - you.duration[DUR_SHUGGOTH_SEED_RELOAD]--; - - if (you.duration[DUR_INFECTED_SHUGGOTH_SEED] > 1) - you.duration[DUR_INFECTED_SHUGGOTH_SEED]--; - else if (you.duration[DUR_INFECTED_SHUGGOTH_SEED] == 1) - { - //jmf: use you.max_hp instead? or would that be too evil? - you.duration[DUR_INFECTED_SHUGGOTH_SEED] = 0; - mpr("A horrible thing bursts from your chest!", MSGCH_WARN); - ouch(1 + you.hp / 2, 0, KILLED_BY_SHUGGOTH); - make_shuggoth(you.x_pos, you.y_pos, 1 + you.hp / 2); - } - if (you.invis > 1) { you.invis--; @@ -2759,7 +2728,8 @@ static bool initialise(void) seed_rng(); - mons_init(mcolour); // this needs to be way up top {dlb} + init_properties(); + init_monsters(mcolour); // this needs to be way up top {dlb} init_playerspells(); // this needs to be way up top {dlb} clrscr(); diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 8c4ea84d6a..2619de6658 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -38,6 +38,7 @@ #include "it_use2.h" #include "itemname.h" #include "items.h" +#include "itemprop.h" #include "misc.h" #include "monplace.h" #include "monstuff.h" @@ -92,8 +93,70 @@ static void explosion_map(struct bolt &beam, int x, int y, int count, int dir, int r); static void explosion_cell(struct bolt &beam, int x, int y, bool drawOnly); +static void ench_animation( int flavour, const monsters *mon = NULL, bool force = false); static void zappy(char z_type, int power, struct bolt &pbolt); +static bool beam_is_blockable( struct bolt &pbolt ) +{ + // BEAM_ELECTRICITY is added here because chain lighting is not + // a true beam (stops at the first target it gets to and redirects + // from there)... but we don't want it shield blockable. + return (!pbolt.is_beam && !pbolt.is_explosion + && pbolt.flavour != BEAM_ELECTRICITY); +} + +// simple animated flash from Rupert Smith (and expanded to be more generic): +void zap_animation( int colour, const monsters *mon, bool force ) +{ + int x = you.x_pos, y = you.y_pos; + + // default to whatever colour magic is today + if (colour == -1) + colour = element_colour( EC_MAGIC ); + + if (mon) + { + if (!force && !player_monster_visible( mon )) + return; + + x = mon->x; + y = mon->y; + } + + if (!see_grid( x, y )) + return; + + const int drawx = x - you.x_pos + 18; + const int drawy = y - you.y_pos + 9; + + if (drawx > 8 && drawx < 26 && drawy > 0 && drawy < 18) + { + textcolor( colour ); + gotoxy( drawx, drawy ); + putch( SYM_ZAP ); + +#ifdef LINUX + update_screen(); +#endif + + delay(50); + } +} + +// special front function for zap_animation to interpret enchantment flavours +static void ench_animation( int flavour, const monsters *mon, bool force ) +{ + const int elem = (flavour == BEAM_HEALING) ? EC_HEAL : + (flavour == BEAM_PAIN) ? EC_UNHOLY : + (flavour == BEAM_DISPEL_UNDEAD) ? EC_HOLY : + (flavour == BEAM_POLYMORPH) ? EC_MUTAGENIC : + (flavour == BEAM_TELEPORT + || flavour == BEAM_BANISH + || flavour == BEAM_BLINK) ? EC_WARP + : EC_ENCHANT; + zap_animation( element_colour( elem ), mon, force ); +} + void zapping(char ztype, int power, struct bolt &pbolt) { @@ -114,9 +177,9 @@ void zapping(char ztype, int power, struct bolt &pbolt) pbolt.type = 0; // default for "0" beams pbolt.flavour = BEAM_MAGIC; // default for "0" beams pbolt.ench_power = power; - pbolt.obviousEffect = false; - pbolt.isBeam = false; // default for all beams. - pbolt.isTracer = false; // default for all player beams + pbolt.obvious_effect = false; + pbolt.is_beam = false; // default for all beams. + pbolt.is_tracer = false; // default for all player beams pbolt.thrower = KILL_YOU_MISSILE; // missile from player pbolt.aux_source = NULL; // additional source info, unused @@ -430,7 +493,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 8 + power / 10; // 25: 10 pbolt.type = SYM_SPACE; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_MAGIC_DARTS: // cap 25 @@ -441,7 +504,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 1500; // hits always pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_STING: // cap 25 @@ -453,7 +516,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_POISON; // extra damage - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_ELECTRICITY: // cap 20 @@ -465,8 +528,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_DISRUPTION: // cap 25 @@ -499,7 +562,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_BOLT; pbolt.flavour = BEAM_FIRE; - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_SMALL_SANDBLAST: // cap 25 @@ -518,7 +581,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_BOLT; pbolt.flavour = BEAM_FRAG; // extra AC resist - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_SANDBLAST: // cap 50 @@ -534,7 +597,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_BOLT; pbolt.flavour = BEAM_FRAG; // extra AC resist - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_BONE_SHARDS: @@ -551,8 +614,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_MAGIC; // unresisted - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_FLAME: // cap 50 @@ -564,7 +627,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_FIRE; - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_FROST: // cap 50 @@ -576,7 +639,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_COLD; - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_STONE_ARROW: // cap 100 @@ -588,7 +651,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_MISSILE; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_STICKY_FLAME: // cap 100 @@ -600,7 +663,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_FIRE; - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_MYSTIC_BLAST: // cap 100 @@ -612,7 +675,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_ICE_BOLT: // cap 100 @@ -643,8 +706,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_LAVA; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_FIRE: // cap 150 @@ -656,8 +719,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_FIRE; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_COLD: // cap 150 @@ -669,8 +732,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_COLD; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_VENOM_BOLT: // cap 150 @@ -682,8 +745,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_POISON; // extra damage - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_NEGATIVE_ENERGY: // cap 150 @@ -695,8 +758,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_NEG; // drains levels - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_IRON_BOLT: // cap 150 @@ -707,7 +770,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 7 + power / 15; // 50: 10 100: 13 pbolt.type = SYM_MISSILE; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_POISON_ARROW: // cap 150 @@ -718,7 +781,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 5 + power / 10; // 50: 10 100: 15 pbolt.type = SYM_MISSILE; pbolt.flavour = BEAM_POISON_ARROW; // extra damage - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; @@ -729,7 +792,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.damage = calc_dice( 3, 15 + (power * 3) / 4 ); pbolt.ench_power *= 5; pbolt.ench_power /= 2; - pbolt.isBeam = true; + pbolt.is_beam = true; break; case ZAP_LIGHTNING: // cap 150 @@ -742,8 +805,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_FIREBALL: // cap 150 @@ -753,7 +816,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.damage = calc_dice( 3, 10 + power / 2 ); pbolt.hit = 40; // hit: 40 pbolt.type = SYM_ZAP; - pbolt.flavour = BEAM_EXPLOSION; // fire + pbolt.flavour = BEAM_FIRE; // fire + pbolt.is_explosion = true; break; case ZAP_ORB_OF_ELECTRICITY: // cap 150 @@ -765,6 +829,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 40; // hit: 40 pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_ELECTRICITY; + pbolt.is_explosion = true; break; case ZAP_ORB_OF_FRAGMENTATION: // cap 150 @@ -775,19 +840,20 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 20; // hit: 20 pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_FRAG; // extra AC resist + pbolt.is_explosion = true; break; - case ZAP_CLEANSING_FLAME: // cap 200 + case ZAP_CLEANSING_FLAME: strcpy(pbolt.beam_name, "golden flame"); pbolt.colour = YELLOW; - pbolt.range = 7 + random2(10); - pbolt.damage = calc_dice( 6, 30 + power ); - pbolt.hit = 20; // hit: 20 + pbolt.range = 7; + pbolt.damage = calc_dice( 3, 30 + (power * 3) / 4 ); + pbolt.hit = 150; pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_HOLY; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_explosion = true; break; case ZAP_CRYSTAL_SPEAR: // cap 200 @@ -799,7 +865,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_MISSILE; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_HELLFIRE: // cap 200 @@ -809,10 +875,10 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.damage = calc_dice( 3, 10 + (power * 3) / 4 ); pbolt.hit = 20 + power / 10; // 50: 25 100: 30 pbolt.type = SYM_ZAP; - pbolt.flavour = BEAM_EXPLOSION; + pbolt.flavour = BEAM_HELLFIRE; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_explosion = true; break; case ZAP_ICE_STORM: // cap 200 @@ -825,6 +891,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.ench_power = power; // used for radius pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_ICE; // half resisted + pbolt.is_explosion = true; break; case ZAP_BEAM_OF_ENERGY: // bolt of innacuracy @@ -836,8 +903,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_ENERGY; // unresisted - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_SPIT_POISON: // cap 50 @@ -853,7 +920,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.hit = 5 + random2( 1 + power / 3 ); // max hit: 19 pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_POISON; - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; case ZAP_BREATHE_FIRE: // cap 50 @@ -870,8 +937,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_FIRE; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_FROST: // cap 50 @@ -888,8 +955,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_COLD; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_ACID: // cap 50 @@ -906,8 +973,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_ACID; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_POISON: // leaves clouds of gas // cap 50 @@ -924,8 +991,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_POISON; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_POWER: // cap 50 @@ -949,8 +1016,8 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_BREATHE_STEAM: // cap 50 @@ -967,45 +1034,45 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_ZAP; pbolt.flavour = BEAM_FIRE; - pbolt.obviousEffect = true; - pbolt.isBeam = true; + pbolt.obvious_effect = true; + pbolt.is_beam = true; break; case ZAP_SLOWING: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_SLOW; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_HASTING: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_HASTE; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_PARALYSIS: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_PARALYSIS; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_CONFUSION: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_CONFUSION; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_INVISIBILITY: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_INVISIBILITY; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_HEALING: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_HEALING; pbolt.damage = dice_def( 1, 7 + power / 3 ); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_DIGGING: @@ -1013,49 +1080,49 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.flavour = BEAM_DIGGING; // not ordinary "0" beam range {dlb} pbolt.range = 3 + random2( power / 5 ) + random2(5); - pbolt.isBeam = true; + pbolt.is_beam = true; break; case ZAP_TELEPORTATION: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_TELEPORT; pbolt.range = 9 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_POLYMORPH_OTHER: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_POLYMORPH; pbolt.range = 9 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_ENSLAVEMENT: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_CHARM; pbolt.range = 7 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_BANISHMENT: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_BANISH; pbolt.range = 7 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_DEGENERATION: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_DEGENERATE; pbolt.range = 7 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_ENSLAVE_UNDEAD: strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_ENSLAVE_UNDEAD; pbolt.range = 7 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_AGONY: @@ -1063,7 +1130,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.flavour = BEAM_PAIN; pbolt.range = 7 + random2(8); pbolt.ench_power *= 5; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_CONTROL_DEMON: @@ -1072,14 +1139,14 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.range = 7 + random2(5); pbolt.ench_power *= 3; pbolt.ench_power /= 2; - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_SLEEP: //jmf: added strcpy(pbolt.beam_name, "0"); pbolt.flavour = BEAM_SLEEP; pbolt.range = 7 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_BACKLIGHT: //jmf: added @@ -1087,7 +1154,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.flavour = BEAM_BACKLIGHT; pbolt.colour = BLUE; pbolt.range = 7 + random2(5); - // pbolt.isBeam = true; + // pbolt.is_beam = true; break; case ZAP_DEBUGGING_RAY: @@ -1099,7 +1166,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_DEBUG; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; default: @@ -1111,7 +1178,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) pbolt.type = SYM_DEBUG; pbolt.flavour = BEAM_MMISSILE; // unresistable - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; break; } // end of switch } // end zappy() @@ -1140,7 +1207,7 @@ static void zappy( char z_type, int power, struct bolt &pbolt ) * 4. Check for beam termination on target * 5. Affect the cell which the beam just moved into -> affect() * 6. Decrease remaining range appropriately - * 7. Check for early out due to aimedAtFeet + * 7. Check for early out due to aimed_at_feet * 8. Draw the beam * 9. Drop an object where the beam 'landed' *10. Beams explode where the beam 'landed' @@ -1167,9 +1234,11 @@ void fire_beam( struct bolt &pbolt, item_def *item ) if (pbolt.flavour != BEAM_LINE_OF_SIGHT) { mprf( MSGCH_DIAGNOSTICS, - "%s%s (%d,%d) to (%d,%d): ty=%d col=%d flav=%d hit=%d dam=%dd%d", - (pbolt.isBeam) ? "beam" : "missile", - (pbolt.isTracer) ? " tracer" : "", + "%s%s%s (%d,%d) to (%d,%d): ty=%d col=%d flav=%d hit=%d dam=%dd%d", + (pbolt.is_beam) ? "beam" : "missile", + (pbolt.is_explosion) ? "*" : + (pbolt.is_big_cloud) ? "+" : "", + (pbolt.is_tracer) ? " tracer" : "", pbolt.source_x, pbolt.source_y, pbolt.target_x, pbolt.target_y, pbolt.type, pbolt.colour, pbolt.flavour, @@ -1178,9 +1247,8 @@ void fire_beam( struct bolt &pbolt, item_def *item ) #endif // init - pbolt.aimedAtFeet = false; - pbolt.msgGenerated = false; - pbolt.isExplosion = false; + pbolt.aimed_at_feet = false; + pbolt.msg_generated = false; roundY = false; roundX = false; @@ -1191,7 +1259,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) // check for aim at feet if (dx == 0 && dy == 0) { - pbolt.aimedAtFeet = true; + pbolt.aimed_at_feet = true; stepx = 0; stepy = 0; tx = pbolt.source_x; @@ -1213,7 +1281,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) } } - // give chance for beam to affect one cell even if aimedAtFeet. + // give chance for beam to affect one cell even if aimed_at_feet. beamTerminate = false; // setup working coords lx = pbolt.source_x; @@ -1224,7 +1292,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) rangeRemaining = pbolt.range; if (pbolt.rangeMax > pbolt.range) { - if (pbolt.isTracer) + if (pbolt.is_tracer) rangeRemaining = pbolt.rangeMax; else rangeRemaining += random2((pbolt.rangeMax - pbolt.range) + 1); @@ -1233,7 +1301,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) // before we start drawing the beam, turn buffering off #ifdef WIN32CONSOLE bool oldValue = true; - if (!pbolt.isTracer) + if (!pbolt.is_tracer) oldValue = setBuffering(false); #endif @@ -1274,7 +1342,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) { // should we ever get a tracer with a wall-affecting // beam (possible I suppose), we'll quit tracing now. - if (!pbolt.isTracer) + if (!pbolt.is_tracer) rangeRemaining -= affect(pbolt, tx, ty); // if it's still a wall, quit. @@ -1363,7 +1431,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) // affect the cell, except in the special case noted // above -- affect() will early out if something gets // hit and the beam is type 'term on target'. - if (!beamTerminate) + if (!beamTerminate || !pbolt.is_explosion) { // random beams: randomize before affect random_beam = false; @@ -1387,12 +1455,12 @@ void fire_beam( struct bolt &pbolt, item_def *item ) beamTerminate = true; // special case - beam was aimed at feet - if (pbolt.aimedAtFeet) + if (pbolt.aimed_at_feet) beamTerminate = true; // actually draw the beam/missile/whatever, // if the player can see the cell. - if (!pbolt.isTracer && pbolt.beam_name[0] != '0' && see_grid(tx,ty)) + if (!pbolt.is_tracer && pbolt.beam_name[0] != '0' && see_grid(tx,ty)) { // we don't clean up the old position. // first, most people like seeing the full path, @@ -1421,7 +1489,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) delay(15); #ifdef MISSILE_TRAILS_OFF - if (!pbolt.isBeam || pbolt.beam_name[0] == '0') + if (!pbolt.is_beam || pbolt.beam_name[0] == '0') viewwindow(1,false); // mv: added. It's not optimal but // is usually enough #endif @@ -1452,7 +1520,7 @@ void fire_beam( struct bolt &pbolt, item_def *item ) beam_explodes(pbolt, tx, ty); - if (pbolt.isTracer) + if (pbolt.is_tracer) { pbolt.target_x = ox; pbolt.target_y = oy; @@ -1461,13 +1529,13 @@ void fire_beam( struct bolt &pbolt, item_def *item ) // canned msg for enchantments that affected no-one if (pbolt.beam_name[0] == '0' && pbolt.flavour != BEAM_DIGGING) { - if (!pbolt.isTracer && !pbolt.msgGenerated && !pbolt.obviousEffect) + if (!pbolt.is_tracer && !pbolt.msg_generated && !pbolt.obvious_effect) canned_msg(MSG_NOTHING_HAPPENS); } // that's it! #ifdef WIN32CONSOLE - if (!pbolt.isTracer) + if (!pbolt.is_tracer) setBuffering(oldValue); #endif } // end fire_beam(); @@ -1582,8 +1650,7 @@ int mons_adjust_flavoured( struct monsters *monster, struct bolt &pbolt, // Poison arrow can poison any living thing regardless of // poison resistance. -- bwr - const int holy = mons_holiness( monster->type ); - if (holy == MH_PLANT || holy == MH_NATURAL) + if (mons_has_lifeforce(monster)) poison_monster( monster, YOU_KILL(pbolt.thrower), 2, true ); } @@ -1625,17 +1692,47 @@ int mons_adjust_flavoured( struct monsters *monster, struct bolt &pbolt, } // end else break; - case BEAM_HOLY: // flame of cleansing - if (mons_holiness(monster->type) == MH_NATURAL - || mons_holiness(monster->type) == MH_NONLIVING - || mons_holiness(monster->type) == MH_PLANT - || mons_holiness(monster->type) == MH_HOLY) + case BEAM_MIASMA: + if (mons_res_negative_energy( monster ) >= 3) { if (doFlavouredEffects) simple_monster_message(monster, " appears unharmed."); hurted = 0; } + else + { + // early out for tracer/no side effects + if (!doFlavouredEffects) + return (hurted); + + if (mons_res_poison( monster ) <= 0) + poison_monster( monster, YOU_KILL(pbolt.thrower) ); + + if (one_chance_in( 3 + 2 * mons_res_negative_energy(monster) )) + { + struct bolt beam; + beam.flavour = BEAM_SLOW; + mons_ench_f2( monster, beam ); + } + } + break; + + case BEAM_HOLY: // flame of cleansing + if (mons_is_unholy( monster )) + { + if (doFlavouredEffects) + simple_monster_message( monster, " writhes in agony!" ); + + hurted = (hurted * 3) / 2; + } + else if (!mons_is_evil( monster )) + { + if (doFlavouredEffects) + simple_monster_message( monster, " appears unharmed." ); + + hurted = 0; + } break; case BEAM_ICE: @@ -1734,7 +1831,7 @@ int mons_adjust_flavoured( struct monsters *monster, struct bolt &pbolt, bool mass_enchantment( int wh_enchant, int pow, int origin ) { int i; // loop variable {dlb} - bool msgGenerated = false; + bool msg_generated = false; struct monsters *monster; viewwindow(0, false); @@ -1755,7 +1852,7 @@ bool mass_enchantment( int wh_enchant, int pow, int origin ) if (mons_friendly(monster)) continue; - if (mons_holiness(monster->type) != MH_UNDEAD) + if (mons_class_holiness(monster->type) != MH_UNDEAD) continue; if (check_mons_resist_magic( monster, pow )) @@ -1764,7 +1861,7 @@ bool mass_enchantment( int wh_enchant, int pow, int origin ) continue; } } - else if (mons_holiness(monster->type) == MH_NATURAL) + else if (mons_holiness(monster) == MH_NATURAL) { if (check_mons_resist_magic( monster, pow )) { @@ -1786,7 +1883,7 @@ bool mass_enchantment( int wh_enchant, int pow, int origin ) if (player_monster_visible( monster )) { // turn message on - msgGenerated = true; + msg_generated = true; switch (wh_enchant) { case ENCH_FEAR: @@ -1803,7 +1900,7 @@ bool mass_enchantment( int wh_enchant, int pow, int origin ) break; default: // oops, I guess not! - msgGenerated = false; + msg_generated = false; } } @@ -1813,10 +1910,10 @@ bool mass_enchantment( int wh_enchant, int pow, int origin ) } } // end "for i" - if (!msgGenerated) + if (!msg_generated) canned_msg(MSG_NOTHING_HAPPENS); - return (msgGenerated); + return (msg_generated); } // end mass_enchantmenet() /* @@ -1838,7 +1935,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) if (mons_del_ench(monster, ENCH_HASTE)) { if (simple_monster_message(monster, " is no longer moving quickly.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; return (MON_AFFECTED); } @@ -1849,7 +1946,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) // put in an exception for fungi, plants and other things you won't // notice slow down. if (simple_monster_message(monster, " seems to slow down.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } return (MON_AFFECTED); @@ -1857,7 +1954,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) if (mons_del_ench(monster, ENCH_SLOW)) { if (simple_monster_message(monster, " is no longer moving slowly.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; return (MON_AFFECTED); } @@ -1868,7 +1965,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) // put in an exception for fungi, plants and other things you won't // notice speed up. if (simple_monster_message(monster, " seems to speed up.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } return (MON_AFFECTED); @@ -1879,12 +1976,12 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) { if (simple_monster_message(monster, "'s wounds heal themselves!")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } else { if (simple_monster_message(monster, " is healed somewhat.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } } return (MON_AFFECTED); @@ -1893,10 +1990,10 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) monster->speed_increment = 0; if (simple_monster_message(monster, " suddenly stops moving!")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; - if (grd[monster->x][monster->y] == DNGN_LAVA_X - || grd[monster->x][monster->y] == DNGN_WATER_X) + if (grd[monster->x][monster->y] == DNGN_LAVA + || grid_is_water(grd[monster->x][monster->y])) { if (mons_flies(monster) == 1) { @@ -1906,8 +2003,8 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) { strcpy(info, ptr_monam(monster, DESC_CAP_THE)); strcat(info, " falls into the "); - strcat(info, (grd[monster->x][monster->y] == DNGN_WATER_X) - ? "water" : "lava"); + strcat(info, (grd[monster->x][monster->y] == DNGN_LAVA) + ? "lava" : "water"); strcat(info, "!"); mpr(info); } @@ -1934,7 +2031,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) // put in an exception for fungi, plants and other things you won't // notice becoming confused. if (simple_monster_message(monster, " appears confused.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } return (MON_AFFECTED); @@ -1954,7 +2051,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) mpr( info ); } - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } return (MON_AFFECTED); @@ -1964,7 +2061,7 @@ int mons_ench_f2(struct monsters *monster, struct bolt &pbolt) // put in an exception for fungi, plants and other things you won't // notice becoming charmed. if (simple_monster_message(monster, " is charmed.")) - pbolt.obviousEffect = true; + pbolt.obvious_effect = true; } return (MON_AFFECTED); @@ -2166,31 +2263,31 @@ void sticky_flame_monster( int mn, bool fromPlayer, int levels ) void fire_tracer(struct monsters *monster, struct bolt &pbolt) { // don't fiddle with any input parameters other than tracer stuff! - pbolt.isTracer = true; + pbolt.is_tracer = true; pbolt.source_x = monster->x; // always safe to do. pbolt.source_y = monster->y; pbolt.beam_source = monster_index(monster); - pbolt.canSeeInvis = (mons_see_invis(monster) != 0); - pbolt.smartMonster = (mons_intel(monster->type) == I_HIGH || + pbolt.can_see_invis = (mons_see_invis(monster) != 0); + pbolt.smart_monster = (mons_intel(monster->type) == I_HIGH || mons_intel(monster->type) == I_NORMAL); - pbolt.isFriendly = mons_friendly(monster); + pbolt.is_friendly = mons_friendly(monster); // init tracer variables pbolt.foe_count = pbolt.fr_count = 0; pbolt.foe_power = pbolt.fr_power = 0; - pbolt.foeRatio = 80; // default - see mons_should_fire() + pbolt.foe_ratio = 80; // default - see mons_should_fire() // foe ratio for summon gtr. demons & undead -- they may be // summoned, but they're hostile and would love nothing better // than to nuke the player and his minions if (monster->attitude != ATT_FRIENDLY) - pbolt.foeRatio = 25; + pbolt.foe_ratio = 25; // fire! fire_beam(pbolt); // unset tracer flag (convenience) - pbolt.isTracer = false; + pbolt.is_tracer = false; } // end tracer_f() bool check_line_of_sight( int sx, int sy, int tx, int ty ) @@ -2218,7 +2315,7 @@ bool check_line_of_sight( int sx, int sy, int tx, int ty ) // Okay, no easy way... set up a LoS beam between the points pbolt.flavour = BEAM_LINE_OF_SIGHT; - pbolt.isTracer = true; + pbolt.is_tracer = true; pbolt.source_x = sx; pbolt.source_y = sy; pbolt.target_x = tx; @@ -2231,7 +2328,7 @@ bool check_line_of_sight( int sx, int sy, int tx, int ty ) pbolt.type = 0; pbolt.damage = dice_def( 0, 1 ); pbolt.colour = BLACK; - pbolt.isBeam = true; + pbolt.is_beam = true; // init tracer variables (used to tell if we "hit" the target) pbolt.foe_count = pbolt.fr_count = 0; @@ -2277,7 +2374,7 @@ static void beam_explodes(struct bolt &beam, int x, int y) beam.target_y = y; // generic explosion - if (beam.flavour == BEAM_EXPLOSION || beam.flavour == BEAM_HOLY) + if (beam.is_explosion) // beam.flavour == BEAM_EXPLOSION || beam.flavour == BEAM_HOLY) { explosion1(beam); return; @@ -2379,7 +2476,7 @@ static bool beam_term_on_target(struct bolt &beam) // in the target cell will have no chance to dodge or block, so we // DON'T affect() the cell if this function returns true! - if (beam.flavour == BEAM_EXPLOSION || beam.flavour == BEAM_HOLY) + if (beam.is_explosion || beam.is_big_cloud) return (true); // POISON BLAST @@ -2402,7 +2499,7 @@ static void beam_drop_object( struct bolt &beam, item_def *item, int x, int y ) ASSERT( item != NULL ); // conditions: beam is missile and not tracer. - if (beam.isTracer || beam.flavour != BEAM_MISSILE) + if (beam.is_tracer || beam.flavour != BEAM_MISSILE) return; if (YOU_KILL(beam.thrower) // ie if you threw it. @@ -2413,11 +2510,11 @@ static void beam_drop_object( struct bolt &beam, item_def *item, int x, int y ) // Using Throwing skill as the fletching/ammo preserving skill. -- bwr switch (item->sub_type) { - case MI_NEEDLE: chance = 6 + you.skills[SK_THROWING] / 6; break; - case MI_STONE: chance = 3 + you.skills[SK_THROWING] / 4; break; - case MI_DART: chance = 2 + you.skills[SK_THROWING] / 6; break; - case MI_ARROW: chance = 2 + you.skills[SK_THROWING] / 4; break; - case MI_BOLT: chance = 2 + you.skills[SK_THROWING] / 5; break; + case MI_NEEDLE: chance = 6 + you.skills[SK_RANGED_COMBAT] / 6; break; + case MI_STONE: chance = 3 + you.skills[SK_RANGED_COMBAT] / 4; break; + case MI_DART: chance = 2 + you.skills[SK_RANGED_COMBAT] / 6; break; + case MI_ARROW: chance = 2 + you.skills[SK_RANGED_COMBAT] / 4; break; + case MI_BOLT: chance = 2 + you.skills[SK_RANGED_COMBAT] / 5; break; case MI_LARGE_ROCK: default: @@ -2595,7 +2692,7 @@ static int affect(struct bolt &beam, int x, int y) if (grd[x][y] < MINMOVE) { - if (beam.isTracer) // tracers always stop on walls. + if (beam.is_tracer) // tracers always stop on walls. return (BEAM_STOP); if (affectsWalls(beam)) @@ -2611,16 +2708,24 @@ static int affect(struct bolt &beam, int x, int y) // grd[x][y] will NOT be a wall for the remainder of this function. // if not a tracer, place clouds - if (!beam.isTracer) + if (!beam.is_tracer) rangeUsed += affect_place_clouds(beam, x, y); // if player is at this location, try to affect unless term_on_target if (x == you.x_pos && y == you.y_pos) { - if (beam_term_on_target(beam) && !beam.isExplosion) + // Done this way so that poison blasts affect the target once (via + // place_cloud) and explosion spells only affect the target once + // (during the explosion phase, not an initial hit during the + // beam phase). + if (!beam.is_big_cloud + && (!beam.is_explosion || beam.in_explosion_phase)) + { + rangeUsed += affect_player( beam ); + } + + if (beam_term_on_target(beam)) return (BEAM_STOP); - - rangeUsed += affect_player(beam); } // if there is a monster at this location, affect it @@ -2628,11 +2733,14 @@ static int affect(struct bolt &beam, int x, int y) int mid = mgrd[x][y]; if (mid != NON_MONSTER && !mons_has_ench( &menv[mid], ENCH_SUBMERGED )) { - if (beam_term_on_target(beam) && !beam.isExplosion) + if (!beam.is_big_cloud + && (!beam.is_explosion || beam.in_explosion_phase)) + { + rangeUsed += affect_monster( beam, &menv[mid] ); + } + + if (beam_term_on_target(beam)) return (BEAM_STOP); - - struct monsters* monster = &menv[mid]; - rangeUsed += affect_monster(beam, monster); } return (rangeUsed); @@ -2642,7 +2750,7 @@ static bool affectsWalls(struct bolt &beam) { // don't know of any explosion that affects walls. But change it here // if there is. - if (beam.isExplosion) + if (beam.is_explosion) return (false); // digging @@ -2682,15 +2790,15 @@ static int affect_wall(struct bolt &beam, int x, int y) { grd[x][y] = DNGN_FLOOR; - if (!beam.msgGenerated) + if (!beam.msg_generated) { if (!silenced(you.x_pos, you.y_pos)) { mpr("You hear a grinding noise.", MSGCH_SOUND); - beam.obviousEffect = true; + beam.obvious_effect = true; } - beam.msgGenerated = true; + beam.msg_generated = true; } } @@ -2710,12 +2818,14 @@ static int affect_wall(struct bolt &beam, int x, int y) if (!silenced(you.x_pos, you.y_pos)) { mpr("You hear a grinding noise.", MSGCH_SOUND); - beam.obviousEffect = true; + beam.obvious_effect = true; } } - if (targ_grid == DNGN_ORCISH_IDOL || (targ_grid >= DNGN_SILVER_STATUE - && targ_grid <= DNGN_STATUE_39)) + if (targ_grid == DNGN_ORCISH_IDOL + || targ_grid == DNGN_SILVER_STATUE + || targ_grid == DNGN_GRANITE_STATUE + || targ_grid == DNGN_ORANGE_CRYSTAL_STATUE) { grd[x][y] = DNGN_FLOOR; @@ -2738,7 +2848,7 @@ static int affect_wall(struct bolt &beam, int x, int y) else if (targ_grid == DNGN_ORANGE_CRYSTAL_STATUE) Visible_Statue[ STATUE_ORANGE_CRYSTAL ] = 0; - beam.obviousEffect = 1; + beam.obvious_effect = 1; } return (BEAM_STOP); @@ -2751,7 +2861,7 @@ static int affect_place_clouds(struct bolt &beam, int x, int y) { int cloud_type; - if (beam.isExplosion) + if (beam.in_explosion_phase) { affect_place_explosion_clouds( beam, x, y ); return (0); // return value irrelevant for explosions @@ -2823,6 +2933,12 @@ static int affect_place_clouds(struct bolt &beam, int x, int y) place_cloud( cloud_type, x, y, random2(5) + 2 ); } + if (beam.flavour == BEAM_MIASMA) + { + cloud_type = YOU_KILL( beam.thrower ) ? CLOUD_MIASMA : CLOUD_MIASMA_MON; + place_cloud( cloud_type, x, y, random2(5) + 2 ); + } + // STICKY FLAME if (strcmp(beam.beam_name, "sticky flame") == 0) { @@ -3024,16 +3140,16 @@ static int affect_player( struct bolt &beam ) return (0); // check for tracer - if (beam.isTracer) + if (beam.is_tracer) { // check can see player // XXX: note the cheat to allow for ME_ALERT to target the player... // replace this with a time since alert system, rather than just // peeking to see if the character is still there. -- bwr - if (beam.canSeeInvis || !you.invis + if (beam.can_see_invis || !you.invis || (you.x_pos == beam.target_x && you.y_pos == beam.target_y)) { - if (beam.isFriendly) + if (beam.is_friendly) { beam.fr_count += 1; beam.fr_power += you.experience_level; @@ -3048,24 +3164,24 @@ static int affect_player( struct bolt &beam ) } // BEGIN real beam code - beam.msgGenerated = true; + beam.msg_generated = true; // use beamHit, NOT beam.hit, for modification of tohit.. geez! beamHit = beam.hit; if (beam.beam_name[0] != '0') { - if (!beam.isExplosion && !beam.aimedAtFeet) + if (!beam.is_explosion && !beam.aimed_at_feet) { // BEGIN BEAM/MISSILE int dodge = random2limit( player_evasion(), 40 ) + random2( you.dex ) / 3 - 2; - if (beam.isBeam) + if (beam.is_beam) { // beams can be dodged if (player_light_armour() - && !beam.aimedAtFeet && coinflip()) + && !beam.aimed_at_feet && coinflip()) { exercise(SK_DODGING, 1); } @@ -3088,24 +3204,24 @@ static int affect_player( struct bolt &beam ) return (0); // no extra used by miss! } } - else + else if (beam_is_blockable(beam)) { // non-beams can be blocked or dodged if (you.equip[EQ_SHIELD] != -1 - && !beam.aimedAtFeet + && !beam.aimed_at_feet && player_shield_class() > 0) { int exer = one_chance_in(3) ? 1 : 0; - // [dshaligram] beam.hit multiplier lowererd to 2.5 - was 5. - // In favour of blocking, dex multiplier changed to .3333 + // [dshaligram] beam.hit multiplier lowered to 3 - was 5. + // In favour of blocking, dex multiplier changed to .25 // (was .2), added shield skill into the equation with a // skill bump. - const int hit = random2( beam.hit * 5 / 2 + const int hit = random2( beam.hit * 3 + 5 * you.shield_blocks * you.shield_blocks ); const int block = random2(player_shield_class()) - + (random2(you.dex) / 3) - + (random2(skill_bump(SK_SHIELDS)) / 3) + + (random2(you.dex) / 4) + + (random2(skill_bump(SK_SHIELDS)) / 4) - 1; if (hit < block) @@ -3123,7 +3239,7 @@ static int affect_player( struct bolt &beam ) exercise( SK_SHIELDS, exer ); } - if (player_light_armour() && !beam.aimedAtFeet + if (player_light_armour() && !beam.aimed_at_feet && coinflip()) exercise(SK_DODGING, 1); @@ -3152,63 +3268,70 @@ static int affect_player( struct bolt &beam ) && beam.flavour != BEAM_INVISIBILITY && beam.flavour != BEAM_HEALING && ((beam.flavour != BEAM_TELEPORT && beam.flavour != BEAM_BANISH) - || !beam.aimedAtFeet) + || !beam.aimed_at_feet) && you_resist_magic( beam.ench_power )) { canned_msg(MSG_YOU_RESIST); return (range_used_on_hit(beam)); } + ench_animation( beam.flavour ); + // these colors are misapplied - see mons_ench_f2() {dlb} switch (beam.flavour) { case BEAM_SLOW: potion_effect( POT_SLOWING, beam.ench_power ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // slow case BEAM_HASTE: potion_effect( POT_SPEED, beam.ench_power ); contaminate_player( 1 ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // haste case BEAM_HEALING: potion_effect( POT_HEAL_WOUNDS, beam.ench_power ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // heal (heal wounds potion eff) case BEAM_PARALYSIS: potion_effect( POT_PARALYSIS, beam.ench_power ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // paralysis case BEAM_CONFUSION: potion_effect( POT_CONFUSION, beam.ench_power ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // confusion case BEAM_INVISIBILITY: potion_effect( POT_INVISIBILITY, beam.ench_power ); contaminate_player( 1 + random2(2) ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // invisibility // 6 is used by digging case BEAM_TELEPORT: you_teleport(); - beam.obviousEffect = true; + beam.obvious_effect = true; + break; + + case BEAM_BLINK: + random_blink(0); + beam.obvious_effect = true; break; case BEAM_POLYMORPH: mpr("This is polymorph other only!"); - beam.obviousEffect = true; + beam.obvious_effect = true; break; case BEAM_CHARM: potion_effect( POT_CONFUSION, beam.ench_power ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // enslavement - confusion? case BEAM_BANISH: @@ -3220,7 +3343,7 @@ static int affect_player( struct bolt &beam ) mpr("You are cast into the Abyss!"); more(); banished(DNGN_ENTER_ABYSS); - beam.obviousEffect = true; + beam.obvious_effect = true; break; // banishment to the abyss case BEAM_PAIN: // pain @@ -3236,7 +3359,7 @@ static int affect_player( struct bolt &beam ) beam.aux_source = "by nerve-wracking pain"; beam_ouch( roll_dice( beam.damage ), beam ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; case BEAM_DISPEL_UNDEAD: @@ -3252,7 +3375,7 @@ static int affect_player( struct bolt &beam ) beam.aux_source = "by dispel undead"; beam_ouch( roll_dice( beam.damage ), beam ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; case BEAM_DISINTEGRATION: @@ -3262,7 +3385,7 @@ static int affect_player( struct bolt &beam ) beam.aux_source = "disintegration bolt"; beam_ouch( roll_dice( beam.damage ), beam ); - beam.obviousEffect = true; + beam.obvious_effect = true; break; default: @@ -3280,12 +3403,11 @@ static int affect_player( struct bolt &beam ) // THE BEAM IS NOW GUARANTEED TO BE A NON-ENCHANTMENT WHICH HIT - snprintf( info, INFO_SIZE, "The %s %s you!", - beam.beam_name, (beam.isExplosion ? "engulfs" : "hits") ); - mpr( info ); + const bool engulfs = (beam.is_explosion || beam.is_big_cloud); + mprf( "The %s %s you!", beam.beam_name, (engulfs) ? "engulfs" : "hits" ); int hurted = 0; - int burn_power = (beam.isExplosion) ? 5 : ((beam.isBeam) ? 3 : 2); + int burn_power = (beam.is_explosion) ? 5 : ((beam.is_beam) ? 3 : 2); // Roll the damage hurted += roll_dice( beam.damage ); @@ -3314,7 +3436,7 @@ static int affect_player( struct bolt &beam ) if (you.equip[EQ_BODY_ARMOUR] != -1) { if (!player_light_armour() && one_chance_in(4) - && random2(1000) <= mass_item( you.inv[you.equip[EQ_BODY_ARMOUR]] )) + && random2(1000) <= item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] )) { exercise( SK_ARMOUR, 1 ); } @@ -3325,6 +3447,15 @@ static int affect_player( struct bolt &beam ) hurted = check_your_resists( hurted, beam.flavour ); + if (beam.flavour == BEAM_MIASMA && hurted > 0) + { + if (player_res_poison() <= 0) + poison_player(1); + + if (one_chance_in( 3 + 2 * player_prot_life() )) + potion_effect( POT_SLOWING, 5 ); + } + // poisoning if (strstr(beam.beam_name, "poison") != NULL && beam.flavour != BEAM_POISON @@ -3371,7 +3502,7 @@ static int affect_player( struct bolt &beam ) splash_with_acid(5); // spore pops - if (beam.isExplosion && beam.flavour == BEAM_SPORE) + if (beam.in_explosion_phase && beam.flavour == BEAM_SPORE) scrolls_burn( 2, OBJ_FOOD ); #if DEBUG_DIAGNOSTICS @@ -3410,10 +3541,10 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) } // check for tracer - if (beam.isTracer) + if (beam.is_tracer) { // check can see other monster - if (!beam.canSeeInvis && mons_has_ench(&menv[tid], ENCH_INVIS)) + if (!beam.can_see_invis && mons_has_ench(&menv[tid], ENCH_INVIS)) { // can't see this monster, ignore it return 0; @@ -3422,10 +3553,10 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) if (beam.beam_name[0] == '0') { - if (beam.isTracer) + if (beam.is_tracer) { // enchant case -- enchantments always hit, so update target immed. - if (beam.isFriendly ^ mons_friendly(mon)) + if (beam.is_friendly ^ mons_friendly(mon)) { beam.foe_count += 1; beam.foe_power += mons_power(tid); @@ -3466,17 +3597,21 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) // so call it now and store. int rangeUsed = range_used_on_hit(beam); + // Doing this here so that the player gets to see monsters + // "flicker and vanish" when turning invisible.... + ench_animation( beam.flavour, mon ); + // now do enchantment affect int ench_result = affect_monster_enchantment(beam, mon); switch(ench_result) { case MON_RESIST: if (simple_monster_message(mon, " resists.")) - beam.msgGenerated = true; + beam.msg_generated = true; break; case MON_UNAFFECTED: if (simple_monster_message(mon, " is unaffected.")) - beam.msgGenerated = true; + beam.msg_generated = true; break; default: break; @@ -3488,7 +3623,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) // BEGIN non-enchantment (could still be tracer) - if (mons_has_ench( mon, ENCH_SUBMERGED ) && !beam.aimedAtFeet) + if (mons_has_ench( mon, ENCH_SUBMERGED ) && !beam.aimed_at_feet) return (0); // missed me! // we need to know how much the monster _would_ be hurt by this, before @@ -3499,7 +3634,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) hurt_final = hurt; - if (beam.isTracer) + if (beam.is_tracer) hurt_final -= mon->armour_class / 2; else hurt_final -= random2(1 + mon->armour_class); @@ -3524,7 +3659,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) hurt_final = mons_adjust_flavoured( mon, beam, hurt_final, false ); #if DEBUG_DIAGNOSTICS - if (!beam.isTracer) + if (!beam.is_tracer) { snprintf( info, INFO_SIZE, "Monster: %s; Damage: pre-AC: %d; post-AC: %d; post-resist: %d", @@ -3536,7 +3671,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) // now, we know how much this monster would (probably) be // hurt by this beam. - if (beam.isTracer) + if (beam.is_tracer) { if (hurt_final != 0) { @@ -3546,7 +3681,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) // fireball at another fire giant, and it only took // 1/3 damage, then power of 5 would be applied to // foe_power or fr_power. - if (beam.isFriendly ^ mons_friendly(mon)) + if (beam.is_friendly ^ mons_friendly(mon)) { beam.foe_count += 1; beam.foe_power += hurt_final * mons_power(tid) / hurt; @@ -3584,7 +3719,9 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) } // explosions always 'hit' - if (!beam.isExplosion && beam.hit < random2(mon->evasion)) + const bool engulfs = (beam.is_explosion || beam.is_big_cloud); + + if (!engulfs && beam.hit < random2(mon->evasion)) { // if the PLAYER cannot see the monster, don't tell them anything! if (player_monster_visible( &menv[tid] ) && mons_near(mon)) @@ -3604,7 +3741,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) { strcpy(info, "The "); strcat(info, beam.beam_name); - strcat(info, beam.isExplosion?" engulfs ":" hits "); + strcat(info, engulfs? " engulfs ":" hits "); if (player_monster_visible( &menv[tid] )) strcat(info, ptr_monam(mon, DESC_NOCAP_THE)); @@ -3694,29 +3831,44 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) if (beam.flavour == BEAM_TELEPORT) // teleportation { if (check_mons_resist_magic( mon, beam.ench_power ) - && !beam.aimedAtFeet) + && !beam.aimed_at_feet) { return (MON_RESIST); } if (simple_monster_message(mon, " looks slightly unstable.")) - beam.obviousEffect = true; + beam.obvious_effect = true; monster_teleport(mon, false); return (MON_AFFECTED); } + if (beam.flavour == BEAM_BLINK) + { + if (!beam.aimed_at_feet + && check_mons_resist_magic( mon, beam.ench_power )) + { + return (MON_RESIST); + } + + if (mons_near( mon ) && player_monster_visible( mon )) + beam.obvious_effect = true; + + monster_blink( mon ); + return (MON_AFFECTED); + } + if (beam.flavour == BEAM_POLYMORPH) { - if (mons_holiness( mon->type ) != MH_NATURAL) + if (mons_holiness( mon ) != MH_NATURAL) return (MON_UNAFFECTED); if (check_mons_resist_magic( mon, beam.ench_power )) return (MON_RESIST); if (monster_polymorph(mon, RANDOM_MONSTER, 100)) - beam.obviousEffect = true; + beam.obvious_effect = true; return (MON_AFFECTED); } @@ -3733,13 +3885,13 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) else monster_die(mon, KILL_RESET, beam.beam_source); - beam.obviousEffect = true; + beam.obvious_effect = true; return (MON_AFFECTED); } if (beam.flavour == BEAM_DEGENERATE) { - if (mons_holiness(mon->type) != MH_NATURAL + if (mons_holiness(mon) != MH_NATURAL || mon->type == MONS_PULSATING_LUMP) { return (MON_UNAFFECTED); @@ -3749,18 +3901,18 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) return (MON_RESIST); if (monster_polymorph(mon, MONS_PULSATING_LUMP, 100)) - beam.obviousEffect = true; + beam.obvious_effect = true; return (MON_AFFECTED); } if (beam.flavour == BEAM_DISPEL_UNDEAD) { - if (mons_holiness(mon->type) != MH_UNDEAD) + if (mons_holiness(mon) != MH_UNDEAD) return (MON_UNAFFECTED); if (simple_monster_message(mon, " convulses!")) - beam.obviousEffect = true; + beam.obvious_effect = true; hurt_monster( mon, roll_dice( beam.damage ) ); @@ -3768,7 +3920,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) } if (beam.flavour == BEAM_ENSLAVE_UNDEAD - && mons_holiness(mon->type) == MH_UNDEAD) + && mons_holiness(mon) == MH_UNDEAD) { #if DEBUG_DIAGNOSTICS snprintf( info, INFO_SIZE, "HD: %d; pow: %d", @@ -3781,7 +3933,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) return (MON_RESIST); simple_monster_message(mon, " is enslaved."); - beam.obviousEffect = true; + beam.obvious_effect = true; // wow, permanent enslaving mon->attitude = ATT_FRIENDLY; @@ -3789,7 +3941,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) } if (beam.flavour == BEAM_ENSLAVE_DEMON - && mons_holiness(mon->type) == MH_DEMONIC) + && mons_holiness(mon) == MH_DEMONIC) { #if DEBUG_DIAGNOSTICS snprintf( info, INFO_SIZE, "HD: %d; pow: %d", @@ -3802,7 +3954,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) return (MON_RESIST); simple_monster_message(mon, " is enslaved."); - beam.obviousEffect = true; + beam.obvious_effect = true; // wow, permanent enslaving mon->attitude = ATT_FRIENDLY; @@ -3828,7 +3980,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) return (MON_UNAFFECTED); if (simple_monster_message(mon, " convulses in agony!")) - beam.obviousEffect = true; + beam.obvious_effect = true; if (strstr( beam.beam_name, "agony" ) != NULL) { @@ -3850,7 +4002,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) if (beam.flavour == BEAM_DISINTEGRATION) /* disrupt/disintegrate */ { if (simple_monster_message(mon, " is blasted.")) - beam.obviousEffect = true; + beam.obvious_effect = true; hurt_monster( mon, roll_dice( beam.damage ) ); @@ -3863,11 +4015,11 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) if (mons_has_ench( mon, ENCH_SLEEP_WARY )) // slept recently return (MON_RESIST); - if (mons_holiness(mon->type) != MH_NATURAL) // no unnatural + if (mons_holiness(mon) != MH_NATURAL) // no unnatural return (MON_UNAFFECTED); if (simple_monster_message(mon, " looks drowsy...")) - beam.obviousEffect = true; + beam.obvious_effect = true; mon->behaviour = BEH_SLEEP; mons_add_ench( mon, ENCH_SLEEP_WARY ); @@ -3879,7 +4031,7 @@ static int affect_monster_enchantment(struct bolt &beam, struct monsters *mon) { if (backlight_monsters(mon->x, mon->y, beam.hit, 0)) { - beam.obviousEffect = true; + beam.obvious_effect = true; return (MON_AFFECTED); } return (MON_UNAFFECTED); @@ -3912,7 +4064,7 @@ deathCheck: static int range_used_on_hit(struct bolt &beam) { // non-beams can only affect one thing (player/monster) - if (!beam.isBeam) + if (!beam.is_beam) return (BEAM_STOP); // CHECK ENCHANTMENTS @@ -3951,7 +4103,7 @@ static int range_used_on_hit(struct bolt &beam) return (0); // generic explosion - if (beam.flavour == BEAM_EXPLOSION) + if (beam.is_explosion || beam.is_big_cloud) return (BEAM_STOP); // plant spit @@ -3985,7 +4137,7 @@ static void explosion1(struct bolt &pbolt) // assume that the player can see/hear the explosion, or // gets burned by it anyway. :) - pbolt.msgGenerated = true; + pbolt.msg_generated = true; if (stricmp(pbolt.beam_name, "hellfire") == 0) { @@ -4005,6 +4157,17 @@ static void explosion1(struct bolt &pbolt) pbolt.flavour = BEAM_HOLY; // same as golden flame? [dlb] } + if (stricmp( pbolt.beam_name, "golden flame" ) == 0) + { + seeMsg = "The flame explodes!"; + hearMsg = "You feel a deep, resonant explosion."; + + pbolt.type = SYM_BURST; + pbolt.flavour = BEAM_HOLY; + ex_size = 2; + } + + if (stricmp(pbolt.beam_name, "fireball") == 0) { seeMsg = "The fireball explodes!"; @@ -4076,7 +4239,7 @@ static void explosion1(struct bolt &pbolt) } - if (!pbolt.isTracer) + if (!pbolt.is_tracer) { // check for see/hear/no msg if (see_grid(x,y) || (x == you.x_pos && y == you.y_pos)) @@ -4086,7 +4249,7 @@ static void explosion1(struct bolt &pbolt) if (!(silenced(x,y) || silenced(you.x_pos, you.y_pos))) mpr(hearMsg, MSGCH_SOUND); else - pbolt.msgGenerated = false; + pbolt.msg_generated = false; } } @@ -4107,8 +4270,8 @@ void explosion( struct bolt &beam, bool hole_in_the_middle ) { int r = beam.ex_size; - // beam is now an explosion; set isExplosion. - beam.isExplosion = true; + // beam is now an explosion; set in_explosion_phase + beam.in_explosion_phase = true; #if DEBUG_DIAGNOSTICS snprintf( info, INFO_SIZE, @@ -4150,7 +4313,7 @@ void explosion( struct bolt &beam, bool hole_in_the_middle ) // turn buffering off #ifdef WIN32CONSOLE bool oldValue = true; - if (!beam.isTracer) + if (!beam.is_tracer) oldValue = setBuffering(false); #endif @@ -4194,7 +4357,7 @@ void explosion( struct bolt &beam, bool hole_in_the_middle ) update_screen(); #endif // only delay on real explosion - if (!beam.isTracer && drawing) + if (!beam.is_tracer && drawing) delay(50); } @@ -4204,13 +4367,13 @@ void explosion( struct bolt &beam, bool hole_in_the_middle ) // ---------------- end boom -------------------------- #ifdef WIN32CONSOLE - if (!beam.isTracer) + if (!beam.is_tracer) setBuffering(oldValue); #endif // duplicate old behaviour - pause after entire explosion // has been drawn. - if (!beam.isTracer) + if (!beam.is_tracer) more(); } @@ -4236,7 +4399,7 @@ static void explosion_cell(struct bolt &beam, int x, int y, bool drawOnly) } // early out for tracer - if (beam.isTracer) + if (beam.is_tracer) return; // now affect items @@ -4327,11 +4490,11 @@ bool nasty_beam(struct monsters *mon, struct bolt &beam) // degeneration / sleep if (beam.flavour == BEAM_DEGENERATE || beam.flavour == BEAM_SLEEP) - return (mons_holiness(mon->type) == MH_NATURAL); + return (mons_holiness(mon) == MH_NATURAL); // dispel undead / control undead if (beam.flavour == BEAM_DISPEL_UNDEAD || beam.flavour == BEAM_ENSLAVE_UNDEAD) - return (mons_holiness(mon->type) == MH_UNDEAD); + return (mons_holiness(mon) == MH_UNDEAD); // pain/agony if (beam.flavour == BEAM_PAIN) @@ -4339,7 +4502,7 @@ bool nasty_beam(struct monsters *mon, struct bolt &beam) // control demon if (beam.flavour == BEAM_ENSLAVE_DEMON) - return (mons_holiness(mon->type) == MH_DEMONIC); + return (mons_holiness(mon) == MH_DEMONIC); // haste if (beam.flavour == BEAM_HASTE) diff --git a/crawl-ref/source/chardump.cc b/crawl-ref/source/chardump.cc index a8638c1118..5beb0e7ab7 100644 --- a/crawl-ref/source/chardump.cc +++ b/crawl-ref/source/chardump.cc @@ -45,6 +45,7 @@ #include "debug.h" #include "describe.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "macro.h" #include "mutation.h" diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index 21f2566c15..597694a81e 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -11,6 +11,7 @@ #include "invent.h" #include "initfile.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "item_use.h" #include "libutil.h" @@ -297,7 +298,7 @@ void CLua::vfnreturns(const char *format, va_list args) } static void push_monster(lua_State *ls, monsters *mons); -static int push_activity_interrupt(lua_State *ls, activity_interrupt_t *t); +static int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t); int CLua::push_args(lua_State *ls, const char *format, va_list args, va_list *targ) { @@ -346,7 +347,7 @@ int CLua::push_args(lua_State *ls, const char *format, va_list args, break; case 'A': argc += push_activity_interrupt( - ls, va_arg(args, activity_interrupt_t *)); + ls, va_arg(args, activity_interrupt_data *)); break; default: --argc; @@ -1239,22 +1240,25 @@ static int l_item_equip_type(lua_State *ls) if (!item || !is_valid_item(*item)) return (0); - int eq = -1; + equipment_type eq = EQ_NONE; + if (item->base_type == OBJ_WEAPONS || item->base_type == OBJ_STAVES) eq = EQ_WEAPON; else if (item->base_type == OBJ_ARMOUR) - eq = armour_equip_slot(*item); + eq = get_armour_slot(*item); else if (item->base_type == OBJ_JEWELLERY) eq = item->sub_type >= AMU_RAGE? EQ_AMULET : EQ_RINGS; - if (eq != -1) + if (eq != EQ_NONE) + { lua_pushnumber(ls, eq); - else - lua_pushnil(ls); - if (eq != -1) lua_pushstring(ls, equip_slot_to_name(eq)); + } else + { lua_pushnil(ls); + lua_pushnil(ls); + } return (2); } @@ -1444,42 +1448,6 @@ static int food_eat(lua_State *ls) return (1); } -// Giving away chunk type information is spoily. -/* -static int food_chunktype(lua_State *ls) -{ - LUA_ITEM(item, 1); - if (item && item->base_type == OBJ_FOOD && item->sub_type == FOOD_CHUNK) - { - int mons_type = item->plus; - int chunk_type = mons_corpse_thingy(mons_type); - const char *schunktype = "unknown"; - switch (chunk_type) - { - case CE_HCL: - case CE_MUTAGEN_GOOD: - case CE_MUTAGEN_BAD: - case CE_MUTAGEN_RANDOM: - schunktype = "mutagenic"; - break; - case CE_POISONOUS: - schunktype = "poisonous"; - break; - case CE_CONTAMINATED: - schunktype = "contaminated"; - break; - case CE_CLEAN: - schunktype = "clean"; - break; - } - lua_pushstring(ls, schunktype); - } - else - lua_pushnil(ls); - return (1); -} -*/ - static int food_rotting(lua_State *ls) { LUA_ITEM(item, 1); @@ -2066,7 +2034,7 @@ static int monster_set(lua_State *ls) return (0); } -static int push_activity_interrupt(lua_State *ls, activity_interrupt_t *t) +static int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t) { if (!t->data) { diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index eb77956909..83b910d236 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -31,6 +31,7 @@ #include "dungeon.h" #include "invent.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "misc.h" #include "monplace.h" @@ -856,13 +857,11 @@ void create_spec_object(void) { if (strstr( "naga barding", specs )) { - mitm[thing_created].sub_type = ARM_BOOTS; - mitm[thing_created].plus2 = TBOOT_NAGA_BARDING; + mitm[thing_created].sub_type = ARM_NAGA_BARDING; } else if (strstr( "centaur barding", specs )) { - mitm[thing_created].sub_type = ARM_BOOTS; - mitm[thing_created].plus2 = TBOOT_CENTAUR_BARDING; + mitm[thing_created].sub_type = ARM_CENTAUR_BARDING; } else if (strstr( "wizard's hat", specs )) { diff --git a/crawl-ref/source/defines.h b/crawl-ref/source/defines.h index d124244593..f1156eec76 100644 --- a/crawl-ref/source/defines.h +++ b/crawl-ref/source/defines.h @@ -41,6 +41,9 @@ // max size of inventory array {dlb}: #define ENDOFPACK 52 +// minimum value for strength required on armour and weapons +#define STR_REQ_THRESHOLD 10 + // max size of monter array {dlb}: #define MAX_MONSTERS 200 // number of monster enchantments @@ -48,6 +51,8 @@ // non-monster for mgrd[][] -- (MNST + 1) {dlb}: #define NON_MONSTER 201 +#define MAX_SUBTYPES 50 + // max size of item list {dlb}: #define MAX_ITEMS 500 // non-item -- (ITEMS + 1) {dlb} @@ -104,6 +109,12 @@ #define MAX_ROD_CHARGE 17 #define ROD_CHARGE_MULT 100 +// Maximum enchantment on weapons/armour/secondary armours +// Note: use armour_max_enchant(item) to get the correct limit for item +#define MAX_WPN_ENCHANT 5 +#define MAX_ARM_ENCHANT 5 +#define MAX_SEC_ENCHANT 2 + #define NUM_STAVE_ADJ 9 // some shortcuts: diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index 0894207395..b288d1bb85 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -18,6 +18,7 @@ #include "food.h" #include "items.h" #include "itemname.h" +#include "itemprop.h" #include "item_use.h" #include "it_use2.h" #include "message.h" @@ -70,7 +71,7 @@ void stop_delay( void ) you.delay_queue.pop(); break; - case DELAY_MEMORIZE: + case DELAY_MEMORISE: // Losing work here is okay... having to start from // scratch is a reasonable behaviour. -- bwr mpr( "Your memorization is interrupted." ); @@ -196,14 +197,19 @@ void handle_delay( void ) break; case DELAY_ARMOUR_ON: - set_ident_flags( you.inv[ delay.parm1 ], ISFLAG_EQ_ARMOUR_MASK ); + { + set_ident_flags( you.inv[ delay.parm1 ], + ISFLAG_EQ_ARMOUR_MASK ); in_name( delay.parm1, DESC_NOCAP_YOUR, str_pass ); - snprintf( info, INFO_SIZE, "You finish putting on %s.", str_pass ); + snprintf( info, INFO_SIZE, + "You finish putting on %s.", str_pass ); mpr(info); - if (you.inv[ delay.parm1 ].sub_type < ARM_SHIELD - || you.inv[ delay.parm1 ].sub_type > ARM_LARGE_SHIELD) + const equipment_type slot = + get_armour_slot( you.inv[delay.parm1] ); + + if (slot == EQ_BODY_ARMOUR) { you.equip[EQ_BODY_ARMOUR] = delay.parm1; @@ -216,11 +222,9 @@ void handle_delay( void ) } else { - switch (you.inv[ delay.parm1 ].sub_type) + switch (slot) { - case ARM_BUCKLER: - case ARM_LARGE_SHIELD: - case ARM_SHIELD: + case EQ_SHIELD: if (you.duration[DUR_CONDENSATION_SHIELD]) { mpr( "Your icy shield evaporates.", MSGCH_DURATION ); @@ -228,18 +232,20 @@ void handle_delay( void ) } you.equip[EQ_SHIELD] = delay.parm1; break; - case ARM_CLOAK: + case EQ_CLOAK: you.equip[EQ_CLOAK] = delay.parm1; break; - case ARM_HELMET: + case EQ_HELMET: you.equip[EQ_HELMET] = delay.parm1; break; - case ARM_GLOVES: + case EQ_GLOVES: you.equip[EQ_GLOVES] = delay.parm1; break; - case ARM_BOOTS: + case EQ_BOOTS: you.equip[EQ_BOOTS] = delay.parm1; break; + default: + break; } } @@ -336,48 +342,52 @@ void handle_delay( void ) you.redraw_armour_class = 1; you.redraw_evasion = 1; break; - + } case DELAY_ARMOUR_OFF: + { in_name( delay.parm1, DESC_NOCAP_YOUR, str_pass ); snprintf( info, INFO_SIZE, "You finish taking off %s.", str_pass ); mpr(info); - if (you.inv[ delay.parm1 ].sub_type < ARM_SHIELD - || you.inv[ delay.parm1 ].sub_type > ARM_LARGE_SHIELD) + const equipment_type slot = + get_armour_slot( you.inv[delay.parm1] ); + + if (slot == EQ_BODY_ARMOUR) { you.equip[EQ_BODY_ARMOUR] = -1; } else { - switch (you.inv[ delay.parm1 ].sub_type) + switch (slot) { - case ARM_BUCKLER: - case ARM_LARGE_SHIELD: - case ARM_SHIELD: + case EQ_SHIELD: if (delay.parm1 == you.equip[EQ_SHIELD]) you.equip[EQ_SHIELD] = -1; break; - case ARM_CLOAK: + case EQ_CLOAK: if (delay.parm1 == you.equip[EQ_CLOAK]) you.equip[EQ_CLOAK] = -1; break; - case ARM_HELMET: + case EQ_HELMET: if (delay.parm1 == you.equip[EQ_HELMET]) you.equip[EQ_HELMET] = -1; break; - case ARM_GLOVES: + case EQ_GLOVES: if (delay.parm1 == you.equip[EQ_GLOVES]) you.equip[EQ_GLOVES] = -1; break; - case ARM_BOOTS: + case EQ_BOOTS: if (delay.parm1 == you.equip[EQ_BOOTS]) you.equip[EQ_BOOTS] = -1; break; + + default: + break; } } @@ -386,12 +396,12 @@ void handle_delay( void ) you.redraw_armour_class = 1; you.redraw_evasion = 1; break; - + } case DELAY_EAT: mpr( "You finish eating." ); break; - case DELAY_MEMORIZE: + case DELAY_MEMORISE: mpr( "You finish memorising." ); add_spell_to_memory( delay.parm1 ); break; diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 95ea53b45d..8179802ae9 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -33,6 +33,7 @@ #include "debug.h" #include "fight.h" #include "itemname.h" +#include "itemprop.h" #include "macro.h" #include "mon-util.h" #include "player.h" @@ -872,6 +873,12 @@ static std::string describe_weapon( const item_def &item, char verbose) "and a skilled user can use it to great effect. "; break; + case WPN_LONGBOW: + description += "A long, strong bow made of yew. " + "It does excellent damage in combat " + "and a skilled archer can use it to great effect. "; + break; + case WPN_BLOWGUN: description += "A long, light tube, open at both ends. Doing " "very little damage, its main use is to fire poisoned " @@ -926,6 +933,17 @@ static std::string describe_weapon( const item_def &item, char verbose) "single-edged blade. "; break; + case WPN_LAJATANG: + description += "A very rare and extremely effective " + "imported weapon, featuring a pole with half-moon blades " + "at both ends. "; + break; + + case WPN_LOCHABER_AXE: + description += "An enormous combination of a pike " + "and a battle axe."; + break; + case WPN_EXECUTIONERS_AXE: description += "A huge axe. "; break; @@ -993,8 +1011,8 @@ static std::string describe_weapon( const item_def &item, char verbose) description += "A large and heavy mace. "; break; - case WPN_GREAT_FLAIL: - description += "A large and heavy flail. "; + case WPN_DIRE_FLAIL: + description += "A flail with spiked lumps on both ends."; break; case WPN_FALCHION: @@ -1091,7 +1109,16 @@ static std::string describe_weapon( const item_def &item, char verbose) } break; case SPWPN_VORPAL: - description += "It inflicts extra damage upon your enemies. "; + if (launches_things(item.sub_type)) + { + description += "Any "; + description += ammo_name( item ); + description += " fired from it inflicts extra damage."; + } + else + { + description += "It inflicts extra damage upon your enemies. "; + } break; case SPWPN_FLAME: description += "It turns projectiles fired from it into " @@ -1168,14 +1195,14 @@ static std::string describe_weapon( const item_def &item, char verbose) switch (hands_reqd_for_weapon(item.base_type, item.sub_type)) { - case HANDS_ONE_HANDED: + case HANDS_ONE: description += "$It is a one handed weapon."; break; - case HANDS_ONE_OR_TWO_HANDED: + case HANDS_HALF: description += "$It can be used with one hand, or more " "effectively with two (i.e. when not using a shield)."; break; - case HANDS_TWO_HANDED: + case HANDS_TWO: description += "$It is a two handed weapon."; break; } @@ -1220,6 +1247,7 @@ static std::string describe_weapon( const item_def &item, char verbose) description += " 'slings' category. "; break; case WPN_BOW: + case WPN_LONGBOW: description += " 'bows' category. "; break; case WPN_HAND_CROSSBOW: @@ -1294,7 +1322,7 @@ static std::string describe_ammo( const item_def &item ) case MI_LARGE_ROCK: description += "A rock, used by giants as a missile. "; break; - case MI_EGGPLANT: + case MI_NONE: // was eggplant description += "A purple vegetable. " "The presence of this object in the game " "indicates a bug (or some kind of cheating on your part). "; @@ -1407,16 +1435,21 @@ static std::string describe_armour( const item_def &item, char verbose ) case ARM_GLOVES: description += "A pair of gloves. "; break; + + case ARM_CENTAUR_BARDING: + description += "An armour made for centaurs, " + "to wear over their equine half."; + break; + + case ARM_NAGA_BARDING: + description += "A special armour made for nagas, " + "to wear over their tails."; + break; + case ARM_BOOTS: - if (item.plus2 == TBOOT_NAGA_BARDING) - description += "A special armour made for Nagas, " - "to wear over their tails. "; - else if (item.plus2 == TBOOT_CENTAUR_BARDING) - description += "An armour made for centaurs, " - "to wear over their equine half. "; - else - description += "A pair of sturdy boots. "; + description += "A pair of boots."; break; + case ARM_BUCKLER: description += "A small shield. "; break; @@ -1561,7 +1594,8 @@ static std::string describe_armour( const item_def &item, char verbose ) // caps and wizard hats don't have a base AC append_value(description, 0, false); } - else if (item.sub_type == ARM_BOOTS && item.plus2 != TBOOT_BOOTS) + else if (item.sub_type == ARM_NAGA_BARDING + || item.sub_type == ARM_CENTAUR_BARDING) { // Barding has AC value 4. append_value(description, 4, false); @@ -2441,7 +2475,7 @@ static std::string describe_jewellery( const item_def &item, char verbose) else if ((!is_random_artefact( item ) && get_ident_type( OBJ_JEWELLERY, item.sub_type ) != ID_KNOWN_TYPE) || (is_random_artefact( item ) - && item_not_ident( item, ISFLAG_KNOW_TYPE ))) + && !item_ident( item, ISFLAG_KNOW_TYPE ))) { description += "A piece of jewellery."; } @@ -3248,7 +3282,7 @@ std::string get_item_description( const item_def &item, char verbose, bool dump { description += "$It weighs around "; - const int mass = mass_item( item ); + const int mass = item_mass( item ); char item_mass[16]; itoa( mass / 10, item_mass, 10 ); @@ -4333,14 +4367,6 @@ void describe_spell(int spelled) "corporeal undead. "; break; - case SPELL_SHUGGOTH_SEED: - description += "implants a shuggoth seed, the larval parasitic form " - "of the fearsome shuggoth, in a living host. The " - "shuggoth seed will draw life from its host and then " - "hatch, whereupon a fully grown shuggoth will burst " - "from the unfortunate host's chest. "; - break; - case SPELL_MAXWELLS_SILVER_HAMMER: description += "bestows a lethal but temporary gravitic field " "to a crushing implement held by the caster. " @@ -5819,6 +5845,44 @@ void describe_monsters(int class_described, unsigned char which_mons) "A small and slimy eel, crackling with electrical discharge."; break; + case MONS_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_YELLOW_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_DRACONIAN_SHIFTER: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_KNIGHT: + { + description += "A "; + + const int subsp = draco_subspecies( &menv[which_mons] ); + switch (subsp) + { + case MONS_DRACONIAN: description += "brown "; break; + case MONS_BLACK_DRACONIAN: description += "black "; break; + case MONS_MOTTLED_DRACONIAN: description += "mottled "; break; + case MONS_YELLOW_DRACONIAN: description += "yellow "; break; + case MONS_GREEN_DRACONIAN: description += "green "; break; + case MONS_PURPLE_DRACONIAN: description += "purple "; break; + case MONS_RED_DRACONIAN: description += "red "; break; + case MONS_WHITE_DRACONIAN: description += "white "; break; + case MONS_PALE_DRACONIAN: description += "pale "; break; + default: + break; + } + + description += "scaled humanoid with wings."; + break; + } case MONS_PLAYER_GHOST: description += "The apparition of "; description += ghost_description(); @@ -6576,7 +6640,7 @@ void describe_god( int which_god, bool give_title ) print_god_abil_desc( ABIL_TSO_ANNIHILATE_UNDEAD ); if (you.piety >= 100) - print_god_abil_desc( ABIL_TSO_THUNDERBOLT ); + print_god_abil_desc( ABIL_TSO_CLEANSING_FLAME ); if (you.piety >= 120) print_god_abil_desc( ABIL_TSO_SUMMON_DAEVA ); diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc index ad12091c91..753adf3207 100644 --- a/crawl-ref/source/direct.cc +++ b/crawl-ref/source/direct.cc @@ -1107,8 +1107,6 @@ std::string feature_description(int mx, int my) return ("A stone staircase leading up."); case DNGN_ENTER_HELL: return ("A gateway to hell."); - case DNGN_BRANCH_STAIRS: - return ("A staircase to a branch level."); case DNGN_TRAP_MECHANICAL: case DNGN_TRAP_MAGICAL: case DNGN_TRAP_III: diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index eaeed683ff..36bf032e42 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -36,8 +36,10 @@ #include "externs.h" #include "dungeon.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "maps.h" +#include "misc.h" #include "mon-util.h" #include "mon-pick.h" #include "monplace.h" @@ -47,6 +49,13 @@ #include "stuff.h" #include "wpn-misc.h" +#define MAX_PIT_MONSTERS 10 + +struct pit_mons_def { + int type; + int rare; +}; + struct spec_t { bool created; bool hooked_up; @@ -121,7 +130,7 @@ static unsigned char item_in_shop(unsigned char shop_type); static bool treasure_area(int level_number, unsigned char ta1_x, unsigned char ta2_x, unsigned char ta1_y, unsigned char ta2_y); -static char rare_weapon(unsigned char w_type); +static int rare_weapon(int w_type); static bool is_weapon_special(int the_weapon); static void set_weapon_special(int the_weapon, int spwpn); static void big_room(int level_number); @@ -134,6 +143,7 @@ static void morgue(spec_room &sr); static void special_room(int level_number, spec_room &sr); static void specr_2(spec_room &sr); static void beehive(spec_room &sr); +static void jelly_pit(int level_number, spec_room &sr); // VAULT FUNCTIONS static void build_vaults(int level_number, int force_vault); @@ -550,9 +560,10 @@ int items( int allow_uniques, // not just true-false, // this replaced the infinite loop (wasteful) -- may need // to make into its own function to allow ease of tweaking // distribution {dlb}: - temp_rand = random2(9); + temp_rand = random2(10); - mitm[p].sub_type = ((temp_rand == 8) ? WPN_DEMON_BLADE : + mitm[p].sub_type = ((temp_rand == 9) ? WPN_LAJATANG : + (temp_rand == 8) ? WPN_DEMON_BLADE : (temp_rand == 7) ? WPN_DEMON_TRIDENT : (temp_rand == 6) ? WPN_DEMON_WHIP : (temp_rand == 5) ? WPN_DOUBLE_SWORD : @@ -669,7 +680,7 @@ int items( int allow_uniques, // not just true-false, case WPN_FLAIL: case WPN_SPIKED_FLAIL: case WPN_GREAT_MACE: - case WPN_GREAT_FLAIL: + case WPN_DIRE_FLAIL: if (one_chance_in(6)) set_equip_race( mitm[p], ISFLAG_ELVEN ); if (one_chance_in(4)) @@ -751,6 +762,7 @@ int items( int allow_uniques, // not just true-false, case WPN_HALBERD: case WPN_GLAIVE: case WPN_EXECUTIONERS_AXE: + case WPN_LOCHABER_AXE: if (one_chance_in(5)) set_equip_race( mitm[p], ISFLAG_ORCISH ); break; @@ -761,6 +773,7 @@ int items( int allow_uniques, // not just true-false, break; case WPN_KATANA: + case WPN_LAJATANG: case WPN_KNIFE: case WPN_SLING: set_equip_race( mitm[p], ISFLAG_NO_RACE ); @@ -774,6 +787,11 @@ int items( int allow_uniques, // not just true-false, set_equip_race( mitm[p], ISFLAG_ELVEN ); break; + case WPN_LONGBOW: + set_equip_race( mitm[p], one_chance_in(3) ? ISFLAG_ELVEN + : ISFLAG_NO_RACE ); + break; + case WPN_CROSSBOW: if (one_chance_in(4)) set_equip_race( mitm[p], ISFLAG_ORCISH ); @@ -815,7 +833,7 @@ int items( int allow_uniques, // not just true-false, // there's a good chance that we'll just strip them of // their ego type at the bottom of this function. -- bwr if (item_level == MAKE_GOOD_ITEM - && cmp_equip_race( mitm[p], ISFLAG_ORCISH )) + && get_equip_race( mitm[p] ) == ISFLAG_ORCISH) { set_equip_race( mitm[p], ISFLAG_NO_RACE ); } @@ -891,7 +909,7 @@ int items( int allow_uniques, // not just true-false, // **** intentional fall through here **** case WPN_FLAIL: case WPN_SPIKED_FLAIL: - case WPN_GREAT_FLAIL: + case WPN_DIRE_FLAIL: case WPN_HAMMER: if (one_chance_in(25)) set_weapon_special(p, SPWPN_PAIN); @@ -1076,14 +1094,15 @@ int items( int allow_uniques, // not just true-false, case WPN_HALBERD: case WPN_GLAIVE: + case WPN_SCYTHE: + case WPN_TRIDENT: + case WPN_LOCHABER_AXE: if (one_chance_in(30)) set_weapon_special(p, SPWPN_HOLY_WRATH); if (one_chance_in(4)) set_weapon_special(p, SPWPN_PROTECTION); // **** intentional fall through here **** - case WPN_SCYTHE: - case WPN_TRIDENT: if (one_chance_in(5)) set_weapon_special(p, SPWPN_SPEED); // **** intentional fall through here **** @@ -1124,18 +1143,18 @@ int items( int allow_uniques, // not just true-false, break; // **** possible intentional fall through here **** case WPN_BOW: + case WPN_LONGBOW: case WPN_CROSSBOW: - if (one_chance_in(30)) - set_weapon_special( p, SPWPN_SPEED ); - - if (one_chance_in(5)) - set_weapon_special( p, SPWPN_PROTECTION ); + { + const int tmp = random2(1000); - if (coinflip()) - set_weapon_special(p, (coinflip() ? SPWPN_FLAME - : SPWPN_FROST)); + set_weapon_special( p, (tmp < 375) ? SPWPN_FLAMING : + (tmp < 750) ? SPWPN_FREEZING : + (tmp < 920) ? SPWPN_PROTECTION : + (tmp < 980) ? SPWPN_VORPAL + : SPWPN_SPEED ); break; - + } case WPN_BLOWGUN: if (one_chance_in(7)) set_weapon_special(p, SPWPN_VENOM); @@ -1253,7 +1272,7 @@ int items( int allow_uniques, // not just true-false, } // value was "0" comment said "orc" so I went with comment {dlb} - if (cmp_equip_race( mitm[p], ISFLAG_ORCISH )) + if (get_equip_race(mitm[p]) == ISFLAG_ORCISH) { // no holy wrath or slay orc and 1/2 the time no-ego const int brand = get_weapon_brand( mitm[p] ); @@ -1279,8 +1298,8 @@ int items( int allow_uniques, // not just true-false, && mitm[p].sub_type != WPN_CLUB && mitm[p].sub_type != WPN_GIANT_CLUB && mitm[p].sub_type != WPN_GIANT_SPIKED_CLUB - && cmp_equip_desc( mitm[p], 0 ) - && cmp_equip_race( mitm[p], 0 )) + && get_equip_desc(mitm[p]) == 0 + && get_equip_race(mitm[p]) == 0) { set_equip_desc( mitm[p], (coinflip() ? ISFLAG_GLOWING : ISFLAG_RUNED) ); @@ -1395,7 +1414,7 @@ int items( int allow_uniques, // not just true-false, // orcish ammo gets poisoned a lot more often -- in the original // code it was poisoned every time!? - if (cmp_equip_race( mitm[p], ISFLAG_ORCISH ) && one_chance_in(3)) + if (get_equip_race(mitm[p]) == ISFLAG_ORCISH && one_chance_in(3)) set_item_ego_type( mitm[p], OBJ_MISSILES, SPMSL_POISONED_II ); // reduced quantity if special @@ -1408,9 +1427,9 @@ int items( int allow_uniques, // not just true-false, mitm[p].plus += random2(5); // elven arrows and dwarven bolts are quality items - if ((cmp_equip_race( mitm[p], ISFLAG_ELVEN ) + if ((get_equip_race(mitm[p]) == ISFLAG_ELVEN && mitm[p].sub_type == MI_ARROW) - || (cmp_equip_race( mitm[p], ISFLAG_DWARVEN ) + || (get_equip_race(mitm[p]) == ISFLAG_DWARVEN && mitm[p].sub_type == MI_BOLT)) { mitm[p].plus += random2(3); @@ -1496,17 +1515,18 @@ int items( int allow_uniques, // not just true-false, } } - hide2armour( &(mitm[p].sub_type) ); + hide2armour(mitm[p]); // mitm[p].special = SPARM_RANDART_II + random2(4); make_item_randart( mitm[p] ); mitm[p].plus = 0; - if (mitm[p].sub_type == ARM_BOOTS) + if (mitm[p].sub_type == ARM_BOOTS + && one_chance_in(10)) { - mitm[p].plus2 = TBOOT_BOOTS; - if (one_chance_in(10)) - mitm[p].plus2 = random2( NUM_BOOT_TYPES ); + mitm[p].sub_type = + coinflip()? ARM_NAGA_BARDING + : ARM_CENTAUR_BARDING; } mitm[p].plus += random2(4); @@ -1560,17 +1580,22 @@ int items( int allow_uniques, // not just true-false, set_equip_race( mitm[p], ISFLAG_ELVEN ); break; + case ARM_NAGA_BARDING: + case ARM_CENTAUR_BARDING: case ARM_BOOTS: - if (one_chance_in(4)) + if (mitm[p].sub_type == ARM_BOOTS) { - mitm[p].plus2 = TBOOT_NAGA_BARDING; - break; - } + if (one_chance_in(4)) + { + mitm[p].sub_type = ARM_NAGA_BARDING; + break; + } - if (one_chance_in(4)) - { - mitm[p].plus2 = TBOOT_CENTAUR_BARDING; - break; + if (one_chance_in(4)) + { + mitm[p].sub_type = ARM_CENTAUR_BARDING; + break; + } } if (one_chance_in(4)) @@ -1582,8 +1607,8 @@ int items( int allow_uniques, // not just true-false, break; case ARM_HELMET: - if (cmp_helmet_type( mitm[p], THELM_CAP ) - || cmp_helmet_type( mitm[p], THELM_WIZARD_HAT )) + if (get_helmet_type(mitm[p]) == THELM_CAP + || get_helmet_type(mitm[p]) == THELM_WIZARD_HAT) { if (one_chance_in(6)) set_equip_race( mitm[p], ISFLAG_ELVEN ); @@ -1642,7 +1667,7 @@ int items( int allow_uniques, // not just true-false, if (50 + item_level >= random2(250) || item_level == MAKE_GOOD_ITEM || (mitm[p].sub_type == ARM_HELMET - && cmp_helmet_type( mitm[p], THELM_WIZARD_HAT ))) + && get_helmet_type(mitm[p]) == THELM_WIZARD_HAT)) { mitm[p].plus += random2(3); @@ -1651,7 +1676,7 @@ int items( int allow_uniques, // not just true-false, if (30 + item_level >= random2(350) && (item_level == MAKE_GOOD_ITEM - || (!cmp_equip_race( mitm[p], ISFLAG_ORCISH ) + || (!get_equip_race(mitm[p]) == ISFLAG_ORCISH || (mitm[p].sub_type <= ARM_PLATE_MAIL && coinflip())))) { switch (mitm[p].sub_type) @@ -1673,7 +1698,7 @@ int items( int allow_uniques, // not just true-false, //break; } case ARM_CLOAK: - if (cmp_equip_race( mitm[p], ISFLAG_DWARVEN )) + if (get_equip_race(mitm[p]) == ISFLAG_DWARVEN) break; switch (random2(4)) @@ -1699,7 +1724,7 @@ int items( int allow_uniques, // not just true-false, break; case ARM_HELMET: - if (cmp_helmet_type(mitm[p],THELM_WIZARD_HAT) && coinflip()) + if (get_helmet_type(mitm[p]) == THELM_WIZARD_HAT && coinflip()) { if (one_chance_in(3)) { @@ -1727,20 +1752,20 @@ int items( int allow_uniques, // not just true-false, break; case ARM_BOOTS: - switch (random2(3)) - { - case 0: - if (mitm[p].plus2 == TBOOT_BOOTS) - set_item_ego_type(mitm[p], OBJ_ARMOUR, SPARM_RUNNING); - break; - case 1: - set_item_ego_type(mitm[p], OBJ_ARMOUR, SPARM_LEVITATION); - break; - case 2: - set_item_ego_type(mitm[p], OBJ_ARMOUR, SPARM_STEALTH); - break; - } + case ARM_NAGA_BARDING: + case ARM_CENTAUR_BARDING: + { + const int tmp = random2(600) + + 200 * (mitm[p].sub_type != ARM_BOOTS); + + set_item_ego_type( mitm[p], OBJ_ARMOUR, + (tmp < 200) ? SPARM_RUNNING : + (tmp < 400) ? SPARM_LEVITATION : + (tmp < 600) ? SPARM_STEALTH : + (tmp < 700) ? SPARM_COLD_RESISTANCE + : SPARM_FIRE_RESISTANCE ); break; + } case ARM_ROBE: switch (random2(4)) @@ -1821,8 +1846,8 @@ int items( int allow_uniques, // not just true-false, } // if not given a racial type, and special, give shiny/runed/etc desc. - if (cmp_equip_race( mitm[p], 0 ) - && cmp_equip_desc( mitm[p], 0 ) + if (get_equip_race(mitm[p]) == 0 + && get_equip_desc(mitm[p]) == 0 && (((is_random_artefact(mitm[p]) || get_armour_ego_type( mitm[p] ) != SPARM_NORMAL) && !one_chance_in(10)) @@ -1849,7 +1874,7 @@ int items( int allow_uniques, // not just true-false, // would be an enchanted item which somehow didn't get converted // into armour). if (item_level == MAKE_GOOD_ITEM) - hide2armour( &(mitm[p].sub_type) ); // what of animal hides? {dlb} + hide2armour(mitm[p]); // what of animal hides? {dlb} // skin armours + Crystal PM don't get special enchantments // or species, but can be randarts @@ -1942,7 +1967,7 @@ int items( int allow_uniques, // not just true-false, for (count = 0; count < 1000; count++) { temp_rand = random2( NUM_MONSTERS ); // random monster - temp_rand = mons_charclass( temp_rand ); // corpse base type + temp_rand = mons_species( temp_rand ); // corpse base type if (mons_weight( temp_rand ) > 0) // drops a corpse break; @@ -2692,9 +2717,9 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes } // deliberate fall through {gdl} case MONS_ORC_PRIEST: - item_race = MAKE_ITEM_ORCISH; - // deliberate fall through {dlb} case MONS_TERENCE: + case MONS_DRACONIAN: + case MONS_DRACONIAN_ZEALOT: if (!one_chance_in(5)) { mitm[bp].base_type = OBJ_WEAPONS; @@ -2727,13 +2752,14 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes item_race = MAKE_ITEM_ELVEN; mitm[bp].base_type = OBJ_WEAPONS; - temp_rand = random2(8); - mitm[bp].sub_type = ((temp_rand > 5) ? WPN_LONG_SWORD : // 2 in 8 - (temp_rand > 3) ? WPN_SHORT_SWORD : // 2 in 8 - (temp_rand > 2) ? WPN_SCIMITAR : // 1 in 8 - (temp_rand > 1) ? WPN_MACE : // 1 in 8 - (temp_rand > 0) ? WPN_BOW // 1 in 8 - : WPN_HAND_CROSSBOW); // 1 in 8 + temp_rand = random2(100); + mitm[bp].sub_type = ((temp_rand > 80) ? WPN_LONG_SWORD : // 20% + (temp_rand > 60) ? WPN_SHORT_SWORD : // 20% + (temp_rand > 48) ? WPN_SCIMITAR : // 12% + (temp_rand > 36) ? WPN_MACE : // 12% + (temp_rand > 24) ? WPN_BOW : // 12% + (temp_rand > 12) ? WPN_LONGBOW // 12% + : WPN_HAND_CROSSBOW); // 12% break; case MONS_DEEP_ELF_ANNIHILATOR: @@ -2743,6 +2769,10 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes case MONS_DEEP_ELF_MAGE: case MONS_DEEP_ELF_SORCERER: case MONS_DEEP_ELF_SUMMONER: + case MONS_DRACONIAN_SHIFTER: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_CALLER: item_race = MAKE_ITEM_ELVEN; mitm[bp].base_type = OBJ_WEAPONS; @@ -2771,6 +2801,14 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes case MONS_RUPERT: case MONS_SKELETAL_WARRIOR: case MONS_WAYNE: + case MONS_PALE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_YELLOW_DRACONIAN: + case MONS_PURPLE_DRACONIAN: mitm[bp].base_type = OBJ_WEAPONS; temp_rand = random2(120); @@ -2803,18 +2841,20 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes case MONS_URUG: case MONS_VAULT_GUARD: case MONS_VAMPIRE_KNIGHT: + case MONS_DRACONIAN_KNIGHT: mitm[bp].base_type = OBJ_WEAPONS; - temp_rand = random2(24); - mitm[bp].sub_type = ((temp_rand > 19) ? WPN_GREAT_SWORD :// 16.67% - (temp_rand > 15) ? WPN_LONG_SWORD : // 16.67% - (temp_rand > 11) ? WPN_BATTLEAXE : // 16.67% - (temp_rand > 7) ? WPN_WAR_AXE : // 16.67% - (temp_rand > 5) ? WPN_GREAT_MACE : // 8.33% - (temp_rand > 3) ? WPN_GREAT_FLAIL :// 8.33% - (temp_rand > 1) ? WPN_GLAIVE : // 8.33% - (temp_rand > 0) ? WPN_BROAD_AXE // 4.17% - : WPN_HALBERD); // 4.17% + temp_rand = random2(25); + mitm[bp].sub_type = ((temp_rand > 20) ? WPN_GREAT_SWORD : // 16% + (temp_rand > 16) ? WPN_LONG_SWORD : // 16% + (temp_rand > 12) ? WPN_BATTLEAXE : // 16% + (temp_rand > 8) ? WPN_WAR_AXE : // 16% + (temp_rand > 5) ? WPN_GREAT_MACE : // 12% + (temp_rand > 3) ? WPN_DIRE_FLAIL : // 8% + (temp_rand > 2) ? WPN_LOCHABER_AXE : // 4% + (temp_rand > 1) ? WPN_GLAIVE : // 4% + (temp_rand > 0) ? WPN_BROAD_AXE // 4% + : WPN_HALBERD); // 4% if (one_chance_in(4)) mitm[bp].plus += 1 + random2(3); @@ -2841,7 +2881,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes if (one_chance_in(10) || menv[mid].type == MONS_ETTIN) { - mitm[bp].sub_type = ((one_chance_in(10)) ? WPN_GREAT_FLAIL + mitm[bp].sub_type = ((one_chance_in(10)) ? WPN_DIRE_FLAIL : WPN_GREAT_MACE); } break; @@ -2883,7 +2923,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes if (one_chance_in(10)) { - mitm[bp].sub_type = (one_chance_in(10) ? WPN_GREAT_FLAIL + mitm[bp].sub_type = (one_chance_in(10) ? WPN_DIRE_FLAIL : WPN_GREAT_MACE); } break; @@ -2893,6 +2933,9 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes item_race = MAKE_ITEM_NO_RACE; mitm[bp].base_type = OBJ_WEAPONS; mitm[bp].sub_type = WPN_BOW; + if (menv[mid].type == MONS_CENTAUR_WARRIOR + && one_chance_in(5)) + mitm[bp].sub_type = WPN_LONGBOW; break; case MONS_YAKTAUR: @@ -3314,6 +3357,22 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes case MONS_JESSICA: case MONS_KOBOLD_DEMONOLOGIST: case MONS_OGRE_MAGE: + case MONS_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_YELLOW_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_DRACONIAN_SHIFTER: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_KNIGHT: case MONS_ORC_WIZARD: case MONS_WIZARD: item_race = MAKE_ITEM_NO_RACE; @@ -3414,16 +3473,16 @@ static void check_doors(void) solid_count = 0; // first half of each conditional represents bounds checking {dlb}: - if (grd[x - 1][y] < DNGN_LAST_SOLID_TILE) + if (grid_is_solid( grd[x - 1][y] )) solid_count++; - if (grd[x + 1][y] < DNGN_LAST_SOLID_TILE) + if (grid_is_solid( grd[x + 1][y] )) solid_count++; - if (grd[x][y - 1] < DNGN_LAST_SOLID_TILE) + if (grid_is_solid( grd[x][y - 1] )) solid_count++; - if (grd[x][y + 1] < DNGN_LAST_SOLID_TILE) + if (grid_is_solid( grd[x][y + 1] )) solid_count++; grd[x][y] = ((solid_count < 2) ? DNGN_FLOOR : DNGN_CLOSED_DOOR); @@ -4086,31 +4145,38 @@ static void place_traps(int level_number) } while (grd[env.trap[i].x][env.trap[i].y] != DNGN_FLOOR); - env.trap[i].type = TRAP_DART; + unsigned char &trap_type = env.trap[i].type; + trap_type = TRAP_DART; if ((random2(1 + level_number) > 1) && one_chance_in(4)) - env.trap[i].type = TRAP_NEEDLE; - if (random2(1 + level_number) > 2) - env.trap[i].type = TRAP_ARROW; + trap_type = TRAP_NEEDLE; if (random2(1 + level_number) > 3) - env.trap[i].type = TRAP_SPEAR; + trap_type = TRAP_SPEAR; if (random2(1 + level_number) > 5) - env.trap[i].type = TRAP_AXE; + trap_type = TRAP_AXE; + + // Note we're boosting arrow trap numbers by moving it + // down the list, and making spear and axe traps rarer. + if (trap_type == TRAP_DART? + random2(1 + level_number) > 2 + : one_chance_in(7)) + trap_type = TRAP_ARROW; + if (random2(1 + level_number) > 7) - env.trap[i].type = TRAP_BOLT; + trap_type = TRAP_BOLT; if (random2(1 + level_number) > 11) - env.trap[i].type = TRAP_BLADE; + trap_type = TRAP_BLADE; if ((random2(1 + level_number) > 14 && one_chance_in(3)) || (player_in_branch( BRANCH_HALL_OF_ZOT ) && coinflip())) { - env.trap[i].type = TRAP_ZOT; + trap_type = TRAP_ZOT; } if (one_chance_in(20)) - env.trap[i].type = TRAP_TELEPORT; + trap_type = TRAP_TELEPORT; if (one_chance_in(40)) - env.trap[i].type = TRAP_AMNESIA; + trap_type = TRAP_AMNESIA; grd[env.trap[i].x][env.trap[i].y] = DNGN_UNDISCOVERED_TRAP; } // end "for i" @@ -4383,7 +4449,7 @@ static void make_trail(int xs, int xr, int ys, int yr, int corrlength, static int good_door_spot(int x, int y) { - if ((grd[x][y] > DNGN_WATER_X && grd[x][y] < DNGN_ENTER_PANDEMONIUM) + if ((!grid_is_solid(grd[x][y]) && grd[x][y] < DNGN_ENTER_PANDEMONIUM) || grd[x][y] == DNGN_CLOSED_DOOR) { return 1; @@ -4444,8 +4510,8 @@ static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel) { // left side if (grd[sx-1][ry] == DNGN_FLOOR - && grd[sx-1][ry-1] < DNGN_LAST_SOLID_TILE - && grd[sx-1][ry+1] < DNGN_LAST_SOLID_TILE) + && grid_is_solid(grd[sx-1][ry-1]) + && grid_is_solid(grd[sx-1][ry+1])) { if (random2(10) < doorlevel) grd[sx-1][ry] = DNGN_CLOSED_DOOR; @@ -4453,8 +4519,8 @@ static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel) // right side if (grd[ex+1][ry] == DNGN_FLOOR - && grd[ex+1][ry-1] < DNGN_LAST_SOLID_TILE - && grd[ex+1][ry+1] < DNGN_LAST_SOLID_TILE) + && grid_is_solid(grd[ex+1][ry-1]) + && grid_is_solid(grd[ex+1][ry+1])) { if (random2(10) < doorlevel) grd[ex+1][ry] = DNGN_CLOSED_DOOR; @@ -4466,8 +4532,8 @@ static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel) { // top if (grd[rx][sy-1] == DNGN_FLOOR - && grd[rx-1][sy-1] < DNGN_LAST_SOLID_TILE - && grd[rx+1][sy-1] < DNGN_LAST_SOLID_TILE) + && grid_is_solid(grd[rx-1][sy-1]) + && grid_is_solid(grd[rx+1][sy-1])) { if (random2(10) < doorlevel) grd[rx][sy-1] = DNGN_CLOSED_DOOR; @@ -4475,8 +4541,8 @@ static bool make_room(int sx,int sy,int ex,int ey,int max_doors, int doorlevel) // bottom if (grd[rx][ey+1] == DNGN_FLOOR - && grd[rx-1][ey+1] < DNGN_LAST_SOLID_TILE - && grd[rx+1][ey+1] < DNGN_LAST_SOLID_TILE) + && grid_is_solid(grd[rx-1][ey+1]) + && grid_is_solid(grd[rx+1][ey+1])) { if (random2(10) < doorlevel) grd[rx][ey+1] = DNGN_CLOSED_DOOR; @@ -4808,6 +4874,79 @@ static void specr_2(spec_room &sr) sr.hooked_up = true; } // end specr_2() +// Fill special room sr with monsters from the pit_list at density%... +// then place a "lord of the pit" of lord_type at (lordx, lordy). +static void fill_monster_pit( spec_room &sr, + FixedVector<pit_mons_def, MAX_PIT_MONSTERS> &pit_list, + int density, int lord_type, int lordx, int lordy ) +{ + int i, x, y; + + // make distribution cumulative + for (i = 1; i < MAX_PIT_MONSTERS; i++) + { + // assuming that the first zero rarity is the end of the list: + if (!pit_list[i].rare) + break; + + pit_list[i].rare = pit_list[i].rare + pit_list[i - 1].rare; + } + + const int num_types = i; + const int rare_sum = pit_list[num_types - 1].rare; + + // calculate die_size, factoring in the density% of the pit + const int die_size = (rare_sum * 100) / density; + +#if DEBUG_DIAGNOSTICS + for (i = 0; i < num_types; i++) + { + char buff[ ITEMNAME_SIZE ]; + + const int delta = ((i > 0) ? pit_list[i].rare - pit_list[i - 1].rare + : pit_list[i].rare); + + const float perc = (static_cast<float>( delta ) * 100.0) + / static_cast<float>( rare_sum ); + + mprf( MSGCH_DIAGNOSTICS, "%6.2f%%: %s", perc, + moname( pit_list[i].type, true, DESC_PLAIN, buff ) ); + } +#endif + + // put the boss monster down + if (lord_type != MONS_PROGRAM_BUG) + mons_place( lord_type, BEH_SLEEP, MHITNOT, true, lordx, lordy ); + + // place monsters and give them items {dlb}: + for (x = sr.x1; x <= sr.x2; x++) + { + for (y = sr.y1; y <= sr.y2; y++) + { + // avoid the boss (or anyone else we may have dropped already) + if (mgrd[x][y] != NON_MONSTER) + continue; + + const int roll = random2( die_size ); + + // density skip (no need to iterate) + if (roll >= rare_sum) + continue; + + // run throught the cumulative chances and place a monster + for (i = 0; i < num_types; i++) + { + if (roll < pit_list[i].rare) + { + mons_place( pit_list[i].type, BEH_SLEEP, MHITNOT, + true, x, y ); + break; + } + } + } + } +} + static void special_room(int level_number, spec_room &sr) { char spec_room_type = SROOM_LAIR_KOBOLD; @@ -4860,8 +4999,12 @@ static void special_room(int level_number, spec_room &sr) if (level_number > 19 && coinflip()) spec_room_type = SROOM_MORGUE; - } + if (level_number > 13 + && one_chance_in(level_number > 23? 4 : + level_number > 18? 5 : 6)) + spec_room_type = SROOM_JELLY_PIT; + } switch (spec_room_type) { @@ -5008,6 +5151,10 @@ static void special_room(int level_number, spec_room &sr) case SROOM_MORGUE: morgue(sr); break; + + case SROOM_JELLY_PIT: + jelly_pit(level_number, sr); + break; } } // end special_room() @@ -5859,7 +6006,7 @@ void item_colour( item_def &item ) break; default: item.colour = LIGHTCYAN; - if (cmp_equip_race( item, ISFLAG_DWARVEN )) + if (get_equip_race(item) == ISFLAG_DWARVEN) item.colour = CYAN; break; } @@ -5883,7 +6030,7 @@ void item_colour( item_def &item ) break; default: item.colour = LIGHTCYAN; - if (cmp_equip_race( item, ISFLAG_DWARVEN )) + if (get_equip_race(item) == ISFLAG_DWARVEN) item.colour = CYAN; break; } @@ -5897,13 +6044,16 @@ void item_colour( item_def &item ) { case ARM_CLOAK: case ARM_ROBE: + case ARM_NAGA_BARDING: + case ARM_CENTAUR_BARDING: + case ARM_CAP: item.colour = random_colour(); break; case ARM_HELMET: //caps and wizard's hats are random coloured - if (cmp_helmet_type( item, THELM_CAP ) - || cmp_helmet_type( item, THELM_WIZARD_HAT )) + if (get_helmet_type(item) == THELM_CAP + || get_helmet_type(item) == THELM_WIZARD_HAT) { item.colour = random_colour(); } @@ -5956,7 +6106,7 @@ void item_colour( item_def &item ) break; default: item.colour = LIGHTCYAN; - if (cmp_equip_race( item, ISFLAG_DWARVEN )) + if (get_equip_race(item) == ISFLAG_DWARVEN) item.colour = CYAN; break; } @@ -6345,74 +6495,13 @@ void item_colour( item_def &item ) // Checks how rare a weapon is. Many of these have special routines for // placement, especially those with a rarity of zero. Chance is out of 10. -static char rare_weapon(unsigned char w_type) +static int rare_weapon(int w_type) { - // zero value weapons must be placed specially -- see items() {dlb} if (is_demonic(w_type)) return 0; - switch (w_type) - { - case WPN_CLUB: - case WPN_DAGGER: - return 10; - case WPN_HAND_AXE: - case WPN_FALCHION: - case WPN_MACE: - case WPN_QUARTERSTAFF: - return 9; - case WPN_BOW: - case WPN_FLAIL: - case WPN_HAMMER: - case WPN_SABRE: - case WPN_SHORT_SWORD: - case WPN_SLING: - case WPN_SPEAR: - return 8; - case WPN_LONG_SWORD: - case WPN_MORNINGSTAR: - case WPN_WAR_AXE: - return 7; - case WPN_BATTLEAXE: - case WPN_CROSSBOW: - case WPN_GREAT_SWORD: - case WPN_SCIMITAR: - case WPN_TRIDENT: - return 6; - case WPN_GLAIVE: - case WPN_HALBERD: - case WPN_BLOWGUN: - return 5; - case WPN_BROAD_AXE: - case WPN_HAND_CROSSBOW: - case WPN_SPIKED_FLAIL: - case WPN_WHIP: - return 4; - case WPN_GREAT_MACE: - return 3; - case WPN_ANCUS: - case WPN_GREAT_FLAIL: - case WPN_SCYTHE: - return 2; - case WPN_GIANT_CLUB: - case WPN_GIANT_SPIKED_CLUB: - return 1; - // zero value weapons must be placed specially -- see items() {dlb} - case WPN_DOUBLE_SWORD: - case WPN_EVENINGSTAR: - case WPN_EXECUTIONERS_AXE: - case WPN_KATANA: - case WPN_KNIFE: - case WPN_QUICK_BLADE: - case WPN_TRIPLE_SWORD: - case WPN_BLESSED_BLADE: - return 0; - - default: - // should not happen now that calls are bounded by NUM_WEAPONS {dlb} - return -1; - } + return (weapon_rarity(w_type)); } // end rare_weapon() //jmf: generate altar based on where you are, or possibly randomly @@ -7320,11 +7409,8 @@ static bool octa_room(spec_room &sr, int oblique_max, unsigned char type_floor) if (grd[x][y] == DNGN_FLOOR && type_floor == DNGN_SHALLOW_WATER) grd[x][y] = DNGN_SHALLOW_WATER; - if (type_floor >= DNGN_LAST_SOLID_TILE - && grd[x][y] == DNGN_CLOSED_DOOR) - { + if (grd[x][y] == DNGN_CLOSED_DOOR && type_floor >= MINMOVE) grd[x][y] = DNGN_FLOOR; // ick - } } if (oblique > 0) @@ -8179,6 +8265,48 @@ static void morgue(spec_room &sr) } } // end morgue() +static void jelly_pit(int level_number, spec_room &sr) +{ + FixedVector< pit_mons_def, MAX_PIT_MONSTERS > pit_list; + const int lordx = sr.x1 + random2(sr.x2 - sr.x1); + const int lordy = sr.y1 + random2(sr.y2 - sr.y1); + + for (int i = 0; i < MAX_PIT_MONSTERS; i++) + { + pit_list[i].type = MONS_PROGRAM_BUG; + pit_list[i].rare = 0; + } + +#if DEBUG_DIAGNOSTICS + mprf( MSGCH_DIAGNOSTICS, "Build: Jelly Pit" ); +#endif + pit_list[0].type = MONS_OOZE; + pit_list[0].rare = 27 - level_number / 5; + + pit_list[1].type = MONS_JELLY; + pit_list[1].rare = 20; + + pit_list[2].type = MONS_BROWN_OOZE; + pit_list[2].rare = 3 + level_number; + + pit_list[3].type = MONS_DEATH_OOZE; + pit_list[3].rare = 2 + (2 * level_number) / 3; + + if (level_number >= 12) + { + pit_list[4].type = MONS_AZURE_JELLY; + pit_list[4].rare = 1 + (level_number - 12) / 3; + } + + if (level_number >= 15) + { + pit_list[5].type = MONS_ACID_BLOB; + pit_list[5].rare = 1 + (level_number - 15) / 4; + } + + fill_monster_pit( sr, pit_list, 90, MONS_PROGRAM_BUG, lordx, lordy ); +} + static bool place_specific_trap(unsigned char spec_x, unsigned char spec_y, unsigned char spec_type) { @@ -8252,7 +8380,7 @@ void define_zombie( int mid, int ztype, int cs, int power ) { // this limit can be updated if mons->number goes >8 bits.. test = random2(182); // not guaranteed to be valid, so.. - cls = mons_charclass(test); + cls = mons_species(test); if (cls == MONS_PROGRAM_BUG) continue; @@ -8329,7 +8457,7 @@ void define_zombie( int mid, int ztype, int cs, int power ) } else { - menv[mid].number = mons_charclass(ztype); + menv[mid].number = mons_species(ztype); mons_sec2 = menv[mid].number; } diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 6fd208d562..5e2d5fb0c6 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -20,6 +20,7 @@ #include "direct.h" #include "dungeon.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "misc.h" #include "monplace.h" @@ -217,13 +218,14 @@ void direct_effect(struct bolt &pbolt) mpr( "You are engulfed in a burst of hellfire!" ); strcpy( pbolt.beam_name, "hellfire" ); pbolt.ex_size = 1; - pbolt.flavour = BEAM_EXPLOSION; + pbolt.flavour = BEAM_HELLFIRE; + pbolt.is_explosion = true; pbolt.type = SYM_ZAP; pbolt.colour = RED; pbolt.thrower = KILL_MON_MISSILE; pbolt.aux_source = NULL; - pbolt.isBeam = false; - pbolt.isTracer = false; + pbolt.is_beam = false; + pbolt.is_tracer = false; pbolt.hit = 20; pbolt.damage = dice_def( 3, 20 ); pbolt.aux_source = "burst of hellfire"; @@ -295,7 +297,7 @@ void mons_direct_effect(struct bolt &pbolt, int i) break; case DMNBM_MUTATION: - if (mons_holiness( monster->type ) != MH_NATURAL) + if (mons_holiness(monster) != MH_NATURAL) simple_monster_message(monster, " is unaffected."); else if (check_mons_resist_magic( monster, pbolt.ench_power )) simple_monster_message(monster, " resists."); @@ -550,17 +552,30 @@ bool acquirement(unsigned char force_class, int agent) int skill = SK_FIGHTING; // Can't do much with launchers, so we'll avoid them for now -- bwr - for (int i = SK_SHORT_BLADES; i <= SK_STAVES; i++) + for (int i = SK_SHORT_BLADES; i < SK_DARTS; i++) { if (i == SK_UNUSED_1) continue; // Adding a small constant allows for the occasional - // weapon in an untrained skill. - count += (you.skills[i] + 1); + // weapon in an untrained skill. Since the game + // doesn't allow for much in the way of good launchers, + // we'll lower their weight. - if (random2(count) < you.skills[i] + 1) - skill = i; + int weight = 0; + + if (i < SK_SLINGS) + weight = you.skills[i] + 3; + else + weight = (you.skills[i] + 2) * 2 / 3; + + if (weight) + { + count += weight; + + if (random2(count) < weight) + skill = i; + } } if (skill == SK_STAVES) @@ -605,7 +620,7 @@ bool acquirement(unsigned char force_class, int agent) else if (class_wanted == OBJ_MISSILES) { int count = 0; - int skill = SK_THROWING; + int skill = SK_RANGED_COMBAT; for (int i = SK_SLINGS; i <= SK_DARTS; i++) { @@ -701,7 +716,7 @@ bool acquirement(unsigned char force_class, int agent) case SP_PALE_DRACONIAN: case SP_UNK0_DRACONIAN: case SP_UNK1_DRACONIAN: - case SP_UNK2_DRACONIAN: + case SP_BASE_DRACONIAN: case SP_SPRIGGAN: if (type_wanted == ARM_GLOVES || type_wanted == ARM_BOOTS) { @@ -1242,7 +1257,7 @@ bool acquirement(unsigned char force_class, int agent) break; case WPN_GREAT_MACE: - case WPN_GREAT_FLAIL: + case WPN_DIRE_FLAIL: mitm[thing_created].sub_type = (coinflip() ? WPN_MACE : WPN_FLAIL); break; @@ -1274,8 +1289,8 @@ bool acquirement(unsigned char force_class, int agent) switch (mitm[thing_created].sub_type) { case ARM_HELMET: - if ((cmp_helmet_type( mitm[thing_created], THELM_HELM ) - || cmp_helmet_type( mitm[thing_created], THELM_HELMET )) + if ((get_helmet_type(mitm[thing_created]) == THELM_HELM + || get_helmet_type(mitm[thing_created]) == THELM_HELMET) && ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE) || player_genus(GENPC_DRACONIAN) || you.species == SP_MINOTAUR @@ -1293,17 +1308,17 @@ bool acquirement(unsigned char force_class, int agent) case ARM_BOOTS: if (you.species == SP_NAGA) - mitm[thing_created].plus2 = TBOOT_NAGA_BARDING; + mitm[thing_created].sub_type = ARM_NAGA_BARDING; else if (you.species == SP_CENTAUR) - mitm[thing_created].plus2 = TBOOT_CENTAUR_BARDING; - else - mitm[thing_created].plus2 = TBOOT_BOOTS; + mitm[thing_created].sub_type = ARM_CENTAUR_BARDING; // fix illegal barding ego types caused by above hack - if (mitm[thing_created].plus2 != TBOOT_BOOTS - && get_armour_ego_type( mitm[thing_created] ) == SPARM_RUNNING) + if (mitm[thing_created].sub_type != ARM_BOOTS + && get_armour_ego_type( mitm[thing_created] ) + == SPARM_RUNNING) { - set_item_ego_type( mitm[thing_created], OBJ_ARMOUR, SPARM_NORMAL ); + set_item_ego_type( + mitm[thing_created], OBJ_ARMOUR, SPARM_NORMAL ); } break; diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index a803a5d5c6..c084ec3154 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -30,7 +30,7 @@ #ifndef ENUM_H #define ENUM_H -enum ABILITIES +enum ability_type { ABIL_NON_ABILITY = -1, ABIL_SPIT_POISON = 1, // 1 @@ -49,7 +49,7 @@ enum ABILITIES ABIL_BREATHE_STEAM, ABIL_FLY, // 15 ABIL_SUMMON_MINOR_DEMON, - ABIL_SUMMON_DEMON, + ABIL_SUMMON_DEMONS, ABIL_HELLFIRE, ABIL_TORMENT, ABIL_RAISE_DEAD, // 20 @@ -79,7 +79,7 @@ enum ABILITIES ABIL_TSO_REPEL_UNDEAD = 120, // 120 ABIL_TSO_SMITING, ABIL_TSO_ANNIHILATE_UNDEAD, - ABIL_TSO_THUNDERBOLT, + ABIL_TSO_CLEANSING_FLAME, ABIL_TSO_SUMMON_DAEVA, // 124 ABIL_KIKU_RECALL_UNDEAD_SLAVES = 130, // 130 ABIL_KIKU_ENSLAVE_UNDEAD = 132, // 132 @@ -110,11 +110,15 @@ enum ABILITIES ABIL_TRAN_SERPENT_OF_HELL, ABIL_ROTTING, ABIL_TORMENT_II, - ABIL_SHUGGOTH_SEED, + ABIL_PAIN, + ABIL_ENSLAVE_UNDEAD, + ABIL_BOLT_OF_FIRE, + ABIL_BOLT_OF_COLD, + ABIL_HELLFROST, ABIL_RENOUNCE_RELIGION = 250 // 250 }; -enum ABILITY_FLAGS +enum ability_flag_type { ABFLAG_NONE = 0x00000000, ABFLAG_BREATH = 0x00000001, // ability uses DUR_BREATH_WEAPON @@ -126,7 +130,7 @@ enum ABILITY_FLAGS ABFLAG_PERMANENT_MP = 0x00000040 // costs permanent MPs }; -enum ACTIVITY +enum activity_type { ACT_NONE = 0, ACT_MULTIDROP, @@ -137,7 +141,7 @@ enum ACTIVITY ACT_ACTIVITY_COUNT }; -enum ACT_INTERRUPT +enum activity_interrupt_type { AI_FORCE_INTERRUPT = 0, // Forcibly kills any activity AI_KEYPRESS = 0x01, @@ -153,7 +157,7 @@ enum ACT_INTERRUPT AI_TELEPORT = 0x400 }; -enum AI_PAYLOAD +enum activity_interrupt_payload_type { AIP_NONE, AIP_INT, @@ -162,7 +166,7 @@ enum AI_PAYLOAD AIP_HP_LOSS }; -enum AMMUNITION_DESCRIPTIONS +enum ammunition_description_type { DAMMO_ORCISH = 3, // 3 DAMMO_ELVEN, @@ -170,7 +174,7 @@ enum AMMUNITION_DESCRIPTIONS }; // Various ways to get the acquirement effect. -enum AQ_AGENTS +enum acquirement_agent_type { AQ_SCROLL = 0, @@ -184,7 +188,7 @@ enum AQ_AGENTS AQ_WIZMODE = 200 }; -enum ARMOUR +enum armour_type { ARM_ROBE, // 0 ARM_LEATHER_ARMOUR, @@ -219,10 +223,16 @@ enum ARMOUR ARM_ANIMAL_SKIN, // 30 ARM_SWAMP_DRAGON_HIDE, ARM_SWAMP_DRAGON_ARMOUR, + ARM_STUDDED_LEATHER_ARMOUR, + ARM_CAP, + ARM_CENTAUR_BARDING, // 35 + ARM_NAGA_BARDING, + NUM_ARMOURS }; -enum ARMOUR_DESCRIPTIONS +// these are for the old system (still used for reading old files) +enum armour_description_type { DARM_PLAIN, // added for the heck of it, 15 Apr 2000 {dlb} DARM_EMBROIDERED_SHINY = 1, // which it is dependent upon armour subtype {dlb} @@ -233,14 +243,13 @@ enum ARMOUR_DESCRIPTIONS DARM_ORCISH }; -enum ARMOUR_PROPERTIES +enum armour_property_type { PARM_AC, // 0 PARM_EVASION }; -// Note: currently the size of the attr array is hard coded at 30! ick! -- bwr -enum ATTRIBUTES +enum attribute_type { ATTR_DIVINE_LIGHTNING_PROTECTION, // 0 // ATTR_SPEC_AIR, // don't use this! @@ -258,10 +267,15 @@ enum ATTRIBUTES ATTR_WALLS, ATTR_LAST_WALLS, ATTR_DELAYED_FIREBALL, // bwr: reserve fireballs - NUM_ATTRIBUTES // must always remain last member {dlb} + ATTR_DEMONIC_POWER_1, + ATTR_DEMONIC_POWER_2, + ATTR_DEMONIC_POWER_3, + ATTR_DEMONIC_POWER_4, + ATTR_DEMONIC_POWER_5, // 19 + NUM_ATTRIBUTES = 30 // must be at least 30 }; -enum BANDS +enum band_type { BAND_NO_BAND = 0, BAND_KOBOLDS = 1, @@ -306,10 +320,11 @@ enum BANDS BAND_BOGGARTS, BAND_BLINK_FROGS, BAND_SKELETAL_WARRIORS, // 44 + BAND_DRACONIAN, // 45 NUM_BANDS // always last }; -enum BEAMS // beam[].flavour +enum beam_type // beam[].flavour { BEAM_MISSILE, // 0 BEAM_MMISSILE, // 1 - and similarly unresistable things @@ -319,13 +334,17 @@ enum BEAMS // beam[].flavour BEAM_ELECTRICITY, // 5 BEAM_POISON, BEAM_NEG, - BEAM_ACID, // 8 - BEAM_EXPLOSION = 10, // 10 - BEAM_SPORE, // 11 - BEAM_POISON_ARROW, // 12 - BEAM_HELLFIRE, // 13 - found 11jan2000 {dlb} - BEAM_ENERGY = 17, - BEAM_HOLY = 18, // 18 - aka beam of cleansing, golden flame + BEAM_ACID, + BEAM_MIASMA, + // BEAM_EXPLOSION, // 10 - use is_explosion, and BEAM of flavour + BEAM_SPORE = 11, + BEAM_POISON_ARROW, + BEAM_HELLFIRE, + BEAM_NAPALM, + BEAM_STEAM, // 15 + BEAM_HELLFROST, + BEAM_ENERGY, + BEAM_HOLY, // 18 - aka beam of cleansing, golden flame BEAM_FRAG, BEAM_LAVA, // 20 BEAM_BACKLIGHT, @@ -352,6 +371,8 @@ enum BEAMS // beam[].flavour BEAM_DISPEL_UNDEAD, // YELLOW BEAM_DISINTEGRATION, // WHITE BEAM_ENSLAVE_DEMON, // colour "16" + BEAM_BLINK, + BEAM_PETRIFY, // new beams for evaporate BEAM_POTION_STINKING_CLOUD, @@ -365,10 +386,10 @@ enum BEAMS // beam[].flavour BEAM_POTION_PURP_SMOKE, BEAM_POTION_RANDOM, - BEAM_LINE_OF_SIGHT, // only to check monster LOS + BEAM_LINE_OF_SIGHT // only used for checking monster LOS }; -enum BOOKS +enum book_type { BOOK_MINOR_MAGIC_I, // 0 BOOK_MINOR_MAGIC_II, @@ -421,7 +442,7 @@ enum BOOKS NUM_BOOKS }; -enum BRANCHES // you.where_are_you +enum branch_type // you.where_are_you { BRANCH_MAIN_DUNGEON, // 0 BRANCH_DIS, @@ -443,10 +464,11 @@ enum BRANCHES // you.where_are_you BRANCH_SNAKE_PIT, BRANCH_ELVEN_HALLS, // 20 BRANCH_TOMB, - BRANCH_SWAMP + BRANCH_SWAMP, + BRANCH_CAVERNS }; -enum BRANCH_STAIRS // you.branch_stairs[] - 10 less than BRANCHES {dlb} +enum branch_stair_type // you.branch_stairs[] - 10 less than BRANCHES {dlb} { STAIRS_ORCISH_MINES, // 0 STAIRS_HIVE, @@ -460,17 +482,18 @@ enum BRANCH_STAIRS // you.branch_stairs[] - 10 less than BRANCHES {dlb} STAIRS_SNAKE_PIT, STAIRS_ELVEN_HALLS, // 10 STAIRS_TOMB, - STAIRS_SWAMP + STAIRS_SWAMP, + STAIRS_CAVERNS }; -enum BURDEN_STATES // you.burden_state +enum burden_state_type // you.burden_state { BS_UNENCUMBERED, // 0 BS_ENCUMBERED = 2, // 2 BS_OVERLOADED = 5 // 5 }; -enum CANNED_MESSAGES // canned_msg() - unsigned char +enum canned_message_type // canned_msg() - unsigned char { MSG_SOMETHING_APPEARS, // 0 MSG_NOTHING_HAPPENS, @@ -482,10 +505,22 @@ enum CANNED_MESSAGES // canned_msg() - unsigned char MSG_UNTHINKING_ACT, MSG_SPELL_FIZZLES, MSG_HUH, - MSG_EMPTY_HANDED + MSG_EMPTY_HANDED, + MSG_NOT_IN_PRESENT_FORM, + MSG_TOO_CONFUSED, + MSG_DISORIENTED, + MSG_CANT_REACH +}; + +enum char_set_type +{ + CSET_ASCII, // flat 7-bit ASCII + CSET_IBM, // 8-bit ANSI/Code Page 437 + CSET_DEC, // 8-bit DEC, 0xE0-0xFF shifted for line drawing chars + NUM_CSET }; -enum CLOUD_TYPES // cloud_type[], place_cloud(), big_cloud() +enum cloud_type { CLOUD_NONE, // 0 CLOUD_FIRE, // 1 @@ -498,6 +533,7 @@ enum CLOUD_TYPES // cloud_type[], place_cloud(), big_cloud() CLOUD_STEAM, // 8 CLOUD_MIASMA = 9, // 9: found 11jan2000 {dlb} CLOUD_BLACK_SMOKE = 10, //was: CLOUD_STICKY_FLAME and wrong 19jan2000 {dlb} + CLOUD_RANDOM = 98, CLOUD_DEBUGGING = 99, // 99: used once as 'nonexistent cloud' {dlb} // if env.cloud_type > 100, it is a monster's cloud {dlb} CLOUD_FIRE_MON = 101, // 101: found 11jan2000 {dlb} @@ -512,7 +548,7 @@ enum CLOUD_TYPES // cloud_type[], place_cloud(), big_cloud() CLOUD_BLACK_SMOKE_MON = 110 // 110: added 19jan2000 {dlb} }; -enum COMMANDS +enum command_type { CMD_NO_CMD = 1000, // 1000 CMD_MOVE_NOWHERE, @@ -610,15 +646,14 @@ enum COMMANDS CMD_CLEAR_MAP }; -enum CONFIRM_LEVEL +enum confirm_level_type { CONFIRM_NONE_EASY, CONFIRM_SAFE_EASY, CONFIRM_ALL_EASY }; -// [dshaligram] 4.1 merge GOOD_ and NAUGHTY_ into generic conducts. -enum CONDUCTS +enum conduct_type { DID_NECROMANCY = 1, // vamp/drain/pain wpns, Zong/Curses DID_UNHOLY, // demon wpns, demon spells @@ -656,7 +691,7 @@ enum CONDUCTS NUM_CONDUCTS }; -enum CORPSE_EFFECTS +enum corpse_effect_type { CE_NOCORPSE, // 0 CE_CLEAN, // 1 @@ -670,13 +705,13 @@ enum CORPSE_EFFECTS CE_ROTTEN = 50 // 50 - must remain at 50 for now {dlb} }; -enum CORPSES +enum corpse_type { CORPSE_BODY, // 0 CORPSE_SKELETON }; -enum DEATH_KNIGHT_CHOICES +enum death_knight_type { DK_NO_SELECTION, DK_NECROMANCY, @@ -684,7 +719,7 @@ enum DEATH_KNIGHT_CHOICES DK_RANDOM }; -enum DECKS +enum deck_type { DECK_OF_WONDERS, // 0 DECK_OF_SUMMONING, @@ -693,13 +728,13 @@ enum DECKS DECK_OF_PUNISHMENT }; -enum DELAY +enum delay_type { DELAY_NOT_DELAYED, DELAY_EAT, DELAY_ARMOUR_ON, DELAY_ARMOUR_OFF, - DELAY_MEMORIZE, + DELAY_MEMORISE, DELAY_BUTCHER, DELAY_AUTOPICKUP, DELAY_WEAPON_SWAP, // for easy_butcher @@ -711,7 +746,7 @@ enum DELAY DELAY_UNINTERUPTABLE // simple uninteruptable delay }; -enum DEMON_BEAMS +enum demon_beam_type { DMNBM_HELLFIRE, // 0 DMNBM_SMITING, @@ -719,14 +754,15 @@ enum DEMON_BEAMS DMNBM_MUTATION }; -enum DEMON_CLASSES // summon_any_demon() +enum demon_class_type { DEMON_LESSER, // 0: Class V DEMON_COMMON, // 1: Class II-IV - DEMON_GREATER // 2: Class I + DEMON_GREATER, // 2: Class I + DEMON_RANDOM // any of the above }; -enum DESCRIPTION_LEVEL +enum description_level_type { DESC_CAP_THE, // 0 DESC_NOCAP_THE, // 1 @@ -740,19 +776,70 @@ enum DESCRIPTION_LEVEL DESC_INVENTORY // 8 }; -enum DIRECTION // (unsigned char) you.char_direction +enum dragon_class_type +{ + DRAGON_LIZARD, + DRAGON_DRACONIAN, + DRAGON_DRAGON +}; + +enum game_direction_type { DIR_DESCENDING = 0, // 0 - change and lose savefile compatibility (!!!) DIR_ASCENDING = 1 // 1 - change and lose savefile compatibility (!!!) }; -enum DROP_MODE +// NOTE: The order of these is very important to their usage! +enum dungeon_char_type +{ + DCHAR_WALL, // 0 + DCHAR_WALL_MAGIC, + DCHAR_FLOOR, + DCHAR_FLOOR_MAGIC, + DCHAR_DOOR_OPEN, + DCHAR_DOOR_CLOSED, // 5 + DCHAR_TRAP, + DCHAR_STAIRS_DOWN, + DCHAR_STAIRS_UP, + DCHAR_ALTAR, + DCHAR_ARCH, // 10 + DCHAR_FOUNTAIN, + DCHAR_WAVY, + DCHAR_STATUE, + DCHAR_INVIS_EXPOSED, + DCHAR_ITEM_DETECTED, // 15 + DCHAR_ITEM_ORB, + DCHAR_ITEM_WEAPON, + DCHAR_ITEM_ARMOUR, + DCHAR_ITEM_WAND, + DCHAR_ITEM_FOOD, // 20 + DCHAR_ITEM_SCROLL, + DCHAR_ITEM_RING, + DCHAR_ITEM_POTION, + DCHAR_ITEM_MISSILE, + DCHAR_ITEM_BOOK, // 25 + DCHAR_ITEM_STAVE, + DCHAR_ITEM_MISCELLANY, + DCHAR_ITEM_CORPSE, + DCHAR_ITEM_GOLD, + DCHAR_ITEM_AMULET, // 30 + DCHAR_CLOUD, // 31 + NUM_DCHAR_TYPES +}; + +enum drop_mode_type { DM_SINGLE, DM_MULTI }; -enum DUNGEON_FEATURES // (unsigned char) grd[][] +// lowest grid value which can be occupied (walk, swim, fly) +#define MINMOVE 31 + +// lowest grid value which can be seen through +#define MINSEE 11 + +enum dungeon_feature_type { DNGN_UNSEEN, // 0 DNGN_ROCK_WALL, @@ -764,14 +851,12 @@ enum DUNGEON_FEATURES // (unsigned char) grd[][] DNGN_ORCISH_IDOL, DNGN_WAX_WALL, // 8 DNGN_PERMAROCK_WALL, // 9 - for undiggable walls - DNGN_LAST_SOLID_TILE = 10, // 10 - just here temporarily {dlb} - DNGN_LAVA_X = 11, // 11 - DNGN_WATER_X, // 12 DNGN_SILVER_STATUE = 21, // 21 DNGN_GRANITE_STATUE, DNGN_ORANGE_CRYSTAL_STATUE, // 23 - DNGN_STATUE_39 = 39, // 39 + DNGN_STATUE_RESERVED_1, + DNGN_STATUE_RESERVED_2, // 25 DNGN_LAVA = 61, // 61 DNGN_DEEP_WATER, // 62 @@ -779,9 +864,10 @@ enum DUNGEON_FEATURES // (unsigned char) grd[][] DNGN_WATER_STUCK, DNGN_FLOOR, // 67 - DNGN_ENTER_HELL = 69, // 69 + DNGN_EXIT_HELL, // 68 + DNGN_ENTER_HELL, // 69 DNGN_OPEN_DOOR, // 70 - DNGN_BRANCH_STAIRS, // 71 + // DNGN_BRANCH_STAIRS, // 71 DNGN_TRAP_MECHANICAL = 75, // 75 DNGN_TRAP_MAGICAL, DNGN_TRAP_III, @@ -827,6 +913,10 @@ enum DUNGEON_FEATURES // (unsigned char) grd[][] DNGN_ENTER_ELVEN_HALLS, // 120 DNGN_ENTER_TOMB, DNGN_ENTER_SWAMP, // 122 + DNGN_ENTER_RESERVED_1, + DNGN_ENTER_RESERVED_2, + DNGN_ENTER_RESERVED_3, + DNGN_ENTER_RESERVED_4, // 126 DNGN_RETURN_FROM_ORCISH_MINES = 130, // 130 DNGN_RETURN_FROM_HIVE, @@ -841,6 +931,10 @@ enum DUNGEON_FEATURES // (unsigned char) grd[][] DNGN_RETURN_FROM_ELVEN_HALLS, // 140 DNGN_RETURN_FROM_TOMB, DNGN_RETURN_FROM_SWAMP, // 142 + DNGN_RETURN_RESERVED_1, + DNGN_RETURN_RESERVED_2, + DNGN_RETURN_RESERVED_3, + DNGN_RETURN_RESERVED_4, // 146 DNGN_ALTAR_ZIN = 180, // 180 DNGN_ALTAR_SHINING_ONE, @@ -865,10 +959,41 @@ enum DUNGEON_FEATURES // (unsigned char) grd[][] DNGN_DRY_FOUNTAIN_VI, DNGN_DRY_FOUNTAIN_VII, DNGN_DRY_FOUNTAIN_VIII, - DNGN_PERMADRY_FOUNTAIN = 210 // added (from dungeon.cc/maps.cc) 22jan2000 {dlb} -}; - -enum DURATIONS // you.duration[] + DNGN_PERMADRY_FOUNTAIN = 210, // added (from dungeon.cc/maps.cc) 22jan2000 {dlb} + + // Real terrain must all occur before 256 to guarantee it fits + // into the unsigned char used for the grid! + + // There aren't really terrain, but they're passed in and used + // to get their appearance character so I'm putting them here for now. + DNGN_ITEM_ORB = 256, + DNGN_INVIS_EXPOSED = 257, + DNGN_ITEM_WEAPON = 258, + DNGN_ITEM_ARMOUR = 259, + DNGN_ITEM_WAND = 260, + DNGN_ITEM_FOOD = 261, + DNGN_ITEM_UNUSED_1 = 262, + DNGN_ITEM_SCROLL = 263, + DNGN_ITEM_RING = 264, + DNGN_ITEM_POTION = 265, + DNGN_ITEM_MISSILE = 266, + DNGN_ITEM_BOOK = 267, + DNGN_ITEM_UNUSED_2 = 268, + DNGN_ITEM_STAVE = 269, + DNGN_ITEM_MISCELLANY = 270, + DNGN_ITEM_CORPSE = 271, + DNGN_ITEM_GOLD = 272, + DNGN_ITEM_AMULET = 273, + DNGN_ITEM_DETECTED = 274, + + DNGN_CLOUD = 280, + NUM_FEATURES, // for use in lookup table in view.cc + + DNGN_RANDOM, + DNGN_START_OF_MONSTERS = 297 // don't go past here! see view.cc +}; + +enum duration_type { DUR_LIQUID_FLAMES, // 0 DUR_ICY_ARMOUR, @@ -891,18 +1016,52 @@ enum DURATIONS // you.duration[] DUR_SEE_INVISIBLE, DUR_WEAPON_BRAND, // general "branding" spell counter DUR_SILENCE, - DUR_GLAMOUR, // 20 - DUR_SHUGGOTH_SEED_RELOAD, - DUR_INFECTED_SHUGGOTH_SEED, - DUR_CONDENSATION_SHIELD, // 23 + DUR_GLAMOUR, // 20 + DUR_CONDENSATION_SHIELD = 23, // 23 DUR_STONESKIN, - DUR_REPEL_UNDEAD, // 25 - DUR_LAST_DUR, //jmf: for asserts - NUM_DURATIONS = 30 - // set at 30 to prevent savefile incompatibilities 12mar2000{dlb} -}; - -enum ENCHANTMENT // menv[].enchantment[] + DUR_REPEL_UNDEAD, // 25 + DUR_STUN, + DUR_CUT, // 27 + NUM_DURATIONS = 30 // must be at least 30 +}; + +// various elemental colour schemes... used for abstracting random short lists +enum element_type +{ + EC_FIRE = 32, // fiery colours (must be first and > higest colour) + EC_ICE, // icy colours + EC_EARTH, // earthy colours + EC_ELECTRICITY, // electrical side of air + EC_AIR, // non-electric and general air magic + EC_POISON, // used only for venom mage and stalker stuff + EC_WATER, // used only for the elemental + EC_MAGIC, // general magical effect + EC_MUTAGENIC, // transmute, poly, radiation effects + EC_WARP, // teleportation and anything similar + EC_ENCHANT, // magical enhancements + EC_HEAL, // holy healing (not necromantic stuff) + EC_HOLY, // general "good" god effects + EC_DARK, // darkness + EC_DEATH, // currently only assassin (and equal to EC_NECRO) + EC_NECRO, // necromancy stuff + EC_UNHOLY, // demonology stuff + EC_VEHUMET, // vehumet's odd-ball colours + EC_CRYSTAL, // colours of crystal + EC_BLOOD, // colours of blood + EC_SMOKE, // colours of smoke + EC_SLIME, // colours of slime + EC_JEWEL, // colourful + EC_ELVEN, // used for colouring elf fabric items + EC_DWARVEN, // used for colouring dwarf fabric items + EC_ORCISH, // used for colouring orc fabric items + EC_GILA, // gila monster colours + EC_FLOOR, // colour of the area's floor + EC_ROCK, // colour of the area's rock + EC_STONE, // colour of the area's stone + EC_RANDOM // any colour (except BLACK) +}; + +enum enchant_type { ENCH_NONE = 0, // 0 ENCH_SLOW, @@ -965,14 +1124,23 @@ enum ENCHANTMENT // menv[].enchantment[] NUM_ENCHANTMENTS }; -enum ENCHANT_STATS +enum enchant_retval +{ + ERV_FAIL, + ERV_NEW, + ERV_INCREASED +}; + +enum enchant_stat_type { ENCHANT_TO_HIT, ENCHANT_TO_DAM }; -enum EQUIPMENT +enum equipment_type { + EQ_NONE = -1, + EQ_WEAPON, // 0 EQ_CLOAK, EQ_HELMET, @@ -993,7 +1161,7 @@ enum EQUIPMENT EQ_ALL_ARMOUR // check all armour types }; -enum FIRE_TYPES +enum fire_type { FIRE_NONE, FIRE_LAUNCHER, @@ -1003,19 +1171,24 @@ enum FIRE_TYPES FIRE_SPEAR, FIRE_HAND_AXE, FIRE_CLUB, + FIRE_ROCK, NUM_FIRE_TYPES }; -enum FLUSH_REASONS +enum flush_reason_type { FLUSH_ON_FAILURE, // spell/ability failed to cast FLUSH_BEFORE_COMMAND, // flush before getting a command FLUSH_ON_MESSAGE, // flush when printing a message - FLUSH_LUA, // flush when Lua wants us to + FLUSH_ON_WARNING_MESSAGE, // flush on MSGCH_WARN messages + FLUSH_ON_DANGER_MESSAGE, // flush on MSGCH_DANGER messages + FLUSH_ON_PROMPT, // flush on MSGCH_PROMPT messages + FLUSH_ON_UNSAFE_YES_OR_NO_PROMPT, // flush when !safe set to yesno() + FLUSH_LUA, // flush when Lua wants to flush NUM_FLUSH_REASONS }; -enum FOODS // mitm[].sub_type[] +enum food_type { FOOD_MEAT_RATION, // 0 FOOD_BREAD_RATION, @@ -1042,21 +1215,21 @@ enum FOODS // mitm[].sub_type[] NUM_FOODS }; -enum GENUS_PLAYER // see player::player_genus() +enum genus_type { GENPC_DRACONIAN, // 0 GENPC_ELVEN, // 1 GENPC_DWARVEN // 2 }; -enum GENDER +enum gender_type { GENDER_NEUTER, GENDER_MALE, GENDER_FEMALE }; -enum GHOST_VALUES +enum ghost_value_type { GVAL_MAX_HP, // 0 GVAL_EV, @@ -1088,9 +1261,9 @@ enum GHOST_VALUES GVAL_DEMONLORD_CYCLE_COLOUR // 13 }; -enum GODS // you.religion +enum god_type { - GOD_NO_GOD, // 0 + GOD_NO_GOD, // 0 -- must be zero GOD_ZIN, GOD_SHINING_ONE, GOD_KIKUBAAQUDGHA, @@ -1108,14 +1281,16 @@ enum GODS // you.religion GOD_RANDOM = 100 }; -enum HANDS_REQUIRED +enum hands_reqd_type { - HANDS_ONE_HANDED = 1, // 1 - HANDS_TWO_HANDED, - HANDS_ONE_OR_TWO_HANDED + HANDS_ONE, + HANDS_HALF, + HANDS_TWO, + + HANDS_DOUBLE // not a level, marks double ended weapons (== half) }; -enum HELMET_TYPES // used in pluses2 +enum helmet_type { THELM_HELMET = 0x0000, THELM_HELM = 0x0001, @@ -1126,7 +1301,6 @@ enum HELMET_TYPES // used in pluses2 THELM_SPECIAL = 0x0004, // type used only for artefacts (mask, hat) THELM_TYPE_MASK = 0x00ff, - THELM_DESC_PLAIN = 0x0000, THELM_DESC_WINGED = 0x0100, THELM_DESC_HORNED = 0x0200, @@ -1139,30 +1313,8 @@ enum HELMET_TYPES // used in pluses2 THELM_DESC_MASK = 0xff00 }; -#if 0 -enum HELMET_DESCRIPTIONS -{ - DHELM_WINGED = 1, // 1 - DHELM_HORNED, - DHELM_CRESTED, - DHELM_PLUMED, - DHELM_SPIKED, // 5 - DHELM_VISORED, - DHELM_JEWELLED -}; - -enum HELMET_TYPES // used in pluses2 -{ - THELM_HELMET = 0, - THELM_HELM, - THELM_CAP, - THELM_WIZARD_HAT, - NUM_HELMET_TYPES, - THELM_SPECIAL // type used only for artefacts (mask, hat) -}; -#endif -enum BOOT_TYPES // used in pluses2 +enum boot_type // used in pluses2 { TBOOT_BOOTS = 0, TBOOT_NAGA_BARDING, @@ -1171,7 +1323,7 @@ enum BOOT_TYPES // used in pluses2 }; -enum HUNGER_STATES // you.hunger_state +enum hunger_state // you.hunger_state { HS_RAVENOUS, // 0: not used within code, really HS_STARVING, @@ -1181,7 +1333,7 @@ enum HUNGER_STATES // you.hunger_state HS_ENGORGED // 5 }; -enum ITEM_STATUS_FLAGS // per item flags: ie. ident status, cursed status +enum item_status_flag_type // per item flags: ie. ident status, cursed status { ISFLAG_KNOW_CURSE = 0x00000001, // curse status ISFLAG_KNOW_TYPE = 0x00000002, // artefact name, sub/special types @@ -1195,9 +1347,9 @@ enum ITEM_STATUS_FLAGS // per item flags: ie. ident status, cursed status ISFLAG_EQ_JEWELLERY_MASK = 0x0000000F, // mask of flags for known jewellery ISFLAG_CURSED = 0x00000100, // cursed - ISFLAG_RESERVED_1 = 0x00000200, // reserved (re-curses on wield?) - ISFLAG_RESERVED_2 = 0x00000400, // reserved (heavy cursed?) - ISFLAG_RESERVED_3 = 0x00000800, // reserved (perma-cursed?) + ISFLAG_RESERVED_1 = 0x00000200, // reserved + ISFLAG_RESERVED_2 = 0x00000400, // reserved + ISFLAG_RESERVED_3 = 0x00000800, // reserved ISFLAG_CURSE_MASK = 0x00000F00, // mask of all curse related flags ISFLAG_RANDART = 0x00001000, // special value is seed @@ -1206,6 +1358,7 @@ enum ITEM_STATUS_FLAGS // per item flags: ie. ident status, cursed status ISFLAG_DROPPED = 0x00004000, // dropped item (no autopickup) ISFLAG_THROWN = 0x00008000, // thrown missile weapon + // these don't have to remain as flags ISFLAG_NO_DESC = 0x00000000, // used for clearing these flags ISFLAG_GLOWING = 0x00010000, // weapons or armour ISFLAG_RUNED = 0x00020000, // weapons or armour @@ -1221,16 +1374,17 @@ enum ITEM_STATUS_FLAGS // per item flags: ie. ident status, cursed status ISFLAG_DEBUG_MARK = 0x80000000 // used for testing item structure }; -enum ITEM_DESCRIPTIONS +enum item_description_type { IDESC_WANDS, IDESC_POTIONS, IDESC_SCROLLS, // special field (like the others) IDESC_RINGS, - IDESC_SCROLLS_II // pluses field + IDESC_SCROLLS_II, + NUM_IDESC }; -enum ITEM_MAKE_SPECIES // used only for race during creation +enum item_make_species_type { MAKE_ITEM_ELVEN = 1, MAKE_ITEM_DWARVEN = 2, @@ -1240,7 +1394,7 @@ enum ITEM_MAKE_SPECIES // used only for race during creation MAKE_ITEM_RANDOM_RACE = 250 }; -enum ITEM_ORIGIN_DUMP_SELECT +enum item_origin_dump_selector { IODS_PRICE = 0, // Extra info is provided based on price IODS_ARTIFACTS = 1, // Extra information on artifacts @@ -1254,22 +1408,23 @@ enum ITEM_ORIGIN_DUMP_SELECT IODS_EVERYTHING = 0xFF }; -enum ITEM_TYPE_ID // used for first index of id[4][50] +enum item_type_id_type { IDTYPE_WANDS = 0, IDTYPE_SCROLLS, IDTYPE_JEWELLERY, - IDTYPE_POTIONS + IDTYPE_POTIONS, + NUM_IDTYPE }; -enum ITEM_TYPE_ID_STATE // used for values in id[4][50] +enum item_type_id_state_type // used for values in id[4][50] { ID_UNKNOWN_TYPE = 0, ID_KNOWN_TYPE, ID_TRIED_TYPE }; -enum JEWELLERY +enum jewellery_type { RING_REGENERATION, // 0 RING_PROTECTION, @@ -1308,7 +1463,7 @@ enum JEWELLERY NUM_JEWELLERY }; -enum JOB +enum job_type { JOB_FIGHTER, // 0 JOB_WIZARD, @@ -1344,7 +1499,7 @@ enum JOB JOB_UNKNOWN = 100 }; -enum KILLBY +enum kill_method_type { KILLED_BY_MONSTER, // 0 KILLED_BY_POISON, @@ -1372,16 +1527,17 @@ enum KILLBY KILLED_BY_SPORE, KILLED_BY_TSO_SMITING, KILLED_BY_PETRIFICATION, // 25 - KILLED_BY_SHUGGOTH, - KILLED_BY_SOMETHING, + KILLED_BY_SOMETHING = 27, KILLED_BY_FALLING_DOWN_STAIRS, KILLED_BY_ACID, KILLED_BY_CURARE, + KILLED_BY_MELTING, + KILLED_BY_BLEEDING, NUM_KILLBY }; -enum KillCategory +enum kill_category { KC_YOU, KC_FRIENDLY, @@ -1389,7 +1545,7 @@ enum KillCategory KC_NCATEGORIES }; -enum KILLER // monster_die(), thing_thrown +enum killer_type // monster_die(), thing_thrown { KILL_YOU = 1, // 1 KILL_MON, @@ -1403,7 +1559,14 @@ enum KILLER // monster_die(), thing_thrown #define YOU_KILL(x) ((x) == KILL_YOU || (x) == KILL_YOU_MISSILE) #define MON_KILL(x) ((x) == KILL_MON || (x) == KILL_MON_MISSILE) -enum LEVEL_TYPES // you.level_type +enum launch_retval +{ + LRET_FUMBLED = 0, // must be left as 0 + LRET_LAUNCHED, + LRET_THROWN +}; + +enum level_area_type // you.level_type { LEVEL_DUNGEON, // 0 LEVEL_LABYRINTH, @@ -1411,14 +1574,14 @@ enum LEVEL_TYPES // you.level_type LEVEL_PANDEMONIUM }; -enum LOAD_MODE +enum load_mode_type { LOAD_START_GAME, LOAD_RESTART_GAME, LOAD_ENTER_LEVEL }; -enum MAP_SECTIONS // see maps.cc and dungeon.cc {dlb} +enum map_section_type // see maps.cc and dungeon.cc {dlb} { MAP_NORTH = 1, // 1 MAP_NORTHWEST, @@ -1430,7 +1593,7 @@ enum MAP_SECTIONS // see maps.cc and dungeon.cc {dlb} }; // if you mess with this list, you'll need to make changes in initfile.cc -enum MESSAGE_CHANNEL +enum msg_channel_type { MSGCH_PLAIN, // regular text MSGCH_PROMPT, // various prompts @@ -1447,13 +1610,16 @@ enum MESSAGE_CHANNEL MSGCH_MONSTER_SPELL, // monsters casting spells MSGCH_MONSTER_ENCHANT,// monsters enchantments up and down MSGCH_MONSTER_DAMAGE, // monster damage reports (param is level) + MSGCH_MONSTER_TARGET, // message marking the monster as a target MSGCH_ROTTEN_MEAT, // messages about chunks/corpses becoming rotten MSGCH_EQUIPMENT, // equipment listing messages - MSGCH_DIAGNOSTICS, // various diagnostic messages + MSGCH_FLOOR_ITEMS, // like equipment, but lists of floor items + MSGCH_MULTITURN_ACTION, // delayed action messages + MSGCH_DIAGNOSTICS, // various diagnostic messages NUM_MESSAGE_CHANNELS // always last }; -enum MESSAGE_COLOURS +enum msg_colour_type { MSGCOL_BLACK = 0, // the order of these colours is important MSGCOL_BLUE, @@ -1476,7 +1642,7 @@ enum MESSAGE_COLOURS MSGCOL_PLAIN // same as plain channel }; -enum MISCELLANY // mitm[].sub_type +enum misc_item_type { MISC_BOTTLED_EFREET, // 0 MISC_CRYSTAL_BALL_OF_SEEING, @@ -1499,7 +1665,7 @@ enum MISCELLANY // mitm[].sub_type NUM_MISCELLANY // mv: used for random generation }; -enum MISSILES // (unsigned char) +enum missile_type { MI_STONE, // 0 MI_ARROW, @@ -1508,10 +1674,11 @@ enum MISSILES // (unsigned char) MI_NEEDLE, MI_LARGE_ROCK, //jmf: it'd be nice to move MI_LARGE_ROCK to DEBRIS_ROCK NUM_MISSILES, - MI_EGGPLANT + MI_NONE // was MI_EGGPLANT... used for launch type detection }; -enum MONS_CLASS_FLAGS +// properties of the monster class (other than resists/vulnerabilities) +enum mons_class_flags { M_NO_FLAGS = 0, @@ -1582,7 +1749,7 @@ enum mon_resist_flags MR_VUL_BLUDGEON = (1<<15) }; -enum MON_TARG_MODE +enum targ_mode_type { TARG_ANY, TARG_ENEMY, @@ -1590,7 +1757,8 @@ enum MON_TARG_MODE TARG_NUM_MODES }; -enum MONSTERS // (int) menv[].type +// note this order is very sensitive... look at mons_is_unique() +enum monster_type // (int) menv[].type { MONS_GIANT_ANT, // 0 MONS_GIANT_BAT, @@ -1757,6 +1925,7 @@ enum MONSTERS // (int) menv[].type MONS_RED_WASP, // 170 MONS_SWAMP_DRAGON, MONS_SWAMP_DRAKE, + MONS_DEATH_DRAKE, MONS_SOLDIER_ANT, MONS_HILL_GIANT, MONS_QUEEN_ANT, // 175 @@ -1870,6 +2039,23 @@ enum MONSTERS // (int) menv[].type MONS_BORIS, // 310 // BCR - end second batch of uniques. + MONS_DRACONIAN, + MONS_BLACK_DRACONIAN, + MONS_MOTTLED_DRACONIAN, + MONS_YELLOW_DRACONIAN, + MONS_GREEN_DRACONIAN, // 315 + MONS_PURPLE_DRACONIAN, + MONS_RED_DRACONIAN, + MONS_WHITE_DRACONIAN, + MONS_PALE_DRACONIAN, + MONS_DRACONIAN_CALLER, // 320 + MONS_DRACONIAN_MONK, + MONS_DRACONIAN_ZEALOT, + MONS_DRACONIAN_SHIFTER, + MONS_DRACONIAN_ANNIHILATOR, + MONS_DRACONIAN_KNIGHT, // 325 + MONS_DRACONIAN_SCORCHER, + // The Lords of Hell: MONS_GERYON = 340, // 340 MONS_DISPATER, @@ -1949,51 +2135,52 @@ enum MONSTERS // (int) menv[].type }; -enum MONSTER_BEHAVIOUR // create_monster() +enum beh_type { BEH_SLEEP, // 0 BEH_WANDER, BEH_SEEK, BEH_FLEE, BEH_CORNERED, + BEH_PANIC, // like flee but without running away + BEH_INVESTIGATE, // investigating an ME_DISTURB NUM_BEHAVIOURS, // max # of legal states BEH_CHARMED, // hostile-but-charmed; create only BEH_FRIENDLY, // used during creation only BEH_HOSTILE, // creation only - BEH_GOD_GIFT // creation only + BEH_GOD_GIFT, // creation only + BEH_GUARD // creation only - monster is guard }; -enum MONSTER_ATTITUDES +enum mon_attitude_type { ATT_HOSTILE, // 0, default in most cases ATT_FRIENDLY, // created friendly (or tamed?) ATT_NEUTRAL }; -enum MONSTER_EVENTS +enum mon_event_type { ME_EVAL, // 0, evaluate monster AI state ME_DISTURB, // noisy ME_ANNOY, // annoy at range ME_ALERT, // alert to presence ME_WHACK, // physical attack + ME_SHOT, // attack at range ME_SCARE, // frighten monster ME_CORNERED // cannot flee }; -#if 0 -// Obsolete... use mons_charclass() -enum MONSTER_CATEGORIES +enum mon_flight_type { - MC_MIMIC, // 0 - NUM_MC, - MC_UNSPECIFIED = 255 // keep at end !!! mind the upper limit of 255 {dlb} + FLY_NOT, + FLY_POWERED, // wings, etc... paralysis == fall + FLY_LEVITATION // doesn't require physical effort }; -#endif // Note: These are currently stored in chars!!! // Need to fix struct monsters and the savefile if you want more. -enum MONSTER_FLAGS +enum monster_flag_type { MF_CREATED_FRIENDLY = 0x01, // no benefit from killing MF_GOD_GIFT = 0x02, // player not penalized by its death @@ -2006,7 +2193,7 @@ enum MONSTER_FLAGS MF_UNUSED_III = 0x80 }; -enum MONSTER_DAMAGE +enum mon_dam_level_type { MDAM_OKAY, MDAM_LIGHTLY_DAMAGED, @@ -2017,14 +2204,14 @@ enum MONSTER_DAMAGE MDAM_DEAD }; -enum MONSTER_DESCRIPTORS // things that cross categorical lines {dlb} +enum mon_desc_type // things that cross categorical lines {dlb} { MDSC_LEAVES_HIDE, // 0 MDSC_REGENERATES, MDSC_NOMSG_WOUNDS }; -enum MONSTER_HOLINESS // matches (char) H_foo in mon-util.h, see: monster_holiness() +enum mon_holy_type // matches (char) H_foo in mon-util.h, see: monster_holiness() { MH_HOLY, // 0 - was -1 MH_NATURAL, // 1 - was 0 @@ -2034,7 +2221,7 @@ enum MONSTER_HOLINESS // matches (char) H_foo in mon-util.h, see: monster_holine MH_PLANT // plants }; -enum MONSTER_INVENTORY_SLOTS // (int) menv[].inv[] +enum mon_inv_type // (int) menv[].inv[] { MSLOT_WEAPON, MSLOT_MISSILE, // although it is a second weapon for MONS_TWO_HEADED_OGRE - how to reconcile cleanly? {dlb} @@ -2047,16 +2234,19 @@ enum MONSTER_INVENTORY_SLOTS // (int) menv[].inv[] NUM_MONSTER_SLOTS = 8 // value must remain 8 for savefile compatibility {dlb} }; -enum MONSTER_ITEM_USE +// order of these is important: +enum mon_itemuse_type { MONUSE_NOTHING, MONUSE_EATS_ITEMS, MONUSE_OPEN_DOORS, MONUSE_STARTING_EQUIPMENT, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, + MONUSE_MAGIC_ITEMS }; -enum MONSTER_SPELLS // mons_cast(), mspell_list[], mons_spells() +// XXX: someday merge these into SPELL_ +enum mon_spell_type { MS_MMISSILE, // 0 MS_FLAME, @@ -2111,12 +2301,23 @@ enum MONSTER_SPELLS // mons_cast(), mspell_list[], mons_spells() MS_METAL_SPLINTERS, // 50 MS_SUMMON_DEMON_GREATER, // [foo]_1 was confusing - renamed 13jan2000 {dlb} MS_BANISHMENT, + MS_CONTROLLED_BLINK, + MS_CONTROL_UNDEAD, + MS_MIASMA, // 55 + MS_SUMMON_LIZARDS, + MS_BLINK_OTHER, + MS_DISPEL_UNDEAD, + MS_HELLFROST, + MS_POISON_ARROW, // 60 + // XXX: before adding more monster versions of player spells we should + // consider merging the two lists into one and just having monsters + // fail to implement the ones that are impractical. NUM_MONSTER_SPELLS, MS_NO_SPELL = 100 }; // XXX: These still need to be applied in mon-data.h -enum MONSTER_SPELL_TEMPLATES +enum mon_spellbook_type { MST_ORC_WIZARD_I = 0, MST_ORC_WIZARD_II, @@ -2131,7 +2332,8 @@ enum MONSTER_SPELL_TEMPLATES MST_VAMPIRE_KNIGHT, MST_VAMPIRE_MAGE, MST_EFREET = 50, - MST_BRAIN_WORM = 52, + MST_KILLER_KLOWN, + MST_BRAIN_WORM, MST_GIANT_ORANGE_BRAIN, MST_RAKSHASA, MST_GREAT_ORB_OF_EYES, // 55 @@ -2204,13 +2406,18 @@ enum MONSTER_SPELL_TEMPLATES MST_BOGGART, MST_EYE_OF_DEVASTATION, // 125 MST_QUICKSILVER_DRAGON, - MST_IRON_DRAGON, // 127 + MST_IRON_DRAGON, MST_SKELETAL_WARRIOR, + MST_MYSTIC, + MST_DEATH_DRAKE, // 130 + MST_DRAC_SCORCHER, // As Bioster would say.. pig*s + MST_DRAC_CALLER, + MST_DRAC_SHIFTER, NUM_MSTYPES, MST_NO_SPELLS = 250 }; -enum MUTATIONS +enum mutation_type { MUT_TOUGH_SKIN, // 0 MUT_STRONG, @@ -2296,7 +2503,7 @@ enum MUTATIONS NUM_MUTATIONS }; -enum OBJECT_CLASSES // (unsigned char) mitm[].base_type +enum object_class_type // (unsigned char) mitm[].base_type { OBJ_WEAPONS, // 0 OBJ_MISSILES, @@ -2321,18 +2528,18 @@ enum OBJECT_CLASSES // (unsigned char) mitm[].base_type // for blanket random sub_type .. see dungeon::items() }; -enum OBJECT_SELECTORS +enum object_selector { OSEL_ANY = -1, OSEL_WIELD = -2 }; -enum ORBS +enum orb_type { ORB_ZOT // 0 }; -enum POTIONS +enum potion_type { POT_HEALING, // 0 POT_HEAL_WOUNDS, @@ -2361,7 +2568,7 @@ enum POTIONS NUM_POTIONS }; -enum PRONOUN_TYPE +enum pronoun_type { PRONOUN_CAP, // 0 PRONOUN_NOCAP, // 1 @@ -2370,7 +2577,7 @@ enum PRONOUN_TYPE PRONOUN_REFLEXIVE // 4 (reflexive is always lowercase) }; -enum PROXIMITY // proximity to player to create monster +enum proximity_type // proximity to player to create monster { PROX_ANYWHERE, PROX_CLOSE_TO_PLAYER, @@ -2378,7 +2585,7 @@ enum PROXIMITY // proximity to player to create monster PROX_NEAR_STAIRS }; -enum RANDART_PROP +enum randart_prop_type { RAP_BRAND, // 0 RAP_AC, @@ -2409,17 +2616,25 @@ enum RANDART_PROP RAP_ACCURACY, RAP_DAMAGE, RAP_CURSED, - RAP_STEALTH + RAP_STEALTH, + RAP_NUM_PROPERTIES }; -enum READ_BOOK_ACTION +enum read_book_action_type { RBOOK_USE_STAFF, - RBOOK_MEMORIZE, + RBOOK_MEMORISE, RBOOK_READ_SPELL }; -enum RUN_DIR +enum run_check_type +{ + RCHECK_LEFT, + RCHECK_FRONT, + RCHECK_RIGHT +}; + +enum run_dir_type { RDIR_UP = 0, RDIR_UP_RIGHT, @@ -2432,7 +2647,7 @@ enum RUN_DIR RDIR_REST }; -enum RUNE_TYPES +enum rune_type { // Note: that runes DIS-SWAMP have the same numberic value as the branch RUNE_DIS = 1, @@ -2456,17 +2671,18 @@ enum RUNE_TYPES RUNE_LOM_LOBON, RUNE_CEREBOV, RUNE_GLOORX_VLOQ, - NUM_RUNE_TYPES // should always be last + NUM_RUNE_TYPES, // should always be last + RUNE_NONE }; -enum SCORE_FORMAT +enum score_format_type { SCORE_TERSE, // one line SCORE_REGULAR, // two lines (name, cause, blank) SCORE_VERBOSE // everything (dates, times, god, etc) }; -enum SCROLLS +enum scroll_type { SCR_IDENTIFY, // 0 SCR_TELEPORTATION, @@ -2494,7 +2710,7 @@ enum SCROLLS NUM_SCROLLS }; -enum SHOPS // (unsigned char) env.sh_type[], item_in_shop(), in_a_shop() +enum shop_type // (unsigned char) env.sh_type[], item_in_shop(), in_a_shop() { SHOP_WEAPON, // 0 SHOP_ARMOUR, @@ -2513,7 +2729,42 @@ enum SHOPS // (unsigned char) env.sh_type[], item_in_shop(), in_a_shop() SHOP_RANDOM = 255 // keep set at 255 for now {dlb} }; -enum SKILLS +enum shout_type +{ + S_SILENT, // silent + S_SHOUT, // shout + S_BARK, // bark + S_SHOUT2, // shout twice + S_ROAR, // roar + S_SCREAM, // scream + S_BELLOW, // bellow (?) + S_SCREECH, // screech + S_BUZZ, // buzz + S_MOAN, // moan + S_WHINE, // irritating whine (mosquito) + S_CROAK, // frog croak + S_GROWL, // for bears + S_HISS, // for snakes and lizards + NUM_SHOUTS, + S_RANDOM +}; + +// These are often addressed relative to each other (esp. delta SIZE_MEDIUM) +enum size_type +{ + SIZE_TINY, // rat/bat + SIZE_LITTLE, // spriggan + SIZE_SMALL, // halfling/kobold/gnome + SIZE_MEDIUM, // human/elf/dwarf + SIZE_LARGE, // troll/ogre + SIZE_BIG, // centaur/naga/large quadrupeds + SIZE_GIANT, // giant + SIZE_HUGE, // dragon + NUM_SIZE_LEVELS, + SIZE_CHARACTER // transformations that don't change size +}; + +enum skill_type { SK_FIGHTING, // 0 SK_SHORT_BLADES, @@ -2527,7 +2778,7 @@ enum SKILLS SK_BOWS, SK_CROSSBOWS, // 10 SK_DARTS, - SK_THROWING, + SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH, // 15 @@ -2550,10 +2801,14 @@ enum SKILLS SK_POISON_MAGIC, SK_INVOCATIONS, SK_EVOCATIONS, - NUM_SKILLS // must remain last member {dlb} + NUM_SKILLS, // must remain last regular member + + SK_BLANK_LINE, // used for skill output + SK_COLUMN_BREAK, // used for skill output + SK_NONE }; -enum SPECIAL_ARMOR +enum special_armour_type { SPARM_NORMAL, // 0 SPARM_RUNNING, @@ -2581,7 +2836,7 @@ enum SPECIAL_ARMOR SPARM_RANDART_V = 29 // 29 - highest value found thus far {dlb} }; -enum SPECIAL_MISSILES // to separate from weapons in general {dlb} +enum special_missile_type // to separate from weapons in general {dlb} { SPMSL_NORMAL, // 0 SPMSL_FLAME, // 1 @@ -2591,23 +2846,32 @@ enum SPECIAL_MISSILES // to separate from weapons in general {dlb} SPMSL_CURARE // 5 }; -enum SPECIAL_ROOMS +enum special_room_type { SROOM_LAIR_ORC, // 0 SROOM_LAIR_KOBOLD, SROOM_TREASURY, SROOM_BEEHIVE, + SROOM_JELLY_PIT, SROOM_MORGUE, NUM_SPECIAL_ROOMS // 5 - must remain final member {dlb} }; -enum SPECIAL_RINGS // jewellery mitm[].special values +enum special_ring_type // jewellery mitm[].special values { SPRING_RANDART = 200, SPRING_UNRANDART = 201 }; -enum SPECIAL_WEAPONS // equivalent to (you.inv[].special or mitm[].special) % 30 +// order is important on these (see player_speed()) +enum speed_type +{ + SPEED_SLOWED, + SPEED_NORMAL, + SPEED_HASTED +}; + +enum brand_type // equivalent to (you.inv[].special or mitm[].special) % 30 { SPWPN_NORMAL, // 0 SPWPN_FLAMING, @@ -2657,7 +2921,7 @@ enum SPECIAL_WEAPONS // equivalent to (you.inv[].special or mitm[].special) % 30 SPWPN_STAFF_OF_WUCAD_MU // 195 }; -enum SPECIAL_WIELD // you.special_wield +enum special_wield_type // you.special_wield { SPWLD_NONE, // 0 SPWLD_SING, @@ -2677,7 +2941,7 @@ enum SPECIAL_WIELD // you.special_wield SPWLD_SHOUT // 54 - see it_use3::special_wielded() {dlb} }; -enum SPECIES +enum species_type { SP_HUMAN = 1, // 1 SP_ELF, @@ -2707,7 +2971,7 @@ enum SPECIES SP_PALE_DRACONIAN, SP_UNK0_DRACONIAN, SP_UNK1_DRACONIAN, - SP_UNK2_DRACONIAN, + SP_BASE_DRACONIAN, SP_CENTAUR, // 30 SP_DEMIGOD, SP_SPRIGGAN, @@ -2721,7 +2985,7 @@ enum SPECIES SP_UNKNOWN = 100 }; -enum SPELLS +enum spell_type { SPELL_IDENTIFY, // 0 SPELL_TELEPORT_SELF, @@ -2905,19 +3169,18 @@ enum SPELLS SPELL_AIR_WALK, // "dematerialize" (air/transmigration) SPELL_SANDBLAST, // mini-frag; can use stones for material comp 195 SPELL_ROTTING, // evil god power or necromantic transmigration - SPELL_SHUGGOTH_SEED, // evil god power or necromantic summoning SPELL_MAXWELLS_SILVER_HAMMER, // vorpal-brand maces etc. SPELL_CONDENSATION_SHIELD, // "shield" of icy vapour - SPELL_SEMI_CONTROLLED_BLINK, //jmf: to test effect 200 - SPELL_STONESKIN, + SPELL_SEMI_CONTROLLED_BLINK, //jmf: to test effect + SPELL_STONESKIN, // 200 SPELL_SIMULACRUM, SPELL_CONJURE_BALL_LIGHTNING, - SPELL_CHAIN_LIGHTNING, // 204 (be wary of 209/210, see below) + SPELL_CHAIN_LIGHTNING, // 203 (be wary of 209/210, see below) NUM_SPELLS, SPELL_NO_SPELL = 210 // 210 - added 22jan2000 {dlb} }; -enum SPELL_FLAGS +enum spflag_type { SPFLAG_NONE = 0x0000, SPFLAG_DIR_OR_TARGET = 0x0001, // use DIR_NONE targeting @@ -2930,7 +3193,14 @@ enum SPELL_FLAGS SPFLAG_UNHOLY = 0x0040 // counts at "unholy" }; -enum SPELL_TYPES //jmf: 24jul2000: changed from integer-list to bitfield +enum spret_type +{ + SPRET_ABORT = 0, // should be left as 0 + SPRET_FAIL, + SPRET_SUCCESS +}; + +enum spschool_flag_type { SPTYP_NONE = 0, // "0" is reserved for no type at all {dlb} SPTYP_CONJURATION = 1, // was 11, but only for old typematch routine {dlb} @@ -2951,13 +3221,13 @@ enum SPELL_TYPES //jmf: 24jul2000: changed from integer-list to bitfield SPTYP_RANDOM = 1<<14 }; -enum SLOT_SELECT_MODES +enum slot_select_mode { SS_FORWARD = 0, SS_BACKWARD = 1 }; -enum STATS +enum stat_type { STAT_STRENGTH, // 0 STAT_DEXTERITY, @@ -2967,14 +3237,14 @@ enum STATS STAT_RANDOM = 255 // leave at 255, added for increase_stats() handling {dlb} }; -enum STATUE_TYPES +enum statue_type { STATUE_SILVER, STATUE_ORANGE_CRYSTAL, NUM_STATUE_TYPES }; -enum STATUS_REDRAW_FLAGS +enum status_redraw_flag_type { REDRAW_HUNGER = 0x00000001, REDRAW_BURDEN = 0x00000002, @@ -3000,7 +3270,7 @@ enum STATUS_REDRAW_FLAGS REDRAW_LINE_3_MASK = 0x007f0000 }; -enum STAVES +enum stave_type { STAFF_WIZARDRY, // 0 STAFF_POWER, @@ -3028,7 +3298,8 @@ enum STAVES NUM_STAVES // must remain last member {dlb} }; -enum SYMBOLS // beam[].type - note that this (and its variants) also accepts values from other enums - confusing {dlb} +// beam[].type - note that this (and its variants) also accepts values from other enums - confusing {dlb} +enum zap_symbol_type { SYM_SPACE = ' ', // 32 SYM_FLASK = '!', // 33 @@ -3043,10 +3314,11 @@ enum SYMBOLS // beam[].type - note that this (and its variants) also accepts val SYM_SCROLL = '?', // 63 SYM_DEBUG = 'X', // 88 SYM_ARMOUR = '[', // 91 - SYM_MISSILE = '`' // 96 + SYM_MISSILE = '`', // 96 + SYM_EXPLOSION = '#' }; -enum TAGS // used during save/load process to identify data blocks +enum tag_type // used during save/load process to identify data blocks { TAG_VERSION = 0, // should NEVER be read in! TAG_YOU = 1, // 'you' structure @@ -3060,7 +3332,7 @@ enum TAGS // used during save/load process to identify data blocks NUM_TAGS }; -enum TAGTYPES // file types supported by tag system +enum tag_file_type // file types supported by tag system { TAGTYPE_PLAYER=0, // Foo.sav TAGTYPE_LEVEL, // Foo.00a, .01a, etc. @@ -3068,7 +3340,7 @@ enum TAGTYPES // file types supported by tag system }; -enum TRANSFORMATIONS +enum transformation_type { TRAN_NONE, // 0 TRAN_SPIDER, @@ -3082,7 +3354,7 @@ enum TRANSFORMATIONS NUM_TRANSFORMATIONS // must remain last member {dlb} }; -enum TRAPS // env.trap_type[] +enum trap_type // env.trap_type[] { TRAP_DART, // 0 TRAP_ARROW, @@ -3096,10 +3368,11 @@ enum TRAPS // env.trap_type[] TRAP_NEEDLE, NUM_TRAPS, // must remain last 'regular' member {dlb} TRAP_UNASSIGNED = 100, // keep set at 100 for now {dlb} + TRAP_NONTELEPORT = 254, TRAP_RANDOM = 255 // set at 255 to avoid potential conflicts {dlb} }; -enum UNARMED_ATTACKS +enum unarmed_attack_type { UNAT_NO_ATTACK, // 0 UNAT_KICK, @@ -3108,31 +3381,150 @@ enum UNARMED_ATTACKS UNAT_PUNCH }; -enum UNDEAD_STATES // you.is_undead +enum undead_state_type // you.is_undead { US_ALIVE, // 0 US_HUNGRY_DEAD, US_UNDEAD }; -enum UNIQUE_ITEM_STATUS +enum unique_item_status_type { UNIQ_NOT_EXISTS = 0, UNIQ_EXISTS = 1, UNIQ_LOST_IN_ABYSS = 2 }; -enum VORPAL_DESCRIPTIONS -{ - DVORP_CRUSHING, // 0 - DVORP_SLICING, - DVORP_PIERCING, - DVORP_CHOPPING +// NOTE: THE ORDER AND VALUE OF THESE IS CURRENTLY VERY IMPORTANT! +enum vault_type +{ + VAULT_VAULT_1 = 0, + VAULT_VAULT_2 = 1, + VAULT_VAULT_3 = 2, + VAULT_VAULT_4 = 3, + VAULT_VAULT_5 = 4, + VAULT_VAULT_6 = 5, + VAULT_VAULT_7 = 6, + VAULT_VAULT_8 = 7, + VAULT_VAULT_9 = 8, + VAULT_VAULT_10 = 9, + VAULT_ORC_TEMPLE = 10, + VAULT_FARM_AND_COUNTRY = 11, + VAULT_FORT_YAKTAUR = 12, + VAULT_BOX_LEVEL = 13, + VAULT_MY_MAP = 14, + + VAULT_VESTIBULE_MAP = 50, + VAULT_CASTLE_DIS = 51, + VAULT_ASMODEUS = 52, + VAULT_ANTAEUS = 53, + VAULT_ERESHKIGAL = 54, + + VAULT_MNOLEG = 60, + VAULT_LOM_LOBON = 61, + VAULT_CEREBOV = 62, + VAULT_GLOORX_VLOQ = 63, + // VAULT_MOLLUSC = 64, + + VAULT_BEEHIVE = 80, + VAULT_SLIME_PIT = 81, + VAULT_BOTTOM_OF_VAULTS = 82, + VAULT_HALL_OF_BLADES = 83, + VAULT_HALL_OF_ZOT = 84, + VAULT_TEMPLE = 85, + VAULT_SNAKE_PIT = 86, + VAULT_ELF_HALL = 87, + VAULT_TOMB_1 = 88, + VAULT_TOMB_2 = 89, + VAULT_TOMB_3 = 90, + VAULT_SWAMP = 91, + + VAULT_RANDOM = 100, + + VAULT_MINIVAULT_1 = 200, + VAULT_MINIVAULT_2 = 201, + VAULT_MINIVAULT_3 = 202, + VAULT_MINIVAULT_4 = 203, + VAULT_MINIVAULT_5 = 204, + VAULT_MINIVAULT_6 = 205, + VAULT_MINIVAULT_7 = 206, + VAULT_MINIVAULT_8 = 207, + VAULT_MINIVAULT_9 = 208, + VAULT_MINIVAULT_10 = 209, + VAULT_MINIVAULT_11 = 210, + VAULT_MINIVAULT_12 = 211, + VAULT_MINIVAULT_13 = 212, + VAULT_MINIVAULT_14 = 213, + VAULT_MINIVAULT_15 = 214, + VAULT_MINIVAULT_16 = 215, + VAULT_MINIVAULT_17 = 216, + VAULT_MINIVAULT_18 = 217, + VAULT_MINIVAULT_19 = 218, + VAULT_MINIVAULT_20 = 219, + VAULT_MINIVAULT_21 = 220, + VAULT_MINIVAULT_22 = 221, + VAULT_MINIVAULT_23 = 222, + VAULT_MINIVAULT_24 = 223, + VAULT_MINIVAULT_25 = 224, + VAULT_MINIVAULT_26 = 225, + VAULT_MINIVAULT_27 = 226, + VAULT_MINIVAULT_28 = 227, + VAULT_MINIVAULT_29 = 228, + VAULT_MINIVAULT_30 = 229, + VAULT_MINIVAULT_31 = 230, + VAULT_MINIVAULT_32 = 231, + VAULT_MINIVAULT_33 = 232, + VAULT_MINIVAULT_34 = 233, + VAULT_MINIVAULT_35 = 234, + + VAULT_RAND_DEMON_1 = 300, + VAULT_RAND_DEMON_2 = 301, + VAULT_RAND_DEMON_3 = 302, + VAULT_RAND_DEMON_4 = 303, + VAULT_RAND_DEMON_5 = 304, + VAULT_RAND_DEMON_6 = 305, + VAULT_RAND_DEMON_7 = 306, + VAULT_RAND_DEMON_8 = 307, + VAULT_RAND_DEMON_9 = 308 +}; + +enum vorpal_damage_type +{ + // Types of damage a weapon can do... currently assuming that anything + // with BLUDGEON always does "AND" with any other specified types, + // and and sets not including BLUDGEON are "OR". + DAM_BASH = 0x0000, // non-melee weapon blugeoning + DAM_BLUDGEON = 0x0001, // crushing + DAM_SLICE = 0x0002, // slicing/chopping + DAM_PIERCE = 0x0004, // stabbing/piercing + DAM_WHIP = 0x0008, // whip slashing (no butcher) + + // These are used for vorpal weapon desc (don't set more than one) + DVORP_NONE = 0x0000, // used for non-melee weapons + DVORP_CRUSHING = 0x1000, + DVORP_SLICING = 0x2000, + DVORP_PIERCING = 0x3000, + DVORP_CHOPPING = 0x4000, // used for axes + DVORP_SLASHING = 0x5000, // used for whips + DVORP_STABBING = 0x6000, // used for knives/daggers + + // These are shortcuts to tie vorpal/damage types for easy setting... + // as above, setting more than one vorpal type is trouble. + DAMV_NON_MELEE = DVORP_NONE | DAM_BASH, // launchers + DAMV_CRUSHING = DVORP_CRUSHING | DAM_BLUDGEON, + DAMV_SLICING = DVORP_SLICING | DAM_SLICE, + DAMV_PIERCING = DVORP_PIERCING | DAM_PIERCE, + DAMV_CHOPPING = DVORP_CHOPPING | DAM_SLICE, + DAMV_SLASHING = DVORP_SLASHING | DAM_WHIP, + DAMV_STABBING = DVORP_STABBING | DAM_PIERCE, + + DAM_MASK = 0x0fff, // strips vorpal specification + DAMV_MASK = 0xf000 // strips non-vorpal specification }; // NOTE: This order is very special! Its basically the same as ZAP_*, // and there are bits of the code that still use that fact.. see zap_wand(). -enum WANDS // mitm[].subtype +enum wand_type // mitm[].subtype { WAND_FLAME, // 0 WAND_FROST, @@ -3157,7 +3549,7 @@ enum WANDS // mitm[].subtype NUM_WANDS // must remain last member {dlb} }; -enum WEAPONS +enum weapon_type { // Base weapons WPN_CLUB, // 0 @@ -3203,19 +3595,24 @@ enum WEAPONS WPN_TRIDENT, WPN_SPIKED_FLAIL, WPN_GREAT_MACE, - WPN_GREAT_FLAIL, // 40 + WPN_DIRE_FLAIL, // 40 WPN_KNIFE, WPN_BLOWGUN, WPN_FALCHION, WPN_BLESSED_BLADE, // 44 - NUM_WEAPONS, // 45 - must be last regular member {dlb} + WPN_LONGBOW, + WPN_LAJATANG, + WPN_LOCHABER_AXE, + + NUM_WEAPONS, // 48 - must be last regular member {dlb} + // special cases WPN_UNARMED = 500, // 500 WPN_UNKNOWN = 1000, // 1000 WPN_RANDOM }; -enum WEAPON_DESCRIPTIONS +enum weapon_description_type { DWPN_PLAIN = 0, // 0 - added to round out enum {dlb} DWPN_RUNED = 1, // 1 @@ -3225,7 +3622,7 @@ enum WEAPON_DESCRIPTIONS DWPN_DWARVEN // 5 }; -enum WEAPON_PROPERTIES +enum weapon_property_type { PWPN_DAMAGE, // 0 PWPN_HIT, @@ -3234,7 +3631,7 @@ enum WEAPON_PROPERTIES #ifdef WIZARD -enum WIZARD_OPTIONS +enum wizard_option_type { WIZ_NEVER, // protect player from accidental wiz WIZ_NO, // don't start character in wiz mode @@ -3243,7 +3640,7 @@ enum WIZARD_OPTIONS #endif -enum ZAPS // zapping(), zappy() +enum zap_type { ZAP_FLAME, // 0 ZAP_FROST, @@ -3292,7 +3689,7 @@ enum ZAPS // zapping(), zappy() ZAP_AGONY, ZAP_DISRUPTION, // 45 ZAP_DISINTEGRATION, // 46 - ZAP_ISKS_CROSS, // 47: Isk's Cross -- commented out, deprecated {dlb} + // ZAP_ISKS_CROSS, // 47: Isk's Cross -- commented out, deprecated {dlb} ZAP_BREATHE_STEAM = 48, // 48 ZAP_CONTROL_DEMON, ZAP_ORB_OF_FRAGMENTATION, // 50 @@ -3305,8 +3702,18 @@ enum ZAPS // zapping(), zappy() ZAP_SMALL_SANDBLAST, ZAP_MAGMA, ZAP_POISON_ARROW, + ZAP_BREATHE_STICKY_FLAME, + ZAP_BREATHE_LIGHTNING, + ZAP_PETRIFY, + ZAP_HELLFROST, NUM_ZAPS // must remain last member {dlb} }; +enum zombie_size_type +{ + Z_NOZOMBIE, + Z_SMALL, + Z_BIG +}; #endif // ENUM_H diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index b9c4b5d3f7..afa9084e8b 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -74,36 +74,36 @@ const int kPathLen = 256; struct monsters; struct ait_hp_loss; -struct activity_interrupt_t +struct activity_interrupt_data { - AI_PAYLOAD apt; + activity_interrupt_payload_type apt; const void *data; - activity_interrupt_t() + activity_interrupt_data() : apt(AIP_NONE), data(NULL) { } - activity_interrupt_t(const int *i) + activity_interrupt_data(const int *i) : apt(AIP_INT), data(i) { } - activity_interrupt_t(const char *s) + activity_interrupt_data(const char *s) : apt(AIP_STRING), data(s) { } - activity_interrupt_t(const std::string &s) + activity_interrupt_data(const std::string &s) : apt(AIP_STRING), data(s.c_str()) { } - activity_interrupt_t(const monsters *m) + activity_interrupt_data(const monsters *m) : apt(AIP_MONSTER), data(m) { } - activity_interrupt_t(const ait_hp_loss *ahl) + activity_interrupt_data(const ait_hp_loss *ahl) : apt(AIP_HP_LOSS), data(ahl) { } - activity_interrupt_t(const activity_interrupt_t &a) + activity_interrupt_data(const activity_interrupt_data &a) : apt(a.apt), data(a.data) { } @@ -172,23 +172,36 @@ struct bolt char ex_size; // explosion radius (0==none) int beam_source; // NON_MONSTER or monster index # char beam_name[40]; - bool isBeam; // beams? (can hits multiple targets?) + bool is_beam; // beams? (can hits multiple targets?) + bool is_explosion; + bool is_big_cloud; // expands into big_cloud at endpoint + bool is_enchant; // no block/dodge, but mag resist + bool is_energy; // mostly energy/non-physical attack + bool is_launched; // was fired from launcher? + bool is_thrown; // was thrown from hand? + bool target_first; // targeting by direction const char *aux_source; // source of KILL_MISC beams // OUTPUT parameters (tracing, ID) - bool obviousEffect; // did an 'obvious' effect happen? + bool obvious_effect; // did an 'obvious' effect happen? int fr_count, foe_count; // # of times a friend/foe is "hit" int fr_power, foe_power; // total levels/hit dice affected // INTERNAL use - should not usually be set outside of beam.cc - bool isTracer; // is this a tracer? - bool aimedAtFeet; // this was aimed at self! - bool msgGenerated; // an appropriate msg was already mpr'd - bool isExplosion; // explosion phase (as opposed to beam phase) - bool smartMonster; // tracer firer can guess at other mons. resists? - bool canSeeInvis; // tracer firer can see invisible? - bool isFriendly; // tracer firer is enslaved or pet - int foeRatio; // 100* foe ratio (see mons_should_fire()) + bool is_tracer; // is this a tracer? + bool aimed_at_feet; // this was aimed at self! + bool msg_generated; // an appropriate msg was already mpr'd + bool in_explosion_phase; // explosion phase (as opposed to beam phase) + bool smart_monster; // tracer firer can guess at other mons. resists? + bool can_see_invis; // tracer firer can see invisible? + bool is_friendly; // tracer firer is enslaved or pet + int foe_ratio; // 100* foe ratio (see mons_should_fire()) + + // A contstructor to try and fix some of the bugs that occur because + // this struct never seems to be properly initialized. Definition + // is over in misc.cc for lack of a better place (short of inlining + // it here). + bolt(); }; @@ -258,7 +271,8 @@ private: struct player { - ACTIVITY activity; // The current multiturn activity, usually set to ACT_NONE + activity_type activity; // The current multiturn activity, usually set + // to ACT_NONE char turn_is_over; // flag signaling that player has performed a timed action unsigned char prev_targ; @@ -644,6 +658,7 @@ private: struct game_options { + bool ascii_display; // Defaults to true ifdef USE_ASCII_CHARACTERS long autopickups; // items to autopickup bool verbose_dump; // make character dumps contain more detail bool detailed_stat_dump; // add detailed stat and resist dump diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index d8e10dd5fd..2b59c92f03 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -48,6 +48,7 @@ #include "it_use2.h" #include "items.h" #include "itemname.h" +#include "itemprop.h" #include "macro.h" #include "misc.h" #include "monplace.h" @@ -229,7 +230,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) bool use_hand_and_a_half_bonus = false; int wpn_skill = SK_UNARMED_COMBAT; - int hands_reqd = HANDS_ONE_HANDED; + int hands_reqd = HANDS_ONE; if (weapon != -1) { @@ -243,8 +244,8 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (unarmed_attacks && !can_do_unarmed_combat && !bearing_shield && ur_armed - && item_uncursed( you.inv[ weapon ] ) - && hands_reqd == HANDS_ONE_OR_TWO_HANDED) + && !item_cursed( you.inv[ weapon ] ) + && hands_reqd == HANDS_HALF) { // currently: +1 dam, +1 hit, -1 spd (loosly) use_hand_and_a_half_bonus = true; @@ -368,7 +369,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) your_to_hit += you.inv[ weapon ].plus; your_to_hit += property( you.inv[ weapon ], PWPN_HIT ); - if (cmp_equip_race( you.inv[ weapon ], ISFLAG_ELVEN ) + if (get_equip_race(you.inv[ weapon ]) == ISFLAG_ELVEN && player_genus(GENPC_ELVEN)) { your_to_hit += (coinflip() ? 2 : 1); @@ -513,7 +514,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) min_speed = 5; // Using both hands can get a weapon up to speed 7 - if ((hands_reqd == HANDS_TWO_HANDED || use_hand_and_a_half_bonus) + if ((hands_reqd == HANDS_TWO || use_hand_and_a_half_bonus) && min_speed > 7) { min_speed = 7; @@ -745,13 +746,13 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (use_hand_and_a_half_bonus) damage_done += random2(3); - if (cmp_equip_race( you.inv[ weapon ], ISFLAG_DWARVEN ) + if (get_equip_race(you.inv[ weapon ]) == ISFLAG_DWARVEN && player_genus(GENPC_DWARVEN)) { damage_done += random2(3); } - if (cmp_equip_race( you.inv[ weapon ], ISFLAG_ORCISH ) + if (get_equip_race(you.inv[ weapon ]) == ISFLAG_ORCISH && you.species == SP_HILL_ORC && coinflip()) { damage_done++; @@ -762,7 +763,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) #endif if (!launches_things( you.inv[ weapon ].sub_type ) - && item_not_ident( you.inv[ weapon ], ISFLAG_KNOW_PLUSES ) + && !item_ident( you.inv[ weapon ], ISFLAG_KNOW_PLUSES ) && random2(100) < you.skills[ wpn_skill ]) { set_ident_flags( you.inv[ weapon ], ISFLAG_KNOW_PLUSES ); @@ -784,8 +785,8 @@ void you_attack(int monster_attacked, bool unarmed_attacks) exercise(SK_STABBING, 1 + random2avg(5, 4)); - if (mons_holiness(defender->type) == MH_NATURAL - || mons_holiness(defender->type) == MH_HOLY) + if (mons_holiness(defender) == MH_NATURAL + || mons_holiness(defender) == MH_HOLY) { did_god_conduct(DID_STABBING, 4); } @@ -920,7 +921,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) #endif if (ur_armed && melee_brand == SPWPN_VAMPIRICISM) { - if (mons_holiness(defender->type) == MH_NATURAL + if (mons_holiness(defender) == MH_NATURAL && damage_done > 0 && you.hp < you.hp_max && !one_chance_in(5)) { @@ -1005,7 +1006,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) mpr(info); - if (mons_holiness(defender->type) == MH_HOLY) + if (mons_holiness(defender) == MH_HOLY) did_god_conduct(DID_KILL_ANGEL, 1); if (you.special_wield == SPWLD_TORMENT) @@ -1041,7 +1042,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) did_god_conduct(DID_UNHOLY, 1); } - if (mons_holiness(defender->type) == MH_HOLY) + if (mons_holiness(defender) == MH_HOLY) did_god_conduct(DID_ATTACK_HOLY, defender->hit_dice); if (defender->type == MONS_HYDRA) @@ -1231,7 +1232,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) { dec_mp(STAFF_COST); - if (item_not_ident( you.inv[weapon], ISFLAG_KNOW_TYPE )) + if (!item_ident( you.inv[weapon], ISFLAG_KNOW_TYPE )) { set_ident_flags( you.inv[weapon], ISFLAG_KNOW_TYPE ); strcpy(info, "You are wielding "); @@ -1319,7 +1320,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) // there should be a case in here for holy monsters, // see elsewhere in fight.cc {dlb} specdam = 0; - switch (mons_holiness(defender->type)) + switch (mons_holiness(defender)) { case MH_UNDEAD: specdam = 1 + random2(damage_done); @@ -1328,6 +1329,9 @@ void you_attack(int monster_attacked, bool unarmed_attacks) case MH_DEMONIC: specdam = 1 + (random2(damage_done * 15) / 10); break; + + default: + break; } break; @@ -1347,7 +1351,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) break; case SPWPN_ORC_SLAYING: - if (mons_charclass(defender->type) == MONS_ORC) + if (mons_species(defender->type) == MONS_ORC) hurt_monster(defender, 1 + random2(damage_done)); break; @@ -1390,7 +1394,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) case SPWPN_VAMPIRICISM: specdam = 0; // NB: does no extra damage - if (mons_holiness(defender->type) != MH_NATURAL) + if (mons_holiness(defender) != MH_NATURAL) break; else if (mons_res_negative_energy(defender) > 0) break; @@ -1419,7 +1423,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) case SPWPN_DISRUPTION: specdam = 0; - if (mons_holiness(defender->type) == MH_UNDEAD && !one_chance_in(3)) + if (mons_holiness(defender) == MH_UNDEAD && !one_chance_in(3)) { simple_monster_message(defender, " shudders."); specdam += random2avg((1 + (damage_done * 3)), 3); @@ -1611,13 +1615,13 @@ void you_attack(int monster_attacked, bool unarmed_attacks) sc_dam += 5; if (you.equip[EQ_HELMET] != -1 - && (cmp_helmet_type( you.inv[you.equip[EQ_HELMET]], THELM_HELMET ) - || cmp_helmet_type( you.inv[you.equip[EQ_HELMET]], THELM_HELM ))) + && (get_helmet_type(you.inv[you.equip[EQ_HELMET]]) == THELM_HELMET + || get_helmet_type(you.inv[you.equip[EQ_HELMET]]) == THELM_HELM)) { sc_dam += 2; - if (cmp_helmet_desc( you.inv[you.equip[EQ_HELMET]], THELM_DESC_SPIKED ) - || cmp_helmet_desc( you.inv[you.equip[EQ_HELMET]], THELM_DESC_HORNED )) + if (get_helmet_desc(you.inv[you.equip[EQ_HELMET]]) == THELM_DESC_SPIKED + || get_helmet_desc(you.inv[you.equip[EQ_HELMET]]) == THELM_DESC_HORNED) { sc_dam += 3; } @@ -1679,7 +1683,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) /* no punching with a shield or 2-handed wpn, except staves */ if (bearing_shield || coinflip() - || (ur_armed && hands_reqd == HANDS_TWO_HANDED + || (ur_armed && hands_reqd == HANDS_TWO && you.inv[weapon].base_type != OBJ_STAVES && you.inv[weapon].sub_type != WPN_QUARTERSTAFF) ) { @@ -1796,7 +1800,7 @@ void you_attack(int monster_attacked, bool unarmed_attacks) if (brand == SPWPN_VENOM && coinflip()) poison_monster( defender, true ); - if (mons_holiness(defender->type) == MH_HOLY) + if (mons_holiness(defender) == MH_HOLY) did_god_conduct(DID_KILL_ANGEL, 1); hit = true; @@ -1909,7 +1913,7 @@ void monster_attack(int monster_attacking) return; if (you.duration[DUR_REPEL_UNDEAD] - && mons_holiness( attacker->type ) == MH_UNDEAD + && mons_holiness( attacker ) == MH_UNDEAD && !check_mons_resist_magic( attacker, you.piety )) { simple_monster_message(attacker, @@ -2025,12 +2029,12 @@ void monster_attack(int monster_attacking) + (5 * you.shield_blocks * you.shield_blocks)); // Factors for blocking: - // [dshaligram] Increased dex weight from .2 to .3333, added weighting - // for shields skill. - const int pro_block = player_shield_class() + (random2(you.dex) / 5); + // [dshaligram] Added weighting for shields skill, increased dex bonus + // from .2 to .25 + const int pro_block = random2(player_shield_class()) - + (random2(you.dex) / 3) - + (random2(skill_bump(SK_SHIELDS)) / 3) + + (random2(you.dex) / 4) + + (random2(skill_bump(SK_SHIELDS)) / 4) - 1; if (!you.paralysis && !you_are_delayed() && !you.conf @@ -2078,8 +2082,8 @@ void monster_attack(int monster_attacking) damage_taken = random2(damage_size); - if (cmp_equip_race(mitm[attacker->inv[hand_used]],ISFLAG_ORCISH) - && mons_charclass(attacker->type) == MONS_ORC + if (get_equip_race(mitm[attacker->inv[hand_used]]) == ISFLAG_ORCISH + && mons_species(attacker->type) == MONS_ORC && coinflip()) { damage_taken++; @@ -2182,7 +2186,7 @@ void monster_attack(int monster_attacking) { if (you.equip[EQ_BODY_ARMOUR] != -1) { - const int body_arm_mass = mass_item( you.inv[you.equip[EQ_BODY_ARMOUR]] ); + const int body_arm_mass = item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] ); if (!player_light_armour() && coinflip() && random2(1000) <= body_arm_mass) @@ -3047,8 +3051,8 @@ bool monsters_fight(int monster_attacking, int monster_attacked) damage_taken = random2(property( mitm[attacker->inv[hand_used]], PWPN_DAMAGE )); - if (cmp_equip_race(mitm[attacker->inv[hand_used]],ISFLAG_ORCISH) - && mons_charclass(attacker->type) == MONS_ORC + if (get_equip_race(mitm[attacker->inv[hand_used]]) == ISFLAG_ORCISH + && mons_species(attacker->type) == MONS_ORC && coinflip()) { damage_taken++; @@ -3463,7 +3467,7 @@ bool monsters_fight(int monster_attacking, int monster_attacked) if (attacker->type == MONS_PLAYER_GHOST) break; specdam = 0; - switch (mons_holiness(defender->type)) + switch (mons_holiness(defender)) { case MH_HOLY: // I would think that it would do zero damage {dlb} @@ -3477,6 +3481,9 @@ bool monsters_fight(int monster_attacking, int monster_attacked) case MH_DEMONIC: specdam += 1 + (random2(damage_taken) * 15) / 10; break; + + default: + break; } break; @@ -3508,7 +3515,7 @@ bool monsters_fight(int monster_attacking, int monster_attacked) break; case SPWPN_ORC_SLAYING: - if (mons_charclass(defender->type) == MONS_ORC) + if (mons_species(defender->type) == MONS_ORC) hurt_monster(defender, 1 + random2(damage_taken)); break; @@ -3575,7 +3582,7 @@ bool monsters_fight(int monster_attacking, int monster_attacked) specdam = 0; - if (mons_holiness(defender->type) == MH_UNDEAD + if (mons_holiness(defender) == MH_UNDEAD && !one_chance_in(3)) { simple_monster_message(defender, " shudders."); @@ -3767,6 +3774,7 @@ static int weapon_type_modify( int weapnum, char noise[80], char noise2[80], return (damage); case WPN_BOW: + case WPN_LONGBOW: case WPN_CROSSBOW: case WPN_HAND_CROSSBOW: if (damage < HIT_STRONG) @@ -3788,6 +3796,7 @@ static int weapon_type_modify( int weapnum, char noise[80], char noise2[80], case WPN_SCYTHE: case WPN_QUICK_BLADE: case WPN_KATANA: + case WPN_LAJATANG: case WPN_EXECUTIONERS_AXE: case WPN_DOUBLE_SWORD: case WPN_TRIPLE_SWORD: @@ -3810,7 +3819,7 @@ static int weapon_type_modify( int weapnum, char noise[80], char noise2[80], case WPN_MACE: case WPN_FLAIL: case WPN_GREAT_MACE: - case WPN_GREAT_FLAIL: + case WPN_DIRE_FLAIL: case WPN_QUARTERSTAFF: case WPN_GIANT_CLUB: case WPN_HAMMER: @@ -3911,7 +3920,7 @@ int weapon_str_weight( int wpn_class, int wpn_type ) else if (wpn_type == WPN_QUICK_BLADE) // high dex is very good for these ret = 1; - if (hands_reqd == HANDS_TWO_HANDED) + if (hands_reqd == HANDS_TWO) ret += 2; // most weapons are capped at 8 @@ -3945,7 +3954,7 @@ static inline int player_weapon_str_weight( void ) const int hands_reqd = hands_reqd_for_weapon( you.inv[weapon].base_type, you.inv[weapon].sub_type ); - if (hands_reqd == HANDS_ONE_OR_TWO_HANDED && !shield) + if (hands_reqd == HANDS_HALF && !shield) ret += 1; return (ret); diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index 51b09a0bf9..6c13965702 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -24,6 +24,7 @@ #include "AppHdr.h" #include "files.h" +#include "version.h" #include <string.h> #include <string> @@ -66,6 +67,7 @@ #include "debug.h" #include "dungeon.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "message.h" #include "misc.h" @@ -320,7 +322,7 @@ bool travel_load_map( char branch, int absdepth ) char minorVersion; if (!determine_level_version( levelFile, majorVersion, minorVersion ) - || majorVersion != 4) + || majorVersion != SAVE_MAJOR_VERSION) { fclose(levelFile); return false; @@ -967,7 +969,8 @@ void save_level(int level_saved, bool was_a_labyrinth, char where_were_you) // 4.7 origin tracking for items // 4.8 widened env.map to 2 bytes - write_tagged_file( saveFile, 4, 8, TAGTYPE_LEVEL ); + // [dshaligram] Winding major version back all the way to 0. + write_tagged_file( saveFile, SAVE_MAJOR_VERSION, 8, TAGTYPE_LEVEL ); fclose(saveFile); @@ -1108,7 +1111,7 @@ void save_game(bool leave_game) // 4.4 added item origins // 4.5 added num_gifts - write_tagged_file( saveFile, 4, 5, TAGTYPE_PLAYER ); + write_tagged_file( saveFile, SAVE_MAJOR_VERSION, 5, TAGTYPE_PLAYER ); fclose(saveFile); @@ -1367,23 +1370,14 @@ static bool determine_version( FILE *restoreFile, if (read2(restoreFile, buf, 2) != 2) return false; // empty file? - // check for 3.30 - if (buf[0] == you.your_name[0] && buf[1] == you.your_name[1]) - { - majorVersion = 0; - minorVersion = 0; - rewind(restoreFile); - return true; - } - // otherwise, read version and validate. majorVersion = buf[0]; minorVersion = buf[1]; - if (majorVersion == 1 || majorVersion == 4) + if (majorVersion == SAVE_MAJOR_VERSION) return true; - return false; // if its not 1 or 4, no idea! + return false; // if its not 0, no idea } static void restore_version( FILE *restoreFile, @@ -1391,7 +1385,7 @@ static void restore_version( FILE *restoreFile, { // assuming the following check can be removed once we can read all // savefile versions. - if (majorVersion < 4) + if (majorVersion != SAVE_MAJOR_VERSION) { snprintf( info, INFO_SIZE, "\nSorry, this release cannot read a v%d.%d savefile.\n", majorVersion, minorVersion); @@ -1401,7 +1395,7 @@ static void restore_version( FILE *restoreFile, switch(majorVersion) { - case 4: + case SAVE_MAJOR_VERSION: restore_tagged_file(restoreFile, TAGTYPE_PLAYER, minorVersion); break; default: @@ -1442,23 +1436,14 @@ static bool determine_level_version( FILE *levelFile, if (read2(levelFile, buf, 2) != 2) return false; // empty file? - // check for 3.30 -- simply started right in with player name. - if (isprint(buf[0]) && buf[0] > 4) // who knows? - { - majorVersion = 0; - minorVersion = 0; - rewind(levelFile); - return true; - } - // otherwise, read version and validate. majorVersion = buf[0]; minorVersion = buf[1]; - if (majorVersion == 1 || majorVersion == 4) + if (majorVersion == SAVE_MAJOR_VERSION) return true; - return false; // if its not 1 or 4, no idea! + return false; // if its not SAVE_MAJOR_VERSION, no idea } static void restore_level_version( FILE *levelFile, @@ -1466,7 +1451,7 @@ static void restore_level_version( FILE *levelFile, { // assuming the following check can be removed once we can read all // savefile versions. - if (majorVersion < 4) + if (majorVersion != SAVE_MAJOR_VERSION) { snprintf( info, INFO_SIZE, "\nSorry, this release cannot read a v%d.%d level file.\n", majorVersion, minorVersion); @@ -1476,7 +1461,7 @@ static void restore_level_version( FILE *levelFile, switch(majorVersion) { - case 4: + case SAVE_MAJOR_VERSION: restore_tagged_file(levelFile, TAGTYPE_LEVEL, minorVersion); break; default: @@ -1505,43 +1490,20 @@ static bool determine_ghost_version( FILE *ghostFile, majorVersion = buf[0]; minorVersion = buf[1]; - if (majorVersion == 4) + if (majorVersion == SAVE_MAJOR_VERSION) return true; - return false; // if its not 4, no idea! -} - -static void restore_old_ghost( FILE *ghostFile ) -{ - char buf[41]; - - read2(ghostFile, buf, 41); // 41 causes EOF. 40 will not. - - // translate - memcpy( ghost.name, buf, 20 ); - - for (int i = 0; i < 20; i++) - ghost.values[i] = static_cast< unsigned short >( buf[i+20] ); - - if (ghost.values[ GVAL_RES_FIRE ] >= 97) - ghost.values[ GVAL_RES_FIRE ] -= 100; - - if (ghost.values[ GVAL_RES_COLD ] >= 97) - ghost.values[ GVAL_RES_COLD ] -= 100; + return false; // if its not SAVE_MAJOR_VERSION, no idea! } static void restore_ghost_version( FILE *ghostFile, char majorVersion, char minorVersion ) { - // currently, we can read all known ghost versions. switch(majorVersion) { - case 4: + case SAVE_MAJOR_VERSION: restore_tagged_file(ghostFile, TAGTYPE_GHOST, minorVersion); break; - case 0: - restore_old_ghost(ghostFile); - break; default: break; } @@ -1642,7 +1604,7 @@ void save_ghost( bool force ) // 4.0-4.3 old tagged savefile (values as unsigned char) // 4.4 new tagged savefile (values as signed short) - write_tagged_file( gfile, 4, 4, TAGTYPE_GHOST ); + write_tagged_file( gfile, SAVE_MAJOR_VERSION, 4, TAGTYPE_GHOST ); fclose(gfile); @@ -1794,6 +1756,8 @@ unsigned char translate_spell(unsigned char spel) case MEPHITIC_CLOUD: return ; */ case SPELL_VENOM_BOLT: return (MS_VENOM_BOLT); + case SPELL_POISON_ARROW: + return (MS_POISON_ARROW); case SPELL_TELEPORT_OTHER: return (MS_TELEPORT_OTHER); case SPELL_SUMMON_SMALL_MAMMAL: @@ -1862,7 +1826,7 @@ void generate_random_demon(void) char st_p[ITEMNAME_SIZE]; - make_name(random2(250), random2(250), random2(250), 3, st_p); + make_name(random_int(), false, st_p); strcpy(ghost.name, st_p); // hp - could be defined below (as could ev, AC etc). Oh well, too late: diff --git a/crawl-ref/source/food.cc b/crawl-ref/source/food.cc index db95c533b8..eee0cd6a78 100644 --- a/crawl-ref/source/food.cc +++ b/crawl-ref/source/food.cc @@ -30,6 +30,7 @@ #include "invent.h" #include "items.h" #include "itemname.h" +#include "itemprop.h" #include "item_use.h" #include "it_use2.h" #include "macro.h" @@ -693,7 +694,7 @@ void eat_from_inventory(int which_inventory_slot) // this is a bit easier to read... most compilers should // handle this the same -- bwr const int mons_type = you.inv[ which_inventory_slot ].plus; - const int chunk_type = mons_corpse_thingy( mons_type ); + const int chunk_type = mons_corpse_effect( mons_type ); const bool rotten = (you.inv[which_inventory_slot].special < 100); eat_chunk( determine_chunk_effect( chunk_type, rotten ) ); @@ -711,7 +712,7 @@ void eat_floor_item(int item_link) { if (mitm[item_link].sub_type == FOOD_CHUNK) { - const int chunk_type = mons_corpse_thingy( mitm[item_link].plus ); + const int chunk_type = mons_corpse_effect( mitm[item_link].plus ); const bool rotten = (mitm[item_link].special < 100); eat_chunk( determine_chunk_effect( chunk_type, rotten ) ); diff --git a/crawl-ref/source/hiscores.cc b/crawl-ref/source/hiscores.cc index 9bbd391d41..f3aba604d1 100644 --- a/crawl-ref/source/hiscores.cc +++ b/crawl-ref/source/hiscores.cc @@ -439,8 +439,12 @@ void hiscores_format_single(char *buf, struct scorefile_entry &se) strcat( buf, " turned to stone" ); break; - case KILLED_BY_SHUGGOTH: - strcat( buf, " eviscerated by a hatching shuggoth" ); + case KILLED_BY_MELTING: + strcat( buf, " melted into a puddle" ); + break; + + case KILLED_BY_BLEEDING: + strcat( buf, " bled to death" ); break; case KILLED_BY_SOMETHING: @@ -838,9 +842,12 @@ int hiscores_format_single_long( char *buf, struct scorefile_entry &se, strcat( buf, "Turned to stone" ); break; - case KILLED_BY_SHUGGOTH: - strcat( buf, "Eviscerated by a hatching shuggoth" ); - needs_damage = true; + case KILLED_BY_MELTING: + strcat( buf, " melted into a puddle" ); + break; + + case KILLED_BY_BLEEDING: + strcat( buf, " bled to death" ); break; case KILLED_BY_SOMETHING: @@ -1725,8 +1732,10 @@ static void hs_search_death(char *inbuf, struct scorefile_entry &se) se.death_type = KILLED_BY_TSO_SMITING; else if (strstr(inbuf, "turned to stone") != NULL) se.death_type = KILLED_BY_PETRIFICATION; - else if (strstr(inbuf, "eviscerated by a hatching") != NULL) - se.death_type = KILLED_BY_SHUGGOTH; + else if (strstr(inbuf, "melted into a puddle") != NULL) + se.death_type = KILLED_BY_MELTING; + else if (strstr(inbuf, "bled to death") != NULL) + se.death_type = KILLED_BY_BLEEDING; // whew! diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc index c7458e9f62..0e64ebd602 100644 --- a/crawl-ref/source/initfile.cc +++ b/crawl-ref/source/initfile.cc @@ -357,6 +357,12 @@ void reset_options(bool clear_name) Options.prev_randpick = false; Options.remember_name = false; +#ifdef USE_ASCII_CHARACTERS + Options.ascii_display = true; +#else + Options.ascii_display = false; +#endif + Options.autopickups = 0x0000; Options.verbose_dump = false; Options.detailed_stat_dump = true; @@ -631,6 +637,32 @@ void read_options(const std::string &s, bool runscript) read_options(st, runscript); } +extern void (*viewwindow) (char, bool); +/* these are all defined in view.cc: */ +extern unsigned char (*mapch) (unsigned char); +extern unsigned char (*mapch2) (unsigned char); +unsigned char mapchar(unsigned char ldfk); +unsigned char mapchar2(unsigned char ldfk); +unsigned char mapchar3(unsigned char ldfk); +unsigned char mapchar4(unsigned char ldfk); +void apply_ascii_display(bool ascii) +{ + if (ascii) + { + // Default to the non-ibm set when it makes sense. + viewwindow = &viewwindow3; + mapch = &mapchar3; + mapch2 = &mapchar4; + } + else + { + // Use the standard ibm default + viewwindow = &viewwindow2; + mapch = &mapchar; + mapch2 = &mapchar2; + } +} + static void read_options(InitLineInput &il, bool runscript) { unsigned int line = 0; @@ -774,6 +806,8 @@ static void read_options(InitLineInput &il, bool runscript) } } #endif + + apply_ascii_display(Options.ascii_display); } static int str_to_killcategory(const std::string &s) @@ -899,6 +933,10 @@ void parse_option_line(const std::string &str, bool runscript) // gives verbose info in char dumps Options.verbose_dump = read_bool( field, Options.verbose_dump ); } + else if (key == "ascii_display") + { + Options.ascii_display = read_bool( field, Options.ascii_display ); + } else if (key == "detailed_stat_dump") { Options.detailed_stat_dump = diff --git a/crawl-ref/source/initfile.h b/crawl-ref/source/initfile.h index d5860fdd77..8be4ffad19 100644 --- a/crawl-ref/source/initfile.h +++ b/crawl-ref/source/initfile.h @@ -29,6 +29,8 @@ void read_options(const std::string &s, bool runscript = false); void parse_option_line(const std::string &line, bool runscript = false); +void apply_ascii_display(bool ascii); + // last updated 12may2000 {dlb} /* *********************************************************************** * called from: acr diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index c30ca12066..272cf8ba2b 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -27,6 +27,7 @@ #include "items.h" #include "it_use2.h" #include "itemname.h" +#include "itemprop.h" #include "misc.h" #include "monplace.h" #include "monstuff.h" @@ -497,8 +498,8 @@ bool evoke_wielded( void ) pract = (one_chance_in(5) ? 1 : 0); did_work = true; - if (item_not_ident( you.inv[you.equip[EQ_WEAPON]], - ISFLAG_KNOW_TYPE )) + if (!item_ident( you.inv[you.equip[EQ_WEAPON]], + ISFLAG_KNOW_TYPE )) { set_ident_flags( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE ); @@ -877,7 +878,8 @@ void tome_of_power(char sc_read_2) beam.thrower = KILL_YOU; beam.aux_source = "an exploding Tome of Power"; beam.ex_size = 2; - beam.isTracer = false; + beam.is_tracer = false; + beam.is_explosion = true; explosion(beam); return; diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 2307435db5..0e59c37712 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -45,6 +45,7 @@ #include "it_use3.h" #include "items.h" #include "itemname.h" +#include "itemprop.h" #include "misc.h" #include "monplace.h" #include "monstuff.h" @@ -90,7 +91,7 @@ bool can_wield(const item_def& weapon) return false; if ((you.species < SP_OGRE || you.species > SP_OGRE_MAGE) - && mass_item( weapon ) >= 500) + && item_mass( weapon ) >= 500) return false; if ((you.species == SP_HALFLING || you.species == SP_GNOME @@ -98,7 +99,7 @@ bool can_wield(const item_def& weapon) && (weapon.sub_type == WPN_GREAT_SWORD || weapon.sub_type == WPN_TRIPLE_SWORD || weapon.sub_type == WPN_GREAT_MACE - || weapon.sub_type == WPN_GREAT_FLAIL + || weapon.sub_type == WPN_DIRE_FLAIL || weapon.sub_type == WPN_BATTLEAXE || weapon.sub_type == WPN_EXECUTIONERS_AXE || weapon.sub_type == WPN_HALBERD @@ -109,7 +110,7 @@ bool can_wield(const item_def& weapon) return false; if (hands_reqd_for_weapon( weapon.base_type, - weapon.sub_type ) == HANDS_TWO_HANDED + weapon.sub_type ) == HANDS_TWO && you.equip[EQ_SHIELD] != -1) return false; @@ -247,7 +248,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) else { if ((you.species < SP_OGRE || you.species > SP_OGRE_MAGE) - && mass_item( you.inv[item_slot] ) >= 500) + && item_mass( you.inv[item_slot] ) >= 500) { mpr("That's too large and heavy for you to wield."); return (false); @@ -259,7 +260,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) && (you.inv[item_slot].sub_type == WPN_GREAT_SWORD || you.inv[item_slot].sub_type == WPN_TRIPLE_SWORD || you.inv[item_slot].sub_type == WPN_GREAT_MACE - || you.inv[item_slot].sub_type == WPN_GREAT_FLAIL + || you.inv[item_slot].sub_type == WPN_DIRE_FLAIL || you.inv[item_slot].sub_type == WPN_BATTLEAXE || you.inv[item_slot].sub_type == WPN_EXECUTIONERS_AXE || you.inv[item_slot].sub_type == WPN_HALBERD @@ -274,7 +275,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) } if (hands_reqd_for_weapon( you.inv[item_slot].base_type, - you.inv[item_slot].sub_type ) == HANDS_TWO_HANDED + you.inv[item_slot].sub_type ) == HANDS_TWO && you.equip[EQ_SHIELD] != -1) { mpr("You can't wield that with a shield."); @@ -617,37 +618,8 @@ void wear_armour(void) do_wear_armour( armour_wear_2, false ); } -int armour_equip_slot(const item_def &item) -{ - int wh_equip = EQ_BODY_ARMOUR; - - switch (item.sub_type) - { - case ARM_BUCKLER: - case ARM_LARGE_SHIELD: - case ARM_SHIELD: - wh_equip = EQ_SHIELD; - break; - case ARM_CLOAK: - wh_equip = EQ_CLOAK; - break; - case ARM_HELMET: - wh_equip = EQ_HELMET; - break; - case ARM_GLOVES: - wh_equip = EQ_GLOVES; - break; - case ARM_BOOTS: - wh_equip = EQ_BOOTS; - break; - } - return (wh_equip); -} - bool do_wear_armour( int item, bool quiet ) { - char wh_equip = 0; - if (!is_valid_item( you.inv[item] )) { if (!quiet) @@ -656,7 +628,8 @@ bool do_wear_armour( int item, bool quiet ) return (false); } - if (you.inv[item].base_type != OBJ_ARMOUR) + const int base_type = you.inv[item].base_type; + if (base_type != OBJ_ARMOUR) { if (!quiet) mpr("You can't wear that."); @@ -664,6 +637,10 @@ bool do_wear_armour( int item, bool quiet ) return (false); } + const int sub_type = you.inv[item].sub_type; + const item_def &invitem = you.inv[item]; + const equipment_type slot = get_armour_slot(invitem); + if (item == you.equip[EQ_WEAPON]) { if (!quiet) @@ -691,7 +668,7 @@ bool do_wear_armour( int item, bool quiet ) || you.inv[item].sub_type == ARM_LARGE_SHIELD) // weapon is two-handed && hands_reqd_for_weapon(you.inv[you.equip[EQ_WEAPON]].base_type, - you.inv[you.equip[EQ_WEAPON]].sub_type) == HANDS_TWO_HANDED) + you.inv[you.equip[EQ_WEAPON]].sub_type) == HANDS_TWO) { if (!quiet) mpr("You'd need three hands to do that!"); @@ -699,21 +676,26 @@ bool do_wear_armour( int item, bool quiet ) return (false); } - if (you.inv[item].sub_type == ARM_BOOTS) - { - if (you.species != SP_NAGA && you.inv[item].plus2 == TBOOT_NAGA_BARDING) - { - if (!quiet) - mpr("You can't wear that!"); + bool can_wear = true; + if (sub_type == ARM_NAGA_BARDING) + can_wear = (you.species == SP_NAGA); - return (false); - } + if (sub_type == ARM_CENTAUR_BARDING) + can_wear = (you.species == SP_CENTAUR); + + if (!can_wear) + { + if (!quiet) + mpr("You can't wear that!"); + return (false); + } - if (you.species != SP_CENTAUR && you.inv[item].plus2 == TBOOT_CENTAUR_BARDING) + if (you.inv[item].sub_type == ARM_BOOTS) + { + if (you.species == SP_NAGA || you.species == SP_CENTAUR) { if (!quiet) - mpr("You can't wear that!"); - + mpr("You can't wear that!"); return (false); } @@ -726,28 +708,24 @@ bool do_wear_armour( int item, bool quiet ) } } - wh_equip = armour_equip_slot(you.inv[item]); - - if (you.species == SP_NAGA && you.inv[item].sub_type == ARM_BOOTS - && you.inv[item].plus2 == TBOOT_NAGA_BARDING + if (you.species == SP_NAGA && sub_type == ARM_NAGA_BARDING && !player_is_shapechanged()) { // it fits } else if (you.species == SP_CENTAUR - && you.inv[item].sub_type == ARM_BOOTS - && you.inv[item].plus2 == TBOOT_CENTAUR_BARDING + && sub_type == ARM_CENTAUR_BARDING && !player_is_shapechanged()) { // it fits } - else if (you.inv[item].sub_type == ARM_HELMET - && (cmp_helmet_type( you.inv[item], THELM_CAP ) - || cmp_helmet_type( you.inv[item], THELM_WIZARD_HAT ))) + else if (sub_type == ARM_HELMET + && (get_helmet_type(invitem) == THELM_CAP + || get_helmet_type(invitem) == THELM_WIZARD_HAT)) { // caps & wiz hats always fit, unless your head's too big (ogres &c) } - else if (!can_equip( wh_equip )) + else if (!can_equip( slot )) { if (!quiet) mpr("You can't wear that in your present form."); @@ -757,8 +735,8 @@ bool do_wear_armour( int item, bool quiet ) // Cannot swim in heavy armour if (player_is_swimming() - && wh_equip == EQ_BODY_ARMOUR - && !is_light_armour( you.inv[item] )) + && slot == EQ_BODY_ARMOUR + && !is_light_armour( invitem )) { if (!quiet) mpr("You can't swim in that!"); @@ -770,14 +748,14 @@ bool do_wear_armour( int item, bool quiet ) if ((you.species >= SP_OGRE && you.species <= SP_OGRE_MAGE) || player_genus(GENPC_DRACONIAN)) { - if ((you.inv[item].sub_type >= ARM_LEATHER_ARMOUR - && you.inv[item].sub_type <= ARM_PLATE_MAIL) - || (you.inv[item].sub_type >= ARM_GLOVES - && you.inv[item].sub_type <= ARM_BUCKLER) - || you.inv[item].sub_type == ARM_CRYSTAL_PLATE_MAIL - || (you.inv[item].sub_type == ARM_HELMET - && (cmp_helmet_type( you.inv[item], THELM_HELM ) - || cmp_helmet_type( you.inv[item], THELM_HELMET )))) + if ((sub_type >= ARM_LEATHER_ARMOUR + && sub_type <= ARM_PLATE_MAIL) + || (sub_type >= ARM_GLOVES + && sub_type <= ARM_BUCKLER) + || sub_type == ARM_CRYSTAL_PLATE_MAIL + || (sub_type == ARM_HELMET + && (get_helmet_type(invitem) == THELM_HELM + || get_helmet_type(invitem) == THELM_HELMET))) { if (!quiet) mpr("This armour doesn't fit on your body."); @@ -789,16 +767,16 @@ bool do_wear_armour( int item, bool quiet ) // Tiny races if (you.species == SP_SPRIGGAN) { - if ((you.inv[item].sub_type >= ARM_LEATHER_ARMOUR - && you.inv[item].sub_type <= ARM_PLATE_MAIL) - || you.inv[item].sub_type == ARM_GLOVES - || you.inv[item].sub_type == ARM_BOOTS - || you.inv[item].sub_type == ARM_SHIELD - || you.inv[item].sub_type == ARM_LARGE_SHIELD - || you.inv[item].sub_type == ARM_CRYSTAL_PLATE_MAIL - || (you.inv[item].sub_type == ARM_HELMET - && (cmp_helmet_type( you.inv[item], THELM_HELM ) - || cmp_helmet_type( you.inv[item], THELM_HELMET )))) + if ((sub_type >= ARM_LEATHER_ARMOUR + && sub_type <= ARM_PLATE_MAIL) + || sub_type == ARM_GLOVES + || sub_type == ARM_BOOTS + || sub_type == ARM_SHIELD + || sub_type == ARM_LARGE_SHIELD + || sub_type == ARM_CRYSTAL_PLATE_MAIL + || (sub_type == ARM_HELMET + && (get_helmet_type(invitem) == THELM_HELM + || get_helmet_type(invitem) == THELM_HELMET))) { if (!quiet) mpr("This armour doesn't fit on your body."); @@ -810,11 +788,10 @@ bool do_wear_armour( int item, bool quiet ) bool removedCloak = false; int cloak = -1; - if ((you.inv[item].sub_type < ARM_SHIELD - || you.inv[item].sub_type > ARM_LARGE_SHIELD) - && (you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed())) + if (slot == EQ_BODY_ARMOUR + && you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed()) { - if (item_uncursed( you.inv[you.equip[EQ_CLOAK]] )) + if (!item_cursed( you.inv[you.equip[EQ_CLOAK]] )) { cloak = you.equip[ EQ_CLOAK ]; if (!takeoff_armour(you.equip[EQ_CLOAK])) @@ -831,42 +808,37 @@ bool do_wear_armour( int item, bool quiet ) } } - if (you.inv[item].sub_type == ARM_CLOAK && you.equip[EQ_CLOAK] != -1) + if (slot == EQ_CLOAK && you.equip[EQ_CLOAK] != -1) { if (!takeoff_armour(you.equip[EQ_CLOAK])) return (false); } - if (you.inv[item].sub_type == ARM_HELMET && you.equip[EQ_HELMET] != -1) + if (slot == EQ_HELMET && you.equip[EQ_HELMET] != -1) { if (!takeoff_armour(you.equip[EQ_HELMET])) return (false); } - if (you.inv[item].sub_type == ARM_GLOVES && you.equip[EQ_GLOVES] != -1) + if (slot == EQ_GLOVES && you.equip[EQ_GLOVES] != -1) { if (!takeoff_armour(you.equip[EQ_GLOVES])) return (false); } - if (you.inv[item].sub_type == ARM_BOOTS && you.equip[EQ_BOOTS] != -1) + if (slot == EQ_BOOTS && you.equip[EQ_BOOTS] != -1) { if (!takeoff_armour(you.equip[EQ_BOOTS])) return (false); } - if ((you.inv[item].sub_type == ARM_SHIELD - || you.inv[item].sub_type == ARM_LARGE_SHIELD - || you.inv[item].sub_type == ARM_BUCKLER) - && you.equip[EQ_SHIELD] != -1) + if (slot == EQ_SHIELD && you.equip[EQ_SHIELD] != -1) { if (!takeoff_armour(you.equip[EQ_SHIELD])) return (false); } - if ((you.inv[item].sub_type < ARM_SHIELD - || you.inv[item].sub_type > ARM_LARGE_SHIELD) - && you.equip[EQ_BODY_ARMOUR] != -1) + if (slot == EQ_BODY_ARMOUR && you.equip[EQ_BODY_ARMOUR] != -1) { if (!takeoff_armour(you.equip[EQ_BODY_ARMOUR])) return (false); @@ -912,13 +884,13 @@ bool takeoff_armour(int item) bool removedCloak = false; int cloak = -1; + const equipment_type slot = get_armour_slot(you.inv[item]); - if (you.inv[item].sub_type < ARM_SHIELD - || you.inv[item].sub_type > ARM_LARGE_SHIELD) + if (slot == EQ_BODY_ARMOUR) { if (you.equip[EQ_CLOAK] != -1 && !cloak_is_being_removed()) { - if (item_uncursed( you.inv[you.equip[EQ_CLOAK]] )) + if (!item_cursed( you.inv[you.equip[EQ_CLOAK]] )) { cloak = you.equip[ EQ_CLOAK ]; if (!takeoff_armour(you.equip[EQ_CLOAK])) @@ -943,11 +915,9 @@ bool takeoff_armour(int item) } else { - switch (you.inv[item].sub_type) + switch (slot) { - case ARM_BUCKLER: - case ARM_LARGE_SHIELD: - case ARM_SHIELD: + case EQ_SHIELD: if (item != you.equip[EQ_SHIELD]) { mpr("You aren't wearing that!"); @@ -955,7 +925,7 @@ bool takeoff_armour(int item) } break; - case ARM_CLOAK: + case EQ_CLOAK: if (item != you.equip[EQ_CLOAK]) { mpr("You aren't wearing that!"); @@ -963,7 +933,7 @@ bool takeoff_armour(int item) } break; - case ARM_HELMET: + case EQ_HELMET: if (item != you.equip[EQ_HELMET]) { mpr("You aren't wearing that!"); @@ -971,8 +941,7 @@ bool takeoff_armour(int item) } break; - - case ARM_GLOVES: + case EQ_GLOVES: if (item != you.equip[EQ_GLOVES]) { mpr("You aren't wearing that!"); @@ -980,13 +949,16 @@ bool takeoff_armour(int item) } break; - case ARM_BOOTS: + case EQ_BOOTS: if (item != you.equip[EQ_BOOTS]) { mpr("You aren't wearing that!"); return false; } break; + + default: + break; } } @@ -1196,6 +1168,7 @@ static void throw_it(struct bolt &pbolt, int throw_2) int lnchHitBonus = 0, lnchDamBonus = 0; // special add from launcher int exHitBonus = 0, exDamBonus = 0; // 'extra' bonus from skill/dex/str int effSkill = 0; // effective launcher skill + int damageMult = 100; bool launched = false; // item is launched bool thrown = false; // item is sensible thrown item @@ -1290,11 +1263,11 @@ static void throw_it(struct bolt &pbolt, int throw_2) } // baseHit and damage for generic objects - baseHit = you.strength - mass_item(item) / 10; + baseHit = you.strength - item_mass(item) / 10; if (baseHit > 0) baseHit = 0; - baseDam = mass_item(item) / 100; + baseDam = item_mass(item) / 100; // special: might be throwing generic weapon; // use base wep. damage, w/ penalty @@ -1322,21 +1295,47 @@ static void throw_it(struct bolt &pbolt, int throw_2) // CALCULATIONS FOR LAUNCHED WEAPONS if (launched) { - const int bow_brand = get_weapon_brand( you.inv[you.equip[EQ_WEAPON]] ); + const item_def &launcher = you.inv[you.equip[EQ_WEAPON]]; + const int bow_brand = get_weapon_brand( launcher ); const int ammo_brand = get_ammo_brand( item ); + const bool two_handed = (you.equip[EQ_SHIELD] == -1); bool poisoned = (ammo_brand == SPMSL_POISONED || ammo_brand == SPMSL_POISONED_II); - - // this is deliberately confusing: the 'hit' value for - // ammo is the _damage_ when used with a launcher. Geez. - baseHit = 0; - baseDam = property( item, PWPN_HIT ); + const int rc_skill = you.skills[SK_RANGED_COMBAT]; + + const int item_base_dam = property( item, PWPN_DAMAGE ); + const int lnch_base_dam = property( launcher, PWPN_DAMAGE ); + + const skill_type launcher_skill = range_skill( launcher ); + const int str_weight = weapon_str_weight( launcher ); + const int dex_weight = 10 - str_weight; + + int speed_base = 10 * property( launcher, PWPN_SPEED ); + int speed_min = 50; + int speed_stat = str_weight * you.strength + dex_weight * you.dex; + int speed = 100; + + baseHit = property( launcher, PWPN_HIT ); + baseDam = item_base_dam + random2(1 + lnch_base_dam); + + if (launcher_skill == SK_BOWS) + speed_min = 40; + else if (launcher_skill == SK_CROSSBOWS) + speed_min = 60; + +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, + "Base hit == %d; Base damage == %d " + "(item %d + launcher %d)", + baseHit, baseDam, + item_base_dam, lnch_base_dam); +#endif // fix ammo damage bonus, since missiles only use inv_plus ammoDamBonus = ammoHitBonus; // check for matches; dwarven,elven,orcish - if (!cmp_equip_race( you.inv[you.equip[EQ_WEAPON]], 0 )) + if (!get_equip_race(you.inv[you.equip[EQ_WEAPON]]) == 0) { if (get_equip_race( you.inv[you.equip[EQ_WEAPON]] ) == get_equip_race( item )) @@ -1345,7 +1344,8 @@ static void throw_it(struct bolt &pbolt, int throw_2) baseDam += 1; // elves with elven bows - if (cmp_equip_race(you.inv[you.equip[EQ_WEAPON]], ISFLAG_ELVEN) + if (get_equip_race(you.inv[you.equip[EQ_WEAPON]]) + == ISFLAG_ELVEN && player_genus(GENPC_ELVEN)) { baseHit += 1; @@ -1353,69 +1353,78 @@ static void throw_it(struct bolt &pbolt, int throw_2) } } - if (you.inv[you.equip[EQ_WEAPON]].sub_type == WPN_CROSSBOW) - { - // extra time taken, as a percentage. range from 30 -> 12 - int extraTime = 30 - ((you.skills[SK_CROSSBOWS] * 2) / 3); - - you.time_taken = (100 + extraTime) * you.time_taken; - you.time_taken /= 100; - } - - if (bow_brand == SPWPN_SPEED) - { - you.time_taken *= 5; - you.time_taken /= 10; - } - // for all launched weapons, maximum effective specific skill // is twice throwing skill. This models the fact that no matter // how 'good' you are with a bow, if you know nothing about // trajectories you're going to be a damn poor bowman. Ditto // for crossbows and slings. - switch (lnchType) + + // [dshaligram] Throwing now two parts launcher skill, one part + // ranged combat. Removed the old model which is... silly. + + shoot_skill = you.skills[launcher_skill]; + effSkill = (shoot_skill * 2 + skill_bump(SK_RANGED_COMBAT)) / 3; + + // FIXME: Use actual body size + if (!two_handed && hands_reqd(launcher, SIZE_MEDIUM) == HANDS_HALF) { - case WPN_SLING: - shoot_skill = you.skills[SK_SLINGS]; - break; - case WPN_BOW: - shoot_skill = you.skills[SK_BOWS]; - break; - case WPN_BLOWGUN: - shoot_skill = you.skills[SK_DARTS]; - break; - case WPN_CROSSBOW: - case WPN_HAND_CROSSBOW: - shoot_skill = you.skills[SK_CROSSBOWS]; - break; - default: - shoot_skill = 0; - break; + speed_base = (speed_base * 3 + 1) / 2; + speed_min = (speed_min * 3 + 1) / 2; + } + + speed = speed_base - shoot_skill * speed_stat / 50; + if (speed < speed_min) + speed = speed_min; + + if (bow_brand == SPWPN_SPEED) + { + // Speed nerf as per 4.1 + speed = 2 * speed / 3; } +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Final launcher speed: %d", speed); +#endif + + you.time_taken = speed * you.time_taken / 100; + + // effSkill = you.skills[SK_RANGED_COMBAT] * 2 + 1; + // effSkill = (shoot_skill > effSkill) ? effSkill : shoot_skill; - effSkill = you.skills[SK_THROWING] * 2 + 1; - effSkill = (shoot_skill > effSkill) ? effSkill : shoot_skill; + // [dshaligram] Improving missile weapons: + // - Remove the strength/enchantment cap where you need to be strong + // to exploit a launcher bonus. + // - Add on launcher and missile pluses to extra damage. + // [dshaligram] This can get large... + exDamBonus = lnchDamBonus + ammoDamBonus; + exHitBonus = lnchHitBonus; + + // Raw ranged combat skill also helps with damage. + if (lnchType != WPN_BLOWGUN) + exDamBonus += rc_skill / 4; + // removed 2 random2(2)s from each of the learning curves, but // left slings because they're hard enough to develop without // a good source of shot in the dungeon. - switch (lnchType) + switch (launcher_skill) + { + case SK_SLINGS: { - case WPN_SLING: // Slings are really easy to learn because they're not // really all that good, and its harder to get ammo anyways. exercise(SK_SLINGS, 1 + random2avg(3, 2)); baseHit += 0; - exHitBonus = (effSkill * 3) / 2; + exHitBonus += (effSkill * 3) / 2; // strength is good if you're using a nice sling. - exDamBonus = (10 * (you.strength - 10)) / 9; - exDamBonus = (exDamBonus * (2 * baseDam + ammoDamBonus)) / 20; + int strbonus = (10 * (you.strength - 10)) / 9; + strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20; // cap - if (exDamBonus > lnchDamBonus + 1) - exDamBonus = lnchDamBonus + 1; + if (strbonus > lnchDamBonus + 1) + strbonus = lnchDamBonus + 1; + exDamBonus += strbonus; // add skill for slings.. helps to find those vulnerable spots exDamBonus += effSkill / 2; @@ -1423,16 +1432,16 @@ static void throw_it(struct bolt &pbolt, int throw_2) if (lnchDamBonus > 0) lnchDamBonus = 0; break; - + } // blowguns take a _very_ steady hand; a lot of the bonus // comes from dexterity. (Dex bonus here as well as below) - case WPN_BLOWGUN: + case SK_DARTS: exercise(SK_DARTS, (coinflip()? 2 : 1)); baseHit -= 2; - exHitBonus = (effSkill * 3) / 2 + you.dex / 2; + exHitBonus += (effSkill * 3) / 2 + you.dex / 2; // no extra damage for blowguns - exDamBonus = 0; + // exDamBonus = 0; // now kill the launcher damage and ammo bonuses if (lnchDamBonus > 0) @@ -1441,52 +1450,62 @@ static void throw_it(struct bolt &pbolt, int throw_2) ammoDamBonus = 0; break; - - case WPN_BOW: + case SK_BOWS: + { exercise(SK_BOWS, (coinflip()? 2 : 1)); baseHit -= 4; - exHitBonus = (effSkill * 2); + exHitBonus += (effSkill * 2); // strength is good if you're using a nice bow - exDamBonus = (10 * (you.strength - 10)) / 4; - exDamBonus = (exDamBonus * (2 * baseDam + ammoDamBonus)) / 20; + int strbonus = (10 * (you.strength - 10)) / 4; + strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20; - // cap - if (exDamBonus > (lnchDamBonus + 1) * 3) - exDamBonus = (lnchDamBonus + 1) * 3; + // cap; reduced this cap, because we don't want to allow + // the extremely-strong to quadruple the enchantment bonus. + if (strbonus > lnchDamBonus + 1) + strbonus = lnchDamBonus + 1; + + exDamBonus += strbonus; // add in skill for bows.. help you to find those vulnerable spots. - exDamBonus += effSkill; + exDamBonus += effSkill * 5 / 4; // now kill the launcher damage bonus if (lnchDamBonus > 0) lnchDamBonus = 0; break; - + } // Crossbows are easy for unskilled people. - case WPN_CROSSBOW: + case SK_CROSSBOWS: exercise(SK_CROSSBOWS, (coinflip()? 2 : 1)); - baseHit += 2; - exHitBonus = (3 * effSkill) / 2 + 6; - exDamBonus = effSkill / 2 + 4; + baseHit += lnchType == WPN_CROSSBOW? 2 : 1; + exHitBonus += (3 * effSkill) / 2 + 6; + exDamBonus += effSkill * 2 / 3 + 4; + if (lnchType == WPN_HAND_CROSSBOW) + { + exHitBonus -= 2; + exDamBonus -= 2; + } break; - case WPN_HAND_CROSSBOW: - exercise(SK_CROSSBOWS, (coinflip()? 2 : 1)); - baseHit += 1; - exHitBonus = (3 * effSkill) / 2 + 4; - exDamBonus = effSkill / 2 + 2; + default: break; } // all launched weapons have a slight chance of improving // throwing skill if (coinflip()) - exercise(SK_THROWING, 1); + exercise(SK_RANGED_COMBAT, 1); // all launched weapons get a tohit boost from throwing skill. - exHitBonus += (3 * you.skills[SK_THROWING]) / 4; + exHitBonus += (3 * you.skills[SK_RANGED_COMBAT]) / 4; + + if (bow_brand == SPWPN_VORPAL) + { + // Vorpal brand adds 35% damage bonus. + exDamBonus = exDamBonus * 135 / 100; + } // special cases for flame, frost, poison, etc. // check for venom brand (usually only available for blowguns) @@ -1502,7 +1521,9 @@ static void throw_it(struct bolt &pbolt, int throw_2) if ((bow_brand == SPWPN_FLAME || ammo_brand == SPMSL_FLAME) && ammo_brand != SPMSL_ICE && bow_brand != SPWPN_FROST) { - baseDam += 1 + random2(5); + // [dshaligram] Branded arrows are much stronger. + damageMult = 150; + pbolt.flavour = BEAM_FIRE; strcpy(pbolt.beam_name, "bolt of "); @@ -1526,7 +1547,9 @@ static void throw_it(struct bolt &pbolt, int throw_2) if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE) && ammo_brand != SPMSL_FLAME && bow_brand != SPWPN_FLAME) { - baseDam += 1 + random2(5); + // [dshaligram] Branded arrows are much stronger. + damageMult = 150; + pbolt.flavour = BEAM_COLD; strcpy(pbolt.beam_name, "bolt of "); @@ -1563,7 +1586,7 @@ static void throw_it(struct bolt &pbolt, int throw_2) * and vice versa */ // ID check - if (item_not_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES ) + if (!item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES ) && random2(100) < shoot_skill) { set_ident_flags(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES); @@ -1593,7 +1616,8 @@ static void throw_it(struct bolt &pbolt, int throw_2) || (wepClass == OBJ_MISSILES && wepType == MI_STONE)) { // elves with elven weapons - if (cmp_equip_race(item, ISFLAG_ELVEN) && player_genus(GENPC_ELVEN)) + if (get_equip_race(item) == ISFLAG_ELVEN + && player_genus(GENPC_ELVEN)) baseHit += 1; // give an appropriate 'tohit' - @@ -1617,11 +1641,11 @@ static void throw_it(struct bolt &pbolt, int throw_2) } } - exHitBonus = you.skills[SK_THROWING] * 2; + exHitBonus = you.skills[SK_RANGED_COMBAT] * 2; baseDam = property( item, PWPN_DAMAGE ); exDamBonus = - (10 * (you.skills[SK_THROWING] / 2 + you.strength - 10)) / 12; + (10 * (you.skills[SK_RANGED_COMBAT] / 2 + you.strength - 10)) / 12; // now, exDamBonus is a multiplier. The full multiplier // is applied to base damage, but only a third is applied @@ -1636,16 +1660,30 @@ static void throw_it(struct bolt &pbolt, int throw_2) baseDam = property( item, PWPN_DAMAGE ); exHitBonus = you.skills[SK_DARTS] * 2; - exHitBonus += (you.skills[SK_THROWING] * 2) / 3; - exDamBonus = you.skills[SK_DARTS] / 4; + exHitBonus += (you.skills[SK_RANGED_COMBAT] * 2) / 3; + exDamBonus = you.skills[SK_DARTS] / 3; + exDamBonus += you.skills[SK_RANGED_COMBAT] / 5; // exercise skills exercise(SK_DARTS, 1 + random2avg(3, 2)); } + if (wepClass == OBJ_MISSILES && wepType == MI_NEEDLE) + { + // Throwing needles is now seriously frowned upon; it's difficult + // to grip a fiddly little needle, and not penalising it cheapens + // blowguns. + exHitBonus -= (30 - you.skills[SK_DARTS]) / 3; + baseHit -= (30 - you.skills[SK_DARTS]) / 4; +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "Needle base hit = %d, exHitBonus = %d", + baseHit, exHitBonus); +#endif + } + // exercise skill if (coinflip()) - exercise(SK_THROWING, 1); + exercise(SK_RANGED_COMBAT, 1); } // range, dexterity bonus, possible skill increase for silly throwing @@ -1676,7 +1714,7 @@ static void throw_it(struct bolt &pbolt, int throw_2) else { // range based on mass & strength, between 1 and 9 - pbolt.range = you.strength - mass_item(item) / 10 + 3; + pbolt.range = you.strength - item_mass(item) / 10 + 3; if (pbolt.range < 1) pbolt.range = 1; @@ -1687,7 +1725,7 @@ static void throw_it(struct bolt &pbolt, int throw_2) pbolt.rangeMax = pbolt.range; if (one_chance_in(20)) - exercise(SK_THROWING, 1); + exercise(SK_RANGED_COMBAT, 1); exHitBonus = you.dex / 4; } @@ -1703,6 +1741,9 @@ static void throw_it(struct bolt &pbolt, int throw_2) else pbolt.damage = dice_def( 1, baseDam - random2(0 - (exDamBonus - 1)) ); + pbolt.damage.size = damageMult * pbolt.damage.size / 100; + scale_dice( pbolt.damage ); + // only add bonuses if we're throwing something sensible if (thrown || launched || wepClass == OBJ_WEAPONS) { @@ -1711,13 +1752,11 @@ static void throw_it(struct bolt &pbolt, int throw_2) } #if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, - "H:%d+%d;a%dl%d. D:%d+%d;a%dl%d -> %d,%dd%d", + mprf( MSGCH_DIAGNOSTICS, + "H:%d+%d;a%dl%d. D:%d+%d;a%dl%d -> %d,%dd%d", baseHit, exHitBonus, ammoHitBonus, lnchHitBonus, baseDam, exDamBonus, ammoDamBonus, lnchDamBonus, pbolt.hit, pbolt.damage.num, pbolt.damage.size ); - - mpr( info, MSGCH_DIAGNOSTICS ); #endif // create message @@ -1733,8 +1772,8 @@ static void throw_it(struct bolt &pbolt, int throw_2) mpr(info); // ensure we're firing a 'missile'-type beam - pbolt.isBeam = false; - pbolt.isTracer = false; + pbolt.is_beam = false; + pbolt.is_tracer = false; // mark this item as thrown if it's a missile, so that we'll pick it up // when we walk over it. @@ -2189,7 +2228,7 @@ void zap_wand(void) // system will default to cycling through all monsters. -- bwr int targ_mode = TARG_ANY; - beam.obviousEffect = false; + beam.obvious_effect = false; if (inv_count() < 1) { @@ -2280,7 +2319,7 @@ void zap_wand(void) zapping( type_zapped, 30 + roll_dice(2, you.skills[SK_EVOCATIONS]), beam ); - if (beam.obviousEffect == 1 || you.inv[item_slot].sub_type == WAND_FIREBALL) + if (beam.obvious_effect == 1 || you.inv[item_slot].sub_type == WAND_FIREBALL) { if (get_ident_type( you.inv[item_slot].base_type, you.inv[item_slot].sub_type ) != ID_KNOWN_TYPE) @@ -2309,7 +2348,7 @@ void zap_wand(void) && (item_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES ) || you.skills[SK_EVOCATIONS] > 5 + random2(15))) { - if (item_not_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES )) + if (!item_ident( you.inv[item_slot], ISFLAG_KNOW_PLUSES )) { mpr("Your skill with magical items lets you calculate the power of this device..."); } @@ -2491,8 +2530,7 @@ static bool affix_weapon_enchantment( void ) switch (get_weapon_brand( you.inv[wpn] )) { case SPWPN_VORPAL: - if (damage_type( you.inv[wpn].base_type, - you.inv[wpn].sub_type ) != DVORP_CRUSHING) + if (get_vorpal_type( you.inv[wpn] ) != DVORP_CRUSHING) { strcat(info, "'s sharpness seems more permanent."); } @@ -2517,7 +2555,8 @@ static bool affix_weapon_enchantment( void ) beam.thrower = KILL_YOU; beam.aux_source = "a fiery explosion"; beam.ex_size = 2; - beam.isTracer = false; + beam.is_tracer = false; + beam.is_explosion = true; explosion(beam); break; @@ -2697,7 +2736,7 @@ static bool enchant_armour( void ) you.redraw_armour_class = 1; - hide2armour( &(you.inv[nthing].sub_type) ); + hide2armour(you.inv[nthing]); return (true); } @@ -2828,7 +2867,7 @@ void read_scroll(void) char str_pass[ ITEMNAME_SIZE ]; // added: scroll effects are never tracers. - beam.isTracer = false; + beam.is_tracer = false; if (you.berserker) { @@ -3005,6 +3044,7 @@ void read_scroll(void) beam.thrower = KILL_YOU; beam.aux_source = "reading a scroll of immolation"; beam.ex_size = 2; + beam.is_explosion = true; explosion(beam); break; @@ -3140,7 +3180,7 @@ void read_scroll(void) affected = EQ_WEAPON; for (i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++) { - if (you.equip[i] != -1 && item_uncursed( you.inv[you.equip[i]] )) + if (you.equip[i] != -1 && !item_cursed( you.inv[you.equip[i]] )) { count++; if (one_chance_in( count )) diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 61c2ea6741..9115ecf6bd 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -128,8 +128,6 @@ void use_randart( unsigned char item_wield_2 ); bool puton_item(int slot, bool prompt_finger = true); -int armour_equip_slot(const item_def &item); - bool enchant_weapon( int which_stat, bool quiet = false ); #endif diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index 9d9955cb51..b1e31a277e 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -28,6 +28,7 @@ #include "externs.h" #include "invent.h" +#include "itemprop.h" #include "macro.h" #include "mon-util.h" #include "randart.h" @@ -37,16 +38,14 @@ #include "view.h" -char id[4][50]; -int prop[4][50][3]; -FixedArray < int, 20, 50 > mss; +char id[NUM_IDTYPE][MAX_SUBTYPES]; -static bool is_random_name_vowel(unsigned char let); +static bool is_random_name_space( char let ); +static bool is_random_name_vowel( char let); static char item_name_2( const item_def &item, char buff[ ITEMNAME_SIZE ], bool terse ); -char reduce(unsigned char reducee); -char retbit(char sed); -char retvow(char sed); +static char retvow(int sed); +static char retlet(int sed ); bool is_vowel( const char chr ) { @@ -55,42 +54,6 @@ bool is_vowel( const char chr ) return (low == 'a' || low == 'e' || low == 'i' || low == 'o' || low == 'u'); } -// Some convenient functions to hide the bit operations and create -// an interface layer between the code and the data in case this -// gets changed again. -- bwr -bool item_cursed( const item_def &item ) -{ - return (item.flags & ISFLAG_CURSED); -} - -bool item_uncursed( const item_def &item ) -{ - return !(item.flags & ISFLAG_CURSED); -} - -bool item_known_cursed( const item_def &item ) -{ - return ((item.flags & ISFLAG_KNOW_CURSE) && (item.flags & ISFLAG_CURSED)); -} - -bool item_known_uncursed( const item_def &item ) -{ - return ((item.flags & ISFLAG_KNOW_CURSE) && !(item.flags & ISFLAG_CURSED)); -} - -#if 0 -// currently unused -bool fully_identified( const item_def &item ) -{ - return ((item.flags & ISFLAG_IDENT_MASK) == ISFLAG_IDENT_MASK); -} -#endif - -bool item_ident( const item_def &item, unsigned long flags ) -{ - return (item.flags & flags); -} - bool item_type_known( const item_def &item ) { return item_ident(item, ISFLAG_KNOW_TYPE) @@ -98,266 +61,6 @@ bool item_type_known( const item_def &item ) && id[IDTYPE_JEWELLERY][item.sub_type] == ID_KNOWN_TYPE); } -bool item_not_ident( const item_def &item, unsigned long flags ) -{ - return ( !(item.flags & flags) ); -} - -void do_curse_item( item_def &item ) -{ - item.flags |= ISFLAG_CURSED; -} - -void do_uncurse_item( item_def &item ) -{ - item.flags &= (~ISFLAG_CURSED); -} - -void set_ident_flags( item_def &item, unsigned long flags ) -{ - item.flags |= flags; -} - -void unset_ident_flags( item_def &item, unsigned long flags ) -{ - item.flags &= (~flags); -} - -// These six functions might seem silly, but they provide a nice layer -// for later changes to these systems. -- bwr -unsigned long get_equip_race( const item_def &item ) -{ - return (item.flags & ISFLAG_RACIAL_MASK); -} - -unsigned long get_equip_desc( const item_def &item ) -{ - return (item.flags & ISFLAG_COSMETIC_MASK); -} - -bool cmp_equip_race( const item_def &item, unsigned long val ) -{ - return (get_equip_race( item ) == val); -} - -bool cmp_equip_desc( const item_def &item, unsigned long val ) -{ - return (get_equip_desc( item ) == val); -} - -void set_equip_race( item_def &item, unsigned long flags ) -{ - ASSERT( (flags & ~ISFLAG_RACIAL_MASK) == 0 ); - - // first check for base-sub pairs that can't ever have racial types - switch (item.base_type) - { - case OBJ_WEAPONS: - if (item.sub_type == WPN_GIANT_CLUB - || item.sub_type == WPN_GIANT_SPIKED_CLUB - || item.sub_type == WPN_KATANA - || item.sub_type == WPN_SLING - || item.sub_type == WPN_KNIFE - || item.sub_type == WPN_QUARTERSTAFF - || item.sub_type == WPN_DEMON_BLADE - || item.sub_type == WPN_DEMON_WHIP - || item.sub_type == WPN_DEMON_TRIDENT) - { - return; - } - break; - - case OBJ_ARMOUR: - if (item.sub_type >= ARM_DRAGON_HIDE) - { - return; - } - break; - - case OBJ_MISSILES: - if (item.sub_type == MI_STONE || item.sub_type == MI_LARGE_ROCK) - { - return; - } - break; - - default: - return; - } - - // check that item is appropriate for racial type - switch (flags) - { - case ISFLAG_ELVEN: - if (item.base_type == OBJ_ARMOUR - && (item.sub_type == ARM_SPLINT_MAIL - || item.sub_type == ARM_BANDED_MAIL - || item.sub_type == ARM_PLATE_MAIL)) - { - return; - } - break; - - case ISFLAG_DWARVEN: - if (item.base_type == OBJ_ARMOUR - && (item.sub_type == ARM_ROBE - || item.sub_type == ARM_LEATHER_ARMOUR)) - { - return; - } - break; - - case ISFLAG_ORCISH: - default: - break; - } - - item.flags &= ~ISFLAG_RACIAL_MASK; // delete previous - item.flags |= flags; -} - -void set_equip_desc( item_def &item, unsigned long flags ) -{ - ASSERT( (flags & ~ISFLAG_COSMETIC_MASK) == 0 ); - - item.flags &= ~ISFLAG_COSMETIC_MASK; // delete previous - item.flags |= flags; -} - -short get_helmet_type( const item_def &item ) -{ - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - return (item.plus2 & THELM_TYPE_MASK); -} - -short get_helmet_desc( const item_def &item ) -{ - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - return (item.plus2 & THELM_DESC_MASK); -} - -void set_helmet_type( item_def &item, short type ) -{ - ASSERT( (type & ~THELM_TYPE_MASK) == 0 ); - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - item.plus2 &= ~THELM_TYPE_MASK; - item.plus2 |= type; -} - -void set_helmet_desc( item_def &item, short type ) -{ - ASSERT( (type & ~THELM_DESC_MASK) == 0 ); - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - item.plus2 &= ~THELM_DESC_MASK; - item.plus2 |= type; -} - -void set_helmet_random_desc( item_def &item ) -{ - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - item.plus2 &= ~THELM_DESC_MASK; - item.plus2 |= (random2(8) << 8); -} - -bool cmp_helmet_type( const item_def &item, short val ) -{ - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - return (get_helmet_type( item ) == val); -} - -bool cmp_helmet_desc( const item_def &item, short val ) -{ - ASSERT( item.base_type == OBJ_ARMOUR && item.sub_type == ARM_HELMET ); - - return (get_helmet_desc( item ) == val); -} - -bool set_item_ego_type( item_def &item, int item_type, int ego_type ) -{ - if (item.base_type == item_type - && !is_random_artefact( item ) - && !is_fixed_artefact( item )) - { - item.special = ego_type; - return (true); - } - - return (false); -} - -int get_weapon_brand( const item_def &item ) -{ - // Weapon ego types are "brands", so we do the randart lookup here. - - // Staves "brands" handled specially - if (item.base_type != OBJ_WEAPONS) - return (SPWPN_NORMAL); - - if (is_fixed_artefact( item )) - { - switch (item.special) - { - case SPWPN_SWORD_OF_CEREBOV: - return (SPWPN_FLAMING); - - case SPWPN_STAFF_OF_OLGREB: - return (SPWPN_VENOM); - - case SPWPN_VAMPIRES_TOOTH: - return (SPWPN_VAMPIRICISM); - - default: - return (SPWPN_NORMAL); - } - } - else if (is_random_artefact( item )) - { - return (randart_wpn_property( item, RAP_BRAND )); - } - - return (item.special); -} - -int get_ammo_brand( const item_def &item ) -{ - // no artefact arrows yet -- bwr - if (item.base_type != OBJ_MISSILES || is_random_artefact( item )) - return (SPMSL_NORMAL); - - return (item.special); -} - -int get_armour_ego_type( const item_def &item ) -{ - // artefact armours have no ego type, must look up powers separately - if (item.base_type != OBJ_ARMOUR - || (is_random_artefact( item ) && !is_unrandom_artefact( item ))) - { - return (SPARM_NORMAL); - } - - return (item.special); -} - -bool item_is_rod( const item_def &item ) -{ - return (item.base_type == OBJ_STAVES - && item.sub_type >= STAFF_SMITING && item.sub_type < STAFF_AIR); -} - -bool item_is_staff( const item_def &item ) -{ - // Isn't De Morgan's law wonderful. -- bwr - return (item.base_type == OBJ_STAVES - && (item.sub_type < STAFF_SMITING || item.sub_type >= STAFF_AIR)); -} - // it_name() and in_name() are now somewhat obsolete now that itemname // takes item_def, so consider them depricated. void it_name( int itn, char des, char buff[ ITEMNAME_SIZE ], bool terse ) @@ -598,7 +301,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], if (item_cursed( item )) strncat(buff, "cursed ", ITEMNAME_SIZE ); else if (Options.show_uncursed - && item_not_ident( item, ISFLAG_KNOW_PLUSES )) + && !item_ident( item, ISFLAG_KNOW_PLUSES )) { strncat(buff, "uncursed ", ITEMNAME_SIZE ); } @@ -687,7 +390,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], // Now that we can have "glowing elven" weapons, it's // probably a good idea to cut out the descriptive // term once it's become obsolete. -- bwr - if (item_not_ident( item, ISFLAG_KNOW_PLUSES ) && !terse) + if (!item_ident( item, ISFLAG_KNOW_PLUSES ) && !terse) { switch (get_equip_desc( item )) { @@ -760,7 +463,14 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], strncat(buff, (terse) ? " (speed)" : " of speed", ITEMNAME_SIZE ); break; case SPWPN_VORPAL: - switch (damage_type(item_clas, item_typ)) + if (is_range_weapon( item )) + { + strncat(buff, (terse) ? " (velocity)" : " of velocity", + ITEMNAME_SIZE ); + break; + } + + switch (get_vorpal_type(item)) { case DVORP_CRUSHING: strncat(buff, (terse) ? " (crush)" : " of crushing", ITEMNAME_SIZE ); @@ -853,8 +563,8 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], (item_typ == MI_BOLT) ? "bolt" : (item_typ == MI_DART) ? "dart" : (item_typ == MI_NEEDLE) ? "needle" : - (item_typ == MI_EGGPLANT) ? "eggplant" : - (item_typ == MI_LARGE_ROCK) ? "large rock" : "", ITEMNAME_SIZE); + (item_typ == MI_LARGE_ROCK) ? "large rock" : + "hysterical raisin", ITEMNAME_SIZE); // this should probably be "" {dlb} if (it_quant > 1) @@ -879,7 +589,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], if (item_cursed( item )) strncat(buff, "cursed ", ITEMNAME_SIZE ); else if (Options.show_uncursed - && item_not_ident( item, ISFLAG_KNOW_PLUSES )) + && !item_ident( item, ISFLAG_KNOW_PLUSES )) { strncat(buff, "uncursed ", ITEMNAME_SIZE ); } @@ -896,8 +606,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], strncat(buff, " ", ITEMNAME_SIZE ); } - if (item_typ == ARM_GLOVES - || (item_typ == ARM_BOOTS && item_plus2 == TBOOT_BOOTS)) + if (item_typ == ARM_GLOVES || item_typ == ARM_BOOTS) { strncat( buff, "pair of ", ITEMNAME_SIZE ); } @@ -911,7 +620,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], // Now that we can have "glowing elven" armour, it's // probably a good idea to cut out the descriptive // term once it's become obsolete. -- bwr - if (item_not_ident( item, ISFLAG_KNOW_PLUSES ) && !terse) + if (!item_ident( item, ISFLAG_KNOW_PLUSES ) && !terse) { switch (get_equip_desc( item )) { @@ -1316,7 +1025,11 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], strncat(buff, "labeled ", ITEMNAME_SIZE ); char buff3[ ITEMNAME_SIZE ]; - make_name( item.special, it_plus, item_clas, 2, buff3 ); + const unsigned long sseed = + item.special + + static_cast<unsigned long>(it_plus) + + (static_cast<unsigned long>(item_clas) << 16); + make_name( sseed, true, buff3 ); strncat( buff, buff3 , ITEMNAME_SIZE ); if (id[ IDTYPE_SCROLLS ][item_typ] == ID_TRIED_TYPE) @@ -1336,7 +1049,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], if (item_cursed( item )) strncat(buff, "cursed ", ITEMNAME_SIZE ); else if (Options.show_uncursed - && item_not_ident( item, ISFLAG_KNOW_PLUSES )) + && !item_ident( item, ISFLAG_KNOW_PLUSES )) { strncat(buff, "uncursed ", ITEMNAME_SIZE ); } @@ -1728,7 +1441,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], case MISC_DECK_OF_TRICKS: case MISC_DECK_OF_WONDERS: strncat(buff, "deck of ", ITEMNAME_SIZE ); - strncat(buff, item_not_ident( item, ISFLAG_KNOW_TYPE ) ? "cards" : + strncat(buff, !item_ident( item, ISFLAG_KNOW_TYPE ) ? "cards" : (item_typ == MISC_DECK_OF_WONDERS) ? "wonders" : (item_typ == MISC_DECK_OF_SUMMONINGS) ? "summonings" : (item_typ == MISC_DECK_OF_TRICKS) ? "tricks" : @@ -1780,7 +1493,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], break; case MISC_LANTERN_OF_SHADOWS: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) strncat(buff, "bone ", ITEMNAME_SIZE ); strncat(buff, "lantern", ITEMNAME_SIZE ); @@ -1789,7 +1502,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], break; case MISC_HORN_OF_GERYON: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) strncat(buff, "silver ", ITEMNAME_SIZE ); strncat(buff, "horn", ITEMNAME_SIZE ); @@ -1798,7 +1511,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], break; case MISC_DISC_OF_STORMS: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) strncat(buff, "grey ", ITEMNAME_SIZE ); strncat(buff, "disc", ITEMNAME_SIZE ); @@ -1807,7 +1520,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], break; case MISC_STONE_OF_EARTH_ELEMENTALS: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) strncat(buff, "nondescript ", ITEMNAME_SIZE ); strncat(buff, "stone", ITEMNAME_SIZE ); @@ -1816,7 +1529,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], break; case MISC_BOTTLED_EFREET: - strncat(buff, (item_not_ident( item, ISFLAG_KNOW_TYPE )) + strncat(buff, (!item_ident( item, ISFLAG_KNOW_TYPE )) ? "sealed bronze flask" : "bottled efreet", ITEMNAME_SIZE ); break; @@ -1833,7 +1546,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], // compacted 15 Apr 2000 {dlb}: case OBJ_BOOKS: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) { char primary = (item.special / 10); char secondary = (item.special % 10); @@ -1930,7 +1643,7 @@ static char item_name_2( const item_def &item, char buff[ITEMNAME_SIZE], // compacted 15 Apr 2000 {dlb}: case OBJ_STAVES: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) { strncat(buff, (item.special == 0) ? "curved" : (item.special == 1) ? "glowing" : @@ -2239,516 +1952,6 @@ char get_ident_type(char cla, int ty) } } // end get_ident_type() -int property( const item_def &item, int prop_type ) -{ - switch (item.base_type) - { - case OBJ_ARMOUR: - case OBJ_WEAPONS: - case OBJ_MISSILES: - return (prop[ item.base_type ][ item.sub_type ][ prop_type ]); - - case OBJ_STAVES: - if (item_is_staff( item )) - return (prop[ OBJ_WEAPONS ][ WPN_QUARTERSTAFF ][ prop_type ]); - else if (prop_type == PWPN_SPEED) // item is rod - return (10); // extra protection against speed 0 - else - return (0); - - default: - return (0); - } -} - -int mass_item( const item_def &item ) -{ - int unit_mass = 0; - - if (item.base_type == OBJ_GOLD) - { - unit_mass = 0; - } - else if (item.base_type == OBJ_CORPSES) - { - unit_mass = mons_weight( item.plus ); - - if (item.sub_type == CORPSE_SKELETON) - unit_mass /= 2; - } - else - { - unit_mass = mss[ item.base_type ][ item.sub_type ]; - } - - return (unit_mass > 0 ? unit_mass : 0); -} - -void init_properties(void) -{ - prop[OBJ_ARMOUR][ARM_ROBE][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_ROBE][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_ROBE] = 60; - - prop[OBJ_ARMOUR][ARM_LEATHER_ARMOUR][PARM_AC] = 2; - prop[OBJ_ARMOUR][ARM_LEATHER_ARMOUR][PARM_EVASION] = -1; - mss[OBJ_ARMOUR][ARM_LEATHER_ARMOUR] = 150; - - prop[OBJ_ARMOUR][ARM_RING_MAIL][PARM_AC] = 4; - prop[OBJ_ARMOUR][ARM_RING_MAIL][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_RING_MAIL] = 300; - - prop[OBJ_ARMOUR][ARM_SCALE_MAIL][PARM_AC] = 5; - prop[OBJ_ARMOUR][ARM_SCALE_MAIL][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_SCALE_MAIL] = 400; - - prop[OBJ_ARMOUR][ARM_CHAIN_MAIL][PARM_AC] = 6; - prop[OBJ_ARMOUR][ARM_CHAIN_MAIL][PARM_EVASION] = -3; - mss[OBJ_ARMOUR][ARM_CHAIN_MAIL] = 450; - - prop[OBJ_ARMOUR][ARM_SPLINT_MAIL][PARM_AC] = 8; - prop[OBJ_ARMOUR][ARM_SPLINT_MAIL][PARM_EVASION] = -5; - mss[OBJ_ARMOUR][ARM_SPLINT_MAIL] = 550; - - prop[OBJ_ARMOUR][ARM_BANDED_MAIL][PARM_AC] = 7; - prop[OBJ_ARMOUR][ARM_BANDED_MAIL][PARM_EVASION] = -4; - mss[OBJ_ARMOUR][ARM_BANDED_MAIL] = 500; - - prop[OBJ_ARMOUR][ARM_PLATE_MAIL][PARM_AC] = 9; - prop[OBJ_ARMOUR][ARM_PLATE_MAIL][PARM_EVASION] = -5; - mss[OBJ_ARMOUR][ARM_PLATE_MAIL] = 650; - - prop[OBJ_ARMOUR][ARM_DRAGON_HIDE][PARM_AC] = 2; - prop[OBJ_ARMOUR][ARM_DRAGON_HIDE][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_DRAGON_HIDE] = 220; - - prop[OBJ_ARMOUR][ARM_TROLL_HIDE][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_TROLL_HIDE][PARM_EVASION] = -1; - mss[OBJ_ARMOUR][ARM_TROLL_HIDE] = 180; - - prop[OBJ_ARMOUR][ARM_CRYSTAL_PLATE_MAIL][PARM_AC] = 16; - prop[OBJ_ARMOUR][ARM_CRYSTAL_PLATE_MAIL][PARM_EVASION] = -8; - mss[OBJ_ARMOUR][ARM_CRYSTAL_PLATE_MAIL] = 1200; - - prop[OBJ_ARMOUR][ARM_DRAGON_ARMOUR][PARM_AC] = 8; - prop[OBJ_ARMOUR][ARM_DRAGON_ARMOUR][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_DRAGON_ARMOUR] = 220; - - prop[OBJ_ARMOUR][ARM_TROLL_LEATHER_ARMOUR][PARM_AC] = 3; - prop[OBJ_ARMOUR][ARM_TROLL_LEATHER_ARMOUR][PARM_EVASION] = -1; - mss[OBJ_ARMOUR][ARM_TROLL_LEATHER_ARMOUR] = 180; - - prop[OBJ_ARMOUR][ARM_ICE_DRAGON_HIDE][PARM_AC] = 2; - prop[OBJ_ARMOUR][ARM_ICE_DRAGON_HIDE][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_ICE_DRAGON_HIDE] = 220; - - prop[OBJ_ARMOUR][ARM_ICE_DRAGON_ARMOUR][PARM_AC] = 9; - prop[OBJ_ARMOUR][ARM_ICE_DRAGON_ARMOUR][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_ICE_DRAGON_ARMOUR] = 220; - - prop[OBJ_ARMOUR][ARM_STEAM_DRAGON_HIDE][PARM_AC] = 0; - prop[OBJ_ARMOUR][ARM_STEAM_DRAGON_HIDE][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_STEAM_DRAGON_HIDE] = 120; - - prop[OBJ_ARMOUR][ARM_STEAM_DRAGON_ARMOUR][PARM_AC] = 3; - prop[OBJ_ARMOUR][ARM_STEAM_DRAGON_ARMOUR][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_STEAM_DRAGON_ARMOUR] = 120; - - prop[OBJ_ARMOUR][ARM_MOTTLED_DRAGON_HIDE][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_MOTTLED_DRAGON_HIDE][PARM_EVASION] = -1; - mss[OBJ_ARMOUR][ARM_MOTTLED_DRAGON_HIDE] = 150; - - prop[OBJ_ARMOUR][ARM_MOTTLED_DRAGON_ARMOUR][PARM_AC] = 5; - prop[OBJ_ARMOUR][ARM_MOTTLED_DRAGON_ARMOUR][PARM_EVASION] = -1; - mss[OBJ_ARMOUR][ARM_MOTTLED_DRAGON_ARMOUR] = 150; - - prop[OBJ_ARMOUR][ARM_STORM_DRAGON_HIDE][PARM_AC] = 2; - prop[OBJ_ARMOUR][ARM_STORM_DRAGON_HIDE][PARM_EVASION] = -5; - mss[OBJ_ARMOUR][ARM_STORM_DRAGON_HIDE] = 400; - - prop[OBJ_ARMOUR][ARM_STORM_DRAGON_ARMOUR][PARM_AC] = 10; - prop[OBJ_ARMOUR][ARM_STORM_DRAGON_ARMOUR][PARM_EVASION] = -5; - mss[OBJ_ARMOUR][ARM_STORM_DRAGON_ARMOUR] = 400; - - prop[OBJ_ARMOUR][ARM_GOLD_DRAGON_HIDE][PARM_AC] = 2; - prop[OBJ_ARMOUR][ARM_GOLD_DRAGON_HIDE][PARM_EVASION] = -10; - mss[OBJ_ARMOUR][ARM_GOLD_DRAGON_HIDE] = 1100; - - prop[OBJ_ARMOUR][ARM_GOLD_DRAGON_ARMOUR][PARM_AC] = 13; - prop[OBJ_ARMOUR][ARM_GOLD_DRAGON_ARMOUR][PARM_EVASION] = -10; - mss[OBJ_ARMOUR][ARM_GOLD_DRAGON_ARMOUR] = 1100; - - prop[OBJ_ARMOUR][ARM_ANIMAL_SKIN][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_ANIMAL_SKIN][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_ANIMAL_SKIN] = 100; - - prop[OBJ_ARMOUR][ARM_SWAMP_DRAGON_HIDE][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_SWAMP_DRAGON_HIDE][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_SWAMP_DRAGON_HIDE] = 200; - - prop[OBJ_ARMOUR][ARM_SWAMP_DRAGON_ARMOUR][PARM_AC] = 7; - prop[OBJ_ARMOUR][ARM_SWAMP_DRAGON_ARMOUR][PARM_EVASION] = -2; - mss[OBJ_ARMOUR][ARM_SWAMP_DRAGON_ARMOUR] = 200; - - prop[OBJ_ARMOUR][ARM_SHIELD][PARM_AC] = 0; - prop[OBJ_ARMOUR][ARM_SHIELD][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_SHIELD] = 100; - - prop[OBJ_ARMOUR][ARM_CLOAK][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_CLOAK][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_CLOAK] = 20; - - prop[OBJ_ARMOUR][ARM_HELMET][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_HELMET][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_HELMET] = 80; - - prop[OBJ_ARMOUR][ARM_GLOVES][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_GLOVES][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_GLOVES] = 20; - - prop[OBJ_ARMOUR][ARM_BOOTS][PARM_AC] = 1; - prop[OBJ_ARMOUR][ARM_BOOTS][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_BOOTS] = 40; - - prop[OBJ_ARMOUR][ARM_BUCKLER][PARM_AC] = 0; - prop[OBJ_ARMOUR][ARM_BUCKLER][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_BUCKLER] = 50; - - prop[OBJ_ARMOUR][ARM_LARGE_SHIELD][PARM_AC] = 0; - prop[OBJ_ARMOUR][ARM_LARGE_SHIELD][PARM_EVASION] = 0; - mss[OBJ_ARMOUR][ARM_LARGE_SHIELD] = 250; - - int i = 0; - - for (i = 0; i < 50; i++) - { - mss[OBJ_WANDS][i] = 100; - mss[OBJ_FOOD][i] = 100; - mss[OBJ_UNKNOWN_I][i] = 200; // labeled as "books" elsewhere - - //jmf: made scrolls, jewellery and potions weigh less. - mss[OBJ_SCROLLS][i] = 20; - mss[OBJ_JEWELLERY][i] = 10; - mss[OBJ_POTIONS][i] = 40; - mss[OBJ_UNKNOWN_II][i] = 5; // "gems" - mss[OBJ_BOOKS][i] = 70; - - mss[OBJ_STAVES][i] = 130; - mss[OBJ_ORBS][i] = 300; - mss[OBJ_MISCELLANY][i] = 100; - mss[OBJ_CORPSES][i] = 100; - } - - // rods are lighter than staves - for (i = STAFF_SMITING; i < STAFF_AIR; i++) - { - mss[OBJ_STAVES][i] = 70; - } - - // this is food, right? - mss[OBJ_FOOD][FOOD_MEAT_RATION] = 80; - mss[OBJ_FOOD][FOOD_BREAD_RATION] = 80; - mss[OBJ_FOOD][FOOD_PEAR] = 20; - mss[OBJ_FOOD][FOOD_APPLE] = 20; - mss[OBJ_FOOD][FOOD_CHOKO] = 30; - mss[OBJ_FOOD][FOOD_HONEYCOMB] = 40; - mss[OBJ_FOOD][FOOD_ROYAL_JELLY] = 55; - mss[OBJ_FOOD][FOOD_SNOZZCUMBER] = 50; - mss[OBJ_FOOD][FOOD_PIZZA] = 40; - mss[OBJ_FOOD][FOOD_APRICOT] = 15; - mss[OBJ_FOOD][FOOD_ORANGE] = 20; - mss[OBJ_FOOD][FOOD_BANANA] = 20; - mss[OBJ_FOOD][FOOD_STRAWBERRY] = 5; - mss[OBJ_FOOD][FOOD_RAMBUTAN] = 10; - mss[OBJ_FOOD][FOOD_LEMON] = 20; - mss[OBJ_FOOD][FOOD_GRAPE] = 5; - mss[OBJ_FOOD][FOOD_SULTANA] = 3; - mss[OBJ_FOOD][FOOD_LYCHEE] = 10; - mss[OBJ_FOOD][FOOD_BEEF_JERKY] = 20; - mss[OBJ_FOOD][FOOD_CHEESE] = 40; - mss[OBJ_FOOD][FOOD_SAUSAGE] = 40; - mss[OBJ_FOOD][FOOD_CHUNK] = 100; - /* mss [OBJ_FOOD] [21] = 40; - mss [OBJ_FOOD] [22] = 50; - mss [OBJ_FOOD] [23] = 60; - mss [OBJ_FOOD] [24] = 60; - mss [OBJ_FOOD] [25] = 100; */ - - mss[OBJ_MISCELLANY][MISC_BOTTLED_EFREET] = 250; - - mss[OBJ_MISCELLANY][MISC_CRYSTAL_BALL_OF_SEEING] = 200; - mss[OBJ_MISCELLANY][MISC_CRYSTAL_BALL_OF_ENERGY] = 200; - mss[OBJ_MISCELLANY][MISC_CRYSTAL_BALL_OF_FIXATION] = 200; - - // weapons: blunt weapons are first to help grouping them together - // note: AC prop can't be 0 or less because of division. - // If it's 1, makes no difference - - // NOTE: I have *removed* AC bit for weapons - just doesn't work - // prop [x] [2] is speed - - prop[OBJ_WEAPONS][WPN_CLUB][PWPN_DAMAGE] = 5; - prop[OBJ_WEAPONS][WPN_CLUB][PWPN_HIT] = 4; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_CLUB][PWPN_SPEED] = 12; - mss[OBJ_WEAPONS][WPN_CLUB] = 50; - - prop[OBJ_WEAPONS][WPN_MACE][PWPN_DAMAGE] = 8; - prop[OBJ_WEAPONS][WPN_MACE][PWPN_HIT] = 3; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_MACE][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_MACE] = 140; - - prop[OBJ_WEAPONS][WPN_GREAT_MACE][PWPN_DAMAGE] = 16; - prop[OBJ_WEAPONS][WPN_GREAT_MACE][PWPN_HIT] = -3; - prop[OBJ_WEAPONS][WPN_GREAT_MACE][PWPN_SPEED] = 18; - mss[OBJ_WEAPONS][WPN_GREAT_MACE] = 260; - - prop[OBJ_WEAPONS][WPN_FLAIL][PWPN_DAMAGE] = 9; - prop[OBJ_WEAPONS][WPN_FLAIL][PWPN_HIT] = 2; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_FLAIL][PWPN_SPEED] = 15; - mss[OBJ_WEAPONS][WPN_FLAIL] = 150; - - prop[OBJ_WEAPONS][WPN_SPIKED_FLAIL][PWPN_DAMAGE] = 12; - prop[OBJ_WEAPONS][WPN_SPIKED_FLAIL][PWPN_HIT] = 1; - prop[OBJ_WEAPONS][WPN_SPIKED_FLAIL][PWPN_SPEED] = 16; - mss[OBJ_WEAPONS][WPN_SPIKED_FLAIL] = 170; - - prop[OBJ_WEAPONS][WPN_GREAT_FLAIL][PWPN_DAMAGE] = 17; - prop[OBJ_WEAPONS][WPN_GREAT_FLAIL][PWPN_HIT] = -4; - prop[OBJ_WEAPONS][WPN_GREAT_FLAIL][PWPN_SPEED] = 19; - mss[OBJ_WEAPONS][WPN_GREAT_FLAIL] = 300; - - prop[OBJ_WEAPONS][WPN_DAGGER][PWPN_DAMAGE] = 3; - prop[OBJ_WEAPONS][WPN_DAGGER][PWPN_HIT] = 6; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_DAGGER][PWPN_SPEED] = 11; - mss[OBJ_WEAPONS][WPN_DAGGER] = 20; - - prop[OBJ_WEAPONS][WPN_KNIFE][PWPN_DAMAGE] = 2; - prop[OBJ_WEAPONS][WPN_KNIFE][PWPN_HIT] = 0; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_KNIFE][PWPN_SPEED] = 11; - mss[OBJ_WEAPONS][WPN_KNIFE] = 10; - - prop[OBJ_WEAPONS][WPN_MORNINGSTAR][PWPN_DAMAGE] = 10; - prop[OBJ_WEAPONS][WPN_MORNINGSTAR][PWPN_HIT] = 2; - prop[OBJ_WEAPONS][WPN_MORNINGSTAR][PWPN_SPEED] = 15; - mss[OBJ_WEAPONS][WPN_MORNINGSTAR] = 150; - - prop[OBJ_WEAPONS][WPN_SHORT_SWORD][PWPN_DAMAGE] = 6; - prop[OBJ_WEAPONS][WPN_SHORT_SWORD][PWPN_HIT] = 5; - prop[OBJ_WEAPONS][WPN_SHORT_SWORD][PWPN_SPEED] = 12; - mss[OBJ_WEAPONS][WPN_SHORT_SWORD] = 100; - - prop[OBJ_WEAPONS][WPN_LONG_SWORD][PWPN_DAMAGE] = 10; - prop[OBJ_WEAPONS][WPN_LONG_SWORD][PWPN_HIT] = 3; - prop[OBJ_WEAPONS][WPN_LONG_SWORD][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_LONG_SWORD] = 160; - - prop[OBJ_WEAPONS][WPN_GREAT_SWORD][PWPN_DAMAGE] = 16; - prop[OBJ_WEAPONS][WPN_GREAT_SWORD][PWPN_HIT] = -1; - prop[OBJ_WEAPONS][WPN_GREAT_SWORD][PWPN_SPEED] = 17; - mss[OBJ_WEAPONS][WPN_GREAT_SWORD] = 250; - - prop[OBJ_WEAPONS][WPN_FALCHION][PWPN_DAMAGE] = 8; - prop[OBJ_WEAPONS][WPN_FALCHION][PWPN_HIT] = 2; - prop[OBJ_WEAPONS][WPN_FALCHION][PWPN_SPEED] = 13; - mss[OBJ_WEAPONS][WPN_FALCHION] = 130; - - prop[OBJ_WEAPONS][WPN_SCIMITAR][PWPN_DAMAGE] = 11; - prop[OBJ_WEAPONS][WPN_SCIMITAR][PWPN_HIT] = 1; - prop[OBJ_WEAPONS][WPN_SCIMITAR][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_SCIMITAR] = 170; - - prop[OBJ_WEAPONS][WPN_HAND_AXE][PWPN_DAMAGE] = 7; - prop[OBJ_WEAPONS][WPN_HAND_AXE][PWPN_HIT] = 2; - prop[OBJ_WEAPONS][WPN_HAND_AXE][PWPN_SPEED] = 13; - mss[OBJ_WEAPONS][WPN_HAND_AXE] = 110; - - prop[OBJ_WEAPONS][WPN_WAR_AXE][PWPN_DAMAGE] = 11; - prop[OBJ_WEAPONS][WPN_WAR_AXE][PWPN_HIT] = 0; - prop[OBJ_WEAPONS][WPN_WAR_AXE][PWPN_SPEED] = 16; - mss[OBJ_WEAPONS][WPN_WAR_AXE] = 150; - - prop[OBJ_WEAPONS][WPN_BROAD_AXE][PWPN_DAMAGE] = 14; - prop[OBJ_WEAPONS][WPN_BROAD_AXE][PWPN_HIT] = 1; - prop[OBJ_WEAPONS][WPN_BROAD_AXE][PWPN_SPEED] = 17; - mss[OBJ_WEAPONS][WPN_BROAD_AXE] = 180; - - prop[OBJ_WEAPONS][WPN_BATTLEAXE][PWPN_DAMAGE] = 17; - prop[OBJ_WEAPONS][WPN_BATTLEAXE][PWPN_HIT] = -2; - prop[OBJ_WEAPONS][WPN_BATTLEAXE][PWPN_SPEED] = 18; - mss[OBJ_WEAPONS][WPN_BATTLEAXE] = 200; - - prop[OBJ_WEAPONS][WPN_SPEAR][PWPN_DAMAGE] = 5; - prop[OBJ_WEAPONS][WPN_SPEAR][PWPN_HIT] = 3; - prop[OBJ_WEAPONS][WPN_SPEAR][PWPN_SPEED] = 13; - mss[OBJ_WEAPONS][WPN_SPEAR] = 50; - - prop[OBJ_WEAPONS][WPN_TRIDENT][PWPN_DAMAGE] = 9; - prop[OBJ_WEAPONS][WPN_TRIDENT][PWPN_HIT] = -2; - prop[OBJ_WEAPONS][WPN_TRIDENT][PWPN_SPEED] = 17; - mss[OBJ_WEAPONS][WPN_TRIDENT] = 160; - - prop[OBJ_WEAPONS][WPN_DEMON_TRIDENT][PWPN_DAMAGE] = 15; - prop[OBJ_WEAPONS][WPN_DEMON_TRIDENT][PWPN_HIT] = -2; - prop[OBJ_WEAPONS][WPN_DEMON_TRIDENT][PWPN_SPEED] = 17; - mss[OBJ_WEAPONS][WPN_DEMON_TRIDENT] = 160; - - prop[OBJ_WEAPONS][WPN_HALBERD][PWPN_DAMAGE] = 13; - prop[OBJ_WEAPONS][WPN_HALBERD][PWPN_HIT] = -3; - prop[OBJ_WEAPONS][WPN_HALBERD][PWPN_SPEED] = 19; - mss[OBJ_WEAPONS][WPN_HALBERD] = 200; - - // sling - // - the three properties are _not_ irrelevant here - // - when something hits something else (either may be you) - // in melee, these are used. - prop[OBJ_WEAPONS][WPN_SLING][PWPN_DAMAGE] = 1; - prop[OBJ_WEAPONS][WPN_SLING][PWPN_HIT] = -1; - prop[OBJ_WEAPONS][WPN_SLING][PWPN_SPEED] = 11; - mss[OBJ_WEAPONS][WPN_SLING] = 10; - - prop[OBJ_WEAPONS][WPN_BOW][PWPN_DAMAGE] = 2; - prop[OBJ_WEAPONS][WPN_BOW][PWPN_HIT] = -3; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_BOW][PWPN_SPEED] = 11; - mss[OBJ_WEAPONS][WPN_BOW] = 100; - - prop[OBJ_WEAPONS][WPN_BLOWGUN][PWPN_DAMAGE] = 1; - prop[OBJ_WEAPONS][WPN_BLOWGUN][PWPN_HIT] = 0; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_BLOWGUN][PWPN_SPEED] = 10; - mss[OBJ_WEAPONS][WPN_BLOWGUN] = 50; - - prop[OBJ_WEAPONS][WPN_CROSSBOW][PWPN_DAMAGE] = 2; - prop[OBJ_WEAPONS][WPN_CROSSBOW][PWPN_HIT] = -1; - prop[OBJ_WEAPONS][WPN_CROSSBOW][PWPN_SPEED] = 15; - mss[OBJ_WEAPONS][WPN_CROSSBOW] = 250; - - prop[OBJ_WEAPONS][WPN_HAND_CROSSBOW][PWPN_DAMAGE] = 1; - prop[OBJ_WEAPONS][WPN_HAND_CROSSBOW][PWPN_HIT] = -1; - prop[OBJ_WEAPONS][WPN_HAND_CROSSBOW][PWPN_SPEED] = 15; - mss[OBJ_WEAPONS][WPN_HAND_CROSSBOW] = 70; - - prop[OBJ_WEAPONS][WPN_GLAIVE][PWPN_DAMAGE] = 15; - prop[OBJ_WEAPONS][WPN_GLAIVE][PWPN_HIT] = -3; - prop[OBJ_WEAPONS][WPN_GLAIVE][PWPN_SPEED] = 18; - mss[OBJ_WEAPONS][WPN_GLAIVE] = 200; - - // staff - hmmm - prop[OBJ_WEAPONS][WPN_QUARTERSTAFF][PWPN_DAMAGE] = 7; - prop[OBJ_WEAPONS][WPN_QUARTERSTAFF][PWPN_HIT] = 6; - prop[OBJ_WEAPONS][WPN_QUARTERSTAFF][PWPN_SPEED] = 12; - mss[OBJ_WEAPONS][WPN_QUARTERSTAFF] = 130; - - prop[OBJ_WEAPONS][WPN_SCYTHE][PWPN_DAMAGE] = 14; - prop[OBJ_WEAPONS][WPN_SCYTHE][PWPN_HIT] = -4; - prop[OBJ_WEAPONS][WPN_SCYTHE][PWPN_SPEED] = 22; - mss[OBJ_WEAPONS][WPN_SCYTHE] = 230; - - // these two should have the same speed because of 2-h ogres. - prop[OBJ_WEAPONS][WPN_GIANT_CLUB][PWPN_DAMAGE] = 15; - prop[OBJ_WEAPONS][WPN_GIANT_CLUB][PWPN_HIT] = -5; - prop[OBJ_WEAPONS][WPN_GIANT_CLUB][PWPN_SPEED] = 16; - mss[OBJ_WEAPONS][WPN_GIANT_CLUB] = 750; - - prop[OBJ_WEAPONS][WPN_GIANT_SPIKED_CLUB][PWPN_DAMAGE] = 18; - prop[OBJ_WEAPONS][WPN_GIANT_SPIKED_CLUB][PWPN_HIT] = -6; - prop[OBJ_WEAPONS][WPN_GIANT_SPIKED_CLUB][PWPN_SPEED] = 17; - mss[OBJ_WEAPONS][WPN_GIANT_SPIKED_CLUB] = 850; - // these two should have the same speed because of 2-h ogres. - - prop[OBJ_WEAPONS][WPN_EVENINGSTAR][PWPN_DAMAGE] = 12; - prop[OBJ_WEAPONS][WPN_EVENINGSTAR][PWPN_HIT] = 2; - prop[OBJ_WEAPONS][WPN_EVENINGSTAR][PWPN_SPEED] = 15; - mss[OBJ_WEAPONS][WPN_EVENINGSTAR] = 150; - - prop[OBJ_WEAPONS][WPN_QUICK_BLADE][PWPN_DAMAGE] = 5; - prop[OBJ_WEAPONS][WPN_QUICK_BLADE][PWPN_HIT] = 6; - prop[OBJ_WEAPONS][WPN_QUICK_BLADE][PWPN_SPEED] = 7; - mss[OBJ_WEAPONS][WPN_QUICK_BLADE] = 100; - - prop[OBJ_WEAPONS][WPN_KATANA][PWPN_DAMAGE] = 13; - prop[OBJ_WEAPONS][WPN_KATANA][PWPN_HIT] = 4; - prop[OBJ_WEAPONS][WPN_KATANA][PWPN_SPEED] = 13; - mss[OBJ_WEAPONS][WPN_KATANA] = 200; - - prop[OBJ_WEAPONS][WPN_BLESSED_BLADE][PWPN_DAMAGE] = 14; - prop[OBJ_WEAPONS][WPN_BLESSED_BLADE][PWPN_HIT] = -3; - prop[OBJ_WEAPONS][WPN_BLESSED_BLADE][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_BLESSED_BLADE] = 160; - - prop[OBJ_WEAPONS][WPN_EXECUTIONERS_AXE][PWPN_DAMAGE] = 20; - prop[OBJ_WEAPONS][WPN_EXECUTIONERS_AXE][PWPN_HIT] = -4; - prop[OBJ_WEAPONS][WPN_EXECUTIONERS_AXE][PWPN_SPEED] = 20; - mss[OBJ_WEAPONS][WPN_EXECUTIONERS_AXE] = 320; - - prop[OBJ_WEAPONS][WPN_DOUBLE_SWORD][PWPN_DAMAGE] = 15; - prop[OBJ_WEAPONS][WPN_DOUBLE_SWORD][PWPN_HIT] = 3; - prop[OBJ_WEAPONS][WPN_DOUBLE_SWORD][PWPN_SPEED] = 16; - mss[OBJ_WEAPONS][WPN_DOUBLE_SWORD] = 220; - - prop[OBJ_WEAPONS][WPN_TRIPLE_SWORD][PWPN_DAMAGE] = 19; - prop[OBJ_WEAPONS][WPN_TRIPLE_SWORD][PWPN_HIT] = -1; - prop[OBJ_WEAPONS][WPN_TRIPLE_SWORD][PWPN_SPEED] = 19; - mss[OBJ_WEAPONS][WPN_TRIPLE_SWORD] = 300; - - prop[OBJ_WEAPONS][WPN_HAMMER][PWPN_DAMAGE] = 7; - prop[OBJ_WEAPONS][WPN_HAMMER][PWPN_HIT] = 2; - prop[OBJ_WEAPONS][WPN_HAMMER][PWPN_SPEED] = 13; - mss[OBJ_WEAPONS][WPN_HAMMER] = 130; - - prop[OBJ_WEAPONS][WPN_ANCUS][PWPN_DAMAGE] = 9; - prop[OBJ_WEAPONS][WPN_ANCUS][PWPN_HIT] = 1; - prop[OBJ_WEAPONS][WPN_ANCUS][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_ANCUS] = 160; - - prop[OBJ_WEAPONS][WPN_WHIP][PWPN_DAMAGE] = 3; - prop[OBJ_WEAPONS][WPN_WHIP][PWPN_HIT] = 1; // helps to get past evasion - prop[OBJ_WEAPONS][WPN_WHIP][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_WHIP] = 30; - - prop[OBJ_WEAPONS][WPN_SABRE][PWPN_DAMAGE] = 7; - prop[OBJ_WEAPONS][WPN_SABRE][PWPN_HIT] = 4; - prop[OBJ_WEAPONS][WPN_SABRE][PWPN_SPEED] = 12; - mss[OBJ_WEAPONS][WPN_SABRE] = 110; - - prop[OBJ_WEAPONS][WPN_DEMON_BLADE][PWPN_DAMAGE] = 13; - prop[OBJ_WEAPONS][WPN_DEMON_BLADE][PWPN_HIT] = 2; - prop[OBJ_WEAPONS][WPN_DEMON_BLADE][PWPN_SPEED] = 15; - mss[OBJ_WEAPONS][WPN_DEMON_BLADE] = 200; - - prop[OBJ_WEAPONS][WPN_DEMON_WHIP][PWPN_DAMAGE] = 10; - prop[OBJ_WEAPONS][WPN_DEMON_WHIP][PWPN_HIT] = 1; - prop[OBJ_WEAPONS][WPN_DEMON_WHIP][PWPN_SPEED] = 14; - mss[OBJ_WEAPONS][WPN_DEMON_WHIP] = 30; - - - // MISSILES: - - prop[OBJ_MISSILES][MI_STONE][PWPN_DAMAGE] = 2; - prop[OBJ_MISSILES][MI_STONE][PWPN_HIT] = 4; - mss[OBJ_MISSILES][MI_STONE] = 5; - - prop[OBJ_MISSILES][MI_ARROW][PWPN_DAMAGE] = 2; - prop[OBJ_MISSILES][MI_ARROW][PWPN_HIT] = 6; - mss[OBJ_MISSILES][MI_ARROW] = 10; - - prop[OBJ_MISSILES][MI_NEEDLE][PWPN_DAMAGE] = 0; - prop[OBJ_MISSILES][MI_NEEDLE][PWPN_HIT] = 1; - mss[OBJ_MISSILES][MI_NEEDLE] = 1; - - prop[OBJ_MISSILES][MI_BOLT][PWPN_DAMAGE] = 2; - prop[OBJ_MISSILES][MI_BOLT][PWPN_HIT] = 8; - mss[OBJ_MISSILES][MI_BOLT] = 12; - - prop[OBJ_MISSILES][MI_DART][PWPN_DAMAGE] = 2; - prop[OBJ_MISSILES][MI_DART][PWPN_HIT] = 4; //whatever - for hand crossbow - mss[OBJ_MISSILES][MI_DART] = 5; - - // large rock - prop[OBJ_MISSILES][MI_LARGE_ROCK][PWPN_DAMAGE] = 20; - prop[OBJ_MISSILES][MI_LARGE_ROCK][PWPN_HIT] = 10; - mss[OBJ_MISSILES][MI_LARGE_ROCK] = 1000; -} - - unsigned char check_item_knowledge(void) { char st_pass[ITEMNAME_SIZE] = ""; @@ -2914,117 +2117,100 @@ unsigned char check_item_knowledge(void) } // end check_item_knowledge() -// must be certain that you are passing the subtype -// to an OBJ_ARMOUR and nothing else, or as they say, -// "Bad Things Will Happen" {dlb}: -bool hide2armour( unsigned char *which_subtype ) +// Used for: Pandemonium demonlords, shopkeepers, scrolls, random artefacts +int make_name( unsigned long seed, bool all_cap, char buff[ ITEMNAME_SIZE ] ) { - switch (*which_subtype) - { - case ARM_DRAGON_HIDE: - *which_subtype = ARM_DRAGON_ARMOUR; - return true; - case ARM_TROLL_HIDE: - *which_subtype = ARM_TROLL_LEATHER_ARMOUR; - return true; - case ARM_ICE_DRAGON_HIDE: - *which_subtype = ARM_ICE_DRAGON_ARMOUR; - return true; - case ARM_MOTTLED_DRAGON_HIDE: - *which_subtype = ARM_MOTTLED_DRAGON_ARMOUR; - return true; - case ARM_STORM_DRAGON_HIDE: - *which_subtype = ARM_STORM_DRAGON_ARMOUR; - return true; - case ARM_GOLD_DRAGON_HIDE: - *which_subtype = ARM_GOLD_DRAGON_ARMOUR; - return true; - case ARM_SWAMP_DRAGON_HIDE: - *which_subtype = ARM_SWAMP_DRAGON_ARMOUR; - return true; - case ARM_STEAM_DRAGON_HIDE: - *which_subtype = ARM_STEAM_DRAGON_ARMOUR; - return true; - default: - return false; - } -} // end hide2armour() - + char name[ITEMNAME_SIZE]; + int numb[17]; -void make_name(unsigned char var1, unsigned char var2, unsigned char var3, - char ncase, char buff[ITEMNAME_SIZE]) -{ - char name[ ITEMNAME_SIZE ] = ""; - FixedVector < unsigned char, 15 > numb; - int len; int i = 0; - int nexty = 0; - int j = 0; - int x = 0; - - numb[0] = var1 * var2; - numb[1] = var1 * var3; - numb[2] = var2 * var3; - numb[3] = var1 * var2 * var3; - numb[4] = var1 + var2; - numb[5] = var2 + var3; - numb[6] = var1 * var2 + var3; - numb[7] = var1 * var3 + var2; - numb[8] = var2 * var3 + var1; - numb[9] = var1 * var2 * var3 - var1; - numb[10] = var1 + var2 + var2; - numb[11] = var2 + var3 * var1; - numb[12] = var1 * var2 * var3; - numb[13] = var1 * var3 * var1; - numb[14] = var2 * var3 * var3; - - for (i = 0; i < 15; i++) - { - while (numb[i] >= 25) - { - numb[i] -= 25; - } - } - - j = numb[6]; - - len = reduce(numb[reduce(numb[11]) / 2]); - - while (len < 5 && j < 10) - { - len += 1 + reduce(1 + numb[j]); - j++; - } - - while (len > 14) - { - len -= 8; - } - - nexty = retbit(numb[4]); - - char k = 0; - - j = 0; + bool want_vowel = false; + bool has_space = false; + + for (i = 0; i < ITEMNAME_SIZE; i++) + name[i] = '\0'; + + const int var1 = (seed & 0xFF); + const int var2 = ((seed >> 8) & 0xFF); + const int var3 = ((seed >> 16) & 0xFF); + const int var4 = ((seed >> 24) & 0xFF); + + numb[0] = 373 * var1 + 409 * var2 + 281 * var3; + numb[1] = 163 * var4 + 277 * var2 + 317 * var3; + numb[2] = 257 * var1 + 179 * var4 + 83 * var3; + numb[3] = 61 * var1 + 229 * var2 + 241 * var4; + numb[4] = 79 * var1 + 263 * var2 + 149 * var3; + numb[5] = 233 * var4 + 383 * var2 + 311 * var3; + numb[6] = 199 * var1 + 211 * var4 + 103 * var3; + numb[7] = 139 * var1 + 109 * var2 + 349 * var4; + numb[8] = 43 * var1 + 389 * var2 + 359 * var3; + numb[9] = 367 * var4 + 101 * var2 + 251 * var3; + numb[10] = 293 * var1 + 59 * var4 + 151 * var3; + numb[11] = 331 * var1 + 107 * var2 + 307 * var4; + numb[12] = 73 * var1 + 157 * var2 + 347 * var3; + numb[13] = 379 * var4 + 353 * var2 + 227 * var3; + numb[14] = 181 * var1 + 173 * var4 + 193 * var3; + numb[15] = 131 * var1 + 167 * var2 + 53 * var4; + numb[16] = 313 * var1 + 127 * var2 + 401 * var3 + 337 * var4; + + int len = 3 + numb[0] % 5 + ((numb[1] % 5 == 0) ? numb[2] % 6 : 1); + + if (all_cap) + len += 6; + + int j = numb[3] % 17; + const int k = numb[4] % 17; + int count = 0; for (i = 0; i < len; i++) { - j++; - - if (j >= 15) + j = (j + 1) % 17; + if (j == 0) { - j = 0; - - k++; - - if (k > 9) + count++; + if (count > 9) break; } - if (nexty == 1 || (i > 0 && !is_random_name_vowel(name[i]))) + if (!has_space && i > 5 && i < len - 4 + && (numb[(k + 10 * j) % 17] % 5) != 3) { - name[i] = retvow(numb[j]); - if ((i == 0 || i == len - 1) && name[i] == 32) + want_vowel = true; + name[i] = ' '; + } + else if (i > 0 + && (want_vowel + || (i > 1 + && is_random_name_vowel( name[i - 1] ) + && !is_random_name_vowel( name[i - 2] ) + && (numb[(k + 4 * j) % 17] % 5) <= 1 ))) + { + want_vowel = true; + name[i] = retvow( numb[(k + 7 * j) % 17] ); + + if (is_random_name_space( name[i] )) + { + if (i == 0) + { + want_vowel = false; + name[i] = retlet( numb[(k + 14 * j) % 17] ); + } + else if (len < 7 + || i <= 2 || i >= len - 3 + || is_random_name_space( name[i - 1] ) + || (i > 1 && is_random_name_space( name[i - 2] )) + || (i > 2 + && !is_random_name_vowel( name[i - 1] ) + && !is_random_name_vowel( name[i - 2] ))) + { + i--; + continue; + } + } + else if (i > 1 + && name[i] == name[i - 1] + && (name[i] == 'y' || name[i] == 'i' + || (numb[(k + 12 * j) % 17] % 5) <= 1)) { i--; continue; @@ -3032,247 +2218,198 @@ void make_name(unsigned char var1, unsigned char var2, unsigned char var3, } else { - if (numb[i / 2] <= 1 && i > 3 && is_random_name_vowel(name[i])) - goto two_letter; + if ((len > 3 || i != 0) + && (numb[(k + 13 * j) % 17] % 7) <= 1 + && (i < len - 2 || (i > 0 && !is_random_name_space(name[i - 1])))) + { + const bool beg = ((i < 1) || is_random_name_space(name[i - 1])); + const bool end = (i >= len - 2); + + const int first = (beg ? 0 : (end ? 14 : 0)); + const int last = (beg ? 27 : (end ? 56 : 67)); + + const int num = last - first; + + i++; + + switch (numb[(k + 11 * j) % 17] % num + first) + { + // start, middle + case 0: strcat(name, "kl"); break; + case 1: strcat(name, "gr"); break; + case 2: strcat(name, "cl"); break; + case 3: strcat(name, "cr"); break; + case 4: strcat(name, "fr"); break; + case 5: strcat(name, "pr"); break; + case 6: strcat(name, "tr"); break; + case 7: strcat(name, "tw"); break; + case 8: strcat(name, "br"); break; + case 9: strcat(name, "pl"); break; + case 10: strcat(name, "bl"); break; + case 11: strcat(name, "str"); i++; len++; break; + case 12: strcat(name, "shr"); i++; len++; break; + case 13: strcat(name, "thr"); i++; len++; break; + // start, middle, end + case 14: strcat(name, "sm"); break; + case 15: strcat(name, "sh"); break; + case 16: strcat(name, "ch"); break; + case 17: strcat(name, "th"); break; + case 18: strcat(name, "ph"); break; + case 19: strcat(name, "pn"); break; + case 20: strcat(name, "kh"); break; + case 21: strcat(name, "gh"); break; + case 22: strcat(name, "mn"); break; + case 23: strcat(name, "ps"); break; + case 24: strcat(name, "st"); break; + case 25: strcat(name, "sk"); break; + case 26: strcat(name, "sch"); i++; len++; break; + // middle, end + case 27: strcat(name, "ts"); break; + case 28: strcat(name, "cs"); break; + case 29: strcat(name, "xt"); break; + case 30: strcat(name, "nt"); break; + case 31: strcat(name, "ll"); break; + case 32: strcat(name, "rr"); break; + case 33: strcat(name, "ss"); break; + case 34: strcat(name, "wk"); break; + case 35: strcat(name, "wn"); break; + case 36: strcat(name, "ng"); break; + case 37: strcat(name, "cw"); break; + case 38: strcat(name, "mp"); break; + case 39: strcat(name, "ck"); break; + case 40: strcat(name, "nk"); break; + case 41: strcat(name, "dd"); break; + case 42: strcat(name, "tt"); break; + case 43: strcat(name, "bb"); break; + case 44: strcat(name, "pp"); break; + case 45: strcat(name, "nn"); break; + case 46: strcat(name, "mm"); break; + case 47: strcat(name, "kk"); break; + case 48: strcat(name, "gg"); break; + case 49: strcat(name, "ff"); break; + case 50: strcat(name, "pt"); break; + case 51: strcat(name, "tz"); break; + case 52: strcat(name, "dgh"); i++; len++; break; + case 53: strcat(name, "rgh"); i++; len++; break; + case 54: strcat(name, "rph"); i++; len++; break; + case 55: strcat(name, "rch"); i++; len++; break; + // middle only + case 56: strcat(name, "cz"); break; + case 57: strcat(name, "xk"); break; + case 58: strcat(name, "zx"); break; + case 59: strcat(name, "xz"); break; + case 60: strcat(name, "cv"); break; + case 61: strcat(name, "vv"); break; + case 62: strcat(name, "nl"); break; + case 63: strcat(name, "rh"); break; + case 64: strcat(name, "dw"); break; + case 65: strcat(name, "nw"); break; + case 66: strcat(name, "khl"); i++; len++; break; + default: + i--; + break; + } + } else - name[i] = numb[j]; + { + if (i == 0) + { + name[i] = 'a' + (numb[(k + 8 * j) % 17] % 26); + want_vowel = is_random_name_vowel( name[i] ); + } + else + { + name[i] = retlet( numb[(k + 3 * j) % 17] ); + } + } } - hello: - - if ((nexty == 0 && is_random_name_vowel(name[i])) - || (nexty == 1 && !is_random_name_vowel(name[i]))) + if (name[i] == '\0') { - if (nexty == 1 && i > 0 && !is_random_name_vowel(name[i - 1])) - i--; + i--; + continue; + } + if (want_vowel && !is_random_name_vowel( name[i] ) + || (!want_vowel && is_random_name_vowel( name[i] ))) + { i--; continue; } - if (!is_random_name_vowel(name[i])) - nexty = 1; + if (is_random_name_space( name[i] )) + has_space = true; + + if (!is_random_name_vowel( name[i] )) + want_vowel = true; else - nexty = 0; + want_vowel = false; + } - x++; + // catch break and try to give a final letter + if (i > 0 + && !is_random_name_space( name[i - 1] ) + && name[i - 1] != 'y' + && is_random_name_vowel( name[i - 1] ) + && (count > 9 || (i < 8 && numb[16] % 3))) + { + name[i] = retlet( numb[j] ); } + + len = strlen( name ); - switch (ncase) + if (len) { - case 2: - for (i = 0; i < len + 1; i++) + for (i = len - 1; i > 0; i--) { - if (i > 3 && name[i] == 0 && name[i + 1] == 0) - { - name[i] = 0; - if (name[i - 1] == 32) - name[i - 1] = 0; + if (!isspace( name[i] )) break; - } - if (name[i] != 32 && name[i] < 30) - name[i] += 65; - if (name[i] > 96) - name[i] -= 32; - } - break; - - case 3: - for (i = 0; i < len + 0; i++) - { - if (i != 0 && name[i] >= 65 && name[i] < 97) - { - if (name[i - 1] == 32) - name[i] += 32; - } - - if (name[i] > 97) - { - if (i == 0 || name[i - 1] == 32) - name[i] -= 32; - } - - if (name[i] < 30) + else { - if (i == 0 || (name[i] != 32 && name[i - 1] == 32)) - name[i] += 65; - else - name[i] += 97; + name[i] = '\0'; + len--; } } - break; - - case 0: - for (i = 0; i < len; i++) - { - if (name[i] != 32 && name[i] < 30) - name[i] += 97; - } - break; - - case 1: - name[i] += 65; - - for (i = 1; i < len; i++) - { - if (name[i] != 32 && name[i] < 30) - name[i] += 97; //97; - } - break; } - if (strlen( name ) == 0) - strncpy( buff, "Plog", 80 ); + if (len >= 3) + strncpy( buff, name, ITEMNAME_SIZE ); else - strncpy( buff, name, 80 ); - - buff[79] = '\0'; - return; - - two_letter: - if (nexty == 1) - goto hello; - - if (!is_random_name_vowel(name[i - 1])) - goto hello; + { + strncpy( buff, "plog", ITEMNAME_SIZE ); + len = 4; + } - i++; + buff[ ITEMNAME_SIZE - 1 ] = '\0'; - switch (i * (retbit(j) + 1)) + for (i = 0; i < len; i++) { - case 0: - strcat(name, "sh"); - break; - case 1: - strcat(name, "ch"); - break; - case 2: - strcat(name, "tz"); - break; - case 3: - strcat(name, "ts"); - break; - case 4: - strcat(name, "cs"); - break; - case 5: - strcat(name, "cz"); - break; - case 6: - strcat(name, "xt"); - break; - case 7: - strcat(name, "xk"); - break; - case 8: - strcat(name, "kl"); - break; - case 9: - strcat(name, "cl"); - break; - case 10: - strcat(name, "fr"); - break; - case 11: - strcat(name, "sh"); - break; - case 12: - strcat(name, "ch"); - break; - case 13: - strcat(name, "gh"); - break; - case 14: - strcat(name, "pr"); - break; - case 15: - strcat(name, "tr"); - break; - case 16: - strcat(name, "mn"); - break; - case 17: - strcat(name, "ph"); - break; - case 18: - strcat(name, "pn"); - break; - case 19: - strcat(name, "cv"); - break; - case 20: - strcat(name, "zx"); - break; - case 21: - strcat(name, "xz"); - break; - case 23: - strcat(name, "dd"); - break; - case 24: - strcat(name, "tt"); - break; - case 25: - strcat(name, "ll"); - break; - //case 26: strcat(name, "sh"); break; - //case 12: strcat(name, "sh"); break; - //case 13: strcat(name, "sh"); break; - default: - i--; - goto hello; + if (all_cap || i == 0 || buff[i - 1] == ' ') + buff[i] = toupper( buff[i] ); } - x += 2; - - goto hello; + return (len); } // end make_name() - -char reduce(unsigned char reducee) +bool is_random_name_space(char let) { - while (reducee >= 26) - { - reducee -= 26; - } - - return reducee; -} // end reduce() + return (let == ' '); +} -bool is_random_name_vowel(unsigned char let) +static bool is_random_name_vowel( char let ) { - return (let == 0 || let == 4 || let == 8 || let == 14 || let == 20 - || let == 24 || let == 32); + return (let == 'a' || let == 'e' || let == 'i' || let == 'o' || let == 'u' + || let == 'y' || let == ' '); } // end is_random_name_vowel() -char retvow(char sed) +static char retvow( int sed ) { - - while (sed > 6) - sed -= 6; - - switch (sed) - { - case 0: - return 0; - case 1: - return 4; - case 2: - return 8; - case 3: - return 14; - case 4: - return 20; - case 5: - return 24; - case 6: - return 32; - } - - return 0; + static const char vowels[] = "aeiouaeiouaeiouy "; + return (vowels[ sed % (sizeof(vowels) - 1) ]); } // end retvow() -char retbit(char sed) +static char retlet( int sed ) { - return (sed % 2); -} // end retbit() + static const char consonants[] = "bcdfghjklmnpqrstvwxzcdfghlmnrstlmnrst"; + return (consonants[ sed % (sizeof(consonants) - 1) ]); +} diff --git a/crawl-ref/source/itemname.h b/crawl-ref/source/itemname.h index 0d1ccc79a2..5e7cc49bfe 100644 --- a/crawl-ref/source/itemname.h +++ b/crawl-ref/source/itemname.h @@ -32,13 +32,6 @@ char item_name( const item_def &item, char descrip, char buff[ITEMNAME_SIZE], /* *********************************************************************** - * called from: beam - describe - fight - item_use - items - monstuff - - * player - * *********************************************************************** */ -int mass_item( const item_def &item ); - - -/* *********************************************************************** * called from: debug - describe - dungeon - fight - files - item_use - * monstuff - mstuff2 - players - spells0 * *********************************************************************** */ @@ -80,40 +73,11 @@ void quant_name( const item_def &item, int quant, char des, * bit operations called from a large number of files * *********************************************************************** */ bool item_cursed( const item_def &item ); -bool item_uncursed( const item_def &item ); - bool item_known_cursed( const item_def &item ); bool item_known_uncursed( const item_def &item ); // bool fully_indentified( const item_def &item ); -bool item_ident( const item_def &item, unsigned long flags ); bool item_type_known( const item_def &item ); -bool item_not_ident( const item_def &item, unsigned long flags ); - -void do_curse_item( item_def &item ); -void do_uncurse_item( item_def &item ); - -void set_ident_flags( item_def &item, unsigned long flags ); -void unset_ident_flags( item_def &item, unsigned long flags ); - -void set_equip_race( item_def &item, unsigned long flags ); -void set_equip_desc( item_def &item, unsigned long flags ); - -unsigned long get_equip_race( const item_def &item ); -unsigned long get_equip_desc( const item_def &item ); - -bool cmp_equip_race( const item_def &item, unsigned long val ); -bool cmp_equip_desc( const item_def &item, unsigned long val ); - -void set_helmet_type( item_def &item, short flags ); -void set_helmet_desc( item_def &item, short flags ); -void set_helmet_random_desc( item_def &item ); - -short get_helmet_type( const item_def &item ); -short get_helmet_desc( const item_def &item ); - -bool cmp_helmet_type( const item_def &item, short val ); -bool cmp_helmet_desc( const item_def &item, short val ); bool set_item_ego_type( item_def &item, int item_type, int ego_type ); @@ -121,20 +85,12 @@ int get_weapon_brand( const item_def &item ); int get_ammo_brand( const item_def &item ); int get_armour_ego_type( const item_def &item ); -bool item_is_rod( const item_def &item ); -bool item_is_staff( const item_def &item ); - /* *********************************************************************** * called from: acr * *********************************************************************** */ void init_properties(void); -/* *********************************************************************** - * called from: files - randart - shopping - * *********************************************************************** */ -void make_name( unsigned char var1, unsigned char var2, unsigned char var3, - char ncase, char buff[ITEMNAME_SIZE] ); - +int make_name( unsigned long seed, bool all_caps, char buff[ ITEMNAME_SIZE ] ); /* *********************************************************************** * called from: files - shopping diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc new file mode 100644 index 0000000000..7f661a6617 --- /dev/null +++ b/crawl-ref/source/itemprop.cc @@ -0,0 +1,2013 @@ +/* + * File: itemprop.cc + * Summary: Misc functions. + * Written by: Brent Ross + * + * Change History (most recent first): + * + * <1> -/--/-- BWR Created + */ + +#include "AppHdr.h" +#include "itemname.h" + +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +#ifdef DOS +#include <conio.h> +#endif + +#include "externs.h" + +#include "items.h" +#include "itemprop.h" +#include "macro.h" +#include "mon-util.h" +#include "player.h" +#include "randart.h" +#include "skills2.h" +#include "stuff.h" +#include "transfor.h" +#include "view.h" + + +// XXX: name strings in most of the following are currently unused! +struct armour_def +{ + armour_type id; + const char *name; + int ac; + int ev; + int mass; + + bool light; + equipment_type slot; + size_type fit_min; + size_type fit_max; +}; + +// Note: the Little-Giant range is used to make armours which are very +// flexible and adjustable and can be worn by any player character... +// providing they also pass the shape test, of course. +static int Armour_index[NUM_ARMOURS]; +static armour_def Armour_prop[NUM_ARMOURS] = +{ + { ARM_ANIMAL_SKIN, "animal skin", 2, 0, 100, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_ROBE, "robe", 2, 0, 60, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_BIG }, + { ARM_LEATHER_ARMOUR, "leather armour", 3, -1, 150, + true, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM }, + { ARM_STUDDED_LEATHER_ARMOUR,"studded leather armour",4, -1, 180, + true, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM }, + + { ARM_RING_MAIL, "ring mail", 4, -2, 250, + false, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM }, + { ARM_SCALE_MAIL, "scale mail", 5, -3, 350, + false, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM }, + { ARM_CHAIN_MAIL, "chain mail", 6, -4, 400, + false, EQ_BODY_ARMOUR, SIZE_SMALL, SIZE_MEDIUM }, + { ARM_BANDED_MAIL, "banded mail", 7, -5, 500, + false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM }, + { ARM_SPLINT_MAIL, "splint mail", 8, -5, 550, + false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM }, + { ARM_PLATE_MAIL, "plate mail", 10, -6, 650, + false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM }, + { ARM_CRYSTAL_PLATE_MAIL, "crystal plate mail", 14, -8, 1200, + false, EQ_BODY_ARMOUR, SIZE_MEDIUM, SIZE_MEDIUM }, + + { ARM_TROLL_HIDE, "troll hide", 2, -1, 220, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_TROLL_LEATHER_ARMOUR, "troll leather armour", 4, -1, 220, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_STEAM_DRAGON_HIDE, "steam dragon hide", 2, 0, 120, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_STEAM_DRAGON_ARMOUR, "steam dragon armour", 4, 0, 120, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_MOTTLED_DRAGON_HIDE, "mottled dragon hide", 2, -1, 150, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_MOTTLED_DRAGON_ARMOUR,"mottled dragon armour", 5, -1, 150, + true, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + + { ARM_SWAMP_DRAGON_HIDE, "swamp dragon hide", 3, -2, 200, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_SWAMP_DRAGON_ARMOUR, "swamp dragon armour", 5, -2, 200, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_DRAGON_HIDE, "dragon hide", 3, -3, 350, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_DRAGON_ARMOUR, "dragon armour", 6, -3, 350, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_ICE_DRAGON_HIDE, "ice dragon hide", 3, -3, 350, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_ICE_DRAGON_ARMOUR, "ice dragon armour", 6, -3, 350, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_STORM_DRAGON_HIDE, "storm dragon hide", 4, -5, 600, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_STORM_DRAGON_ARMOUR, "storm dragon armour", 8, -5, 600, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_GOLD_DRAGON_HIDE, "gold dragon hide", 5, -8, 1100, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + { ARM_GOLD_DRAGON_ARMOUR, "gold dragaon armour", 10, -8, 1100, + false, EQ_BODY_ARMOUR, SIZE_LITTLE, SIZE_GIANT }, + + { ARM_CLOAK, "cloak", 1, 0, 40, + true, EQ_CLOAK, SIZE_LITTLE, SIZE_BIG }, + { ARM_GLOVES, "gloves", 1, 0, 20, + true, EQ_GLOVES, SIZE_SMALL, SIZE_MEDIUM }, + + { ARM_HELMET, "helmet", 1, 0, 80, + false, EQ_HELMET, SIZE_SMALL, SIZE_MEDIUM }, + { ARM_CAP, "cap", 0, 0, 40, + true, EQ_HELMET, SIZE_LITTLE, SIZE_LARGE }, + + // Note that barding size is compared against torso so it currently + // needs to fit medium, but that doesn't matter as much as race + // and shapeshift status. + { ARM_BOOTS, "boots", 1, 0, 30, + true, EQ_BOOTS, SIZE_SMALL, SIZE_MEDIUM }, + { ARM_CENTAUR_BARDING, "centaur barding", 4, -2, 100, + true, EQ_BOOTS, SIZE_MEDIUM, SIZE_MEDIUM }, + { ARM_NAGA_BARDING, "naga barding", 4, -2, 100, + true, EQ_BOOTS, SIZE_MEDIUM, SIZE_MEDIUM }, + + // Note: shields use ac-value as sh-value, EV pen is used for heavy_shield + { ARM_BUCKLER, "buckler", 3, 0, 90, + true, EQ_SHIELD, SIZE_LITTLE, SIZE_MEDIUM }, + { ARM_SHIELD, "shield", 5, -1, 150, + false, EQ_SHIELD, SIZE_SMALL, SIZE_BIG }, + { ARM_LARGE_SHIELD, "large shield", 7, -2, 230, + false, EQ_SHIELD, SIZE_MEDIUM, SIZE_GIANT }, +}; + +struct weapon_def +{ + int id; + const char *name; + int dam; + int hit; + int speed; + int mass; + int str_weight; + + skill_type skill; + hands_reqd_type hands; + size_type fit_size; // actual size is one size smaller + missile_type ammo; // MI_NONE for non-launchers + bool throwable; + + int dam_type; +}; + +static int Weapon_index[NUM_WEAPONS]; +static weapon_def Weapon_prop[NUM_WEAPONS] = +{ + // Maces & Flails + { WPN_WHIP, "whip", 4, 2, 13, 30, 2, + SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLASHING }, + { WPN_CLUB, "club", 5, 3, 13, 50, 7, + SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, true, + DAMV_CRUSHING }, + { WPN_HAMMER, "hammer", 7, 3, 13, 90, 7, + SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_MACE, "mace", 8, 3, 14, 120, 8, + SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_FLAIL, "flail", 9, 2, 15, 130, 8, + SK_MACES_FLAILS, HANDS_ONE, SIZE_SMALL, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_ANCUS, "ancus", 9, 2, 14, 120, 8, + SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_MORNINGSTAR, "morningstar", 10, -2, 15, 140, 8, + SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_PIERCING | DAM_BLUDGEON }, + { WPN_DEMON_WHIP, "demon whip", 10, 2, 13, 30, 2, + SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLASHING }, + { WPN_SPIKED_FLAIL, "spiked flail", 12, -3, 16, 190, 8, + SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_PIERCING | DAM_BLUDGEON }, + { WPN_EVENINGSTAR, "eveningstar", 12, -2, 15, 180, 8, + SK_MACES_FLAILS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_PIERCING | DAM_BLUDGEON }, + { WPN_DIRE_FLAIL, "dire flail", 13, -6, 14, 240, 9, + SK_MACES_FLAILS, HANDS_DOUBLE, SIZE_MEDIUM, MI_NONE, false, + DAMV_PIERCING | DAM_BLUDGEON }, + { WPN_GREAT_MACE, "great mace", 18, -5, 19, 270, 9, + SK_MACES_FLAILS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_GIANT_CLUB, "giant club", 19, -8, 20, 330, 10, + SK_MACES_FLAILS, HANDS_TWO, SIZE_BIG, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_GIANT_SPIKED_CLUB, "giant spiked club", 20, -9, 21, 350, 10, + SK_MACES_FLAILS, HANDS_TWO, SIZE_BIG, MI_NONE, false, + DAMV_PIERCING | DAM_BLUDGEON }, + + // Short blades + { WPN_KNIFE, "knife", 3, 5, 10, 10, 1, + SK_SHORT_BLADES, HANDS_ONE, SIZE_LITTLE, MI_NONE, false, + DAMV_STABBING | DAM_SLICE }, + { WPN_DAGGER, "dagger", 4, 6, 10, 20, 1, + SK_SHORT_BLADES, HANDS_ONE, SIZE_LITTLE, MI_NONE, true, + DAMV_STABBING | DAM_SLICE }, + { WPN_QUICK_BLADE, "quick blade", 5, 6, 8, 50, 0, + SK_SHORT_BLADES, HANDS_ONE, SIZE_LITTLE, MI_NONE, false, + DAMV_STABBING | DAM_SLICE }, + { WPN_SHORT_SWORD, "short sword", 6, 4, 11, 80, 2, + SK_SHORT_BLADES, HANDS_ONE, SIZE_SMALL, MI_NONE, false, + DAMV_SLICING | DAM_PIERCE }, + { WPN_SABRE, "sabre", 7, 4, 11, 90, 2, + SK_SHORT_BLADES, HANDS_ONE, SIZE_SMALL, MI_NONE, false, + DAMV_SLICING | DAM_PIERCE }, + + // Long swords + { WPN_FALCHION, "falchion", 8, 2, 13, 170, 4, + SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, // or perhaps DAMV_CHOPPING is more apt? + { WPN_LONG_SWORD, "long sword", 10, -2, 14, 160, 3, + SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, + { WPN_SCIMITAR, "scimitar", 11, -2, 14, 170, 3, + SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, + { WPN_KATANA, "katana", 13, -1, 13, 160, 3, + SK_LONG_SWORDS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, + { WPN_DEMON_BLADE, "demon blade", 13, -3, 15, 200, 4, + SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, + { WPN_BLESSED_BLADE, "blessed blade", 14, -3, 14, 200, 4, + SK_LONG_SWORDS, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, + { WPN_DOUBLE_SWORD, "double sword", 15, -5, 16, 220, 5, + SK_LONG_SWORDS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false, + DAMV_SLICING }, + { WPN_GREAT_SWORD, "great sword", 16, -5, 17, 250, 6, + SK_LONG_SWORDS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_SLICING }, + { WPN_TRIPLE_SWORD, "triple sword", 17, -5, 17, 260, 6, + SK_LONG_SWORDS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_SLICING }, + + // Axes + { WPN_HAND_AXE, "hand axe", 7, 3, 13, 80, 6, + SK_AXES, HANDS_ONE, SIZE_SMALL, MI_NONE, true, + DAMV_CHOPPING }, + { WPN_WAR_AXE, "war axe", 11, -3, 16, 180, 7, + SK_AXES, HANDS_ONE, SIZE_MEDIUM, MI_NONE, false, + DAMV_CHOPPING }, + { WPN_BROAD_AXE, "broad axe", 14, -6, 17, 230, 8, + SK_AXES, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false, + DAMV_CHOPPING }, + { WPN_BATTLEAXE, "battleaxe", 16, -7, 18, 250, 8, + SK_AXES, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_CHOPPING }, + { WPN_EXECUTIONERS_AXE, "executioner\'s axe", 18, -8, 18, 280, 9, + SK_AXES, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_CHOPPING }, + + // Polearms + { WPN_SPEAR, "spear", 6, 3, 12, 50, 3, + SK_POLEARMS, HANDS_HALF, SIZE_SMALL, MI_NONE, true, + DAMV_PIERCING }, + { WPN_TRIDENT, "trident", 9, 2, 14, 160, 4, + SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false, + DAMV_PIERCING }, + { WPN_DEMON_TRIDENT, "demon trident", 13, 2, 14, 160, 4, + SK_POLEARMS, HANDS_HALF, SIZE_MEDIUM, MI_NONE, false, + DAMV_PIERCING }, + { WPN_HALBERD, "halberd", 13, -3, 16, 200, 5, + SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_CHOPPING | DAM_PIERCE }, + { WPN_SCYTHE, "scythe", 14, -4, 20, 220, 7, + SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_SLICING }, + { WPN_GLAIVE, "glaive", 15, -3, 18, 200, 6, + SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_CHOPPING }, + { WPN_LOCHABER_AXE, "lochaber axe", 18, -6, 20, 200, 8, + SK_POLEARMS, HANDS_TWO, SIZE_LARGE, MI_NONE, false, + DAMV_CHOPPING }, + + { WPN_QUARTERSTAFF, "quarterstaff", 9, 2, 12, 180, 7, + SK_STAVES, HANDS_DOUBLE, SIZE_LARGE, MI_NONE, false, + DAMV_CRUSHING }, + { WPN_LAJATANG, "lajatang", 14, -3, 14, 200, 3, + SK_STAVES, HANDS_DOUBLE, SIZE_LARGE, MI_NONE, false, + DAMV_SLICING }, + + // Range weapons + // Notes: + // - HANDS_HALF means a reloading time penalty if using shield + // - damage field is used for bonus strength damage (string tension) + // - slings get a bonus from dex, not str (as tension is meaningless) + // - str weight is used for speed and applying dex to skill + { WPN_BLOWGUN, "blowgun", 0, 2, 10, 20, 0, + SK_DARTS, HANDS_HALF, SIZE_LITTLE, MI_NEEDLE, false, + DAMV_NON_MELEE }, + { WPN_SLING, "sling", 0, 2, 11, 20, 1, + SK_SLINGS, HANDS_HALF, SIZE_LITTLE, MI_STONE, false, + DAMV_NON_MELEE }, + { WPN_HAND_CROSSBOW, "hand crossbow", 3, 4, 15, 70, 5, + SK_CROSSBOWS, HANDS_HALF, SIZE_SMALL, MI_DART, false, + DAMV_NON_MELEE }, + { WPN_CROSSBOW, "crossbow", 5, 4, 15, 150, 8, + SK_CROSSBOWS, HANDS_TWO, SIZE_MEDIUM, MI_BOLT, false, + DAMV_NON_MELEE }, + { WPN_BOW, "bow", 4, 2, 11, 90, 2, + SK_BOWS, HANDS_TWO, SIZE_MEDIUM, MI_ARROW, false, + DAMV_NON_MELEE }, + { WPN_LONGBOW, "longbow", 5, 0, 12, 120, 3, + SK_BOWS, HANDS_TWO, SIZE_LARGE, MI_ARROW, false, + DAMV_NON_MELEE }, +}; + +struct missile_def +{ + int id; + const char *name; + int dam; + int mass; + bool throwable; +}; + +static int Missile_index[NUM_MISSILES]; +static missile_def Missile_prop[NUM_MISSILES] = +{ + { MI_NEEDLE, "needle", 0, 1, false }, + { MI_STONE, "stone", 4, 2, true }, + { MI_DART, "dart", 5, 3, true }, + { MI_ARROW, "arrow", 6, 5, false }, + { MI_BOLT, "bolt", 8, 5, false }, + { MI_LARGE_ROCK, "large rock", 20, 1000, true }, +}; + +struct food_def +{ + int id; + const char *name; + int value; + int carn_mod; + int herb_mod; + int mass; + int turns; +}; + +// NOTE: Any food with special random messages or side effects +// currently only takes one turn to eat (except ghouls and chunks)... +// if this changes then those items will have to have special code +// (like ghoul chunks) to guarantee that the special thing is only +// done once. See the ghoul eating code over in food.cc. +static int Food_index[NUM_FOODS]; +static food_def Food_prop[NUM_FOODS] = +{ + { FOOD_MEAT_RATION, "meat ration", 5000, 500, -1500, 80, 4 }, + { FOOD_SAUSAGE, "sausage", 1500, 150, -400, 40, 1 }, + { FOOD_CHUNK, "chunk", 1000, 100, -500, 100, 3 }, + { FOOD_BEEF_JERKY, "beef jerky", 800, 100, -250, 20, 1 }, + + { FOOD_BREAD_RATION, "bread ration", 4400, -1500, 750, 80, 4 }, + { FOOD_SNOZZCUMBER, "snozzcumber", 1500, -500, 500, 50, 1 }, + { FOOD_ORANGE, "orange", 1000, -350, 400, 20, 1 }, + { FOOD_BANANA, "banana", 1000, -350, 400, 20, 1 }, + { FOOD_LEMON, "lemon", 1000, -350, 400, 20, 1 }, + { FOOD_PEAR, "pear", 700, -250, 300, 20, 1 }, + { FOOD_APPLE, "apple", 700, -250, 300, 20, 1 }, + { FOOD_APRICOT, "apricot", 700, -250, 300, 15, 1 }, + { FOOD_CHOKO, "choko", 600, -200, 250, 30, 1 }, + { FOOD_RAMBUTAN, "rambutan", 600, -200, 250, 10, 1 }, + { FOOD_LYCHEE, "lychee", 600, -200, 250, 10, 1 }, + { FOOD_STRAWBERRY, "strawberry", 200, -80, 100, 5, 1 }, + { FOOD_GRAPE, "grape", 100, -40, 50, 2, 1 }, + { FOOD_SULTANA, "sultana", 70, -30, 30, 1, 1 }, + + { FOOD_ROYAL_JELLY, "royal jelly", 4000, 0, 0, 55, 1 }, + { FOOD_HONEYCOMB, "honeycomb", 2000, 0, 0, 40, 1 }, + { FOOD_PIZZA, "pizza", 1500, 0, 0, 40, 1 }, + { FOOD_CHEESE, "cheese", 1200, 0, 0, 40, 1 }, +}; + +// Must call this functions early on so that the above tables can +// be accessed correctly. +void init_properties(void) +{ + int i; + + for (i = 0; i < NUM_ARMOURS; i++) + Armour_index[ Armour_prop[i].id ] = i; + + for (i = 0; i < NUM_WEAPONS; i++) + Weapon_index[ Weapon_prop[i].id ] = i; + + for (i = 0; i < NUM_MISSILES; i++) + Missile_index[ Missile_prop[i].id ] = i; + + for (i = 0; i < NUM_FOODS; i++) + Food_index[ Food_prop[i].id ] = i; +} + + +// Some convenient functions to hide the bit operations and create +// an interface layer between the code and the data in case this +// gets changed again. -- bwr + +// +// Item cursed status functions: +// +bool item_cursed( const item_def &item ) +{ + return (item.flags & ISFLAG_CURSED); +} + +bool item_known_cursed( const item_def &item ) +{ + return ((item.flags & ISFLAG_KNOW_CURSE) && (item.flags & ISFLAG_CURSED)); +} + +bool item_known_uncursed( const item_def &item ) +{ + return ((item.flags & ISFLAG_KNOW_CURSE) && !(item.flags & ISFLAG_CURSED)); +} + +void do_curse_item( item_def &item ) +{ + item.flags |= ISFLAG_CURSED; +} + +void do_uncurse_item( item_def &item ) +{ + item.flags &= (~ISFLAG_CURSED); +} + +// +// Item identification status: +// +bool item_ident( const item_def &item, unsigned long flags ) +{ + return ((item.flags & flags) == flags); +} + +void set_ident_flags( item_def &item, unsigned long flags ) +{ + item.flags |= flags; +} + +void unset_ident_flags( item_def &item, unsigned long flags ) +{ + item.flags &= (~flags); +} + +// +// Equipment race and description: +// +unsigned long get_equip_race( const item_def &item ) +{ + return (item.flags & ISFLAG_RACIAL_MASK); +} + +unsigned long get_equip_desc( const item_def &item ) +{ + return (item.flags & ISFLAG_COSMETIC_MASK); +} + +void set_equip_race( item_def &item, unsigned long flags ) +{ + ASSERT( (flags & ~ISFLAG_RACIAL_MASK) == 0 ); + + // first check for base-sub pairs that can't ever have racial types + switch (item.base_type) + { + case OBJ_WEAPONS: + if (item.sub_type == WPN_GIANT_CLUB + || item.sub_type == WPN_GIANT_SPIKED_CLUB + || item.sub_type == WPN_KATANA + || item.sub_type == WPN_LAJATANG + || item.sub_type == WPN_SLING + || item.sub_type == WPN_KNIFE + || item.sub_type == WPN_QUARTERSTAFF + || item.sub_type == WPN_DEMON_BLADE + || item.sub_type == WPN_DEMON_WHIP + || item.sub_type == WPN_DEMON_TRIDENT) + { + return; + } + break; + + case OBJ_ARMOUR: + // not hides, dragon armour, crystal plate, or barding + if (item.sub_type >= ARM_DRAGON_HIDE + && item.sub_type <= ARM_SWAMP_DRAGON_ARMOUR + && item.sub_type != ARM_CENTAUR_BARDING + && item.sub_type != ARM_NAGA_BARDING) + { + return; + } + break; + + case OBJ_MISSILES: + if (item.sub_type == MI_STONE || item.sub_type == MI_LARGE_ROCK) + return; + break; + + default: + return; + } + + // check that item is appropriate for racial type + switch (flags) + { + case ISFLAG_ELVEN: + if (item.base_type == OBJ_ARMOUR + && (item.sub_type == ARM_SPLINT_MAIL + || item.sub_type == ARM_BANDED_MAIL + || item.sub_type == ARM_PLATE_MAIL)) + { + return; + } + break; + + case ISFLAG_DWARVEN: + if (item.base_type == OBJ_ARMOUR + && (item.sub_type == ARM_ROBE + || item.sub_type == ARM_LEATHER_ARMOUR + || item.sub_type == ARM_STUDDED_LEATHER_ARMOUR)) + { + return; + } + break; + + case ISFLAG_ORCISH: + default: + break; + } + + item.flags &= ~ISFLAG_RACIAL_MASK; // delete previous + item.flags |= flags; +} + +void set_equip_desc( item_def &item, unsigned long flags ) +{ + ASSERT( (flags & ~ISFLAG_COSMETIC_MASK) == 0 ); + + item.flags &= ~ISFLAG_COSMETIC_MASK; // delete previous + item.flags |= flags; +} + +// +// These functions handle the description and subtypes for helmets/caps +// +short get_helmet_type( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR + && get_armour_slot( item ) == EQ_HELMET ); + + return (item.plus2 & THELM_TYPE_MASK); +} + +short get_helmet_desc( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR + && get_armour_slot( item ) == EQ_HELMET ); + + return (item.plus2 & THELM_DESC_MASK); +} + +void set_helmet_type( item_def &item, short type ) +{ + ASSERT( (type & ~THELM_TYPE_MASK) == 0 ); + ASSERT( item.base_type == OBJ_ARMOUR + && get_armour_slot( item ) == EQ_HELMET ); + + // make sure we have the right sub_type (to get properties correctly) + if (type == THELM_HELMET || type == THELM_HELM) + item.sub_type = ARM_HELMET; + else + item.sub_type = ARM_CAP; + + item.plus2 &= ~THELM_TYPE_MASK; + item.plus2 |= type; +} + +void set_helmet_desc( item_def &item, short type ) +{ + ASSERT( (type & ~THELM_DESC_MASK) == 0 ); + ASSERT( item.base_type == OBJ_ARMOUR + && get_armour_slot( item ) == EQ_HELMET ); + + if (item.sub_type == ARM_CAP && type > THELM_DESC_PLUMED) + type = THELM_DESC_PLAIN; + + item.plus2 &= ~THELM_DESC_MASK; + item.plus2 |= type; +} + +void set_helmet_random_desc( item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR + && get_armour_slot( item ) == EQ_HELMET ); + + item.plus2 &= ~THELM_DESC_MASK; + + if (item.sub_type == ARM_HELMET) + item.plus2 |= (random2(8) << 8); + else + item.plus2 |= (random2(5) << 8); + +} + +bool is_helmet_type( const item_def &item, short val ) +{ + if (item.base_type != OBJ_ARMOUR || get_armour_slot( item ) != EQ_HELMET) + return (false); + + return (get_helmet_type( item ) == val); +} + +// +// Ego item functions: +// +bool set_item_ego_type( item_def &item, int item_type, int ego_type ) +{ + if (item.base_type == item_type + && !is_random_artefact( item ) + && !is_fixed_artefact( item )) + { + item.special = ego_type; + return (true); + } + + return (false); +} + +int get_weapon_brand( const item_def &item ) +{ + // Weapon ego types are "brands", so we do the randart lookup here. + + // Staves "brands" handled specially + if (item.base_type != OBJ_WEAPONS) + return (SPWPN_NORMAL); + + if (is_fixed_artefact( item )) + { + switch (item.special) + { + case SPWPN_SWORD_OF_CEREBOV: + return (SPWPN_FLAMING); + + case SPWPN_STAFF_OF_OLGREB: + return (SPWPN_VENOM); + + case SPWPN_VAMPIRES_TOOTH: + return (SPWPN_VAMPIRICISM); + + default: + return (SPWPN_NORMAL); + } + } + else if (is_random_artefact( item )) + { + return (randart_wpn_property( item, RAP_BRAND )); + } + + return (item.special); +} + +int get_ammo_brand( const item_def &item ) +{ + // no artefact arrows yet -- bwr + if (item.base_type != OBJ_MISSILES || is_random_artefact( item )) + return (SPMSL_NORMAL); + + return (item.special); +} + +int get_armour_ego_type( const item_def &item ) +{ + // artefact armours have no ego type, must look up powers separately + if (item.base_type != OBJ_ARMOUR + || (is_random_artefact( item ) && !is_unrandom_artefact( item ))) + { + return (SPARM_NORMAL); + } + + return (item.special); +} + +// +// Armour information and checking functions +// +bool hide2armour( item_def &item ) +{ + if (item.base_type != OBJ_ARMOUR) + return (false); + + switch (item.sub_type) + { + default: + return (false); + + case ARM_DRAGON_HIDE: + item.sub_type = ARM_DRAGON_ARMOUR; + break; + + case ARM_TROLL_HIDE: + item.sub_type = ARM_TROLL_LEATHER_ARMOUR; + break; + + case ARM_ICE_DRAGON_HIDE: + item.sub_type = ARM_ICE_DRAGON_ARMOUR; + break; + + case ARM_MOTTLED_DRAGON_HIDE: + item.sub_type = ARM_MOTTLED_DRAGON_ARMOUR; + break; + + case ARM_STORM_DRAGON_HIDE: + item.sub_type = ARM_STORM_DRAGON_ARMOUR; + break; + + case ARM_GOLD_DRAGON_HIDE: + item.sub_type = ARM_GOLD_DRAGON_ARMOUR; + break; + + case ARM_SWAMP_DRAGON_HIDE: + item.sub_type = ARM_SWAMP_DRAGON_ARMOUR; + break; + + case ARM_STEAM_DRAGON_HIDE: + item.sub_type = ARM_STEAM_DRAGON_ARMOUR; + break; + } + + return (true); +} // end hide2armour() + +// Return the enchantment limit of a piece of armour +int armour_max_enchant( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + const int eq_slot = get_armour_slot( item ); + + int max_plus = MAX_SEC_ENCHANT; + if (eq_slot == EQ_BODY_ARMOUR || eq_slot == EQ_SHIELD) + max_plus = MAX_ARM_ENCHANT; + + return (max_plus); +} + +// doesn't include animal skin (only skins we can make and enchant) +bool armour_is_hide( const item_def &item, bool inc_made ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + switch (item.sub_type) + { + case ARM_TROLL_LEATHER_ARMOUR: + case ARM_DRAGON_ARMOUR: + case ARM_ICE_DRAGON_ARMOUR: + case ARM_STEAM_DRAGON_ARMOUR: + case ARM_MOTTLED_DRAGON_ARMOUR: + case ARM_STORM_DRAGON_ARMOUR: + case ARM_GOLD_DRAGON_ARMOUR: + case ARM_SWAMP_DRAGON_ARMOUR: + return (inc_made); + + case ARM_TROLL_HIDE: + case ARM_DRAGON_HIDE: + case ARM_ICE_DRAGON_HIDE: + case ARM_STEAM_DRAGON_HIDE: + case ARM_MOTTLED_DRAGON_HIDE: + case ARM_STORM_DRAGON_HIDE: + case ARM_GOLD_DRAGON_HIDE: + case ARM_SWAMP_DRAGON_HIDE: + return (true); + + default: + break; + } + + return (false); +} + +// used to distinguish shiny and embroidered +bool armour_not_shiny( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + switch (item.sub_type) + { + case ARM_ROBE: + case ARM_CLOAK: + case ARM_GLOVES: + case ARM_BOOTS: + case ARM_NAGA_BARDING: + case ARM_CENTAUR_BARDING: + case ARM_CAP: + case ARM_LEATHER_ARMOUR: + case ARM_STUDDED_LEATHER_ARMOUR: + case ARM_ANIMAL_SKIN: + case ARM_TROLL_HIDE: + case ARM_TROLL_LEATHER_ARMOUR: + return (true); + + default: + break; + } + + return (false); +} + +int armour_str_required( const item_def &arm ) +{ + ASSERT (arm.base_type == OBJ_ARMOUR ); + + int ret = 0; + + const equipment_type slot = get_armour_slot( arm ); + const int mass = item_mass( arm ); + + switch (slot) + { + case EQ_BODY_ARMOUR: + ret = mass / 35; + break; + + case EQ_SHIELD: + ret = mass / 15; + break; + + default: + break; + } + + return ((ret < STR_REQ_THRESHOLD) ? 0 : ret); +} + +equipment_type get_armour_slot( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + return (Armour_prop[ Armour_index[item.sub_type] ].slot); +} + +bool jewellery_is_amulet( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_JEWELLERY ); + + return (item.sub_type >= AMU_RAGE); +} + +bool check_jewellery_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_JEWELLERY ); + + // Currently assuming amulets are always wearable (only needs + // to be held over head or heart... giants can strap it on with + // a bit of binder twine). However, rings need to actually fit + // around the ring finger to work, and so the big cannot use them. + return (size <= SIZE_LARGE || jewellery_is_amulet( item )); +} + +// Returns the basic light status of an armour, ignoring things like the +// elven bonus... you probably want is_light_armour() most times. +bool base_armour_is_light( const item_def &item ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + return (Armour_prop[ Armour_index[item.sub_type] ].light); +} + +// returns number of sizes off +int fit_armour_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + const size_type min = Armour_prop[ Armour_index[item.sub_type] ].fit_min; + const size_type max = Armour_prop[ Armour_index[item.sub_type] ].fit_max; + + if (size < min) + return (min - size); // -'ve means levels too small + else if (size > max) + return (max - size); // +'ve means levels too large + + return (0); +} + +// returns true if armour fits size (shape needs additional verification) +bool check_armour_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + return (fit_armour_size( item, size ) == 0); +} + +// Note that this function is used to check validity of equipment +// coming out of transformations... so it shouldn't contain any +// wield/unwield only checks like two-handed weapons and shield. +bool check_armour_shape( const item_def &item, bool quiet ) +{ + ASSERT( item.base_type == OBJ_ARMOUR ); + + const int slot = get_armour_slot( item ); + + if (!player_is_shapechanged()) + { + switch (slot) + { + case EQ_BOOTS: + switch (you.species) + { + case SP_NAGA: + if (item.sub_type != ARM_NAGA_BARDING) + { + if (!quiet) + mpr( "You can't wear that!" ); + + return (false); + } + break; + + case SP_CENTAUR: + if (item.sub_type != ARM_CENTAUR_BARDING) + { + if (!quiet) + mpr( "You can't wear that!" ); + + return (false); + } + break; + + case SP_KENKU: + if (!quiet) + { + if (item.sub_type == ARM_BOOTS) + mpr( "Boots don't fit your feet!" ); + else + mpr( "You can't wear barding!" ); + } + return (false); + + case SP_MERFOLK: + if (player_in_water() && item.sub_type == ARM_BOOTS) + { + if (!quiet) + mpr( "You don't currently have feet!" ); + + return (false); + } + // intentional fall-through + default: + if (item.sub_type == ARM_NAGA_BARDING + || item.sub_type == ARM_CENTAUR_BARDING) + { + if (!quiet) + mpr( "You can't wear barding!" ); + + return (false); + } + + if (you.mutation[MUT_HOOVES] >= 2) + { + if (!quiet) + mpr( "You can't wear boots with hooves!" ); + + return (false); + } + break; + } + break; + + case EQ_HELMET: + if (item.sub_type == ARM_CAP) + break; + + if (you.species == SP_KENKU) + { + if (!quiet) + mpr( "That helmet does not fit your head!" ); + + return (false); + } + + if (you.species == SP_MINOTAUR || you.mutation[MUT_HORNS]) + { + if (!quiet) + mpr( "You can't wear that with your horns!" ); + + return (false); + } + break; + + case EQ_GLOVES: + if (you.mutation[MUT_CLAWS] >= 3) + { + if (!quiet) + mpr( "You can't wear gloves with your huge claws!" ); + + return (false); + } + break; + + case EQ_BODY_ARMOUR: + // Cannot swim in heavy armour + if (player_is_swimming() && !is_light_armour( item )) + { + if (!quiet) + mpr("You can't swim in that!"); + + return (false); + } + + // Draconians are human-sized, but have wings that cause problems + // with most body armours (only very flexible fit allowed). + if (player_genus( GENPC_DRACONIAN ) + && !check_armour_size( item, SIZE_BIG )) + { + if (!quiet) + mpr( "That armour doesn't fit your wings." ); + + return (false); + } + break; + + default: + break; + } + } + else + { + // Note: some transformation include all of the above as well + if (item.sub_type == ARM_NAGA_BARDING + || item.sub_type == ARM_CENTAUR_BARDING) + { + if (!quiet) + mpr( "You can't wear barding in your current form!" ); + + return (false); + } + } + + // Note: This need to be checked after all the special cases + // above, and in addition to shapechanged or not. This is + // a simple check against the armour types that are forced off. + + // FIXME FIXME FIXME + /* + if (!transform_can_equip_type( slot )) + { + if (!quiet) + mpr( "You can't wear that in your current form!" ); + + return (false); + } + */ + + return (true); +} + +// +// Weapon information and checking functions: +// + +// Checks how rare a weapon is. Many of these have special routines for +// placement, especially those with a rarity of zero. Chance is out of 10. +int weapon_rarity( int w_type ) +{ + switch (w_type) + { + case WPN_CLUB: + case WPN_DAGGER: + return (10); + + case WPN_HAND_AXE: + case WPN_MACE: + case WPN_QUARTERSTAFF: + return (9); + + case WPN_BOW: + case WPN_FLAIL: + case WPN_HAMMER: + case WPN_SABRE: + case WPN_SHORT_SWORD: + case WPN_SLING: + case WPN_SPEAR: + return (8); + + case WPN_FALCHION: + case WPN_LONG_SWORD: + case WPN_MORNINGSTAR: + case WPN_WAR_AXE: + return (7); + + case WPN_BATTLEAXE: + case WPN_CROSSBOW: + case WPN_GREAT_SWORD: + case WPN_SCIMITAR: + case WPN_TRIDENT: + return (6); + + case WPN_GLAIVE: + case WPN_HALBERD: + case WPN_BLOWGUN: + return (5); + + case WPN_BROAD_AXE: + case WPN_HAND_CROSSBOW: + case WPN_SPIKED_FLAIL: + case WPN_WHIP: + return (4); + + case WPN_GREAT_MACE: + return (3); + + case WPN_ANCUS: + case WPN_DIRE_FLAIL: + case WPN_SCYTHE: + case WPN_LONGBOW: + return (2); + + case WPN_GIANT_CLUB: + case WPN_GIANT_SPIKED_CLUB: + case WPN_LOCHABER_AXE: + return (1); + + case WPN_DOUBLE_SWORD: + case WPN_EVENINGSTAR: + case WPN_EXECUTIONERS_AXE: + case WPN_KATANA: + case WPN_LAJATANG: + case WPN_KNIFE: + case WPN_QUICK_BLADE: + case WPN_TRIPLE_SWORD: + case WPN_DEMON_TRIDENT: + case WPN_DEMON_WHIP: + case WPN_DEMON_BLADE: + case WPN_BLESSED_BLADE: + // zero value weapons must be placed specially -- see make_item() {dlb} + return (0); + + default: + break; + } + + return (0); +} // end rare_weapon() + +int get_vorpal_type( const item_def &item ) +{ + int ret = DVORP_NONE; + + if (item.base_type == OBJ_WEAPONS) + ret = (Weapon_prop[ Weapon_index[item.sub_type] ].dam_type & DAMV_MASK); + + return (ret); +} // end vorpal_type() + +int get_damage_type( const item_def &item ) +{ + int ret = DAM_BASH; + + if (item.base_type == OBJ_WEAPONS) + ret = (Weapon_prop[ Weapon_index[item.sub_type] ].dam_type & DAM_MASK); + + return (ret); +} // end damage_type() + +bool does_damage_type( const item_def &item, int dam_type ) +{ + return (get_damage_type( item ) & dam_type); +} // end does_damage_type() + + +// give hands required to wield weapon for a torso of "size" +hands_reqd_type hands_reqd( const item_def &item, size_type size ) +{ + int ret = HANDS_ONE; + int fit; + bool doub = false; + + switch (item.base_type) + { + case OBJ_STAVES: + case OBJ_WEAPONS: + // Merging staff with magical staves for consistancy... doing + // as a special case because we want to be very flexible with + // these useful objects (we want spriggans and ogre magi to + // be able to use them). + if (item.base_type == OBJ_STAVES || item.sub_type == WPN_QUARTERSTAFF) + { + if (size < SIZE_SMALL) + ret = HANDS_TWO; + else if (size > SIZE_LARGE) + ret = HANDS_ONE; + else + ret = HANDS_HALF; + break; + } + + ret = Weapon_prop[ Weapon_index[item.sub_type] ].hands; + + // size is the level where we can use one hand for one end + if (ret == HANDS_DOUBLE) + { + doub = true; + ret = HANDS_HALF; + } + + // adjust handedness for size only for non-whip melee weapons + if (!is_range_weapon( item ) + && item.sub_type != WPN_WHIP + && item.sub_type != WPN_DEMON_WHIP) + { + fit = cmp_weapon_size( item, size ); + + // Adjust handedness for non-medium races: + // (XX values don't matter, see fit_weapon_wieldable_size) + // + // Spriggan Kobold Human Ogre Big Giant + // Little 0 0 0 XX XX XX + // Small +1 0 0 -2 XX XX + // Medium XX +1 0 -1 -2 XX + // Large XX XX 0 0 -1 -2 + // Big XX XX XX 0 0 -1 + // Giant XX XX XX XX 0 0 + + // Note the stretching of double weapons for larger characters + // by one level since they tend to be larger weapons. + if (size < SIZE_MEDIUM && fit > 0) + ret += fit; + else if (size > SIZE_MEDIUM && fit < 0) + ret += (fit + doub); + } + break; + + case OBJ_CORPSES: // unwieldy + ret = HANDS_TWO; + break; + + case OBJ_ARMOUR: // barding and body armours are unwieldy + if (item.sub_type == ARM_NAGA_BARDING + || item.sub_type == ARM_CENTAUR_BARDING + || get_armour_slot( item ) == EQ_BODY_ARMOUR) + { + ret = HANDS_TWO; + } + break; + + default: + break; + } + + if (ret > HANDS_TWO) + ret = HANDS_TWO; + else if (ret < HANDS_ONE) + ret = HANDS_ONE; + + return (static_cast< hands_reqd_type >( ret )); +} + +bool is_double_ended( const item_def &item ) +{ + if (item.base_type == OBJ_STAVES) + return (true); + else if (item.base_type != OBJ_WEAPONS) + return (false); + + return (Weapon_prop[ Weapon_index[item.sub_type] ].hands == HANDS_DOUBLE); +} + +int double_wpn_awkward_speed( const item_def &item ) +{ + ASSERT( is_double_ended( item ) ); + + const int base = property( item, PWPN_SPEED ); + + return ((base * 30 + 10) / 20 + 2); +} + + +bool is_demonic( const item_def &item ) +{ + if (item.base_type == OBJ_WEAPONS) + { + switch (item.sub_type) + { + case WPN_DEMON_BLADE: + case WPN_DEMON_WHIP: + case WPN_DEMON_TRIDENT: + return (true); + + default: + break; + } + } + + return (false); +} // end is_demonic() + +int weapon_str_weight( const item_def &wpn ) +{ + ASSERT (wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES); + + if (wpn.base_type == OBJ_STAVES) + return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].str_weight); + + return (Weapon_prop[ Weapon_index[wpn.sub_type] ].str_weight); +} + +int weapon_dex_weight( const item_def &wpn ) +{ + return (10 - weapon_str_weight( wpn )); +} + +int weapon_impact_mass( const item_def &wpn ) +{ + ASSERT (wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES); + + return ((weapon_str_weight( wpn ) * item_mass( wpn ) + 5) / 10); +} + +int weapon_str_required( const item_def &wpn, bool hand_half ) +{ + ASSERT (wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES); + + const int req = weapon_impact_mass( wpn ) / ((hand_half) ? 11 : 10); + + return ((req < STR_REQ_THRESHOLD) ? 0 : req); +} + +// returns melee skill of item +skill_type weapon_skill( const item_def &item ) +{ + if (item.base_type == OBJ_WEAPONS && !is_range_weapon( item )) + return (Weapon_prop[ Weapon_index[item.sub_type] ].skill); + else if (item.base_type == OBJ_STAVES) + return (SK_STAVES); + + // this is used to mark that only fighting applies. + return (SK_FIGHTING); +} + +// front function for the above when we don't have a physical item to check +skill_type weapon_skill( int wclass, int wtype ) +{ + item_def wpn; + + wpn.base_type = wclass; + wpn.sub_type = wtype; + + return (weapon_skill( wpn )); +} // end weapon_skill() + +// returns range skill of the item +skill_type range_skill( const item_def &item ) +{ + if (item.base_type == OBJ_WEAPONS && is_range_weapon( item )) + return (Weapon_prop[ Weapon_index[item.sub_type] ].skill); + else if (item.base_type == OBJ_MISSILES && item.sub_type == MI_DART) + return (SK_DARTS); + + return (SK_RANGED_COMBAT); +} + +// front function for the above when we don't have a physical item to check +skill_type range_skill( int wclass, int wtype ) +{ + item_def wpn; + + wpn.base_type = wclass; + wpn.sub_type = wtype; + + return (range_skill( wpn )); +} // end weapon_skill() + + +// Calculate the bonus to melee EV for using "wpn", with "skill" and "dex" +// to protect a body of size "body". +int weapon_ev_bonus( const item_def &wpn, int skill, size_type body, int dex, + bool hide_hidden ) +{ + ASSERT( wpn.base_type == OBJ_WEAPONS || wpn.base_type == OBJ_STAVES ); + + int ret = 0; + + // Note: ret currently measured in halves (see skill factor) + if (wpn.sub_type == WPN_WHIP || wpn.sub_type == WPN_DEMON_WHIP) + ret = 3 + (dex / 5); + else if (weapon_skill( wpn ) == SK_POLEARMS) + ret = 2 + (dex / 5); + + // weapons of reaching are naturally a bit longer/flexier + if (!hide_hidden || item_ident( wpn, ISFLAG_KNOW_TYPE )) + { + if (get_weapon_brand( wpn ) == SPWPN_REACHING) + ret += 1; + } + + // only consider additional modifications if we have a positive base: + if (ret > 0) + { + // Size factors: + // - large characters can't cover their flanks as well + // - note that not all weapons are available to small characters + if (body > SIZE_LARGE) + ret -= (4 * (body - SIZE_LARGE) - 2); + else if (body < SIZE_MEDIUM) + ret += 1; + + // apply skill (and dividing by 2) + ret = (ret * (skill + 10)) / 20; + + // make sure things can't get too insane + if (ret > 8) + ret = 8 + (ret - 8) / 2; + } + + // Note: this is always a bonus + return ((ret > 0) ? ret : 0); +} + +static size_type weapon_size( const item_def &item ) +{ + ASSERT (item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES); + + if (item.base_type == OBJ_STAVES) + return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].fit_size); + + return (Weapon_prop[ Weapon_index[item.sub_type] ].fit_size); +} + +// returns number of sizes off +int cmp_weapon_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); + + return (weapon_size( item ) - size); +} + +// Returns number of sizes away from being a usable weapon +int fit_weapon_wieldable_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); + + const int fit = cmp_weapon_size( item, size ); + + return ((fit < -2) ? fit + 2 : (fit > 1) ? fit - 1 : 0); +} + +// Returns number of sizes away from being throwable... the window +// is currently [size - 5, size - 1]. +int fit_item_throwable_size( const item_def &item, size_type size ) +{ + int ret = item_size( item ) - size; + + return ((ret >= 0) ? ret + 1 : (ret > -6) ? 0 : ret + 5); +} + +// Returns true if weapon is usable as a tool +// Note that we assume that tool usable >= wieldable +bool check_weapon_tool_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); + + // Staves are currently usable for everyone just to be nice. + if (item.base_type == OBJ_STAVES || item.sub_type == WPN_QUARTERSTAFF) + return (true); + + const int fit = cmp_weapon_size( item, size ); + + return (fit >= -3 && fit <= 1); +} + +// Returns true if weapon is uasable as a weapon +bool check_weapon_wieldable_size( const item_def &item, size_type size ) +{ + ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); + + return (fit_weapon_wieldable_size( item, size ) == 0); +} + +// Note that this function is used to check validity of equipment +// coming out of transformations... so it shouldn't contain any +// wield/unwield only checks like two-handed weapons and shield. +// check_id is only used for descriptions, where we don't want to +// give away any information the player doesn't have yet. +bool check_weapon_shape( const item_def &item, bool quiet, bool check_id ) +{ + const int brand = get_weapon_brand( item ); + + if ((!check_id || item_ident( item, ISFLAG_KNOW_TYPE )) + && ((item.base_type == OBJ_WEAPONS + && item.sub_type == WPN_BLESSED_BLADE) + || brand == SPWPN_HOLY_WRATH + || brand == SPWPN_DISRUPTION) + && (you.is_undead || you.species == SP_DEMONSPAWN)) + { + if (!quiet) + mpr( "This weapon will not allow you to wield it." ); + + return (false); + } + + // Note: this should always be done last, see check_armour_shape() + // FIXME FIXME FIXME + /* + if (!transform_can_equip_type( EQ_WEAPON )) + { + if (!quiet) + mpr( "You can't wield anything in your current form!" ); + + return (false); + } + */ + + return (true); +} + +// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield) +int get_inv_wielded( void ) +{ + return (player_weapon_wielded() ? you.equip[EQ_WEAPON] : -1); +} + +// Returns the you.inv[] index of our hand tool or -1 (no item, not usable) +// Note that we don't count armour and such as "tools" here because +// this function is used to judge if the item will sticky curse to +// our hands. +int get_inv_hand_tool( void ) +{ + const int tool = you.equip[EQ_WEAPON]; + + // FIXME + /* + if (tool == -1 || !is_tool( you.inv[tool] )) + return (-1); + + if (you.inv[tool].base_type == OBJ_WEAPONS + || you.inv[tool].base_type == OBJ_STAVES) + { + // assuring that bad "shape" weapons aren't in hand + ASSERT( check_weapon_shape( you.inv[tool], false ) ); + + if (!check_weapon_tool_size( you.inv[tool], player_size() )) + return (-1); + } + */ + + return (tool); +} + +// Returns the you.inv[] index of the thing in our hand... this is provided +// as a service to specify that both of the above are irrelevant. +// Do not use this for low level functions dealing with wielding directly. +int get_inv_in_hand( void ) +{ + return (you.equip[EQ_WEAPON]); +} + +// +// Launcher and ammo functions: +// +missile_type fires_ammo_type( const item_def &item ) +{ + if (item.base_type != OBJ_WEAPONS) + return (MI_NONE); + + return (Weapon_prop[ Weapon_index[item.sub_type] ].ammo); +} + +bool is_range_weapon( const item_def &item ) +{ + return (fires_ammo_type( item ) != MI_NONE); +} + +bool is_range_weapon_type( weapon_type wtype ) +{ + item_def wpn; + + wpn.base_type = OBJ_WEAPONS; + wpn.sub_type = wtype; + + return (is_range_weapon( wpn )); +} + +const char * ammo_name( const item_def &bow ) +{ + ASSERT( is_range_weapon( bow ) ); + + const int ammo = fires_ammo_type( bow ); + + return (Missile_prop[ Missile_index[ammo] ].name); +} + +// returns true if item can be reasonably thrown without a launcher +bool is_throwable( const item_def &wpn ) +{ + if (wpn.base_type == OBJ_WEAPONS) + return (Weapon_prop[ Weapon_index[wpn.sub_type] ].throwable); + else if (wpn.base_type == OBJ_MISSILES) + return (Missile_prop[ Missile_index[wpn.sub_type] ].throwable); + + return (false); +} + +// FIXME +#if 0 +// decide if "being" is launching or throwing "ammo" +launch_retval is_launched( int being_id, const item_def &ammo, bool msg ) +{ + ASSERT( being_id != MHITNOT ); + + launch_retval ret = LRET_FUMBLED; + + const item_def * lnch = 0; + int fit = 0; + + if (being_id == MHITYOU) + { + const int wpn = get_inv_wielded(); + lnch = (wpn == -1) ? 0 : &you.inv[wpn]; + fit = fit_item_throwable_size( ammo, player_size() ); + } + else // monster case + { + const int wpn = menv[being_id].inv[MSLOT_WEAPON]; + lnch = (wpn == NON_ITEM) ? 0 : &mitm[wpn]; + fit = fit_item_throwable_size( ammo, mons_size( menv[being_id].type ) ); + } + + if (lnch + && lnch->base_type == OBJ_WEAPONS + && is_range_weapon( *lnch ) + && ammo.base_type == OBJ_MISSILES + && ammo.sub_type == fires_ammo_type( *lnch )) + { + ret = LRET_LAUNCHED; + } + else if (is_throwable( ammo )) + { + if (fit == 0) + ret = LRET_THROWN; + else + { + ret = LRET_FUMBLED; + + if (being_id == MHITYOU && msg) + { + mpr( MSGCH_WARN, "It's difficult to throw such a%s object.", + (fit > 0) ? " large" : (fit < 0) ? " small" : "n awkward" ); + } + } + } + + return (ret); +} +#endif + +// +// Staff/rod functions: +// +bool item_is_rod( const item_def &item ) +{ + return (item.base_type == OBJ_STAVES + && item.sub_type >= STAFF_SMITING && item.sub_type < STAFF_AIR); +} + +bool item_is_staff( const item_def &item ) +{ + // Isn't De Morgan's law wonderful. -- bwr + return (item.base_type == OBJ_STAVES + && (item.sub_type < STAFF_SMITING || item.sub_type >= STAFF_AIR)); +} + +// +// Ring functions: +// +// Returns number of pluses on jewellery (always none for amulets yet). +int ring_has_pluses( const item_def &item ) +{ + ASSERT (item.base_type == OBJ_JEWELLERY); + + switch (item.sub_type) + { + case RING_SLAYING: + return (2); + + case RING_PROTECTION: + case RING_EVASION: + case RING_STRENGTH: + case RING_INTELLIGENCE: + case RING_DEXTERITY: + return (1); + + default: + break; + } + + return (0); +} + +// +// Food functions: +// +bool food_is_meat( const item_def &item ) +{ + ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD ); + + return (Food_prop[ Food_index[item.sub_type] ].carn_mod > 0); +} + +bool food_is_veg( const item_def &item ) +{ + ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD ); + + return (Food_prop[ Food_index[item.sub_type] ].herb_mod > 0); +} + +// returns food value for one turn of eating +int food_value( const item_def &item ) +{ + ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD ); + + const int herb = you.mutation[MUT_HERBIVOROUS]; + + // XXX: this needs to be better merged with the mutation system + const int carn = (you.species == SP_KOBOLD || you.species == SP_GHOUL) ? 3 + : you.mutation[MUT_CARNIVOROUS]; + + const food_def &food = Food_prop[ Food_index[item.sub_type] ]; + + int ret = food.value; + + ret += (carn * food.carn_mod); + ret += (herb * food.herb_mod); + + return ((ret > 0) ? div_rand_round( ret, food.turns ) : 0); +} + +int food_turns( const item_def &item ) +{ + ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD ); + + return (Food_prop[ Food_index[item.sub_type] ].turns); +} + +bool can_cut_meat( const item_def &item ) +{ + return (does_damage_type( item, DAM_SLICE )); +} + +// returns true if item counts as a tool for tool size comaparisons and msgs +bool is_tool( const item_def &item ) +{ + // Currently using OBJ_WEAPONS instead of can_cut_meat() as almost + // any weapon might be an evocable artefact. + return (item.base_type == OBJ_WEAPONS + || item.base_type == OBJ_STAVES + || (item.base_type == OBJ_MISCELLANY + && item.sub_type != MISC_RUNE_OF_ZOT)); +} + + +// +// Generic item functions: +// +int property( const item_def &item, int prop_type ) +{ + switch (item.base_type) + { + case OBJ_ARMOUR: + if (prop_type == PARM_AC) + return (Armour_prop[ Armour_index[item.sub_type] ].ac); + else if (prop_type == PARM_EVASION) + return (Armour_prop[ Armour_index[item.sub_type] ].ev); + break; + + case OBJ_WEAPONS: + if (prop_type == PWPN_DAMAGE) + return (Weapon_prop[ Weapon_index[item.sub_type] ].dam); + else if (prop_type == PWPN_HIT) + return (Weapon_prop[ Weapon_index[item.sub_type] ].hit); + else if (prop_type == PWPN_SPEED) + return (Weapon_prop[ Weapon_index[item.sub_type] ].speed); + break; + + case OBJ_MISSILES: + if (prop_type == PWPN_DAMAGE) + return (Missile_prop[ Missile_index[item.sub_type] ].dam); + break; + + case OBJ_STAVES: + if (prop_type == PWPN_DAMAGE) + return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].dam); + else if (prop_type == PWPN_HIT) + return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].hit); + else if (prop_type == PWPN_SPEED) + return (Weapon_prop[ Weapon_index[WPN_QUARTERSTAFF] ].speed); + break; + + default: + break; + } + + return (0); +} + +int item_mass( const item_def &item ) +{ + int unit_mass = 0; + + switch (item.base_type) + { + case OBJ_WEAPONS: + unit_mass = Weapon_prop[ Weapon_index[item.sub_type] ].mass; + break; + + case OBJ_ARMOUR: + unit_mass = Armour_prop[ Armour_index[item.sub_type] ].mass; + + if (get_equip_race( item ) == ISFLAG_ELVEN) + { + const int reduc = (unit_mass >= 25) ? unit_mass / 5 : 5; + + // truncate to the nearest 5 and reduce the item mass: + unit_mass -= ((reduc / 5) * 5); + unit_mass = MAXIMUM( unit_mass, 5 ); + } + break; + + case OBJ_MISSILES: + unit_mass = Missile_prop[ Missile_index[item.sub_type] ].mass; + break; + + case OBJ_FOOD: + unit_mass = Food_prop[ Food_index[item.sub_type] ].mass; + break; + + case OBJ_WANDS: + unit_mass = 100; + break; + + case OBJ_UNKNOWN_I: + unit_mass = 200; // labeled "books" + break; + + case OBJ_SCROLLS: + unit_mass = 20; + break; + + case OBJ_JEWELLERY: + unit_mass = 10; + break; + + case OBJ_POTIONS: + unit_mass = 40; + break; + + case OBJ_UNKNOWN_II: + unit_mass = 5; // labeled "gems" + break; + + case OBJ_BOOKS: + unit_mass = 70; + break; + + case OBJ_STAVES: + unit_mass = 130; + break; + + case OBJ_ORBS: + unit_mass = 300; + break; + + case OBJ_MISCELLANY: + switch (item.sub_type) + { + case MISC_BOTTLED_EFREET: + case MISC_CRYSTAL_BALL_OF_SEEING: + case MISC_CRYSTAL_BALL_OF_ENERGY: + case MISC_CRYSTAL_BALL_OF_FIXATION: + unit_mass = 150; + break; + + default: + unit_mass = 100; + break; + } + break; + + case OBJ_CORPSES: + unit_mass = mons_weight( item.plus ); + + if (item.sub_type == CORPSE_SKELETON) + unit_mass /= 10; + break; + + default: + case OBJ_GOLD: + unit_mass = 0; + break; + } + + return ((unit_mass > 0) ? unit_mass : 0); +} + +// Note that this function, an item sizes in general aren't quite on the +// same scale as PCs and monsters. +size_type item_size( const item_def &item ) +{ + int size = SIZE_TINY; + + switch (item.base_type) + { + case OBJ_WEAPONS: + case OBJ_STAVES: + size = Weapon_prop[ Weapon_index[item.sub_type] ].fit_size - 1; + break; + + case OBJ_ARMOUR: + size = SIZE_MEDIUM; + switch (item.sub_type) + { + case ARM_GLOVES: + case ARM_HELMET: + case ARM_CAP: + case ARM_BOOTS: + case ARM_BUCKLER: + // tiny armour + break; + + case ARM_SHIELD: + size = SIZE_LITTLE; + break; + + case ARM_LARGE_SHIELD: + size = SIZE_SMALL; + break; + + default: // body armours and bardings + size = SIZE_MEDIUM; + break; + } + break; + + case OBJ_MISSILES: + if (item.sub_type == MI_LARGE_ROCK) + size = SIZE_SMALL; + break; + + case OBJ_MISCELLANY: + if (item.sub_type == MISC_PORTABLE_ALTAR_OF_NEMELEX) + { + size = SIZE_SMALL; + } + break; + + case OBJ_CORPSES: + // FIXME + // size = mons_size( item.plus, PSIZE_BODY ); + size = SIZE_SMALL; + break; + + default: // sundry tiny items + break; + } + + if (size < SIZE_TINY) + size = SIZE_TINY; + else if (size > SIZE_HUGE) + size = SIZE_HUGE; + + return (static_cast<size_type>( size )); +} + +// returns true if we might be interested in dumping the colour +bool is_colourful_item( const item_def &item ) +{ + bool ret = false; + + switch (item.base_type) + { + case OBJ_ARMOUR: + if (item.sub_type == ARM_ROBE + || item.sub_type == ARM_CLOAK + || item.sub_type == ARM_CAP + || item.sub_type == ARM_NAGA_BARDING + || item.sub_type == ARM_CENTAUR_BARDING) + { + ret = true; + } + break; + + default: + break; + } + + return (ret); +} diff --git a/crawl-ref/source/itemprop.h b/crawl-ref/source/itemprop.h new file mode 100644 index 0000000000..aa565a8ddf --- /dev/null +++ b/crawl-ref/source/itemprop.h @@ -0,0 +1,142 @@ +/* + * File: itemname.cc + * Summary: Misc functions. + * Written by: Brent Ross + * + * Change History (most recent first): + * + * <1> -/--/-- BWR Created + */ + + +#ifndef ITEMPROP_H +#define ITEMPROP_H + +#include "externs.h" + +void init_properties(void); + +// cursed: +bool item_cursed( const item_def &item ); +bool item_known_cursed( const item_def &item ); +bool item_known_uncursed( const item_def &item ); +void do_curse_item( item_def &item ); +void do_uncurse_item( item_def &item ); + +// ident: +bool item_ident( const item_def &item, unsigned long flags ); +void set_ident_flags( item_def &item, unsigned long flags ); +void unset_ident_flags( item_def &item, unsigned long flags ); + +// racial item and item descriptions: +void set_equip_race( item_def &item, unsigned long flags ); +void set_equip_desc( item_def &item, unsigned long flags ); +unsigned long get_equip_race( const item_def &item ); +unsigned long get_equip_desc( const item_def &item ); + +// helmet functions: +void set_helmet_type( item_def &item, short flags ); +void set_helmet_desc( item_def &item, short flags ); +void set_helmet_random_desc( item_def &item ); + +short get_helmet_type( const item_def &item ); +short get_helmet_desc( const item_def &item ); + +bool is_helmet_type( const item_def &item, short val ); + +// ego items: +bool set_item_ego_type( item_def &item, int item_type, int ego_type ); +int get_weapon_brand( const item_def &item ); +int get_armour_ego_type( const item_def &item ); +int get_ammo_brand( const item_def &item ); + +// armour functions: +int armour_max_enchant( const item_def &item ); +bool armour_is_hide( const item_def &item, bool inc_made = false ); +bool armour_not_shiny( const item_def &item ); +int armour_str_required( const item_def &arm ); + +equipment_type get_armour_slot( const item_def &item ); + +bool jewellery_is_amulet( const item_def &item ); +bool check_jewellery_size( const item_def &item, size_type size ); + +bool hide2armour( item_def &item ); + +bool base_armour_is_light( const item_def &item ); +int fit_armour_size( const item_def &item, size_type size ); +bool check_armour_size( const item_def &item, size_type size ); +bool check_armour_shape( const item_def &item, bool quiet ); + +// weapon functions: +int weapon_rarity( int w_type ); + +int cmp_weapon_size( const item_def &item, size_type size ); +bool check_weapon_tool_size( const item_def &item, size_type size ); +int fit_weapon_wieldable_size( const item_def &item, size_type size ); +bool check_weapon_wieldable_size( const item_def &item, size_type size ); + +int fit_item_throwable_size( const item_def &item, size_type size ); + +bool check_weapon_shape( const item_def &item, bool quiet, bool check_id = false ); + +int weapon_ev_bonus( const item_def &wpn, int skill, size_type body, int dex, + bool hide_hidden = false ); + +int get_inv_wielded( void ); +int get_inv_hand_tool( void ); +int get_inv_in_hand( void ); + +hands_reqd_type hands_reqd( const item_def &item, size_type size ); +bool is_double_ended( const item_def &item ); + +int double_wpn_awkward_speed( const item_def &item ); + +bool is_demonic( const item_def &item ); + +int get_vorpal_type( const item_def &item ); +int get_damage_type( const item_def &item ); +bool does_damage_type( const item_def &item, int dam_type ); + +int weapon_str_weight( const item_def &wpn ); +int weapon_dex_weight( const item_def &wpn ); +int weapon_impact_mass( const item_def &wpn ); +int weapon_str_required( const item_def &wpn, bool half ); + +skill_type weapon_skill( const item_def &item ); +skill_type weapon_skill( int wclass, int wtype ); + +skill_type range_skill( const item_def &item ); +skill_type range_skill( int wclass, int wtype ); + +// launcher and ammo functions: +bool is_range_weapon( const item_def &item ); +bool is_range_weapon_type( weapon_type wtype ); +missile_type fires_ammo_type( const item_def &item ); +const char * ammo_name( const item_def &bow ); +bool is_throwable( const item_def &wpn ); +launch_retval is_launched( int being_id, const item_def &ammo, bool msg = false ); + +// staff/rod functions: +bool item_is_rod( const item_def &item ); +bool item_is_staff( const item_def &item ); + +// ring functions: +int ring_has_pluses( const item_def &item ); + +// food functions: +bool food_is_meat( const item_def &item ); +bool food_is_veg( const item_def &item ); +int food_value( const item_def &item ); +int food_turns( const item_def &item ); +bool can_cut_meat( const item_def &item ); + +// generic item property functions: +bool is_tool( const item_def &item ); +int property( const item_def &item, int prop_type ); +int item_mass( const item_def &item ); +size_type item_size( const item_def &item ); + +bool is_colourful_item( const item_def &item ); + +#endif diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 5949668139..7c7a822343 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -40,6 +40,7 @@ #include "it_use2.h" #include "item_use.h" #include "itemname.h" +#include "itemprop.h" #include "misc.h" #include "monplace.h" #include "monstuff.h" @@ -1299,8 +1300,8 @@ bool items_stack( const item_def &item1, const item_def &item2 ) // if either isn't identified and they look different. -- bwr if (item1.base_type == OBJ_POTIONS && item1.special != item2.special - && (item_not_ident( item1, ISFLAG_KNOW_TYPE ) - || item_not_ident( item2, ISFLAG_KNOW_TYPE ))) + && (!item_ident( item1, ISFLAG_KNOW_TYPE ) + || !item_ident( item2, ISFLAG_KNOW_TYPE ))) { return (false); } @@ -1386,7 +1387,7 @@ int find_free_slot(const item_def &i) // the player's inventory is full. int move_item_to_player( int obj, int quant_got, bool quiet ) { - int item_mass = 0; + int imass = 0; int unit_mass = 0; int retval = quant_got; char brek = 0; @@ -1413,17 +1414,17 @@ int move_item_to_player( int obj, int quant_got, bool quiet ) return (retval); } - unit_mass = mass_item( mitm[obj] ); + unit_mass = item_mass( mitm[obj] ); if (quant_got > mitm[obj].quantity || quant_got <= 0) quant_got = mitm[obj].quantity; - item_mass = unit_mass * quant_got; + imass = unit_mass * quant_got; brek = 0; // multiply both constants * 10 - if ((int) you.burden + item_mass > carrying_capacity()) + if ((int) you.burden + imass > carrying_capacity()) { // calculate quantity we can actually pick up int part = (carrying_capacity() - (int)you.burden) / unit_mass; @@ -2657,8 +2658,9 @@ void handle_time( long time_delta ) boom.thrower = KILL_MISC; boom.aux_source = "a magical explosion"; boom.beam_source = NON_MONSTER; - boom.isBeam = false; - boom.isTracer = false; + boom.is_beam = false; + boom.is_tracer = false; + boom.is_explosion = true; strcpy(boom.beam_name, "magical storm"); boom.ench_power = (you.magic_contamination * 5); @@ -2686,7 +2688,7 @@ void handle_time( long time_delta ) // and an appropriate other spell skill... is 1/20 too fast? if (you.equip[EQ_WEAPON] != -1 && you.inv[you.equip[EQ_WEAPON]].base_type == OBJ_STAVES - && item_not_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE ) + && !item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE ) && one_chance_in(20)) { int total_skill = you.skills[SK_SPELLCASTING]; @@ -2880,7 +2882,7 @@ void handle_time( long time_delta ) // exercise armour *xor* stealth skill: {dlb} if (!player_light_armour()) { - if (random2(1000) <= mass_item( you.inv[you.equip[EQ_BODY_ARMOUR]] )) + if (random2(1000) <= item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] )) { return; } @@ -2897,7 +2899,7 @@ void handle_time( long time_delta ) return; if (you.equip[EQ_BODY_ARMOUR] != -1 - && random2( mass_item( you.inv[you.equip[EQ_BODY_ARMOUR]] )) >= 100) + && random2( item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] )) >= 100) { return; } diff --git a/crawl-ref/source/makefile.mgw b/crawl-ref/source/makefile.mgw index 312dcd705d..750e25a6c7 100644 --- a/crawl-ref/source/makefile.mgw +++ b/crawl-ref/source/makefile.mgw @@ -12,7 +12,9 @@ COPY = copy OS_TYPE = WIN32CONSOLE CFLAGS = -Wall -Wwrite-strings -Wstrict-prototypes \ -Wmissing-prototypes -Wmissing-declarations \ - -D$(OS_TYPE) $(EXTRA_FLAGS) + -D$(OS_TYPE) $(EXTRA_FLAGS) -DCLUA_BINDINGS \ + -DWINMM_PLAY_SOUNDS -DREGEX_PCRE + OBJECTS := $(OBJECTS) libw32c.o LDFLAGS = diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index e15334a033..8cadd1cebd 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -24,6 +24,7 @@ it_use2.o \ it_use3.o \ item_use.o \ itemname.o \ +itemprop.o \ items.o \ lev-pand.o \ libutil.o \ diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc index e349621b61..55fd6736cd 100644 --- a/crawl-ref/source/misc.cc +++ b/crawl-ref/source/misc.cc @@ -132,7 +132,22 @@ void turn_corpse_into_chunks( item_def &item ) } } // end place_chunks() -bool grid_destroys_items( unsigned char grid ) +bool grid_is_opaque( int grid ) +{ + return (grid < MINSEE && grid != DNGN_ORCISH_IDOL); +} + +bool grid_is_solid( int grid ) +{ + return (grid < MINMOVE); +} + +bool grid_is_water( int grid ) +{ + return (grid == DNGN_SHALLOW_WATER || grid == DNGN_DEEP_WATER); +} + +bool grid_destroys_items( int grid ) { return (grid == DNGN_LAVA || grid == DNGN_DEEP_WATER); } @@ -1921,3 +1936,24 @@ int trap_at_xy(int which_x, int which_y) // no idea how well this will be handled elsewhere: {dlb} return (-1); } // end trap_at_xy() + +// A constructor for bolt to help guarantee that we start clean (this has +// caused way too many bugs). Putting it here since there's no good place to +// put it, and it doesn't do anything other than initialize it's members. +// +// TODO: Eventually it'd be nice to have a proper factory for these things +// (extended from setup_mons_cast() and zapping() which act as limited ones). +bolt::bolt() : range(0), rangeMax(0), type(SYM_ZAP), colour(BLACK), + flavour(BEAM_MAGIC), source_x(0), source_y(0), damage(0,0), + ench_power(0), hit(0), target_x(0), target_y(0), + thrower(KILL_MISC), ex_size(0), beam_source(MHITNOT), + beam_name(), + is_beam(false), is_explosion(false), is_big_cloud(false), + is_enchant(false), is_energy(false), + is_launched(false), is_thrown(false), target_first(false), + aux_source(NULL), obvious_effect(false), + fr_count(0), foe_count(0), fr_power(0), foe_power(0), + is_tracer(false), aimed_at_feet(false), msg_generated(false), + in_explosion_phase(false), smart_monster(false), + can_see_invis(false), is_friendly(false), foe_ratio(0) +{ } diff --git a/crawl-ref/source/misc.h b/crawl-ref/source/misc.h index dee5163d6a..3f109eed6b 100644 --- a/crawl-ref/source/misc.h +++ b/crawl-ref/source/misc.h @@ -131,7 +131,10 @@ void weird_writing(char stringy[40]); * *********************************************************************** */ unsigned char trap_category(unsigned char trap_type); -bool grid_destroys_items( unsigned char grid ); +bool grid_is_opaque(int grid); +bool grid_is_solid(int grid); +bool grid_is_water(int grid); +bool grid_destroys_items( int grid ); const char *grid_item_destruction_message( unsigned char grid ); diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 748296cb60..f51df5b096 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -107,7 +107,7 @@ MONS_PROGRAM_BUG, 'B', LIGHTRED, "program bug", M_NO_EXP_GAIN, MR_NO_FLAGS, - 0, 10, MONS_PROGRAM_BUG, MH_NATURAL, -3, + 0, 10, MONS_PROGRAM_BUG, MONS_PROGRAM_BUG, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -120,7 +120,7 @@ MONS_GIANT_ANT, 'a', DARKGREY, "giant ant", M_NO_FLAGS, MR_VUL_POISON, - 700, 10, MONS_GIANT_ANT, MH_NATURAL, -3, + 700, 10, MONS_GIANT_ANT, MONS_GIANT_ANT, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 3, 3, 5, 0 }, 4, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, @@ -132,7 +132,7 @@ MONS_GIANT_BAT, 'b', DARKGREY, "giant bat", M_FLIES | M_SEE_INVIS | M_WARM_BLOOD, MR_NO_FLAGS, - 150, 4, MONS_GIANT_BAT, MH_NATURAL, -1, + 150, 4, MONS_GIANT_BAT, MONS_GIANT_BAT, MH_NATURAL, -1, { 1, 0, 0, 0 }, { 1, 2, 3, 0 }, 1, 14, 30, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, @@ -144,7 +144,7 @@ MONS_CENTAUR, 'c', BROWN, "centaur", M_WARM_BLOOD, MR_NO_FLAGS, - 1500, 10, MONS_CENTAUR, MH_NATURAL, -3, + 1500, 10, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, 3, 7, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, @@ -156,7 +156,7 @@ MONS_RED_DEVIL, '4', RED, "red devil", M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, - 0, 10, MONS_RED_DEVIL, MH_DEMONIC, -7, + 0, 10, MONS_RED_DEVIL, MONS_RED_DEVIL, MH_DEMONIC, -7, { 18, 0, 0, 0 }, { 5, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -168,7 +168,7 @@ MONS_ETTIN, 'C', BROWN, "ettin", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_ETTIN, MH_NATURAL, -3, + 0, 10, MONS_HILL_GIANT, MONS_ETTIN, MH_NATURAL, -3, { 18, 12, 0, 0 }, { 7, 3, 5, 0 }, 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL, @@ -180,7 +180,7 @@ MONS_FUNGUS, 'f', LIGHTGREY, "fungus", M_NO_EXP_GAIN, MR_RES_POISON, - 0, 10, MONS_FUNGUS, MH_PLANT, 5000, + 0, 10, MONS_PLANT, MONS_FUNGUS, MH_PLANT, 5000, { 0, 0, 0, 0 }, { 8, 3, 5, 0 }, 1, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -192,7 +192,7 @@ MONS_GOBLIN, 'g', LIGHTGREY, "goblin", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 400, 10, MONS_GOBLIN, MH_NATURAL, -1, + 400, 10, MONS_GOBLIN, MONS_GOBLIN, MH_NATURAL, -1, { 4, 0, 0, 0 }, { 1, 2, 4, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -204,7 +204,7 @@ MONS_HOUND, 'h', BROWN, "hound", M_SEE_INVIS | M_WARM_BLOOD, MR_NO_FLAGS, - 300, 10, MONS_HOUND, MH_NATURAL, -3, + 300, 10, MONS_HOUND, MONS_HOUND, MH_NATURAL, -3, { 6, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 13, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL, @@ -215,9 +215,9 @@ // note: these things regenerate { MONS_IMP, '5', RED, "imp", - M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL, + M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, - 0, 13, MONS_IMP, MH_DEMONIC, -9, + 0, 13, MONS_IMP, MONS_IMP, MH_DEMONIC, -9, { 4, 0, 0, 0 }, { 3, 3, 3, 0 }, 3, 14, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -229,7 +229,7 @@ MONS_JACKAL, 'j', YELLOW, "jackal", M_WARM_BLOOD, MR_NO_FLAGS, - 200, 10, MONS_JACKAL, MH_NATURAL, -1, + 200, 10, MONS_HOUND, MONS_JACKAL, MH_NATURAL, -1, { 3, 0, 0, 0 }, { 1, 3, 5, 0 }, 2, 12, 14, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, @@ -241,7 +241,7 @@ MONS_KILLER_BEE, 'k', YELLOW, "killer bee", M_FLIES, MR_VUL_POISON, - 150, 11, MONS_KILLER_BEE, MH_NATURAL, -3, + 150, 11, MONS_KILLER_BEE, MONS_KILLER_BEE, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 18, 20, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT, @@ -253,7 +253,7 @@ MONS_KILLER_BEE_LARVA, 'w', LIGHTGREY, "killer bee larva", M_NO_SKELETON, MR_VUL_POISON, - 150, 5, MONS_KILLER_BEE_LARVA, MH_NATURAL, -3, + 150, 5, MONS_KILLER_BEE_LARVA, MONS_KILLER_BEE_LARVA, MH_NATURAL, -3, { 3, 0, 0, 0 }, { 1, 3, 5, 0 }, 1, 5, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -263,9 +263,9 @@ { MONS_MANTICORE, 'm', BROWN, "manticore", - M_WARM_BLOOD, + M_WARM_BLOOD | M_SPECIAL_ABILITY, MR_NO_FLAGS, - 1800, 10, MONS_MANTICORE, MH_NATURAL, -3, + 1800, 10, MONS_MANTICORE, MONS_MANTICORE, MH_NATURAL, -3, { 14, 8, 8, 0 }, { 9, 3, 5, 0 }, 5, 7, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SILENT, I_NORMAL, @@ -278,7 +278,7 @@ MONS_NECROPHAGE, 'n', DARKGREY, "necrophage", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 500, 10, MONS_NECROPHAGE, MH_UNDEAD, -5, + 500, 10, MONS_GHOUL, MONS_NECROPHAGE, MH_UNDEAD, -5, { 8, 0, 0, 0 }, { 5, 3, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -290,7 +290,7 @@ MONS_ORC, 'o', LIGHTRED, "orc", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 600, 10, MONS_ORC, MH_NATURAL, -3, + 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 1, 4, 6, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -302,9 +302,9 @@ // dangerous, but still come out at 200+ XP { MONS_PHANTOM, 'p', BLUE, "phantom", - M_EVIL, + M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_COLD, - 0, 5, MONS_PHANTOM, MH_UNDEAD, -4, + 0, 5, MONS_PHANTOM, MONS_PHANTOM, MH_UNDEAD, -4, { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, 3, 13, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -316,7 +316,7 @@ MONS_QUASIT, 'q', LIGHTGREY, "quasit", M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 0, 10, MONS_QUASIT, MH_DEMONIC, 50, + 0, 10, MONS_QUASIT, MONS_QUASIT, MH_DEMONIC, 50, { 3, 2, 2, 0 }, { 3, 2, 6, 0 }, 5, 17, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, @@ -328,7 +328,7 @@ MONS_RAT, 'r', BROWN, "rat", M_WARM_BLOOD, MR_NO_FLAGS, - 200, 10, MONS_RAT, MH_NATURAL, -1, + 200, 10, MONS_RAT, MONS_RAT, MH_NATURAL, -1, { 3, 0, 0, 0 }, { 1, 1, 3, 0 }, 1, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, @@ -340,7 +340,7 @@ MONS_SCORPION, 's', DARKGREY, "scorpion", M_NO_FLAGS, MR_VUL_POISON, - 500, 10, MONS_SCORPION, MH_NATURAL, -3, + 500, 10, MONS_SCORPION, MONS_SCORPION, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 3, 3, 5, 0 }, 5, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -368,7 +368,7 @@ MONS_UGLY_THING, 'u', BROWN, "ugly thing", M_WARM_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 600, 10, MONS_UGLY_THING, MH_NATURAL, -3, + 600, 10, MONS_UGLY_THING, MONS_UGLY_THING, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 8, 3, 5, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -380,7 +380,7 @@ MONS_FIRE_VORTEX, 'v', RED, "fire vortex", M_LEVITATE | M_CONFUSED, MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD | MR_RES_ELEC, - 0, 5, MONS_FIRE_VORTEX, MH_NONLIVING, 5000, + 0, 5, MONS_FIRE_VORTEX, MONS_FIRE_VORTEX, MH_NONLIVING, 5000, { 30, 0, 0, 0 }, { 3, 3, 5, 0 }, 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -392,7 +392,7 @@ MONS_WORM, 'w', LIGHTRED, "worm", M_NO_SKELETON, MR_NO_FLAGS, - 350, 4, MONS_WORM, MH_NATURAL, -2, + 350, 4, MONS_WORM, MONS_WORM, MH_NATURAL, -2, { 12, 0, 0, 0 }, { 5, 3, 5, 0 }, 1, 5, 6, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, @@ -405,7 +405,7 @@ MONS_ABOMINATION_SMALL, 'x', BLACK, "abomination", M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_ABOMINATION_SMALL, MH_DEMONIC, -5, + 0, 10, MONS_ABOMINATION_SMALL, MONS_ABOMINATION_SMALL, MH_DEMONIC, -5, { 23, 0, 0, 0 }, { 6, 2, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -417,7 +417,7 @@ MONS_YELLOW_WASP, 'y', YELLOW, "yellow wasp", M_FLIES, MR_VUL_POISON, - 220, 12, MONS_YELLOW_WASP, MH_NATURAL, -3, + 220, 12, MONS_YELLOW_WASP, MONS_YELLOW_WASP, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 4, 3, 5, 0 }, 5, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, @@ -430,7 +430,7 @@ MONS_ZOMBIE_SMALL, 'z', BROWN, "", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 6, MONS_ZOMBIE_SMALL, MH_UNDEAD, -1, + 0, 6, MONS_ZOMBIE_SMALL, MONS_ZOMBIE_SMALL, MH_UNDEAD, -1, { 10, 0, 0, 0 }, { 1, 5, 5, 0 }, 0, 4, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -442,7 +442,7 @@ MONS_ANGEL, 'A', WHITE, "Angel", M_FLIES | M_SPELLCASTER, MR_RES_POISON | MR_RES_ELEC, - 0, 10, MONS_ANGEL, MH_HOLY, -8, + 0, 10, MONS_ANGEL, MONS_ANGEL, MH_HOLY, -8, { 20, 0, 0, 0 }, { 9, 3, 5, 0 }, 10, 10, 10, 7, MST_ANGEL, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -454,7 +454,7 @@ MONS_GIANT_BEETLE, 'B', DARKGREY, "giant beetle", M_NO_FLAGS, MR_VUL_POISON, - 1000, 10, MONS_GIANT_BEETLE, MH_NATURAL, -3, + 1000, 10, MONS_GIANT_BEETLE, MONS_GIANT_BEETLE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 7, 6, 0 }, 10, 3, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -466,7 +466,7 @@ MONS_CYCLOPS, 'C', BROWN, "cyclops", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 2500, 10, MONS_CYCLOPS, MH_NATURAL, -3, + 2500, 10, MONS_HILL_GIANT, MONS_CYCLOPS, MH_NATURAL, -3, { 35, 0, 0, 0 }, { 9, 3, 5, 0 }, 5, 3, 7, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, @@ -476,9 +476,9 @@ { MONS_DRAGON, 'D', GREEN, "dragon", - M_FLIES, //jmf: warm blood? + M_FLIES | M_SPECIAL_ABILITY, //jmf: warm blood? MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, - 2200, 12, MONS_DRAGON, MH_NATURAL, -4, + 2200, 12, MONS_DRAGON, MONS_DRAGON, MH_NATURAL, -4, { 20, 13, 13, 0 }, { 12, 5, 5, 0 }, 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL, @@ -492,7 +492,7 @@ MONS_TWO_HEADED_OGRE, 'O', LIGHTRED, "two-headed ogre", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 1500, 15, MONS_TWO_HEADED_OGRE, MH_NATURAL, -4, + 1500, 15, MONS_OGRE, MONS_TWO_HEADED_OGRE, MH_NATURAL, -4, { 17, 13, 0, 0 }, { 6, 3, 5, 0 }, 1, 4, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL, @@ -504,7 +504,7 @@ MONS_FIEND, '1', LIGHTRED, "Fiend", //jmf: was RED, like Balrog M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, - 0, 18, MONS_FIEND, MH_DEMONIC, -12, + 0, 18, MONS_FIEND, MONS_FIEND, MH_DEMONIC, -12, { 25, 15, 15, 0 }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -516,7 +516,7 @@ MONS_GIANT_SPORE, 'G', GREEN, "giant spore", M_LEVITATE, MR_RES_POISON, - 0, 10, MONS_GIANT_SPORE, MH_NATURAL, -3, + 0, 10, MONS_PLANT, MONS_GIANT_SPORE, MH_NATURAL, -3, { 1, 0, 0, 0 }, { 1, 0, 0, 1 }, 0, 10, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -528,7 +528,7 @@ MONS_HOBGOBLIN, 'g', BROWN, "hobgoblin", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 500, 10, MONS_HOBGOBLIN, MH_NATURAL, -1, + 500, 10, MONS_GOBLIN, MONS_HOBGOBLIN, MH_NATURAL, -1, { 5, 0, 0, 0 }, { 1, 4, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -540,7 +540,7 @@ MONS_ICE_BEAST, 'I', WHITE, "ice beast", M_NO_FLAGS, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 12, MONS_ICE_BEAST, MH_NATURAL, -3, + 0, 12, MONS_ICE_BEAST, MONS_ICE_BEAST, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 5, 3, 5, 0 }, 5, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE, @@ -552,7 +552,7 @@ MONS_JELLY, 'J', LIGHTRED, "jelly", M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS, MR_RES_POISON, - 0, 13, MONS_JELLY, MH_NATURAL, -3, + 0, 13, MONS_JELLY, MONS_JELLY, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 3, 5, 5, 0 }, 0, 2, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -564,7 +564,7 @@ MONS_KOBOLD, 'K', BROWN, "kobold", M_WARM_BLOOD, MR_NO_FLAGS, - 400, 10, MONS_KOBOLD, MH_NATURAL, -1, + 400, 10, MONS_KOBOLD, MONS_KOBOLD, MH_NATURAL, -1, { 4, 0, 0, 0 }, { 1, 2, 3, 0 }, 2, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, @@ -576,7 +576,7 @@ MONS_LICH, 'L', WHITE, "lich", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, - 0, 16, MONS_LICH, MH_UNDEAD, -11, + 0, 16, MONS_LICH, MONS_LICH, MH_UNDEAD, -11, { 15, 0, 0, 0 }, { 20, 2, 4, 0 }, 10, 10, 10, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -588,7 +588,7 @@ MONS_MUMMY, 'M', WHITE, "mummy", M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 10, MONS_MUMMY, MH_UNDEAD, -5, + 0, 10, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, -5, { 20, 0, 0, 0 }, { 3, 5, 3, 0 }, 3, 6, 6, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL, @@ -600,7 +600,7 @@ MONS_GUARDIAN_NAGA, 'N', LIGHTGREEN, "guardian naga", M_SPELLCASTER | M_SEE_INVIS | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_POISON, - 350, 10, MONS_GUARDIAN_NAGA, MH_NATURAL, -6, + 350, 10, MONS_NAGA, MONS_GUARDIAN_NAGA, MH_NATURAL, -6, { 19, 0, 0, 0 }, { 8, 3, 5, 0 }, 6, 14, 15, 7, MST_GUARDIAN_NAGA, CE_MUTAGEN_RANDOM, Z_SMALL, S_SHOUT, I_HIGH, @@ -612,7 +612,7 @@ MONS_OGRE, 'O', BROWN, "ogre", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 1300, 10, MONS_OGRE, MH_NATURAL, -3, + 1300, 10, MONS_OGRE, MONS_OGRE, MH_NATURAL, -3, { 17, 0, 0, 0 }, { 5, 3, 5, 0 }, 1, 6, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -624,7 +624,7 @@ MONS_PLANT, 'P', GREEN, "plant", M_NO_EXP_GAIN, MR_NO_FLAGS, - 0, 10, MONS_PLANT, MH_PLANT, 5000, + 0, 10, MONS_PLANT, MONS_PLANT, MH_PLANT, 5000, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -636,7 +636,7 @@ MONS_QUEEN_BEE, 'Q', YELLOW, "queen bee", M_FLIES, MR_VUL_POISON, - 200, 14, MONS_QUEEN_BEE, MH_NATURAL, -3, + 200, 14, MONS_KILLER_BEE, MONS_QUEEN_BEE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -648,7 +648,7 @@ MONS_RAKSHASA, 'R', YELLOW, "rakshasa", M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON, - 0, 15, MONS_RAKSHASA, MH_NATURAL, -10, + 0, 15, MONS_RAKSHASA, MONS_RAKSHASA, MH_NATURAL, -10, { 20, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 14, 10, 7, MST_RAKSHASA, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -660,7 +660,7 @@ MONS_SNAKE, 'S', GREEN, "snake", M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 200, 10, MONS_SNAKE, MH_NATURAL, -3, + 200, 10, MONS_SNAKE, MONS_SNAKE, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 1, 15, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, @@ -672,7 +672,7 @@ MONS_TROLL, 'T', BROWN, "troll", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 1500, 10, MONS_TROLL, MH_NATURAL, -3, + 1500, 10, MONS_TROLL, MONS_TROLL, MH_NATURAL, -3, { 20, 15, 15, 0 }, { 7, 3, 5, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -684,7 +684,7 @@ MONS_UNSEEN_HORROR, 'x', MAGENTA, "unseen horror", M_LEVITATE | M_SEE_INVIS | M_INVIS, MR_RES_ELEC, - 0, 12, MONS_UNSEEN_HORROR, MH_NATURAL, -3, + 0, 12, MONS_UNSEEN_HORROR, MONS_UNSEEN_HORROR, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 7, 3, 5, 0 }, 5, 10, 30, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE, @@ -696,7 +696,7 @@ MONS_VAMPIRE, 'V', RED, "vampire", M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 11, MONS_VAMPIRE, MH_UNDEAD, -6, + 0, 11, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6, { 22, 0, 0, 0 }, { 6, 3, 5, 0 }, 10, 10, 10, 7, MST_VAMPIRE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -708,7 +708,7 @@ MONS_WRAITH, 'W', DARKGREY, "wraith", M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 11, MONS_WRAITH, MH_UNDEAD, -7, + 0, 11, MONS_WRAITH, MONS_WRAITH, MH_UNDEAD, -7, { 13, 0, 0, 0 }, { 6, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -721,7 +721,7 @@ MONS_ABOMINATION_LARGE, 'X', BLACK, "abomination", M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_ABOMINATION_LARGE, MH_DEMONIC, -7, + 0, 10, MONS_ABOMINATION_SMALL, MONS_ABOMINATION_LARGE, MH_DEMONIC, -7, { 40, 0, 0, 0 }, { 11, 2, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -733,7 +733,7 @@ MONS_YAK, 'Y', BROWN, "yak", M_WARM_BLOOD, MR_NO_FLAGS, - 1200, 10, MONS_YAK, MH_NATURAL, -3, + 1200, 10, MONS_YAK, MONS_YAK, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 7, 3, 5, 0 }, 4, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_BELLOW, I_ANIMAL, @@ -746,7 +746,7 @@ MONS_ZOMBIE_LARGE, 'Z', BROWN, "", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 6, MONS_ZOMBIE_LARGE, MH_UNDEAD, -1, + 0, 6, MONS_ZOMBIE_SMALL, MONS_ZOMBIE_LARGE, MH_UNDEAD, -1, { 23, 0, 0, 0 }, { 6, 3, 5, 0 }, 8, 5, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -758,7 +758,7 @@ MONS_ORC_WARRIOR, 'o', YELLOW, "orc warrior", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_ORC, MH_NATURAL, -3, + 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 4, 4, 6, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -770,7 +770,7 @@ MONS_KOBOLD_DEMONOLOGIST, 'K', MAGENTA, "kobold demonologist", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_KOBOLD, MH_NATURAL, -5, + 0, 10, MONS_KOBOLD, MONS_KOBOLD, MH_NATURAL, -5, { 4, 0, 0, 0 }, { 4, 3, 5, 0 }, 2, 13, 10, 7, MST_KOBOLD_DEMONOLOGIST, CE_POISONOUS, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -782,7 +782,7 @@ MONS_ORC_WIZARD, 'o', MAGENTA, "orc wizard", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_ORC, MH_NATURAL, -5, + 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -5, { 5, 0, 0, 0 }, { 3, 3, 4, 0 }, 1, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -794,7 +794,7 @@ MONS_ORC_KNIGHT, 'o', LIGHTCYAN, "orc knight", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_ORC, MH_NATURAL, -3, + 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3, { 25, 0, 0, 0 }, { 9, 4, 7, 0 }, 2, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -822,7 +822,7 @@ MONS_WYVERN, 'D', LIGHTRED, "wyvern", M_NO_FLAGS, //jmf: warm blood? MR_NO_FLAGS, - 2000, 10, MONS_WYVERN, MH_NATURAL, -3, + 2000, 10, MONS_WYVERN, MONS_WYVERN, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 3, 5, 0 }, 5, 10, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, @@ -834,7 +834,7 @@ MONS_BIG_KOBOLD, 'K', RED, "big kobold", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_BIG_KOBOLD, MH_NATURAL, -3, + 0, 10, MONS_KOBOLD, MONS_BIG_KOBOLD, MH_NATURAL, -3, { 7, 0, 0, 0 }, { 5, 3, 5, 0 }, 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_NORMAL, @@ -846,7 +846,7 @@ MONS_GIANT_EYEBALL, 'G', WHITE, "giant eyeball", M_NO_SKELETON | M_LEVITATE, MR_NO_FLAGS, - 400, 10, MONS_GIANT_EYEBALL, MH_NATURAL, -3, + 400, 10, MONS_GIANT_EYEBALL, MONS_GIANT_EYEBALL, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 3, 3, 5, 0 }, 0, 1, 3, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_PLANT, @@ -858,7 +858,7 @@ MONS_WIGHT, 'W', LIGHTGREY, "wight", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_WIGHT, MH_UNDEAD, -4, + 0, 10, MONS_WRAITH, MONS_WIGHT, MH_UNDEAD, -4, { 8, 0, 0, 0 }, { 3, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -868,9 +868,9 @@ { MONS_OKLOB_PLANT, 'P', GREEN, "oklob plant", - M_NO_FLAGS, + M_SPECIAL_ABILITY, MR_RES_POISON, - 0, 10, MONS_OKLOB_PLANT, MH_PLANT, -3, + 0, 10, MONS_PLANT, MONS_OKLOB_PLANT, MH_PLANT, -3, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -882,7 +882,7 @@ MONS_WOLF_SPIDER, 's', BROWN, "wolf spider", M_NO_FLAGS, MR_VUL_POISON, - 800, 10, MONS_WOLF_SPIDER, MH_NATURAL, -3, + 800, 10, MONS_WOLF_SPIDER, MONS_WOLF_SPIDER, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, 3, 10, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -894,7 +894,7 @@ MONS_SHADOW, ' ', BLACK, "shadow", M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_SHADOW, MH_UNDEAD, -5, + 0, 10, MONS_WRAITH, MONS_SHADOW, MH_UNDEAD, -5, { 5, 0, 0, 0 }, { 3, 3, 5, 0 }, 12, 10, 10, 7, BLACK, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL, @@ -906,7 +906,7 @@ MONS_HUNGRY_GHOST, 'p', GREEN, "hungry ghost", M_SEE_INVIS | M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_HUNGRY_GHOST, MH_UNDEAD, -4, + 0, 10, MONS_PHANTOM, MONS_HUNGRY_GHOST, MH_UNDEAD, -4, { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, 0, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -918,7 +918,7 @@ MONS_EYE_OF_DRAINING, 'G', LIGHTGREY, "eye of draining", M_NO_SKELETON | M_LEVITATE | M_SEE_INVIS, MR_NO_FLAGS, - 400, 10, MONS_EYE_OF_DRAINING, MH_NATURAL, 5000, + 400, 10, MONS_GIANT_EYEBALL, MONS_EYE_OF_DRAINING, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 7, 3, 5, 0 }, 3, 1, 5, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -930,7 +930,7 @@ MONS_BUTTERFLY, 'b', BLACK, "butterfly", M_FLIES | M_CONFUSED, MR_VUL_POISON, - 150, 10, MONS_BUTTERFLY, MH_NATURAL, -3, + 150, 10, MONS_BUTTERFLY, MONS_BUTTERFLY, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 1, 3, 5, 0 }, 0, 25, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, @@ -942,7 +942,7 @@ MONS_WANDERING_MUSHROOM, 'f', BROWN, "wandering mushroom", M_NO_FLAGS, MR_RES_POISON, - 0, 10, MONS_WANDERING_MUSHROOM, MH_PLANT, -3, + 0, 10, MONS_PLANT, MONS_WANDERING_MUSHROOM, MH_PLANT, -3, { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, 5, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -954,7 +954,7 @@ MONS_EFREET, 'E', RED, "efreet", M_SPELLCASTER | M_LEVITATE | M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, - 0, 12, MONS_EFREET, MH_DEMONIC, -3, + 0, 12, MONS_EFREET, MONS_EFREET, MH_DEMONIC, -3, { 12, 0, 0, 0 }, { 7, 3, 5, 0 }, 10, 5, 10, 7, MST_EFREET, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -966,7 +966,7 @@ MONS_BRAIN_WORM, 'w', LIGHTMAGENTA, "brain worm", M_SPELLCASTER, MR_NO_FLAGS, - 150, 10, MONS_BRAIN_WORM, MH_NATURAL, -3, + 150, 10, MONS_WORM, MONS_BRAIN_WORM, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 5, 3, 3, 0 }, 1, 5, 10, 7, MST_BRAIN_WORM, CE_POISONOUS, Z_SMALL, S_SILENT, I_REPTILE, @@ -978,7 +978,7 @@ MONS_GIANT_ORANGE_BRAIN, 'G', LIGHTRED, "giant orange brain", M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, MR_NO_FLAGS, - 1000, 13, MONS_GIANT_ORANGE_BRAIN, MH_NATURAL, -8, + 1000, 13, MONS_GIANT_ORANGE_BRAIN, MONS_GIANT_ORANGE_BRAIN, MH_NATURAL, -8, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 2, 4, 10, 7, MST_GIANT_ORANGE_BRAIN, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -990,7 +990,7 @@ MONS_BOULDER_BEETLE, 'B', LIGHTGREY, "boulder beetle", M_NO_FLAGS, MR_VUL_POISON, - 2500, 10, MONS_BOULDER_BEETLE, MH_NATURAL, -3, + 2500, 10, MONS_GIANT_BEETLE, MONS_BOULDER_BEETLE, MH_NATURAL, -3, { 35, 0, 0, 0 }, { 9, 3, 5, 0 }, 20, 2, 3, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -1002,7 +1002,7 @@ MONS_FLYING_SKULL, 'z', WHITE, "flying skull", M_LEVITATE, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_FLYING_SKULL, MH_UNDEAD, -3, + 0, 10, MONS_SKELETON_SMALL, MONS_FLYING_SKULL, MH_UNDEAD, -3, { 7, 0, 0, 0 }, { 2, 3, 5, 0 }, 10, 17, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_ANIMAL, @@ -1012,9 +1012,9 @@ { MONS_HELL_HOUND, 'h', DARKGREY, "hell hound", - M_SEE_INVIS | M_EVIL, + M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, - 0, 10, MONS_HELL_HOUND, MH_DEMONIC, -3, + 0, 10, MONS_HOUND, MONS_HELL_HOUND, MH_DEMONIC, -3, { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, 6, 13, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_BARK, I_NORMAL, @@ -1026,7 +1026,7 @@ MONS_MINOTAUR, 'm', LIGHTRED, "minotaur", M_WARM_BLOOD, MR_NO_FLAGS, - 1500, 10, MONS_MINOTAUR, MH_NATURAL, -3, + 1500, 10, MONS_MINOTAUR, MONS_MINOTAUR, MH_NATURAL, -3, { 35, 0, 0, 0 }, { 13, 3, 5, 0 }, 5, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_BELLOW, I_NORMAL, @@ -1036,9 +1036,9 @@ { MONS_ICE_DRAGON, 'D', WHITE, "ice dragon", - M_FLIES, + M_FLIES | M_SPECIAL_ABILITY, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 2200, 10, MONS_ICE_DRAGON, MH_NATURAL, -3, + 2200, 10, MONS_DRAGON, MONS_ICE_DRAGON, MH_NATURAL, -3, { 17, 17, 17, 0 }, { 12, 5, 5, 0 }, 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL, @@ -1050,7 +1050,7 @@ MONS_SLIME_CREATURE, 'J', GREEN, "slime creature", M_AMPHIBIOUS, MR_RES_POISON, - 0, 5, MONS_SLIME_CREATURE, MH_NATURAL, -3, + 0, 5, MONS_SLIME_CREATURE, MONS_SLIME_CREATURE, MH_NATURAL, -3, { 22, 0, 0, 0 }, { 11, 3, 5, 0 }, 1, 4, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1062,7 +1062,7 @@ MONS_FREEZING_WRAITH, 'W', LIGHTBLUE, "freezing wraith", M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 10, MONS_FREEZING_WRAITH, MH_UNDEAD, -4, + 0, 10, MONS_WRAITH, MONS_FREEZING_WRAITH, MH_UNDEAD, -4, { 19, 0, 0, 0 }, { 8, 3, 5, 0 }, 12, 10, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -1075,7 +1075,7 @@ MONS_RAKSHASA_FAKE, 'R', YELLOW, "rakshasa", M_EVIL, MR_RES_POISON, - 0, 10, MONS_RAKSHASA_FAKE, MH_NATURAL, 5000, + 0, 10, MONS_RAKSHASA_FAKE, MONS_RAKSHASA_FAKE, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 1, 0, 0, 1 }, 0, 30, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_PLANT, @@ -1087,7 +1087,7 @@ MONS_GREAT_ORB_OF_EYES, 'G', LIGHTGREEN, "great orb of eyes", M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, MR_RES_POISON, - 900, 13, MONS_GREAT_ORB_OF_EYES, MH_NATURAL, 5000, + 900, 13, MONS_GIANT_EYEBALL, MONS_GREAT_ORB_OF_EYES, MH_NATURAL, 5000, { 20, 0, 0, 0 }, { 12, 3, 5, 0 }, 10, 3, 10, 7, MST_GREAT_ORB_OF_EYES, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1099,7 +1099,7 @@ MONS_HELLION, '3', BLACK, "hellion", M_SPELLCASTER | M_ON_FIRE | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, - 0, 11, MONS_HELLION, MH_DEMONIC, -7, + 0, 11, MONS_HELLION, MONS_HELLION, MH_DEMONIC, -7, { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, 5, 10, 13, 7, RED, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_HIGH, @@ -1111,7 +1111,7 @@ MONS_ROTTING_DEVIL, '4', GREEN, "rotting devil", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_ROTTING_DEVIL, MH_DEMONIC, -7, + 0, 10, MONS_ROTTING_DEVIL, MONS_ROTTING_DEVIL, MH_DEMONIC, -7, { 8, 0, 0, 0 }, { 5, 3, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1123,7 +1123,7 @@ MONS_TORMENTOR, '3', YELLOW, "tormentor", M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_FIRE, - 0, 10, MONS_TORMENTOR, MH_DEMONIC, -6, + 0, 10, MONS_TORMENTOR, MONS_TORMENTOR, MH_DEMONIC, -6, { 8, 8, 0, 0 }, { 7, 3, 5, 0 }, 12, 12, 13, 7, MST_TORMENTOR, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -1135,7 +1135,7 @@ MONS_REAPER, '2', LIGHTGREY, "reaper", M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_REAPER, MH_DEMONIC, 5000, + 0, 10, MONS_REAPER, MONS_REAPER, MH_DEMONIC, 5000, { 32, 0, 0, 0 }, { 8, 3, 5, 0 }, 15, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1147,7 +1147,7 @@ MONS_SOUL_EATER, '2', DARKGREY, "soul eater", M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 12, MONS_SOUL_EATER, MH_DEMONIC, -10, + 0, 12, MONS_SOUL_EATER, MONS_SOUL_EATER, MH_DEMONIC, -10, { 25, 0, 0, 0 }, { 11, 3, 5, 0 }, 18, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1159,7 +1159,7 @@ MONS_HAIRY_DEVIL, '4', LIGHTRED, "hairy devil", M_EVIL, MR_RES_POISON, - 0, 10, MONS_HAIRY_DEVIL, MH_DEMONIC, -4, + 0, 10, MONS_HAIRY_DEVIL, MONS_HAIRY_DEVIL, MH_DEMONIC, -4, { 9, 9, 0, 0 }, { 6, 3, 5, 0 }, 7, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -1171,7 +1171,7 @@ MONS_ICE_DEVIL, '2', WHITE, "ice devil", M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 11, MONS_ICE_DEVIL, MH_DEMONIC, -6, + 0, 11, MONS_ICE_DEVIL, MONS_ICE_DEVIL, MH_DEMONIC, -6, { 16, 0, 0, 0 }, { 11, 3, 5, 0 }, 12, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1183,7 +1183,7 @@ MONS_BLUE_DEVIL, '3', BLUE, "blue devil", M_FLIES | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 10, MONS_BLUE_DEVIL, MH_DEMONIC, -5, + 0, 10, MONS_BLUE_DEVIL, MONS_BLUE_DEVIL, MH_DEMONIC, -5, { 21, 0, 0, 0 }, { 7, 3, 5, 0 }, 14, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1196,7 +1196,7 @@ MONS_BEAST, '4', BROWN, "beast", M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_BEAST, MH_DEMONIC, -3, + 0, 10, MONS_BEAST, MONS_BEAST, MH_DEMONIC, -3, { 12, 0, 0, 0 }, { 5, 3, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_NORMAL, @@ -1208,7 +1208,7 @@ MONS_IRON_DEVIL, '3', CYAN, "iron devil", M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, - 0, 10, MONS_IRON_DEVIL, MH_DEMONIC, -6, + 0, 10, MONS_IRON_DEVIL, MONS_IRON_DEVIL, MH_DEMONIC, -6, { 14, 14, 0, 0 }, { 8, 3, 5, 0 }, 16, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREECH, I_HIGH, @@ -1220,7 +1220,7 @@ MONS_GLOWING_SHAPESHIFTER, '@', RED, "glowing shapeshifter", M_NO_FLAGS, MR_NO_FLAGS, - 600, 10, MONS_SHAPESHIFTER, MH_NATURAL, -6, + 600, 10, MONS_SHAPESHIFTER, MONS_GLOWING_SHAPESHIFTER, MH_NATURAL, -6, { 15, 0, 0, 0 }, { 10, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1232,7 +1232,7 @@ MONS_SHAPESHIFTER, '@', LIGHTRED, "shapeshifter", M_NO_FLAGS, MR_NO_FLAGS, - 600, 10, MONS_SHAPESHIFTER, MH_NATURAL, -6, + 600, 10, MONS_SHAPESHIFTER, MONS_SHAPESHIFTER, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1244,7 +1244,7 @@ MONS_GIANT_MITE, 's', LIGHTRED, "giant mite", M_NO_FLAGS, MR_VUL_POISON, - 350, 10, MONS_GIANT_MITE, MH_NATURAL, -1, + 350, 10, MONS_GIANT_MITE, MONS_GIANT_MITE, MH_NATURAL, -1, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 1, 7, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -1253,10 +1253,10 @@ , { - MONS_STEAM_DRAGON, 'd', LIGHTGREY, "steam dragon", + MONS_STEAM_DRAGON, 'D', LIGHTGREY, "steam dragon", M_SPELLCASTER | M_FLIES, MR_NO_FLAGS, - 1000, 10, MONS_STEAM_DRAGON, MH_NATURAL, -3, + 1000, 10, MONS_DRAGON, MONS_STEAM_DRAGON, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 4, 5, 5, 0 }, 5, 10, 10, 7, MST_STEAM_DRAGON, CE_CLEAN, Z_BIG, S_SILENT, I_ANIMAL_LIKE, @@ -1268,7 +1268,7 @@ MONS_VERY_UGLY_THING, 'u', RED, "very ugly thing", M_WARM_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 750, 10, MONS_VERY_UGLY_THING, MH_NATURAL, -3, + 750, 10, MONS_UGLY_THING, MONS_VERY_UGLY_THING, MH_NATURAL, -3, { 17, 0, 0, 0 }, { 12, 3, 5, 0 }, 4, 8, 8, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_BIG, S_SHOUT, I_NORMAL, @@ -1280,7 +1280,7 @@ MONS_ORC_SORCERER, 'o', DARKGREY, "orc sorcerer", M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_RES_FIRE, - 600, 12, MONS_ORC, MH_NATURAL, -3, + 600, 12, MONS_ORC, MONS_ORC, MH_NATURAL, -3, { 7, 0, 0, 0 }, { 8, 2, 3, 0 }, 5, 12, 10, 7, MST_ORC_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -1292,7 +1292,7 @@ MONS_HIPPOGRIFF, 'H', BROWN, "hippogriff", M_FLIES | M_WARM_BLOOD, MR_NO_FLAGS, - 1000, 10, MONS_HIPPOGRIFF, MH_NATURAL, -3, + 1000, 10, MONS_HIPPOGRIFF, MONS_HIPPOGRIFF, MH_NATURAL, -3, { 10, 8, 8, 0 }, { 7, 3, 5, 0 }, 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL, @@ -1304,7 +1304,7 @@ MONS_GRIFFON, 'H', YELLOW, "griffon", M_FLIES | M_WARM_BLOOD, MR_NO_FLAGS, - 1800, 10, MONS_GRIFFON, MH_NATURAL, -3, + 1800, 10, MONS_GRIFFON, MONS_GRIFFON, MH_NATURAL, -3, { 18, 10, 10, 0 }, { 12, 3, 5, 0 }, 4, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL, @@ -1316,7 +1316,7 @@ MONS_HYDRA, 'D', LIGHTGREEN, "hydra", M_AMPHIBIOUS, // because it likes the swamp -- bwr MR_RES_POISON, - 1800, 11, MONS_HYDRA, MH_NATURAL, -3, + 1800, 11, MONS_HYDRA, MONS_HYDRA, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 13, 3, 5, 0 }, 0, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_REPTILE, @@ -1329,7 +1329,7 @@ MONS_SKELETON_SMALL, 'z', LIGHTGREY, "", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_SKELETON_SMALL, MH_UNDEAD, -1, + 0, 10, MONS_SKELETON_SMALL, MONS_SKELETON_SMALL, MH_UNDEAD, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1342,7 +1342,7 @@ MONS_SKELETON_LARGE, 'Z', LIGHTGREY, "", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_SKELETON_LARGE, MH_UNDEAD, -1, + 0, 10, MONS_SKELETON_SMALL, MONS_SKELETON_LARGE, MH_UNDEAD, -1, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1355,7 +1355,7 @@ MONS_HELL_KNIGHT, '@', RED, "hell knight", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_RES_FIRE, - 550, 10, MONS_HUMAN, MH_NATURAL, -3, + 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 10, 3, 6, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -1367,7 +1367,7 @@ MONS_NECROMANCER, '@', DARKGREY, "necromancer", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 550, 10, MONS_HUMAN, MH_NATURAL, -4, + 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 10, 2, 4, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -1379,7 +1379,7 @@ MONS_WIZARD, '@', MAGENTA, "wizard", M_SPELLCASTER | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_ELEC, - 550, 10, MONS_HUMAN, MH_NATURAL, -4, + 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 10, 2, 4, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -1391,7 +1391,7 @@ MONS_ORC_PRIEST, 'o', LIGHTGREEN, "orc priest", M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 600, 10, MONS_ORC, MH_NATURAL, -4, + 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 3, 3, 4, 0 }, 1, 10, 10, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -1403,7 +1403,7 @@ MONS_ORC_HIGH_PRIEST, 'o', GREEN, "orc high priest", M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_EVIL, MR_RES_HELLFIRE, - 600, 10, MONS_ORC, MH_NATURAL, -4, + 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -4, { 7, 0, 0, 0 }, { 11, 3, 4, 0 }, 1, 12, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -1420,7 +1420,7 @@ MONS_HUMAN, '@', LIGHTGRAY, "human", M_WARM_BLOOD, MR_NO_FLAGS, - 550, 10, MONS_HUMAN, MH_NATURAL, -3, + 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 1, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -1432,7 +1432,7 @@ MONS_GNOLL, 'g', YELLOW, "gnoll", M_WARM_BLOOD, MR_NO_FLAGS, - 750, 10, MONS_GNOLL, MH_NATURAL, -3, + 750, 10, MONS_GNOLL, MONS_GNOLL, MH_NATURAL, -3, { 9, 0, 0, 0 }, { 2, 4, 5, 0 }, 2, 9, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -1444,7 +1444,7 @@ MONS_CLAY_GOLEM, '8', BROWN, "clay golem", M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_CLAY_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_CLAY_GOLEM, MH_NONLIVING, 5000, { 11, 11, 0, 0 }, { 8, 7, 3, 0 }, 7, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1456,7 +1456,7 @@ MONS_WOOD_GOLEM, '8', YELLOW, "wood golem", M_NO_FLAGS, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_WOOD_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_WOOD_GOLEM, MH_NONLIVING, 5000, { 10, 0, 0, 0 }, { 6, 6, 3, 0 }, 5, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1468,7 +1468,7 @@ MONS_STONE_GOLEM, '8', LIGHTGREY, "stone golem", M_NO_FLAGS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_STONE_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_STONE_GOLEM, MH_NONLIVING, 5000, { 28, 0, 0, 0 }, { 12, 7, 4, 0 }, 12, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1480,7 +1480,7 @@ MONS_IRON_GOLEM, '8', CYAN, "iron golem", M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_IRON_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_IRON_GOLEM, MH_NONLIVING, 5000, { 35, 0, 0, 0 }, { 15, 7, 4, 0 }, 15, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1492,7 +1492,7 @@ MONS_CRYSTAL_GOLEM, '8', WHITE, "crystal golem", M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_CRYSTAL_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_CRYSTAL_GOLEM, MH_NONLIVING, 5000, { 40, 0, 0, 0 }, { 13, 7, 4, 0 }, 22, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1504,7 +1504,7 @@ MONS_TOENAIL_GOLEM, '8', LIGHTGREY, "toenail golem", M_NO_FLAGS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_TOENAIL_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_TOENAIL_GOLEM, MH_NONLIVING, 5000, { 13, 0, 0, 0 }, { 9, 5, 3, 0 }, 8, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1513,10 +1513,10 @@ , { - MONS_MOTTLED_DRAGON, 'd', LIGHTMAGENTA, "mottled dragon", + MONS_MOTTLED_DRAGON, 'D', RED, "mottled dragon", M_SPELLCASTER | M_FLIES, MR_RES_POISON | MR_RES_FIRE, - 1100, 10, MONS_MOTTLED_DRAGON, MH_NATURAL, -3, + 1100, 10, MONS_DRAGON, MONS_MOTTLED_DRAGON, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 5, 3, 5, 0 }, 5, 10, 10, 7, MST_MOTTLED_DRAGON, CE_POISONOUS, Z_BIG, S_SILENT, I_ANIMAL_LIKE, @@ -1528,7 +1528,7 @@ MONS_EARTH_ELEMENTAL, '#', BROWN, "earth elemental", M_NO_FLAGS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_EARTH_ELEMENTAL, MH_NONLIVING, 5000, + 0, 10, MONS_EARTH_ELEMENTAL, MONS_EARTH_ELEMENTAL, MH_NONLIVING, 5000, { 40, 0, 0, 0 }, { 6, 5, 5, 0 }, 14, 4, 6, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1540,7 +1540,7 @@ MONS_FIRE_ELEMENTAL, '#', YELLOW, "fire elemental", M_FLIES, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD | MR_RES_ELEC, - 0, 10, MONS_FIRE_ELEMENTAL, MH_NONLIVING, 5000, + 0, 10, MONS_EARTH_ELEMENTAL, MONS_FIRE_ELEMENTAL, MH_NONLIVING, 5000, { 5, 0, 0, 0 }, { 6, 3, 5, 0 }, 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1552,7 +1552,7 @@ MONS_AIR_ELEMENTAL, 'v', LIGHTGREY, "air elemental", M_LEVITATE | M_SEE_INVIS | M_FLIES, MR_RES_ELEC | MR_RES_POISON, - 0, 5, MONS_AIR_ELEMENTAL, MH_NONLIVING, 5000, + 0, 5, MONS_EARTH_ELEMENTAL, MONS_AIR_ELEMENTAL, MH_NONLIVING, 5000, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 2, 18, 25, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1566,7 +1566,7 @@ MONS_ICE_FIEND, '1', WHITE, "Ice Fiend", M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_FROZEN | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 10, MONS_ICE_FIEND, MH_DEMONIC, -12, + 0, 10, MONS_FIEND, MONS_ICE_FIEND, MH_DEMONIC, -12, { 25, 25, 0, 0 }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_ICE_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -1578,7 +1578,7 @@ MONS_SHADOW_FIEND, '1', DARKGREY, "Shadow Fiend", M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_SHADOW_FIEND, MH_DEMONIC, -13, + 0, 10, MONS_FIEND, MONS_SHADOW_FIEND, MH_DEMONIC, -13, { 25, 15, 15, 0 }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_SHADOW_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -1590,7 +1590,7 @@ MONS_BROWN_SNAKE, 'S', BROWN, "brown snake", M_COLD_BLOOD | M_AMPHIBIOUS, MR_RES_POISON, - 300, 10, MONS_BROWN_SNAKE, MH_NATURAL, -3, + 300, 10, MONS_SNAKE, MONS_BROWN_SNAKE, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, 2, 15, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, @@ -1602,7 +1602,7 @@ MONS_GIANT_LIZARD, 'l', GREEN, "giant lizard", M_COLD_BLOOD, MR_NO_FLAGS, - 600, 10, MONS_GIANT_LIZARD, MH_NATURAL, -3, + 600, 10, MONS_GIANT_LIZARD, MONS_GIANT_LIZARD, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, @@ -1614,7 +1614,7 @@ MONS_SPECTRAL_WARRIOR, 'W', LIGHTGREEN, "spectral warrior", M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 13, MONS_SPECTRAL_WARRIOR, MH_UNDEAD, -6, + 0, 13, MONS_WRAITH, MONS_SPECTRAL_WARRIOR, MH_UNDEAD, -6, { 18, 0, 0, 0 }, { 9, 3, 5, 0 }, 12, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -1626,7 +1626,7 @@ MONS_PULSATING_LUMP, 'J', RED, "pulsating lump", M_SEE_INVIS, MR_RES_POISON, - 0, 3, MONS_PULSATING_LUMP, MH_NATURAL, -3, + 0, 3, MONS_JELLY, MONS_PULSATING_LUMP, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 10, 3, 5, 0 }, 2, 6, 5, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1638,7 +1638,7 @@ MONS_STORM_DRAGON, 'D', LIGHTBLUE, "storm dragon", M_SPELLCASTER | M_FLIES, MR_RES_ELEC | MR_RES_COLD, - 2800, 12, MONS_STORM_DRAGON, MH_NATURAL, -5, + 2800, 12, MONS_DRAGON, MONS_STORM_DRAGON, MH_NATURAL, -5, { 25, 15, 15, 0 }, { 14, 5, 5, 0 }, 13, 10, 12, 7, MST_STORM_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_NORMAL, @@ -1650,7 +1650,7 @@ MONS_YAKTAUR, 'c', LIGHTRED, "yaktaur", M_WARM_BLOOD, MR_NO_FLAGS, - 2000, 10, MONS_YAKTAUR, MH_NATURAL, -3, + 2000, 10, MONS_YAKTAUR, MONS_YAKTAUR, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 8, 3, 5, 0 }, 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, @@ -1662,7 +1662,7 @@ MONS_DEATH_YAK, 'Y', DARKGREY, "death yak", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 1500, 10, MONS_DEATH_YAK, MH_NATURAL, -5, + 1500, 10, MONS_YAK, MONS_DEATH_YAK, MH_NATURAL, -5, { 30, 0, 0, 0 }, { 14, 3, 5, 0 }, 9, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_BELLOW, I_ANIMAL, @@ -1674,7 +1674,7 @@ MONS_ROCK_TROLL, 'T', LIGHTGREY, "rock troll", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 2200, 11, MONS_ROCK_TROLL, MH_NATURAL, -4, + 2200, 11, MONS_TROLL, MONS_ROCK_TROLL, MH_NATURAL, -4, { 30, 20, 20, 0 }, { 11, 3, 5, 0 }, 13, 6, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -1686,7 +1686,7 @@ MONS_STONE_GIANT, 'C', LIGHTGREY, "stone giant", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 3000, 10, MONS_STONE_GIANT, MH_NATURAL, -4, + 3000, 10, MONS_HILL_GIANT, MONS_STONE_GIANT, MH_NATURAL, -4, { 45, 0, 0, 0 }, { 16, 3, 5, 0 }, 12, 2, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -1698,7 +1698,7 @@ MONS_FLAYED_GHOST, 'p', RED, "flayed ghost", M_FLIES | M_EVIL, MR_RES_POISON, - 0, 10, MONS_FLAYED_GHOST, MH_UNDEAD, -4, + 0, 10, MONS_PHANTOM, MONS_FLAYED_GHOST, MH_UNDEAD, -4, { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, 0, 14, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1710,7 +1710,7 @@ MONS_BUMBLEBEE, 'k', RED, "bumblebee", M_FLIES, MR_VUL_POISON, - 300, 10, MONS_BUMBLEBEE, MH_NATURAL, -3, + 300, 10, MONS_KILLER_BEE, MONS_BUMBLEBEE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, 4, 15, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT, @@ -1722,7 +1722,7 @@ MONS_REDBACK, 's', RED, "redback", M_NO_FLAGS, MR_VUL_POISON, - 1000, 14, MONS_REDBACK, MH_NATURAL, -3, + 1000, 14, MONS_WOLF_SPIDER, MONS_REDBACK, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 6, 3, 5, 0 }, 2, 12, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -1732,9 +1732,9 @@ { MONS_INSUBSTANTIAL_WISP, 'p', LIGHTGREY, "insubstantial wisp", - M_LEVITATE, + M_LEVITATE | M_SPECIAL_ABILITY, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 0, 17, MONS_INSUBSTANTIAL_WISP, MH_NONLIVING, 5000, + 0, 17, MONS_INSUBSTANTIAL_WISP, MONS_INSUBSTANTIAL_WISP, MH_NONLIVING, 5000, { 12, 0, 0, 0 }, { 6, 1, 2, 0 }, 20, 20, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_PLANT, @@ -1746,7 +1746,7 @@ MONS_VAPOUR, '#', LIGHTGREY, "vapour", M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_INVIS | M_CONFUSED, MR_RES_ELEC | MR_RES_POISON, - 0, 21, MONS_VAPOUR, MH_NONLIVING, 5000, + 0, 21, MONS_VAPOUR, MONS_VAPOUR, MH_NONLIVING, 5000, { 0, 0, 0, 0 }, { 12, 2, 3, 0 }, 0, 12, 10, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1758,7 +1758,7 @@ MONS_OGRE_MAGE, 'O', MAGENTA, "ogre-mage", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_EVIL, MR_RES_ELEC, - 0, 16, MONS_OGRE, MH_NATURAL, -6, + 0, 16, MONS_OGRE, MONS_OGRE, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 10, 3, 5, 0 }, 1, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_HIGH, @@ -1770,7 +1770,7 @@ MONS_SPINY_WORM, 'w', DARKGREY, "spiny worm", M_NO_FLAGS, MR_VUL_POISON, - 1300, 13, MONS_SPINY_WORM, MH_NATURAL, -3, + 1300, 13, MONS_WORM, MONS_SPINY_WORM, MH_NATURAL, -3, { 32, 0, 0, 0 }, { 12, 3, 5, 0 }, 10, 6, 9, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_PLANT, @@ -1784,7 +1784,7 @@ MONS_DANCING_WEAPON, '(', BLACK, "dancing weapon", M_LEVITATE, MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_DANCING_WEAPON, MH_NONLIVING, 5000, + 0, 10, MONS_DANCING_WEAPON, MONS_DANCING_WEAPON, MH_NONLIVING, 5000, { 30, 0, 0, 0 }, { 15, 0, 0, 15 }, 10, 20, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -1796,7 +1796,7 @@ MONS_TITAN, 'C', MAGENTA, "titan", M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_RES_ELEC, - 3500, 12, MONS_TITAN, MH_NATURAL, -7, + 3500, 12, MONS_HILL_GIANT, MONS_TITAN, MH_NATURAL, -7, { 55, 0, 0, 0 }, { 20, 3, 5, 0 }, 10, 3, 10, 7, MST_TITAN, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, @@ -1808,7 +1808,7 @@ MONS_GOLDEN_DRAGON, 'D', YELLOW, "golden dragon", M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 3000, 17, MONS_GOLDEN_DRAGON, MH_NATURAL, -8, + 3000, 17, MONS_DRAGON, MONS_GOLDEN_DRAGON, MH_NATURAL, -8, { 40, 20, 20, 0 }, { 18, 4, 4, 0 }, 15, 7, 10, 7, MST_GOLDEN_DRAGON, CE_POISONOUS, Z_BIG, S_ROAR, I_HIGH, @@ -1822,7 +1822,7 @@ MONS_ELF, 'e', DARKGREY, "elf", M_WARM_BLOOD, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -3, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 3, 3, 3, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_PLANT, @@ -1836,9 +1836,9 @@ // more intuitively know that this isn't a regular lizard. -- bwr { MONS_LINDWURM, 'd', LIGHTGREEN, "lindwurm", - M_NO_FLAGS, + M_SPECIAL_ABILITY, MR_NO_FLAGS, - 1000, 11, MONS_LINDWURM, MH_NATURAL, -3, + 1000, 11, MONS_DRAGON, MONS_LINDWURM, MH_NATURAL, -3, { 20, 10, 10, 0 }, { 9, 3, 5, 0 }, 8, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_ROAR, I_REPTILE, @@ -1850,7 +1850,7 @@ MONS_ELEPHANT_SLUG, 'm', LIGHTGREY, "elephant slug", M_NO_SKELETON, MR_VUL_POISON, - 1500, 10, MONS_ELEPHANT_SLUG, MH_NATURAL, -3, + 1500, 10, MONS_GIANT_SLUG, MONS_ELEPHANT_SLUG, MH_NATURAL, -3, { 40, 0, 0, 0 }, { 20, 5, 3, 0 }, 2, 1, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -1862,7 +1862,7 @@ MONS_WAR_DOG, 'h', CYAN, "war dog", M_SEE_INVIS | M_WARM_BLOOD, MR_NO_FLAGS, - 350, 10, MONS_WAR_DOG, MH_NATURAL, -3, + 350, 10, MONS_HOUND, MONS_WAR_DOG, MH_NATURAL, -3, { 12, 0, 0, 0 }, { 4, 3, 5, 0 }, 4, 15, 17, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, @@ -1874,7 +1874,7 @@ MONS_GREY_RAT, 'r', LIGHTGREY, "grey rat", M_WARM_BLOOD, MR_NO_FLAGS, - 250, 10, MONS_GREY_RAT, MH_NATURAL, -3, + 250, 10, MONS_RAT, MONS_GREY_RAT, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 1, 3, 6, 0 }, 2, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL, @@ -1886,7 +1886,7 @@ MONS_GREEN_RAT, 'r', LIGHTGREEN, "green rat", M_WARM_BLOOD, MR_NO_FLAGS, - 250, 10, MONS_GREEN_RAT, MH_NATURAL, -3, + 250, 10, MONS_RAT, MONS_GREEN_RAT, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 2, 3, 5, 0 }, 5, 11, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_ANIMAL, @@ -1898,7 +1898,7 @@ MONS_ORANGE_RAT, 'r', LIGHTRED, "orange rat", M_WARM_BLOOD, MR_NO_FLAGS, - 250, 10, MONS_ORANGE_RAT, MH_NATURAL, -3, + 250, 10, MONS_RAT, MONS_ORANGE_RAT, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 3, 3, 5, 0 }, 7, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_ANIMAL, @@ -1910,7 +1910,7 @@ MONS_BLACK_SNAKE, 'S', DARKGREY, "black snake", M_COLD_BLOOD, MR_RES_POISON, - 500, 12, MONS_BLACK_SNAKE, MH_NATURAL, -3, + 500, 12, MONS_SNAKE, MONS_BLACK_SNAKE, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, 4, 15, 18, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, @@ -1922,7 +1922,7 @@ MONS_SHEEP, 'Y', LIGHTGREY, "sheep", M_WARM_BLOOD, MR_NO_FLAGS, - 1200, 10, MONS_SHEEP, MH_NATURAL, -3, + 1200, 10, MONS_SHEEP, MONS_SHEEP, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BELLOW, I_ANIMAL, @@ -1934,7 +1934,7 @@ MONS_GHOUL, 'n', RED, "ghoul", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 500, 12, MONS_GHOUL, MH_UNDEAD, -5, + 500, 12, MONS_GHOUL, MONS_GHOUL, MH_UNDEAD, -5, { 9, 0, 0, 0 }, { 4, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -1946,7 +1946,7 @@ MONS_HOG, 'h', LIGHTRED, "hog", M_WARM_BLOOD, MR_NO_FLAGS, - 700, 10, MONS_HOG, MH_NATURAL, -3, + 700, 10, MONS_HOG, MONS_HOG, MH_NATURAL, -3, { 14, 0, 0, 0 }, { 6, 3, 5, 0 }, 2, 9, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, @@ -1958,7 +1958,7 @@ MONS_GIANT_MOSQUITO, 'y', DARKGREY, "giant mosquito", M_FLIES, MR_VUL_POISON, - 100, 10, MONS_GIANT_MOSQUITO, MH_NATURAL, -3, + 100, 10, MONS_GIANT_MOSQUITO, MONS_GIANT_MOSQUITO, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 1, 3, 5, 0 }, 0, 13, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_WHINE, I_PLANT, @@ -1970,7 +1970,7 @@ MONS_GIANT_CENTIPEDE, 's', GREEN, "giant centipede", M_NO_FLAGS, MR_VUL_POISON, - 350, 10, MONS_GIANT_CENTIPEDE, MH_NATURAL, -3, + 350, 10, MONS_GIANT_CENTIPEDE, MONS_GIANT_CENTIPEDE, MH_NATURAL, -3, { 2, 0, 0, 0 }, { 2, 3, 3, 0 }, 2, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -1984,7 +1984,7 @@ MONS_IRON_TROLL, 'T', CYAN, "iron troll", M_WARM_BLOOD | M_EVIL, MR_RES_FIRE | MR_RES_COLD, - 2400, 10, MONS_IRON_TROLL, MH_NATURAL, -5, + 2400, 10, MONS_TROLL, MONS_IRON_TROLL, MH_NATURAL, -5, { 35, 25, 25, 0 }, { 16, 3, 5, 0 }, 20, 4, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_ROAR, I_NORMAL, @@ -1996,8 +1996,8 @@ MONS_NAGA, 'N', GREEN, "naga", M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, - 750, 10, MONS_NAGA, MH_NATURAL, -6, - { 6, 0, 0, 0 }, + 750, 10, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6, + { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, 6, 10, 8, 7, MST_NAGA, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR @@ -2008,7 +2008,7 @@ MONS_FIRE_GIANT, 'C', RED, "fire giant", M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_RES_FIRE, - 2400, 11, MONS_FIRE_GIANT, MH_NATURAL, -4, + 2400, 11, MONS_HILL_GIANT, MONS_FIRE_GIANT, MH_NATURAL, -4, { 30, 0, 0, 0 }, { 16, 3, 6, 0 }, 8, 4, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -2020,7 +2020,7 @@ MONS_FROST_GIANT, 'C', LIGHTBLUE, "frost giant", M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_RES_COLD, - 2600, 11, MONS_FROST_GIANT, MH_NATURAL, -4, + 2600, 11, MONS_HILL_GIANT, MONS_FROST_GIANT, MH_NATURAL, -4, { 35, 0, 0, 0 }, { 16, 4, 5, 0 }, 9, 3, 10, 7, MST_FROST_GIANT, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -2029,10 +2029,10 @@ , { - MONS_FIREDRAKE, 'd', RED, "firedrake", - M_FLIES, + MONS_FIREDRAKE, 'l', RED, "firedrake", + M_FLIES | M_SPECIAL_ABILITY, MR_RES_FIRE, - 900, 10, MONS_FIREDRAKE, MH_NATURAL, -3, + 900, 10, MONS_FIREDRAKE, MONS_FIREDRAKE, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 6, 3, 5, 0 }, 3, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL, @@ -2044,7 +2044,7 @@ MONS_SHADOW_DRAGON, 'D', DARKGREY, "shadow dragon", M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_RES_POISON | MR_RES_COLD, - 2000, 12, MONS_SHADOW_DRAGON, MH_NATURAL, -5, + 2000, 12, MONS_DRAGON, MONS_SHADOW_DRAGON, MH_NATURAL, -5, { 20, 15, 15, 0 }, { 17, 5, 5, 0 }, 15, 10, 10, 7, MST_SHADOW_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_HIGH, @@ -2055,7 +2055,7 @@ MONS_YELLOW_SNAKE, 'S', YELLOW, "yellow snake", M_COLD_BLOOD, MR_RES_POISON, - 400, 10, MONS_YELLOW_SNAKE, MH_NATURAL, -3, + 400, 10, MONS_SNAKE, MONS_YELLOW_SNAKE, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 4, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, @@ -2067,7 +2067,7 @@ MONS_GREY_SNAKE, 'S', LIGHTGREY, "grey snake", M_COLD_BLOOD, MR_NO_FLAGS, - 600, 10, MONS_GREY_SNAKE, MH_NATURAL, -3, + 600, 10, MONS_SNAKE, MONS_GREY_SNAKE, MH_NATURAL, -3, { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, 4, 16, 18, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE, @@ -2079,7 +2079,7 @@ MONS_DEEP_TROLL, 'T', DARKGREY, "deep troll", M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 1500, 12, MONS_DEEP_TROLL, MH_NATURAL, -3, + 1500, 12, MONS_TROLL, MONS_DEEP_TROLL, MH_NATURAL, -3, { 27, 20, 20, 0 }, { 10, 3, 5, 0 }, 6, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -2091,7 +2091,7 @@ MONS_GIANT_BLOWFLY, 'y', LIGHTGREY, "giant blowfly", M_FLIES, MR_VUL_POISON, - 200, 10, MONS_GIANT_BLOWFLY, MH_NATURAL, -3, + 200, 10, MONS_GIANT_BLOWFLY, MONS_GIANT_BLOWFLY, MH_NATURAL, -3, { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, 2, 15, 19, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_PLANT, @@ -2103,7 +2103,7 @@ MONS_RED_WASP, 'y', RED, "red wasp", M_FLIES, MR_VUL_POISON, - 400, 14, MONS_RED_WASP, MH_NATURAL, -3, + 400, 14, MONS_YELLOW_WASP, MONS_RED_WASP, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 8, 3, 5, 0 }, 7, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_BUZZ, I_PLANT, @@ -2115,8 +2115,8 @@ MONS_SWAMP_DRAGON, 'D', BROWN, "swamp dragon", M_SPELLCASTER | M_FLIES, MR_RES_POISON, - 1900, 11, MONS_SWAMP_DRAGON, MH_NATURAL, -3, - { 13, 9, 9, 0 }, + 1900, 11, MONS_DRAGON, MONS_SWAMP_DRAGON, MH_NATURAL, -3, + { 18, 9, 9, 0 }, { 9, 5, 5, 0 }, 7, 7, 10, 7, MST_SWAMP_DRAGON, CE_CONTAMINATED, Z_BIG, S_ROAR, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS @@ -2124,11 +2124,11 @@ , { - MONS_SWAMP_DRAKE, 'd', BROWN, "swamp drake", + MONS_SWAMP_DRAKE, 'l', BROWN, "swamp drake", M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON, - 900, 11, MONS_SWAMP_DRAKE, MH_NATURAL, -3, - { 11, 0, 0, 0 }, + 900, 11, MONS_DRAGON, MONS_SWAMP_DRAKE, MH_NATURAL, -3, + { 14, 0, 0, 0 }, { 4, 5, 5, 0 }, 3, 11, 11, 7, MST_SWAMP_DRAKE, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS @@ -2136,10 +2136,22 @@ , { + MONS_DEATH_DRAKE, 'l', DARKGREY, "death drake", + M_SPELLCASTER | M_FLIES | M_EVIL, + MR_RES_POISON, + 900, 11, MONS_DRAGON, MONS_DEATH_DRAKE, MH_NATURAL, 3, + { 12, 0, 0, 0 }, + { 9, 5, 7, 0 }, + 6, 14, 13, 10, MST_DEATH_DRAKE, CE_HCL, Z_BIG, S_ROAR, I_ANIMAL_LIKE, + MONUSE_OPEN_DOORS +} +, + +{ MONS_SOLDIER_ANT, 'a', LIGHTGREY, "soldier ant", M_NO_FLAGS, MR_VUL_POISON, - 900, 10, MONS_SOLDIER_ANT, MH_NATURAL, -3, + 900, 10, MONS_GIANT_ANT, MONS_SOLDIER_ANT, MH_NATURAL, -3, { 14, 0, 0, 0 }, { 6, 3, 5, 0 }, 8, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -2151,7 +2163,7 @@ MONS_HILL_GIANT, 'C', LIGHTRED, "hill giant", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 1600, 10, MONS_HILL_GIANT, MH_NATURAL, -3, + 1600, 10, MONS_HILL_GIANT, MONS_HILL_GIANT, MH_NATURAL, -3, { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, @@ -2163,7 +2175,7 @@ MONS_QUEEN_ANT, 'Q', DARKGREY, "queen ant", M_NO_FLAGS, MR_VUL_POISON, - 1200, 10, MONS_QUEEN_ANT, MH_NATURAL, -3, + 1200, 10, MONS_GIANT_ANT, MONS_QUEEN_ANT, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 13, 3, 5, 0 }, 14, 3, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -2175,7 +2187,7 @@ MONS_ANT_LARVA, 'w', LIGHTGREY, "ant larva", M_NO_SKELETON, MR_VUL_POISON, - 350, 5, MONS_ANT_LARVA, MH_NATURAL, -3, + 350, 5, MONS_GIANT_ANT, MONS_ANT_LARVA, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 2, 6, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, @@ -2188,7 +2200,7 @@ MONS_GIANT_FROG, 'F', GREEN, "giant frog", M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 500, 10, MONS_GIANT_FROG, MH_NATURAL, -3, + 500, 10, MONS_GIANT_FROG, MONS_GIANT_FROG, MH_NATURAL, -3, { 9, 0, 0, 0 }, { 4, 3, 5, 0 }, 0, 12, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, @@ -2200,7 +2212,7 @@ MONS_GIANT_BROWN_FROG, 'F', BROWN, "giant brown frog", M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 890, 10, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3, + 890, 10, MONS_GIANT_FROG, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3, { 14, 0, 0, 0 }, { 8, 3, 5, 0 }, 2, 11, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_CROAK, I_ANIMAL, @@ -2212,7 +2224,7 @@ MONS_SPINY_FROG, 'F', YELLOW, "spiny frog", M_COLD_BLOOD | M_AMPHIBIOUS, MR_RES_POISON, - 1000, 10, MONS_SPINY_FROG, MH_NATURAL, -3, + 1000, 10, MONS_GIANT_FROG, MONS_SPINY_FROG, MH_NATURAL, -3, { 26, 0, 0, 0 }, { 7, 3, 5, 0 }, 6, 9, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_CROAK, I_ANIMAL, @@ -2222,9 +2234,9 @@ { MONS_BLINK_FROG, 'F', LIGHTGREEN, "blink frog", - M_COLD_BLOOD | M_AMPHIBIOUS, + M_COLD_BLOOD | M_AMPHIBIOUS | M_SPECIAL_ABILITY, MR_NO_FLAGS, - 800, 12, MONS_BLINK_FROG, MH_NATURAL, -5, + 800, 12, MONS_GIANT_FROG, MONS_BLINK_FROG, MH_NATURAL, -5, { 20, 0, 0, 0 }, { 6, 3, 5, 0 }, 3, 12, 14, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, @@ -2235,7 +2247,7 @@ MONS_GIANT_COCKROACH, 'a', BROWN, "giant cockroach", M_NO_FLAGS, MR_NO_FLAGS, - 250, 10, MONS_GIANT_COCKROACH, MH_NATURAL, -1, + 250, 10, MONS_GIANT_COCKROACH, MONS_GIANT_COCKROACH, MH_NATURAL, -1, { 2, 0, 0, 0 }, { 1, 3, 4, 0 }, 3, 10, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_INSECT, @@ -2246,7 +2258,7 @@ MONS_SMALL_SNAKE, 'S', LIGHTGREEN, "small snake", M_COLD_BLOOD, MR_NO_FLAGS, - 100, 13, MONS_SMALL_SNAKE, MH_NATURAL, -1, + 100, 13, MONS_SNAKE, MONS_SMALL_SNAKE, MH_NATURAL, -1, { 2, 0, 0, 0 }, { 1, 2, 3, 0 }, 0, 11, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, @@ -2258,7 +2270,7 @@ MONS_WHITE_IMP, '5', WHITE, "white imp", M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, MR_RES_COLD, - 0, 10, MONS_WHITE_IMP, MH_DEMONIC, -3, + 0, 10, MONS_IMP, MONS_WHITE_IMP, MH_DEMONIC, -3, { 4, 0, 0, 0 }, { 2, 3, 5, 0 }, 4, 10, 10, 7, MST_WHITE_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2270,7 +2282,7 @@ MONS_LEMURE, '5', YELLOW, "lemure", M_EVIL, MR_RES_POISON, - 0, 10, MONS_LEMURE, MH_DEMONIC, -3, + 0, 10, MONS_LEMURE, MONS_LEMURE, MH_DEMONIC, -3, { 12, 0, 0, 0 }, { 2, 3, 5, 0 }, 1, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL, @@ -2282,7 +2294,7 @@ MONS_UFETUBUS, '5', LIGHTCYAN, "ufetubus", M_EVIL, MR_VUL_FIRE | MR_RES_COLD, - 0, 10, MONS_UFETUBUS, MH_DEMONIC, -3, + 0, 10, MONS_UFETUBUS, MONS_UFETUBUS, MH_DEMONIC, -3, { 5, 5, 0, 0 }, { 1, 4, 6, 0 }, 2, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2294,7 +2306,7 @@ MONS_MANES, '5', LIGHTRED, "manes", M_EVIL, MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, - 0, 10, MONS_MANES, MH_DEMONIC, -3, + 0, 10, MONS_MANES, MONS_MANES, MH_DEMONIC, -3, { 5, 3, 3, 0 }, { 3, 3, 5, 0 }, 2, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2306,7 +2318,7 @@ MONS_MIDGE, '5', LIGHTGREEN, "midge", M_FLIES | M_EVIL, MR_RES_POISON, - 0, 10, MONS_MIDGE, MH_DEMONIC, -3, + 0, 10, MONS_MIDGE, MONS_MIDGE, MH_DEMONIC, -3, { 8, 0, 0, 0 }, { 2, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2318,7 +2330,7 @@ MONS_NEQOXEC, '3', MAGENTA, "neqoxec", M_SPELLCASTER | M_LEVITATE | M_EVIL, MR_RES_POISON, - 0, 12, MONS_NEQOXEC, MH_DEMONIC, -6, + 0, 12, MONS_NEQOXEC, MONS_NEQOXEC, MH_DEMONIC, -6, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 4, 12, 10, 7, MST_NEQOXEC, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2330,7 +2342,7 @@ MONS_ORANGE_DEMON, '3', LIGHTRED, "orange demon", M_EVIL, MR_NO_FLAGS, - 0, 12, MONS_ORANGE_DEMON, MH_DEMONIC, -6, + 0, 12, MONS_ORANGE_DEMON, MONS_ORANGE_DEMON, MH_DEMONIC, -6, { 10, 5, 0, 0 }, { 8, 4, 5, 0 }, 3, 7, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SCREECH, I_NORMAL, @@ -2342,7 +2354,7 @@ MONS_HELLWING, '3', LIGHTGREY, "hellwing", M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON, - 0, 12, MONS_HELLWING, MH_DEMONIC, -6, + 0, 12, MONS_HELLWING, MONS_HELLWING, MH_DEMONIC, -6, { 17, 10, 0, 0 }, { 7, 4, 5, 0 }, 8, 10, 10, 7, MST_HELLWING, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL, @@ -2354,7 +2366,7 @@ MONS_SMOKE_DEMON, '4', LIGHTGREY, "smoke demon", M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_FIRE, - 0, 12, MONS_SMOKE_DEMON, MH_DEMONIC, -6, + 0, 12, MONS_SMOKE_DEMON, MONS_SMOKE_DEMON, MH_DEMONIC, -6, { 8, 5, 5, 0 }, { 7, 3, 5, 0 }, 5, 9, 9, 7, MST_SMOKE_DEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL, @@ -2366,7 +2378,7 @@ MONS_YNOXINUL, '3', CYAN, "ynoxinul", M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD, - 0, 12, MONS_YNOXINUL, MH_DEMONIC, -6, + 0, 12, MONS_YNOXINUL, MONS_YNOXINUL, MH_DEMONIC, -6, { 12, 0, 0, 0 }, { 6, 3, 5, 0 }, 3, 10, 10, 7, MST_YNOXINUL, CE_CONTAMINATED, Z_NOZOMBIE, S_BELLOW, I_NORMAL, @@ -2378,7 +2390,7 @@ MONS_EXECUTIONER, '1', LIGHTGREY, "Executioner", M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, - 0, 14, MONS_EXECUTIONER, MH_DEMONIC, -9, + 0, 14, MONS_EXECUTIONER, MONS_EXECUTIONER, MH_DEMONIC, -9, { 30, 10, 10, 0 }, { 12, 3, 5, 0 }, 10, 15, 20, 7, MST_HELL_KNIGHT_I, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH, @@ -2390,7 +2402,7 @@ MONS_GREEN_DEATH, '1', GREEN, "Green Death", M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON, - 0, 14, MONS_GREEN_DEATH, MH_DEMONIC, -9, + 0, 14, MONS_GREEN_DEATH, MONS_GREEN_DEATH, MH_DEMONIC, -9, { 32, 0, 0, 0 }, { 13, 3, 5, 0 }, 5, 7, 12, 7, MST_GREEN_DEATH, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -2402,7 +2414,7 @@ MONS_BLUE_DEATH, '1', BLUE, "Blue Death", M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 14, MONS_BLUE_DEATH, MH_DEMONIC, -9, + 0, 14, MONS_BLUE_DEATH, MONS_BLUE_DEATH, MH_DEMONIC, -9, { 20, 20, 0, 0 }, { 12, 3, 5, 0 }, 10, 10, 12, 7, MST_BLUE_DEATH, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -2414,7 +2426,7 @@ MONS_BALRUG, '1', RED, "Balrug", M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, - 0, 14, MONS_BALRUG, MH_DEMONIC, -9, + 0, 14, MONS_BALRUG, MONS_BALRUG, MH_DEMONIC, -9, { 25, 0, 0, 0 }, { 14, 3, 5, 0 }, 5, 12, 12, 7, MST_BALRUG, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -2426,7 +2438,7 @@ MONS_CACODEMON, '1', YELLOW, "Cacodemon", M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_ELEC, - 0, 14, MONS_CACODEMON, MH_DEMONIC, -9, + 0, 14, MONS_CACODEMON, MONS_CACODEMON, MH_DEMONIC, -9, { 22, 0, 0, 0 }, { 13, 3, 5, 0 }, 11, 10, 10, 7, MST_CACODEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -2439,7 +2451,7 @@ MONS_DEMONIC_CRAWLER, '3', DARKGREY, "demonic crawler", M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE, - 0, 12, MONS_DEMONIC_CRAWLER, MH_DEMONIC, -6, + 0, 12, MONS_DEMONIC_CRAWLER, MONS_DEMONIC_CRAWLER, MH_DEMONIC, -6, { 13, 13, 13, 13 }, { 9, 3, 5, 0 }, 10, 6, 9, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_NORMAL, @@ -2451,7 +2463,7 @@ MONS_SUN_DEMON, '2', YELLOW, "sun demon", M_SEE_INVIS | M_LEVITATE | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_VUL_COLD | MR_RES_HELLFIRE, - 0, 14, MONS_SUN_DEMON, MH_DEMONIC, -6, + 0, 14, MONS_SUN_DEMON, MONS_SUN_DEMON, MH_DEMONIC, -6, { 30, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2463,7 +2475,7 @@ MONS_SHADOW_IMP, '5', DARKGREY, "shadow imp", M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, MR_RES_COLD | MR_RES_POISON, - 0, 11, MONS_SHADOW_IMP, MH_DEMONIC, -3, + 0, 11, MONS_IMP, MONS_SHADOW_IMP, MH_DEMONIC, -3, { 6, 0, 0, 0 }, { 2, 3, 5, 0 }, 3, 11, 10, 7, MST_SHADOW_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2475,7 +2487,7 @@ MONS_SHADOW_DEMON, '3', DARKGREY, "shadow demon", M_SEE_INVIS | M_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 12, MONS_SHADOW_DEMON, MH_DEMONIC, -7, + 0, 12, MONS_SHADOW_DEMON, MONS_SHADOW_DEMON, MH_DEMONIC, -7, { 21, 0, 0, 0 }, { 6, 3, 5, 0 }, 7, 12, 11, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_CROAK, I_HIGH, @@ -2487,7 +2499,7 @@ MONS_LOROCYPROCA, '2', BLUE, "Lorocyproca", M_SEE_INVIS | M_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC, - 0, 12, MONS_LOROCYPROCA, MH_DEMONIC, -7, + 0, 12, MONS_LOROCYPROCA, MONS_LOROCYPROCA, MH_DEMONIC, -7, { 25, 25, 0, 0 }, { 12, 3, 5, 0 }, 10, 12, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, @@ -2499,7 +2511,7 @@ MONS_SHADOW_WRAITH, 'W', BLUE, "shadow wraith", M_LEVITATE | M_SEE_INVIS | M_INVIS | M_EVIL, MR_RES_POISON, - 0, 15, MONS_SHADOW_WRAITH, MH_UNDEAD, -8, + 0, 15, MONS_WRAITH, MONS_SHADOW_WRAITH, MH_UNDEAD, -8, { 20, 0, 0, 0 }, { 10, 3, 5, 0 }, 7, 7, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH, @@ -2511,7 +2523,7 @@ MONS_GIANT_AMOEBA, 'J', BLUE, "giant amoeba", M_NO_SKELETON | M_SEE_INVIS | M_AMPHIBIOUS, MR_RES_POISON, - 1000, 10, MONS_GIANT_AMOEBA, MH_NATURAL, -3, + 1000, 10, MONS_GIANT_AMOEBA, MONS_GIANT_AMOEBA, MH_NATURAL, -3, { 25, 0, 0, 0 }, { 12, 3, 5, 0 }, 0, 4, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2523,7 +2535,7 @@ MONS_GIANT_SLUG, 'm', GREEN, "giant slug", M_NO_SKELETON | M_AMPHIBIOUS, MR_NO_FLAGS, - 700, 10, MONS_GIANT_SLUG, MH_NATURAL, -3, + 700, 10, MONS_GIANT_SLUG, MONS_GIANT_SLUG, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 10, 5, 3, 0 }, 0, 2, 6, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -2535,7 +2547,7 @@ MONS_GIANT_SNAIL, 'm', LIGHTGREEN, "giant snail", M_NO_SKELETON | M_AMPHIBIOUS, MR_NO_FLAGS, - 900, 10, MONS_GIANT_SNAIL, MH_NATURAL, -3, + 900, 10, MONS_GIANT_SLUG, MONS_GIANT_SNAIL, MH_NATURAL, -3, { 18, 0, 0, 0 }, { 14, 5, 3, 0 }, 7, 2, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -2547,7 +2559,7 @@ MONS_SPATIAL_VORTEX, 'v', BLACK, "spatial vortex", M_LEVITATE | M_CONFUSED, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 5, MONS_SPATIAL_VORTEX, MH_NONLIVING, 5000, + 0, 5, MONS_FIRE_VORTEX, MONS_SPATIAL_VORTEX, MH_NONLIVING, 5000, { 50, 0, 0, 0 }, { 6, 6, 6, 0 }, 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2557,9 +2569,9 @@ { MONS_PIT_FIEND, '1', BROWN, "Pit Fiend", - M_FLIES | M_SEE_INVIS | M_EVIL, + M_FLIES | M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 18, MONS_PIT_FIEND, MH_DEMONIC, -12, + 0, 18, MONS_FIEND, MONS_PIT_FIEND, MH_DEMONIC, -12, { 28, 21, 21, 0 }, { 19, 4, 5, 0 }, 17, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -2571,7 +2583,7 @@ MONS_BORING_BEETLE, 'B', BROWN, "boring beetle", M_NO_FLAGS, MR_VUL_POISON, - 1300, 10, MONS_BORING_BEETLE, MH_NATURAL, -3, + 1300, 10, MONS_GIANT_BEETLE, MONS_BORING_BEETLE, MH_NATURAL, -3, { 26, 0, 0, 0 }, { 8, 3, 5, 0 }, 13, 4, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, @@ -2583,7 +2595,7 @@ MONS_GARGOYLE, 'g', DARKGREY, "gargoyle", M_FLIES, MR_RES_POISON | MR_RES_ELEC, - 0, 12, MONS_GARGOYLE, MH_NONLIVING, -6, + 0, 12, MONS_GARGOYLE, MONS_GARGOYLE, MH_NONLIVING, -6, { 10, 6, 6, 0 }, { 4, 3, 5, 0 }, 18, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -2596,7 +2608,7 @@ MONS_METAL_GARGOYLE, 'g', CYAN, "metal gargoyle", M_FLIES, MR_RES_POISON | MR_RES_ELEC, - 0, 12, MONS_METAL_GARGOYLE, MH_NONLIVING, -6, + 0, 12, MONS_GARGOYLE, MONS_METAL_GARGOYLE, MH_NONLIVING, -6, { 19, 10, 10, 0 }, { 8, 3, 5, 0 }, 20, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -2609,7 +2621,7 @@ MONS_MOLTEN_GARGOYLE, 'g', RED, "molten gargoyle", M_FLIES, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE, - 0, 12, MONS_MOLTEN_GARGOYLE, MH_NONLIVING, -6, + 0, 12, MONS_GARGOYLE, MONS_MOLTEN_GARGOYLE, MH_NONLIVING, -6, { 12, 8, 8, 0 }, { 5, 3, 5, 0 }, 14, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -2625,7 +2637,7 @@ MONS_MNOLEG, '&', LIGHTGREEN, "Mnoleg", M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE, - 0, 25, MONS_MNOLEG, MH_DEMONIC, 5000, + 0, 25, MONS_MNOLEG, MONS_MNOLEG, MH_DEMONIC, 5000, { 23, 23, 0, 0 }, { 17, 0, 0, 199 }, 10, 13, 13, 7, MST_MNOLEG, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_HIGH, @@ -2637,7 +2649,7 @@ MONS_LOM_LOBON, '&', LIGHTBLUE, "Lom Lobon", M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 25, MONS_LOM_LOBON, MH_DEMONIC, 5000, + 0, 25, MONS_LOM_LOBON, MONS_LOM_LOBON, MH_DEMONIC, 5000, { 40, 0, 0, 0 }, { 19, 0, 0, 223 }, 10, 7, 8, 7, MST_LOM_LOBON, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH, @@ -2649,7 +2661,7 @@ MONS_CEREBOV, '&', RED, "Cerebov", M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE, - 0, 25, MONS_CEREBOV, MH_DEMONIC, -6, + 0, 25, MONS_CEREBOV, MONS_CEREBOV, MH_DEMONIC, -6, { 50, 0, 0, 0 }, { 21, 0, 0, 253 }, 15, 8, 10, 7, MST_CEREBOV, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -2661,7 +2673,7 @@ MONS_GLOORX_VLOQ, '&', DARKGREY, "Gloorx Vloq", M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, - 0, 25, MONS_GLOORX_VLOQ, MH_DEMONIC, -14, + 0, 25, MONS_GLOORX_VLOQ, MONS_GLOORX_VLOQ, MH_DEMONIC, -14, { 20, 0, 0, 0 }, { 16, 0, 0, 234 }, 10, 10, 10, 7, MST_GLOORX_VLOQ, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH, @@ -2680,8 +2692,8 @@ MONS_NAGA_MAGE, 'N', LIGHTRED, "naga mage", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, - 750, 13, MONS_NAGA, MH_NATURAL, -6, - { 5, 0, 0, 0 }, + 750, 13, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6, + { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, 6, 10, 8, 7, MST_NAGA_MAGE, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR @@ -2692,8 +2704,8 @@ MONS_NAGA_WARRIOR, 'N', BLUE, "naga warrior", M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, - 750, 12, MONS_NAGA, MH_NATURAL, -6, - { 11, 0, 0, 0 }, + 750, 12, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6, + { 20, 0, 0, 0 }, { 10, 5, 5, 0 }, 6, 10, 8, 7, MST_NAGA, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR @@ -2704,7 +2716,7 @@ MONS_ORC_WARLORD, 'o', RED, "orc warlord", M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, - 600, 15, MONS_ORC, MH_NATURAL, -3, + 600, 15, MONS_ORC, MONS_ORC, MH_NATURAL, -3, { 32, 0, 0, 0 }, { 15, 4, 7, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2716,7 +2728,7 @@ MONS_DEEP_ELF_SOLDIER, 'e', CYAN, "deep elf soldier", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 6, 0, 0, 0 }, { 3, 3, 3, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2728,7 +2740,7 @@ MONS_DEEP_ELF_FIGHTER, 'e', LIGHTBLUE, "deep elf fighter", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 9, 0, 0, 0 }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2740,7 +2752,7 @@ MONS_DEEP_ELF_KNIGHT, 'e', BLUE, "deep elf knight", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 14, 0, 0, 0 }, { 11, 3, 3, 0 }, 0, 15, 11, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2752,7 +2764,7 @@ MONS_DEEP_ELF_MAGE, 'e', LIGHTRED, "deep elf mage", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_ELEC, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 4, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2764,7 +2776,7 @@ MONS_DEEP_ELF_SUMMONER, 'e', YELLOW, "deep elf summoner", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_SUMMONER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2776,7 +2788,7 @@ MONS_DEEP_ELF_CONJURER, 'e', LIGHTGREEN, "deep elf conjurer", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_ELEC, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2788,7 +2800,7 @@ MONS_DEEP_ELF_PRIEST, 'e', LIGHTGREY, "deep elf priest", M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 9, 0, 0, 0 }, { 5, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2800,7 +2812,7 @@ MONS_DEEP_ELF_HIGH_PRIEST, 'e', DARKGREY, "deep elf high priest", M_SPELLCASTER | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 14, 0, 0, 0 }, { 11, 3, 3, 0 }, 3, 13, 10, 7, MST_DEEP_ELF_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2812,7 +2824,7 @@ MONS_DEEP_ELF_DEMONOLOGIST, 'e', MAGENTA, "deep elf demonologist", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 12, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_DEMONOLOGIST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2824,7 +2836,7 @@ MONS_DEEP_ELF_ANNIHILATOR, 'e', GREEN, "deep elf annihilator", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS, MR_RES_ELEC, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 15, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2836,7 +2848,7 @@ MONS_DEEP_ELF_SORCERER, 'e', RED, "deep elf sorcerer", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_SPEAKS, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 14, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2848,7 +2860,7 @@ MONS_DEEP_ELF_DEATH_MAGE, 'e', WHITE, "deep elf death mage", M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 450, 10, MONS_ELF, MH_NATURAL, -6, + 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, { 12, 0, 0, 0 }, { 15, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_DEATH_MAGE, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -2860,7 +2872,7 @@ MONS_BROWN_OOZE, 'J', BROWN, "brown ooze", M_NO_SKELETON | M_SEE_INVIS, MR_RES_POISON, - 0, 11, MONS_BROWN_OOZE, MH_NATURAL, -7, + 0, 11, MONS_JELLY, MONS_BROWN_OOZE, MH_NATURAL, -7, { 25, 0, 0, 0 }, { 7, 3, 5, 0 }, 10, 1, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2872,7 +2884,7 @@ MONS_AZURE_JELLY, 'J', LIGHTBLUE, "azure jelly", M_NO_SKELETON | M_SEE_INVIS, MR_RES_POISON | MR_RES_COLD | MR_VUL_FIRE | MR_RES_ELEC, - 0, 11, MONS_AZURE_JELLY, MH_NATURAL, -4, + 0, 11, MONS_JELLY, MONS_AZURE_JELLY, MH_NATURAL, -4, { 12, 12, 12, 12 }, { 15, 3, 5, 0 }, 5, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2884,7 +2896,7 @@ MONS_DEATH_OOZE, 'J', DARKGREY, "death ooze", M_NO_SKELETON | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 13, MONS_DEATH_OOZE, MH_UNDEAD, -8, + 0, 13, MONS_JELLY, MONS_DEATH_OOZE, MH_UNDEAD, -8, { 32, 32, 0, 0 }, { 11, 3, 3, 0 }, 2, 4, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2894,9 +2906,9 @@ { MONS_ACID_BLOB, 'J', LIGHTGREEN, "acid blob", - M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS | M_SPECIAL_ABILITY, MR_RES_POISON, - 0, 12, MONS_ACID_BLOB, MH_NATURAL, -7, + 0, 12, MONS_JELLY, MONS_ACID_BLOB, MH_NATURAL, -7, { 42, 0, 0, 0 }, { 18, 3, 5, 0 }, 1, 3, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2908,7 +2920,7 @@ MONS_ROYAL_JELLY, 'J', YELLOW, "royal jelly", M_NO_SKELETON | M_SEE_INVIS, MR_RES_POISON, - 0, 20, MONS_ROYAL_JELLY, MH_NATURAL, -7, + 0, 20, MONS_JELLY, MONS_ROYAL_JELLY, MH_NATURAL, -7, { 50, 0, 0, 0 }, { 21, 0, 0, 111 }, 8, 4, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -2920,7 +2932,7 @@ MONS_TERENCE, '@', LIGHTCYAN, "Terence", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -3, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, { 3, 0, 0, 0 }, { 1, 0, 0, 14 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2932,7 +2944,7 @@ MONS_JESSICA, '@', LIGHTGREY, "Jessica", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -3, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, { 4, 0, 0, 0 }, { 1, 0, 0, 10 }, 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2944,7 +2956,7 @@ MONS_IJYB, 'g', BLUE, "Ijyb", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 5, MONS_GOBLIN, MH_NATURAL, -3, + 0, 5, MONS_GOBLIN, MONS_GOBLIN, MH_NATURAL, -3, { 4, 0, 0, 0 }, { 3, 0, 0, 28 }, 2, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2956,7 +2968,7 @@ MONS_SIGMUND, '@', YELLOW, "Sigmund", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -3, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 3, 0, 0, 25 }, 0, 11, 10, 7, MST_ORC_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2968,7 +2980,7 @@ MONS_BLORK_THE_ORC, 'o', BROWN, "Blork the orc", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_ORC, MH_NATURAL, -4, + 0, 20, MONS_ORC, MONS_ORC, MH_NATURAL, -4, { 7, 0, 0, 0 }, { 3, 0, 0, 32 }, 0, 9, 8, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2980,7 +2992,7 @@ MONS_EDMUND, '@', RED, "Edmund", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -4, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, { 6, 0, 0, 0 }, { 4, 0, 0, 27 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -2992,7 +3004,7 @@ MONS_PSYCHE, '@', LIGHTMAGENTA, "Psyche", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -4, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, { 7, 0, 0, 0 }, { 5, 0, 0, 24 }, 0, 12, 13, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3004,7 +3016,7 @@ MONS_EROLCHA, 'O', LIGHTBLUE, "Erolcha", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_SPEAKS | M_EVIL, MR_RES_ELEC, - 0, 20, MONS_OGRE, MH_NATURAL, -7, + 0, 20, MONS_OGRE, MONS_OGRE, MH_NATURAL, -7, { 20, 0, 0, 0 }, { 6, 0, 0, 45 }, 3, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3016,7 +3028,7 @@ MONS_DONALD, '@', BLUE, "Donald", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 8, 0, 0, 0 }, { 5, 0, 0, 33 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3028,7 +3040,7 @@ MONS_URUG, 'o', RED, "Urug", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_ORC, MH_NATURAL, -5, + 0, 20, MONS_ORC, MONS_ORC, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 6, 0, 0, 38 }, 0, 11, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3040,7 +3052,7 @@ MONS_MICHAEL, '@', LIGHTGREY, "Michael", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 9, 0, 0, 0 }, { 6, 0, 0, 36 }, 0, 10, 10, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3052,7 +3064,7 @@ MONS_JOSEPH, '@', CYAN, "Joseph", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 9, 0, 0, 0 }, { 7, 0, 0, 42 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3064,7 +3076,7 @@ MONS_SNORG, 'T', GREEN, "Snorg", M_WARM_BLOOD | M_SPEAKS | M_EVIL, MR_NO_FLAGS, - 0, 20, MONS_TROLL, MH_NATURAL, -6, + 0, 20, MONS_TROLL, MONS_TROLL, MH_NATURAL, -6, { 20, 15, 15, 0 }, { 8, 0, 0, 45 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3076,7 +3088,7 @@ MONS_ERICA, '@', MAGENTA, "Erica", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 10, 0, 0, 0 }, { 9, 0, 0, 43 }, 0, 11, 11, 7, MST_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3088,7 +3100,7 @@ MONS_JOSEPHINE, '@', WHITE, "Josephine", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 11, 0, 0, 0 }, { 9, 0, 0, 47 }, 0, 10, 10, 7, MST_NECROMANCER_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3100,7 +3112,7 @@ MONS_HAROLD, '@', LIGHTGREEN, "Harold", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 9, 0, 0, 51 }, 0, 8, 10, 7, MST_HELL_KNIGHT_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3112,7 +3124,7 @@ MONS_NORBERT, '@', BROWN, "Norbert", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 10, 0, 0, 53 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3124,7 +3136,7 @@ MONS_JOZEF, '@', LIGHTMAGENTA, "Jozef", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 11, 0, 0, 60 }, 0, 9, 10, 7, MST_GUARDIAN_NAGA, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3136,7 +3148,7 @@ MONS_AGNES, '@', LIGHTBLUE, "Agnes", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 11, 0, 0, 0 }, { 11, 0, 0, 64 }, 0, 10, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3148,7 +3160,7 @@ MONS_MAUD, '@', RED, "Maud", M_WARM_BLOOD | M_SPEAKS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 13, 0, 0, 55 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3160,7 +3172,7 @@ MONS_LOUISE, '@', BLUE, "Louise", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD, MR_RES_ELEC, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 13, 0, 0, 52 }, 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3172,7 +3184,7 @@ MONS_FRANCIS, '@', YELLOW, "Francis", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 12, 0, 0, 0 }, { 14, 0, 0, 67 }, 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3184,7 +3196,7 @@ MONS_FRANCES, '@', YELLOW, "Frances", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 11, 0, 0, 0 }, { 14, 0, 0, 70 }, 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3196,7 +3208,7 @@ MONS_RUPERT, '@', RED, "Rupert", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, MR_RES_ELEC, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 13, 0, 0, 0 }, { 16, 0, 0, 80 }, 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3208,7 +3220,7 @@ MONS_WAYNE, '@', YELLOW, "Wayne", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 17, 0, 0, 78 }, 1, 10, 7, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3220,7 +3232,7 @@ MONS_DUANE, '@', YELLOW, "Duane", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 14, 0, 0, 0 }, { 18, 0, 0, 83 }, 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3230,9 +3242,9 @@ { MONS_XTAHUA, 'D', RED, "Xtahua", - M_SPEAKS | M_SEE_INVIS | M_FLIES, + M_SPEAKS | M_SEE_INVIS | M_FLIES | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, - 0, 20, MONS_DRAGON, MH_NATURAL, -7, + 0, 20, MONS_DRAGON, MONS_DRAGON, MH_NATURAL, -7, { 29, 17, 17, 0 }, { 19, 0, 0, 133 }, 15, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_NORMAL, @@ -3244,10 +3256,10 @@ MONS_NORRIS, '@', LIGHTRED, "Norris", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 16, 0, 0, 0 }, { 20, 0, 0, 95 }, - 1, 9, 9, 7, MST_HELL_KNIGHT_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, + 1, 9, 9, 7, MST_MYSTIC, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR } , @@ -3256,7 +3268,7 @@ MONS_ADOLF, '@', DARKGREY, "Adolf", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 17, 0, 0, 0 }, { 21, 0, 0, 105 }, 0, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3268,7 +3280,7 @@ MONS_MARGERY, '@', RED, "Margery", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_SEE_INVIS, MR_NO_FLAGS, - 0, 20, MONS_HUMAN, MH_NATURAL, -5, + 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, { 18, 0, 0, 0 }, { 22, 0, 0, 119 }, 0, 10, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3280,7 +3292,7 @@ MONS_BORIS, 'L', RED, "Boris", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, - 0, 23, MONS_LICH, MH_UNDEAD, -11, + 0, 23, MONS_LICH, MONS_LICH, MH_UNDEAD, -11, { 15, 0, 0, 0 }, { 22, 0, 0, 99 }, 12, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -3293,7 +3305,7 @@ MONS_GERYON, '&', GREEN, "Geryon", M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, MR_NO_FLAGS, - 0, 25, MONS_GERYON, MH_DEMONIC, -6, + 0, 25, MONS_GERYON, MONS_GERYON, MH_DEMONIC, -6, { 30, 0, 0, 0 }, { 15, 0, 0, 240 }, 15, 6, 10, 7, MST_GERYON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL, @@ -3305,7 +3317,7 @@ MONS_DISPATER, '&', MAGENTA, "Dispater", M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, - 0, 25, MONS_DISPATER, MH_DEMONIC, -10, + 0, 25, MONS_DISPATER, MONS_DISPATER, MH_DEMONIC, -10, { 15, 0, 0, 0 }, { 16, 0, 0, 222 }, 15, 3, 6, 7, MST_DISPATER, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3317,7 +3329,7 @@ MONS_ASMODEUS, '&', LIGHTMAGENTA, "Asmodeus", M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE, - 0, 25, MONS_ASMODEUS, MH_DEMONIC, -12, + 0, 25, MONS_ASMODEUS, MONS_ASMODEUS, MH_DEMONIC, -12, { 20, 0, 0, 0 }, { 17, 0, 0, 245 }, 12, 7, 9, 7, MST_ASMODEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3330,7 +3342,7 @@ MONS_ANTAEUS, 'C', LIGHTCYAN, "Antaeus", M_SPELLCASTER | M_SPEAKS, MR_RES_ELEC | MR_VUL_FIRE | MR_RES_COLD, - 0, 25, MONS_ANTAEUS, MH_DEMONIC, -9, + 0, 25, MONS_HILL_GIANT, MONS_ANTAEUS, MH_DEMONIC, -9, { 30, 0, 0, 0 }, { 22, 0, 0, 250 }, 10, 4, 7, 7, MST_ANTAEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3342,7 +3354,7 @@ MONS_ERESHKIGAL, '&', WHITE, "Ereshkigal", M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD, - 0, 25, MONS_ERESHKIGAL, MH_DEMONIC, -10, + 0, 25, MONS_ERESHKIGAL, MONS_ERESHKIGAL, MH_DEMONIC, -10, { 20, 0, 0, 0 }, { 18, 0, 0, 238 }, 15, 6, 9, 7, MST_ERESHKIGAL, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3354,7 +3366,7 @@ MONS_ANCIENT_LICH, 'L', DARKGREY, "ancient lich", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC, - 0, 20, MONS_LICH, MH_UNDEAD, -14, + 0, 20, MONS_LICH, MONS_LICH, MH_UNDEAD, -14, { 20, 0, 0, 0 }, { 27, 2, 4, 0 }, 20, 10, 12, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3367,7 +3379,7 @@ MONS_OOZE, 'J', LIGHTGREY, "ooze", M_NO_SKELETON | M_SEE_INVIS, MR_RES_POISON, - 0, 5, MONS_OOZE, MH_NATURAL, -6, + 0, 5, MONS_JELLY, MONS_OOZE, MH_NATURAL, -6, { 5, 0, 0, 0 }, { 3, 3, 5, 0 }, 1, 3, 8, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3379,7 +3391,7 @@ MONS_VAULT_GUARD, '@', CYAN, "vault guard", M_WARM_BLOOD | M_SEE_INVIS, MR_NO_FLAGS, - 0, 12, MONS_HUMAN, MH_NATURAL, -3, + 0, 12, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 13, 3, 5, 0 }, 1, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3393,7 +3405,7 @@ MONS_CURSE_SKULL, 'z', DARKGREY, "curse skull", M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, - 0, 50, MONS_CURSE_SKULL, MH_UNDEAD, 5000, + 0, 50, MONS_LICH, MONS_CURSE_SKULL, MH_UNDEAD, 5000, { 0, 0, 0, 0 }, { 13, 0, 0, 66 }, 40, 3, 10, 7, MST_CURSE_SKULL, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, @@ -3405,7 +3417,7 @@ MONS_VAMPIRE_KNIGHT, 'V', CYAN, "vampire knight", M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 13, MONS_VAMPIRE, MH_UNDEAD, -6, + 0, 13, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6, { 33, 0, 0, 0 }, { 11, 3, 7, 0 }, 10, 10, 10, 7, MST_VAMPIRE_KNIGHT, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3417,7 +3429,7 @@ MONS_VAMPIRE_MAGE, 'V', MAGENTA, "vampire mage", M_SPELLCASTER | M_SEE_INVIS | M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 15, MONS_VAMPIRE, MH_UNDEAD, -6, + 0, 15, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6, { 22, 0, 0, 0 }, { 8, 3, 4, 0 }, 10, 10, 10, 7, MST_VAMPIRE_MAGE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -3429,7 +3441,7 @@ MONS_SHINING_EYE, 'G', LIGHTMAGENTA, "shining eye", M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, MR_NO_FLAGS, - 0, 14, MONS_SHINING_EYE, MH_NATURAL, 5000, + 0, 14, MONS_SHINING_EYE, MONS_SHINING_EYE, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 3, 1, 7, 7, MST_SHINING_EYE, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3441,8 +3453,8 @@ MONS_ORB_GUARDIAN, 'X', MAGENTA, "Orb Guardian", M_NO_SKELETON | M_SEE_INVIS, MR_NO_FLAGS, - 0, 20, MONS_ORB_GUARDIAN, MH_NATURAL, -6, - { 40, 0, 0, 0 }, + 0, 20, MONS_ORB_GUARDIAN, MONS_ORB_GUARDIAN, MH_NATURAL, -6, + { 45, 0, 0, 0 }, { 15, 3, 5, 0 }, 13, 13, 14, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS @@ -3453,7 +3465,7 @@ MONS_DAEVA, 'A', YELLOW, "Daeva", M_LEVITATE | M_SPELLCASTER, MR_RES_POISON, - 0, 12, MONS_DAEVA, MH_HOLY, -8, + 0, 12, MONS_ANGEL, MONS_DAEVA, MH_HOLY, -8, { 25, 0, 0, 0 }, { 12, 3, 5, 0 }, 10, 13, 13, 7, MST_DAEVA, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3466,7 +3478,7 @@ MONS_SPECTRAL_THING, 'W', GREEN, "", M_LEVITATE | M_SEE_INVIS, MR_RES_POISON | MR_RES_COLD, - 0, 11, MONS_SPECTRAL_THING, MH_UNDEAD, 5000, + 0, 11, MONS_WRAITH, MONS_SPECTRAL_THING, MH_UNDEAD, 5000, { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, 8, 5, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3478,8 +3490,8 @@ MONS_GREATER_NAGA, 'N', RED, "greater naga", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, - 750, 10, MONS_NAGA, MH_NATURAL, 5000, - { 18, 0, 0, 0 }, + 750, 10, MONS_NAGA, MONS_NAGA, MH_NATURAL, 5000, + { 24, 0, 0, 0 }, { 15, 3, 5, 0 }, 6, 10, 8, 7, MST_NAGA_MAGE, CE_POISONOUS, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR @@ -3490,7 +3502,7 @@ MONS_SKELETAL_DRAGON, 'D', LIGHTGREY, "skeletal dragon", M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 12, MONS_SKELETAL_DRAGON, MH_UNDEAD, -4, + 0, 12, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_DRAGON, MH_UNDEAD, -4, { 30, 20, 20, 0 }, { 20, 8, 8, 0 }, 20, 4, 8, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3502,7 +3514,7 @@ MONS_TENTACLED_MONSTROSITY, 'X', GREEN, "tentacled monstrosity", M_SEE_INVIS | M_AMPHIBIOUS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, - 0, 10, MONS_TENTACLED_MONSTROSITY, MH_NATURAL, -5, + 0, 10, MONS_TENTACLED_MONSTROSITY, MONS_TENTACLED_MONSTROSITY, MH_NATURAL, -5, { 22, 17, 13, 19 }, { 25, 3, 5, 0 }, 5, 5, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3514,7 +3526,7 @@ MONS_SPHINX, 'H', LIGHTGREY, "sphinx", M_FLIES | M_SEE_INVIS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, - 0, 10, MONS_SPHINX, MH_NATURAL, -3, + 0, 10, MONS_SPHINX, MONS_SPHINX, MH_NATURAL, -3, { 25, 12, 12, 0 }, { 16, 3, 5, 0 }, 5, 5, 13, 7, MST_SPHINX, CE_CLEAN, Z_NOZOMBIE, S_SHOUT, I_HIGH, @@ -3526,7 +3538,7 @@ MONS_ROTTING_HULK, 'n', BROWN, "rotting hulk", M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 12, MONS_ROTTING_HULK, MH_UNDEAD, -5, + 0, 12, MONS_GHOUL, MONS_ROTTING_HULK, MH_UNDEAD, -5, { 25, 0, 0, 0 }, { 10, 3, 5, 0 }, 5, 7, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3538,7 +3550,7 @@ MONS_GUARDIAN_MUMMY, 'M', YELLOW, "guardian mummy", M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 13, MONS_GUARDIAN_MUMMY, MH_UNDEAD, -5, + 0, 13, MONS_MUMMY, MONS_GUARDIAN_MUMMY, MH_UNDEAD, -5, { 30, 0, 0, 0 }, { 7, 5, 3, 0 }, 6, 9, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3550,7 +3562,7 @@ MONS_GREATER_MUMMY, 'M', DARKGREY, "greater mummy", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, - 0, 20, MONS_MUMMY, MH_UNDEAD, 5000, + 0, 20, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, 5000, { 35, 0, 0, 0 }, { 15, 5, 3, 100 }, 10, 6, 10, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3562,7 +3574,7 @@ MONS_MUMMY_PRIEST, 'M', RED, "mummy priest", M_SPELLCASTER | M_PRIEST | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, - 0, 16, MONS_MUMMY, MH_UNDEAD, 5000, + 0, 16, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, 5000, { 30, 0, 0, 0 }, { 10, 5, 3, 0 }, 8, 7, 9, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3574,7 +3586,7 @@ MONS_CENTAUR_WARRIOR, 'c', YELLOW, "centaur warrior", M_WARM_BLOOD, MR_NO_FLAGS, - 1500, 12, MONS_CENTAUR, MH_NATURAL, -3, + 1500, 12, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3, { 16, 0, 0, 0 }, { 9, 3, 5, 0 }, 4, 8, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, @@ -3586,7 +3598,7 @@ MONS_YAKTAUR_CAPTAIN, 'c', RED, "yaktaur captain", M_WARM_BLOOD, MR_NO_FLAGS, - 2000, 10, MONS_YAKTAUR, MH_NATURAL, -3, + 2000, 10, MONS_YAKTAUR, MONS_YAKTAUR, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 14, 3, 5, 0 }, 5, 5, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, @@ -3594,11 +3606,205 @@ } , +{ // Base draconian -- for use like MONS_HUMAN, MONS_ELF although we + // now store the draconian subspecies in the high byte of mon->number + // for those listed as species MONS_DRACONIAN. + MONS_DRACONIAN, 'd', BROWN, "draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3, + { 15, 0, 0, 0 }, + { 3, 6, 4, 0 }, + 7, 8, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_BLACK_DRACONIAN, 'd', DARKGREY, "black draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_RES_ELEC, + 900, 10, MONS_DRACONIAN, MONS_BLACK_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_YELLOW_DRACONIAN, 'd', YELLOW, "yellow draconian", + M_FLIES | M_HUMANOID | M_COLD_BLOOD | M_SPECIAL_ABILITY, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_YELLOW_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_PALE_DRACONIAN, 'd', LIGHTGREY, "pale draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_RES_FIRE, + 900, 10, MONS_DRACONIAN, MONS_PALE_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 14, 12, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_GREEN_DRACONIAN, 'd', LIGHTGREEN, "green draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_RES_POISON, + 900, 10, MONS_DRACONIAN, MONS_GREEN_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 10, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_PURPLE_DRACONIAN, 'd', MAGENTA, "purple draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_PURPLE_DRACONIAN, MH_NATURAL, 6, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 8, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_RED_DRACONIAN, 'd', RED, "red draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD | M_SPECIAL_ABILITY, + MR_RES_FIRE, + 900, 10, MONS_DRACONIAN, MONS_RED_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_WHITE_DRACONIAN, 'd', WHITE, "white draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD | M_SPECIAL_ABILITY, + MR_RES_COLD, + 900, 10, MONS_DRACONIAN, MONS_WHITE_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_MOTTLED_DRACONIAN, 'd', LIGHTMAGENTA, "mottled draconian", + M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_RES_FIRE, + 900, 10, MONS_DRACONIAN, MONS_MOTTLED_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 14, 6, 4, 0 }, + 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_CALLER, 'd', BROWN, "draconian caller", + M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3, + { 20, 0, 0, 0 }, + { 16, 5, 5, 0 }, + 9, 10, 10, 10, MST_DRAC_CALLER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_MONK, 'd', BLUE, "draconian monk", + M_FIGHTER | M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3, + { 15, 15, 15, 0 }, + { 16, 6, 4, 0 }, + 6, 20, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_ZEALOT, 'd', LIGHTBLUE, "draconian zealot", + M_SPELLCASTER | M_HUMANOID | M_PRIEST | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 3, + { 15, 0, 0, 0 }, + { 16, 6, 4, 0 }, + 12, 10, 10, 10, MST_DEEP_ELF_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_SHIFTER, 'd', LIGHTCYAN, "draconian shifter", + M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4, + { 15, 0, 0, 0 }, + { 16, 5, 5, 0 }, + 8, 16, 10, 10, MST_DRAC_SHIFTER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_ANNIHILATOR, 'd', GREEN, "draconian annihilator", + M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4, + { 15, 0, 0, 0 }, + { 16, 5, 5, 0 }, + 8, 10, 10, 10, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_KNIGHT, 'd', CYAN, "draconian knight", + M_SPELLCASTER | M_HUMANOID | M_PRIEST | M_FIGHTER | M_FLIES | M_COLD_BLOOD, + MR_NO_FLAGS, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4, + { 15, 0, 0, 0 }, + { 16, 6, 4, 0 }, + 12, 12, 10, 6, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + +{ + MONS_DRACONIAN_SCORCHER, 'd', LIGHTRED, "draconian scorcher", + M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_FLIES | M_COLD_BLOOD, + MR_RES_FIRE | MR_RES_HELLFIRE, + 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, 4, + { 15, 0, 0, 0 }, + { 16, 5, 5, 0 }, + 8, 12, 10, 10, MST_DRAC_SCORCHER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, + MONUSE_STARTING_EQUIPMENT +} +, + { MONS_KILLER_KLOWN, '@', BLACK, "Killer Klown", - M_SEE_INVIS | M_SPEAKS | M_WARM_BLOOD, + M_SEE_INVIS | M_SPEAKS | M_WARM_BLOOD | M_SPECIAL_ABILITY, MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, - 0, 15, MONS_KILLER_KLOWN, MH_NATURAL, 5000, + 0, 15, MONS_HUMAN, MONS_KILLER_KLOWN, MH_NATURAL, 5000, { 30, 0, 0, 0 }, { 20, 5, 5, 0 }, 10, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, @@ -3610,7 +3816,7 @@ MONS_ELECTRIC_GOLEM, '8', LIGHTCYAN, "electric golem", M_SPELLCASTER | M_SEE_INVIS, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 0, 10, MONS_ELECTRIC_GOLEM, MH_NONLIVING, 5000, + 0, 10, MONS_CLAY_GOLEM, MONS_ELECTRIC_GOLEM, MH_NONLIVING, 5000, { 12, 12, 12, 12 }, { 15, 7, 4, 0 }, 5, 20, 20, 7, MST_ELECTRIC_GOLEM, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3620,9 +3826,9 @@ { MONS_BALL_LIGHTNING, '*', LIGHTCYAN, "ball lightning", - M_FLIES | M_CONFUSED | M_SPELLCASTER, + M_FLIES | M_CONFUSED | M_SPELLCASTER | M_SPECIAL_ABILITY, MR_RES_ELEC, - 0, 20, MONS_BALL_LIGHTNING, MH_NONLIVING, 5000, + 0, 20, MONS_BALL_LIGHTNING, MONS_BALL_LIGHTNING, MH_NONLIVING, 5000, { 5, 0, 0, 0 }, { 12, 0, 0, 1 }, 0, 10, 20, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_PLANT, @@ -3634,7 +3840,7 @@ MONS_ORB_OF_FIRE, '*', RED, "orb of fire", M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, - 0, 10, MONS_ORB_OF_FIRE, MH_NONLIVING, 5000, + 0, 10, MONS_ORB_OF_FIRE, MONS_ORB_OF_FIRE, MH_NONLIVING, 5000, { 0, 0, 0, 0 }, { 30, 0, 0, 150 }, 20, 20, 20, 7, MST_ORB_OF_FIRE, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, @@ -3646,7 +3852,7 @@ MONS_QUOKKA, 'r', LIGHTGREY, "quokka", M_WARM_BLOOD, MR_NO_FLAGS, - 300, 10, MONS_QUOKKA, MH_NATURAL, -1, + 300, 10, MONS_QUOKKA, MONS_QUOKKA, MH_NATURAL, -1, { 5, 0, 0, 0 }, { 1, 3, 5, 0 }, 2, 13, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_NORMAL, @@ -3658,7 +3864,7 @@ MONS_EYE_OF_DEVASTATION, 'G', YELLOW, "eye of devastation", M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, MR_NO_FLAGS, - 0, 11, MONS_EYE_OF_DEVASTATION, MH_NATURAL, 5000, + 0, 11, MONS_GIANT_EYEBALL, MONS_EYE_OF_DEVASTATION, MH_NATURAL, 5000, { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 12, 1, 7, 7, MST_EYE_OF_DEVASTATION, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3670,7 +3876,7 @@ MONS_MOTH_OF_WRATH, 'y', BROWN, "moth of wrath", M_FLIES, MR_NO_FLAGS, - 0, 10, MONS_MOTH_OF_WRATH, MH_NATURAL, -3, + 0, 10, MONS_MOTH_OF_WRATH, MONS_MOTH_OF_WRATH, MH_NATURAL, -3, { 25, 0, 0, 0 }, { 9, 3, 5, 0 }, 0, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3682,7 +3888,7 @@ MONS_DEATH_COB, '%', YELLOW, "death cob", M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_DEATH_COB, MH_UNDEAD, -3, + 0, 10, MONS_DEATH_COB, MONS_DEATH_COB, MH_UNDEAD, -3, { 20, 0, 0, 0 }, { 10, 4, 5, 0 }, 10, 15, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_MOAN, I_NORMAL, @@ -3694,7 +3900,7 @@ MONS_CURSE_TOE, 'z', DARKGREY, "curse toe", M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, - 0, 60, MONS_CURSE_TOE, MH_UNDEAD, 5000, + 0, 60, MONS_LICH, MONS_CURSE_TOE, MH_UNDEAD, 5000, { 0, 0, 0, 0 }, { 14, 0, 0, 77 }, 50, 1, 12, 7, MST_CURSE_SKULL, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, @@ -3707,7 +3913,7 @@ MONS_GOLD_MIMIC, '$', YELLOW, "pile of gold coins", M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, - 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, + 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3719,7 +3925,7 @@ MONS_WEAPON_MIMIC, ')', BLACK, "mimic", M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, - 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, + 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 17, 17, 17, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3731,7 +3937,7 @@ MONS_ARMOUR_MIMIC, '[', BLACK, "mimic", M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, - 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, + 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 15, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3743,7 +3949,7 @@ MONS_SCROLL_MIMIC, '?', LIGHTGREY, "mimic", M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, - 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, + 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3755,7 +3961,7 @@ MONS_POTION_MIMIC, '!', BLACK, "mimic", M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, - 0, 13, MONS_GOLD_MIMIC, MH_NONLIVING, -3, + 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, @@ -3767,7 +3973,7 @@ MONS_HELL_HOG, 'h', RED, "hell-hog", M_SPELLCASTER | M_THICK_SKIN | M_EVIL, MR_NO_FLAGS, - 0, 10, MONS_HELL_HOG, MH_DEMONIC, -3, + 0, 10, MONS_HELL_HOG, MONS_HELL_HOG, MH_DEMONIC, -3, { 20, 0, 0, 0 }, { 11, 3, 5, 0 }, 2, 9, 14, 7, MST_HELL_HOG, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_ANIMAL, @@ -3779,7 +3985,7 @@ MONS_SERPENT_OF_HELL, 'D', RED, "Serpent of Hell", M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE, - 0, 18, MONS_SERPENT_OF_HELL, MH_DEMONIC, -13, + 0, 18, MONS_SERPENT_OF_HELL, MONS_SERPENT_OF_HELL, MH_DEMONIC, -13, { 35, 15, 15, 0 }, { 20, 4, 4, 0 }, 12, 9, 14, 7, MST_SERPENT_OF_HELL, CE_CLEAN, Z_NOZOMBIE, S_ROAR, I_HIGH, @@ -3791,7 +3997,7 @@ MONS_BOGGART, 'g', DARKGREY, "boggart", M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS, MR_NO_FLAGS, - 0, 14, MONS_BOGGART, MH_NATURAL, -7, + 0, 14, MONS_BOGGART, MONS_BOGGART, MH_NATURAL, -7, { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 0, 12, 12, 7, MST_BOGGART, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, @@ -3803,7 +4009,7 @@ MONS_QUICKSILVER_DRAGON, 'D', LIGHTCYAN, "quicksilver dragon", M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_NO_FLAGS, - 0, 14, MONS_QUICKSILVER_DRAGON, MH_NATURAL, -7, + 0, 14, MONS_DRAGON, MONS_QUICKSILVER_DRAGON, MH_NATURAL, -7, { 45, 0, 0, 0 }, { 16, 3, 5, 0 }, 10, 15, 15, 7, MST_QUICKSILVER_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, @@ -3815,7 +4021,7 @@ MONS_IRON_DRAGON, 'D', CYAN, "iron dragon", M_SPELLCASTER | M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 0, 14, MONS_IRON_DRAGON, MH_NATURAL, -7, + 0, 14, MONS_DRAGON, MONS_IRON_DRAGON, MH_NATURAL, -7, { 25, 25, 25, 0 }, { 18, 5, 3, 0 }, 20, 6, 8, 7, MST_IRON_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, @@ -3827,7 +4033,7 @@ MONS_SKELETAL_WARRIOR, 'z', CYAN, "skeletal warrior", M_SPELLCASTER | M_ACTUAL_SPELLS | M_EVIL, MR_RES_POISON | MR_RES_COLD, - 0, 10, MONS_SKELETAL_WARRIOR, MH_UNDEAD, -7, + 0, 10, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_WARRIOR, MH_UNDEAD, -7, { 25, 0, 0, 0 }, { 10, 5, 3, 0 }, 15, 10, 10, 7, MST_SKELETAL_WARRIOR, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_NORMAL, @@ -3841,7 +4047,7 @@ MONS_PLAYER_GHOST, 'p', DARKGREY, "", M_SPEAKS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_FLIES, MR_RES_POISON, - 0, 15, MONS_PLAYER_GHOST, MH_UNDEAD, -5, + 0, 15, MONS_PHANTOM, MONS_PLAYER_GHOST, MH_UNDEAD, -5, { 5, 0, 0, 0 }, { 4, 2, 3, 0 }, 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH, @@ -3854,7 +4060,7 @@ MONS_PANDEMONIUM_DEMON, '&', BLACK, "&", M_SPELLCASTER | M_SPEAKS | M_EVIL, MR_RES_POISON, - 0, 14, MONS_PANDEMONIUM_DEMON, MH_DEMONIC, -5, + 0, 14, MONS_PANDEMONIUM_DEMON, MONS_PANDEMONIUM_DEMON, MH_DEMONIC, -5, { 5, 0, 0, 0 }, { 4, 2, 3, 0 }, 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_HIGH, @@ -3867,7 +4073,7 @@ MONS_LAVA_WORM, 'w', RED, "lava worm", M_NO_FLAGS, MR_RES_FIRE | MR_VUL_COLD, - 0, 10, MONS_LAVA_WORM, MH_NATURAL, -3, + 0, 10, MONS_LAVA_WORM, MONS_LAVA_WORM, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 1, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, @@ -3879,7 +4085,7 @@ MONS_LAVA_FISH, ';', RED, "lava fish", M_NO_FLAGS, MR_RES_FIRE | MR_VUL_COLD, - 0, 10, MONS_LAVA_FISH, MH_NATURAL, -3, + 0, 10, MONS_BIG_FISH, MONS_LAVA_FISH, MH_NATURAL, -3, { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, 4, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, @@ -3889,9 +4095,9 @@ { MONS_LAVA_SNAKE, 'S', RED, "lava snake", - M_NO_FLAGS, + M_SPECIAL_ABILITY, MR_RES_FIRE | MR_VUL_COLD, - 0, 10, MONS_LAVA_SNAKE, MH_NATURAL, -3, + 0, 10, MONS_SNAKE, MONS_LAVA_SNAKE, MH_NATURAL, -3, { 7, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_HISS, I_ANIMAL_LIKE, @@ -3903,7 +4109,7 @@ MONS_SALAMANDER, 'S', LIGHTRED, "salamander", M_WARM_BLOOD, MR_RES_FIRE | MR_VUL_COLD, - 0, 10, MONS_SALAMANDER, MH_NATURAL, -3, + 0, 10, MONS_SALAMANDER, MONS_SALAMANDER, MH_NATURAL, -3, { 23, 0, 0, 0 }, { 14, 3, 5, 0 }, 5, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_HIGH, @@ -3918,7 +4124,7 @@ MONS_BIG_FISH, ';', LIGHTGREEN, "big fish", M_COLD_BLOOD, MR_NO_FLAGS, - 0, 10, MONS_BIG_FISH, MH_NATURAL, -3, + 0, 10, MONS_BIG_FISH, MONS_BIG_FISH, MH_NATURAL, -3, { 8, 0, 0, 0 }, { 4, 3, 5, 0 }, 1, 12, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, @@ -3930,7 +4136,7 @@ MONS_GIANT_GOLDFISH, ';', LIGHTRED, "giant goldfish", M_COLD_BLOOD, MR_NO_FLAGS, - 0, 10, MONS_GIANT_GOLDFISH, MH_NATURAL, -3, + 0, 10, MONS_BIG_FISH, MONS_GIANT_GOLDFISH, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 7, 3, 5, 0 }, 5, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, @@ -3940,9 +4146,9 @@ { MONS_ELECTRICAL_EEL, ';', LIGHTBLUE, "electrical eel", - M_COLD_BLOOD, + M_COLD_BLOOD | M_SPECIAL_ABILITY, MR_RES_ELEC, - 0, 10, MONS_ELECTRICAL_EEL, MH_NATURAL, -3, + 0, 10, MONS_ELECTRICAL_EEL, MONS_ELECTRICAL_EEL, MH_NATURAL, -3, { 0, 0, 0, 0 }, { 3, 3, 5, 0 }, 1, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, @@ -3954,7 +4160,7 @@ MONS_JELLYFISH, 'J', CYAN, "jellyfish", M_NO_FLAGS, MR_RES_POISON, - 0, 10, MONS_JELLYFISH, MH_NATURAL, -3, + 0, 10, MONS_JELLYFISH, MONS_JELLYFISH, MH_NATURAL, -3, { 1, 1, 0, 0 }, { 4, 3, 5, 0 }, 0, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, @@ -3966,7 +4172,7 @@ MONS_WATER_ELEMENTAL, '{', LIGHTBLUE, "water elemental", M_FLIES, MR_RES_POISON | MR_VUL_FIRE | MR_RES_ELEC, - 0, 10, MONS_WATER_ELEMENTAL, MH_NONLIVING, 5000, + 0, 10, MONS_EARTH_ELEMENTAL, MONS_WATER_ELEMENTAL, MH_NONLIVING, 5000, { 25, 0, 0, 0 }, { 6, 5, 3, 0 }, 0, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -3978,7 +4184,7 @@ MONS_SWAMP_WORM, 'w', BROWN, "swamp worm", M_AMPHIBIOUS, MR_NO_FLAGS, - 0, 10, MONS_SWAMP_WORM, MH_NATURAL, -3, + 0, 10, MONS_WORM, MONS_SWAMP_WORM, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 5, 5, 0 }, 3, 12, 12, 0, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, @@ -4002,7 +4208,7 @@ not think it fits into Crawl ... {dlb} MONS_SHUGGOTH, 'A', LIGHTGREEN, "shuggoth", M_NO_SKELETON | M_SEE_INVIS, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 1000, 10, MONS_SHUGGOTH, MH_DEMONIC, 300, + 1000, 10, MONS_SHUGGOTH, MONS_SHUGGOTH, MH_DEMONIC, 300, { 5, 5, 5, 0 }, { 10, 4, 4, 0 }, 10, 10, 20, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, -1, I_NORMAL, @@ -4015,7 +4221,7 @@ not think it fits into Crawl ... {dlb} MONS_WOLF, 'h', LIGHTGREY, "wolf", M_WARM_BLOOD | M_SEE_INVIS, //jmf: until smell exists MR_NO_FLAGS, - 450, 10, MONS_WOLF, MH_NATURAL, -3, + 450, 10, MONS_HOUND, MONS_WOLF, MH_NATURAL, -3, { 8, 2, 2, 0 }, { 4, 3, 5, 0 }, 3, 15, 17, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL, @@ -4027,7 +4233,7 @@ not think it fits into Crawl ... {dlb} MONS_WARG, 'h', DARKGREY, "warg", M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, - 600, 12, MONS_WARG, MH_NATURAL, -6, + 600, 12, MONS_HOUND, MONS_WARG, MH_NATURAL, -6, { 12, 3, 3, 0 }, { 4, 4, 5, 0 }, 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, @@ -4039,7 +4245,7 @@ not think it fits into Crawl ... {dlb} MONS_BEAR, 'U', BROWN, "bear", M_WARM_BLOOD, MR_NO_FLAGS, - 2000, 10, MONS_BEAR, MH_NATURAL, -3, + 2000, 10, MONS_BEAR, MONS_BEAR, MH_NATURAL, -3, { 10, 6, 6, 0 }, { 7, 3, 3, 0 }, 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, @@ -4051,7 +4257,7 @@ not think it fits into Crawl ... {dlb} MONS_GRIZZLY_BEAR, 'U', LIGHTGREY, "grizzly bear", M_WARM_BLOOD, MR_NO_FLAGS, - 2500, 10, MONS_GRIZZLY_BEAR, MH_NATURAL, -3, + 2500, 10, MONS_BEAR, MONS_GRIZZLY_BEAR, MH_NATURAL, -3, { 12, 8, 8, 0 }, { 7, 4, 4, 0 }, 5, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, @@ -4063,7 +4269,7 @@ not think it fits into Crawl ... {dlb} MONS_POLAR_BEAR, 'U', WHITE, "polar bear", M_WARM_BLOOD | M_AMPHIBIOUS, MR_RES_COLD, - 2500, 10, MONS_POLAR_BEAR, MH_NATURAL, -3, + 2500, 10, MONS_BEAR, MONS_POLAR_BEAR, MH_NATURAL, -3, { 20, 5, 5, 0 }, //jmf: polar bears have very strong jaws & necks { 7, 5, 3, 0 }, 7, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, @@ -4075,7 +4281,7 @@ not think it fits into Crawl ... {dlb} MONS_BLACK_BEAR, 'U', DARKGREY, "black bear", M_WARM_BLOOD, MR_NO_FLAGS, - 1800, 10, MONS_BLACK_BEAR, MH_NATURAL, -3, + 1800, 10, MONS_BEAR, MONS_BLACK_BEAR, MH_NATURAL, -3, { 4, 4, 4, 0 }, { 6, 3, 3, 0 }, 2, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_GROWL, I_ANIMAL, @@ -4088,7 +4294,7 @@ not think it fits into Crawl ... {dlb} MONS_SIMULACRUM_SMALL, 'z', WHITE, "", M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 6, MONS_SIMULACRUM_SMALL, MH_UNDEAD, -1, + 0, 6, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_SMALL, MH_UNDEAD, -1, { 6, 0, 0, 0 }, { 2, 3, 5, 0 }, 10, 4, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -4101,7 +4307,7 @@ not think it fits into Crawl ... {dlb} MONS_SIMULACRUM_LARGE, 'Z', WHITE, "", M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, - 0, 6, MONS_SIMULACRUM_LARGE, MH_UNDEAD, -1, + 0, 6, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE, MH_UNDEAD, -1, { 14, 0, 0, 0 }, { 5, 3, 5, 0 }, 10, 5, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, @@ -4113,7 +4319,7 @@ not think it fits into Crawl ... {dlb} MONS_GIANT_NEWT, 'l', LIGHTGREEN, "giant newt", M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 150, 10, MONS_GIANT_NEWT, MH_NATURAL, -3, + 150, 10, MONS_GIANT_LIZARD, MONS_GIANT_NEWT, MH_NATURAL, -3, { 3, 0, 0, 0 }, { 1, 1, 2, 0 }, 0, 15, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, @@ -4125,7 +4331,7 @@ not think it fits into Crawl ... {dlb} MONS_GIANT_GECKO, 'l', YELLOW, "giant gecko", M_COLD_BLOOD, MR_NO_FLAGS, - 250, 10, MONS_GIANT_GECKO, MH_NATURAL, -3, + 250, 10, MONS_GIANT_LIZARD, MONS_GIANT_GECKO, MH_NATURAL, -3, { 5, 0, 0, 0 }, { 1, 3, 5, 0 }, 1, 14, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, @@ -4137,7 +4343,7 @@ not think it fits into Crawl ... {dlb} MONS_GIANT_IGUANA, 'l', BLUE, "giant iguana", M_COLD_BLOOD, MR_NO_FLAGS, - 400, 10, MONS_GIANT_IGUANA, MH_NATURAL, -3, + 400, 10, MONS_GIANT_LIZARD, MONS_GIANT_IGUANA, MH_NATURAL, -3, { 15, 0, 0, 0 }, { 3, 3, 5, 0 }, 5, 9, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE, @@ -4150,7 +4356,7 @@ not think it fits into Crawl ... {dlb} MONS_GILA_MONSTER, 'l', BLACK, "gila monster", M_COLD_BLOOD, MR_NO_FLAGS, - 500, 10, MONS_GILA_MONSTER, MH_NATURAL, -3, + 500, 10, MONS_GIANT_LIZARD, MONS_GILA_MONSTER, MH_NATURAL, -3, { 20, 0, 0, 0 }, { 5, 4, 4, 0 }, 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_HISS, I_REPTILE, @@ -4159,10 +4365,10 @@ not think it fits into Crawl ... {dlb} , { - MONS_KOMODO_DRAGON, 'l', BROWN, "komodo dragon", + MONS_KOMODO_DRAGON, 'l', LIGHTRED, "komodo dragon", M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, - 800, 10, MONS_KOMODO_DRAGON, MH_NATURAL, -3, + 800, 10, MONS_GIANT_LIZARD, MONS_KOMODO_DRAGON, MH_NATURAL, -3, { 30, 0, 0, 0 }, { 8, 3, 5, 0 }, 7, 8, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_HISS, I_REPTILE, diff --git a/crawl-ref/source/mon-pick.cc b/crawl-ref/source/mon-pick.cc index f4a3446230..79fc29f1fc 100644 --- a/crawl-ref/source/mon-pick.cc +++ b/crawl-ref/source/mon-pick.cc @@ -46,6 +46,8 @@ static int mons_tartarus_level(int mcls); static int mons_tartarus_rare(int mcls); static int mons_tomb_level(int mcls); static int mons_tomb_rare(int mcls); +static int mons_caverns_level(int mcls); +static int mons_caverns_rare(int mcls); /* ******************* BEGIN EXTERNAL FUNCTIONS ******************* */ int branch_depth(int branch) @@ -116,7 +118,8 @@ int mons_level(int mcls) (you.where_are_you == BRANCH_ELVEN_HALLS) ? mons_hallelf_level : (you.where_are_you == BRANCH_TOMB) ? mons_tomb_level : (you.where_are_you == BRANCH_SWAMP) ? mons_swamp_level : - (you.where_are_you == BRANCH_VAULTS) ? mons_standard_level + (you.where_are_you == BRANCH_VAULTS) ? mons_standard_level : + (you.where_are_you == BRANCH_CAVERNS) ? mons_caverns_level : mons_standard_level); monster_level = fnc_level(mcls); @@ -153,7 +156,8 @@ int mons_rarity(int mcls) (you.where_are_you == BRANCH_ELVEN_HALLS) ? mons_hallelf_rare : (you.where_are_you == BRANCH_TOMB) ? mons_tomb_rare : (you.where_are_you == BRANCH_SWAMP) ? mons_swamp_rare : - (you.where_are_you == BRANCH_VAULTS) ? mons_standard_rare + (you.where_are_you == BRANCH_VAULTS) ? mons_standard_rare : + (you.where_are_you == BRANCH_CAVERNS) ? mons_caverns_rare : mons_standard_rare); monster_rarity = fnc_rarity(mcls); @@ -188,6 +192,7 @@ bool mons_abyss(int mcls) case MONS_FLAYED_GHOST: case MONS_FLYING_SKULL: case MONS_FREEZING_WRAITH: + case MONS_DEATH_DRAKE: case MONS_FUNGUS: case MONS_GIANT_EYEBALL: case MONS_GIANT_ORANGE_BRAIN: @@ -539,11 +544,12 @@ static int mons_dis_level(int mcls) case MONS_FLAYED_GHOST: case MONS_FREEZING_WRAITH: + case MONS_DEATH_DRAKE: case MONS_HAIRY_DEVIL: case MONS_IRON_DEVIL: case MONS_VAMPIRE: case MONS_WRAITH: - mlev += 4; + mlev += 3; break; case MONS_BLUE_DEVIL: @@ -1092,6 +1098,7 @@ static int mons_tartarus_rare(int mcls) case MONS_IMP: case MONS_SHADOW_DRAGON: + case MONS_DEATH_DRAKE: return 20; case MONS_RED_DEVIL: @@ -2186,6 +2193,7 @@ static int mons_hallzot_rare(int mcls) case MONS_SKELETAL_DRAGON: return 40; case MONS_SHADOW_DRAGON: + case MONS_DEATH_DRAKE: return 30; case MONS_DEEP_ELF_ANNIHILATOR: case MONS_DEEP_ELF_DEATH_MAGE: @@ -2204,6 +2212,68 @@ static int mons_hallzot_rare(int mcls) } } // end mons_hallzot_rare() +static int mons_caverns_level( int mcls ) +{ + + int mlev = you.branch_stairs[STAIRS_CAVERNS] + 1; + + switch (mcls) + { + case MONS_YELLOW_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + mlev++; + break; + + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_KNIGHT: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_SHIFTER: + mlev += 3; + break; + + default: + mlev += 99; + break; + } + + return (mlev); +} + +static int mons_caverns_rare( int mcls ) +{ + switch (mcls) + { + case MONS_YELLOW_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_KNIGHT: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_SHIFTER: + return (500); + + default: + return (0); + } +} + static int mons_standard_level(int mcls) { switch (mcls) @@ -2345,6 +2415,14 @@ static int mons_standard_level(int mcls) case MONS_GARGOYLE: case MONS_GIANT_AMOEBA: case MONS_KOBOLD_DEMONOLOGIST: + case MONS_YELLOW_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: return 18; case MONS_GIANT_SLUG: @@ -2391,6 +2469,13 @@ static int mons_standard_level(int mcls) case MONS_REDBACK: case MONS_SPHINX: case MONS_VAPOUR: + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_KNIGHT: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_SHIFTER: return 22; case MONS_ORC_SORCERER: @@ -2631,6 +2716,13 @@ static int mons_standard_rare(int mcls) case MONS_RED_WASP: case MONS_SIMULACRUM_SMALL: case MONS_SIMULACRUM_LARGE: + case MONS_YELLOW_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_WHITE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_PALE_DRACONIAN: + case MONS_GREEN_DRACONIAN: return 25; case MONS_BUTTERFLY: @@ -2647,6 +2739,14 @@ static int mons_standard_rare(int mcls) case MONS_STORM_DRAGON: case MONS_VERY_UGLY_THING: case MONS_WIZARD: + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_KNIGHT: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_SHIFTER: + case MONS_MOTTLED_DRACONIAN: return 20; case MONS_BORING_BEETLE: diff --git a/crawl-ref/source/mon-spll.h b/crawl-ref/source/mon-spll.h index 4799b4e2db..03d2f2fdcc 100644 --- a/crawl-ref/source/mon-spll.h +++ b/crawl-ref/source/mon-spll.h @@ -355,7 +355,7 @@ MS_SUMMON_DEMON }, { MST_GREEN_DEATH, - MS_POISON_BLAST, + MS_POISON_ARROW, MS_POISON_BLAST, MS_NO_SPELL, MS_VENOM_BOLT, @@ -443,7 +443,7 @@ MS_NO_SPELL }, { MST_GLOORX_VLOQ, - MS_POISON_BLAST, + MS_POISON_ARROW, MS_SLOW, MS_SUMMON_DEMON, MS_NEGATIVE_BOLT, @@ -519,7 +519,7 @@ MS_CRYSTAL_SPEAR, MS_BLINK, MS_IRON_BOLT, - MS_POISON_BLAST, + MS_POISON_ARROW, MS_TELEPORT }, { MST_DEEP_ELF_SORCERER, @@ -558,7 +558,7 @@ MS_VENOM_BOLT, MS_ORB_ENERGY, MS_HASTE, - MS_VENOM_BOLT, + MS_POISON_ARROW, MS_TELEPORT_OTHER, MS_TELEPORT }, @@ -730,5 +730,44 @@ MS_NO_SPELL, MS_NO_SPELL }, + { MST_MYSTIC, + MS_BRAIN_FEED, + MS_SMITE, + MS_INVIS, + MS_CONFUSE, + MS_PARALYSIS, + MS_HEAL }, + + { MST_DEATH_DRAKE, + MS_MIASMA, + MS_MIASMA, + MS_NO_SPELL, + MS_MIASMA, + MS_MIASMA, + MS_NO_SPELL }, + + { MST_DRAC_SCORCHER, + MS_FIRE_BOLT, + MS_STICKY_FLAME, + MS_NO_SPELL, + MS_FIREBALL, + MS_HELLFIRE, + MS_HELLFIRE_BURST }, + + { MST_DRAC_CALLER, + MS_NO_SPELL, + MS_SUMMON_LIZARDS, + MS_SUMMON_LIZARDS, + MS_NO_SPELL, + MS_NO_SPELL, + MS_SUMMON_LIZARDS }, + + { MST_DRAC_SHIFTER, + MS_NO_SPELL, + MS_BLINK_OTHER, + MS_BLINK, + MS_NO_SPELL, + MS_BLINK_OTHER, + MS_CONTROLLED_BLINK }, #endif diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index eeb629802b..f4e402219a 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -30,6 +30,7 @@ #include "debug.h" #include "itemname.h" +#include "itemprop.h" #include "mstuff2.h" #include "player.h" #include "randart.h" @@ -117,7 +118,7 @@ static monsterentry *seekmonster(int p_monsterid); #define smc seekmonster(mc) /* ******************** BEGIN PUBLIC FUNCTIONS ******************** */ -void mons_init(FixedVector < unsigned short, 1000 > &colour) +void init_monsters(FixedVector < unsigned short, 1000 > &colour) { unsigned int x; // must be unsigned to match size_t {dlb} @@ -190,12 +191,12 @@ static int scan_mon_inv_randarts( struct monsters *mon, int ra_prop ) return (ret); } -int mons_holiness(const monsters *mons) +mon_holy_type mons_holiness(const monsters *mon) { - return (mons_holiness(mons->type)); + return (mons_class_holiness(mon->type)); } -int mons_holiness(int mc) +mon_holy_type mons_class_holiness(int mc) { return (smc->holiness); } // end mons_holiness() @@ -217,7 +218,7 @@ bool invalid_monster(const monsters *mons) bool mons_is_mimic( int mc ) { - return (mons_charclass( mc ) == MONS_GOLD_MIMIC); + return (mons_species( mc ) == MONS_GOLD_MIMIC); } bool mons_is_demon( int mc ) @@ -225,7 +226,7 @@ bool mons_is_demon( int mc ) const int show_char = mons_char( mc ); // Not every demonic monster is a demon (ie hell hog, hell hound) - if (mons_holiness( mc ) == MH_DEMONIC + if (mons_class_holiness( mc ) == MH_DEMONIC && (isdigit( show_char ) || show_char == '&')) { return (true); @@ -276,18 +277,33 @@ int mons_weight(int mc) return (smc->weight); } // end mons_weight() - -int mons_corpse_thingy(int mc) +corpse_effect_type mons_corpse_effect(int mc) { return (smc->corpse_thingy); -} // end mons_corpse_thingy() +} // end mons_corpse_effect() + +monster_type mons_species( int mc ) +{ + return (smc->species); +} // end mons_species() -int mons_charclass(int mc) +monster_type mons_genus( int mc ) { - return (smc->charclass); -} // end mons_charclass() + return (smc->genus); +} + +monster_type draco_subspecies( const monsters *mon ) +{ + ASSERT( mons_genus( mon->type ) == MONS_DRACONIAN ); + + monster_type ret = mons_species( mon->type ); + if (ret == MONS_DRACONIAN && mon->type != MONS_DRACONIAN) + ret = static_cast<monster_type>( mon->number ); + + return (ret); +} int mons_shouts(int mc) { @@ -303,6 +319,7 @@ bool mons_is_unique( int mc ) { if (mc <= MONS_PROGRAM_BUG || (mc >= MONS_NAGA_MAGE && mc <= MONS_ROYAL_JELLY) + || (mc >= MONS_DRACONIAN && mc <= MONS_DRACONIAN_SCORCHER) || (mc >= MONS_ANCIENT_LICH && (mc != MONS_PLAYER_GHOST && mc != MONS_PANDEMONIUM_DEMON))) { @@ -482,7 +499,7 @@ int mons_res_elec( struct monsters *mon ) bool mons_res_asphyx( const monsters *mon ) { - const int holiness = mons_holiness( mon->type ); + const int holiness = mons_holiness( mon ); return (holiness == MH_UNDEAD || holiness == MH_DEMONIC || holiness == MH_NONLIVING); @@ -620,11 +637,12 @@ int mons_res_negative_energy( struct monsters *mon ) { int mc = mon->type; - if (mons_holiness( mon->type ) == MH_UNDEAD - || mons_holiness( mon->type ) == MH_DEMONIC - || mons_holiness( mon->type ) == MH_NONLIVING - || mons_holiness( mon->type ) == MH_PLANT - || mon->type == MONS_SHADOW_DRAGON) + if (mons_holiness(mon) == MH_UNDEAD + || mons_holiness(mon) == MH_DEMONIC + || mons_holiness(mon) == MH_NONLIVING + || mons_holiness(mon) == MH_PLANT + || mon->type == MONS_SHADOW_DRAGON + || mon->type == MONS_DEATH_DRAKE) { return (3); // to match the value for players } @@ -647,6 +665,26 @@ int mons_res_negative_energy( struct monsters *mon ) return (u); } // end mons_res_negative_energy() +bool mons_is_evil( const monsters *mon ) +{ + return (mons_class_flag( mon->type, M_EVIL )); +} + +bool mons_is_unholy( const monsters *mon ) +{ + const mon_holy_type holy = mons_holiness( mon ); + + return (holy == MH_UNDEAD || holy == MH_DEMONIC); +} + +bool mons_has_lifeforce( const monsters *mon ) +{ + const int holy = mons_holiness( mon ); + + return (holy == MH_NATURAL || holy == MH_PLANT); + // && !mons_has_ench( mon, ENCH_PETRIFY )); +} + int mons_skeleton(int mc) { if (mons_zombie_size(mc) == 0 @@ -1170,7 +1208,7 @@ const char *monam( int mons_num, int mons, bool vis, char desc, int mons_wpn ) return (gmo_n); } // end monam() -void moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]) +const char *moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]) { glog[0] = '\0'; @@ -1193,7 +1231,7 @@ void moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]) } strcpy(gmon_name, glog); - return; + return (glog); } if (!mons_is_unique( mons_num )) @@ -1237,6 +1275,8 @@ void moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]) } strcat(glog, gmon_name); + + return (glog); } // end moname() /* ********************* END PUBLIC FUNCTIONS ********************* */ @@ -1329,6 +1369,11 @@ bool mons_friendly(const monsters *m) return (m->attitude == ATT_FRIENDLY || mons_has_ench(m, ENCH_CHARM)); } +bool mons_is_paralysed(const monsters *m) +{ + return (m->speed_increment == 0); +} + bool mons_is_confused(const monsters *m) { return (mons_has_ench(m, ENCH_CONFUSION) && @@ -1434,13 +1479,13 @@ bool mons_should_fire(struct bolt &beam) return (false); // if we either hit no friends, or monster too dumb to care - if (beam.fr_count == 0 || !beam.smartMonster) + if (beam.fr_count == 0 || !beam.smart_monster) return (true); // only fire if they do acceptably low collateral damage // the default for this is 50%; in other words, don't // hit a foe unless you hit 2 or fewer friends. - if (beam.foe_power >= (beam.foeRatio * beam.fr_power) / 100) + if (beam.foe_power >= (beam.foe_ratio * beam.fr_power) / 100) return (true); return (false); @@ -1652,6 +1697,7 @@ bool ms_requires_tracer(int monspell) case MS_IRON_BOLT: case MS_LIGHTNING_BOLT: case MS_MARSH_GAS: + case MS_MIASMA: case MS_METAL_SPLINTERS: case MS_MMISSILE: case MS_NEGATIVE_BOLT: @@ -1659,6 +1705,7 @@ bool ms_requires_tracer(int monspell) case MS_PAIN: case MS_PARALYSIS: case MS_POISON_BLAST: + case MS_POISON_ARROW: case MS_POISON_SPLASH: case MS_QUICKSILVER_BOLT: case MS_SLOW: @@ -2067,7 +2114,8 @@ bool monster_can_swap(const monsters *m) // Efreet and fire elementals are disqualified because they leave behind // clouds of flame. - if (m->type == MONS_EFREET || m->type == MONS_FIRE_ELEMENTAL) + if (m->type == MONS_EFREET || m->type == MONS_FIRE_ELEMENTAL + || m->type == MONS_ROTTING_DEVIL) return (false); int mchar = me->showchar; diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index a74abfa5a3..16e1d451d5 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -74,9 +74,10 @@ struct monsterentry // Note that this may make draining attacks less attractive (LRH) char exp_mod; - unsigned short charclass; // + monster_type genus, // "team" the monster plays for + species; // corpse type of the monster - char holiness; // -1=holy,0=normal,1=undead,2=very very evil + mon_holy_type holiness; // -1=holy,0=normal,1=undead,2=very very evil short resist_magic; // (positive is ??) // max damage in a turn is total of these four? @@ -101,7 +102,7 @@ struct monsterentry short sec; // not used (250) most o/t time // eating the corpse: 1=clean,2=might be contaminated,3=poison,4=very bad - char corpse_thingy; + corpse_effect_type corpse_thingy; // 0=no zombie, 1=small zombie (z) 107, 2=_BIG_ zombie (Z) 108 char zombie_size; // 0-12: see above, -1=random one of (0-7) @@ -120,7 +121,7 @@ struct monsterentry /* *********************************************************************** * called from: acr * *********************************************************************** */ -void mons_init( FixedVector<unsigned short, 1000>& colour ); +void init_monsters( FixedVector<unsigned short, 1000>& colour ); // last updated 12may2000 {dlb} /* *********************************************************************** @@ -202,17 +203,9 @@ int mons_damage(int mc, int rt); // last updated 12may2000 {dlb} /* *********************************************************************** - * called from: dungeon - fight - monstuff - spells4 - * *********************************************************************** */ -int mons_charclass(int mcls); - - -// last updated 12may2000 {dlb} -/* *********************************************************************** * called from: food - spells4 * *********************************************************************** */ -int mons_corpse_thingy(int mclass); - +corpse_effect_type mons_corpse_effect(int mc); // last updated 12may2000 {dlb} /* *********************************************************************** @@ -226,8 +219,8 @@ bool mons_class_flag(int mc, int bf); * called from: beam - effects - fight - monstuff - mstuff2 - spells2 - * spells3 - spells4 * *********************************************************************** */ -int mons_holiness(int mclass); -int mons_holiness(const monsters *); +mon_holy_type mons_class_holiness(int mclass); +mon_holy_type mons_holiness(const monsters *); bool mons_is_mimic( int mc ); bool mons_is_demon( int mc ); @@ -348,7 +341,7 @@ void define_monster(int mid); /* *********************************************************************** * called from: debug - itemname - mon-util * *********************************************************************** */ -void moname(int mcl, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]); +const char *moname(int mcl, bool vis, char descrip, char glog[ ITEMNAME_SIZE ]); // last updated 12may2000 {dlb} @@ -413,6 +406,11 @@ bool mons_is_confused(const monsters *m); bool mons_is_fleeing(const monsters *m); bool mons_is_sleeping(const monsters *m); bool mons_is_batty(const monsters *m); +bool mons_is_evil( const monsters *mon ); +bool mons_is_unholy( const monsters *mon ); +bool mons_has_lifeforce( const monsters *mon ); +monster_type mons_genus( int mc ); +monster_type mons_species( int mc ); int mons_has_ench( const monsters *mon, unsigned int ench, unsigned int ench2 = ENCH_NONE ); @@ -433,7 +431,9 @@ bool mons_is_stationary(const monsters *mons); bool invalid_monster(const monsters *mons); bool monster_can_swap(const monsters *m); +bool mons_is_paralysed(const monsters *m); bool monster_senior(const monsters *first, const monsters *second); +monster_type draco_subspecies( const monsters *mon ); #endif diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 9ed276c03e..0d1013e3f2 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -771,6 +771,34 @@ static int choose_band( int mon_type, int power, int &band_size ) band = BAND_SKELETAL_WARRIORS; // skeletal warrior band_size = 2 + random2(3); break; + // Journey -- Added Draconian Packs + case MONS_WHITE_DRACONIAN: + case MONS_RED_DRACONIAN: + case MONS_PURPLE_DRACONIAN: + case MONS_MOTTLED_DRACONIAN: + case MONS_YELLOW_DRACONIAN: + case MONS_BLACK_DRACONIAN: + case MONS_GREEN_DRACONIAN: + case MONS_PALE_DRACONIAN: + if (power > 18 && one_chance_in(3)) + { + band = BAND_DRACONIAN; + band_size = 2 + random2(3); + } + break; + case MONS_DRACONIAN_CALLER: + case MONS_DRACONIAN_MONK: + case MONS_DRACONIAN_SCORCHER: + case MONS_DRACONIAN_KNIGHT: + case MONS_DRACONIAN_ANNIHILATOR: + case MONS_DRACONIAN_ZEALOT: + case MONS_DRACONIAN_SHIFTER: + if (power > 20) + { + band = BAND_DRACONIAN; + band_size = 3 + random2(4); + } + break; } // end switch if (band != BAND_NO_BAND && band_size == 0) @@ -1002,6 +1030,27 @@ static int band_member(int band, int power) case BAND_SKELETAL_WARRIORS: mon_type = MONS_SKELETAL_WARRIOR; break; + case BAND_DRACONIAN: + { + const int temp_rand = random2( (power < 24) ? 24 : 37 ); + mon_type = + ((temp_rand > 35) ? MONS_DRACONIAN_CALLER : // 1 in 34 + (temp_rand > 33) ? MONS_DRACONIAN_KNIGHT : // 2 in 34 + (temp_rand > 31) ? MONS_DRACONIAN_MONK : // 2 in 34 + (temp_rand > 29) ? MONS_DRACONIAN_SHIFTER : // 2 in 34 + (temp_rand > 27) ? MONS_DRACONIAN_ANNIHILATOR :// 2 in 34 + (temp_rand > 25) ? MONS_DRACONIAN_SCORCHER : // 2 in 34 + (temp_rand > 23) ? MONS_DRACONIAN_ZEALOT : // 2 in 34 + (temp_rand > 20) ? MONS_YELLOW_DRACONIAN : // 3 in 34 + (temp_rand > 17) ? MONS_GREEN_DRACONIAN : // 3 in 34 + (temp_rand > 14) ? MONS_BLACK_DRACONIAN : // 3 in 34 + (temp_rand > 11) ? MONS_WHITE_DRACONIAN : // 3 in 34 + (temp_rand > 8) ? MONS_PALE_DRACONIAN : // 3 in 34 + (temp_rand > 5) ? MONS_PURPLE_DRACONIAN : // 3 in 34 + (temp_rand > 2) ? MONS_MOTTLED_DRACONIAN : // 3 in 34 + MONS_RED_DRACONIAN ); // 3 in 34 + break; + } } return (mon_type); @@ -1304,3 +1353,53 @@ int summon_any_demon(char demon_class) return summoned; } // end summon_any_demon() + +monster_type rand_dragon( dragon_class_type type ) +{ + monster_type summoned = MONS_PROGRAM_BUG; + int temp_rand; + + switch (type) + { + case DRAGON_LIZARD: + temp_rand = random2(100); + summoned = ((temp_rand > 85) ? MONS_GIANT_GECKO : + (temp_rand > 59) ? MONS_GIANT_LIZARD : + (temp_rand > 34) ? MONS_GIANT_IGUANA : + (temp_rand > 22) ? MONS_GILA_MONSTER : + (temp_rand > 11) ? MONS_KOMODO_DRAGON : + (temp_rand > 8) ? MONS_FIREDRAKE : + (temp_rand > 2) ? MONS_SWAMP_DRAKE + : MONS_DEATH_DRAKE ); + break; + + case DRAGON_DRACONIAN: + temp_rand = random2(70); + summoned = ((temp_rand > 60) ? MONS_YELLOW_DRACONIAN : + (temp_rand > 50) ? MONS_BLACK_DRACONIAN : + (temp_rand > 40) ? MONS_PALE_DRACONIAN : + (temp_rand > 30) ? MONS_GREEN_DRACONIAN : + (temp_rand > 20) ? MONS_PURPLE_DRACONIAN : + (temp_rand > 10) ? MONS_RED_DRACONIAN + : MONS_WHITE_DRACONIAN); + break; + + case DRAGON_DRAGON: + temp_rand = random2(90); + summoned = ((temp_rand > 80) ? MONS_MOTTLED_DRAGON : + (temp_rand > 70) ? MONS_LINDWURM : + (temp_rand > 60) ? MONS_STORM_DRAGON : + (temp_rand > 50) ? MONS_MOTTLED_DRAGON : + (temp_rand > 40) ? MONS_STEAM_DRAGON : + (temp_rand > 30) ? MONS_DRAGON : + (temp_rand > 20) ? MONS_ICE_DRAGON : + (temp_rand > 10) ? MONS_SWAMP_DRAGON + : MONS_SHADOW_DRAGON); + break; + + default: + break; + } + + return (summoned); +} diff --git a/crawl-ref/source/monplace.h b/crawl-ref/source/monplace.h index f2fde75111..ba45fe36d2 100644 --- a/crawl-ref/source/monplace.h +++ b/crawl-ref/source/monplace.h @@ -78,4 +78,6 @@ bool place_monster( int &id, int mon_type, int power, char behaviour, int proximity = PROX_ANYWHERE, int extra = 250, int dur = 0 ); +monster_type rand_dragon( dragon_class_type type ); + #endif // MONPLACE_H diff --git a/crawl-ref/source/monspeak.cc b/crawl-ref/source/monspeak.cc index 09b348867d..dd1b9b6ad8 100644 --- a/crawl-ref/source/monspeak.cc +++ b/crawl-ref/source/monspeak.cc @@ -114,7 +114,7 @@ bool mons_speaks(struct monsters *monster) if (mons_has_ench(monster, ENCH_CONFUSION)) { - if (mons_holiness( monster->type ) == MH_DEMONIC + if (mons_holiness( monster ) == MH_DEMONIC && monster->type != MONS_IMP) { return (false); @@ -259,7 +259,7 @@ bool mons_speaks(struct monsters *monster) } else if (monster->behaviour == BEH_FLEE) { - if (mons_holiness( monster->type ) == MH_DEMONIC + if (mons_holiness( monster ) == MH_DEMONIC && monster->type != MONS_IMP) { return (false); @@ -378,7 +378,7 @@ bool mons_speaks(struct monsters *monster) } else if (mons_friendly(monster)) { - if (mons_holiness( monster->type ) == MH_DEMONIC + if (mons_holiness( monster ) == MH_DEMONIC && monster->type != MONS_IMP) { return (false); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index cd5d36e5e2..0bb43b9de2 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -36,6 +36,7 @@ #include "fight.h" #include "itemname.h" #include "items.h" +#include "itemprop.h" #include "misc.h" #include "monplace.h" #include "monspeak.h" @@ -282,7 +283,7 @@ static void monster_drop_ething(struct monsters *monster, static void place_monster_corpse(struct monsters *monster) { - int corpse_class = mons_charclass(monster->type); + int corpse_class = mons_species(monster->type); if (mons_has_ench(monster, ENCH_SHAPESHIFTER)) corpse_class = MONS_SHAPESHIFTER; @@ -450,15 +451,15 @@ void monster_die(struct monsters *monster, char killer, int i) { if (you.duration[DUR_PRAYER]) { - if (mons_holiness(monster->type) == MH_NATURAL) + if (mons_holiness(monster) == MH_NATURAL) did_god_conduct(DID_DEDICATED_KILL_LIVING, monster->hit_dice); - if (mons_holiness(monster->type) == MH_UNDEAD) + if (mons_holiness(monster) == MH_UNDEAD) did_god_conduct(DID_DEDICATED_KILL_UNDEAD, monster->hit_dice); - if (mons_holiness(monster->type) == MH_DEMONIC) + if (mons_holiness(monster) == MH_DEMONIC) did_god_conduct(DID_DEDICATED_KILL_DEMON, monster->hit_dice); @@ -473,7 +474,7 @@ void monster_die(struct monsters *monster, char killer, int i) monster->hit_dice); } - if (mons_holiness(monster->type) == MH_HOLY) + if (mons_holiness(monster) == MH_HOLY) did_god_conduct(DID_KILL_ANGEL, monster->hit_dice); } @@ -505,12 +506,12 @@ void monster_die(struct monsters *monster, char killer, int i) } if (you.duration[DUR_DEATH_CHANNEL] - && mons_holiness(monster->type) == MH_NATURAL - && mons_weight(mons_charclass(monster->type))) + && mons_holiness(monster) == MH_NATURAL + && mons_weight(mons_species(monster->type))) { if (create_monster( MONS_SPECTRAL_THING, 0, BEH_FRIENDLY, monster->x, monster->y, you.pet_target, - mons_charclass(monster->type)) != -1) + mons_species(monster->type)) != -1) { if (death_message) mpr("A glowing mist starts to gather..."); @@ -537,8 +538,8 @@ void monster_die(struct monsters *monster, char killer, int i) gain_exp(exper_value( monster ) / 2 + 1); - int targ_holy = mons_holiness(monster->type), - attacker_holy = mons_holiness(menv[i].type); + int targ_holy = mons_holiness(monster), + attacker_holy = mons_holiness(&menv[i]); if (attacker_holy == MH_UNDEAD) { @@ -692,7 +693,7 @@ void monster_die(struct monsters *monster, char killer, int i) if (mons_has_ench(monster, ENCH_ABJ_I, ENCH_ABJ_VI)) { - if (mons_weight(mons_charclass(monster->type))) + if (mons_weight(mons_species(monster->type))) { if (monster->type == MONS_SIMULACRUM_SMALL || monster->type == MONS_SIMULACRUM_LARGE) @@ -784,7 +785,7 @@ static bool jelly_divide(struct monsters * parent) { // 10-50 for now - must take clouds into account: if (mgrd[parent->x + jex][parent->y + jey] == NON_MONSTER - && grd[parent->x + jex][parent->y + jey] > DNGN_LAST_SOLID_TILE + && !grid_is_solid(grd[parent->x + jex][parent->y + jey]) && (parent->x + jex != you.x_pos || parent->y + jey != you.y_pos)) { foundSpot = true; @@ -872,12 +873,12 @@ static bool valid_morph( struct monsters *monster, int new_mclass ) unsigned char current_tile = grd[monster->x][monster->y]; // morph targets are _always_ "base" classes, not derived ones. - new_mclass = mons_charclass(new_mclass); + new_mclass = mons_species(new_mclass); /* various inappropriate polymorph targets */ - if (mons_holiness( new_mclass ) != mons_holiness( monster->type ) + if (mons_class_holiness( new_mclass ) != mons_holiness( monster ) || mons_class_flag( new_mclass, M_NO_EXP_GAIN ) // not helpless - || new_mclass == mons_charclass( monster->type ) // must be different + || new_mclass == mons_species( monster->type ) // must be different || new_mclass == MONS_PROGRAM_BUG || new_mclass == MONS_SHAPESHIFTER || new_mclass == MONS_GLOWING_SHAPESHIFTER @@ -943,7 +944,7 @@ bool monster_polymorph( struct monsters *monster, int targetc, int power ) targetc = random2( NUM_MONSTERS ); // valid targets are always base classes - targetc = mons_charclass( targetc ); + targetc = mons_species( targetc ); target_power = mons_power( targetc ); @@ -1266,7 +1267,7 @@ void print_wounds(struct monsters *monster) bool wounded_damaged(int wound_class) { // this schema needs to be abstracted into real categories {dlb}: - const int holy = mons_holiness(wound_class); + const int holy = mons_class_holiness(wound_class); if (holy == MH_UNDEAD || holy == MH_NONLIVING || holy == MH_PLANT) return (true); @@ -2325,6 +2326,10 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) FixedArray < unsigned int, 19, 19 > show; + const monster_type mclass = (mons_genus( monster->type ) == MONS_DRACONIAN) + ? draco_subspecies( monster ) + : static_cast<monster_type>( monster->type ); + if (!mons_near( monster ) || monster->behaviour == BEH_SLEEP || mons_has_ench( monster, ENCH_SUBMERGED )) @@ -2334,7 +2339,7 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) // losight(show, grd, you.x_pos, you.y_pos); - switch (monster->type) + switch (mclass) { case MONS_BALL_LIGHTNING: if (monster->attitude == ATT_HOSTILE @@ -2373,7 +2378,7 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) if (tx < 0 || tx > GXM || ty < 0 || ty > GYM) continue; - if (grd[tx][ty] > DNGN_LAST_SOLID_TILE) + if (!grid_is_solid(grd[tx][ty])) { monster->hit_points = -1; used = true; @@ -2439,7 +2444,7 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) beem.aux_source = "bolt of electricity"; beem.range = 4; beem.rangeMax = 13; - beem.isBeam = true; + beem.is_beam = true; // fire tracer fire_tracer(monster, beem); @@ -2455,6 +2460,7 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) case MONS_ACID_BLOB: case MONS_OKLOB_PLANT: + case MONS_YELLOW_DRACONIAN: if (mons_has_ench(monster, ENCH_CONFUSION)) break; @@ -2560,7 +2566,7 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) beem.flavour = BEAM_MISSILE; beem.thrower = KILL_MON; beem.aux_source = "volley of spikes"; - beem.isBeam = false; + beem.is_beam = false; // fire tracer fire_tracer(monster, beem); @@ -2583,6 +2589,8 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) case MONS_LINDWURM: case MONS_FIREDRAKE: case MONS_XTAHUA: + case MONS_WHITE_DRACONIAN: + case MONS_RED_DRACONIAN: if (!mons_player_visible( monster )) break; @@ -2600,7 +2608,8 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) // good idea? if (mons_should_fire(beem)) { - simple_monster_message(monster, " breathes."); + simple_monster_message(monster, " breathes.", + MSGCH_MONSTER_SPELL); fire_beam(beem); mmov_x = 0; mmov_y = 0; @@ -2608,6 +2617,9 @@ static bool handle_special_ability(struct monsters *monster, bolt & beem) } } break; + + default: + break; } return (used); @@ -2640,9 +2652,9 @@ static bool handle_potion(struct monsters *monster, bolt & beem) case POT_HEALING: case POT_HEAL_WOUNDS: if (monster->hit_points <= monster->max_hit_points / 2 - && mons_holiness(monster->type) != MH_UNDEAD - && mons_holiness(monster->type) != MH_NONLIVING - && mons_holiness(monster->type) != MH_PLANT) + && mons_holiness(monster) != MH_UNDEAD + && mons_holiness(monster) != MH_NONLIVING + && mons_holiness(monster) != MH_PLANT) { simple_monster_message(monster, " drinks a potion."); @@ -2847,12 +2859,12 @@ static bool handle_wand(struct monsters *monster, bolt &beem) // set up the beam int power = 30 + monster->hit_dice; - struct SBeam theBeam = mons_spells(mzap, power); + bolt theBeam = mons_spells(mzap, power); // XXX: ugly hack this: static char wand_buff[ ITEMNAME_SIZE ]; - strcpy( beem.beam_name, theBeam.name.c_str() ); + strcpy( beem.beam_name, theBeam.beam_name ); beem.beam_source = monster_index(monster); beem.source_x = monster->x; beem.source_y = monster->y; @@ -2864,8 +2876,8 @@ static bool handle_wand(struct monsters *monster, bolt &beem) beem.hit = theBeam.hit; beem.type = theBeam.type; beem.flavour = theBeam.flavour; - beem.thrower = theBeam.thrown; - beem.isBeam = theBeam.isBeam; + beem.thrower = theBeam.thrower; + beem.is_beam = theBeam.is_beam; item_def item = mitm[ monster->inv[MSLOT_WAND] ]; @@ -2960,7 +2972,7 @@ static bool handle_wand(struct monsters *monster, bolt &beem) // charge expenditure {dlb} mitm[monster->inv[MSLOT_WAND]].plus--; - beem.isTracer = false; + beem.is_tracer = false; fire_beam( beem ); return (true); @@ -2970,6 +2982,46 @@ static bool handle_wand(struct monsters *monster, bolt &beem) return (false); } // end handle_wand() +static int get_draconian_breath_spell( struct monsters *monster ) +{ + int draco_breath = MS_NO_SPELL; + + if (mons_genus( monster->type ) == MONS_DRACONIAN) + { + switch (draco_subspecies( monster )) + { + case MONS_BLACK_DRACONIAN: + draco_breath = MS_LIGHTNING_BOLT; + break; + + case MONS_PALE_DRACONIAN: + draco_breath = MS_STEAM_BALL; + break; + + case MONS_GREEN_DRACONIAN: + draco_breath = MS_POISON_BLAST; + break; + + case MONS_PURPLE_DRACONIAN: + draco_breath = MS_ORB_ENERGY; + break; + + case MONS_MOTTLED_DRACONIAN: + draco_breath = MS_STICKY_FLAME; + break; + + case MONS_DRACONIAN: + case MONS_YELLOW_DRACONIAN: // already handled as ability + case MONS_RED_DRACONIAN: // already handled as ability + case MONS_WHITE_DRACONIAN: // already handled as ability + default: + break; + } + } + + return (draco_breath); +} + //--------------------------------------------------------------- // // handle_spell @@ -2982,10 +3034,12 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) { bool monsterNearby = mons_near(monster); bool finalAnswer = false; // as in: "Is that your...?" {dlb} + const int draco_breath = get_draconian_breath_spell(monster); // yes, there is a logic to this ordering {dlb}: if (monster->behaviour == BEH_SLEEP - || !mons_class_flag( monster->type, M_SPELLCASTER ) + || (!mons_class_flag(monster->type, M_SPELLCASTER) + && draco_breath == MS_NO_SPELL) || mons_has_ench( monster, ENCH_SUBMERGED )) { return (false); @@ -3105,7 +3159,7 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) } // If no useful spells... cast no spell. - if (num_no_spell == 6) + if (num_no_spell == 6 && draco_breath == MS_NO_SPELL) return (false); // up to four tries to pick a spell. @@ -3179,6 +3233,12 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) } } + if (spell_cast == MS_NO_SPELL && draco_breath != MS_NO_SPELL) + { + spell_cast = draco_breath; + finalAnswer = true; + } + // should the monster *still* not have a spell, well, too bad {dlb}: if (spell_cast == MS_NO_SPELL) return (false); @@ -3210,6 +3270,20 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) switch (monster->type) { default: + if (spell_cast == draco_breath) + { + if (!simple_monster_message(monster, " breathes.", + MSGCH_MONSTER_SPELL)) + { + if (!silenced(monster->x, monster->y) + && !silenced(you.x_pos, you.y_pos)) + { + mpr("You hear a roar.", MSGCH_SOUND); + } + } + break; + } + if (silenced(monster->x, monster->y)) return (false); @@ -3273,6 +3347,7 @@ static bool handle_spell( struct monsters *monster, bolt & beem ) case MONS_SHADOW_DRAGON: case MONS_SWAMP_DRAGON: case MONS_SWAMP_DRAKE: + case MONS_DEATH_DRAKE: case MONS_HELL_HOG: case MONS_SERPENT_OF_HELL: case MONS_QUICKSILVER_DRAGON: @@ -3840,7 +3915,7 @@ static bool handle_pickup(struct monsters *monster) if (quant > max_eat - eaten) quant = max_eat - eaten; - hps_gained += (quant * mass_item( mitm[item] )) / 20 + quant; + hps_gained += (quant * item_mass( mitm[item] )) / 20 + quant; eaten += quant; } else @@ -3910,8 +3985,8 @@ static bool handle_pickup(struct monsters *monster) // wimpy monsters (Kob, gob) shouldn't pick up halberds etc // of course, this also block knives {dlb}: - if ((mons_charclass(monster->type) == MONS_KOBOLD - || mons_charclass(monster->type) == MONS_GOBLIN) + if ((mons_species(monster->type) == MONS_KOBOLD + || mons_species(monster->type) == MONS_GOBLIN) && property( mitm[item], PWPN_HIT ) <= 0) { return (false); @@ -4159,6 +4234,7 @@ static bool mons_can_displace(const monsters *mpusher, const monsters *mpushee) // past, either, but they may be woken up by a crowd trying to // elbow past them, and the wake-up check happens downstream. if (mons_is_confused(mpusher) || mons_is_confused(mpushee) + || mons_is_paralysed(mpusher) || mons_is_paralysed(mpushee) || mons_is_sleeping(mpusher)) return (false); @@ -4704,6 +4780,12 @@ forget_it: 2 + random2(4) ); } + if (monster->type == MONS_ROTTING_DEVIL) + { + place_cloud( CLOUD_MIASMA_MON, monster->x, monster->y, + 2 + random2(3) ); + } + /* this appears to be the real one, ie where the movement occurs: */ monster->x += mmov_x; monster->y += mmov_y; @@ -4885,7 +4967,7 @@ static void mons_in_cloud(struct monsters *monster) case CLOUD_MIASMA_MON: simple_monster_message(monster, " is engulfed in a dark miasma!"); - if (mons_holiness(monster->type) != MH_NATURAL) + if (mons_holiness(monster) != MH_NATURAL) return; poison_monster(monster, (env.cloud[wc].type == CLOUD_MIASMA)); diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index d2e87ede33..2c2dc1d927 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -27,6 +27,7 @@ #include "debug.h" #include "effects.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "misc.h" #include "monplace.h" @@ -509,7 +510,7 @@ void mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cast) { summonik = random2(241); // hmmmm ... {dlb} } - while (mons_holiness(summonik) != MH_UNDEAD); + while (mons_class_holiness(summonik) != MH_UNDEAD); create_monster(summonik, duration, SAME_ATTITUDE(monster), you.x_pos, you.y_pos, monster->foe, 250); @@ -547,6 +548,29 @@ void mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cast) } return; + // Journey -- Added in Summon Lizards and Draconian + case MS_SUMMON_LIZARDS: + if (!mons_friendly( monster ) && !monsterNearby && + monster_abjuration( 1, true ) > 0 && coinflip()) + { + monster_abjuration( monster->hit_dice * 10, false ); + return; + } + + sumcount2 = 1 + random2(3) + random2( monster->hit_dice / 5 + 1 ); + + duration = 2 + monster->hit_dice / 5; + if (duration > 6) + duration = 6; + + for (sumcount = 0; sumcount < sumcount2; sumcount++) + { + create_monster( rand_dragon( DRAGON_LIZARD ), duration, + SAME_ATTITUDE(monster), + monster->x, monster->y, monster->foe, 250 ); + } + break; + case MS_CANTRIP: // Monster spell of uselessness, just prints a message. // This spell exists so that some monsters with really strong @@ -645,6 +669,7 @@ void setup_mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cas case MS_SUMMON_UFETUBUS: case MS_SUMMON_BEAST: // Geryon case MS_SUMMON_UNDEAD: // summon undead around player + case MS_SUMMON_LIZARDS: case MS_TORMENT: case MS_SUMMON_DEMON_GREATER: case MS_CANTRIP: @@ -656,7 +681,7 @@ void setup_mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cas // Need to correct this for power of spellcaster int power = 12 * monster->hit_dice; - struct SBeam theBeam = mons_spells(spell_cast, power); + struct bolt theBeam = mons_spells(spell_cast, power); pbolt.colour = theBeam.colour; pbolt.range = theBeam.range; @@ -666,13 +691,13 @@ void setup_mons_cast(struct monsters *monster, struct bolt &pbolt, int spell_cas pbolt.ench_power = theBeam.ench_power; pbolt.type = theBeam.type; pbolt.flavour = theBeam.flavour; - pbolt.thrower = theBeam.thrown; + pbolt.thrower = theBeam.thrower; pbolt.aux_source = NULL; - strcpy( pbolt.beam_name, theBeam.name.c_str() ); - pbolt.isBeam = theBeam.isBeam; + strcpy( pbolt.beam_name, theBeam.beam_name ); + pbolt.is_beam = theBeam.is_beam; pbolt.source_x = monster->x; pbolt.source_y = monster->y; - pbolt.isTracer = false; + pbolt.is_tracer = false; if (pbolt.beam_name[0] && pbolt.beam_name[0] != '0') pbolt.aux_source = pbolt.beam_name; @@ -744,9 +769,13 @@ void monster_teleport(struct monsters *monster, bool instan) void setup_dragon(struct monsters *monster, struct bolt &pbolt) { + const int type = (mons_genus( monster->type ) == MONS_DRACONIAN) + ? draco_subspecies( monster ) : monster->type; + int scaling = 100; + strcpy(pbolt.beam_name, ptr_monam( monster, DESC_PLAIN )); - switch (monster->type) + switch (type) { case MONS_FIREDRAKE: case MONS_HELL_HOUND: @@ -756,28 +785,54 @@ void setup_dragon(struct monsters *monster, struct bolt &pbolt) strcat(pbolt.beam_name, "'s blast of flame"); pbolt.flavour = BEAM_FIRE; pbolt.colour = RED; - pbolt.aux_source = "blast of flame"; + pbolt.aux_source = "blast of fiery breath"; break; case MONS_ICE_DRAGON: strcat(pbolt.beam_name, "'s blast of cold"); pbolt.flavour = BEAM_COLD; pbolt.colour = WHITE; - pbolt.aux_source = "blast of cold"; + pbolt.aux_source = "blast of icy breath"; + break; + + case MONS_RED_DRACONIAN: + snprintf( pbolt.beam_name, ITEMNAME_SIZE, "%s's searing breath", + ptr_monam( monster, DESC_PLAIN ) ); +#ifdef DEBUG_DIAGNOSTICS + mprf( MSGCH_DIAGNOSTICS, "bolt name: '%s'", pbolt.beam_name ); +#endif + pbolt.flavour = BEAM_FIRE; + pbolt.colour = RED; + pbolt.aux_source = "blast of searing breath"; + scaling = 65; break; + case MONS_WHITE_DRACONIAN: + snprintf( pbolt.beam_name, ITEMNAME_SIZE, "%s's chilling breath", + ptr_monam( monster, DESC_PLAIN ) ); +#ifdef DEBUG_DIAGNOSTICS + mprf( MSGCH_DIAGNOSTICS, "bolt name: '%s'", pbolt.beam_name ); +#endif + pbolt.flavour = BEAM_COLD; + pbolt.colour = WHITE; + pbolt.aux_source = "blast of chilling breath"; + scaling = 65; + break; + default: DEBUGSTR("Bad monster class in setup_dragon()"); + break; } pbolt.range = 4; pbolt.rangeMax = 13; pbolt.damage = dice_def( 3, (monster->hit_dice * 2) ); + pbolt.damage.size = scaling * pbolt.damage.size / 100; pbolt.type = SYM_ZAP; pbolt.hit = 30; pbolt.beam_source = monster_index(monster); pbolt.thrower = KILL_MON; - pbolt.isBeam = true; + pbolt.is_beam = true; } // end setup_dragon(); void setup_generic_throw(struct monsters *monster, struct bolt &pbolt) @@ -790,7 +845,7 @@ void setup_generic_throw(struct monsters *monster, struct bolt &pbolt) pbolt.flavour = BEAM_MISSILE; pbolt.thrower = KILL_MON_MISSILE; pbolt.aux_source = NULL; - pbolt.isBeam = false; + pbolt.is_beam = false; } // decide if something is launched or thrown @@ -920,6 +975,7 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) lnchDamBonus = 0; break; case WPN_BOW: + case WPN_LONGBOW: baseHit = 0; hitMult = 60; damMult = 35; @@ -947,7 +1003,7 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) break; } - baseDam = property( item, PWPN_HIT ); + baseDam = property( item, PWPN_DAMAGE ); // missiles don't have pluses2; use hit bonus ammoDamBonus = ammoHitBonus; @@ -962,7 +1018,7 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) baseHit++; baseDam++; - if (cmp_equip_race(mitm[monster->inv[MSLOT_WEAPON]], ISFLAG_ELVEN)) + if (get_equip_race(mitm[monster->inv[MSLOT_WEAPON]]) == ISFLAG_ELVEN) pbolt.hit++; } @@ -1077,6 +1133,7 @@ bool mons_throw(struct monsters *monster, struct bolt &pbolt, int hand_used) pbolt.damage.size += lnchDamBonus; pbolt.hit += lnchHitBonus; } + scale_dice(pbolt.damage); // decrease inventory fire_beam( pbolt, &item ); @@ -1097,7 +1154,8 @@ void spore_goes_pop(struct monsters *monster) if (monster == NULL) return; - beam.isTracer = false; + beam.is_tracer = false; + beam.is_explosion = true; beam.beam_source = monster_index(monster); beam.type = SYM_BURST; beam.target_x = monster->x; @@ -1133,40 +1191,42 @@ void spore_goes_pop(struct monsters *monster) explosion(beam); } // end spore_goes_pop() -struct SBeam mons_spells( int spell_cast, int power ) +bolt mons_spells( int spell_cast, int power ) { ASSERT(power > 0); - struct SBeam beam; + bolt beam; - beam.name = "****"; // initialize to some bogus values so we can catch problems + strcpy(beam.beam_name, "****"); // initialize to some bogus values so we can catch problems beam.colour = 1000; - beam.range = -1; + beam.range = beam.rangeMax = 8; beam.hit = -1; beam.damage = dice_def( 1, 0 ); beam.ench_power = -1; beam.type = -1; beam.flavour = -1; - beam.thrown = -1; + beam.thrower = -1; + beam.is_beam = false; + beam.is_explosion = false; switch (spell_cast) { case MS_MMISSILE: beam.colour = LIGHTMAGENTA; //inv_colour [throw_2]; - beam.name = "magic dart"; // inv_name [throw_2]); + strcpy(beam.beam_name, "magic dart"); // inv_name [throw_2]); beam.range = 6; beam.rangeMax = 10; beam.damage = dice_def( 3, 4 + (power / 100) ); beam.hit = 1500; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_MMISSILE; - beam.isBeam = false; + beam.is_beam = false; break; case MS_FLAME: beam.colour = RED; - beam.name = "puff of flame"; + strcpy(beam.beam_name, "puff of flame"); beam.range = 6; beam.rangeMax = 10; @@ -1177,14 +1237,14 @@ struct SBeam mons_spells( int spell_cast, int power ) beam.hit = 60; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_FIRE; - beam.isBeam = false; + beam.is_beam = false; break; case MS_FROST: beam.colour = WHITE; - beam.name = "puff of frost"; + strcpy(beam.beam_name, "puff of frost"); beam.range = 6; beam.rangeMax = 10; @@ -1194,422 +1254,461 @@ struct SBeam mons_spells( int spell_cast, int power ) beam.hit = 60; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_COLD; - beam.isBeam = false; + beam.is_beam = false; break; case MS_PARALYSIS: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_PARALYSIS; - beam.thrown = KILL_MON_MISSILE; - beam.isBeam = true; + beam.thrower = KILL_MON_MISSILE; + beam.is_beam = true; break; case MS_SLOW: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_SLOW; - beam.thrown = KILL_MON_MISSILE; - beam.isBeam = true; + beam.thrower = KILL_MON_MISSILE; + beam.is_beam = true; break; case MS_HASTE: // (self) - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_HASTE; - beam.thrown = KILL_MON_MISSILE; - beam.isBeam = true; + beam.thrower = KILL_MON_MISSILE; + beam.is_beam = true; break; case MS_CONFUSE: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_CONFUSION; - beam.thrown = KILL_MON_MISSILE; - beam.isBeam = true; + beam.thrower = KILL_MON_MISSILE; + beam.is_beam = true; break; case MS_VENOM_BOLT: - beam.name = "bolt of poison"; + strcpy(beam.beam_name, "bolt of poison"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 6 + power / 13 ); beam.colour = LIGHTGREEN; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_POISON; beam.hit = 7 + random2(power) / 80; - beam.isBeam = true; + beam.is_beam = true; + break; + + case MS_POISON_ARROW: + strcpy( beam.beam_name, "poison arrow" ); + beam.damage = dice_def( 4, 5 + power / 4 ); + beam.colour = LIGHTGREEN; + beam.type = SYM_MISSILE; + beam.thrower = KILL_MON; + beam.flavour = BEAM_POISON_ARROW; + beam.hit = 40 + power / 5; + beam.range = beam.rangeMax = 8; break; case MS_FIRE_BOLT: - beam.name = "bolt of fire"; + strcpy(beam.beam_name, "bolt of fire"); beam.range = 4; beam.rangeMax = 13; beam.damage = dice_def( 3, 8 + power / 11 ); beam.colour = RED; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_FIRE; beam.hit = 8 + random2(power) / 80; // hit - beam.isBeam = true; + beam.is_beam = true; break; case MS_COLD_BOLT: - beam.name = "bolt of cold"; + strcpy(beam.beam_name, "bolt of cold"); beam.range = 4; beam.rangeMax = 13; beam.damage = dice_def( 3, 8 + power / 11 ); beam.colour = WHITE; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_COLD; beam.hit = 8 + random2(power) / 80; // hit - beam.isBeam = true; + beam.is_beam = true; break; case MS_LIGHTNING_BOLT: - beam.name = "bolt of lightning"; + strcpy(beam.beam_name, "bolt of lightning"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 10 + power / 9 ); beam.colour = LIGHTCYAN; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_ELECTRICITY; beam.hit = 10 + random2(power) / 40; - beam.isBeam = true; + beam.is_beam = true; break; case MS_INVIS: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_INVISIBILITY; - beam.thrown = KILL_MON; - beam.isBeam = true; + beam.thrower = KILL_MON; + beam.is_beam = true; break; case MS_FIREBALL: beam.colour = RED; - beam.name = "fireball"; + strcpy(beam.beam_name, "fireball"); beam.range = 6; beam.rangeMax = 10; beam.damage = dice_def( 3, 7 + power / 10 ); beam.hit = 40; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; - beam.flavour = BEAM_EXPLOSION; // why not BEAM_FIRE? {dlb} - beam.isBeam = false; + beam.thrower = KILL_MON; + beam.flavour = BEAM_FIRE; // why not BEAM_FIRE? {dlb} + beam.is_beam = false; + beam.is_explosion = true; break; case MS_HEAL: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_HEALING; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.hit = 5 + (power / 5); - beam.isBeam = true; + beam.is_beam = true; break; case MS_TELEPORT: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_TELEPORT; // 6 is used by digging - beam.thrown = KILL_MON; - beam.isBeam = true; + beam.thrower = KILL_MON; + beam.is_beam = true; break; case MS_TELEPORT_OTHER: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_TELEPORT; // 6 is used by digging - beam.thrown = KILL_MON; - beam.isBeam = true; + beam.thrower = KILL_MON; + beam.is_beam = true; break; case MS_BLINK: - beam.isBeam = false; + beam.is_beam = false; break; case MS_CRYSTAL_SPEAR: // was splinters - beam.name = "crystal spear"; + strcpy(beam.beam_name, "crystal spear"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 12 + power / 10 ); beam.colour = WHITE; beam.type = SYM_MISSILE; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_MMISSILE; beam.hit = 6; // + random2(power) / 10; - beam.isBeam = false; + beam.is_beam = false; break; case MS_DIG: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 3; beam.rangeMax = 7 + random2(power) / 10; beam.type = 0; beam.flavour = BEAM_DIGGING; - beam.thrown = KILL_MON; - beam.isBeam = true; + beam.thrower = KILL_MON; + beam.is_beam = true; break; case MS_NEGATIVE_BOLT: // negative energy - beam.name = "bolt of negative energy"; + strcpy(beam.beam_name, "bolt of negative energy"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 6 + power / 13 ); beam.colour = DARKGREY; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_NEG; beam.hit = 7 + random2(power) / 80; - beam.isBeam = true; + beam.is_beam = true; break; // 20, 21 are used case MS_ORB_ENERGY: // mystic blast beam.colour = LIGHTMAGENTA; - beam.name = "orb of energy"; + strcpy(beam.beam_name, "orb of energy"); beam.range = 6; beam.rangeMax = 10; beam.damage = dice_def( 3, 7 + (power / 14) ); beam.hit = 10 + (power / 20); beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_MMISSILE; - beam.isBeam = false; + beam.is_beam = false; break; // 23 is brain feed case MS_STEAM_BALL: beam.colour = LIGHTGREY; - beam.name = "ball of steam"; + strcpy(beam.beam_name, "ball of steam"); beam.range = 6; beam.rangeMax = 10; beam.damage = dice_def( 3, 6 ); beam.hit = 11; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_FIRE; // fire - I think this is appropriate - beam.isBeam = false; + beam.is_beam = false; break; // 27 is summon devils // 28 is animate dead case MS_PAIN: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 7; beam.rangeMax = 14; beam.type = 0; beam.flavour = BEAM_PAIN; // pain - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; // beam.damage = dice_def( 1, 50 ); beam.damage = dice_def( 1, 7 + (power / 20) ); beam.ench_power = 50; - beam.isBeam = true; + beam.is_beam = true; break; // 30 is smiting case MS_STICKY_FLAME: beam.colour = RED; - beam.name = "sticky flame"; + strcpy(beam.beam_name, "sticky flame"); beam.range = 6; beam.rangeMax = 10; beam.damage = dice_def( 3, 3 + power / 50 ); beam.hit = 8 + power / 15; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_FIRE; - beam.isBeam = false; + beam.is_beam = false; break; case MS_POISON_BLAST: // demon - beam.name = "blast of poison"; + strcpy(beam.beam_name, "blast of poison"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 3 + power / 25 ); beam.colour = LIGHTGREEN; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_POISON; beam.hit = 7 + random2(power) / 80; - beam.isBeam = true; + beam.is_beam = true; + beam.is_big_cloud = true; break; case MS_PURPLE_BLAST: // purple bang thing beam.colour = LIGHTMAGENTA; - beam.name = "orb of energy"; + strcpy(beam.beam_name, "orb of energy"); beam.range = 6; beam.rangeMax = 10; beam.damage = dice_def( 3, 10 + power / 15 ); beam.hit = 10 + power / 20; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; - beam.flavour = BEAM_EXPLOSION; // an exploding magical missile - beam.isBeam = false; + beam.thrower = KILL_MON_MISSILE; + beam.flavour = BEAM_MMISSILE; + beam.is_beam = false; + beam.is_explosion = true; break; case MS_ENERGY_BOLT: // eye of devastation beam.colour = YELLOW; - beam.name = "bolt of energy"; + strcpy(beam.beam_name, "bolt of energy"); beam.range = 9; beam.rangeMax = 23; beam.damage = dice_def( 3, 20 ); beam.hit = 9; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_NUKE; // a magical missile which destroys walls - beam.isBeam = true; + beam.is_beam = true; break; case MS_STING: // sting beam.colour = GREEN; - beam.name = "sting"; + strcpy(beam.beam_name, "sting"); beam.range = 8; beam.rangeMax = 12; beam.damage = dice_def( 1, 6 + power / 25 ); beam.hit = 60; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_POISON; - beam.isBeam = false; + beam.is_beam = false; break; case MS_IRON_BOLT: beam.colour = LIGHTCYAN; - beam.name = "iron bolt"; + strcpy(beam.beam_name, "iron bolt"); beam.range = 4; beam.rangeMax = 8; beam.damage = dice_def( 3, 8 + (power / 9) ); beam.hit = 6 + (power / 25); beam.type = SYM_MISSILE; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_MMISSILE; // similarly unresisted thing - beam.isBeam = false; + beam.is_beam = false; break; case MS_STONE_ARROW: beam.colour = LIGHTGREY; - beam.name = "stone arrow"; + strcpy(beam.beam_name, "stone arrow"); beam.range = 8; beam.rangeMax = 12; beam.damage = dice_def( 3, 5 + (power / 10) ); beam.hit = 5 + power / 47; beam.type = SYM_MISSILE; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_MMISSILE; // similarly unresisted thing - beam.isBeam = false; + beam.is_beam = false; break; case MS_POISON_SPLASH: beam.colour = GREEN; - beam.name = "splash of poison"; + strcpy(beam.beam_name, "splash of poison"); beam.range = 5; beam.rangeMax = 10; beam.damage = dice_def( 1, 4 + power / 10 ); beam.hit = 9; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_POISON; - beam.isBeam = false; + beam.is_beam = false; break; case MS_DISINTEGRATE: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 7; beam.rangeMax = 14; beam.type = 0; beam.flavour = BEAM_DISINTEGRATION; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.ench_power = 50; // beam.hit = 30 + (power / 10); beam.damage = dice_def( 1, 30 + (power / 10) ); - beam.isBeam = true; + beam.is_beam = true; break; case MS_MARSH_GAS: // swamp drake - beam.name = "foul vapour"; + strcpy(beam.beam_name, "foul vapour"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 2 + power / 25 ); beam.colour = GREEN; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_POISON; beam.hit = 7 + random2(power) / 80; - beam.isBeam = false; + beam.is_beam = false; + beam.is_big_cloud = true; break; + case MS_MIASMA: // death drake + strcpy( beam.beam_name, "foul vapour" ); + beam.damage = dice_def( 3, 5 + power / 24 ); + beam.colour = DARKGREY; + beam.type = SYM_ZAP; + beam.thrower = KILL_MON; + beam.flavour = BEAM_MIASMA; + beam.hit = 80 + power / 20; + beam.is_beam = false; + beam.range = beam.rangeMax = 8; + break; + case MS_QUICKSILVER_BOLT: // Quicksilver dragon beam.colour = random_colour(); - beam.name = "bolt of energy"; + strcpy(beam.beam_name, "bolt of energy"); beam.range = 9; beam.rangeMax = 23; beam.damage = dice_def( 3, 25 ); beam.hit = 9; beam.type = SYM_ZAP; - beam.thrown = KILL_MON_MISSILE; + beam.thrower = KILL_MON_MISSILE; beam.flavour = BEAM_MMISSILE; - beam.isBeam = false; + beam.is_beam = false; break; case MS_HELLFIRE: // fiend's hellfire - beam.name = "hellfire"; + strcpy(beam.beam_name, "hellfire"); beam.colour = RED; beam.range = 4; beam.rangeMax = 13; beam.damage = dice_def( 3, 25 ); beam.hit = 20; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; - beam.flavour = BEAM_EXPLOSION; // hellfire - not BEAM_HELLFIRE? {dlb} - beam.isBeam = true; + beam.thrower = KILL_MON; + beam.flavour = BEAM_HELLFIRE; + beam.is_beam = true; + beam.is_explosion = true; break; case MS_METAL_SPLINTERS: - beam.name = "spray of metal splinters"; + strcpy(beam.beam_name, "spray of metal splinters"); beam.range = 7; beam.rangeMax = 16; beam.damage = dice_def( 3, 20 + power / 20 ); beam.colour = CYAN; beam.type = SYM_ZAP; - beam.thrown = KILL_MON; + beam.thrower = KILL_MON; beam.flavour = BEAM_FRAG; beam.hit = 15 + random2(power) / 50; - beam.isBeam = true; + beam.is_beam = true; break; case MS_BANISHMENT: - beam.name = "0"; + strcpy(beam.beam_name, "0"); beam.range = 5; beam.rangeMax = 9; beam.type = 0; beam.flavour = BEAM_BANISH; - beam.thrown = KILL_MON_MISSILE; - beam.isBeam = true; + beam.thrower = KILL_MON_MISSILE; + beam.is_beam = true; + break; + + case MS_BLINK_OTHER: + strcpy(beam.beam_name, "0"); + beam.type = 0; + beam.flavour = BEAM_BLINK; + beam.thrower = KILL_MON; + beam.is_beam = true; + beam.is_enchant = true; + beam.range = 8; + beam.rangeMax = 8; break; default: diff --git a/crawl-ref/source/mstuff2.h b/crawl-ref/source/mstuff2.h index 1bdd23232f..8ac7be902c 100644 --- a/crawl-ref/source/mstuff2.h +++ b/crawl-ref/source/mstuff2.h @@ -19,22 +19,6 @@ #include "externs.h" -struct SBeam -{ - std::string name; - int colour; - int range; - int rangeMax; - int hit; - dice_def damage; - int ench_power; - int type; - int flavour; - int thrown; - bool isBeam; -}; - - /* beam_colour = _pass[0]; beam_range = _pass[1]; @@ -50,7 +34,7 @@ struct SBeam /* *********************************************************************** * called from: monstuff - mstuff2 * *********************************************************************** */ -struct SBeam mons_spells(int spell_cast, int power); +bolt mons_spells(int spell_cast, int power); // last updated 12may2000 {dlb} diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc index 5c24984a06..09d4c4d105 100644 --- a/crawl-ref/source/newgame.cc +++ b/crawl-ref/source/newgame.cc @@ -86,6 +86,7 @@ #include "fight.h" #include "initfile.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "macro.h" #include "player.h" @@ -251,7 +252,7 @@ static void pick_random_species_and_class( void ) { // we only want draconians counted once in this loop... // we'll add the variety lower down -- bwr - if (sp >= SP_WHITE_DRACONIAN && sp <= SP_UNK2_DRACONIAN) + if (sp >= SP_WHITE_DRACONIAN && sp <= SP_BASE_DRACONIAN) continue; for (int cl = JOB_FIGHTER; cl < NUM_JOBS; cl++) @@ -356,9 +357,8 @@ bool new_game(void) //jmf: NEW ASSERTS: we ought to do a *lot* of these ASSERT(NUM_SPELLS < SPELL_NO_SPELL); - ASSERT(NUM_DURATIONS > DUR_LAST_DUR); ASSERT(NUM_JOBS < JOB_UNKNOWN); - ASSERT(NUM_ATTRIBUTES < 30); + ASSERT(NUM_ATTRIBUTES >= 30); init_player(); @@ -627,7 +627,7 @@ bool new_game(void) // don't change object type modifier unless it starts plain if (you.inv[i].base_type <= OBJ_ARMOUR - && cmp_equip_race( you.inv[i], 0 )) // == DARM_PLAIN + && get_equip_race(you.inv[i]) == 0 ) // == DARM_PLAIN { // now add appropriate species type mod: switch (you.species) @@ -1805,7 +1805,7 @@ void species_stat_init(unsigned char which_species) case SP_PALE_DRACONIAN: case SP_UNK0_DRACONIAN: case SP_UNK1_DRACONIAN: - case SP_UNK2_DRACONIAN: sb = 9; ib = 6; db = 2; break; // 17 + case SP_BASE_DRACONIAN: sb = 9; ib = 6; db = 2; break; // 17 } modify_all_stats( sb, ib, db ); @@ -2381,7 +2381,7 @@ static bool give_wanderer_weapon( int slot, int wpn_skill ) static void create_wanderer( void ) { const int util_skills[] = - { SK_DARTS, SK_THROWING, SK_ARMOUR, SK_DODGING, SK_STEALTH, + { SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH, SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT, SK_INVOCATIONS, SK_EVOCATIONS }; const int num_util_skills = sizeof(util_skills) / sizeof(int); @@ -2393,7 +2393,7 @@ static void create_wanderer( void ) const int fight_util_skills[] = { SK_FIGHTING, SK_SHORT_BLADES, SK_AXES, SK_MACES_FLAILS, SK_POLEARMS, - SK_DARTS, SK_THROWING, SK_ARMOUR, SK_DODGING, SK_STEALTH, + SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH, SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT, SK_INVOCATIONS, SK_EVOCATIONS }; const int num_fight_util_skills = sizeof(fight_util_skills) / sizeof(int); @@ -2404,7 +2404,7 @@ static void create_wanderer( void ) SK_FIRE_MAGIC, SK_ICE_MAGIC, SK_AIR_MAGIC, SK_EARTH_MAGIC, SK_FIGHTING, SK_SHORT_BLADES, SK_LONG_SWORDS, SK_AXES, SK_MACES_FLAILS, SK_POLEARMS, SK_STAVES, - SK_DARTS, SK_THROWING, SK_ARMOUR, SK_DODGING, SK_STEALTH, + SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH, SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT, SK_INVOCATIONS, SK_EVOCATIONS }; const int num_not_rare_skills = sizeof(not_rare_skills) / sizeof(int); @@ -2417,7 +2417,7 @@ static void create_wanderer( void ) SK_FIRE_MAGIC, SK_ICE_MAGIC, SK_AIR_MAGIC, SK_EARTH_MAGIC, SK_FIGHTING, SK_SHORT_BLADES, SK_LONG_SWORDS, SK_AXES, SK_MACES_FLAILS, SK_POLEARMS, SK_STAVES, - SK_DARTS, SK_THROWING, SK_ARMOUR, SK_DODGING, SK_STEALTH, + SK_DARTS, SK_RANGED_COMBAT, SK_ARMOUR, SK_DODGING, SK_STEALTH, SK_STABBING, SK_SHIELDS, SK_TRAPS_DOORS, SK_UNARMED_COMBAT, SK_INVOCATIONS, SK_EVOCATIONS }; const int num_all_skills = sizeof(all_skills) / sizeof(int); @@ -2640,7 +2640,7 @@ static void create_wanderer( void ) add_spell_to_memory( spell_list[ school ] ); } } - else if (you.skills[ SK_THROWING ] && one_chance_in(3)) // these are rare + else if (you.skills[ SK_RANGED_COMBAT ] && one_chance_in(3)) // these are rare { // Ranger style wanderer // Rare since starting with a throwing weapon is very good @@ -2846,10 +2846,10 @@ static char letter_to_species(int keyn) static char species_to_letter(int spec) { - if (spec > SP_RED_DRACONIAN && spec <= SP_UNK2_DRACONIAN) + if (spec > SP_RED_DRACONIAN && spec <= SP_BASE_DRACONIAN) spec = SP_RED_DRACONIAN; - else if (spec > SP_UNK2_DRACONIAN) - spec -= SP_UNK2_DRACONIAN - SP_RED_DRACONIAN; + else if (spec > SP_BASE_DRACONIAN) + spec -= SP_BASE_DRACONIAN - SP_RED_DRACONIAN; return 'a' + spec - 1; } @@ -2920,7 +2920,7 @@ spec_query: *linebuf = 0; for (int i = SP_HUMAN; i < NUM_SPECIES; ++i) { - if (i > SP_RED_DRACONIAN && i <= SP_UNK2_DRACONIAN) + if (i > SP_RED_DRACONIAN && i <= SP_BASE_DRACONIAN) continue; if (you.char_class != JOB_UNKNOWN && @@ -3401,7 +3401,7 @@ void give_items_skills() if (you.species == SP_KOBOLD) { - you.skills[SK_THROWING] = 1; + you.skills[SK_RANGED_COMBAT] = 1; you.skills[SK_DARTS] = 1; you.skills[SK_DODGING] = 1; you.skills[SK_STEALTH] = 1; @@ -3427,7 +3427,7 @@ void give_items_skills() you.skills[(player_light_armour()? SK_DODGING : SK_ARMOUR)] = 2; you.skills[SK_SHIELDS] = 2; - you.skills[SK_THROWING] = 2; + you.skills[SK_RANGED_COMBAT] = 2; you.skills[(coinflip() ? SK_STABBING : SK_SHIELDS)]++; } break; @@ -3654,7 +3654,7 @@ void give_items_skills() you.skills[SK_STEALTH] = 2; you.skills[SK_STABBING] = 1; you.skills[SK_DODGING + random2(3)]++; - you.skills[SK_THROWING] = 1; + you.skills[SK_RANGED_COMBAT] = 1; you.skills[SK_DARTS] = 1; you.skills[SK_TRAPS_DOORS] = 2; break; @@ -3858,12 +3858,12 @@ void give_items_skills() you.skills[SK_DODGING] = 1; you.skills[SK_STEALTH] = 3; you.skills[SK_STABBING] = 2; - you.skills[SK_THROWING] = 1; + you.skills[SK_RANGED_COMBAT] = 1; you.skills[SK_DARTS] = 1; if (you.species == SP_DEEP_ELF) you.skills[SK_CROSSBOWS] = 1; else - you.skills[SK_THROWING] += 1; + you.skills[SK_RANGED_COMBAT] += 1; break; @@ -3956,7 +3956,7 @@ void give_items_skills() you.skills[SK_POLEARMS] = 1; you.skills[SK_ARMOUR] = 2; you.skills[SK_DODGING] = 2; - you.skills[SK_THROWING] = 2; + you.skills[SK_RANGED_COMBAT] = 2; } break; @@ -4019,7 +4019,7 @@ void give_items_skills() you.equip[EQ_BODY_ARMOUR] = 4; you.skills[SK_FIGHTING] = 2; - you.skills[SK_THROWING] = 3; + you.skills[SK_RANGED_COMBAT] = 3; // Removing spellcasting -- bwr // you.skills[SK_SPELLCASTING] = 1; @@ -4066,7 +4066,7 @@ void give_items_skills() you.skills[SK_POLEARMS] = 2; you.skills[SK_DODGING] = 2; - you.skills[SK_THROWING] += 1; + you.skills[SK_RANGED_COMBAT] += 1; break; default: @@ -4285,7 +4285,7 @@ void give_items_skills() you.skills[SK_STEALTH] = 1; if (you.species == SP_GNOME && you.char_class == JOB_EARTH_ELEMENTALIST) - you.skills[SK_THROWING]++; + you.skills[SK_RANGED_COMBAT]++; else you.skills[ coinflip() ? SK_DODGING : SK_STEALTH ]++; break; @@ -4334,7 +4334,7 @@ void give_items_skills() you.skills[SK_FIGHTING] = 1; you.skills[SK_UNARMED_COMBAT] = 3; - you.skills[SK_THROWING] = 2; + you.skills[SK_RANGED_COMBAT] = 2; you.skills[SK_DODGING] = 2; you.skills[SK_SPELLCASTING] = 2; you.skills[SK_TRANSMIGRATION] = 2; @@ -4421,7 +4421,7 @@ void give_items_skills() you.equip[EQ_WEAPON] = 0; you.equip[EQ_BODY_ARMOUR] = 1; - you.skills[SK_THROWING] = 1; + you.skills[SK_RANGED_COMBAT] = 1; you.skills[SK_DARTS] = 2; you.skills[SK_DODGING] = 2; you.skills[SK_STEALTH] = 1; @@ -4724,7 +4724,7 @@ void give_items_skills() you.skills[SK_FIGHTING] = 2; you.skills[SK_DODGING] = 1; you.skills[SK_SHIELDS] = 1; - you.skills[SK_THROWING] = 2; + you.skills[SK_RANGED_COMBAT] = 2; you.skills[SK_STAVES] = 3; you.skills[SK_INVOCATIONS] = 2; break; @@ -4808,7 +4808,7 @@ void give_items_skills() you.skills[SK_STEALTH] = 2; you.skills[SK_STABBING] = 2; you.skills[SK_DODGING + random2(3)]++; - //you.skills[SK_THROWING] = 1; //jmf: removed these, added magic below + //you.skills[SK_RANGED_COMBAT] = 1; //jmf: removed these, added magic below //you.skills[SK_DARTS] = 1; you.skills[SK_SPELLCASTING] = 1; you.skills[SK_ENCHANTMENTS] = 1; diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index f9a5f514dd..5fa0ff13bd 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -70,6 +70,7 @@ #include "hiscores.h" #include "invent.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "macro.h" #include "mon-util.h" @@ -98,8 +99,7 @@ int check_your_resists(int hurted, int flavour) #endif if (flavour == BEAM_FIRE || flavour == BEAM_LAVA - || flavour == BEAM_HELLFIRE || flavour == BEAM_EXPLOSION - || flavour == BEAM_FRAG) + || flavour == BEAM_HELLFIRE || flavour == BEAM_FRAG) { if (you.duration[DUR_CONDENSATION_SHIELD] > 0) { @@ -169,6 +169,9 @@ int check_your_resists(int hurted, int flavour) break; case BEAM_POISON_ARROW: + // [dshaligram] NOT importing uber-poison arrow from 4.1. Giving no + // bonus to poison resistant players seems strange and unnecessarily + // arbitrary. resist = player_res_poison(); if (!resist) @@ -179,7 +182,7 @@ int check_your_resists(int hurted, int flavour) hurted /= 2; if (!you.is_undead) - poison_player( coinflip() ? 2 : 3, true ); + poison_player( 2 + random2(3), true ); } break; @@ -225,6 +228,30 @@ int check_your_resists(int hurted, int flavour) hurted /= 10; } break; + + case BEAM_ACID: + if (player_res_acid()) + { + canned_msg( MSG_YOU_RESIST ); + hurted /= 3; + } + break; + + case BEAM_MIASMA: + if (player_prot_life() > random2(3)) + { + canned_msg( MSG_YOU_RESIST ); + hurted = 0; + } + break; + + case BEAM_HOLY: + if (!you.is_undead && you.species != SP_DEMONSPAWN) + { + canned_msg( MSG_YOU_RESIST ); + hurted = 0; + } + break; } /* end switch */ return (hurted); @@ -313,7 +340,7 @@ void item_corrode( char itco ) suppress_msg = true; } else if ((you.inv[itco].sub_type == ARM_CRYSTAL_PLATE_MAIL - || cmp_equip_race( you.inv[itco], ISFLAG_DWARVEN )) + || get_equip_race(you.inv[itco]) == ISFLAG_DWARVEN) && !one_chance_in(5)) { it_resists = true; @@ -328,7 +355,7 @@ void item_corrode( char itco ) it_resists = true; suppress_msg = true; } - else if (cmp_equip_race( you.inv[itco], ISFLAG_DWARVEN ) + else if (get_equip_race(you.inv[itco]) == ISFLAG_DWARVEN && !one_chance_in(5)) { it_resists = true; @@ -337,7 +364,8 @@ void item_corrode( char itco ) break; case OBJ_MISSILES: - if (cmp_equip_race( you.inv[itco], ISFLAG_DWARVEN ) && !one_chance_in(5)) + if (get_equip_race(you.inv[itco]) == ISFLAG_DWARVEN + && !one_chance_in(5)) { it_resists = true; suppress_msg = false; diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 5a4edebd21..149185ed6b 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -32,6 +32,7 @@ #include "clua.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "macro.h" #include "misc.h" @@ -44,6 +45,7 @@ #include "spl-util.h" #include "spells4.h" #include "stuff.h" +#include "transfor.h" #include "travel.h" #include "view.h" #include "wpn-misc.h" @@ -157,7 +159,7 @@ bool player_genus(unsigned char which_genus, unsigned char species) case SP_PALE_DRACONIAN: case SP_UNK0_DRACONIAN: case SP_UNK1_DRACONIAN: - case SP_UNK2_DRACONIAN: + case SP_BASE_DRACONIAN: return (which_genus == GENPC_DRACONIAN); case SP_ELF: @@ -373,7 +375,7 @@ int player_damage_type( void ) if (wpn != -1) { - return (damage_type( you.inv[wpn].base_type, you.inv[wpn].sub_type )); + return (damage_type(you.inv[wpn])); } else if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON @@ -771,6 +773,14 @@ int player_res_cold(bool calc_unid) return (rc); } +int player_res_acid( void ) +{ + return (!transform_changed_physiology() + && ((you.species == SP_GOLDEN_DRACONIAN + && you.experience_level >= 7) + || you.mutation[MUT_YELLOW_SCALES] == 3)); +} + int player_res_electricity(bool calc_unid) { int re = 0; @@ -1221,20 +1231,13 @@ int player_AC(void) // which uses "plus2"... since not all members have the same // AC value, we use special cases. -- bwr if (i == EQ_HELMET - && (cmp_helmet_type( you.inv[ item ], THELM_CAP ) - || cmp_helmet_type( you.inv[ item ], THELM_WIZARD_HAT ) - || cmp_helmet_type( you.inv[ item ], THELM_SPECIAL ))) + && (get_helmet_type(you.inv[ item ]) == THELM_CAP + || get_helmet_type(you.inv[ item ]) == THELM_WIZARD_HAT + || get_helmet_type(you.inv[ item ]) == THELM_SPECIAL)) { continue; } - if (i == EQ_BOOTS - && (you.inv[ item ].plus2 == TBOOT_NAGA_BARDING - || you.inv[ item ].plus2 == TBOOT_CENTAUR_BARDING)) - { - AC += 3; - } - int racial_bonus = 0; // additional levels of armour skill const unsigned long armour_race = get_equip_race( you.inv[ item ] ); const int ac_value = property( you.inv[ item ], PARM_AC ); @@ -1440,7 +1443,7 @@ int player_AC(void) bool is_light_armour( const item_def &item ) { - if (cmp_equip_race( item, ISFLAG_ELVEN )) + if (get_equip_race(item) == ISFLAG_ELVEN) return (true); switch (item.sub_type) @@ -1673,7 +1676,7 @@ unsigned char player_see_invis(bool calc_unid) // This does NOT do line of sight! It checks the monster's visibility // with repect to the players perception, but doesn't do walls or range... // to find if the square the monster is in is visible see mons_near(). -bool player_monster_visible( struct monsters *mon ) +bool player_monster_visible( const monsters *mon ) { if (mons_has_ench( mon, ENCH_SUBMERGED ) || (mons_has_ench( mon, ENCH_INVIS ) && !player_see_invis())) @@ -1724,7 +1727,7 @@ int burden_change(void) } else { - you.burden += mass_item( you.inv[bu] ) * you.inv[bu].quantity; + you.burden += item_mass( you.inv[bu] ) * you.inv[bu].quantity; } } @@ -2126,7 +2129,7 @@ void level_change(void) case SP_PALE_DRACONIAN: case SP_UNK0_DRACONIAN: case SP_UNK1_DRACONIAN: - case SP_UNK2_DRACONIAN: + case SP_BASE_DRACONIAN: if (you.experience_level == 7) { switch (you.species) @@ -2162,7 +2165,7 @@ void level_change(void) break; case SP_UNK0_DRACONIAN: case SP_UNK1_DRACONIAN: - case SP_UNK2_DRACONIAN: + case SP_BASE_DRACONIAN: mpr(""); break; } @@ -2462,9 +2465,9 @@ int check_stealth(void) const int boots = you.equip[EQ_BOOTS]; if (arm != -1 && !player_light_armour()) - stealth -= (mass_item( you.inv[arm] ) / 10); + stealth -= (item_mass( you.inv[arm] ) / 10); - if (cloak != -1 && cmp_equip_race( you.inv[cloak], ISFLAG_ELVEN )) + if (cloak != -1 && get_equip_race(you.inv[cloak]) == ISFLAG_ELVEN) stealth += 20; if (boots != -1) @@ -2472,7 +2475,7 @@ int check_stealth(void) if (get_armour_ego_type( you.inv[boots] ) == SPARM_STEALTH) stealth += 50; - if (cmp_equip_race( you.inv[boots], ISFLAG_ELVEN )) + if (get_equip_race(you.inv[boots]) == ISFLAG_ELVEN) stealth += 20; } @@ -2634,9 +2637,6 @@ void display_char_status(void) if (you.duration[DUR_SILENCE]) //jmf: added 27mar2000 mpr( "You radiate silence." ); - if (you.duration[DUR_INFECTED_SHUGGOTH_SEED]) //jmf: added 19mar2000 - mpr( "You are infected with a shuggoth parasite." ); - if (you.duration[DUR_STONESKIN]) mpr( "Your skin is tough as stone." ); @@ -2812,7 +2812,7 @@ char *species_name( int speci, int level, bool genus, bool adj, bool cap ) break; case SP_UNK0_DRACONIAN: case SP_UNK1_DRACONIAN: - case SP_UNK2_DRACONIAN: + case SP_BASE_DRACONIAN: default: strcpy( species_buff, "Draconian" ); break; @@ -4009,7 +4009,7 @@ void perform_activity() } #ifdef CLUA_BINDINGS -static const char *activity_interrupt_name(ACT_INTERRUPT ai) +static const char *activity_interrupt_name(activity_interrupt_type ai) { switch (ai) { @@ -4052,8 +4052,8 @@ static void kill_activity() you.activity = ACT_NONE; } -static bool userdef_interrupt_activity( ACT_INTERRUPT ai, - const activity_interrupt_t &at ) +static bool userdef_interrupt_activity( activity_interrupt_type ai, + const activity_interrupt_data &at ) { #ifdef CLUA_BINDINGS lua_State *ls = clua.state(); @@ -4101,7 +4101,8 @@ static bool userdef_interrupt_activity( ACT_INTERRUPT ai, return true; } -void interrupt_activity( ACT_INTERRUPT ai, const activity_interrupt_t &at ) +void interrupt_activity( activity_interrupt_type ai, + const activity_interrupt_data &at ) { if (you.running && !you.activity) you.activity = you.running > 0? ACT_RUNNING : ACT_TRAVELING; diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 4b2feced38..70db5bea41 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -149,7 +149,7 @@ int player_regen(void); * called from: fight - files - it_use2 - misc - ouch - spells - spells2 * *********************************************************************** */ int player_res_cold(bool calc_unid = true); - +int player_res_acid(void); /* *********************************************************************** * called from: fight - files - ouch @@ -282,7 +282,7 @@ int slaying_bonus(char which_affected); * spells3 * *********************************************************************** */ unsigned char player_see_invis(bool calc_unid = true); -bool player_monster_visible( struct monsters *mon ); +bool player_monster_visible( const monsters *mon ); /* *********************************************************************** @@ -442,8 +442,9 @@ void rot_player( int amount ); void perform_activity(); -void interrupt_activity( ACT_INTERRUPT ai, - const activity_interrupt_t &a = activity_interrupt_t() ); +void interrupt_activity( activity_interrupt_type ai, + const activity_interrupt_data &a + = activity_interrupt_data() ); // last updated 15sep2001 {bwr} /* *********************************************************************** @@ -451,6 +452,8 @@ void interrupt_activity( ACT_INTERRUPT ai, * *********************************************************************** */ bool player_has_spell( int spell ); +bool player_weapon_wielded(); + void run_macro(const char *macroname = NULL); #endif diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc index 753c1d15fe..57558ffeab 100644 --- a/crawl-ref/source/randart.cc +++ b/crawl-ref/source/randart.cc @@ -20,6 +20,7 @@ #include "externs.h" #include "itemname.h" +#include "itemprop.h" #include "stuff.h" #include "wpn-misc.h" @@ -1182,11 +1183,11 @@ finished_curses: if (random5(10) == 0 && (aclass != OBJ_ARMOUR || atype != ARM_CLOAK - || !cmp_equip_race( item, ISFLAG_ELVEN )) + || get_equip_race(item) != ISFLAG_ELVEN) && (aclass != OBJ_ARMOUR || atype != ARM_BOOTS - || !cmp_equip_race( item, ISFLAG_ELVEN ) - && get_armour_ego_type( item ) != SPARM_STEALTH)) + || get_equip_race(item) != ISFLAG_ELVEN) + && get_armour_ego_type( item ) != SPARM_STEALTH) { power_level++; proprt[RAP_STEALTH] = 10 + random5(70); @@ -1239,7 +1240,7 @@ const char *randart_name( const item_def &item ) push_rng_state(); seed_rng( seed ); - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) { switch (random5(21)) { @@ -1286,7 +1287,7 @@ const char *randart_name( const item_def &item ) { char st_p2[ITEMNAME_SIZE]; - make_name(random5(250), random5(250), random5(250), 3, st_p); + make_name(random_int(), false, st_p); standard_name_weap( item.sub_type, st_p2 ); strcat(art_n, st_p2); @@ -1336,7 +1337,7 @@ const char *randart_armour_name( const item_def &item ) push_rng_state(); seed_rng( seed ); - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) { switch (random5(21)) { @@ -1382,7 +1383,7 @@ const char *randart_armour_name( const item_def &item ) { char st_p2[ITEMNAME_SIZE]; - make_name(random5(250), random5(250), random5(250), 3, st_p); + make_name(random_int(), false, st_p); standard_name_armour(item, st_p2); strcat(art_n, st_p2); if (random5(3) == 0) @@ -1432,7 +1433,7 @@ const char *randart_ring_name( const item_def &item ) push_rng_state(); seed_rng( seed ); - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) { temp_rand = random5(21); @@ -1473,7 +1474,7 @@ const char *randart_ring_name( const item_def &item ) } else { - make_name(random5(250), random5(250), random5(250), 3, st_p); + make_name(random_int(), false, st_p); strcat(art_n, (item.sub_type < AMU_RAGE) ? "ring" : "amulet"); @@ -1773,6 +1774,7 @@ void standard_name_weap(unsigned char item_typ, char glorg[ITEMNAME_SIZE]) (item_typ == WPN_HALBERD) ? "halberd" : (item_typ == WPN_SLING) ? "sling" : (item_typ == WPN_BOW) ? "bow" : + (item_typ == WPN_LONGBOW) ? "longbow" : (item_typ == WPN_BLOWGUN) ? "blowgun" : (item_typ == WPN_CROSSBOW) ? "crossbow" : (item_typ == WPN_HAND_CROSSBOW) ? "hand crossbow" : @@ -1782,6 +1784,7 @@ void standard_name_weap(unsigned char item_typ, char glorg[ITEMNAME_SIZE]) (item_typ == WPN_EVENINGSTAR) ? "eveningstar" : (item_typ == WPN_QUICK_BLADE) ? "quick blade" : (item_typ == WPN_KATANA) ? "katana" : + (item_typ == WPN_LAJATANG) ? "lajatang" : (item_typ == WPN_EXECUTIONERS_AXE) ? "executioner's axe" : (item_typ == WPN_DOUBLE_SWORD) ? "double sword" : (item_typ == WPN_TRIPLE_SWORD) ? "triple sword" : @@ -1791,13 +1794,14 @@ void standard_name_weap(unsigned char item_typ, char glorg[ITEMNAME_SIZE]) (item_typ == WPN_SABRE) ? "sabre" : (item_typ == WPN_DEMON_BLADE) ? "demon blade" : (item_typ == WPN_BLESSED_BLADE)? "blessed blade" : + (item_typ == WPN_LOCHABER_AXE) ? "lochaber axe" : (item_typ == WPN_DEMON_WHIP) ? "demon whip" : (item_typ == WPN_DEMON_TRIDENT) ? "demon trident" : (item_typ == WPN_BROAD_AXE) ? "broad axe" : (item_typ == WPN_WAR_AXE) ? "war axe" : (item_typ == WPN_SPIKED_FLAIL) ? "spiked flail" : (item_typ == WPN_GREAT_MACE) ? "great mace" : - (item_typ == WPN_GREAT_FLAIL) ? "great flail" : + (item_typ == WPN_DIRE_FLAIL) ? "dire flail" : (item_typ == WPN_FALCHION) ? "falchion" : (item_typ == WPN_GIANT_CLUB) @@ -1860,8 +1864,8 @@ void standard_name_armour( const item_def &item, char glorg[ITEMNAME_SIZE] ) break; case ARM_HELMET: - if (cmp_helmet_type( item, THELM_HELM ) - || cmp_helmet_type( item, THELM_HELMET )) + if (get_helmet_type(item) == THELM_HELM + || get_helmet_type(item) == THELM_HELMET) { short dhelm = get_helmet_desc( item ); @@ -1894,13 +1898,16 @@ void standard_name_armour( const item_def &item, char glorg[ITEMNAME_SIZE] ) strcat(glorg, "gloves"); break; + case ARM_NAGA_BARDING: + strcat(glorg, "naga barding"); + break; + + case ARM_CENTAUR_BARDING: + strcat(glorg, "centaur barding"); + break; + case ARM_BOOTS: - if (item.plus2 == TBOOT_NAGA_BARDING) - strcat(glorg, "naga barding"); - else if (item.plus2 == TBOOT_CENTAUR_BARDING) - strcat(glorg, "centaur barding"); - else - strcat(glorg, "boots"); + strcat(glorg, "boots"); break; case ARM_BUCKLER: diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index cb2202093a..2cfd469994 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -39,6 +39,7 @@ #include "food.h" #include "it_use2.h" #include "itemname.h" +#include "itemprop.h" #include "item_use.h" #include "items.h" #include "misc.h" @@ -314,7 +315,7 @@ void pray(void) && random2( you.piety ) > 70 && !grid_destroys_items( grd[you.x_pos][you.y_pos] ) && one_chance_in(4) - && you.skills[ best_skill(SK_SLINGS, SK_THROWING) ] >= 3) + && you.skills[ best_skill(SK_SLINGS, SK_RANGED_COMBAT) ] >= 3) { success = acquirement( OBJ_MISSILES, you.religion ); if (success) @@ -955,10 +956,11 @@ void Xom_acts(bool niceness, int sever, bool force_sever) beam.target_y = you.y_pos; strcpy(beam.beam_name, "blast of lightning"); beam.colour = LIGHTCYAN; - beam.thrower = KILL_YOU; // your explosion + beam.thrower = KILL_MISC; beam.aux_source = "Xom's lightning strike"; beam.ex_size = 2; - beam.isTracer = false; + beam.is_tracer = false; + beam.is_explosion = true; explosion(beam); @@ -2352,9 +2354,7 @@ static bool bless_weapon( int god, int brand, int colour ) // as currently only Zin and TSO do this is our permabrand effect: holy_word( 100, true ); - - more(); - mesclr(); + delay(500); return (true); } diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc index cef4bb0d78..cff3ce8f51 100644 --- a/crawl-ref/source/shopping.cc +++ b/crawl-ref/source/shopping.cc @@ -28,6 +28,7 @@ #include "invent.h" #include "items.h" #include "itemname.h" +#include "itemprop.h" #include "macro.h" #include "player.h" #include "randart.h" @@ -617,6 +618,7 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) break; case WPN_LONG_SWORD: + case WPN_LONGBOW: case WPN_SCIMITAR: valued += 45; break; @@ -646,8 +648,9 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) valued += 65; break; - case WPN_GREAT_FLAIL: - valued += 75; + case WPN_DIRE_FLAIL: + case WPN_LOCHABER_AXE: + valued += 90; break; case WPN_EVENINGSTAR: @@ -675,6 +678,7 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) case WPN_TRIPLE_SWORD: case WPN_DEMON_BLADE: case WPN_BLESSED_BLADE: + case WPN_LAJATANG: valued += 200; break; } @@ -737,15 +741,15 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) } // elf/dwarf - if (cmp_equip_race( item, ISFLAG_ELVEN ) - || cmp_equip_race( item, ISFLAG_DWARVEN )) + if (get_equip_race(item) == ISFLAG_ELVEN + || get_equip_race(item) == ISFLAG_DWARVEN) { valued *= 12; valued /= 10; } // value was "6" but comment read "orc", so I went with comment {dlb} - if (cmp_equip_race( item, ISFLAG_ORCISH )) + if (get_equip_race(item) == ISFLAG_ORCISH) { valued *= 8; valued /= 10; @@ -795,7 +799,7 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) valued += 50; } else if (item_ident( item, ISFLAG_KNOW_TYPE ) - && !cmp_equip_desc( item, 0 )) + && get_equip_desc(item) != 0) { valued += 20; } @@ -823,7 +827,7 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) case MI_DART: case MI_LARGE_ROCK: case MI_STONE: - case MI_EGGPLANT: + case MI_NONE: valued++; break; case MI_ARROW: @@ -892,6 +896,8 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) break; case ARM_BANDED_MAIL: + case ARM_CENTAUR_BARDING: + case ARM_NAGA_BARDING: valued += 150; break; @@ -1006,14 +1012,14 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) valued /= 10; } - if (cmp_equip_race( item, ISFLAG_ELVEN ) - || cmp_equip_race( item, ISFLAG_DWARVEN )) + if (get_equip_race(item) == ISFLAG_ELVEN + || get_equip_race(item) == ISFLAG_DWARVEN) { valued *= 12; valued /= 10; } - if (cmp_equip_race( item, ISFLAG_ORCISH )) + if (get_equip_race(item) == ISFLAG_ORCISH) { valued *= 8; valued /= 10; @@ -1046,7 +1052,7 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) valued += 50; } else if (item_ident( item, ISFLAG_KNOW_TYPE ) - && !cmp_equip_desc( item, 0 )) + && get_equip_desc(item) != 0) { valued += 20; } @@ -1469,7 +1475,7 @@ unsigned int item_value( item_def item, id_arr id, bool ident ) break; case OBJ_STAVES: - if (item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (!item_ident( item, ISFLAG_KNOW_TYPE )) valued = 120; else if (item.sub_type == STAFF_SMITING || item.sub_type == STAFF_STRIKING @@ -1563,8 +1569,10 @@ const char *shop_name(int sx, int sy) char st_p[ITEMNAME_SIZE]; - make_name( cshop->keeper_name[0], cshop->keeper_name[1], - cshop->keeper_name[2], 3, st_p ); + unsigned long seed = static_cast<unsigned long>( cshop->keeper_name[0] ) + | (static_cast<unsigned long>( cshop->keeper_name[1] ) << 8) + | (static_cast<unsigned long>( cshop->keeper_name[1] ) << 16); + make_name( seed, false, st_p ); strcpy(sh_name, st_p); strcat(sh_name, "'s "); diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc index 416c31de9c..6a6f468125 100644 --- a/crawl-ref/source/skills2.cc +++ b/crawl-ref/source/skills2.cc @@ -61,7 +61,7 @@ const char *skills[50][6] = { {"Bows", "Shooter", "Yeoman", "Archer", "Merry %s", "Merry %s"}, {"Crossbows", "Shooter", "Sharpshooter", "Archer", "%s Ballista", "%s Ballista"}, // 10 {"Darts", "Dart Thrower", "Hurler", "Hurler, First Class", "%s Darts Champion", "Universal Darts Champion"}, - {"Throwing", "Chucker", "Thrower", "Deadly Accurate", "Hawkeye", "Sniper"}, + {"Ranged Combat", "Chucker", "Thrower", "Deadly Accurate", "Hawkeye", "Sniper"}, {"Armour", "Covered", "Protected", "Tortoise", "Impregnable", "Invulnerable"}, {"Dodging", "Ducker", "Dodger", "Nimble", "Spry", "Acrobat"}, @@ -136,7 +136,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 100, // SK_BOWS 100, // SK_CROSSBOWS 100, // SK_DARTS - 100, // SK_THROWING + 100, // SK_RANGED_COMBAT 100, // SK_ARMOUR 100, // SK_DODGING 100, // SK_STEALTH @@ -179,7 +179,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 60, // SK_BOWS 100, // SK_CROSSBOWS 90, // SK_DARTS - 80, // SK_THROWING + 80, // SK_RANGED_COMBAT 120, // SK_ARMOUR 80, // SK_DODGING 80, // SK_STEALTH @@ -222,7 +222,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 60, // SK_BOWS 100, // SK_CROSSBOWS 90, // SK_DARTS - 80, // SK_THROWING + 80, // SK_RANGED_COMBAT 110, // SK_ARMOUR 90, // SK_DODGING 90, // SK_STEALTH @@ -265,7 +265,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 70, // SK_BOWS 100, // SK_CROSSBOWS 90, // SK_DARTS - 80, // SK_THROWING + 80, // SK_RANGED_COMBAT 140, // SK_ARMOUR 75, // SK_DODGING 70, // SK_STEALTH @@ -308,7 +308,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 74, // SK_BOWS 75, // SK_CROSSBOWS 75, // SK_DARTS - 80, // SK_THROWING + 80, // SK_RANGED_COMBAT 140, // SK_ARMOUR 70, // SK_DODGING 65, // SK_STEALTH @@ -351,7 +351,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 100, // SK_BOWS 100, // SK_CROSSBOWS 100, // SK_DARTS - 70, // SK_THROWING + 70, // SK_RANGED_COMBAT 140, // SK_ARMOUR 70, // SK_DODGING 75, // SK_STEALTH @@ -394,7 +394,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 150, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 70, // SK_ARMOUR 120, // SK_DODGING 150, // SK_STEALTH @@ -437,7 +437,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 140, // SK_BOWS 100, // SK_CROSSBOWS 120, // SK_DARTS - 115, // SK_THROWING + 115, // SK_RANGED_COMBAT 60, // SK_ARMOUR 110, // SK_DODGING 140, // SK_STEALTH @@ -480,7 +480,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 70, // SK_BOWS 90, // SK_CROSSBOWS 50, // SK_DARTS - 60, // SK_THROWING + 60, // SK_RANGED_COMBAT 150, // SK_ARMOUR 70, // SK_DODGING 60, // SK_STEALTH @@ -523,7 +523,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 130, // SK_DARTS - 130, // SK_THROWING + 130, // SK_RANGED_COMBAT 90, // SK_ARMOUR 140, // SK_DODGING 150, // SK_STEALTH @@ -566,7 +566,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 80, // SK_BOWS 90, // SK_CROSSBOWS 50, // SK_DARTS - 60, // SK_THROWING + 60, // SK_RANGED_COMBAT 140, // SK_ARMOUR 70, // SK_DODGING 60, // SK_STEALTH @@ -609,7 +609,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 140, // SK_BOWS 140, // SK_CROSSBOWS 140, // SK_DARTS - 140, // SK_THROWING + 140, // SK_RANGED_COMBAT 140, // SK_ARMOUR 140, // SK_DODGING 140, // SK_STEALTH @@ -652,7 +652,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 150, // SK_ARMOUR 150, // SK_DODGING 40, // SK_STEALTH @@ -695,7 +695,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 100, // SK_BOWS 90, // SK_CROSSBOWS 60, // SK_DARTS - 100, // SK_THROWING + 100, // SK_RANGED_COMBAT 150, // SK_ARMOUR 70, // SK_DODGING 70, // SK_STEALTH @@ -738,7 +738,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 150, // SK_BOWS 180, // SK_CROSSBOWS 150, // SK_DARTS - 100, // SK_THROWING + 100, // SK_RANGED_COMBAT 140, // SK_ARMOUR 150, // SK_DODGING 200, // SK_STEALTH @@ -781,7 +781,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 180, // SK_BOWS 180, // SK_CROSSBOWS 180, // SK_DARTS - 130, // SK_THROWING + 130, // SK_RANGED_COMBAT 150, // SK_ARMOUR 130, // SK_DODGING 250, // SK_STEALTH @@ -824,7 +824,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 150, // SK_BOWS 150, // SK_CROSSBOWS 150, // SK_DARTS - 150, // SK_THROWING + 150, // SK_RANGED_COMBAT 170, // SK_ARMOUR 130, // SK_DODGING 100, // SK_STEALTH @@ -867,7 +867,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -910,7 +910,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -953,7 +953,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -996,7 +996,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1039,7 +1039,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1082,7 +1082,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1125,7 +1125,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1168,7 +1168,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1211,7 +1211,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1254,7 +1254,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1297,7 +1297,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1340,7 +1340,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1383,7 +1383,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 60, // SK_BOWS 85, // SK_CROSSBOWS 80, // SK_DARTS - 60, // SK_THROWING + 60, // SK_RANGED_COMBAT 180, // SK_ARMOUR 170, // SK_DODGING 200, // SK_STEALTH @@ -1426,7 +1426,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 110, // SK_BOWS 110, // SK_CROSSBOWS 110, // SK_DARTS - 110, // SK_THROWING + 110, // SK_RANGED_COMBAT 110, // SK_ARMOUR 110, // SK_DODGING 110, // SK_STEALTH @@ -1469,7 +1469,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 70, // SK_BOWS 100, // SK_CROSSBOWS 70, // SK_DARTS - 90, // SK_THROWING + 90, // SK_RANGED_COMBAT 170, // SK_ARMOUR 50, // SK_DODGING 50, // SK_STEALTH @@ -1512,7 +1512,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 90, // SK_BOWS 90, // SK_CROSSBOWS 90, // SK_DARTS - 90, // SK_THROWING + 90, // SK_RANGED_COMBAT 80, // SK_ARMOUR 80, // SK_DODGING 130, // SK_STEALTH @@ -1555,7 +1555,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 110, // SK_BOWS 110, // SK_CROSSBOWS 110, // SK_DARTS - 110, // SK_THROWING + 110, // SK_RANGED_COMBAT 110, // SK_ARMOUR 110, // SK_DODGING 110, // SK_STEALTH @@ -1598,7 +1598,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 130, // SK_BOWS 130, // SK_CROSSBOWS 130, // SK_DARTS - 130, // SK_THROWING + 130, // SK_RANGED_COMBAT 110, // SK_ARMOUR 110, // SK_DODGING 80, // SK_STEALTH @@ -1641,7 +1641,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 80, // SK_BOWS 80, // SK_CROSSBOWS 90, // SK_DARTS - 90, // SK_THROWING + 90, // SK_RANGED_COMBAT 90, // SK_ARMOUR 90, // SK_DODGING 100, // SK_STEALTH @@ -1684,7 +1684,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 140, // SK_BOWS 140, // SK_CROSSBOWS 100, // SK_DARTS - 100, // SK_THROWING + 100, // SK_RANGED_COMBAT 160, // SK_ARMOUR 60, // SK_DODGING 90, // SK_STEALTH @@ -1732,7 +1732,7 @@ const int spec_skills[ NUM_SPECIES ][40] = { 120, // SK_BOWS 120, // SK_CROSSBOWS 120, // SK_DARTS - 120, // SK_THROWING + 120, // SK_RANGED_COMBAT 200, // SK_ARMOUR 120, // SK_DODGING 120, // SK_STEALTH @@ -1894,7 +1894,7 @@ void show_skills(void) } /* Extra CR between classes of weapons and such things */ - if (x == SK_STAVES || x == SK_THROWING || x == SK_TRAPS_DOORS + if (x == SK_STAVES || x == SK_RANGED_COMBAT || x == SK_TRAPS_DOORS || x == SK_UNARMED_COMBAT || x == SK_POISON_MAGIC) { scrln++; @@ -2333,8 +2333,10 @@ void wield_warning(bool newWeapon) return; } + // [dshaligram] No more annoying throwing skill warnings. +#ifdef OBSOLETE_THROW_SKILL_WARNING // must be a launcher - int effSkill = you.skills[SK_THROWING] * 2 + 1; + int effSkill = you.skills[SK_RANGED_COMBAT] * 2 + 1; int shoot_skill = 0; switch (wepType) @@ -2363,4 +2365,5 @@ void wield_warning(bool newWeapon) strcat( info, wepstr ); mpr( info, MSGCH_WARN ); } +#endif } diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 53a3d580dd..a559b66f84 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -29,6 +29,7 @@ #include "invent.h" #include "it_use2.h" #include "itemname.h" +#include "itemprop.h" #include "misc.h" #include "monplace.h" #include "monstuff.h" @@ -82,7 +83,7 @@ void blink(void) } } - if (grd[beam.tx][beam.ty] <= DNGN_LAST_SOLID_TILE + if (grid_is_solid(grd[beam.tx][beam.ty]) || mgrd[beam.tx][beam.ty] != NON_MONSTER) { mpr("Oops! Maybe something was there already."); @@ -215,9 +216,10 @@ void cast_fire_storm(int powc) beam.beam_source = MHITYOU; beam.thrower = KILL_YOU_MISSILE; beam.aux_source = NULL; - beam.obviousEffect = false; - beam.isBeam = false; - beam.isTracer = false; + beam.obvious_effect = false; + beam.is_beam = false; + beam.is_tracer = false; + beam.is_explosion = true; beam.ench_power = powc; // used for radius strcpy( beam.beam_name, "great blast of fire" ); beam.hit = 20 + powc / 10; @@ -244,11 +246,10 @@ void cast_chain_lightning( int powc ) beam.hit = AUTOMATIC_HIT; beam.type = SYM_ZAP; beam.flavour = BEAM_ELECTRICITY; - beam.obviousEffect = true; - beam.isBeam = false; // since we want to stop at our target - beam.isExplosion = false; - beam.isTracer = false; - beam.isExplosion = false; + beam.obvious_effect = true; + beam.is_beam = false; // since we want to stop at our target + beam.is_explosion = false; + beam.is_tracer = false; int sx, sy; int tx, ty; @@ -436,7 +437,7 @@ void conjure_flame(int pow) continue; } - if (grd[ spelld.tx ][ spelld.ty ] <= DNGN_LAST_SOLID_TILE + if (grid_is_solid(grd[ spelld.tx ][ spelld.ty ]) || mgrd[ spelld.tx ][ spelld.ty ] != NON_MONSTER || env.cgrid[ spelld.tx ][ spelld.ty ] != EMPTY_CLOUD) { @@ -490,8 +491,8 @@ void stinking_cloud( int pow ) beem.beam_source = MHITYOU; beem.thrower = KILL_YOU; beem.aux_source = NULL; - beem.isBeam = false; - beem.isTracer = false; + beem.is_beam = false; + beem.is_tracer = false; fire_beam(beem); } // end stinking_cloud() @@ -1187,7 +1188,7 @@ void manage_fire_shield(void) //if ( one_chance_in(3) ) beam.range ++; - if (grd[you.x_pos + stx][you.y_pos + sty] > DNGN_LAST_SOLID_TILE + if (!grid_is_solid(grd[you.x_pos + stx][you.y_pos + sty]) && env.cgrid[you.x_pos + stx][you.y_pos + sty] == EMPTY_CLOUD) { place_cloud( CLOUD_FIRE, you.x_pos + stx, you.y_pos + sty, diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index b8bb4a78d4..3c61fc2aa7 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -32,6 +32,7 @@ #include "dungeon.h" #include "effects.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "misc.h" #include "monplace.h" @@ -116,7 +117,7 @@ unsigned char detect_items( int pow ) static void fuzz_detect_creatures(int pow, int *fuzz_radius, int *fuzz_chance) { #ifdef DEBUG_DIAGNOSTICS - mprf("dc_fuzz: Power is %d", pow); + mprf(MSGCH_DIAGNOSTICS, "dc_fuzz: Power is %d", pow); #endif if (pow < 1) @@ -570,8 +571,7 @@ bool brand_weapon(int which_brand, int power) in_name( wpn, DESC_CAP_YOUR, str_pass ); strcpy( info, str_pass ); - const int wpn_type = damage_type( you.inv[wpn].base_type, - you.inv[wpn].sub_type ); + const int wpn_type = damage_type(you.inv[wpn]); switch (which_brand) // use SPECIAL_WEAPONS here? { @@ -748,7 +748,7 @@ void turn_undead(int pow) // used to inflict random2(5) + (random2(pow) / 20) damage, // in addition {dlb} - if (mons_holiness(monster->type) == MH_UNDEAD) + if (mons_holiness(monster) == MH_UNDEAD) { if (check_mons_resist_magic( monster, pow )) { @@ -791,8 +791,8 @@ void holy_word(int pow, bool silent) if (monster->type == -1 || !mons_near(monster)) continue; - if (mons_holiness(monster->type) == MH_UNDEAD - || mons_holiness(monster->type) == MH_DEMONIC) + if (mons_holiness(monster) == MH_UNDEAD + || mons_holiness(monster) == MH_DEMONIC) { simple_monster_message(monster, " convulses!"); @@ -959,7 +959,7 @@ void drain_life(int pow) if (monster->type == -1) continue; - if (mons_holiness( monster->type ) != MH_NATURAL) + if (mons_holiness(monster) != MH_NATURAL) continue; if (mons_res_negative_energy( monster )) @@ -1030,7 +1030,7 @@ int vampiric_drain(int pow) monster = &menv[mgr]; - const int holy = mons_holiness(monster->type); + const int holy = mons_holiness(monster); if (holy == MH_UNDEAD || holy == MH_DEMONIC) { diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index ff66e68eb1..1d6f710b05 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -26,6 +26,7 @@ #include "debug.h" #include "delay.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "it_use2.h" #include "misc.h" @@ -164,7 +165,7 @@ bool detect_curse(bool suppress_msg) || you.inv[loopy].base_type == OBJ_ARMOUR || you.inv[loopy].base_type == OBJ_JEWELLERY)) { - if (item_not_ident( you.inv[loopy], ISFLAG_KNOW_CURSE )) + if (!item_ident( you.inv[loopy], ISFLAG_KNOW_CURSE )) success = true; set_ident_flags( you.inv[loopy], ISFLAG_KNOW_CURSE ); @@ -868,7 +869,7 @@ bool project_noise(void) // player can use this spell to "sound out" the dungeon -- bwr if (plox[0] > 1 && plox[0] < (GXM - 2) && plox[1] > 1 && plox[1] < (GYM - 2) - && grd[ plox[0] ][ plox[1] ] > DNGN_LAST_SOLID_TILE) + && !grid_is_solid(grd[ plox[0] ][ plox[1] ])) { noisy( 30, plox[0], plox[1] ); success = true; @@ -939,7 +940,7 @@ bool recall(char type_recalled) || monster->number == LIGHTRED)) ) { if (monster->type != MONS_REAPER - && mons_holiness(monster->type) != MH_UNDEAD) + && mons_holiness(monster) != MH_UNDEAD) { continue; } diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index b8082ce6d0..076be063a6 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -28,6 +28,7 @@ #include "effects.h" #include "it_use2.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "invent.h" #include "misc.h" @@ -57,7 +58,6 @@ enum DEBRIS // jmf: add for shatter, dig, and Giants to throw NUM_DEBRIS }; // jmf: ...and I'll actually implement the items Real Soon Now... -static bool mons_can_host_shuggoth(int type); // static int make_a_random_cloud(int x, int y, int pow, int ctype); static int make_a_rot_cloud(int x, int y, int pow, int ctype); static int quadrant_blink(int x, int y, int pow, int garbage); @@ -708,6 +708,7 @@ void cast_sticks_to_snakes(int pow) || you.inv[ weapon ].sub_type == WPN_GIANT_CLUB || you.inv[ weapon ].sub_type == WPN_GIANT_SPIKED_CLUB || you.inv[ weapon ].sub_type == WPN_BOW + || you.inv[ weapon ].sub_type == WPN_LONGBOW || you.inv[ weapon ].sub_type == WPN_ANCUS || you.inv[ weapon ].sub_type == WPN_HALBERD || you.inv[ weapon ].sub_type == WPN_GLAIVE @@ -720,7 +721,7 @@ void cast_sticks_to_snakes(int pow) // ogres, and most importantly ogre magi). Still it's unlikely // any character is strong enough to bother lugging a few of // these around. -- bwr - if (mass_item( you.inv[ weapon ] ) < 500) + if (item_mass( you.inv[ weapon ] ) < 500) mon = MONS_SNAKE; else mon = MONS_BROWN_SNAKE; @@ -851,7 +852,7 @@ static int sleep_monsters(int x, int y, int pow, int garbage) int mnstr = mgrd[x][y]; if (mnstr == NON_MONSTER) return 0; - if (mons_holiness( menv[mnstr].type ) != MH_NATURAL) return 0; + if (mons_holiness(&menv[mnstr]) != MH_NATURAL) return 0; if (check_mons_resist_magic( &menv[mnstr], pow )) return 0; // Why shouldn't we be able to sleep friendly monsters? -- bwr @@ -884,7 +885,7 @@ static int tame_beast_monsters(int x, int y, int pow, int garbage) struct monsters *monster = &menv[which_mons]; - if (mons_holiness(monster->type) != MH_NATURAL) return 0; + if (mons_holiness(monster) != MH_NATURAL) return 0; if (mons_intel_type(monster->type) != I_ANIMAL) return 0; if (mons_friendly(monster)) return 0; @@ -1012,7 +1013,7 @@ static int ignite_poison_monsters(int x, int y, int pow, int garbage) struct monsters *const mon = &menv[ mon_index ]; // Monsters which have poison corpses or poisonous attacks: - if (mons_corpse_thingy( mon->type ) == CE_POISONOUS + if (mons_corpse_effect( mon->type ) == CE_POISONOUS || mon->type == MONS_GIANT_ANT || mon->type == MONS_SMALL_SNAKE || mon->type == MONS_SNAKE @@ -1707,7 +1708,7 @@ static int intoxicate_monsters(int x, int y, int pow, int garbage) return 0; if (mons_intel(menv[mon].type) < I_NORMAL) return 0; - if (mons_holiness(menv[mon].type) != MH_NATURAL) + if (mons_holiness(&menv[mon]) != MH_NATURAL) return 0; if (mons_res_poison(&menv[mon]) > 0) return 0; @@ -1746,7 +1747,7 @@ static int glamour_monsters(int x, int y, int pow, int garbage) if (mons_intel(menv[mon].type) < I_NORMAL) return (0); - if (mons_holiness(mon) != MH_NATURAL) + if (mons_class_holiness(mon) != MH_NATURAL) return (0); if (!mons_is_humanoid( menv[mon].type )) @@ -1936,10 +1937,10 @@ void cast_evaporate(int pow) beem.beam_source = MHITYOU; beem.thrower = KILL_YOU_MISSILE; beem.aux_source = NULL; - beem.isBeam = false; - beem.isTracer = false; + beem.is_beam = false; + beem.is_tracer = false; - beem.hit = you.dex / 2 + roll_dice( 2, you.skills[SK_THROWING] / 2 + 1 ); + beem.hit = you.dex / 2 + roll_dice( 2, you.skills[SK_RANGED_COMBAT] / 2 + 1 ); beem.damage = dice_def( 1, 0 ); // no damage, just producing clouds beem.ench_power = pow; // used for duration only? @@ -2016,7 +2017,7 @@ void cast_evaporate(int pow) } if (coinflip()) - exercise( SK_THROWING, 1 ); + exercise( SK_RANGED_COMBAT, 1 ); fire_beam(beem); @@ -2103,7 +2104,7 @@ void cast_fulsome_distillation( int powc ) break; default: - switch (mons_corpse_thingy( mitm[corpse].plus )) + switch (mons_corpse_effect( mitm[corpse].plus )) { case CE_CLEAN: potion_type = (power_up ? POT_CONFUSION : POT_WATER); @@ -2208,7 +2209,7 @@ static int rot_living(int x, int y, int pow, int message) if (mon == NON_MONSTER) return 0; - if (mons_holiness(menv[mon].type) != MH_NATURAL) + if (mons_holiness(&menv[mon]) != MH_NATURAL) return 0; if (check_mons_resist_magic(&menv[mon], pow)) @@ -2240,7 +2241,7 @@ static int rot_undead(int x, int y, int pow, int garbage) if (mon == NON_MONSTER) return 0; - if (mons_holiness(menv[mon].type) != MH_UNDEAD) + if (mons_holiness(&menv[mon]) != MH_UNDEAD) return 0; if (check_mons_resist_magic(&menv[mon], pow)) @@ -2315,7 +2316,7 @@ void do_monster_rot(int mon) { int damage = 1 + random2(3); - if (mons_holiness(menv[mon].type) == MH_UNDEAD && random2(5)) + if (mons_holiness(&menv[mon]) == MH_UNDEAD && random2(5)) { apply_area_cloud(make_a_normal_cloud, menv[mon].x, menv[mon].y, 10, 1, CLOUD_MIASMA); @@ -2378,7 +2379,7 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike blast.colour = 0; blast.target_x = beam.tx; blast.target_y = beam.ty; - blast.isTracer = false; + blast.is_tracer = false; blast.flavour = BEAM_FRAG; // Number of dice vary... 3 is easy/common, but it can get as high as 6. @@ -2930,7 +2931,7 @@ void cast_apportation(int pow) } // mass of one unit - const int unit_mass = mass_item( mitm[ item ] ); + const int unit_mass = item_mass( mitm[ item ] ); // assume we can pull everything int max_units = mitm[ item ].quantity; @@ -3010,63 +3011,6 @@ void cast_sandblast(int pow) } } // end cast_sandblast() -static bool mons_can_host_shuggoth(int type) //jmf: simplified -{ - if (mons_holiness(type) != MH_NATURAL) - return false; - if (mons_class_flag(type, M_WARM_BLOOD)) - return true; - - return false; -} - -void cast_shuggoth_seed(int powc) -{ - struct dist beam; - int i; - - mpr("Sow seed in whom?", MSGCH_PROMPT); - - direction( beam, DIR_TARGET, TARG_ENEMY ); - - if (!beam.isValid) - { - mpr("You feel a distant frustration."); - return; - } - - if (beam.isMe) - { - if (!you.is_undead) - { - you.duration[DUR_INFECTED_SHUGGOTH_SEED] = 10; - mpr("A deathly dread twitches in your chest."); - } - else - mpr("You feel a distant frustration."); - } - - i = mgrd[beam.tx][beam.ty]; - - if (i == NON_MONSTER) - { - mpr("You feel a distant frustration."); - return; - } - - if (mons_can_host_shuggoth(menv[i].type)) - { - if (random2(powc) > 100) - mons_add_ench(&menv[i], ENCH_YOUR_SHUGGOTH_III); - else - mons_add_ench(&menv[i], ENCH_YOUR_SHUGGOTH_IV); - - simple_monster_message(&menv[i], " twitches."); - } - - return; -} - void cast_condensation_shield(int pow) { if (you.equip[EQ_SHIELD] != -1 || you.fire_shield) diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc index f162e31cfe..302afdab4c 100644 --- a/crawl-ref/source/spl-book.cc +++ b/crawl-ref/source/spl-book.cc @@ -29,6 +29,7 @@ #include "food.h" #include "invent.h" #include "itemname.h" +#include "itemprop.h" #include "items.h" #include "it_use3.h" #include "player.h" @@ -888,7 +889,7 @@ unsigned char spellbook_contents( item_def &book, int action, out.cprintf( "Select a spell to cast." EOL ); break; - case RBOOK_MEMORIZE: + case RBOOK_MEMORISE: out.cprintf( "Select a spell to memorise (%d level%s available)." EOL, spell_levels, (spell_levels == 1) ? "" : "s" ); break; @@ -1074,7 +1075,7 @@ static bool which_spellbook( int &book, int &spell ) return (false); } - spell = read_book( you.inv[book], RBOOK_MEMORIZE ); + spell = read_book( you.inv[book], RBOOK_MEMORISE ); clrscr(); return (true); @@ -1409,7 +1410,7 @@ bool learn_spell(void) #endif } - start_delay( DELAY_MEMORIZE, spell_difficulty( specspell ), specspell ); + start_delay( DELAY_MEMORISE, spell_difficulty( specspell ), specspell ); you.turn_is_over = 1; redraw_screen(); @@ -1424,7 +1425,7 @@ int count_staff_spells(const item_def &item, bool need_id) if (item.base_type != OBJ_STAVES) return (-1); - if (need_id && item_not_ident( item, ISFLAG_KNOW_TYPE )) + if (need_id && !item_ident( item, ISFLAG_KNOW_TYPE )) return (0); const int stype = item.sub_type; @@ -1467,7 +1468,7 @@ int staff_spell( int staff ) return (0); } - if (item_not_ident( you.inv[staff], ISFLAG_KNOW_TYPE )) + if (!item_ident( you.inv[staff], ISFLAG_KNOW_TYPE )) { set_ident_flags( you.inv[staff], ISFLAG_KNOW_TYPE ); you.wield_change = true; diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index e572fe4a6e..fb6d60bf62 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -31,6 +31,7 @@ #include "food.h" #include "it_use2.h" #include "itemname.h" +#include "itemprop.h" #include "macro.h" #include "monplace.h" #include "monstuff.h" @@ -676,7 +677,7 @@ bool your_spells( int spc2, int powc, bool allow_fail ) if (you.equip[EQ_WEAPON] != -1 && item_is_staff( you.inv[you.equip[EQ_WEAPON]] ) - && item_not_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE )) + && !item_ident( you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_TYPE )) { switch (you.inv[you.equip[EQ_WEAPON]].sub_type) { @@ -1861,10 +1862,6 @@ bool your_spells( int spc2, int powc, bool allow_fail ) cast_rotting(powc); break; - case SPELL_SHUGGOTH_SEED: - cast_shuggoth_seed(powc); - break; - case SPELL_CONDENSATION_SHIELD: cast_condensation_shield(powc); break; @@ -2018,7 +2015,7 @@ bool miscast_effect( unsigned int sp_type, int mag_pow, int mag_fail, } // setup beam - beam.isTracer = false; + beam.is_tracer = false; spec_effect = spec_effect / 100; diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index aebf186999..d024fada5b 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -26,6 +26,7 @@ #include "stuff.h" #include "itemname.h" #include "macro.h" +#include "misc.h" #include "monstuff.h" #include "player.h" #include "spl-book.h" @@ -781,7 +782,7 @@ static struct playerspell *seekspell(int spell) static bool cloud_helper( int (*func) (int, int, int, int), int x, int y, int pow, int ctype ) { - if (grd[x][y] > DNGN_LAST_SOLID_TILE && env.cgrid[x][y] == EMPTY_CLOUD) + if (!grid_is_solid(grd[x][y]) && env.cgrid[x][y] == EMPTY_CLOUD) { func(x, y, pow, ctype); return true; diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc index 0c7dfe6e34..496a113bd8 100644 --- a/crawl-ref/source/stash.cc +++ b/crawl-ref/source/stash.cc @@ -9,6 +9,7 @@ #include "clua.h" #include "describe.h" #include "itemname.h" +#include "itemprop.h" #include "files.h" #include "invent.h" #include "items.h" diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 7826d6b269..01b5b8a030 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -357,6 +357,31 @@ void pop_rng_state() #endif // USE_SYSTEM_RAND +// Attempts to make missile weapons nicer to the player by +// reducing the extreme variance in damage done. +void scale_dice( dice_def &dice, int threshold ) +{ + while (dice.size > threshold) + { + dice.num *= 2; + // If it's an odd number, lose one; this is more than + // compensated by the increase in number of dice. + dice.size = dice.size / 2; + } +} + +int bestroll(int max, int rolls) +{ + int best = 0; + for (int i = 0; i < rolls; i++) + { + int curr = random2(max); + if (curr > best) + best = curr; + } + return (best); +} + // random2avg() returns same mean value as random2() but with a lower variance // never use with rolls < 2 as that would be silly - use random2() instead {dlb} int random2avg(int max, int rolls) @@ -734,6 +759,199 @@ unsigned char random_colour(void) return (1 + random2(15)); } // end random_colour() +// returns if a colour is one of the special element colours (ie not regular) +bool is_element_colour( int col ) +{ + // striping any COLFLAGS (just in case) + return ((col & 0x007f) >= EC_FIRE); +} + +int element_colour( int element, bool no_random ) +{ + // Doing this so that we don't have to do recursion here at all + // (these were the only cases which had possible double evaluation): + if (element == EC_FLOOR) + element = env.floor_colour; + else if (element == EC_ROCK) + element = env.rock_colour; + + // pass regular colours through for safety. + if (!is_element_colour( element )) + return (element); + + int ret = BLACK; + + // Setting no_random to true will get the first colour in the cases + // below. This is potentially useful for calls to this function + // which might want a consistant result. + int tmp_rand = (no_random ? 0 : random2(120)); + + switch (element & 0x007f) // strip COLFLAGs just in case + { + case EC_FIRE: + ret = (tmp_rand < 40) ? RED : + (tmp_rand < 80) ? YELLOW + : LIGHTRED; + break; + + case EC_ICE: + ret = (tmp_rand < 40) ? LIGHTBLUE : + (tmp_rand < 80) ? BLUE + : WHITE; + break; + + case EC_EARTH: + ret = (tmp_rand < 60) ? BROWN : LIGHTRED; + break; + + case EC_AIR: + ret = (tmp_rand < 60) ? LIGHTGREY : WHITE; + break; + + case EC_ELECTRICITY: + ret = (tmp_rand < 40) ? LIGHTCYAN : + (tmp_rand < 80) ? LIGHTBLUE + : CYAN; + break; + + case EC_POISON: + ret = (tmp_rand < 60) ? LIGHTGREEN : GREEN; + break; + + case EC_WATER: + ret = (tmp_rand < 60) ? BLUE : CYAN; + break; + + case EC_MAGIC: + ret = (tmp_rand < 30) ? LIGHTMAGENTA : + (tmp_rand < 60) ? LIGHTBLUE : + (tmp_rand < 90) ? MAGENTA + : BLUE; + break; + + case EC_MUTAGENIC: + case EC_WARP: + ret = (tmp_rand < 60) ? LIGHTMAGENTA : MAGENTA; + break; + + case EC_ENCHANT: + ret = (tmp_rand < 60) ? LIGHTBLUE : BLUE; + break; + + case EC_HEAL: + ret = (tmp_rand < 60) ? LIGHTBLUE : YELLOW; + break; + + case EC_BLOOD: + ret = (tmp_rand < 60) ? RED : DARKGREY; + break; + + case EC_DEATH: // assassin + case EC_NECRO: // necromancer + ret = (tmp_rand < 80) ? DARKGREY : MAGENTA; + break; + + case EC_UNHOLY: // ie demonology + ret = (tmp_rand < 80) ? DARKGREY : RED; + break; + + case EC_DARK: + ret = DARKGREY; + break; + + case EC_HOLY: + ret = (tmp_rand < 60) ? YELLOW : WHITE; + break; + + case EC_VEHUMET: + ret = (tmp_rand < 40) ? LIGHTRED : + (tmp_rand < 80) ? LIGHTMAGENTA + : LIGHTBLUE; + break; + + case EC_CRYSTAL: + ret = (tmp_rand < 40) ? LIGHTGREY : + (tmp_rand < 80) ? GREEN + : LIGHTRED; + break; + + case EC_SLIME: + ret = (tmp_rand < 40) ? GREEN : + (tmp_rand < 80) ? BROWN + : LIGHTGREEN; + break; + + case EC_SMOKE: + ret = (tmp_rand < 30) ? LIGHTGREY : + (tmp_rand < 60) ? DARKGREY : + (tmp_rand < 90) ? LIGHTBLUE + : MAGENTA; + break; + + case EC_JEWEL: + ret = (tmp_rand < 12) ? WHITE : + (tmp_rand < 24) ? YELLOW : + (tmp_rand < 36) ? LIGHTMAGENTA : + (tmp_rand < 48) ? LIGHTRED : + (tmp_rand < 60) ? LIGHTGREEN : + (tmp_rand < 72) ? LIGHTBLUE : + (tmp_rand < 84) ? MAGENTA : + (tmp_rand < 96) ? RED : + (tmp_rand < 108) ? GREEN + : BLUE; + break; + + case EC_ELVEN: + ret = (tmp_rand < 40) ? LIGHTGREEN : + (tmp_rand < 80) ? GREEN : + (tmp_rand < 100) ? LIGHTBLUE + : BLUE; + break; + + case EC_DWARVEN: + ret = (tmp_rand < 40) ? BROWN : + (tmp_rand < 80) ? LIGHTRED : + (tmp_rand < 100) ? LIGHTGREY + : CYAN; + break; + + case EC_ORCISH: + ret = (tmp_rand < 40) ? DARKGREY : + (tmp_rand < 80) ? RED : + (tmp_rand < 100) ? BROWN + : MAGENTA; + break; + + case EC_GILA: + ret = (tmp_rand < 30) ? LIGHTMAGENTA : + (tmp_rand < 60) ? MAGENTA : + (tmp_rand < 90) ? YELLOW : + (tmp_rand < 105) ? LIGHTRED + : RED; + break; + + case EC_STONE: + if (player_in_branch( BRANCH_HALL_OF_ZOT )) + ret = env.rock_colour; + else + ret = LIGHTGREY; + break; + + case EC_RANDOM: + ret = 1 + random2(15); // always random + break; + + case EC_FLOOR: // should alredy be handled + case EC_ROCK: // should alredy be handled + default: + break; + } + + ASSERT( !is_element_colour( ret ) ); + + return ((ret == BLACK) ? GREEN : ret); +} + char index_to_letter(int the_index) { return (the_index + ((the_index < 26) ? 'a' : ('A' - 26))); diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h index 25691fd56f..4c9bf4474e 100644 --- a/crawl-ref/source/stuff.h +++ b/crawl-ref/source/stuff.h @@ -33,9 +33,11 @@ bool one_chance_in(int a_million); int random2(int randmax); unsigned long random_int(void); int random2avg( int max, int rolls ); +int bestroll(int max, int rolls); int roll_dice( int num, int size ); int roll_dice( const struct dice_def &dice ); +void scale_dice( dice_def &dice, int threshold = 24 ); int random2limit(int max, int limit); @@ -64,6 +66,8 @@ bool silenced(char x, char y); bool player_can_hear(char x, char y); unsigned char random_colour(void); +bool is_element_colour( int col ); +int element_colour( int element, bool no_random = false ); char index_to_letter (int the_index); diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index b115cbf6fe..715fb01285 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -84,6 +84,7 @@ #include "externs.h" #include "files.h" #include "itemname.h" +#include "itemprop.h" #include "monstuff.h" #include "mon-util.h" #include "randart.h" diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc index 9ee38d548d..144a838bb2 100644 --- a/crawl-ref/source/transfor.cc +++ b/crawl-ref/source/transfor.cc @@ -440,7 +440,7 @@ void untransform(void) // probably need something better to cover all possibilities. -bwr if ((you.species == SP_NAGA || you.species == SP_CENTAUR) && you.equip[ EQ_BOOTS ] != -1 - && you.inv[ you.equip[EQ_BOOTS] ].plus2 != TBOOT_NAGA_BARDING) + && you.inv[ you.equip[EQ_BOOTS] ].sub_type != ARM_NAGA_BARDING) { rem_stuff[EQ_BOOTS] = 1; remove_equipment(rem_stuff); @@ -451,7 +451,7 @@ void untransform(void) // XXX: This whole system is a mess as it still relies on special // cases to handle a large number of things (see wear_armour()) -- bwr -bool can_equip( char use_which ) +bool can_equip( equipment_type use_which ) { // if more cases are added to this if must also change in @@ -519,6 +519,16 @@ bool can_equip( char use_which ) return (true); } // end can_equip() +// raw comparison of an item, must use check_armour_shape for full version +bool transform_can_equip_type( int eq_slot ) +{ + // FIXME FIXME FIXME + return (false); + + // const int form = you.attribute[ATTR_TRANSFORMATION]; + // return (!must_remove( Trans[form].rem_stuff, eq_slot )); +} + void extra_hp(int amount_extra) // must also set in calc_hp { calc_hp(); @@ -549,3 +559,16 @@ void drop_everything(void) return; } // end drop_everything() + +// Used to mark transformations which override species/mutation intrinsics. +// If phys_scales is true then we're checking to see if the form keeps +// the physical (AC/EV) properties from scales... the special intrinsic +// features (resistances, etc) are lost in those forms however. +bool transform_changed_physiology( bool phys_scales ) +{ + return (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE + && you.attribute[ATTR_TRANSFORMATION] != TRAN_BLADE_HANDS + && (!phys_scales + || (you.attribute[ATTR_TRANSFORMATION] != TRAN_LICH + && you.attribute[ATTR_TRANSFORMATION] != TRAN_STATUE))); +} diff --git a/crawl-ref/source/transfor.h b/crawl-ref/source/transfor.h index 5efa5a87b2..4fbbe1aaa7 100644 --- a/crawl-ref/source/transfor.h +++ b/crawl-ref/source/transfor.h @@ -13,6 +13,7 @@ #define TRANSFOR_H #include "FixVec.h" +#include "enum.h" // last updated 12may2000 {dlb} @@ -26,7 +27,7 @@ void untransform(void); /* *********************************************************************** * called from: item_use * *********************************************************************** */ -bool can_equip(char use_which); +bool can_equip(equipment_type use_which); // last updated 12may2000 {dlb} @@ -42,5 +43,6 @@ bool transform(int pow, char which_trans); * *********************************************************************** */ bool remove_equipment( FixedVector<char, 8>& remove_stuff ); +bool transform_changed_physiology( bool phys_scales = false ); #endif diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc index 6d8347f8dc..5958e8fbf3 100644 --- a/crawl-ref/source/travel.cc +++ b/crawl-ref/source/travel.cc @@ -525,7 +525,6 @@ void initialise_travel() traversable_terrain[DNGN_FLOOR] = traversable_terrain[DNGN_ENTER_HELL] = traversable_terrain[DNGN_OPEN_DOOR] = - traversable_terrain[DNGN_BRANCH_STAIRS] = traversable_terrain[DNGN_UNDISCOVERED_TRAP] = traversable_terrain[DNGN_ENTER_SHOP] = traversable_terrain[DNGN_ENTER_LABYRINTH] = diff --git a/crawl-ref/source/version.h b/crawl-ref/source/version.h index cf8256e07d..5bc1dedec4 100644 --- a/crawl-ref/source/version.h +++ b/crawl-ref/source/version.h @@ -47,5 +47,6 @@ * *********************************************************************** */ #define BUILD_DATE __DATE__ +#define SAVE_MAJOR_VERSION 0 #endif diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 6bb8d1bdef..7adbceb4e8 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -224,11 +224,6 @@ static void get_ibm_symbol(unsigned int object, unsigned short *ch, *ch = 39; break; - case DNGN_BRANCH_STAIRS: - *ch = 240; - *color = BROWN; - break; - case DNGN_TRAP_MECHANICAL: *color = LIGHTCYAN; *ch = 94; @@ -738,35 +733,27 @@ void viewwindow2(char draw_it, bool do_updates) } } - if (you.flash_colour != BLACK - && buffy[bufcount + 1] != DARKGREY) - buffy[bufcount + 1] = you.flash_colour; - bufcount += 2; } } - if (you.flash_colour == BLACK) + const int flash_colour = + you.flash_colour != BLACK? you.flash_colour : + you.berserker ? RED : + show_green != BLACK ? show_green : + you.special_wield == SPWLD_SHADOW? DARKGREY : + BLACK; + if (flash_colour != BLACK) { - if (you.berserker) + for (count_x = 1; count_x < 1400; count_x += 2) { - for (count_x = 1; count_x < 1400; count_x += 2) - { - if (buffy[count_x] != DARKGREY) - buffy[count_x] = RED; - } + if (buffy[count_x] != DARKGREY) + buffy[count_x] = flash_colour; } if (show_green != BLACK) { - for (count_x = 1; count_x < 1400; count_x += 2) - { - if (buffy[count_x] != DARKGREY) - buffy[count_x] = show_green; - } - show_green = BLACK; - if (you.special_wield == SPWLD_SHADOW) show_green = DARKGREY; } @@ -1326,7 +1313,7 @@ bool check_awaken(int mons_aw) { int mons_perc = 0; struct monsters *monster = &menv[mons_aw]; - const int mon_holy = mons_holiness( monster->type ); + const int mon_holy = mons_holiness(monster); // berserkers aren't really concerned about stealth if (you.berserker) @@ -2799,8 +2786,6 @@ unsigned char mapchar(unsigned char ldfk) showed = '8'; break; - case DNGN_LAVA_X: - case DNGN_WATER_X: case DNGN_LAVA: case DNGN_DEEP_WATER: case DNGN_SHALLOW_WATER: @@ -2952,9 +2937,6 @@ unsigned char mapchar2(unsigned char ldfk) showed = 254; break; - //case DNGN_LAVA_X: showed = 247; break; // deprecated? {dlb} - //case DNGN_WATER_X: showed = 247; break; // deprecated? {dlb} - case 20: // orcish idol case 24: // ??? case 25: // ??? @@ -3242,11 +3224,6 @@ void get_non_ibm_symbol(unsigned int object, unsigned short *ch, *ch = '\''; break; - case DNGN_BRANCH_STAIRS: - *color = BROWN; - *ch = '>'; - break; - case DNGN_TRAP_MECHANICAL: *color = 11; *ch = '^'; @@ -3742,26 +3719,28 @@ void viewwindow3(char draw_it, bool do_updates) } } - if (you.berserker) + const int flash_colour = + you.flash_colour != BLACK? you.flash_colour : + you.berserker ? RED : + show_green != BLACK ? show_green : + you.special_wield == SPWLD_SHADOW? DARKGREY : + BLACK; + if (flash_colour != BLACK) { for (count_x = 1; count_x < 1400; count_x += 2) { if (buffy[count_x] != DARKGREY) - buffy[count_x] = RED; + buffy[count_x] = flash_colour; } - } - if (show_green != BLACK) - { - for (count_x = 1; count_x < 1400; count_x += 2) + if (show_green != BLACK) { - if (buffy[count_x] != DARKGREY) - buffy[count_x] = show_green; + show_green = BLACK; + if (you.special_wield == SPWLD_SHADOW) + show_green = DARKGREY; } - - show_green = ((you.special_wield == SPWLD_SHADOW) ? DARKGREY - : BLACK); } + you.flash_colour = BLACK; #ifdef DOS_TERM puttext(2, 1, 34, 17, buffy.buffer()); @@ -3828,8 +3807,6 @@ unsigned char mapchar3(unsigned char ldfk) showed = '8'; break; - case DNGN_LAVA_X: - case DNGN_WATER_X: case DNGN_LAVA: case DNGN_DEEP_WATER: case DNGN_SHALLOW_WATER: @@ -3990,8 +3967,6 @@ unsigned char mapchar4(unsigned char ldfk) showed = '8'; break; - case DNGN_LAVA_X: - case DNGN_WATER_X: case DNGN_LAVA: case DNGN_DEEP_WATER: case DNGN_SHALLOW_WATER: diff --git a/crawl-ref/source/wpn-misc.cc b/crawl-ref/source/wpn-misc.cc index afc7494c01..754401a7cd 100644 --- a/crawl-ref/source/wpn-misc.cc +++ b/crawl-ref/source/wpn-misc.cc @@ -25,9 +25,16 @@ ************************************************** */ -char damage_type(unsigned char wclass, unsigned char wtype) +// FIXME: Remove these eventually + +int damage_type(const item_def &item) { - char type_damage = DVORP_CRUSHING; // this is the default, btw {dlb} + return (damage_type(item.base_type, item.sub_type)); +} + +int damage_type(int wclass, int wtype) +{ + int type_damage = DVORP_CRUSHING; // this is the default, btw {dlb} if (wclass == OBJ_WEAPONS) { @@ -47,6 +54,8 @@ char damage_type(unsigned char wclass, unsigned char wtype) case WPN_SCYTHE: case WPN_SHORT_SWORD: case WPN_TRIPLE_SWORD: + case WPN_BLESSED_BLADE: + case WPN_LAJATANG: type_damage = DVORP_SLICING; break; @@ -67,6 +76,7 @@ char damage_type(unsigned char wclass, unsigned char wtype) case WPN_GLAIVE: case WPN_HALBERD: case WPN_HAND_AXE: + case WPN_LOCHABER_AXE: type_damage = DVORP_CHOPPING; break; } @@ -75,7 +85,7 @@ char damage_type(unsigned char wclass, unsigned char wtype) return (type_damage); } // end damage_type() -bool can_cut_meat(unsigned char wclass, unsigned char wtype) +bool can_cut_meat(int wclass, int wtype) { int type = damage_type( wclass, wtype ); @@ -85,9 +95,9 @@ bool can_cut_meat(unsigned char wclass, unsigned char wtype) return (false); } -int hands_reqd_for_weapon(unsigned char wclass, unsigned char wtype) +int hands_reqd_for_weapon(int wclass, int wtype) { - int reqd_hands = HANDS_ONE_HANDED; + int reqd_hands = HANDS_ONE; switch (wclass) { @@ -103,10 +113,14 @@ int hands_reqd_for_weapon(unsigned char wclass, unsigned char wtype) case WPN_GREAT_SWORD: case WPN_TRIPLE_SWORD: case WPN_GREAT_MACE: - case WPN_GREAT_FLAIL: + case WPN_DIRE_FLAIL: case WPN_GIANT_CLUB: case WPN_GIANT_SPIKED_CLUB: - reqd_hands = HANDS_TWO_HANDED; + case WPN_LOCHABER_AXE: + case WPN_BOW: + case WPN_LONGBOW: + case WPN_CROSSBOW: + reqd_hands = HANDS_TWO; break; case WPN_SPEAR: @@ -116,13 +130,17 @@ int hands_reqd_for_weapon(unsigned char wclass, unsigned char wtype) case WPN_BROAD_AXE: case WPN_KATANA: case WPN_DOUBLE_SWORD: - reqd_hands = HANDS_ONE_OR_TWO_HANDED; + case WPN_LAJATANG: + case WPN_HAND_CROSSBOW: + case WPN_BLOWGUN: + case WPN_SLING: + reqd_hands = HANDS_HALF; break; } break; case OBJ_STAVES: - reqd_hands = HANDS_TWO_HANDED; + reqd_hands = HANDS_TWO; break; } @@ -149,6 +167,7 @@ bool launches_things( unsigned char weapon_subtype ) { case WPN_SLING: case WPN_BOW: + case WPN_LONGBOW: case WPN_CROSSBOW: case WPN_HAND_CROSSBOW: case WPN_BLOWGUN: @@ -168,106 +187,13 @@ unsigned char launched_by(unsigned char weapon_subtype) case WPN_SLING: return MI_STONE; case WPN_BOW: + case WPN_LONGBOW: return MI_ARROW; case WPN_CROSSBOW: return MI_BOLT; case WPN_HAND_CROSSBOW: return MI_DART; default: - return MI_EGGPLANT; // lame debugging code :P {dlb} + return MI_NONE; // lame debugging code :P {dlb} } } // end launched_by() - -int weapon_skill(const item_def &item) -{ - return weapon_skill(item.base_type, item.sub_type); -} - -// this function returns the skill that the weapon would use in melee -int weapon_skill(int wclass, int wtype) -{ - int skill2use = SK_FIGHTING; - - if (wclass == OBJ_STAVES - && (wtype < STAFF_SMITING || wtype >= STAFF_AIR)) - { - skill2use = SK_STAVES; - } - else if (wclass != OBJ_WEAPONS) - skill2use = SK_FIGHTING; - else - { - switch (wtype) - { - case WPN_CLUB: - case WPN_MACE: - case WPN_HAMMER: - case WPN_ANCUS: - case WPN_WHIP: - case WPN_FLAIL: - case WPN_MORNINGSTAR: - case WPN_GIANT_CLUB: - case WPN_GIANT_SPIKED_CLUB: - case WPN_EVENINGSTAR: - case WPN_DEMON_WHIP: - case WPN_SPIKED_FLAIL: - case WPN_GREAT_FLAIL: - case WPN_GREAT_MACE: - case WPN_BOW: - case WPN_BLOWGUN: - case WPN_CROSSBOW: - case WPN_HAND_CROSSBOW: - skill2use = SK_MACES_FLAILS; - break; - - case WPN_KNIFE: - case WPN_DAGGER: - case WPN_SHORT_SWORD: - case WPN_QUICK_BLADE: - case WPN_SABRE: - skill2use = SK_SHORT_BLADES; - break; - - case WPN_FALCHION: - case WPN_LONG_SWORD: - case WPN_SCIMITAR: - case WPN_KATANA: - case WPN_DOUBLE_SWORD: - case WPN_DEMON_BLADE: - case WPN_GREAT_SWORD: - case WPN_TRIPLE_SWORD: - skill2use = SK_LONG_SWORDS; - break; - - case WPN_HAND_AXE: - case WPN_WAR_AXE: - case WPN_BROAD_AXE: - case WPN_BATTLEAXE: - case WPN_EXECUTIONERS_AXE: - skill2use = SK_AXES; - break; - - case WPN_SPEAR: - case WPN_HALBERD: - case WPN_GLAIVE: - case WPN_SCYTHE: - case WPN_TRIDENT: - case WPN_DEMON_TRIDENT: - skill2use = SK_POLEARMS; - break; - - case WPN_QUARTERSTAFF: - skill2use = SK_STAVES; - break; - } - } - - return (skill2use); -} // end weapon_skill() -/* - ************************************************** - * * - * END PUBLIC FUNCTIONS * - * * - ************************************************** -*/ diff --git a/crawl-ref/source/wpn-misc.h b/crawl-ref/source/wpn-misc.h index dce7ba7cd4..55b9e35c86 100644 --- a/crawl-ref/source/wpn-misc.h +++ b/crawl-ref/source/wpn-misc.h @@ -20,19 +20,20 @@ /* *********************************************************************** * called from: food.h * *********************************************************************** */ -bool can_cut_meat(unsigned char wclass, unsigned char wtype); +bool can_cut_meat(int wclass, int wtype); /* *********************************************************************** * called from: acr - fight - food - item_use - itemname - spells2 * *********************************************************************** */ -char damage_type(unsigned char wclass, unsigned char wtype); +int damage_type(int wclass, int wtype); +int damage_type(const item_def &item); // last updated: 10jun2000 {dlb} /* *********************************************************************** * called from: describe - fight - item_use * *********************************************************************** */ -int hands_reqd_for_weapon(unsigned char wclass, unsigned char wtype); +int hands_reqd_for_weapon(int wclass, int wtype); // last updated: 10jun2000 {dlb} @@ -57,13 +58,4 @@ unsigned char launched_by(unsigned char weapon_subtype); bool launches_things( unsigned char weapon_subtype ); -// last updated: 10jun2000 {dlb} -/* *********************************************************************** - * called from: describe - fight - files - it_use3 - newgame - spells1 - * *********************************************************************** */ -int weapon_skill(int wclass, int wtype); - -int weapon_skill(const item_def &item); - - #endif |