summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-04-06 18:13:14 +0000
committerj-p-e-g <j-p-e-g@c06c8d41-db1a-0410-9941-cceddc491573>2009-04-06 18:13:14 +0000
commitc5887300c0f938671c78fc4a59f74ea98ac5bd04 (patch)
tree0aa4af54b9bf23b76fbba657c8d04633ac71118e
parentacd89a148d572cedafcf498496df2d3ce42a6980 (diff)
downloadcrawl-ref-c5887300c0f938671c78fc4a59f74ea98ac5bd04.tar.gz
crawl-ref-c5887300c0f938671c78fc4a59f74ea98ac5bd04.zip
Fix 2726622: untransforming not prompting for safe-inscribed equipment
Also, when transforming voluntarily (i.e. not via Xom or by drawing a card) you get prompted for the loss of safe-inscribed equipment. If you opt out, it costs neither turn nor mana. There's an edge case when you change from one transformation to another one: if that fails for whatever reason you lose the turn (due to untransforming) and the spell fizzles (including mana loss). git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@9588 c06c8d41-db1a-0410-9941-cceddc491573
-rw-r--r--crawl-ref/source/delay.cc14
-rw-r--r--crawl-ref/source/item_use.cc7
-rw-r--r--crawl-ref/source/spl-cast.cc12
-rw-r--r--crawl-ref/source/transfor.cc98
-rw-r--r--crawl-ref/source/transfor.h4
5 files changed, 102 insertions, 33 deletions
diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc
index 7b1f8f0e85..5af430ddd0 100644
--- a/crawl-ref/source/delay.cc
+++ b/crawl-ref/source/delay.cc
@@ -592,7 +592,8 @@ void handle_interrupted_swap(bool swap_if_safe, bool force_unsafe,
// Turn is over, set up a delay to do swapping next turn.
if (prompt && yesno(prompt_str, true, 'n') || safe && swap_if_safe)
{
- start_delay(DELAY_WEAPON_SWAP, 1, weap);
+ if (weap == -1 || check_warning_inscriptions(you.inv[weap], OPER_WIELD))
+ start_delay(DELAY_WEAPON_SWAP, 1, weap);
you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
}
return;
@@ -604,7 +605,8 @@ void handle_interrupted_swap(bool swap_if_safe, bool force_unsafe,
if (_is_butcher_delay(delay)
&& (safe || prompt && yesno(prompt_str, true, 'n')))
{
- start_delay(DELAY_WEAPON_SWAP, 1, weap);
+ if (weap == -1 || check_warning_inscriptions(you.inv[weap], OPER_WIELD))
+ start_delay(DELAY_WEAPON_SWAP, 1, weap);
you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
}
return;
@@ -620,9 +622,11 @@ void handle_interrupted_swap(bool swap_if_safe, bool force_unsafe,
return;
}
- weapon_switch(weap);
- print_stats();
-
+ if (weap == -1 || check_warning_inscriptions(you.inv[weap], OPER_WIELD))
+ {
+ weapon_switch(weap);
+ print_stats();
+ }
you.attribute[ATTR_WEAPON_SWAP_INTERRUPTED] = 0;
}
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index cc1b5f89bd..cbef83db3c 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -324,7 +324,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages,
return (false);
}
- // Wield the weapon.
+ // Make sure that wielding the weapon won't kill the player.
if (!safe_to_remove_or_wear(new_wpn, false))
return (false);
@@ -334,7 +334,7 @@ bool wield_weapon(bool auto_wield, int slot, bool show_weff_messages,
you.equip[EQ_WEAPON] = item_slot;
- // any oddness on wielding taken care of here
+ // Any oddness on wielding taken care of here.
wield_effects(item_slot, show_weff_messages);
mpr(new_wpn.name(DESC_INVENTORY_EQUIP).c_str());
@@ -3460,10 +3460,11 @@ static bool _swap_rings(int ring_slot)
if (!remove_ring(unwanted, false))
return (false);
- // Put on the new ring.
+ // Check that the new ring won't kill us.
if (!safe_to_remove_or_wear(you.inv[ring_slot], false))
return (false);
+ // Put on the new ring.
start_delay(DELAY_JEWELLERY_ON, 1, ring_slot);
return (true);
diff --git a/crawl-ref/source/spl-cast.cc b/crawl-ref/source/spl-cast.cc
index f8d54c1e02..42c040a3c0 100644
--- a/crawl-ref/source/spl-cast.cc
+++ b/crawl-ref/source/spl-cast.cc
@@ -1773,32 +1773,32 @@ spret_type your_spells(spell_type spell, int powc, bool allow_fail)
// Transformations.
case SPELL_BLADE_HANDS:
if (!transform(powc, TRAN_BLADE_HANDS))
- canned_msg(MSG_SPELL_FIZZLES);
+ return (SPRET_ABORT);
break;
case SPELL_SPIDER_FORM:
if (!transform(powc, TRAN_SPIDER))
- canned_msg(MSG_SPELL_FIZZLES);
+ return (SPRET_ABORT);
break;
case SPELL_STATUE_FORM:
if (!transform(powc, TRAN_STATUE))
- canned_msg(MSG_SPELL_FIZZLES);
+ return (SPRET_ABORT);
break;
case SPELL_ICE_FORM:
if (!transform(powc, TRAN_ICE_BEAST))
- canned_msg(MSG_SPELL_FIZZLES);
+ return (SPRET_ABORT);
break;
case SPELL_DRAGON_FORM:
if (!transform(powc, TRAN_DRAGON))
- canned_msg(MSG_SPELL_FIZZLES);
+ return (SPRET_ABORT);
break;
case SPELL_NECROMUTATION:
if (!transform(powc, TRAN_LICH))
- canned_msg(MSG_SPELL_FIZZLES);
+ return (SPRET_ABORT);
break;
case SPELL_ALTER_SELF:
diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc
index 6431e6477e..fe17503537 100644
--- a/crawl-ref/source/transfor.cc
+++ b/crawl-ref/source/transfor.cc
@@ -17,6 +17,7 @@ REVISION("$Rev$");
#include "externs.h"
#include "delay.h"
+#include "invent.h"
#include "it_use2.h"
#include "item_use.h"
#include "itemprop.h"
@@ -26,6 +27,7 @@ REVISION("$Rev$");
#include "player.h"
#include "randart.h"
#include "skills2.h"
+#include "state.h"
#include "stuff.h"
#include "traps.h"
@@ -414,6 +416,34 @@ bool check_transformation_stat_loss(const std::set<equipment_type> &remove,
return (false);
}
+// Returns true if the player got prompted by an inscription warning and
+// chose to opt out.
+bool _check_transformation_inscription_warning(
+ const std::set<equipment_type> &remove)
+{
+ // Check over all items to be removed or melded.
+ 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;
+
+ const item_def& item = you.inv[you.equip[e]];
+
+ operation_types op = OPER_WEAR;
+ if (e == EQ_WEAPON)
+ op = OPER_WIELD;
+ else if (item.base_type == OBJ_JEWELLERY)
+ op = OPER_PUTON;
+
+ if (!check_old_item_warning(item, op))
+ return (true);
+ }
+
+ return (false);
+}
+
// FIXME: Switch to 4.1 transforms handling.
size_type transform_size(int psize)
{
@@ -446,12 +476,26 @@ static void _transformation_expiration_warning()
}
}
-// Transforms you into the specified form. If quiet is true, fails silently
+static bool _abort_or_fizzle()
+{
+ if (you.turn_is_over)
+ {
+ canned_msg(MSG_SPELL_FIZZLES);
+ return (true); // pay the necessary costs
+ }
+ return (false); // SPRET_ABORT
+}
+
+// Transforms you into the specified form. If force is true, checks for
+// inscription warnings are skipped, and the transformation fails silently
// (if it fails). If just_check is true the transformation doesn't actually
// happen, but the method returns whether it would be successful.
-bool transform(int pow, transformation_type which_trans, bool quiet,
+bool transform(int pow, transformation_type which_trans, bool force,
bool just_check)
{
+ if (!force && crawl_state.is_god_acting())
+ force = true;
+
if (you.species == SP_MERFOLK && player_is_swimming()
&& which_trans != TRAN_DRAGON && which_trans != TRAN_BAT)
{
@@ -461,7 +505,7 @@ bool transform(int pow, transformation_type which_trans, bool quiet,
// form is completely over-riding any other... goes well with
// the forced transform when entering water)... but merfolk can
// transform into flying forms.
- if (!quiet)
+ if (!force)
mpr("You cannot transform out of your normal form while in water.");
return (false);
}
@@ -485,39 +529,55 @@ bool transform(int pow, transformation_type which_trans, bool quiet,
}
else
{
- if (!quiet)
+ if (!force)
mpr("You cannot extend your transformation any further!");
return (false);
}
}
+ // The actual transformation may still fail later (e.g. due to cursed
+ // equipment). In any case, untransforming costs us a turn but nothing
+ // else (as does the "End Transformation" ability).
if (!just_check && you.attribute[ATTR_TRANSFORMATION] != TRAN_NONE)
- untransform();
+ {
+ bool skip_wielding = false;
+ switch (which_trans)
+ {
+ case TRAN_STATUE:
+ case TRAN_LICH:
+ break;
+ default:
+ skip_wielding = true;
+ break;
+ }
+ // Skip wielding weapon if it gets unwielded again right away.
+ untransform(skip_wielding);
+ }
// Catch some conditions which prevent transformation.
if (you.is_undead
&& (you.species != SP_VAMPIRE
|| which_trans != TRAN_BAT && you.hunger_state <= HS_SATIATED))
{
- if (!quiet)
+ if (!force)
mpr("Your unliving flesh cannot be transformed in this way.");
- return (false);
+ return (_abort_or_fizzle());
}
if (which_trans == TRAN_LICH && you.duration[DUR_DEATHS_DOOR])
{
- if (!quiet)
+ if (!force)
{
mpr("The transformation conflicts with an enchantment "
"already in effect.");
}
- return (false);
+ return (_abort_or_fizzle());
}
std::set<equipment_type> rem_stuff = _init_equipment_removal(which_trans);
- if (_check_for_cursed_equipment(rem_stuff, which_trans, quiet))
- return (false);
+ if (_check_for_cursed_equipment(rem_stuff, which_trans, force))
+ return (_abort_or_fizzle());
int str = 0, dex = 0, symbol = '@', colour = LIGHTGREY, xhp = 0, dur = 0;
const char* tran_name = "buggy";
@@ -605,16 +665,19 @@ bool transform(int pow, transformation_type which_trans, bool quiet,
break;
}
- if (check_transformation_stat_loss(rem_stuff, quiet,
+ if (check_transformation_stat_loss(rem_stuff, force,
std::max(-str, 0), std::max(-dex, 0)))
{
- return (false);
+ return (_abort_or_fizzle());
}
// If we're just pretending return now.
if (just_check)
return (true);
+ if (!force && _check_transformation_inscription_warning(rem_stuff))
+ return (_abort_or_fizzle());
+
// All checks done, transformation will take place now.
you.redraw_evasion = true;
you.redraw_armour_class = true;
@@ -716,7 +779,7 @@ bool transform_can_butcher_barehanded(transformation_type tt)
return (tt == TRAN_BLADE_HANDS || tt == TRAN_DRAGON);
}
-void untransform(void)
+void untransform(bool skip_wielding)
{
const flight_type old_flight = you.flight_mode();
@@ -776,7 +839,6 @@ void untransform(void)
you.duration[DUR_STONESKIN] = 1;
hp_downscale = 15;
-
break;
case TRAN_ICE_BEAST:
@@ -788,7 +850,6 @@ void untransform(void)
you.duration[DUR_ICY_ARMOUR] = 1;
hp_downscale = 12;
-
break;
case TRAN_DRAGON:
@@ -843,7 +904,10 @@ void untransform(void)
}
calc_hp();
- handle_interrupted_swap(true, false, true);
+ if (!skip_wielding)
+ handle_interrupted_swap(true, false, true);
+
+ you.turn_is_over = true;
}
// XXX: This whole system is a mess as it still relies on special
diff --git a/crawl-ref/source/transfor.h b/crawl-ref/source/transfor.h
index d9cc16f1bc..e037b0d5c8 100644
--- a/crawl-ref/source/transfor.h
+++ b/crawl-ref/source/transfor.h
@@ -30,7 +30,7 @@ enum transformation_type
bool transform_can_butcher_barehanded(transformation_type tt);
-void untransform(void);
+void untransform(bool skip_wielding = false);
bool can_equip(equipment_type use_which, bool ignore_temporary);
bool check_transformation_stat_loss(const std::set<equipment_type> &remove,
@@ -38,7 +38,7 @@ bool check_transformation_stat_loss(const std::set<equipment_type> &remove,
int dex_loss = 0, int int_loss = 0);
size_type transform_size(int psize = PSIZE_BODY);
-bool transform(int pow, transformation_type which_trans, bool quiet = false,
+bool transform(int pow, transformation_type which_trans, bool force = false,
bool just_check = false);
void remove_one_equip(equipment_type eq, bool meld = true);