game[junk bag]: try to implement sell/identify in shop.

This commit is contained in:
ALONSO Laurent
2022-01-24 10:43:58 +01:00
committed by Celtic Minstrel
parent a182c61a50
commit a343ad9b9f
13 changed files with 95 additions and 45 deletions

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;

View File

@@ -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];
}

View File

@@ -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);

View File

@@ -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);
};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {