summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spl-miscast.cc
diff options
context:
space:
mode:
authorAdam Borowski <kilobyte@angband.pl>2013-05-28 03:23:20 +0200
committerAdam Borowski <kilobyte@angband.pl>2013-05-29 03:23:49 +0200
commit42993c7a02bf24d02280df06c7140851e8cabb1a (patch)
tree06e615a5e52bcdb3adaacb8f8b6647822f15908b /crawl-ref/source/spl-miscast.cc
parentba45822b41b6e70911ecd7a59a4e4f6fca56d0d1 (diff)
parent536f84b0a61318597e2980852e89e9a41d2dedb4 (diff)
downloadcrawl-ref-42993c7a02bf24d02280df06c7140851e8cabb1a.tar.gz
crawl-ref-42993c7a02bf24d02280df06c7140851e8cabb1a.zip
Merge branch 'master' into djinn
Diffstat (limited to 'crawl-ref/source/spl-miscast.cc')
-rw-r--r--crawl-ref/source/spl-miscast.cc272
1 files changed, 257 insertions, 15 deletions
diff --git a/crawl-ref/source/spl-miscast.cc b/crawl-ref/source/spl-miscast.cc
index d49c574d9e..a0d87c33cf 100644
--- a/crawl-ref/source/spl-miscast.cc
+++ b/crawl-ref/source/spl-miscast.cc
@@ -85,7 +85,8 @@ MiscastEffect::MiscastEffect(actor* _target, int _source,
ASSERT(!_cause.empty());
ASSERT(count_bits(_school) == 1);
ASSERT(_school <= SPTYP_LAST_SCHOOL || _school == SPTYP_RANDOM);
- ASSERT(level >= 0 && level <= 3);
+ ASSERT(level >= 0);
+ ASSERT(level <= 3);
init();
do_miscast();
@@ -216,7 +217,8 @@ void MiscastEffect::init()
source_known = true;
}
- ASSERT(kc != KC_NCATEGORIES && kt != KILL_NONE);
+ ASSERT(kc != KC_NCATEGORIES);
+ ASSERT(kt != KILL_NONE);
if (death_curse && !invalid_monster_index(kill_source))
{
@@ -253,7 +255,8 @@ string MiscastEffect::get_default_cause(bool attribute_to_user) const
{
// This is only for true miscasts, which means both a spell and that
// the source of the miscast is the same as the target of the miscast.
- ASSERT(source >= 0 && source <= NON_MONSTER);
+ ASSERT(source >= 0);
+ ASSERT(source <= NON_MONSTER);
ASSERT(spell != SPELL_NO_SPELL);
ASSERT(school == SPTYP_NONE);
@@ -285,7 +288,8 @@ bool MiscastEffect::neither_end_silenced()
void MiscastEffect::do_miscast()
{
- ASSERT(recursion_depth >= 0 && recursion_depth < MAX_RECURSE);
+ ASSERT(recursion_depth >= 0);
+ ASSERT(recursion_depth < MAX_RECURSE);
if (recursion_depth == 0)
did_msg = false;
@@ -375,6 +379,14 @@ void MiscastEffect::do_miscast()
msg_ch = MSGCH_PLAIN;
sound_loudness = 0;
+ if (source == ZOT_TRAP_MISCAST)
+ {
+ _zot();
+ if (target->is_player())
+ xom_is_stimulated(150);
+ return;
+ }
+
switch (sp_type)
{
case SPTYP_CONJURATION: _conjuration(severity); break;
@@ -549,7 +561,8 @@ bool MiscastEffect::_ouch(int dam, beam_type flavour)
bool MiscastEffect::_explosion()
{
ASSERT(!beam.name.empty());
- ASSERT(beam.damage.num != 0 && beam.damage.size != 0);
+ ASSERT(beam.damage.num != 0);
+ ASSERT(beam.damage.size != 0);
ASSERT(beam.flavour != BEAM_NONE);
int max_dam = beam.damage.num * beam.damage.size;
@@ -730,7 +743,9 @@ bool MiscastEffect::_create_monster(monster_type what, int abj_deg,
// simply be ignored.
if (data.abjuration_duration != 0)
{
- if (you.penance[god] > 0)
+ if (what == RANDOM_MOBILE_MONSTER)
+ data.summon_type = SPELL_SHADOW_CREATURES;
+ else if (you.penance[god] > 0)
data.summon_type = MON_SUMM_WRATH;
else if (source == ZOT_TRAP_MISCAST)
data.summon_type = MON_SUMM_ZOT;
@@ -1716,11 +1731,7 @@ void MiscastEffect::_necromancy(int severity)
all_msg = "You smell decay.";
}
- if (target->is_player())
- you.rotting++;
- else
- target_as_monster()->add_ench(mon_enchant(ENCH_ROT, 1,
- guilty));
+ target->rot(act_source, 1, 0, true);
}
else if (you.species == SP_MUMMY)
{
@@ -1740,7 +1751,7 @@ void MiscastEffect::_necromancy(int severity)
{
bool success = false;
- for (int i = random2(3); i >= 0; --i)
+ for (int i = random2(2); i >= 0; --i)
{
if (_create_monster(MONS_SHADOW, 2, true))
success = true;
@@ -1766,7 +1777,7 @@ void MiscastEffect::_necromancy(int severity)
if (one_chance_in(3))
{
do_msg();
- target->drain_exp(act_source);
+ target->drain_exp(act_source, cause.c_str());
break;
}
}
@@ -1843,7 +1854,7 @@ void MiscastEffect::_necromancy(int severity)
|| !avoid_lethal(you.hp))
{
do_msg();
- target->drain_exp(act_source);
+ target->drain_exp(act_source, cause.c_str());
break;
}
@@ -2177,7 +2188,7 @@ void MiscastEffect::_fire(int severity)
do_msg();
if (target->is_player())
- napalm_player(random2avg(7,3) + 1);
+ napalm_player(random2avg(7,3) + 1, cause);
else
{
monster* mon_target = target_as_monster();
@@ -2841,3 +2852,234 @@ void MiscastEffect::_do_poison(int amount)
else
target->poison(act_source, amount);
}
+
+void MiscastEffect::_zot()
+{
+ bool success = false;
+ int roll;
+ switch (random2(4))
+ {
+ case 0: // mainly explosions
+ beam.name = "explosion";
+ beam.damage = dice_def(3, 20);
+ beam.ex_size = coinflip() ? 1 : 2;
+ beam.glyph = dchar_glyph(DCHAR_FIRED_BURST);
+ switch (random2(10))
+ {
+ case 0:
+ case 1:
+ all_msg = "There is a sudden explosion of magical energy!";
+ beam.flavour = BEAM_MISSILE;
+ beam.colour = random_colour();
+ _explosion();
+ break;
+ case 2:
+ case 3:
+ all_msg = "There is a sudden explosion of flames!";
+ beam.flavour = BEAM_FIRE;
+ beam.colour = RED;
+ _explosion();
+ break;
+ case 4:
+ case 5:
+ all_msg = "There is a sudden explosion of frost!";
+ beam.flavour = BEAM_COLD;
+ beam.colour = WHITE;
+ _explosion();
+ break;
+ case 6:
+ all_msg = "There is a sudden explosion of flying shrapnel!";
+ beam.flavour = BEAM_FRAG;
+ beam.colour = CYAN;
+ _explosion();
+ break;
+ case 7:
+ all_msg = "There is a sudden explosion of electrical discharges!";
+ beam.flavour = BEAM_ELECTRICITY;
+ beam.colour = LIGHTBLUE;
+ _explosion();
+ break;
+ case 8:
+ if (_create_monster(MONS_BALL_LIGHTNING, 3))
+ all_msg = "A ball of electricity appears!";
+ do_msg();
+ break;
+ case 9:
+ if (_create_monster(MONS_TWISTER, 1))
+ all_msg = "A huge vortex of air appears!";
+ do_msg();
+ break;
+ }
+ break;
+ case 1: // summons
+ reroll_1:
+ switch (random2(9))
+ {
+ case 0:
+ if (_create_monster(MONS_SOUL_EATER, 4, true))
+ {
+ you_msg = "Something reaches out for you...";
+ mon_msg_seen = "Something reaches out for @the_monster@...";
+ mon_msg_unseen = "Something reaches out from thin air...";
+ }
+ do_msg();
+ break;
+ case 1:
+ if (_create_monster(MONS_REAPER, 4, true))
+ {
+ you_msg = "Death has come for you...";
+ mon_msg_seen = "Death has come for @the_monster@...";
+ mon_msg_unseen = "Death appears from thin air...";
+ }
+ do_msg();
+ break;
+ case 2:
+ if (_create_monster(summon_any_demon(RANDOM_DEMON_GREATER), 0, true))
+ all_msg = "You sense a hostile presence.";
+ do_msg();
+ break;
+ case 3:
+ case 4:
+ for (int i = 1 + random2(2); i >= 0; --i)
+ {
+ if (_create_monster(summon_any_demon(RANDOM_DEMON_COMMON), 0, true))
+ success = true;
+ }
+ if (success)
+ {
+ you_msg = "Something turns its malign attention towards "
+ "you...";
+ mon_msg = "You sense a malign presence.";
+ do_msg();
+ }
+ break;
+ case 5:
+ for (int i = 3 + random2(5); i >= 0; --i)
+ {
+ if (_create_monster(summon_any_demon(RANDOM_DEMON_LESSER), 0, true))
+ success = true;
+ }
+ if (success && neither_end_silenced())
+ {
+ you_msg = "A chorus of chattering voices calls out to"
+ " you!";
+ mon_msg = "A chorus of chattering voices calls out!";
+ msg_ch = MSGCH_SOUND;
+ sound_loudness = 3;
+ do_msg();
+ }
+ break;
+ case 6:
+ case 7:
+ for (int i = 2 + random2(3); i >= 0; --i)
+ {
+ if (_create_monster(RANDOM_MOBILE_MONSTER, 4, true))
+ success = true;
+ }
+ if (success)
+ {
+ all_msg = "Wisps of shadow whirl around...";
+ do_msg();
+ }
+ break;
+ case 8:
+ if (!_malign_gateway())
+ goto reroll_1;
+ break;
+ }
+ break;
+ case 2:
+ case 3: // other misc stuff
+ reroll_2:
+ // Cases at the end are for players only.
+ switch (random2(target->is_player() ? 14 : 10))
+ {
+ case 0:
+ target->paralyse(act_source, 2 + random2(4), cause);
+ break;
+ case 1:
+ target->petrify(guilty);
+ break;
+ case 2:
+ target->rot(act_source, 0, 3 + random2(3));
+ break;
+ case 3:
+ if (!_send_to_abyss())
+ goto reroll_2;
+ break;
+ case 4:
+ you_msg = "You feel incredibly sick.";
+ mon_msg_seen = "@The_monster@ looks incredibly sick.";
+ _do_poison(10 + random2avg(19, 2));
+ do_msg();
+ break;
+ case 5:
+ if (!target->is_player())
+ target->polymorph(0);
+ else if (coinflip())
+ {
+ you_msg = "You feel very strange.";
+ delete_mutation(RANDOM_MUTATION, cause, true, false, false, false);
+ do_msg();
+ }
+ else
+ {
+ you_msg = "Your body is distorted in a weirdly horrible way!";
+ mutate(RANDOM_BAD_MUTATION, cause, false, false);
+ if (coinflip())
+ mutate(RANDOM_BAD_MUTATION, cause, false, false);
+ do_msg();
+ }
+ break;
+ case 6:
+ case 7:
+ roll = random2(3); // Give 2 of 3 effects.
+ if (roll != 0)
+ _potion_effect(POT_CONFUSION, 15);
+ if (roll != 1)
+ _potion_effect(POT_SLOWING, 15);
+ if (roll != 2)
+ {
+ you_msg = "Space warps around you!";
+ mon_msg_seen = "Space warps around @the_monster@!";
+ mon_msg_unseen = "A piece of empty space twists and writhes.";
+ _ouch(5 + random2avg(9, 2));
+ if (target->alive())
+ {
+ if (!target->no_tele())
+ {
+ if (one_chance_in(3))
+ target->teleport(true);
+ else
+ target->blink(false);
+ }
+ }
+ }
+ break;
+ case 8:
+ case 9:
+ if (target->is_player())
+ contaminate_player(2 + random2avg(14, 2), false);
+ else
+ target->polymorph(0);
+ break;
+ case 10:
+ if (you.magic_points > 0)
+ {
+ dec_mp(10 + random2(21));
+ mpr("You suddenly feel drained of magical energy!", MSGCH_WARN);
+ }
+ break;
+ case 11:
+ case 12:
+ _lose_stat(STAT_RANDOM, 1 + random2avg((coinflip() ? 7 : 4), 2));
+ break;
+ case 13:
+ mpr("An unnatural silence engulfs you.");
+ you.increase_duration(DUR_SILENCE, 10 + random2(21), 30);
+ invalidate_agrid(true);
+ break;
+ }
+ break;
+ }
+}