diff options
Diffstat (limited to 'crawl-ref/source')
-rw-r--r-- | crawl-ref/source/abl-show.cc | 27 | ||||
-rw-r--r-- | crawl-ref/source/acr.cc | 16 | ||||
-rw-r--r-- | crawl-ref/source/item_use.cc | 15 | ||||
-rw-r--r-- | crawl-ref/source/transfor.cc | 197 | ||||
-rw-r--r-- | crawl-ref/source/transfor.h | 3 |
5 files changed, 193 insertions, 65 deletions
diff --git a/crawl-ref/source/abl-show.cc b/crawl-ref/source/abl-show.cc index 7696b5589a..62be13def5 100644 --- a/crawl-ref/source/abl-show.cc +++ b/crawl-ref/source/abl-show.cc @@ -832,7 +832,7 @@ bool activate_ability() return false; } - if ( you.duration[DUR_CONF] ) + if (you.duration[DUR_CONF]) { talents = your_talents(true); if ( talents.empty() ) @@ -844,7 +844,7 @@ bool activate_ability() } int selected = -1; - while ( selected < 0 ) + while (selected < 0) { msg::streams(MSGCH_PROMPT) << "Use which ability? (? or * to list)" << std::endl; @@ -871,7 +871,7 @@ bool activate_ability() // try to find the hotkey for (unsigned int i = 0; i < talents.size(); ++i) { - if ( talents[i].hotkey == keyin ) + if (talents[i].hotkey == keyin) { selected = static_cast<int>(i); break; @@ -879,7 +879,7 @@ bool activate_ability() } // if we can't, cancel out - if ( selected < 0 ) + if (selected < 0) { mpr("You can't do that."); crawl_state.zero_turns_taken(); @@ -894,17 +894,20 @@ bool activate_ability() static bool _activate_talent(const talent& tal) { // Doing these would outright kill the player due to stat drain. - if (tal.which == ABIL_TRAN_BAT && you.strength <= 5) + if (tal.which == ABIL_TRAN_BAT) { - mpr("You lack the strength for this transformation."); - crawl_state.zero_turns_taken(); - return (false); + if (you.strength <= 5) + { + mpr("You lack the strength for this transformation.", MSGCH_WARN); + crawl_state.zero_turns_taken(); + return (false); + } } else if (tal.which == ABIL_END_TRANSFORMATION && you.attribute[ATTR_TRANSFORMATION] == TRAN_BAT && you.dex <= 5) { - mpr("Turning back with such low dexterity would be fatal!"); + mpr("Turning back with such low dexterity would be fatal!", MSGCH_WARN); more(); crawl_state.zero_turns_taken(); return (false); @@ -1831,7 +1834,11 @@ static bool _do_ability(const ability_def& abil) break; case ABIL_TRAN_BAT: - transform(100, TRAN_BAT); + if (!transform(100, TRAN_BAT)) + { + crawl_state.zero_turns_taken(); + return (false); + } break; case ABIL_RENOUNCE_RELIGION: diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc index 119e0adf5c..5b364affc1 100644 --- a/crawl-ref/source/acr.cc +++ b/crawl-ref/source/acr.cc @@ -3467,14 +3467,12 @@ static keycode_type _get_next_keycode() return (keyin); } -/* - * Check squares adjacent to player for given feature and return how - * many there are. If there's only one, return the dx and dy. - */ +// Check squares adjacent to player for given feature and return how +// many there are. If there's only one, return the dx and dy. static int _check_adjacent(dungeon_feature_type feat, int &dx, int &dy) { int num = 0; - int _dx, _dy; + int _dx = 0, _dy = 0; for (int x = -1; x <= 1; x++) for (int y = -1; y <= 1; y++) @@ -3494,11 +3492,9 @@ static int _check_adjacent(dungeon_feature_type feat, int &dx, int &dy) return num; } -/* - Opens doors and handles some aspects of untrapping. If either move_x or - move_y are non-zero, the pair carries a specific direction for the door - to be opened (eg if you type ctrl - dir). - */ +// Opens doors and handles some aspects of untrapping. If either move_x or +// move_y are non-zero, the pair carries a specific direction for the door +// to be opened (eg if you type ctrl - dir). static void _open_door(int move_x, int move_y, bool check_confused) { struct dist door_move; diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index 64dee389db..17a3c500d8 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -322,10 +322,11 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages) if (!can_wield(&you.inv[item_slot], true)) return (false); - // for non-auto_wield cases checked above + // For non-auto_wield cases checked above. if (auto_wield && !check_warning_inscriptions(you.inv[item_slot], OPER_WIELD)) return (false); + // Wield the weapon. if (!safe_to_remove_or_wear(you.inv[item_slot], false)) return (false); @@ -821,8 +822,12 @@ void wear_armour( int slot ) // slot is for tiles else if (!armour_prompt("Wear which item?", &armour_wear_2, OPER_WEAR)) return; - if (safe_to_remove_or_wear( you.inv[armour_wear_2], wearing_slot(slot) )) + // Wear the armour. + if (safe_to_remove_or_wear( you.inv[armour_wear_2], + wearing_slot(armour_wear_2) )) + { do_wear_armour( armour_wear_2, false ); + } } static int armour_equip_delay(const item_def &item) @@ -2928,6 +2933,7 @@ static bool swap_rings(int ring_slot) if (!remove_ring(unwanted, false)) return (false); + // Put on the new ring. if (!safe_to_remove_or_wear(you.inv[ring_slot], false)) return (false); @@ -2983,6 +2989,7 @@ bool puton_item(int item_slot, bool prompt_finger) return false; } + // Put on the new amulet. if (!safe_to_remove_or_wear(you.inv[item_slot], false)) return (false); @@ -2992,6 +2999,7 @@ bool puton_item(int item_slot, bool prompt_finger) return (true); } + // Put on the amulet. if (!safe_to_remove_or_wear(you.inv[item_slot], false)) return (false); @@ -3254,8 +3262,10 @@ bool remove_ring(int slot, bool announce) if (item_cursed( you.inv[you.equip[hand_used]] )) { if (announce) + { mprf("%s is stuck to you!", you.inv[you.equip[hand_used]].name(DESC_CAP_YOUR).c_str()); + } else mpr("It's stuck to you!"); @@ -3265,6 +3275,7 @@ bool remove_ring(int slot, bool announce) ring_wear_2 = you.equip[hand_used]; + // Remove the ring. if (!safe_to_remove_or_wear(you.inv[ring_wear_2], true)) return (false); diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc index 6931400de3..d2f7bd9051 100644 --- a/crawl-ref/source/transfor.cc +++ b/crawl-ref/source/transfor.cc @@ -27,6 +27,7 @@ #include "misc.h" #include "output.h" #include "player.h" +#include "randart.h" #include "skills2.h" #include "stuff.h" #include "traps.h" @@ -34,10 +35,67 @@ void drop_everything(void); void extra_hp(int amount_extra); +static void _init_equipment_removal(std::set<equipment_type> &rem_stuff, + int which_trans) +{ + switch (which_trans) + { + case TRAN_SPIDER: + // Spiders CAN wear soft helmets + if (you.equip[EQ_HELMET] == -1 + || !is_hard_helmet(you.inv[you.equip[EQ_HELMET]])) + { + rem_stuff.erase(EQ_HELMET); + } + break; + + case TRAN_BAT: + // Bats CAN wear soft helmets. + if (you.equip[EQ_HELMET] == -1 + || !is_hard_helmet(you.inv[you.equip[EQ_HELMET]])) + { + rem_stuff.erase(EQ_HELMET); + } + break; + + case TRAN_ICE_BEAST: + rem_stuff.erase(EQ_CLOAK); + // Ice beasts CAN wear soft helmets. + if (you.equip[EQ_HELMET] == -1 + || !is_hard_helmet(you.inv[you.equip[EQ_HELMET]])) + { + rem_stuff.erase(EQ_HELMET); + } + break; + + case TRAN_BLADE_HANDS: + rem_stuff.erase(EQ_CLOAK); + rem_stuff.erase(EQ_HELMET); + rem_stuff.erase(EQ_BOOTS); + rem_stuff.erase(EQ_BODY_ARMOUR); + break; + + case TRAN_STATUE: + rem_stuff.erase(EQ_WEAPON); // can still hold a weapon + rem_stuff.erase(EQ_CLOAK); + rem_stuff.erase(EQ_HELMET); + break; + + case TRAN_AIR: + // Can't wear anything at all! + rem_stuff.insert(EQ_LEFT_RING); + rem_stuff.insert(EQ_RIGHT_RING); + rem_stuff.insert(EQ_AMULET); + break; + default: + break; + } +} + bool remove_equipment(std::set<equipment_type> removed) { - if ( removed.find(EQ_WEAPON) != removed.end() && - you.equip[EQ_WEAPON] != -1) + if (removed.find(EQ_WEAPON) != removed.end() + && you.equip[EQ_WEAPON] != -1) { unwield_item(); canned_msg(MSG_EMPTY_HANDED); @@ -45,10 +103,10 @@ bool remove_equipment(std::set<equipment_type> removed) // Remove items in order (std::set is a sorted container) std::set<equipment_type>::const_iterator iter; - for ( iter = removed.begin(); iter != removed.end(); ++iter ) + for (iter = removed.begin(); iter != removed.end(); ++iter) { const equipment_type e = *iter; - if ( e == EQ_WEAPON || you.equip[e] == -1 ) + if (e == EQ_WEAPON || you.equip[e] == -1) continue; mprf("%s falls away.", @@ -58,7 +116,7 @@ bool remove_equipment(std::set<equipment_type> removed) you.equip[e] = -1; } - return true; + return (true); } // end remove_equipment() bool remove_one_equip(equipment_type eq) @@ -76,7 +134,7 @@ static bool check_for_cursed_equipment(const std::set<equipment_type> &remove) for (iter = remove.begin(); iter != remove.end(); ++iter ) { equipment_type e = *iter; - if ( you.equip[e] == -1 ) + if (you.equip[e] == -1) continue; if (item_cursed( you.inv[ you.equip[e] ] )) @@ -91,6 +149,78 @@ static bool check_for_cursed_equipment(const std::set<equipment_type> &remove) return (false); } // end check_for_cursed_equipment() +// Count the stat boosts yielded by all items to be removed, and count +// future losses (caused by the transformation) like a current stat boost, +// as well. If the sum of all bosts of a stat is equal to or greater than +// the current stat, give a message and return true. +bool check_transformation_stat_loss(const std::set<equipment_type> &remove, + int str_loss, int dex_loss, int int_loss, + bool quiet) +{ + // Initialize with additional losses, if any. + int prop_str = str_loss; + int prop_dex = dex_loss; + int prop_int = int_loss; + + // Check over all items to be removed. + std::set<equipment_type>::const_iterator iter; + for (iter = remove.begin(); iter != remove.end(); ++iter) + { + equipment_type e = *iter; + if (you.equip[e] == -1) + continue; + + item_def item = you.inv[you.equip[e]]; + if (item.base_type == OBJ_JEWELLERY) + { + if (!item_ident( item, ISFLAG_KNOW_PLUSES )) + continue; + + 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); + } + + // Since there might be multiple items whose effects cancel each other + // out while worn, if at any point in the order of checking this list + // (which is the same order as when removing items) one of your stats + // would reach 0, return true. + if (prop_str >= you.strength || prop_int >= you.intel + || prop_dex >= you.dex) + { + if (!quiet) + { + mpr("This transformation would result in fatal stat loss!", + MSGCH_WARN); + } + return (true); + } + } + + return (false); +} + // FIXME: Switch to 4.1 transforms handling. size_type transform_size(int psize) { @@ -163,10 +293,10 @@ bool transform(int pow, transformation_type which_trans) return (false); } - //jmf: silently discard this enchantment + //jmf: Silently discard this enchantment you.duration[DUR_STONESKIN] = 0; - // We drop everything except jewellery by default + // We drop everything except jewellery by default. equipment_type default_rem[] = { EQ_WEAPON, EQ_CLOAK, EQ_HELMET, EQ_GLOVES, EQ_BOOTS, EQ_SHIELD, EQ_BODY_ARMOUR @@ -174,6 +304,7 @@ bool transform(int pow, transformation_type which_trans) std::set<equipment_type> rem_stuff(default_rem, default_rem + ARRAYSZ(default_rem)); + _init_equipment_removal(rem_stuff, which_trans); you.redraw_evasion = true; you.redraw_armour_class = true; @@ -183,13 +314,6 @@ bool transform(int pow, transformation_type which_trans) switch (which_trans) { case TRAN_SPIDER: // also AC +3, ev +3, fast_run - // spiders CAN wear soft helmets - if ( you.equip[EQ_HELMET] == -1 - || !is_hard_helmet(you.inv[you.equip[EQ_HELMET]])) - { - rem_stuff.erase(EQ_HELMET); - } - if (check_for_cursed_equipment( rem_stuff )) return (false); @@ -210,16 +334,11 @@ bool transform(int pow, transformation_type which_trans) return (true); case TRAN_BAT: - // bats CAN wear soft helmets - if ( you.equip[EQ_HELMET] == -1 - || !is_hard_helmet(you.inv[you.equip[EQ_HELMET]])) - { - rem_stuff.erase(EQ_HELMET); - } + if (check_for_cursed_equipment(rem_stuff)) + return (false); - // high ev, low ac, high speed - if (check_for_cursed_equipment( rem_stuff )) - return false; + if (check_transformation_stat_loss(rem_stuff, 5)) // Str loss = 5 + return (false); mprf("You turn into a %sbat.", you.species == SP_VAMPIRE ? "vampire " : ""); @@ -232,6 +351,7 @@ bool transform(int pow, transformation_type which_trans) if (you.duration[DUR_TRANSFORMATION] > 100) you.duration[DUR_TRANSFORMATION] = 100; + // high ev, low ac, high speed modify_stat( STAT_DEXTERITY, 5, true, "gaining the bat transformation"); modify_stat( STAT_STRENGTH, -5, true, @@ -242,16 +362,8 @@ bool transform(int pow, transformation_type which_trans) return (true); case TRAN_ICE_BEAST: // also AC +3, cold +3, fire -1, pois +1 - rem_stuff.erase(EQ_CLOAK); - // ice beasts CAN wear soft helmets - if ( you.equip[EQ_HELMET] == -1 - || !is_hard_helmet(you.inv[you.equip[EQ_HELMET]])) - { - rem_stuff.erase(EQ_HELMET); - } - if (check_for_cursed_equipment( rem_stuff )) - return false; + return (false); mpr( "You turn into a creature of crystalline ice." ); @@ -292,12 +404,11 @@ bool transform(int pow, transformation_type which_trans) return (true); case TRAN_STATUE: // also AC +20, ev -5, elec +1, pois +1, neg +1, slow - rem_stuff.erase(EQ_WEAPON); // can still hold a weapon - rem_stuff.erase(EQ_CLOAK); - rem_stuff.erase(EQ_HELMET); - if (check_for_cursed_equipment( rem_stuff )) - return false; + return (false); + + if (check_transformation_stat_loss(rem_stuff, 0, 2)) // Dex loss = 2 + return (false); if (you.species == SP_GNOME && coinflip()) mpr( "Look, a garden gnome. How cute!" ); @@ -306,7 +417,7 @@ bool transform(int pow, transformation_type which_trans) else mpr( "You turn into a living statue of rough stone." ); - // too stiff to make use of shields, gloves, or armour -- bwr + // Too stiff to make use of shields, gloves, or armour -- bwr remove_equipment( rem_stuff ); you.attribute[ATTR_TRANSFORMATION] = TRAN_STATUE; @@ -333,8 +444,10 @@ bool transform(int pow, transformation_type which_trans) return false; if (you.species == SP_MERFOLK && player_is_swimming()) + { mpr("You fly out of the water as you turn into " "a fearsome dragon!"); + } else mpr("You turn into a fearsome dragon!"); @@ -364,6 +477,8 @@ bool transform(int pow, transformation_type which_trans) return (true); case TRAN_LICH: + // Don't need to remove anything. + // also AC +3, cold +1, neg +3, pois +1, is_undead, res magic +50, // spec_death +1, and drain attack (if empty-handed) if (you.duration[DUR_DEATHS_DOOR]) @@ -403,10 +518,6 @@ bool transform(int pow, transformation_type which_trans) return (true); case TRAN_AIR: - rem_stuff.insert(EQ_LEFT_RING); - rem_stuff.insert(EQ_RIGHT_RING); - rem_stuff.insert(EQ_AMULET); - if (check_for_cursed_equipment( rem_stuff )) return false; diff --git a/crawl-ref/source/transfor.h b/crawl-ref/source/transfor.h index 12a1edc83a..933f512cb8 100644 --- a/crawl-ref/source/transfor.h +++ b/crawl-ref/source/transfor.h @@ -48,6 +48,9 @@ void untransform(void); * called from: item_use * *********************************************************************** */ bool can_equip(equipment_type use_which, bool ignore_temporary); +bool check_transformation_stat_loss(const std::set<equipment_type> &remove, + int str_loss = 0, int dex_loss = 0, + int int_loss = 0, bool quiet = false); size_type transform_size(int psize = PSIZE_BODY); // last updated 12may2000 {dlb} |