From 53a915ae2eef1b5c39147e2ccaf6695b2e995898 Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Sun, 11 Nov 2007 16:29:05 +0000 Subject: Implementing FR 1829063: warning when putting on/removing items with a stat property that will be fatal. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@2839 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/it_use2.cc | 12 +++-- crawl-ref/source/it_use2.h | 2 +- crawl-ref/source/item_use.cc | 108 ++++++++++++++++++++++++++++++++++++++++--- crawl-ref/source/item_use.h | 2 + crawl-ref/source/player.cc | 2 +- crawl-ref/source/randart.cc | 14 ++++++ crawl-ref/source/randart.h | 2 + 7 files changed, 130 insertions(+), 12 deletions(-) diff --git a/crawl-ref/source/it_use2.cc b/crawl-ref/source/it_use2.cc index 2d88e96d3d..6eeb4ac953 100644 --- a/crawl-ref/source/it_use2.cc +++ b/crawl-ref/source/it_use2.cc @@ -27,6 +27,7 @@ #include "beam.h" #include "effects.h" #include "food.h" +#include "item_use.h" #include "itemname.h" #include "itemprop.h" #include "misc.h" @@ -365,12 +366,15 @@ bool potion_effect( potion_type pot_eff, int pow ) return (effect); } // end potion_effect() -void unwield_item(bool showMsgs) +bool unwield_item(bool showMsgs) { const int unw = you.equip[EQ_WEAPON]; if ( unw == -1 ) - return; + return (false); + if (!safe_to_remove_or_wear(you.inv[unw], true)) + return (false); + you.equip[EQ_WEAPON] = -1; you.special_wield = SPWLD_NONE; you.wield_change = true; @@ -413,7 +417,7 @@ void unwield_item(bool showMsgs) break; } - return; + return (true); } const int brand = get_weapon_brand( item ); @@ -498,7 +502,7 @@ void unwield_item(bool showMsgs) mpr("You fell your mana capacity decrease."); } - return; + return (true); } // end unwield_item() // This does *not* call ev_mod! diff --git a/crawl-ref/source/it_use2.h b/crawl-ref/source/it_use2.h index 408e32b847..96c6f4f9c6 100644 --- a/crawl-ref/source/it_use2.h +++ b/crawl-ref/source/it_use2.h @@ -69,6 +69,6 @@ void unwear_armour(char unw); /* *********************************************************************** * called from: decks - it_use3 - item_use - items - spells3 - transfor * *********************************************************************** */ -void unwield_item(bool showMsgs = true); +bool unwield_item(bool showMsgs = true); #endif diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 955cbd4ac5..e415a4f369 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -236,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; @@ -260,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; @@ -724,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) @@ -1019,6 +1025,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] ); @@ -1052,6 +1061,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]); @@ -2560,6 +2572,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 @@ -2578,7 +2661,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); @@ -2628,12 +2714,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; @@ -2900,8 +2992,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]); diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 6a4c4bc41d..1fe300ed7b 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -67,6 +67,8 @@ void drink(void); bool elemental_missile_beam(int launcher_brand, int ammo_brand); +bool safe_to_remove_or_wear(const item_def &item, bool remove); + // last updated 12may2000 {dlb} /* *********************************************************************** * called from: acr diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index d8350b300f..eeb0a796e2 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -4061,7 +4061,7 @@ bool items_give_ability(const int slot, randart_prop_type abil) // none of the equipped items possesses this ability return (false); -} // end scan_randarts() +} // end items_give_ability() /* Checks each equip slot for a randart, and adds up all of those with a given property. Slow if any randarts are worn, so avoid where possible. */ diff --git a/crawl-ref/source/randart.cc b/crawl-ref/source/randart.cc index 9559069127..10b7e81e06 100644 --- a/crawl-ref/source/randart.cc +++ b/crawl-ref/source/randart.cc @@ -1523,6 +1523,20 @@ int randart_wpn_property( const item_def &item, randart_prop_type prop ) return randart_wpn_property( item, prop, known ); } +int randart_known_wpn_property( const item_def &item, randart_prop_type prop ) +{ + randart_properties_t proprt; + randart_known_props_t known; + + randart_wpn_properties( item, proprt, known ); + + if (known[prop]) + return ( proprt[prop] ); + else + return (0); +} + + int randart_wpn_num_props( const item_def &item ) { randart_properties_t proprt; diff --git a/crawl-ref/source/randart.h b/crawl-ref/source/randart.h index 7658bce3c7..ecdac587ab 100644 --- a/crawl-ref/source/randart.h +++ b/crawl-ref/source/randart.h @@ -81,6 +81,8 @@ int randart_wpn_property( const item_def &item, randart_prop_type prop, int randart_wpn_property( const item_def &item, randart_prop_type prop ); +int randart_known_wpn_property( const item_def &item, randart_prop_type prop ); + int randart_wpn_num_props( const item_def &item ); int randart_wpn_num_props( const randart_properties_t &proprt ); -- cgit v1.2.3-54-g00ecf