From c96c36a0477909874c98bdbda3d13333ddb453e2 Mon Sep 17 00:00:00 2001 From: j-p-e-g Date: Sun, 26 Oct 2008 13:18:19 +0000 Subject: Implement FR 1894211: All transformations will now cause your equipment to meld into your body than rather than being removed, so that when untransforming you don't have to put everything on again. * Wielded stuff cannot be melded, and does not yet use the autoswap function. * As before, the low-level transformation spells refuse to work with cursed equipment. * The messages are unnecessarily spammy if you change forms while already transformed (first everything is re-equipped, then unequipped again). Conversely, on simply untransforming the lack of messages might be confusing. * Might be buggy, feedback welcome! git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7300 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/docs/obsolete/crawlhistory.txt | 17 ++++++++++++ crawl-ref/settings/menu_colours.txt | 3 ++ crawl-ref/source/command.cc | 22 +++++++++------ crawl-ref/source/delay.cc | 36 +++++++++++++----------- crawl-ref/source/delay.h | 2 ++ crawl-ref/source/invent.cc | 7 +++-- crawl-ref/source/item_use.cc | 19 +++++++++---- crawl-ref/source/item_use.h | 5 +++- crawl-ref/source/itemname.cc | 21 ++++++-------- crawl-ref/source/output.cc | 38 +++++++++++++------------- crawl-ref/source/player.cc | 41 ++++++++++++++++++++++++---- crawl-ref/source/player.h | 1 + crawl-ref/source/spl-util.cc | 6 ---- crawl-ref/source/spl-util.h | 5 ---- crawl-ref/source/tilereg.cc | 6 ++-- crawl-ref/source/tilesdl.cc | 10 +++---- crawl-ref/source/transfor.cc | 47 +++++++++++++++++++++++++++----- 17 files changed, 190 insertions(+), 96 deletions(-) diff --git a/crawl-ref/docs/obsolete/crawlhistory.txt b/crawl-ref/docs/obsolete/crawlhistory.txt index f7173be2eb..1ca190f488 100644 --- a/crawl-ref/docs/obsolete/crawlhistory.txt +++ b/crawl-ref/docs/obsolete/crawlhistory.txt @@ -1249,6 +1249,23 @@ File 'spl-mis.h': -------------------------------------------------- +File 'spl-util.cc': + * Changelog(most recent first): * + * + * <3> 04oct2001 bwr absorbed spells0.cc + * <2> 24jun2000 jmf changed to use new data structure + * <1> 12jun2000 dlb created after much thought + +-------------------------------------------------- + +File 'spl-util.h': + * Changelog(most recent first): + * + * 24jun2000 jmf simplified structures + * <00> 12jun2000 dlb created after much thought + +-------------------------------------------------- + File 'state.cc': * Change History (most recent first): * diff --git a/crawl-ref/settings/menu_colours.txt b/crawl-ref/settings/menu_colours.txt index 7eacf0ecb3..2cdef96ef9 100644 --- a/crawl-ref/settings/menu_colours.txt +++ b/crawl-ref/settings/menu_colours.txt @@ -3,6 +3,9 @@ menu := menu_colour ae := autopickup_exceptions +# Items currently not affecting you. +menu = darkgrey:(melded) + # Bad items menu = lightred:.*bad_item.* diff --git a/crawl-ref/source/command.cc b/crawl-ref/source/command.cc index bfe6ace2f1..735a31adeb 100644 --- a/crawl-ref/source/command.cc +++ b/crawl-ref/source/command.cc @@ -554,17 +554,20 @@ void list_armour() : "unknown") << " : "; - if (armour_id != -1) + if (!you_can_wear(i,true)) + estr << " (unavailable)"; + else if (armour_id != -1 && !you_tran_can_wear(you.inv[armour_id]) + || !you_tran_can_wear(i)) + { + estr << " (currently unavailable)"; + } + else if (armour_id != -1) { estr << you.inv[armour_id].name(DESC_INVENTORY); colour = menu_colour(estr.str(), menu_colour_item_prefix(you.inv[armour_id]), "equip"); } - else if (!you_can_wear(i,true)) - estr << " (unavailable)"; - else if (!you_tran_can_wear(i, true)) - estr << " (currently unavailable)"; else if (!you_can_wear(i)) estr << " (restricted)"; else @@ -595,15 +598,18 @@ void list_jewellery(void) : "unknown ") << " : "; - if (jewellery_id != -1) + if (jewellery_id != -1 && !you_tran_can_wear(you.inv[jewellery_id]) + || !you_tran_can_wear(i)) + { + jstr << " (currently unavailable)"; + } + else if (jewellery_id != -1) { jstr << you.inv[jewellery_id].name(DESC_INVENTORY); std::string prefix = menu_colour_item_prefix(you.inv[jewellery_id]); colour = menu_colour(jstr.str(), prefix, "equip"); } - else if (!you_tran_can_wear(i)) - jstr << " (currently unavailable)"; else jstr << " none"; diff --git a/crawl-ref/source/delay.cc b/crawl-ref/source/delay.cc index 7debfe2fdb..0b1bbaae46 100644 --- a/crawl-ref/source/delay.cc +++ b/crawl-ref/source/delay.cc @@ -50,7 +50,6 @@ extern std::vector items_for_multidrop; static int _interrupts_blocked = 0; static void _xom_check_corpse_waste(); -static void _armour_wear_effects(const int item_inv_slot); static void _handle_run_delays(const delay_queue_item &delay); static void _handle_macro_delay(); static void _finish_delay(const delay_queue_item &delay); @@ -943,7 +942,7 @@ static void _finish_delay(const delay_queue_item &delay) break; case DELAY_ARMOUR_ON: - _armour_wear_effects(delay.parm1); + armour_wear_effects(delay.parm1); break; case DELAY_ARMOUR_OFF: @@ -1234,7 +1233,7 @@ static void _finish_delay(const delay_queue_item &delay) #endif } -static void _armour_wear_effects(const int item_slot) +void armour_wear_effects(const int item_slot) { item_def &arm = you.inv[item_slot]; @@ -1244,6 +1243,10 @@ static void _armour_wear_effects(const int item_slot) set_ident_flags(arm, ISFLAG_EQ_ARMOUR_MASK ); + const equipment_type eq_slot = get_armour_slot(arm); + const bool melded = (arm.link == you.equip[eq_slot]); + const bool known_cursed = item_known_cursed(arm); + if (!was_known) { if (Options.autoinscribe_randarts && is_random_artefact( arm )) @@ -1253,10 +1256,8 @@ static void _armour_wear_effects(const int item_slot) take_note(Note(NOTE_ID_ITEM, 0, 0, arm.name(DESC_NOCAP_A).c_str(), origin_desc(arm).c_str())); } - mprf("You finish putting on %s.", arm.name(DESC_NOCAP_YOUR).c_str()); - - const equipment_type eq_slot = get_armour_slot(arm); - const bool known_cursed = item_known_cursed(arm); + if (!melded) + mprf("You finish putting on %s.", arm.name(DESC_NOCAP_YOUR).c_str()); if (eq_slot == EQ_BODY_ARMOUR) { @@ -1269,17 +1270,20 @@ static void _armour_wear_effects(const int item_slot) you.duration[DUR_ICY_ARMOUR] = 0; } } - else + else if (eq_slot == EQ_SHIELD) + { + if (you.duration[DUR_CONDENSATION_SHIELD]) + { + mpr( "Your icy shield evaporates.", MSGCH_DURATION ); + you.duration[DUR_CONDENSATION_SHIELD] = 0; + } + you.equip[EQ_SHIELD] = item_slot; + } + else if (!melded) { switch (eq_slot) { case EQ_SHIELD: - if (you.duration[DUR_CONDENSATION_SHIELD]) - { - mpr( "Your icy shield evaporates.", MSGCH_DURATION ); - you.duration[DUR_CONDENSATION_SHIELD] = 0; - } - you.equip[EQ_SHIELD] = item_slot; break; case EQ_CLOAK: you.equip[EQ_CLOAK] = item_slot; @@ -1382,9 +1386,9 @@ static void _armour_wear_effects(const int item_slot) } if (is_random_artefact( arm )) - use_randart( item_slot ); + use_randart( arm, melded ); - if (item_cursed( arm )) + if (item_cursed( arm ) && !melded) { mpr( "Oops, that feels deathly cold." ); learned_something_new(TUT_YOU_CURSED); diff --git a/crawl-ref/source/delay.h b/crawl-ref/source/delay.h index 2857cb6978..5f65eabec8 100644 --- a/crawl-ref/source/delay.h +++ b/crawl-ref/source/delay.h @@ -87,4 +87,6 @@ delay_type get_delay(const std::string &); bool interrupt_activity( activity_interrupt_type ai, const activity_interrupt_data &a = activity_interrupt_data() ); + +void armour_wear_effects(const int item_slot); #endif diff --git a/crawl-ref/source/invent.cc b/crawl-ref/source/invent.cc index fbef463669..b396e80fd3 100644 --- a/crawl-ref/source/invent.cc +++ b/crawl-ref/source/invent.cc @@ -800,11 +800,14 @@ std::vector select_items( const std::vector &items, static bool _item_class_selected(const item_def &i, int selector) { const int itype = i.base_type; - if (selector == OSEL_ANY || selector == itype) + if (selector == OSEL_ANY || selector == itype && itype != OBJ_ARMOUR) return (true); switch (selector) { + case OBJ_ARMOUR: + return (you_tran_can_wear(i)); + case OSEL_UNIDENT: return !fully_identified(i); @@ -1105,7 +1108,7 @@ std::vector prompt_invent_items( } else if (!isspace( keyin )) { - // we've got a character we don't understand... + // We've got a character we don't understand... canned_msg( MSG_HUH ); } else diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc index ce6a2e8b86..ab9a648ccb 100644 --- a/crawl-ref/source/item_use.cc +++ b/crawl-ref/source/item_use.cc @@ -1097,7 +1097,7 @@ bool do_wear_armour( int item, bool quiet ) if (you.equip[EQ_BODY_ARMOUR] != -1 && item_cursed(you.inv[you.equip[EQ_BODY_ARMOUR]]) ) { - if ( !quiet ) + if (!quiet) { mprf("%s is stuck to your body!", you.inv[you.equip[EQ_BODY_ARMOUR]].name(DESC_CAP_YOUR) @@ -1178,12 +1178,19 @@ bool takeoff_armour(int item) } } + const equipment_type slot = get_armour_slot(invitem); + if (!you_tran_can_wear(invitem) && invitem.link == you.equip[slot]) + { + mprf("%s is melded into your body!", + invitem.name(DESC_CAP_YOUR).c_str()); + return (false); + } + if (!safe_to_remove_or_wear(invitem, true)) return (false); bool removedCloak = false; int cloak = -1; - const equipment_type slot = get_armour_slot(invitem); if (slot == EQ_BODY_ARMOUR) { @@ -3029,7 +3036,7 @@ bool safe_to_remove_or_wear(const item_def &item, bool remove, // one of the worn rings. // // Does not do amulets. -static bool swap_rings(int ring_slot) +static bool _swap_rings(int ring_slot) { // Ask the player which existing ring is persona non grata. int unwanted = prompt_ring_to_remove(ring_slot); @@ -3086,7 +3093,7 @@ bool puton_item(int item_slot, bool prompt_finger) if (you.equip[EQ_LEFT_RING] != -1 && you.equip[EQ_RIGHT_RING] != -1) { - return swap_rings(item_slot); + return _swap_rings(item_slot); } } else if (you.equip[EQ_AMULET] != -1) @@ -4698,7 +4705,7 @@ void use_randart(unsigned char item_wield_2) use_randart( you.inv[ item_wield_2 ] ); } -void use_randart(item_def &item) +void use_randart(item_def &item, bool unmeld) { #define unknown_proprt(prop) (proprt[(prop)] && !known[(prop)]) @@ -4791,7 +4798,7 @@ void use_randart(item_def &item) randart_wpn_learn_prop(item, RAP_BERSERK); } - if (!item_cursed(item) && proprt[RAP_CURSED] > 0 + if (!unmeld && !item_cursed(item) && proprt[RAP_CURSED] > 0 && one_chance_in(proprt[RAP_CURSED])) { do_curse_item( item, false ); diff --git a/crawl-ref/source/item_use.h b/crawl-ref/source/item_use.h index 2ddbad1423..4424a3a9a6 100644 --- a/crawl-ref/source/item_use.h +++ b/crawl-ref/source/item_use.h @@ -81,6 +81,9 @@ void examine_object(void); bool puton_ring(int slot = -1, bool prompt_finger = true); void jewellery_remove_effects(item_def &item, bool mesg = true); +// called from: transfor +void jewellery_wear_effects(item_def &item); + // last updated 12may2000 {dlb} /* *********************************************************************** * called from: acr @@ -151,7 +154,7 @@ void wield_effects(int item_wield_2, bool showMsgs); * called from: delay.cc item_use.cc it_use2.cc * *********************************************************************** */ void use_randart( unsigned char item_wield_2 ); -void use_randart(item_def &item); +void use_randart(item_def &item, bool unmeld = false); bool puton_item(int slot, bool prompt_finger = true); diff --git a/crawl-ref/source/itemname.cc b/crawl-ref/source/itemname.cc index ccbc250be7..7cb451f0bf 100644 --- a/crawl-ref/source/itemname.cc +++ b/crawl-ref/source/itemname.cc @@ -28,6 +28,7 @@ #include "it_use2.h" #include "item_use.h" #include "itemprop.h" +#include "items.h" #include "macro.h" #include "makeitem.h" #include "mon-util.h" @@ -189,18 +190,19 @@ std::string item_def::name(description_level_type descrip, buff << auxname; bool equipped = false; - if (descrip == DESC_INVENTORY_EQUIP && in_inventory(*this)) + if (descrip == DESC_INVENTORY_EQUIP && item_is_equipped(*this, true)) { ASSERT( this->link != -1 ); + equipped = true; - if (this->link == you.equip[EQ_WEAPON]) + if (!you_tran_can_wear(*this)) + buff << " (melded)"; + else if (this->link == you.equip[EQ_WEAPON]) { if (this->base_type == OBJ_WEAPONS || item_is_staff(*this)) buff << " (weapon)"; else buff << " (in hand)"; - - equipped = true; } else if (this->link == you.equip[EQ_CLOAK] || this->link == you.equip[EQ_HELMET] @@ -210,32 +212,27 @@ std::string item_def::name(description_level_type descrip, || this->link == you.equip[EQ_BODY_ARMOUR]) { buff << " (worn)"; - equipped = true; } else if (this->link == you.equip[EQ_LEFT_RING]) { buff << " (left hand)"; - equipped = true; } else if (this->link == you.equip[EQ_RIGHT_RING]) { buff << " (right hand)"; - equipped = true; } else if (this->link == you.equip[EQ_AMULET]) { buff << " (around neck)"; - equipped = true; } else if (this->link == you.m_quiver->get_fire_item()) { buff << " (quivered)"; - equipped = true; // well, sort of } - } + } - if (descrip != DESC_BASENAME) - { + if (descrip != DESC_BASENAME) + { const bool tried = !ident && !equipped && item_type_tried(*this); std::string tried_str; diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc index dab690ae97..59d4daf10e 100644 --- a/crawl-ref/source/output.cc +++ b/crawl-ref/source/output.cc @@ -1638,7 +1638,19 @@ static void _print_overview_screen_equip(column_composer& cols, // uncomment (and change 42 to 33) to bring back slot names // snprintf(slot, sizeof slot, "%-7s: ", equip_slot_to_name(eqslot); - if (you.equip[ e_order[i] ] != -1) + if (!you_can_wear(e_order[i], true)) + { + snprintf(buf, sizeof buf, + "%s(%s unavailable)", + slot, slot_name_lwr); + } + else if (!you_tran_can_wear(e_order[i], true)) + { + snprintf(buf, sizeof buf, + "%s(%s currently unavailable)", + slot, slot_name_lwr); + } + else if (you.equip[ e_order[i] ] != -1) { const int item_idx = you.equip[e_order[i]]; const item_def& item = you.inv[item_idx]; @@ -1654,6 +1666,12 @@ static void _print_overview_screen_equip(column_composer& cols, colname); equip_chars.push_back(equip_char); } + else if (!you_can_wear(e_order[i])) + { + snprintf(buf, sizeof buf, + "%s(%s restricted)", + slot, slot_name_lwr); + } else if (e_order[i] == EQ_WEAPON && you.attribute[ATTR_TRANSFORMATION] == TRAN_BLADE_HANDS) { @@ -1664,24 +1682,6 @@ static void _print_overview_screen_equip(column_composer& cols, { snprintf(buf, sizeof buf, "%s - Unarmed", slot); } - else if (!you_can_wear(e_order[i], true)) - { - snprintf(buf, sizeof buf, - "%s(%s unavailable)", - slot, slot_name_lwr); - } - else if (!you_tran_can_wear(e_order[i], true)) - { - snprintf(buf, sizeof buf, - "%s(%s currently unavailable)", - slot, slot_name_lwr); - } - else if (!you_can_wear(e_order[i])) - { - snprintf(buf, sizeof buf, - "%s(%s restricted)", - slot, slot_name_lwr); - } else { snprintf(buf, sizeof buf, diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc index 1e38fb5282..d79d211372 100644 --- a/crawl-ref/source/player.cc +++ b/crawl-ref/source/player.cc @@ -588,6 +588,29 @@ bool player_has_feet() return (true); } +bool you_tran_can_wear(const item_def &item) +{ + switch (item.base_type) + { + case OBJ_WEAPONS: + return you_tran_can_wear(EQ_WEAPON); + + case OBJ_JEWELLERY: + return you_tran_can_wear(jewellery_is_amulet(item) ? EQ_AMULET + : EQ_LEFT_RING); + case OBJ_ARMOUR: + if (item.sub_type == ARM_CAP) + { + const int transform = you.attribute[ATTR_TRANSFORMATION]; + return (transform != TRAN_BAT && transform != TRAN_AIR); + } + return you_tran_can_wear(get_armour_slot(item), true); + + default: + return (true); + } +} + bool you_tran_can_wear(int eq, bool check_mutation) { // Not a transformation, but also temporary -> check first. @@ -605,14 +628,14 @@ bool you_tran_can_wear(int eq, bool check_mutation) } } - int transform = you.attribute[ATTR_TRANSFORMATION]; + const int transform = you.attribute[ATTR_TRANSFORMATION]; // No further restrictions. if (transform == TRAN_NONE || transform == TRAN_LICH) return (true); - // Bats cannot use anything, clouds obviously so. - if (transform == TRAN_BAT || transform == TRAN_AIR) + // Bats cannot wear anything except amulets, clouds obviously nothing. + if (transform == TRAN_BAT && eq != EQ_AMULET || transform == TRAN_AIR) return (false); // Everyone else can wear jewellery, at least. @@ -730,6 +753,9 @@ bool berserk_check_wielded_weapon() // Returns number of matches (in the case of rings, both are checked) int player_equip( equipment_type slot, int sub_type, bool calc_unid ) { + if (!you_tran_can_wear(slot)) + return (0); + int ret = 0; switch (slot) @@ -826,6 +852,9 @@ int player_equip( equipment_type slot, int sub_type, bool calc_unid ) // and armour type-id on wield/wear. int player_equip_ego_type( int slot, int special ) { + if (!you_tran_can_wear(slot)) + return (0); + int ret = 0; int wpn; @@ -1960,10 +1989,10 @@ int player_AC(void) for (i = EQ_CLOAK; i <= EQ_BODY_ARMOUR; i++) { - if ( i == EQ_SHIELD ) + if (i == EQ_SHIELD) continue; - if ( you.equip[i] == -1 ) + if (you.equip[i] == -1 || !you_tran_can_wear(you.equip[i])) continue; const item_def& item = you.inv[you.equip[i]]; @@ -4416,7 +4445,7 @@ int scan_randarts(randart_prop_type which_property, bool calc_unid) { const int eq = you.equip[i]; - if (eq == -1) + if (eq == -1 || !you_tran_can_wear(eq)) continue; // Only weapons give their effects when in our hands. diff --git a/crawl-ref/source/player.h b/crawl-ref/source/player.h index fe4b69e58f..42eb7f0351 100644 --- a/crawl-ref/source/player.h +++ b/crawl-ref/source/player.h @@ -339,6 +339,7 @@ bool is_player_same_species( const int mon, bool = false ); bool you_can_wear( int eq, bool special_armour = false ); bool player_has_feet(void); +bool you_tran_can_wear(const item_def &item); bool you_tran_can_wear( int eq, bool check_mutation = false ); /* *********************************************************************** diff --git a/crawl-ref/source/spl-util.cc b/crawl-ref/source/spl-util.cc index 3cfed59490..087a78474f 100644 --- a/crawl-ref/source/spl-util.cc +++ b/crawl-ref/source/spl-util.cc @@ -4,12 +4,6 @@ * Written by: don brodale * * * * Modified for Crawl Reference by $Author$ on $Date$ - * - * Changelog(most recent first): * - * - * <3> 04oct2001 bwr absorbed spells0.cc - * <2> 24jun2000 jmf changed to use new data structure - * <1> 12jun2000 dlb created after much thought */ #include "AppHdr.h" diff --git a/crawl-ref/source/spl-util.h b/crawl-ref/source/spl-util.h index 76f3dba729..2b8196c8b4 100644 --- a/crawl-ref/source/spl-util.h +++ b/crawl-ref/source/spl-util.h @@ -4,11 +4,6 @@ * Written by: don brodale * * Modified for Crawl Reference by $Author$ on $Date$ - * - * Changelog(most recent first): - * - * 24jun2000 jmf simplified structures - * <00> 12jun2000 dlb created after much thought */ diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc index 021fd9c2bb..1e2660f0f2 100644 --- a/crawl-ref/source/tilereg.cc +++ b/crawl-ref/source/tilereg.cc @@ -2270,8 +2270,8 @@ struct box_vert void MessageRegion::render() { int idx = -1; - unsigned char char_back; - unsigned char col_back; + unsigned char char_back = 0; + unsigned char col_back = 0; if (this == TextRegion::cursor_region && cursor_x > 0 && cursor_y > 0) { @@ -2522,7 +2522,7 @@ void MenuRegion::place_entries() { m_entries[i].sx = entry_start + tile_indent; entry_height = std::max(max_tile_height, text_height); - + // Currently, menus only support one texture at a time. tex = m_entries[i].texture; ASSERT(m_entries[i].texture == tex || tex == TEX_MAX); diff --git a/crawl-ref/source/tilesdl.cc b/crawl-ref/source/tilesdl.cc index badcfd4656..77c940bda7 100644 --- a/crawl-ref/source/tilesdl.cc +++ b/crawl-ref/source/tilesdl.cc @@ -193,13 +193,13 @@ bool TilesFramework::initialise() m_region_tile = new DungeonRegion(&m_image, m_fonts[lbl_font].font, TILE_X, TILE_Y); - m_region_map = new MapRegion(Options.tile_map_pixels); + m_region_map = new MapRegion(Options.tile_map_pixels); m_region_self_inv = new InventoryRegion(&m_image, m_fonts[lbl_font].font, TILE_X, TILE_Y); - m_region_msg = new MessageRegion(m_fonts[msg_font].font); + m_region_msg = new MessageRegion(m_fonts[msg_font].font); m_region_stat = new StatRegion(m_fonts[stat_font].font); - m_region_crt = new CRTRegion(m_fonts[crt_font].font); + m_region_crt = new CRTRegion(m_fonts[crt_font].font); m_region_menu = new MenuRegion(&m_image, m_fonts[crt_font].font); m_layers[LAYER_NORMAL].m_regions.push_back(m_region_tile); @@ -594,7 +594,7 @@ int TilesFramework::getch_ck() while (!key) { - unsigned int ticks; + unsigned int ticks = 0; if (SDL_WaitEvent(&event)) { @@ -1115,7 +1115,7 @@ void TilesFramework::update_inventory() for (int eq = 0; eq < NUM_EQUIP; eq++) { - if (you.equip[eq] == i) + if (you.equip[eq] == i && you_tran_can_wear(you.inv[i])) { desc.flag |= TILEI_FLAG_EQUIP; break; diff --git a/crawl-ref/source/transfor.cc b/crawl-ref/source/transfor.cc index ab380739e1..d67baf0ec1 100644 --- a/crawl-ref/source/transfor.cc +++ b/crawl-ref/source/transfor.cc @@ -98,7 +98,7 @@ bool remove_equipment(std::set removed) canned_msg(MSG_EMPTY_HANDED); } - // Remove items in order. (std::set is a sorted container) + // Meld items into you in (reverse) order. (std::set is a sorted container) std::set::const_iterator iter; for (iter = removed.begin(); iter != removed.end(); ++iter) { @@ -106,19 +106,41 @@ bool remove_equipment(std::set removed) if (e == EQ_WEAPON || you.equip[e] == -1) continue; - mprf("%s falls away.", + mprf("%s melds into your body.", you.inv[you.equip[e]].name(DESC_CAP_YOUR).c_str()); if (e == EQ_LEFT_RING || e == EQ_RIGHT_RING || e == EQ_AMULET) { item_def &ring = you.inv[you.equip[e]]; - you.equip[e] = -1; - jewellery_remove_effects(ring, false); + jewellery_remove_effects(ring); } else // armour { unwear_armour( you.equip[e] ); - you.equip[e] = -1; + } + } + + return (true); +} + +static bool _unmeld_equipment(std::set melded) +{ + // Unmeld items in order. + std::set::const_iterator iter; + for (iter = melded.begin(); iter != melded.end(); ++iter) + { + const equipment_type e = *iter; + if (e == EQ_WEAPON || you.equip[e] == -1) + continue; + + if (e == EQ_LEFT_RING || e == EQ_RIGHT_RING || e == EQ_AMULET) + { + item_def &ring = you.inv[you.equip[e]]; + jewellery_wear_effects(ring); + } + else // armour + { + armour_wear_effects( you.equip[e] ); } } @@ -138,7 +160,7 @@ static bool check_for_cursed_equipment(const std::set &remove, bool quiet = false) { std::set::const_iterator iter; - for (iter = remove.begin(); iter != remove.end(); ++iter ) + for (iter = remove.begin(); iter != remove.end(); ++iter) { equipment_type e = *iter; if (you.equip[e] == -1) @@ -670,10 +692,19 @@ void untransform(void) you.symbol = '@'; you.colour = LIGHTGREY; - // must be unset first or else infinite loops might result -- bwr + // Must be unset first or else infinite loops might result. -- bwr const transformation_type old_form = static_cast(you.attribute[ ATTR_TRANSFORMATION ]); + // We may have to unmeld a couple of equipment types. + const equipment_type default_rem[] = { + EQ_CLOAK, EQ_HELMET, EQ_GLOVES, EQ_BOOTS, EQ_SHIELD, EQ_BODY_ARMOUR + }; + + std::set melded(default_rem, + default_rem + ARRAYSZ(default_rem)); + _init_equipment_removal(melded, old_form); + you.attribute[ ATTR_TRANSFORMATION ] = TRAN_NONE; you.duration[ DUR_TRANSFORMATION ] = 0; @@ -762,6 +793,8 @@ void untransform(void) break; } + _unmeld_equipment(melded); + // Re-check terrain now that be may no longer be flying. if (old_flight && you.flight_mode() == FL_NONE) move_player_to_grid(you.pos(), false, true, true); -- cgit v1.2.3-54-g00ecf