From c5887300c0f938671c78fc4a59f74ea98ac5bd04 Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Mon, 6 Apr 2009 18:13:14 +0000 Subject: 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 --- crawl-ref/source/delay.cc | 14 ++++--- crawl-ref/source/item_use.cc | 7 ++-- crawl-ref/source/spl-cast.cc | 12 +++--- crawl-ref/source/transfor.cc | 98 ++++++++++++++++++++++++++++++++++++-------- crawl-ref/source/transfor.h | 4 +- 5 files changed, 102 insertions(+), 33 deletions(-) (limited to 'crawl-ref') 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 &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 &remove) +{ + // Check over all items to be removed or melded. + std::set::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 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 &remove, @@ -38,7 +38,7 @@ bool check_transformation_stat_loss(const std::set &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); -- cgit v1.2.3-54-g00ecf