From a343ad9b9fe784d39aa302f00a379c379ca2aff8 Mon Sep 17 00:00:00 2001 From: ALONSO Laurent Date: Mon, 24 Jan 2022 10:43:58 +0100 Subject: [PATCH] game[junk bag]: try to implement sell/identify in shop. --- rsrc/dialogs/preferences.xml | 14 ++++++++------ rsrc/dialogs/select-pc-with-bag.xml | 22 ++++++++++++++++++++++ rsrc/dialogs/select-pc.xml | 9 +++++---- src/game/boe.actions.cpp | 15 +++++++++++---- src/game/boe.items.cpp | 24 +++++++++++++----------- src/game/boe.party.cpp | 3 +-- src/game/boe.text.cpp | 20 +++++++++----------- src/game/boe.town.cpp | 1 + src/game/boe.ui.hpp | 1 + src/scenario/item.cpp | 20 ++++++++++++++++++++ src/scenario/item.hpp | 3 ++- src/universe/party.cpp | 4 +--- src/universe/pc.cpp | 4 +--- 13 files changed, 95 insertions(+), 45 deletions(-) create mode 100644 rsrc/dialogs/select-pc-with-bag.xml diff --git a/rsrc/dialogs/preferences.xml b/rsrc/dialogs/preferences.xml index 8b96f093..89537bee 100644 --- a/rsrc/dialogs/preferences.xml +++ b/rsrc/dialogs/preferences.xml @@ -22,23 +22,25 @@ Slow Quite Slow + For older machines: - - No graphics frills (lose special effects) - + No graphics frills (lose special effects) Turn off terrain animation Turn of frills on shore - Don't Save Maps No Sounds + Skip splash screen on startup + Show room descriptions more than once Never show instant help Reset instant help (all help windows will reappear) + Make game easier (monsters much weaker) Fewer wandering monsters - Skip splash screen on startup - Scale UI: + Show the junk bag + + Scale UI: 1 1.5 diff --git a/rsrc/dialogs/select-pc-with-bag.xml b/rsrc/dialogs/select-pc-with-bag.xml new file mode 100644 index 00000000..6b35f739 --- /dev/null +++ b/rsrc/dialogs/select-pc-with-bag.xml @@ -0,0 +1,22 @@ + + + + Hit a button or type '1'-'7'. + + + + + + + + + + + + + + + Bag + Select a PC: + + diff --git a/rsrc/dialogs/select-pc.xml b/rsrc/dialogs/select-pc.xml index 202ebf45..bdf116f5 100644 --- a/rsrc/dialogs/select-pc.xml +++ b/rsrc/dialogs/select-pc.xml @@ -1,7 +1,7 @@ - Hit a button or type '1'-'6'. + Hit a button or type '1'-'6'. @@ -9,14 +9,15 @@ - - Bag Select a PC: - + + + + diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp index ab61765c..329164df 100644 --- a/src/game/boe.actions.cpp +++ b/src/game/boe.actions.cpp @@ -820,8 +820,7 @@ static void handle_drop_item(short item_hit, bool& need_redraw) { static void handle_item_shop_action(short item_hit) { long i = item_hit - item_sbar->getPosition(); - cPlayer& shopper = univ.party[stat_window]; - cItem& target = shopper.items[item_hit]; + cItem& target = stat_window<=6 ? univ.party[stat_window].items[item_hit] : univ.party.get_junk_item(item_hit); switch(stat_screen_mode) { case MODE_IDENTIFY: if(!take_gold(shop_identify_cost,false)) @@ -830,14 +829,22 @@ static void handle_item_shop_action(short item_hit) { play_sound(68); ASB("Your item is identified."); target.ident = true; - shopper.combine_things(); + if (stat_window<=6) + univ.party[stat_window].combine_things(); + else { + univ.party.combine_junk_items(); + set_stat_window(ITEM_WIN_JUNK); + } } break; case MODE_SELL_WEAP: case MODE_SELL_ARMOR: case MODE_SELL_ANY: play_sound(-39); univ.party.gold += store_selling_values[i]; ASB("You sell your item."); - shopper.take_item(item_hit); + if (stat_window<=6) + univ.party[stat_window].take_item(item_hit); + else + univ.party.take_junk_item(item_hit); put_item_screen(stat_window); break; case MODE_ENCHANT: diff --git a/src/game/boe.items.cpp b/src/game/boe.items.cpp index f7709863..ca66cde9 100644 --- a/src/game/boe.items.cpp +++ b/src/game/boe.items.cpp @@ -196,10 +196,7 @@ void give_thing(short pc_num, short item_num) { add_string_to_buf("Give: Item is cursed."); else { item_store = item_to_give; - if (univ.party.show_junk_bag && pc_num!=7) - who_to = char_select_pc(4, "Give item to who? (type '7' for Bag)"); - else - who_to = char_select_pc(3, "Give item to who?"); + who_to = char_select_pc((univ.party.show_junk_bag && pc_num!=7 && (item_to_give.cursed || !item_to_give.unsellable)) ? 4 : 3, "Give item to who?"); if(overall_mode == MODE_COMBAT && who_to < 6 && !adjacent(univ.party[pc_num].combat_pos,univ.party[who_to].combat_pos)) { add_string_to_buf("Give: Must be adjacent."); who_to = 6; @@ -219,11 +216,11 @@ void give_thing(short pc_num, short item_num) { ; // ok else { if(who_to<6 && !univ.party[who_to].has_space()) - ASB("Can't give: PC has max. # of items."); + add_string_to_buf("Can't give: PC has max. # of items."); else if(who_to<6) - ASB("Can't give: PC carrying too much."); + add_string_to_buf("Can't give: PC carrying too much."); else - ASB("Can't give: unknown problem."); + add_string_to_buf("Can't give: unknown problem."); if(how_many > 0) item_to_give.charges += how_many; take_given_item = false; @@ -550,7 +547,11 @@ static bool display_item_event_filter(cDialog& me, std::string id, size_t& first give_help(38,0,me); return true; } - + if (current_getting_pc==7 && !item.cursed && item.unsellable) { + beep(); // TODO: This is a game event, so it should have a game sound, not a system alert. + me["prompt"].setText("The object resists any attempt to insert it into the bag."); + return true; + } set_item_flag(&item); play_sound(0); // formerly force_play_sound if (current_getting_pc<6) { @@ -559,8 +560,10 @@ static bool display_item_event_filter(cDialog& me, std::string id, size_t& first flags |= GIVE_ALLOW_OVERLOAD; univ.party[current_getting_pc].give_item(item, flags); } - else + else { univ.party.give_junk_item(item, is_combat() ? -1 : is_town() ? univ.party.town_num : 200); + if (stat_window==ITEM_WIN_JUNK) set_stat_window(stat_window); + } } *item_array[item_hit] = cItem(); item_array.erase(item_array.begin() + item_hit); @@ -598,7 +601,6 @@ bool display_item(location from_loc,short /*pc_num*/,short mode, bool check_cont else if(mode == 0) stole_something = show_get_items("Getting all adjacent items:", item_array, current_getting_pc); else stole_something = show_get_items("Getting all nearby items:", item_array, current_getting_pc); - if (stat_window==ITEM_WIN_JUNK) set_stat_window(stat_window); // FIXME MUST NO BE HERE put_item_screen(stat_window); put_pc_screen(); @@ -942,7 +944,7 @@ short char_select_pc(short mode,const char *title) { set_cursor(sword_curs); - cDialog selectPc("select-pc"); + cDialog selectPc(mode==4 ? "select-pc-with-bag" : "select-pc"); selectPc.attachClickHandlers(select_pc_event_filter, {"cancel", "pick1", "pick2", "pick3", "pick4", "pick5", "pick6", "junk"}); selectPc["title"].setText(title); diff --git a/src/game/boe.party.cpp b/src/game/boe.party.cpp index 58e551fc..8bb7a74c 100644 --- a/src/game/boe.party.cpp +++ b/src/game/boe.party.cpp @@ -630,8 +630,7 @@ void do_mage_spell(short pc_num,eSpell spell_num,bool freebie) { } if (numDone) { univ.party.combine_junk_items(); - if (stat_window==ITEM_WIN_JUNK) - set_stat_window(ITEM_WIN_JUNK); + if (stat_window==ITEM_WIN_JUNK) set_stat_window(ITEM_WIN_JUNK); } } break; diff --git a/src/game/boe.text.cpp b/src/game/boe.text.cpp index 9dcf1b8c..cb87c24d 100644 --- a/src/game/boe.text.cpp +++ b/src/game/boe.text.cpp @@ -339,11 +339,9 @@ void put_item_screen(eItemWinMode screen_num) { if (is_town()) place_item_button(2,i,ITEMBTN_DROP); } } -#if 0 - if(stat_screen_mode != MODE_INVEN && stat_screen_mode != MODE_SHOP) { - place_buy_button(i,pc,i_num); - } -#endif + // now add identify or sell button if in shop + if (stat_screen_mode==MODE_IDENTIFY || stat_screen_mode==MODE_SELL_WEAP || stat_screen_mode==MODE_SELL_ARMOR || stat_screen_mode==MODE_SELL_ANY) + place_buy_button(i,7,i_num); } // end of if item is there } // end of for(short i = 0; i < 8; i++) break; @@ -419,18 +417,18 @@ void put_item_screen(eItemWinMode screen_num) { } void place_buy_button(short position,short pc_num,short item_num) { + if (pc_num<0 || pc_num>7) return; rectangle dest_rect,source_rect; rectangle button_sources[3] = {{24,0,36,30},{36,0,48,30},{48,0,60,30}}; short val_to_place; // TODO: This is now duplicated here and in start_town_mode() short aug_cost[10] = {4,7,10,8, 15,15,10, 0,0,0}; - const cPlayer& pc = univ.party[pc_num]; - const cItem& item = pc.items[item_num]; + const cItem& item = pc_num<=6 ? univ.party[pc_num].items[item_num] : univ.party.get_junk_item(item_num); if(item.variety == eItemType::NO_ITEM) return; - + bool const is_equipped = pc_num<=6 ? univ.party[pc_num].equip[item_num] : false; dest_rect = item_buttons[position][ITEMBTN_SPEC]; val_to_place = (item.charges > 0) ? @@ -447,19 +445,19 @@ void place_buy_button(short position,short pc_num,short item_num) { } break; case MODE_SELL_WEAP: - if((*item.variety).is_weapon && !pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { + if((*item.variety).is_weapon && !is_equipped && item.ident && val_to_place > 0 && !item.unsellable) { item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[1]; } break; case MODE_SELL_ARMOR: - if((*item.variety).is_armour && !pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { + if((*item.variety).is_armour && !is_equipped && item.ident && val_to_place > 0 && !item.unsellable) { item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[1]; } break; case MODE_SELL_ANY: - if(!pc.equip[item_num] && item.ident && val_to_place > 0 && !item.unsellable) { + if(!is_equipped && item.ident && val_to_place > 0 && !item.unsellable) { item_area_button_active[position][ITEMBTN_SPEC] = true; source_rect = button_sources[1]; } diff --git a/src/game/boe.town.cpp b/src/game/boe.town.cpp index 269fa1da..0f4080cd 100644 --- a/src/game/boe.town.cpp +++ b/src/game/boe.town.cpp @@ -598,6 +598,7 @@ void start_town_combat(eDirection direction) { set_pc_moves(); pick_next_pc(); center = univ.current_pc().combat_pos; + UI::toolbar.reset_active_button(); UI::toolbar.draw(mainPtr); put_pc_screen(); set_stat_window_for_pc(univ.cur_pc); diff --git a/src/game/boe.ui.hpp b/src/game/boe.ui.hpp index 145c405a..553ac77d 100644 --- a/src/game/boe.ui.hpp +++ b/src/game/boe.ui.hpp @@ -40,6 +40,7 @@ class cToolbar { void draw_buttons(); void init(); public: + void reset_active_button() { active=-1; } void draw(sf::RenderTarget& targ); eToolbarButton button_hit(sf::RenderWindow& win, location click); }; diff --git a/src/scenario/item.cpp b/src/scenario/item.cpp index 5baad196..7e5d1f22 100644 --- a/src/scenario/item.cpp +++ b/src/scenario/item.cpp @@ -101,6 +101,26 @@ bool cItem::abil_group() const { return false; } +bool cItem::can_be_combined_with(cItem const &item) const +{ + if (!ident || !item.ident || variety==eItemType::NO_ITEM || item.variety==eItemType::NO_ITEM || + type_flag==0 || item.type_flag==0) + return false; + if (name!=item.name || weight!=item.weight || graphic_num!=item.graphic_num || + value!=item.value || special_class!=item.special_class) return false; + if (item_level != item.item_level || awkward!=item.awkward || bonus!=item.bonus || protection!=item.protection) + return false; + if (weap_type!=item.weap_type || magic_use_type!=item.magic_use_type || ability!=item.ability) + return false; + if (ability!=eItemAbil::NONE && (abil_data[0]!=item.abil_data[0] || abil_data[1]!=item.abil_data[1])) + return false; + if (missile!=item.missile || is_special!=item.is_special) + return false; + if (magic!=item.magic || cursed!=item.cursed || enchanted!=item.enchanted || unsellable!=item.unsellable) + return false; + return true; +} + cItem::cItem(){ variety = eItemType::NO_ITEM; item_level = 0; diff --git a/src/scenario/item.hpp b/src/scenario/item.hpp index c1bd4c93..96b4cb37 100644 --- a/src/scenario/item.hpp +++ b/src/scenario/item.hpp @@ -79,7 +79,8 @@ public: cItem(); explicit cItem(eItemPreset preset); explicit cItem(eAlchemy recipe); - + bool can_be_combined_with(cItem const &item) const; + cPictNum get_picture_num(bool tiny=false) const; void import_legacy(legacy::item_record_type const & old); void writeTo(std::ostream& file, std::string prefix = "") const; diff --git a/src/universe/party.cpp b/src/universe/party.cpp index 91959dd4..468267be 100644 --- a/src/universe/party.cpp +++ b/src/universe/party.cpp @@ -260,9 +260,7 @@ bool cParty::is_junk_item_compatible_with_town(item_num_t id, int townId) const static bool combine_items(cItem &item1, cItem const &item2) { - if (item1.variety != eItemType::NO_ITEM && item1.ident && item2.ident && - item2.variety != eItemType::NO_ITEM && item1.type_flag == item2.type_flag && - item1.name == item2.name && item1.special_class == item2.special_class) { + if (item1.can_be_combined_with(item2)) { short test = item1.charges + item2.charges; if(test > 125) { item1.charges = 125; diff --git a/src/universe/pc.cpp b/src/universe/pc.cpp index e9499dfe..5d6ef26c 100644 --- a/src/universe/pc.cpp +++ b/src/universe/pc.cpp @@ -712,9 +712,7 @@ void cPlayer::combine_things() { for(int i = 0; i < items.size(); i++) { if(items[i].variety != eItemType::NO_ITEM && items[i].type_flag > 0 && items[i].ident) { for(int j = i + 1; j < items.size(); j++) - if(items[j].variety != eItemType::NO_ITEM && items[j].type_flag == items[i].type_flag && - items[j].name == items[i].name && items[j].special_class == items[i].special_class && - items[j].ident) { + if(items[j].can_be_combined_with(items[i])) { if(print_result) print_result("(items combined)"); short test = items[i].charges + items[j].charges; if(test > 125) {