From 4d0b7c461fd459e01cab475eb6b01ab5ea9d4689 Mon Sep 17 00:00:00 2001 From: haranp Date: Sat, 4 Oct 2008 14:44:13 +0000 Subject: Redid monster death idiom so that monsters::hurt can implicitly call monster_die(). (This behaviour can be overriden.) Minor code cleanups elsewhere, removal of dead code from bolt. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7123 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/beam.cc | 385 ++++++++++++++++++------------------------- crawl-ref/source/beam.h | 62 ++----- crawl-ref/source/effects.cc | 36 ++-- crawl-ref/source/enum.h | 56 ++++--- crawl-ref/source/externs.h | 10 +- crawl-ref/source/fight.cc | 20 +-- crawl-ref/source/items.cc | 4 - crawl-ref/source/mon-util.cc | 30 ++-- crawl-ref/source/monstuff.cc | 12 +- crawl-ref/source/monstuff.h | 3 +- crawl-ref/source/mstuff2.cc | 1 - crawl-ref/source/ouch.cc | 6 +- crawl-ref/source/player.cc | 4 +- crawl-ref/source/spells2.cc | 33 ++-- crawl-ref/source/spells3.cc | 14 +- crawl-ref/source/spells4.cc | 48 ++---- crawl-ref/source/spl-cast.cc | 5 +- crawl-ref/source/stuff.cc | 10 +- crawl-ref/source/stuff.h | 2 - crawl-ref/source/traps.cc | 10 +- 20 files changed, 305 insertions(+), 446 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index d5324c22fd..8968e408e6 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -61,10 +61,6 @@ #define BEAM_STOP 1000 // all beams stopped by subtracting this // from remaining range -#define MON_RESIST 0 // monster resisted -#define MON_UNAFFECTED 1 // monster unaffected -#define MON_AFFECTED 2 // monster was affected -#define MON_OTHER 3 // monster unaffected, but for other reasons static FixedArray < bool, 19, 19 > explode_map; @@ -80,7 +76,7 @@ static int _affect_place_clouds(bolt &beam, const coord_def& p); static void _affect_place_explosion_clouds(bolt &beam, const coord_def& p); static int _affect_player(bolt &beam, item_def *item = NULL); static int _affect_monster(bolt &beam, monsters *mon, item_def *item = NULL); -static int _affect_monster_enchantment(bolt &beam, monsters *mon); +static mon_resist_type _affect_monster_enchantment(bolt &beam, monsters *mon); static void _beam_paralyses_monster( bolt &pbolt, monsters *monster ); static void _beam_petrifies_monster( bolt &pbolt, monsters *monster ); static int _range_used_on_hit(bolt &beam); @@ -93,9 +89,8 @@ static void _explosion_cell(bolt &beam, const coord_def& p, bool drawOnly, static void _ench_animation(int flavour, const monsters *mon = NULL, bool force = false); static void _zappy(zap_type z_type, int power, bolt &pbolt); -static void _monster_die(monsters *mons, const bolt &beam); -static bool _nasty_beam(monsters *mon, bolt &beam); -static bool _nice_beam(monsters *mon, bolt &beam); +static bool _nasty_beam(monsters *mon, const bolt &beam); +static bool _nice_beam(monsters *mon, const bolt &beam); static std::set beam_message_cache; @@ -126,11 +121,6 @@ static void _beam_mpr(msg_channel_type channel, const char *s, ...) beam_message_cache.insert(message); } -static void _monster_die(monsters *mons, const bolt &beam) -{ - monster_die(mons, beam.killer(), beam.beam_source); -} - static kill_category _whose_kill(const bolt &beam) { if (YOU_KILL(beam.thrower)) @@ -1512,7 +1502,7 @@ static bool _affect_mon_in_wall(bolt &pbolt, item_def *item, if (mid == NON_MONSTER) return (false); - if (pbolt.is_enchant + if (pbolt.is_enchantment() || (!pbolt.is_explosion && !pbolt.is_big_cloud && (grd(where) == DNGN_METAL_WALL || pbolt.flavour != BEAM_ELECTRICITY))) @@ -1738,7 +1728,7 @@ void fire_beam(bolt &pbolt, item_def *item, bool drop_item) // Actually draw the beam/missile/whatever, // if the player can see the cell. - if (!pbolt.is_tracer && pbolt.name[0] != '0' && see_grid(testpos)) + if (!pbolt.is_tracer && !pbolt.is_enchantment() && see_grid(testpos)) { // We don't clean up the old position. // First, most people like to see the full path, @@ -1775,7 +1765,7 @@ void fire_beam(bolt &pbolt, item_def *item, bool drop_item) #ifdef MISSILE_TRAILS_OFF // mv: It's not optimal but is usually enough. - if (!pbolt.is_beam || pbolt.name[0] == '0') + if (!pbolt.is_beam || pbolt.is_enchantment()) viewwindow(true, false); #endif } @@ -1810,7 +1800,7 @@ void fire_beam(bolt &pbolt, item_def *item, bool drop_item) // Canned msg for enchantments that affected no-one, but only if the // enchantment is yours. - if (pbolt.name[0] == '0') + if (pbolt.is_enchantment()) { if (!pbolt.is_tracer && !pbolt.msg_generated && !pbolt.obvious_effect && YOU_KILL(pbolt.thrower)) @@ -2283,7 +2273,7 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin, // * Returns MON_RESIST if monster is unaffected due to magic resist. // * Returns MON_UNAFFECTED if monster is immune to enchantment. // * Returns MON_AFFECTED in all other cases (already enchanted, etc). -int mons_ench_f2(monsters *monster, bolt &pbolt) +mon_resist_type mons_ench_f2(monsters *monster, bolt &pbolt) { switch (pbolt.flavour) // put in magic resistance { @@ -2338,11 +2328,11 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) case BEAM_HEALING: if (YOU_KILL(pbolt.thrower)) { - if (cast_healing(5 + roll_dice( pbolt.damage ), monster->pos()) > 0) + if (cast_healing(5 + pbolt.damage.roll(), monster->pos()) > 0) pbolt.obvious_effect = true; pbolt.msg_generated = true; // to avoid duplicate "nothing happens" } - else if (heal_monster( monster, 5 + roll_dice( pbolt.damage ), false )) + else if (heal_monster( monster, 5 + pbolt.damage.roll(), false )) { if (monster->hit_points == monster->max_hit_points) { @@ -2443,7 +2433,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) } return (MON_AFFECTED); -} // end mons_ench_f2() +} // degree is ignored. static void _slow_monster(monsters *mon, int /* degree */) @@ -2509,7 +2499,6 @@ bool curare_hits_monster( const bolt &beam, monsters *monster, kill_category who, int levels ) { const bool res_poison = mons_res_poison(monster) > 0; - bool mondied = false; poison_monster(monster, who, levels, false); @@ -2524,14 +2513,10 @@ bool curare_hits_monster( const bolt &beam, monsters *monster, if (hurted) { simple_monster_message(monster, " convulses."); - if ((monster->hit_points -= hurted) < 1) - { - _monster_die(monster, beam); - mondied = true; - } + monster->hurt(beam.agent(), hurted, BEAM_POISON); } - if (!mondied) + if (monster->alive()) _slow_monster(monster, levels); } @@ -2539,7 +2524,7 @@ bool curare_hits_monster( const bolt &beam, monsters *monster, if (who == KC_YOU) did_god_conduct( DID_POISON, 5 + random2(3) ); - return (mondied); + return (!monster->alive()); } // Actually poisons a monster (w/ message). @@ -2702,7 +2687,7 @@ void mimic_alert(monsters *mimic) static bool _isBouncy(bolt &beam, unsigned char gridtype) { - if (beam.name[0] == '0') + if (beam.is_enchantment()) return (false); if (beam.flavour == BEAM_ELECTRICITY && gridtype != DNGN_METAL_WALL) @@ -3192,7 +3177,7 @@ static int _affect_place_clouds(bolt &beam, const coord_def& p) } // now exit (all enchantments) - if (beam.name[0] == '0') + if (beam.is_enchantment()) return (0); int clouty = env.cgrid(p); @@ -3436,7 +3421,7 @@ static std::string _beam_zapper(const bolt &beam) static bool _beam_is_harmless(bolt &beam, monsters *mon) { // For enchantments, this is already handled in _nasty_beam(). - if (beam.name[0] == '0') + if (beam.is_enchantment()) return (!_nasty_beam(mon, beam)); // The others are handled here. @@ -3486,7 +3471,7 @@ static bool _beam_is_harmless_player(bolt &beam) // Shouldn't happen anyway since enchantments are either aimed at self // (not prompted) or cast at monsters and don't explode or bounce. - if (beam.name[0] == '0') + if (beam.is_enchantment()) return (false); // The others are handled here. @@ -3589,7 +3574,7 @@ static int _affect_player( bolt &beam, item_def *item ) if (you.invisible() && !beam.can_see_invis) beamHit /= 2; - if (beam.name[0] != '0') + if (!beam.is_enchantment()) { if (!beam.is_explosion && !beam.aimed_at_feet) { @@ -3851,7 +3836,7 @@ static int _affect_player( bolt &beam, item_def *item ) if (beam.aux_source.empty()) beam.aux_source = "by nerve-wracking pain"; - _beam_ouch(roll_dice(beam.damage), beam); + _beam_ouch(beam.damage.roll(), beam); beam.obvious_effect = true; break; @@ -3877,7 +3862,7 @@ static int _affect_player( bolt &beam, item_def *item ) beam.damage.size /= 3; } } - _beam_ouch(roll_dice(beam.damage), beam); + _beam_ouch(beam.damage.roll(), beam); beam.obvious_effect = true; break; @@ -3887,7 +3872,7 @@ static int _affect_player( bolt &beam, item_def *item ) if (beam.aux_source.empty()) beam.aux_source = "a disintegration bolt"; - _beam_ouch(roll_dice(beam.damage), beam); + _beam_ouch(beam.damage.roll(), beam); beam.obvious_effect = true; break; @@ -3947,7 +3932,7 @@ static int _affect_player( bolt &beam, item_def *item ) (beam.is_beam) ? 3 : 2; // Roll the damage. - hurted += roll_dice( beam.damage ); + hurted += beam.damage.roll(); #if DEBUG_DIAGNOSTICS int roll = hurted; @@ -4225,13 +4210,12 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) } beam.obvious_effect = true; _update_hurt_or_helped(beam, mon); - mon->hit_points = 0; - _monster_die(mon, beam); + mon->hurt(beam.agent(), INSTANT_DEATH); return (BEAM_STOP); } bool hit_woke_orc = false; - if (beam.name[0] == '0') // enchantments + if (beam.is_enchantment()) // enchantments: no to-hit check { if (beam.is_tracer) { @@ -4294,19 +4278,17 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) enable_attack_conducts(conducts); - // !@#*( affect_monster_enchantment() has side-effects on - // the beam structure which screw up range_used_on_hit(), - // so call it now and store. - int rangeUsed = _range_used_on_hit(beam); - // Doing this here so that the player gets to see monsters // "flicker and vanish" when turning invisible.... _ench_animation( beam.flavour, mon ); // now do enchantment affect - int ench_result = _affect_monster_enchantment(beam, mon); + mon_resist_type ench_result = _affect_monster_enchantment(beam, mon); if (mon->alive()) { + if (mons_is_mimic(mon->type)) + mimic_alert(mon); + switch (ench_result) { case MON_RESIST: @@ -4325,7 +4307,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) if (hit_woke_orc) beogh_follower_convert(mon, true); - return (rangeUsed); + return (_range_used_on_hit(beam)); // END non-tracer enchantment } @@ -4339,7 +4321,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) // we decide if it actually hits. // Roll the damage: - hurt = roll_dice( beam.damage ); + hurt = beam.damage.roll(); // Water absorbs some of the damage for submerged monsters. if (submerged) @@ -4571,19 +4553,12 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) } // Now hurt monster. - hurt_monster( mon, hurt_final ); + mon->hurt(beam.agent(), hurt_final, beam.flavour); - if (mon->hit_points < 1) - { - _monster_die(mon, beam); - } - else + if (mon->alive()) { if (thrower == KILL_YOU_MISSILE && mons_near(mon)) - { - const monsters *mons = static_cast(mon); - print_wounds(mons); - } + print_wounds(mon); // Don't annoy friendlies or good neutrals if the player's beam // did no damage. Hostiles will still take umbrage. @@ -4655,107 +4630,130 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) return (_range_used_on_hit(beam)); } -static int _affect_monster_enchantment(bolt &beam, monsters *mon) +bool _beam_has_saving_throw(const bolt& beam) { - bool death_check = false; + if (beam.aimed_at_feet) + return (false); + + bool rc = true; - if (beam.flavour == BEAM_TELEPORT) // teleportation + switch (beam.flavour) { - if (check_mons_resist_magic( mon, beam.ench_power ) - && !beam.aimed_at_feet) - { - return (mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST); - } + case BEAM_HASTE: + case BEAM_HEALING: + case BEAM_INVISIBILITY: + case BEAM_DISPEL_UNDEAD: + case BEAM_ENSLAVE_DEMON: // it has a different saving throw + rc = false; + break; + default: + break; + } + return rc; +} - if (mons_near(mon) && player_monster_visible(mon)) - beam.obvious_effect = true; +bool _ench_flavour_affects_monster(beam_type flavour, const monsters* mon) +{ + bool rc = true; + switch (flavour) + { + case BEAM_POLYMORPH: + rc = mon->can_mutate(); + break; - monster_teleport(mon, false); + case BEAM_DEGENERATE: + rc = (mons_holiness(mon) == MH_NATURAL + && mon->type != MONS_PULSATING_LUMP); + break; - return (MON_AFFECTED); - } + case BEAM_ENSLAVE_UNDEAD: + rc = (mons_holiness(mon) == MH_UNDEAD && mon->attitude != ATT_FRIENDLY); + break; - if (beam.flavour == BEAM_BLINK) - { - if (!beam.aimed_at_feet - && check_mons_resist_magic( mon, beam.ench_power )) - { - return mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST; - } + case BEAM_DISPEL_UNDEAD: + rc = (mons_holiness(mon) == MH_UNDEAD); + break; - if (mons_near( mon ) && player_monster_visible( mon )) - beam.obvious_effect = true; + case BEAM_ENSLAVE_DEMON: + rc = (mons_holiness(mon) == MH_DEMONIC && !mons_friendly(mon)); + break; - monster_blink( mon ); - return (MON_AFFECTED); + case BEAM_PAIN: + rc = !mons_res_negative_energy(mon); + break; + + case BEAM_SLEEP: + rc = !mon->has_ench(ENCH_SLEEP_WARY) // slept recently + && mons_holiness(mon) == MH_NATURAL // no unnatural + && mons_res_cold(mon) <= 0; // can't be hibernated + break; + + default: + break; } + + return rc; +} - if (beam.flavour == BEAM_POLYMORPH) +static mon_resist_type _affect_monster_enchantment(bolt &beam, monsters *mon) +{ + // Early out if the enchantment is meaningless. + if (!_ench_flavour_affects_monster(beam.flavour, mon)) + return (MON_UNAFFECTED); + + // Check magic resistance. + if (_beam_has_saving_throw(beam)) { - if (!mon->can_mutate()) + if (mons_immune_magic(mon)) return (MON_UNAFFECTED); + if (check_mons_resist_magic(mon, beam.ench_power)) + return (MON_RESIST); + } - if (check_mons_resist_magic( mon, beam.ench_power )) - return (mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST); - + switch (beam.flavour) + { + case BEAM_TELEPORT: + if (you.can_see(mon)) + beam.obvious_effect = true; + monster_teleport(mon, false); + return (MON_AFFECTED); + + case BEAM_BLINK: + if (you.can_see(mon)) + beam.obvious_effect = true; + monster_blink(mon); + return (MON_AFFECTED); + + case BEAM_POLYMORPH: if (mon->mutate()) beam.obvious_effect = true; - if (YOU_KILL(beam.thrower)) { did_god_conduct(DID_DELIBERATE_MUTATING, 2 + random2(3), beam.effect_known); } - return (MON_AFFECTED); - } - - if (beam.flavour == BEAM_BANISH) - { - if (check_mons_resist_magic( mon, beam.ench_power )) - return mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST; + case BEAM_BANISH: if (you.level_type == LEVEL_ABYSS) simple_monster_message(mon, " wobbles for a moment."); else - _monster_die(mon, beam); - + mon->banish(); beam.obvious_effect = true; return (MON_AFFECTED); - } - - if (beam.flavour == BEAM_DEGENERATE) - { - if (mons_holiness(mon) != MH_NATURAL - || mon->type == MONS_PULSATING_LUMP) - { - return (MON_UNAFFECTED); - } - - if (check_mons_resist_magic( mon, beam.ench_power )) - return mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST; + case BEAM_DEGENERATE: if (monster_polymorph(mon, MONS_PULSATING_LUMP)) beam.obvious_effect = true; - return (MON_AFFECTED); - } - - if (beam.flavour == BEAM_DISPEL_UNDEAD) - { - if (mons_holiness(mon) != MH_UNDEAD) - return (MON_UNAFFECTED); + case BEAM_DISPEL_UNDEAD: if (simple_monster_message(mon, " convulses!")) beam.obvious_effect = true; + mon->hurt(beam.agent(), beam.damage.roll()); + return (MON_AFFECTED); - hurt_monster( mon, roll_dice( beam.damage ) ); - - death_check = true; - } - - if (beam.flavour == BEAM_ENSLAVE_UNDEAD - && mons_holiness(mon) == MH_UNDEAD) + case BEAM_ENSLAVE_UNDEAD: { const god_type god = (crawl_state.is_god_acting()) ? crawl_state.which_god_acting() @@ -4766,12 +4764,6 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon) "HD: %d; pow: %d", mon->hit_dice, beam.ench_power); #endif - if (mon->attitude == ATT_FRIENDLY) - return (MON_UNAFFECTED); - - if (check_mons_resist_magic(mon, beam.ench_power)) - return mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST; - beam.obvious_effect = true; if (player_will_anger_monster(mon)) { @@ -4790,9 +4782,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon) return (MON_AFFECTED); } - if (beam.flavour == BEAM_ENSLAVE_DEMON - && mons_holiness(mon) == MH_DEMONIC) - { + case BEAM_ENSLAVE_DEMON: #if DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "HD: %d; pow: %d", mon->hit_dice, beam.ench_power ); @@ -4804,10 +4794,6 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon) return (MON_RESIST); } - // Already friendly. - if (mons_friendly(mon)) - return (MON_UNAFFECTED); - beam.obvious_effect = true; if (player_will_anger_monster(mon)) { @@ -4817,116 +4803,47 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon) simple_monster_message(mon, " is enslaved."); - // Wow, permanent enslaving! + // Wow, permanent enslaving! (sometimes) if (one_chance_in(2 + mon->hit_dice / 4)) mon->attitude = ATT_FRIENDLY; else mon->add_ench(ENCH_CHARM); behaviour_event(mon, ME_ALERT, MHITNOT); - return (MON_AFFECTED); - } - - // - // Everything past this point must pass this magic resistance test. - // - // Using check_mons_resist_magic here since things like disintegrate - // are beyond this point. -- bwr - - // death_check should be set true already if one of the beams above - // did its thing but wants to see if the monster died. - // - if (!death_check - && check_mons_resist_magic( mon, beam.ench_power ) - && beam.flavour != BEAM_HASTE - && beam.flavour != BEAM_HEALING - && beam.flavour != BEAM_INVISIBILITY) - { - return mons_immune_magic(mon) ? MON_UNAFFECTED : MON_RESIST; - } - - if (beam.flavour == BEAM_PAIN) /* pain/agony */ - { - if (mons_res_negative_energy( mon )) - return (MON_UNAFFECTED); + case BEAM_PAIN: // pain/agony if (simple_monster_message(mon, " convulses in agony!")) beam.obvious_effect = true; - if (beam.name.find("agony") != std::string::npos) - { - // AGONY - mon->hit_points = mon->hit_points / 2; - - if (mon->hit_points < 1) - mon->hit_points = 1; - } - else - { - // PAIN - hurt_monster( mon, roll_dice( beam.damage ) ); - } - - death_check = true; - } + if (beam.name.find("agony") != std::string::npos) // agony + mon->hit_points = std::max(mon->hit_points/2, 1); + else // pain + mon->hurt(beam.agent(), beam.damage.roll(), beam.flavour); + return (MON_AFFECTED); - if (beam.flavour == BEAM_DISINTEGRATION) /* disrupt/disintegrate */ - { + case BEAM_DISINTEGRATION: // disrupt/disintegrate if (simple_monster_message(mon, " is blasted.")) beam.obvious_effect = true; - - hurt_monster( mon, roll_dice( beam.damage ) ); - - death_check = true; - } - - - if (beam.flavour == BEAM_SLEEP) - { - if (mon->has_ench(ENCH_SLEEP_WARY)) // slept recently - return (MON_RESIST); - - if (mons_holiness(mon) != MH_NATURAL) // no unnatural - return (MON_UNAFFECTED); - - // Cold res monsters resist hibernation (for consistency - // with mass sleep). - if (mons_res_cold(mon) > 0) - return (MON_UNAFFECTED); - + mon->hurt(beam.agent(), beam.damage.roll(), beam.flavour); + return (MON_AFFECTED); + + case BEAM_SLEEP: if (simple_monster_message(mon, " looks drowsy...")) beam.obvious_effect = true; - mon->put_to_sleep(); - return (MON_AFFECTED); - } - if (beam.flavour == BEAM_BACKLIGHT) - { + case BEAM_BACKLIGHT: if (backlight_monsters(mon->pos(), beam.hit, 0)) { beam.obvious_effect = true; return (MON_AFFECTED); } return (MON_UNAFFECTED); - } - // Everything else? - if (!death_check) + default: return (mons_ench_f2(mon, beam)); - - if (mon->hit_points < 1) - _monster_die(mon, beam); - else - { - print_wounds(mon); - - if (mons_is_mimic( mon->type )) - mimic_alert(mon); } - - return (MON_AFFECTED); } @@ -4938,7 +4855,7 @@ static int _range_used_on_hit(bolt &beam) return (BEAM_STOP); // CHECK ENCHANTMENTS - if (beam.name[0] == '0') + if (beam.is_enchantment()) { switch(beam.flavour) { @@ -5454,10 +5371,10 @@ static void _explosion_map( bolt &beam, const coord_def& p, // Only enchantments should need the actual monster type // to determine this; non-enchantments are pretty // straightforward. -static bool _nasty_beam(monsters *mon, bolt &beam) +static bool _nasty_beam(monsters *mon, const bolt &beam) { // Take care of non-enchantments. - if (beam.name[0] != '0') + if (!beam.is_enchantment()) return (true); // Now for some non-hurtful enchantments. @@ -5496,7 +5413,7 @@ static bool _nasty_beam(monsters *mon, bolt &beam) return (true); } -static bool _nice_beam(monsters *mon, bolt &beam) +static bool _nice_beam(monsters *mon, const bolt &beam) { // haste/healing/invisibility if (beam.flavour == BEAM_HASTE || beam.flavour == BEAM_HEALING @@ -5523,8 +5440,8 @@ bolt::bolt() : range(0), type('*'), ench_power(0), hit(0), thrower(KILL_MISC), ex_size(0), beam_source(MHITNOT), name(), is_beam(false), is_explosion(false), is_big_cloud(false), - is_enchant(false), is_energy(false), is_launched(false), - is_thrown(false), target_first(false), aimed_at_spot(false), +// is_launched(false), + aimed_at_spot(false), aux_source(), affects_nothing(false), obvious_effect(false), effect_known(true), fr_count(0), foe_count(0), fr_power(0), foe_power(0), fr_hurt(0), foe_hurt(0), fr_helped(0), @@ -5585,3 +5502,19 @@ void bolt::setup_retrace() affects_nothing = true; aimed_at_spot = true; } + +actor* bolt::agent() const +{ + if (YOU_KILL(this->thrower)) + return (&you); + else if (this->beam_source != NON_MONSTER) + return (&menv[this->beam_source]); + else + return (NULL); +} + +bool bolt::is_enchantment() const +{ + return (this->flavour >= BEAM_FIRST_ENCHANTMENT + && this->flavour <= BEAM_LAST_ENCHANTMENT); +} diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h index 1806c7ac9f..ec42152515 100644 --- a/crawl-ref/source/beam.h +++ b/crawl-ref/source/beam.h @@ -18,12 +18,20 @@ class monsters; enum demon_beam_type { - DMNBM_HELLFIRE, // 0 + DMNBM_HELLFIRE, DMNBM_SMITING, DMNBM_BRAIN_FEED, DMNBM_MUTATION }; +enum mon_resist_type +{ + MON_RESIST, // monster resisted + MON_UNAFFECTED, // monster unaffected + MON_AFFECTED, // monster was affected + MON_OTHER // monster unaffected, but for other reasons +}; + // must match wand subtypes! (see item_def::zap()) enum zap_type { @@ -115,11 +123,6 @@ struct bolt bool is_beam; // beams? (can hits multiple targets?) bool is_explosion; bool is_big_cloud; // expands into big_cloud at endpoint - bool is_enchant; // no block/dodge, but mag resist - bool is_energy; // mostly energy/non-physical attack - bool is_launched; // was fired from launcher? - bool is_thrown; // was thrown from hand? - bool target_first; // targeting by direction bool aimed_at_spot; // aimed at (x,y), should not cross std::string aux_source; // source of KILL_MISC beams @@ -151,38 +154,31 @@ struct bolt ray_def ray; // shoot on this specific ray + public: // A constructor to try and fix some of the bugs that occur because // this struct never seems to be properly initialized. Definition // is over in beam.cc. bolt(); + bool is_enchantment() const; // no block/dodge, but mag resist void set_target(const dist &); void setup_retrace(); // Returns YOU_KILL or MON_KILL, depending on the source of the beam. killer_type killer() const; + + actor* agent() const; }; void sticky_flame_player(); - void sticky_flame_monster(int mn, kill_category who, int hurt_final); - dice_def calc_dice( int num_dice, int max_damage ); // Test if the to-hit (attack) beats evasion (defence). bool test_beam_hit(int attack, int defence); - -/* *********************************************************************** - * called from: bang - it_use2 - monstuff - mstuff2 - * *********************************************************************** */ void fire_beam(bolt &pbolt, item_def *item = NULL, bool drop_item = false); -// last updated 12may2000 {dlb} -/* *********************************************************************** - * called from: ability - it_use3 - item_use - mstuff2 - religion - - * spells - spells4 - * *********************************************************************** */ int explosion( bolt &pbolt, bool hole_in_the_middle = false, bool explode_in_wall = false, bool stop_at_statues = true, @@ -190,58 +186,30 @@ int explosion( bolt &pbolt, bool hole_in_the_middle = false, bool show_more = true, bool affect_items = true); -// last updated 22jan2001 {gdl} -/* *********************************************************************** - * called from: effects - spells2 - spells4 - * *********************************************************************** */ int mons_adjust_flavoured(monsters *monster, bolt &pbolt, int hurted, bool doFlavouredEffects = true); -/* *********************************************************************** - * called from: ability - item_use - spell - * returns true if messages were generated during the enchantment - * *********************************************************************** */ +// returns true if messages were generated during the enchantment bool mass_enchantment( enchant_type wh_enchant, int pow, int who, int *m_succumbed = NULL, int *m_attempted = NULL ); -/* *********************************************************************** - * called from: fight - monstuff - mstuff2 - * *********************************************************************** */ -int mons_ench_f2( monsters *monster, struct bolt &pbolt ); +mon_resist_type mons_ench_f2(monsters *monster, bolt &pbolt); -/* *********************************************************************** - * called from: fight - monstuff - spells2 - * *********************************************************************** */ bool poison_monster( monsters *monster, kill_category who, int levels = 1, bool force = false, bool verbose = true ); - - -/* *********************************************************************** - * called from: monstuff - * *********************************************************************** */ void fire_tracer( const monsters *monster, struct bolt &pbolt, bool explode_only = false ); - bool check_line_of_sight( const coord_def& source, const coord_def& target ); - -/* *********************************************************************** - * called from: monstuff - * *********************************************************************** */ void mimic_alert( monsters *mimic ); - - bool zapping( zap_type ztype, int power, struct bolt &pbolt, bool needs_tracer = false, std::string msg = "" ); - bool player_tracer( zap_type ztype, int power, struct bolt &pbolt, int range = 0 ); - int affect(bolt &beam, const coord_def& p, item_def *item = NULL, bool affect_items = true); - void beam_drop_object( bolt &beam, item_def *item, const coord_def& where ); #endif diff --git a/crawl-ref/source/effects.cc b/crawl-ref/source/effects.cc index 582270242a..a785592378 100644 --- a/crawl-ref/source/effects.cc +++ b/crawl-ref/source/effects.cc @@ -113,47 +113,38 @@ int holy_word_monsters(coord_def where, int pow, int caster) retval = holy_word_player(pow, caster); // Is a monster in this cell? - int mon = mgrd(where); + const int mon = mgrd(where); if (mon == NON_MONSTER) return retval; monsters *monster = &menv[mon]; - if (invalid_monster(monster) || !mons_is_unholy(monster) + if (!monster->alive() + || !mons_is_unholy(monster) || (is_good_god(you.religion) && (is_follower(monster) || mons_neutral(monster)))) { return retval; } - int hploss = std::max(0, roll_dice(2, 15) + (random2(pow) / 3)); + const int hploss = roll_dice(2, 15) + (random2(pow) / 3); + retval = 1; // Currently, holy word annoys the monsters it affects because it // can kill them, and because hostile monsters don't use it. behaviour_event(monster, ME_ANNOY, MHITYOU); simple_monster_message(monster, " convulses!"); - hurt_monster(monster, hploss); - - if (hploss) + monster->hurt(&you, hploss); + + if (monster->alive()) { - retval = 1; - if (!monster->alive()) - { - monster_die(monster, KILL_YOU, NON_MONSTER); - return retval; - } - } + if (monster->speed_increment >= 25) + monster->speed_increment -= 20; - if (monster->speed_increment >= 25) - { - retval = 1; - monster->speed_increment -= 20; + monster->add_ench(ENCH_FEAR); } - if (monster->add_ench(ENCH_FEAR)) - retval = 1; - return retval; } @@ -247,7 +238,7 @@ int torment_monsters(coord_def where, int pow, int caster) monsters *monster = &menv[mon]; - if (invalid_monster(monster) || mons_res_negative_energy(monster) == 3) + if (!monster->alive() || mons_res_negative_energy(monster) == 3) return retval; int hploss = std::max(0, monster->hit_points / 2 - 1); @@ -260,10 +251,7 @@ int torment_monsters(coord_def where, int pow, int caster) { retval = 1; if (!monster->alive()) - { - monster_die(monster, KILL_YOU, NON_MONSTER); return retval; - } } simple_monster_message(monster, " convulses!"); diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index dca549073d..64c48819e6 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -175,68 +175,70 @@ enum quiver_type enum beam_type // beam[].flavour { - BEAM_NONE, // 0 + BEAM_NONE, BEAM_MISSILE, BEAM_MMISSILE, // and similarly irresistible things BEAM_FIRE, BEAM_COLD, - BEAM_MAGIC, // 5 + BEAM_MAGIC, BEAM_ELECTRICITY, BEAM_POISON, BEAM_NEG, BEAM_ACID, - BEAM_MIASMA, // 10 + BEAM_MIASMA, BEAM_SPORE, BEAM_POISON_ARROW, BEAM_HELLFIRE, BEAM_NAPALM, - BEAM_STEAM, // 15 + BEAM_STEAM, BEAM_HELLFROST, BEAM_ENERGY, - BEAM_HOLY, // aka beam of cleansing, golden flame + BEAM_HOLY, BEAM_FRAG, - BEAM_LAVA, // 20 + BEAM_LAVA, BEAM_BACKLIGHT, BEAM_SLEEP, BEAM_ICE, BEAM_NUKE, BEAM_RANDOM, // 25 - currently translates into FIRE..ACID - // These used to be handled in the colour field: - BEAM_SLOW, // BLACK - BEAM_HASTE, // BLUE - BEAM_HEALING, // GREEN - BEAM_PARALYSIS, // CYAN - BEAM_CONFUSION, // RED - 30 - BEAM_INVISIBILITY, // MAGENTA - BEAM_DIGGING, // BROWN - BEAM_TELEPORT, // LIGHTGREY - BEAM_POLYMORPH, // DARKGREY - BEAM_CHARM, // LIGHTBLUE - 35 - BEAM_BANISH, // LIGHTGREEN - BEAM_DEGENERATE, // LIGHTCYAN - BEAM_ENSLAVE_UNDEAD, // LIGHTRED - BEAM_PAIN, // LIGHTMAGENTA - BEAM_DISPEL_UNDEAD, // YELLOW - 40 - BEAM_DISINTEGRATION, // WHITE - BEAM_ENSLAVE_DEMON, // colour "16" + // Enchantments + BEAM_FIRST_ENCHANTMENT, + BEAM_SLOW = BEAM_FIRST_ENCHANTMENT, + BEAM_HASTE, + BEAM_HEALING, + BEAM_PARALYSIS, + BEAM_CONFUSION, + BEAM_INVISIBILITY, + BEAM_DIGGING, + BEAM_TELEPORT, + BEAM_POLYMORPH, + BEAM_CHARM, + BEAM_BANISH, + BEAM_DEGENERATE, + BEAM_ENSLAVE_UNDEAD, + BEAM_PAIN, + BEAM_DISPEL_UNDEAD, + BEAM_DISINTEGRATION, + BEAM_ENSLAVE_DEMON, BEAM_BLINK, BEAM_PETRIFY, + BEAM_LAST_ENCHANTMENT = BEAM_PETRIFY, // new beams for evaporate - BEAM_POTION_STINKING_CLOUD, // 45 + BEAM_POTION_STINKING_CLOUD, BEAM_POTION_POISON, BEAM_POTION_MIASMA, BEAM_POTION_STEAM, BEAM_POTION_FIRE, - BEAM_POTION_COLD, // 50 + BEAM_POTION_COLD, BEAM_POTION_BLACK_SMOKE, BEAM_POTION_GREY_SMOKE, BEAM_POTION_BLUE_SMOKE, BEAM_POTION_PURP_SMOKE, - BEAM_POTION_RANDOM, // 55 + BEAM_POTION_RANDOM, BEAM_TORMENT_DAMAGE, // Pseudo-beam for damage flavour. diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 6214570cd7..184f366e61 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -303,7 +303,8 @@ public: virtual bool can_safely_mutate() const = 0; virtual bool mutate() = 0; virtual int hurt(const actor *attacker, int amount, - beam_type flavour = BEAM_MISSILE) = 0; + beam_type flavour = BEAM_MISSILE, + bool cleanup_dead = true) = 0; virtual void heal(int amount, bool max_too = false) = 0; virtual void banish(const std::string &who = "") = 0; virtual void blink(bool allow_partial_control = true) = 0; @@ -404,6 +405,7 @@ struct dice_def int size; dice_def( int n = 0, int s = 0 ) : num(n), size(s) {} + int roll() const; }; struct run_check_dir @@ -892,7 +894,8 @@ public: void rot(actor *agent, int rotlevel, int immed_rot); void heal(int amount, bool max_too = false); int hurt(const actor *attacker, int amount, - beam_type flavour = BEAM_MISSILE); + beam_type flavour = BEAM_MISSILE, + bool cleanup_dead = true); int holy_aura() const; int warding() const; @@ -1292,7 +1295,8 @@ public: void confuse(int strength); void rot(actor *agent, int rotlevel, int immed_rot); int hurt(const actor *attacker, int amount, - beam_type flavour = BEAM_MISSILE); + beam_type flavour = BEAM_MISSILE, + bool cleanup_dead = true); void heal(int amount, bool max_too = false); void blink(bool allow_partial_control = true); void teleport(bool right_now = false, bool abyss_shift = false); diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 8e1d8623bc..a4268f015b 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -1189,7 +1189,7 @@ bool melee_attack::player_apply_aux_unarmed() stab_bonus = 0; aux_damage = player_apply_monster_ac(aux_damage); - aux_damage = hurt_monster(def, aux_damage); + aux_damage = def->hurt(&you, aux_damage, BEAM_MISSILE, false); damage_done = aux_damage; if (damage_done > 0) @@ -1221,12 +1221,9 @@ bool melee_attack::player_apply_aux_unarmed() } if (def->hit_points < 1) - { monster_die(def, KILL_YOU, NON_MONSTER); - return (true); - } - return (false); + return (!def->alive()); } std::string melee_attack::debug_damage_number() @@ -1722,7 +1719,8 @@ int melee_attack::player_weapon_type_modify(int damage) bool melee_attack::player_hurt_monster() { - return damage_done && (damage_done = hurt_monster(def, damage_done)); + return damage_done && (damage_done = def->hurt(&you, damage_done, + BEAM_MISSILE, false)); } void melee_attack::player_exercise_combat_skills() @@ -1852,15 +1850,9 @@ bool melee_attack::player_monattk_hit_effects(bool mondied) special_damage); #endif - special_damage = hurt_monster(def, special_damage); + special_damage = def->hurt(&you, special_damage); - if (def->hit_points < 1) - { - monster_die(def, KILL_YOU, NON_MONSTER); - return (true); - } - - return (false); + return (!def->alive()); } static bool is_boolean_resist(beam_type flavour) diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index f20a518928..992bb6a5ad 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -364,10 +364,6 @@ void unlink_item( int dest ) mitm[dest].pos.reset(); mitm[dest].link = NON_ITEM; - - // This causes problems when changing levels. -- bwr - // if (monster->type == MONS_DANCING_WEAPON) - // monster_die(monster, KILL_RESET, NON_MONSTER); return; } } diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 2ca6d2addc..123d8a5511 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -4951,9 +4951,12 @@ god_type monsters::deity() const return (god); } -int monsters::hurt(const actor *agent, int amount, beam_type flavour) +int monsters::hurt(const actor *agent, int amount, beam_type flavour, + bool cleanup_dead) { - if (amount <= 0) + if (amount == INSTANT_DEATH) + amount = hit_points; + else if (amount <= 0) return (0); amount = std::min(amount, hit_points); @@ -4962,9 +4965,11 @@ int monsters::hurt(const actor *agent, int amount, beam_type flavour) // Allow the victim to exhibit passive damage behaviour (royal jelly). react_to_damage(amount, flavour); - if (agent && (hit_points < 1 || hit_dice < 1) && type != -1) + if (cleanup_dead && (hit_points < 1 || hit_dice < 1) && type != -1) { - if (agent->atype() == ACT_PLAYER) + if (agent == NULL) + monster_die(this, KILL_MISC, NON_MONSTER); + else if (agent->atype() == ACT_PLAYER) monster_die(this, KILL_YOU, NON_MONSTER); else { @@ -6136,7 +6141,9 @@ void monsters::apply_enchantment(const mon_enchant &me) if (dam > 0) { - hurt_monster(this, dam); + // We don't have a reasonable agent to give. + // Don't clean up the monster in order to credit properly. + this->hurt(NULL, dam, BEAM_POISON, false); #if DEBUG_DIAGNOSTICS // For debugging, we don't have this silent. @@ -6145,6 +6152,7 @@ void monsters::apply_enchantment(const mon_enchant &me) mprf(MSGCH_DIAGNOSTICS, "poison damage: %d", dam ); #endif + // Credit the kill. if (hit_points < 1) { monster_die(this, me.killer(), me.kill_agent()); @@ -6159,7 +6167,7 @@ void monsters::apply_enchantment(const mon_enchant &me) { if (hit_points > 1 && one_chance_in(3)) { - hurt_monster(this, 1); + this->hurt(NULL, 1); // nonlethal so we don't care about agent if (hit_points < max_hit_points && coinflip()) --max_hit_points; } @@ -6171,19 +6179,21 @@ void monsters::apply_enchantment(const mon_enchant &me) // Assumption: mons_res_fire has already been checked. case ENCH_STICKY_FLAME: { - int dam = - resist_adjust_damage(this, BEAM_FIRE, res_fire(), - roll_dice( 2, 4 ) - 1); + int dam = resist_adjust_damage(this, BEAM_FIRE, res_fire(), + roll_dice(2, 4) - 1); if (dam > 0) { - hurt_monster(this, dam); simple_monster_message(this, " burns!"); + // We don't have a reasonable agent to give. + // Don't clean up the monster in order to credit properly. + this->hurt(NULL, dam, BEAM_NAPALM, false); #if DEBUG_DIAGNOSTICS mprf( MSGCH_DIAGNOSTICS, "sticky flame damage: %d", dam ); #endif + // Credit the kill. if (hit_points < 1) { monster_die(this, me.killer(), me.kill_agent()); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index f2549cd11d..caa77f743d 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -1968,15 +1968,9 @@ void mons_get_damage_level( const monsters* monster, std::string& desc, void print_wounds(const monsters *monster) { - if (monster->type == -1) + if (!monster->alive() || monster->hit_points == monster->max_hit_points) return; - if (monster->hit_points == monster->max_hit_points - || monster->hit_points < 1) - { - return; - } - if (monster_descriptor(monster->type, MDSC_NOMSG_WOUNDS)) return; @@ -7398,15 +7392,13 @@ static void _mons_in_cloud(monsters *monster) behaviour_event(monster, ME_DISTURB, MHITNOT, monster->pos()); } - hurted = std::max(0, hurted); - if (hurted > 0) { #ifdef DEBUG_DIAGNOSTICS mprf(MSGCH_DIAGNOSTICS, "%s takes %d damage from cloud.", monster->name(DESC_CAP_THE).c_str(), hurted); #endif - hurt_monster(monster, hurted); + monster->hurt(NULL, hurted, BEAM_MISSILE, false); if (monster->hit_points < 1) { diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index ee76711d2e..21b58c7126 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -183,7 +183,8 @@ bool message_current_target(void); unsigned int monster_index(const monsters *monster); -void mons_get_damage_level(const monsters*, std::string& desc, mon_dam_level_type&); +void mons_get_damage_level(const monsters*, std::string& desc, + mon_dam_level_type&); int hurt_monster(monsters *victim, int damage_dealt); diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc index 773e4433cf..7d827de14c 100644 --- a/crawl-ref/source/mstuff2.cc +++ b/crawl-ref/source/mstuff2.cc @@ -1819,7 +1819,6 @@ bolt mons_spells( monsters *mons, spell_type spell_cast, int power ) beam.flavour = BEAM_BLINK; beam.thrower = KILL_MON; beam.is_beam = true; - beam.is_enchant = true; break; default: diff --git a/crawl-ref/source/ouch.cc b/crawl-ref/source/ouch.cc index 120b0f316f..6fb5819f63 100644 --- a/crawl-ref/source/ouch.cc +++ b/crawl-ref/source/ouch.cc @@ -804,11 +804,9 @@ static void _yred_mirrors_injury(int dam, int death_source) flash_monster_colour(mon, RED, 200); #endif - hurt_monster(mon, dam); + mon->hurt(&you, dam); - if (mon->hit_points < 1) - monster_die(mon, KILL_YOU, NON_MONSTER); - else + if (mon->alive()) print_wounds(mon); lose_piety(integer_sqrt(dam)); diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index ebd6b2d28b..c0d0cf39e0 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -6450,8 +6450,10 @@ void player::teleport(bool now, bool abyss_shift) you_teleport(); } -int player::hurt(const actor *agent, int amount, beam_type flavour) +int player::hurt(const actor *agent, int amount, beam_type flavour, + bool cleanup_dead) { + // We ignore cleanup_dead here. const monsters *mon = dynamic_cast(agent); if (agent->atype() == ACT_MONSTER) { diff --git a/crawl-ref/source/spells2.cc b/crawl-ref/source/spells2.cc index f181ab51b5..35f0257eee 100644 --- a/crawl-ref/source/spells2.cc +++ b/crawl-ref/source/spells2.cc @@ -640,7 +640,7 @@ void cast_refrigeration(int pow) // Handle the player. const dice_def dam_dice(3, 5 + pow / 10); - const int hurted = check_your_resists(roll_dice( dam_dice ), BEAM_COLD); + const int hurted = check_your_resists(dam_dice.roll(), BEAM_COLD); if (hurted > 0) { @@ -694,15 +694,16 @@ void cast_refrigeration(int pow) if (monster->alive() && mons_near(monster)) { // Calculate damage and apply. - int hurt = mons_adjust_flavoured(monster,beam,roll_dice(dam_dice)); - if (hurt > 0) - hurt_monster(monster, hurt); - - // Kill monster if necessary; cold-blooded creatures can be slowed. - if (monster->hit_points < 1) - monster_die(monster, KILL_YOU, NON_MONSTER); - else if (mons_class_flag(monster->type, M_COLD_BLOOD) && coinflip()) + int hurt = mons_adjust_flavoured(monster, beam, dam_dice.roll()); + monster->hurt(&you, hurt, BEAM_COLD); + + // Cold-blooded creatures can be slowed. + if (monster->alive() + && mons_class_flag(monster->type, M_COLD_BLOOD) + && coinflip()) + { monster->add_ench(ENCH_SLOW); + } } } } @@ -743,12 +744,10 @@ void drain_life(int pow) const int hurted = 3 + random2(7) + random2(pow); behaviour_event(monster, ME_WHACK, MHITYOU, you.pos()); - hurt_monster(monster, hurted); hp_gain += hurted; - if (monster->hit_points < 1) - monster_die(monster, KILL_YOU, NON_MONSTER); - else + monster->hurt(&you, hurted); + if (monster->alive()) print_wounds(monster); } } @@ -805,15 +804,13 @@ bool vampiric_drain(int pow, const dist &vmove) return (false); } - hurt_monster(monster, inflicted); - mprf("You feel life coursing from %s into your body!", monster->name(DESC_NOCAP_THE).c_str()); - print_wounds(monster); + monster->hurt(&you, inflicted); - if (monster->hit_points < 1) - monster_die(monster, KILL_YOU, NON_MONSTER); + if (monster->alive()) + print_wounds(monster); inc_hp(inflicted / 2, false); diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 9cb7ac7434..a968f7de85 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -221,11 +221,8 @@ int cast_smiting(int power, dist &beam) // Maxes out at around 40 damage at 27 Invocations, which is // plenty in my book (the old max damage was around 70, // which seems excessive). - hurt_monster(monster, 7 + (random2(power) * 33 / 191)); - - if (monster->hit_points < 1) - monster_die(monster, KILL_YOU, NON_MONSTER); - else + monster->hurt(&you, 7 + (random2(power) * 33 / 191)); + if (monster->alive()) print_wounds(monster); } } @@ -278,11 +275,8 @@ int airstrike(int power, dist &beam) if (hurted < 0) hurted = 0; - hurt_monster(monster, hurted); - - if (monster->hit_points < 1) - monster_die(monster, KILL_YOU, NON_MONSTER); - else + monster->hurt(&you, hurted); + if (monster->alive()) print_wounds(monster); } } diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index c7e2b572c2..10fc85342c 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -74,24 +74,16 @@ void do_monster_rot(int mon); inline bool player_hurt_monster(int monster, int damage) { ASSERT( monster != NON_MONSTER ); + monsters& m = menv[monster]; if (damage > 0) { - hurt_monster( &menv[monster], damage ); - - if (menv[monster].hit_points > 0) - { - const monsters *mons = static_cast(&menv[monster]); - print_wounds(mons); - } - else - { - monster_die(&menv[monster], KILL_YOU, NON_MONSTER); - return (true); - } + m.hurt(&you, damage); + if (m.alive()) + print_wounds(&m); } - return (false); + return (!m.alive()); } // Here begin the actual spells: @@ -180,7 +172,7 @@ static int _shatter_monsters(coord_def where, int pow, int garbage) break; } - int damage = roll_dice( dam_dice ) - random2( menv[monster].ac ); + int damage = dam_dice.roll() - random2( menv[monster].ac ); if (damage > 0) player_hurt_monster( monster, damage ); @@ -592,7 +584,7 @@ static int _ignite_poison_monsters(coord_def where, int pow, int garbage) // (although only one should actually be present at a given time). dam_dice.num += strength; - int damage = roll_dice( dam_dice ); + int damage = dam_dice.roll(); if (damage > 0) { damage = mons_adjust_flavoured( mon, beam, damage ); @@ -1742,7 +1734,7 @@ bool cast_fragmentation(int pow, const dist& spd) beam.colour = WHITE; beam.damage.num = 2; beam.flavour = BEAM_ICE; - if (player_hurt_monster(midx, roll_dice(beam.damage))) + if (player_hurt_monster(midx, beam.damage.roll())) beam.damage.num++; break; @@ -1766,7 +1758,7 @@ bool cast_fragmentation(int pow, const dist& spd) else { beam.damage.num = 2; - if (player_hurt_monster(midx, roll_dice(beam.damage))) + if (player_hurt_monster(midx, beam.damage.roll())) beam.damage.num += 2; } goto all_done; // i.e. no "Foo Explodes!" @@ -1779,7 +1771,7 @@ bool cast_fragmentation(int pow, const dist& spd) // fizzle (since we don't actually explode wood golems). -- bwr explode = false; beam.damage.num = 2; - player_hurt_monster(midx, roll_dice(beam.damage)); + player_hurt_monster(midx, beam.damage.roll()); break; case MONS_IRON_GOLEM: @@ -1788,7 +1780,7 @@ bool cast_fragmentation(int pow, const dist& spd) beam.name = "blast of metal fragments"; beam.colour = CYAN; beam.damage.num = 4; - if (player_hurt_monster(midx, roll_dice(beam.damage))) + if (player_hurt_monster(midx, beam.damage.roll())) beam.damage.num += 2; break; @@ -1801,7 +1793,7 @@ bool cast_fragmentation(int pow, const dist& spd) beam.name = "blast of rock fragments"; beam.colour = BROWN; beam.damage.num = 3; - if (player_hurt_monster(midx, roll_dice(beam.damage))) + if (player_hurt_monster(midx, beam.damage.roll())) beam.damage.num++; break; @@ -1823,7 +1815,7 @@ bool cast_fragmentation(int pow, const dist& spd) } { - int statue_damage = roll_dice(beam.damage) * 2; + int statue_damage = beam.damage.roll() * 2; if (pow >= 50 && one_chance_in(10)) statue_damage = mon->hit_points; @@ -1838,7 +1830,7 @@ bool cast_fragmentation(int pow, const dist& spd) beam.name = "blast of crystal shards"; beam.colour = WHITE; beam.damage.num = 4; - if (player_hurt_monster(midx, roll_dice(beam.damage))) + if (player_hurt_monster(midx, beam.damage.roll())) beam.damage.num += 2; break; @@ -1855,7 +1847,7 @@ bool cast_fragmentation(int pow, const dist& spd) beam.name = "blast of petrified fragments"; beam.colour = mon->colour; beam.damage.num = petrifying ? 2 : 3; - if (player_hurt_monster(midx, roll_dice(beam.damage))) + if (player_hurt_monster(midx, beam.damage.roll())) beam.damage.num++; break; } @@ -2237,13 +2229,9 @@ void cast_far_strike(int pow) } // Inflict the damage. - hurt_monster( monster, damage ); - if (monster->hit_points < 1) - monster_die(monster, KILL_YOU, NON_MONSTER); - else - print_wounds( monster ); - - return; + monster->hurt(&you, damage); + if (monster->alive()) + print_wounds(monster); } int cast_apportation(int pow) diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index a0274b61d5..7a55036f2c 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -2575,9 +2575,8 @@ void MiscastEffect::_ouch(int dam, beam_type flavour) beem.flavour = flavour; dam = mons_adjust_flavoured(mon_target, beem, dam, true); - hurt_monster(mon_target, dam); - - if (mon_target->hit_points < 1) + mon_target->hurt(NULL, dam, BEAM_MISSILE, false); + if (!mon_target->alive()) monster_die(mon_target, kt, kill_source); } else diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc index 36124b4e70..2b78d546c8 100644 --- a/crawl-ref/source/stuff.cc +++ b/crawl-ref/source/stuff.cc @@ -650,11 +650,6 @@ int roll_dice( int num, int size ) return (ret); } -int roll_dice( const struct dice_def &dice ) -{ - return (roll_dice( dice.num, dice.size )); -} - // originally designed to randomize evasion - // values are slightly lowered near (max) and // approach an upper limit somewhere near (limit/2) @@ -1673,3 +1668,8 @@ int random_rod_subtype() { return STAFF_SMITING + random2(NUM_STAVES - STAFF_SMITING); } + +int dice_def::roll() const +{ + return roll_dice(this->num, this->size); +} diff --git a/crawl-ref/source/stuff.h b/crawl-ref/source/stuff.h index 3c6818776c..7682bd2fe5 100644 --- a/crawl-ref/source/stuff.h +++ b/crawl-ref/source/stuff.h @@ -40,10 +40,8 @@ int random2avg( int max, int rolls ); int bestroll(int max, int rolls); int roll_dice( int num, int size ); -int roll_dice( const struct dice_def &dice ); void scale_dice( dice_def &dice, int threshold = 24 ); - // Various ways to iterate over things. // stack_iterator guarantees validity so long as you don't manually diff --git a/crawl-ref/source/traps.cc b/crawl-ref/source/traps.cc index b69a514fd4..a66b9fb40f 100644 --- a/crawl-ref/source/traps.cc +++ b/crawl-ref/source/traps.cc @@ -471,9 +471,9 @@ void trap_def::trigger(actor& triggerer, bool flat_footed) if (!mons_is_summoned(m)) bleed_onto_floor(m->pos(), m->type, damage_taken, true); - hurt_monster(m, damage_taken); - if (m->hit_points < 1) - monster_die(m, KILL_MISC, NON_MONSTER); + m->hurt(NULL, damage_taken); + if (in_sight && m->alive()) + print_wounds(m); } } break; @@ -1203,9 +1203,7 @@ void trap_def::shoot_ammo(actor& act, bool was_known) poison_monster(monster, KC_OTHER); // Apply damage. - hurt_monster(monster, damage_taken); - if (monster->hit_points < 1) - monster_die(monster, KILL_MISC, NON_MONSTER); + monster->hurt(NULL, damage_taken); } // Drop the item (sometimes.) -- cgit v1.2.3-54-g00ecf