summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-29 16:09:35 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2008-12-29 16:09:35 +0000
commitf5d7515c3cd305b003f95ac5c636eb0c529a0b9c (patch)
treeefca9d3347f9806a1088a2a90fd5f3d7ba03e2d9 /crawl-ref/source
parent14c07a62dab6301ce6e7613786c584b12be85c80 (diff)
downloadcrawl-ref-f5d7515c3cd305b003f95ac5c636eb0c529a0b9c.tar.gz
crawl-ref-f5d7515c3cd305b003f95ac5c636eb0c529a0b9c.zip
Implement divination miscasts for orange statues, fix silver and orange statues to attack monsters as they attack the player. Also fix clouds not being cleared on level reset in dungeon.cc.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8017 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/beam.cc25
-rw-r--r--crawl-ref/source/beam.h5
-rw-r--r--crawl-ref/source/dungeon.cc7
-rw-r--r--crawl-ref/source/externs.h31
-rw-r--r--crawl-ref/source/fight.cc6
-rw-r--r--crawl-ref/source/it_use2.cc3
-rw-r--r--crawl-ref/source/mon-util.cc31
-rw-r--r--crawl-ref/source/monstuff.cc2
-rw-r--r--crawl-ref/source/mstuff2.cc23
-rw-r--r--crawl-ref/source/player.cc8
-rw-r--r--crawl-ref/source/religion.cc2
-rw-r--r--crawl-ref/source/spl-cast.cc53
12 files changed, 143 insertions, 53 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index 248c50f04c..13644d9d7d 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -2562,7 +2562,7 @@ bool curare_hits_monster(actor *agent, monsters *monster, kill_category who,
}
if (monster->alive())
- enchant_monster_with_flavour(monster, BEAM_SLOW);
+ enchant_monster_with_flavour(monster, agent, BEAM_SLOW);
}
// Deities take notice.
@@ -3593,7 +3593,7 @@ void bolt::affect_player_enchantment() {
break;
case BEAM_PETRIFY:
- you.petrify( ench_power );
+ you.petrify( agent(), ench_power );
obvious_effect = true;
break;
@@ -4608,11 +4608,13 @@ bool _ench_flavour_affects_monster(beam_type flavour, const monsters* mon)
return rc;
}
-bool enchant_monster_with_flavour(monsters* mon, beam_type flavour, int powc)
+bool enchant_monster_with_flavour(monsters* mon, actor *foe,
+ beam_type flavour, int powc)
{
bolt dummy;
dummy.flavour = flavour;
dummy.ench_power = powc;
+ dummy.set_agent(foe);
dummy.apply_enchantment_to_monster(mon);
return dummy.obvious_effect;
}
@@ -5462,6 +5464,23 @@ void bolt::setup_retrace()
aimed_at_spot = true;
}
+void bolt::set_agent(actor *actor)
+{
+ // NULL actor is fine by us.
+ if (!actor)
+ return;
+
+ if (actor->atype() == ACT_PLAYER)
+ {
+ thrower = KILL_YOU_MISSILE;
+ }
+ else
+ {
+ thrower = KILL_MON_MISSILE;
+ beam_source = monster_index(dynamic_cast<monsters*>(actor));
+ }
+}
+
actor* bolt::agent() const
{
if (YOU_KILL(this->thrower))
diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h
index e88008f4ec..bec6360a0c 100644
--- a/crawl-ref/source/beam.h
+++ b/crawl-ref/source/beam.h
@@ -118,6 +118,7 @@ public:
bool is_enchantment() const; // no block/dodge, use magic resist
void set_target(const dist &targ);
+ void set_agent(actor *agent);
void setup_retrace();
// Returns YOU_KILL or MON_KILL, depending on the source of the beam.
@@ -245,8 +246,8 @@ int mons_adjust_flavoured(monsters *monster, bolt &pbolt, int hurted,
bool doFlavouredEffects = true);
// Return whether the effect was visible.
-bool enchant_monster_with_flavour(monsters* mon, beam_type flavour,
- int powc = 0);
+bool enchant_monster_with_flavour(monsters* mon, actor *atk,
+ beam_type flavour, int powc = 0);
// returns true if messages were generated during the enchantment
bool mass_enchantment( enchant_type wh_enchant, int pow, int who,
diff --git a/crawl-ref/source/dungeon.cc b/crawl-ref/source/dungeon.cc
index 4df4bf78df..3342bf40fe 100644
--- a/crawl-ref/source/dungeon.cc
+++ b/crawl-ref/source/dungeon.cc
@@ -925,6 +925,13 @@ static void _reset_level()
menv[i].reset();
env.mons_alloc.init(MONS_PROGRAM_BUG);
+
+ // Zap clouds
+ env.cgrid.init(EMPTY_CLOUD);
+
+ const cloud_struct empty;
+ env.cloud.init(empty);
+
mgrd.init(NON_MONSTER);
igrd.init(NON_ITEM);
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 4c11d2a6e0..134c247218 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -338,10 +338,10 @@ public:
virtual void teleport(bool right_now = false, bool abyss_shift = false) = 0;
virtual void poison(actor *attacker, int amount = 1) = 0;
virtual bool sicken(int amount) = 0;
- virtual void paralyse(int strength) = 0;
- virtual void petrify(int strength) = 0;
- virtual void slow_down(int strength) = 0;
- virtual void confuse(int strength) = 0;
+ virtual void paralyse(actor *attacker, int strength) = 0;
+ virtual void petrify(actor *attacker, int strength) = 0;
+ virtual void slow_down(actor *attacker, int strength) = 0;
+ virtual void confuse(actor *attacker, 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, actor* attacker) { }
@@ -1061,10 +1061,10 @@ public:
void make_hungry(int nutrition, bool silent = true);
void poison(actor *agent, int amount = 1);
bool sicken(int amount);
- void paralyse(int str);
- void petrify(int str);
- void slow_down(int str);
- void confuse(int strength);
+ void paralyse(actor *, int str);
+ void petrify(actor *, int str);
+ void slow_down(actor *, int str);
+ void confuse(actor *, int strength);
void rot(actor *agent, int rotlevel, int immed_rot);
void heal(int amount, bool max_too = false);
int hurt(const actor *attacker, int amount,
@@ -1323,6 +1323,8 @@ public:
void react_to_damage(int damage, beam_type flavour);
+ void forget_random_spell();
+
void add_enchantment_effect(const mon_enchant &me, bool quiet = false);
void remove_enchantment_effect(const mon_enchant &me, bool quiet = false);
void apply_enchantments();
@@ -1489,10 +1491,10 @@ public:
void poison(actor *agent, int amount = 1);
bool sicken(int strength);
- void paralyse(int str);
- void petrify(int str);
- void slow_down(int str);
- void confuse(int strength);
+ void paralyse(actor *, int str);
+ void petrify(actor *, int str);
+ void slow_down(actor *, int str);
+ void confuse(actor *, int strength);
void rot(actor *agent, int rotlevel, int immed_rot);
int hurt(const actor *attacker, int amount,
beam_type flavour = BEAM_MISSILE,
@@ -1559,6 +1561,11 @@ struct cloud_struct
kill_category whose;
killer_type killer;
+ cloud_struct() : pos(), type(CLOUD_NONE), decay(0), spread_rate(0),
+ whose(KC_OTHER), killer(KILL_NONE)
+ {
+ }
+
void set_whose(kill_category _whose);
void set_killer(killer_type _killer);
diff --git a/crawl-ref/source/fight.cc b/crawl-ref/source/fight.cc
index 5f8ed20af7..1f9c08369e 100644
--- a/crawl-ref/source/fight.cc
+++ b/crawl-ref/source/fight.cc
@@ -4215,9 +4215,9 @@ void melee_attack::wasp_paralyse_defender()
if (defender->res_poison() <= 0)
{
if (one_chance_in(paralyse_roll))
- defender->paralyse( roll_dice(1, 3) );
+ defender->paralyse( attacker, roll_dice(1, 3) );
else
- defender->slow_down( roll_dice(1, 3) );
+ defender->slow_down( attacker, roll_dice(1, 3) );
}
}
@@ -4440,7 +4440,7 @@ void melee_attack::mons_apply_attack_flavour(const mon_attack_def &attk)
if (one_chance_in(10)
|| (damage_done > 2 && one_chance_in(3)))
{
- defender->confuse(1 + random2(3 + atk->hit_dice));
+ defender->confuse(attacker, 1 + random2(3 + atk->hit_dice));
}
break;
diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc
index 16ba9dfdd4..2c3714ae77 100644
--- a/crawl-ref/source/it_use2.cc
+++ b/crawl-ref/source/it_use2.cc
@@ -217,7 +217,8 @@ bool potion_effect( potion_type pot_eff, int pow, bool was_known )
break;
case POT_PARALYSIS:
- you.paralyse((2 + random2( 6 + you.duration[DUR_PARALYSIS] )) / factor);
+ you.paralyse(NULL,
+ (2 + random2( 6 + you.duration[DUR_PARALYSIS] )) / factor);
xom_is_stimulated(64 / factor);
break;
diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc
index 1435023650..4f7e80b8cf 100644
--- a/crawl-ref/source/mon-util.cc
+++ b/crawl-ref/source/mon-util.cc
@@ -5663,27 +5663,27 @@ void monsters::rot(actor *agent, int rotlevel, int immed_rot)
}
}
-void monsters::confuse(int strength)
+void monsters::confuse(actor *atk, int strength)
{
- enchant_monster_with_flavour(this, BEAM_CONFUSION, strength);
+ enchant_monster_with_flavour(this, atk, BEAM_CONFUSION, strength);
}
-void monsters::paralyse(int strength)
+void monsters::paralyse(actor *atk, int strength)
{
- enchant_monster_with_flavour(this, BEAM_PARALYSIS, strength);
+ enchant_monster_with_flavour(this, atk, BEAM_PARALYSIS, strength);
}
-void monsters::petrify(int strength)
+void monsters::petrify(actor *atk, int strength)
{
if (mons_is_insubstantial(type))
return;
- enchant_monster_with_flavour(this, BEAM_PETRIFY, strength);
+ enchant_monster_with_flavour(this, atk, BEAM_PETRIFY, strength);
}
-void monsters::slow_down(int strength)
+void monsters::slow_down(actor *atk, int strength)
{
- enchant_monster_with_flavour(this, BEAM_SLOW, strength);
+ enchant_monster_with_flavour(this, atk, BEAM_SLOW, strength);
}
void monsters::set_ghost(const ghost_demon &g)
@@ -5986,6 +5986,17 @@ bool monsters::add_ench(const mon_enchant &ench)
return (true);
}
+void monsters::forget_random_spell()
+{
+ int which_spell = -1;
+ int count = 0;
+ for (int i = 0; i < NUM_MONSTER_SPELL_SLOTS; ++i)
+ if (spells[i] != SPELL_NO_SPELL && one_chance_in(++count))
+ which_spell = i;
+ if (which_spell != -1)
+ spells[which_spell] = SPELL_NO_SPELL;
+}
+
void monsters::add_enchantment_effect(const mon_enchant &ench, bool quiet)
{
// Check for slow/haste.
@@ -7512,12 +7523,12 @@ item_type_id_state_type monsters::drink_potion_effect(potion_type ptype)
break;
case POT_SPEED:
- if (enchant_monster_with_flavour(this, BEAM_HASTE))
+ if (enchant_monster_with_flavour(this, this, BEAM_HASTE))
ident = ID_KNOWN_TYPE;
break;
case POT_INVISIBILITY:
- if (enchant_monster_with_flavour(this, BEAM_INVISIBILITY))
+ if (enchant_monster_with_flavour(this, this, BEAM_INVISIBILITY))
ident = ID_KNOWN_TYPE;
break;
diff --git a/crawl-ref/source/monstuff.cc b/crawl-ref/source/monstuff.cc
index 795b825621..6fc5625818 100644
--- a/crawl-ref/source/monstuff.cc
+++ b/crawl-ref/source/monstuff.cc
@@ -6556,7 +6556,7 @@ static void _handle_monster_move(int i, monsters *monster)
}
}
- if (mons_is_lurking(monster))
+ if (mons_is_lurking(monster) || mons_is_submerged(monster))
{
// Lurking monsters only stop lurking if their target is right
// next to them, otherwise they just sit there.
diff --git a/crawl-ref/source/mstuff2.cc b/crawl-ref/source/mstuff2.cc
index ecdfc8e4ca..a2276bac09 100644
--- a/crawl-ref/source/mstuff2.cc
+++ b/crawl-ref/source/mstuff2.cc
@@ -24,6 +24,7 @@
#include "itemname.h"
#include "itemprop.h"
#include "items.h"
+#include "Kills.h"
#include "message.h"
#include "misc.h"
#include "monplace.h"
@@ -2237,7 +2238,8 @@ static int _monster_abjuration(const monsters *caster, bool actual)
bool silver_statue_effects(monsters *mons)
{
- if ((mons_player_visible(mons) || one_chance_in(3)) && !one_chance_in(3))
+ actor *foe = mons->get_foe();
+ if (foe && mons->can_see(foe) && !one_chance_in(3))
{
const std::string msg =
"'s eyes glow " + weird_glowing_colour() + '.';
@@ -2247,7 +2249,7 @@ bool silver_statue_effects(monsters *mons)
mgen_data(
summon_any_demon((coinflip() ? DEMON_COMMON
: DEMON_LESSER)),
- BEH_HOSTILE, 5, you.pos(), MHITYOU));
+ BEH_HOSTILE, 5, foe->pos(), MHITYOU));
return (true);
}
return (false);
@@ -2255,12 +2257,21 @@ bool silver_statue_effects(monsters *mons)
bool orange_statue_effects(monsters *mons)
{
- if ((mons_player_visible(mons) || one_chance_in(3))
- && !one_chance_in(3))
+ actor *foe = mons->get_foe();
+ if (foe && mons->can_see(foe) && !one_chance_in(3))
{
- mpr("A hostile presence attacks your mind!", MSGCH_WARN);
+ if (you.can_see(foe))
+ {
+ if (foe == &you)
+ mprf(MSGCH_WARN, "A hostile presence attacks your mind!");
+ else if (you.can_see(mons))
+ mprf(MSGCH_WARN, "%s fixes %s piercing gaze on %s.",
+ mons->name(DESC_CAP_THE).c_str(),
+ mons->pronoun(PRONOUN_NOCAP_POSSESSIVE).c_str(),
+ foe->name(DESC_NOCAP_THE).c_str());
+ }
- MiscastEffect( &you, monster_index(mons), SPTYP_DIVINATION,
+ MiscastEffect( foe, monster_index(mons), SPTYP_DIVINATION,
random2(15), random2(150),
"an orange crystal statue");
return (true);
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index cc236f217a..f04a9e4094 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -6827,12 +6827,12 @@ void player::rot(actor *who, int rotlevel, int immed_rot)
disease_player( 50 + random2(100) );
}
-void player::confuse(int str)
+void player::confuse(actor *who, int str)
{
confuse_player(str);
}
-void player::paralyse(int str)
+void player::paralyse(actor *who, int str)
{
int &paralysis(duration[DUR_PARALYSIS]);
@@ -6846,7 +6846,7 @@ void player::paralyse(int str)
paralysis = 13;
}
-void player::petrify(int str)
+void player::petrify(actor *who, int str)
{
int &petrif(duration[DUR_PETRIFIED]);
@@ -6859,7 +6859,7 @@ void player::petrify(int str)
petrif = std::min(13, petrif);
}
-void player::slow_down(int str)
+void player::slow_down(actor *foe, int str)
{
::slow_player( str );
}
diff --git a/crawl-ref/source/religion.cc b/crawl-ref/source/religion.cc
index 2ca8d4d9b4..c1e1845971 100644
--- a/crawl-ref/source/religion.cc
+++ b/crawl-ref/source/religion.cc
@@ -4145,7 +4145,7 @@ static bool _zin_retribution()
you.put_to_sleep();
break;
case 2:
- you.paralyse(3 + random2(10));
+ you.paralyse(NULL, 3 + random2(10));
break;
}
break;
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index d448f053c5..2623db1db4 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -2461,8 +2461,10 @@ void MiscastEffect::do_miscast()
// killed a target which was alive when the object was created.
if (!target->alive())
{
+#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "Miscast target '%s' already dead",
target->name(DESC_PLAIN, true).c_str());
+#endif
return;
}
@@ -2484,13 +2486,8 @@ void MiscastEffect::do_miscast()
sp_type = school;
if (sp_type == SPTYP_RANDOM)
{
- // XXX: Monsters currently have no divination miscasts.
- do
- {
- int exp = (random2(SPTYP_LAST_EXPONENT));
- sp_type = (spschool_flag_type) (1 << exp);
- } while (sp_type == SPTYP_DIVINATION
- && target->atype() == ACT_MONSTER);
+ int exp = (random2(SPTYP_LAST_EXPONENT));
+ sp_type = (spschool_flag_type) (1 << exp);
}
}
@@ -2788,13 +2785,13 @@ void MiscastEffect::_potion_effect(int pot_eff, int pot_pow)
}
// Intentional fallthrough if that didn't work.
case POT_SLOWING:
- target->slow_down(pot_pow);
+ target->slow_down(act_source, pot_pow);
break;
case POT_PARALYSIS:
- target->paralyse(pot_pow);
+ target->paralyse(act_source, pot_pow);
break;
case POT_CONFUSION:
- target->confuse(pot_pow);
+ target->confuse(act_source, pot_pow);
break;
default:
@@ -3662,6 +3659,42 @@ void MiscastEffect::_divination_you(int severity)
// XXX: Monster divination miscasts.
void MiscastEffect::_divination_mon(int severity)
{
+ switch (severity)
+ {
+ case 0: // just a harmless message
+ mon_msg_seen = "@The_monster@ looks momentarily confused.";
+ break;
+
+ case 1: // more annoying things
+ switch (random2(2))
+ {
+ case 0:
+ mon_msg_seen = "@The_monster@ looks slightly disoriented.";
+ break;
+ case 1:
+ mon_target->confuse(
+ act_source,
+ 1 + random2(3 + act_source->get_experience_level()));
+ break;
+ }
+ break;
+
+ case 2: // even more annoying things
+ mon_msg_seen = "@The_monster@ shudders.";
+ mon_target->confuse(
+ act_source,
+ 5 + random2(3 + act_source->get_experience_level()));
+ break;
+
+ case 3: // nasty
+ mon_msg_seen = "@The_monster@ reels.";
+ if (one_chance_in(7))
+ mon_target->forget_random_spell();
+ mon_target->confuse(
+ act_source,
+ 8 + random2(3 + act_source->get_experience_level()));
+ break;
+ }
}
void MiscastEffect::_necromancy(int severity)