diff options
author | Adam Borowski <kilobyte@angband.pl> | 2013-05-28 03:23:20 +0200 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2013-05-29 03:23:49 +0200 |
commit | 42993c7a02bf24d02280df06c7140851e8cabb1a (patch) | |
tree | 06e615a5e52bcdb3adaacb8f8b6647822f15908b /crawl-ref/source/spl-miscast.cc | |
parent | ba45822b41b6e70911ecd7a59a4e4f6fca56d0d1 (diff) | |
parent | 536f84b0a61318597e2980852e89e9a41d2dedb4 (diff) | |
download | crawl-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.cc | 272 |
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; + } +} |