From 8674d7ae28e958983128c045fb8504b037785da7 Mon Sep 17 00:00:00 2001 From: dshaligram Date: Sat, 24 Feb 2007 11:13:12 +0000 Subject: Monster attack refactoring. Likely to be buggy. Fixed tracer explosion beams generating clouds. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@959 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/Kills.cc | 4 +- crawl-ref/source/Kills.h | 3 + crawl-ref/source/acr.cc | 12 +- crawl-ref/source/beam.cc | 16 +- crawl-ref/source/debug.cc | 6 +- crawl-ref/source/describe.cc | 2 +- crawl-ref/source/dungeon.cc | 38 +- crawl-ref/source/enum.h | 45 +- crawl-ref/source/externs.h | 198 +++- crawl-ref/source/fight.cc | 2696 +++++++++++++----------------------------- crawl-ref/source/fight.h | 40 +- crawl-ref/source/files.cc | 8 +- crawl-ref/source/it_use2.cc | 15 +- crawl-ref/source/mon-data.h | 735 ++++++------ crawl-ref/source/mon-util.cc | 408 ++++++- crawl-ref/source/mon-util.h | 25 +- crawl-ref/source/monplace.cc | 8 +- crawl-ref/source/monstuff.cc | 25 +- crawl-ref/source/mstuff2.cc | 10 +- crawl-ref/source/output.cc | 4 +- crawl-ref/source/player.cc | 315 ++++- crawl-ref/source/religion.cc | 6 - crawl-ref/source/spells1.cc | 4 +- crawl-ref/source/spells2.cc | 2 +- crawl-ref/source/spells3.cc | 12 +- crawl-ref/source/spells4.cc | 12 +- crawl-ref/source/tags.cc | 16 +- crawl-ref/source/tutorial.cc | 4 +- 28 files changed, 2240 insertions(+), 2429 deletions(-) diff --git a/crawl-ref/source/Kills.cc b/crawl-ref/source/Kills.cc index 06b8dc8cd1..9bff79ec8c 100644 --- a/crawl-ref/source/Kills.cc +++ b/crawl-ref/source/Kills.cc @@ -363,8 +363,8 @@ static const char *modifier_suffixes[] = // Pluralizes a monster name. This'll need to be updated for correctness // whenever new monsters are added. -static std::string pluralize(const std::string &name, - const char *no_of[] = NULL) +std::string pluralize(const std::string &name, + const char *no_of[]) { std::string::size_type pos; diff --git a/crawl-ref/source/Kills.h b/crawl-ref/source/Kills.h index f3ada4fe40..625b145cba 100644 --- a/crawl-ref/source/Kills.h +++ b/crawl-ref/source/Kills.h @@ -12,6 +12,9 @@ #include #include "enum.h" +std::string pluralize(const std::string &name, + const char *no_of[] = NULL); + struct monsters; // Not intended for external use! diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 74f591eb6b..9e317eb7a6 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -522,7 +522,7 @@ static void handle_wizard_command( void ) case 'h': you.rotting = 0; - you.poison = 0; + you.poisoning = 0; you.disease = 0; set_hp( abs(you.hp_max), false ); set_hunger( 5000 + abs(you.hunger), true ); @@ -530,7 +530,7 @@ static void handle_wizard_command( void ) case 'H': you.rotting = 0; - you.poison = 0; + you.poisoning = 0; you.disease = 0; inc_hp( 10, true ); set_hp( you.hp_max, false ); @@ -2068,16 +2068,16 @@ static void decrement_durations() dec_disease_player(); - if (you.poison > 0) + if (you.poisoning > 0) { - if (random2(5) <= (you.poison - 1)) + if (random2(5) <= (you.poisoning - 1)) { - if (you.poison > 10 && random2(you.poison) >= 8) + if (you.poisoning > 10 && random2(you.poisoning) >= 8) { ouch(random2(10) + 5, 0, KILLED_BY_POISON); mpr("You feel extremely sick.", MSGCH_DANGER); } - else if (you.poison > 5 && coinflip()) + else if (you.poisoning > 5 && coinflip()) { ouch((coinflip()? 3 : 2), 0, KILLED_BY_POISON); mpr("You feel very sick.", MSGCH_WARN); diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index de4e421b9e..43ce150c9d 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -2328,6 +2328,8 @@ static void beam_explodes(struct bolt &beam, int x, int y) return; } + if (beam.is_tracer) + return; // cloud producer -- POISON BLAST if (beam.name == "blast of poison") @@ -3518,14 +3520,14 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) hurt_final = hurt; if (beam.is_tracer) - hurt_final -= mon->armour_class / 2; + hurt_final -= mon->ac / 2; else - hurt_final -= random2(1 + mon->armour_class); + hurt_final -= random2(1 + mon->ac); if (beam.flavour == BEAM_FRAG) { - hurt_final -= random2(1 + mon->armour_class); - hurt_final -= random2(1 + mon->armour_class); + hurt_final -= random2(1 + mon->ac); + hurt_final -= random2(1 + mon->ac); } if (hurt_final < 1) @@ -3607,7 +3609,7 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) // FIXME We're randomising mon->evasion, which is further // randomised inside test_hit. This is so we stay close to the 4.0 // to-hit system (which had very little love for monsters). - if (!engulfs && !test_hit(beam.hit, random2(mon->evasion))) + if (!engulfs && !test_hit(beam.hit, random2(mon->ev))) { // if the PLAYER cannot see the monster, don't tell them anything! if (player_monster_visible( &menv[tid] ) && mons_near(mon)) @@ -3674,11 +3676,11 @@ static int affect_monster(struct bolt &beam, struct monsters *mon) { // ench_power == AUTOMATIC_HIT if this is a poisoned needle. if (beam.ench_power == AUTOMATIC_HIT - && random2(100) < 90 - (3 * mon->armour_class)) + && random2(100) < 90 - (3 * mon->ac)) { poison_monster( mon, YOU_KILL(beam.thrower), 2 ); } - else if (random2(hurt_final) - random2(mon->armour_class) > 0) + else if (random2(hurt_final) - random2(mon->ac) > 0) { poison_monster( mon, YOU_KILL(beam.thrower) ); } diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc index 53fc10ae2c..1a65c92601 100644 --- a/crawl-ref/source/debug.cc +++ b/crawl-ref/source/debug.cc @@ -1206,7 +1206,7 @@ void stethoscope(int mwh) snprintf( info, INFO_SIZE,"HD=%d HP=%d/%d AC=%d EV=%d MR=%d SP=%d energy=%d num=%d flags=%04lx", menv[i].hit_dice, menv[i].hit_points, menv[i].max_hit_points, - menv[i].armour_class, menv[i].evasion, + menv[i].ac, menv[i].ev, mons_resist_magic( &menv[i] ), menv[i].speed, menv[i].speed_increment, menv[i].number, menv[i].flags ); @@ -1943,8 +1943,8 @@ static void fsim_mon_stats(FILE *o, const monsters &mon) fprintf(o, "Monster : %s\n", moname(mon.type, true, DESC_PLAIN, buf)); fprintf(o, "HD : %d\n", mon.hit_dice); - fprintf(o, "AC : %d\n", mon.armour_class); - fprintf(o, "EV : %d\n", mon.evasion); + fprintf(o, "AC : %d\n", mon.ac); + fprintf(o, "EV : %d\n", mon.ev); } static void fsim_title(FILE *o, int mon, int ms) diff --git a/crawl-ref/source/describe.cc b/crawl-ref/source/describe.cc index 7f8c52e54e..d9c9d10048 100644 --- a/crawl-ref/source/describe.cc +++ b/crawl-ref/source/describe.cc @@ -307,7 +307,7 @@ static void randart_descpr( std::string &description, const item_def &item ) if (proprt[ RAP_MUTAGENIC ] > 3) description += "$It glows with mutagenic radiation."; else if (proprt[ RAP_MUTAGENIC ]) - description += "$It emits mutagenic radiations."; + description += "$It emits mutagenic radiation."; if (old_length != description.length()) description += "$"; diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc index 6192d0110c..236d6d5b16 100644 --- a/crawl-ref/source/dungeon.cc +++ b/crawl-ref/source/dungeon.cc @@ -3351,7 +3351,7 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes if (get_weapon_brand( mitm[thing_created] ) == SPWPN_PROTECTION ) - menv[mid].armour_class += 5; + menv[mid].ac += 5; if (!force_item || mitm[thing_created].colour == BLACK) item_colour( mitm[thing_created] ); @@ -3576,19 +3576,19 @@ void give_item(int mid, int level_number) //mv: cleanup+minor changes if (force_colour) mitm[thing_created].colour = force_colour; - menv[mid].armour_class += property( mitm[thing_created], PARM_AC ); + menv[mid].ac += property( mitm[thing_created], PARM_AC ); const int armour_plus = mitm[thing_created].plus; ASSERT(abs(armour_plus) < 20); if (abs(armour_plus) < 20) - menv[mid].armour_class += armour_plus; + menv[mid].ac += armour_plus; - menv[mid].evasion += property( mitm[thing_created], PARM_EVASION ) / 2; + menv[mid].ev += property( mitm[thing_created], PARM_EVASION ) / 2; - if (menv[mid].evasion < 1) - menv[mid].evasion = 1; // This *shouldn't* happen. + if (menv[mid].ev < 1) + menv[mid].ev = 1; // This *shouldn't* happen. } // end give_item() //--------------------------------------------------------------------------- @@ -8932,15 +8932,15 @@ void define_zombie( int mid, int ztype, int cs, int power ) menv[mid].hit_points = hit_points( menv[mid].hit_dice, 6, 5 ); menv[mid].max_hit_points = menv[mid].hit_points; - menv[mid].armour_class -= 2; + menv[mid].ac -= 2; - if (menv[mid].armour_class < 0) - menv[mid].armour_class = 0; + if (menv[mid].ac < 0) + menv[mid].ac = 0; - menv[mid].evasion -= 5; + menv[mid].ev -= 5; - if (menv[mid].evasion < 0) - menv[mid].evasion = 0; + if (menv[mid].ev < 0) + menv[mid].ev = 0; menv[mid].speed -= 2; @@ -8960,15 +8960,15 @@ void define_zombie( int mid, int ztype, int cs, int power ) menv[mid].hit_points = hit_points( menv[mid].hit_dice, 5, 4 ); menv[mid].max_hit_points = menv[mid].hit_points; - menv[mid].armour_class -= 4; + menv[mid].ac -= 4; - if (menv[mid].armour_class < 0) - menv[mid].armour_class = 0; + if (menv[mid].ac < 0) + menv[mid].ac = 0; - menv[mid].evasion -= 2; + menv[mid].ev -= 2; - if (menv[mid].evasion < 0) - menv[mid].evasion = 0; + if (menv[mid].ev < 0) + menv[mid].ev = 0; menv[mid].type = ((mons_zombie_size( menv[mid].number ) == 2) ? MONS_SKELETON_LARGE : MONS_SKELETON_SMALL); @@ -8985,7 +8985,7 @@ void define_zombie( int mid, int ztype, int cs, int power ) { menv[mid].hit_points = hit_points( menv[mid].hit_dice, 4, 4 ); menv[mid].max_hit_points = menv[mid].hit_points; - menv[mid].armour_class += 4; + menv[mid].ac += 4; menv[mid].type = MONS_SPECTRAL_THING; } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 9cb755a6d1..a6000a6a44 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -875,8 +875,8 @@ enum description_level_type DESC_NOCAP_YOUR, // 5 DESC_PLAIN, // 6 DESC_NOCAP_ITS, // 7 - DESC_INVENTORY_EQUIP, // 8 - DESC_INVENTORY // 8 + DESC_INVENTORY_EQUIP, // 8 + DESC_INVENTORY // 9 }; enum dragon_class_type @@ -1841,7 +1841,6 @@ 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? @@ -2290,6 +2289,46 @@ enum beh_type BEH_GUARD // creation only - monster is guard }; +enum mon_attack_type +{ + AT_NONE, + AT_HIT, // including weapon attacks + AT_BITE, + AT_STING, + AT_SPORE, + AT_TOUCH, + AT_ENGULF, + AT_CLAW, + AT_TAIL_SLAP +}; + +enum mon_attack_flavour +{ + AF_PLAIN, + AF_ACID, + AF_BLINK, + AF_COLD, + AF_CONFUSE, + AF_DISEASE, + AF_DRAIN_DEX, + AF_DRAIN_STR, + AF_DRAIN_XP, + AF_ELEC, + AF_FIRE, + AF_HUNGER, + AF_MUTATE, + AF_BAD_MUTATE, + AF_PARALYSE, + AF_POISON, + AF_POISON_NASTY, + AF_POISON_MEDIUM, + AF_POISON_STRONG, + AF_POISON_STR, + AF_ROT, + AF_VAMPIRIC, + AF_KLOWN +}; + enum mon_attitude_type { ATT_HOSTILE, // 0, default in most cases diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 0a57670a3f..d69b010db4 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -103,11 +103,13 @@ class coord_def; class actor { public: - virtual ~actor() { } + virtual ~actor(); virtual int id() const = 0; virtual actor_type atype() const = 0; + virtual bool alive() const = 0; + virtual coord_def pos() const = 0; virtual bool swimming() const = 0; virtual bool floundering() const = 0; @@ -119,12 +121,15 @@ public: virtual int damage_brand(int which_attack = -1) = 0; virtual item_def *weapon(int which_attack = -1) = 0; virtual item_def *shield() = 0; + virtual item_def *slot_item(equipment_type eq) = 0; - virtual void make_hungry(int nutrition, bool silent) + virtual int hunger_level() const { return HS_ENGORGED; } + virtual void make_hungry(int nutrition, bool silent = true) { } virtual std::string name(description_level_type type) const = 0; + virtual std::string pronoun(pronoun_type which_pronoun) const = 0; virtual std::string conj_verb(const std::string &verb) const = 0; virtual bool fumbles_attack(bool verbose = true) = 0; @@ -134,6 +139,73 @@ public: virtual bool cannot_fight() const = 0; virtual void attacking(actor *other) = 0; virtual void go_berserk(bool intentional) = 0; + virtual void hurt(actor *attacker, int amount) = 0; + virtual void heal(int amount, bool max_too = false) = 0; + virtual void banish() = 0; + virtual void blink() = 0; + virtual void teleport(bool right_now = false, bool abyss_shift = false) = 0; + virtual void poison(actor *attacker, int amount = 1) = 0; + virtual void paralyse(int strength) = 0; + virtual void slow_down(int strength) = 0; + virtual void confuse(int strength) = 0; + virtual void rot(actor *attacker, int rotlevel, int immediate_rot) = 0; + virtual void expose_to_element(beam_type element, int strength = 0) = 0; + virtual void drain_stat(int stat, int amount) { } + + virtual bool wearing_light_armour(bool = true) const { return (true); } + virtual int skill(skill_type sk, bool skill_bump = false) const + { + return (0); + } + + virtual void exercise(skill_type sk, int qty) { } + + virtual int stat_hp() const = 0; + virtual int stat_maxhp() const = 0; + virtual int armour_class() const = 0; + virtual int melee_evasion(const actor *attacker) const = 0; + virtual int shield_bonus() const = 0; + virtual int shield_block_penalty() const = 0; + virtual int shield_bypass_ability(int tohit) const = 0; + + virtual void shield_block_succeeded() { } + + virtual int mons_species() const = 0; + + virtual int holiness() const = 0; + virtual int res_fire() const = 0; + virtual int res_cold() const = 0; + virtual int res_elec() const = 0; + virtual int res_poison() const = 0; + virtual int res_negative_energy() const = 0; + + virtual bool levitates() const = 0; + + virtual bool paralysed() const = 0; + virtual bool confused() const = 0; + virtual bool asleep() const { return (false); } + + virtual void god_conduct(int thing_done, int level) { } + + virtual bool incapacitated() const + { + return paralysed() || confused(); + } + + virtual int holy_aura() const + { + return (0); + } + + virtual int warding() const + { + return (0); + } + + virtual bool visible() const + { + return (true); + } }; struct ait_hp_loss @@ -536,7 +608,7 @@ public: int might; int levitation; - int poison; + int poisoning; int rotting; int berserker; @@ -637,6 +709,10 @@ public: // actor int id() const; + actor_type atype() const { return ACT_PLAYER; } + + bool alive() const; + coord_def pos() const; bool swimming() const; bool floundering() const; @@ -647,6 +723,7 @@ public: item_def *shield(); std::string name(description_level_type type) const; + std::string pronoun(pronoun_type pro) const; std::string conj_verb(const std::string &verb) const; bool fumbles_attack(bool verbose = true); @@ -654,10 +731,56 @@ public: void attacking(actor *other); void go_berserk(bool intentional); + void banish(); + void blink(); + void teleport(bool right_now = false, bool abyss_shift = false); + void drain_stat(int stat, int amount); + + void expose_to_element(beam_type element, int strength = 0); + void god_conduct(int thing_done, int level); + + int hunger_level() const { return hunger_state; } + void make_hungry(int nutrition, bool silent = true); + void poison(actor *agent, int amount = 1); + void paralyse(int str); + void slow_down(int str); + void confuse(int strength); + void rot(actor *agent, int rotlevel, int immed_rot); + void heal(int amount, bool max_too = false); + void hurt(actor *agent, int amount); + + int holy_aura() const; + int warding() const; + + int mons_species() const; + + int holiness() const; + int res_fire() const; + int res_cold() const; + int res_elec() const; + int res_poison() const; + int res_negative_energy() const; + + bool levitates() const; + + bool paralysed() const; + bool confused() const; + + int armour_class() const; + int melee_evasion(const actor *attacker) const; + + int stat_hp() const { return hp; } + int stat_maxhp() const { return hp_max; } + + int shield_bonus() const; + int shield_block_penalty() const; + int shield_bypass_ability(int tohit) const; - void make_hungry(int nutrition, bool silent); + void shield_block_succeeded(); - actor_type atype() const { return ACT_PLAYER; } + bool wearing_light_armour(bool with_skill = true) const; + void exercise(skill_type skill, int qty); + int skill(skill_type skill, bool skill_bump = false) const; }; extern player you; @@ -671,6 +794,21 @@ public: void clear() { init(MS_NO_SPELL); } }; +struct mon_attack_def +{ + mon_attack_type type; + mon_attack_flavour flavour; + int damage; + + static mon_attack_def attk(int damage, + mon_attack_type type = AT_HIT, + mon_attack_flavour flav = AF_PLAIN) + { + mon_attack_def def = { type, flav, damage }; + return (def); + } +}; + class monsters : public actor { public: @@ -678,8 +816,8 @@ public: int hit_points; int max_hit_points; int hit_dice; - int armour_class; - int evasion; + int ac; + int ev; unsigned int speed; unsigned int speed_increment; unsigned char x; @@ -705,22 +843,68 @@ public: public: // actor interface int id() const; + bool alive() 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 *slot_item(equipment_type eq); item_def *weapon(int which_attack = -1); item_def *shield(); std::string name(description_level_type type) const; + std::string pronoun(pronoun_type pro) const; std::string conj_verb(const std::string &verb) const; bool fumbles_attack(bool verbose = true); bool cannot_fight() const; + int skill(skill_type skill, bool skill_bump = false) const; + void attacking(actor *other); void go_berserk(bool intentional); + void banish(); + void expose_to_element(beam_type element, int strength = 0); + bool visible() const; + + int mons_species() const; + + int holiness() const; + int res_fire() const; + int res_cold() const; + int res_elec() const; + int res_poison() const; + int res_negative_energy() const; + + bool levitates() const; + + bool paralysed() const; + bool confused() const; + bool asleep() const; + + int holy_aura() const; + + int armour_class() const; + int melee_evasion(const actor *attacker) const; + + void poison(actor *agent, int amount = 1); + void paralyse(int str); + void slow_down(int str); + void confuse(int strength); + void rot(actor *agent, int rotlevel, int immed_rot); + void hurt(actor *agent, int amount); + void heal(int amount, bool max_too = false); + void blink(); + void teleport(bool right_now = false, bool abyss_shift = false); + + int stat_hp() const { return hit_points; } + int stat_maxhp() const { return max_hit_points; } + + int shield_bonus() const; + int shield_block_penalty() const; + int shield_bypass_ability(int tohit) const; actor_type atype() const { return ACT_MONSTER; } }; diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 40f8d82476..e455918b62 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -88,6 +88,8 @@ static inline int player_weapon_dex_weight( void ); static inline int calc_stat_to_hit_base( void ); static inline int calc_stat_to_dam_base( void ); +static void mons_lose_attack_energy(monsters *attacker, int wpn_speed, + int which_attack); /* ************************************************** @@ -218,16 +220,16 @@ int calc_heavy_armour_penalty( bool random_factor ) // My guess is that its supposed to encourage monk-style play -- bwr if (!ur_armed) { - if ( random_factor ) + if ( random_factor ) { - heavy_armour *= (coinflip() ? 3 : 2); - } - // (2+3)/2 - else + heavy_armour *= (coinflip() ? 3 : 2); + } + // (2+3)/2 + else { - heavy_armour *= 5; - heavy_armour /= 2; - } + heavy_armour *= 5; + heavy_armour /= 2; + } } return heavy_armour; } @@ -313,11 +315,12 @@ static bool chop_hydra_head( const actor *attacker, } static bool actor_decapitates_hydra(actor *attacker, actor *defender, - int damage_done) + int damage_done, int damage_type = -1) { if (defender->id() == MONS_HYDRA) { - const int dam_type = attacker->damage_type(); + const int dam_type = + damage_type != -1? damage_type : attacker->damage_type(); const int wpn_brand = attacker->damage_brand(); return chop_hydra_head(attacker, defender, damage_done, @@ -340,6 +343,8 @@ melee_attack::melee_attack(actor *attk, actor *defn, bool allow_unarmed, int which_attack) : attacker(attk), defender(defn), atk(NULL), def(NULL), + did_hit(false), perceived_attack(false), + needs_message(false), attacker_visible(false), defender_visible(false), unarmed_ok(allow_unarmed), attack_number(which_attack), to_hit(0), base_damage(0), potential_damage(0), damage_done(0), @@ -349,6 +354,7 @@ melee_attack::melee_attack(actor *attk, actor *defn, spwld(SPWLD_NONE), hand_half_bonus(false), art_props(0), attack_verb(), verb_degree(), no_damage_message(), special_damage_message(), unarmed_attack(), + shield(NULL), defender_shield(NULL), heavy_armour_penalty(0), can_do_unarmed(false), water_attack(false) { @@ -391,8 +397,13 @@ void melee_attack::init_attack() } shield = attacker->shield(); + if (defender) + defender_shield = defender->shield(); water_attack = is_water_attack(attacker, defender); + attacker_visible = attacker->visible(); + defender_visible = defender && defender->visible(); + needs_message = attacker_visible || defender_visible; } bool melee_attack::is_water_attack(const actor *attk, @@ -434,8 +445,21 @@ void melee_attack::check_special_wield_effects() } } +void melee_attack::identify_mimic(monsters *mon) +{ + if (mon && mons_is_mimic(mon->type) + && mons_near(mon) && player_monster_visible(mon)) + { + mon->flags |= MF_KNOWN_MIMIC; + } +} + bool melee_attack::attack() { + // If a mimic is attacking or defending, it is thereafter known. + identify_mimic(atk); + identify_mimic(def); + if (attacker->fumbles_attack()) return (false); @@ -695,7 +719,7 @@ bool melee_attack::player_aux_unarmed() // XXX We're clobbering did_hit did_hit = false; - if (to_hit >= def->evasion || one_chance_in(30)) + if (to_hit >= def->ev || one_chance_in(30)) { if (player_apply_aux_unarmed()) return (true); @@ -815,7 +839,7 @@ void melee_attack::player_announce_hit() std::string melee_attack::player_why_missed() { - if ((to_hit + heavy_armour_penalty / 2) >= def->evasion) + if ((to_hit + heavy_armour_penalty / 2) >= def->ev) return "Your armour prevents you from hitting "; else return "You miss "; @@ -838,10 +862,10 @@ bool melee_attack::player_hits_monster() { #if DEBUG_DIAGNOSTICS mprf( MSGCH_DIAGNOSTICS, "your to-hit: %d; defender EV: %d", - to_hit, def->evasion ); + to_hit, def->ev ); #endif - return (to_hit >= def->evasion + return (to_hit >= def->ev || one_chance_in(3) || ((mons_is_paralysed(def) || def->behaviour == BEH_SLEEP) && !one_chance_in(10 + you.skills[SK_STABBING]))); @@ -1057,9 +1081,9 @@ 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) + if (def->ac > 0) { - int ac = def->armour_class + int ac = def->ac - random2( you.skills[SK_STABBING] / stab_bonus ); if (ac > 0) @@ -1069,8 +1093,8 @@ int melee_attack::player_apply_monster_ac(int damage) else { // apply AC normally - if (def->armour_class > 0) - damage -= random2(1 + def->armour_class); + if (def->ac > 0) + damage -= random2(1 + def->ac); } return (damage); @@ -1288,11 +1312,11 @@ bool melee_attack::player_monattk_hit_effects(bool mondied) if (actor_decapitates_hydra(attacker, defender, damage_done)) return (true); - // These two are mutually exclusive! + // These two (staff damage and damage brand) are mutually exclusive! player_apply_staff_damage(); // Returns true if the monster croaked. - if (player_apply_damage_brand()) + if (apply_damage_brand()) return (true); if (!no_damage_message.empty()) @@ -1305,10 +1329,10 @@ bool melee_attack::player_monattk_hit_effects(bool mondied) defender->name(DESC_NOCAP_THE).c_str()); } - if (!special_damage_message.empty()) + if (needs_message && !special_damage_message.empty()) mprf("%s", special_damage_message.c_str()); - player_sustain_passive_damage(); + hurt_monster(def, special_damage); if (def->hit_points < 1) @@ -1320,25 +1344,97 @@ bool melee_attack::player_monattk_hit_effects(bool mondied) return (false); } -void melee_attack::player_calc_brand_damage( - int res, - const char *message_format) +int melee_attack::resist_adjust_damage(int res, int rawdamage) { - if (res == 0) - special_damage = random2(damage_done) / 2 + 1; + if (res > 0) + { + if (defender->atype() == ACT_MONSTER) + rawdamage = 0; + else + rawdamage /= 1 + res * res; + } else if (res < 0) - special_damage = random2(damage_done) + 1; + rawdamage *= 2; + + if (rawdamage < 0) + rawdamage = 0; - if (special_damage) + return (rawdamage); +} + +void melee_attack::calc_elemental_brand_damage( + int res, + const char *verb) +{ + special_damage = resist_adjust_damage(res, random2(damage_done) / 2 + 1); + + if (special_damage > 0 && verb) { special_damage_message = make_stringf( - message_format, + "%s %s %s%s", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb(verb).c_str(), defender->name(DESC_NOCAP_THE).c_str(), special_attack_punctuation().c_str()); } } -bool melee_attack::player_apply_damage_brand() +int melee_attack::fire_res_apply_cerebov_downgrade(int res) +{ + if (weapon && weapon->special == SPWPN_SWORD_OF_CEREBOV) + --res; + + return (res); +} + +void melee_attack::drain_defender() +{ + // What to do, they're different... + if (defender->atype() == ACT_PLAYER) + drain_player(); + else + drain_monster(); +} + +void melee_attack::drain_player() +{ + drain_exp(); + special_damage = + random2(damage_done) / (2 + defender->res_negative_energy()) + 1; + + // Noop for monsters, but what the heck. + attacker->god_conduct(DID_NECROMANCY, 2); +} + +void melee_attack::drain_monster() +{ + if (defender->res_negative_energy() > 0 || one_chance_in(3)) + return; + + special_damage_message = + make_stringf( + "%s %s %s!", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb("drain").c_str(), + 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); + attacker->god_conduct(DID_NECROMANCY, 2); +} + +bool melee_attack::apply_damage_brand() { // Monster resistance to the brand. int res = 0; @@ -1347,19 +1443,18 @@ bool melee_attack::player_apply_damage_brand() 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; - - player_calc_brand_damage(res, "You burn %s%s"); + res = fire_res_apply_cerebov_downgrade( defender->res_fire() ); + calc_elemental_brand_damage(res, "burn"); + defender->expose_to_element(BEAM_FIRE); break; case SPWPN_FREEZING: - player_calc_brand_damage(mons_res_cold(def), "You freeze %s%s"); + calc_elemental_brand_damage(defender->res_cold(), "freeze"); + defender->expose_to_element(BEAM_COLD); break; case SPWPN_HOLY_WRATH: - switch (mons_holiness(def)) + switch (defender->holiness()) { case MH_UNDEAD: special_damage = 1 + random2(damage_done); @@ -1373,72 +1468,61 @@ bool melee_attack::player_apply_damage_brand() break; } if (special_damage) + { special_damage_message = make_stringf( - "%s convulses%s", + "%s %s%s", defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("convulse").c_str(), special_attack_punctuation().c_str()); + } break; case SPWPN_ELECTROCUTION: - if (mons_flies(def)) + if (defender->levitates()) break; - else if (mons_res_elec(def) > 0) + else if (defender->res_elec() > 0) break; else if (one_chance_in(3)) { - special_damage_message = - "There is a sudden explosion of sparks!"; - special_damage = random2avg(28, 3); + special_damage_message = + defender->atype() == ACT_PLAYER? + "You are electrocuted!" + : "There is a sudden explosion of sparks!"; + special_damage = 10 + random2(15); } break; case SPWPN_ORC_SLAYING: - if (mons_species(def->type) == MONS_ORC) + if (def->mons_species() == MONS_ORC) { special_damage = 1 + random2(damage_done); special_damage_message = make_stringf( - "%s convulses%s", + "%s %s%s", defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("convulse").c_str(), special_attack_punctuation().c_str()); } break; case SPWPN_VENOM: + case SPWPN_STAFF_OF_OLGREB: if (!one_chance_in(4)) { // Poison monster message needs to arrive after hit message. emit_nodmg_hit_message(); - poison_monster(def, true); + + // Weapons of venom do two levels of poisoning to the player, + // but only one level to monsters. + defender->poison( attacker, 2 ); } 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 ); + drain_defender(); break; - + /* 9 = speed - done before */ case SPWPN_VORPAL: special_damage = 1 + random2(damage_done) / 2; @@ -1447,9 +1531,9 @@ bool melee_attack::player_apply_damage_brand() break; case SPWPN_VAMPIRICISM: - if (mons_holiness(def) != MH_NATURAL || - mons_res_negative_energy(def) > 0 || - damage_done < 1 || you.hp == you.hp_max || + if (defender->holiness() != MH_NATURAL || + defender->res_negative_energy() > 0 || + damage_done < 1 || attacker->stat_hp() == attacker->stat_maxhp() || one_chance_in(5)) { break; @@ -1457,44 +1541,68 @@ bool melee_attack::player_apply_damage_brand() // 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) + if (attacker->atype() == ACT_PLAYER) + mpr("You feel better."); + else if (attacker_visible) { - inc_hp(damage_done, false); + if (defender->atype() == ACT_PLAYER) + mprf("%s draws strength from your injuries!", + attacker->name(DESC_CAP_THE).c_str()); + else + mprf("%s is healed.", + attacker->name(DESC_CAP_THE).c_str()); } - else + { - inc_hp(1 + random2(damage_done), false); + int hp_boost = 0; + + // thus is probably more valuable on larger weapons? + if (weapon + && is_fixed_artefact( *weapon ) + && weapon->special == SPWPN_VAMPIRES_TOOTH) + { + hp_boost = damage_done; + } + else + { + hp_boost = 1 + random2(damage_done); + } + + attacker->heal(hp_boost); } + + if (attacker->hunger_level() != HS_ENGORGED) + attacker->make_hungry(-random2avg(59, 2)); - if (you.hunger_state != HS_ENGORGED) - lessen_hunger(random2avg(59, 2), true); - - did_god_conduct( DID_NECROMANCY, 2 ); + attacker->god_conduct( DID_NECROMANCY, 2 ); break; case SPWPN_DISRUPTION: - if (mons_holiness(def) == MH_UNDEAD && !one_chance_in(3)) + if (defender->holiness() == MH_UNDEAD && !one_chance_in(3)) { special_damage_message = - str_simple_monster_message(def, " shudders."); + defender->atype() == ACT_MONSTER? + make_stringf("%s %s.", + defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("shudder").c_str()) + : ("You are blasted by holy energy!"); + 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]) + if (defender->res_negative_energy() <= 0 + && random2(8) <= attacker->skill(SK_NECROMANCY)) { special_damage_message = - str_simple_monster_message(def, " convulses in agony."); - special_damage += random2( 1 + you.skills[SK_NECROMANCY] ); + make_stringf("%s %s in agony.", + defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("writhe").c_str()); + special_damage += random2( 1 + attacker->skill(SK_NECROMANCY) ); } - did_god_conduct(DID_NECROMANCY, 4); + attacker->god_conduct(DID_NECROMANCY, 4); break; case SPWPN_DISTORTION: @@ -1506,10 +1614,12 @@ bool melee_attack::player_apply_damage_brand() if (one_chance_in(5)) { emit_nodmg_hit_message(); - simple_monster_message( - def, - " basks in the translocular energy." ); - heal_monster(def, 1 + random2avg(7, 2), true); // heh heh + special_damage_message = + make_stringf("%s %s in the translocular energy.", + defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("bask").c_str()); + + defender->heal(1 + random2avg(7, 2), true); // heh heh } break; } @@ -1529,7 +1639,7 @@ bool melee_attack::player_apply_damage_brand() special_damage_message = make_stringf( "Space warps horribly around %s!", - ptr_monam(def, DESC_NOCAP_THE)); + defender->name(DESC_NOCAP_THE).c_str()); special_damage += 3 + random2avg(24, 2); break; @@ -1538,27 +1648,35 @@ bool melee_attack::player_apply_damage_brand() if (one_chance_in(3)) { emit_nodmg_hit_message(); - monster_blink(def); + defender->blink(); break; } - if (coinflip()) + // Used to be coinflip() || coinflip() for players, just coinflip() + // for monsters; this is a compromise. Note that it makes banishment + // a touch more likely for players, and a shade less likely for + // monsters. + if (!one_chance_in(3)) { emit_nodmg_hit_message(); - monster_teleport(def, coinflip()); + defender->teleport(coinflip(), one_chance_in(5)); break; } if (coinflip()) { emit_nodmg_hit_message(); - monster_die(def, KILL_RESET, 0); + defender->banish(); return (true); } break; case SPWPN_CONFUSE: { + // FIXME: Generalise. + if (defender->atype() != ACT_MONSTER || attacker->atype() != ACT_PLAYER) + break; + emit_nodmg_hit_message(); // declaring these just to pass to the enchant function @@ -2181,1942 +2299,726 @@ int melee_attack::player_calc_base_weapon_damage() bool melee_attack::mons_attack_mons() { - return (false); + mons_perform_attack(); + if (perceived_attack && (def->foe == MHITNOT || one_chance_in(3)) + && atk->alive()) + { + def->foe = monster_index(atk); + } + return (did_hit); } -bool melee_attack::mons_attack_you() +bool melee_attack::mons_self_destructs() { + if (atk->type == MONS_GIANT_SPORE || atk->type == MONS_BALL_LIGHTNING) + { + atk->hit_points = -1; + return (true); + } return (false); } -int melee_attack::mons_to_hit() +bool melee_attack::mons_attack_warded_off() { - // TODO - return 0; + const int holy = defender->holy_aura(); + if (holy && mons_holiness(atk) == MH_UNDEAD + && !check_mons_resist_magic( atk, holy )) + { + if (needs_message) + { + mprf("%s tries to attack %s, but is repelled by %s holy auro.", + atk->name(DESC_CAP_THE).c_str(), + defender->name(DESC_NOCAP_THE).c_str(), + defender->pronoun(PRONOUN_NOCAP_POSSESSIVE).c_str()); + } + return (true); + } + + // [dshaligram] Note: warding is no longer a simple 50% chance. + const int warding = defender->warding(); + if (warding + && mons_is_summoned(atk) + && !check_mons_resist_magic( atk, warding )) + { + if (needs_message) + { + mprf("%s tries to attack %s, but flinches away.", + atk->name(DESC_CAP_THE).c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + } + return (true); + } + + return (false); } -/////////////////////////////////////////////////////////////////////////// +int melee_attack::mons_attk_delay() +{ + return (weapon? property(*weapon, PWPN_SPEED) : 0); +} -static void tutorial_weapon_check(const item_def *weapon) +bool melee_attack::attack_shield_blocked(bool verbose) { - if (weapon && - (weapon->base_type != OBJ_WEAPONS - || is_range_weapon(*weapon))) + if (!defender_shield) + return (false); + + if (defender->incapacitated()) + return (false); + + const int con_block = random2(attacker->shield_bypass_ability(to_hit) + + defender->shield_block_penalty()); + const int pro_block = defender->shield_bonus(); + + if (pro_block >= con_block) { - learned_something_new(TUT_WIELD_WEAPON); + perceived_attack = true; + + if (needs_message && verbose) + mprf("%s %s %s attack.", + defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("block").c_str(), + attacker->name(DESC_NOCAP_YOUR).c_str()); + + defender->shield_block_succeeded(); + + return (true); } + + return (false); } -// Returns true if you hit the monster. -bool you_attack(int monster_attacked, bool unarmed_attacks) +int melee_attack::mons_calc_damage(const mon_attack_def &attk) { - monsters *defender = &menv[monster_attacked]; - melee_attack attk(&you, defender, unarmed_attacks); + int damage = 0; + int damage_max = 0; + if (weapon + && weapon->base_type == OBJ_WEAPONS + && !is_range_weapon(*weapon)) + { + damage_max = property( *weapon, PWPN_DAMAGE ); + damage += random2( damage_max ); - // We're trying to hit a monster, break out of travel/explore now. - interrupt_activity(AI_HIT_MONSTER, defender); + if (get_equip_race(*weapon) == ISFLAG_ORCISH + && mons_species(atk->type) == MONS_ORC + && coinflip()) + { + damage++; + } - // For tutorials, check if the player is fighting with something unsuitable - tutorial_weapon_check(attk.weapon); + if (weapon->plus2 >= 0) + damage += random2( weapon->plus2 ); + else + damage -= random2( 1 - weapon->plus2 ); - return attk.attack(); + damage -= 1 + random2(3); + } + + damage_max += attk.damage; + damage += 1 + random2(attk.damage); + + if (water_attack) + damage *= 2; + + return (mons_apply_defender_ac(damage, damage_max)); } -static void mons_lose_attack_energy(monsters *attacker, int wpn_speed, - int which_attack) +int melee_attack::mons_apply_defender_ac(int damage, int damage_max) { - // speed adjustment for weapon using monsters - if (wpn_speed > 0) + int ac = defender->armour_class(); + if (ac > 0) { - // only get one third penalty/bonus for second weapons. - if (which_attack > 0) - wpn_speed = (20 + wpn_speed) / 3; + int damage_reduction = random2(ac + 1); + if (!defender->wearing_light_armour()) + { + if (const item_def *arm = defender->slot_item(EQ_BODY_ARMOUR)) + { + const int armac = property(*arm, PARM_AC); + int perc = 2 * (defender->skill(SK_ARMOUR) + armac); + if (perc > 50) + perc = 50; - attacker->speed_increment -= (wpn_speed - 10) / 2; + int min = 1 + (damage_max * perc) / 100; + if (min > ac / 2) + min = ac / 2; + + if (damage_reduction < min) + damage_reduction = min; + } + } + damage -= damage_reduction; } + + if (damage < 1) + damage = 0; + + return damage; } -void monster_attack(int monster_attacking) +std::string melee_attack::mons_attack_verb(const mon_attack_def &attk) { - struct monsters *attacker = &menv[monster_attacking]; + static const char *attack_types[] = + { + "", + "hit", // including weapon attacks + "bite", + "sting", - int damage_taken = 0; - bool hit = false; - bool blocked = false; + // spore + "hit", + + "touch", + "engulf", + "claw", + "tail slap" + }; - // being attacked by a water creature while standing in water? - bool water_attack = false; + return attack_types[ attk.type ]; +} - bool bearing_shield = (you.equip[EQ_SHIELD] != -1); +std::string melee_attack::mons_weapon_desc() +{ + if (weapon) + return make_stringf(" with %s", item_name(*weapon, DESC_NOCAP_A)); - int mmov_x = 0; - int specdam = 0; - char heads = 0; // for hydras {dlb} - int hand_used = 0; - int extraDamage = 0; // from special mon. attacks (burn, freeze, etc) - int resistValue = 0; // player resist value (varies) - int wpn_speed; - char str_pass[ ITEMNAME_SIZE ]; + return (""); +} -#if DEBUG_DIAGNOSTICS - char st_prn[ 20 ]; -#endif +std::string melee_attack::mons_defender_name() +{ + if (attacker == defender) + return attacker->pronoun(PRONOUN_REFLEXIVE); + else + return defender->name(DESC_NOCAP_THE); +} - if (attacker->type == MONS_HYDRA) - heads = attacker->number; +void melee_attack::mons_announce_hit(const mon_attack_def &attk) +{ + if (water_attack && attacker_visible && attacker != defender) + mprf("%s uses the watery terrain to its advantage.", + attacker->name(DESC_CAP_THE).c_str()); + + mprf("%s %s %s%s%s%s", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb( mons_attack_verb(attk) ).c_str(), + mons_defender_name().c_str(), + debug_damage_number().c_str(), + mons_weapon_desc().c_str(), + attack_strength_punctuation().c_str()); +} - if (mons_friendly(attacker)) - return; +void melee_attack::mons_announce_dud_hit(const mon_attack_def &attk) +{ + mprf("%s %s %s but doesn't do any damage.", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb( mons_attack_verb(attk) ).c_str(), + mons_defender_name().c_str()); +} - if (attacker->type == MONS_GIANT_SPORE - || attacker->type == MONS_BALL_LIGHTNING) +void melee_attack::check_defender_train_dodging() +{ + if (defender->wearing_light_armour(false) + && attacker_visible + && one_chance_in(3)) { - attacker->hit_points = -1; - return; + perceived_attack = true; + defender->exercise(SK_DODGING, 1); } +} - // if a friend wants to help, they can attack - if (you.pet_target == MHITNOT) - you.pet_target = monster_attacking; - - if (mons_has_ench( attacker, ENCH_SUBMERGED )) +void melee_attack::check_defender_train_armour() +{ + if (defender->wearing_light_armour()) return; + + const item_def *arm = defender->slot_item(EQ_BODY_ARMOUR); + if (arm && coinflip() && random2(1000) <= item_mass(*arm)) + defender->exercise(SK_ARMOUR, coinflip()? 2 : 1); +} - // If a mimic is attacking the player, it is thereafter known. - if (mons_is_mimic(attacker->type)) - attacker->flags |= MF_KNOWN_MIMIC; +void melee_attack::mons_set_weapon(const mon_attack_def &attk) +{ + weapon = attk.type == AT_HIT? attacker->weapon(attack_number) : NULL; + damage_brand = attacker->damage_brand(attack_number); +} - if (you.duration[DUR_REPEL_UNDEAD] - && mons_holiness( attacker ) == MH_UNDEAD - && !check_mons_resist_magic( attacker, you.piety )) - { - if (simple_monster_message( - attacker, - " tries to attack you, but is repelled by your holy aura.")) - interrupt_activity( AI_MONSTER_ATTACKS, attacker ); +void melee_attack::mons_do_poison(const mon_attack_def &attk) +{ + if (defender->res_poison() > 0) return; - } - - if (wearing_amulet(AMU_WARDING) - || (you.religion == GOD_VEHUMET && you.duration[DUR_PRAYER] - && (!player_under_penance() && you.piety >= piety_breakpoint(2)))) + + if (attk.flavour == AF_POISON_NASTY + || one_chance_in( 15 + 5 * (attk.flavour == AF_POISON) ) + || (damage_done > 2 + && one_chance_in( attk.flavour == AF_POISON? 4 : 3 ))) { - if (mons_has_ench(attacker, ENCH_ABJ_I, ENCH_ABJ_VI)) + if (needs_message) { - // should be scaled {dlb} - if (coinflip()) + if (defender->atype() == ACT_PLAYER + && (attk.type == AT_BITE || attk.type == AT_STING)) { - if (simple_monster_message( - attacker, - " tries to attack you, but flinches away.")) - interrupt_activity( AI_MONSTER_ATTACKS, attacker ); - return; + mprf("%s %s was poisonous!", + attacker->name(DESC_CAP_YOUR).c_str(), + mons_attack_verb(attk).c_str()); } + else + mprf("%s poisons %s!", + attacker->name(DESC_CAP_THE).c_str(), + defender->name(DESC_NOCAP_THE).c_str()); } - } - if (grd[attacker->x][attacker->y] == DNGN_SHALLOW_WATER - && !mons_flies( attacker ) - && !mons_class_flag( attacker->type, M_AMPHIBIOUS ) - && monster_habitat( attacker->type ) == DNGN_FLOOR - && one_chance_in(4)) - { - if (simple_monster_message(attacker, " splashes around in the water.")) - interrupt_activity( AI_MONSTER_ATTACKS, attacker ); - return; - } + int amount = 1; + if (attk.flavour == AF_POISON_NASTY) + amount++; + else if (attk.flavour == AF_POISON_MEDIUM) + amount += random2(3); + else if (attk.flavour == AF_POISON_STRONG) + amount += roll_dice(2, 5); - if (player_in_water() - && !player_is_swimming() - && monster_habitat( attacker->type ) == DNGN_DEEP_WATER) - { - water_attack = true; - simple_monster_message(attacker, - " uses the watery terrain to its advantage."); + defender->poison( attacker, amount ); } +} + +void melee_attack::wasp_paralyse_defender() +{ + // [dshaligram] Adopted 4.1.2's wasp mechanics, in slightly modified form. + if (attacker->id() == MONS_RED_WASP) + defender->poison( attacker, coinflip()? 2 : 1 ); + + if (!defender->res_poison() && one_chance_in( damage_done > 4? 3 : 20 )) + defender->paralyse( roll_dice(1, 3) ); + else + defender->slow_down( roll_dice(1, 3) ); +} + +void melee_attack::splash_monster_with_acid(int strength) +{ + special_damage += roll_dice(2, 4); + if (needs_message) + mprf("%s is splashed with acid.", defender->name(DESC_CAP_THE).c_str()); +} - char runthru; - bool player_perceives_attack = false; +void melee_attack::splash_defender_with_acid(int strength) +{ + if (defender->atype() == ACT_PLAYER) + splash_with_acid(strength); + else + splash_monster_with_acid(strength); +} - for (runthru = 0; runthru < 4; runthru++) +void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk) +{ + // Most of this is from BWR 4.1.2. + + int res = 0; + switch (attk.flavour) { - blocked = false; - wpn_speed = 0; // 0 = didn't attack w/ weapon + default: + break; + + case AF_POISON: + case AF_POISON_NASTY: + case AF_POISON_MEDIUM: + case AF_POISON_STRONG: + mons_do_poison(attk); + break; - if (attacker->type == MONS_HYDRA) + case AF_POISON_STR: + res = defender->res_poison(); + if (res <= 0) { - if (heads < 1) - break; - runthru = 0; - heads--; + defender->poison( attacker, roll_dice(1,3) ); + if (one_chance_in(4)) + defender->drain_stat( STAT_STRENGTH, 1 ); } + break; - char mdam = mons_damage( attacker->type, runthru ); + case AF_ROT: + if (one_chance_in(20) || (damage_done > 2 && one_chance_in(3))) + defender->rot( attacker, 2 + random2(3), damage_done > 5 ); + break; - if (attacker->type == MONS_ZOMBIE_SMALL - || attacker->type == MONS_ZOMBIE_LARGE - || attacker->type == MONS_SKELETON_SMALL - || attacker->type == MONS_SKELETON_LARGE - || attacker->type == MONS_SIMULACRUM_SMALL - || attacker->type == MONS_SIMULACRUM_LARGE - || attacker->type == MONS_SPECTRAL_THING) - { - mdam = mons_damage(attacker->number, runthru); - - // these are cumulative, of course: {dlb} - if (mdam > 1) - mdam--; - if (mdam > 4) - mdam--; - if (mdam > 11) - mdam--; - if (mdam > 14) - mdam--; - } + case AF_DISEASE: + if (defender->atype() == ACT_PLAYER) + disease_player( 50 + random2(100) ); + break; - if (mdam == 0) - break; + case AF_FIRE: + if (atk->type == MONS_FIRE_VORTEX) + atk->hit_points = -10; - if ((attacker->type == MONS_TWO_HEADED_OGRE - || attacker->type == MONS_ETTIN) - && runthru == 1) - { - hand_used = 1; - } + special_damage = + resist_adjust_damage(defender->res_fire(), + atk->hit_dice + random2(atk->hit_dice)); + if (needs_message && special_damage) + mprf("%s %s engulfed in flames%s", + defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("are").c_str(), + special_attack_punctuation().c_str()); - damage_taken = 0; + defender->expose_to_element(BEAM_FIRE, 2); + break; + + case AF_COLD: + special_damage = + resist_adjust_damage(defender->res_cold(), + atk->hit_dice + random2( 2 * atk->hit_dice )); + if (needs_message && special_damage) + mprf("%s %s %s!", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb("freeze").c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + break; - int mons_to_hit = 16 + attacker->hit_dice; //* attacker->hit_dice;//* 3 + case AF_ELEC: + special_damage = + resist_adjust_damage(defender->res_elec(), + atk->hit_dice + random2( 2 * atk->hit_dice )); + if (defender->levitates()) + special_damage = special_damage * 2 / 3; + + if (needs_message && special_damage) + mprf("%s %s %s!", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb("shock").c_str(), + defender->name(DESC_NOCAP_THE).c_str()); + break; - if (water_attack) - mons_to_hit += 5; + case AF_VAMPIRIC: + if (defender->res_negative_energy() > random2(3)) + break; - if (attacker->inv[hand_used] != NON_ITEM - && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS) + if (defender->stat_hp() < defender->stat_maxhp()) { - mons_to_hit += mitm[attacker->inv[hand_used]].plus; + defender->heal(1 + random2(damage_done), coinflip()); - mons_to_hit += property( mitm[attacker->inv[hand_used]], PWPN_HIT ); + if (needs_message) + { + mprf("%s %s strength from %s injuries!", + attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb("draw").c_str(), + defender->name(DESC_NOCAP_YOUR).c_str()); + } - wpn_speed = property( mitm[attacker->inv[hand_used]], PWPN_SPEED ); + // 4.1.2 actually drains max hp; we're being nicer and just doing + // a rot effect. + if ((damage_done > 6 && one_chance_in(3)) || one_chance_in(20)) + { + if (defender->atype() == ACT_PLAYER) + mprf("You feel less resilient."); + defender->rot( attacker, 0, coinflip()? 2 : 1 ); + } } + break; - // Factors against blocking - // [dshaligram] Scaled back HD effect to 50% of previous, reduced - // shield_blocks multiplier to 5. - const int con_block = - random2(15 + attacker->hit_dice / 2 - + (5 * you.shield_blocks * you.shield_blocks)); - - // Factors for blocking: - // [dshaligram] Added weighting for shields skill, increased dex bonus - // from .2 to .25 - const int pro_block = - random2(player_shield_class()) - + (random2(you.dex) / 4) - + (random2(skill_bump(SK_SHIELDS)) / 4) - - 1; - - if (!you.paralysis && !you_are_delayed() && !you.conf - && player_monster_visible( attacker ) - && player_shield_class() > 0 - && con_block <= pro_block) + case AF_DRAIN_STR: + if ((one_chance_in(20) || (damage_done > 0 && one_chance_in(3))) + && defender->res_negative_energy() < random2(4)) { - you.shield_blocks++; + defender->drain_stat(STAT_STRENGTH, 1); + } + break; - snprintf( info, INFO_SIZE, "You block %s's attack.", - ptr_monam( attacker, DESC_NOCAP_THE ) ); + case AF_DRAIN_DEX: + if ((one_chance_in(20) || (damage_done > 0 && one_chance_in(3))) + && defender->res_negative_energy() < random2(4)) + { + defender->drain_stat(STAT_DEXTERITY, 1); + } + break; - mpr(info); + case AF_HUNGER: + if (defender->holiness() == MH_UNDEAD) + break; - blocked = true; - hit = false; - player_perceives_attack = true; + if (one_chance_in(20) || (damage_done > 0 && coinflip())) + defender->make_hungry(400, false); + break; - if (bearing_shield && one_chance_in(4)) - exercise(SK_SHIELDS, 1); - } - else if (player_light_armour(true) && one_chance_in(3)) + case AF_BLINK: + if (one_chance_in(3)) { - exercise(SK_DODGING, 1); + mprf("%s %s!", attacker->name(DESC_CAP_THE).c_str(), + attacker->conj_verb("blink").c_str()); + attacker->blink(); } + break; - const int player_dodge = random2limit(player_evasion(), 40) - + random2(you.dex) / 3 - - (player_monster_visible(attacker) ? 2 : 14) - - (you_are_delayed() ? 5 : 0); - - if (!blocked - && (random2(mons_to_hit) >= player_dodge || one_chance_in(30))) + case AF_CONFUSE: + if (attk.type == AT_SPORE) { - hit = true; + if (defender->res_poison()) + break; - int damage_size = 0; + if (--atk->hit_dice <= 0) + atk->hit_points = -1; - if (attacker->inv[hand_used] != NON_ITEM - && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS - && (mitm[attacker->inv[hand_used]].sub_type < WPN_SLING - || mitm[attacker->inv[hand_used]].sub_type > WPN_CROSSBOW)) - { - damage_size = property( mitm[attacker->inv[hand_used]], - PWPN_DAMAGE ); - - damage_taken = random2(damage_size); - - if (get_equip_race(mitm[attacker->inv[hand_used]]) == ISFLAG_ORCISH - && mons_species(attacker->type) == MONS_ORC - && coinflip()) - { - damage_taken++; - } - - if (mitm[attacker->inv[hand_used]].plus2 >= 0) - { - /* + or 0 to-dam */ - damage_taken += random2(mitm[attacker->inv[hand_used]].plus2 + 1); - } - else - { - /* - to-dam */ - damage_taken -= (random2(1 + abs(mitm[attacker->inv[hand_used]].plus2))); - } - - damage_taken -= 1 + random2(3); //1; - } - - damage_size += mdam; - damage_taken += 1 + random2(mdam); - - if (water_attack) - damage_taken *= 2; - - int ac = player_AC(); - - if (ac > 0) - { - int damage_reduction = random2(ac + 1); - - if (!player_light_armour()) - { - const int body_arm_ac = property( you.inv[you.equip[EQ_BODY_ARMOUR]], - PARM_AC ); - - int percent = 2 * (you.skills[SK_ARMOUR] + body_arm_ac); - - if (percent > 50) - percent = 50; - - int min = 1 + (damage_size * percent) / 100; - - if (min > ac / 2) - min = ac / 2; - - if (damage_reduction < min) - damage_reduction = min; - } - - damage_taken -= damage_reduction; - } - - if (damage_taken < 1) - damage_taken = 0; - - } - else if (!blocked) - { - hit = false; - if (simple_monster_message(attacker, " misses you.")) - player_perceives_attack = true; - } - - if ((hit && !blocked) || damage_taken > 0) - player_perceives_attack = true; - - if (damage_taken < 1 && hit && !blocked) - { - mprf("%s hits you but doesn't do any damage.", - ptr_monam(attacker, DESC_CAP_THE)); - } - - if (damage_taken > 0) - { - hit = true; - - mmov_x = attacker->inv[hand_used]; - - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " hits you"); - -#if DEBUG_DIAGNOSTICS - strcat(info, " for "); - // note: doesn't take account of special weapons etc - itoa( damage_taken, st_prn, 10 ); - strcat( info, st_prn ); -#endif - - if (attacker->type != MONS_DANCING_WEAPON && mmov_x != NON_ITEM - && mitm[mmov_x].base_type == OBJ_WEAPONS - && !is_range_weapon( mitm[mmov_x] )) - { - strcat(info, " with "); - it_name(mmov_x, DESC_NOCAP_A, str_pass); // was 7 - strcat(info, str_pass); - } - - strcat(info, "!"); - - mpr( info, MSGCH_PLAIN ); - - if (hit) - { - if (you.equip[EQ_BODY_ARMOUR] != -1) - { - const int body_arm_mass = item_mass( you.inv[you.equip[EQ_BODY_ARMOUR]] ); - - // Being generous here...this can train both Armour - // and Dodging. - if (!player_light_armour(false) && coinflip() - && random2(1000) <= body_arm_mass) - { - // raised from 1 {bwross} - exercise(SK_ARMOUR, (coinflip() ? 2 : 1)); - } - } - } - - /* special attacks: */ - int mclas = attacker->type; - - if (mclas == MONS_KILLER_KLOWN) - { - switch (random2(6)) - { - case 0: - // comment and enum do not match {dlb} - mclas = MONS_SNAKE; // scorp - break; - case 1: - mclas = MONS_NECROPHAGE; - break; - case 2: - mclas = MONS_WRAITH; - break; - case 3: - mclas = MONS_FIRE_ELEMENTAL; - break; - case 4: - mclas = MONS_ICE_BEAST; - break; - case 5: - mclas = MONS_PHANTOM; - break; - } - } - - switch (mclas) - { - case MONS_GILA_MONSTER: - case MONS_GIANT_ANT: - case MONS_WOLF_SPIDER: - case MONS_REDBACK: - if (player_res_poison()) - break; - - if (one_chance_in(20) - || (damage_taken > 3 && one_chance_in(4))) - { - simple_monster_message( attacker, - "'s bite was poisonous!" ); - - if (attacker->type == MONS_REDBACK) - poison_player( random2avg(9, 2) + 3 ); - else - poison_player(1); - } - break; - - case MONS_KILLER_BEE: - case MONS_BUMBLEBEE: - if (!player_res_poison() - && (one_chance_in(20) - || (damage_taken > 2 && one_chance_in(3)))) - - { - simple_monster_message( attacker, " stings you!" ); - - if (attacker->type == MONS_BUMBLEBEE) - poison_player( random2(3) ); - else - poison_player(1); - } - break; - - case MONS_ROTTING_DEVIL: - case MONS_NECROPHAGE: - case MONS_GHOUL: - case MONS_DEATH_OOZE: - if (you.is_undead) - break; - - // both sides call random2() - looking familiar by now {dlb} - if (one_chance_in(20) || (damage_taken > 2 && one_chance_in(3))) - { - rot_player( 2 + random2(3) ); - - if (damage_taken > 5) - rot_hp(1); - } - - if (one_chance_in(4)) - disease_player( 50 + random2(100) ); - break; - - case MONS_KOMODO_DRAGON: - case MONS_GIANT_MOSQUITO: - if (!one_chance_in(3)) - disease_player( 50 + random2(100) ); - break; - - case MONS_FIRE_VORTEX: - attacker->hit_points = -10; - // fall through -- intentional? {dlb} - case MONS_FIRE_ELEMENTAL: - case MONS_BALRUG: - case MONS_SUN_DEMON: - strcpy(info, "You are engulfed in flames"); - - resistValue = player_res_fire(); - extraDamage = 15 + random2(15); - if (resistValue > 0) - { - extraDamage /= (1 + resistValue * resistValue); - } - else - { - if (resistValue < 0) - extraDamage += 8 + random2(8); - } - - strcat(info, (extraDamage < 10) ? "." : - (extraDamage < 25) ? "!" : - "!!"); - - mpr(info); - - if (you.duration[DUR_CONDENSATION_SHIELD] > 0) - { - mpr("Your icy shield dissipates!", MSGCH_DURATION); - you.duration[DUR_CONDENSATION_SHIELD] = 0; - you.redraw_armour_class = 1; - } - - damage_taken += extraDamage; - expose_player_to_element(BEAM_FIRE, 1); - break; - - case MONS_SMALL_SNAKE: - case MONS_SNAKE: - case MONS_GIANT_MITE: - case MONS_GOLD_MIMIC: - case MONS_WEAPON_MIMIC: - case MONS_ARMOUR_MIMIC: - case MONS_SCROLL_MIMIC: - case MONS_POTION_MIMIC: - if (!player_res_poison() - && (one_chance_in(20) - || (damage_taken > 2 && one_chance_in(4)))) - { - poison_player(1); - } - break; - - case MONS_QUEEN_BEE: - case MONS_GIANT_CENTIPEDE: - case MONS_SOLDIER_ANT: - case MONS_QUEEN_ANT: - if (!player_res_poison()) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings you!"); - mpr(info); - - poison_player(2); - } - break; - - case MONS_SCORPION: - case MONS_BROWN_SNAKE: - case MONS_BLACK_SNAKE: - case MONS_YELLOW_SNAKE: - case MONS_SPINY_FROG: - if (!player_res_poison() - && (one_chance_in(15) - || (damage_taken > 2 && one_chance_in(4)))) - // ^^^yep, this should be a function^^^ {dlb} - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " poisons you!"); - mpr(info); - - poison_player(1); - } - break; - - case MONS_SHADOW_DRAGON: - case MONS_SPECTRAL_THING: - if (coinflip()) - break; - // fall-through {dlb} - case MONS_WIGHT: // less likely because wights do less damage - case MONS_WRAITH: - - // enum does not match comment 14jan2000 {dlb} - case MONS_SOUL_EATER: // shadow devil - - // enum does not match comment 14jan2000 {dlb} - case MONS_SPECTRAL_WARRIOR: // spectre - - case MONS_SHADOW_FIEND: - case MONS_ORANGE_RAT: - case MONS_SHADOW_WRAITH: - case MONS_ANCIENT_LICH: - case MONS_LICH: - case MONS_BORIS: - if (one_chance_in(30) || (damage_taken > 5 && coinflip())) - drain_exp(); - break; - - - case MONS_RED_WASP: - if (!player_res_poison()) - poison_player( (coinflip() ? 2 : 1) ); - // intentional fall-through {dlb} - case MONS_YELLOW_WASP: - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings you."); - mpr(info); - - if (!player_res_poison() - && (one_chance_in(20) - || (damage_taken > 2 && !one_chance_in(3)))) - // maybe I should flip back the other way? {dlb} - { - if (you.paralysis > 0) - mpr("You still can't move!", MSGCH_WARN); - else - mpr("You suddenly lose the ability to move!", - MSGCH_WARN); - if ( you.paralysis == 0 || mclas == MONS_RED_WASP ) - you.paralysis += 1 + random2(3); - } - break; - - case MONS_SPINY_WORM: - if (!player_res_poison()) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings you!"); - mpr(info); - - poison_player( 2 + random2(4) ); - } - // intentional fall-through {dlb} - case MONS_BROWN_OOZE: - case MONS_ACID_BLOB: - case MONS_ROYAL_JELLY: - case MONS_JELLY: - mpr("You are splashed with acid!"); - splash_with_acid(3); - break; - - case MONS_SIMULACRUM_SMALL: - case MONS_SIMULACRUM_LARGE: - resistValue = player_res_cold(); - if (resistValue > 0) - extraDamage = 0; - else if (resistValue == 0) - { - extraDamage += roll_dice( 1, 4 ); - mprf("%s chills you.", ptr_monam(attacker, DESC_CAP_THE)); - } - else if (resistValue < 0) - { - extraDamage = roll_dice( 2, 4 ); - mprf("%s freezes you.", ptr_monam(attacker, DESC_CAP_THE)); - } - - damage_taken += extraDamage; - expose_player_to_element(BEAM_COLD, 1); - break; - - case MONS_ICE_DEVIL: - case MONS_ICE_BEAST: - case MONS_FREEZING_WRAITH: - case MONS_ICE_FIEND: - case MONS_WHITE_IMP: - case MONS_ANTAEUS: - case MONS_AZURE_JELLY: - extraDamage = attacker->hit_dice + random2(attacker->hit_dice * 2); - resistValue = player_res_cold(); - - if (resistValue > 0) - { - extraDamage /= (1 + resistValue * resistValue); - } - - if (resistValue < 0) - { - extraDamage += attacker->hit_dice + - random2(attacker->hit_dice * 2); - } - - if (extraDamage > 4) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - if (extraDamage < 10) - strcat(info, " chills you."); - else - strcat(info, " freezes you!"); - if (extraDamage > 19) - strcat(info, "!"); - mpr(info); - } - - damage_taken += extraDamage; - - expose_player_to_element(BEAM_COLD, 1); - break; - - case MONS_ELECTRIC_GOLEM: - if (!player_res_electricity()) - { - damage_taken += attacker->hit_dice - + random2(attacker->hit_dice * 2); - - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " shocks you!"); - mpr(info); - } - break; - - case MONS_VAMPIRE: - if (you.is_undead) - break; - -/* ****************************************************************** - if ( damage_taken > 6 && one_chance_in(3) || !one_chance_in(20)) - { - mpr("You feel less resilient."); - you.hp_max -= ( coinflip() ? 2 : 1 ); - deflate_hp(you.hp_max, false); - heal_monster(attacker, 5 + random2(8), true); - } -****************************************************************** */ - - // heh heh {dlb} - // oh, this is mean! {gdl} - if (heal_monster(attacker, random2(damage_taken), true)) - simple_monster_message(attacker, " draws strength from your injuries!"); - - break; - - case MONS_SHADOW: - if (player_prot_life() <= random2(3) - && (one_chance_in(20) - || (damage_taken > 0 && one_chance_in(3)))) - { - lose_stat(STAT_STRENGTH, 1); - } - break; - - case MONS_HUNGRY_GHOST: - if (you.is_undead == US_UNDEAD) - break; - - if (one_chance_in(20) || (damage_taken > 0 && coinflip())) - make_hungry(400, false); - break; - - case MONS_GUARDIAN_NAGA: - break; - - case MONS_PHANTOM: - case MONS_INSUBSTANTIAL_WISP: - case MONS_BLINK_FROG: - case MONS_MIDGE: - if (one_chance_in(3)) - { - simple_monster_message(attacker, " blinks."); - monster_blink(attacker); - } - break; - - case MONS_JELLYFISH: - case MONS_ORANGE_DEMON: - // if ( !one_chance_in(3) ) break; - if (player_res_poison()) - break; - - if (attacker->type == MONS_ORANGE_DEMON - && (!one_chance_in(4) || runthru != 1)) - { - break; - } - - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings you!"); - mpr(info); - - poison_player(1); - lose_stat(STAT_STRENGTH, 1); - break; - - case MONS_PULSATING_LUMP: - if (one_chance_in(3)) - { - if (one_chance_in(5)) - mutate(100); - else - give_bad_mutation(); - } - break; - - case MONS_MOTH_OF_WRATH: - if (one_chance_in(3)) - { - simple_monster_message(attacker, " infuriates you!"); - go_berserk(false); - } - break; - - default: - break; - } // end of switch for special attacks. - /* use break for level drain, maybe with beam variables, - because so many creatures use it. */ - } - - /* special weapons */ - if (hit - && (attacker->inv[hand_used] != NON_ITEM - || ((attacker->type == MONS_PLAYER_GHOST - || attacker->type == MONS_PANDEMONIUM_DEMON) - && ghost.values[ GVAL_BRAND ] != SPWPN_NORMAL))) - { - unsigned char itdam; - - if (attacker->type == MONS_PLAYER_GHOST - || attacker->type == MONS_PANDEMONIUM_DEMON) - { - itdam = ghost.values[ GVAL_BRAND ]; - } - else - { - const item_def& mons_weapon = mitm[attacker->inv[hand_used]]; - if ( is_range_weapon(mons_weapon) ) - itdam = SPWPN_NORMAL; - else - itdam = mons_weapon.special; - } - - specdam = 0; - - switch (itdam) - { - case SPWPN_NORMAL: - default: - break; - - case SPWPN_SWORD_OF_CEREBOV: - case SPWPN_FLAMING: - specdam = 0; - resistValue = player_res_fire(); - - if (itdam == SPWPN_SWORD_OF_CEREBOV) - resistValue -= 1; - - if (resistValue > 0) - { - damage_taken += (random2(damage_taken) / 2 + 1) / - (1 + (resistValue * resistValue)); - } - - if (resistValue <= 0) - specdam = random2(damage_taken) / 2 + 1; - - if (resistValue < 0) - specdam += random2(damage_taken) / 2 + 1; - - if (specdam) - { - simple_monster_message(attacker, " burns you."); -/* ********************** - -commented out for now - if (specdam < 3) - strcat(info, "."); - if (specdam >= 3 && specdam < 7) - strcat(info, "!"); - if (specdam >= 7) - strcat(info, "!!"); - -*********************** */ - } - - if (you.duration[DUR_CONDENSATION_SHIELD] > 0) - { - mpr("Your icy shield dissipates!", MSGCH_DURATION); - you.duration[DUR_CONDENSATION_SHIELD] = 0; - you.redraw_armour_class = 1; - } - break; - - case SPWPN_FREEZING: - specdam = 0; - resistValue = player_res_cold(); - - if (resistValue <= 0) - specdam = random2(damage_taken) / 2 + 1; - - if (resistValue < 0) - specdam += random2(damage_taken) / 2 + 1; - - if (resistValue > 0) - { - damage_taken += (random2(damage_taken) / 2 + 1) / - (1 + (resistValue * resistValue)); - } - - if (specdam) - { - simple_monster_message(attacker, " freezes you."); - -/* ********************** - -commented out for now - if (specdam < 3) - strcat(info, "."); - if (specdam >= 3 && specdam < 7) - strcat(info, "!"); - if (specdam >= 7) - strcat(info, "!!"); - -*********************** */ - } - break; - - - case SPWPN_HOLY_WRATH: - if (attacker->type == MONS_PLAYER_GHOST) - break; // ghosts can't wield holy wrath - - if (you.is_undead) - { - specdam = random2(damage_taken); - - if (specdam) - { - strcpy(info, "The wound is extremely painful"); - - if (specdam < 3) - strcat(info, "."); - else if (specdam < 7) - strcat(info, "!"); - else - strcat(info, "!!"); - - mpr(info); - } - } - break; - - case SPWPN_ELECTROCUTION: - // This runs the risk of making levitation into a - // cheap version of the Resist spell (with added - // bonuses), so it shouldn't be used anywhere else, - // and should possibly be removed from this case as - // well. -- bwr - if (player_is_levitating()) // you're not grounded - break; - - if (player_res_electricity()) // resist lightning - break; - - specdam = 0; - - // This is related to old code where elec wpns had charges -#if 0 - if (menv[monster_attacking].type != MONS_PLAYER_GHOST - && (mitm[attacker->inv[hand_used]].plus2 <= 0 - || item_cursed( mitm[attacker->inv[hand_used]] ))) - { - break; - } -#endif - - if (one_chance_in(3)) - { - mpr("You are electrocuted!"); - specdam += 10 + random2(15); - } - break; - - case SPWPN_ORC_SLAYING: - if (you.species == SP_HILL_ORC) - { - specdam = random2(damage_taken); - - if (specdam) - { - strcpy(info, "The wound is extremely painful"); - - if (specdam < 3) - strcat(info, "."); - else if (specdam < 7) - strcat(info, "!"); - else - strcat(info, "!!"); - - mpr(info); - } - } - break; - - case SPWPN_STAFF_OF_OLGREB: - case SPWPN_VENOM: - if (!player_res_poison() && one_chance_in(3)) - { - simple_monster_message(attacker, - (attacker->type == MONS_DANCING_WEAPON) - ? " is poisoned!" : "'s weapon is poisoned!"); - - poison_player(2); - } - break; - - case SPWPN_PROTECTION: - break; - - case SPWPN_DRAINING: - drain_exp(); - specdam = random2(damage_taken) / (2 + player_prot_life()) + 1; - break; - - case SPWPN_SPEED: - wpn_speed = (wpn_speed + 1) / 2; - break; - - case SPWPN_VORPAL: - specdam = 1 + (random2(damage_taken) / 2); - break; - - case SPWPN_VAMPIRES_TOOTH: - case SPWPN_VAMPIRICISM: - specdam = 0; // note does no extra damage - - if (you.is_undead) - break; - - if (one_chance_in(5)) - break; - - // heh heh {dlb} - if (heal_monster(attacker, 1 + random2(damage_taken), true)) - simple_monster_message(attacker, " draws strength from your injuries!"); - break; - - case SPWPN_DISRUPTION: - if (attacker->type == MONS_PLAYER_GHOST) - break; - - if (you.is_undead) - { - specdam = random2(damage_taken) + random2(damage_taken) - + random2(damage_taken) + random2(damage_taken); - - if (specdam) - { - strcpy(info, "You are blasted by holy energy"); - - if (specdam < 7) - strcat(info, "."); - else if (specdam < 15) - strcat(info, "!"); - else - strcat(info, "!!"); - - mpr(info); - } - } - break; - - - case SPWPN_DISTORTION: - if (one_chance_in(3)) - { - mpr("Your body is twisted painfully."); - specdam += 1 + random2avg(7, 2); - break; - } - - if (one_chance_in(3)) - { - mpr("Your body is terribly warped!"); - specdam += 3 + random2avg(24, 2); - break; - } - - if (one_chance_in(3)) - { - random_blink(true); - break; - } - - if (coinflip()) - { - you_teleport(); - break; - } - - if (coinflip()) - { - you_teleport2( true, one_chance_in(5) ); - break; - } + if (needs_message) + mprf("%s %s engulfed in a cloud of spores!", + defender->name(DESC_CAP_THE).c_str(), + defender->conj_verb("are").c_str()); + } - if (coinflip() && you.level_type != LEVEL_ABYSS) - { - you.banished = true; - break; - } - break; - } // end of switch - } // end of special weapons + if (one_chance_in(10) + || (damage_done > 2 && one_chance_in(3))) + { + defender->confuse( 1 + random2( 3 + atk->hit_dice ) ); + } + break; - damage_taken += specdam; + case AF_DRAIN_XP: + if (attacker->id() == MONS_SPECTRAL_THING && coinflip()) + break; - if (damage_taken > 0) + if (one_chance_in(30) + || (damage_done > 5 && coinflip()) + || (attk.damage == 0 && !one_chance_in(3))) { - ouch(damage_taken, monster_attacking, KILLED_BY_MONSTER); - - if (you.religion == GOD_XOM && you.hp <= you.hp_max / 3 - && one_chance_in(10)) - { - Xom_acts(true, you.experience_level, false); - } + drain_defender(); } + + break; - mons_lose_attack_energy(attacker, wpn_speed, runthru); - } // end of for runthru - - if (player_perceives_attack) - interrupt_activity(AI_MONSTER_ATTACKS, attacker); + case AF_PARALYSE: + // Only wasps at the moment. + wasp_paralyse_defender(); + break; - return; -} // end monster_attack() + case AF_ACID: + if (attacker->id() == MONS_SPINY_WORM && defender->res_poison() <= 0) + defender->poison( attacker, 2 + random2(4) ); + splash_defender_with_acid(3); + break; + } +} -bool monsters_fight(int monster_attacking, int monster_attacked) +void melee_attack::mons_perform_attack_rounds() { - struct monsters *attacker = &menv[monster_attacking]; - struct monsters *defender = &menv[monster_attacked]; - - int weapon = -1; // monster weapon, if any - int damage_taken = 0; - bool hit = false; - // int mmov_x = 0; - bool water_attack = false; - int specdam = 0; - int hand_used = 0; - bool sees = false; - int wpn_speed; // 0 == didn't use actual weapon - int habitat = monster_habitat( attacker->type ); - char str_pass[ ITEMNAME_SIZE ]; - -#if DEBUG_DIAGNOSTICS - char st_prn[ 20 ]; + const int nrounds = atk->type == MONS_HYDRA? atk->number : 4; +#ifdef DEBUG_DIAGNOSTICS + mprf(MSGCH_DIAGNOSTICS, "%s gets %d attacks", + attacker->name(DESC_CAP_THE).c_str(), + nrounds); #endif - if (attacker->type == MONS_GIANT_SPORE - || attacker->type == MONS_BALL_LIGHTNING) - { - attacker->hit_points = -1; - return false; - } - - if (mons_has_ench( attacker, ENCH_SUBMERGED ) - && habitat != DNGN_FLOOR - && habitat != monster_habitat( defender->type )) - { - return false; - } - - if (attacker->fumbles_attack(true)) - return true; - - // habitat is the favoured habitat of the attacker - water_attack = defender->floundering() && attacker->swimming(); - - if (mons_near(attacker) && mons_near(defender)) - sees = true; - - // Any objects seen in combat are thereafter known mimics. - if (mons_is_mimic(attacker->type) && mons_near(attacker)) - attacker->flags |= MF_KNOWN_MIMIC; - - if (mons_is_mimic(defender->type) && mons_near(defender)) - defender->flags |= MF_KNOWN_MIMIC; - - // now disturb defender, regardless - behaviour_event(defender, ME_WHACK, monster_attacking); - - int heads = 0; - - if (attacker->type == MONS_HYDRA) - heads = attacker->number; + const coord_def pos = defender->pos(); - for (int runthru = 0; runthru < 4; runthru++) + for (attack_number = 0; attack_number < nrounds; ++attack_number) { - if (attacker->type == MONS_HYDRA) - { - runthru = 0; - if (heads-- < 1) - break; - } - - int mdam = mons_damage(attacker->type, runthru); - wpn_speed = 0; - - if (attacker->type == MONS_ZOMBIE_SMALL - || attacker->type == MONS_ZOMBIE_LARGE - || attacker->type == MONS_SKELETON_SMALL - || attacker->type == MONS_SKELETON_LARGE - || attacker->type == MONS_SIMULACRUM_SMALL - || attacker->type == MONS_SIMULACRUM_LARGE - || attacker->type == MONS_SPECTRAL_THING) - // what do these things have in common? {dlb} - { - mdam = mons_damage(attacker->number, runthru); - // cumulative reductions - series of if-conditions - // is necessary: {dlb} - if (mdam > 1) - mdam--; - if (mdam > 2) - mdam--; - if (mdam > 5) - mdam--; - if (mdam > 9) - mdam--; // was: "-= 2" {dlb} - } - - if (mdam == 0) + // Monster went away? + if (!defender->alive() || defender->pos() != pos) break; - if (mons_wields_two_weapons(attacker) - && runthru == 1 && attacker->inv[MSLOT_MISSILE] != NON_ITEM) - { - hand_used = 1; - } - - damage_taken = 0; - - int mons_to_hit = 20 + attacker->hit_dice * 5; - // * menv [monster_attacking].hit_dice; // * 3 - - if (water_attack) - mons_to_hit += 5; - - weapon = attacker->inv[hand_used]; - - if (weapon != NON_ITEM) - { - mons_to_hit += mitm[weapon].plus; - // mons_to_hit += 3 * property( mitm[weapon], PWPN_HIT ); - mons_to_hit += property( mitm[weapon], PWPN_HIT ); - - wpn_speed = property( mitm[ weapon ], PWPN_SPEED ); - } - - mons_to_hit = random2(mons_to_hit); - - if (mons_to_hit >= defender->evasion || - ((mons_is_paralysed(defender) || defender->behaviour == BEH_SLEEP) - && !one_chance_in(20))) - { - hit = true; - - if (attacker->inv[hand_used] != NON_ITEM - && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS - && !is_range_weapon( mitm[attacker->inv[hand_used]] )) - { - damage_taken = random2(property( mitm[attacker->inv[hand_used]], - PWPN_DAMAGE )); - - if (get_equip_race(mitm[attacker->inv[hand_used]]) == ISFLAG_ORCISH - && mons_species(attacker->type) == MONS_ORC - && coinflip()) - { - damage_taken++; - } - - //if (mitm[mons_inv[i][0]].plus > 80) damage_taken -= 100; - // damage_taken += mitm[mons_inv[i][0]].plus; - - if (mitm[attacker->inv[hand_used]].plus2 >= 0) - { - /* + or 0 to-dam */ - damage_taken += random2(mitm[attacker->inv[hand_used]].plus2 + 1); - } - else - { - /* - to-dam */ - damage_taken -= random2(abs(mitm[attacker->inv[hand_used]].plus2 + 1)); - } - - damage_taken -= 1 + random2(3); //1; - } - - damage_taken += 1 + random2(mdam); + // Monsters hitting themselves get just one round. + if (attack_number > 0 && attacker == defender) + break; + + const mon_attack_def attk = mons_attack_spec(atk, attack_number); + if (attk.type == AT_NONE) + break; - if (water_attack) - damage_taken *= 2; + damage_done = 0; + mons_set_weapon(attk); + to_hit = mons_to_hit(); - damage_taken -= random2(1 + defender->armour_class); + final_attack_delay = mons_attk_delay(); + if (damage_brand == SPWPN_SPEED) + final_attack_delay = final_attack_delay / 2 + 1; - if (damage_taken < 1) - damage_taken = 0; - } - else - { - hit = false; + mons_lose_attack_energy(atk, final_attack_delay, attack_number); - if (sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " misses "); - if (attacker == defender) - strcat(info, - mons_pronoun(attacker->type, PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - } + bool shield_blocked = false; + bool this_round_hit = false; - if (damage_taken < 1 && hit) + if (attacker != defender) { - if (sees) + if (attack_shield_blocked(true)) { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " hits "); - if ( attacker == defender ) - strcat(info, - mons_pronoun(attacker->type, PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); -#if DEBUG_DIAGNOSTICS - strcat(info, " for "); - // note: doesn't take account of special weapons etc - itoa(damage_taken, st_prn, 10); - strcat(info, st_prn); -#endif - strcat(info, "."); // but doesn't do any you.damage."); - mpr(info); + shield_blocked = true; + perceived_attack = true; + this_round_hit = did_hit = true; } + else + check_defender_train_dodging(); } - if (hit) //(int) damage_taken > 0) + if (!shield_blocked) { - int mmov_x = attacker->inv[hand_used]; - - if (sees) + const int defender_evasion = defender->melee_evasion(attacker); + if (attacker == defender || random2(to_hit) >= defender_evasion) { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " hits "); - if (attacker == defender) - strcat(info, - mons_pronoun(attacker->type, PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - - if (attacker->type != MONS_DANCING_WEAPON - && attacker->inv[hand_used] != NON_ITEM - && mitm[attacker->inv[hand_used]].base_type == OBJ_WEAPONS - && !is_range_weapon( mitm[attacker->inv[hand_used]] )) - { - strcat(info, " with "); - it_name(mmov_x, DESC_NOCAP_A, str_pass); // was 7 - strcat(info, str_pass); - } - - strcat(info, "! "); - mpr(info); + this_round_hit = did_hit = true; + perceived_attack = true; + damage_done = mons_calc_damage(attk); } - - if (actor_decapitates_hydra(attacker, defender, damage_taken)) + else { - mons_lose_attack_energy(attacker, wpn_speed, runthru); - - if (defender->hit_points < 1) - { - monster_die(defender, KILL_MON, monster_attacking); - return (true); - } + this_round_hit = false; + perceived_attack = perceived_attack || attacker_visible; - // Skip rest of attack. - continue; + if (needs_message) + mprf("%s misses %s.", + attacker->name(DESC_CAP_THE).c_str(), + mons_defender_name().c_str()); } + } - // special attacks: - switch (attacker->type) - { - // enum does not match comment 14jan2000 {dlb} - case MONS_CENTAUR: // cockatrice - case MONS_JELLY: - case MONS_GUARDIAN_NAGA: - break; - - case MONS_GIANT_ANT: - case MONS_WOLF_SPIDER: - case MONS_REDBACK: - case MONS_SPINY_WORM: - case MONS_JELLYFISH: - case MONS_ORANGE_DEMON: - if (attacker->type == MONS_SPINY_WORM || one_chance_in(20) - || (damage_taken > 3 && one_chance_in(4))) - { - if (sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - poison_monster(defender, false); - } - break; - - case MONS_KILLER_BEE: - case MONS_BUMBLEBEE: - if (one_chance_in(20) - || (damage_taken > 2 && one_chance_in(3))) - { - if (sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - poison_monster(defender, false); - } - break; - - case MONS_NECROPHAGE: - case MONS_ROTTING_DEVIL: - case MONS_GHOUL: - case MONS_DEATH_OOZE: - if (mons_res_negative_energy( defender )) - break; - - if (one_chance_in(20) - || (damage_taken > 2 && one_chance_in(3))) - { - defender->max_hit_points -= 1 + random2(3); - - if (defender->hit_points > defender->max_hit_points) - defender->hit_points = defender->max_hit_points; - } - break; - - case MONS_FIRE_VORTEX: - attacker->hit_points = -10; - // deliberate fall-through - case MONS_FIRE_ELEMENTAL: - case MONS_BALRUG: - case MONS_SUN_DEMON: - specdam = 0; - if (mons_res_fire(defender) == 0) - specdam = 15 + random2(15); - else if (mons_res_fire(defender) < 0) - specdam = 20 + random2(25); - - if (specdam) - simple_monster_message(defender, " is engulfed in flame!"); - - damage_taken += specdam; - break; - - case MONS_QUEEN_BEE: - case MONS_GIANT_CENTIPEDE: - case MONS_SOLDIER_ANT: - case MONS_QUEEN_ANT: - //if ((damage_taken > 2 && one_chance_in(3) ) || one_chance_in(20) ) - //{ - if (sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " stings "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - poison_monster(defender, false); - //} - break; + if (damage_done < 1 && this_round_hit && !shield_blocked) + mons_announce_dud_hit(attk); - // enum does not match comment 14jan2000 {dlb} - case MONS_SCORPION: // snake - case MONS_BROWN_SNAKE: - case MONS_BLACK_SNAKE: - case MONS_YELLOW_SNAKE: - case MONS_GOLD_MIMIC: - case MONS_WEAPON_MIMIC: - case MONS_ARMOUR_MIMIC: - case MONS_SCROLL_MIMIC: - case MONS_POTION_MIMIC: - if (one_chance_in(20) || (damage_taken > 2 && one_chance_in(4))) - poison_monster(defender, false); - break; + if (damage_done > 0) + { + mons_announce_hit(attk); + check_defender_train_armour(); - case MONS_SHADOW_DRAGON: - case MONS_SPECTRAL_THING: - if (coinflip()) - break; - // intentional fall-through - case MONS_WIGHT: - case MONS_WRAITH: - case MONS_SOUL_EATER: - case MONS_SHADOW_FIEND: - case MONS_SPECTRAL_WARRIOR: - case MONS_ORANGE_RAT: - case MONS_ANCIENT_LICH: - case MONS_LICH: - case MONS_BORIS: - if (mons_res_negative_energy( defender )) - break; - - if (one_chance_in(30) || (damage_taken > 5 && coinflip())) - { - simple_monster_message(defender, " is drained."); + if (actor_decapitates_hydra(attacker, defender, damage_done, + attacker->damage_type(attack_number))) + continue; - if (one_chance_in(5)) - defender->hit_dice--; + special_damage = 0; + special_damage_message.clear(); - defender->max_hit_points -= 2 + random2(3); - defender->hit_points -= 2 + random2(3); + // Monsters attacking themselves don't get attack flavour, the + // message sequences look too weird. + if (attacker != defender) + mons_apply_attack_flavour(attk); + + if (!special_damage_message.empty()) + mprf("%s", special_damage_message.c_str()); + + defender->hurt(attacker, damage_done + special_damage); + + if (!defender->alive() || attacker == defender) + return; - if (defender->hit_points >= defender->max_hit_points) - defender->hit_points = defender->max_hit_points; + special_damage = 0; + apply_damage_brand(); - if (defender->hit_points < 1 || defender->hit_dice < 1) - { - monster_die(defender, KILL_MON, monster_attacking); - return true; - } - } - break; + if (!special_damage_message.empty()) + mprf("%s", special_damage_message.c_str()); - // enum does not match comment 14jan2000 {dlb} - case MONS_WORM: // giant wasp - break; + if (special_damage > 0) + defender->hurt(attacker, special_damage); + } + } +} - case MONS_SIMULACRUM_SMALL: - case MONS_SIMULACRUM_LARGE: - specdam = 0; +bool melee_attack::mons_perform_attack() +{ + if (attacker != defender && mons_self_destructs()) + return (did_hit = perceived_attack = true); - if (mons_res_cold(defender) == 0) - specdam = roll_dice( 1, 4 ); - else if (mons_res_cold(defender) < 0) - specdam = roll_dice( 2, 4 ); + if (attacker != defender && mons_attack_warded_off()) + { + perceived_attack = true; + return (false); + } - if (specdam && sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " freezes "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } + mons_perform_attack_rounds(); + + return (did_hit); +} - damage_taken += specdam; - break; +void melee_attack::mons_check_attack_perceived() +{ + if (!perceived_attack) + return; - case MONS_ICE_DEVIL: - case MONS_ICE_BEAST: - case MONS_FREEZING_WRAITH: - case MONS_ICE_FIEND: - case MONS_WHITE_IMP: - case MONS_AZURE_JELLY: - case MONS_ANTAEUS: - specdam = 0; - if (mons_res_cold(defender) == 0) - { - specdam = attacker->hit_dice + random2(attacker->hit_dice * 2); - } - else if (mons_res_cold(defender) < 0) - { - specdam = random2(attacker->hit_dice * 3) + (attacker->hit_dice * 2); - } + if (defender->atype() == ACT_PLAYER) + { + interrupt_activity(AI_MONSTER_ATTACKS, atk); + + // if a friend wants to help, they can attack + if (you.pet_target == MHITNOT) + you.pet_target = monster_index(atk); + } +} - if (specdam && sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " freezes "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - damage_taken += specdam; - break; +bool melee_attack::mons_attack_you() +{ + mons_perform_attack(); + mons_check_attack_perceived(); + return (did_hit); +} - case MONS_ELECTRIC_GOLEM: - if (mons_flies(defender) == 0 && mons_res_elec(defender) == 0) - { - specdam = attacker->hit_dice + random2(attacker->hit_dice * 2); - } +int melee_attack::mons_to_hit() +{ + int mhit = 16 + atk->hit_dice; + if (water_attack) + mhit += 5; - if (specdam && sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " shocks "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - damage_taken += specdam; - break; + if (weapon && weapon->base_type == OBJ_WEAPONS) + mhit += weapon->plus + property(*weapon, PWPN_HIT); - case MONS_VAMPIRE: - case MONS_VAMPIRE_KNIGHT: - case MONS_VAMPIRE_MAGE: - if (mons_res_negative_energy(defender) > 0) - break; + return (mhit); +} - // heh heh {dlb} - if (heal_monster(attacker, random2(damage_taken), true)) - simple_monster_message(attacker, " is healed."); - break; - } - } +/////////////////////////////////////////////////////////////////////////// - // special weapons: - if (hit - && (attacker->inv[hand_used] != NON_ITEM - || ((attacker->type == MONS_PLAYER_GHOST - || attacker->type == MONS_PANDEMONIUM_DEMON) - && ghost.values[ GVAL_BRAND ] != SPWPN_NORMAL))) - { - unsigned char itdam; +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 (attacker->type == MONS_PLAYER_GHOST - || attacker->type == MONS_PANDEMONIUM_DEMON) - { - itdam = ghost.values[ GVAL_BRAND ]; - } - else - itdam = mitm[attacker->inv[hand_used]].special; +// 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); - specdam = 0; + // We're trying to hit a monster, break out of travel/explore now. + interrupt_activity(AI_HIT_MONSTER, defender); - if (attacker->type == MONS_PLAYER_GHOST - || attacker->type == MONS_PANDEMONIUM_DEMON) - { - switch (itdam) - { - case SPWPN_NORMAL: - default: - break; - - case SPWPN_SWORD_OF_CEREBOV: - case SPWPN_FLAMING: - specdam = 0; - - if (itdam == SPWPN_SWORD_OF_CEREBOV - || mons_res_fire(defender) <= 0) - { - specdam = 1 + random2(damage_taken); - } - - if (specdam) - { - if (sees) - { - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " burns "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE )); - - if (specdam < 3) - strcat(info, "."); - else if (specdam < 7) - strcat(info, "!"); - else - strcat(info, "!!"); - - mpr(info); - } - } - break; - - case SPWPN_FREEZING: - specdam = 0; - - if (mons_res_cold(defender) <= 0) - specdam = 1 + random2(damage_taken); - - if (specdam) - { - if (sees) - { - // mmov_x = attacker->inv[hand_used]; - - strcpy(info, ptr_monam(attacker, DESC_CAP_THE)); - strcat(info, " freezes "); - if (attacker == defender) - strcat(info, mons_pronoun(attacker->type, - PRONOUN_REFLEXIVE)); - else - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - - if (specdam < 3) - strcat(info, "."); - else if (specdam < 7) - strcat(info, "!"); - else - strcat(info, "!!"); - - mpr(info); - } - } - break; - - case SPWPN_HOLY_WRATH: - if (attacker->type == MONS_PLAYER_GHOST) - break; - specdam = 0; - switch (mons_holiness(defender)) - { - case MH_HOLY: - // I would think that it would do zero damage {dlb} - damage_taken -= 5 + random2(5); - break; - - case MH_UNDEAD: - specdam += 1 + random2(damage_taken); - break; - - case MH_DEMONIC: - specdam += 1 + (random2(damage_taken) * 15) / 10; - break; - - default: - break; - } - break; - - case SPWPN_ELECTROCUTION: - //if ( attacker->type == MONS_PLAYER_GHOST ) break; - if (mons_flies(defender) > 0 || mons_res_elec(defender) > 0) - break; - - specdam = 0; + // For tutorials, check if the player is fighting with something unsuitable + tutorial_weapon_check(attk.weapon); -#if 0 - // more of the old code... -- bwr - if (menv[monster_attacking].type != MONS_PLAYER_GHOST - && (mitm[attacker->inv[hand_used]].plus2 <= 0 - || item_cursed( mitm[attacker->inv[hand_used]] ))) - { - break; - } -#endif + return attk.attack(); +} - if (one_chance_in(3)) - { - if (sees) - mpr("There is a sudden explosion of sparks!"); - - specdam += 10 + random2(15); - //mitm[attacker->inv[hand_used]].plus2 --; - } - break; - - case SPWPN_ORC_SLAYING: - if (mons_species(defender->type) == MONS_ORC) - hurt_monster(defender, 1 + random2(damage_taken)); - break; - - case SPWPN_STAFF_OF_OLGREB: - case SPWPN_VENOM: - if (!one_chance_in(3)) - poison_monster(defender, false); - break; - - //case 7: // protection - - case SPWPN_DRAINING: - if (!mons_res_negative_energy( defender ) - && (one_chance_in(30) - || (damage_taken > 5 && coinflip()))) - { - simple_monster_message(defender, " is drained"); - - if (one_chance_in(5)) - defender->hit_dice--; - - defender->max_hit_points -= 2 + random2(3); - defender->hit_points -= 2 + random2(3); - - if (defender->hit_points >= defender->max_hit_points) - defender->hit_points = defender->max_hit_points; - - if (defender->hit_points < 1 - || defender->hit_dice < 1) - { - monster_die(defender, KILL_MON, monster_attacking); - return true; - } - specdam = 1 + (random2(damage_taken) / 2); - } - break; - - case SPWPN_SPEED: - wpn_speed = (wpn_speed + 1) / 2; - break; - - case SPWPN_VORPAL: - specdam += 1 + (random2(damage_taken) / 2); - break; - - case SPWPN_VAMPIRES_TOOTH: - case SPWPN_VAMPIRICISM: - specdam = 0; // note does no extra damage - - if (mons_res_negative_energy( defender )) - break; - - if (one_chance_in(5)) - break; - - // heh heh {dlb} - if (heal_monster(attacker, 1 + random2(damage_taken), true)) - simple_monster_message(attacker, " is healed."); - break; - - case SPWPN_DISRUPTION: - if (attacker->type == MONS_PLAYER_GHOST) - break; - - specdam = 0; - - if (mons_holiness(defender) == MH_UNDEAD - && !one_chance_in(3)) - { - simple_monster_message(defender, " shudders."); - specdam += random2avg(1 + (3 * damage_taken), 3); - } - break; - - - case SPWPN_DISTORTION: - if (one_chance_in(3)) - { - if (mons_near(defender) - && player_monster_visible(defender)) - { - strcpy(info, "Space bends around "); - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "."); - mpr(info); - } - - specdam += 1 + random2avg(7, 2); - break; - } - if (one_chance_in(3)) - { - if (mons_near(defender) - && player_monster_visible(defender)) - { - strcpy(info, "Space warps horribly around "); - strcat(info, ptr_monam(defender, DESC_NOCAP_THE)); - strcat(info, "!"); - mpr(info); - } - - specdam += 3 + random2avg(24, 2); - break; - } - - if (one_chance_in(3)) - { - monster_blink(defender); - break; - } - - if (coinflip()) - { - monster_teleport(defender, coinflip()); - break; - } - - if (coinflip()) - { - monster_die(defender, KILL_RESET, monster_attacking); - break; - } - break; - } - } - } // end of if special weapon +// Lose attack energy for attacking with a weapon. The monster has already lost +// the base attack cost by this point. +static void mons_lose_attack_energy(monsters *attacker, int wpn_speed, + int which_attack) +{ + // Monsters lose energy only for the first two weapon attacks; subsequent + // hits are free. + if (which_attack > 1) + return; + + // speed adjustment for weapon using monsters + if (wpn_speed > 0) + { + // only get one third penalty/bonus for second weapons. + if (which_attack > 0) + wpn_speed = (20 + wpn_speed) / 3; - damage_taken += specdam; + attacker->speed_increment -= (wpn_speed - 10) / 2; + } +} - if (damage_taken > 0) - { - hurt_monster(defender, damage_taken); +void monster_attack(int monster_attacking) +{ + monsters *attacker = &menv[monster_attacking]; + + if (mons_friendly(attacker) && !mons_is_confused(attacker)) + return; - if (defender->hit_points < 1) - { - monster_die(defender, KILL_MON, monster_attacking); - return true; - } - } + melee_attack attk(attacker, &you); + attk.attack(); +} // end monster_attack() - mons_lose_attack_energy(attacker, wpn_speed, runthru); - } // end of for runthru +bool monsters_fight(int monster_attacking, int monster_attacked) +{ + monsters *attacker = &menv[monster_attacking]; + monsters *defender = &menv[monster_attacked]; - return true; + melee_attack attk(attacker, defender); + return attk.attack(); } // end monsters_fight() @@ -4146,7 +3048,7 @@ int weapon_str_weight( int wpn_class, int wpn_type ) // - Short Blades are the best for the dexterous... although they // are very limited in damage potential // - Long Swords are better for the dexterous, the two-handed - // swords are a 50/50 split; bastard swords are in between. + // swords are a 50/50 spit; bastard swords are in between. // - Staves: didn't want to punish the mages who want to use // these... made it a 50/50 split after the 2-hnd bonus // - Polearms: Spears and tridents are the only ones that can diff --git a/crawl-ref/source/fight.h b/crawl-ref/source/fight.h index 84bb0f0c28..2d1d6d6260 100644 --- a/crawl-ref/source/fight.h +++ b/crawl-ref/source/fight.h @@ -64,7 +64,11 @@ public: // If attacker and/or defender are monsters, these are set. monsters *atk, *def; - bool did_hit; + bool did_hit, perceived_attack; + + // If all or part of the action is visible to the player, we need a message. + bool needs_message; + bool attacker_visible, defender_visible; bool unarmed_ok; int attack_number; @@ -100,6 +104,7 @@ public: std::string unarmed_attack; item_def *shield; + item_def *defender_shield; // Armour penalties? int heavy_armour_penalty; @@ -125,16 +130,47 @@ private: void check_autoberserk(); void check_special_wield_effects(); void emit_nodmg_hit_message(); + void identify_mimic(monsters *mon); std::string debug_damage_number(); std::string special_attack_punctuation(); std::string attack_strength_punctuation(); + bool attack_shield_blocked(bool verbose); + bool apply_damage_brand(); + void calc_elemental_brand_damage(int res, const char *verb); + int resist_adjust_damage(int res, int rawdamage); + int fire_res_apply_cerebov_downgrade(int res); + void drain_defender(); + void drain_player(); + void drain_monster(); + void check_defender_train_armour(); + void check_defender_train_dodging(); + void splash_defender_with_acid(int strength); + void splash_monster_with_acid(int strength); + private: // Monster-attack specific stuff bool mons_attack_you(); bool mons_attack_mons(); int mons_to_hit(); + bool mons_self_destructs(); + bool mons_attack_warded_off(); + int mons_attk_delay(); + int mons_calc_damage(const mon_attack_def &attk); + void mons_apply_attack_flavour(const mon_attack_def &attk); + int mons_apply_defender_ac(int damage, int damage_max); + bool mons_perform_attack(); + void mons_perform_attack_rounds(); + void mons_check_attack_perceived(); + std::string mons_attack_verb(const mon_attack_def &attk); + std::string mons_weapon_desc(); + void mons_announce_hit(const mon_attack_def &attk); + void mons_announce_dud_hit(const mon_attack_def &attk); + void mons_set_weapon(const mon_attack_def &attk); + void mons_do_poison(const mon_attack_def &attk); + std::string mons_defender_name(); + void wasp_paralyse_defender(); private: // Player-attack specific stuff @@ -162,8 +198,6 @@ private: 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(); diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc index bedfa97b1f..463cc14603 100644 --- a/crawl-ref/source/files.cc +++ b/crawl-ref/source/files.cc @@ -1322,8 +1322,8 @@ void load_ghost(void) menv[imn].hit_dice = ghost.values[ GVAL_EXP_LEVEL ]; menv[imn].hit_points = ghost.values[ GVAL_MAX_HP ]; menv[imn].max_hit_points = ghost.values[ GVAL_MAX_HP ]; - menv[imn].armour_class = ghost.values[ GVAL_AC]; - menv[imn].evasion = ghost.values[ GVAL_EV ]; + menv[imn].ac = ghost.values[ GVAL_AC]; + menv[imn].ev = ghost.values[ GVAL_EV ]; menv[imn].speed = 10; menv[imn].speed_increment = 70; menv[imn].attitude = ATT_HOSTILE; @@ -1966,8 +1966,8 @@ void generate_random_demon(void) menv[rdem].hit_dice = ghost.values[ GVAL_DEMONLORD_HIT_DICE ]; menv[rdem].hit_points = ghost.values[ GVAL_MAX_HP ]; menv[rdem].max_hit_points = ghost.values[ GVAL_MAX_HP ]; - menv[rdem].armour_class = ghost.values[ GVAL_AC ]; - menv[rdem].evasion = ghost.values[ GVAL_EV ]; + menv[rdem].ac = ghost.values[ GVAL_AC ]; + menv[rdem].ev = ghost.values[ GVAL_EV ]; menv[rdem].speed = (one_chance_in(3) ? 10 : 6 + roll_dice(2, 9)); menv[rdem].speed_increment = 70; menv[rdem].colour = random_colour(); // demon's colour diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index 7535af2ac0..74d60c78ad 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -63,7 +63,7 @@ bool potion_effect( char pot_eff, int pow ) set_hp(you.hp_max, false); } - you.poison = 0; + you.poisoning = 0; you.rotting = 0; you.disease = 0; you.conf = 0; @@ -166,18 +166,7 @@ bool potion_effect( char pot_eff, int pow ) break; case POT_PARALYSIS: - snprintf( info, INFO_SIZE, "You %s the ability to move!", - (you.paralysis) ? "still haven't" : "suddenly lose" ); - - mpr( info, MSGCH_WARN ); - - new_value = 2 + random2( 6 + you.paralysis ); - - if (new_value > you.paralysis) - you.paralysis = new_value; - - if (you.paralysis > 13) - you.paralysis = 13; + you.paralyse(2 + random2( 6 + you.paralysis )); break; case POT_CONFUSION: diff --git a/crawl-ref/source/mon-data.h b/crawl-ref/source/mon-data.h index 6070f1c48e..55dd6ac490 100644 --- a/crawl-ref/source/mon-data.h +++ b/crawl-ref/source/mon-data.h @@ -113,7 +113,7 @@ M_NO_EXP_GAIN, MR_NO_FLAGS, 0, 10, MONS_PROGRAM_BUG, MONS_PROGRAM_BUG, MH_NATURAL, -3, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_HUGE @@ -126,7 +126,7 @@ M_NO_FLAGS, MR_VUL_POISON, 700, 10, MONS_GIANT_ANT, MONS_GIANT_ANT, MH_NATURAL, -3, - { 8, 0, 0, 0 }, + { {AT_BITE, AF_POISON, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 4, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LITTLE @@ -138,7 +138,7 @@ M_FLIES | M_SEE_INVIS | M_WARM_BLOOD, MR_NO_FLAGS, 150, 4, MONS_GIANT_BAT, MONS_GIANT_BAT, MH_NATURAL, -1, - { 1, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 1}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 2, 3, 0 }, 1, 14, 30, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_TINY @@ -150,7 +150,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 1500, 10, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 3, 7, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -162,7 +162,7 @@ M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 10, MONS_RED_DEVIL, MONS_RED_DEVIL, MH_DEMONIC, -7, - { 18, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -174,7 +174,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_HILL_GIANT, MONS_ETTIN, MH_NATURAL, -3, - { 18, 12, 0, 0 }, + { {AT_HIT, AF_PLAIN, 18}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL, MONUSE_STARTING_EQUIPMENT, SIZE_GIANT @@ -186,7 +186,7 @@ M_NO_EXP_GAIN, MR_RES_POISON, 0, 10, MONS_PLANT, MONS_FUNGUS, MH_PLANT, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 1, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_TINY @@ -198,7 +198,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 400, 10, MONS_GOBLIN, MONS_GOBLIN, MH_NATURAL, -1, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 2, 4, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -210,7 +210,7 @@ M_SEE_INVIS | M_WARM_BLOOD, MR_NO_FLAGS, 300, 10, MONS_HOUND, MONS_HOUND, MH_NATURAL, -3, - { 6, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 2, 13, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -223,7 +223,7 @@ M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 13, MONS_IMP, MONS_IMP, MH_DEMONIC, -9, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 3, 0 }, 3, 14, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_LITTLE @@ -235,7 +235,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 200, 10, MONS_HOUND, MONS_JACKAL, MH_NATURAL, -1, - { 3, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 2, 12, 14, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -247,7 +247,7 @@ M_FLIES, MR_VUL_POISON, 150, 11, MONS_KILLER_BEE, MONS_KILLER_BEE, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_STING, AF_POISON, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 2, 18, 20, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -259,7 +259,7 @@ M_NO_SKELETON, MR_VUL_POISON, 150, 5, MONS_KILLER_BEE_LARVA, MONS_KILLER_BEE_LARVA, MH_NATURAL, -3, - { 3, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 1, 5, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -271,7 +271,7 @@ M_WARM_BLOOD | M_SPECIAL_ABILITY, MR_NO_FLAGS, 1800, 10, MONS_MANTICORE, MONS_MANTICORE, MH_NATURAL, -3, - { 14, 8, 8, 0 }, + { {AT_BITE, AF_PLAIN, 14}, {AT_CLAW, AF_PLAIN, 8}, {AT_CLAW, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 5, 7, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_BIG @@ -284,7 +284,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 500, 10, MONS_GHOUL, MONS_NECROPHAGE, MH_UNDEAD, -5, - { 8, 0, 0, 0 }, + { {AT_HIT, AF_ROT, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -296,7 +296,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 4, 6, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -310,7 +310,7 @@ M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_COLD, 0, 5, MONS_PHANTOM, MONS_PHANTOM, MH_UNDEAD, -4, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_BLINK, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 3, 13, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -321,10 +321,10 @@ MONS_QUASIT, 'q', LIGHTGREY, "quasit", M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 0, 10, MONS_QUASIT, MONS_QUASIT, MH_DEMONIC, 50, - { 3, 2, 2, 0 }, + 0, 10, MONS_QUASIT, MONS_QUASIT, MH_DEMONIC, 5, + { {AT_BITE, AF_DRAIN_DEX, 3}, {AT_CLAW, AF_DRAIN_DEX, 2}, {AT_CLAW, AF_DRAIN_DEX, 2}, {AT_NONE, AF_PLAIN, 0} }, { 3, 2, 6, 0 }, - 5, 17, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, + 5, 17, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_SMALL } , @@ -334,7 +334,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 200, 10, MONS_RAT, MONS_RAT, MH_NATURAL, -1, - { 3, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 1, 3, 0 }, 1, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_TINY @@ -346,7 +346,7 @@ M_NO_FLAGS, MR_VUL_POISON, 500, 10, MONS_SCORPION, MONS_SCORPION, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_STING, AF_POISON_MEDIUM, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 5, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -374,7 +374,7 @@ M_WARM_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 600, 10, MONS_UGLY_THING, MONS_UGLY_THING, MH_NATURAL, -3, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -386,7 +386,7 @@ M_LEVITATE | M_CONFUSED, MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD | MR_RES_ELEC, 0, 5, MONS_FIRE_VORTEX, MONS_FIRE_VORTEX, MH_NONLIVING, MAG_IMMUNE, - { 30, 0, 0, 0 }, + { {AT_ENGULF, AF_FIRE, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -398,7 +398,7 @@ M_NO_SKELETON, MR_NO_FLAGS, 350, 4, MONS_WORM, MONS_WORM, MH_NATURAL, -2, - { 12, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 1, 5, 6, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_MEDIUM @@ -411,7 +411,7 @@ M_EVIL, MR_NO_FLAGS, 0, 10, MONS_ABOMINATION_SMALL, MONS_ABOMINATION_SMALL, MH_DEMONIC, -5, - { 23, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 23}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 2, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -423,7 +423,7 @@ M_FLIES, MR_VUL_POISON, 220, 12, MONS_YELLOW_WASP, MONS_YELLOW_WASP, MH_NATURAL, -3, - { 13, 0, 0, 0 }, + { {AT_STING, AF_PARALYSE, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 5, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -436,7 +436,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 6, MONS_ZOMBIE_SMALL, MONS_ZOMBIE_SMALL, MH_UNDEAD, -1, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 5, 5, 0 }, 0, 4, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -448,7 +448,7 @@ M_FLIES | M_SPELLCASTER, MR_RES_POISON | MR_RES_ELEC, 0, 10, MONS_ANGEL, MONS_ANGEL, MH_HOLY, -8, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 6, 5, 0 }, 10, 20, 15, 7, MST_ANGEL, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -460,7 +460,7 @@ M_NO_FLAGS, MR_VUL_POISON, 1000, 10, MONS_GIANT_BEETLE, MONS_GIANT_BEETLE, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 7, 6, 0 }, 10, 3, 5, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_MEDIUM @@ -472,7 +472,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 2500, 10, MONS_HILL_GIANT, MONS_CYCLOPS, MH_NATURAL, -3, - { 35, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 5, 3, 7, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_STARTING_EQUIPMENT, SIZE_GIANT @@ -481,10 +481,10 @@ { MONS_DRAGON, 'D', GREEN, "dragon", - M_FLIES | M_SPECIAL_ABILITY | M_CLAWS, //jmf: warm blood? + M_FLIES | M_SPECIAL_ABILITY, //jmf: warm blood? MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, 2200, 12, MONS_DRAGON, MONS_DRAGON, MH_NATURAL, -4, - { 20, 13, 13, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 13}, {AT_CLAW, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0} }, { 12, 5, 5, 0 }, 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -498,7 +498,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 1500, 15, MONS_OGRE, MONS_TWO_HEADED_OGRE, MH_NATURAL, -4, - { 17, 13, 0, 0 }, + { {AT_HIT, AF_PLAIN, 17}, {AT_HIT, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 1, 4, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT2, I_NORMAL, MONUSE_STARTING_EQUIPMENT, SIZE_LARGE @@ -510,7 +510,7 @@ M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 18, MONS_FIEND, MONS_FIEND, MH_DEMONIC, -12, - { 25, 15, 15, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -522,7 +522,7 @@ M_LEVITATE, MR_RES_POISON | MR_RES_ASPHYX, 0, 10, MONS_PLANT, MONS_GIANT_SPORE, MH_NATURAL, -3, - { 1, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 1}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 0, 0, 1 }, 0, 10, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -534,7 +534,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 500, 10, MONS_GOBLIN, MONS_HOBGOBLIN, MH_NATURAL, -1, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 4, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -546,7 +546,7 @@ M_NO_FLAGS, MR_RES_POISON | MR_RES_ASPHYX | MR_VUL_FIRE | MR_RES_COLD, 0, 12, MONS_ICE_BEAST, MONS_ICE_BEAST, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_CLAW, AF_COLD, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 5, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_LARGE @@ -558,7 +558,7 @@ 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 }, + { {AT_HIT, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 5, 5, 0 }, 0, 2, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_EATS_ITEMS, SIZE_MEDIUM @@ -570,7 +570,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 400, 10, MONS_KOBOLD, MONS_KOBOLD, MH_NATURAL, -1, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 2, 3, 0 }, 2, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -582,7 +582,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 16, MONS_LICH, MONS_LICH, MH_UNDEAD, -11, - { 15, 0, 0, 0 }, + { {AT_TOUCH, AF_DRAIN_XP, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 20, 2, 4, 0 }, 10, 10, 10, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -594,7 +594,7 @@ M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, -5, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 5, 3, 0 }, 3, 6, 6, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -606,7 +606,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_POISON, 350, 10, MONS_NAGA, MONS_GUARDIAN_NAGA, MH_NATURAL, -6, - { 19, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 19}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 6, 14, 15, 7, MST_GUARDIAN_NAGA, CE_MUTAGEN_RANDOM, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_BIG @@ -618,7 +618,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 1300, 10, MONS_OGRE, MONS_OGRE, MH_NATURAL, -3, - { 17, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 17}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 1, 6, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_STARTING_EQUIPMENT, SIZE_LARGE @@ -630,7 +630,7 @@ M_NO_EXP_GAIN, MR_RES_POISON, 0, 10, MONS_PLANT, MONS_PLANT, MH_PLANT, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 10, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -642,7 +642,7 @@ M_FLIES, MR_VUL_POISON, 200, 14, MONS_KILLER_BEE, MONS_QUEEN_BEE, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_STING, AF_POISON_NASTY, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LITTLE @@ -654,7 +654,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON, 0, 15, MONS_RAKSHASA, MONS_RAKSHASA, MH_NATURAL, -10, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 10, 14, 10, 7, MST_RAKSHASA, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -666,7 +666,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 200, 10, MONS_SNAKE, MONS_SNAKE, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_BITE, AF_POISON, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 1, 15, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, MONUSE_NOTHING, SIZE_SMALL @@ -675,10 +675,10 @@ { MONS_TROLL, 'T', BROWN, "troll", - M_WARM_BLOOD | M_EVIL | M_CLAWS, + M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 1500, 10, MONS_TROLL, MONS_TROLL, MH_NATURAL, -3, - { 20, 15, 15, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -690,7 +690,7 @@ M_LEVITATE | M_SEE_INVIS | M_INVIS, MR_NO_FLAGS, 0, 12, MONS_UNSEEN_HORROR, MONS_UNSEEN_HORROR, MH_NATURAL, -3, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 5, 10, 30, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_MEDIUM @@ -702,7 +702,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 11, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6, - { 22, 0, 0, 0 }, + { {AT_BITE, AF_VAMPIRIC, 22}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 10, 10, 10, 7, MST_VAMPIRE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -714,7 +714,7 @@ M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 11, MONS_WRAITH, MONS_WRAITH, MH_UNDEAD, -7, - { 13, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_XP, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 10, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -727,7 +727,7 @@ M_EVIL, MR_NO_FLAGS, 0, 10, MONS_ABOMINATION_SMALL, MONS_ABOMINATION_LARGE, MH_DEMONIC, -7, - { 40, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 40}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 2, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_BIG @@ -739,7 +739,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 1200, 10, MONS_YAK, MONS_YAK, MH_NATURAL, -3, - { 18, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 4, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_BELLOW, I_ANIMAL, MONUSE_NOTHING, SIZE_BIG @@ -752,7 +752,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 6, MONS_ZOMBIE_SMALL, MONS_ZOMBIE_LARGE, MH_UNDEAD, -1, - { 23, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 23}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 8, 5, 5, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -764,7 +764,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 4, 6, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -776,7 +776,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_KOBOLD, MONS_KOBOLD, MH_NATURAL, -5, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 2, 13, 10, 7, MST_KOBOLD_DEMONOLOGIST, CE_POISONOUS, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -788,7 +788,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -5, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 4, 0 }, 1, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -800,7 +800,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -3, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 4, 7, 0 }, 2, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -828,7 +828,7 @@ M_NO_FLAGS, //jmf: warm blood? MR_NO_FLAGS, 2000, 10, MONS_WYVERN, MONS_WYVERN, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 5, 10, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_BIG @@ -840,7 +840,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_KOBOLD, MONS_BIG_KOBOLD, MH_NATURAL, -3, - { 7, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -852,7 +852,7 @@ M_NO_SKELETON | M_LEVITATE, MR_RES_ASPHYX, 400, 10, MONS_GIANT_EYEBALL, MONS_GIANT_EYEBALL, MH_NATURAL, -3, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 0, 1, 3, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_MEDIUM @@ -864,7 +864,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_WRAITH, MONS_WIGHT, MH_UNDEAD, -4, - { 8, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_XP, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -876,7 +876,7 @@ M_SPECIAL_ABILITY, MR_RES_POISON, 0, 10, MONS_PLANT, MONS_OKLOB_PLANT, MH_PLANT, -3, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 10, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -888,7 +888,7 @@ M_NO_FLAGS, MR_VUL_POISON, 800, 10, MONS_WOLF_SPIDER, MONS_WOLF_SPIDER, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_POISON_MEDIUM, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 3, 10, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -900,7 +900,7 @@ M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_WRAITH, MONS_SHADOW, MH_UNDEAD, -5, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_STR, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 12, 10, 10, 7, BLACK, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_ANIMAL, MONUSE_OPEN_DOORS, SIZE_SMALL @@ -912,7 +912,7 @@ M_SEE_INVIS | M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_PHANTOM, MONS_HUNGRY_GHOST, MH_UNDEAD, -4, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_HUNGER, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 0, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -924,7 +924,7 @@ M_NO_SKELETON | M_LEVITATE | M_SEE_INVIS, MR_RES_ASPHYX, 400, 10, MONS_GIANT_EYEBALL, MONS_EYE_OF_DRAINING, MH_NATURAL, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 3, 1, 5, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_MEDIUM @@ -936,7 +936,7 @@ M_FLIES | M_CONFUSED, MR_VUL_POISON | MR_RES_ASPHYX, 150, 10, MONS_BUTTERFLY, MONS_BUTTERFLY, MH_NATURAL, -3, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 0, 25, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -948,7 +948,7 @@ M_NO_FLAGS, MR_RES_POISON, 0, 10, MONS_PLANT, MONS_WANDERING_MUSHROOM, MH_PLANT, -3, - { 20, 0, 0, 0 }, + { {AT_SPORE, AF_CONFUSE, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 5, 0, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_TINY @@ -960,7 +960,7 @@ M_SPELLCASTER | M_LEVITATE | M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, 0, 12, MONS_EFREET, MONS_EFREET, MH_DEMONIC, -3, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 10, 5, 10, 7, MST_EFREET, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_LARGE @@ -972,7 +972,7 @@ M_SPELLCASTER, MR_NO_FLAGS, 150, 10, MONS_WORM, MONS_BRAIN_WORM, MH_NATURAL, -3, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 3, 0 }, 1, 5, 10, 7, MST_BRAIN_WORM, CE_POISONOUS, Z_SMALL, S_SILENT, I_REPTILE, MONUSE_NOTHING, SIZE_SMALL @@ -984,7 +984,7 @@ M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, MR_RES_ASPHYX, 1000, 13, MONS_GIANT_ORANGE_BRAIN, MONS_GIANT_ORANGE_BRAIN, MH_NATURAL, -8, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 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, SIZE_SMALL @@ -996,7 +996,7 @@ M_NO_FLAGS, MR_VUL_POISON, 2500, 10, MONS_GIANT_BEETLE, MONS_BOULDER_BEETLE, MH_NATURAL, -3, - { 35, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 20, 2, 3, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LARGE @@ -1008,7 +1008,7 @@ M_LEVITATE, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_SKELETON_SMALL, MONS_FLYING_SKULL, MH_UNDEAD, -3, - { 7, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 10, 17, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_ANIMAL, MONUSE_NOTHING, SIZE_TINY @@ -1020,7 +1020,7 @@ M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 10, MONS_HOUND, MONS_HELL_HOUND, MH_DEMONIC, -3, - { 13, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 6, 13, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_BARK, I_NORMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -1032,7 +1032,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 1500, 10, MONS_MINOTAUR, MONS_MINOTAUR, MH_NATURAL, -3, - { 35, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 3, 5, 0 }, 5, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_BELLOW, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1041,10 +1041,10 @@ { MONS_ICE_DRAGON, 'D', WHITE, "ice dragon", - M_FLIES | M_SPECIAL_ABILITY | M_CLAWS, + M_FLIES | M_SPECIAL_ABILITY, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 2200, 10, MONS_DRAGON, MONS_ICE_DRAGON, MH_NATURAL, -3, - { 17, 17, 17, 0 }, + { {AT_BITE, AF_PLAIN, 17}, {AT_CLAW, AF_PLAIN, 17}, {AT_CLAW, AF_PLAIN, 17}, {AT_NONE, AF_PLAIN, 0} }, { 12, 5, 5, 0 }, 10, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -1056,7 +1056,7 @@ M_AMPHIBIOUS, MR_RES_POISON, 0, 5, MONS_SLIME_CREATURE, MONS_SLIME_CREATURE, MH_NATURAL, -3, - { 22, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 22}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 1, 4, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -1068,7 +1068,7 @@ M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_WRAITH, MONS_FREEZING_WRAITH, MH_UNDEAD, -4, - { 19, 0, 0, 0 }, + { {AT_HIT, AF_COLD, 19}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 12, 10, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1081,7 +1081,7 @@ M_EVIL, MR_RES_POISON, 0, 10, MONS_RAKSHASA_FAKE, MONS_RAKSHASA_FAKE, MH_NATURAL, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 0, 0, 1 }, 0, 30, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_PLANT, MONUSE_NOTHING, SIZE_MEDIUM @@ -1093,7 +1093,7 @@ M_NO_SKELETON | M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS, MR_RES_POISON, 900, 13, MONS_GIANT_EYEBALL, MONS_GREAT_ORB_OF_EYES, MH_NATURAL, MAG_IMMUNE, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 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, SIZE_LARGE @@ -1105,7 +1105,7 @@ M_SPELLCASTER | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 11, MONS_HELLION, MONS_HELLION, MH_DEMONIC, -7, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 5, 10, 13, 7, MST_BURNING_DEVIL, CE_NOCORPSE, Z_NOZOMBIE, S_SCREAM, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1117,7 +1117,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_ROTTING_DEVIL, MONS_ROTTING_DEVIL, MH_DEMONIC, -7, - { 8, 0, 0, 0 }, + { {AT_HIT, AF_ROT, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 2, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1129,7 +1129,7 @@ M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_FIRE, 0, 10, MONS_TORMENTOR, MONS_TORMENTOR, MH_DEMONIC, -6, - { 8, 8, 0, 0 }, + { {AT_HIT, AF_PLAIN, 8}, {AT_HIT, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 12, 12, 13, 7, MST_TORMENTOR, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1141,7 +1141,7 @@ M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_REAPER, MONS_REAPER, MH_DEMONIC, MAG_IMMUNE, - { 32, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 32}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 15, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -1153,7 +1153,7 @@ M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_SOUL_EATER, MONS_SOUL_EATER, MH_DEMONIC, -10, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_XP, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 18, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1165,7 +1165,7 @@ M_EVIL, MR_RES_POISON, 0, 10, MONS_HAIRY_DEVIL, MONS_HAIRY_DEVIL, MH_DEMONIC, -4, - { 9, 9, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 7, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_SMALL @@ -1177,7 +1177,7 @@ M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 11, MONS_ICE_DEVIL, MONS_ICE_DEVIL, MH_DEMONIC, -6, - { 16, 0, 0, 0 }, + { {AT_HIT, AF_COLD, 16}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 12, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1189,7 +1189,7 @@ M_FLIES | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_BLUE_DEVIL, MONS_BLUE_DEVIL, MH_DEMONIC, -5, - { 21, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 21}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 14, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1202,7 +1202,7 @@ M_EVIL, MR_NO_FLAGS, 0, 10, MONS_BEAST, MONS_BEAST, MH_DEMONIC, -3, - { 12, 0, 0, 0 }, + { {AT_CLAW, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 0, 0, 0, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1214,7 +1214,7 @@ M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 10, MONS_IRON_DEVIL, MONS_IRON_DEVIL, MH_DEMONIC, -6, - { 14, 14, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 16, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREECH, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1226,7 +1226,7 @@ M_NO_FLAGS, MR_NO_FLAGS, 600, 10, MONS_SHAPESHIFTER, MONS_GLOWING_SHAPESHIFTER, MH_NATURAL, -6, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1238,7 +1238,7 @@ M_NO_FLAGS, MR_NO_FLAGS, 600, 10, MONS_SHAPESHIFTER, MONS_SHAPESHIFTER, MH_NATURAL, -6, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1250,7 +1250,7 @@ M_NO_FLAGS, MR_VUL_POISON, 350, 10, MONS_GIANT_MITE, MONS_GIANT_MITE, MH_NATURAL, -1, - { 5, 0, 0, 0 }, + { {AT_BITE, AF_POISON, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 1, 7, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -1259,10 +1259,10 @@ { MONS_STEAM_DRAGON, 'D', LIGHTGREY, "steam dragon", - M_SPELLCASTER | M_FLIES | M_CLAWS, + M_SPELLCASTER | M_FLIES, MR_NO_FLAGS, 1000, 10, MONS_DRAGON, MONS_STEAM_DRAGON, MH_NATURAL, -3, - { 12, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 12}, {AT_CLAW, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 5, 5, 0 }, 5, 10, 10, 7, MST_STEAM_DRAGON, CE_CLEAN, Z_BIG, S_SILENT, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -1274,7 +1274,7 @@ M_WARM_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 750, 10, MONS_UGLY_THING, MONS_VERY_UGLY_THING, MH_NATURAL, -3, - { 17, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 17}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 4, 8, 8, 7, MST_NO_SPELLS, CE_MUTAGEN_RANDOM, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1286,7 +1286,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_RES_FIRE, 600, 12, MONS_ORC, MONS_ORC, MH_NATURAL, -3, - { 7, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 2, 3, 0 }, 5, 12, 10, 7, MST_ORC_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1298,7 +1298,7 @@ M_FLIES | M_WARM_BLOOD, MR_NO_FLAGS, 1000, 10, MONS_HIPPOGRIFF, MONS_HIPPOGRIFF, MH_NATURAL, -3, - { 10, 8, 8, 0 }, + { {AT_BITE, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 8}, {AT_CLAW, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL, MONUSE_OPEN_DOORS, SIZE_BIG @@ -1310,7 +1310,7 @@ M_FLIES | M_WARM_BLOOD, MR_NO_FLAGS, 1800, 10, MONS_GRIFFON, MONS_GRIFFON, MH_NATURAL, -3, - { 18, 10, 10, 0 }, + { {AT_BITE, AF_PLAIN, 18}, {AT_CLAW, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 4, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SCREECH, I_ANIMAL, MONUSE_OPEN_DOORS, SIZE_BIG @@ -1322,7 +1322,7 @@ M_AMPHIBIOUS, // because it likes the swamp -- bwr MR_RES_POISON, 1800, 11, MONS_HYDRA, MONS_HYDRA, MH_NATURAL, -3, - { 18, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 3, 5, 0 }, 0, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_REPTILE, MONUSE_OPEN_DOORS, SIZE_BIG @@ -1335,7 +1335,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SKELETON_SMALL, MONS_SKELETON_SMALL, MH_UNDEAD, -1, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -1348,7 +1348,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SKELETON_SMALL, MONS_SKELETON_LARGE, MH_UNDEAD, -1, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 0, 0, 0, 0 }, 0, 0, 0, 0, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -1361,7 +1361,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_RES_FIRE, 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, - { 13, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 6, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1373,7 +1373,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 2, 4, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1385,7 +1385,7 @@ M_SPELLCASTER | M_SPEAKS | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_ELEC, 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 2, 4, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1397,7 +1397,7 @@ M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -4, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 4, 0 }, 1, 10, 10, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1409,7 +1409,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_EVIL, MR_RES_HELLFIRE, 600, 10, MONS_ORC, MONS_ORC, MH_NATURAL, -4, - { 7, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 4, 0 }, 1, 12, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1426,7 +1426,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 550, 10, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1438,7 +1438,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 750, 10, MONS_GNOLL, MONS_GNOLL, MH_NATURAL, -3, - { 9, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 4, 5, 0 }, 2, 9, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1450,7 +1450,7 @@ M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_CLAY_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 11, 11, 0, 0 }, + { {AT_HIT, AF_PLAIN, 11}, {AT_HIT, AF_PLAIN, 11}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 7, 3, 0 }, 7, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1462,7 +1462,7 @@ M_NO_FLAGS, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_WOOD_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 6, 3, 0 }, 5, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1474,7 +1474,7 @@ M_NO_FLAGS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_STONE_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 28, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 28}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 7, 4, 0 }, 12, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1486,7 +1486,7 @@ M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_IRON_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 35, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 7, 4, 0 }, 15, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1498,7 +1498,7 @@ M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_CRYSTAL_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 40, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 40}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 7, 4, 0 }, 22, 3, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1510,7 +1510,7 @@ M_NO_FLAGS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_TOENAIL_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 13, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 5, 3, 0 }, 8, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1519,10 +1519,10 @@ { MONS_MOTTLED_DRAGON, 'D', RED, "mottled dragon", - M_SPELLCASTER | M_FLIES | M_CLAWS, + M_SPELLCASTER | M_FLIES, MR_RES_POISON | MR_RES_FIRE, 1100, 10, MONS_DRAGON, MONS_MOTTLED_DRAGON, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 5, 10, 10, 7, MST_MOTTLED_DRAGON, CE_POISONOUS, Z_BIG, S_SILENT, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -1534,7 +1534,7 @@ M_NO_FLAGS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_EARTH_ELEMENTAL, MONS_EARTH_ELEMENTAL, MH_NONLIVING, MAG_IMMUNE, - { 40, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 40}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 5, 5, 0 }, 14, 4, 6, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_BIG @@ -1546,7 +1546,7 @@ M_FLIES, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD | MR_RES_ELEC, 0, 10, MONS_EARTH_ELEMENTAL, MONS_FIRE_ELEMENTAL, MH_NONLIVING, MAG_IMMUNE, - { 5, 0, 0, 0 }, + { {AT_ENGULF, AF_FIRE, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_BIG @@ -1558,7 +1558,7 @@ M_LEVITATE | M_SEE_INVIS | M_FLIES, MR_RES_ELEC | MR_RES_POISON, 0, 5, MONS_EARTH_ELEMENTAL, MONS_AIR_ELEMENTAL, MH_NONLIVING, MAG_IMMUNE, - { 15, 0, 0, 0 }, + { {AT_ENGULF, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 2, 18, 25, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_BIG @@ -1572,7 +1572,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_FIEND, MONS_ICE_FIEND, MH_DEMONIC, -12, - { 25, 25, 0, 0 }, + { {AT_CLAW, AF_COLD, 25}, {AT_CLAW, AF_COLD, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_ICE_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1584,7 +1584,7 @@ M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_FIEND, MONS_SHADOW_FIEND, MH_DEMONIC, -13, - { 25, 15, 15, 0 }, + { {AT_HIT, AF_DRAIN_XP, 25}, {AT_HIT, AF_DRAIN_XP, 15}, {AT_HIT, AF_DRAIN_XP, 15}, {AT_NONE, AF_PLAIN, 0} }, { 18, 3, 5, 0 }, 15, 6, 10, 7, MST_SHADOW_FIEND, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1596,7 +1596,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_RES_POISON, 300, 10, MONS_SNAKE, MONS_BROWN_SNAKE, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_BITE, AF_POISON_MEDIUM, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 2, 15, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_MEDIUM @@ -1608,7 +1608,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 600, 10, MONS_GIANT_LIZARD, MONS_GIANT_LIZARD, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, MONUSE_NOTHING, SIZE_LITTLE @@ -1620,7 +1620,7 @@ M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_WRAITH, MONS_SPECTRAL_WARRIOR, MH_UNDEAD, -6, - { 18, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_XP, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 12, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1632,7 +1632,7 @@ M_SEE_INVIS, MR_RES_POISON | MR_RES_ASPHYX, 0, 3, MONS_JELLY, MONS_PULSATING_LUMP, MH_NATURAL, -3, - { 13, 0, 0, 0 }, + { {AT_HIT, AF_MUTATE, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 2, 6, 5, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LITTLE @@ -1641,10 +1641,10 @@ { MONS_STORM_DRAGON, 'D', LIGHTBLUE, "storm dragon", - M_SPELLCASTER | M_FLIES | M_CLAWS, + M_SPELLCASTER | M_FLIES, MR_RES_ELEC | MR_RES_COLD, 2800, 12, MONS_DRAGON, MONS_STORM_DRAGON, MH_NATURAL, -5, - { 25, 15, 15, 0 }, + { {AT_BITE, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} }, { 14, 5, 5, 0 }, 13, 10, 12, 7, MST_STORM_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -1656,7 +1656,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 2000, 10, MONS_YAKTAUR, MONS_YAKTAUR, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -1668,7 +1668,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 1500, 10, MONS_YAK, MONS_DEATH_YAK, MH_NATURAL, -5, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 3, 5, 0 }, 9, 5, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_BELLOW, I_ANIMAL, MONUSE_NOTHING, SIZE_BIG @@ -1680,7 +1680,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 2200, 11, MONS_TROLL, MONS_ROCK_TROLL, MH_NATURAL, -4, - { 30, 20, 20, 0 }, + { {AT_BITE, AF_PLAIN, 30}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 13, 6, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -1692,7 +1692,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 3000, 10, MONS_HILL_GIANT, MONS_STONE_GIANT, MH_NATURAL, -4, - { 45, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 45}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 3, 5, 0 }, 12, 2, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_STARTING_EQUIPMENT, SIZE_GIANT @@ -1704,7 +1704,7 @@ M_FLIES | M_EVIL, MR_RES_POISON, 0, 10, MONS_PHANTOM, MONS_FLAYED_GHOST, MH_UNDEAD, -4, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 0, 14, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1716,7 +1716,7 @@ M_FLIES, MR_VUL_POISON, 300, 10, MONS_KILLER_BEE, MONS_BUMBLEBEE, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_STING, AF_POISON_MEDIUM, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 4, 15, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_BUZZ, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -1728,7 +1728,7 @@ M_NO_FLAGS, MR_VUL_POISON, 1000, 14, MONS_WOLF_SPIDER, MONS_REDBACK, MH_NATURAL, -3, - { 18, 0, 0, 0 }, + { {AT_BITE, AF_POISON_STRONG, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 2, 12, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -1740,7 +1740,7 @@ M_LEVITATE | M_SPECIAL_ABILITY, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 0, 17, MONS_INSUBSTANTIAL_WISP, MONS_INSUBSTANTIAL_WISP, MH_NONLIVING, MAG_IMMUNE, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_BLINK, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 1, 2, 0 }, 20, 20, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_PLANT, MONUSE_NOTHING, SIZE_TINY @@ -1752,7 +1752,7 @@ M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_INVIS | M_CONFUSED, MR_RES_ELEC | MR_RES_POISON, 0, 21, MONS_VAPOUR, MONS_VAPOUR, MH_NONLIVING, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 2, 3, 0 }, 0, 12, 10, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LITTLE @@ -1764,7 +1764,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD | M_EVIL, MR_RES_ELEC, 0, 16, MONS_OGRE, MONS_OGRE, MH_NATURAL, -6, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 1, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_LARGE @@ -1776,7 +1776,7 @@ M_NO_FLAGS, MR_VUL_POISON, 1300, 13, MONS_WORM, MONS_SPINY_WORM, MH_NATURAL, -3, - { 32, 0, 0, 0 }, + { {AT_STING, AF_ACID, 32}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 10, 6, 9, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_BIG @@ -1790,7 +1790,7 @@ M_LEVITATE, MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_DANCING_WEAPON, MONS_DANCING_WEAPON, MH_NONLIVING, MAG_IMMUNE, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 0, 0, 15 }, 10, 20, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING @@ -1802,7 +1802,7 @@ M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_RES_ELEC, 3500, 12, MONS_HILL_GIANT, MONS_TITAN, MH_NATURAL, -7, - { 55, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 55}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 20, 3, 5, 0 }, 10, 3, 10, 7, MST_TITAN, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -1811,10 +1811,10 @@ { MONS_GOLDEN_DRAGON, 'D', YELLOW, "golden dragon", - M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_CLAWS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 3000, 17, MONS_DRAGON, MONS_GOLDEN_DRAGON, MH_NATURAL, -8, - { 40, 20, 20, 0 }, + { {AT_BITE, AF_PLAIN, 40}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} }, { 18, 4, 4, 0 }, 15, 7, 10, 7, MST_GOLDEN_DRAGON, CE_POISONOUS, Z_BIG, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -1828,7 +1828,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 3, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -1844,7 +1844,7 @@ M_SPECIAL_ABILITY, MR_NO_FLAGS, 1000, 11, MONS_DRAGON, MONS_LINDWURM, MH_NATURAL, -3, - { 20, 10, 10, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 8, 6, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_ROAR, I_REPTILE, MONUSE_NOTHING, SIZE_GIANT @@ -1856,7 +1856,7 @@ M_NO_SKELETON, MR_VUL_POISON, 1500, 10, MONS_GIANT_SLUG, MONS_ELEPHANT_SLUG, MH_NATURAL, -3, - { 40, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 40}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 20, 5, 3, 0 }, 2, 1, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_BIG @@ -1868,7 +1868,7 @@ M_SEE_INVIS | M_WARM_BLOOD, MR_NO_FLAGS, 350, 10, MONS_HOUND, MONS_WAR_DOG, MH_NATURAL, -3, - { 12, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 4, 15, 17, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -1880,7 +1880,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 250, 10, MONS_RAT, MONS_GREY_RAT, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 6, 0 }, 2, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_TINY @@ -1892,7 +1892,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 250, 10, MONS_RAT, MONS_GREEN_RAT, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 5, 11, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_TINY @@ -1904,7 +1904,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 250, 10, MONS_RAT, MONS_ORANGE_RAT, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_DRAIN_XP, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 7, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_ANIMAL, MONUSE_NOTHING, SIZE_LITTLE @@ -1916,7 +1916,7 @@ M_COLD_BLOOD, MR_RES_POISON, 500, 12, MONS_SNAKE, MONS_BLACK_SNAKE, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_POISON_STRONG, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 4, 15, 18, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_MEDIUM @@ -1928,7 +1928,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 1200, 10, MONS_SHEEP, MONS_SHEEP, MH_NATURAL, -3, - { 13, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 2, 7, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BELLOW, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -1937,10 +1937,10 @@ { MONS_GHOUL, 'n', RED, "ghoul", - M_EVIL | M_CLAWS, + M_EVIL, MR_RES_POISON | MR_RES_COLD, 500, 12, MONS_GHOUL, MONS_GHOUL, MH_UNDEAD, -5, - { 9, 0, 0, 0 }, + { {AT_CLAW, AF_ROT, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_HCL, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -1952,7 +1952,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 700, 10, MONS_HOG, MONS_HOG, MH_NATURAL, -3, - { 14, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 2, 9, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -1964,7 +1964,7 @@ M_FLIES, MR_VUL_POISON, 100, 10, MONS_GIANT_MOSQUITO, MONS_GIANT_MOSQUITO, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_BITE, AF_DISEASE, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 0, 13, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_WHINE, I_PLANT, MONUSE_NOTHING, SIZE_TINY @@ -1976,7 +1976,7 @@ M_NO_FLAGS, MR_VUL_POISON, 350, 10, MONS_GIANT_CENTIPEDE, MONS_GIANT_CENTIPEDE, MH_NATURAL, -3, - { 2, 0, 0, 0 }, + { {AT_STING, AF_POISON_NASTY, 2}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 3, 0 }, 2, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -1990,7 +1990,7 @@ M_WARM_BLOOD | M_EVIL, MR_RES_FIRE | MR_RES_COLD, 2400, 10, MONS_TROLL, MONS_IRON_TROLL, MH_NATURAL, -5, - { 35, 25, 25, 0 }, + { {AT_BITE, AF_PLAIN, 35}, {AT_CLAW, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0} }, { 16, 3, 5, 0 }, 20, 4, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_ROAR, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2002,7 +2002,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, 750, 10, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6, - { 13, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 6, 10, 8, 7, MST_NAGA, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -2014,7 +2014,7 @@ M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_RES_FIRE, 2400, 11, MONS_HILL_GIANT, MONS_FIRE_GIANT, MH_NATURAL, -4, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 3, 6, 0 }, 8, 4, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT @@ -2026,7 +2026,7 @@ M_SPELLCASTER | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_RES_COLD, 2600, 11, MONS_HILL_GIANT, MONS_FROST_GIANT, MH_NATURAL, -4, - { 35, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 4, 5, 0 }, 9, 3, 10, 7, MST_FROST_GIANT, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT @@ -2038,7 +2038,7 @@ M_FLIES | M_SPECIAL_ABILITY, MR_RES_FIRE, 900, 10, MONS_FIREDRAKE, MONS_FIREDRAKE, MH_NATURAL, -3, - { 8, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 3, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_ANIMAL, MONUSE_OPEN_DOORS @@ -2047,10 +2047,10 @@ { MONS_SHADOW_DRAGON, 'D', DARKGREY, "shadow dragon", - M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL | M_CLAWS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 2000, 12, MONS_DRAGON, MONS_SHADOW_DRAGON, MH_NATURAL, -5, - { 20, 15, 15, 0 }, + { {AT_BITE, AF_DRAIN_XP, 20}, {AT_CLAW, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} }, { 17, 5, 5, 0 }, 15, 10, 10, 7, MST_SHADOW_DRAGON, CE_CLEAN, Z_BIG, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -2061,7 +2061,7 @@ M_COLD_BLOOD, MR_RES_POISON, 400, 10, MONS_SNAKE, MONS_YELLOW_SNAKE, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_BITE, AF_POISON_MEDIUM, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 4, 14, 13, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_MEDIUM @@ -2073,7 +2073,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 600, 10, MONS_SNAKE, MONS_GREY_SNAKE, MH_NATURAL, -3, - { 30, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 4, 16, 18, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_LARGE @@ -2085,7 +2085,7 @@ M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, 1500, 12, MONS_TROLL, MONS_DEEP_TROLL, MH_NATURAL, -3, - { 27, 20, 20, 0 }, + { {AT_BITE, AF_PLAIN, 27}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 6, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_BIG @@ -2097,7 +2097,7 @@ M_FLIES, MR_VUL_POISON, 200, 10, MONS_GIANT_BLOWFLY, MONS_GIANT_BLOWFLY, MH_NATURAL, -3, - { 13, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 2, 15, 19, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_PLANT, MONUSE_NOTHING, SIZE_TINY @@ -2109,7 +2109,7 @@ M_FLIES, MR_VUL_POISON, 400, 14, MONS_YELLOW_WASP, MONS_RED_WASP, MH_NATURAL, -3, - { 23, 0, 0, 0 }, + { {AT_STING, AF_PARALYSE, 23}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 7, 14, 15, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_BUZZ, I_PLANT, MONUSE_NOTHING, SIZE_TINY @@ -2118,10 +2118,10 @@ { MONS_SWAMP_DRAGON, 'D', BROWN, "swamp dragon", - M_SPELLCASTER | M_FLIES | M_CLAWS, + M_SPELLCASTER | M_FLIES, MR_RES_POISON, 1900, 11, MONS_DRAGON, MONS_SWAMP_DRAGON, MH_NATURAL, -3, - { 18, 9, 9, 0 }, + { {AT_BITE, AF_PLAIN, 18}, {AT_CLAW, AF_PLAIN, 9}, {AT_CLAW, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0} }, { 9, 5, 5, 0 }, 7, 7, 10, 7, MST_SWAMP_DRAGON, CE_CONTAMINATED, Z_BIG, S_ROAR, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -2133,7 +2133,7 @@ M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON, 900, 11, MONS_DRAGON, MONS_SWAMP_DRAKE, MH_NATURAL, -3, - { 14, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 5, 5, 0 }, 3, 11, 11, 7, MST_SWAMP_DRAKE, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS, SIZE_BIG @@ -2145,7 +2145,7 @@ M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON, 900, 11, MONS_DRAGON, MONS_DEATH_DRAKE, MH_NATURAL, -3, - { 12, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 5, 7, 0 }, 6, 14, 13, 10, MST_DEATH_DRAKE, CE_HCL, Z_BIG, S_ROAR, I_ANIMAL_LIKE, MONUSE_OPEN_DOORS, SIZE_BIG @@ -2157,7 +2157,7 @@ M_NO_FLAGS, MR_VUL_POISON, 900, 10, MONS_GIANT_ANT, MONS_SOLDIER_ANT, MH_NATURAL, -3, - { 14, 0, 0, 0 }, + { {AT_STING, AF_POISON_NASTY, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 8, 10, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LITTLE @@ -2169,7 +2169,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 1600, 10, MONS_HILL_GIANT, MONS_HILL_GIANT, MH_NATURAL, -3, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 3, 4, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -2181,7 +2181,7 @@ M_NO_FLAGS, MR_VUL_POISON, 1200, 10, MONS_GIANT_ANT, MONS_QUEEN_ANT, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_STING, AF_POISON_NASTY, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 3, 5, 0 }, 14, 3, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_SMALL @@ -2193,7 +2193,7 @@ M_NO_SKELETON, MR_VUL_POISON, 350, 5, MONS_GIANT_ANT, MONS_ANT_LARVA, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 2, 6, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -2206,7 +2206,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 500, 10, MONS_GIANT_FROG, MONS_GIANT_FROG, MH_NATURAL, -3, - { 9, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 0, 12, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -2218,7 +2218,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 890, 10, MONS_GIANT_FROG, MONS_GIANT_BROWN_FROG, MH_NATURAL, -3, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 2, 11, 13, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_CROAK, I_ANIMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -2230,7 +2230,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_RES_POISON, 1000, 10, MONS_GIANT_FROG, MONS_SPINY_FROG, MH_NATURAL, -3, - { 26, 0, 0, 0 }, + { {AT_STING, AF_POISON_MEDIUM, 26}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 6, 9, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_CROAK, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -2242,7 +2242,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS | M_SPECIAL_ABILITY, MR_NO_FLAGS, 800, 12, MONS_GIANT_FROG, MONS_BLINK_FROG, MH_NATURAL, -5, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_BLINK, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 3, 12, 14, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_CROAK, I_ANIMAL, MONUSE_NOTHING, SIZE_LITTLE @@ -2253,7 +2253,7 @@ M_NO_FLAGS, MR_NO_FLAGS, 250, 10, MONS_GIANT_COCKROACH, MONS_GIANT_COCKROACH, MH_NATURAL, -1, - { 2, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 2}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 4, 0 }, 3, 10, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_TINY @@ -2264,7 +2264,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 100, 13, MONS_SNAKE, MONS_SMALL_SNAKE, MH_NATURAL, -1, - { 2, 0, 0, 0 }, + { {AT_BITE, AF_POISON, 2}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 2, 3, 0 }, 0, 11, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, MONUSE_NOTHING, SIZE_LITTLE @@ -2276,7 +2276,7 @@ M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, MR_RES_COLD, 0, 10, MONS_IMP, MONS_WHITE_IMP, MH_DEMONIC, -3, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_COLD, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 4, 10, 10, 7, MST_WHITE_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LITTLE @@ -2288,7 +2288,7 @@ M_EVIL, MR_RES_POISON, 0, 10, MONS_LEMURE, MONS_LEMURE, MH_DEMONIC, -3, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 1, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_SMALL @@ -2300,7 +2300,7 @@ M_EVIL, MR_VUL_FIRE | MR_RES_COLD, 0, 10, MONS_UFETUBUS, MONS_UFETUBUS, MH_DEMONIC, -3, - { 5, 5, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 4, 6, 0 }, 2, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2312,7 +2312,7 @@ M_EVIL, MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 10, MONS_MANES, MONS_MANES, MH_DEMONIC, -3, - { 5, 3, 3, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_HIT, AF_PLAIN, 3}, {AT_HIT, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 2, 8, 8, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_SMALL @@ -2324,7 +2324,7 @@ M_FLIES | M_EVIL, MR_RES_POISON, 0, 10, MONS_MIDGE, MONS_MIDGE, MH_DEMONIC, -3, - { 8, 0, 0, 0 }, + { {AT_HIT, AF_BLINK, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 4, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -2336,7 +2336,7 @@ M_SPELLCASTER | M_LEVITATE | M_EVIL, MR_RES_POISON, 0, 12, MONS_NEQOXEC, MONS_NEQOXEC, MH_DEMONIC, -6, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 4, 12, 10, 7, MST_NEQOXEC, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2348,7 +2348,7 @@ M_EVIL, MR_NO_FLAGS, 0, 12, MONS_ORANGE_DEMON, MONS_ORANGE_DEMON, MH_DEMONIC, -6, - { 10, 5, 0, 0 }, + { {AT_STING, AF_POISON_STR, 10}, {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 4, 5, 0 }, 3, 7, 7, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SCREECH, I_NORMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -2360,7 +2360,7 @@ M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON, 0, 12, MONS_HELLWING, MONS_HELLWING, MH_DEMONIC, -6, - { 17, 10, 0, 0 }, + { {AT_HIT, AF_PLAIN, 17}, {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 4, 5, 0 }, 8, 10, 10, 7, MST_HELLWING, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2372,7 +2372,7 @@ M_SPELLCASTER | M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_FIRE, 0, 12, MONS_SMOKE_DEMON, MONS_SMOKE_DEMON, MH_DEMONIC, -6, - { 8, 5, 5, 0 }, + { {AT_HIT, AF_PLAIN, 8}, {AT_HIT, AF_PLAIN, 5}, {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 5, 9, 9, 7, MST_SMOKE_DEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -2384,7 +2384,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_YNOXINUL, MONS_YNOXINUL, MH_DEMONIC, -6, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 3, 10, 10, 7, MST_YNOXINUL, CE_CONTAMINATED, Z_NOZOMBIE, S_BELLOW, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2396,7 +2396,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 14, MONS_EXECUTIONER, MONS_EXECUTIONER, MH_DEMONIC, -9, - { 30, 10, 10, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_HIT, AF_PLAIN, 10}, {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 10, 15, 20, 7, MST_HELL_KNIGHT_I, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2408,7 +2408,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON, 0, 14, MONS_GREEN_DEATH, MONS_GREEN_DEATH, MH_DEMONIC, -9, - { 32, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 32}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 3, 5, 0 }, 5, 7, 12, 7, MST_GREEN_DEATH, CE_POISONOUS, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2420,7 +2420,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 14, MONS_BLUE_DEATH, MONS_BLUE_DEATH, MH_DEMONIC, -9, - { 20, 20, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 10, 10, 12, 7, MST_BLUE_DEATH, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2432,7 +2432,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE | MR_VUL_COLD, 0, 14, MONS_BALRUG, MONS_BALRUG, MH_DEMONIC, -9, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_FIRE, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 3, 5, 0 }, 5, 12, 12, 7, MST_BALRUG, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -2444,7 +2444,7 @@ M_SPELLCASTER | M_LEVITATE | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_ELEC, 0, 14, MONS_CACODEMON, MONS_CACODEMON, MH_DEMONIC, -9, - { 22, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 22}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 3, 5, 0 }, 11, 10, 10, 7, MST_CACODEMON, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2457,7 +2457,7 @@ M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE, 0, 12, MONS_DEMONIC_CRAWLER, MONS_DEMONIC_CRAWLER, MH_DEMONIC, -6, - { 13, 13, 13, 13 }, + { {AT_HIT, AF_PLAIN, 13}, {AT_HIT, AF_PLAIN, 13}, {AT_HIT, AF_PLAIN, 13} }, { 9, 3, 5, 0 }, 10, 6, 9, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_BIG @@ -2469,7 +2469,7 @@ M_SEE_INVIS | M_LEVITATE | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_VUL_COLD | MR_RES_HELLFIRE, 0, 14, MONS_SUN_DEMON, MONS_SUN_DEMON, MH_DEMONIC, -6, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_FIRE, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 10, 12, 12, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2481,7 +2481,7 @@ M_SPELLCASTER | M_FLIES | M_SPEAKS | M_EVIL, MR_RES_COLD | MR_RES_POISON, 0, 11, MONS_IMP, MONS_SHADOW_IMP, MH_DEMONIC, -3, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 3, 11, 10, 7, MST_SHADOW_IMP, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LITTLE @@ -2493,7 +2493,7 @@ M_SEE_INVIS | M_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_SHADOW_DEMON, MONS_SHADOW_DEMON, MH_DEMONIC, -7, - { 21, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 21}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 7, 12, 11, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_CROAK, I_HIGH, MONUSE_OPEN_DOORS, SIZE_SMALL @@ -2505,7 +2505,7 @@ M_SEE_INVIS | M_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC, 0, 12, MONS_LOROCYPROCA, MONS_LOROCYPROCA, MH_DEMONIC, -7, - { 25, 25, 0, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 10, 12, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2517,7 +2517,7 @@ M_LEVITATE | M_SEE_INVIS | M_INVIS | M_EVIL, MR_RES_POISON, 0, 15, MONS_WRAITH, MONS_SHADOW_WRAITH, MH_UNDEAD, -8, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_XP, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 7, 7, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2529,7 +2529,7 @@ M_NO_SKELETON | M_SEE_INVIS | M_AMPHIBIOUS, MR_RES_POISON, 1000, 10, MONS_GIANT_AMOEBA, MONS_GIANT_AMOEBA, MH_NATURAL, -3, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 5, 0 }, 0, 4, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LITTLE @@ -2541,7 +2541,7 @@ M_NO_SKELETON | M_AMPHIBIOUS, MR_NO_FLAGS, 700, 10, MONS_GIANT_SLUG, MONS_GIANT_SLUG, MH_NATURAL, -3, - { 23, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 23}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 5, 3, 0 }, 0, 2, 6, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LARGE @@ -2553,7 +2553,7 @@ M_NO_SKELETON | M_AMPHIBIOUS, MR_NO_FLAGS, 900, 10, MONS_GIANT_SLUG, MONS_GIANT_SNAIL, MH_NATURAL, -3, - { 18, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 5, 3, 0 }, 7, 2, 4, 10, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LARGE @@ -2565,7 +2565,7 @@ M_LEVITATE | M_CONFUSED, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 5, MONS_FIRE_VORTEX, MONS_SPATIAL_VORTEX, MH_NONLIVING, MAG_IMMUNE, - { 50, 0, 0, 0 }, + { {AT_ENGULF, AF_PLAIN, 50}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 6, 6, 0 }, 0, 5, 15, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -2577,7 +2577,7 @@ M_FLIES | M_SEE_INVIS | M_EVIL | M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD | MR_RES_ELEC, 0, 18, MONS_FIEND, MONS_PIT_FIEND, MH_DEMONIC, -12, - { 28, 21, 21, 0 }, + { {AT_HIT, AF_PLAIN, 28}, {AT_HIT, AF_PLAIN, 21}, {AT_HIT, AF_PLAIN, 21}, {AT_NONE, AF_PLAIN, 0} }, { 19, 4, 5, 0 }, 17, 5, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2589,7 +2589,7 @@ M_NO_FLAGS, MR_VUL_POISON, 1300, 10, MONS_GIANT_BEETLE, MONS_BORING_BEETLE, MH_NATURAL, -3, - { 26, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 26}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 13, 4, 6, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_SILENT, I_INSECT, MONUSE_NOTHING, SIZE_LARGE @@ -2601,7 +2601,7 @@ M_FLIES, MR_RES_POISON | MR_RES_ELEC, 0, 12, MONS_GARGOYLE, MONS_GARGOYLE, MH_NONLIVING, -6, - { 10, 6, 6, 0 }, + { {AT_BITE, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 6}, {AT_CLAW, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 18, 6, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2614,7 +2614,7 @@ M_FLIES, MR_RES_POISON | MR_RES_ELEC, 0, 12, MONS_GARGOYLE, MONS_METAL_GARGOYLE, MH_NONLIVING, -6, - { 19, 10, 10, 0 }, + { {AT_BITE, AF_PLAIN, 19}, {AT_CLAW, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 20, 4, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2627,7 +2627,7 @@ M_FLIES, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE, 0, 12, MONS_GARGOYLE, MONS_MOLTEN_GARGOYLE, MH_NONLIVING, -6, - { 12, 8, 8, 0 }, + { {AT_BITE, AF_FIRE, 12}, {AT_CLAW, AF_PLAIN, 8}, {AT_CLAW, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 14, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -2643,7 +2643,7 @@ M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE, 0, 25, MONS_MNOLEG, MONS_MNOLEG, MH_DEMONIC, MAG_IMMUNE, - { 23, 23, 0, 0 }, + { {AT_HIT, AF_PLAIN, 23}, {AT_HIT, AF_PLAIN, 23}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 17, 0, 0, 199 }, 10, 13, 13, 7, MST_MNOLEG, CE_CONTAMINATED, Z_NOZOMBIE, S_BUZZ, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2655,7 +2655,7 @@ M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 25, MONS_LOM_LOBON, MONS_LOM_LOBON, MH_DEMONIC, MAG_IMMUNE, - { 40, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 40}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 19, 0, 0, 223 }, 10, 7, 8, 7, MST_LOM_LOBON, CE_CONTAMINATED, Z_NOZOMBIE, S_SCREAM, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2667,7 +2667,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE, 0, 25, MONS_CEREBOV, MONS_CEREBOV, MH_DEMONIC, -6, - { 50, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 50}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 21, 0, 0, 253 }, 15, 8, 10, 7, MST_CEREBOV, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT @@ -2679,7 +2679,7 @@ M_LEVITATE | M_SEE_INVIS | M_SPELLCASTER | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 25, MONS_GLOORX_VLOQ, MONS_GLOORX_VLOQ, MH_DEMONIC, -14, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 0, 0, 234 }, 10, 10, 10, 7, MST_GLOORX_VLOQ, CE_CONTAMINATED, Z_NOZOMBIE, S_MOAN, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -2698,7 +2698,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, 750, 13, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 6, 10, 8, 7, MST_NAGA_MAGE, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -2710,7 +2710,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, 750, 12, MONS_NAGA, MONS_NAGA, MH_NATURAL, -6, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 5, 5, 0 }, 6, 10, 8, 7, MST_NAGA, CE_POISONOUS, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -2722,7 +2722,7 @@ M_WARM_BLOOD | M_EVIL, MR_NO_FLAGS, 600, 15, MONS_ORC, MONS_ORC, MH_NATURAL, -3, - { 32, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 32}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 4, 7, 0 }, 3, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2734,7 +2734,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 3, 0 }, 0, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2746,7 +2746,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 9, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2758,7 +2758,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 3, 0 }, 0, 15, 11, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2770,7 +2770,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_ELEC, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2782,7 +2782,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_SUMMONER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2794,7 +2794,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_RES_ELEC, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 3, 0 }, 0, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2806,7 +2806,7 @@ M_SPELLCASTER | M_PRIEST | M_WARM_BLOOD, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 9, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2818,7 +2818,7 @@ M_SPELLCASTER | M_SPEAKS | M_PRIEST | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 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, SIZE_MEDIUM @@ -2830,7 +2830,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_DEMONOLOGIST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2842,7 +2842,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS, MR_RES_ELEC, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2854,7 +2854,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_SPEAKS, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 3, 3, 0 }, 0, 13, 10, 7, MST_DEEP_ELF_SORCERER, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2866,7 +2866,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD | M_SEE_INVIS | M_EVIL, MR_NO_FLAGS, 450, 10, MONS_ELF, MONS_ELF, MH_NATURAL, -6, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 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, SIZE_MEDIUM @@ -2878,7 +2878,7 @@ 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 }, + { {AT_HIT, AF_ACID, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 10, 1, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_EATS_ITEMS, SIZE_LITTLE @@ -2890,7 +2890,7 @@ M_NO_SKELETON | M_SEE_INVIS, MR_RES_POISON | MR_RES_COLD | MR_VUL_FIRE | MR_RES_ELEC | MR_RES_ASPHYX, 0, 11, MONS_JELLY, MONS_AZURE_JELLY, MH_NATURAL, -4, - { 12, 12, 12, 12 }, + { {AT_HIT, AF_COLD, 12}, {AT_HIT, AF_COLD, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12} }, { 15, 3, 5, 0 }, 5, 10, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_EATS_ITEMS, SIZE_LITTLE @@ -2902,7 +2902,7 @@ M_NO_SKELETON | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ASPHYX, 0, 13, MONS_JELLY, MONS_DEATH_OOZE, MH_UNDEAD, -8, - { 32, 32, 0, 0 }, + { {AT_HIT, AF_ROT, 32}, {AT_HIT, AF_PLAIN, 32}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 3, 0 }, 2, 4, 12, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_EATS_ITEMS, SIZE_LITTLE @@ -2914,7 +2914,7 @@ 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 }, + { {AT_HIT, AF_ACID, 42}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 18, 3, 5, 0 }, 1, 3, 14, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_EATS_ITEMS, SIZE_LITTLE @@ -2926,7 +2926,7 @@ 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 }, + { {AT_HIT, AF_ACID, 50}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 21, 0, 0, 111 }, 8, 4, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_EATS_ITEMS, SIZE_SMALL @@ -2938,7 +2938,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, - { 3, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 0, 0, 14 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2950,7 +2950,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 0, 0, 10 }, 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2962,7 +2962,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 5, MONS_GOBLIN, MONS_GOBLIN, MH_NATURAL, -3, - { 4, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 0, 0, 28 }, 2, 12, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_SMALL @@ -2974,7 +2974,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 0, 0, 25 }, 0, 11, 10, 7, MST_ORC_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2986,7 +2986,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_ORC, MONS_ORC, MH_NATURAL, -4, - { 7, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 0, 0, 32 }, 0, 9, 8, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -2998,7 +2998,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 0, 0, 27 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3010,7 +3010,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -4, - { 7, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 0, 0, 24 }, 0, 12, 13, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3023,7 +3023,7 @@ | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_ELEC, 0, 20, MONS_OGRE, MONS_OGRE, MH_NATURAL, -7, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 0, 0, 45 }, 3, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_LARGE @@ -3035,7 +3035,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 8, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 0, 0, 33 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3047,7 +3047,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_ORC, MONS_ORC, MH_NATURAL, -5, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 0, 0, 38 }, 0, 11, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3059,7 +3059,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 9, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 0, 0, 36 }, 0, 10, 10, 7, MST_ORC_WIZARD_III, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3071,7 +3071,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 9, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 9}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 0, 0, 42 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3083,7 +3083,7 @@ M_WARM_BLOOD | M_SPEAKS | M_EVIL | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_TROLL, MONS_TROLL, MH_NATURAL, -6, - { 20, 15, 15, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} }, { 8, 0, 0, 45 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -3095,7 +3095,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 10, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 0, 0, 43 }, 0, 11, 11, 7, MST_WIZARD_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3107,7 +3107,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 11, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 11}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 0, 0, 47 }, 0, 10, 10, 7, MST_NECROMANCER_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3119,7 +3119,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 0, 0, 51 }, 0, 8, 10, 7, MST_HELL_KNIGHT_II, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3131,7 +3131,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 0, 0, 53 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3143,7 +3143,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 0, 0, 60 }, 0, 9, 10, 7, MST_GUARDIAN_NAGA, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3155,7 +3155,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 11, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 11}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 0, 0, 64 }, 0, 10, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3167,7 +3167,7 @@ M_WARM_BLOOD | M_SPEAKS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 0, 0, 55 }, 0, 10, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3179,7 +3179,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SPEAKS | M_WARM_BLOOD | M_UNIQUE, MR_RES_ELEC, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 0, 0, 52 }, 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3192,7 +3192,7 @@ | M_SEE_INVIS | M_EVIL | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 12, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 0, 0, 67 }, 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3205,7 +3205,7 @@ | M_SEE_INVIS | M_EVIL | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 11, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 11}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 0, 0, 70 }, 0, 10, 10, 7, MST_ORC_HIGH_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3218,7 +3218,7 @@ | M_SEE_INVIS | M_UNIQUE, MR_RES_ELEC, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 13, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 13}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 0, 0, 80 }, 0, 10, 10, 7, MST_WIZARD_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3231,7 +3231,7 @@ | M_SEE_INVIS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 17, 0, 0, 78 }, 1, 10, 7, 7, MST_ORC_PRIEST, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3244,7 +3244,7 @@ | M_SEE_INVIS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 18, 0, 0, 83 }, 0, 10, 10, 7, MST_ORC_WIZARD_I, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3253,10 +3253,10 @@ { MONS_XTAHUA, 'D', RED, "Xtahua", - M_SPEAKS | M_SEE_INVIS | M_FLIES | M_SPECIAL_ABILITY | M_UNIQUE | M_CLAWS, + M_SPEAKS | M_SEE_INVIS | M_FLIES | M_SPECIAL_ABILITY | M_UNIQUE, MR_RES_POISON | MR_RES_FIRE | MR_VUL_COLD, 0, 20, MONS_DRAGON, MONS_DRAGON, MH_NATURAL, -7, - { 29, 17, 17, 0 }, + { {AT_BITE, AF_PLAIN, 29}, {AT_CLAW, AF_PLAIN, 17}, {AT_CLAW, AF_PLAIN, 17}, {AT_NONE, AF_PLAIN, 0} }, { 19, 0, 0, 133 }, 15, 7, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -3269,7 +3269,7 @@ | M_SEE_INVIS | M_EVIL | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 16, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 16}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 20, 0, 0, 95 }, 1, 9, 9, 7, MST_MYSTIC, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3282,7 +3282,7 @@ | M_SEE_INVIS | M_EVIL | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 17, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 17}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 21, 0, 0, 105 }, 0, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3295,7 +3295,7 @@ | M_SEE_INVIS | M_UNIQUE, MR_NO_FLAGS, 0, 20, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -5, - { 18, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 18}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 22, 0, 0, 119 }, 0, 10, 10, 7, MST_EFREET, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3308,7 +3308,7 @@ | M_UNIQUE, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 23, MONS_LICH, MONS_LICH, MH_UNDEAD, -11, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_TOUCH, AF_DRAIN_XP, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 22, 0, 0, 99 }, 12, 10, 10, 7, MST_LICH_IV, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3321,7 +3321,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_UNIQUE, MR_NO_FLAGS, 0, 25, MONS_GERYON, MONS_GERYON, MH_DEMONIC, -6, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 0, 0, 240 }, 15, 6, 10, 7, MST_GERYON, CE_CONTAMINATED, Z_NOZOMBIE, S_ROAR, I_NORMAL, MONUSE_STARTING_EQUIPMENT, SIZE_GIANT @@ -3333,7 +3333,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 25, MONS_DISPATER, MONS_DISPATER, MH_DEMONIC, -10, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 0, 0, 222 }, 15, 3, 6, 7, MST_DISPATER, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_LARGE @@ -3345,7 +3345,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE, 0, 25, MONS_ASMODEUS, MONS_ASMODEUS, MH_DEMONIC, -12, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 17, 0, 0, 245 }, 12, 7, 9, 7, MST_ASMODEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_LARGE @@ -3358,7 +3358,7 @@ M_SPELLCASTER | M_SPEAKS | M_UNIQUE, MR_RES_ELEC | MR_VUL_FIRE | MR_RES_COLD, 0, 25, MONS_HILL_GIANT, MONS_ANTAEUS, MH_DEMONIC, -9, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_COLD, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 22, 0, 0, 250 }, 10, 4, 7, 7, MST_ANTAEUS, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_GIANT @@ -3370,7 +3370,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_ELEC | MR_RES_POISON | MR_RES_COLD, 0, 25, MONS_ERESHKIGAL, MONS_ERESHKIGAL, MH_DEMONIC, -10, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 18, 0, 0, 238 }, 15, 6, 9, 7, MST_ERESHKIGAL, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_LARGE @@ -3382,7 +3382,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_FIRE | MR_RES_ELEC, 0, 20, MONS_LICH, MONS_LICH, MH_UNDEAD, -14, - { 20, 0, 0, 0 }, + { {AT_TOUCH, AF_DRAIN_XP, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 27, 2, 4, 0 }, 20, 10, 12, 7, MST_LICH_I, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -3395,7 +3395,7 @@ M_NO_SKELETON | M_SEE_INVIS, MR_RES_POISON | MR_RES_ASPHYX, 0, 5, MONS_JELLY, MONS_OOZE, MH_NATURAL, -6, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_ACID, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 1, 3, 8, 7, MST_NO_SPELLS, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LITTLE @@ -3407,7 +3407,7 @@ M_WARM_BLOOD | M_SEE_INVIS, MR_NO_FLAGS, 0, 12, MONS_HUMAN, MONS_HUMAN, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 3, 5, 0 }, 1, 13, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3421,7 +3421,7 @@ M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 50, MONS_LICH, MONS_CURSE_SKULL, MH_UNDEAD, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 13, 0, 0, 66 }, 40, 3, 10, 7, MST_CURSE_SKULL, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, MONUSE_NOTHING, SIZE_TINY @@ -3433,7 +3433,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6, - { 33, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 33}, {AT_BITE, AF_VAMPIRIC, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 7, 0 }, 10, 10, 10, 7, MST_VAMPIRE_KNIGHT, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3445,7 +3445,7 @@ M_SPELLCASTER | M_SEE_INVIS | M_FLIES | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 15, MONS_VAMPIRE, MONS_VAMPIRE, MH_UNDEAD, -6, - { 22, 0, 0, 0 }, + { {AT_BITE, AF_VAMPIRIC, 22}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 4, 0 }, 10, 10, 10, 7, MST_VAMPIRE_MAGE, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3457,7 +3457,7 @@ M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, MR_RES_ASPHYX, 0, 14, MONS_SHINING_EYE, MONS_SHINING_EYE, MH_NATURAL, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 3, 1, 7, 7, MST_SHINING_EYE, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_MEDIUM @@ -3469,7 +3469,7 @@ M_NO_SKELETON | M_SEE_INVIS, MR_NO_FLAGS, 0, 20, MONS_ORB_GUARDIAN, MONS_ORB_GUARDIAN, MH_NATURAL, -6, - { 45, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 45}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 3, 5, 0 }, 13, 13, 14, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -3481,7 +3481,7 @@ M_LEVITATE | M_SPELLCASTER, MR_RES_POISON, 0, 12, MONS_ANGEL, MONS_DAEVA, MH_HOLY, -8, - { 25, 10, 10, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_HIT, AF_PLAIN, 10}, {AT_HIT, AF_PLAIN, 10}, {AT_NONE, AF_PLAIN, 0} }, { 14, 6, 5, 0 }, 10, 13, 10, 7, MST_DAEVA, CE_NOCORPSE, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3494,7 +3494,7 @@ M_LEVITATE | M_SEE_INVIS, MR_RES_POISON | MR_RES_COLD, 0, 11, MONS_WRAITH, MONS_SPECTRAL_THING, MH_UNDEAD, MAG_IMMUNE, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_DRAIN_XP, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 8, 5, 7, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -3506,7 +3506,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, 750, 10, MONS_NAGA, MONS_NAGA, MH_NATURAL, MAG_IMMUNE, - { 24, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 24}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 3, 5, 0 }, 6, 10, 8, 7, MST_NAGA_MAGE, CE_POISONOUS, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -3515,10 +3515,10 @@ { MONS_SKELETAL_DRAGON, 'D', LIGHTGREY, "skeletal dragon", - M_SEE_INVIS | M_EVIL | M_CLAWS, + M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 12, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_DRAGON, MH_UNDEAD, -4, - { 30, 20, 20, 0 }, + { {AT_BITE, AF_PLAIN, 30}, {AT_CLAW, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0} }, { 20, 8, 8, 0 }, 20, 4, 8, 7, MST_NO_SPELLS, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -3530,7 +3530,7 @@ M_SEE_INVIS | M_AMPHIBIOUS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_TENTACLED_MONSTROSITY, MONS_TENTACLED_MONSTROSITY, MH_NATURAL, -5, - { 22, 17, 13, 19 }, + { {AT_HIT, AF_PLAIN, 22}, {AT_HIT, AF_PLAIN, 17}, {AT_HIT, AF_PLAIN, 13} }, { 25, 3, 5, 0 }, 5, 5, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -3542,7 +3542,7 @@ M_FLIES | M_SEE_INVIS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_WARM_BLOOD, MR_NO_FLAGS, 0, 10, MONS_SPHINX, MONS_SPHINX, MH_NATURAL, -3, - { 25, 12, 12, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0} }, { 16, 3, 5, 0 }, 5, 5, 13, 7, MST_SPHINX, CE_CLEAN, Z_NOZOMBIE, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_BIG @@ -3554,7 +3554,7 @@ M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 12, MONS_GHOUL, MONS_ROTTING_HULK, MH_UNDEAD, -5, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_DISEASE, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 5, 7, 8, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -3566,7 +3566,7 @@ M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 13, MONS_MUMMY, MONS_GUARDIAN_MUMMY, MH_UNDEAD, -5, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 5, 3, 0 }, 6, 9, 9, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -3578,7 +3578,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 20, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, MAG_IMMUNE, - { 35, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 35}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 15, 5, 3, 100 }, 10, 6, 10, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3590,7 +3590,7 @@ M_SPELLCASTER | M_PRIEST | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_COLD | MR_RES_ELEC, 0, 16, MONS_MUMMY, MONS_MUMMY, MH_UNDEAD, MAG_IMMUNE, - { 30, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 5, 3, 0 }, 8, 7, 9, 7, MST_MUMMY, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3602,7 +3602,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 1500, 12, MONS_CENTAUR, MONS_CENTAUR, MH_NATURAL, -3, - { 16, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 16}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 4, 8, 15, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_BIG @@ -3614,7 +3614,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 2000, 10, MONS_YAKTAUR, MONS_YAKTAUR, MH_NATURAL, -3, - { 23, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 23}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 3, 5, 0 }, 5, 5, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_SHOUT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -3628,7 +3628,7 @@ M_HUMANOID | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -1, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 3, 6, 4, 0 }, 7, 8, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3640,7 +3640,7 @@ M_HUMANOID | M_COLD_BLOOD, MR_RES_ELEC, 900, 10, MONS_DRACONIAN, MONS_BLACK_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3652,7 +3652,7 @@ M_HUMANOID | M_COLD_BLOOD | M_SPECIAL_ABILITY, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_YELLOW_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3664,7 +3664,7 @@ M_HUMANOID | M_COLD_BLOOD, MR_RES_FIRE, 900, 10, MONS_DRACONIAN, MONS_PALE_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 14, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3676,7 +3676,7 @@ M_HUMANOID | M_COLD_BLOOD, MR_RES_POISON, 900, 10, MONS_DRACONIAN, MONS_GREEN_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_POISONOUS, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3688,7 +3688,7 @@ M_HUMANOID | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_PURPLE_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 8, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3700,7 +3700,7 @@ M_HUMANOID | M_COLD_BLOOD | M_SPECIAL_ABILITY, MR_RES_FIRE, 900, 10, MONS_DRACONIAN, MONS_RED_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3712,7 +3712,7 @@ M_HUMANOID | M_COLD_BLOOD | M_SPECIAL_ABILITY, MR_RES_COLD, 900, 10, MONS_DRACONIAN, MONS_WHITE_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3724,7 +3724,7 @@ M_HUMANOID | M_COLD_BLOOD, MR_RES_FIRE, 900, 10, MONS_DRACONIAN, MONS_MOTTLED_DRACONIAN, MH_NATURAL, -2, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 14, 5, 4, 0 }, 9, 10, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3736,7 +3736,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 16, 4, 3, 0 }, 9, 10, 10, 10, MST_DRAC_CALLER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3748,7 +3748,8 @@ M_FIGHTER | M_HUMANOID | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -3, - { 35, 20, 15, 0 }, + { {AT_HIT, AF_PLAIN, 35}, {AT_HIT, AF_PLAIN, 20}, + {AT_TAIL_SLAP, AF_PLAIN, 15} }, { 16, 6, 3, 0 }, 6, 20, 10, 10, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3760,7 +3761,7 @@ M_SPELLCASTER | M_HUMANOID | M_PRIEST | M_COLD_BLOOD | M_EVIL, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 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, SIZE_MEDIUM @@ -3772,7 +3773,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -4, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 16, 4, 4, 0 }, 8, 16, 10, 10, MST_DRAC_SHIFTER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3784,7 +3785,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -4, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 16, 4, 2, 0 }, 8, 10, 10, 10, MST_DEEP_ELF_ANNIHILATOR, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3796,7 +3797,7 @@ M_SPELLCASTER | M_HUMANOID | M_FIGHTER | M_COLD_BLOOD, MR_NO_FLAGS, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -4, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 16, 6, 4, 0 }, 12, 12, 10, 6, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3808,7 +3809,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_HUMANOID | M_COLD_BLOOD | M_EVIL, MR_RES_FIRE | MR_RES_HELLFIRE, 900, 10, MONS_DRACONIAN, MONS_DRACONIAN, MH_NATURAL, -4, - { 15, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 15}, {AT_HIT, AF_PLAIN, 0}, {AT_HIT, AF_PLAIN, 0} }, { 16, 4, 2, 0 }, 8, 12, 10, 10, MST_DRAC_SCORCHER, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_STARTING_EQUIPMENT, SIZE_MEDIUM @@ -3818,9 +3819,9 @@ { MONS_KILLER_KLOWN, '@', BLACK, "Killer Klown", M_SEE_INVIS | M_SPEAKS | M_WARM_BLOOD | M_SPECIAL_ABILITY, - MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, - 0, 15, MONS_HUMAN, MONS_KILLER_KLOWN, MH_NATURAL, MAG_IMMUNE, - { 30, 0, 0, 0 }, + MR_NO_FLAGS, + 0, 15, MONS_HUMAN, MONS_KILLER_KLOWN, MH_NATURAL, -6, + { {AT_HIT, AF_KLOWN, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 20, 5, 5, 0 }, 10, 15, 15, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -3831,8 +3832,8 @@ MONS_ELECTRIC_GOLEM, '8', LIGHTCYAN, "electric golem", M_SPELLCASTER | M_SEE_INVIS, MR_RES_ELEC | MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, - 0, 10, MONS_CLAY_GOLEM, MONS_ELECTRIC_GOLEM, MH_NONLIVING, MAG_IMMUNE, - { 12, 12, 12, 12 }, + 0, 10, MONS_CLAY_GOLEM, MONS_ELECTRIC_GOLEM, MH_NONLIVING, -8, + { {AT_HIT, AF_ELEC, 12}, {AT_HIT, AF_ELEC, 12}, {AT_HIT, AF_ELEC, 12}, {AT_HIT, AF_PLAIN, 12} }, { 15, 7, 4, 0 }, 5, 20, 20, 7, MST_ELECTRIC_GOLEM, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -3844,7 +3845,7 @@ M_FLIES | M_CONFUSED | M_SPELLCASTER | M_SPECIAL_ABILITY, MR_RES_ELEC, 0, 20, MONS_BALL_LIGHTNING, MONS_BALL_LIGHTNING, MH_NONLIVING, MAG_IMMUNE, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 0, 0, 1 }, 0, 10, 20, 7, MST_STORM_DRAGON, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_LITTLE @@ -3856,7 +3857,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD | MR_RES_POISON, 0, 10, MONS_ORB_OF_FIRE, MONS_ORB_OF_FIRE, MH_NONLIVING, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 30, 0, 0, 150 }, 20, 20, 20, 7, MST_ORB_OF_FIRE, CE_CONTAMINATED, Z_NOZOMBIE, S_SHOUT, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_LITTLE @@ -3868,7 +3869,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 300, 10, MONS_QUOKKA, MONS_QUOKKA, MH_NATURAL, -1, - { 5, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 2, 13, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_NORMAL, MONUSE_NOTHING, SIZE_TINY @@ -3880,7 +3881,7 @@ M_NO_SKELETON | M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS, MR_RES_ASPHYX, 0, 11, MONS_GIANT_EYEBALL, MONS_EYE_OF_DEVASTATION, MH_NATURAL, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 3, 5, 0 }, 12, 1, 7, 7, MST_EYE_OF_DEVASTATION, CE_POISONOUS, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_BIG @@ -3892,7 +3893,7 @@ M_FLIES, MR_NO_FLAGS, 0, 10, MONS_MOTH_OF_WRATH, MONS_MOTH_OF_WRATH, MH_NATURAL, -3, - { 25, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 9, 3, 5, 0 }, 0, 10, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -3904,7 +3905,7 @@ M_SPEAKS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_DEATH_COB, MONS_DEATH_COB, MH_UNDEAD, -3, - { 20, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 4, 5, 0 }, 10, 15, 25, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_MOAN, I_NORMAL, MONUSE_OPEN_DOORS, SIZE_TINY @@ -3916,7 +3917,7 @@ M_LEVITATE | M_SPELLCASTER | M_SEE_INVIS | M_EVIL, MR_RES_ELEC | MR_RES_POISON | MR_RES_HELLFIRE | MR_RES_COLD, 0, 60, MONS_LICH, MONS_CURSE_TOE, MH_UNDEAD, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 0, 0, 77 }, 50, 1, 12, 7, MST_CURSE_TOE, CE_NOCORPSE, Z_NOZOMBIE, S_MOAN, I_HIGH, MONUSE_NOTHING, SIZE_TINY @@ -3929,7 +3930,7 @@ M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, - { 12, 12, 12, 0 }, + { {AT_HIT, AF_POISON, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_NOTHING, SIZE_TINY @@ -3941,7 +3942,7 @@ M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, - { 17, 17, 17, 0 }, + { {AT_HIT, AF_POISON, 17}, {AT_HIT, AF_PLAIN, 17}, {AT_HIT, AF_PLAIN, 17}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_NOTHING, SIZE_LITTLE @@ -3953,7 +3954,7 @@ M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, - { 12, 12, 12, 0 }, + { {AT_HIT, AF_POISON, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 15, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_NOTHING, SIZE_SMALL @@ -3965,7 +3966,7 @@ M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, - { 12, 12, 12, 0 }, + { {AT_HIT, AF_POISON, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_NOTHING, SIZE_TINY @@ -3977,7 +3978,7 @@ M_NO_SKELETON, MR_RES_POISON | MR_RES_ELEC | MR_RES_FIRE | MR_RES_COLD, 0, 13, MONS_GOLD_MIMIC, MONS_GOLD_MIMIC, MH_NONLIVING, -3, - { 12, 12, 12, 0 }, + { {AT_HIT, AF_POISON, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_HIT, AF_PLAIN, 12}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 5, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_NORMAL, MONUSE_NOTHING, SIZE_TINY @@ -3989,7 +3990,7 @@ M_SPELLCASTER | M_THICK_SKIN | M_EVIL, MR_NO_FLAGS, 0, 10, MONS_HELL_HOG, MONS_HELL_HOG, MH_DEMONIC, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 11, 3, 5, 0 }, 2, 9, 14, 7, MST_HELL_HOG, CE_CLEAN, Z_NOZOMBIE, S_SILENT, I_ANIMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -4001,7 +4002,7 @@ M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_EVIL, MR_RES_POISON | MR_RES_HELLFIRE, 0, 18, MONS_SERPENT_OF_HELL, MONS_SERPENT_OF_HELL, MH_DEMONIC, -13, - { 35, 15, 15, 0 }, + { {AT_BITE, AF_PLAIN, 35}, {AT_CLAW, AF_PLAIN, 15}, {AT_CLAW, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0} }, { 20, 4, 4, 0 }, 12, 9, 14, 7, MST_SERPENT_OF_HELL, CE_CLEAN, Z_NOZOMBIE, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -4013,7 +4014,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_SEE_INVIS, MR_NO_FLAGS, 0, 14, MONS_BOGGART, MONS_BOGGART, MH_NATURAL, -7, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 0, 12, 12, 7, MST_BOGGART, CE_CONTAMINATED, Z_SMALL, S_SHOUT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_LITTLE @@ -4022,10 +4023,10 @@ { MONS_QUICKSILVER_DRAGON, 'D', LIGHTCYAN, "quicksilver dragon", - M_SPELLCASTER | M_FLIES | M_SEE_INVIS | M_CLAWS, + M_SPELLCASTER | M_FLIES | M_SEE_INVIS, MR_NO_FLAGS, 0, 14, MONS_DRAGON, MONS_QUICKSILVER_DRAGON, MH_NATURAL, -7, - { 45, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 16, 3, 5, 0 }, 10, 15, 15, 7, MST_QUICKSILVER_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_GIANT @@ -4034,10 +4035,10 @@ { MONS_IRON_DRAGON, 'D', CYAN, "iron dragon", - M_SPELLCASTER | M_SEE_INVIS | M_CLAWS, + M_SPELLCASTER | M_SEE_INVIS, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD, 0, 14, MONS_DRAGON, MONS_IRON_DRAGON, MH_NATURAL, -7, - { 25, 25, 25, 0 }, + { {AT_BITE, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 25}, {AT_CLAW, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0} }, { 18, 5, 3, 0 }, 20, 6, 8, 7, MST_IRON_DRAGON, CE_CONTAMINATED, Z_SMALL, S_ROAR, I_HIGH, MONUSE_OPEN_DOORS, SIZE_HUGE @@ -4049,7 +4050,7 @@ M_SPELLCASTER | M_ACTUAL_SPELLS | M_EVIL, MR_RES_POISON | MR_RES_COLD, 0, 10, MONS_SKELETAL_WARRIOR, MONS_SKELETAL_WARRIOR, MH_UNDEAD, -7, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 10, 5, 3, 0 }, 15, 10, 10, 7, MST_SKELETAL_WARRIOR, CE_CONTAMINATED, Z_SMALL, S_SILENT, I_NORMAL, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -4063,7 +4064,7 @@ M_SPEAKS | M_SPELLCASTER | M_ACTUAL_SPELLS | M_FLIES | M_UNIQUE, MR_RES_POISON, 0, 15, MONS_PHANTOM, MONS_PLAYER_GHOST, MH_UNDEAD, -5, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 2, 3, 0 }, 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_OPEN_DOORS, SIZE_MEDIUM @@ -4076,7 +4077,7 @@ M_SPELLCASTER | M_SPEAKS | M_EVIL | M_UNIQUE, MR_RES_POISON, 0, 14, MONS_PANDEMONIUM_DEMON, MONS_PANDEMONIUM_DEMON, MH_DEMONIC, -5, - { 5, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 2, 3, 0 }, 1, 2, 10, 7, MST_GHOST, CE_CONTAMINATED, Z_NOZOMBIE, S_RANDOM, I_HIGH, MONUSE_OPEN_DOORS, SIZE_LARGE @@ -4089,7 +4090,7 @@ M_NO_FLAGS, MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_LAVA_WORM, MONS_LAVA_WORM, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_BITE, AF_FIRE, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 5, 0 }, 1, 10, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_LARGE @@ -4101,7 +4102,7 @@ M_NO_FLAGS, MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_BIG_FISH, MONS_LAVA_FISH, MH_NATURAL, -3, - { 10, 0, 0, 0 }, + { {AT_BITE, AF_FIRE, 10}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 4, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_LITTLE @@ -4113,7 +4114,7 @@ M_SPECIAL_ABILITY, MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_SNAKE, MONS_LAVA_SNAKE, MH_NATURAL, -3, - { 7, 0, 0, 0 }, + { {AT_BITE, AF_FIRE, 7}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 2, 17, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_HISS, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_MEDIUM @@ -4125,7 +4126,7 @@ M_WARM_BLOOD, MR_RES_FIRE | MR_VUL_COLD, 0, 10, MONS_SALAMANDER, MONS_SALAMANDER, MH_NATURAL, -3, - { 23, 0, 0, 0 }, + { {AT_HIT, AF_FIRE, 23}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 14, 3, 5, 0 }, 5, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_HIGH, MONUSE_WEAPONS_ARMOUR, SIZE_MEDIUM @@ -4140,7 +4141,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 0, 10, MONS_BIG_FISH, MONS_BIG_FISH, MH_NATURAL, -3, - { 8, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 1, 12, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_SMALL @@ -4152,7 +4153,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 0, 10, MONS_BIG_FISH, MONS_GIANT_GOLDFISH, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 5, 0 }, 5, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_LITTLE @@ -4164,7 +4165,7 @@ M_COLD_BLOOD | M_SPECIAL_ABILITY, MR_RES_ELEC, 0, 10, MONS_ELECTRICAL_EEL, MONS_ELECTRICAL_EEL, MH_NATURAL, -3, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 1, 15, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_ANIMAL_LIKE, MONUSE_NOTHING, SIZE_SMALL @@ -4176,7 +4177,7 @@ M_NO_FLAGS, MR_RES_POISON, 0, 10, MONS_JELLYFISH, MONS_JELLYFISH, MH_NATURAL, -3, - { 1, 1, 0, 0 }, + { {AT_STING, AF_POISON_STR, 1}, {AT_HIT, AF_PLAIN, 1}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 0, 5, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LITTLE @@ -4188,7 +4189,7 @@ M_FLIES, MR_RES_POISON | MR_VUL_FIRE | MR_RES_ELEC, 0, 10, MONS_EARTH_ELEMENTAL, MONS_WATER_ELEMENTAL, MH_NONLIVING, MAG_IMMUNE, - { 25, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 25}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 6, 5, 3, 0 }, 0, 7, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_OPEN_DOORS, SIZE_BIG @@ -4200,7 +4201,7 @@ M_AMPHIBIOUS, MR_NO_FLAGS, 0, 10, MONS_WORM, MONS_SWAMP_WORM, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 5, 5, 0 }, 3, 12, 12, 0, MST_NO_SPELLS, CE_NOCORPSE, Z_SMALL, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -4212,7 +4213,7 @@ M_WARM_BLOOD | M_SEE_INVIS, //jmf: until smell exists MR_NO_FLAGS, 450, 10, MONS_HOUND, MONS_WOLF, MH_NATURAL, -3, - { 8, 2, 2, 0 }, + { {AT_BITE, AF_PLAIN, 8}, {AT_CLAW, AF_PLAIN, 2}, {AT_CLAW, AF_PLAIN, 2}, {AT_NONE, AF_PLAIN, 0} }, { 4, 3, 5, 0 }, 3, 15, 17, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_BARK, I_ANIMAL, MONUSE_NOTHING, SIZE_SMALL @@ -4224,7 +4225,7 @@ M_SEE_INVIS | M_WARM_BLOOD, MR_RES_POISON, 600, 12, MONS_HOUND, MONS_WARG, MH_NATURAL, -6, - { 12, 3, 3, 0 }, + { {AT_BITE, AF_PLAIN, 12}, {AT_CLAW, AF_PLAIN, 3}, {AT_CLAW, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0} }, { 4, 4, 5, 0 }, 4, 12, 13, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_SMALL, S_BARK, I_ANIMAL, MONUSE_NOTHING, SIZE_LARGE @@ -4236,7 +4237,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 2000, 10, MONS_BEAR, MONS_BEAR, MH_NATURAL, -3, - { 10, 6, 6, 0 }, + { {AT_BITE, AF_PLAIN, 10}, {AT_CLAW, AF_PLAIN, 6}, {AT_CLAW, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0} }, { 7, 3, 3, 0 }, 4, 4, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, MONUSE_NOTHING, SIZE_LARGE @@ -4248,7 +4249,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 2500, 10, MONS_BEAR, MONS_GRIZZLY_BEAR, MH_NATURAL, -3, - { 12, 8, 8, 0 }, + { {AT_BITE, AF_PLAIN, 12}, {AT_CLAW, AF_PLAIN, 8}, {AT_CLAW, AF_PLAIN, 8}, {AT_NONE, AF_PLAIN, 0} }, { 7, 4, 4, 0 }, 5, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, MONUSE_NOTHING, SIZE_LARGE @@ -4260,7 +4261,7 @@ M_WARM_BLOOD | M_AMPHIBIOUS, MR_RES_COLD, 2500, 10, MONS_BEAR, MONS_POLAR_BEAR, MH_NATURAL, -3, - { 20, 5, 5, 0 }, //jmf: polar bears have very strong jaws & necks + { {AT_BITE, AF_PLAIN, 20}, {AT_CLAW, AF_PLAIN, 5}, {AT_CLAW, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0} }, { 7, 5, 3, 0 }, 7, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_BIG, S_GROWL, I_ANIMAL, MONUSE_NOTHING, SIZE_BIG @@ -4272,7 +4273,7 @@ M_WARM_BLOOD, MR_NO_FLAGS, 1800, 10, MONS_BEAR, MONS_BLACK_BEAR, MH_NATURAL, -3, - { 4, 4, 4, 0 }, + { {AT_BITE, AF_PLAIN, 4}, {AT_CLAW, AF_PLAIN, 4}, {AT_CLAW, AF_PLAIN, 4}, {AT_NONE, AF_PLAIN, 0} }, { 6, 3, 3, 0 }, 2, 8, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_GROWL, I_ANIMAL, MONUSE_NOTHING, SIZE_MEDIUM @@ -4285,7 +4286,7 @@ M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 6, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_SMALL, MH_UNDEAD, -1, - { 6, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 6}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 2, 3, 5, 0 }, 10, 4, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_SMALL @@ -4298,7 +4299,7 @@ M_EVIL, MR_RES_POISON | MR_VUL_FIRE | MR_RES_COLD, 0, 6, MONS_SIMULACRUM_SMALL, MONS_SIMULACRUM_LARGE, MH_UNDEAD, -1, - { 14, 0, 0, 0 }, + { {AT_HIT, AF_PLAIN, 14}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 3, 5, 0 }, 10, 5, 7, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_NOZOMBIE, S_SILENT, I_PLANT, MONUSE_NOTHING, SIZE_LARGE @@ -4310,7 +4311,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 150, 10, MONS_GIANT_LIZARD, MONS_GIANT_NEWT, MH_NATURAL, -3, - { 3, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 3}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 1, 2, 0 }, 0, 15, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, MONUSE_NOTHING, SIZE_TINY @@ -4322,7 +4323,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 250, 10, MONS_GIANT_LIZARD, MONS_GIANT_GECKO, MH_NATURAL, -3, - { 5, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 5}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 1, 3, 5, 0 }, 1, 14, 12, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_SILENT, I_REPTILE, MONUSE_NOTHING, SIZE_TINY @@ -4334,7 +4335,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 400, 10, MONS_GIANT_LIZARD, MONS_GIANT_IGUANA, MH_NATURAL, -3, - { 15, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 15}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 3, 3, 5, 0 }, 5, 9, 10, 7, MST_NO_SPELLS, CE_CLEAN, Z_SMALL, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_LITTLE @@ -4347,7 +4348,7 @@ M_COLD_BLOOD, MR_NO_FLAGS, 500, 10, MONS_GIANT_LIZARD, MONS_GILA_MONSTER, MH_NATURAL, -3, - { 20, 0, 0, 0 }, + { {AT_BITE, AF_PLAIN, 20}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 5, 4, 4, 0 }, 3, 12, 10, 7, MST_NO_SPELLS, CE_POISONOUS, Z_BIG, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_LITTLE @@ -4359,7 +4360,7 @@ M_COLD_BLOOD | M_AMPHIBIOUS, MR_NO_FLAGS, 800, 10, MONS_GIANT_LIZARD, MONS_KOMODO_DRAGON, MH_NATURAL, -3, - { 30, 0, 0, 0 }, + { {AT_BITE, AF_DISEASE, 30}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 8, 3, 5, 0 }, 7, 8, 10, 7, MST_NO_SPELLS, CE_CONTAMINATED, Z_BIG, S_HISS, I_REPTILE, MONUSE_NOTHING, SIZE_MEDIUM @@ -4371,7 +4372,7 @@ M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_ORANGE_STATUE, MH_NONLIVING, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 0, 0, 160 }, 30, 1, 6, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_NOTHING, SIZE_LARGE @@ -4383,7 +4384,7 @@ M_SPECIAL_ABILITY, MR_RES_POISON | MR_RES_FIRE | MR_RES_COLD | MR_RES_ELEC, 0, 10, MONS_CLAY_GOLEM, MONS_SILVER_STATUE, MH_NONLIVING, MAG_IMMUNE, - { 0, 0, 0, 0 }, + { {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0}, {AT_NONE, AF_PLAIN, 0} }, { 12, 0, 0, 150 }, 30, 1, 10, 7, MST_NO_SPELLS, CE_NOCORPSE, Z_NOZOMBIE, S_SILENT, I_HIGH, MONUSE_NOTHING, SIZE_LARGE diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 7dc536835a..2a74cef64b 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -28,9 +28,11 @@ #include "externs.h" +#include "beam.h" #include "debug.h" #include "itemname.h" #include "itemprop.h" +#include "Kills.h" #include "misc.h" #include "monplace.h" #include "mstuff2.h" @@ -560,18 +562,104 @@ int mons_colour(const monsters *monster) return (monster->colour); } -int mons_damage(int mc, int rt) +int mons_zombie_base(const monsters *monster) { - ASSERT(rt >= 0); - ASSERT(rt <= 3); + return (monster->number); +} - if (rt < 0 || rt > 3) // make it fool-proof - return (0); +bool mons_is_zombified(const monsters *monster) +{ + switch (monster->type) + { + case MONS_ZOMBIE_SMALL: case MONS_ZOMBIE_LARGE: + case MONS_SKELETON_SMALL: case MONS_SKELETON_LARGE: + case MONS_SIMULACRUM_SMALL: case MONS_SIMULACRUM_LARGE: + case MONS_SPECTRAL_THING: + return (true); + default: + return (false); + } +} + +int downscale_zombie_damage(int damage) +{ + // these are cumulative, of course: {dlb} + if (damage > 1) + damage--; + if (damage > 4) + damage--; + if (damage > 11) + damage--; + if (damage > 14) + damage--; + + return (damage); +} + +mon_attack_def downscale_zombie_attack(const monsters *mons, + mon_attack_def attk) +{ + switch (attk.type) + { + case AT_STING: case AT_SPORE: + case AT_TOUCH: case AT_ENGULF: + attk.type = AT_HIT; + break; + default: + break; + } + + if (mons->type == MONS_SIMULACRUM_LARGE + || mons->type == MONS_SIMULACRUM_SMALL) + { + attk.flavour = AF_COLD; + } + else + { + attk.flavour = AF_PLAIN; + } + + attk.damage = downscale_zombie_damage(attk.damage); + + return (attk); +} + +mon_attack_def mons_attack_spec(const monsters *mons, int attk_number) +{ + int mc = mons->type; + const bool zombified = mons_is_zombified(mons); + + if ((attk_number < 0 || attk_number > 3) || mc == MONS_HYDRA) + attk_number = 0; + + if (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON) + return mon_attack_def::attk(ghost.values[GVAL_DAMAGE]); + + if (zombified) + mc = mons_zombie_base(mons); - if (rt == 0 && (mc == MONS_PLAYER_GHOST || mc == MONS_PANDEMONIUM_DEMON)) - return (ghost.values[ GVAL_DAMAGE ]); + mon_attack_def attk = smc->attack[attk_number]; + if (attk.flavour == AF_KLOWN) + { + switch (random2(6)) + { + case 0: attk.flavour = AF_POISON_NASTY; break; + case 1: attk.flavour = AF_ROT; break; + case 2: attk.flavour = AF_DRAIN_XP; break; + case 3: attk.flavour = AF_FIRE; break; + case 4: attk.flavour = AF_COLD; break; + case 5: attk.flavour = AF_BLINK; break; + } + } + + return (zombified? downscale_zombie_attack(mons, attk) : attk); +} - return (smc->damage[rt]); +int mons_damage(int mc, int rt) +{ + if (rt < 0 || rt > 3) + rt = 0; + return smc->attack[rt].damage; } // end mons_damage() int mons_resist_magic( const monsters *mon ) @@ -580,7 +668,7 @@ int mons_resist_magic( const monsters *mon ) // negative values get multiplied with mhd if (u < 0) - u = mon->hit_dice * (-u * 2); + u = mon->hit_dice * -u; u += scan_mon_inv_randarts( mon, RAP_MAGIC ); @@ -603,7 +691,7 @@ bool check_mons_resist_magic( const monsters *monster, int pow ) { int mrs = mons_resist_magic(monster); - if (mrs == 5000) + if (mrs == MAG_IMMUNE) return (true); // Evil, evil hack to make weak one hd monsters easier for first @@ -633,7 +721,7 @@ bool check_mons_resist_magic( const monsters *monster, int pow ) mpr( info, MSGCH_DIAGNOSTICS ); #endif - return ((mrch2 < mrchance) ? true : false); + return (mrch2 < mrchance); } // end check_mons_resist_magic() int mons_res_elec( const monsters *mon ) @@ -1310,8 +1398,8 @@ void define_monster(int index) mons.hit_dice = hd; mons.hit_points = hp; mons.max_hit_points = hp_max; - mons.armour_class = ac; - mons.evasion = ev; + mons.ac = ac; + mons.ev = ev; mons.speed = speed; mons.speed_increment = 70; mons.number = monnumber; @@ -1493,6 +1581,12 @@ const char *moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZ case DESC_PLAIN: strcpy(glog, "it"); break; + case DESC_NOCAP_YOUR: + strcpy(glog, "its"); + break; + case DESC_CAP_YOUR: + strcpy(glog, "Its"); + break; } strcpy(gmon_name, glog); @@ -1504,9 +1598,11 @@ const char *moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZ switch (descrip) { case DESC_CAP_THE: + case DESC_CAP_YOUR: strcpy(glog, "The "); break; case DESC_NOCAP_THE: + case DESC_NOCAP_YOUR: strcpy(glog, "the "); break; case DESC_CAP_A: @@ -1541,6 +1637,15 @@ const char *moname(int mons_num, bool vis, char descrip, char glog[ ITEMNAME_SIZ strcat(glog, gmon_name); + if ((descrip == DESC_CAP_YOUR || descrip == DESC_NOCAP_YOUR) && *glog) + { + const int lastch = glog[ strlen(glog) - 1 ]; + if (lastch == 's' || lastch == 'x') + strcat(glog, "'"); + else + strcat(glog, "'s"); + } + return (glog); } // end moname() @@ -1634,6 +1739,11 @@ bool mons_wields_two_weapons(const monsters *m) return (m->type == MONS_TWO_HEADED_OGRE || m->type == MONS_ETTIN); } +bool mons_is_summoned(const monsters *m) +{ + return (mons_has_ench(m, ENCH_ABJ_I, ENCH_ABJ_VI)); +} + // Does not check whether the monster can dual-wield - that is the // caller's responsibility. int mons_offhand_weapon_index(const monsters *m) @@ -1641,9 +1751,12 @@ int mons_offhand_weapon_index(const monsters *m) return (m->inv[1]); } -int mons_base_damage_type(const monsters *m) +int mons_base_damage_brand(const monsters *m) { - return (mons_class_flag(m->type, M_CLAWS)? DVORP_CLAWING : DVORP_CRUSHING); + if (m->type == MONS_PLAYER_GHOST || m->type == MONS_PANDEMONIUM_DEMON) + return ghost.values[ GVAL_BRAND ]; + + return (SPWPN_NORMAL); } int mons_size(const monsters *m) @@ -2504,8 +2617,11 @@ int monsters::damage_type(int which_attack) const item_def *mweap = weapon(which_attack); if (!mweap) - return (mons_base_damage_type(this)); - + { + const mon_attack_def atk = mons_attack_spec(this, which_attack); + return (atk.type == AT_CLAW? DVORP_CLAWING : DVORP_CRUSHING); + } + return (get_vorpal_type(*mweap)); } @@ -2515,7 +2631,7 @@ int monsters::damage_brand(int which_attack) if (!mweap) return (SPWPN_NORMAL); - + return (!is_range_weapon(*mweap)? get_weapon_brand(*mweap) : SPWPN_NORMAL); } @@ -2542,6 +2658,23 @@ item_def *monsters::weapon(int which_attack) return (weap == NON_ITEM? NULL : &mitm[weap]); } +static int equip_slot_to_mslot(equipment_type eq) +{ + switch (eq) + { + case EQ_WEAPON: return MSLOT_WEAPON; + case EQ_BODY_ARMOUR: return MSLOT_ARMOUR; + default: return (-1); + } +} + +item_def *monsters::slot_item(equipment_type eq) +{ + int mslot = equip_slot_to_mslot(eq); + int mindex = mslot == -1? NON_ITEM : inv[mslot]; + return (mindex == NON_ITEM? NULL: &mitm[mindex]); +} + item_def *monsters::shield() { return (NULL); @@ -2552,9 +2685,20 @@ std::string monsters::name(description_level_type desc) const return (ptr_monam(this, desc)); } +std::string monsters::pronoun(pronoun_type pro) const +{ + return (mons_pronoun(type, pro)); +} + std::string monsters::conj_verb(const std::string &verb) const { - return (verb + "s"); + if (!verb.empty() && verb[0] == '!') + return (verb.substr(1)); + + if (verb == "are") + return ("is"); + + return (pluralize(verb)); } int monsters::id() const @@ -2571,7 +2715,12 @@ bool monsters::fumbles_attack(bool verbose) { mprf(MSGCH_SOUND, "You hear a splashing noise."); } + return (true); } + + if (mons_is_submerged(this)) + return (true); + return (false); } @@ -2588,3 +2737,224 @@ void monsters::attacking(actor * /* other */) void monsters::go_berserk(bool /* intentional */) { } + +void monsters::expose_to_element(beam_type, int) +{ +} + +void monsters::banish() +{ + // [dshaligram] FIXME: We should really put these monsters on a + // queue and load them when the player enters the Abyss. + monster_die(this, KILL_RESET, 0); +} + +int monsters::holy_aura() const +{ + return ((type == MONS_DAEVA || type == MONS_ANGEL)? hit_dice : 0); +} + +bool monsters::visible() const +{ + return (mons_near(this) && player_monster_visible(this)); +} + +bool monsters::confused() const +{ + return (mons_is_confused(this)); +} + +bool monsters::paralysed() const +{ + return (mons_is_paralysed(this)); +} + +bool monsters::asleep() const +{ + return (mons_is_sleeping(this)); +} + +int monsters::shield_bonus() const +{ + // XXX: Monsters don't actually get shields yet. + const item_def *shld = const_cast(this)->shield(); + if (shld) + { + const int shld_c = property(*shld, PARM_AC); + return (random2(shld_c + random2(hit_dice / 2)) / 2); + } + return (0); +} + +int monsters::shield_block_penalty() const +{ + return (0); +} + +int monsters::shield_bypass_ability(int) const +{ + return (15 + hit_dice / 2); +} + +int monsters::armour_class() const +{ + return (ac); +} + +int monsters::melee_evasion(const actor *act) const +{ + int evasion = ev; + if (paralysed() || asleep() || one_chance_in(20)) + evasion = 0; + else if (confused()) + evasion /= 2; + return (evasion); +} + +void monsters::heal(int amount, bool max_too) +{ + hit_points += amount; + if (max_too) + max_hit_points += amount; + if (hit_points > max_hit_points) + hit_points = max_hit_points; +} + +int monsters::holiness() const +{ + return (mons_holiness(this)); +} + +int monsters::res_fire() const +{ + return (mons_res_fire(this)); +} + +int monsters::res_cold() const +{ + return (mons_res_cold(this)); +} + +int monsters::res_elec() const +{ + return (mons_res_elec(this)); +} + +int monsters::res_poison() const +{ + return (mons_res_poison(this)); +} + +int monsters::res_negative_energy() const +{ + return (mons_res_negative_energy(this)); +} + +bool monsters::levitates() const +{ + return (mons_flies(this)); +} + +int monsters::mons_species() const +{ + return ::mons_species(type); +} + +void monsters::poison(actor *agent, int amount) +{ + if (amount <= 0) + return; + + // Scale poison down for monsters. + if (!(amount /= 2)) + amount = 1; + + poison_monster(this, agent->atype() == ACT_PLAYER, amount); +} + +int monsters::skill(skill_type sk, bool) const +{ + switch (sk) + { + case SK_NECROMANCY: + return (holiness() == MH_UNDEAD? hit_dice / 2 : hit_dice / 3); + + default: + return (0); + } +} + +void monsters::blink() +{ + monster_blink(this); +} + +void monsters::teleport(bool now, bool) +{ + monster_teleport(this, now, false); +} + +bool monsters::alive() const +{ + return (hit_points > 0 && type != -1); +} + +void monsters::hurt(actor *agent, int amount) +{ + if (amount <= 0) + return; + + hit_points -= amount; + if ((hit_points < 1 || hit_dice < 1) && type != -1) + { + if (agent->atype() == ACT_PLAYER) + monster_die(this, KILL_YOU, 0); + else + monster_die(this, KILL_MON, + monster_index( dynamic_cast(agent) )); + } +} + +void monsters::rot(actor *agent, int rotlevel, int immed_rot) +{ + if (mons_holiness(this) != MH_NATURAL) + return; + + // Apply immediate damage because we can't handle rotting for monsters yet. + const int damage = immed_rot + random2(rotlevel * 3); + if (damage) + { + if (mons_near(this) && player_monster_visible(this)) + mprf("%s %s!", + name(DESC_CAP_THE).c_str(), + rotlevel == 0? "looks less resilient" : "rots"); + hurt(agent, damage); + if (alive()) + { + max_hit_points -= immed_rot * 2; + if (hit_points > max_hit_points) + hit_points = max_hit_points; + } + } +} + +void monsters::confuse(int strength) +{ + bolt beam_temp; + beam_temp.flavour = BEAM_CONFUSION; + mons_ench_f2( this, beam_temp ); +} + +void monsters::paralyse(int strength) +{ + bolt paralysis; + paralysis.flavour = BEAM_PARALYSIS; + mons_ench_f2(this, paralysis); +} + +void monsters::slow_down(int strength) +{ + bolt slow; + slow.flavour = BEAM_SLOW; + mons_ench_f2(this, slow); +} diff --git a/crawl-ref/source/mon-util.h b/crawl-ref/source/mon-util.h index 01d1419df6..e0728b79ce 100644 --- a/crawl-ref/source/mon-util.h +++ b/crawl-ref/source/mon-util.h @@ -54,15 +54,12 @@ #define I_ANIMAL_LIKE 5 #define I_REPTILE 6 - -// [dshaligram] PACKED is *not* relevant; the amount of padding space it -// saves is not enough to merit it. struct monsterentry { short mc; // monster number unsigned char showchar, colour; - const char *name /*[32]*/; //longest is 23 till now (31 is max alowed here) + const char *name; unsigned long bitfields; unsigned long resists; @@ -82,16 +79,15 @@ struct monsterentry short resist_magic; // (positive is ??) // max damage in a turn is total of these four? - unsigned char damage[4]; + mon_attack_def attack[4]; -// hpdice[4]: [0]=HD [1]=min_hp [2]=rand_hp [3]=add_hp -// min hp = [0]*[1]+[3] & max hp = [0]*([1]+[2])+[3]) -// example: the Iron Golem, hpdice={15,7,4,0} -// 15*7 < hp < 15*(7+4), -// 105 < hp < 165 -// hp will be around 135 each time. (assuming an good random number generator) -// !!!!!!! The system is exactly the same as before, only the way of writing changed !!!! - unsigned char hpdice[4]; // until we have monsters with 32767 hp,this is easily possible + // hpdice[4]: [0]=HD [1]=min_hp [2]=rand_hp [3]=add_hp + // min hp = [0]*[1]+[3] & max hp = [0]*([1]+[2])+[3]) + // example: the Iron Golem, hpdice={15,7,4,0} + // 15*7 < hp < 15*(7+4), + // 105 < hp < 165 + // hp will be around 135 each time. + unsigned hpdice[4]; char AC; // armour class @@ -202,7 +198,7 @@ int mons_resist_turn_undead( const monsters *mon ); * called from: fight - monstuff * *********************************************************************** */ int mons_damage(int mc, int rt); - +mon_attack_def mons_attack_spec(const monsters *, int rt); // last updated 12may2000 {dlb} /* *********************************************************************** @@ -231,6 +227,7 @@ bool mons_is_demon( int mc ); bool mons_is_humanoid( int mc ); bool mons_wields_two_weapons(const monsters *m); +bool mons_is_summoned(const monsters *m); // last updated 12may2000 {dlb} /* *********************************************************************** diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc index 565e5200aa..aec559be54 100644 --- a/crawl-ref/source/monplace.cc +++ b/crawl-ref/source/monplace.cc @@ -160,15 +160,17 @@ bool place_monster(int &id, int mon_type, int power, char behaviour, lev_mons = random2(power); } - if (player_in_branch( BRANCH_MAIN_DUNGEON ) && lev_mons < 28) + if (player_in_branch( BRANCH_MAIN_DUNGEON ) + && lev_mons < 28 + && lev_mons > 0) { // potentially nasty surprise, but very rare if (one_chance_in(5000)) - lev_mons = random2(27); + lev_mons += random2(12); // slightly out of depth monsters are more common: if (one_chance_in(50)) - lev_mons += random2(6); + lev_mons += random2(5); if (lev_mons > 27) lev_mons = 27; diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index c70898a1c3..ee06ba98a5 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -330,6 +330,9 @@ static void place_monster_corpse(const monsters *monster) void monster_die(monsters *monster, char killer, int i) { + if (monster->type == -1) + return; + int dmi; // dead monster's inventory int xom_will_act = 0; int monster_killed = monster_index(monster); @@ -773,8 +776,8 @@ void monster_cleanup(monsters *monster) monster->hit_points = 0; monster->max_hit_points = 0; monster->hit_dice = 0; - monster->armour_class = 0; - monster->evasion = 0; + monster->ac = 0; + monster->ev = 0; monster->speed_increment = 0; monster->attitude = ATT_HOSTILE; monster->behaviour = BEH_SLEEP; @@ -857,8 +860,8 @@ static bool jelly_divide(struct monsters * parent) child->hit_dice = parent->hit_dice; child->hit_points = parent->hit_points; child->max_hit_points = child->hit_points; - child->armour_class = parent->armour_class; - child->evasion = parent->evasion; + child->ac = parent->ac; + child->ev = parent->ev; child->speed = parent->speed; child->speed_increment = 70 + random2(5); child->behaviour = parent->behaviour; /* Look at this! */ @@ -3084,7 +3087,12 @@ static int get_draconian_breath_spell( struct monsters *monster ) // [ds] Check line-of-fire here. It won't happen elsewhere. bolt beem; setup_mons_cast(monster, beem, draco_breath); + fire_tracer(monster, beem); + + mprf(MSGCH_DIAGNOSTICS, "tracer: foes: %d, friends: %d", + beem.foe_count, beem.fr_count); + if (!mons_should_fire(beem)) draco_breath = MS_NO_SPELL; } @@ -3807,6 +3815,7 @@ static void handle_monster_move(int i, monsters *monster) // [ds] Special abilities shouldn't overwhelm spellcasting // in monsters that have both. This aims to give them both // roughly the same weight. + if (coinflip()? handle_special_ability(monster, beem) || handle_monster_spell(monster, beem) @@ -4123,7 +4132,7 @@ static bool handle_pickup(struct monsters *monster) if (get_weapon_brand(mitm[monster->inv[MSLOT_WEAPON]]) == SPWPN_PROTECTION) { - monster->armour_class += 3; + monster->ac += 3; } if (monsterNearby) @@ -5024,7 +5033,7 @@ static void mons_in_cloud(struct monsters *monster) hurted += (random2(15) * 10) / speed; // remember that the above is in addition to the other you.damage. - hurted -= random2(1 + monster->armour_class); + hurted -= random2(1 + monster->ac); break; // to damage routine at end {dlb} case CLOUD_STINK: @@ -5055,7 +5064,7 @@ static void mons_in_cloud(struct monsters *monster) hurted += (random2(15) * 10) / speed; // remember that the above is in addition to the other damage. - hurted -= random2(1 + monster->armour_class); + hurted -= random2(1 + monster->ac); break; // to damage routine at end {dlb} // what of armour of poison resistance here? {dlb} @@ -5094,7 +5103,7 @@ static void mons_in_cloud(struct monsters *monster) if (mons_res_fire(monster) < 0) hurted += (random2(6) * 10) / speed; - hurted -= random2(1 + monster->armour_class); + hurted -= random2(1 + monster->ac); break; // to damage routine at end {dlb} case CLOUD_MIASMA: diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 92e14fe6cb..b667ea9e3d 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -163,7 +163,7 @@ void mons_trap(struct monsters *monster) } return; // early return {dlb} } - else if (random2(monster->evasion) > 8) + else if (random2(monster->ev) > 8) { if (monsterNearby && !simple_monster_message(monster, " avoids a huge, swinging blade.")) @@ -190,7 +190,7 @@ void mons_trap(struct monsters *monster) } damage_taken = 10 + random2avg(29, 2); - damage_taken -= random2(1 + monster->armour_class); + damage_taken -= random2(1 + monster->ac); if (damage_taken < 0) damage_taken = 0; @@ -266,17 +266,17 @@ void mons_trap(struct monsters *monster) // determine whether projectile hits, calculate damage: {dlb} if (((20 + (you.your_level * 2)) * random2(200)) / 100 - >= monster->evasion) + >= monster->ev) { damage_taken = roll_dice( beem.damage ); - damage_taken -= random2(1 + monster->armour_class); + damage_taken -= random2(1 + monster->ac); if (damage_taken < 0) damage_taken = 0; if (beem.colour == OBJ_MISSILES && beem.type == MI_NEEDLE - && random2(100) < 50 - (3*monster->armour_class/2)) + && random2(100) < 50 - (3*monster->ac/2)) { apply_poison = true; } diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index 7375d57062..21f79e82e7 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -537,12 +537,12 @@ void print_stats(void) cprintf( "Fire " ); } - if (you.poison) + if (you.poisoning) { // We skip marking "quite" poisoned and instead mark the // levels where the rules for dealing poison damage change // significantly. See acr.cc for that code. -- bwr - textcolor( bad_ench_colour( you.poison, 5, 10 ) ); + textcolor( bad_ench_colour( you.poisoning, 5, 10 ) ); cprintf( "Pois " ); } diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index bb27354858..2b38d25339 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -34,6 +34,7 @@ #include "clua.h" #include "delay.h" +#include "effects.h" #include "fight.h" #include "food.h" #include "itemname.h" @@ -51,6 +52,8 @@ #include "religion.h" #include "skills.h" #include "skills2.h" +#include "spells1.h" +#include "spells3.h" #include "spl-util.h" #include "spells4.h" #include "stuff.h" @@ -61,7 +64,18 @@ std::string pronoun_you(description_level_type desc) { - return (desc == DESC_CAP_A || desc == DESC_CAP_THE? "You" : "you"); + switch (desc) + { + case DESC_CAP_A: case DESC_CAP_THE: + return "You"; + case DESC_NOCAP_A: case DESC_NOCAP_THE: + default: + return "you"; + case DESC_CAP_YOUR: + return "Your"; + case DESC_NOCAP_YOUR: + return "your"; + } } ////////////////////////////////////////////////////////////////////////// @@ -2931,12 +2945,12 @@ void display_char_status(void) if (player_is_levitating()) mpr( "You are hovering above the floor." ); - if (you.poison) + if (you.poisoning) { snprintf( info, INFO_SIZE, "You are %s poisoned.", - (you.poison > 10) ? "extremely" : - (you.poison > 5) ? "very" : - (you.poison > 3) ? "quite" + (you.poisoning > 10) ? "extremely" : + (you.poisoning > 5) ? "very" : + (you.poisoning > 3) ? "quite" : "mildly" ); mpr(info); } @@ -4082,13 +4096,13 @@ void poison_player( int amount, bool force ) if ((!force && player_res_poison()) || amount <= 0) return; - const int old_value = you.poison; - you.poison += amount; + const int old_value = you.poisoning; + you.poisoning += amount; - if (you.poison > 40) - you.poison = 40; + if (you.poisoning > 40) + you.poisoning = 40; - if (you.poison > old_value) + if (you.poisoning > old_value) { snprintf( info, INFO_SIZE, "You are %spoisoned.", (old_value > 0) ? "more " : "" ); @@ -4101,14 +4115,14 @@ void poison_player( int amount, bool force ) void reduce_poison_player( int amount ) { - if (you.poison == 0 || amount <= 0) + if (you.poisoning == 0 || amount <= 0) return; - you.poison -= amount; + you.poisoning -= amount; - if (you.poison <= 0) + if (you.poisoning <= 0) { - you.poison = 0; + you.poisoning = 0; mpr( "You feel better.", MSGCH_RECOVERY ); } else @@ -4302,6 +4316,13 @@ void rot_player( int amount ) } } +////////////////////////////////////////////////////////////////////////////// +// actor + +actor::~actor() +{ +} + ////////////////////////////////////////////////////////////////////////////// // player @@ -4339,7 +4360,7 @@ void player::init() levitation = 0; might = 0; paralysis = 0; - poison = 0; + poisoning = 0; rotting = 0; fire_shield = 0; slow = 0; @@ -4676,6 +4697,19 @@ std::string player::name(description_level_type type) const return (pronoun_you(type)); } +std::string player::pronoun(pronoun_type pro) const +{ + switch (pro) + { + default: + case PRONOUN_CAP: return "You"; + case PRONOUN_NOCAP: return "you"; + case PRONOUN_CAP_POSSESSIVE: return "Your"; + case PRONOUN_NOCAP_POSSESSIVE: return "your"; + case PRONOUN_REFLEXIVE: return "yourself"; + } +} + std::string player::conj_verb(const std::string &verb) const { return (verb); @@ -4686,6 +4720,13 @@ int player::id() const return (-1); } +bool player::alive() const +{ + // Simplistic, but if the player dies the game is over anyway, so + // nobody can ask further questions. + return (true); +} + bool player::fumbles_attack(bool verbose) { // fumbling in shallow water : @@ -4729,7 +4770,249 @@ void player::go_berserk(bool intentional) ::go_berserk(intentional); } +void player::god_conduct(int thing_done, int level) +{ + ::did_god_conduct(thing_done, level); +} + +void player::banish() +{ + banished = true; +} + void player::make_hungry(int hunger_increase, bool silent) { - ::make_hungry(hunger_increase, silent); + if (hunger_increase > 0) + ::make_hungry(hunger_increase, silent); + else if (hunger_increase < 0) + ::lessen_hunger(-hunger_increase, silent); +} + +int player::holy_aura() const +{ + return (duration[DUR_REPEL_UNDEAD]? piety : 0); +} + +int player::warding() const +{ + if (wearing_amulet(AMU_WARDING)) + return (30); + + if (religion == GOD_VEHUMET && duration[DUR_PRAYER] + && !player_under_penance() && piety >= piety_breakpoint(2)) + { + // Clamp piety at 160 and scale that down to a max of 30. + const int wardpiety = piety > 160? 160 : piety; + return (wardpiety * 3 / 16); + } + + return (0); +} + +bool player::paralysed() const +{ + return (paralysis); +} + +bool player::confused() const +{ + return (conf); +} + +int player::shield_block_penalty() const +{ + return (5 * shield_blocks * shield_blocks); +} + +int player::shield_bonus() const +{ + return random2(player_shield_class()) + + (random2(dex) / 4) + + (random2(skill_bump(SK_SHIELDS)) / 4) + - 1; +} + +int player::shield_bypass_ability(int tohit) const +{ + return (10 + tohit * 2); +} + +void player::shield_block_succeeded() +{ + shield_blocks++; + + if (one_chance_in(4)) + exercise(SK_SHIELDS, 1); +} + +bool player::wearing_light_armour(bool with_skill) const +{ + return (player_light_armour(with_skill)); +} + +void player::exercise(skill_type sk, int qty) +{ + ::exercise(sk, qty); +} + +int player::skill(skill_type sk, bool bump) const +{ + return (bump? skill_bump(sk) : skills[sk]); +} + +int player::armour_class() const +{ + return (player_AC()); +} + +int player::melee_evasion(const actor *act) const +{ + return (random2limit(player_evasion(), 40) + + random2(you.dex) / 3 + - (act->visible()? 2 : 14) + - (you_are_delayed()? 5 : 0)); +} + +void player::heal(int amount, bool max_too) +{ + ::inc_hp(amount, max_too); +} + +int player::holiness() const +{ + if (is_undead) + return (MH_UNDEAD); + + if (species == SP_DEMONSPAWN) + return (MH_DEMONIC); + + return (MH_NATURAL); +} + +int player::res_fire() const +{ + return (player_res_fire()); +} + +int player::res_cold() const +{ + return (player_res_cold()); +} + +int player::res_elec() const +{ + return (player_res_electricity()); +} + +int player::res_poison() const +{ + return (player_res_poison()); +} + +int player::res_negative_energy() const +{ + return (player_prot_life()); +} + +bool player::levitates() const +{ + return (player_is_levitating()); +} + +int player::mons_species() const +{ + switch (species) + { + case SP_HILL_ORC: + return (MONS_ORC); + case SP_ELF: case SP_HIGH_ELF: case SP_GREY_ELF: + case SP_DEEP_ELF: case SP_SLUDGE_ELF: + return (MONS_ELF); + default: + return (MONS_HUMAN); + } +} + +void player::poison(actor*, int amount) +{ + ::poison_player(amount); +} + +void player::expose_to_element(beam_type element, int st) +{ + ::expose_player_to_element(element, st); +} + +void player::blink() +{ + random_blink(true); +} + +void player::teleport(bool now, bool abyss_shift) +{ + if (now) + you_teleport2(true, abyss_shift); + else + you_teleport(); +} + +void player::hurt(actor *agent, int amount) +{ + if (agent->atype() == ACT_MONSTER) + ouch(amount, monster_index( dynamic_cast(agent) ), + KILLED_BY_MONSTER); + else + { + // Should never happen! + ASSERT(false); + ouch(amount, 0, KILLED_BY_SOMETHING); + } + + if (religion == GOD_XOM && hp <= hp_max / 3 + && one_chance_in(10)) + { + Xom_acts(true, experience_level, false); + } +} + +void player::drain_stat(int stat, int amount) +{ + lose_stat(stat, amount); +} + +void player::rot(actor *who, int rotlevel, int immed_rot) +{ + if (is_undead) + return; + + if (rotlevel) + rot_player( rotlevel ); + + if (immed_rot) + rot_hp(immed_rot); + + if (rotlevel && one_chance_in(4)) + disease_player( 50 + random2(100) ); +} + +void player::confuse(int str) +{ + confuse_player(str); +} + +void player::paralyse(int str) +{ + mprf( "You %s the ability to move!", + (paralysis) ? "still haven't" : "suddenly lose" ); + + if (str > paralysis) + paralysis = str; + + if (paralysis > 13) + paralysis = 13; +} + +void player::slow_down(int str) +{ + ::slow_player( str ); } diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc index cf0a5b775a..70c86b192e 100644 --- a/crawl-ref/source/religion.cc +++ b/crawl-ref/source/religion.cc @@ -2640,13 +2640,7 @@ void handle_god_time(void) // to make up for the new spell training requirements, else // it's practically impossible to get Master of Arcane status. if (one_chance_in(100)) - { lose_piety(1); -#ifdef DEBUG_DIAGNOSTICS - mprf(MSGCH_DIAGNOSTICS, - "Sif Muna piety decay (new piety = %d)", you.piety); -#endif - } if (you.piety < 1) excommunication(); break; diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 2f99be2980..9ebca41787 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -652,7 +652,7 @@ bool cast_revivification(int power) void cast_cure_poison(int mabil) { - if (!you.poison) + if (!you.poisoning) canned_msg(MSG_NOTHING_HAPPENS); else reduce_poison_player( 2 + random2(mabil) + random2(3) ); @@ -664,7 +664,7 @@ void purification(void) { mpr("You feel purified!"); - you.poison = 0; + you.poisoning = 0; you.rotting = 0; you.conf = 0; you.slow = 0; diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index 2fffba6e3e..62c3a21ef8 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -521,7 +521,7 @@ void cast_twisted(int power, int corps_beh, int corps_hit) menv[mon].max_hit_points = menv[mon].hit_points; if (colour == LIGHTRED) - menv[mon].armour_class += total_mass / 1000; + menv[mon].ac += total_mass / 1000; } } } // end cast_twisted() diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 82905972ff..5adb01c171 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -263,11 +263,13 @@ int airstrike(int power) hurted = random2( random2(12) + (random2(power) / 6) + (random2(power) / 7) ); - hurted -= random2(1 + monster->armour_class); - if ( mons_flies(monster) ) { - hurted *= 3; - hurted /= 2; - } + hurted -= random2(1 + monster->ac); + + if ( mons_flies(monster) ) + { + hurted *= 3; + hurted /= 2; + } if (hurted < 0) hurted = 0; diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index a3443587ff..cc79bf91d4 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -258,7 +258,7 @@ static int shatter_monsters(int x, int y, int pow, int garbage) break; } - int damage = roll_dice( dam_dice ) - random2( menv[monster].armour_class ); + int damage = roll_dice( dam_dice ) - random2( menv[monster].ac ); if (damage > 0) player_hurt_monster( monster, damage ); @@ -1186,7 +1186,7 @@ void cast_ignite_poison(int pow) } // player is poisoned - damage += roll_dice( you.poison, 6 ); + damage += roll_dice( you.poisoning, 6 ); if (damage) { @@ -1209,10 +1209,10 @@ void cast_ignite_poison(int pow) ouch( damage, 0, KILLED_BY_TARGETTING ); - if (you.poison > 0) + if (you.poisoning > 0) { mpr( "You feel that the poison has left your system." ); - you.poison = 0; + you.poisoning = 0; } } @@ -2859,8 +2859,8 @@ void cast_far_strike(int pow) struct monsters *monster = &menv[ mgrd[targ.tx][targ.ty] ]; // apply monster's AC - if (monster->armour_class > 0) - damage -= random2( 1 + monster->armour_class ); + if (monster->ac > 0) + damage -= random2( 1 + monster->ac ); #if 0 // Removing damage limiter since it's categorized at level 4 right now. diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index b24b85d2d7..6655fec60b 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -662,10 +662,10 @@ static void tag_construct_you(struct tagHeader &th) marshallByte(th,you.levitation); - if (you.poison > 215) - you.poison = 215; + if (you.poisoning > 215) + you.poisoning = 215; - marshallByte(th,you.poison); + marshallByte(th,you.poisoning); marshallShort(th, you.hunger); @@ -930,7 +930,7 @@ static void tag_read_you(struct tagHeader &th, char minorVersion) you.haste = unmarshallByte(th); you.might = unmarshallByte(th); you.levitation = unmarshallByte(th); - you.poison = unmarshallByte(th); + you.poisoning = unmarshallByte(th); you.hunger = unmarshallShort(th); // how many you.equip? @@ -1301,8 +1301,8 @@ static void tag_construct_level_monsters(struct tagHeader &th) { const monsters &m = menv[i]; - marshallByte(th, m.armour_class); - marshallByte(th, m.evasion); + marshallByte(th, m.ac); + marshallByte(th, m.ev); marshallByte(th, m.hit_dice); marshallByte(th, m.speed); marshallByte(th, m.speed_increment); @@ -1473,8 +1473,8 @@ static void tag_read_level_monsters(struct tagHeader &th, char minorVersion) for (i = 0; i < count; i++) { - menv[i].armour_class = unmarshallByte(th); - menv[i].evasion = unmarshallByte(th); + menv[i].ac = unmarshallByte(th); + menv[i].ev = unmarshallByte(th); menv[i].hit_dice = unmarshallByte(th); menv[i].speed = unmarshallByte(th); // Avoid sign extension when loading files (Elethiomel's hang) diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc index a98aa9115a..3a452a3122 100644 --- a/crawl-ref/source/tutorial.cc +++ b/crawl-ref/source/tutorial.cc @@ -751,7 +751,7 @@ void tutorial_prayer_reminder() void tutorial_healing_reminder() { - if (you.poison) + if (you.poisoning) { if (Options.tutorial_events[TUT_NEED_POISON_HEALING]) return; @@ -761,7 +761,7 @@ void tutorial_healing_reminder() { if (Options.tutorial_events[TUT_NEED_HEALING]) learned_something_new(TUT_NEED_HEALING); - else if (you.num_turns - Options.tut_last_healed >= 50 && !you.poison) + else if (you.num_turns - Options.tut_last_healed >= 50 && !you.poisoning) { if (Options.tut_just_triggered) return; -- cgit v1.2.3-54-g00ecf