diff options
Diffstat (limited to 'crawl-ref/source/spells4.cc')
-rw-r--r-- | crawl-ref/source/spells4.cc | 439 |
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; } |