summaryrefslogtreecommitdiffstats
path: root/crawl-ref
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-22 15:53:37 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2008-05-22 15:53:37 +0000
commit2a73bdc6a3be5efa46dfdf32bb86edfcf5d0bd4c (patch)
tree8f0fc9dad7bcda05c27e23aca77ec987ed21c8c5 /crawl-ref
parent9a1e7565ec8802a38a9649744920923fc262dff7 (diff)
downloadcrawl-ref-2a73bdc6a3be5efa46dfdf32bb86edfcf5d0bd4c.tar.gz
crawl-ref-2a73bdc6a3be5efa46dfdf32bb86edfcf5d0bd4c.zip
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
Diffstat (limited to 'crawl-ref')
-rw-r--r--crawl-ref/source/abl-show.cc222
-rw-r--r--crawl-ref/source/beam.cc723
-rw-r--r--crawl-ref/source/beam.h6
-rw-r--r--crawl-ref/source/decks.cc4
-rw-r--r--crawl-ref/source/it_use3.cc1
-rw-r--r--crawl-ref/source/item_use.cc149
-rw-r--r--crawl-ref/source/itemprop.cc160
-rw-r--r--crawl-ref/source/items.cc8
-rw-r--r--crawl-ref/source/mon-util.cc15
-rw-r--r--crawl-ref/source/player.cc4
-rw-r--r--crawl-ref/source/spells1.cc56
-rw-r--r--crawl-ref/source/spells1.h2
-rw-r--r--crawl-ref/source/spells3.cc7
-rw-r--r--crawl-ref/source/spells3.h2
-rw-r--r--crawl-ref/source/spells4.cc13
-rw-r--r--crawl-ref/source/spells4.h2
-rw-r--r--crawl-ref/source/spl-cast.cc112
17 files changed, 990 insertions, 496 deletions
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<beam_type>(
- random_range(BEAM_FIRE, BEAM_ACID) );
+ pbolt.flavour = static_cast<beam_type>(
+ 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<weapon_type>( 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<zap_type>(wand.zap());
+ zap_type type_zapped = static_cast<zap_type>(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<zap_type>(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_type>( 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<zap_type>(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<zap_type>(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: