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

@@ -22,23 +22,25 @@
<led name='slow' relative='pos-in pos' anchor='spd-head' top='4' left='190' width='53'>Slow</led>
<led name='snail' relative='pos-in pos' anchor='spd-head' top='4' left='274' width='70'>Quite Slow</led>
</group>
<!-- older machine -->
<text size='large' relative='pos-in pos' anchor='spd-head' top='23' left='0' width='182' height='17'>For older machines:</text>
<led name='nofrills' relative='pos-in pos' rel-anchor='prev' top='6' left='0' width='335'>
No graphics frills (lose special effects)
</led>
<led name='nofrills' relative='pos-in pos' rel-anchor='prev' top='6' left='0' width='335'>No graphics frills (lose special effects)</led>
<led name='noanim' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='335'>Turn off terrain animation</led>
<led name='noshore' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='335'>Turn of frills on shore</led>
<led name='nomaps' relative='pos-in pos' rel-anchor='prev' top='15' left='0' width='120'>Don't Save Maps</led>
<led name='nosound' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='117'>No Sounds</led>
<led name='skipsplash' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='340'>Skip splash screen on startup</led>
<!-- help -->
<led name='repeatdesc' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='287'>Show room descriptions more than once</led>
<led name='nohelp' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='306'>Never show instant help</led>
<led name='resethelp' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='340'>
Reset instant help (all help windows will reappear)
</led>
<!-- make game easier -->
<led name='easier' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='352'>Make game easier (monsters much weaker)</led>
<led name='lesswm' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='340'>Fewer wandering monsters</led>
<led name='skipsplash' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='340'>Skip splash screen on startup</led>
<text name='scale-head' size='large' relative='neg pos' anchor='skipsplash' top='17' left='10' width='260' height='17'>Scale UI:</text>
<led name='junk' relative='pos-in pos' rel-anchor='prev' top='10' left='0' width='120'>Show the junk bag</led>
<!-- scaling -->
<text name='scale-head' size='large' relative='neg pos' anchor='junk' top='17' left='10' width='260' height='17'>Scale UI:</text>
<group name='scaleui'>
<led name='1' relative='pos-in pos' anchor='scale-head' top='4' left='15' width='33'>1</led>
<led name='1_5' relative='pos-in pos' anchor='scale-head' top='4' left='55' width='33'>1.5</led>

View File

@@ -0,0 +1,22 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<dialog defbtn='cancel'>
<text top='215' left='11' width='184' height='18'>Hit a button or type '1'-'7'.</text>
<pict type='dlog' num='6' top='8' left='8'/>
<button name='pick1' type='regular' def-key='1' top='31' left='69'><key/></button>
<button name='pick2' type='regular' def-key='2' top='56' left='69'><key/></button>
<button name='pick3' type='regular' def-key='3' top='81' left='69'><key/></button>
<button name='pick4' type='regular' def-key='4' top='106' left='69'><key/></button>
<button name='pick5' type='regular' def-key='5' top='131' left='69'><key/></button>
<button name='pick6' type='regular' def-key='6' top='156' left='69'><key/></button>
<button name='junk' type='regular' def-key='7' top='181' left='69'><key/></button>
<text name='pc1' framed='true' top='35' left='138' width='139' height='16'/>
<text name='pc2' framed='true' top='60' left='138' width='139' height='16'/>
<text name='pc3' framed='true' top='85' left='138' width='139' height='16'/>
<text name='pc4' framed='true' top='110' left='138' width='139' height='16'/>
<text name='pc5' framed='true' top='135' left='138' width='139' height='16'/>
<text name='pc6' framed='true' top='160' left='138' width='139' height='16'/>
<text name='junk-text' framed='true' top='185' left='138' width='139' height='16'>Bag</text>
<text name='title' size='large' top='10' left='49' width='228' height='16'>Select a PC:</text>
<button name='cancel' type='regular' top='212' left='214'>Cancel</button>
</dialog>

View File

@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
<dialog defbtn='cancel'>
<text top='215' left='11' width='184' height='18'>Hit a button or type '1'-'6'.</text>
<text top='190' left='11' width='184' height='18'>Hit a button or type '1'-'6'.</text>
<pict type='dlog' num='6' top='8' left='8'/>
<button name='pick1' type='regular' def-key='1' top='31' left='69'><key/></button>
<button name='pick2' type='regular' def-key='2' top='56' left='69'><key/></button>
@@ -9,14 +9,15 @@
<button name='pick4' type='regular' def-key='4' top='106' left='69'><key/></button>
<button name='pick5' type='regular' def-key='5' top='131' left='69'><key/></button>
<button name='pick6' type='regular' def-key='6' top='156' left='69'><key/></button>
<button name='junk' type='regular' def-key='7' top='181' left='69'><key/></button>
<text name='pc1' framed='true' top='35' left='138' width='139' height='16'/>
<text name='pc2' framed='true' top='60' left='138' width='139' height='16'/>
<text name='pc3' framed='true' top='85' left='138' width='139' height='16'/>
<text name='pc4' framed='true' top='110' left='138' width='139' height='16'/>
<text name='pc5' framed='true' top='135' left='138' width='139' height='16'/>
<text name='pc6' framed='true' top='160' left='138' width='139' height='16'/>
<text name='junk-text' framed='true' top='185' left='138' width='139' height='16'>Bag</text>
<text name='title' size='large' top='10' left='49' width='228' height='16'>Select a PC:</text>
<button name='cancel' type='regular' top='212' left='214'>Cancel</button>
<button name='cancel' type='regular' top='187' left='214'>Cancel</button>
<!-- to make select-pc and select-pc-junk similar -->
<button name='junk' type='regular' def-key='7' top='181' left='69'></button>
<text name='junk-text' top='185' left='138' width='139' height='16'></text>
</dialog>

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