summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/beam.cc112
-rw-r--r--crawl-ref/source/itemname.cc113
-rw-r--r--crawl-ref/source/itemname.h4
-rw-r--r--crawl-ref/source/misc.cc7
-rw-r--r--crawl-ref/source/spells1.cc50
-rw-r--r--crawl-ref/source/spells1.h2
-rw-r--r--crawl-ref/source/spells3.cc2
-rw-r--r--crawl-ref/source/spells4.cc64
-rw-r--r--crawl-ref/source/spl-cast.cc10
9 files changed, 207 insertions, 157 deletions
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index d886ec06c9..77f3c7dffa 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -200,7 +200,7 @@ void zap_animation( int colour, const monsters *mon, bool force )
}
}
-// special front function for zap_animation to interpret enchantment flavours
+// Special front function for zap_animation to interpret enchantment flavours.
static void _ench_animation( int flavour, const monsters *mon, bool force )
{
const int elem = (flavour == BEAM_HEALING) ? EC_HEAL :
@@ -1675,7 +1675,7 @@ static void _zappy( zap_type z_type, int power, bolt &pbolt )
* Now handles all beamed/thrown items and spells, tracers, and their effects.
* item is used for items actually thrown/launched
*
- * if item is NULL, there is no physical object being thrown that could
+ * If item is NULL, there is no physical object being thrown that could
* land on the ground.
*/
@@ -1891,9 +1891,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item )
// 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
// above -- affect() will early out if something gets
@@ -1910,9 +1908,7 @@ void fire_beam( bolt &pbolt, item_def *item, bool drop_item )
}
if (!pbolt.affects_nothing)
- {
rangeRemaining -= affect(pbolt, tx, ty, item);
- }
if (random_beam)
{
@@ -2186,7 +2182,7 @@ int mons_adjust_flavoured( monsters *monster, bolt &pbolt,
}
else
{
- // early out for tracer/no side effects
+ // Early out for tracer/no side effects.
if (!doFlavouredEffects)
return (hurted);
@@ -2360,8 +2356,9 @@ static bool _monster_resists_mass_enchantment(monsters *monster,
if (check_mons_resist_magic( monster, pow ))
{
- simple_monster_message(monster, mons_immune_magic(monster) ?
- " is unaffected." : " resists.");
+ simple_monster_message(monster,
+ mons_immune_magic(monster)? " is unaffected."
+ : " resists.");
return (true);
}
}
@@ -2376,8 +2373,9 @@ static bool _monster_resists_mass_enchantment(monsters *monster,
if (check_mons_resist_magic( monster, pow ))
{
- simple_monster_message(monster, mons_immune_magic(monster) ?
- " is unaffected." : " resists.");
+ simple_monster_message(monster,
+ mons_immune_magic(monster)? " is unaffected."
+ : " resists.");
return (true);
}
}
@@ -2476,9 +2474,9 @@ bool mass_enchantment( enchant_type wh_enchant, int pow, int origin,
// * Returns MON_AFFECTED in all other cases (already enchanted, etc).
int mons_ench_f2(monsters *monster, bolt &pbolt)
{
- switch (pbolt.flavour) /* put in magic resistance */
+ switch (pbolt.flavour) // put in magic resistance
{
- case BEAM_SLOW: /* 0 = slow monster */
+ case BEAM_SLOW:
// try to remove haste, if monster is hasted
if (monster->del_ench(ENCH_HASTE))
{
@@ -2504,7 +2502,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
}
return (MON_AFFECTED);
- case BEAM_HASTE: // 1 = haste
+ case BEAM_HASTE:
if (monster->del_ench(ENCH_SLOW))
{
if (simple_monster_message(monster, " is no longer moving slowly."))
@@ -2513,7 +2511,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
return (MON_AFFECTED);
}
- // not slowed, haste it
+ // Not slowed, haste it.
if (!monster->has_ench(ENCH_HASTE)
&& !mons_is_stationary(monster)
&& monster->add_ench(ENCH_HASTE))
@@ -2526,7 +2524,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
}
return (MON_AFFECTED);
- case BEAM_HEALING: /* 2 = healing */
+ case BEAM_HEALING:
if (YOU_KILL(pbolt.thrower))
{
if (cast_healing(5 + roll_dice( pbolt.damage ),
@@ -2551,11 +2549,11 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
}
return (MON_AFFECTED);
- case BEAM_PARALYSIS: /* 3 = paralysis */
+ case BEAM_PARALYSIS:
_beam_paralyses_monster(pbolt, monster);
return (MON_AFFECTED);
- case BEAM_CONFUSION: /* 4 = confusion */
+ case BEAM_CONFUSION:
if (!mons_class_is_confusable(monster->type))
return (MON_UNAFFECTED);
@@ -2569,7 +2567,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
}
return (MON_AFFECTED);
- case BEAM_INVISIBILITY: /* 5 = invisibility */
+ case BEAM_INVISIBILITY:
{
// Store the monster name before it becomes an "it" -- bwr
const std::string monster_name = monster->name(DESC_CAP_THE);
@@ -2602,7 +2600,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
}
return (MON_AFFECTED);
}
- case BEAM_CHARM: /* 9 = charm */
+ case BEAM_CHARM:
if (player_will_anger_monster(monster))
{
simple_monster_message(monster, " is repulsed!");
@@ -2620,7 +2618,7 @@ int mons_ench_f2(monsters *monster, bolt &pbolt)
default:
break;
- } /* end of switch (beam_colour) */
+ }
return (MON_AFFECTED);
} // end mons_ench_f2()
@@ -2736,20 +2734,19 @@ void _sticky_flame_monster( int mn, kill_category who, int levels )
}
}
-/*
- * Used by monsters in "planning" which spell to cast. Fires off a "tracer"
- * which tells the monster what it'll hit if it breathes/casts etc.
- *
- * The output from this tracer function is four variables in the beam struct:
- * fr_count, foe_count: a count of how many friends and foes will (probably)
- * be hit by this beam
- * fr_power, foe_power: a measure of how many 'friendly' hit dice it will
- * affect, and how many 'unfriendly' hit dice.
- *
- * Note that beam properties must be set, as the tracer will take them
- * into account, as well as the monster's intelligence.
- *
- */
+//
+// Used by monsters in "planning" which spell to cast. Fires off a "tracer"
+// which tells the monster what it'll hit if it breathes/casts etc.
+//
+// The output from this tracer function is four variables in the beam struct:
+// fr_count, foe_count: a count of how many friends and foes will (probably)
+// be hit by this beam
+// fr_power, foe_power: a measure of how many 'friendly' hit dice it will
+// affect, and how many 'unfriendly' hit dice.
+//
+// Note that beam properties must be set, as the tracer will take them
+// into account, as well as the monster's intelligence.
+//
void fire_tracer(const monsters *monster, bolt &pbolt)
{
// Don't fiddle with any input parameters other than tracer stuff!
@@ -3044,13 +3041,13 @@ int affect(bolt &beam, int x, int y, item_def *item)
if (grid_is_solid(grd[x][y]))
{
- if (beam.is_tracer) // tracers always stop on walls.
+ if (beam.is_tracer) // Tracers always stop on walls.
return (BEAM_STOP);
if (_affects_wall(beam, grd[x][y]))
rangeUsed += _affect_wall(beam, x, y);
- // if it's still a wall, quit - we can't do anything else to a
+ // If it's still a wall, quit - we can't do anything else to a
// wall (but we still might be able to do something to any
// monster inside the wall). Otherwise effects (like clouds,
// etc.) are still possible.
@@ -3375,7 +3372,7 @@ static void _affect_place_explosion_clouds(bolt &beam, int x, int y)
cloud_type cl_type;
int duration;
- // first check: FIRE/COLD over water/lava
+ // First check: FIRE/COLD over water/lava.
if (grd[x][y] == DNGN_LAVA && beam.flavour == BEAM_COLD
|| grid_is_watery(grd[x][y]) && _is_fiery(beam))
{
@@ -4041,7 +4038,7 @@ static int _affect_player( bolt &beam, item_def *item )
}
}
- // sticky flame
+ // Sticky flame.
if (beam.name == "sticky flame"
&& (you.species != SP_MOTTLED_DRACONIAN
|| you.experience_level < 6))
@@ -4053,22 +4050,22 @@ static int _affect_player( bolt &beam, item_def *item )
}
}
- // simple cases for scroll burns
+ // Simple cases for scroll burns.
if (beam.flavour == BEAM_LAVA || beam.name == "hellfire")
expose_player_to_element(BEAM_LAVA, burn_power);
- // more complex (geez..)
+ // More complex (geez..)
if (beam.flavour == BEAM_FIRE && beam.name != "ball of steam")
expose_player_to_element(BEAM_FIRE, burn_power);
- // potions exploding
+ // Potions exploding.
if (beam.flavour == BEAM_COLD)
expose_player_to_element(BEAM_COLD, burn_power);
if (beam.flavour == BEAM_ACID)
splash_with_acid(5);
- // spore pops
+ // Spore pops.
if (beam.in_explosion_phase && beam.flavour == BEAM_SPORE)
expose_player_to_element(BEAM_SPORE, burn_power);
@@ -4197,7 +4194,7 @@ static bool _beam_is_harmless(bolt &beam, monsters *mon)
}
}
-// return amount of range used up by affectation of this monster
+// Returns amount of range used up by affectation of this monster.
static int _affect_monster(bolt &beam, monsters *mon, item_def *item)
{
const int tid = mgrd[mon->x][mon->y];
@@ -4261,15 +4258,16 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item)
{
if (beam.is_tracer)
{
- if (beam.thrower == KILL_YOU_MISSILE)
+ if (beam.thrower == KILL_YOU_MISSILE || beam.thrower == KILL_YOU)
{
- if (!_beam_is_harmless(beam, mon))
+ if (!beam.fr_count && !_beam_is_harmless(beam, mon))
{
const bool target = (beam.target_x == mon->x
&& beam.target_y == mon->y);
if (stop_attack_prompt(mon, true, target))
{
+ mpr("Test2");
beam.fr_count = 1;
return (BEAM_STOP);
}
@@ -4428,9 +4426,9 @@ static int _affect_monster(bolt &beam, monsters *mon, item_def *item)
// hurt by this beam.
if (beam.is_tracer)
{
- if (beam.thrower == KILL_YOU_MISSILE)
+ if (beam.thrower == KILL_YOU_MISSILE || beam.thrower == KILL_YOU)
{
- if (!_beam_is_harmless(beam, mon))
+ if (!beam.fr_count && !_beam_is_harmless(beam, mon))
{
const bool target = (beam.target_x == mon->x
&& beam.target_y == mon->y);
@@ -4812,7 +4810,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon)
simple_monster_message(mon, " is enslaved.");
- // wow, permanent enslaving
+ // Wow, permanent enslaving!
mon->attitude = ATT_FRIENDLY;
return (MON_AFFECTED);
}
@@ -4831,7 +4829,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon)
return (MON_RESIST);
}
- // already friendly
+ // Already friendly.
if (mons_friendly(mon))
return (MON_UNAFFECTED);
@@ -4940,7 +4938,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon)
return (MON_UNAFFECTED);
}
- // everything else?
+ // Everything else?
if (!death_check)
return (mons_ench_f2(mon, beam));
@@ -4958,7 +4956,7 @@ static int _affect_monster_enchantment(bolt &beam, monsters *mon)
}
-// extra range used on hit
+// Extra range used on hit.
static int _range_used_on_hit(bolt &beam)
{
// Non-beams can only affect one thing (player/monster).
@@ -5000,11 +4998,11 @@ static int _range_used_on_hit(bolt &beam)
if (beam.name == "hellfire")
return (0);
- // generic explosion
+ // Generic explosion.
if (beam.is_explosion || beam.is_big_cloud)
return (BEAM_STOP);
- // plant spit
+ // Plant spit.
if (beam.flavour == BEAM_ACID)
return (BEAM_STOP);
@@ -5376,7 +5374,7 @@ static void _explosion_cell(bolt &beam, int x, int y, bool drawOnly)
beam.flavour = BEAM_RANDOM;
}
- // early out for tracer
+ // Early out for tracer.
if (beam.is_tracer)
return;
@@ -5457,11 +5455,11 @@ static void _explosion_map( bolt &beam, int x, int y,
// straightforward.
static bool _nasty_beam(monsters *mon, bolt &beam)
{
- // take care of non-enchantments
+ // Take care of non-enchantments.
if (beam.name[0] != '0')
return (true);
- // now for some non-hurtful enchantments
+ // Now for some non-hurtful enchantments.
// No charming holy beings!
if (beam.flavour == BEAM_CHARM)
diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc
index 82bddb848e..7e7a897242 100644
--- a/crawl-ref/source/itemname.cc
+++ b/crawl-ref/source/itemname.cc
@@ -2209,9 +2209,6 @@ bool is_good_item(const item_def &item)
if (is_emergency_item(item))
return (true);
- if (is_useless_item(item) || is_dangerous_item(item))
- return (false);
-
switch (item.base_type)
{
case OBJ_SCROLLS:
@@ -2238,7 +2235,7 @@ bool is_good_item(const item_def &item)
}
// Returns true if using an item only has harmful effects.
-bool is_bad_item(const item_def &item)
+bool is_bad_item(const item_def &item, bool temp)
{
if (!item_type_known(item))
return (false);
@@ -2251,6 +2248,11 @@ bool is_bad_item(const item_def &item)
case SCR_CURSE_ARMOUR:
case SCR_CURSE_WEAPON:
return (true);
+ case SCR_SUMMONING:
+ // Summoning will always produce hostile monsters if you worship
+ // a good god. (Use temp to allow autopickup to prevent monsters
+ // from reading it.)
+ return (temp && is_good_god(you.religion));
default:
return (false);
}
@@ -2266,13 +2268,15 @@ bool is_bad_item(const item_def &item)
case POT_DEGENERATION:
case POT_DECAY:
case POT_PARALYSIS:
- // Well, strictly poison is not that bad if you're poison resistant...
+ return (true);
case POT_POISON:
case POT_STRONG_POISON:
- return (true);
+ // Poison is not that bad if you're poison resistant.
+ return (!player_res_poison()
+ || !temp && you.species == SP_VAMPIRE);
case POT_MUTATION:
return (you.is_undead
- && (you.species != SP_VAMPIRE
+ && (temp || you.species != SP_VAMPIRE
|| you.hunger_state < HS_SATIATED));
default:
return (false);
@@ -2297,7 +2301,7 @@ bool is_bad_item(const item_def &item)
}
// Returns true if using an item is risky but may occasionally be worthwhile.
-bool is_dangerous_item(const item_def &item)
+bool is_dangerous_item(const item_def &item, bool temp)
{
if (!item_type_known(item))
{
@@ -2318,8 +2322,10 @@ bool is_dangerous_item(const item_def &item)
switch (item.sub_type)
{
case SCR_IMMOLATION:
- case SCR_TORMENT:
return (true);
+ case SCR_TORMENT:
+ return (!player_mutation_level(MUT_TORMENT_RESISTANCE)
+ || !temp && you.species == SP_VAMPIRE);
default:
return (false);
}
@@ -2329,11 +2335,14 @@ bool is_dangerous_item(const item_def &item)
case POT_MUTATION:
// Only living characters can mutate.
return (!you.is_undead
- || you.species == SP_VAMPIRE
+ || temp && you.species == SP_VAMPIRE
&& you.hunger_state >= HS_SATIATED);
default:
return (false);
}
+ case OBJ_BOOKS:
+ // The Tome of Destruction is certainly risky.
+ return (item.sub_type == BOOK_DESTRUCTION);
default:
return (false);
}
@@ -2355,7 +2364,7 @@ bool is_useless_item(const item_def &item, bool temp)
return (false);
// A bad item is always useless.
- if (is_bad_item(item))
+ if (is_bad_item(item, temp))
return (true);
switch (item.sub_type)
@@ -2364,6 +2373,9 @@ bool is_useless_item(const item_def &item, bool temp)
case SCR_RANDOM_USELESSNESS:
case SCR_NOISE:
return (true);
+ case SCR_TORMENT:
+ return (player_mutation_level(MUT_TORMENT_RESISTANCE)
+ || !temp && you.species == SP_VAMPIRE);
default:
return (false);
}
@@ -2375,23 +2387,14 @@ bool is_useless_item(const item_def &item, bool temp)
if (!item_type_known(item))
return (false);
- switch (item.sub_type)
- {
- case POT_CONFUSION:
- case POT_SLOWING:
- case POT_DEGENERATION:
- case POT_DECAY:
- case POT_PARALYSIS:
- case POT_POISON:
- case POT_STRONG_POISON:
- case POT_MUTATION:
- // Certainly not useless if it can be used for attacking.
- return (!player_knows_spell(SPELL_EVAPORATE));
- }
+ // No potion is useless if it can be used for Evaporate.
+ if (player_knows_spell(SPELL_EVAPORATE))
+ return (false);
+
+ // Apart from Evaporate, mummies can't use potions.
if (you.species == SP_MUMMY)
return (true);
- // Do a second switch for the other potions.
switch (item.sub_type)
{
case POT_BERSERK_RAGE:
@@ -2401,7 +2404,7 @@ bool is_useless_item(const item_def &item, bool temp)
case POT_GAIN_DEXTERITY:
return (you.species == SP_GHOUL
|| temp && you.species == SP_VAMPIRE
- && you.hunger_state >= HS_SATIATED);
+ && you.hunger_state < HS_SATIATED);
case POT_LEVITATION:
return (you.permanent_levitation() || you.permanent_flight());
@@ -2412,6 +2415,10 @@ bool is_useless_item(const item_def &item, bool temp)
case POT_BLOOD_COAGULATED:
return (!can_ingest(item.base_type, item.sub_type, true, true,
false));
+ case POT_POISON:
+ case POT_STRONG_POISON:
+ // If you're poison resistant, poison is only useless.
+ return player_res_poison();
}
return (false);
@@ -2420,43 +2427,45 @@ bool is_useless_item(const item_def &item, bool temp)
if (!item_type_known(item))
return (false);
- if (is_bad_item(item))
+ if (is_bad_item(item, temp))
return (true);
- if (you.species == SP_MUMMY || you.species == SP_GHOUL)
+ switch (item.sub_type)
{
- switch (item.sub_type)
- {
- case AMU_RAGE:
- case RING_REGENERATION:
- case RING_SUSTENANCE:
- case RING_HUNGER:
- case RING_LIFE_PROTECTION:
- return (true);
- }
- }
+ case AMU_RAGE:
+ return (you.is_undead
+ && (!temp || you.species == SP_VAMPIRE
+ && you.hunger_state <= HS_SATIATED)
+ || you.religion == GOD_TROG);
+
+ case RING_LIFE_PROTECTION:
+ case RING_HUNGER:
+ case RING_REGENERATION:
+ case RING_SUSTENANCE:
+ return (you.is_undead
+ && (!temp || you.species == SP_VAMPIRE
+ && you.hunger_state == HS_STARVING));
- if (item.sub_type == RING_SEE_INVISIBLE)
+ case RING_SEE_INVISIBLE:
return (player_mutation_level(MUT_ACUTE_VISION));
- if (item.sub_type == RING_POISON_RESISTANCE)
- {
- return (you.species != SP_VAMPIRE
- && player_mutation_level(MUT_POISON_RESISTANCE));
- }
+ case RING_POISON_RESISTANCE:
+ return (player_res_poison()
+ && (temp || you.species != SP_VAMPIRE));
- if (item.sub_type == AMU_CONTROLLED_FLIGHT)
+ case AMU_CONTROLLED_FLIGHT:
return (player_genus(GENPC_DRACONIAN) || you.permanent_flight());
- if (you.religion == GOD_TROG)
- {
- return (item.sub_type == RING_WIZARDRY
- || item.sub_type == AMU_RAGE);
+ case RING_WIZARDRY:
+ return (you.religion == GOD_TROG);
+
+ default:
+ return (false);
}
- return (false);
case OBJ_STAVES:
if (you.religion == GOD_TROG && !item_is_rod(item))
return (true);
+
default:
return (false);
}
@@ -2504,9 +2513,9 @@ const std::string menu_colour_item_prefix(const item_def &item, bool temp)
prefixes.push_back("emergency_item");
if (is_good_item(item))
prefixes.push_back("good_item");
- if (is_dangerous_item(item))
+ if (is_dangerous_item(item, temp))
prefixes.push_back("dangerous_item");
- if (is_bad_item(item))
+ if (is_bad_item(item, temp))
prefixes.push_back("bad_item");
if (is_useless_item(item, temp))
prefixes.push_back("useless_item");
diff --git a/crawl-ref/source/itemname.h b/crawl-ref/source/itemname.h
index 2bafdf2e59..3b4a674044 100644
--- a/crawl-ref/source/itemname.h
+++ b/crawl-ref/source/itemname.h
@@ -111,8 +111,8 @@ bool item_type_tried( const item_def &item );
bool is_interesting_item( const item_def& item );
bool is_emergency_item( const item_def& item );
bool is_good_item(const item_def &item);
-bool is_bad_item(const item_def &item);
-bool is_dangerous_item( const item_def& item );
+bool is_bad_item(const item_def &item, bool temp = false);
+bool is_dangerous_item( const item_def& item, bool temp = false);
bool is_useless_item(const item_def &item, bool temp = false);
std::string make_name( unsigned long seed, bool all_caps );
diff --git a/crawl-ref/source/misc.cc b/crawl-ref/source/misc.cc
index 90879d3d75..fadc4b16b3 100644
--- a/crawl-ref/source/misc.cc
+++ b/crawl-ref/source/misc.cc
@@ -2721,6 +2721,9 @@ std::string your_hand(bool plural)
bool stop_attack_prompt(const monsters *mon, bool beam_attack,
bool beam_target)
{
+ if (you.confused())
+ return (false);
+
bool retval = false;
bool prompt = false;
@@ -2734,7 +2737,7 @@ bool stop_attack_prompt(const monsters *mon, bool beam_attack,
if (isFriendly)
{
- // listed in the form: "your rat", "Blork the orc"
+ // Listed in the form: "your rat", "Blork the orc".
snprintf(info, INFO_SIZE, "Really %s %s%s?",
(beam_attack) ? (beam_target) ? "fire at"
: "fire through"
@@ -2769,7 +2772,7 @@ bool stop_attack_prompt(const monsters *mon, bool beam_attack,
prompt = true;
}
- if (!you.confused() && prompt)
+ if (prompt)
retval = !yesno(info, false, 'n');
return (retval);
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index e151ef26bd..d4b474bd17 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -552,27 +552,45 @@ bool conjure_flame(int pow)
return true;
}
-int stinking_cloud( int pow, bolt &beem )
+bool stinking_cloud( int pow, bolt &beem )
{
- beem.name = "ball of vapour";
- beem.colour = GREEN;
- beem.range = 6;
- beem.rangeMax = 6;
- beem.damage = dice_def( 1, 0 );
- beem.hit = 20;
- beem.type = dchar_glyph(DCHAR_FIRED_ZAP);
- beem.flavour = BEAM_MMISSILE;
- beem.ench_power = pow;
+ beem.name = "ball of vapour";
+ beem.colour = GREEN;
+ beem.range = 6;
+ beem.rangeMax = 6;
+ beem.damage = dice_def( 1, 0 );
+ beem.hit = 20;
+ beem.type = dchar_glyph(DCHAR_FIRED_ZAP);
+ beem.flavour = BEAM_MMISSILE;
+ beem.ench_power = pow;
beem.beam_source = MHITYOU;
- beem.thrower = KILL_YOU;
+ beem.thrower = KILL_YOU;
+ beem.is_beam = false;
beem.aux_source.clear();
- beem.is_beam = false;
- beem.is_tracer = false;
+ // Fire tracer.
+ beem.source_x = you.x_pos;
+ beem.source_y = you.y_pos;
+ beem.can_see_invis = player_see_invis();
+ beem.smart_monster = true;
+ beem.attitude = ATT_FRIENDLY;
+ beem.fr_count = 0;
+ beem.is_tracer = true;
fire_beam(beem);
- return (1);
-} // end stinking_cloud()
+ if (beem.fr_count > 0)
+ {
+ // We don't want to fire through friendlies.
+ canned_msg(MSG_OK);
+ return (false);
+ }
+
+ // Really fire.
+ beem.is_tracer = false;
+ fire_beam(beem);
+
+ return (true);
+}
int cast_big_c(int pow, cloud_type cty, kill_category whose, bolt &beam)
{
@@ -590,7 +608,7 @@ void big_cloud(cloud_type cl_type, kill_category whose,
static bool _mons_hostile(const monsters *mon)
{
- // needs to be done this way because of friendly/neutral enchantments
+ // Needs to be done this way because of friendly/neutral enchantments.
return (!mons_friendly(mon) && !mons_neutral(mon));
}
diff --git a/crawl-ref/source/spells1.h b/crawl-ref/source/spells1.h
index 0a14e106b1..0e1ea589db 100644
--- a/crawl-ref/source/spells1.h
+++ b/crawl-ref/source/spells1.h
@@ -92,7 +92,7 @@ void cast_ring_of_flames(int power);
bool conjure_flame(int pow);
void extension(int pow);
bool fireball(int power, bolt &beam);
-int stinking_cloud(int pow, bolt &beam);
+bool stinking_cloud(int pow, bolt &beam);
void abjuration(int pow);
// last updated 24may2000 {dlb}
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index bc8ed70904..f3974c099c 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -265,7 +265,7 @@ int airstrike(int power, dist &beam)
behaviour_event(monster, ME_ANNOY, MHITYOU);
if (mons_is_mimic( monster->type ))
mimic_alert(monster);
- }
+ }
conduct.enabled = true;
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 9ef2376bd2..bd58066c2c 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -1305,8 +1305,6 @@ bool backlight_monsters(int x, int y, int pow, int garbage)
bool cast_evaporate(int pow, bolt& beem, int potion)
{
- struct dist spelld;
-
if (potion == -1)
return (false);
else if (you.inv[potion].base_type != OBJ_POTIONS)
@@ -1316,22 +1314,21 @@ bool cast_evaporate(int pow, bolt& beem, int potion)
return (false);
}
- beem.name = "potion";
- beem.colour = you.inv[potion].colour;
- beem.range = 9;
- beem.rangeMax = 9;
- beem.type = dchar_glyph(DCHAR_FIRED_FLASK);
+ beem.name = "potion";
+ beem.colour = you.inv[potion].colour;
+ beem.range = 9;
+ beem.rangeMax = 9;
+ beem.type = dchar_glyph(DCHAR_FIRED_FLASK);
beem.beam_source = MHITYOU;
- beem.thrower = KILL_YOU_MISSILE;
+ beem.thrower = KILL_YOU_MISSILE;
+ beem.is_beam = false;
beem.aux_source.clear();
- beem.is_beam = false;
- beem.is_tracer = false;
- beem.hit = you.dex / 2 + roll_dice( 2, you.skills[SK_THROWING] / 2 + 1 );
- beem.damage = dice_def( 1, 0 ); // no damage, just producing clouds
- beem.ench_power = pow; // used for duration only?
+ beem.hit = you.dex / 2 + roll_dice( 2, you.skills[SK_THROWING] / 2 + 1 );
+ beem.damage = dice_def( 1, 0 ); // no damage, just producing clouds
+ beem.ench_power = pow; // used for duration only?
- beem.flavour = BEAM_POTION_STINKING_CLOUD;
+ beem.flavour = BEAM_POTION_STINKING_CLOUD;
switch (you.inv[potion].sub_type)
{
@@ -1341,6 +1338,7 @@ bool cast_evaporate(int pow, bolt& beem, int potion)
break;
case POT_DEGENERATION:
+ beem.effect_known = false;
beem.flavour = (coinflip() ? BEAM_POTION_POISON : BEAM_POTION_MIASMA);
beem.ench_power *= 2;
break;
@@ -1373,6 +1371,7 @@ bool cast_evaporate(int pow, bolt& beem, int potion)
break; // stinking cloud
// deliberate fall through
case POT_BERSERK_RAGE:
+ beem.effect_known = false;
beem.flavour = (coinflip() ? BEAM_POTION_FIRE : BEAM_POTION_STEAM);
break;
@@ -1382,17 +1381,19 @@ bool cast_evaporate(int pow, bolt& beem, int potion)
case POT_GAIN_INTELLIGENCE:
case POT_EXPERIENCE:
case POT_MAGIC:
+ beem.effect_known = false;
switch (random2(5))
{
- case 0: beem.flavour = BEAM_POTION_FIRE; break;
- case 1: beem.flavour = BEAM_POTION_COLD; break;
- case 2: beem.flavour = BEAM_POTION_POISON; break;
- case 3: beem.flavour = BEAM_POTION_MIASMA; break;
- default: beem.flavour = BEAM_POTION_RANDOM; break;
+ case 0: beem.flavour = BEAM_POTION_FIRE; break;
+ case 1: beem.flavour = BEAM_POTION_COLD; break;
+ case 2: beem.flavour = BEAM_POTION_POISON; break;
+ case 3: beem.flavour = BEAM_POTION_MIASMA; break;
+ default: beem.flavour = BEAM_POTION_RANDOM; break;
}
break;
default:
+ beem.effect_known = false;
switch (random2(12))
{
case 0: beem.flavour = BEAM_POTION_FIRE; break;
@@ -1408,12 +1409,31 @@ bool cast_evaporate(int pow, bolt& beem, int potion)
break;
}
+ // Fire tracer.
+ beem.source_x = you.x_pos;
+ beem.source_y = you.y_pos;
+ beem.can_see_invis = player_see_invis();
+ beem.smart_monster = true;
+ beem.attitude = ATT_FRIENDLY;
+ beem.fr_count = 0;
+ beem.is_tracer = true;
+ fire_beam(beem);
+
+ if (beem.fr_count > 0)
+ {
+ // We don't want to fire through friendlies.
+ canned_msg(MSG_OK);
+ return (false);
+ }
+
if (coinflip())
exercise( SK_THROWING, 1 );
+ // Really fire.
+ beem.is_tracer = false;
fire_beam(beem);
- // both old and new code use up a potion:
+ // Use up a potion.
if (is_blood_potion(you.inv[potion]))
remove_oldest_blood_potion(you.inv[potion]);
@@ -1464,9 +1484,9 @@ void cast_fulsome_distillation( int powc )
return;
}
- const bool rotten = food_is_rotten(mitm[corpse]);
+ const bool rotten = food_is_rotten(mitm[corpse]);
const bool big_monster = (mons_type_hit_dice( mitm[corpse].plus ) >= 5);
- const bool power_up = (rotten && big_monster);
+ const bool power_up = (rotten && big_monster);
potion_type pot_type = POT_WATER;
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index f202254d83..065c549315 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -938,9 +938,10 @@ spret_type your_spells(spell_type spell, int powc, bool allow_fail)
(testbits(flags, SPFLAG_HELPFUL) ? TARG_FRIEND : TARG_ENEMY);
targeting_type dir =
- (testbits( flags, SPFLAG_TARGET ) ? DIR_TARGET :
- testbits( flags, SPFLAG_GRID ) ? DIR_TARGET :
- testbits( flags, SPFLAG_DIR ) ? DIR_DIR : DIR_NONE);
+ (testbits( flags, SPFLAG_TARGET ) ? DIR_TARGET :
+ testbits( flags, SPFLAG_GRID ) ? DIR_TARGET :
+ testbits( flags, SPFLAG_DIR ) ? DIR_DIR
+ : DIR_NONE);
const char *prompt = get_spell_target_prompt(spell);
if (spell == SPELL_EVAPORATE)
@@ -1235,7 +1236,8 @@ spret_type your_spells(spell_type spell, int powc, bool allow_fail)
break;
case SPELL_MEPHITIC_CLOUD:
- stinking_cloud(powc, beam);
+ if (!stinking_cloud(powc, beam))
+ return (SPRET_ABORT);
break;
case SPELL_RING_OF_FLAMES: