summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/spells4.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/spells4.cc')
-rw-r--r--crawl-ref/source/spells4.cc439
1 files changed, 321 insertions, 118 deletions
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 947a2274aa..c76a02a8a1 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -44,6 +44,7 @@
#include "ouch.h"
#include "player.h"
#include "randart.h"
+#include "religion.h"
#include "skills.h"
#include "spells1.h"
#include "spells4.h"
@@ -65,9 +66,13 @@ enum DEBRIS // jmf: add for shatter, dig, and Giants to throw
NUM_DEBRIS
}; // jmf: ...and I'll actually implement the items Real Soon Now...
+// static int make_a_random_cloud(int x, int y, int pow, int ctype);
static int make_a_rot_cloud(int x, int y, int pow, cloud_type ctype);
static int quadrant_blink(int x, int y, int pow, int garbage);
+//void cast_animate_golem(int pow); // see actual function for reasoning {dlb}
+//void cast_detect_magic(int pow); //jmf: as above...
+//void cast_eringyas_surprising_bouquet(int powc);
void do_monster_rot(int mon);
//jmf: FIXME: put somewhere else (misc.cc?)
@@ -113,6 +118,43 @@ std::string your_hand( bool plural )
return result;
}
+// I need to make some debris for metal, crystal and stone.
+// They could go in OBJ_MISSILES, but I think I'd rather move
+// MI_LARGE_ROCK into OBJ_DEBRIS and code giants to throw any
+// OBJ_DEBRIS they get their meaty mits on.
+static void place_debris(int x, int y, int debris_type)
+{
+#ifdef USE_DEBRIS_CODE
+ switch (debris_type)
+ {
+ // hate to say this, but the first parameter only allows specific quantity
+ // for *food* and nothing else -- and I would hate to see that parameter
+ // (force_unique) abused any more than it already has been ... {dlb}:
+ case DEBRIS_STONE:
+ large = items( random2(3), OBJ_MISSILES, MI_LARGE_ROCK, true, 1, 250 );
+ small = items( 3 + random2(6) + random2(6) + random2(6),
+ OBJ_MISSILES, MI_STONE, true, 1, 250 );
+ break;
+ case DEBRIS_METAL:
+ case DEBRIS_WOOD:
+ case DEBRIS_CRYSTAL:
+ break;
+ }
+
+ if (small != NON_ITEM)
+ move_item_to_grid( &small, x, y );
+
+ if (large != NON_ITEM)
+ move_item_to_grid( &large, x, y );
+
+#else
+ UNUSED( x );
+ UNUSED( y );
+ UNUSED( debris_type );
+ return;
+#endif
+} // end place_debris()
+
// just to avoid typing this over and over
// now returns true if monster died -- bwr
inline bool player_hurt_monster(int monster, int damage)
@@ -281,7 +323,8 @@ static int shatter_walls(int x, int y, int pow, int garbage)
{
UNUSED( garbage );
- int chance = 0;
+ int chance = 0;
+ int stuff = 0;
// if not in-bounds then we can't really shatter it -- bwr
if (x <= 5 || x >= GXM - 5 || y <= 5 || y >= GYM - 5)
@@ -293,6 +336,7 @@ static int shatter_walls(int x, int y, int pow, int garbage)
if (see_grid(x, y))
mpr("A secret door shatters!");
grd[x][y] = DNGN_FLOOR;
+ stuff = DEBRIS_WOOD;
chance = 100;
break;
@@ -301,42 +345,47 @@ static int shatter_walls(int x, int y, int pow, int garbage)
if (see_grid(x, y))
mpr("A door shatters!");
grd[x][y] = DNGN_FLOOR;
+ stuff = DEBRIS_WOOD;
chance = 100;
break;
case DNGN_METAL_WALL:
+ stuff = DEBRIS_METAL;
chance = pow / 10;
break;
case DNGN_ORCISH_IDOL:
case DNGN_GRANITE_STATUE:
chance = 50;
+ stuff = DEBRIS_STONE;
break;
- case DNGN_CLEAR_STONE_WALL:
case DNGN_STONE_WALL:
chance = pow / 6;
+ stuff = DEBRIS_STONE;
break;
- case DNGN_CLEAR_ROCK_WALL:
case DNGN_ROCK_WALL:
chance = pow / 4;
+ stuff = DEBRIS_ROCK;
break;
case DNGN_GREEN_CRYSTAL_WALL:
chance = 50;
+ stuff = DEBRIS_CRYSTAL;
break;
default:
break;
}
- if (random2(100) < chance)
+ if (stuff && random2(100) < chance)
{
if (!silenced( x, y ))
noisy( 30, x, y );
grd[x][y] = DNGN_FLOOR;
+ place_debris(x, y, stuff);
return (1);
}
@@ -401,16 +450,14 @@ void cast_forescry(int pow)
{
if (!you.duration[DUR_FORESCRY])
mpr("You begin to receive glimpses of the immediate future...");
- else
- mpr("Your vision of the future intensifies.");
you.duration[DUR_FORESCRY] += 5 + random2(pow);
if (you.duration[DUR_FORESCRY] > 30)
you.duration[DUR_FORESCRY] = 30;
- you.redraw_evasion = true;
-}
+ you.redraw_evasion = 1;
+} // end cast_forescry()
void cast_see_invisible(int pow)
{
@@ -424,7 +471,113 @@ void cast_see_invisible(int pow)
if (you.duration[DUR_SEE_INVISIBLE] > 100)
you.duration[DUR_SEE_INVISIBLE] = 100;
+} // end cast_see_invisible()
+
+#if 0
+// FIXME: This would be kinda cool if implemented right.
+// The idea is that, like detect_secret_doors, the spell gathers all
+// sorts of information about a thing and then tells the caster a few
+// cryptic hints. So for a (+3,+5) Mace of Flaming, one might detect
+// "enchantment and heat", but for a cursed ring of hunger, one might
+// detect "enchantment and ice" (since it gives you a 'deathly cold'
+// feeling when you put it on) or "necromancy" (since it's evil).
+// A weapon of Divine Wrath and a randart that makes you angry might
+// both give similar messages. The key would be to not tell more than
+// hints about whether an item is benign or cursed, but give info
+// on how strong its enchantment is (and therefore how valuable it
+// probably is).
+static void cast_detect_magic(int pow)
+{
+ struct dist bmove;
+ int x, y;
+ int monster = 0, item = 0, next; //int max;
+ FixedVector < int, NUM_SPELL_TYPES > found;
+ int strong = 0; // int curse = 0;
+
+ for (next = 0; next < NUM_SPELL_TYPES; next++)
+ {
+ found[next] = 0;
+ }
+
+ mpr("Which direction?", MSGCH_PROMPT);
+ direction( bmove, DIR_DIR, TARG_ANY, true );
+
+ if (!bmove.isValid)
+ {
+ canned_msg(MSG_SPELL_FIZZLES);
+ return;
+ }
+
+ if (bmove.dx == 0 && bmove.dy == 0)
+ {
+ mpr("You detect a divination in progress.");
+ return;
+ }
+
+ x = you.x_pos + bmove.dx;
+ y = you.y_pos + bmove.dy;
+
+ monster = mgrd[x][y];
+ if (monster == NON_MONSTER)
+ goto do_items;
+ else
+ goto all_done;
+
+ do_items:
+ item = igrd[x][y];
+
+ if (item == NON_ITEM)
+ goto all_done;
+
+ while (item != NON_ITEM)
+ {
+ next = mitm[item].link;
+ if (is_dumpable_artefact(mitm[item].base_type,
+ mitm[item].sub_type,
+ mitm[item].plus,
+ mitm[item].plus2,
+ mitm[item].special, 0, 0))
+ {
+ strong++;
+ //FIXME: do checks for randart properties
+ }
+ else
+ {
+ switch (mitm[item].base_type)
+ {
+ case OBJ_WEAPONS:
+ found[SPTYP_ENCHANTMENT] += (mitm[item].plus > 50);
+ found[SPTYP_ENCHANTMENT] += (mitm[item].plus2 > 50);
+ break;
+
+ case OBJ_MISSILES:
+ found[SPTYP_ENCHANTMENT] += (mitm[item].plus > 50);
+ found[SPTYP_ENCHANTMENT] += (mitm[item].plus2 > 50);
+ break;
+
+ case OBJ_ARMOUR:
+ found[SPTYP_ENCHANTMENT] += mitm[item].plus;
+ }
+ }
+ }
+
+ all_done:
+ if (monster)
+ {
+ mpr("You detect a morphogenic field, such as a monster might have.");
+ }
+ if (strong)
+ {
+ mpr("You detect very strong enchantments.");
+ return;
+ }
+ else
+ {
+ //FIXME:
+ }
+ return;
}
+#endif
// The description idea was okay, but this spell just isn't that exciting.
// So I'm converting it to the more practical expose secret doors. -- bwr
@@ -469,8 +622,7 @@ void cast_summon_butterflies(int pow)
for (int scount = 1; scount < num; scount++)
{
create_monster( MONS_BUTTERFLY, 3, BEH_FRIENDLY,
- you.x_pos, you.y_pos, MHITYOU, 250,
- false, false, false, true );
+ you.x_pos, you.y_pos, MHITYOU, 250 );
}
}
@@ -508,8 +660,7 @@ void cast_summon_large_mammal(int pow)
}
create_monster( mon, 3, BEH_FRIENDLY, you.x_pos, you.y_pos,
- you.pet_target, 250,
- false, false, false, true );
+ you.pet_target, 250 );
}
void cast_sticks_to_snakes(int pow)
@@ -550,8 +701,7 @@ void cast_sticks_to_snakes(int pow)
}
if (create_monster( mon, dur, behaviour, you.x_pos, you.y_pos,
- MHITYOU, 250,
- false, false, false, true ) != -1)
+ MHITYOU, 250 ) != -1)
{
how_many++;
}
@@ -596,10 +746,19 @@ void cast_sticks_to_snakes(int pow)
if (pow > 20 && one_chance_in(3))
mon = MONS_BROWN_SNAKE;
- create_monster(mon, dur, behaviour, you.x_pos, you.y_pos, MHITYOU, 250,
- false, false, false, true);
+ create_monster(mon, dur, behaviour, you.x_pos, you.y_pos, MHITYOU, 250);
}
+#ifdef USE_DEBRIS_CODE
+ if (you.inv[ weapon ].base_type == OBJ_DEBRIS
+ && (you.inv[ weapon ].sub_type == DEBRIS_WOOD))
+ {
+ // this is how you get multiple big snakes
+ how_many = 1;
+ mpr("FIXME: implement OBJ_DEBRIS conversion! (spells4.cc)");
+ }
+#endif // USE_DEBRIS_CODE
+
if (how_many > you.inv[you.equip[EQ_WEAPON]].quantity)
how_many = you.inv[you.equip[EQ_WEAPON]].quantity;
@@ -630,8 +789,7 @@ void cast_summon_dragon(int pow)
if (create_monster( MONS_DRAGON, 3,
(happy ? BEH_FRIENDLY : BEH_HOSTILE),
- you.x_pos, you.y_pos, MHITYOU, 250,
- false, false, false, true) != -1)
+ you.x_pos, you.y_pos, MHITYOU, 250 ) != -1)
{
mprf("A dragon appears.%s",
happy ? "" : " It doesn't look very happy.");
@@ -703,12 +861,12 @@ static int sleep_monsters(int x, int y, int pow, int garbage)
// if (mons_friendly( &menv[mnstr] )) return 0;
//jmf: now that sleep == hibernation:
- if (mons_res_cold( &menv[mnstr] ) > 0 && coinflip())
- return 0;
- if (menv[mnstr].has_ench(ENCH_SLEEP_WARY))
- return 0;
+ if (mons_res_cold( &menv[mnstr] ) > 0 && coinflip()) return 0;
+ if (menv[mnstr].has_ench(ENCH_SLEEP_WARY)) return 0;
- menv[mnstr].put_to_sleep();
+ menv[mnstr].behaviour = BEH_SLEEP;
+ menv[mnstr].add_ench(ENCH_SLEEPY);
+ menv[mnstr].add_ench(ENCH_SLEEP_WARY);
if (mons_class_flag( menv[mnstr].type, M_COLD_BLOOD ) && coinflip())
menv[mnstr].add_ench(ENCH_SLOW);
@@ -1073,15 +1231,28 @@ void cast_silence(int pow)
if (you.duration[DUR_SILENCE] > 100)
you.duration[DUR_SILENCE] = 100;
-
- if (you.duration[DUR_BEHELD])
- {
- mpr("You break out of your daze!", MSGCH_RECOVERY);
- you.duration[DUR_BEHELD] = 0;
- you.beheld_by.clear();
- }
} // end cast_silence()
+
+/* ******************************************************************
+// no hooks for this anywhere {dlb}:
+
+void cast_animate_golem(int pow)
+{
+ // must have more than 20 max_hitpoints
+
+ // must be wielding a Scroll of Paper (for chem)
+
+ // must be standing on a pile of <foo> (for foo in: wood, metal, rock, stone)
+
+ // Will cost you 5-10% of max_hitpoints, or 20 + some, whichever is more
+ mpr("You imbue the inanimate form with a portion of your life force.");
+
+ naughty(NAUGHTY_CREATED_LIFE, 10);
+}
+
+****************************************************************** */
+
static int discharge_monsters( int x, int y, int pow, int garbage )
{
UNUSED( garbage );
@@ -1187,12 +1358,12 @@ static int distortion_monsters(int x, int y, int pow, int message)
if (you.skills[SK_TRANSLOCATIONS] < random2(8))
{
miscast_effect( SPTYP_TRANSLOCATION, pow / 9 + 1, pow, 100,
- "cast bend on self" );
+ "a distortion effect" );
}
else
{
miscast_effect( SPTYP_TRANSLOCATION, 1, 1, 100,
- "cast bend on self" );
+ "a distortion effect" );
}
return 1;
@@ -1384,16 +1555,63 @@ static int make_a_rot_cloud(int x, int y, int pow, cloud_type ctype)
return 0;
} // end make_a_rot_cloud()
-int make_a_normal_cloud(int x, int y, int pow, int spread_rate,
- cloud_type ctype, kill_category whose)
+int make_a_normal_cloud(int x, int y, int pow, cloud_type ctype,
+ kill_category whose)
{
place_cloud( ctype, x, y,
(3 + random2(pow / 4) + random2(pow / 4) + random2(pow / 4)),
- whose, spread_rate );
+ whose );
return 1;
} // end make_a_normal_cloud()
+#if 0
+
+static int make_a_random_cloud(int x, int y, int pow, int ctype)
+{
+ if (ctype == CLOUD_NONE)
+ ctype = CLOUD_BLACK_SMOKE;
+
+ unsigned char cloud_material;
+
+ switch (random2(9))
+ {
+ case 0:
+ cloud_material = CLOUD_FIRE;
+ break;
+ case 1:
+ cloud_material = CLOUD_STINK;
+ break;
+ case 2:
+ cloud_material = CLOUD_COLD;
+ break;
+ case 3:
+ cloud_material = CLOUD_POISON;
+ break;
+ case 4:
+ cloud_material = CLOUD_BLUE_SMOKE;
+ break;
+ case 5:
+ cloud_material = CLOUD_STEAM;
+ break;
+ case 6:
+ cloud_material = CLOUD_PURP_SMOKE;
+ break;
+ default:
+ cloud_material = ctype;
+ break;
+ }
+
+ // that last bit is equivalent to "random2(pow/4) + random2(pow/4)
+ // + random2(pow/4)" {dlb}
+ // can you see the pattern? {dlb}
+ place_cloud(cloud_material, x, y, 3 + random2avg(3 * (pow / 4) - 2, 3));
+
+ return 1;
+} // end make_a_random_cloud()
+
+#endif
+
static int passwall(int x, int y, int pow, int garbage)
{
UNUSED( garbage );
@@ -1404,7 +1622,7 @@ static int passwall(int x, int y, int pow, int garbage)
int shallow = 1 + (you.skills[SK_EARTH_MAGIC] / 8);
// allow statues as entry points?
- if (grd[x][y] != DNGN_ROCK_WALL && grd[x][y] != DNGN_CLEAR_ROCK_WALL)
+ if (grd[x][y] != DNGN_ROCK_WALL)
// Irony: you can start on a secret door but not a door.
// Worked stone walls are out, they're not diggable and
// are used for impassable walls... I'm not sure we should
@@ -1433,7 +1651,6 @@ static int passwall(int x, int y, int pow, int garbage)
done = true;
break;
case DNGN_ROCK_WALL:
- case DNGN_CLEAR_ROCK_WALL:
case DNGN_ORCISH_IDOL:
case DNGN_GRANITE_STATUE:
case DNGN_SECRET_DOOR:
@@ -1505,12 +1722,8 @@ void cast_intoxicate(int pow)
{
potion_effect( POT_CONFUSION, 10 + (100 - pow) / 10);
- if (one_chance_in(20)
- && lose_stat( STAT_INTELLIGENCE, 1 + random2(3), false,
- "casting intoxication"))
- {
+ if (one_chance_in(20) && lose_stat( STAT_INTELLIGENCE, 1 + random2(3) ))
mpr("Your head spins!");
- }
apply_area_visible(intoxicate_monsters, pow);
} // end cast_intoxicate()
@@ -1972,8 +2185,7 @@ void cast_fulsome_distillation( int powc )
void make_shuggoth(int x, int y, int hp)
{
int mon = create_monster( MONS_SHUGGOTH, 100 + random2avg(58, 3),
- BEH_HOSTILE, x, y, MHITNOT, 250,
- false, false, false, true );
+ BEH_HOSTILE, x, y, MHITNOT, 250 );
if (mon != -1)
{
@@ -2303,11 +2515,9 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
// Stone and rock terrain
//
case DNGN_ROCK_WALL:
- case DNGN_CLEAR_ROCK_WALL:
case DNGN_SECRET_DOOR:
blast.colour = env.rock_colour;
// fall-through
- case DNGN_CLEAR_STONE_WALL:
case DNGN_STONE_WALL:
what = "wall";
if (player_in_branch( BRANCH_HALL_OF_ZOT ))
@@ -2334,11 +2544,7 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
&& (grid == DNGN_ORCISH_IDOL
|| grid == DNGN_GRANITE_STATUE
|| (pow >= 40 && grid == DNGN_ROCK_WALL && one_chance_in(3))
- || (pow >= 40 && grid == DNGN_CLEAR_ROCK_WALL
- && one_chance_in(3))
- || (pow >= 60 && grid == DNGN_STONE_WALL && one_chance_in(10))
- || (pow >= 60 && grid == DNGN_CLEAR_STONE_WALL &&
- one_chance_in(10)) ))
+ || (pow >= 60 && grid == DNGN_STONE_WALL && one_chance_in(10))))
{
// terrain blew up real good:
blast.ex_size = 2;
@@ -2448,6 +2654,7 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
: "The dungeon floor");
break;
+ case DNGN_TRAP_III: // What are these? Should they explode? -- bwr
default:
// FIXME: cute message for water?
break;
@@ -2466,6 +2673,9 @@ void cast_fragmentation(int pow) // jmf: ripped idea from airstrike
// if damage dice are zero we assume that nothing happened at all.
canned_msg(MSG_SPELL_FIZZLES);
}
+
+ if (debris)
+ place_debris(beam.tx, beam.ty, debris);
} // end cast_fragmentation()
void cast_twist(int pow)
@@ -2510,7 +2720,7 @@ void cast_twist(int pow)
return;
} // end cast_twist()
-bool cast_portal_projectile(int pow, bolt& beam)
+bool cast_portaled_projectile(int pow, bolt& beam)
{
if ( pow > 50 )
pow = 50;
@@ -2521,12 +2731,6 @@ bool cast_portal_projectile(int pow, bolt& beam)
return false;
}
- if (trans_wall_blocking( beam.target_x, beam.target_y ))
- {
- mpr("A translucent wall is in the way.");
- return 0;
- }
-
const int idx = get_fire_item_index();
if ( idx == ENDOFPACK )
{
@@ -2555,8 +2759,8 @@ bool cast_portal_projectile(int pow, bolt& beam)
void cast_far_strike(int pow)
{
- dist targ;
- bolt tmp; // used, but ignored
+ struct dist targ;
+ struct bolt tmp; // used, but ignored
// Get target, using DIR_TARGET for targetting only,
// since we don't use fire_beam() for this spell.
@@ -2564,39 +2768,37 @@ void cast_far_strike(int pow)
return;
// Get the target monster...
- if (mgrd[targ.tx][targ.ty] == NON_MONSTER || targ.isMe)
+ if (mgrd[targ.tx][targ.ty] == NON_MONSTER
+ || targ.isMe)
{
mpr("There is no monster there!");
return;
}
- if (trans_wall_blocking( targ.tx, targ.ty ))
- {
- mpr("A translucent wall is in the way.");
- return;
- }
-
// Start with weapon base damage...
+ const int weapon = you.equip[ EQ_WEAPON ];
int damage = 3; // default unarmed damage
int speed = 10; // default unarmed time
- if (you.weapon()) // if not unarmed
+ if (weapon != -1) // if not unarmed
{
- const item_def& wpn(*you.weapon());
// look up the damage base
- if (wpn.base_type == OBJ_WEAPONS)
+ if (you.inv[ weapon ].base_type == OBJ_WEAPONS)
{
- damage = property( wpn, PWPN_DAMAGE );
- speed = property( wpn, PWPN_SPEED );
+ damage = property( you.inv[ weapon ], PWPN_DAMAGE );
+ speed = property( you.inv[ weapon ], PWPN_SPEED );
- if (get_weapon_brand(wpn) == SPWPN_SPEED)
- speed /= 2;
+ if (get_weapon_brand( you.inv[ weapon ] ) == SPWPN_SPEED)
+ {
+ speed *= 5;
+ speed /= 10;
+ }
}
- else if (item_is_staff(wpn))
+ else if (item_is_staff( you.inv[ weapon ] ))
{
- damage = property(wpn, PWPN_DAMAGE );
- speed = property(wpn, PWPN_SPEED );
+ damage = property( you.inv[ weapon ], PWPN_DAMAGE );
+ speed = property( you.inv[ weapon ], PWPN_SPEED );
}
}
@@ -2637,12 +2839,21 @@ void cast_far_strike(int pow)
damage *= dammod;
damage /= 78;
- monsters *monster = &menv[ mgrd[targ.tx][targ.ty] ];
+ struct monsters *monster = &menv[ mgrd[targ.tx][targ.ty] ];
// apply monster's AC
if (monster->ac > 0)
damage -= random2( 1 + monster->ac );
+#if 0
+ // Removing damage limiter since it's categorized at level 4 right now.
+
+ // Force transmitted is limited by skill...
+ const int limit = (you.skills[SK_TRANSLOCATIONS] + 1) / 2 + 3;
+ if (damage > limit)
+ damage = limit;
+#endif
+
// Roll the damage...
damage = 1 + random2( damage );
@@ -2667,7 +2878,7 @@ void cast_far_strike(int pow)
int cast_apportation(int pow)
{
- dist beam;
+ struct dist beam;
mpr("Pull items from where?");
@@ -2686,12 +2897,6 @@ int cast_apportation(int pow)
return (-1);
}
- if (trans_wall_blocking( beam.tx, beam.ty ))
- {
- mpr("A translucent wall is in the way.");
- return (0);
- }
-
// Protect the player from destroying the item
const dungeon_feature_type grid = grd[ you.x_pos ][ you.y_pos ];
@@ -2779,7 +2984,7 @@ int cast_apportation(int pow)
&& mitm[item].sub_type == MI_THROWING_NET
&& item_is_stationary(mitm[item]))
{
- const int mon = mgrd[ beam.tx ][ beam.ty ];
+ int mon = mgrd[ beam.tx ][ beam.ty ];
remove_item_stationary(mitm[item]);
if (mon != NON_MONSTER)
@@ -2794,24 +2999,37 @@ int cast_apportation(int pow)
void cast_sandblast(int pow, bolt &beam)
{
- bool big = false;
+ bool big = true;
+
+ // this type of power manipulation should be done with the others,
+ // currently over in it_use2.cc (ack) -- bwr
+ // int hurt = 2 + random2(5) + random2(4) + random2(pow) / 20;
- if (you.weapon())
+ big = false;
+
+ if (you.equip[EQ_WEAPON] != -1)
{
- const item_def& wpn(*you.weapon());
- big = (wpn.base_type == OBJ_MISSILES)
- && (wpn.sub_type == MI_STONE || wpn.sub_type == MI_LARGE_ROCK);
+ int wep = you.equip[EQ_WEAPON];
+ if (you.inv[wep].base_type == OBJ_MISSILES
+ && (you.inv[wep].sub_type == MI_STONE
+ || you.inv[wep].sub_type == MI_LARGE_ROCK))
+ big = true;
}
if (big)
+ {
dec_inv_item_quantity( you.equip[EQ_WEAPON], 1 );
-
- zapping(big ? ZAP_SANDBLAST : ZAP_SMALL_SANDBLAST, pow, beam);
-}
+ zapping(ZAP_SANDBLAST, pow, beam);
+ }
+ else
+ {
+ zapping(ZAP_SMALL_SANDBLAST, pow, beam);
+ }
+} // end cast_sandblast()
void cast_condensation_shield(int pow)
{
- if (you.shield() || you.duration[DUR_FIRE_SHIELD])
+ if (you.equip[EQ_SHIELD] != -1 || you.duration[DUR_FIRE_SHIELD])
canned_msg(MSG_SPELL_FIZZLES);
else
{
@@ -2823,7 +3041,7 @@ void cast_condensation_shield(int pow)
else
{
mpr("A crackling disc of dense vapour forms in the air!");
- you.redraw_armour_class = true;
+ you.redraw_armour_class = 1;
you.duration[DUR_CONDENSATION_SHIELD] = 10 + roll_dice(2, pow / 5);
}
@@ -2855,35 +3073,20 @@ static int quadrant_blink(int x, int y, int pow, int garbage)
const int dist = random2(6) + 2; // 2-7
const int ox = you.x_pos + (x - you.x_pos) * dist;
const int oy = you.y_pos + (y - you.y_pos) * dist;
-
- // This can take a while if pow is high and there's lots of translucent
- // walls nearby.
+
int tx, ty;
- bool found = false;
for ( int i = 0; i < (pow*pow) / 500 + 1; ++i )
{
- // find a space near our target... First try to find a random
- // square not adjacent to the player, then one adjacent if
- // that fails.
- if ( !random_near_space(ox, oy, tx, ty) &&
- !random_near_space(ox, oy, tx, ty, true))
+ // find a space near our target...
+ if ( !random_near_space(ox, oy, tx, ty) )
return 0;
-
- // which is close enough, and also far enough from us
- if ( distance(ox, oy, tx, ty) > 10 &&
- distance(you.x_pos, you.y_pos, tx, ty) < 8 )
- continue;
-
- if (!see_grid_no_trans(tx, ty))
- continue;
- found = true;
- break;
+ // which is close enough, and also far enough from us
+ if ( distance(ox, oy, tx, ty) <= 10 &&
+ distance(you.x_pos, you.y_pos, tx, ty) >= 8 )
+ break;
}
- if (!found)
- return(0);
-
you.moveto(tx, ty);
return 1;
}