From 2a73bdc6a3be5efa46dfdf32bb86edfcf5d0bd4c Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Thu, 22 May 2008 15:53:37 +0000 Subject: Improve player beam tracer for firing through friendlies: * name the monster you're firing through ("your goblin zombie") * use maximum possible range * make it work for spells and abilities, as well Still todo: * apply the same logic to firing missiles * don't prompt for monsters that wouldn't be harmed (e.g. living allies for Dispel Undead, etc.) git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@5177 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/abl-show.cc | 222 +++++++------ crawl-ref/source/beam.cc | 723 ++++++++++++++++++++++++++++++++++++------- crawl-ref/source/beam.h | 6 +- crawl-ref/source/decks.cc | 4 +- crawl-ref/source/it_use3.cc | 1 + crawl-ref/source/item_use.cc | 149 ++++----- crawl-ref/source/itemprop.cc | 160 +++++----- crawl-ref/source/items.cc | 8 +- crawl-ref/source/mon-util.cc | 15 +- crawl-ref/source/player.cc | 4 +- crawl-ref/source/spells1.cc | 56 ++-- crawl-ref/source/spells1.h | 2 +- crawl-ref/source/spells3.cc | 7 +- crawl-ref/source/spells3.h | 2 +- crawl-ref/source/spells4.cc | 13 +- crawl-ref/source/spells4.h | 2 +- crawl-ref/source/spl-cast.cc | 112 +++---- 17 files changed, 990 insertions(+), 496 deletions(-) (limited to 'crawl-ref/source') diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index d61ab5bcc2..d2be5637ea 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -1039,29 +1039,30 @@ static bool _do_ability(const ability_def& abil) break; case ABIL_SPIT_POISON: // Naga + spit poison mutation + { if (you.duration[DUR_BREATH_WEAPON]) { canned_msg(MSG_CANNOT_DO_YET); return (false); } - else if ( !spell_direction(abild, beam) ) + + const int pow = you.experience_level + + player_mutation_level(MUT_SPIT_POISON) * 5 + + (you.species == SP_NAGA) * 10; + + if (!spell_direction(abild, beam) + || !player_tracer(ZAP_SPIT_POISON, pow, beam)) { return (false); } else { - mpr("You spit poison."); - - zapping( ZAP_SPIT_POISON, - you.experience_level - + player_mutation_level(MUT_SPIT_POISON) * 5 - + (you.species == SP_NAGA) * 10, - beam ); + zapping(ZAP_SPIT_POISON, pow, beam); you.duration[DUR_BREATH_WEAPON] = 3 + random2(5); } break; - + } case ABIL_EVOKE_MAPPING: // randarts case ABIL_MAPPING: // Gnome + sense surrounds mut if (abil.ability == ABIL_MAPPING @@ -1110,65 +1111,86 @@ static bool _do_ability(const ability_def& abil) case ABIL_BREATHE_STICKY_FLAME: case ABIL_BREATHE_STEAM: if (you.duration[DUR_BREATH_WEAPON] - && abil.ability != ABIL_SPIT_ACID) + && abil.ability != ABIL_SPIT_ACID) { canned_msg(MSG_CANNOT_DO_YET); return (false); } - else if ( !spell_direction( abild, beam ) ) - { + else if (!spell_direction(abild, beam)) return (false); - } switch (abil.ability) { case ABIL_BREATHE_FIRE: + // Don't check for hell serpents - they get hell fire, + // never regular fire. (GDL) power = you.experience_level; power += player_mutation_level(MUT_BREATHE_FLAMES) * 4; if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON) power += 12; - // don't check for hell serpents - they get hell fire, - // never regular fire (GDL) - mprf("You breathe fire%c", (power < 15)?'.':'!'); + snprintf(info, INFO_SIZE, "You breathe fire%c", + (power < 15) ? '.':'!'); - zapping( ZAP_BREATHE_FIRE, power, beam); + if (!zapping(ZAP_BREATHE_FIRE, power, beam, true, info)) + return (false); break; case ABIL_BREATHE_FROST: - mpr("You exhale a wave of freezing cold."); - zapping(ZAP_BREATHE_FROST, you.experience_level, beam); + if (!zapping(ZAP_BREATHE_FROST, you.experience_level, beam, true, + "You exhale a wave of freezing cold.")) + { + return (false); + } break; case ABIL_BREATHE_POISON: - mpr("You exhale a blast of poison gas."); - zapping(ZAP_BREATHE_POISON, you.experience_level, beam); + if (!zapping(ZAP_BREATHE_POISON, you.experience_level, beam, true, + "You exhale a blast of poison gas.")) + { + return (false); + } break; case ABIL_BREATHE_LIGHTNING: - mpr("You spit a bolt of lightning."); - zapping(ZAP_LIGHTNING, (you.experience_level * 2), beam); + if (!zapping(ZAP_LIGHTNING, (you.experience_level * 2), beam, true, + "You spit a bolt of lightning.")) + { + return (false); + } break; case ABIL_SPIT_ACID: - mpr("You spit acid."); - zapping(ZAP_BREATHE_ACID, you.experience_level, beam); + if (!zapping(ZAP_BREATHE_ACID, you.experience_level, beam, true, + "You spit acid.")) + { + return (false); + } break; case ABIL_BREATHE_POWER: - mpr("You spit a bolt of incandescent energy."); - zapping(ZAP_BREATHE_POWER, you.experience_level, beam); + if (!zapping(ZAP_BREATHE_POWER, you.experience_level, beam, true, + "You spit a bolt of incandescent energy.")) + { + return (false); + } break; case ABIL_BREATHE_STICKY_FLAME: - mpr("You spit a glob of burning liquid."); - zapping(ZAP_STICKY_FLAME, you.experience_level, beam); + if (!zapping(ZAP_STICKY_FLAME, you.experience_level, beam, true, + "You spit a glob of burning liquid.")) + { + return (false); + } break; case ABIL_BREATHE_STEAM: - mpr("You exhale a blast of scalding steam."); - zapping(ZAP_BREATHE_STEAM, you.experience_level, beam); + if (!zapping(ZAP_BREATHE_STEAM, you.experience_level, beam, true, + "You exhale a blast of scalding steam.")) + { + return (false); + } break; default: @@ -1271,12 +1293,12 @@ static bool _do_ability(const ability_def& abil) break; case ABIL_CONTROL_DEMON: - if ( !spell_direction(abild, beam) ) + if (!spell_direction(abild, beam) + || !zapping(ZAP_CONTROL_DEMON, you.experience_level * 5, beam, + true)) { return (false); } - - zapping(ZAP_CONTROL_DEMON, you.experience_level * 5, beam); break; case ABIL_TO_PANDEMONIUM: @@ -1296,23 +1318,22 @@ static bool _do_ability(const ability_def& abil) case ABIL_THROW_FLAME: case ABIL_THROW_FROST: - if ( !spell_direction(abild, beam) ) + if (!spell_direction(abild, beam)) + return (false); + + if (!zapping((abil.ability == ABIL_THROW_FLAME ? ZAP_FLAME : ZAP_FROST), + you.experience_level * 3, beam, true)) { return (false); } - - zapping( (abil.ability == ABIL_THROW_FLAME ? ZAP_FLAME : ZAP_FROST), - you.experience_level * 3, - beam ); break; case ABIL_BOLT_OF_DRAINING: - if ( !spell_direction(abild, beam) ) - { + if (!spell_direction(abild, beam)) return (false); - } - zapping(ZAP_NEGATIVE_ENERGY, you.experience_level * 6, beam); + if (!zapping(ZAP_NEGATIVE_ENERGY, you.experience_level * 6, beam, true)) + return (false); break; case ABIL_EVOKE_TURN_INVISIBLE: // ring, randarts, darkness items @@ -1383,66 +1404,20 @@ static bool _do_ability(const ability_def& abil) exercise(SK_INVOCATIONS, 5 + random2(8)); break; -// no longer in use, maybe keep for other cases (or remove!) -/* - case ABIL_ZIN_PESTILENCE: - mpr( "You call forth a swarm of pestilential beasts!" ); - - if (!summon_swarm( you.skills[SK_INVOCATIONS] * 8, false, true )) - mpr( "Nothing seems to have answered your call." ); - - exercise( SK_INVOCATIONS, 2 + random2(4) ); - break; - - case ABIL_ZIN_HOLY_WORD: - holy_word(you.skills[SK_INVOCATIONS] * 8, HOLY_WORD_GENERIC, you.x_pos, - you.y_pos, true); - exercise(SK_INVOCATIONS, 3 + random2(5)); - break; - - case ABIL_ZIN_SUMMON_GUARDIAN: - summon_ice_beast_etc(you.skills[SK_INVOCATIONS] * 4, MONS_ANGEL, true); - exercise(SK_INVOCATIONS, 8 + random2(10)); - break; - - case ABIL_TSO_REPEL_UNDEAD: - turn_undead(you.piety); - - if (!you.duration[DUR_REPEL_UNDEAD]) - mpr( "You feel a holy aura protecting you." ); - - you.duration[DUR_REPEL_UNDEAD] += 8 - + roll_dice(2, 2 * you.skills[SK_INVOCATIONS]); - - if (you.duration[ DUR_REPEL_UNDEAD ] > 50) - you.duration[ DUR_REPEL_UNDEAD ] = 50; - - exercise(SK_INVOCATIONS, 1); - break; - - case ABIL_TSO_ANNIHILATE_UNDEAD: - if ( !spell_direction(spd, beam) ) - { - return (false); - } - - zapping(ZAP_DISPEL_UNDEAD, you.skills[SK_INVOCATIONS] * 6, beam); - exercise(SK_INVOCATIONS, 2 + random2(4)); - break; -*/ - case ABIL_TSO_DIVINE_SHIELD: cast_divine_shield(); exercise( SK_INVOCATIONS, (coinflip()? 3 : 2) ); break; case ABIL_TSO_CLEANSING_FLAME: - if ( !spell_direction(spd, beam) ) + if (!spell_direction(spd, beam)) + return (false); + + if (!zapping(ZAP_CLEANSING_FLAME, 20 + you.skills[SK_INVOCATIONS] * 6, + beam, true)) { return (false); } - - zapping(ZAP_CLEANSING_FLAME, 20 + you.skills[SK_INVOCATIONS] * 6, beam); exercise(SK_INVOCATIONS, 3 + random2(6)); break; @@ -1457,12 +1432,14 @@ static bool _do_ability(const ability_def& abil) break; case ABIL_KIKU_ENSLAVE_UNDEAD: - if ( !spell_direction(spd, beam) ) + if (!spell_direction(spd, beam)) + return (false); + + if (!zapping(ZAP_ENSLAVE_UNDEAD, you.skills[SK_INVOCATIONS] * 8, beam, + true)) { return (false); } - - zapping( ZAP_ENSLAVE_UNDEAD, you.skills[SK_INVOCATIONS] * 8, beam ); exercise(SK_INVOCATIONS, 5 + random2(5)); break; @@ -1523,15 +1500,18 @@ static bool _do_ability(const ability_def& abil) break; case ABIL_MAKHLEB_MINOR_DESTRUCTION: - if ( !spell_direction(spd, beam) ) - { + if (!spell_direction(spd, beam)) return (false); - } power = you.skills[SK_INVOCATIONS] + random2( 1 + you.skills[SK_INVOCATIONS] ) + random2( 1 + you.skills[SK_INVOCATIONS] ); + // Since the actual beam is random, check with BEAM_MMISSILE and the + // highest range possible (electricity). + if (!player_tracer(ZAP_DEBUGGING_RAY, power, beam, 13)) + return (false); + switch (random2(5)) { case 0: zapping( ZAP_FLAME, power, beam ); break; @@ -1554,14 +1534,17 @@ static bool _do_ability(const ability_def& abil) break; case ABIL_MAKHLEB_MAJOR_DESTRUCTION: - if ( !spell_direction(spd, beam) ) - { + if (!spell_direction(spd, beam)) return (false); - } power = you.skills[SK_INVOCATIONS] * 3 - + random2( 1 + you.skills[SK_INVOCATIONS] ) - + random2( 1 + you.skills[SK_INVOCATIONS] ); + + random2( 1 + you.skills[SK_INVOCATIONS] ) + + random2( 1 + you.skills[SK_INVOCATIONS] ); + + // Since the actual beam is random, check with BEAM_MMISSILE and the + // highest range possible (orb of electricity). + if (!player_tracer(ZAP_DEBUGGING_RAY, power, beam, 20)) + return (false); switch (random2(8)) { @@ -1579,17 +1562,17 @@ static bool _do_ability(const ability_def& abil) // make a divine lightning bolt... beam.beam_source = NON_MONSTER; - beam.type = dchar_glyph(DCHAR_FIRED_BURST); - beam.damage = dice_def( 3, 30 ); - beam.flavour = BEAM_ELECTRICITY; - beam.target_x = you.x_pos; - beam.target_y = you.y_pos; - beam.name = "blast of lightning"; - beam.colour = LIGHTCYAN; - beam.thrower = KILL_YOU; - beam.aux_source = "Makhleb's lightning strike"; - beam.ex_size = 1 + you.skills[SK_INVOCATIONS] / 8; - beam.is_tracer = false; + beam.type = dchar_glyph(DCHAR_FIRED_BURST); + beam.damage = dice_def( 3, 30 ); + beam.flavour = BEAM_ELECTRICITY; + beam.target_x = you.x_pos; + beam.target_y = you.y_pos; + beam.name = "blast of lightning"; + beam.colour = LIGHTCYAN; + beam.thrower = KILL_YOU; + beam.aux_source = "Makhleb's lightning strike"; + beam.ex_size = 1 + you.skills[SK_INVOCATIONS] / 8; + beam.is_tracer = false; // ... and fire! explosion(beam); @@ -1700,12 +1683,17 @@ static bool _do_ability(const ability_def& abil) case ABIL_LUGONU_BANISH: if (!spell_direction(spd, beam, DIR_NONE, TARG_ENEMY)) return (false); + if (beam.target_x == you.x_pos && beam.target_y == you.y_pos) { mpr("You cannot banish yourself!"); return (false); } - zapping( ZAP_BANISHMENT, 16 + you.skills[SK_INVOCATIONS] * 8, beam ); + if (!zapping(ZAP_BANISHMENT, 16 + you.skills[SK_INVOCATIONS] * 8, beam, + true)) + { + return (false); + } exercise(SK_INVOCATIONS, 3 + random2(5)); break; diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc index d96086afe3..99c87eac7b 100644 --- a/crawl-ref/source/beam.cc +++ b/crawl-ref/source/beam.cc @@ -211,7 +211,27 @@ static void _ench_animation( int flavour, const monsters *mon, bool force ) zap_animation( element_colour( elem ), mon, force ); } -bool zapping(zap_type ztype, int power, bolt &pbolt) +static void _beam_set_default_values(bolt &beam, int power) +{ + beam.range = 8 + random2(5); // default for "0" beams (I think) + beam.rangeMax = 0; + beam.hit = 0; // default for "0" beams (I think) + beam.damage = dice_def( 1, 0 ); // default for "0" beams (I think) + beam.type = 0; // default for "0" beams + beam.flavour = BEAM_MAGIC; // default for "0" beams + beam.ench_power = power; + beam.obvious_effect = false; + beam.is_beam = false; // default for all beams. + beam.is_tracer = false; // default for all player beams + beam.thrower = KILL_YOU_MISSILE; // missile from player + beam.aux_source.clear(); // additional source info, unused +} + +// If needs_tracer is true, we need to check the beam path for friendly +// monsters for *player beams* only! If allies are found, the player is +// prompted to stop or continue. +bool zapping(zap_type ztype, int power, bolt &pbolt, bool needs_tracer, + std::string msg) { #if DEBUG_DIAGNOSTICS @@ -222,46 +242,30 @@ bool zapping(zap_type ztype, int power, bolt &pbolt) // equal to range. This is OK, since rangeMax really only matters for // stuff monsters throw/zap. - // all of the following might be changed by zappy(): - pbolt.range = 8 + random2(5); // default for "0" beams (I think) - pbolt.rangeMax = 0; - pbolt.hit = 0; // default for "0" beams (I think) - pbolt.damage = dice_def( 1, 0 ); // default for "0" beams (I think) - pbolt.type = 0; // default for "0" beams - pbolt.flavour = BEAM_MAGIC; // default for "0" beams - pbolt.ench_power = power; - pbolt.obvious_effect = false; - pbolt.is_beam = false; // default for all beams. - pbolt.is_tracer = false; // default for all player beams - pbolt.thrower = KILL_YOU_MISSILE; // missile from player - pbolt.aux_source.clear(); // additional source info, unused + // All of the following settings might be changed by _zappy(). + _beam_set_default_values(pbolt, power); - // fill in the bolt structure - _zappy( ztype, power, pbolt ); + // For player bolts, check whether tracer goes through friendlies. + // NOTE: Whenever zapping() is called with a randomized value for power, + // player_tracer should be called directly with the highest power possible + // respecting current skill, experience level etc. - if (pbolt.thrower == KILL_YOU_MISSILE) + if (needs_tracer && pbolt.thrower == KILL_YOU_MISSILE + && !player_tracer(ztype, power, pbolt)) { - pbolt.is_tracer = true; - // XXX: rangeMax needs to be set appropriately for the tracer! - pbolt.attitude = ATT_FRIENDLY; - pbolt.source_x = you.x_pos; - pbolt.source_y = you.y_pos; - fire_beam(pbolt); - - if (pbolt.fr_count > 0 && !yesno("Really fire through this friendly " - "creature?", true, 'n')) - { - canned_msg(MSG_OK); - you.turn_is_over = false; - return (false); - } - pbolt.is_tracer = false; + return (false); } + // fill in the bolt structure + _zappy( ztype, power, pbolt ); + + if (!msg.empty()) + mpr(msg.c_str()); + if (ztype == ZAP_LIGHTNING && !silenced(you.x_pos, you.y_pos)) { // XXX: needs to check silenced at other location, too {dlb} - mpr("You hear a mighty clap of thunder!"); + mpr("You hear a mighty clap of thunder!", MSGCH_SOUND); noisy( 25, you.x_pos, you.y_pos ); } @@ -270,6 +274,432 @@ bool zapping(zap_type ztype, int power, bolt &pbolt) return (true); } // end zapping() +// pbolt needs to be initialized for tracing: with the the maximum range, +// and the flavour to allow for completely resistant monsters. +static void _get_max_range( zap_type z_type, int power, bolt &pbolt ) +{ + // sorted by range + switch (z_type) + { + case ZAP_SMALL_SANDBLAST: + pbolt.rangeMax = 2; + pbolt.flavour = BEAM_FRAG; // extra AC resist + break; + + case ZAP_SANDBLAST: + if (power > 50) + power = 50; + +// pbolt.range = 2 + random2(power) / 20; + pbolt.rangeMax = 2 + (power-1) / 20; // max 4 + pbolt.flavour = BEAM_FRAG; // extra AC resist + break; + + case ZAP_FLAME_TONGUE: + if (power > 25) + power = 25; + +// pbolt.range = 1 + random2(2) + random2(power) / 10; + pbolt.rangeMax = 2 + (power-1) / 10; // max 4 + pbolt.flavour = BEAM_FIRE; + break; + + case ZAP_CLEANSING_FLAME: + pbolt.name = "golden flame"; + pbolt.rangeMax = 7; + pbolt.flavour = BEAM_HOLY; + pbolt.is_explosion = true; + break; + + case ZAP_MAGMA: + pbolt.rangeMax = 8; + pbolt.flavour = BEAM_LAVA; + pbolt.is_beam = true; + break; + + case ZAP_IRON_BOLT: + pbolt.rangeMax = 9; + pbolt.flavour = BEAM_MMISSILE; // unresistable + break; + + case ZAP_CRYSTAL_SPEAR: + pbolt.rangeMax = 9; + pbolt.flavour = BEAM_MMISSILE; // unresistable + break; + + case ZAP_SPIT_POISON: + if (power > 50) + power = 50; + +// pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.rangeMax = 3 + power / 2; + if (pbolt.rangeMax > 9) + pbolt.rangeMax = 9; + + pbolt.flavour = BEAM_POISON; + break; + + case ZAP_BREATHE_FIRE: + if (power > 50) + power = 50; + +// pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.rangeMax = 3 + power / 2; + if (pbolt.rangeMax > 9) + pbolt.rangeMax = 9; + + pbolt.flavour = BEAM_FIRE; + pbolt.is_beam = true; + break; + + case ZAP_BREATHE_FROST: + if (power > 50) + power = 50; + +// pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.rangeMax = 3 + power / 2; + if (pbolt.rangeMax > 9) + pbolt.rangeMax = 9; + + pbolt.flavour = BEAM_COLD; + pbolt.is_beam = true; + break; + + case ZAP_BREATHE_ACID: + if (power > 50) + power = 50; + +// pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.rangeMax = 3 + power / 2; + if (pbolt.rangeMax > 9) + pbolt.rangeMax = 9; + + pbolt.flavour = BEAM_ACID; + pbolt.is_beam = true; + break; + + case ZAP_BREATHE_POISON: // leaves clouds of gas + if (power > 50) + power = 50; + +// pbolt.range = 3 + random2( 1 + power / 2 ); + pbolt.rangeMax = 3 + power / 2; + if (pbolt.rangeMax > 9) + pbolt.rangeMax = 9; + + pbolt.flavour = BEAM_POISON; + pbolt.is_beam = true; + break; + + case ZAP_BREATHE_POWER: + if (power > 50) + power = 50; + +// pbolt.range = 6 + random2( 1 + power / 2 ); + pbolt.rangeMax = 6 + power / 2; + if (pbolt.rangeMax > 9) + pbolt.rangeMax = 9; + + pbolt.flavour = BEAM_MMISSILE; // unresistable + pbolt.is_beam = true; + break; + + case ZAP_BREATHE_STEAM: + pbolt.rangeMax = 9; + pbolt.flavour = BEAM_STEAM; + pbolt.is_beam = true; + break; + + case ZAP_STRIKING: + case ZAP_MAGIC_DARTS: + case ZAP_STONE_ARROW: + case ZAP_MYSTIC_BLAST: + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_MMISSILE; // unresistable + break; + + case ZAP_STING: + case ZAP_POISON_ARROW: + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_POISON; + break; + + case ZAP_FLAME: + case ZAP_STICKY_FLAME: + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_FIRE; + break; + + case ZAP_FROST: + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_COLD; + break; + + case ZAP_ICE_BOLT: + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_ICE; // half resistable + break; + + case ZAP_ELECTRICITY: + pbolt.rangeMax = 13; + pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects + pbolt.is_beam = true; + break; + + case ZAP_DISRUPTION: + case ZAP_DISINTEGRATION: + pbolt.name = "0"; + pbolt.rangeMax = 14; + pbolt.flavour = BEAM_DISINTEGRATION; + break; + + case ZAP_PAIN: + pbolt.name = "0"; + pbolt.rangeMax = 14; + pbolt.flavour = BEAM_PAIN; + break; + + case ZAP_DISPEL_UNDEAD: + pbolt.name = "0"; + pbolt.rangeMax = 14; + pbolt.flavour = BEAM_DISPEL_UNDEAD; + break; + + case ZAP_FIRE: + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_FIRE; + pbolt.is_beam = true; + break; + + case ZAP_BONE_SHARDS: + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_MAGIC; // unresisted + pbolt.is_beam = true; + break; + + case ZAP_COLD: + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_COLD; + pbolt.is_beam = true; + break; + + case ZAP_NEGATIVE_ENERGY: + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_NEG; // drains levels + pbolt.is_beam = true; + break; + + case ZAP_BEAM_OF_ENERGY: // bolt of innacuracy + pbolt.range = 16; + pbolt.flavour = BEAM_ENERGY; // unresisted + pbolt.is_beam = true; + break; + + case ZAP_VENOM_BOLT: + pbolt.rangeMax = 17; + pbolt.flavour = BEAM_POISON; + pbolt.is_beam = true; + break; + + case ZAP_LIGHTNING: + pbolt.rangeMax = 17; + pbolt.flavour = BEAM_ELECTRICITY; // beams & reflects + pbolt.is_beam = true; + break; + + // enchantments + case ZAP_ENSLAVEMENT: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_CHARM; + break; + + case ZAP_BANISHMENT: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_BANISH; + break; + + case ZAP_DEGENERATION: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_DEGENERATE; + break; + + case ZAP_ENSLAVE_UNDEAD: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_ENSLAVE_UNDEAD; + break; + + case ZAP_CONTROL_DEMON: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_ENSLAVE_DEMON; + break; + + case ZAP_SLEEP: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_SLEEP; + break; + + case ZAP_BACKLIGHT: + pbolt.name = "0"; + pbolt.rangeMax = 11; + pbolt.flavour = BEAM_BACKLIGHT; + break; + + case ZAP_SLOWING: + pbolt.name = "0"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_SLOW; + break; + + case ZAP_HASTING: + pbolt.name = "0"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_HASTE; + break; + + case ZAP_PARALYSIS: + pbolt.name = "0"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_PARALYSIS; + break; + + case ZAP_CONFUSION: + pbolt.name = "0"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_CONFUSION; + break; + + case ZAP_INVISIBILITY: + pbolt.name = "0"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_INVISIBILITY; + break; + + case ZAP_HEALING: + pbolt.name = "0"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_HEALING; + break; + + case ZAP_TELEPORTATION: + pbolt.name = "0"; + pbolt.rangeMax = 13; + pbolt.flavour = BEAM_TELEPORT; + break; + + case ZAP_POLYMORPH_OTHER: + pbolt.name = "0"; + pbolt.rangeMax = 13; + pbolt.flavour = BEAM_POLYMORPH; + break; + + case ZAP_AGONY: + pbolt.name = "0agony"; + pbolt.rangeMax = 14; + pbolt.flavour = BEAM_PAIN; + break; + + case ZAP_DIGGING: + pbolt.name = "0"; +// pbolt.range = 3 + random2( power / 5 ) + random2(5); + pbolt.rangeMax = 6 + power / 5; + pbolt.flavour = BEAM_DIGGING; + pbolt.is_beam = true; + break; + + // explosions + case ZAP_FIREBALL: + pbolt.name = "fireball"; + pbolt.rangeMax = 12; + pbolt.flavour = BEAM_FIRE; // fire + pbolt.is_explosion = true; + break; + + case ZAP_ICE_STORM: + pbolt.name = "great blast of cold"; + pbolt.rangeMax = 13; + pbolt.ench_power = power; // used for radius + pbolt.flavour = BEAM_ICE; // half resisted + pbolt.is_explosion = true; + break; + + case ZAP_ORB_OF_FRAGMENTATION: // cap 150 + pbolt.name = "metal orb"; + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_FRAG; // extra AC resist + pbolt.is_explosion = true; + break; + + case ZAP_HELLFIRE: + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_HELLFIRE; + pbolt.is_explosion = true; + break; + + case ZAP_ORB_OF_ELECTRICITY: // cap 150 + pbolt.name = "orb of electricity"; + pbolt.rangeMax = 20; + pbolt.flavour = BEAM_ELECTRICITY; + pbolt.is_explosion = true; + break; + + case ZAP_DEBUGGING_RAY: + default: // buggy beam + pbolt.rangeMax = 16; + pbolt.flavour = BEAM_MMISSILE; // unresistable + break; + } +} + +// FIXME: Also needs to check for fleeing monster with TSO and neutrals for +// all good gods. +bool player_tracer( zap_type ztype, int power, bolt &pbolt, int range) +{ + _beam_set_default_values(pbolt, power); + pbolt.name = "unimportant"; + _get_max_range(ztype, power, pbolt); + + // override range if necessary + if (range > 0) + pbolt.rangeMax = range; + + pbolt.is_tracer = true; + pbolt.source_x = you.x_pos; + pbolt.source_y = you.y_pos; + pbolt.beam_source = 0; + pbolt.can_see_invis = player_see_invis(); + pbolt.smart_monster = true; + pbolt.attitude = ATT_FRIENDLY; + + // init tracer variables + pbolt.foe_count = pbolt.fr_count = 0; + pbolt.foe_power = pbolt.fr_power = 0; + pbolt.fr_helped = pbolt.fr_hurt = 0; + pbolt.foe_helped = pbolt.foe_hurt = 0; + pbolt.foe_ratio = 100; + + fire_beam(pbolt); + + // Should only happen if the player answered 'n' to one of those + // "Fire through friendly?" prompts. + if (pbolt.fr_count > 0) + { + canned_msg(MSG_OK); + you.turn_is_over = false; + return (false); + } + + // Set to non-tracing for actual firing. + pbolt.is_tracer = false; + return (true); + +} + dice_def calc_dice( int num_dice, int max_damage ) { dice_def ret( num_dice, 0 ); @@ -295,8 +725,7 @@ dice_def calc_dice( int num_dice, int max_damage ) return (ret); } -// *do not* call this function directly (duh - it's static), need to -// see zapping() for default values not set within this function {dlb} +// Need to see zapping() for default values not set within this function {dlb} static void _zappy( zap_type z_type, int power, bolt &pbolt ) { int temp_rand = 0; // probability determination {dlb} @@ -1353,7 +1782,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) if (!pbolt.aimed_at_feet) ray.advance_through(pbolt.target()); - // give chance for beam to affect one cell even if aimed_at_feet. + // Give chance for beam to affect one cell even if aimed_at_feet. beamTerminate = false; // setup range @@ -1385,15 +1814,15 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) // See if tx, ty is blocked by something. if (grid_is_solid(grd[tx][ty])) { - // first, check to see if this beam affects walls. + // First, check to see if this beam affects walls. if (_affects_wall(pbolt, grd[tx][ty])) { - // should we ever get a tracer with a wall-affecting + // Should we ever get a tracer with a wall-affecting // beam (possible I suppose), we'll quit tracing now. if (!pbolt.is_tracer) rangeRemaining -= affect(pbolt, tx, ty, item); - // if it's still a wall, quit. + // If it's still a wall, quit. if (grid_is_solid(grd[tx][ty])) break; // breaks from line tracing } @@ -1441,23 +1870,23 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) } // end else - beam doesn't affect walls } // endif - is tx, ty wall? - // at this point, if grd[tx][ty] is still a wall, we + // At this point, if grd[tx][ty] is still a wall, we // couldn't find any path: bouncy, fuzzy, or not - so break. if (grid_is_solid(grd[tx][ty])) break; - // check for "target termination" + // Check for "target termination" // occurs when beam can be targetted at empty // cell (e.g. a mage wants an explosion to happen - // between two monsters) + // between two monsters). - // in this case, don't affect the cell - players and + // In this case, don't affect the cell - players and // monsters have no chance to dodge or block such // a beam, and we want to avoid silly messages. if (tx == pbolt.target_x && ty == pbolt.target_y) beamTerminate = _beam_term_on_target(pbolt, tx, ty); - // affect the cell, except in the special case noted + // Affect the cell, except in the special case noted // above -- affect() will early out if something gets // hit and the beam is type 'term on target'. if (!beamTerminate || !pbolt.is_explosion) @@ -1467,9 +1896,8 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) if (pbolt.flavour == BEAM_RANDOM) { random_beam = true; - pbolt.flavour = - static_cast( - random_range(BEAM_FIRE, BEAM_ACID) ); + pbolt.flavour = static_cast( + random_range(BEAM_FIRE, BEAM_ACID)); } if (!pbolt.affects_nothing) @@ -1482,22 +1910,22 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) } } - // always decrease range by 1 + // Always decrease range by 1. rangeRemaining -= 1; - // check for range termination + // Check for range termination. if (rangeRemaining <= 0) beamTerminate = true; - // special case - beam was aimed at feet + // Special case - beam was aimed at feet. if (pbolt.aimed_at_feet) beamTerminate = true; - // actually draw the beam/missile/whatever, + // Actually draw the beam/missile/whatever, // if the player can see the cell. if (!pbolt.is_tracer && pbolt.name[0] != '0' && see_grid(tx,ty)) { - // we don't clean up the old position. + // We don't clean up the old position. // First, most people like to see the full path, // and second, it is hard to do it right with // respect to killed monsters, cloud trails, etc. @@ -1510,8 +1938,8 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) if (tile_beam == -1) tile_beam = tileidx_bolt(pbolt); - if (tile_beam != -1 && in_los_bounds(drawx, drawy) && - (tx != you.x_pos || ty != you.y_pos)) + if (tile_beam != -1 && in_los_bounds(drawx, drawy) + && (tx != you.x_pos || ty != you.y_pos)) { TileDrawBolt(drawx-1, drawy-1, tile_beam); delay(15); @@ -1554,7 +1982,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) ASSERT(!drop_item || item); - // check for explosion. NOTE that for tracers, we have to make a copy + // Check for explosion. NOTE that for tracers, we have to make a copy // of target co-ords and then reset after calling this -- tracers should // never change any non-tracers fields in the beam structure. -- GDL int ox = pbolt.target_x; @@ -1568,7 +1996,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) pbolt.target_y = oy; } - // canned msg for enchantments that affected no-one, but only if the + // Canned msg for enchantments that affected no-one, but only if the // enchantment is yours. if (pbolt.name[0] == '0') { @@ -1603,7 +2031,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item ) } -// returns damage taken by a monster from a "flavoured" (fire, ice, etc.) +// Returns damage taken by a monster from a "flavoured" (fire, ice, etc.) // attack -- damage from clouds and branded weapons handled elsewhere. int mons_adjust_flavoured( monsters *monster, bolt &pbolt, int hurted, bool doFlavouredEffects ) @@ -2126,7 +2554,8 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) if (monster->add_ench( mon_enchant(ENCH_CONFUSION, 0, _whose_kill(pbolt)) )) { - // put in an exception for things you won't notice becoming confused. + // Put in an exception for things you won't notice becoming + // confused. if (simple_monster_message(monster, " appears confused.")) pbolt.obvious_effect = true; } @@ -2173,8 +2602,8 @@ int mons_ench_f2(monsters *monster, bolt &pbolt) if (monster->add_ench(ENCH_CHARM)) { - // put in an exception for fungi, plants and other things you won't - // notice becoming charmed. + // Put in an exception for fungi, plants and other things + // you won't notice becoming charmed. if (simple_monster_message(monster, " is charmed.")) pbolt.obvious_effect = true; } @@ -2519,11 +2948,12 @@ static bool _beam_term_on_target(bolt &beam, int x, int y) { if (beam.flavour == BEAM_LINE_OF_SIGHT) { - beam.foe_count++; + if (beam.thrower != KILL_YOU_MISSILE) + beam.foe_count++; return (true); } - // generic - all explosion-type beams can be targeted at empty space, + // Generic - all explosion-type beams can be targeted at empty space, // and will explode there. This semantic also means that a creature // in the target cell will have no chance to dodge or block, so we // DON'T affect() the cell if this function returns true! @@ -2553,7 +2983,7 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y ) { ASSERT( item != NULL ); - // conditions: beam is missile and not tracer. + // Conditions: beam is missile and not tracer. if (beam.is_tracer || beam.flavour != BEAM_MISSILE) return; @@ -2565,12 +2995,12 @@ void beam_drop_object( bolt &beam, item_def *item, int x, int y ) { if (item->sub_type == MI_THROWING_NET) { - // player or monster on position is caught in net + // Player or monster on position is caught in net. if (you.x_pos == x && you.y_pos == y && you.attribute[ATTR_HELD] || mgrd[x][y] != NON_MONSTER && mons_is_caught(&menv[mgrd[x][y]])) { - // if no trapping net found mark this one + // If no trapping net found mark this one. if (get_trapping_net(x,y, true) == NON_ITEM) set_item_stationary(*item); } @@ -2593,10 +3023,10 @@ static bool _found_player(const bolt &beam, int x, int y) int affect(bolt &beam, int x, int y, item_def *item) { - // extra range used by hitting something + // Extra range used by hitting something. int rangeUsed = 0; - // line of sight never affects anything + // Line of sight never affects anything. if (beam.flavour == BEAM_LINE_OF_SIGHT) return (0); @@ -2724,7 +3154,7 @@ static bool _affects_wall(const bolt &beam, int wall) return (false); } -// return amount of extra range used up by affectation of this wall. +// Returns amount of extra range used up by affectation of this wall. static int _affect_wall(bolt &beam, int x, int y) { int rangeUsed = 0; @@ -2746,7 +3176,7 @@ static int _affect_wall(bolt &beam, int x, int y) { grd[x][y] = DNGN_FLOOR; - // blood does not transfer onto floor + // Blood does not transfer onto floor. if (is_bloodcovered(x,y)) env.map[x][y].property = FPROP_NONE; @@ -2822,7 +3252,7 @@ static int _affect_wall(bolt &beam, int x, int y) { grd[x][y] = DNGN_FLOOR; - // blood does not transfer onto floor + // Blood does not transfer onto floor. if (is_bloodcovered(x,y)) env.map[x][y].property = FPROP_NONE; @@ -3105,7 +3535,7 @@ static std::string _beam_zapper(const bolt &beam) return menv[beam_src].name(DESC_PLAIN); } -// return amount of extra range used up by affectation of the player +// Returns amount of extra range used up by affectation of the player. static int _affect_player( bolt &beam, item_def *item ) { // digging -- don't care. @@ -3115,8 +3545,10 @@ static int _affect_player( bolt &beam, item_def *item ) // check for tracer if (beam.is_tracer) { - // check can see player - if (beam.can_see_invis || !you.invisible() || _fuzz_invis_tracer(beam)) + // Check whether thrower can see player, unless thrower == player. + if (beam.thrower != KILL_YOU_MISSILE + && (beam.can_see_invis || !you.invisible() + || _fuzz_invis_tracer(beam))) { if (mons_att_wont_attack(beam.attitude)) { @@ -3125,8 +3557,11 @@ static int _affect_player( bolt &beam, item_def *item ) } else { - beam.foe_count++; - beam.foe_power += you.experience_level; + if (beam.thrower != KILL_YOU_MISSILE) + { + beam.foe_count++; + beam.foe_power += you.experience_level; + } } } return (_range_used_on_hit(beam)); @@ -3140,7 +3575,7 @@ static int _affect_player( bolt &beam, item_def *item ) // BEGIN real beam code beam.msg_generated = true; - // use beamHit, NOT beam.hit, for modification of tohit.. geez! + // Use beamHit, NOT beam.hit, for modification of tohit.. geez! int beamHit = beam.hit; // Monsters shooting at an invisible player are very inaccurate. @@ -3156,7 +3591,7 @@ static int _affect_player( bolt &beam, item_def *item ) if (beam.is_beam) { - // beams can be dodged + // Beams can be dodged. if (player_light_armour(true) && !beam.aimed_at_feet && coinflip()) { @@ -3201,7 +3636,7 @@ static int _affect_player( bolt &beam, item_def *item ) return (BEAM_STOP); } - // some training just for the "attempt" + // Some training just for the "attempt". if (coinflip()) exercise( SK_SHIELDS, exer ); } @@ -3447,10 +3882,10 @@ static int _affect_player( bolt &beam, item_def *item ) { beam.fr_hurt++; if (beam.beam_source == NON_MONSTER) - // Beam from player rebounded and hit player + // Beam from player rebounded and hit player. xom_is_stimulated(255); else - // Beam from an ally or neutral + // Beam from an ally or neutral. xom_is_stimulated(128); } else @@ -3468,7 +3903,7 @@ static int _affect_player( bolt &beam, item_def *item ) } } - // regardless of affect, we need to know if this is a stopper + // Regardless of affect, we need to know if this is a stopper // or not - it seems all of the above are. return (_range_used_on_hit(beam)); @@ -3485,7 +3920,7 @@ static int _affect_player( bolt &beam, item_def *item ) int burn_power = (beam.is_explosion) ? 5 : (beam.is_beam) ? 3 : 2; - // Roll the damage + // Roll the damage. hurted += roll_dice( beam.damage ); #if DEBUG_DIAGNOSTICS @@ -3524,8 +3959,8 @@ static int _affect_player( bolt &beam, item_def *item ) if (hurted < 0) hurted = 0; - // if the beam is an actual missile or of the MMISSILE type (Earth magic) - // might bleed on the floor + // If the beam is an actual missile or of the MMISSILE type (Earth magic) + // might bleed on the floor. if (!engulfs && (beam.flavour == BEAM_MISSILE || beam.flavour == BEAM_MMISSILE)) { @@ -3669,7 +4104,7 @@ static int _name_to_skill_level(const std::string& name) static void _update_hurt_or_helped(bolt &beam, monsters *mon) { - if (mons_atts_aligned(beam.attitude, mons_attitude(mon))) + if (!mons_atts_aligned(beam.attitude, mons_attitude(mon))) { if (nasty_beam(mon, beam)) beam.foe_hurt++; @@ -3682,7 +4117,7 @@ static void _update_hurt_or_helped(bolt &beam, monsters *mon) { beam.fr_hurt++; - // Harmful beam from this monster rebounded and hit the monster + // Harmful beam from this monster rebounded and hit the monster. int midx = monster_index(mon); if (midx == beam.beam_source) xom_is_stimulated(128); @@ -3721,7 +4156,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) // check can see other monster if (!beam.can_see_invis && menv[tid].invisible()) { - // can't see this monster, ignore it + // Can't see this monster, ignore it. return 0; } } @@ -3755,16 +4190,36 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) { if (beam.is_tracer) { - // enchant case -- enchantments always hit, so update target immed. - if (mons_atts_aligned(beam.attitude, mons_attitude(mon))) + // Enchant case -- enchantments always hit, so update target immed. + if (!mons_atts_aligned(beam.attitude, mons_attitude(mon))) { - beam.foe_count += 1; - beam.foe_power += mons_power(mons_type); + if (beam.thrower != KILL_YOU_MISSILE) + { + beam.foe_count += 1; + beam.foe_power += mons_power(mons_type); + } } else { - beam.fr_count += 1; - beam.fr_power += mons_power(mons_type); + bool count_friend = true; + if (beam.thrower == KILL_YOU_MISSILE) + { + snprintf(info, INFO_SIZE, "Really fire through %s?", + mon->name(DESC_NOCAP_THE).c_str()); + + if (!yesno(info)) + { + beam.fr_count = 1; + return (BEAM_STOP); + } + else + count_friend = false; + } + if (count_friend) + { + beam.fr_count += 1; + beam.fr_power += mons_power(mons_type); + } } return (_range_used_on_hit(beam)); @@ -3779,8 +4234,8 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) god_conduct_trigger conduct; conduct.enabled = false; - // nasty enchantments will annoy the monster, and are considered - // naughty (even if a monster might resist) + // Nasty enchantments will annoy the monster, and are considered + // naughty (even if a monster might resist). if (nasty_beam(mon, beam)) { if (YOU_KILL( beam.thrower )) @@ -3864,7 +4319,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) if (submerged && !beam.aimed_at_spot) return (0); // missed me! - // we need to know how much the monster _would_ be hurt by this, before + // We need to know how much the monster _would_ be hurt by this, before // we decide if it actually hits. // Roll the damage: @@ -3905,7 +4360,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) const int raw_damage = hurt_final; - // check monster resists, _without_ side effects (since the + // Check monster resists, _without_ side effects (since the // beam/missile might yet miss!) hurt_final = mons_adjust_flavoured( mon, beam, raw_damage, false ); @@ -3922,34 +4377,61 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) // hurt by this beam. if (beam.is_tracer) { - if (hurt_final > 0) + // Check only if actual damage, but always count friends for player. + if (hurt_final > 0 || beam.thrower == KILL_YOU_MISSILE) { - // monster could be hurt somewhat, but only apply the + // Monster could be hurt somewhat, but only apply the // monster's power based on how badly it is affected. // For example, if a fire giant (power 16) threw a // fireball at another fire giant, and it only took // 1/3 damage, then power of 5 would be applied to // foe_power or fr_power. - if (mons_atts_aligned(beam.attitude, mons_attitude(mon))) + if (!mons_atts_aligned(beam.attitude, mons_attitude(mon))) { - beam.foe_count += 1; - beam.foe_power += 2 * hurt_final * mons_power(mons_type) / hurt; + if (beam.thrower != KILL_YOU_MISSILE) + { + // Counting foes is only important for monster tracers. + beam.foe_count += 1; + beam.foe_power += 2 * hurt_final * mons_power(mons_type) + / hurt; + } } else { - beam.fr_count += 1; - beam.fr_power += 2 * hurt_final * mons_power(mons_type) / hurt; + bool count_friend = true; + if (beam.thrower == KILL_YOU_MISSILE) + { + snprintf(info, INFO_SIZE, "Really fire through %s?", + mon->name(DESC_NOCAP_THE).c_str()); + + if (!yesno(info)) + { + beam.fr_count = 1; + return (BEAM_STOP); + } + else + { + // Don't count friends we don't want counted. + count_friend = false; + } + } + if (count_friend) + { + beam.fr_count += 1; + beam.fr_power += 2 * hurt_final * mons_power(mons_type) + / hurt; + } } } - // either way, we could hit this monster, so return range used + // Either way, we could hit this monster, so return range used. return (_range_used_on_hit(beam)); } // END non-enchantment (could still be tracer) // BEGIN real non-enchantment beam - // player beams which hit friendlies or good neutrals will annoy + // Player beams which hit friendlies or good neutrals will annoy // them and be considered naughty if they do damage (this is so as // not to penalize players that fling fireballs into a melee with // fire elementals on their side - the elementals won't give a sh*t, @@ -4010,7 +4492,7 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) // to-hit system (which had very little love for monsters). if (!engulfs && !test_beam_hit(beam_hit, random2(mon->ev))) { - // if the PLAYER cannot see the monster, don't tell them anything! + // If the PLAYER cannot see the monster, don't tell them anything! if (player_monster_visible( &menv[tid] ) && mons_near(mon)) { msg::stream << "The " << beam.name << " misses " @@ -4071,13 +4553,13 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item) monster_caught_in_net(mon, beam); } - // note that hurt_final was calculated above, so we don't need it again. + // Note that hurt_final was calculated above, so we don't need it again. // just need to apply flavoured specials (since we called with - // doFlavouredEffects = false above) + // doFlavouredEffects = false above). hurt_final = mons_adjust_flavoured(mon, beam, raw_damage); - // if the beam is an actual missile or of the MMISSILE type (Earth magic) - // might bleed on the floor + // If the beam is an actual missile or of the MMISSILE type (Earth magic) + // might bleed on the floor. if (!engulfs && (beam.flavour == BEAM_MISSILE || beam.flavour == BEAM_MMISSILE)) { @@ -4444,7 +4926,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon) // extra range used on hit static int _range_used_on_hit(bolt &beam) { - // non-beams can only affect one thing (player/monster) + // Non-beams can only affect one thing (player/monster). if (!beam.is_beam) return (BEAM_STOP); @@ -4479,7 +4961,7 @@ static int _range_used_on_hit(bolt &beam) return (0); } - // hellfire stops for nobody! + // Hellfire stops for nobody! if (beam.name == "hellfire") return (0); @@ -4491,11 +4973,11 @@ static int _range_used_on_hit(bolt &beam) if (beam.flavour == BEAM_ACID) return (BEAM_STOP); - // lava doesn't go far, but it goes through most stuff + // Lava doesn't go far, but it goes through most stuff. if (beam.flavour == BEAM_LAVA) return (1); - // If it isn't lightning, reduce range by a lot + // If it isn't lightning, reduce range by a lot. if (beam.flavour != BEAM_ELECTRICITY) return (random2(4) + 2); @@ -4574,7 +5056,8 @@ static void _explosion1(bolt &pbolt) pbolt.name = "blast of shrapnel"; pbolt.type = dchar_glyph(DCHAR_FIRED_ZAP); - pbolt.flavour = BEAM_FRAG; // sets it from pure damage to shrapnel (which is absorbed extra by armour) + pbolt.flavour = BEAM_FRAG; // Sets it from pure damage to shrapnel + // (which is absorbed extra by armour). } if (pbolt.name == "great blast of cold") @@ -4613,14 +5096,14 @@ static void _explosion1(bolt &pbolt) if (!pbolt.is_tracer && *seeMsg && *hearMsg) { // check for see/hear/no msg - if (see_grid(x,y) || (x == you.x_pos && y == you.y_pos)) + if (see_grid(x,y) || x == you.x_pos && y == you.y_pos) mpr(seeMsg); else { - if (!(silenced(x,y) || silenced(you.x_pos, you.y_pos))) - mpr(hearMsg, MSGCH_SOUND); - else + if (silenced(x,y) || silenced(you.x_pos, you.y_pos)) pbolt.msg_generated = false; + else + mpr(hearMsg, MSGCH_SOUND); } } diff --git a/crawl-ref/source/beam.h b/crawl-ref/source/beam.h index 77c0a9eb99..02fa3c106c 100644 --- a/crawl-ref/source/beam.h +++ b/crawl-ref/source/beam.h @@ -238,7 +238,11 @@ bool check_line_of_sight( int sx, int sy, int tx, int ty ); void mimic_alert( monsters *mimic ); -bool zapping( zap_type ztype, int power, struct bolt &pbolt ); +bool zapping( zap_type ztype, int power, struct bolt &pbolt, + bool needs_tracer = false, std::string msg = "" ); + +bool player_tracer( zap_type ztype, int power, struct bolt &pbolt, + int range = 0 ); int affect(bolt &beam, int x, int y, item_def *item = NULL); diff --git a/crawl-ref/source/decks.cc b/crawl-ref/source/decks.cc index 2c59b1d8da..4231df4bc9 100644 --- a/crawl-ref/source/decks.cc +++ b/crawl-ref/source/decks.cc @@ -1610,7 +1610,7 @@ static bool _damaging_card(card_type card, int power, deck_rarity_type rarity) break; case CARD_PAIN: - if ( power_level == 2 ) + if (power_level == 2) { _mass_drain(power); return true; @@ -1623,7 +1623,7 @@ static bool _damaging_card(card_type card, int power, deck_rarity_type rarity) break; } - if ( spell_direction( target, beam ) ) + if (spell_direction(target, beam) && player_tracer(ztype, power/4, beam)) zapping(ztype, random2(power/4), beam); else rc = false; diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index 0b9dfabf03..f478c5ee9d 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -797,6 +797,7 @@ static bool disc_of_storms(void) beam.target_x = you.x_pos + random2(13) - 6; beam.target_y = you.y_pos + random2(13) - 6; + // non-controlleable zapping( which_zap, 30 + you.skills[SK_EVOCATIONS] * 2, beam ); disc_count--; diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 5150573186..737fefe839 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -1799,7 +1799,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, // even though direction is allowed, we're throwing so we // want to use tx, ty to make the missile fly to map edge. - if ( !teleport ) + if (!teleport) pbolt.set_target(thr); pbolt.flavour = BEAM_MISSILE; @@ -1841,9 +1841,10 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, // get the launcher class,type. Convenience. if (you.equip[EQ_WEAPON] < 0) lnchType = NUM_WEAPONS; - else + else { lnchType = static_cast( you.inv[you.equip[EQ_WEAPON]].sub_type ); + } // baseHit and damage for generic objects baseHit = you.strength - item_mass(item) / 10; @@ -1936,11 +1937,11 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, } } - // lower accuracy if held in a net (needs testing) + // Lower accuracy if held in a net (needs testing). if (you.attribute[ATTR_HELD]) baseHit--; - // for all launched weapons, maximum effective specific skill + // For all launched weapons, maximum effective specific skill // is twice throwing skill. This models the fact that no matter // how 'good' you are with a bow, if you know nothing about // trajectories you're going to be a damn poor bowman. Ditto @@ -1968,10 +1969,10 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, // [dshaligram] This can get large... exDamBonus = lnchDamBonus + random2(1 + ammoDamBonus); - exDamBonus = exDamBonus > 0? random2(exDamBonus + 1) - : -random2(-exDamBonus + 1); - exHitBonus = lnchHitBonus > 0? random2(lnchHitBonus + 1) - : -random2(-lnchHitBonus + 1); + exDamBonus = (exDamBonus > 0 ? random2(exDamBonus + 1) + : -random2(-exDamBonus + 1)); + exHitBonus = (lnchHitBonus > 0 ? random2(lnchHitBonus + 1) + : -random2(-lnchHitBonus + 1)); // Identify ammo type if the information is there. Note // that the bow is always type-identified because it's @@ -1983,7 +1984,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, set_ident_flags(you.inv[throw_2], ISFLAG_KNOW_TYPE); } - // removed 2 random2(2)s from each of the learning curves, but + // Removed 2 random2(2)s from each of the learning curves, but // left slings because they're hard enough to develop without // a good source of shot in the dungeon. switch (launcher_skill) @@ -2000,7 +2001,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, exHitBonus += (effSkill * 3) / 2; - // strength is good if you're using a nice sling. + // Strength is good if you're using a nice sling. int strbonus = (10 * (you.strength - 10)) / 9; strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20; @@ -2009,25 +2010,25 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, strbonus = lnchDamBonus + 1; exDamBonus += strbonus; - // add skill for slings.. helps to find those vulnerable spots + // Add skill for slings... helps to find those vulnerable spots. dice_mult = dice_mult * (14 + random2(1 + effSkill)) / 14; - // now kill the launcher damage bonus + // Now kill the launcher damage bonus. if (lnchDamBonus > 0) lnchDamBonus = 0; break; } - // blowguns take a _very_ steady hand; a lot of the bonus - // comes from dexterity. (Dex bonus here as well as below) + // Blowguns take a _very_ steady hand; a lot of the bonus + // comes from dexterity. (Dex bonus here as well as below). case SK_DARTS: baseHit -= 2; exercise(SK_DARTS, (coinflip()? 2 : 1)); exHitBonus += (effSkill * 3) / 2 + you.dex / 2; - // no extra damage for blowguns + // No extra damage for blowguns. // exDamBonus = 0; - // now kill the launcher damage and ammo bonuses + // Now kill the launcher damage and ammo bonuses. if (lnchDamBonus > 0) lnchDamBonus = 0; if (ammoDamBonus > 0) @@ -2040,23 +2041,23 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, exercise(SK_BOWS, (coinflip()? 2 : 1)); exHitBonus += (effSkill * 2); - // strength is good if you're using a nice bow + // Strength is good if you're using a nice bow. int strbonus = (10 * (you.strength - 10)) / 4; strbonus = (strbonus * (2 * baseDam + ammoDamBonus)) / 20; - // cap; reduced this cap, because we don't want to allow + // Cap; reduced this cap, because we don't want to allow // the extremely-strong to quadruple the enchantment bonus. if (strbonus > lnchDamBonus + 1) strbonus = lnchDamBonus + 1; exDamBonus += strbonus; - // add in skill for bows.. help you to find those vulnerable spots. + // Add in skill for bows - helps you to find those vulnerable spots. // exDamBonus += effSkill; dice_mult = dice_mult * (17 + random2(1 + effSkill)) / 17; - // now kill the launcher damage bonus + // Now kill the launcher damage bonus. if (lnchDamBonus > 0) lnchDamBonus = 0; break; @@ -2082,7 +2083,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, break; } - // Slings and Darts train Throwing a bit + // Slings and Darts train Throwing a bit. if (launcher_skill == SK_SLINGS || launcher_skill == SK_DARTS) { if (coinflip()) @@ -2101,11 +2102,11 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, dice_mult = dice_mult * 130 / 100; } - // special cases for flame, frost, poison, etc. - // check for venom brand (usually only available for blowguns) + // Special cases for flame, frost, poison, etc. + // check for venom brand. if (bow_brand == SPWPN_VENOM && ammo_brand == SPMSL_NORMAL) { - // poison brand the ammo + // Poison brand the ammo. set_item_ego_type( item, OBJ_MISSILES, SPMSL_POISONED ); pbolt.name = item.name(DESC_PLAIN); } @@ -2128,7 +2129,6 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, pbolt.type = dchar_glyph(DCHAR_FIRED_BOLT); pbolt.thrower = KILL_YOU_MISSILE; pbolt.aux_source.clear(); - } if ((bow_brand == SPWPN_FROST || ammo_brand == SPMSL_ICE) @@ -2150,20 +2150,20 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, pbolt.aux_source.clear(); } - /* the chief advantage here is the extra damage this does - * against susceptible creatures */ + // The chief advantage here is the extra damage this does + // against susceptible creatures. - /* Note: weapons & ammo of eg fire are not cumulative - * ammo of fire and weapons of frost don't work together, - * and vice versa */ + // Note: weapons & ammo of eg fire are not cumulative + // ammo of fire and weapons of frost don't work together, + // and vice versa. // ID check. Can't ID off teleported projectiles, uh, because // it's too weird. Also it messes up the messages. if (item_ident(you.inv[you.equip[EQ_WEAPON]], ISFLAG_KNOW_PLUSES)) { - if ( !teleport - && !item_ident(you.inv[throw_2], ISFLAG_KNOW_PLUSES) - && random2(100) < shoot_skill ) + if (!teleport + && !item_ident(you.inv[throw_2], ISFLAG_KNOW_PLUSES) + && random2(100) < shoot_skill) { set_ident_flags( item, ISFLAG_KNOW_PLUSES ); set_ident_flags( you.inv[throw_2], ISFLAG_KNOW_PLUSES ); @@ -2195,28 +2195,28 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, baseHit = 0; - // missiles only use inv_plus + // Missiles only use inv_plus. if (wepClass == OBJ_MISSILES) ammoDamBonus = ammoHitBonus; - // all weapons that use 'throwing' go here.. + // All weapons that use 'throwing' go here. if (wepClass == OBJ_WEAPONS || (wepClass == OBJ_MISSILES && (wepType == MI_STONE || wepType == MI_LARGE_ROCK || wepType == MI_DART || wepType == MI_JAVELIN))) { - // elves with elven weapons + // Elves with elven weapons. if (get_equip_race(item) == ISFLAG_ELVEN && player_genus(GENPC_ELVEN)) { baseHit += 1; } - // give an appropriate 'tohit' - - // hand axes and clubs are -5 - // daggers are +1 - // spears are -1 - // rocks are 0 + // Give an appropriate 'tohit': + // * hand axes and clubs are -5 + // * daggers are +1 + // * spears are -1 + // * rocks are 0 if (wepClass == OBJ_WEAPONS) { switch (wepType) @@ -2251,11 +2251,11 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, baseDam = property( item, PWPN_DAMAGE ); - // dwarves/orcs with dwarven/orcish weapons - if ( (get_equip_race(item) == ISFLAG_DWARVEN - && player_genus(GENPC_DWARVEN)) || - (get_equip_race(item) == ISFLAG_ORCISH - && you.species == SP_HILL_ORC)) + // Dwarves/orcs with dwarven/orcish weapons. + if (get_equip_race(item) == ISFLAG_DWARVEN + && player_genus(GENPC_DWARVEN) + || get_equip_race(item) == ISFLAG_ORCISH + && you.species == SP_HILL_ORC) { baseDam += 1; } @@ -2263,7 +2263,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, exDamBonus = (10 * (you.skills[SK_THROWING] / 2 + you.strength - 10)) / 12; - // now, exDamBonus is a multiplier. The full multiplier + // Now, exDamBonus is a multiplier. The full multiplier // is applied to base damage, but only a third is applied // to the magical modifier. exDamBonus = (exDamBonus * (3 * baseDam + ammoDamBonus)) / 30; @@ -2302,19 +2302,18 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, exercise(SK_THROWING, 1 + coinflip()); break; case MI_THROWING_NET: - // Nets use throwing skill - // They don't do any damage! + // Nets use throwing skill. They don't do any damage! baseDam = 0; exDamBonus = 0; ammoDamBonus = 0; - // but accuracy is important for this one + // ... but accuracy is important for this one. baseHit = 1; exHitBonus += (skill_bump(SK_THROWING) * 7 / 2); // Adjust for strength and dex. exHitBonus = dex_adjust_thrown_tohit(exHitBonus); - // Nets train throwing + // Nets train throwing. exercise(SK_THROWING, 1); break; } @@ -2334,9 +2333,9 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, exercise(SK_THROWING, 1); // ID check - if ( !teleport - && !item_ident(you.inv[throw_2], ISFLAG_KNOW_PLUSES) - && random2(100) < you.skills[SK_THROWING] ) + if (!teleport + && !item_ident(you.inv[throw_2], ISFLAG_KNOW_PLUSES) + && random2(100) < you.skills[SK_THROWING]) { set_ident_flags( item, ISFLAG_KNOW_PLUSES ); set_ident_flags( you.inv[throw_2], ISFLAG_KNOW_PLUSES ); @@ -2346,7 +2345,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, } } - // range, dexterity bonus, possible skill increase for silly throwing + // Range, dexterity bonus, possible skill increase for silly throwing. if (projected) { if (wepType == MI_LARGE_ROCK) @@ -2427,14 +2426,14 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, pbolt.damage.size = dice_mult * pbolt.damage.size / 100; pbolt.damage.size += slayDam; - // only add bonuses if we're throwing something sensible + // Only add bonuses if we're throwing something sensible. if (projected || wepClass == OBJ_WEAPONS) { pbolt.hit += ammoHitBonus + lnchHitBonus; pbolt.damage.size += ammoDamBonus + lnchDamBonus; } - // Add in bonus (only from Portal Projectile for now) + // Add in bonus (only from Portal Projectile for now). if (acc_bonus != DEBUG_COOKIE) pbolt.hit += acc_bonus; @@ -2448,17 +2447,17 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, pbolt.hit, pbolt.damage.num, pbolt.damage.size ); #endif - // create message + // Create message. mprf( "You %s%s %s.", projected? "" : "awkwardly ", projected == LRET_LAUNCHED ? "shoot" : "throw", item.name(DESC_NOCAP_A).c_str() ); - // ensure we're firing a 'missile'-type beam + // Ensure we're firing a 'missile'-type beam. pbolt.is_beam = false; pbolt.is_tracer = false; - // mark this item as thrown if it's a missile, so that we'll pick it up + // Mark this item as thrown if it's a missile, so that we'll pick it up // when we walk over it. if (wepClass == OBJ_MISSILES || wepClass == OBJ_WEAPONS) item.flags |= ISFLAG_THROWN; @@ -2484,9 +2483,9 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, } } - if ( did_return ) + if (did_return) { - // Fire beam in reverse + // Fire beam in reverse. pbolt.setup_retrace(); viewwindow(true, false); fire_beam(pbolt, &item, false); @@ -2494,25 +2493,26 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, msg::stream << item.name(DESC_CAP_THE) << " returns to your pack!" << std::endl; - // Player saw the item return + // Player saw the item return. if (!is_artefact(you.inv[throw_2])) set_ident_flags(you.inv[throw_2], ISFLAG_KNOW_TYPE); } else { - // should have returned but didn't + // Should have returned but didn't. if (returning && item_type_known(you.inv[throw_2])) + { msg::stream << item.name(DESC_CAP_THE) << " fails to return to your pack!" << std::endl; - + } dec_inv_item_quantity( throw_2, 1 ); } - // throwing and blowguns are silent + // Throwing and blowguns are silent if (projected == LRET_LAUNCHED && lnchType != WPN_BLOWGUN) noisy( 6, you.x_pos, you.y_pos ); - // but any monster nearby can see that something has been thrown: + // ... but any monster nearby can see that something has been thrown: alert_nearby_monsters(); you.turn_is_over = true; @@ -3355,10 +3355,12 @@ void zap_wand( int slot ) zap_wand.ty = you.y_pos + random2(13) - 6; } - const zap_type type_zapped = static_cast(wand.zap()); + zap_type type_zapped = static_cast(wand.zap()); + bool random = false; if (wand.sub_type == WAND_RANDOM_EFFECTS) { beam.effect_known = false; + random = true; if (dangerous) { // Xom loves it when you use a Wand of Random Effects and @@ -3371,13 +3373,18 @@ void zap_wand( int slot ) beam.source_y = you.y_pos; beam.set_target(zap_wand); - // zapping() updates beam - if (!zapping( static_cast(type_zapped), - 30 + roll_dice(2, you.skills[SK_EVOCATIONS]), beam )) + // Check whether we may hit friends, use "safe" values for random effects + // (highest possible range, and unresistable beam flavour). + if (!player_tracer(random ? ZAP_DEBUGGING_RAY : type_zapped, + 2 * (you.skills[SK_EVOCATIONS] - 1), beam, + random ? 17 : 0)) { return; } + // zapping() updates beam + zapping( type_zapped, 30 + roll_dice(2, you.skills[SK_EVOCATIONS]), beam ); + // take off a charge wand.plus--; diff --git a/crawl-ref/source/itemprop.cc b/crawl-ref/source/itemprop.cc index c8004d4424..eb37710c5c 100644 --- a/crawl-ref/source/itemprop.cc +++ b/crawl-ref/source/itemprop.cc @@ -42,7 +42,7 @@ #include "xom.h" -// XXX: name strings in most of the following are currently unused! +// XXX: Name strings in most of the following are currently unused! struct armour_def { armour_type id; @@ -139,7 +139,7 @@ static armour_def Armour_prop[NUM_ARMOURS] = { ARM_BOOTS, "boots", 1, 0, 30, true, EQ_BOOTS, SIZE_SMALL, SIZE_MEDIUM }, // Changed max. barding size to large to allow for the appropriate - // monsters that don't differentiate between torso and general. + // monster types (monsters don't differentiate between torso and general). { ARM_CENTAUR_BARDING, "centaur barding", 4, -2, 100, true, EQ_BOOTS, SIZE_MEDIUM, SIZE_LARGE }, { ARM_NAGA_BARDING, "naga barding", 4, -2, 100, @@ -397,7 +397,7 @@ struct food_def // NOTE: Any food with special random messages or side effects // currently only takes one turn to eat (except ghouls and chunks)... -// if this changes then those items will have to have special code +// If this changes then those items will have to have special code // (like ghoul chunks) to guarantee that the special thing is only // done once. See the ghoul eating code over in food.cc. static int Food_index[NUM_FOODS]; @@ -433,7 +433,7 @@ static food_def Food_prop[NUM_FOODS] = // be accessed correctly. void init_properties() { - // compare with enum comments, to catch changes + // Compare with enum comments, to catch changes. COMPILE_CHECK(NUM_ARMOURS == 37, c1); COMPILE_CHECK(NUM_WEAPONS == 55, c2); COMPILE_CHECK(NUM_MISSILES == 9, c3); @@ -591,11 +591,11 @@ void unset_ident_flags( item_def &item, unsigned long flags ) } // Returns the mask of interesting identify bits for this item -// (e.g., scrolls don't have know-cursedness.) +// (e.g., scrolls don't have know-cursedness). unsigned long full_ident_mask( const item_def& item ) { unsigned long flagset = ISFLAG_IDENT_MASK; - switch ( item.base_type ) + switch (item.base_type) { case OBJ_FOOD: case OBJ_CORPSES: @@ -636,10 +636,9 @@ unsigned long full_ident_mask( const item_def& item ) if (item_type_known(item)) flagset &= (~ISFLAG_KNOW_TYPE); - if ( is_artefact(item) ) - { + if (is_artefact(item)) flagset |= ISFLAG_KNOW_PROPERTIES; - } + return flagset; } @@ -989,7 +988,7 @@ bool hide2armour( item_def &item ) return (true); } // end hide2armour() -// Return the enchantment limit of a piece of armour +// Return the enchantment limit of a piece of armour. int armour_max_enchant( const item_def &item ) { ASSERT( item.base_type == OBJ_ARMOUR ); @@ -1003,7 +1002,7 @@ int armour_max_enchant( const item_def &item ) return (max_plus); } -// doesn't include animal skin (only skins we can make and enchant) +// Doesn't include animal skin (only skins we can make and enchant). bool armour_is_hide( const item_def &item, bool inc_made ) { ASSERT( item.base_type == OBJ_ARMOUR ); @@ -1037,7 +1036,7 @@ bool armour_is_hide( const item_def &item, bool inc_made ) return (false); } -// used to distinguish shiny and embroidered +// Used to distinguish shiny and embroidered. bool armour_not_shiny( const item_def &item ) { ASSERT( item.base_type == OBJ_ARMOUR ); @@ -1127,7 +1126,7 @@ bool base_armour_is_light( const item_def &item ) return (Armour_prop[ Armour_index[item.sub_type] ].light); } -// returns number of sizes off +// Returns number of sizes off (0 if fitting). int fit_armour_size( const item_def &item, size_type size ) { ASSERT( item.base_type == OBJ_ARMOUR ); @@ -1143,7 +1142,7 @@ int fit_armour_size( const item_def &item, size_type size ) return (0); } -// returns true if armour fits size (shape needs additional verification) +// Returns true if armour fits size (shape needs additional verification). bool check_armour_size( const item_def &item, size_type size ) { ASSERT( item.base_type == OBJ_ARMOUR ); @@ -1258,7 +1257,7 @@ bool check_armour_shape( const item_def &item, bool quiet ) break; case EQ_BODY_ARMOUR: - // Cannot swim in heavy armour + // Cannot swim in heavy armour. if (player_is_swimming() && !is_light_armour( item )) { if (!quiet) @@ -1314,7 +1313,7 @@ bool check_armour_shape( const item_def &item, bool quiet ) return (true); } -// if known is true, only returns true for *known* weapons of electrocution +// If known is true, only returns true for *known* weapons of electrocution. bool item_is_rechargable(const item_def &it, bool known) { // These are obvious @@ -1323,9 +1322,9 @@ bool item_is_rechargable(const item_def &it, bool known) // ... but electro-weapons can also be charged return ( it.base_type == OBJ_WEAPONS - && !is_random_artefact( it ) - && !is_fixed_artefact( it ) - && get_weapon_brand( it ) == SPWPN_ELECTROCUTION + && !is_random_artefact(it) + && !is_fixed_artefact(it) + && get_weapon_brand(it) == SPWPN_ELECTROCUTION && (!known || item_type_known(it)) ); } @@ -1338,19 +1337,19 @@ bool is_enchantable_weapon(const item_def &wpn, bool uncurse) // if (!item_is_equipped(wpn)) // return (false); - // artefacts cannot be enchanted (missiles can't be artefacts) + // Artefacts cannot be enchanted (missiles can't be artefacts). if (wpn.base_type == OBJ_WEAPONS - && (is_fixed_artefact( wpn ) - || is_random_artefact( wpn ))) + && (is_fixed_artefact(wpn) + || is_random_artefact(wpn))) { return (uncurse && item_cursed( wpn )); // ?EW may uncurse artefacts } // Nor can highly enchanted items (missiles only have one stat) - if ( wpn.plus >= 9 - || wpn.base_type == OBJ_WEAPONS && wpn.plus2 >= 9 ) + if (wpn.plus >= 9 + || wpn.base_type == OBJ_WEAPONS && wpn.plus2 >= 9) { - return (uncurse && item_cursed( wpn )); // ?EW may uncurse items + return (uncurse && item_cursed( wpn )); // ?EW may uncurse items. } return (true); @@ -1361,23 +1360,19 @@ bool is_enchantable_armour(const item_def &arm, bool uncurse) if (arm.base_type != OBJ_ARMOUR) return (false); - // only equipped items should be affected -// if (!item_is_equipped(arm)) -// return (false); - - // artefacts cannot be enchanted - if (is_fixed_artefact( arm ) - || is_random_artefact( arm )) + // Artefacts cannot be enchanted. + if (is_fixed_artefact(arm) + || is_random_artefact(arm)) { - return (uncurse && item_cursed( arm )); // ?EA may uncurse artefacts + return (uncurse && item_cursed(arm)); // ?EA may uncurse artefacts. } - // Nor can highly enchanted items - if ( arm.plus >= 2 - && (arm.sub_type >= ARM_CLOAK && arm.sub_type <= ARM_BOOTS - || is_shield(arm)) ) + // Nor can highly enchanted items. + if (arm.plus >= 2 + && (arm.sub_type >= ARM_CLOAK && arm.sub_type <= ARM_BOOTS + || is_shield(arm))) { - return (uncurse && item_cursed( arm )); // ?EA may uncurse items + return (uncurse && item_cursed(arm)); // ?EA may uncurse items. } return (true); @@ -1468,7 +1463,7 @@ int weapon_rarity( int w_type ) case WPN_BLESSED_DOUBLE_SWORD: case WPN_BLESSED_GREAT_SWORD: case WPN_BLESSED_TRIPLE_SWORD: - // zero value weapons must be placed specially -- see make_item() {dlb} + // Zero value weapons must be placed specially -- see make_item() {dlb} return (0); default: @@ -1476,7 +1471,7 @@ int weapon_rarity( int w_type ) } return (0); -} // end rare_weapon() +} int get_vorpal_type( const item_def &item ) { @@ -1486,7 +1481,7 @@ int get_vorpal_type( const item_def &item ) ret = (Weapon_prop[ Weapon_index[item.sub_type] ].dam_type & DAMV_MASK); return (ret); -} // end vorpal_type() +} int get_damage_type( const item_def &item ) { @@ -1496,12 +1491,12 @@ int get_damage_type( const item_def &item ) ret = (Weapon_prop[ Weapon_index[item.sub_type] ].dam_type & DAM_MASK); return (ret); -} // end damage_type() +} bool does_damage_type( const item_def &item, int dam_type ) { return (get_damage_type( item ) & dam_type); -} // end does_damage_type() +} hands_reqd_type hands_reqd(object_class_type base_type, int sub_type, @@ -1513,7 +1508,7 @@ hands_reqd_type hands_reqd(object_class_type base_type, int sub_type, return hands_reqd(item, size); } -// give hands required to wield weapon for a torso of "size" +// Give hands required to wield weapon for a torso of "size". hands_reqd_type hands_reqd( const item_def &item, size_type size ) { int ret = HANDS_ONE; @@ -1541,14 +1536,14 @@ hands_reqd_type hands_reqd( const item_def &item, size_type size ) ret = Weapon_prop[ Weapon_index[item.sub_type] ].hands; - // size is the level where we can use one hand for one end + // Size is the level where we can use one hand for one end. if (ret == HANDS_DOUBLE) { doub = true; - ret = HANDS_TWO; // HANDS_HALF once double-ended is implemented + ret = HANDS_TWO; // HANDS_HALF once double-ended is implemented. } - // adjust handedness for size only for non-whip melee weapons + // Adjust handedness for size only for non-whip melee weapons. if (!is_range_weapon( item ) && item.sub_type != WPN_WHIP && item.sub_type != WPN_DEMON_WHIP) @@ -1775,7 +1770,7 @@ int weapon_str_required( const item_def &wpn, bool hand_half ) return ((req < STR_REQ_THRESHOLD) ? 0 : req); } -// returns melee skill of item +// Returns melee skill of item. skill_type weapon_skill( const item_def &item ) { if (item.base_type == OBJ_WEAPONS && !is_range_weapon( item )) @@ -1783,11 +1778,11 @@ skill_type weapon_skill( const item_def &item ) else if (item.base_type == OBJ_STAVES) return (SK_STAVES); - // this is used to mark that only fighting applies. + // This is used to mark that only fighting applies. return (SK_FIGHTING); } -// front function for the above when we don't have a physical item to check +// Front function for the above when we don't have a physical item to check. skill_type weapon_skill( object_class_type wclass, int wtype ) { item_def wpn; @@ -1796,9 +1791,9 @@ skill_type weapon_skill( object_class_type wclass, int wtype ) wpn.sub_type = wtype; return (weapon_skill( wpn )); -} // end weapon_skill() +} -// returns range skill of the item +// Returns range skill of the item. skill_type range_skill( const item_def &item ) { if (item.base_type == OBJ_WEAPONS && is_range_weapon( item )) @@ -1816,7 +1811,7 @@ skill_type range_skill( const item_def &item ) return (SK_THROWING); } -// front function for the above when we don't have a physical item to check +// Front function for the above when we don't have a physical item to check. skill_type range_skill( object_class_type wclass, int wtype ) { item_def wpn; @@ -1825,7 +1820,7 @@ skill_type range_skill( object_class_type wclass, int wtype ) wpn.sub_type = wtype; return (range_skill( wpn )); -} // end weapon_skill() +} // Calculate the bonus to melee EV for using "wpn", with "skill" and "dex" @@ -1837,20 +1832,20 @@ int weapon_ev_bonus( const item_def &wpn, int skill, size_type body, int dex, int ret = 0; - // Note: ret currently measured in halves (see skill factor) + // Note: ret currently measured in halves (see skill factor). if (wpn.sub_type == WPN_WHIP || wpn.sub_type == WPN_DEMON_WHIP) ret = 3 + (dex / 5); else if (weapon_skill( wpn ) == SK_POLEARMS) ret = 2 + (dex / 5); - // weapons of reaching are naturally a bit longer/flexier + // Weapons of reaching are naturally a bit longer/flexier. if (!hide_hidden || item_type_known( wpn )) { if (get_weapon_brand( wpn ) == SPWPN_REACHING) ret += 1; } - // only consider additional modifications if we have a positive base: + // Only consider additional modifications if we have a positive base: if (ret > 0) { // Size factors: @@ -1864,12 +1859,12 @@ int weapon_ev_bonus( const item_def &wpn, int skill, size_type body, int dex, // apply skill (and dividing by 2) ret = (ret * (skill + 10)) / 20; - // make sure things can't get too insane + // Make sure things can't get too insane. if (ret > 8) ret = 8 + (ret - 8) / 2; } - // Note: this is always a bonus + // Note: this is always a bonus. return ((ret > 0) ? ret : 0); } @@ -1883,7 +1878,7 @@ static size_type weapon_size( const item_def &item ) return (Weapon_prop[ Weapon_index[item.sub_type] ].fit_size); } -// returns number of sizes off +// Returns number of sizes off. int cmp_weapon_size( const item_def &item, size_type size ) { ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); @@ -1891,14 +1886,15 @@ int cmp_weapon_size( const item_def &item, size_type size ) return (weapon_size( item ) - size); } -// Returns number of sizes away from being a usable weapon +// Returns number of sizes away from being a usable weapon. int fit_weapon_wieldable_size( const item_def &item, size_type size ) { ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); const int fit = cmp_weapon_size( item, size ); - return ((fit < -2) ? fit + 2 : (fit > 1) ? fit - 1 : 0); + return ((fit < -2) ? fit + 2 : + (fit > 1) ? fit - 1 : 0); } // Returns number of sizes away from being throwable... the window @@ -1907,11 +1903,13 @@ int fit_item_throwable_size( const item_def &item, size_type size ) { int ret = item_size( item ) - size; - return ((ret >= 0) ? ret + 1 : (ret > -6) ? 0 : ret + 5); + return ((ret >= 0) ? ret + 1 : + (ret > -6) ? 0 + : ret + 5); } -// Returns true if weapon is usable as a tool -// Note that we assume that tool usable >= wieldable +// Returns true if weapon is usable as a tool. +// Note that we assume that tool usable >= wieldable. bool check_weapon_tool_size( const item_def &item, size_type size ) { ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); @@ -1925,7 +1923,7 @@ bool check_weapon_tool_size( const item_def &item, size_type size ) return (fit >= -3 && fit <= 1); } -// Returns true if weapon is usable as a weapon +// Returns true if weapon is usable as a weapon. bool check_weapon_wieldable_size( const item_def &item, size_type size ) { ASSERT( item.base_type == OBJ_WEAPONS || item.base_type == OBJ_STAVES ); @@ -1969,7 +1967,7 @@ bool check_weapon_shape( const item_def &item, bool quiet, bool check_id ) return (true); } -// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield) +// Returns the you.inv[] index of our wielded weapon or -1 (no item, not wield). int get_inv_wielded( void ) { return (player_weapon_wielded() ? you.equip[EQ_WEAPON] : -1); @@ -2035,9 +2033,9 @@ bool is_range_weapon( const item_def &item ) return (fires_ammo_type( item ) != MI_NONE); } -// decide if something is launched or thrown +// Decide if something is launched or thrown. launch_retval is_launched(actor *actor, const item_def *launcher, - const item_def &missile) + const item_def &missile) { if (missile.base_type == OBJ_MISSILES && launcher @@ -2072,7 +2070,7 @@ const char *ammo_name( const item_def &bow ) return ammo_name(fires_ammo_type( bow )); } -// returns true if item has an associated launcher +// Returns true if item has an associated launcher. bool has_launcher( const item_def &ammo ) { ASSERT(ammo.base_type == OBJ_MISSILES); @@ -2081,7 +2079,7 @@ bool has_launcher( const item_def &ammo ) && ammo.sub_type != MI_THROWING_NET); } -// returns true if item can be reasonably thrown without a launcher +// Returns true if item can be reasonably thrown without a launcher. bool is_throwable( const item_def &wpn, size_type bodysize ) { if (wpn.base_type == OBJ_WEAPONS) @@ -2168,14 +2166,14 @@ bool is_blood_potion( const item_def &item) || item.sub_type == POT_BLOOD_COAGULATED); } -// returns food value for one turn of eating +// Returns food value for one turn of eating. int food_value( const item_def &item ) { ASSERT( is_valid_item( item ) && item.base_type == OBJ_FOOD ); const int herb = player_mutation_level(MUT_HERBIVOROUS); - // XXX: this needs to be better merged with the mutation system + // XXX: This needs to be better merged with the mutation system. const int carn = player_mutation_level(MUT_CARNIVOROUS); const food_def &food = Food_prop[ Food_index[item.sub_type] ]; @@ -2202,13 +2200,13 @@ bool can_cut_meat( const item_def &item ) bool food_is_rotten( const item_def &item ) { - return (item.special < 100) && ((item.base_type == OBJ_CORPSES && - item.sub_type == CORPSE_BODY) || - (item.base_type == OBJ_FOOD && - item.sub_type == FOOD_CHUNK)); + return (item.special < 100) && (item.base_type == OBJ_CORPSES + && item.sub_type == CORPSE_BODY + || item.base_type == OBJ_FOOD + && item.sub_type == FOOD_CHUNK); } -// returns true if item counts as a tool for tool size comparisons and msgs +// Returns true if item counts as a tool for tool size comparisons and msgs. bool is_tool( const item_def &item ) { // Currently using OBJ_WEAPONS instead of can_cut_meat() as almost @@ -2462,7 +2460,7 @@ int item_mass( const item_def &item ) { const int reduc = (unit_mass >= 25) ? unit_mass / 5 : 5; - // truncate to the nearest 5 and reduce the item mass: + // Truncate to the nearest 5 and reduce the item mass: unit_mass -= ((reduc / 5) * 5); unit_mass = MAXIMUM( unit_mass, 5 ); } @@ -2549,7 +2547,7 @@ int item_mass( const item_def &item ) return ((unit_mass > 0) ? unit_mass : 0); } -// Note that this function, an item sizes in general aren't quite on the +// Note that this function, and item sizes in general aren't quite on the // same scale as PCs and monsters. size_type item_size( const item_def &item ) { @@ -2617,7 +2615,7 @@ size_type item_size( const item_def &item ) return (static_cast( size )); } -// returns true if we might be interested in dumping the colour +// Returns true if we might be interested in dumping the colour. bool is_colourful_item( const item_def &item ) { bool ret = false; diff --git a/crawl-ref/source/items.cc b/crawl-ref/source/items.cc index 7652cff35d..f1f2915a0a 100644 --- a/crawl-ref/source/items.cc +++ b/crawl-ref/source/items.cc @@ -2492,7 +2492,7 @@ bool item_def::launched_by(const item_def &launcher) const int item_def::zap() const { if (base_type != OBJ_WANDS) - return ZAP_DEBUGGING_RAY; + return (ZAP_DEBUGGING_RAY); zap_type result; switch (sub_type) @@ -2503,9 +2503,9 @@ int item_def::zap() const case WAND_RANDOM_EFFECTS: result = static_cast(random2(16)); - if ( one_chance_in(20) ) + if (one_chance_in(20)) result = ZAP_NEGATIVE_ENERGY; - if ( one_chance_in(17) ) + if (one_chance_in(17)) result = ZAP_ENSLAVEMENT; break; @@ -2513,7 +2513,7 @@ int item_def::zap() const result = static_cast(sub_type); break; } - return result; + return (result); } int item_def::index() const diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index c96fcbb0a1..4f65770fa1 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -1613,11 +1613,11 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, } } - // Assumed visible from now on + // Assumed visible from now on. // Various special cases: // non-gold mimics, dancing weapons, ghosts, Pan demons - if ( mons_is_mimic(mon.type) && mon.type != MONS_GOLD_MIMIC ) + if (mons_is_mimic(mon.type) && mon.type != MONS_GOLD_MIMIC) { item_def item; get_mimic_item( &mon, item ); @@ -1645,17 +1645,17 @@ static std::string _str_monam(const monsters& mon, description_level_type desc, // Start with the prefix. // (Uniques don't get this, because their names are proper nouns.) - if ( !mons_is_unique(mon.type) ) + if (!mons_is_unique(mon.type)) { switch (desc) { case DESC_CAP_THE: - (mons_friendly(&mon)) ? result = "Your " - : result = "The "; + result = (mons_friendly(&mon) ? "Your " + : "The "); break; case DESC_NOCAP_THE: - (mons_friendly(&mon)) ? result = "your " - : result = "the "; + result = (mons_friendly(&mon) ? "your " + : "the "); break; case DESC_CAP_A: result = "A "; @@ -4022,6 +4022,7 @@ std::string monsters::name(description_level_type desc, bool force_vis) const desc = DESC_NOCAP_THE; std::string monnam = _str_monam(*this, desc, force_vis); + return (possessive? apostrophise(monnam) : monnam); } diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index e7760c8972..b8f3ce1b1d 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -2542,10 +2542,10 @@ int player_see_invis(bool calc_unid) if (artefacts > 0) si += artefacts; - if ( si > 1 ) + if (si > 1) si = 1; - return si; + return (si); } // This does NOT do line of sight! It checks the monster's visibility diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc index 309023e596..5ba787ae61 100644 --- a/crawl-ref/source/spells1.cc +++ b/crawl-ref/source/spells1.cc @@ -238,29 +238,31 @@ void random_blink(bool allow_partial_control, bool override_abyss) return; } // end random_blink() -int fireball(int power, bolt &beam) +bool fireball(int power, bolt &beam) { - zapping(ZAP_FIREBALL, power, beam); - return (1); + if (!zapping(ZAP_FIREBALL, power, beam, true)) + return (false); + + return (true); } // end fireball() int cast_fire_storm(int powc, bolt &beam) { - beam.ex_size = 2 + (random2(powc) > 75); - beam.flavour = BEAM_LAVA; - beam.type = dchar_glyph(DCHAR_FIRED_ZAP); - beam.colour = RED; - beam.beam_source = MHITYOU; - beam.thrower = KILL_YOU_MISSILE; + beam.name = "great blast of fire"; + beam.ex_size = 2 + (random2(powc) > 75); + beam.flavour = BEAM_LAVA; + beam.type = dchar_glyph(DCHAR_FIRED_ZAP); + beam.colour = RED; + beam.beam_source = MHITYOU; + beam.thrower = KILL_YOU_MISSILE; beam.aux_source.clear(); beam.obvious_effect = false; - beam.is_beam = false; - beam.is_tracer = false; + beam.is_beam = false; + beam.is_tracer = false; beam.is_explosion = true; - beam.ench_power = powc; // used for radius - beam.name = "great blast of fire"; - beam.hit = 20 + powc / 10; - beam.damage = calc_dice( 9, 20 + powc ); + beam.ench_power = powc; // used for radius + beam.hit = 20 + powc / 10; + beam.damage = calc_dice( 9, 20 + powc ); explosion( beam, false, false, true, true, false ); mpr("A raging storm of fire appears!"); @@ -276,19 +278,19 @@ void cast_chain_lightning( int powc ) struct bolt beam; // initialize beam structure - beam.name = "lightning arc"; - beam.aux_source = "chain lightning"; - beam.beam_source = MHITYOU; - beam.thrower = KILL_YOU_MISSILE; - beam.range = 8; - beam.rangeMax = 8; - beam.hit = AUTOMATIC_HIT; - beam.type = dchar_glyph(DCHAR_FIRED_ZAP); - beam.flavour = BEAM_ELECTRICITY; + beam.name = "lightning arc"; + beam.aux_source = "chain lightning"; + beam.beam_source = MHITYOU; + beam.thrower = KILL_YOU_MISSILE; + beam.range = 8; + beam.rangeMax = 8; + beam.hit = AUTOMATIC_HIT; + beam.type = dchar_glyph(DCHAR_FIRED_ZAP); + beam.flavour = BEAM_ELECTRICITY; beam.obvious_effect = true; - beam.is_beam = false; // since we want to stop at our target - beam.is_explosion = false; - beam.is_tracer = false; + beam.is_beam = false; // since we want to stop at our target + beam.is_explosion = false; + beam.is_tracer = false; int sx, sy; int tx, ty; diff --git a/crawl-ref/source/spells1.h b/crawl-ref/source/spells1.h index 7e88df47fa..0fe8e171cd 100644 --- a/crawl-ref/source/spells1.h +++ b/crawl-ref/source/spells1.h @@ -91,7 +91,7 @@ void cast_berserk(void); void cast_ring_of_flames(int power); bool conjure_flame(int pow); void extension(int pow); -int fireball(int power, bolt &beam); +bool fireball(int power, bolt &beam); int stinking_cloud(int pow, bolt &beam); void abjuration(int pow); diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc index 0d5f064560..aa9063d5e7 100644 --- a/crawl-ref/source/spells3.cc +++ b/crawl-ref/source/spells3.cc @@ -308,12 +308,12 @@ int airstrike(int power, dist &beam) return (success); } // end airstrike() -int cast_bone_shards(int power, bolt &beam) +bool cast_bone_shards(int power, bolt &beam) { bool success = false; if (you.equip[EQ_WEAPON] == -1 - || you.inv[you.equip[EQ_WEAPON]].base_type != OBJ_CORPSES) + || you.inv[you.equip[EQ_WEAPON]].base_type != OBJ_CORPSES) { canned_msg(MSG_SPELL_FIZZLES); } @@ -326,6 +326,9 @@ int cast_bone_shards(int power, bolt &beam) power *= 15; power += mons_weight( you.inv[you.equip[EQ_WEAPON]].plus ); + if (!player_tracer(ZAP_BONE_SHARDS, power, beam)) + return (false); + mpr("The skeleton explodes into sharp fragments of bone!"); dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 ); diff --git a/crawl-ref/source/spells3.h b/crawl-ref/source/spells3.h index 44636eb093..d758b40308 100644 --- a/crawl-ref/source/spells3.h +++ b/crawl-ref/source/spells3.h @@ -36,7 +36,7 @@ int airstrike(int power, dist &beam); /* *********************************************************************** * called from: spell * *********************************************************************** */ -int cast_bone_shards(int power, bolt &); +bool cast_bone_shards(int power, bolt &); // updated 24may2000 {dlb} diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc index a2cf1ee5e6..3004edbfe8 100644 --- a/crawl-ref/source/spells4.cc +++ b/crawl-ref/source/spells4.cc @@ -2636,21 +2636,24 @@ int cast_apportation(int pow) return (done); } -void cast_sandblast(int pow, bolt &beam) +bool cast_sandblast(int pow, bolt &beam) { bool big = false; if (you.weapon()) { const item_def& wpn(*you.weapon()); - big = (wpn.base_type == OBJ_MISSILES) - && (wpn.sub_type == MI_STONE || wpn.sub_type == MI_LARGE_ROCK); + big = (wpn.base_type == OBJ_MISSILES + && (wpn.sub_type == MI_STONE || wpn.sub_type == MI_LARGE_ROCK)); } - if (big) + bool success = zapping(big ? ZAP_SANDBLAST + : ZAP_SMALL_SANDBLAST, pow, beam, true); + + if (big && success) dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 ); - zapping(big ? ZAP_SANDBLAST : ZAP_SMALL_SANDBLAST, pow, beam); + return (success); } void cast_condensation_shield(int pow) diff --git a/crawl-ref/source/spells4.h b/crawl-ref/source/spells4.h index b29418a055..3675cb8566 100644 --- a/crawl-ref/source/spells4.h +++ b/crawl-ref/source/spells4.h @@ -42,7 +42,7 @@ void cast_intoxicate(int pow); void cast_mass_sleep(int pow); void cast_passwall(int pow); void cast_rotting(int pow); -void cast_sandblast(int powc, bolt &beam); +bool cast_sandblast(int powc, bolt &beam); void cast_see_invisible(int pow); void cast_shatter(int pow); diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc index fffba572d9..9fb62bbdf5 100644 --- a/crawl-ref/source/spl-cast.cc +++ b/crawl-ref/source/spl-cast.cc @@ -470,9 +470,8 @@ int calc_spell_power(spell_type spell, bool apply_intel, bool fail_rate_check) // When checking failure rates, wizardry is handled after the various // stepping calulations. - int power = - (you.skills[SK_SPELLCASTING] / 2) - + (fail_rate_check? 0 : player_mag_abil(false)); + int power = (you.skills[SK_SPELLCASTING] / 2) + + (fail_rate_check? 0 : player_mag_abil(false)); int enhanced = 0; unsigned int disciplines = get_spell_disciplines( spell ); @@ -979,7 +978,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) const bool needs_path = (!testbits(flags, SPFLAG_GRID) && !testbits(flags, SPFLAG_TARGET)); - if (!spell_direction( spd, beam, dir, targ, needs_path, prompt )) + if (!spell_direction(spd, beam, dir, targ, needs_path, prompt)) return (SPRET_ABORT); if (testbits( flags, SPFLAG_NOT_SELF ) && spd.isMe) @@ -1108,12 +1107,13 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_MAGIC_DART: - if (!zapping(ZAP_MAGIC_DARTS, powc, beam)) + if (!zapping(ZAP_MAGIC_DARTS, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_FIREBALL: - fireball(powc, beam); + if (!fireball(powc, beam)) + return (SPRET_ABORT); break; case SPELL_DELAYED_FIREBALL: @@ -1155,7 +1155,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_STRIKING: - if (!zapping( ZAP_STRIKING, powc, beam )) + if (!zapping(ZAP_STRIKING, powc, beam, true)) return (SPRET_ABORT); break; @@ -1165,27 +1165,27 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_DIG: - if (!zapping(ZAP_DIGGING, powc, beam)) + if (!zapping(ZAP_DIGGING, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_BOLT_OF_FIRE: - if (!zapping(ZAP_FIRE, powc, beam)) + if (!zapping(ZAP_FIRE, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_BOLT_OF_COLD: - if (!zapping(ZAP_COLD, powc, beam)) + if (!zapping(ZAP_COLD, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_LIGHTNING_BOLT: - if (!zapping(ZAP_LIGHTNING, powc, beam)) + if (!zapping(ZAP_LIGHTNING, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_BOLT_OF_MAGMA: - if (!zapping(ZAP_MAGMA, powc, beam)) + if (!zapping(ZAP_MAGMA, powc, beam, true)) return (SPRET_ABORT); break; @@ -1193,26 +1193,27 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) // Trying is already enough, even if it fails. did_god_conduct(DID_DELIBERATE_MUTATING, 10); - if (!zapping(ZAP_POLYMORPH_OTHER, powc, beam)) + if (!zapping(ZAP_POLYMORPH_OTHER, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_SLOW: - if (!zapping(ZAP_SLOWING, powc, beam)) + if (!zapping(ZAP_SLOWING, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_HASTE: - zapping(ZAP_HASTING, powc, beam); + if (!zapping(ZAP_HASTING, powc, beam, true)) + return (SPRET_ABORT); break; case SPELL_PARALYSE: - if (!zapping(ZAP_PARALYSIS, powc, beam)) + if (!zapping(ZAP_PARALYSIS, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_CONFUSE: - if (!zapping(ZAP_CONFUSION, powc, beam)) + if (!zapping(ZAP_CONFUSION, powc, beam, true)) return (SPRET_ABORT); break; @@ -1225,16 +1226,17 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_INVISIBILITY: - zapping(ZAP_INVISIBILITY, powc, beam); + if (!zapping(ZAP_INVISIBILITY, powc, beam, true)) + return (SPRET_ABORT); break; case SPELL_THROW_FLAME: - if (!zapping(ZAP_FLAME, powc, beam)) + if (!zapping(ZAP_FLAME, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_THROW_FROST: - if (!zapping(ZAP_FROST, powc, beam)) + if (!zapping(ZAP_FROST, powc, beam, true)) return (SPRET_ABORT); break; @@ -1268,7 +1270,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_VENOM_BOLT: - if (!zapping(ZAP_VENOM_BOLT, powc, beam)) + if (!zapping(ZAP_VENOM_BOLT, powc, beam, true)) return (SPRET_ABORT); break; @@ -1278,7 +1280,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) case SPELL_TELEPORT_OTHER: // teleport creature (I think) - if (!zapping(ZAP_TELEPORTATION, powc, beam)) + if (!zapping(ZAP_TELEPORTATION, powc, beam, true)) return (SPRET_ABORT); break; @@ -1349,17 +1351,17 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_BOLT_OF_DRAINING: - if (!zapping(ZAP_NEGATIVE_ENERGY, powc, beam)) + if (!zapping(ZAP_NEGATIVE_ENERGY, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_LEHUDIBS_CRYSTAL_SPEAR: - if (!zapping(ZAP_CRYSTAL_SPEAR, powc, beam)) + if (!zapping(ZAP_CRYSTAL_SPEAR, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_BOLT_OF_INACCURACY: - if (!zapping(ZAP_BEAM_OF_ENERGY, powc, beam)) + if (!zapping(ZAP_BEAM_OF_ENERGY, powc, beam, true)) return (SPRET_ABORT); break; @@ -1368,7 +1370,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_POISON_ARROW: - if (!zapping( ZAP_POISON_ARROW, powc, beam )) + if (!zapping(ZAP_POISON_ARROW, powc, beam, true)) return (SPRET_ABORT); break; @@ -1386,7 +1388,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_ISKENDERUNS_MYSTIC_BLAST: - if (!zapping( ZAP_MYSTIC_BLAST, powc, beam )) + if (!zapping(ZAP_MYSTIC_BLAST, powc, beam, true)) return (SPRET_ABORT); break; @@ -1399,7 +1401,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_ENSLAVEMENT: - if (!zapping(ZAP_ENSLAVEMENT, powc, beam)) + if (!zapping(ZAP_ENSLAVEMENT, powc, beam, true)) return (SPRET_ABORT); break; @@ -1425,7 +1427,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_PAIN: - if (!zapping(ZAP_PAIN, powc, beam)) + if (!zapping(ZAP_PAIN, powc, beam, true)) return (SPRET_ABORT); dec_hp(1, false); break; @@ -1481,7 +1483,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_STICKY_FLAME: - if (!zapping(ZAP_STICKY_FLAME, powc, beam)) + if (!zapping(ZAP_STICKY_FLAME, powc, beam, true)) return (SPRET_ABORT); break; @@ -1511,7 +1513,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_DISPEL_UNDEAD: - if (!zapping(ZAP_DISPEL_UNDEAD, powc, beam)) + if (!zapping(ZAP_DISPEL_UNDEAD, powc, beam, true)) return (SPRET_ABORT); break; @@ -1520,12 +1522,12 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_THUNDERBOLT: - if (!zapping(ZAP_LIGHTNING, powc, beam)) + if (!zapping(ZAP_LIGHTNING, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_FLAME_OF_CLEANSING: - if (!zapping(ZAP_CLEANSING_FLAME, powc, beam)) + if (!zapping(ZAP_CLEANSING_FLAME, powc, beam, true)) return (SPRET_ABORT); break; @@ -1544,7 +1546,8 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_BONE_SHARDS: - cast_bone_shards(powc, beam); + if (!cast_bone_shards(powc, beam)) + return (SPRET_ABORT); break; case SPELL_BANISHMENT: @@ -1553,17 +1556,17 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) mpr("You cannot banish yourself!"); break; } - if (!zapping(ZAP_BANISHMENT, powc, beam)) + if (!zapping(ZAP_BANISHMENT, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_CIGOTUVIS_DEGENERATION: - if (!zapping(ZAP_DEGENERATION, powc, beam)) + if (!zapping(ZAP_DEGENERATION, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_STING: - if (!zapping(ZAP_STING, powc, beam)) + if (!zapping(ZAP_STING, powc, beam, true)) return (SPRET_ABORT); break; @@ -1577,9 +1580,9 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_HELLFIRE: - // should only be available from: + // Should only be available from: // staff of Dispater & Sceptre of Asmodeus - if (!zapping(ZAP_HELLFIRE, powc, beam)) + if (!zapping(ZAP_HELLFIRE, powc, beam, true)) return (SPRET_ABORT); break; @@ -1652,12 +1655,12 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_BOLT_OF_IRON: - if (!zapping(ZAP_IRON_BOLT, powc, beam)) + if (!zapping(ZAP_IRON_BOLT, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_STONE_ARROW: - if (!zapping(ZAP_STONE_ARROW, powc, beam)) + if (!zapping(ZAP_STONE_ARROW, powc, beam, true)) return (SPRET_ABORT); break; @@ -1670,7 +1673,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_SHOCK: - if (!zapping(ZAP_ELECTRICITY, powc, beam)) + if (!zapping(ZAP_ELECTRICITY, powc, beam, true)) return (SPRET_ABORT); break; @@ -1687,7 +1690,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_ORB_OF_ELECTROCUTION: - if (!zapping(ZAP_ORB_OF_ELECTRICITY, powc, beam)) + if (!zapping(ZAP_ORB_OF_ELECTRICITY, powc, beam, true)) return (SPRET_ABORT); break; @@ -1738,7 +1741,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_DEBUGGING_RAY: - if (!zapping(ZAP_DEBUGGING_RAY, powc, beam)) + if (!zapping(ZAP_DEBUGGING_RAY, powc, beam, true)) return (SPRET_ABORT); break; @@ -1753,7 +1756,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_AGONY: - if (!zapping(ZAP_AGONY, powc, beam)) + if (!zapping(ZAP_AGONY, powc, beam, true)) return (SPRET_ABORT); break; @@ -1762,12 +1765,12 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_DISRUPT: - if (!zapping(ZAP_DISRUPTION, powc, beam)) + if (!zapping(ZAP_DISRUPTION, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_DISINTEGRATE: - if (!zapping(ZAP_DISINTEGRATION, powc, beam)) + if (!zapping(ZAP_DISINTEGRATION, powc, beam, true)) return (SPRET_ABORT); break; @@ -1804,12 +1807,12 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_ORB_OF_FRAGMENTATION: - if (!zapping(ZAP_ORB_OF_FRAGMENTATION, powc, beam)) + if (!zapping(ZAP_ORB_OF_FRAGMENTATION, powc, beam, true)) return (SPRET_ABORT); break; case SPELL_ICE_BOLT: - if (!zapping(ZAP_ICE_BOLT, powc, beam)) + if (!zapping(ZAP_ICE_BOLT, powc, beam, true)) return (SPRET_ABORT); break; @@ -1823,7 +1826,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_ICE_STORM: - if (!zapping(ZAP_ICE_STORM, powc, beam)) + if (!zapping(ZAP_ICE_STORM, powc, beam, true)) return (SPRET_ABORT); break; @@ -1842,7 +1845,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) //jmf: new spells 19mar2000 case SPELL_FLAME_TONGUE: - if (!zapping(ZAP_FLAME_TONGUE, powc, beam)) + if (!zapping(ZAP_FLAME_TONGUE, powc, beam, true)) return (SPRET_ABORT); break; @@ -1878,7 +1881,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) mprf(MSGCH_DIAGNOSTICS, "Sleep power stepdown: %d -> %d", powc, sleep_power); #endif - if (!zapping(ZAP_SLEEP, sleep_power, beam)) + if (!zapping(ZAP_SLEEP, sleep_power, beam, true)) return (SPRET_ABORT); break; } @@ -1938,7 +1941,7 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_BACKLIGHT: - if (!zapping(ZAP_BACKLIGHT, powc + 10, beam)) + if (!zapping(ZAP_BACKLIGHT, powc + 10, beam, true)) return (SPRET_ABORT); break; @@ -1964,7 +1967,8 @@ spret_type your_spells( spell_type spell, int powc, bool allow_fail ) break; case SPELL_SANDBLAST: - cast_sandblast(powc, beam); + if (!cast_sandblast(powc, beam)) + return (SPRET_ABORT); break; case SPELL_ROTTING: -- cgit v1.2.3-54-g00ecf