summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/abl-show.cc27
-rw-r--r--crawl-ref/source/acr.cc16
-rw-r--r--crawl-ref/source/item_use.cc15
-rw-r--r--crawl-ref/source/transfor.cc197
-rw-r--r--crawl-ref/source/transfor.h3
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}