From 4a6ed4aa315d47f6ac7186eb217e08c6bea38a1d Mon Sep 17 00:00:00 2001 From: dshaligram Date: Sun, 8 Jul 2007 15:34:10 +0000 Subject: [1746247] Award experience for confused monsters killing themselves and other monsters. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1800 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/Kills.cc | 8 ++-- crawl-ref/source/beam.cc | 15 ++++--- crawl-ref/source/enum.h | 7 +++- crawl-ref/source/fight.cc | 3 +- crawl-ref/source/monstuff.cc | 99 +++++++++++++++++++++++++++----------------- crawl-ref/source/monstuff.h | 3 +- crawl-ref/source/spells4.cc | 4 +- 7 files changed, 86 insertions(+), 53 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/Kills.cc b/crawl-ref/source/Kills.cc index 1f3b8c7d37..74c3215f35 100644 --- a/crawl-ref/source/Kills.cc +++ b/crawl-ref/source/Kills.cc @@ -81,10 +81,10 @@ void KillMaster::load(FILE *file) void KillMaster::record_kill(const monsters *mon, int killer, bool ispet) { - kill_category kc = - (killer == KILL_YOU || killer == KILL_YOU_MISSILE)? KC_YOU : - (ispet)? KC_FRIENDLY : - KC_OTHER; + const kill_category kc = + YOU_KILL(killer)? KC_YOU : + ispet? KC_FRIENDLY : + KC_OTHER; categorized_kills[kc].record_kill(mon); } diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index 2319a82f22..78725baf45 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -136,8 +136,8 @@ static kill_category whose_kill(const bolt &beam) { if (beam.beam_source >= 0 && beam.beam_source < MAX_MONSTERS) { - const monsters &mons = menv[beam.beam_source]; - if (mons.attitude == ATT_FRIENDLY) + const monsters *mons = &menv[beam.beam_source]; + if (mons_friendly(mons)) return (KC_FRIENDLY); } } @@ -1851,6 +1851,8 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin ) if (pow > 200) pow = 200; + const kill_category kc = origin == MHITYOU? KC_YOU : KC_OTHER; + for (i = 0; i < MAX_MONSTERS; i++) { monster = &menv[i]; @@ -1864,7 +1866,7 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin ) if (monster_resists_mass_enchantment(monster, wh_enchant, pow)) continue; - if (monster->add_ench(wh_enchant)) + if (monster->add_ench(mon_enchant(wh_enchant, 0, kc))) { if (player_monster_visible( monster )) { @@ -1927,7 +1929,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) // not hasted, slow it if (!monster->has_ench(ENCH_SLOW) && !mons_is_stationary(monster) - && monster->add_ench(ENCH_SLOW)) + && monster->add_ench(mon_enchant(ENCH_SLOW, 0, whose_kill(pbolt)))) { if (!mons_is_paralysed(monster) && simple_monster_message(monster, " seems to slow down.")) @@ -1981,7 +1983,8 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) return (MON_AFFECTED); case BEAM_CONFUSION: /* 4 = confusion */ - if (monster->add_ench(ENCH_CONFUSION)) + if (monster->add_ench( + mon_enchant(ENCH_CONFUSION, 0, whose_kill(pbolt)))) { // put in an exception for fungi, plants and other things you won't // notice becoming confused. @@ -2048,7 +2051,7 @@ static void beam_paralyses_monster(bolt &pbolt, monsters *monster) if (simple_monster_message(monster, " suddenly stops moving!")) pbolt.obvious_effect = true; - mons_check_pool(monster, pbolt.killer()); + mons_check_pool(monster, pbolt.killer(), pbolt.beam_source); } } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 9e7de149b2..9352571060 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -1707,16 +1707,19 @@ enum kill_category enum killer_type // monster_die(), thing_thrown { - KILL_YOU = 1, // 1 + KILL_NONE = 0, + KILL_YOU, // 1 KILL_MON, KILL_YOU_MISSILE, KILL_MON_MISSILE, + KILL_YOU_CONF, KILL_MISC, // 5 KILL_RESET, // abjuration, etc. KILL_DISMISSED // only on new game startup }; -#define YOU_KILL(x) ((x) == KILL_YOU || (x) == KILL_YOU_MISSILE) +#define YOU_KILL(x) ((x) == KILL_YOU || (x) == KILL_YOU_MISSILE \ + || (x) == KILL_YOU_CONF) #define MON_KILL(x) ((x) == KILL_MON || (x) == KILL_MON_MISSILE) enum launch_retval diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc index 8e3a564bdd..b242901b06 100644 --- a/crawl-ref/source/fight.cc +++ b/crawl-ref/source/fight.cc @@ -1729,8 +1729,9 @@ bool melee_attack::apply_damage_brand() { // declaring these just to pass to the enchant function bolt beam_temp; + beam_temp.thrower = KILL_YOU; beam_temp.flavour = BEAM_CONFUSION; - mons_ench_f2( def, beam_temp ); + mons_ench_f2( def, beam_temp ); } you.duration[DUR_CONFUSING_TOUCH] -= random2(20); diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc index 3d1b4c755b..7d43767837 100644 --- a/crawl-ref/source/monstuff.cc +++ b/crawl-ref/source/monstuff.cc @@ -366,13 +366,44 @@ static void check_kill_milestone(const monsters *mons, } #endif // DGL_MILESTONES +static void give_adjusted_experience(monsters *monster, killer_type killer, + bool pet_kill) +{ + if (YOU_KILL(killer)) + gain_exp( exper_value( monster ) ); + else if (pet_kill) + gain_exp( exper_value( monster ) / 2 + 1 ); +} + +static bool is_pet_kill(killer_type killer, int i) +{ + if (!MON_KILL(killer)) + return (false); + + if (i == ANON_FRIENDLY_MONSTER) + return (true); + + if (i < 0 || i >= MAX_MONSTERS) + return (false); + + const monsters *m = &menv[i]; + if (mons_friendly(m)) + return (true); + + // Check if the monster was confused by you or a friendly, which + // makes casualties to this monster collateral kills. + const mon_enchant me = m->get_ench(ENCH_CONFUSION); + return (me.ench == ENCH_CONFUSION + && (me.who == KC_YOU || me.who == KC_FRIENDLY)); +} + void monster_die(monsters *monster, killer_type killer, int i, bool silent) { if (monster->type == -1) return; - int monster_killed = monster_index(monster); - bool death_message = + const int monster_killed = monster_index(monster); + const bool death_message = !silent && mons_near(monster) && player_monster_visible(monster); bool in_transit = false; const bool hard_reset = testbits(monster->flags, MF_HARD_RESET); @@ -381,6 +412,15 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) check_kill_milestone(monster, killer, i); #endif + // Award experience for suicide if the suicide was caused by the + // player. + if (MON_KILL(killer) && monster_killed == i) + { + const mon_enchant me = monster->get_ench(ENCH_CONFUSION); + if (me.ench == ENCH_CONFUSION && me.who == KC_YOU) + killer = KILL_YOU_CONF; + } + // Take note! if (killer != KILL_RESET && killer != KILL_DISMISSED) { @@ -394,7 +434,6 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) monster->name(DESC_NOCAP_A, true).c_str())); } } - // From time to time Trog gives you a little bonus if (killer == KILL_YOU && you.duration[DUR_BERSERKER]) @@ -426,11 +465,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) if (you.prev_targ == monster_killed) you.prev_targ = MHITNOT; - const bool pet_kill = - (MON_KILL(killer) - && (i == ANON_FRIENDLY_MONSTER || - ((i >= 0 && i < 200) - && mons_friendly(&menv[i])))); + const bool pet_kill = is_pet_kill(killer, i); if (monster->type == MONS_GIANT_SPORE || monster->type == MONS_BALL_LIGHTNING) @@ -446,12 +481,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) MSGCH_MONSTER_DAMAGE, MDAM_DEAD ); if (!testbits(monster->flags, MF_CREATED_FRIENDLY)) - { - if (YOU_KILL(killer)) - gain_exp( exper_value( monster ) ); - else if (pet_kill) - gain_exp( exper_value( monster ) / 2 + 1 ); - } + give_adjusted_experience(monster, killer, pet_kill); if (monster->type == MONS_FIRE_VORTEX) place_cloud(CLOUD_FIRE, monster->x, monster->y, 2 + random2(4), @@ -462,17 +492,12 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) { if (!silent) simple_monster_message( - monster, " vaporizes!", MSGCH_MONSTER_DAMAGE, + monster, " vapourises!", MSGCH_MONSTER_DAMAGE, MDAM_DEAD ); if (!testbits(monster->flags, MF_CREATED_FRIENDLY)) - { - if (YOU_KILL(killer)) - gain_exp( exper_value( monster ) ); - else if (pet_kill) - gain_exp( exper_value( monster ) / 2 + 1 ); - } - + give_adjusted_experience(monster, killer, pet_kill); + place_cloud(CLOUD_COLD, monster->x, monster->y, 2 + random2(4), monster->kill_alignment()); } @@ -495,12 +520,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) if (!testbits(monster->flags, MF_CREATED_FRIENDLY)) - { - if (YOU_KILL(killer)) - gain_exp( exper_value( monster ) ); - else if (pet_kill) - gain_exp( exper_value( monster ) / 2 + 1 ); - } + give_adjusted_experience(monster, killer, pet_kill); } else { @@ -508,6 +528,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) { case KILL_YOU: /* You kill in combat. */ case KILL_YOU_MISSILE: /* You kill by missile or beam. */ + case KILL_YOU_CONF: /* You kill by confusion */ { bool created_friendly = testbits(monster->flags, MF_CREATED_FRIENDLY); @@ -732,6 +753,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) // fall-through case KILL_DISMISSED: + default: monster->destroy_inventory(); break; } @@ -739,7 +761,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) if (monster->type == MONS_MUMMY) { - if (YOU_KILL(killer)) + if (YOU_KILL(killer) && killer != KILL_YOU_CONF) { if (curse_an_item(true)) mpr("You feel nervous for a moment...", MSGCH_MONSTER_SPELL); @@ -749,7 +771,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) || monster->type == MONS_GREATER_MUMMY || monster->type == MONS_MUMMY_PRIEST) { - if (YOU_KILL(killer)) + if (YOU_KILL(killer) && killer != KILL_YOU_CONF) { mpr("You feel extremely nervous for a moment...", MSGCH_MONSTER_SPELL); @@ -821,10 +843,7 @@ void monster_die(monsters *monster, killer_type killer, int i, bool silent) } if (!hard_reset) - monster_drop_ething(monster, - killer == KILL_YOU_MISSILE - || killer == KILL_YOU - || pet_kill); + monster_drop_ething(monster, YOU_KILL(killer) || pet_kill); monster_cleanup(monster); } // end monster_die @@ -4165,7 +4184,7 @@ static void do_move_monster(monsters *monster, int xi, int yi) mons_check_pool(monster); } -void mons_check_pool(monsters *mons, killer_type killer) +void mons_check_pool(monsters *mons, killer_type killer, int killnum) { // Levitating/flying monsters don't make contact with the terrain. const int lev = mons->levitates(); @@ -4207,8 +4226,14 @@ void mons_check_pool(monsters *mons, killer_type killer) mons, " drowns.", MSGCH_MONSTER_DAMAGE, MDAM_DEAD); } - - monster_die(mons, killer, 0, true); + + if (killer == KILL_NONE) + { + // Self-kill. + killer = KILL_MON; + killnum = monster_index(mons); + } + monster_die(mons, killer, killnum, true); } } } diff --git a/crawl-ref/source/monstuff.h b/crawl-ref/source/monstuff.h index b3bf8eb035..f5095a916c 100644 --- a/crawl-ref/source/monstuff.h +++ b/crawl-ref/source/monstuff.h @@ -50,7 +50,8 @@ bool monster_polymorph(monsters *monster, monster_type targetc, void monster_die(monsters *monster, killer_type killer, int i, bool silent = false); -void mons_check_pool(monsters *monster, killer_type killer = KILL_MISC); +void mons_check_pool(monsters *monster, killer_type killer = KILL_NONE, + int killnum = -1); // last updated: 17dec2000 {gdl} /* *********************************************************************** diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index 1c8d0e34bf..cca3770ac2 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -1713,7 +1713,7 @@ static int intoxicate_monsters(int x, int y, int pow, int garbage) if (mons_res_poison(&menv[mon]) > 0) return 0; - menv[mon].add_ench(ENCH_CONFUSION); + menv[mon].add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_YOU)); return 1; } // end intoxicate_monsters() @@ -1779,7 +1779,7 @@ static int glamour_monsters(int x, int y, int pow, int garbage) break; case 1: case 4: - menv[mon].add_ench(ENCH_CONFUSION); + menv[mon].add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_YOU)); break; case 2: case 5: -- cgit v1.2.3-54-g00ecf