diff options
Diffstat (limited to 'crawl-ref/source/it_use3.cc')
-rw-r--r-- | crawl-ref/source/it_use3.cc | 437 |
1 files changed, 210 insertions, 227 deletions
diff --git a/crawl-ref/source/it_use3.cc b/crawl-ref/source/it_use3.cc index e3d33d45d8..126bdcdfb4 100644 --- a/crawl-ref/source/it_use3.cc +++ b/crawl-ref/source/it_use3.cc @@ -50,8 +50,10 @@ #include "spl-book.h" #include "spl-cast.h" #include "spl-util.h" +#include "state.h" #include "stuff.h" #include "view.h" +#include "xom.h" static bool ball_of_energy(void); static bool ball_of_fixation(void); @@ -248,94 +250,173 @@ void special_wielded() return; } // end special_wielded() -static void reaching_weapon_attack(void) +static bool reaching_weapon_attack(const item_def& wpn) { - struct dist beam; - int x_distance, y_distance; - int x_middle, y_middle; - int skill; + dist beam; mpr("Attack whom?", MSGCH_PROMPT); direction(beam, DIR_TARGET, TARG_ENEMY); + if (!beam.isValid) - return; + return false; if (beam.isMe) { canned_msg(MSG_UNTHINKING_ACT); - return; + return false; } - x_distance = abs(beam.tx - you.x_pos); - y_distance = abs(beam.ty - you.y_pos); + const int x_distance = abs(beam.tx - you.x_pos); + const int y_distance = abs(beam.ty - you.y_pos); if (x_distance > 2 || y_distance > 2) + { mpr("Your weapon cannot reach that far!"); + return false; + } else if (mgrd[beam.tx][beam.ty] == NON_MONSTER) { + // Must return true, otherwise you get a free discovery + // of invisible monsters. Maybe we shouldn't do practice + // here to prevent scumming...but that would just encourage + // finding popcorn monsters. mpr("You attack empty space."); + return true; } - else + + /* BCR - Added a check for monsters in the way. Only checks cardinal + * directions. Knight moves are ignored. Assume the weapon + * slips between the squares. + */ + + // if we're attacking more than a space away + if ((x_distance > 1) || (y_distance > 1)) { - /* BCR - Added a check for monsters in the way. Only checks cardinal - * directions. Knight moves are ignored. Assume the weapon - * slips between the squares. - */ + const int x_middle = MAX(beam.tx, you.x_pos) - (x_distance / 2); + const int y_middle = MAX(beam.ty, you.y_pos) - (y_distance / 2); - // if we're attacking more than a space away - if ((x_distance > 1) || (y_distance > 1)) + // if either the x or the y is the same, we should check for + // a monster: + if (((beam.tx == you.x_pos) || (beam.ty == you.y_pos)) + && (mgrd[x_middle][y_middle] != NON_MONSTER)) { - x_middle = MAX(beam.tx, you.x_pos) - (x_distance / 2); - y_middle = MAX(beam.ty, you.y_pos) - (y_distance / 2); + const int skill = weapon_skill( wpn.base_type, wpn.sub_type ); - // if either the x or the y is the same, we should check for - // a monster: - if (((beam.tx == you.x_pos) || (beam.ty == you.y_pos)) - && (mgrd[x_middle][y_middle] != NON_MONSTER)) + if ((5 + (3 * skill)) > random2(100)) { - skill = weapon_skill( you.inv[you.equip[EQ_WEAPON]].base_type, - you.inv[you.equip[EQ_WEAPON]].sub_type ); - - if ((5 + (3 * skill)) > random2(100)) - { - mpr("You reach to attack!"); - you_attack(mgrd[beam.tx][beam.ty], false); - } - else - { - mpr("You could not reach far enough!"); - you_attack(mgrd[x_middle][y_middle], false); - } + mpr("You reach to attack!"); + you_attack(mgrd[beam.tx][beam.ty], false); } else { - mpr("You reach to attack!"); - you_attack(mgrd[beam.tx][beam.ty], false); + mpr("You could not reach far enough!"); + you_attack(mgrd[x_middle][y_middle], false); } } else { + mpr("You reach to attack!"); you_attack(mgrd[beam.tx][beam.ty], false); } } + else + you_attack(mgrd[beam.tx][beam.ty], false); - return; + return true; } // end reaching_weapon_attack() +static bool evoke_horn_of_geryon() +{ + // Note: This assumes that the Vestibule has not been changed. + bool rc = false; + + if (player_in_branch( BRANCH_VESTIBULE_OF_HELL )) + { + mpr("You produce a weird and mournful sound."); + + for (int count_x = 0; count_x < GXM; count_x++) + { + for (int count_y = 0; count_y < GYM; count_y++) + { + if (grd[count_x][count_y] == DNGN_STONE_ARCH) + { + rc = true; + + map_marker *marker = + env.markers.find(coord_def(count_x, count_y), + MAT_FEATURE); + + if (marker) + { + map_feature_marker *featm = + dynamic_cast<map_feature_marker*>(marker); + grd[count_x][count_y] = featm->feat; + env.markers.remove(marker); + } + } + } + } + + if (rc) + mpr("Your way has been unbarred."); + } + else + { + mpr("You produce a hideous howling noise!"); + create_monster( MONS_BEAST, 4, BEH_HOSTILE, you.x_pos, you.y_pos, + MHITYOU, 250, false, false, false, true ); + } + return rc; +} + +static bool evoke_sceptre_of_asmodeus() +{ + bool rc = true; + if ( one_chance_in(21) ) + rc = false; + else if (one_chance_in(2)) + { + // summon devils, maybe a Fiend + const monster_type mtype = (one_chance_in(4) ? MONS_FIEND : + summon_any_demon(DEMON_COMMON)); + const bool good_summon = (create_monster( mtype, 6, BEH_HOSTILE, + you.x_pos, you.y_pos, + MHITYOU, 250) != -1); + + if (good_summon) + { + if (mtype == MONS_FIEND) + mpr("\"Your arrogance condemns you, mortal!\""); + else + mpr("The Sceptre summons one of its servants."); + } + else + mpr("The air shimmers briefly."); + } + else + { + // Cast a destructive spell + const spell_type spl = static_cast<spell_type>( + random_choose_weighted( 114, SPELL_BOLT_OF_FIRE, + 57, SPELL_LIGHTNING_BOLT, + 57, SPELL_BOLT_OF_DRAINING, + 12, SPELL_HELLFIRE, + 0 )); + your_spells( spl, you.skills[SK_EVOCATIONS] * 8, false ); + } + return true; +} + // returns true if item successfully evoked. -bool evoke_wielded( void ) +bool evoke_wielded() { - char opened_gates = 0; - unsigned char spell_casted = random2(21); - int count_x, count_y; - int temp_rand = 0; // for probability determination {dlb} int power = 0; int pract = 0; bool did_work = false; // used for default "nothing happens" message - int wield = you.equip[EQ_WEAPON]; + const int wield = you.equip[EQ_WEAPON]; if (you.duration[DUR_BERSERKER]) { @@ -345,6 +426,7 @@ bool evoke_wielded( void ) else if (wield == -1) { mpr("You aren't wielding anything!"); + crawl_state.zero_turns_taken(); return (false); } @@ -358,15 +440,18 @@ bool evoke_wielded( void ) switch (wpn.base_type) { case OBJ_WEAPONS: - if (get_weapon_brand( wpn ) == SPWPN_REACHING - && enough_mp(1, false)) + if (get_weapon_brand(wpn) == SPWPN_REACHING && enough_mp(1, false)) { - // needed a cost to prevent evocation training abuse -- bwr - dec_mp(1); - make_hungry( 50, false ); - reaching_weapon_attack(); - pract = (one_chance_in(5) ? 1 : 0); - did_work = true; + if ( reaching_weapon_attack(wpn) ) + { + // needed a cost to prevent evocation training abuse -- bwr + dec_mp(1); + make_hungry( 50, false ); + pract = (one_chance_in(5) ? 1 : 0); + did_work = true; + } + else + return false; } else if (is_fixed_artefact( wpn )) { @@ -391,56 +476,13 @@ bool evoke_wielded( void ) did_work = true; break; - // let me count the number of ways spell_casted is - // used here ... one .. two .. three ... >CRUNCH< - // three licks to get to the center of a ... {dlb} case SPWPN_SCEPTRE_OF_ASMODEUS: - spell_casted = random2(21); - - if (spell_casted == 0) - break; - - make_hungry( 200, false ); - pract = 1; - - if (spell_casted < 2) // summon devils, maybe a Fiend + if ( evoke_sceptre_of_asmodeus() ) { - - spell_casted = (one_chance_in(4) ? MONS_FIEND - : MONS_HELLION + random2(10)); - - bool good_summon = (create_monster( spell_casted, - 6, BEH_HOSTILE, - you.x_pos, you.y_pos, - MHITYOU, 250) != -1); - - if (good_summon) - { - if (spell_casted == MONS_FIEND) - mpr("\"Your arrogance condemns you, mortal!\""); - else - mpr("The Sceptre summons one of its servants."); - } - + make_hungry(200, false); did_work = true; - break; + pract = 1; } - - temp_rand = random2(240); - - if (temp_rand > 125) - spell_casted = SPELL_BOLT_OF_FIRE; // 114 in 240 - else if (temp_rand > 68) - spell_casted = SPELL_LIGHTNING_BOLT; // 57 in 240 - else if (temp_rand > 11) - spell_casted = SPELL_BOLT_OF_DRAINING; // 57 in 240 - else - spell_casted = SPELL_HELLFIRE; // 12 in 240 - - power = you.skills[SK_EVOCATIONS] * 8; - your_spells( static_cast<spell_type>(spell_casted), - power, false ); - did_work = true; break; case SPWPN_STAFF_OF_OLGREB: @@ -588,51 +630,8 @@ bool evoke_wielded( void ) break; case MISC_HORN_OF_GERYON: - // Note: This assumes that the Vestibule has not been changed. - if (player_in_branch( BRANCH_VESTIBULE_OF_HELL )) - { - mpr("You produce a weird and mournful sound."); - - for (count_x = 0; count_x < GXM; count_x++) - { - for (count_y = 0; count_y < GYM; count_y++) - { - if (grd[count_x][count_y] == DNGN_STONE_ARCH) - { - opened_gates++; - - map_marker *marker = - env.markers.find(coord_def(count_x, count_y), - MAT_FEATURE); - - if (marker) - { - map_feature_marker *featm = - dynamic_cast<map_feature_marker*>(marker); - grd[count_x][count_y] = featm->feat; - env.markers.remove(marker); - } - } - } - } - - if (opened_gates) - { - mpr("Your way has been unbarred."); - pract = 1; - } - } - else - { - mpr("You produce a hideous howling noise!"); - int midx = create_monster( MONS_BEAST, 4, - BEH_HOSTILE, you.x_pos, you.y_pos, - MHITYOU, 250 ); - // avoid scumming; also prevents it from showing up on notes - if ( midx != -1 ) - menv[midx].flags |= MF_CREATED_FRIENDLY; - // no practice - } + if ( evoke_horn_of_geryon() ) + pract = 1; break; case MISC_BOX_OF_BEASTS: @@ -674,6 +673,8 @@ bool evoke_wielded( void ) if (!unevokable) you.turn_is_over = true; + else + crawl_state.zero_turns_taken(); return (did_work); } // end evoke_wielded() @@ -719,7 +720,7 @@ static bool ball_of_seeing(void) if (use < 2) { - lose_stat( STAT_INTELLIGENCE, 1 ); + lose_stat( STAT_INTELLIGENCE, 1, false, "using a ball of seeing"); } else if (use < 5 && enough_mp(1, true)) { @@ -795,16 +796,11 @@ static bool disc_of_storms(void) return (ret); } // end disc_of_storms() -void tome_of_power(char sc_read_2) +void tome_of_power(int slot) { - int temp_rand = 0; // probability determination {dlb} - int powc = 5 + you.skills[SK_EVOCATIONS] + roll_dice( 5, you.skills[SK_EVOCATIONS] ); - spell_type spell_casted = SPELL_NO_SPELL; - struct bolt beam; - msg::stream << "The book opens to a page covered in " << weird_writing() << '.' << std::endl; @@ -813,7 +809,7 @@ void tome_of_power(char sc_read_2) if (!yesno("Read it?")) return; - set_ident_flags( you.inv[sc_read_2], ISFLAG_IDENT_MASK ); + set_ident_flags( you.inv[slot], ISFLAG_KNOW_TYPE ); if (you.mutation[MUT_BLURRY_VISION] > 0 && random2(4) < you.mutation[MUT_BLURRY_VISION]) @@ -825,46 +821,35 @@ void tome_of_power(char sc_read_2) mpr("You find yourself reciting the magical words!"); exercise( SK_EVOCATIONS, 1 ); - temp_rand = random2(50) + random2( you.skills[SK_EVOCATIONS] / 3 ); - - switch (random2(50)) + if ( random2(50) < 7 ) { - case 0: - case 3: - case 4: - case 6: - case 7: - case 8: - case 9: mpr("A cloud of weird smoke pours from the book's pages!"); big_cloud( random_smoke_type(), KC_YOU, you.x_pos, you.y_pos, 20, 10 + random2(8) ); xom_is_stimulated(16); - return; - case 1: - case 14: + } + else if ( random2(43) < 2 ) + { mpr("A cloud of choking fumes pours from the book's pages!"); big_cloud(CLOUD_POISON, KC_YOU, you.x_pos, you.y_pos, 20, 7 + random2(5)); xom_is_stimulated(64); - return; - - case 2: - case 13: + } + else if ( random2(41) < 2 ) + { mpr("A cloud of freezing gas pours from the book's pages!"); big_cloud(CLOUD_COLD, KC_YOU, you.x_pos, you.y_pos, 20, 8 + random2(5)); xom_is_stimulated(64); - return; - - case 5: - case 11: - case 12: + } + else if ( random2(39) < 3 ) + { if (one_chance_in(5)) { mpr("The book disappears in a mighty explosion!"); - dec_inv_item_quantity( sc_read_2, 1 ); + dec_inv_item_quantity( slot, 1 ); } + bolt beam; beam.type = SYM_BURST; beam.damage = dice_def( 3, 15 ); // unsure about this // BEAM_EXPLOSION instead? [dlb] @@ -876,16 +861,16 @@ void tome_of_power(char sc_read_2) // your explosion, (not someone else's explosion) beam.beam_source = NON_MONSTER; beam.thrower = KILL_YOU; - beam.aux_source = "an exploding Tome of Power"; + beam.aux_source = "an exploding tome of Destruction"; beam.ex_size = 2; beam.is_tracer = false; beam.is_explosion = true; explosion(beam); xom_is_stimulated(255); - return; - - case 10: + } + else if (one_chance_in(36)) + { if (create_monster( MONS_ABOMINATION_SMALL, 6, BEH_HOSTILE, you.x_pos, you.y_pos, MHITYOU, 250 ) != -1) { @@ -893,65 +878,62 @@ void tome_of_power(char sc_read_2) mpr("It doesn't look too friendly."); } xom_is_stimulated(255); - return; } + else + { + viewwindow(1, false); - viewwindow(1, false); - - temp_rand = random2(23) + random2( you.skills[SK_EVOCATIONS] / 3 ); - - if (temp_rand > 25) - temp_rand = 25; - - spell_casted = ((temp_rand > 19) ? SPELL_FIREBALL : - (temp_rand > 16) ? SPELL_BOLT_OF_FIRE : - (temp_rand > 13) ? SPELL_BOLT_OF_COLD : - (temp_rand > 11) ? SPELL_LIGHTNING_BOLT : - (temp_rand > 10) ? SPELL_LEHUDIBS_CRYSTAL_SPEAR : - (temp_rand > 9) ? SPELL_VENOM_BOLT : - (temp_rand > 8) ? SPELL_BOLT_OF_DRAINING : - (temp_rand > 7) ? SPELL_BOLT_OF_INACCURACY : - (temp_rand > 6) ? SPELL_STICKY_FLAME : - (temp_rand > 5) ? SPELL_TELEPORT_SELF : - (temp_rand > 4) ? SPELL_CIGOTUVIS_DEGENERATION : - (temp_rand > 3) ? SPELL_POLYMORPH_OTHER : - (temp_rand > 2) ? SPELL_MEPHITIC_CLOUD : - (temp_rand > 1) ? SPELL_THROW_FLAME : - (temp_rand > 0) ? SPELL_THROW_FROST - : SPELL_MAGIC_DART); - - your_spells( spell_casted, powc, false ); -} // end tome_of_power() - -void skill_manual(char sc_read_2) -{ - set_ident_flags( you.inv[sc_read_2], ISFLAG_IDENT_MASK ); - - const int skill = you.inv[sc_read_2].plus; - - const char* skname = skill_name(skill); - mprf("This is a manual of %s!", skname); + int temp_rand = random2(23) + random2(you.skills[SK_EVOCATIONS] / 3); + + if (temp_rand > 25) + temp_rand = 25; + + const spell_type spell_casted = + ((temp_rand > 24) ? SPELL_LEHUDIBS_CRYSTAL_SPEAR : + (temp_rand > 21) ? SPELL_BOLT_OF_FIRE : + (temp_rand > 18) ? SPELL_BOLT_OF_COLD : + (temp_rand > 16) ? SPELL_LIGHTNING_BOLT : + (temp_rand > 10) ? SPELL_FIREBALL : + (temp_rand > 9) ? SPELL_VENOM_BOLT : + (temp_rand > 8) ? SPELL_BOLT_OF_DRAINING : + (temp_rand > 7) ? SPELL_BOLT_OF_INACCURACY : + (temp_rand > 6) ? SPELL_STICKY_FLAME : + (temp_rand > 5) ? SPELL_TELEPORT_SELF : + (temp_rand > 4) ? SPELL_CIGOTUVIS_DEGENERATION : + (temp_rand > 3) ? SPELL_POLYMORPH_OTHER : + (temp_rand > 2) ? SPELL_MEPHITIC_CLOUD : + (temp_rand > 1) ? SPELL_THROW_FLAME : + (temp_rand > 0) ? SPELL_THROW_FROST + : SPELL_MAGIC_DART); + + your_spells( spell_casted, powc, false ); + } +} +void skill_manual(int slot) +{ + // Removed confirmation request because you know it's + // a manual in advance. you.turn_is_over = true; + item_def& manual(you.inv[slot]); + set_ident_flags( manual, ISFLAG_KNOW_TYPE ); + const int skill = manual.plus; - if (!yesno("Read it?")) - return; - - mprf("You read about %s.", skname); + mprf("You read about %s.", skill_name(skill)); exercise(skill, 500); if (one_chance_in(10)) { - mpr("The book crumbles into dust."); - dec_inv_item_quantity( sc_read_2, 1 ); + mpr("The manual crumbles into dust."); + dec_inv_item_quantity( slot, 1 ); } else { - mpr("The book looks somewhat more worn."); + mpr("The manual looks somewhat more worn."); } xom_is_stimulated(14); -} // end skill_manual() +} static bool box_of_beasts() { @@ -1016,7 +998,7 @@ static bool ball_of_energy(void) if (use < 2 || you.max_magic_points == 0) { - lose_stat(STAT_INTELLIGENCE, 1); + lose_stat(STAT_INTELLIGENCE, 1, false, "using a ball of energy"); } else if ((use < 4 && enough_mp(1, true)) || you.magic_points == you.max_magic_points) @@ -1049,15 +1031,16 @@ static bool ball_of_energy(void) } return (ret); -} // end ball_of_energy() +} static bool ball_of_fixation(void) { mpr("You gaze into the crystal ball."); mpr("You are mesmerised by a rainbow of scintillating colours!"); - you.duration[DUR_PARALYSIS] = 100; - you.duration[DUR_SLOW] = 100; + const int duration = random_range(15, 40); + you.duration[DUR_PARALYSIS] = duration; + you.duration[DUR_SLOW] = duration; return (true); -} // end ball_of_fixation() +} |