diff options
Diffstat (limited to 'crawl-ref/source/item_use.cc')
-rw-r--r-- | crawl-ref/source/item_use.cc | 450 |
1 files changed, 338 insertions, 112 deletions
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index c6e724b10a..4187ef411e 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -36,6 +36,7 @@ #include "beam.h" #include "cio.h" +#include "cloud.h" #include "command.h" #include "debug.h" #include "delay.h" @@ -61,6 +62,7 @@ #include "player.h" #include "randart.h" #include "religion.h" +#include "shopping.h" #include "skills.h" #include "skills2.h" #include "spells1.h" @@ -69,10 +71,12 @@ #include "spl-book.h" #include "spl-cast.h" #include "spl-util.h" +#include "state.h" #include "stuff.h" #include "transfor.h" #include "tutorial.h" #include "view.h" +#include "xom.h" static bool drink_fountain(); static bool enchant_armour(); @@ -232,7 +236,9 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) { if (you.equip[EQ_WEAPON] != -1) { - unwield_item(show_weff_messages); + if (!unwield_item(show_weff_messages)) + return (false); + canned_msg( MSG_EMPTY_HANDED ); you.turn_is_over = true; @@ -256,9 +262,12 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) if (!can_wield(&you.inv[item_slot], true)) return (false); + if (!safe_to_remove_or_wear(you.inv[item_slot], false)) + return (false); + // Go ahead and wield the weapon. - if (you.equip[EQ_WEAPON] != -1) - unwield_item(show_weff_messages); + if (you.equip[EQ_WEAPON] != -1 && !unwield_item(show_weff_messages)) + return (false); you.equip[EQ_WEAPON] = item_slot; @@ -400,6 +409,8 @@ void wield_effects(int item_wield_2, bool showMsgs) { unsigned char i_dam = 0; + const bool known_cursed = item_known_cursed(you.inv[item_wield_2]); + // and here we finally get to the special effects of wielding {dlb} if (you.inv[item_wield_2].base_type == OBJ_MISCELLANY) { @@ -421,6 +432,7 @@ void wield_effects(int item_wield_2, bool showMsgs) // inc_max_mp(13); calc_mp(); set_ident_flags( you.inv[item_wield_2], ISFLAG_EQ_WEAPON_MASK ); + mpr("You feel your mana capacity increase."); } else { @@ -592,7 +604,11 @@ void wield_effects(int item_wield_2, bool showMsgs) break; case SPWPN_DISTORTION: - miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, "a distortion effect" ); + if (!was_known) + xom_is_stimulated(128); + miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, + was_known ? "distortion wield" : + "unknowing distortion wield"); break; case SPWPN_SINGING_SWORD: @@ -644,7 +660,10 @@ void wield_effects(int item_wield_2, bool showMsgs) if (item_cursed( you.inv[item_wield_2] )) { mpr("It sticks to your hand!"); - xom_is_stimulated(64); + if (known_cursed) + xom_is_stimulated(32); + else + xom_is_stimulated(64); } } @@ -710,7 +729,8 @@ void wear_armour(void) if (!armour_prompt("Wear which item?", &armour_wear_2, OPER_WEAR)) return; - do_wear_armour( armour_wear_2, false ); + if (safe_to_remove_or_wear(you.inv[armour_wear_2], false)) + do_wear_armour( armour_wear_2, false ); } static int armour_equip_delay(const item_def &item) @@ -757,8 +777,7 @@ bool can_wear_armour(const item_def &item, bool verbose, bool ignore_temporary) if (sub_type == ARM_GLOVES) { - if (you.species == SP_TROLL || you.species == SP_GHOUL - || you.mutation[MUT_CLAWS] >= 3) + if (you.has_claws(false) >= 3) { if (verbose) mpr( "You can't wear gloves with your huge claws!" ); @@ -776,6 +795,20 @@ bool can_wear_armour(const item_def &item, bool verbose, bool ignore_temporary) return (false); } + if (you.mutation[MUT_TALONS]) + { + if (verbose) + mpr("Boots don't fit your talons!"); + return (false); + } + + if (you.mutation[MUT_PAWS]) + { + if (verbose) + mpr("Boots don't fit your paws!"); + return (false); + } + if (you.species == SP_NAGA) { if (verbose) @@ -991,6 +1024,9 @@ bool do_wear_armour( int item, bool quiet ) return (false); } + if (!safe_to_remove_or_wear(you.inv[item], false)) + return (false); + you.turn_is_over = true; int delay = armour_equip_delay( you.inv[item] ); @@ -1024,6 +1060,9 @@ bool takeoff_armour(int item) } } + if (!safe_to_remove_or_wear(you.inv[item], true)) + return (false); + bool removedCloak = false; int cloak = -1; const equipment_type slot = get_armour_slot(you.inv[item]); @@ -1164,6 +1203,20 @@ static bool fire_item_matches(const item_def &item, unsigned fire_type) if (!is_valid_item(item)) return (false); + if (you.attribute[ATTR_HELD]) + { + if (item.base_type == OBJ_MISSILES) + { + const item_def *weapon = you.weapon(); + if (weapon && weapon->sub_type == WPN_BLOWGUN + && item.launched_by(*weapon)) + { + return (true); + } + } + return (false); + } + if (item.base_type == OBJ_MISSILES) { if ((fire_type & FIRE_DART) && item.sub_type == MI_DART) @@ -1474,6 +1527,18 @@ int launcher_final_speed(const item_def &launcher, const item_def *shield) speed_base = speed_base * speed_adjust / 100; speed_min = speed_min * speed_adjust / 100; } + + // do the same when trying to shoot while held in a net + if (you.attribute[ATTR_HELD]) // only for blowguns + { + int speed_adjust = 105; // analogous to buckler and one-handed weapon + speed_adjust -= ((speed_adjust - 100) * 5 / 10) + * you.skills[SK_THROWING] / 27; + + // also reduce the speed cap. + speed_base = speed_base * speed_adjust / 100; + speed_min = speed_min * speed_adjust / 100; + } int speed = speed_base - 4 * shoot_skill * speed_stat / 250; if (speed < speed_min) @@ -1744,6 +1809,12 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, } } } + + // lower accuracy if held in a net (needs testing) + if (you.attribute[ATTR_HELD]) + { + baseHit--; + } // for all launched weapons, maximum effective specific skill // is twice throwing skill. This models the fact that no matter @@ -2006,8 +2077,15 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, { // elves with elven weapons if (get_equip_race(item) == ISFLAG_ELVEN - && player_genus(GENPC_ELVEN)) + && player_genus(GENPC_ELVEN)) baseHit += 1; + if ( (get_equip_race(item) == ISFLAG_DWARVEN + && player_genus(GENPC_DWARVEN)) || + (get_equip_race(item) == ISFLAG_ORCISH + && you.species == SP_HILL_ORC)) + { + baseDam += 1; + } // give an appropriate 'tohit' - // hand axes and clubs are -5 @@ -2210,7 +2288,7 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, pbolt.damage.size += ammoDamBonus + lnchDamBonus; } - // Add in bonus (only from Portaled Projectile for now) + // Add in bonus (only from Portal Projectile for now) if (acc_bonus != DEBUG_COOKIE) pbolt.hit += acc_bonus; @@ -2285,13 +2363,18 @@ bool throw_it(bolt &pbolt, int throw_2, bool teleport, int acc_bonus, void jewellery_wear_effects(item_def &item) { - item_type_id_state_type ident = ID_TRIED_TYPE; + item_type_id_state_type ident = ID_TRIED_TYPE; + randart_prop_type fake_rap = RAP_NUM_PROPERTIES; + bool learn_pluses = false; // Randart jewellery shouldn't auto-ID just because the // base type is known. Somehow the player should still // be told, preferably by message. (jpeg) - const bool artefact = is_random_artefact( item ); - const bool identified = fully_identified( item ); + const bool artefact = is_random_artefact( item ); + const bool known_pluses = item_ident( item, ISFLAG_KNOW_PLUSES ); + const bool known_cursed = item_known_cursed( item ); + const bool known_bad = item_type_known( item ) + && (item_value( item ) <= 2); switch (item.sub_type) { @@ -2318,11 +2401,12 @@ void jewellery_wear_effects(item_def &item) { if (!artefact) ident = ID_KNOWN_TYPE; - else if (!identified) + else if (!known_pluses) { mprf("You feel %s.", item.plus > 0? "well-protected" : "more vulnerable"); } + learn_pluses = true; } break; @@ -2330,7 +2414,9 @@ void jewellery_wear_effects(item_def &item) if (!you.duration[DUR_INVIS]) { mpr("You become transparent for a moment."); - if (!artefact) + if (artefact) + fake_rap = RAP_INVISIBLE; + else ident = ID_KNOWN_TYPE; } break; @@ -2341,32 +2427,39 @@ void jewellery_wear_effects(item_def &item) { if (!artefact) ident = ID_KNOWN_TYPE; - else if (!identified) + else if (!known_pluses) mprf("You feel %s.", item.plus > 0? "nimbler" : "more awkward"); + learn_pluses = true; } break; case RING_STRENGTH: - modify_stat(STAT_STRENGTH, item.plus, !artefact); + modify_stat(STAT_STRENGTH, item.plus, !artefact, item); if (item.plus != 0 && !artefact) ident = ID_KNOWN_TYPE; + learn_pluses = true; break; case RING_DEXTERITY: - modify_stat(STAT_DEXTERITY, item.plus, !artefact); + modify_stat(STAT_DEXTERITY, item.plus, !artefact, item); if (item.plus != 0 && !artefact) ident = ID_KNOWN_TYPE; + learn_pluses = true; break; case RING_INTELLIGENCE: - modify_stat(STAT_INTELLIGENCE, item.plus, !artefact); + modify_stat(STAT_INTELLIGENCE, item.plus, !artefact, item); if (item.plus != 0 && !artefact) ident = ID_KNOWN_TYPE; + learn_pluses = true; break; case RING_MAGICAL_POWER: + mpr("You feel your mana capacity increase."); calc_mp(); - if (!artefact) + if (artefact) + fake_rap = RAP_MAGICAL_POWER; + else ident = ID_KNOWN_TYPE; break; @@ -2374,7 +2467,9 @@ void jewellery_wear_effects(item_def &item) if (!scan_randarts( RAP_LEVITATE )) { mpr("You feel buoyant."); - if (!artefact) + if (artefact) + fake_rap = RAP_LEVITATE; + else ident = ID_KNOWN_TYPE; } break; @@ -2383,7 +2478,9 @@ void jewellery_wear_effects(item_def &item) if (!scan_randarts( RAP_CAN_TELEPORT )) { mpr("You feel slightly jumpy."); - if (!artefact) + if (artefact) + fake_rap = RAP_CAUSE_TELEPORTATION; + else ident = ID_KNOWN_TYPE; } break; @@ -2392,7 +2489,9 @@ void jewellery_wear_effects(item_def &item) if (!scan_randarts( RAP_BERSERK )) { mpr("You feel a brief urge to hack something to bits."); - if (!artefact) + if (artefact) + fake_rap = RAP_BERSERK; + else ident = ID_KNOWN_TYPE; } break; @@ -2405,19 +2504,33 @@ void jewellery_wear_effects(item_def &item) // Artefacts have completely different appearance than base types // so we don't allow them to make the base types known if (artefact) + { use_randart(item); + + if (learn_pluses && (item.plus != 0 || item.plus2 != 0)) + set_ident_flags( item, ISFLAG_KNOW_PLUSES ); + + if (fake_rap != RAP_NUM_PROPERTIES) + randart_wpn_learn_prop( item, fake_rap ); + } else + { set_ident_type( item.base_type, item.sub_type, ident ); - if (ident == ID_KNOWN_TYPE) - set_ident_flags( item, ISFLAG_EQ_JEWELLERY_MASK ); + if (ident == ID_KNOWN_TYPE) + set_ident_flags( item, ISFLAG_EQ_JEWELLERY_MASK ); + } if (item_cursed( item )) { mprf("Oops, that %s feels deathly cold.", jewellery_is_amulet(item)? "amulet" : "ring"); learned_something_new(TUT_YOU_CURSED); - xom_is_stimulated(128); + + if (known_cursed || known_bad) + xom_is_stimulated(64); + else + xom_is_stimulated(128); } // cursed or not, we know that since we've put the ring on @@ -2467,6 +2580,77 @@ static int prompt_ring_to_remove(int new_ring) return (you.equip[eqslot]); } +// Checks whether a to-be-worn or to-be-removed item affects +// character stats and whether wearing/removing it could be fatal. +// If so, warns the player. +bool safe_to_remove_or_wear(const item_def &item, bool remove) +{ + int prop_str = 0; + int prop_dex = 0; + int prop_int = 0; + + // don't warn when putting on an unknown item + if (item.base_type == OBJ_JEWELLERY && item_ident( item, ISFLAG_KNOW_PLUSES )) + { + switch (item.sub_type) + { + case RING_STRENGTH: + if (item.plus != 0) + prop_str = item.plus; + break; + case RING_DEXTERITY: + if (item.plus != 0) + prop_dex = item.plus; + break; + case RING_INTELLIGENCE: + if (item.plus != 0) + prop_int = item.plus; + break; + default: + break; + } + } + + if (is_random_artefact( item )) + { + prop_str += randart_known_wpn_property(item, RAP_STRENGTH); + prop_int += randart_known_wpn_property(item, RAP_INTELLIGENCE); + prop_dex += randart_known_wpn_property(item, RAP_DEXTERITY); + } + + if (remove) + { + std::string prompt = item.base_type == OBJ_WEAPONS ? "Unwield" : "Remov"; + prompt += "ing this item could be fatal. "; + prompt += item.base_type == OBJ_WEAPONS ? "Unwield" : "Remove"; + prompt += " anyway? "; + + if ((prop_str >= you.strength || prop_int >= you.intel || + prop_dex >= you.dex) + && !yesno(prompt.c_str(), false, 'n')) + { + return (false); + } + } + else // put on + { + std::string prompt = item.base_type == OBJ_WEAPONS ? "Wield" : "Wear"; + prompt += "ing this item could be fatal. "; + prompt += item.base_type == OBJ_WEAPONS ? "Wield" : "Put on"; + prompt += " anyway? "; + + if ((-prop_str >= you.strength || -prop_int >= you.intel || + -prop_dex >= you.dex) + && !yesno(prompt.c_str(), false, 'n')) + { + return (false); + } + } + + + return (true); +} + // Assumptions: // you.inv[ring_slot] is a valid ring. // EQ_LEFT_RING and EQ_RIGHT_RING are both occupied, and ring_slot is not @@ -2485,7 +2669,10 @@ static bool swap_rings(int ring_slot) if (!remove_ring(unwanted, false)) return (false); - + + if (!safe_to_remove_or_wear(you.inv[ring_slot], false)) + return (false); + start_delay(DELAY_JEWELLERY_ON, 1, ring_slot); return (true); @@ -2535,12 +2722,18 @@ bool puton_item(int item_slot, bool prompt_finger) !remove_ring( you.equip[EQ_AMULET], true )) return false; + if (!safe_to_remove_or_wear(you.inv[item_slot], false)) + return (false); + start_delay(DELAY_JEWELLERY_ON, 1, item_slot); // Assume it's going to succeed. return (true); } + if (!safe_to_remove_or_wear(you.inv[item_slot], false)) + return (false); + // First ring goes on left hand if we're choosing automatically. int hand_used = 0; @@ -2658,15 +2851,15 @@ void jewellery_remove_effects(item_def &item) break; case RING_STRENGTH: - modify_stat(STAT_STRENGTH, -item.plus, true); + modify_stat(STAT_STRENGTH, -item.plus, true, item, true); break; case RING_DEXTERITY: - modify_stat(STAT_DEXTERITY, -item.plus, true); + modify_stat(STAT_DEXTERITY, -item.plus, true, item, true); break; case RING_INTELLIGENCE: - modify_stat(STAT_INTELLIGENCE, -item.plus, true); + modify_stat(STAT_INTELLIGENCE, -item.plus, true, item, true); break; case RING_INVISIBILITY: @@ -2682,6 +2875,7 @@ void jewellery_remove_effects(item_def &item) break; case RING_MAGICAL_POWER: + mpr("You feel your mana capacity decrease."); // dec_max_mp(9); break; @@ -2806,8 +3000,12 @@ bool remove_ring(int slot, bool announce) set_ident_flags( you.inv[you.equip[hand_used]], ISFLAG_KNOW_CURSE ); return (false); } - + ring_wear_2 = you.equip[hand_used]; + + if (!safe_to_remove_or_wear(you.inv[ring_wear_2], true)) + return (false); + you.equip[hand_used] = -1; jewellery_remove_effects(you.inv[ring_wear_2]); @@ -2881,19 +3079,21 @@ void zap_wand(void) const bool dangerous = player_in_a_dangerous_place(); if (alreadyknown) { - if (wand.sub_type == WAND_TELEPORTATION) + switch ( wand.sub_type ) { + case WAND_TELEPORTATION: targ_mode = TARG_ANY; - } - else if (wand.sub_type == WAND_HASTING - || wand.sub_type == WAND_HEALING - || wand.sub_type == WAND_INVISIBILITY) - { + break; + + case WAND_HASTING: + case WAND_HEALING: + case WAND_INVISIBILITY: targ_mode = TARG_FRIEND; - } - else - { + break; + + default: targ_mode = TARG_ENEMY; + break; } } @@ -2913,28 +3113,10 @@ void zap_wand(void) zap_wand.ty = you.y_pos + random2(13) - 6; } - // blargh! blech! this is just begging to be a problem ... - // not to mention work-around after work-around as wands are - // added, removed, or altered {dlb}: - char type_zapped = wand.sub_type; - - if (type_zapped == WAND_ENSLAVEMENT) - type_zapped = ZAP_ENSLAVEMENT; - - if (type_zapped == WAND_DRAINING) - type_zapped = ZAP_NEGATIVE_ENERGY; - - if (type_zapped == WAND_DISINTEGRATION) - type_zapped = ZAP_DISINTEGRATION; - - if (type_zapped == WAND_RANDOM_EFFECTS) + const zap_type type_zapped = static_cast<zap_type>(wand.zap()); + if (wand.sub_type == WAND_RANDOM_EFFECTS) { - type_zapped = random2(16); beam.effect_known = false; - if (one_chance_in(20)) - type_zapped = ZAP_NEGATIVE_ENERGY; - if (one_chance_in(17)) - type_zapped = ZAP_ENSLAVEMENT; if (dangerous) { // Xom loves it when you use a Wand of Random Effects and @@ -2947,6 +3129,7 @@ void zap_wand(void) beam.source_y = you.y_pos; beam.set_target(zap_wand); + // zapping() updates beam zapping( static_cast<zap_type>(type_zapped), 30 + roll_dice(2, you.skills[SK_EVOCATIONS]), beam ); @@ -2975,7 +3158,8 @@ void zap_wand(void) { if (!item_ident( wand, ISFLAG_KNOW_PLUSES )) { - mpr("Your skill with magical items lets you calculate the power of this device..."); + mpr("Your skill with magical items lets you calculate " + "the power of this device..."); } mprf("This wand has %d charge%s left.", @@ -3053,7 +3237,7 @@ void drink(void) return; } - if (inv_count() < 1) + if (inv_count() == 0) { canned_msg(MSG_NOTHING_CARRIED); return; @@ -3189,7 +3373,10 @@ bool drink_fountain() if (one_chance_in(10)) gone_dry = true; else if ( random2(50) > 40 ) // no message! + { grd[you.x_pos][you.y_pos] = DNGN_BLUE_FOUNTAIN; + set_terrain_changed(you.x_pos, you.y_pos); + } } if (gone_dry) @@ -3199,6 +3386,10 @@ bool drink_fountain() grd[you.x_pos][you.y_pos] = DNGN_DRY_FOUNTAIN_I; else grd[you.x_pos][you.y_pos] = DNGN_DRY_FOUNTAIN_II; + + set_terrain_changed(you.x_pos, you.y_pos); + + crawl_state.cancel_cmd_repeat(); } you.turn_is_over = true; @@ -3268,8 +3459,8 @@ static bool affix_weapon_enchantment() success = false; // is only naughty if you know you're doing it - if (get_ident_type(OBJ_SCROLLS, SCR_ENCHANT_WEAPON_III)==ID_KNOWN_TYPE) - did_god_conduct(DID_UNHOLY, 10); + did_god_conduct(DID_UNHOLY, 10, + get_ident_type(OBJ_SCROLLS, SCR_ENCHANT_WEAPON_III)==ID_KNOWN_TYPE); break; @@ -3280,7 +3471,7 @@ static bool affix_weapon_enchantment() // from unwield_item miscast_effect( SPTYP_TRANSLOCATION, 9, 90, 100, - "a distortion effect" ); + "distortion affixation" ); success = false; break; @@ -3295,7 +3486,7 @@ static bool affix_weapon_enchantment() return (success); } -bool enchant_weapon( int which_stat, bool quiet ) +bool enchant_weapon( enchant_stat_type which_stat, bool quiet ) { const int wpn = you.equip[ EQ_WEAPON ]; bool affected = true; @@ -3489,20 +3680,17 @@ static bool enchant_armour( void ) static void handle_read_book( int item_slot ) { - int spell, spell_index; + item_def& book(you.inv[item_slot]); - if (you.inv[item_slot].sub_type == BOOK_DESTRUCTION) + if (book.sub_type == BOOK_DESTRUCTION) { if (silenced(you.x_pos, you.y_pos)) - { mpr("This book does not work if you cannot read it aloud!"); - return; - } - - tome_of_power(item_slot); + else + tome_of_power(item_slot); return; } - else if (you.inv[item_slot].sub_type == BOOK_MANUAL) + else if (book.sub_type == BOOK_MANUAL) { skill_manual(item_slot); return; @@ -3511,25 +3699,23 @@ static void handle_read_book( int item_slot ) while (true) { // Spellbook - spell = read_book( you.inv[item_slot], RBOOK_READ_SPELL ); + const int ltr = read_book( book, RBOOK_READ_SPELL ); - if (spell < 'a' || spell > 'h') //jmf: was 'g', but 8=h + if (ltr < 'a' || ltr > 'h') //jmf: was 'g', but 8=h { mesclr( true ); return; } - spell_index = letter_to_index( spell ); - - const spell_type nthing = - which_spell_in_book(you.inv[item_slot].sub_type, spell_index); - if (nthing == SPELL_NO_SPELL) + const spell_type spell = which_spell_in_book(book.sub_type, + letter_to_index(ltr)); + if (spell == SPELL_NO_SPELL) { mesclr( true ); return; } - describe_spell( nthing ); + describe_spell( spell ); } } @@ -3574,6 +3760,7 @@ void read_scroll(void) if (scroll.base_type != OBJ_BOOKS && scroll.base_type != OBJ_SCROLLS) { mpr("You can't read that!"); + crawl_state.zero_turns_taken(); return; } @@ -3587,6 +3774,7 @@ void read_scroll(void) if (silenced(you.x_pos, you.y_pos)) { mpr("Magic scrolls do not work when you're silenced!"); + crawl_state.zero_turns_taken(); return; } @@ -3689,10 +3877,11 @@ void read_scroll(void) } break; - case SCR_FORGETFULNESS: - mpr("You feel momentarily disoriented."); - if (!wearing_amulet(AMU_CLARITY)) - forget_map(50 + random2(50)); + case SCR_FOG: + mpr("The scroll dissolves into smoke."); + big_cloud( one_chance_in(20) ? CLOUD_POISON : + (one_chance_in(19) ? CLOUD_STEAM : random_smoke_type()), + KC_YOU, you.x_pos, you.y_pos, 50, 8 + random2(8)); break; case SCR_MAGIC_MAPPING: @@ -3714,8 +3903,7 @@ void read_scroll(void) torment( TORMENT_SCROLL, you.x_pos, you.y_pos ); // is only naughty if you know you're doing it - if (item_type_known(scroll)) - did_god_conduct(DID_UNHOLY, 10); + did_god_conduct(DID_UNHOLY, 10, item_type_known(scroll)); break; case SCR_IMMOLATION: @@ -3737,6 +3925,9 @@ void read_scroll(void) beam.ex_size = 2; beam.is_explosion = true; + if (!alreadyknown) + beam.effect_known = false; + explosion(beam); break; @@ -3788,7 +3979,6 @@ void read_scroll(void) case SCR_ENCHANT_WEAPON_III: if (you.equip[ EQ_WEAPON ] != -1) { - // Successfully affixing the enchantment will print // its own message. if (!affix_weapon_enchantment()) @@ -3898,6 +4088,7 @@ void read_scroll(void) do_curse_item( item ); } break; + } // end switch // finally, destroy and identify the scroll @@ -3943,62 +4134,96 @@ void use_randart(unsigned char item_wield_2) use_randart( you.inv[ item_wield_2 ] ); } -void use_randart(const item_def &item) +void use_randart(item_def &item) { +#define unknown_proprt(prop) (proprt[(prop)] && !known[(prop)]) + ASSERT( is_random_artefact( item ) ); const bool alreadyknown = item_type_known(item); const bool dangerous = player_in_a_dangerous_place(); - const bool ident = fully_identified(item); - randart_properties_t proprt; - randart_wpn_properties( item, proprt ); + randart_properties_t proprt; + randart_known_props_t known; + randart_wpn_properties( item, proprt, known ); - // Give messages for stat changes, possibly only if !identified + // Only give property messages for previously unknown properties. if (proprt[RAP_AC]) { - you.redraw_armour_class = 1; - if (!ident) + you.redraw_armour_class = true; + if (!known[RAP_AC]) { mprf("You feel %s.", proprt[RAP_AC] > 0? "well-protected" : "more vulnerable"); + randart_wpn_learn_prop(item, RAP_AC); } } if (proprt[RAP_EVASION]) { - you.redraw_evasion = 1; - if (!ident) + you.redraw_evasion = true; + if (!known[RAP_EVASION]) { mprf("You feel somewhat %s.", proprt[RAP_EVASION] > 0? "nimbler" : "more awkward"); + randart_wpn_learn_prop(item, RAP_EVASION); + } + } + + if (proprt[RAP_MAGICAL_POWER]) + { + you.redraw_magic_points = true; + if (!known[RAP_MAGICAL_POWER]) + { + mprf("You feel your mana capacity %s.", + proprt[RAP_MAGICAL_POWER] > 0? "increase" : "decrease"); + randart_wpn_learn_prop(item, RAP_MAGICAL_POWER); } } // modify ability scores // output result even when identified (because of potential fatality) - modify_stat( STAT_STRENGTH, proprt[RAP_STRENGTH], false ); - modify_stat( STAT_INTELLIGENCE, proprt[RAP_INTELLIGENCE], false ); - modify_stat( STAT_DEXTERITY, proprt[RAP_DEXTERITY], false ); + modify_stat( STAT_STRENGTH, proprt[RAP_STRENGTH], false, item ); + modify_stat( STAT_INTELLIGENCE, proprt[RAP_INTELLIGENCE], false, item ); + modify_stat( STAT_DEXTERITY, proprt[RAP_DEXTERITY], false, item ); + + const randart_prop_type stat_props[3] = + {RAP_STRENGTH, RAP_INTELLIGENCE, RAP_DEXTERITY}; + for (int i = 0; i < 3; i++) + if (unknown_proprt(stat_props[i])) + randart_wpn_learn_prop(item, stat_props[i]); // For evokable stuff, check whether other equipped items yield - // the same ability. If not, give a message. - // Do NOT give all these messages if the randart is identified. - if (!ident) + // the same ability. If not, and if the ability granted hasn't + // already been discovered, give a message. + if (unknown_proprt(RAP_LEVITATE) + && !items_give_ability(item.link, RAP_LEVITATE)) { - if (proprt[RAP_LEVITATE] && !items_give_ability(item.link, RAP_LEVITATE)) - mpr("You feel buoyant."); + mpr("You feel buoyant."); + randart_wpn_learn_prop(item, RAP_LEVITATE); + } - if (proprt[RAP_INVISIBLE] && !you.duration[DUR_INVIS]) - mpr("You become transparent for a moment."); + if (unknown_proprt(RAP_INVISIBLE) && !you.duration[DUR_INVIS]) + { + mpr("You become transparent for a moment."); + randart_wpn_learn_prop(item, RAP_INVISIBLE); + } - if (proprt[RAP_CAN_TELEPORT] && !items_give_ability(item.link, RAP_CAN_TELEPORT)) - mpr("You feel slightly jumpy."); + if (unknown_proprt(RAP_CAN_TELEPORT) + && !items_give_ability(item.link, RAP_CAN_TELEPORT)) + { + mpr("You feel slightly jumpy."); + randart_wpn_learn_prop(item, RAP_CAN_TELEPORT); + } - if (proprt[RAP_BERSERK] && !items_give_ability(item.link, RAP_BERSERK)) - mpr("You feel a brief urge to hack something to bits."); + if (unknown_proprt(RAP_BERSERK) + && !items_give_ability(item.link, RAP_BERSERK)) + { + mpr("You feel a brief urge to hack something to bits."); + randart_wpn_learn_prop(item, RAP_BERSERK); } + if (proprt[RAP_NOISES]) you.special_wield = SPWLD_NOISE; @@ -4008,6 +4233,7 @@ void use_randart(const item_def &item) // there is a dangerous monster nearby... xom_is_stimulated(255); } +#undef unknown_proprt } bool wearing_slot(int inv_slot) |