From 30414416d011ed83d9e7c8b753a56ac7096e6775 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Mon, 12 Feb 2007 07:40:59 +0000 Subject: Break up you_attack() into a slew of smaller functions. The functions are still fairly tangled, but they're better than the old monster. The idea is to also put monster-vs-player and monster-vs-monster into the melee_attack framework so that refactoring combat code with elements of 4.1 becomes easier. This is a big refactoring, so it's likely to be buggy. Some of the combat diagnostics - notably the damage rolls - are also AWOL. Will fix going forward. Note: The combat code is still classic b26. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@950 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/describe.cc | 4 +- crawl-ref/source/enum.h | 8 + crawl-ref/source/externs.h | 120 +- crawl-ref/source/fight.cc | 3348 +++++++++++++++++++++--------------------- crawl-ref/source/fight.h | 127 +- crawl-ref/source/it_use2.cc | 2 +- crawl-ref/source/item_use.cc | 50 +- crawl-ref/source/item_use.h | 2 + crawl-ref/source/mon-data.h | 740 +++++----- crawl-ref/source/mon-util.cc | 162 +- crawl-ref/source/mon-util.h | 4 +- crawl-ref/source/monplace.cc | 8 +- crawl-ref/source/monstuff.cc | 10 + crawl-ref/source/monstuff.h | 1 + crawl-ref/source/player.cc | 399 +++-- crawl-ref/source/player.h | 6 + crawl-ref/source/randart.cc | 11 +- crawl-ref/source/randart.h | 6 +- crawl-ref/source/shopping.cc | 3 +- crawl-ref/source/transfor.cc | 9 +- crawl-ref/source/view.cc | 27 +- 21 files changed, 2739 insertions(+), 2308 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index b8c834e835..7f8c52e54e 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -154,7 +154,7 @@ static void randart_descpr( std::string &description, const item_def &item ) { unsigned int old_length = description.length(); - FixedVector< char, RA_PROPERTIES > proprt; + randart_properties_t proprt; randart_wpn_properties( item, proprt ); if (proprt[ RAP_AC ]) @@ -4523,7 +4523,7 @@ static std::string describe_draconian(const monsters *mon) if (subsp == MONS_DRACONIAN) description += "A "; else - description += "An enormous, muscular "; + description += "A muscular "; switch (subsp) { diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 4c19fd10f4..9cb755a6d1 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -169,6 +169,13 @@ enum activity_interrupt_payload_type AIP_HP_LOSS }; +enum actor_type +{ + ACT_NONE = -1, + ACT_PLAYER, + ACT_MONSTER +}; + enum ammunition_description_type { DAMMO_ORCISH = 3, // 3 @@ -1835,6 +1842,7 @@ enum mons_class_flags M_UNIQUE = (1<<20), // monster is a unique M_CLAWS = (1<<21), // Chops off hydra heads in combat. + M_ACID_SPLASH = (1<<22), // Passive acid splash when hit. M_SPECIAL_ABILITY = (1<<26), // XXX: eventually make these spells? diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 5d53e443fe..0a57670a3f 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -96,6 +96,46 @@ struct activity_interrupt_data } }; +class item_def; +class melee_attack; +class coord_def; + +class actor +{ +public: + virtual ~actor() { } + + virtual int id() const = 0; + virtual actor_type atype() const = 0; + + virtual coord_def pos() const = 0; + virtual bool swimming() const = 0; + virtual bool floundering() const = 0; + + virtual size_type body_size(int psize = PSIZE_TORSO, + bool base = false) const = 0; + + virtual int damage_type(int which_attack = -1) = 0; + virtual int damage_brand(int which_attack = -1) = 0; + virtual item_def *weapon(int which_attack = -1) = 0; + virtual item_def *shield() = 0; + + virtual void make_hungry(int nutrition, bool silent) + { + } + + virtual std::string name(description_level_type type) const = 0; + virtual std::string conj_verb(const std::string &verb) const = 0; + + virtual bool fumbles_attack(bool verbose = true) = 0; + + // Returns true if the actor has no way to attack (plants, statues). + // (statues have only indirect attacks). + virtual bool cannot_fight() const = 0; + virtual void attacking(actor *other) = 0; + virtual void go_berserk(bool intentional) = 0; +}; + struct ait_hp_loss { int hp; @@ -380,8 +420,9 @@ private: typedef std::vector delay_queue_type; -struct player +class player : public actor { +public: bool turn_is_over; // flag signaling that player has performed a timed action bool banished; // flag signaling that the player is due a visit to the @@ -574,17 +615,52 @@ struct player FixedVector ability_letter_table; // ref to ability by enum public: - player(); - void init(); + player(); + void init(); + + bool is_valid() const; + std::string short_desc() const; + + // For sorting + bool operator < (const player &p) const; + +public: + bool in_water() const; + bool can_swim() const; + bool is_levitating() const; + + bool has_spell(int spell) const; + + size_type transform_size(int psize = PSIZE_TORSO) const; + + item_def *slot_item(equipment_type eq); + + // actor + int id() const; + coord_def pos() const; + bool swimming() const; + bool floundering() const; + size_type body_size(int psize = PSIZE_TORSO, bool base = false) const; + int damage_type(int attk = -1); + int damage_brand(int attk = -1); + item_def *weapon(int which_attack = -1); + item_def *shield(); + + std::string name(description_level_type type) const; + std::string conj_verb(const std::string &verb) const; + + bool fumbles_attack(bool verbose = true); + bool cannot_fight() const; - bool is_valid() const; - std::string short_desc() const; + void attacking(actor *other); + void go_berserk(bool intentional); - // For sorting - bool operator < (const player &p) const; + void make_hungry(int nutrition, bool silent); + + actor_type atype() const { return ACT_PLAYER; } }; -extern struct player you; +extern player you; class monster_spells : public FixedVector { @@ -595,8 +671,9 @@ public: void clear() { init(MS_NO_SPELL); } }; -struct monsters +class monsters : public actor { +public: int type; int hit_points; int max_hit_points; @@ -625,10 +702,27 @@ struct monsters god_type god; // Usually GOD_NO_GOD. - coord_def pos() const - { - return coord_def(x, y); - } +public: + // actor interface + int id() const; + coord_def pos() const; + bool swimming() const; + bool floundering() const; + size_type body_size(int psize = PSIZE_TORSO, bool base = false) const; + int damage_type(int attk = -1); + int damage_brand(int attk = -1); + item_def *weapon(int which_attack = -1); + item_def *shield(); + std::string name(description_level_type type) const; + std::string conj_verb(const std::string &verb) const; + + bool fumbles_attack(bool verbose = true); + bool cannot_fight() const; + + void attacking(actor *other); + void go_berserk(bool intentional); + + actor_type atype() const { return ACT_MONSTER; } }; struct cloud_struct diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 3fbae8f4e5..3af1ea3ef6 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -51,6 +51,7 @@ #include "items.h" #include "itemname.h" #include "itemprop.h" +#include "item_use.h" #include "macro.h" #include "misc.h" #include "monplace.h" @@ -78,9 +79,6 @@ // ... was 5, 12, 21 // how these are used will be replaced by a function in a second ... :P {dlb} -static int weapon_type_modify( int weap, char noise[80], char noise2[80], - int damage ); - static void stab_message(struct monsters *defender, int stab_bonus); int weapon_str_weight( int wpn_class, int wpn_type ); @@ -146,7 +144,7 @@ static int calc_your_to_hit_unarmed() int your_to_hit; your_to_hit = 13 + you.dex / 2 + you.skills[SK_UNARMED_COMBAT] / 2 - + you.skills[SK_FIGHTING] / 5; + + you.skills[SK_FIGHTING] / 5; if (wearing_amulet(AMU_INACCURACY)) your_to_hit -= 5; @@ -158,154 +156,13 @@ static int calc_your_to_hit_unarmed() return your_to_hit; } - + // Calculates your to-hit roll. If random_factor is true, be // stochastic; if false, determinstic (e.g. for chardumps.) -int calc_your_to_hit( int heavy_armour, - bool hand_and_a_half_bonus, - bool water_attack, - bool random_factor ) +int calc_your_to_hit( bool random_factor ) { - - const int weapon = you.equip[EQ_WEAPON]; - const bool ur_armed = (weapon != -1); // compacts code a bit {dlb} - - int wpn_skill = SK_UNARMED_COMBAT; - - if (weapon != -1) - { - wpn_skill = weapon_skill( you.inv[weapon].base_type, - you.inv[weapon].sub_type ); - } - - int your_to_hit; - - // preliminary to_hit modifications: - your_to_hit = 15 + (calc_stat_to_hit_base() / 2); - - if (water_attack) - your_to_hit += 5; - - if (wearing_amulet(AMU_INACCURACY)) - your_to_hit -= 5; - - // if you can't see yourself, you're a little less acurate. - if (you.invis && !player_see_invis()) - your_to_hit -= 5; - - // fighting contribution - your_to_hit += maybe_random2(1 + you.skills[SK_FIGHTING], random_factor); - - // weapon skill contribution - if (ur_armed) - { - if (wpn_skill != SK_FIGHTING) - { - your_to_hit += maybe_random2(you.skills[wpn_skill] + 1, - random_factor); - } - } - else - { // ...you must be unarmed - your_to_hit += - (you.species == SP_TROLL || you.species == SP_GHOUL) ? 4 : 2; - - your_to_hit += maybe_random2(1 + you.skills[SK_UNARMED_COMBAT], - random_factor); - } - - // weapon bonus contribution - if (ur_armed) - { - if (you.inv[ weapon ].base_type == OBJ_WEAPONS) - { - your_to_hit += you.inv[ weapon ].plus; - your_to_hit += property( you.inv[ weapon ], PWPN_HIT ); - - if (get_equip_race(you.inv[ weapon ]) == ISFLAG_ELVEN - && player_genus(GENPC_ELVEN)) - { - your_to_hit += (random_factor && coinflip() ? 2 : 1); - } - } - else if (item_is_staff( you.inv[ weapon ] )) - { - // magical staff - your_to_hit += property( you.inv[ weapon ], PWPN_HIT ); - } - } - - // slaying bonus - your_to_hit += slaying_bonus(PWPN_HIT); - - // hunger penalty - if (you.hunger_state == HS_STARVING) - your_to_hit -= 3; - - // armour penalty - your_to_hit -= heavy_armour; - -#if DEBUG_DIAGNOSTICS - int roll_hit = your_to_hit; -#endif - - // hit roll - your_to_hit = maybe_random2(your_to_hit, random_factor); - -#if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, "to hit die: %d; rolled value: %d", - roll_hit, your_to_hit ); - - mpr( info, MSGCH_DIAGNOSTICS ); -#endif - - if (hand_and_a_half_bonus) - your_to_hit += maybe_random2(3, random_factor); - - if (ur_armed && wpn_skill == SK_SHORT_BLADES && you.sure_blade) - your_to_hit += 5 + - (random_factor ? random2limit( you.sure_blade, 10 ) : - you.sure_blade / 2); - - // other stuff - if (!ur_armed) - { - if ( you.confusing_touch ) - // just trying to touch is easier that trying to damage - your_to_hit += maybe_random2(you.dex, random_factor); - - switch ( you.attribute[ATTR_TRANSFORMATION] ) - { - case TRAN_NONE: - break; - case TRAN_SPIDER: - your_to_hit += maybe_random2(10, random_factor); - break; - case TRAN_ICE_BEAST: - your_to_hit += maybe_random2(10, random_factor); - break; - case TRAN_BLADE_HANDS: - your_to_hit += maybe_random2(12, random_factor); - break; - case TRAN_STATUE: - your_to_hit += maybe_random2(9, random_factor); - break; - case TRAN_SERPENT_OF_HELL: - case TRAN_DRAGON: - your_to_hit += maybe_random2(10, random_factor); - break; - case TRAN_LICH: - your_to_hit += maybe_random2(10, random_factor); - break; - case TRAN_AIR: - your_to_hit = 0; - break; - default: - break; - } - } - - return your_to_hit; + melee_attack attk(&you, NULL); + return attk.calc_to_hit(random_factor); } // Calculates your heavy armour penalty. If random_factor is true, @@ -376,17 +233,19 @@ int calc_heavy_armour_penalty( bool random_factor ) } // Returns true if a head got lopped off. -static bool chop_hydra_head( const monsters *attacker, - monsters *defender, +static bool chop_hydra_head( const actor *attacker, + actor *def, int damage_done, int dam_type, int wpn_brand ) { + monsters *defender = dynamic_cast(def); + const bool defender_visible = mons_near(defender); // Monster attackers have only a 25% chance of making the // chop-check to prevent runaway head inflation. - if (attacker && !one_chance_in(4)) + if (attacker->atype() == ACT_MONSTER && !one_chance_in(4)) return (false); if ((dam_type == DVORP_SLICING || dam_type == DVORP_CHOPPING @@ -420,9 +279,9 @@ static bool chop_hydra_head( const monsters *attacker, { if (defender_visible) mprf( "%s %s %s's last head off!", - actor_name(attacker, DESC_CAP_THE).c_str(), - actor_verb(attacker, verb).c_str(), - str_monam(defender, DESC_NOCAP_THE).c_str() ); + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb(verb).c_str(), + defender->name(DESC_NOCAP_THE).c_str() ); defender->hit_points = -1; } @@ -430,9 +289,9 @@ static bool chop_hydra_head( const monsters *attacker, { if (defender_visible) mprf( "%s %s one of %s's heads off!", - actor_name(attacker, DESC_CAP_THE).c_str(), - actor_verb(attacker, verb).c_str(), - str_monam(defender, DESC_NOCAP_THE).c_str() ); + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb(verb).c_str(), + defender->name(DESC_NOCAP_THE).c_str() ); if (wpn_brand == SPWPN_FLAMING) { @@ -453,13 +312,13 @@ static bool chop_hydra_head( const monsters *attacker, return (false); } -static bool actor_decapitates_hydra(monsters *attacker, monsters *defender, +static bool actor_decapitates_hydra(actor *attacker, actor *defender, int damage_done) { - if (defender->type == MONS_HYDRA) + if (defender->id() == MONS_HYDRA) { - const int dam_type = actor_damage_type(attacker); - const int wpn_brand = actor_damage_brand(attacker); + const int dam_type = attacker->damage_type(); + const int wpn_brand = attacker->damage_brand(); return chop_hydra_head(attacker, defender, damage_done, dam_type, wpn_brand); @@ -467,165 +326,104 @@ static bool actor_decapitates_hydra(monsters *attacker, monsters *defender, return (false); } -static bool player_fumbles_attack() +static bool player_fights_well_unarmed(int heavy_armour_penalty) { - // fumbling in shallow water : - if (player_in_water() && !player_is_swimming()) - { - if (random2(you.dex) < 4 || one_chance_in(5)) - { - mpr("Unstable footing causes you to fumble your attack."); - return (true); - } - } - return (false); + return (you.burden_state == BS_UNENCUMBERED + && random2(20) < you.skills[SK_UNARMED_COMBAT] + && random2(1 + heavy_armour_penalty) < 2); } -// Returns true if you hit the monster. -bool you_attack(int monster_attacked, bool unarmed_attacks) +////////////////////////////////////////////////////////////////////////// +// Melee attack + +melee_attack::melee_attack(actor *attk, actor *defn, + bool allow_unarmed, int which_attack) + : attacker(attk), defender(defn), + atk(NULL), def(NULL), + unarmed_ok(allow_unarmed), + attack_number(which_attack), + to_hit(0), base_damage(0), potential_damage(0), damage_done(0), + special_damage(0), aux_damage(0), stab_attempt(false), stab_bonus(0), + weapon(NULL), damage_brand(SPWPN_NORMAL), + wpn_skill(SK_UNARMED_COMBAT), hands(HANDS_ONE), + spwld(SPWLD_NONE), hand_half_bonus(false), + art_props(0), attack_verb(), verb_degree(), + no_damage_message(), special_damage_message(), unarmed_attack(), + heavy_armour_penalty(0), can_do_unarmed(false), + water_attack(false) { - monsters *defender = &menv[monster_attacked]; - - int your_to_hit; - int damage_done = 0; - bool hit = false; - bool base_nodamage = false; - unsigned char stab_bonus = 0; // this is never negative {dlb} - int temp_rand; // for probability determination {dlb} - - const int weapon = you.equip[EQ_WEAPON]; - const bool ur_armed = (weapon != -1); // compacts code a bit {dlb} - const bool bearing_shield = (you.equip[EQ_SHIELD] != -1); - - const int melee_brand = player_damage_brand(); - - bool water_attack = false; - - char damage_noise[80], damage_noise2[80]; - - char str_pass[ ITEMNAME_SIZE ]; - char base_damage_message[ITEMNAME_SIZE]; - char special_damage_message[ITEMNAME_SIZE]; - -#if DEBUG_DIAGNOSTICS - char st_prn[ 20 ]; -#endif + init_attack(); +} - FixedVector< char, RA_PROPERTIES > art_proprt; +void melee_attack::check_hand_half_bonus_eligible() +{ + hand_half_bonus = + unarmed_ok + && !can_do_unarmed + && !shield + && weapon + && !item_cursed( *weapon ) + && hands == HANDS_HALF; +} - special_damage_message[0] = 0; - base_damage_message[0] = 0; +void melee_attack::init_attack() +{ + if (attacker->atype() == ACT_MONSTER) + atk = dynamic_cast(attacker); - // We're trying to hit a monster, break out of travel/explore now. - interrupt_activity(AI_HIT_MONSTER, defender); + if (defender && defender->atype() == ACT_MONSTER) + def = dynamic_cast(defender); - if (ur_armed && (you.inv[weapon].base_type != OBJ_WEAPONS - || you.inv[weapon].sub_type == WPN_BOW || you.inv[weapon].sub_type == WPN_SLING)) - learned_something_new(TUT_WIELD_WEAPON); - - if (ur_armed && you.inv[weapon].base_type == OBJ_WEAPONS - && is_random_artefact( you.inv[weapon] )) - { - randart_wpn_properties( you.inv[weapon], art_proprt ); - } - else - { - // Probably over protective, but in this code we're going - // to play it safe. -- bwr - for (int i = 0; i < RA_PROPERTIES; i++) - art_proprt[i] = 0; - } - - const int heavy_armour = calc_heavy_armour_penalty(true); - - // Calculate the following two flags in advance - // to know what player does this combat turn: - bool can_do_unarmed_combat = false; - - if (you.burden_state == BS_UNENCUMBERED - && random2(20) < you.skills[SK_UNARMED_COMBAT] - && random2(1 + heavy_armour) < 2) - { - can_do_unarmed_combat = true; - } - - // if we're not getting potential unarmed attacks, and not wearing a - // shield, and have a suitable uncursed weapon we get the bonus. - bool use_hand_and_a_half_bonus = false; + weapon = attacker->weapon(attack_number); + damage_brand = attacker->damage_brand(attack_number); - int wpn_skill = SK_UNARMED_COMBAT; - int hands = HANDS_ONE; - - if (weapon != -1) + if (weapon && weapon->base_type == OBJ_WEAPONS + && is_random_artefact( *weapon )) { - wpn_skill = weapon_skill( you.inv[weapon].base_type, - you.inv[weapon].sub_type ); - - hands = hands_reqd( you.inv[weapon], player_size() ); + randart_wpn_properties( *weapon, art_props ); } - if (unarmed_attacks - && !can_do_unarmed_combat - && !bearing_shield && ur_armed - && !item_cursed( you.inv[ weapon ] ) - && hands == HANDS_HALF) + wpn_skill = weapon? weapon_skill( *weapon ) : SK_UNARMED_COMBAT; + if (weapon) { - // currently: +1 dam, +1 hit, -1 spd (loosely) - use_hand_and_a_half_bonus = true; + hands = hands_reqd( *weapon, attacker->body_size() ); + spwld = item_special_wield_effect( *weapon ); } -/* - ************************************************************************** - * * - * IMPORTANT: When altering damage routines, must also change in ouch.cc * - * for saving of player ghosts. * - * * - ************************************************************************** - */ - bool helpless = mons_class_flag(defender->type, M_NO_EXP_GAIN) - || mons_is_statue(defender->type); - - if (mons_friendly(defender)) - did_god_conduct(DID_ATTACK_FRIEND, 5); - - if (you.pet_target == MHITNOT) - you.pet_target = monster_attacked; + shield = attacker->shield(); - if (player_fumbles_attack()) - return (false); - - // Swimmers get bonus against non-swimmers wading in water. - water_attack = player_is_swimming() && monster_floundering(defender); - - // new unified to-hit calculation - your_to_hit = calc_your_to_hit( heavy_armour, use_hand_and_a_half_bonus, - water_attack, true ); - - //jmf: check for backlight enchantment - if (mons_has_ench(defender, ENCH_BACKLIGHT_I, ENCH_BACKLIGHT_IV)) - your_to_hit += 2 + random2(8); + water_attack = is_water_attack(attacker, defender); +} - // energy expenditure in terms of food: - make_hungry(3, true); +bool melee_attack::is_water_attack(const actor *attk, + const actor *defn) const +{ + return (defn && attk->swimming() && defn->floundering()); +} - if (ur_armed && - you.inv[ weapon ].base_type == OBJ_WEAPONS && - is_random_artefact( you.inv[ weapon ] ) && - art_proprt[RAP_ANGRY] >= 1 && - random2(1 + art_proprt[RAP_ANGRY])) +void melee_attack::check_autoberserk() +{ + if (weapon + && art_props[RAP_ANGRY] >= 1 + && !one_chance_in(1 + art_props[RAP_ANGRY])) { - go_berserk(false); + attacker->go_berserk(false); } +} - switch (you.special_wield) +void melee_attack::check_special_wield_effects() +{ + switch (spwld) { case SPWLD_TROG: if (coinflip()) - go_berserk(false); + attacker->go_berserk(false); break; case SPWLD_WUCAD_MU: - if (one_chance_in(9)) + // XXX At some distant point in the future, allow + // miscast_effect to operate on any actor. + if (one_chance_in(9) && attacker->atype() == ACT_PLAYER) { miscast_effect( SPTYP_DIVINATION, random2(9), random2(70), 100, "the Staff of Wucad Mu" ); @@ -634,1433 +432,1793 @@ bool you_attack(int monster_attacked, bool unarmed_attacks) default: break; } +} - if (you.mutation[MUT_BERSERK] && - (random2(100) < (you.mutation[MUT_BERSERK] * 10) - 5)) - go_berserk(false); +bool melee_attack::attack() +{ + if (attacker->fumbles_attack()) + return (false); - // calculate damage - int damage = 1; + // Allow god to get offended, etc. + attacker->attacking(defender); - if (!ur_armed) // empty-handed - { - damage = 3; + // A lot of attack parameters get set in here. 'Ware. + to_hit = calc_to_hit(); - if (you.confusing_touch) - { - // no base hand damage while using this spell - damage = 0; - } + // The attacker loses nutrition. + attacker->make_hungry(3, true); - // if (you.mutation[MUT_DRAIN_LIFE]) - // special_brand = SPWPN_DRAINING; + check_autoberserk(); + check_special_wield_effects(); - if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE) - { - switch (you.attribute[ATTR_TRANSFORMATION]) - { - case TRAN_SPIDER: - damage = 5; - // special_brand = SPWPN_VENOM; - break; - case TRAN_ICE_BEAST: - damage = 12; - // special_brand = SPWPN_FREEZING; - break; - case TRAN_BLADE_HANDS: - damage = 12 + (you.strength / 4) + (you.dex / 4); - break; - case TRAN_STATUE: - damage = 12 + you.strength; - break; - case TRAN_SERPENT_OF_HELL: - case TRAN_DRAGON: - damage = 20 + you.strength; - break; - case TRAN_LICH: - damage = 5; - // special_brand = SPWPN_DRAINING; - break; - case TRAN_AIR: - damage = 0; - break; - } - } - else if (you.equip[ EQ_GLOVES ] == -1) - { - // claw damage only applies for bare hands - if (you.species == SP_TROLL) - damage += 5; - else if (you.species == SP_GHOUL) - damage += 2; + // Trying to stay general beyond this point is a recipe for insanity. + // Maybe when Stone Soup hits 1.0... :-) + return (attacker->atype() == ACT_PLAYER? player_attack() : + defender->atype() == ACT_PLAYER? mons_attack_you() : + mons_attack_mons() ); +} - damage += (you.mutation[ MUT_CLAWS ] * 2); - } +bool melee_attack::player_attack() +{ + potential_damage = + !weapon? player_calc_base_unarmed_damage() + : player_calc_base_weapon_damage(); - damage += you.skills[SK_UNARMED_COMBAT]; - } - else + player_apply_attack_delay(); + player_stab_check(); + + if (player_hits_monster()) { - if (you.inv[ weapon ].base_type == OBJ_WEAPONS - || item_is_staff( you.inv[ weapon ] )) - { - damage = property( you.inv[ weapon ], PWPN_DAMAGE ); - } - } + did_hit = true; -#if DEBUG_DIAGNOSTICS - const int base_damage = damage; -#endif + // This actually does more than calculate damage - it also sets up + // messages, etc. + player_calc_hit_damage(); - int weapon_speed2 = 10; - int min_speed = 3; + // always upset monster regardless of damage + behaviour_event(def, ME_WHACK, MHITYOU); + + if (player_hurt_monster()) + player_exercise_combat_skills(); + + if (player_check_monster_died()) + return (true); - if (ur_armed) - { - if (you.inv[ weapon ].base_type == OBJ_WEAPONS - || item_is_staff( you.inv[ weapon ] )) - { - weapon_speed2 = property( you.inv[ weapon ], PWPN_SPEED ); - weapon_speed2 -= you.skills[ wpn_skill ] / 2; + if (damage_done < 1) + no_damage_message = + make_stringf("You %s %s.", + attack_verb.c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + } + else + player_warn_miss(); - min_speed = property( you.inv[ weapon ], PWPN_SPEED ) / 2; + if (did_hit && (damage_done > 0 || !player_monster_visible(def))) + player_announce_hit(); - // Short blades can get up to at least unarmed speed. - if (wpn_skill == SK_SHORT_BLADES && min_speed > 5) - min_speed = 5; + if (did_hit && player_monattk_hit_effects(false)) + return (true); - // Using both hands can get a weapon up to speed 7 - if ((hands == HANDS_TWO || use_hand_and_a_half_bonus) - && min_speed > 7) - { - min_speed = 7; - } + const bool did_primary_hit = did_hit; + + if (unarmed_ok && player_aux_unarmed()) + return (true); - // never go faster than speed 3 (ie 3 attacks per round) - if (min_speed < 3) - min_speed = 3; + if ((did_primary_hit || did_hit) && def->type != -1) + print_wounds(def); - // Hand and a half bonus only helps speed up to a point, any more - // than speed 10 must come from skill and the weapon - if (use_hand_and_a_half_bonus && weapon_speed2 > 10) - weapon_speed2--; + return (did_primary_hit || did_hit); +} - // apply minimum to weapon skill modification - if (weapon_speed2 < min_speed) - weapon_speed2 = min_speed; +// Returns true to end the attack round. +bool melee_attack::player_aux_unarmed() +{ + damage_brand = SPWPN_NORMAL; + int uattack = UNAT_NO_ATTACK; - if (you.inv[weapon].base_type == OBJ_WEAPONS - && melee_brand == SPWPN_SPEED) - { - weapon_speed2 = (weapon_speed2 + 1) / 2; - } - } - } - else + if (can_do_unarmed) { - // Unarmed speed - if (you.burden_state == BS_UNENCUMBERED - && one_chance_in(heavy_armour + 1)) + if (you.species == SP_NAGA) + uattack = UNAT_HEADBUTT; + else + uattack = (coinflip() ? UNAT_HEADBUTT : UNAT_KICK); + + if ((you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON + || player_genus(GENPC_DRACONIAN) + || (you.species == SP_MERFOLK && player_is_swimming()) + || you.mutation[ MUT_STINGER ]) + && one_chance_in(3)) { - weapon_speed2 = 10 - you.skills[SK_UNARMED_COMBAT] / 5; - - /* this shouldn't happen anyway...sanity */ - if (weapon_speed2 < 5) - weapon_speed2 = 5; + uattack = UNAT_TAILSLAP; } + + if (coinflip()) + uattack = UNAT_PUNCH; } - if (bearing_shield) + for (int scount = 0; scount < 4; scount++) { - switch (you.inv[you.equip[EQ_SHIELD]].sub_type) + unarmed_attack.clear(); + damage_brand = SPWPN_NORMAL; + aux_damage = 0; + + switch (scount) { - case ARM_LARGE_SHIELD: - if (you.skills[SK_SHIELDS] <= 10 + random2(17)) - weapon_speed2++; - // [dshaligram] Fall-through - - case ARM_SHIELD: - if (you.skills[SK_SHIELDS] <= 3 + random2(17)) - weapon_speed2++; - break; - } - } + case 0: + if (uattack != UNAT_KICK) //jmf: hooves mutation + { + if ((you.species != SP_CENTAUR && !you.mutation[MUT_HOOVES]) + || coinflip()) + { + continue; + } + } - // Never allow anything faster than 3 to get through... three attacks - // per round is enough... 5 or 10 is just silly. -- bwr - if (weapon_speed2 < 3) - weapon_speed2 = 3; + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL + || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST + || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON + || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER) + { + continue; + } - you.time_taken *= weapon_speed2; - you.time_taken /= 10; + unarmed_attack = "kick"; + aux_damage = ((you.mutation[MUT_HOOVES] + || you.species == SP_CENTAUR) ? 10 : 5); + break; - if (you.time_taken < 1) - you.time_taken = 1; + case 1: + if (uattack != UNAT_HEADBUTT) + { + if ((!you.mutation[MUT_HORNS] && you.species != SP_KENKU) + || !one_chance_in(3)) + { + continue; + } + } -#if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, "Weapon speed: %d; min: %d; speed: %d; attack time: %d", - weapon_speed2, min_speed, weapon_speed2, you.time_taken ); + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL + || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER + || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST + || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON) + { + continue; + } - mpr( info, MSGCH_DIAGNOSTICS ); -#endif + unarmed_attack = + (you.species == SP_KENKU) ? "peck" : "headbutt"; - // DO STABBING + aux_damage = 5 + you.mutation[MUT_HORNS] * 3; + + // minotaurs used to get +5 damage here, now they get + // +6 because of the horns. - bool stabAttempt = false; - bool rollNeeded = true; + if (you.equip[EQ_HELMET] != -1 + && (get_helmet_type(you.inv[you.equip[EQ_HELMET]]) == THELM_HELMET + || get_helmet_type(you.inv[you.equip[EQ_HELMET]]) == THELM_HELM)) + { + aux_damage += 2; - // This ordering is important! + 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) + { + aux_damage += 3; + } + } + break; - // not paying attention (but not batty) - if (defender->foe != MHITYOU && !testbits(defender->flags, MF_BATTY)) - { - stabAttempt = true; - stab_bonus = 3; - } + case 2: /* draconians */ + if (uattack != UNAT_TAILSLAP) + { + // not draconian, and not wet merfolk + if ((!player_genus(GENPC_DRACONIAN) + && (!(you.species == SP_MERFOLK && player_is_swimming())) + && !you.mutation[ MUT_STINGER ]) + || (!one_chance_in(4))) - // confused (but not perma-confused) - if (mons_has_ench(defender, ENCH_CONFUSION) - && !mons_class_flag(defender->type, M_CONFUSED)) - { - stabAttempt = true; - stab_bonus = 2; - } + { + continue; + } + } - // fleeing - if (defender->behaviour == BEH_FLEE) - { - stabAttempt = true; - stab_bonus = 2; - } + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER + || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST) + { + continue; + } - // sleeping - if (defender->behaviour == BEH_SLEEP) - { - stabAttempt = true; - rollNeeded = false; - stab_bonus = 1; - } + unarmed_attack = "tail-slap"; + aux_damage = 6; - // helpless (plants, etc) - if (helpless) - stabAttempt = false; + if (you.mutation[ MUT_STINGER ] > 0) + { + aux_damage += (you.mutation[ MUT_STINGER ] * 2 - 1); + damage_brand = SPWPN_VENOM; + } - // see if we need to roll against dexterity / stabbing - if (stabAttempt && rollNeeded) - stabAttempt = (random2(200) <= you.skills[SK_STABBING] + you.dex); + /* grey dracs have spiny tails, or something */ + // maybe add this to player messaging {dlb} + // + // STINGER mutation doesn't give extra damage here... that + // would probably be a bit much, we'll still get the + // poison bonus so it's still somewhat good. + if (you.species == SP_GREY_DRACONIAN && you.experience_level >= 7) + aux_damage = 12; + break; - // check for invisibility - no stabs on invisible monsters. - if (!player_monster_visible( defender )) - { - stabAttempt = false; - stab_bonus = 0; - } + case 3: + if (uattack != UNAT_PUNCH) + continue; -#if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, "your to-hit: %d; defender EV: %d", - your_to_hit, defender->evasion ); + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL + || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER + || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST + || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON) + { + continue; + } - mpr( info, MSGCH_DIAGNOSTICS ); -#endif + /* no punching with a shield or 2-handed wpn, except staves */ + if (shield || coinflip() + || (weapon + && hands == HANDS_TWO + && weapon->base_type != OBJ_STAVES + && weapon->sub_type != WPN_QUARTERSTAFF) ) + { + continue; + } - if ((your_to_hit >= defender->evasion || one_chance_in(30)) || - ((mons_is_paralysed(defender) || defender->behaviour == BEH_SLEEP) - && !one_chance_in(10 + you.skills[SK_STABBING]))) - { - hit = true; - int dammod = 78; + unarmed_attack = "punch"; - const int dam_stat_val = calc_stat_to_dam_base(); + /* applied twice */ + aux_damage = 5 + you.skills[SK_UNARMED_COMBAT] / 3; - if (dam_stat_val > 11) - dammod += (random2(dam_stat_val - 11) * 2); - else if (dam_stat_val < 9) - dammod -= (random2(9 - dam_stat_val) * 3); + if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) + { + unarmed_attack = "slash"; + aux_damage += 6; + } + break; - damage *= dammod; //random2(you.strength); - damage /= 78; + /* To add more, add to while part of loop below as well */ + default: + continue; -#if DEBUG_DIAGNOSTICS - const int str_damage = damage; -#endif + } - // Yes, this isn't the *2 damage that monsters get, but since - // monster hps and player hps are different (as are the sizes - // of the attacks) it just wouldn't be fair to give merfolk - // that gross a potential... still they do get something for - // making use of the water. -- bwr - if (water_attack) - damage += random2avg(10,2); + // unified to-hit calculation + to_hit = random2( calc_your_to_hit_unarmed() ); + + make_hungry(2, true); -#if DEBUG_DIAGNOSTICS - const int water_damage = damage; -#endif + alert_nearby_monsters(); - // apply damage bonus from ring of slaying - // (before randomization -- some of these rings - // are stupidly powerful) -- GDL - damage += slaying_bonus(PWPN_DAMAGE); + // XXX We're clobbering did_hit + did_hit = false; + if (to_hit >= def->evasion || one_chance_in(30)) + { + if (player_apply_aux_unarmed()) + return (true); + } + else + { + mprf("Your %s misses %s.", + unarmed_attack.c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + } + } -#if DEBUG_DIAGNOSTICS - const int slay_damage = damage; + return (false); +} - snprintf( info, INFO_SIZE, - "melee base: %d; str: %d; water: %d; to-dam: %d", - base_damage, str_damage, water_damage, slay_damage ); +bool melee_attack::player_apply_aux_unarmed() +{ + did_hit = true; - mpr( info, MSGCH_DIAGNOSTICS ); -#endif + aux_damage = player_aux_stat_modify_damage(aux_damage); + aux_damage += slaying_bonus(PWPN_DAMAGE); - damage_done = random2(damage); + aux_damage = random2(aux_damage); -#if DEBUG_DIAGNOSTICS - const int roll_damage = damage_done; -#endif + // Clobber wpn_skill + wpn_skill = SK_UNARMED_COMBAT; + aux_damage = player_apply_weapon_skill(aux_damage); + aux_damage = player_apply_fighting_skill(aux_damage, true); + aux_damage = player_apply_misc_modifiers(aux_damage); - if (ur_armed && (you.inv[ weapon ].base_type == OBJ_WEAPONS - || item_is_staff( you.inv[ weapon ] ))) - { - damage_done *= 25 + (random2( you.skills[ wpn_skill ] + 1 )); - damage_done /= 25; - } + // Clear stab bonus which will be set for the primary weapon attack. + stab_bonus = 0; + aux_damage = player_apply_monster_ac(aux_damage); + + if (aux_damage < 1) + aux_damage = 0; + else + hurt_monster(def, damage_done); -#if DEBUG_DIAGNOSTICS - const int skill_damage = damage_done; -#endif + if (damage_done > 0) + { + player_exercise_combat_skills(); + + mprf("You %s %s%s%s", + unarmed_attack.c_str(), + defender->name(DESC_NOCAP_THE).c_str(), + debug_damage_number().c_str(), + attack_strength_punctuation().c_str()); + + if (damage_brand == SPWPN_VENOM && coinflip()) + poison_monster( def, true ); + + if (mons_holiness(def) == MH_HOLY) + did_god_conduct(DID_KILL_ANGEL, 1); + } + else // no damage was done + { + mprf("You %s %s%s.", + unarmed_attack.c_str(), + defender->name(DESC_NOCAP_THE).c_str(), + player_monster_visible(def)? + ", but do no damage" : ""); + } + + if (def->hit_points < 1) + { + monster_die(def, KILL_YOU, 0); + return (true); + } - damage_done *= 30 + (random2(you.skills[SK_FIGHTING] + 1)); - damage_done /= 30; + return (false); +} -#if DEBUG_DIAGNOSTICS - const int fight_damage = damage_done; +std::string melee_attack::debug_damage_number() +{ +#ifdef DEBUG_DIAGNOSTICS + return make_stringf(" for %d", damage_done); +#else + return (""); #endif +} - if (you.might > 1) - damage_done += 1 + random2(10); - - if (you.hunger_state == HS_STARVING) - damage_done -= random2(5); - -#if DEBUG_DIAGNOSTICS - const int preplus_damage = damage_done; - int plus_damage = damage_done; - int bonus_damage = damage_done; -#endif +std::string melee_attack::special_attack_punctuation() +{ + if (special_damage < 3) + return "."; + else if (special_damage < 7) + return "!"; + else + return "!!"; +} - if (ur_armed && you.inv[ weapon ].base_type == OBJ_WEAPONS) - { - int hoggl = you.inv[ weapon ].plus2; +std::string melee_attack::attack_strength_punctuation() +{ + if (damage_done < HIT_WEAK) + return "."; + else if (damage_done < HIT_MED) + return "!"; + else if (damage_done < HIT_STRONG) + return "!!"; + else + return "!!!"; +} - damage_done += (hoggl > -1) ? (random2(1 + hoggl)) : (hoggl); +void melee_attack::player_announce_hit() +{ + if (!verb_degree.empty() && verb_degree[0] != ' ') + verb_degree = " " + verb_degree; + + mprf("You %s %s%s%s%s", + attack_verb.c_str(), + ptr_monam(def, DESC_NOCAP_THE), + verb_degree.c_str(), + debug_damage_number().c_str(), + attack_strength_punctuation().c_str()); +} -#if DEBUG_DIAGNOSTICS - plus_damage = damage_done; -#endif +std::string melee_attack::player_why_missed() +{ + if ((to_hit + heavy_armour_penalty / 2) >= def->evasion) + return "Your armour prevents you from hitting "; + else + return "You miss "; +} - // removed 2-handed weapons from here... their "bonus" is - // already included in the damage stat for the weapon -- bwr - if (use_hand_and_a_half_bonus) - damage_done += random2(3); +void melee_attack::player_warn_miss() +{ + did_hit = false; - if (get_equip_race(you.inv[ weapon ]) == ISFLAG_DWARVEN - && player_genus(GENPC_DWARVEN)) - { - damage_done += random2(3); - } + // upset only non-sleeping monsters if we missed + if (def->behaviour != BEH_SLEEP) + behaviour_event( def, ME_WHACK, MHITYOU ); - if (get_equip_race(you.inv[ weapon ]) == ISFLAG_ORCISH - && you.species == SP_HILL_ORC && coinflip()) - { - damage_done++; - } + mprf("%s%s.", + player_why_missed().c_str(), + ptr_monam(def, DESC_NOCAP_THE)); +} +bool melee_attack::player_hits_monster() +{ #if DEBUG_DIAGNOSTICS - bonus_damage = damage_done; + mprf( MSGCH_DIAGNOSTICS, "your to-hit: %d; defender EV: %d", + to_hit, def->evasion ); #endif - if (!is_range_weapon( you.inv[weapon] ) - && !item_ident( you.inv[ weapon ], ISFLAG_KNOW_PLUSES ) - && random2(100) < you.skills[ wpn_skill ]) - { - set_ident_flags( you.inv[ weapon ], ISFLAG_KNOW_PLUSES ); - strcpy(info, "You are wielding "); - in_name( weapon , DESC_NOCAP_A, str_pass ); - strcat(info, str_pass); - strcat(info, "."); - mpr(info); - more(); - you.wield_change = true; - } - } + return (to_hit >= def->evasion + || one_chance_in(3) + || ((mons_is_paralysed(def) || def->behaviour == BEH_SLEEP) + && !one_chance_in(10 + you.skills[SK_STABBING]))); +} - // The stabbing message looks better here: - if (stabAttempt) - { - // construct reasonable message - stab_message( defender, stab_bonus ); +int melee_attack::player_stat_modify_damage(int damage) +{ + int dammod = 78; + const int dam_stat_val = calc_stat_to_dam_base(); + + if (dam_stat_val > 11) + dammod += (random2(dam_stat_val - 11) * 2); + else if (dam_stat_val < 9) + dammod -= (random2(9 - dam_stat_val) * 3); + + damage *= dammod; + damage /= 78; - exercise(SK_STABBING, 1 + random2avg(5, 4)); + return (damage); +} - if (mons_holiness(defender) == MH_NATURAL - || mons_holiness(defender) == MH_HOLY) - { - did_god_conduct(DID_STABBING, 4); - } - } - else - { - stab_bonus = 0; - // ok.. if you didn't backstab, you wake up the neighborhood. - // I can live with that. - alert_nearby_monsters(); - } +int melee_attack::player_aux_stat_modify_damage(int damage) +{ + int dammod = 10; + const int dam_stat_val = calc_stat_to_dam_base(); + + if (dam_stat_val > 11) + dammod += random2(dam_stat_val - 11) / 3; + if (dam_stat_val < 9) + dammod -= random2(9 - dam_stat_val) / 2; + + damage *= dammod; + damage /= 10; -#if DEBUG_DIAGNOSTICS - int stab_damage = damage_done; -#endif + return (damage); +} - if (stab_bonus) - { - // lets make sure we have some damage to work with... - if (damage_done < 1) - damage_done = 1; +int melee_attack::player_apply_water_attack_bonus(int damage) +{ +#if 0 + // Yes, this isn't the *2 damage that monsters get, but since + // monster hps and player hps are different (as are the sizes + // of the attacks) it just wouldn't be fair to give merfolk + // that gross a potential... still they do get something for + // making use of the water. -- bwr + // return (damage + random2avg(10,2)); +#endif - if (defender->behaviour == BEH_SLEEP) - { - // Sleeping moster wakes up when stabbed but may be groggy - if (random2(200) <= you.skills[SK_STABBING] + you.dex) - { - unsigned int stun = random2( you.dex + 1 ); + // [dshaligram] Experimenting with the full double damage bonus since + // it takes real effort to set up a water attack and it's very situational. + return (damage * 2); +} - if (defender->speed_increment > stun) - defender->speed_increment -= stun; - else - defender->speed_increment = 0; - } - } +int melee_attack::player_apply_weapon_skill(int damage) +{ + if (weapon && (weapon->base_type == OBJ_WEAPONS + || item_is_staff( *weapon ))) + { + damage *= 25 + (random2( you.skills[ wpn_skill ] + 1 )); + damage /= 25; + } - switch (wpn_skill) - { - case SK_SHORT_BLADES: - { - int bonus = (you.dex * (you.skills[SK_STABBING] + 1)) / 5; + return (damage); +} - if (you.inv[ weapon ].sub_type != WPN_DAGGER) - bonus /= 2; +int melee_attack::player_apply_fighting_skill(int damage, bool aux) +{ + const int base = aux? 40 : 30; + + damage *= base + (random2(you.skills[SK_FIGHTING] + 1)); + damage /= base; - bonus = stepdown_value( bonus, 10, 10, 30, 30 ); + return (damage); +} - damage_done += bonus; - } - // fall through - case SK_LONG_SWORDS: - damage_done *= 10 + you.skills[SK_STABBING] / - (stab_bonus + (wpn_skill == SK_SHORT_BLADES ? 0 : 1)); - damage_done /= 10; - // fall through - default: - damage_done *= 12 + you.skills[SK_STABBING] / stab_bonus; - damage_done /= 12; - } +int melee_attack::player_apply_misc_modifiers(int damage) +{ + if (you.might > 1) + damage += 1 + random2(10); + + if (you.hunger_state == HS_STARVING) + damage -= random2(5); -#if DEBUG_DIAGNOSTICS - stab_damage = damage_done; -#endif + return (damage); +} - // when stabbing we can get by some of the armour - if (defender->armour_class > 0) - { - int ac = defender->armour_class - - random2( you.skills[SK_STABBING] / stab_bonus ); +int melee_attack::player_apply_weapon_bonuses(int damage) +{ + if (weapon && weapon->base_type == OBJ_WEAPONS) + { + int wpn_damage_plus = weapon->plus2; + + damage += (wpn_damage_plus > -1) ? (random2(1 + wpn_damage_plus)) + : -(1 + random2(-wpn_damage_plus)); - if (ac > 0) - damage_done -= random2(1 + ac); - } + // removed 2-handed weapons from here... their "bonus" is + // already included in the damage stat for the weapon -- bwr + if (hand_half_bonus) + damage += random2(3); + + if (get_equip_race(*weapon) == ISFLAG_DWARVEN + && player_genus(GENPC_DWARVEN)) + { + damage += random2(3); } - else + + if (get_equip_race(*weapon) == ISFLAG_ORCISH + && you.species == SP_HILL_ORC && coinflip()) { - // apply AC normally - if (defender->armour_class > 0) - damage_done -= random2(1 + defender->armour_class); + damage++; } + } -#if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, - "melee roll: %d; skill: %d; fight: %d; pre wpn plus: %d", - roll_damage, skill_damage, fight_damage, preplus_damage ); - - mpr( info, MSGCH_DIAGNOSTICS ); - - snprintf( info, INFO_SIZE, - "melee plus: %d; bonus: %d; stab: %d; post AC: %d", - plus_damage, bonus_damage, stab_damage, damage_done ); + return (damage); +} - mpr( info, MSGCH_DIAGNOSTICS ); -#endif +void melee_attack::player_weapon_auto_id() +{ + if (weapon + && !is_range_weapon( *weapon ) + && !item_ident( *weapon, ISFLAG_KNOW_PLUSES ) + && random2(100) < you.skills[ wpn_skill ]) + { + set_ident_flags( *weapon, ISFLAG_KNOW_PLUSES ); + mprf("You are wielding %s.", + item_name(*weapon, DESC_NOCAP_A)); + more(); + you.wield_change = true; + } +} - // This doesn't actually modify damage -- bwr - damage_done = weapon_type_modify( weapon, damage_noise, damage_noise2, - damage_done ); +int melee_attack::player_stab_weapon_bonus(int damage) +{ + switch (wpn_skill) + { + case SK_SHORT_BLADES: + { + int bonus = (you.dex * (you.skills[SK_STABBING] + 1)) / 5; + + if (weapon->sub_type != WPN_DAGGER) + bonus /= 2; + + bonus = stepdown_value( bonus, 10, 10, 30, 30 ); + + damage += bonus; + } + // fall through + case SK_LONG_SWORDS: + damage *= 10 + you.skills[SK_STABBING] / + (stab_bonus + (wpn_skill == SK_SHORT_BLADES ? 0 : 1)); + damage /= 10; + // fall through + default: + damage *= 12 + you.skills[SK_STABBING] / stab_bonus; + damage /= 12; + } - if (damage_done < 0) - damage_done = 0; + return (damage); +} - // always upset monster regardless of damage - behaviour_event(defender, ME_WHACK, MHITYOU); +int melee_attack::player_stab(int damage) +{ + // The stabbing message looks better here: + if (stab_attempt) + { + // construct reasonable message + stab_message( def, stab_bonus ); - if (hurt_monster(defender, damage_done)) + exercise(SK_STABBING, 1 + random2avg(5, 4)); + + if (mons_holiness(def) == MH_NATURAL + || mons_holiness(def) == MH_HOLY) { - if (ur_armed && wpn_skill) - { - if (!helpless || you.skills[ wpn_skill ] < 2) - exercise( wpn_skill, 1 ); - } - else - { - if (!helpless || you.skills[SK_UNARMED_COMBAT] < 2) - exercise(SK_UNARMED_COMBAT, 1); - } - - if ((!helpless || you.skills[SK_FIGHTING] < 2) - && one_chance_in(3)) - { - exercise(SK_FIGHTING, 1); - } + did_god_conduct(DID_STABBING, 4); } + } + else + { + stab_bonus = 0; + // ok.. if you didn't backstab, you wake up the neighborhood. + // I can live with that. + alert_nearby_monsters(); + } - if (defender->hit_points < 1) + if (stab_bonus) + { + // lets make sure we have some damage to work with... + if (damage < 1) + damage = 1; + + if (def->behaviour == BEH_SLEEP) { -#if DEBUG_DIAGNOSTICS - /* note: doesn't take account of special weapons etc */ - snprintf( info, INFO_SIZE, "Hit for %d.", damage_done ); - mpr( info, MSGCH_DIAGNOSTICS ); -#endif - if (ur_armed && melee_brand == SPWPN_VAMPIRICISM) + // Sleeping moster wakes up when stabbed but may be groggy + if (random2(200) <= you.skills[SK_STABBING] + you.dex) { - if (mons_holiness(defender) == MH_NATURAL - && damage_done > 0 && you.hp < you.hp_max - && !one_chance_in(5)) - { - mpr("You feel better."); - - // more than if not killed - inc_hp(1 + random2(damage_done), false); - - if (you.hunger_state != HS_ENGORGED) - lessen_hunger(30 + random2avg(59, 2), true); - - did_god_conduct(DID_NECROMANCY, 2); - } + unsigned int stun = random2( you.dex + 1 ); + + if (def->speed_increment > stun) + def->speed_increment -= stun; + else + def->speed_increment = 0; } + } - monster_die(defender, KILL_YOU, 0); - - if (defender->type == MONS_GIANT_SPORE) - mprf("You %s the giant spore.", damage_noise); - else if (defender->type == MONS_BALL_LIGHTNING) - mprf("You %s the ball lightning.", damage_noise); + damage = player_stab_weapon_bonus(damage); + } - return (true); - } + return (damage); +} - if (damage_done < 1 && player_monster_visible( defender )) +int melee_attack::player_apply_monster_ac(int damage) +{ + if (stab_bonus) + { + // when stabbing we can get by some of the armour + if (def->armour_class > 0) { - hit = true; - base_nodamage = true; - snprintf( base_damage_message, INFO_SIZE, "You %s %s.", - damage_noise, ptr_monam(defender, DESC_NOCAP_THE)); + int ac = def->armour_class + - random2( you.skills[SK_STABBING] / stab_bonus ); + + if (ac > 0) + damage -= random2(1 + ac); } } else { - hit = false; + // apply AC normally + if (def->armour_class > 0) + damage -= random2(1 + def->armour_class); + } - // upset only non-sleeping monsters if we missed - if (defender->behaviour != BEH_SLEEP) - behaviour_event( defender, ME_WHACK, MHITYOU ); + return (damage); +} - if ((your_to_hit + heavy_armour / 2) >= defender->evasion) - strcpy(info, "Your armour prevents you from hitting "); - else - strcpy(info, "You miss "); +int melee_attack::player_weapon_type_modify(int damage) +{ + int weap_type = WPN_UNKNOWN; - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } + if (!weapon) + weap_type = WPN_UNARMED; + else if (item_is_staff( *weapon )) + weap_type = WPN_QUARTERSTAFF; + else if (weapon->base_type == OBJ_WEAPONS) + weap_type = weapon->sub_type; - if (hit && damage_done > 0 - || (hit && damage_done < 1 && mons_has_ench(defender,ENCH_INVIS))) + // All weak hits look the same, except for when the player + // has a non-weapon in hand. -- bwr + if (damage < HIT_WEAK) { - snprintf(info, INFO_SIZE, "You %s %s%s", damage_noise, - ptr_monam(defender, DESC_NOCAP_THE), damage_noise2); -#if DEBUG_DIAGNOSTICS - strcat( info, " for " ); - /* note: doesn't take account of special weapons etc */ - itoa( damage_done, st_prn, 10 ); - strcat( info, st_prn ); -#endif - if (damage_done < HIT_WEAK) - strcat(info, "."); - else if (damage_done < HIT_MED) - strcat(info, "!"); - else if (damage_done < HIT_STRONG) - strcat(info, "!!"); + if (weap_type != WPN_UNKNOWN) + attack_verb = "hit"; else - strcat(info, "!!!"); - - mpr(info); - - if (mons_holiness(defender) == MH_HOLY) - did_god_conduct(DID_KILL_ANGEL, 1); - - if (you.special_wield == SPWLD_TORMENT) - { - torment(TORMENT_SPWLD, you.x_pos, you.y_pos); - did_god_conduct(DID_UNHOLY, 5); - } + attack_verb = "clumsily bash"; - if (you.special_wield == SPWLD_ZONGULDROK - || you.special_wield == SPWLD_CURSE) - { - did_god_conduct(DID_NECROMANCY, 3); - } + return (damage); } - /* remember, damage_done is still useful! */ - if (hit) + // take transformations into account, if no weapon is wielded + if (weap_type == WPN_UNARMED + && you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE) { - if (defender->type == MONS_JELLY - || defender->type == MONS_BROWN_OOZE - || defender->type == MONS_ACID_BLOB - || defender->type == MONS_ROYAL_JELLY) - { - weapon_acid(5); - } - - int specdam = 0; - - if (ur_armed - && you.inv[ weapon ].base_type == OBJ_WEAPONS - && is_demonic( you.inv[ weapon ] )) + switch (you.attribute[ATTR_TRANSFORMATION]) { - did_god_conduct(DID_UNHOLY, 1); - } + case TRAN_SPIDER: + if (damage < HIT_STRONG) + attack_verb = "bite"; + else + attack_verb = "maul"; + break; + case TRAN_BLADE_HANDS: + if (damage < HIT_MED) + attack_verb = "slash"; + else if (damage < HIT_STRONG) + attack_verb = "slice"; + else + attack_verb = "shred"; + break; + case TRAN_ICE_BEAST: + case TRAN_STATUE: + case TRAN_LICH: + if (damage < HIT_MED) + attack_verb = "punch"; + else + attack_verb = "pummel"; + break; + case TRAN_DRAGON: + case TRAN_SERPENT_OF_HELL: + if (damage < HIT_MED) + attack_verb = "claw"; + else if (damage < HIT_STRONG) + attack_verb = "bite"; + else + { + attack_verb = "maul"; + if (defender->body_size() <= SIZE_MEDIUM && coinflip()) + attack_verb = "trample on"; + } + break; + case TRAN_AIR: + attack_verb = "buffet"; + break; + } // transformations - if (mons_holiness(defender) == MH_HOLY) - did_god_conduct(DID_ATTACK_HOLY, defender->hit_dice); - - // If decapitation, extra damage is bypassed. - if (actor_decapitates_hydra(NULL, defender, damage_done)) - goto mons_dies; - - // jmf: BEGIN STAFF HACK - // How much bonus damage will a staff of do? - // FIXME: make these not macros. inline functions? - // actually, it will all be pulled out and replaced by functions -- {dlb} - // - // This is similar to the previous, in both value and distribution, except - // that instead of just SKILL, its now averaged with Evocations. -- bwr -#define STAFF_DAMAGE(SKILL) (roll_dice( 3, 1 + (you.skills[(SKILL)] + you.skills[SK_EVOCATIONS]) / 12 )) - -#define STAFF_COST 2 - - // magic staves have their own special damage - if (ur_armed && item_is_staff( you.inv[weapon] )) + return (damage); + } + + switch (weapon? get_damage_type(*weapon) : -1) + { + case DAM_PIERCE: + if (damage < HIT_MED) + attack_verb = "puncture"; + else if (damage < HIT_STRONG) + attack_verb = "impale"; + else { - specdam = 0; + attack_verb = "spit"; + verb_degree = " like a pig"; + } + break; - if (you.magic_points >= STAFF_COST - && random2(20) <= you.skills[SK_EVOCATIONS]) - { - switch (you.inv[weapon].sub_type) - { - case STAFF_AIR: - if (damage_done + you.skills[SK_AIR_MAGIC] > random2(30)) - { - if (mons_res_elec(defender)) - break; + case DAM_SLICE: + if (damage < HIT_MED) + attack_verb = "slash"; + else if (damage < HIT_STRONG) + attack_verb = "slice"; + else + { + attack_verb = "open"; + verb_degree = " like a pillowcase"; + } + break; - specdam = STAFF_DAMAGE(SK_AIR_MAGIC); + case DAM_BLUDGEON: + if (damage < HIT_MED) + attack_verb = one_chance_in(4)? "thump" : "sock"; + else if (damage < HIT_STRONG) + attack_verb = "bludgeon"; + else + { + attack_verb = "crush"; + verb_degree = " like a grape"; + } + break; - if (specdam) - { - snprintf( special_damage_message, INFO_SIZE, - "%s is jolted!", - ptr_monam(defender, DESC_CAP_THE) ); - } - } - break; + case DAM_WHIP: + if (damage < HIT_MED) + attack_verb = "whack"; + else + attack_verb = "thrash"; + break; - case STAFF_COLD: // FIXME: I don't think I used these right ... - if (mons_res_cold(defender) > 0) - break; + case -1: // unarmed + if (you.species == SP_TROLL || you.mutation[MUT_CLAWS]) + { + if (damage < HIT_MED) + attack_verb = "claw"; + else if (damage < HIT_STRONG) + attack_verb = "mangle"; + else + attack_verb = "eviscerate"; + } + else + { + if (damage < HIT_MED) + attack_verb = "punch"; + else + attack_verb = "pummel"; + } + break; - specdam = STAFF_DAMAGE(SK_ICE_MAGIC); + case WPN_UNKNOWN: + default: + attack_verb = "hit"; + break; + } - if (mons_res_cold(defender) < 0) - specdam += STAFF_DAMAGE(SK_ICE_MAGIC); + return (damage); +} - if (specdam) - { - snprintf( special_damage_message, INFO_SIZE, - "You freeze %s!", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - break; +bool melee_attack::player_hurt_monster() +{ + return damage_done && hurt_monster(def, damage_done); +} - case STAFF_EARTH: - if (mons_flies(defender)) - break; //jmf: lame, but someone ought to resist +void melee_attack::player_exercise_combat_skills() +{ + const bool helpless = defender->cannot_fight(); + + if (!helpless || you.skills[ wpn_skill ] < 2) + exercise( wpn_skill, 1 ); + + if ((!helpless || you.skills[SK_FIGHTING] < 2) + && one_chance_in(3)) + { + exercise(SK_FIGHTING, 1); + } +} - specdam = STAFF_DAMAGE(SK_EARTH_MAGIC); +// Returns true if the combat round should end here. +bool melee_attack::player_monattk_hit_effects(bool mondied) +{ + if (mons_holiness(def) == MH_HOLY) + did_god_conduct(mondied? DID_KILL_ANGEL : DID_ATTACK_HOLY, 1); - if (specdam) - { - snprintf( special_damage_message, INFO_SIZE, - "You crush %s!", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - break; + if (spwld == SPWLD_TORMENT && coinflip()) + { + torment(TORMENT_SPWLD, you.x_pos, you.y_pos); + did_god_conduct(DID_UNHOLY, 5); + } - case STAFF_FIRE: - if (mons_res_fire(defender) > 0) - break; + if (spwld == SPWLD_ZONGULDROK || spwld == SPWLD_CURSE) + did_god_conduct(DID_NECROMANCY, 3); - specdam = STAFF_DAMAGE(SK_FIRE_MAGIC); + if (weapon + && weapon->base_type == OBJ_WEAPONS + && is_demonic( *weapon )) + { + did_god_conduct(DID_UNHOLY, 1); + } + + if (mondied && damage_brand == SPWPN_VAMPIRICISM) + { + if (mons_holiness(def) == MH_NATURAL + && damage_done > 0 && you.hp < you.hp_max + && !one_chance_in(5)) + { + mpr("You feel better."); + + // more than if not killed + inc_hp(1 + random2(damage_done), false); + + if (you.hunger_state != HS_ENGORGED) + lessen_hunger(30 + random2avg(59, 2), true); + + did_god_conduct(DID_NECROMANCY, 2); + } + } - if (mons_res_fire(defender) < 0) - specdam += STAFF_DAMAGE(SK_FIRE_MAGIC); + if (mondied) + return (true); - if (specdam) - { - snprintf( special_damage_message, INFO_SIZE, - "You burn %s!", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - break; + // These effects apply only to monsters that are still alive: + + if (actor_decapitates_hydra(attacker, defender, damage_done)) + return (true); - case STAFF_POISON: - // cap chance at 30% -- let staff of Olgreb shine - temp_rand = damage_done + you.skills[SK_POISON_MAGIC]; + // These two are mutually exclusive! + player_apply_staff_damage(); - if (temp_rand > 30) - temp_rand = 30; + // Returns true if the monster croaked. + if (player_apply_damage_brand()) + return (true); - if (random2(100) < temp_rand) - { - // HACK: poison_monster emits a message, so - // we need to get ours out first. - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; // don't double-message - } - poison_monster(defender, true); - } - break; + if (!no_damage_message.empty()) + { + if (special_damage > 0) + emit_nodmg_hit_message(); + else + mprf("You %s %s, but do no damage.", + attack_verb.c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + } + + if (!special_damage_message.empty()) + mprf("%s", special_damage_message.c_str()); - case STAFF_DEATH: - if (mons_res_negative_energy(defender) > 0) - break; + player_sustain_passive_damage(); + hurt_monster(def, special_damage); - if (random2(8) <= you.skills[SK_NECROMANCY]) - { - specdam = STAFF_DAMAGE(SK_NECROMANCY); + if (def->hit_points < 1) + { + monster_die(def, KILL_YOU, 0); + return (true); + } - if (specdam) - { - snprintf( special_damage_message, INFO_SIZE, - "%s convulses in agony!", - ptr_monam(defender, DESC_CAP_THE)); + return (false); +} - did_god_conduct(DID_NECROMANCY, 4); - } - } - break; +void melee_attack::player_calc_brand_damage( + int res, + const char *message_format) +{ + if (res == 0) + special_damage = random2(damage_done) / 2 + 1; + else if (res < 0) + special_damage = random2(damage_done) + 1; - case STAFF_POWER: - case STAFF_SUMMONING: - case STAFF_CHANNELING: - case STAFF_CONJURATION: - case STAFF_ENCHANTMENT: - case STAFF_ENERGY: - case STAFF_WIZARDRY: - break; + if (special_damage) + { + special_damage_message = make_stringf( + message_format, + defender->name(DESC_NOCAP_THE).c_str(), + special_attack_punctuation().c_str()); + } +} - default: - mpr("You're wielding some staff I've never heard of! (fight.cc)"); - break; - } // end switch - } +bool melee_attack::player_apply_damage_brand() +{ + // Monster resistance to the brand. + int res = 0; + + special_damage = 0; + switch (damage_brand) + { + case SPWPN_FLAMING: + res = mons_res_fire(def); + if (weapon && weapon->special == SPWPN_SWORD_OF_CEREBOV && res >= 0) + res = (res > 0) - 1; - if (specdam > 0) - { - dec_mp(STAFF_COST); + player_calc_brand_damage(res, "You burn %s%s"); + break; - if (!item_type_known(you.inv[weapon])) - { - set_ident_flags( you.inv[weapon], ISFLAG_KNOW_TYPE ); - strcpy(info, "You are wielding "); - in_name( weapon, DESC_NOCAP_A, str_pass); - strcat(info, str_pass); - strcat(info, "."); - mpr(info); - more(); - you.wield_change = true; - } - } -#undef STAFF_DAMAGE -#undef STAFF_COST -// END STAFF HACK - } + case SPWPN_FREEZING: + player_calc_brand_damage(mons_res_cold(def), "You freeze %s%s"); + break; + + case SPWPN_HOLY_WRATH: + switch (mons_holiness(def)) + { + case MH_UNDEAD: + special_damage = 1 + random2(damage_done); + break; + + case MH_DEMONIC: + special_damage = 1 + (random2(damage_done * 15) / 10); + break; + + default: + break; + } + if (special_damage) + special_damage_message = + make_stringf( + "%s convulses%s", + defender->name(DESC_CAP_THE).c_str(), + special_attack_punctuation().c_str()); + break; + + case SPWPN_ELECTROCUTION: + if (mons_flies(def)) + break; + else if (mons_res_elec(def) > 0) + break; + else if (one_chance_in(3)) + { + special_damage_message = + "There is a sudden explosion of sparks!"; + special_damage = random2avg(28, 3); + } + break; + + case SPWPN_ORC_SLAYING: + if (mons_species(def->type) == MONS_ORC) + { + special_damage = 1 + random2(damage_done); + special_damage_message = + make_stringf( + "%s convulses%s", + defender->name(DESC_CAP_THE).c_str(), + special_attack_punctuation().c_str()); + } + break; + + case SPWPN_VENOM: + if (!one_chance_in(4)) + { + // Poison monster message needs to arrive after hit message. + emit_nodmg_hit_message(); + poison_monster(def, true); + } + break; + + case SPWPN_DRAINING: + if (mons_res_negative_energy(def) > 0 || one_chance_in(3)) + break; + + special_damage_message = + make_stringf( + "You drain %s!", + defender->name(DESC_NOCAP_THE).c_str()); + + if (one_chance_in(5)) + def->hit_dice--; + + def->max_hit_points -= 2 + random2(3); + def->hit_points -= 2 + random2(3); + + if (def->hit_points >= def->max_hit_points) + def->hit_points = def->max_hit_points; + + if (def->hit_dice < 1) + def->hit_points = 0; + + special_damage = 1 + (random2(damage_done) / 2); + did_god_conduct( DID_NECROMANCY, 2 ); + break; + + /* 9 = speed - done before */ + case SPWPN_VORPAL: + special_damage = 1 + random2(damage_done) / 2; + // note: leaving special_damage_message empty because there + // isn't one. + break; + + case SPWPN_VAMPIRICISM: + if (mons_holiness(def) != MH_NATURAL || + mons_res_negative_energy(def) > 0 || + damage_done < 1 || you.hp == you.hp_max || + one_chance_in(5)) + { + break; + } + + // We only get here if we've done base damage, so no + // worries on that score. + mpr("You feel better."); + + // thus is probably more valuable on larger weapons? + if (weapon + && is_fixed_artefact( *weapon ) + && weapon->special == SPWPN_VAMPIRES_TOOTH) + { + inc_hp(damage_done, false); + } else { - // handle special brand damage (unarmed or armed non-staff ego): - int res = 0; + inc_hp(1 + random2(damage_done), false); + } + + if (you.hunger_state != HS_ENGORGED) + lessen_hunger(random2avg(59, 2), true); + + did_god_conduct( DID_NECROMANCY, 2 ); + break; + + case SPWPN_DISRUPTION: + if (mons_holiness(def) == MH_UNDEAD && !one_chance_in(3)) + { + special_damage_message = + str_simple_monster_message(def, " shudders."); + special_damage += random2avg((1 + (damage_done * 3)), 3); + } + break; + + case SPWPN_PAIN: + if (mons_res_negative_energy(def) <= 0 + && random2(8) <= you.skills[SK_NECROMANCY]) + { + special_damage_message = + str_simple_monster_message(def, " convulses in agony."); + special_damage += random2( 1 + you.skills[SK_NECROMANCY] ); + } + did_god_conduct(DID_NECROMANCY, 4); + break; - switch (melee_brand) + case SPWPN_DISTORTION: + //jmf: blink frogs *like* distortion + // I think could be amended to let blink frogs "grow" like + // jellies do {dlb} + if (defender->id() == MONS_BLINK_FROG) + { + if (one_chance_in(5)) { - case SPWPN_NORMAL: - break; + emit_nodmg_hit_message(); + simple_monster_message( + def, + " basks in the translocular energy." ); + heal_monster(def, 1 + random2avg(7, 2), true); // heh heh + } + break; + } + + if (one_chance_in(3)) + { + special_damage_message = + make_stringf( + "Space bends around %s.", + defender->name(DESC_NOCAP_THE).c_str()); + special_damage += 1 + random2avg(7, 2); + break; + } - case SPWPN_FLAMING: - specdam = 0; + if (one_chance_in(3)) + { + special_damage_message = + make_stringf( + "Space warps horribly around %s!", + ptr_monam(def, DESC_NOCAP_THE)); + + special_damage += 3 + random2avg(24, 2); + break; + } - res = mons_res_fire(defender); - if (ur_armed && you.inv[weapon].special == SPWPN_SWORD_OF_CEREBOV) - { - if (res < 3 && res > 0) - res = 0; - else if (res == 0) - res = -1; - } + if (one_chance_in(3)) + { + emit_nodmg_hit_message(); + monster_blink(def); + break; + } - if (res == 0) - specdam = random2(damage_done) / 2 + 1; - else if (res < 0) - specdam = random2(damage_done) + 1; + if (coinflip()) + { + emit_nodmg_hit_message(); + monster_teleport(def, coinflip()); + break; + } - if (specdam) - { - snprintf(special_damage_message, INFO_SIZE, - "You burn %s", - ptr_monam(defender, DESC_NOCAP_THE)); + if (coinflip()) + { + emit_nodmg_hit_message(); + monster_die(def, KILL_RESET, 0); + return (true); + } + break; - if (specdam < 3) - strcat(special_damage_message, "."); - else if (specdam < 7) - strcat(special_damage_message, "!"); - else - strcat(special_damage_message, "!!"); - } - break; + case SPWPN_CONFUSE: + { + emit_nodmg_hit_message(); + + // declaring these just to pass to the enchant function + bolt beam_temp; + beam_temp.flavour = BEAM_CONFUSION; + + mons_ench_f2( def, beam_temp ); + + you.confusing_touch -= random2(20); + + if (you.confusing_touch < 1) + you.confusing_touch = 1; + break; + } + } - case SPWPN_FREEZING: - specdam = 0; + return (false); +} - res = mons_res_cold(defender); - if (res == 0) - specdam = 1 + random2(damage_done) / 2; - else if (res < 0) - specdam = 1 + random2(damage_done); +void melee_attack::player_sustain_passive_damage() +{ + if (mons_class_flag(defender->id(), M_ACID_SPLASH)) + weapon_acid(5); +} - if (specdam) - { - snprintf(special_damage_message, INFO_SIZE, - "You freeze %s", - ptr_monam(defender, DESC_NOCAP_THE)); +int melee_attack::player_staff_damage(int skill) +{ + return + roll_dice(3, + 1 + (you.skills[skill] + you.skills[SK_EVOCATIONS]) / 2); +} - if (specdam < 3) - strcat(special_damage_message, "."); - else if (specdam < 7) - strcat(special_damage_message, "!"); - else - strcat(special_damage_message, "!!"); +void melee_attack::emit_nodmg_hit_message() +{ + if (!no_damage_message.empty()) + { + mprf("%s", no_damage_message.c_str()); + no_damage_message.clear(); + } +} - mpr(info); - } - break; +void melee_attack::player_apply_staff_damage() +{ + special_damage = 0; + + if (!weapon || !item_is_staff(*weapon)) + return; - case SPWPN_HOLY_WRATH: - // there should be a case in here for holy monsters, - // see elsewhere in fight.cc {dlb} - specdam = 0; - switch (mons_holiness(defender)) - { - case MH_UNDEAD: - specdam = 1 + random2(damage_done); - break; + const int staff_cost = 2; + + if (you.magic_points < staff_cost + || random2(15) > you.skills[SK_EVOCATIONS]) + { + return; + } + + switch (weapon->sub_type) + { + case STAFF_AIR: + if (damage_done + you.skills[SK_AIR_MAGIC] <= random2(20)) + break; - case MH_DEMONIC: - specdam = 1 + (random2(damage_done * 15) / 10); - break; + if (mons_res_elec(def)) + break; - default: - break; - } - break; + special_damage = player_staff_damage(SK_AIR_MAGIC); + + if (special_damage) + special_damage_message = + make_stringf("%s is jolted!", + defender->name(DESC_CAP_THE).c_str()); + + break; + + case STAFF_COLD: + if (mons_res_cold(def) > 0) + break; + + special_damage = player_staff_damage(SK_ICE_MAGIC); + + if (mons_res_cold(def) < 0) + special_damage += player_staff_damage(SK_ICE_MAGIC); + + if (special_damage) + { + special_damage_message = + make_stringf( + "You freeze %s!", + defender->name(DESC_NOCAP_THE).c_str()); + } + break; + case STAFF_EARTH: + special_damage = player_staff_damage(SK_EARTH_MAGIC); - case SPWPN_ELECTROCUTION: - specdam = 0; + if (special_damage) + { + special_damage_message = + make_stringf( + "You crush %s!", + defender->name(DESC_NOCAP_THE).c_str()); + } + break; - if (mons_flies(defender)) - break; - else if (mons_res_elec(defender) > 0) - break; - else if (one_chance_in(3)) - { - strcpy(special_damage_message, - "There is a sudden explosion of sparks!"); - specdam = random2avg(28, 3); - } - break; + case STAFF_FIRE: + if (mons_res_fire(def) > 0) + break; - case SPWPN_ORC_SLAYING: - if (mons_species(defender->type) == MONS_ORC) - hurt_monster(defender, 1 + random2(damage_done)); - break; + special_damage = player_staff_damage(SK_FIRE_MAGIC); - case SPWPN_VENOM: - if (!one_chance_in(4)) - { - // HACK - poison_monster bites us again - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; - } - poison_monster(defender, true); - } - break; + if (mons_res_fire(def) < 0) + special_damage += player_staff_damage(SK_FIRE_MAGIC); - case SPWPN_DRAINING: - if (mons_res_negative_energy(defender) > 0 || one_chance_in(3)) - break; + if (special_damage) + { + special_damage_message = + make_stringf( + "You burn %s!", + defender->name(DESC_NOCAP_THE).c_str()); + } + break; - snprintf(special_damage_message, INFO_SIZE, "You drain %s!", - ptr_monam(defender, DESC_NOCAP_THE)); + case STAFF_POISON: + // cap chance at 30% -- let staff of Olgreb shine + int temp_rand = damage_done + you.skills[SK_POISON_MAGIC]; - if (one_chance_in(5)) - defender->hit_dice--; + if (temp_rand > 30) + temp_rand = 30; - defender->max_hit_points -= 2 + random2(3); - defender->hit_points -= 2 + random2(3); + if (random2(100) < temp_rand) + { + // Poison monster message needs to arrive after hit message. + emit_nodmg_hit_message(); + poison_monster(def, true); + } + break; - if (defender->hit_points >= defender->max_hit_points) - defender->hit_points = defender->max_hit_points; + case STAFF_DEATH: + if (mons_res_negative_energy(def) > 0) + break; - if (defender->hit_dice < 1) - defender->hit_points = 0; + if (random2(8) <= you.skills[SK_NECROMANCY]) + { + special_damage = player_staff_damage(SK_NECROMANCY); - specdam = 1 + (random2(damage_done) / 2); - did_god_conduct( DID_NECROMANCY, 2 ); - break; + if (special_damage) + { + special_damage_message = + make_stringf( + "%s convulses in agony!", + defender->name(DESC_CAP_THE).c_str()); - /* 9 = speed - done before */ + did_god_conduct(DID_NECROMANCY, 4); + } + } + break; - case SPWPN_VORPAL: - specdam = 1 + random2(damage_done) / 2; - // note: leaving special_damage_message empty because there - // isn't one. - break; + case STAFF_POWER: + case STAFF_SUMMONING: + case STAFF_CHANNELING: + case STAFF_CONJURATION: + case STAFF_ENCHANTMENT: + case STAFF_ENERGY: + case STAFF_WIZARDRY: + break; - case SPWPN_VAMPIRICISM: - specdam = 0; // NB: does no extra damage + default: + mpr("You're wielding some staff I've never heard of! (fight.cc)"); + break; + } // end switch - if (mons_holiness(defender) != MH_NATURAL || - mons_res_negative_energy(defender) > 0 || - damage_done < 1 || you.hp == you.hp_max || - one_chance_in(5)) - break; + if (special_damage > 0) + { + dec_mp(staff_cost); - // We only get here if we've done base damage, so no - // worries on that score. - mpr("You feel better."); + if (!item_type_known(*weapon)) + { + set_ident_flags( *weapon, ISFLAG_KNOW_TYPE ); - // thus is probably more valuable on larger weapons? - if (ur_armed - && is_fixed_artefact( you.inv[weapon] ) - && you.inv[weapon].special == SPWPN_VAMPIRES_TOOTH) - { - inc_hp(damage_done, false); - } - else - inc_hp(1 + random2(damage_done), false); + mprf("You are wielding %s.", + item_name(*weapon, DESC_NOCAP_A)); + more(); + you.wield_change = true; + } + } +} - if (you.hunger_state != HS_ENGORGED) - lessen_hunger(random2avg(59, 2), true); +bool melee_attack::player_check_monster_died() +{ + if (def->hit_points < 1) + { +#if DEBUG_DIAGNOSTICS + /* note: doesn't take account of special weapons etc */ + mprf( MSGCH_DIAGNOSTICS, "Hit for %d.", damage_done ); +#endif - did_god_conduct( DID_NECROMANCY, 2 ); - break; + player_monattk_hit_effects(true); - case SPWPN_DISRUPTION: - specdam = 0; - if (mons_holiness(defender) == MH_UNDEAD && !one_chance_in(3)) - { - // see previous HACKs - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; - } - simple_monster_message(defender, " shudders."); - specdam += random2avg((1 + (damage_done * 3)), 3); - } - break; + if (def->type == MONS_GIANT_SPORE || def->type == MONS_BALL_LIGHTNING) + mprf("You %s %s.", attack_verb.c_str(), + ptr_monam(def, DESC_NOCAP_THE)); - case SPWPN_PAIN: - specdam = 0; - if (mons_res_negative_energy(defender) <= 0 - && random2(8) <= you.skills[SK_NECROMANCY]) - { - // see previous HACKs - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; - } - simple_monster_message(defender, " convulses in agony."); - specdam += random2( 1 + you.skills[SK_NECROMANCY] ); - } - did_god_conduct(DID_NECROMANCY, 4); - break; + monster_die(def, KILL_YOU, 0); - case SPWPN_DISTORTION: - //jmf: blink frogs *like* distortion - // I think could be amended to let blink frogs "grow" like - // jellies do {dlb} - if (defender->type == MONS_BLINK_FROG) - { - if (one_chance_in(5)) - { - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; - } - simple_monster_message( defender, - " basks in the translocular energy." ); - heal_monster(defender, 1 + random2avg(7, 2), true); // heh heh - } - break; - } + return (true); + } - if (one_chance_in(3)) - { - snprintf(special_damage_message, INFO_SIZE, - "Space bends around %s.", - ptr_monam(defender, DESC_NOCAP_THE)); - specdam += 1 + random2avg(7, 2); - break; - } + return (false); +} - if (one_chance_in(3)) - { - snprintf( special_damage_message, INFO_SIZE, - "Space warps horribly around %s!", - ptr_monam(defender, DESC_NOCAP_THE)); - specdam += 3 + random2avg(24, 2); - break; - } +void melee_attack::player_calc_hit_damage() +{ + potential_damage = player_stat_modify_damage(potential_damage); - if (one_chance_in(3)) - { - monster_blink(defender); - break; - } + if (water_attack) + potential_damage = player_apply_water_attack_bonus(potential_damage); + + // apply damage bonus from ring of slaying + // (before randomization -- some of these rings + // are stupidly powerful) -- GDL + potential_damage += slaying_bonus(PWPN_DAMAGE); + damage_done = potential_damage > 0? 1 + random2(potential_damage) : 0; + damage_done = player_apply_weapon_skill(damage_done); + damage_done = player_apply_fighting_skill(damage_done, false); + damage_done = player_apply_misc_modifiers(damage_done); + damage_done = player_apply_weapon_bonuses(damage_done); + + player_weapon_auto_id(); + + damage_done = player_stab(damage_done); + damage_done = player_apply_monster_ac(damage_done); + + // This doesn't actually modify damage -- bwr + damage_done = player_weapon_type_modify( damage_done ); + + if (damage_done < 0) + damage_done = 0; +} - if (coinflip()) - { - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; - } - monster_teleport(defender, coinflip()); - break; - } +int melee_attack::calc_to_hit(bool random) +{ + return (attacker->atype() == ACT_PLAYER? player_to_hit(random) + : mons_to_hit()); +} - if (coinflip()) - { - if ( base_nodamage ) - mpr(base_damage_message); - monster_die(defender, KILL_RESET, 0); - return (true); - } - break; +int melee_attack::player_to_hit(bool random_factor) +{ + heavy_armour_penalty = calc_heavy_armour_penalty(random_factor); + can_do_unarmed = player_fights_well_unarmed(heavy_armour_penalty); - case SPWPN_CONFUSE: - { - if ( base_nodamage ) - { - mpr(base_damage_message); - base_nodamage = false; - } + hand_half_bonus = + unarmed_ok + && !can_do_unarmed + && !shield + && weapon + && !item_cursed( *weapon ) + && hands == HANDS_HALF; - // declaring these just to pass to the enchant function - struct bolt beam_temp; - beam_temp.flavour = BEAM_CONFUSION; + int your_to_hit = 15 + (calc_stat_to_hit_base() / 2); - mons_ench_f2( defender, beam_temp ); + if (water_attack) + your_to_hit += 5; - you.confusing_touch -= random2(20); + if (wearing_amulet(AMU_INACCURACY)) + your_to_hit -= 5; - if (you.confusing_touch < 1) - you.confusing_touch = 1; - } - break; - } /* end switch */ - } + // if you can't see yourself, you're a little less acurate. + if (you.invis && !player_see_invis()) + your_to_hit -= 5; - /* remember, the hydra function sometimes skips straight to mons_dies */ -#if DEBUG_DIAGNOSTICS - snprintf( info, INFO_SIZE, "brand: %d; melee special damage: %d", - melee_brand, specdam ); - mpr( info, MSGCH_DIAGNOSTICS ); -#endif - if ( base_nodamage ) + // fighting contribution + your_to_hit += maybe_random2(1 + you.skills[SK_FIGHTING], random_factor); + + // weapon skill contribution + if (weapon) + { + if (wpn_skill != SK_FIGHTING) { - if ( specdam > 0 ) - mpr(base_damage_message); - else - mprf("You %s %s, but do no damage.", - damage_noise, ptr_monam(defender, DESC_NOCAP_THE)); + your_to_hit += maybe_random2(you.skills[wpn_skill] + 1, + random_factor); } - if ( special_damage_message[0] ) - mpr(special_damage_message); - - hurt_monster( defender, specdam ); - } // end if (hit) + } + else + { // ...you must be unarmed + your_to_hit += + (you.species == SP_TROLL || you.species == SP_GHOUL) ? 4 : 2; - mons_dies: - if (defender->hit_points < 1) - { - monster_die(defender, KILL_YOU, 0); - return (hit); + your_to_hit += maybe_random2(1 + you.skills[SK_UNARMED_COMBAT], + random_factor); } - if (unarmed_attacks) + // weapon bonus contribution + if (weapon) { - char attack_name[20] = ""; - int sc_dam = 0; - int brand = SPWPN_NORMAL; - - int unarmed_attack = UNAT_NO_ATTACK; - - if (can_do_unarmed_combat) + if (weapon->base_type == OBJ_WEAPONS) { - if (you.species == SP_NAGA) - unarmed_attack = UNAT_HEADBUTT; - else - unarmed_attack = (coinflip() ? UNAT_HEADBUTT : UNAT_KICK); + your_to_hit += weapon->plus; + your_to_hit += property( *weapon, PWPN_HIT ); - if ((you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON - || player_genus(GENPC_DRACONIAN) - || (you.species == SP_MERFOLK && player_is_swimming()) - || you.mutation[ MUT_STINGER ]) - && one_chance_in(3)) + if (get_equip_race(*weapon) == ISFLAG_ELVEN + && player_genus(GENPC_ELVEN)) { - unarmed_attack = UNAT_TAILSLAP; + your_to_hit += (random_factor && coinflip() ? 2 : 1); } - - if (coinflip()) - unarmed_attack = UNAT_PUNCH; } - - for (unsigned char scount = 0; scount < 4; scount++) + else if (item_is_staff( *weapon )) { - brand = SPWPN_NORMAL; - - switch (scount) - { - case 0: - if (unarmed_attack != UNAT_KICK) //jmf: hooves mutation - { - if ((you.species != SP_CENTAUR && !you.mutation[MUT_HOOVES]) - || coinflip()) - { - continue; - } - } - - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL - || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST - || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON - || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER) - { - continue; - } - - strcpy(attack_name, "kick"); - sc_dam = ((you.mutation[MUT_HOOVES] - || you.species == SP_CENTAUR) ? 10 : 5); - break; - - case 1: - if (unarmed_attack != UNAT_HEADBUTT) - { - if ((!you.mutation[MUT_HORNS] && you.species != SP_KENKU) - || !one_chance_in(3)) - { - continue; - } - } - - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL - || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER - || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST - || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON) - { - continue; - } - - strcpy(attack_name, (you.species == SP_KENKU) ? "peck" - : "headbutt"); - - sc_dam = 5 + you.mutation[MUT_HORNS] * 3; - // minotaurs used to get +5 damage here, now they get - // +6 because of the horns. + // magical staff + your_to_hit += property( *weapon, PWPN_HIT ); + } + } - if (you.equip[EQ_HELMET] != -1 - && (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; + // slaying bonus + your_to_hit += slaying_bonus(PWPN_HIT); - 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; - } - } - break; + // hunger penalty + if (you.hunger_state == HS_STARVING) + your_to_hit -= 3; - case 2: /* draconians */ - if (unarmed_attack != UNAT_TAILSLAP) - { - // not draconian and not wet merfolk - if ((!player_genus(GENPC_DRACONIAN) - && (!(you.species == SP_MERFOLK && player_is_swimming())) - && !you.mutation[ MUT_STINGER ]) - || (!one_chance_in(4))) + // armour penalty + your_to_hit -= heavy_armour_penalty; - { - continue; - } - } +#if DEBUG_DIAGNOSTICS + int roll_hit = your_to_hit; +#endif - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER - || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST) - { - continue; - } + // hit roll + your_to_hit = maybe_random2(your_to_hit, random_factor); - strcpy(attack_name, "tail-slap"); - sc_dam = 6; +#if DEBUG_DIAGNOSTICS + mprf( MSGCH_DIAGNOSTICS, "to hit die: %d; rolled value: %d", + roll_hit, your_to_hit ); +#endif - if (you.mutation[ MUT_STINGER ] > 0) - { - sc_dam += (you.mutation[ MUT_STINGER ] * 2 - 1); - brand = SPWPN_VENOM; - } + if (hand_half_bonus) + your_to_hit += maybe_random2(3, random_factor); - /* grey dracs have spiny tails, or something */ - // maybe add this to player messaging {dlb} - // - // STINGER mutation doesn't give extra damage here... that - // would probably be a bit much, we'll still get the - // poison bonus so it's still somewhat good. - if (you.species == SP_GREY_DRACONIAN && you.experience_level >= 7) - { - sc_dam = 12; - } - break; + if (weapon && wpn_skill == SK_SHORT_BLADES && you.sure_blade) + your_to_hit += 5 + + (random_factor ? random2limit( you.sure_blade, 10 ) : + you.sure_blade / 2); - case 3: - if (unarmed_attack != UNAT_PUNCH) - continue; + // other stuff + if (!weapon) + { + if ( you.confusing_touch ) + // just trying to touch is easier that trying to damage + your_to_hit += maybe_random2(you.dex, random_factor); - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_SERPENT_OF_HELL - || you.attribute[ATTR_TRANSFORMATION] == TRAN_SPIDER - || you.attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST - || you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON) - { - continue; - } + switch ( you.attribute[ATTR_TRANSFORMATION] ) + { + case TRAN_SPIDER: + your_to_hit += maybe_random2(10, random_factor); + break; + case TRAN_ICE_BEAST: + your_to_hit += maybe_random2(10, random_factor); + break; + case TRAN_BLADE_HANDS: + your_to_hit += maybe_random2(12, random_factor); + break; + case TRAN_STATUE: + your_to_hit += maybe_random2(9, random_factor); + break; + case TRAN_SERPENT_OF_HELL: + case TRAN_DRAGON: + your_to_hit += maybe_random2(10, random_factor); + break; + case TRAN_LICH: + your_to_hit += maybe_random2(10, random_factor); + break; + case TRAN_AIR: + your_to_hit = 0; + break; + case TRAN_NONE: + default: + break; + } + } - /* no punching with a shield or 2-handed wpn, except staves */ - if (bearing_shield || coinflip() - || (ur_armed && hands == HANDS_TWO - && you.inv[weapon].base_type != OBJ_STAVES - && you.inv[weapon].sub_type != WPN_QUARTERSTAFF) ) - { - continue; - } + // Check for backlight (Corona). + if (defender + && defender->atype() == ACT_MONSTER + && mons_has_ench(def, ENCH_BACKLIGHT_I, ENCH_BACKLIGHT_IV)) + { + your_to_hit += 2 + random2(8); + } - strcpy(attack_name, "punch"); + return (your_to_hit); +} - /* applied twice */ - sc_dam = 5 + you.skills[SK_UNARMED_COMBAT] / 3; +void melee_attack::player_stab_check() +{ + bool roll_needed = true; + // This ordering is important! - if (you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) - { - strcpy(attack_name, "slash"); - sc_dam += 6; - } - break; + // not paying attention (but not batty) + if (def->foe != MHITYOU && !testbits(def->flags, MF_BATTY)) + { + stab_attempt = true; + stab_bonus = 3; + } - /* To add more, add to while part of loop below as well */ - default: - continue; + // confused (but not perma-confused) + if (mons_has_ench(def, ENCH_CONFUSION) + && !mons_class_flag(def->type, M_CONFUSED)) + { + stab_attempt = true; + stab_bonus = 2; + } - } + // fleeing + if (def->behaviour == BEH_FLEE) + { + stab_attempt = true; + stab_bonus = 2; + } - // unified to-hit calculation - your_to_hit = calc_your_to_hit_unarmed(); - your_to_hit = random2(your_to_hit); + // sleeping + if (def->behaviour == BEH_SLEEP) + { + stab_attempt = true; + roll_needed = false; + stab_bonus = 1; + } - make_hungry(2, true); + // helpless (plants, etc) + if (defender->cannot_fight()) + stab_attempt = false; - damage = sc_dam; //4 + you.experience_level / 3; + // see if we need to roll against dexterity / stabbing + if (stab_attempt && roll_needed) + stab_attempt = (random2(200) <= you.skills[SK_STABBING] + you.dex); - alert_nearby_monsters(); + // check for invisibility - no stabs on invisible monsters. + if (!player_monster_visible( def )) + { + stab_attempt = false; + stab_bonus = 0; + } +} - if (your_to_hit >= defender->evasion || one_chance_in(30)) - { - hit = true; - int dammod = 10; +void melee_attack::player_apply_attack_delay() +{ + int attack_delay = weapon? player_weapon_speed() : player_unarmed_speed(); + attack_delay = player_apply_shield_delay(attack_delay); - const int dam_stat_val = calc_stat_to_dam_base(); + if (attack_delay < 3) + attack_delay = 3; - if (dam_stat_val > 11) - dammod += random2(dam_stat_val - 11) / 3; - if (dam_stat_val < 9) - dammod -= random2(9 - dam_stat_val) / 2; + final_attack_delay = attack_delay; - damage *= dammod; - damage /= 10; + you.time_taken = (you.time_taken * final_attack_delay) / 10; + if (you.time_taken < 1) + you.time_taken = 1; - damage += slaying_bonus(PWPN_DAMAGE); +#if DEBUG_DIAGNOSTICS + mprf( MSGCH_DIAGNOSTICS, + "Weapon speed: %d; min: %d; attack time: %d", + final_attack_delay, min_delay, you.time_taken ); +#endif +} - damage_done = (int) random2(damage); +int melee_attack::player_weapon_speed() +{ + int attack_delay = 0; + + if (weapon && (weapon->base_type == OBJ_WEAPONS + || item_is_staff( *weapon ))) + { + attack_delay = property( *weapon, PWPN_SPEED ); + attack_delay -= you.skills[ wpn_skill ] / 2; + + min_delay = property( *weapon, PWPN_SPEED ) / 2; - damage_done *= 40 + (random2(you.skills[SK_FIGHTING] + 1)); - damage_done /= 40; + // Short blades can get up to at least unarmed speed. + if (wpn_skill == SK_SHORT_BLADES && min_delay > 5) + min_delay = 5; + + // Using both hands can get a weapon up to speed 7 + if ((hands == HANDS_TWO || hand_half_bonus) + && min_delay > 7) + { + min_delay = 7; + } + + // never go faster than speed 3 (ie 3 attacks per round) + if (min_delay < 3) + min_delay = 3; + + // Hand and a half bonus only helps speed up to a point, any more + // than speed 10 must come from skill and the weapon + if (hand_half_bonus && attack_delay > 10) + attack_delay--; + + // apply minimum to weapon skill modification + if (attack_delay < min_delay) + attack_delay = min_delay; + + if (weapon->base_type == OBJ_WEAPONS + && damage_brand == SPWPN_SPEED) + { + attack_delay = (attack_delay + 1) / 2; + } + } + + return (attack_delay); +} - damage_done *= 25 + (random2(you.skills[SK_UNARMED_COMBAT]+1)); - damage_done /= 25; +int melee_attack::player_unarmed_speed() +{ + int unarmed_delay = 10; - if (you.might > 1) - damage_done += 1 + random2(10); + min_delay = 5; + + // Unarmed speed + if (you.burden_state == BS_UNENCUMBERED + && one_chance_in(heavy_armour_penalty + 1)) + { + unarmed_delay = 10 - you.skills[SK_UNARMED_COMBAT] / 5; + + /* this shouldn't happen anyway...sanity */ + if (unarmed_delay < min_delay) + unarmed_delay = min_delay; + } - if (you.hunger_state == HS_STARVING) - damage_done -= random2(5); + return (unarmed_delay); +} - damage_done -= random2(1 + defender->armour_class); +int melee_attack::player_apply_shield_delay(int attack_delay) +{ + if (shield) + { + switch (shield->sub_type) + { + case ARM_LARGE_SHIELD: + if (you.skills[SK_SHIELDS] <= 10 + random2(17)) + attack_delay++; + // [dshaligram] Fall-through + + case ARM_SHIELD: + if (you.skills[SK_SHIELDS] <= 3 + random2(17)) + attack_delay++; + break; + } + } - if (damage_done < 1) - damage_done = 0; - else - hurt_monster(defender, damage_done); + return (attack_delay); +} - if (damage_done > 0) - { - if ((!helpless || you.skills[SK_FIGHTING] < 2) - && one_chance_in(5)) - { - exercise(SK_FIGHTING, 1); - } +int melee_attack::player_calc_base_unarmed_damage() +{ + int damage = 3; - if (!helpless || you.skills[SK_UNARMED_COMBAT] < 2) - exercise(SK_UNARMED_COMBAT, 1); + if (you.confusing_touch) + { + // no base hand damage while using this spell + damage = 0; + } - strcpy(info, "You "); - strcat(info, attack_name); - strcat(info, " "); - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); + if (you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE) + { + switch (you.attribute[ATTR_TRANSFORMATION]) + { + case TRAN_SPIDER: + damage = 5; + break; + case TRAN_ICE_BEAST: + damage = 12; + break; + case TRAN_BLADE_HANDS: + damage = 12 + (you.strength / 4) + (you.dex / 4); + break; + case TRAN_STATUE: + damage = 12 + you.strength; + break; + case TRAN_SERPENT_OF_HELL: + case TRAN_DRAGON: + damage = 20 + you.strength; + break; + case TRAN_LICH: + damage = 5; + break; + case TRAN_AIR: + damage = 0; + break; + } + } + else if (you.equip[ EQ_GLOVES ] == -1) + { + // claw damage only applies for bare hands + if (you.species == SP_TROLL) + damage += 5; + else if (you.species == SP_GHOUL) + damage += 2; -#if DEBUG_DIAGNOSTICS - strcat(info, " for "); - itoa(damage_done, st_prn, 10); - strcat(info, st_prn); -#endif + damage += (you.mutation[ MUT_CLAWS ] * 2); + } - if (damage_done < HIT_WEAK) - strcat(info, "."); - else if (damage_done < HIT_MED) - strcat(info, "!"); - else if (damage_done < HIT_STRONG) - strcat(info, "!!"); - else - strcat(info, "!!!"); + damage += you.skills[SK_UNARMED_COMBAT]; - mpr(info); + return (damage); +} - if (brand == SPWPN_VENOM && coinflip()) - poison_monster( defender, true ); +int melee_attack::player_calc_base_weapon_damage() +{ + int damage = 0; + + if (weapon->base_type == OBJ_WEAPONS + || item_is_staff( *weapon )) + { + damage = property( *weapon, PWPN_DAMAGE ); + } - if (mons_holiness(defender) == MH_HOLY) - did_god_conduct(DID_KILL_ANGEL, 1); + return (damage); +} - hit = true; - } - else // no damage was done - { - strcpy(info, "You "); - strcat(info, attack_name); - strcat(info, " "); - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); +/////////////////////////////////////////////////////////////////////////// - if (player_monster_visible( defender )) - strcat(info, ", but do no damage."); - else - strcat(info, "."); +bool melee_attack::mons_attack_mons() +{ + return (false); +} - mpr(info); - hit = true; - } +bool melee_attack::mons_attack_you() +{ + return (false); +} +int melee_attack::mons_to_hit() +{ + // TODO + return 0; +} - if (defender->hit_points < 1) - { - monster_die(defender, KILL_YOU, 0); +/////////////////////////////////////////////////////////////////////////// - if (defender->type == MONS_GIANT_SPORE) - { - strcpy(info, "You "); - strcat(info, attack_name); - strcat(info, "the giant spore."); - mpr(info); - } - else if (defender->type == MONS_BALL_LIGHTNING) - { - strcpy(info, "You "); - strcat(info, attack_name); - strcat(info, "the ball lightning."); - mpr(info); - } - return (true); - } - } - else - { - strcpy(info, "Your "); - strcat(info, attack_name); - strcat(info, " misses "); - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - } +static void tutorial_weapon_check(const item_def *weapon) +{ + if (weapon && + (weapon->base_type != OBJ_WEAPONS + || is_range_weapon(*weapon))) + { + learned_something_new(TUT_WIELD_WEAPON); } +} - if (hit) - print_wounds(defender); +// Returns true if you hit the monster. +bool you_attack(int monster_attacked, bool unarmed_attacks) +{ + monsters *defender = &menv[monster_attacked]; + melee_attack attk(&you, defender, unarmed_attacks); + + // We're trying to hit a monster, break out of travel/explore now. + interrupt_activity(AI_HIT_MONSTER, defender); + + // For tutorials, check if the player is fighting with something unsuitable + tutorial_weapon_check(attk.weapon); - return (hit); -} // end you_attack() + return attk.attack(); +} static void mons_lose_attack_energy(monsters *attacker, int wpn_speed, int which_attack) @@ -3190,17 +3348,11 @@ bool monsters_fight(int monster_attacking, int monster_attacked) return false; } - if (monster_floundering(attacker) && one_chance_in(4)) - { - mpr("You hear a splashing noise."); + if (attacker->fumbles_attack(true)) return true; - } // habitat is the favoured habitat of the attacker - if (monster_floundering(defender) && habitat == DNGN_DEEP_WATER) - { - water_attack = true; - } + water_attack = defender->floundering() && attacker->swimming(); if (mons_near(attacker) && mons_near(defender)) sees = true; @@ -3974,201 +4126,6 @@ bool monsters_fight(int monster_attacking, int monster_attacked) ************************************************** */ - -// Added by DML 6/10/99. -// For now, always returns damage: that is, it never modifies values, -// just adds 'color'. -static int weapon_type_modify( int weapnum, char noise[80], char noise2[80], - int damage ) -{ - int weap_type = WPN_UNKNOWN; - - if (weapnum == -1) - weap_type = WPN_UNARMED; - else if (item_is_staff( you.inv[weapnum] )) - weap_type = WPN_QUARTERSTAFF; - else if (you.inv[weapnum].base_type == OBJ_WEAPONS) - weap_type = you.inv[weapnum].sub_type; - - noise2[0] = 0; - - // All weak hits look the same, except for when the player - // has a non-weapon in hand. -- bwr - if (damage < HIT_WEAK) - { - if (weap_type != WPN_UNKNOWN) - strcpy( noise, "hit" ); - else - strcpy( noise, "clumsily bash" ); - - return (damage); - } - - // take transformations into account, if no weapon is wielded - if (weap_type == WPN_UNARMED - && you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE) - { - switch (you.attribute[ATTR_TRANSFORMATION]) - { - case TRAN_SPIDER: - if (damage < HIT_STRONG) - strcpy( noise, "bite" ); - else - strcpy( noise, "maul" ); - break; - case TRAN_BLADE_HANDS: - if (damage < HIT_MED) - strcpy( noise, "slash" ); - else if (damage < HIT_STRONG) - strcpy( noise, "slice" ); - else - strcpy( noise, "shred" ); - break; - case TRAN_ICE_BEAST: - case TRAN_STATUE: - case TRAN_LICH: - if (damage < HIT_MED) - strcpy( noise, "punch" ); - else - strcpy( noise, "pummel" ); - break; - case TRAN_DRAGON: - case TRAN_SERPENT_OF_HELL: - if (damage < HIT_MED) - strcpy( noise, "claw" ); - else if (damage < HIT_STRONG) - strcpy( noise, "bite" ); - else - strcpy( noise, "maul" ); - break; - case TRAN_AIR: - strcpy( noise, "buffet" ); - break; - } // transformations - - return (damage); - } - - switch (weap_type) - { - case WPN_KNIFE: - case WPN_DAGGER: - case WPN_SHORT_SWORD: - case WPN_TRIDENT: - case WPN_DEMON_TRIDENT: - case WPN_SPEAR: - if (damage < HIT_MED) - strcpy( noise, "puncture" ); - else if (damage < HIT_STRONG) - strcpy( noise, "impale" ); - else - { - strcpy( noise, "spit" ); - strcpy( noise2, " like a pig" ); - } - return (damage); - - case WPN_BOW: - case WPN_LONGBOW: - case WPN_CROSSBOW: - case WPN_HAND_CROSSBOW: - if (damage < HIT_STRONG) - strcpy( noise, "puncture" ); - else - strcpy( noise, "skewer" ); - return (damage); - - case WPN_LONG_SWORD: - case WPN_GREAT_SWORD: - case WPN_SCIMITAR: - case WPN_FALCHION: - case WPN_HALBERD: - case WPN_GLAIVE: - case WPN_HAND_AXE: - case WPN_WAR_AXE: - case WPN_BROAD_AXE: - case WPN_BATTLEAXE: - case WPN_SCYTHE: - case WPN_QUICK_BLADE: - case WPN_KATANA: - case WPN_LAJATANG: - case WPN_LOCHABER_AXE: - case WPN_EXECUTIONERS_AXE: - case WPN_DOUBLE_SWORD: - case WPN_TRIPLE_SWORD: - case WPN_SABRE: - case WPN_DEMON_BLADE: - case WPN_BLESSED_BLADE: - if (damage < HIT_MED) - strcpy( noise, "slash" ); - else if (damage < HIT_STRONG) - strcpy( noise, "slice" ); - else - { - strcpy( noise, "open" ); - strcpy( noise2, " like a pillowcase" ); - } - return (damage); - - case WPN_SLING: - case WPN_CLUB: - case WPN_MACE: - case WPN_FLAIL: - case WPN_GREAT_MACE: - case WPN_DIRE_FLAIL: - case WPN_QUARTERSTAFF: - case WPN_GIANT_CLUB: - case WPN_HAMMER: - case WPN_ANCUS: - case WPN_MORNINGSTAR: /*for now, just a bludgeoning weapon */ - case WPN_SPIKED_FLAIL: /*for now, just a bludgeoning weapon */ - case WPN_EVENINGSTAR: - case WPN_GIANT_SPIKED_CLUB: - if (damage < HIT_MED) - strcpy( noise, "sock" ); - else if (damage < HIT_STRONG) - strcpy( noise, "bludgeon" ); - else - { - strcpy( noise, "crush" ); - strcpy( noise2, " like a grape" ); - } - return (damage); - - case WPN_WHIP: - case WPN_DEMON_WHIP: - if (damage < HIT_MED) - strcpy( noise, "whack" ); - else - strcpy( noise, "thrash" ); - return (damage); - - case WPN_UNARMED: - if (you.species == SP_TROLL || you.mutation[MUT_CLAWS]) - { - if (damage < HIT_MED) - strcpy( noise, "claw" ); - else if (damage < HIT_STRONG) - strcpy( noise, "mangle" ); - else - strcpy( noise, "eviscerate" ); - } - else - { - if (damage < HIT_MED) - strcpy( noise, "punch" ); - else - strcpy( noise, "pummel" ); - } - return (damage); - - case WPN_UNKNOWN: - default: - strcpy( noise, "hit" ); - return (damage); - } -} // end weapon_type_modify() - // Returns a value between 0 and 10 representing the weight given to str int weapon_str_weight( int wpn_class, int wpn_type ) { @@ -4299,37 +4256,34 @@ static void stab_message( struct monsters *defender, int stab_bonus ) switch(stab_bonus) { - case 3: // big melee, monster surrounded/not paying attention - if (r<3) - { - snprintf( info, INFO_SIZE, "You strike %s from a blind spot!", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - else - { - snprintf( info, INFO_SIZE, "You catch %s momentarily off-guard.", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - break; - case 2: // confused/fleeing - if (r<4) - { - snprintf( info, INFO_SIZE, "You catch %s completely off-guard!", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - else - { - snprintf( info, INFO_SIZE, "You strike %s from behind!", - ptr_monam(defender, DESC_NOCAP_THE) ); - } - break; - case 1: - snprintf( info, INFO_SIZE, "%s fails to defend %s.", - ptr_monam(defender, DESC_CAP_THE), - mons_pronoun( defender->type, PRONOUN_REFLEXIVE ) ); - break; + case 3: // big melee, monster surrounded/not paying attention + if (r<3) + { + mprf( "You strike %s from a blind spot!", + ptr_monam(defender, DESC_NOCAP_THE) ); + } + else + { + mprf( "You catch %s momentarily off-guard.", + ptr_monam(defender, DESC_NOCAP_THE) ); + } + break; + case 2: // confused/fleeing + if (r<4) + { + mprf( "You catch %s completely off-guard!", + ptr_monam(defender, DESC_NOCAP_THE) ); + } + else + { + mprf( "You strike %s from behind!", + ptr_monam(defender, DESC_NOCAP_THE) ); + } + break; + case 1: + mprf( "%s fails to defend %s.", + ptr_monam(defender, DESC_CAP_THE), + mons_pronoun( defender->type, PRONOUN_REFLEXIVE ) ); + break; } // end switch - - mpr(info); } - diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h index fb6a1a812b..84bb0f0c28 100644 --- a/crawl-ref/source/fight.h +++ b/crawl-ref/source/fight.h @@ -16,6 +16,7 @@ #include "externs.h" +#include "randart.h" // added Sept 18, 2000 -- bwr /* *********************************************************************** @@ -50,9 +51,131 @@ void monster_attack(int monster_attacking); * *********************************************************************** */ bool monsters_fight(int monster_attacking, int monster_attacked); -int calc_your_to_hit( int heavy_armour, bool hand_and_a_half_bonus, - bool water_attack, bool random_factor ); +int calc_your_to_hit( bool random_factor ); int calc_heavy_armour_penalty( bool random_factor ); +struct melee_attack +{ +public: + // At the moment this only covers players fighting monsters + actor *attacker, *defender; + + // If attacker and/or defender are monsters, these are set. + monsters *atk, *def; + + bool did_hit; + + bool unarmed_ok; + int attack_number; + + int to_hit; + int base_damage; + int potential_damage; + int damage_done; + int special_damage; + int aux_damage; + + bool stab_attempt; + int stab_bonus; + + int min_delay; + int final_attack_delay; + + // Attacker's damage output potential: + + item_def *weapon; + int damage_brand; // Can be special even if unarmed (transforms) + int wpn_skill, hands; + int spwld; // Special wield effects? + bool hand_half_bonus; + + // If weapon is a randart, its properties. + randart_properties_t art_props; + + // Attack messages + std::string attack_verb, verb_degree; + std::string no_damage_message; + std::string special_damage_message; + std::string unarmed_attack; + + item_def *shield; + + // Armour penalties? + int heavy_armour_penalty; + bool can_do_unarmed; + + // Attacker uses watery terrain to advantage vs defender. Implies that + // both attacker and defender are in water. + bool water_attack; + +public: + melee_attack(actor *attacker, actor *defender, + bool allow_unarmed = true, int attack_num = -1); + + // Applies attack damage and other effects. + bool attack(); + + int calc_to_hit(bool random = true); + +private: + void init_attack(); + bool is_water_attack(const actor *, const actor *) const; + void check_hand_half_bonus_eligible(); + void check_autoberserk(); + void check_special_wield_effects(); + void emit_nodmg_hit_message(); + + std::string debug_damage_number(); + std::string special_attack_punctuation(); + std::string attack_strength_punctuation(); + +private: + // Monster-attack specific stuff + bool mons_attack_you(); + bool mons_attack_mons(); + int mons_to_hit(); + +private: + // Player-attack specific stuff + bool player_attack(); + bool player_aux_unarmed(); + bool player_apply_aux_unarmed(); + int player_stat_modify_damage(int damage); + int player_aux_stat_modify_damage(int damage); + int player_to_hit(bool random_factor); + void player_apply_attack_delay(); + int player_apply_water_attack_bonus(int damage); + int player_apply_weapon_bonuses(int damage); + int player_apply_weapon_skill(int damage); + int player_apply_fighting_skill(int damage, bool aux); + int player_apply_misc_modifiers(int damage); + int player_apply_monster_ac(int damage); + void player_weapon_auto_id(); + int player_stab_weapon_bonus(int damage); + int player_stab(int damage); + int player_weapon_type_modify(int damage); + + bool player_hits_monster(); + int player_calc_base_weapon_damage(); + int player_calc_base_unarmed_damage(); + bool player_hurt_monster(); + void player_exercise_combat_skills(); + bool player_monattk_hit_effects(bool mondied); + void player_calc_brand_damage(int res, const char *message_format); + bool player_apply_damage_brand(); + void player_sustain_passive_damage(); + int player_staff_damage(int skill); + void player_apply_staff_damage(); + bool player_check_monster_died(); + void player_calc_hit_damage(); + void player_stab_check(); + int player_weapon_speed(); + int player_unarmed_speed(); + int player_apply_shield_delay(int attack_delay); + void player_announce_hit(); + std::string player_why_missed(); + void player_warn_miss(); +}; + #endif diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index 6886197e7e..7535af2ac0 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -527,7 +527,7 @@ void unuse_randart(const item_def &item) { ASSERT( is_random_artefact( item ) ); - FixedVector< char, RA_PROPERTIES > proprt; + randart_properties_t proprt; randart_wpn_properties( item, proprt ); if (proprt[RAP_AC]) diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 1f65e6233d..d615bc4421 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -338,6 +338,54 @@ void warn_shield_penalties() warn_launcher_shield_slowdown(*weapon); } +int item_special_wield_effect(const item_def &item) +{ + if (item.base_type != OBJ_WEAPONS || !is_artefact(item)) + return (SPWLD_NONE); + + int i_eff = SPWPN_NORMAL; + if (is_random_artefact( item )) + i_eff = randart_wpn_property(item, RAP_BRAND); + else + i_eff = item.special; + + switch (i_eff) + { + case SPWPN_SINGING_SWORD: + return (SPWLD_SING); + + case SPWPN_WRATH_OF_TROG: + return (SPWLD_TROG); + + case SPWPN_SCYTHE_OF_CURSES: + return (SPWLD_CURSE); + + case SPWPN_MACE_OF_VARIABILITY: + return (SPWLD_VARIABLE); + + case SPWPN_GLAIVE_OF_PRUNE: + return (SPWLD_NONE); + + case SPWPN_SCEPTRE_OF_TORMENT: + return (SPWLD_TORMENT); + + case SPWPN_SWORD_OF_ZONGULDROK: + return (SPWLD_ZONGULDROK); + + case SPWPN_SWORD_OF_POWER: + return (SPWLD_POWER); + + case SPWPN_STAFF_OF_OLGREB: + return (SPWLD_OLGREB); + + case SPWPN_STAFF_OF_WUCAD_MU: + return (SPWLD_WUCAD_MU); + + default: + return (SPWLD_NONE); + } +} + // provide a function for handling initial wielding of 'special' // weapons, or those whose function is annoying to reproduce in // other places *cough* auto-butchering *cough* {gdl} @@ -3546,7 +3594,7 @@ void use_randart(const item_def &item) { ASSERT( is_random_artefact( item ) ); - FixedVector< char, RA_PROPERTIES > proprt; + randart_properties_t proprt; randart_wpn_properties( item, proprt ); if (proprt[RAP_AC]) diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 5f79db1476..f85fe548ce 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -147,4 +147,6 @@ int launcher_final_speed(const item_def &launcher, void warn_shield_penalties(); +int item_special_wield_effect(const item_def &item); + #endif diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index f8eee48142..6070f1c48e 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -23,12 +23,13 @@ - Here are the rows: - row 1: monster id, display character, display colour, name - row 2: monster flags - - row 3: mass, experience modifier, charclass, holiness, resist magic - - row 4: damage for each of four attacks - - row 5: hit dice, described by four parameters - - row 6: AC, evasion, speed, speed_inc, sec(spell), corpse_thingy, + - row 3: monster resistance flags + - row 4: mass, experience modifier, charclass, holiness, resist magic + - row 5: damage for each of four attacks + - row 6: hit dice, described by four parameters + - row 7: AC, evasion, speed, speed_inc, sec(spell), corpse_thingy, zombie size, shouts, intel - - row 6: gmon_use class + - row 8: gmon_use class, body size - Some further explanations: @@ -115,7 +116,7 @@ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_HUGE } , @@ -128,7 +129,7 @@ { 8, 0, 0, 0 }, { 3, 3, 5, 0 }, 4, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -140,7 +141,7 @@ { 1, 0, 0, 0 }, { 1, 2, 3, 0 }, 1, 14, 30, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -152,7 +153,7 @@ { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, 3, 7, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -164,7 +165,7 @@ { 18, 0, 0, 0 }, { 5, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -176,7 +177,7 @@ { 18, 12, 0, 0 }, { 7, 3, 5, 0 }, 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_GIANT } , @@ -188,7 +189,7 @@ { 0, 0, 0, 0 }, { 8, 3, 5, 0 }, 1, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -200,7 +201,7 @@ { 4, 0, 0, 0 }, { 1, 2, 4, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -212,7 +213,7 @@ { 6, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 13, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -225,7 +226,7 @@ { 4, 0, 0, 0 }, { 3, 3, 3, 0 }, 3, 14, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LITTLE } , @@ -237,7 +238,7 @@ { 3, 0, 0, 0 }, { 1, 3, 5, 0 }, 2, 12, 14, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -249,7 +250,7 @@ { 10, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 18, 20, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -261,7 +262,7 @@ { 3, 0, 0, 0 }, { 1, 3, 5, 0 }, 1, 5, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -273,7 +274,7 @@ { 14, 8, 8, 0 }, { 9, 3, 5, 0 }, 5, 7, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -286,7 +287,7 @@ { 8, 0, 0, 0 }, { 5, 3, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -298,7 +299,7 @@ { 5, 0, 0, 0 }, { 1, 4, 6, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -312,7 +313,7 @@ { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, 3, 13, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -324,7 +325,7 @@ { 3, 2, 2, 0 }, { 3, 2, 6, 0 }, 5, 17, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -336,7 +337,7 @@ { 3, 0, 0, 0 }, { 1, 1, 3, 0 }, 1, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -348,7 +349,7 @@ { 10, 0, 0, 0 }, { 3, 3, 5, 0 }, 5, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -363,7 +364,7 @@ { 50, 0, 0, 0 }, { 10, 5, 5, 0 }, 3, 3, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_HUGE } , ****************************************************************** */ @@ -376,7 +377,7 @@ { 12, 0, 0, 0 }, { 8, 3, 5, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -388,7 +389,7 @@ { 30, 0, 0, 0 }, { 3, 3, 5, 0 }, 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -400,7 +401,7 @@ { 12, 0, 0, 0 }, { 5, 3, 5, 0 }, 1, 5, 6, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -413,7 +414,7 @@ { 23, 0, 0, 0 }, { 6, 2, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -425,7 +426,7 @@ { 13, 0, 0, 0 }, { 4, 3, 5, 0 }, 5, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -438,7 +439,7 @@ { 10, 0, 0, 0 }, { 1, 5, 5, 0 }, 0, 4, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -450,7 +451,7 @@ { 25, 0, 0, 0 }, { 12, 6, 5, 0 }, 10, 20, 15, 7, MST_ANGEL, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -462,7 +463,7 @@ { 20, 0, 0, 0 }, { 5, 7, 6, 0 }, 10, 3, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -474,7 +475,7 @@ { 35, 0, 0, 0 }, { 9, 3, 5, 0 }, 5, 3, 7, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_GIANT } , @@ -486,7 +487,7 @@ { 20, 13, 13, 0 }, { 12, 5, 5, 0 }, 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -500,7 +501,7 @@ { 17, 13, 0, 0 }, { 6, 3, 5, 0 }, 1, 4, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_LARGE } , @@ -512,7 +513,7 @@ { 25, 15, 15, 0 }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -524,7 +525,7 @@ { 1, 0, 0, 0 }, { 1, 0, 0, 1 }, 0, 10, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -536,7 +537,7 @@ { 5, 0, 0, 0 }, { 1, 4, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -548,19 +549,19 @@ { 5, 0, 0, 0 }, { 5, 3, 5, 0 }, 5, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , { MONS_JELLY, 'J', LIGHTRED, "jelly", - M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS, + M_SEE_INVIS | M_SPLITS | M_AMPHIBIOUS | M_ACID_SPLASH, MR_RES_POISON | MR_RES_ASPHYX, 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, - MONUSE_EATS_ITEMS + MONUSE_EATS_ITEMS, SIZE_MEDIUM } , @@ -572,7 +573,7 @@ { 4, 0, 0, 0 }, { 1, 2, 3, 0 }, 2, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -584,7 +585,7 @@ { 15, 0, 0, 0 }, { 20, 2, 4, 0 }, 10, 10, 10, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -596,7 +597,7 @@ { 20, 0, 0, 0 }, { 3, 5, 3, 0 }, 3, 6, 6, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -608,7 +609,7 @@ { 19, 0, 0, 0 }, { 8, 3, 5, 0 }, 6, 14, 15, 7, MST_GUARDIAN_NAGA, CE_MUTAGEN_RANDOM, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -620,7 +621,7 @@ { 17, 0, 0, 0 }, { 5, 3, 5, 0 }, 1, 6, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_LARGE } , @@ -632,7 +633,7 @@ { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -644,7 +645,7 @@ { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -656,7 +657,7 @@ { 20, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 14, 10, 7, MST_RAKSHASA, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -668,7 +669,7 @@ { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 1, 15, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -680,7 +681,7 @@ { 20, 15, 15, 0 }, { 7, 3, 5, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -692,7 +693,7 @@ { 12, 0, 0, 0 }, { 7, 3, 5, 0 }, 5, 10, 30, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -704,7 +705,7 @@ { 22, 0, 0, 0 }, { 6, 3, 5, 0 }, 10, 10, 10, 7, MST_VAMPIRE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -716,7 +717,7 @@ { 13, 0, 0, 0 }, { 6, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -729,7 +730,7 @@ { 40, 0, 0, 0 }, { 11, 2, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -741,7 +742,7 @@ { 18, 0, 0, 0 }, { 7, 3, 5, 0 }, 4, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_BELLOW, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -754,7 +755,7 @@ { 23, 0, 0, 0 }, { 6, 3, 5, 0 }, 8, 5, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -766,7 +767,7 @@ { 20, 0, 0, 0 }, { 4, 4, 6, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -778,7 +779,7 @@ { 4, 0, 0, 0 }, { 4, 3, 5, 0 }, 2, 13, 10, 7, MST_KOBOLD_DEMONOLOGIST, CE_POISONOUS, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -790,7 +791,7 @@ { 5, 0, 0, 0 }, { 3, 3, 4, 0 }, 1, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -802,7 +803,7 @@ { 25, 0, 0, 0 }, { 9, 4, 7, 0 }, 2, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -817,7 +818,7 @@ { 0, 0, 0, 0 }, { 10, 5, 5, 0 }, 3, 3, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_HUGE } , ****************************************************************** */ @@ -830,7 +831,7 @@ { 20, 0, 0, 0 }, { 5, 3, 5, 0 }, 5, 10, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -842,7 +843,7 @@ { 7, 0, 0, 0 }, { 5, 3, 5, 0 }, 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -854,7 +855,7 @@ { 0, 0, 0, 0 }, { 3, 3, 5, 0 }, 0, 1, 3, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -866,7 +867,7 @@ { 8, 0, 0, 0 }, { 3, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -878,7 +879,7 @@ { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -890,7 +891,7 @@ { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, 3, 10, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -902,7 +903,7 @@ { 5, 0, 0, 0 }, { 3, 3, 5, 0 }, 12, 10, 10, 7, BLACK, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_SMALL } , @@ -914,7 +915,7 @@ { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, 0, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -926,7 +927,7 @@ { 0, 0, 0, 0 }, { 7, 3, 5, 0 }, 3, 1, 5, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -938,7 +939,7 @@ { 0, 0, 0, 0 }, { 1, 3, 5, 0 }, 0, 25, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -950,7 +951,7 @@ { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, 5, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -962,7 +963,7 @@ { 12, 0, 0, 0 }, { 7, 3, 5, 0 }, 10, 5, 10, 7, MST_EFREET, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LARGE } , @@ -974,7 +975,7 @@ { 0, 0, 0, 0 }, { 5, 3, 3, 0 }, 1, 5, 10, 7, MST_BRAIN_WORM, CE_POISONOUS, Z_SMALL, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -986,7 +987,7 @@ { 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, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_SMALL } , @@ -998,7 +999,7 @@ { 35, 0, 0, 0 }, { 9, 3, 5, 0 }, 20, 2, 3, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -1010,7 +1011,7 @@ { 7, 0, 0, 0 }, { 2, 3, 5, 0 }, 10, 17, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1022,7 +1023,7 @@ { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, 6, 13, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_BARK, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -1034,7 +1035,7 @@ { 35, 0, 0, 0 }, { 13, 3, 5, 0 }, 5, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_BELLOW, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1046,7 +1047,7 @@ { 17, 17, 17, 0 }, { 12, 5, 5, 0 }, 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -1058,7 +1059,7 @@ { 22, 0, 0, 0 }, { 11, 3, 5, 0 }, 1, 4, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -1070,7 +1071,7 @@ { 19, 0, 0, 0 }, { 8, 3, 5, 0 }, 12, 10, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1083,7 +1084,7 @@ { 0, 0, 0, 0 }, { 1, 0, 0, 1 }, 0, 30, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -1095,7 +1096,7 @@ { 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, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1107,7 +1108,7 @@ { 10, 0, 0, 0 }, { 7, 3, 5, 0 }, 5, 10, 13, 7, MST_BURNING_DEVIL, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1119,7 +1120,7 @@ { 8, 0, 0, 0 }, { 5, 3, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1131,7 +1132,7 @@ { 8, 8, 0, 0 }, { 7, 3, 5, 0 }, 12, 12, 13, 7, MST_TORMENTOR, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1143,7 +1144,7 @@ { 32, 0, 0, 0 }, { 8, 3, 5, 0 }, 15, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -1155,7 +1156,7 @@ { 25, 0, 0, 0 }, { 11, 3, 5, 0 }, 18, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1167,7 +1168,7 @@ { 9, 9, 0, 0 }, { 6, 3, 5, 0 }, 7, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_SMALL } , @@ -1179,7 +1180,7 @@ { 16, 0, 0, 0 }, { 11, 3, 5, 0 }, 12, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1191,7 +1192,7 @@ { 21, 0, 0, 0 }, { 7, 3, 5, 0 }, 14, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1204,7 +1205,7 @@ { 12, 0, 0, 0 }, { 5, 3, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1216,7 +1217,7 @@ { 14, 14, 0, 0 }, { 8, 3, 5, 0 }, 16, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREECH, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1228,7 +1229,7 @@ { 15, 0, 0, 0 }, { 10, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1240,7 +1241,7 @@ { 5, 0, 0, 0 }, { 7, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1252,7 +1253,7 @@ { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 1, 7, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1264,7 +1265,7 @@ { 12, 0, 0, 0 }, { 4, 5, 5, 0 }, 5, 10, 10, 7, MST_STEAM_DRAGON, CE_CLEAN, Z_BIG, S_SILENT, I_ANIMAL_LIKE, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -1276,7 +1277,7 @@ { 17, 0, 0, 0 }, { 12, 3, 5, 0 }, 4, 8, 8, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1288,7 +1289,7 @@ { 7, 0, 0, 0 }, { 8, 2, 3, 0 }, 5, 12, 10, 7, MST_ORC_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1300,7 +1301,7 @@ { 10, 8, 8, 0 }, { 7, 3, 5, 0 }, 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -1312,7 +1313,7 @@ { 18, 10, 10, 0 }, { 12, 3, 5, 0 }, 4, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -1324,7 +1325,7 @@ { 18, 0, 0, 0 }, { 13, 3, 5, 0 }, 0, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_REPTILE, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -1337,7 +1338,7 @@ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -1350,7 +1351,7 @@ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -1363,7 +1364,7 @@ { 13, 0, 0, 0 }, { 10, 3, 6, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1375,7 +1376,7 @@ { 6, 0, 0, 0 }, { 10, 2, 4, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1387,7 +1388,7 @@ { 6, 0, 0, 0 }, { 10, 2, 4, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1399,7 +1400,7 @@ { 6, 0, 0, 0 }, { 3, 3, 4, 0 }, 1, 10, 10, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1411,7 +1412,7 @@ { 7, 0, 0, 0 }, { 11, 3, 4, 0 }, 1, 12, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1428,7 +1429,7 @@ { 10, 0, 0, 0 }, { 1, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1440,7 +1441,7 @@ { 9, 0, 0, 0 }, { 2, 4, 5, 0 }, 2, 9, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1452,7 +1453,7 @@ { 11, 11, 0, 0 }, { 8, 7, 3, 0 }, 7, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1464,7 +1465,7 @@ { 10, 0, 0, 0 }, { 6, 6, 3, 0 }, 5, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1476,7 +1477,7 @@ { 28, 0, 0, 0 }, { 12, 7, 4, 0 }, 12, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1488,7 +1489,7 @@ { 35, 0, 0, 0 }, { 15, 7, 4, 0 }, 15, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1500,7 +1501,7 @@ { 40, 0, 0, 0 }, { 13, 7, 4, 0 }, 22, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1512,7 +1513,7 @@ { 13, 0, 0, 0 }, { 9, 5, 3, 0 }, 8, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1524,7 +1525,7 @@ { 15, 0, 0, 0 }, { 5, 3, 5, 0 }, 5, 10, 10, 7, MST_MOTTLED_DRAGON, CE_POISONOUS, Z_BIG, S_SILENT, I_ANIMAL_LIKE, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -1536,7 +1537,7 @@ { 40, 0, 0, 0 }, { 6, 5, 5, 0 }, 14, 4, 6, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -1548,7 +1549,7 @@ { 5, 0, 0, 0 }, { 6, 3, 5, 0 }, 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -1560,7 +1561,7 @@ { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 2, 18, 25, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -1574,7 +1575,7 @@ { 25, 25, 0, 0 }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_ICE_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1586,7 +1587,7 @@ { 25, 15, 15, 0 }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_SHADOW_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1598,7 +1599,7 @@ { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, 2, 15, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -1610,7 +1611,7 @@ { 20, 0, 0, 0 }, { 5, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -1622,7 +1623,7 @@ { 18, 0, 0, 0 }, { 9, 3, 5, 0 }, 12, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1634,7 +1635,7 @@ { 13, 0, 0, 0 }, { 10, 3, 5, 0 }, 2, 6, 5, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -1646,7 +1647,7 @@ { 25, 15, 15, 0 }, { 14, 5, 5, 0 }, 13, 10, 12, 7, MST_STORM_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -1658,7 +1659,7 @@ { 15, 0, 0, 0 }, { 8, 3, 5, 0 }, 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -1670,7 +1671,7 @@ { 30, 0, 0, 0 }, { 14, 3, 5, 0 }, 9, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_BELLOW, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -1682,7 +1683,7 @@ { 30, 20, 20, 0 }, { 11, 3, 5, 0 }, 13, 6, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -1694,7 +1695,7 @@ { 45, 0, 0, 0 }, { 16, 3, 5, 0 }, 12, 2, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_GIANT } , @@ -1706,7 +1707,7 @@ { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, 0, 14, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1718,7 +1719,7 @@ { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, 4, 15, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1730,7 +1731,7 @@ { 18, 0, 0, 0 }, { 6, 3, 5, 0 }, 2, 12, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1742,7 +1743,7 @@ { 12, 0, 0, 0 }, { 6, 1, 2, 0 }, 20, 20, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1754,7 +1755,7 @@ { 0, 0, 0, 0 }, { 12, 2, 3, 0 }, 0, 12, 10, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -1766,7 +1767,7 @@ { 12, 0, 0, 0 }, { 10, 3, 5, 0 }, 1, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LARGE } , @@ -1778,7 +1779,7 @@ { 32, 0, 0, 0 }, { 12, 3, 5, 0 }, 10, 6, 9, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -1804,7 +1805,7 @@ { 55, 0, 0, 0 }, { 20, 3, 5, 0 }, 10, 3, 10, 7, MST_TITAN, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -1816,7 +1817,7 @@ { 40, 20, 20, 0 }, { 18, 4, 4, 0 }, 15, 7, 10, 7, MST_GOLDEN_DRAGON, CE_POISONOUS, Z_BIG, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -1830,7 +1831,7 @@ { 10, 0, 0, 0 }, { 3, 3, 3, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -1846,7 +1847,7 @@ { 20, 10, 10, 0 }, { 9, 3, 5, 0 }, 8, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_ROAR, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_GIANT } , @@ -1858,7 +1859,7 @@ { 40, 0, 0, 0 }, { 20, 5, 3, 0 }, 2, 1, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -1870,7 +1871,7 @@ { 12, 0, 0, 0 }, { 4, 3, 5, 0 }, 4, 15, 17, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -1882,7 +1883,7 @@ { 5, 0, 0, 0 }, { 1, 3, 6, 0 }, 2, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1894,7 +1895,7 @@ { 10, 0, 0, 0 }, { 2, 3, 5, 0 }, 5, 11, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1906,7 +1907,7 @@ { 20, 0, 0, 0 }, { 3, 3, 5, 0 }, 7, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -1918,7 +1919,7 @@ { 20, 0, 0, 0 }, { 7, 3, 5, 0 }, 4, 15, 18, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -1930,7 +1931,7 @@ { 13, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BELLOW, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -1942,7 +1943,7 @@ { 9, 0, 0, 0 }, { 4, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -1954,7 +1955,7 @@ { 14, 0, 0, 0 }, { 6, 3, 5, 0 }, 2, 9, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -1966,7 +1967,7 @@ { 10, 0, 0, 0 }, { 1, 3, 5, 0 }, 0, 13, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_WHINE, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1978,7 +1979,7 @@ { 2, 0, 0, 0 }, { 2, 3, 3, 0 }, 2, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -1992,7 +1993,7 @@ { 35, 25, 25, 0 }, { 16, 3, 5, 0 }, 20, 4, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_ROAR, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2004,7 +2005,7 @@ { 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 + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -2016,7 +2017,7 @@ { 30, 0, 0, 0 }, { 16, 3, 6, 0 }, 8, 4, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_GIANT } , @@ -2028,7 +2029,7 @@ { 35, 0, 0, 0 }, { 16, 4, 5, 0 }, 9, 3, 10, 7, MST_FROST_GIANT, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_GIANT } , @@ -2052,7 +2053,7 @@ { 20, 15, 15, 0 }, { 17, 5, 5, 0 }, 15, 10, 10, 7, MST_SHADOW_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , { @@ -2063,7 +2064,7 @@ { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 4, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -2075,7 +2076,7 @@ { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, 4, 16, 18, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -2087,7 +2088,7 @@ { 27, 20, 20, 0 }, { 10, 3, 5, 0 }, 6, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -2099,7 +2100,7 @@ { 13, 0, 0, 0 }, { 5, 3, 5, 0 }, 2, 15, 19, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -2111,7 +2112,7 @@ { 23, 0, 0, 0 }, { 8, 3, 5, 0 }, 7, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_BUZZ, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -2123,7 +2124,7 @@ { 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 + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -2135,7 +2136,7 @@ { 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 + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -2147,7 +2148,7 @@ { 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 + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -2159,7 +2160,7 @@ { 14, 0, 0, 0 }, { 6, 3, 5, 0 }, 8, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -2171,7 +2172,7 @@ { 30, 0, 0, 0 }, { 11, 3, 5, 0 }, 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -2183,7 +2184,7 @@ { 20, 0, 0, 0 }, { 13, 3, 5, 0 }, 14, 3, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -2195,7 +2196,7 @@ { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 2, 6, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -2208,7 +2209,7 @@ { 9, 0, 0, 0 }, { 4, 3, 5, 0 }, 0, 12, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -2220,7 +2221,7 @@ { 14, 0, 0, 0 }, { 8, 3, 5, 0 }, 2, 11, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_CROAK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -2232,7 +2233,7 @@ { 26, 0, 0, 0 }, { 7, 3, 5, 0 }, 6, 9, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_CROAK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -2244,7 +2245,7 @@ { 20, 0, 0, 0 }, { 6, 3, 5, 0 }, 3, 12, 14, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , { @@ -2255,7 +2256,7 @@ { 2, 0, 0, 0 }, { 1, 3, 4, 0 }, 3, 10, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , { @@ -2266,7 +2267,7 @@ { 2, 0, 0, 0 }, { 1, 2, 3, 0 }, 0, 11, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -2278,7 +2279,7 @@ { 4, 0, 0, 0 }, { 2, 3, 5, 0 }, 4, 10, 10, 7, MST_WHITE_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LITTLE } , @@ -2290,7 +2291,7 @@ { 12, 0, 0, 0 }, { 2, 3, 5, 0 }, 1, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_SMALL } , @@ -2302,7 +2303,7 @@ { 5, 5, 0, 0 }, { 1, 4, 6, 0 }, 2, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2314,7 +2315,7 @@ { 5, 3, 3, 0 }, { 3, 3, 5, 0 }, 2, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_SMALL } , @@ -2326,7 +2327,7 @@ { 8, 0, 0, 0 }, { 2, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -2338,7 +2339,7 @@ { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 4, 12, 10, 7, MST_NEQOXEC, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2350,7 +2351,7 @@ { 10, 5, 0, 0 }, { 8, 4, 5, 0 }, 3, 7, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SCREECH, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -2362,7 +2363,7 @@ { 17, 10, 0, 0 }, { 7, 4, 5, 0 }, 8, 10, 10, 7, MST_HELLWING, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2374,7 +2375,7 @@ { 8, 5, 5, 0 }, { 7, 3, 5, 0 }, 5, 9, 9, 7, MST_SMOKE_DEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -2386,7 +2387,7 @@ { 12, 0, 0, 0 }, { 6, 3, 5, 0 }, 3, 10, 10, 7, MST_YNOXINUL, CE_CONTAMINATED, Z_NOZOMBIE, S_BELLOW, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2398,7 +2399,7 @@ { 30, 10, 10, 0 }, { 12, 3, 5, 0 }, 10, 15, 20, 7, MST_HELL_KNIGHT_I, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2410,7 +2411,7 @@ { 32, 0, 0, 0 }, { 13, 3, 5, 0 }, 5, 7, 12, 7, MST_GREEN_DEATH, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2422,7 +2423,7 @@ { 20, 20, 0, 0 }, { 12, 3, 5, 0 }, 10, 10, 12, 7, MST_BLUE_DEATH, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2434,7 +2435,7 @@ { 25, 0, 0, 0 }, { 14, 3, 5, 0 }, 5, 12, 12, 7, MST_BALRUG, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -2446,7 +2447,7 @@ { 22, 0, 0, 0 }, { 13, 3, 5, 0 }, 11, 10, 10, 7, MST_CACODEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2459,7 +2460,7 @@ { 13, 13, 13, 13 }, { 9, 3, 5, 0 }, 10, 6, 9, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -2471,7 +2472,7 @@ { 30, 0, 0, 0 }, { 10, 3, 5, 0 }, 10, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2483,7 +2484,7 @@ { 6, 0, 0, 0 }, { 2, 3, 5, 0 }, 3, 11, 10, 7, MST_SHADOW_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LITTLE } , @@ -2495,7 +2496,7 @@ { 21, 0, 0, 0 }, { 6, 3, 5, 0 }, 7, 12, 11, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_CROAK, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_SMALL } , @@ -2507,7 +2508,7 @@ { 25, 25, 0, 0 }, { 12, 3, 5, 0 }, 10, 12, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2519,7 +2520,7 @@ { 20, 0, 0, 0 }, { 10, 3, 5, 0 }, 7, 7, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2531,7 +2532,7 @@ { 25, 0, 0, 0 }, { 12, 3, 5, 0 }, 0, 4, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -2543,7 +2544,7 @@ { 23, 0, 0, 0 }, { 10, 5, 3, 0 }, 0, 2, 6, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -2555,7 +2556,7 @@ { 18, 0, 0, 0 }, { 14, 5, 3, 0 }, 7, 2, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -2567,7 +2568,7 @@ { 50, 0, 0, 0 }, { 6, 6, 6, 0 }, 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -2579,7 +2580,7 @@ { 28, 21, 21, 0 }, { 19, 4, 5, 0 }, 17, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2591,7 +2592,7 @@ { 26, 0, 0, 0 }, { 8, 3, 5, 0 }, 13, 4, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -2603,7 +2604,7 @@ { 10, 6, 6, 0 }, { 4, 3, 5, 0 }, 18, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2616,7 +2617,7 @@ { 19, 10, 10, 0 }, { 8, 3, 5, 0 }, 20, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2629,7 +2630,7 @@ { 12, 8, 8, 0 }, { 5, 3, 5, 0 }, 14, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -2645,7 +2646,7 @@ { 23, 23, 0, 0 }, { 17, 0, 0, 199 }, 10, 13, 13, 7, MST_MNOLEG, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2657,7 +2658,7 @@ { 40, 0, 0, 0 }, { 19, 0, 0, 223 }, 10, 7, 8, 7, MST_LOM_LOBON, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2669,7 +2670,7 @@ { 50, 0, 0, 0 }, { 21, 0, 0, 253 }, 15, 8, 10, 7, MST_CEREBOV, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_GIANT } , @@ -2681,7 +2682,7 @@ { 20, 0, 0, 0 }, { 16, 0, 0, 234 }, 10, 10, 10, 7, MST_GLOORX_VLOQ, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -2700,7 +2701,7 @@ { 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 + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -2712,7 +2713,7 @@ { 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 + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -2724,7 +2725,7 @@ { 32, 0, 0, 0 }, { 15, 4, 7, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2736,7 +2737,7 @@ { 6, 0, 0, 0 }, { 3, 3, 3, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2748,7 +2749,7 @@ { 9, 0, 0, 0 }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2760,7 +2761,7 @@ { 14, 0, 0, 0 }, { 11, 3, 3, 0 }, 0, 15, 11, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2772,7 +2773,7 @@ { 5, 0, 0, 0 }, { 4, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2784,7 +2785,7 @@ { 5, 0, 0, 0 }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_SUMMONER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2796,7 +2797,7 @@ { 5, 0, 0, 0 }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2808,7 +2809,7 @@ { 9, 0, 0, 0 }, { 5, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2820,7 +2821,7 @@ { 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, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2832,7 +2833,7 @@ { 12, 0, 0, 0 }, { 12, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_DEMONOLOGIST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2844,7 +2845,7 @@ { 12, 0, 0, 0 }, { 15, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2856,7 +2857,7 @@ { 12, 0, 0, 0 }, { 14, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2868,19 +2869,19 @@ { 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, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , { MONS_BROWN_OOZE, 'J', BROWN, "brown ooze", - M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS | M_ACID_SPLASH, MR_RES_POISON | MR_RES_ASPHYX, 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, - MONUSE_EATS_ITEMS + MONUSE_EATS_ITEMS, SIZE_LITTLE } , @@ -2892,7 +2893,7 @@ { 12, 12, 12, 12 }, { 15, 3, 5, 0 }, 5, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_EATS_ITEMS + MONUSE_EATS_ITEMS, SIZE_LITTLE } , @@ -2904,31 +2905,31 @@ { 32, 32, 0, 0 }, { 11, 3, 3, 0 }, 2, 4, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_EATS_ITEMS + MONUSE_EATS_ITEMS, SIZE_LITTLE } , { MONS_ACID_BLOB, 'J', LIGHTGREEN, "acid blob", - M_NO_SKELETON | M_SEE_INVIS | M_SPECIAL_ABILITY, + M_NO_SKELETON | M_SEE_INVIS | M_SPECIAL_ABILITY | M_ACID_SPLASH, MR_RES_POISON | MR_RES_ASPHYX, 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, - MONUSE_EATS_ITEMS + MONUSE_EATS_ITEMS, SIZE_LITTLE } , { MONS_ROYAL_JELLY, 'J', YELLOW, "royal jelly", - M_NO_SKELETON | M_SEE_INVIS, + M_NO_SKELETON | M_SEE_INVIS | M_ACID_SPLASH, MR_RES_POISON | MR_RES_ASPHYX, 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, - MONUSE_EATS_ITEMS + MONUSE_EATS_ITEMS, SIZE_SMALL } , @@ -2940,7 +2941,7 @@ { 3, 0, 0, 0 }, { 1, 0, 0, 14 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2952,7 +2953,7 @@ { 4, 0, 0, 0 }, { 1, 0, 0, 10 }, 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2964,7 +2965,7 @@ { 4, 0, 0, 0 }, { 3, 0, 0, 28 }, 2, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_SMALL } , @@ -2976,7 +2977,7 @@ { 5, 0, 0, 0 }, { 3, 0, 0, 25 }, 0, 11, 10, 7, MST_ORC_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -2988,7 +2989,7 @@ { 7, 0, 0, 0 }, { 3, 0, 0, 32 }, 0, 9, 8, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3000,7 +3001,7 @@ { 6, 0, 0, 0 }, { 4, 0, 0, 27 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3012,7 +3013,7 @@ { 7, 0, 0, 0 }, { 5, 0, 0, 24 }, 0, 12, 13, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3025,7 +3026,7 @@ { 20, 0, 0, 0 }, { 6, 0, 0, 45 }, 3, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LARGE } , @@ -3037,7 +3038,7 @@ { 8, 0, 0, 0 }, { 5, 0, 0, 33 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3049,7 +3050,7 @@ { 12, 0, 0, 0 }, { 6, 0, 0, 38 }, 0, 11, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3061,7 +3062,7 @@ { 9, 0, 0, 0 }, { 6, 0, 0, 36 }, 0, 10, 10, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3073,7 +3074,7 @@ { 9, 0, 0, 0 }, { 7, 0, 0, 42 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3085,7 +3086,7 @@ { 20, 15, 15, 0 }, { 8, 0, 0, 45 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -3097,7 +3098,7 @@ { 10, 0, 0, 0 }, { 9, 0, 0, 43 }, 0, 11, 11, 7, MST_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3109,7 +3110,7 @@ { 11, 0, 0, 0 }, { 9, 0, 0, 47 }, 0, 10, 10, 7, MST_NECROMANCER_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3121,7 +3122,7 @@ { 12, 0, 0, 0 }, { 9, 0, 0, 51 }, 0, 8, 10, 7, MST_HELL_KNIGHT_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3133,7 +3134,7 @@ { 14, 0, 0, 0 }, { 10, 0, 0, 53 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3145,7 +3146,7 @@ { 14, 0, 0, 0 }, { 11, 0, 0, 60 }, 0, 9, 10, 7, MST_GUARDIAN_NAGA, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3157,7 +3158,7 @@ { 11, 0, 0, 0 }, { 11, 0, 0, 64 }, 0, 10, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3169,7 +3170,7 @@ { 14, 0, 0, 0 }, { 13, 0, 0, 55 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3181,7 +3182,7 @@ { 12, 0, 0, 0 }, { 13, 0, 0, 52 }, 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3194,7 +3195,7 @@ { 12, 0, 0, 0 }, { 14, 0, 0, 67 }, 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3207,7 +3208,7 @@ { 11, 0, 0, 0 }, { 14, 0, 0, 70 }, 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3220,7 +3221,7 @@ { 13, 0, 0, 0 }, { 16, 0, 0, 80 }, 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3233,7 +3234,7 @@ { 14, 0, 0, 0 }, { 17, 0, 0, 78 }, 1, 10, 7, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3246,7 +3247,7 @@ { 14, 0, 0, 0 }, { 18, 0, 0, 83 }, 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3258,7 +3259,7 @@ { 29, 17, 17, 0 }, { 19, 0, 0, 133 }, 15, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -3271,7 +3272,7 @@ { 16, 0, 0, 0 }, { 20, 0, 0, 95 }, 1, 9, 9, 7, MST_MYSTIC, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3284,7 +3285,7 @@ { 17, 0, 0, 0 }, { 21, 0, 0, 105 }, 0, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3297,7 +3298,7 @@ { 18, 0, 0, 0 }, { 22, 0, 0, 119 }, 0, 10, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3310,7 +3311,7 @@ { 15, 0, 0, 0 }, { 22, 0, 0, 99 }, 12, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3323,7 +3324,7 @@ { 30, 0, 0, 0 }, { 15, 0, 0, 240 }, 15, 6, 10, 7, MST_GERYON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_GIANT } , @@ -3335,7 +3336,7 @@ { 15, 0, 0, 0 }, { 16, 0, 0, 222 }, 15, 3, 6, 7, MST_DISPATER, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LARGE } , @@ -3347,7 +3348,7 @@ { 20, 0, 0, 0 }, { 17, 0, 0, 245 }, 12, 7, 9, 7, MST_ASMODEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LARGE } , @@ -3360,7 +3361,7 @@ { 30, 0, 0, 0 }, { 22, 0, 0, 250 }, 10, 4, 7, 7, MST_ANTAEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_GIANT } , @@ -3372,7 +3373,7 @@ { 20, 0, 0, 0 }, { 18, 0, 0, 238 }, 15, 6, 9, 7, MST_ERESHKIGAL, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LARGE } , @@ -3384,7 +3385,7 @@ { 20, 0, 0, 0 }, { 27, 2, 4, 0 }, 20, 10, 12, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , /* number is set in define_monster */ @@ -3397,7 +3398,7 @@ { 5, 0, 0, 0 }, { 3, 3, 5, 0 }, 1, 3, 8, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -3409,7 +3410,7 @@ { 20, 0, 0, 0 }, { 13, 3, 5, 0 }, 1, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3423,7 +3424,7 @@ { 0, 0, 0, 0 }, { 13, 0, 0, 66 }, 40, 3, 10, 7, MST_CURSE_SKULL, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -3435,7 +3436,7 @@ { 33, 0, 0, 0 }, { 11, 3, 7, 0 }, 10, 10, 10, 7, MST_VAMPIRE_KNIGHT, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3447,7 +3448,7 @@ { 22, 0, 0, 0 }, { 8, 3, 4, 0 }, 10, 10, 10, 7, MST_VAMPIRE_MAGE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3459,7 +3460,7 @@ { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 3, 1, 7, 7, MST_SHINING_EYE, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -3471,7 +3472,7 @@ { 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 + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -3483,7 +3484,7 @@ { 25, 10, 10, 0 }, { 14, 6, 5, 0 }, 10, 13, 10, 7, MST_DAEVA, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3496,7 +3497,7 @@ { 20, 0, 0, 0 }, { 8, 3, 5, 0 }, 8, 5, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -3508,7 +3509,7 @@ { 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 + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -3520,7 +3521,7 @@ { 30, 20, 20, 0 }, { 20, 8, 8, 0 }, 20, 4, 8, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -3532,7 +3533,7 @@ { 22, 17, 13, 19 }, { 25, 3, 5, 0 }, 5, 5, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -3544,7 +3545,7 @@ { 25, 12, 12, 0 }, { 16, 3, 5, 0 }, 5, 5, 13, 7, MST_SPHINX, CE_CLEAN, Z_NOZOMBIE, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -3556,7 +3557,7 @@ { 25, 0, 0, 0 }, { 10, 3, 5, 0 }, 5, 7, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -3568,7 +3569,7 @@ { 30, 0, 0, 0 }, { 7, 5, 3, 0 }, 6, 9, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -3580,7 +3581,7 @@ { 35, 0, 0, 0 }, { 15, 5, 3, 100 }, 10, 6, 10, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3592,7 +3593,7 @@ { 30, 0, 0, 0 }, { 10, 5, 3, 0 }, 8, 7, 9, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3604,7 +3605,7 @@ { 16, 0, 0, 0 }, { 9, 3, 5, 0 }, 4, 8, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_BIG } , @@ -3616,7 +3617,7 @@ { 23, 0, 0, 0 }, { 14, 3, 5, 0 }, 5, 5, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -3630,7 +3631,7 @@ { 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 + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3642,7 +3643,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3654,7 +3655,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3666,7 +3667,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 14, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3678,7 +3679,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3690,7 +3691,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 8, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3702,7 +3703,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3714,7 +3715,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3726,7 +3727,7 @@ { 20, 0, 0, 0 }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3738,7 +3739,7 @@ { 20, 0, 0, 0 }, { 16, 4, 3, 0 }, 9, 10, 10, 10, MST_DRAC_CALLER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3750,7 +3751,7 @@ { 35, 20, 15, 0 }, { 16, 6, 3, 0 }, 6, 20, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3762,7 +3763,7 @@ { 15, 0, 0, 0 }, { 16, 4, 2, 0 }, 12, 10, 10, 10, MST_DEEP_ELF_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3774,7 +3775,7 @@ { 15, 0, 0, 0 }, { 16, 4, 4, 0 }, 8, 16, 10, 10, MST_DRAC_SHIFTER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3786,7 +3787,7 @@ { 15, 0, 0, 0 }, { 16, 4, 2, 0 }, 8, 10, 10, 10, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3798,7 +3799,7 @@ { 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 + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3810,7 +3811,7 @@ { 15, 0, 0, 0 }, { 16, 4, 2, 0 }, 8, 12, 10, 10, MST_DRAC_SCORCHER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_STARTING_EQUIPMENT + MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM } , @@ -3822,7 +3823,7 @@ { 30, 0, 0, 0 }, { 20, 5, 5, 0 }, 10, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -3834,7 +3835,7 @@ { 12, 12, 12, 12 }, { 15, 7, 4, 0 }, 5, 20, 20, 7, MST_ELECTRIC_GOLEM, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -3846,7 +3847,7 @@ { 5, 0, 0, 0 }, { 12, 0, 0, 1 }, 0, 10, 20, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LITTLE } , @@ -3858,7 +3859,7 @@ { 0, 0, 0, 0 }, { 30, 0, 0, 150 }, 20, 20, 20, 7, MST_ORB_OF_FIRE, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LITTLE } , @@ -3870,7 +3871,7 @@ { 5, 0, 0, 0 }, { 1, 3, 5, 0 }, 2, 13, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -3882,7 +3883,7 @@ { 0, 0, 0, 0 }, { 10, 3, 5, 0 }, 12, 1, 7, 7, MST_EYE_OF_DEVASTATION, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -3894,7 +3895,7 @@ { 25, 0, 0, 0 }, { 9, 3, 5, 0 }, 0, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -3906,7 +3907,7 @@ { 20, 0, 0, 0 }, { 10, 4, 5, 0 }, 10, 15, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_MOAN, I_NORMAL, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_TINY } , @@ -3918,7 +3919,7 @@ { 0, 0, 0, 0 }, { 14, 0, 0, 77 }, 50, 1, 12, 7, MST_CURSE_TOE, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -3931,7 +3932,7 @@ { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -3943,7 +3944,7 @@ { 17, 17, 17, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -3955,7 +3956,7 @@ { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 15, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -3967,7 +3968,7 @@ { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -3979,7 +3980,7 @@ { 12, 12, 12, 0 }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -3991,7 +3992,7 @@ { 20, 0, 0, 0 }, { 11, 3, 5, 0 }, 2, 9, 14, 7, MST_HELL_HOG, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -4003,7 +4004,7 @@ { 35, 15, 15, 0 }, { 20, 4, 4, 0 }, 12, 9, 14, 7, MST_SERPENT_OF_HELL, CE_CLEAN, Z_NOZOMBIE, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -4015,7 +4016,7 @@ { 5, 0, 0, 0 }, { 2, 3, 5, 0 }, 0, 12, 12, 7, MST_BOGGART, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_LITTLE } , @@ -4027,7 +4028,7 @@ { 45, 0, 0, 0 }, { 16, 3, 5, 0 }, 10, 15, 15, 7, MST_QUICKSILVER_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_GIANT } , @@ -4039,7 +4040,7 @@ { 25, 25, 25, 0 }, { 18, 5, 3, 0 }, 20, 6, 8, 7, MST_IRON_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_HUGE } , @@ -4051,7 +4052,7 @@ { 25, 0, 0, 0 }, { 10, 5, 3, 0 }, 15, 10, 10, 7, MST_SKELETAL_WARRIOR, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_NORMAL, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -4065,7 +4066,7 @@ { 5, 0, 0, 0 }, { 4, 2, 3, 0 }, 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_MEDIUM } , @@ -4078,7 +4079,7 @@ { 5, 0, 0, 0 }, { 4, 2, 3, 0 }, 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_HIGH, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_LARGE } , @@ -4091,7 +4092,7 @@ { 15, 0, 0, 0 }, { 6, 3, 5, 0 }, 1, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -4103,7 +4104,7 @@ { 10, 0, 0, 0 }, { 4, 3, 5, 0 }, 4, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -4115,7 +4116,7 @@ { 7, 0, 0, 0 }, { 3, 3, 5, 0 }, 2, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_HISS, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -4127,7 +4128,7 @@ { 23, 0, 0, 0 }, { 14, 3, 5, 0 }, 5, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_HIGH, - MONUSE_WEAPONS_ARMOUR + MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM } , @@ -4142,7 +4143,7 @@ { 8, 0, 0, 0 }, { 4, 3, 5, 0 }, 1, 12, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -4154,7 +4155,7 @@ { 15, 0, 0, 0 }, { 7, 3, 5, 0 }, 5, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -4166,7 +4167,7 @@ { 0, 0, 0, 0 }, { 3, 3, 5, 0 }, 1, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -4178,7 +4179,7 @@ { 1, 1, 0, 0 }, { 4, 3, 5, 0 }, 0, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -4190,7 +4191,7 @@ { 25, 0, 0, 0 }, { 6, 5, 3, 0 }, 0, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_OPEN_DOORS + MONUSE_OPEN_DOORS, SIZE_BIG } , @@ -4202,35 +4203,10 @@ { 20, 0, 0, 0 }, { 5, 5, 5, 0 }, 3, 12, 12, 0, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE }, // end water monsters {dlb} -/* ************************************************************************ -Josh added the following, but they just won't work in the game just yet ... -besides, four bear types !?!?! isn't that a *bit* excessive given the -limited diversity of existing monster types? - -I'm still far from happy about the inclusion of "Shuggoths" -- I just do -not think it fits into Crawl ... {dlb} -************************************************************************ */ - //jmf: it's never created anywhere yet, so you can save the punctuation. - // as to bears & wolves: the lair needs more variety. - -#if 0 -{ - 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, 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, - MONUSE_NOTHING -} -, -#endif - { MONS_WOLF, 'h', LIGHTGREY, "wolf", M_WARM_BLOOD | M_SEE_INVIS, //jmf: until smell exists @@ -4239,7 +4215,7 @@ not think it fits into Crawl ... {dlb} { 8, 2, 2, 0 }, { 4, 3, 5, 0 }, 3, 15, 17, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -4251,7 +4227,7 @@ not think it fits into Crawl ... {dlb} { 12, 3, 3, 0 }, { 4, 4, 5, 0 }, 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -4263,7 +4239,7 @@ not think it fits into Crawl ... {dlb} { 10, 6, 6, 0 }, { 7, 3, 3, 0 }, 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -4275,7 +4251,7 @@ not think it fits into Crawl ... {dlb} { 12, 8, 8, 0 }, { 7, 4, 4, 0 }, 5, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -4287,7 +4263,7 @@ not think it fits into Crawl ... {dlb} { 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, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_BIG } , @@ -4299,7 +4275,7 @@ not think it fits into Crawl ... {dlb} { 4, 4, 4, 0 }, { 6, 3, 3, 0 }, 2, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_GROWL, I_ANIMAL, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -4312,7 +4288,7 @@ not think it fits into Crawl ... {dlb} { 6, 0, 0, 0 }, { 2, 3, 5, 0 }, 10, 4, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_SMALL } , @@ -4325,7 +4301,7 @@ not think it fits into Crawl ... {dlb} { 14, 0, 0, 0 }, { 5, 3, 5, 0 }, 10, 5, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -4337,7 +4313,7 @@ not think it fits into Crawl ... {dlb} { 3, 0, 0, 0 }, { 1, 1, 2, 0 }, 0, 15, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -4349,7 +4325,7 @@ not think it fits into Crawl ... {dlb} { 5, 0, 0, 0 }, { 1, 3, 5, 0 }, 1, 14, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_TINY } , @@ -4361,7 +4337,7 @@ not think it fits into Crawl ... {dlb} { 15, 0, 0, 0 }, { 3, 3, 5, 0 }, 5, 9, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -4374,7 +4350,7 @@ not think it fits into Crawl ... {dlb} { 20, 0, 0, 0 }, { 5, 4, 4, 0 }, 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LITTLE } , @@ -4386,7 +4362,7 @@ not think it fits into Crawl ... {dlb} { 30, 0, 0, 0 }, { 8, 3, 5, 0 }, 7, 8, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_HISS, I_REPTILE, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_MEDIUM } , @@ -4398,7 +4374,7 @@ not think it fits into Crawl ... {dlb} { 0, 0, 0, 0 }, { 12, 0, 0, 160 }, 30, 1, 6, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , @@ -4410,7 +4386,7 @@ not think it fits into Crawl ... {dlb} { 0, 0, 0, 0 }, { 12, 0, 0, 150 }, 30, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, - MONUSE_NOTHING + MONUSE_NOTHING, SIZE_LARGE } , diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index b0733fe0c9..7dc536835a 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -31,6 +31,7 @@ #include "debug.h" #include "itemname.h" #include "itemprop.h" +#include "misc.h" #include "monplace.h" #include "mstuff2.h" #include "player.h" @@ -635,7 +636,6 @@ bool check_mons_resist_magic( const monsters *monster, int pow ) return ((mrch2 < mrchance) ? true : false); } // end check_mons_resist_magic() - int mons_res_elec( const monsters *mon ) { int mc = mon->type; @@ -712,7 +712,6 @@ int mons_res_poison( const monsters *mon ) return (u); } // end mons_res_poison() - int mons_res_fire( const monsters *mon ) { int mc = mon->type; @@ -1642,47 +1641,14 @@ int mons_offhand_weapon_index(const monsters *m) return (m->inv[1]); } -int mons_weapon_index(const monsters *m) -{ - // This randomly picks one of the wielded weapons for monsters that can use - // two weapons. Not ideal, but better than nothing. fight.cc does it right, - // for various values of right. - int weap = m->inv[MSLOT_WEAPON]; - - if (mons_wields_two_weapons(m)) - { - const int offhand = mons_offhand_weapon_index(m); - if (offhand != NON_ITEM && (weap == NON_ITEM || coinflip())) - weap = offhand; - } - - return (weap); -} - int mons_base_damage_type(const monsters *m) { return (mons_class_flag(m->type, M_CLAWS)? DVORP_CLAWING : DVORP_CRUSHING); } -int mons_damage_type(const monsters *m) +int mons_size(const monsters *m) { - const int mweap = mons_weapon_index(m); - - if (mweap == NON_ITEM) - return (mons_base_damage_type(m)); - - return (get_vorpal_type(mitm[mweap])); -} - -int mons_damage_brand(const monsters *m) -{ - const int mweap = mons_weapon_index(m); - - if (mweap == NON_ITEM) - return (SPWPN_NORMAL); - - const item_def &weap = mitm[mweap]; - return (!is_range_weapon(weap)? get_weapon_brand(weap) : SPWPN_NORMAL); + return m->body_size(); } bool mons_friendly(const monsters *m) @@ -2500,3 +2466,125 @@ bool monster_senior(const monsters *m1, const monsters *m2) return (mchar1 == mchar2 && m1->hit_dice > m2->hit_dice); } + + +/////////////////////////////////////////////////////////////////////////////// +// monsters methods + +coord_def monsters::pos() const +{ + return coord_def(x, y); +} + +bool monsters::swimming() const +{ + const int grid = grd[x][y]; + return (grid_is_watery(grid) && monster_habitat(type) == DNGN_DEEP_WATER); +} + +bool monsters::floundering() const +{ + const int grid = grd[x][y]; + return (grid_is_water(grid) + // Can't use monster_habitable_grid because that'll return true + // for non-water monsters in shallow water. + && monster_habitat(type) != DNGN_DEEP_WATER + && !mons_class_flag(type, M_AMPHIBIOUS) + && !mons_flies(this)); +} + +size_type monsters::body_size(int /* psize */, bool /* base */) const +{ + const monsterentry *e = seekmonster(type); + return (e? e->size : SIZE_MEDIUM); +} + +int monsters::damage_type(int which_attack) +{ + const item_def *mweap = weapon(which_attack); + + if (!mweap) + return (mons_base_damage_type(this)); + + return (get_vorpal_type(*mweap)); +} + +int monsters::damage_brand(int which_attack) +{ + const item_def *mweap = weapon(which_attack); + + if (!mweap) + return (SPWPN_NORMAL); + + return (!is_range_weapon(*mweap)? get_weapon_brand(*mweap) : SPWPN_NORMAL); +} + +item_def *monsters::weapon(int which_attack) +{ + if (which_attack > 1) + which_attack &= 1; + + // This randomly picks one of the wielded weapons for monsters that can use + // two weapons. Not ideal, but better than nothing. fight.cc does it right, + // for various values of right. + int weap = inv[MSLOT_WEAPON]; + + if (which_attack && mons_wields_two_weapons(this)) + { + const int offhand = mons_offhand_weapon_index(this); + if (offhand != NON_ITEM + && (weap == NON_ITEM || which_attack == 1 || coinflip())) + { + weap = offhand; + } + } + + return (weap == NON_ITEM? NULL : &mitm[weap]); +} + +item_def *monsters::shield() +{ + return (NULL); +} + +std::string monsters::name(description_level_type desc) const +{ + return (ptr_monam(this, desc)); +} + +std::string monsters::conj_verb(const std::string &verb) const +{ + return (verb + "s"); +} + +int monsters::id() const +{ + return (type); +} + +bool monsters::fumbles_attack(bool verbose) +{ + if (floundering() && one_chance_in(4)) + { + if (verbose && !silenced(you.x_pos, you.y_pos) + && !silenced(x, y)) + { + mprf(MSGCH_SOUND, "You hear a splashing noise."); + } + } + return (false); +} + +bool monsters::cannot_fight() const +{ + return mons_class_flag(type, M_NO_EXP_GAIN) + || mons_is_statue(type); +} + +void monsters::attacking(actor * /* other */) +{ +} + +void monsters::go_berserk(bool /* intentional */) +{ +} diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index e7584b97df..01d1419df6 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -111,6 +111,8 @@ struct monsterentry char intel; // 0=none, 1=worst...4=best char gmon_use; + + size_type size; }; // mondata[] - again, no idea why this was externed {dlb} @@ -229,8 +231,6 @@ bool mons_is_demon( int mc ); bool mons_is_humanoid( int mc ); bool mons_wields_two_weapons(const monsters *m); -int mons_damage_type(const monsters *m); -int mons_damage_brand(const monsters *m); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index e7eb5e0116..565e5200aa 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -100,13 +100,7 @@ bool monster_habitable_grid(int monster_class, int actual_grid, bool flies) // extra damage from water-natives. bool monster_floundering(const monsters *m) { - const int grid = grd[m->x][m->y]; - return ((grid == DNGN_DEEP_WATER || grid == DNGN_SHALLOW_WATER) - // Can't use monster_habitable_grid because that'll return true - // for non-water monsters in shallow water. - && monster_habitat(m->type) != DNGN_DEEP_WATER - && !mons_class_flag(m->type, M_AMPHIBIOUS) - && !mons_flies(m)); + return (m->floundering()); } // Returns true if the monster can submerge in the given grid diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index d0f2095504..c70898a1c3 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1770,6 +1770,16 @@ static void handle_behaviour(struct monsters *mon) } } // end handle_behaviour() +std::string str_simple_monster_message(monsters *mons, const char *event) +{ + if (mons_near(mons) && player_monster_visible(mons)) + return make_stringf("%s%s", + ptr_monam(mons, DESC_CAP_THE), + event ); + + return (""); +} + // note that this function *completely* blocks messaging for monsters // distant or invisible to the player ... look elsewhere for a function // permitting output of "It" messages for the invisible {dlb} diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index 333abfdfd8..408ce8023f 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -88,6 +88,7 @@ bool random_near_space( int ox, int oy, int &tx, int &ty, bool simple_monster_message(struct monsters *monster, const char *event, int channel = MSGCH_PLAIN, int param = 0); +std::string str_simple_monster_message(monsters *mons, const char *event); /* *********************************************************************** * called from: acr diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index dea3890397..bb27354858 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -35,11 +35,13 @@ #include "clua.h" #include "delay.h" #include "fight.h" +#include "food.h" #include "itemname.h" #include "itemprop.h" #include "items.h" #include "macro.h" #include "misc.h" +#include "monstuff.h" #include "mon-util.h" #include "mutation.h" #include "notes.h" @@ -57,39 +59,12 @@ #include "tutorial.h" #include "view.h" -///////////////////////////////////////////////////////////////////////////// -// Actor stuff - generic functions that can be called with a monster pointer, -// or NULL for the player. - std::string pronoun_you(description_level_type desc) { return (desc == DESC_CAP_A || desc == DESC_CAP_THE? "You" : "you"); } -std::string actor_name(const monsters *actor, description_level_type desc) -{ - return (actor? ptr_monam(actor, desc) : pronoun_you(desc)); -} - -// actor_verb(NULL, "chop") == chop, as in "You chop" -// actor_verb(monster, "chop") == chops, as in "The skeletal warrior chops". -std::string actor_verb(const monsters *actor, const std::string &verb) -{ - // Simplistic - we really should be conjugating the verb - // appropriately. We'll special-case as necessary. - return (actor? verb + "s" : verb); -} - -int actor_damage_type(const monsters *actor) -{ - return (actor? mons_damage_type(actor) : player_damage_type()); -} - -int actor_damage_brand(const monsters *actor) -{ - return (actor? mons_damage_brand(actor) : player_damage_brand()); -} - +////////////////////////////////////////////////////////////////////////// /* you.duration []: //jmf: obsolete, see enum.h instead //[ds] Well, can we lose it yet? @@ -331,7 +306,7 @@ bool move_player_to_grid( int x, int y, bool stepped, bool allow_shift, bool player_can_swim() { - return (you.species == SP_MERFOLK); + return you.can_swim(); } bool is_grid_dangerous(int grid) @@ -362,13 +337,17 @@ bool player_in_hell( void ) bool player_in_water(void) { return (!player_is_levitating() - && (grd[you.x_pos][you.y_pos] == DNGN_DEEP_WATER - || grd[you.x_pos][you.y_pos] == DNGN_SHALLOW_WATER)); + && grid_is_water(grd[you.x_pos][you.y_pos])); } bool player_is_swimming(void) { - return (player_in_water() && player_can_swim()); + return you.swimming(); +} + +bool player_floundering() +{ + return (player_in_water() && !player_can_swim()); } bool player_under_penance(void) @@ -422,16 +401,13 @@ bool player_genus(unsigned char which_genus, unsigned char species) // eq must be in [EQ_WEAPON, EQ_AMULET], or bad things will happen. item_def *player_slot_item(equipment_type eq) { - ASSERT(eq >= EQ_WEAPON && eq <= EQ_AMULET); - - const int item = you.equip[eq]; - return (item == -1? NULL : &you.inv[item]); + return you.slot_item(eq); } // Returns the item in the player's weapon slot. item_def *player_weapon() { - return player_slot_item(EQ_WEAPON); + return you.weapon(); } bool player_weapon_wielded() @@ -627,66 +603,13 @@ int player_equip_ego_type( int slot, int special ) int player_damage_type( void ) { - const int wpn = you.equip[ EQ_WEAPON ]; - - if (wpn != -1) - { - return (get_vorpal_type(you.inv[wpn])); - } - else if (you.equip[EQ_GLOVES] == -1 && - you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) - { - return (DVORP_SLICING); - } - else if (you.equip[EQ_GLOVES] == -1 && - (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON - || you.mutation[MUT_CLAWS] - || you.species == SP_TROLL - || you.species == SP_GHOUL)) - { - return (DVORP_CLAWING); - } - - return (DVORP_CRUSHING); + return you.damage_type(); } // returns band of player's melee damage int player_damage_brand( void ) { - int ret = SPWPN_NORMAL; - const int wpn = you.equip[ EQ_WEAPON ]; - - if (wpn != -1) - { - if ( !is_range_weapon(you.inv[wpn]) ) - ret = get_weapon_brand( you.inv[wpn] ); - } - else if (you.confusing_touch) - ret = SPWPN_CONFUSE; - else if (you.mutation[MUT_DRAIN_LIFE]) - ret = SPWPN_DRAINING; - else - { - switch (you.attribute[ATTR_TRANSFORMATION]) - { - case TRAN_SPIDER: - ret = SPWPN_VENOM; - break; - - case TRAN_ICE_BEAST: - ret = SPWPN_FREEZING; - break; - - case TRAN_LICH: - ret = SPWPN_DRAINING; - break; - - default: - break; - } - } - - return (ret); + return you.damage_brand(); } int player_teleport(bool calc_unid) @@ -1803,48 +1726,7 @@ bool player_is_shapechanged(void) // natural one. size_type player_size( int psize, bool base ) { - size_type ret = (base) ? SIZE_CHARACTER : transform_size( psize ); - - if (ret == SIZE_CHARACTER) - { - // transformation has size of character's species: - switch (you.species) - { - case SP_OGRE: - case SP_OGRE_MAGE: - case SP_TROLL: - ret = SIZE_LARGE; - break; - - case SP_NAGA: - // Most of their body is on the ground giving them a low profile. - if (psize == PSIZE_TORSO || psize == PSIZE_PROFILE) - ret = SIZE_MEDIUM; - else - ret = SIZE_BIG; - break; - - case SP_CENTAUR: - ret = (psize == PSIZE_TORSO) ? SIZE_MEDIUM : SIZE_BIG; - break; - - case SP_SPRIGGAN: - ret = SIZE_LITTLE; - break; - - case SP_HALFLING: - case SP_GNOME: - case SP_KOBOLD: - ret = SIZE_SMALL; - break; - - default: - ret = SIZE_MEDIUM; - break; - } - } - - return (ret); + return you.body_size(psize, base); } int player_evasion(void) @@ -1966,7 +1848,7 @@ int player_mag_abil(bool is_weighted) // Returns the shield the player is wearing, or NULL if none. item_def *player_shield() { - return player_slot_item(EQ_SHIELD); + return you.shield(); } int player_shield_class(void) //jmf: changes for new spell @@ -3134,9 +3016,7 @@ void display_char_status(void) : "very slow" ); mpr(info); - // XXX Assumes no hand-and-a-half bonus. Oh well. - const int to_hit = calc_your_to_hit( calc_heavy_armour_penalty(false), - false, false, false ) * 2; + const int to_hit = calc_your_to_hit( false ) * 2; // Messages based largely on percentage chance of missing the // average EV 10 humanoid, and very agile EV 30 (pretty much // max EV for monsters currently). @@ -3471,18 +3351,12 @@ bool wearing_amulet(char amulet, bool calc_unid) bool player_is_levitating(void) { - return (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON || you.levitation); + return you.is_levitating(); } bool player_has_spell( int spell ) { - for (int i = 0; i < 25; i++) - { - if (you.spells[i] == spell) - return (true); - } - - return (false); + return you.has_spell(spell); } int species_exp_mod(char species) @@ -4626,3 +4500,236 @@ bool player::operator < (const player &p) const || (experience == p.experience && stricmp(your_name, p.your_name) < 0)); } + +coord_def player::pos() const +{ + return coord_def(x_pos, y_pos); +} + +bool player::is_levitating() const +{ + return (attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON || levitation); +} + +bool player::in_water() const +{ + return !is_levitating() + && grid_is_water(grd[you.x_pos][you.y_pos]); +} + +bool player::can_swim() const +{ + return (species == SP_MERFOLK); +} + +bool player::swimming() const +{ + return in_water() && can_swim(); +} + +bool player::has_spell(int spell) const +{ + for (int i = 0; i < 25; i++) + { + if (spells[i] == spell) + return (true); + } + + return (false); +} + +bool player::floundering() const +{ + return in_water() && !can_swim(); +} + +size_type player::body_size(int psize, bool base) const +{ + size_type ret = (base) ? SIZE_CHARACTER : transform_size( psize ); + + if (ret == SIZE_CHARACTER) + { + // transformation has size of character's species: + switch (species) + { + case SP_OGRE: + case SP_OGRE_MAGE: + case SP_TROLL: + ret = SIZE_LARGE; + break; + + case SP_NAGA: + // Most of their body is on the ground giving them a low profile. + if (psize == PSIZE_TORSO || psize == PSIZE_PROFILE) + ret = SIZE_MEDIUM; + else + ret = SIZE_BIG; + break; + + case SP_CENTAUR: + ret = (psize == PSIZE_TORSO) ? SIZE_MEDIUM : SIZE_BIG; + break; + + case SP_SPRIGGAN: + ret = SIZE_LITTLE; + break; + + case SP_HALFLING: + case SP_GNOME: + case SP_KOBOLD: + ret = SIZE_SMALL; + break; + + default: + ret = SIZE_MEDIUM; + break; + } + } + + return (ret); +} + +int player::damage_type(int) +{ + const int wpn = equip[ EQ_WEAPON ]; + + if (wpn != -1) + { + return (get_vorpal_type(inv[wpn])); + } + else if (equip[EQ_GLOVES] == -1 && + attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) + { + return (DVORP_SLICING); + } + else if (equip[EQ_GLOVES] == -1 && + (attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON + || mutation[MUT_CLAWS] + || species == SP_TROLL + || species == SP_GHOUL)) + { + return (DVORP_CLAWING); + } + + return (DVORP_CRUSHING); +} + +int player::damage_brand(int) +{ + int ret = SPWPN_NORMAL; + const int wpn = equip[ EQ_WEAPON ]; + + if (wpn != -1) + { + if ( !is_range_weapon(inv[wpn]) ) + ret = get_weapon_brand( inv[wpn] ); + } + else if (confusing_touch) + ret = SPWPN_CONFUSE; + else if (mutation[MUT_DRAIN_LIFE]) + ret = SPWPN_DRAINING; + else + { + switch (attribute[ATTR_TRANSFORMATION]) + { + case TRAN_SPIDER: + ret = SPWPN_VENOM; + break; + + case TRAN_ICE_BEAST: + ret = SPWPN_FREEZING; + break; + + case TRAN_LICH: + ret = SPWPN_DRAINING; + break; + + default: + break; + } + } + + return (ret); +} + +item_def *player::slot_item(equipment_type eq) +{ + ASSERT(eq >= EQ_WEAPON && eq <= EQ_AMULET); + + const int item = equip[eq]; + return (item == -1? NULL : &inv[item]); +} + +// Returns the item in the player's weapon slot. +item_def *player::weapon(int /* which_attack */) +{ + return slot_item(EQ_WEAPON); +} + +item_def *player::shield() +{ + return slot_item(EQ_SHIELD); +} + +std::string player::name(description_level_type type) const +{ + return (pronoun_you(type)); +} + +std::string player::conj_verb(const std::string &verb) const +{ + return (verb); +} + +int player::id() const +{ + return (-1); +} + +bool player::fumbles_attack(bool verbose) +{ + // fumbling in shallow water : + if (floundering()) + { + if (random2(dex) < 4 || one_chance_in(5)) + { + if (verbose) + mpr("Unstable footing causes you to fumble your attack."); + return (true); + } + } + return (false); +} + +bool player::cannot_fight() const +{ + return (false); +} + +void player::attacking(actor *other) +{ + if (other && other->atype() == ACT_MONSTER) + { + const monsters *mons = dynamic_cast(other); + if (mons_friendly(mons)) + did_god_conduct(DID_ATTACK_FRIEND, 5); + else + pet_target = monster_index(mons); + } + + if (mutation[MUT_BERSERK] && + (random2(100) < (mutation[MUT_BERSERK] * 10) - 5)) + { + go_berserk(false); + } +} + +void player::go_berserk(bool intentional) +{ + ::go_berserk(intentional); +} + +void player::make_hungry(int hunger_increase, bool silent) +{ + ::make_hungry(hunger_increase, silent); +} diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index 29d551582d..8cd5c23ff3 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -18,8 +18,13 @@ std::string actor_name(const monsters *actor, description_level_type desc); std::string actor_verb(const monsters *actor, const std::string &verb); +int actor_size(const monsters *actor); int actor_damage_type(const monsters *actor); int actor_damage_brand(const monsters *actor); +bool actor_swimming(const monsters *actor); +bool actor_floundering(const monsters *actor); +item_def *actor_weapon(const monsters *actor, int which_attack = -1); +item_def *actor_shield(const monsters *actor); bool move_player_to_grid( int x, int y, bool stepped, bool allow_shift, bool force ); @@ -52,6 +57,7 @@ bool player_light_armour(bool with_skill = false); * *********************************************************************** */ bool player_in_water(void); bool player_is_swimming(void); +bool player_floundering(); bool player_is_levitating(void); /* *********************************************************************** diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc index 7a33cd310b..11ba9180c6 100644 --- a/crawl-ref/source/randart.cc +++ b/crawl-ref/source/randart.cc @@ -674,6 +674,11 @@ char does_unrandart_exist(int whun) return (unrandart_exist[whun]); } +bool is_artefact( const item_def &item ) +{ + return (is_random_artefact(item) || is_fixed_artefact(item)); +} + // returns true is item is a pure randart or an unrandart bool is_random_artefact( const item_def &item ) { @@ -745,7 +750,7 @@ static long calc_seed( const item_def &item ) } void randart_wpn_properties( const item_def &item, - FixedVector< char, RA_PROPERTIES > &proprt ) + randart_properties_t &proprt ) { ASSERT( is_random_artefact( item ) ); @@ -1213,9 +1218,9 @@ finished_curses: } -int randart_wpn_property( const item_def &item, char prop ) +int randart_wpn_property( const item_def &item, int prop ) { - FixedVector< char, RA_PROPERTIES > proprt; + randart_properties_t proprt; randart_wpn_properties( item, proprt ); diff --git a/crawl-ref/source/randart.h b/crawl-ref/source/randart.h index da41ef6f06..9a7d0d6344 100644 --- a/crawl-ref/source/randart.h +++ b/crawl-ref/source/randart.h @@ -23,6 +23,7 @@ #define RANDART_SEED_MASK 0x00ffffff +bool is_artefact( const item_def &item ); bool is_random_artefact( const item_def &item ); bool is_unrandom_artefact( const item_def &item ); bool is_fixed_artefact( const item_def &item ); @@ -61,14 +62,15 @@ char does_unrandart_exist(int whun); * *********************************************************************** */ int find_okay_unrandart(unsigned char aclass, unsigned char atype = OBJ_RANDOM); +typedef FixedVector< int, RA_PROPERTIES > randart_properties_t; /* *********************************************************************** * called from: describe - fight - it_use2 - item_use - player * *********************************************************************** */ void randart_wpn_properties( const item_def &item, - FixedVector< char, RA_PROPERTIES > &proprt ); + randart_properties_t &proprt ); -int randart_wpn_property( const item_def &item, char prop ); +int randart_wpn_property( const item_def &item, int prop ); /* *********************************************************************** diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc index d4a16c5c33..ee3df95b1d 100644 --- a/crawl-ref/source/shopping.cc +++ b/crawl-ref/source/shopping.cc @@ -485,8 +485,7 @@ int randart_value( const item_def &item ) ASSERT( is_random_artefact( item ) ); int ret = 10; - FixedVector< char, RA_PROPERTIES > prop; - + randart_properties_t prop; randart_wpn_properties( item, prop ); // Brands are already accounted for via existing ego checks diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc index 2499ee9fb4..c456a48b15 100644 --- a/crawl-ref/source/transfor.cc +++ b/crawl-ref/source/transfor.cc @@ -90,9 +90,14 @@ static bool check_for_cursed_equipment( FixedVector < char, 8 > &remove_stuff ) } // end check_for_cursed_equipment() // FIXME: Switch to 4.1 transforms handling. -size_type transform_size(int) +size_type transform_size(int psize) { - const int transform = you.attribute[ATTR_TRANSFORMATION]; + return you.transform_size(psize); +} + +size_type player::transform_size(int psize) const +{ + const int transform = attribute[ATTR_TRANSFORMATION]; switch (transform) { case TRAN_SPIDER: diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index b23ae18f15..7e46c170dc 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -3408,16 +3408,25 @@ void viewwindow(bool draw_it, bool do_updates) const int gx = count_x + you.x_pos - 16; const int gy = count_y + you.y_pos - 8; - if (Options.tutorial_left && in_bounds(gx, gy)) + if (Options.tutorial_left && in_bounds(gx, gy) + && count_x >= 8 && count_x <= 24) { - if (is_feature('>',gx,gy)) - learned_something_new(TUT_SEEN_STAIRS); - else if (is_feature('_',gx,gy)) - learned_something_new(TUT_SEEN_ALTAR); - else if (grd[gx][gy] == DNGN_CLOSED_DOOR) - learned_something_new(TUT_SEEN_DOOR,gx,gy); - else if (grd[gx][gy] == DNGN_ENTER_SHOP) - learned_something_new(TUT_SEEN_SHOP,gx,gy); + const int ex = gx - you.x_pos + 9; + const int ey = gy - you.y_pos + 9; + + int object = env.show[ex][ey]; + + if (object) + { + if (is_feature('>',gx,gy)) + learned_something_new(TUT_SEEN_STAIRS); + else if (is_feature('_',gx,gy)) + learned_something_new(TUT_SEEN_ALTAR); + else if (grd[gx][gy] == DNGN_CLOSED_DOOR) + learned_something_new(TUT_SEEN_DOOR,gx,gy); + else if (grd[gx][gy] == DNGN_ENTER_SHOP) + learned_something_new(TUT_SEEN_SHOP,gx,gy); + } } // order is important here -- cgit v1.2.3-54-g00ecf