summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-08 15:34:10 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-07-08 15:34:10 +0000
commit4a6ed4aa315d47f6ac7186eb217e08c6bea38a1d (patch)
tree0310dfc6788043db7ba118fff6dccbc38a16c7c1
parent8fda0acad5c6c6bf377684d2c14de56ea2e77adf (diff)
downloadcrawl-ref-4a6ed4aa315d47f6ac7186eb217e08c6bea38a1d.tar.gz
crawl-ref-4a6ed4aa315d47f6ac7186eb217e08c6bea38a1d.zip
[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
-rw-r--r--crawl-ref/source/Kills.cc8
-rw-r--r--crawl-ref/source/beam.cc15
-rw-r--r--crawl-ref/source/enum.h7
-rw-r--r--crawl-ref/source/fight.cc3
-rw-r--r--crawl-ref/source/monstuff.cc99
-rw-r--r--crawl-ref/source/monstuff.h3
-rw-r--r--crawl-ref/source/spells4.cc4
7 files changed, 86 insertions, 53 deletions
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: