Don't display 'no item' response if another PC can shop. (#679)
These are the rules: - If the active PC gets an empty shop, iterate from the first to last PC until finding someone who can see a shop item - If none can shop, show the 'no item' response - When the active PC buys something, if this clears out the shop, iterate from the first to last PC until finding someone who can see a shop item - if none can see an item, stay on the empty shop of the PC that was active when the last item was bought. - When shopping ends, if the shop interface was the last thing to change the player's active PC, it puts it back how it was. Fix #669
This commit is contained in:
@@ -895,6 +895,14 @@ void handle_switch_pc(short which_pc, bool& need_redraw, bool& need_reprint) {
|
||||
add_string_to_buf("Set active: PC must be here & active.");
|
||||
else {
|
||||
univ.cur_pc = which_pc;
|
||||
|
||||
// The shop interface may have taken control of the active PC. If the player
|
||||
// manually sets active PC before shopping ends, don't restore the active PC from before
|
||||
// shopping switched it. Unless the player buys something again, forcing it to store again.
|
||||
extern short store_cur_pc;
|
||||
if(store_cur_pc != -1)
|
||||
store_cur_pc = -1;
|
||||
|
||||
set_stat_window_for_pc(which_pc);
|
||||
add_string_to_buf("Now " + std::string(overall_mode == MODE_SHOPPING ? "shopping" : "active") + ": " + pc.name);
|
||||
adjust_spell_menus();
|
||||
|
@@ -98,8 +98,38 @@ std::vector<int> shop_array;
|
||||
|
||||
cShop active_shop;
|
||||
short active_shop_num;
|
||||
short store_cur_pc = -1;
|
||||
|
||||
bool start_shop_mode(short which,short cost_adj,std::string store_name, bool cancel_when_empty) {
|
||||
// For healing shops, other PCs might be able to buy something if
|
||||
// the active PC can't
|
||||
bool start_shop_mode_other_pc(bool allow_empty = false) {
|
||||
// The shop might change the current PC multiple times, but we want to restore
|
||||
// it to the original active PC when shopping ends, so only store if we're
|
||||
// not yet storing
|
||||
if(store_cur_pc == -1)
|
||||
store_cur_pc = univ.cur_pc;
|
||||
|
||||
// But I actually want to store the PC that's active now, so if no one can buy anything but
|
||||
// we want to leave an empty shop, we can leave the PC selection where it is.
|
||||
short pc_buying = univ.cur_pc;
|
||||
|
||||
bool other_pc_can_buy = false;
|
||||
for(int i = 0; i < 6; ++i){
|
||||
if(univ.party[i].main_status != eMainStatus::ABSENT){
|
||||
univ.cur_pc = i;
|
||||
if(start_shop_mode(active_shop_num,active_shop.getCostAdjust(),save_talk_str1,true,true)){
|
||||
other_pc_can_buy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!other_pc_can_buy && allow_empty){
|
||||
start_shop_mode(active_shop_num,active_shop.getCostAdjust(),save_talk_str1,false,true);
|
||||
}
|
||||
return other_pc_can_buy;
|
||||
}
|
||||
|
||||
bool start_shop_mode(short which,short cost_adj,std::string store_name, bool cancel_when_empty, bool already_started) {
|
||||
rectangle area_rect;
|
||||
if(which < 0 || which >= univ.scenario.shops.size()) {
|
||||
showError("The scenario tried to place you in a nonexistent shop!");
|
||||
@@ -138,7 +168,8 @@ bool start_shop_mode(short which,short cost_adj,std::string store_name, bool can
|
||||
area_rect = talk_area_rect;
|
||||
talk_gworld().create(area_rect.width(), area_rect.height());
|
||||
|
||||
store_pre_shop_mode = overall_mode;
|
||||
if(!already_started)
|
||||
store_pre_shop_mode = overall_mode;
|
||||
overall_mode = MODE_SHOPPING;
|
||||
stat_screen_mode = MODE_SHOP;
|
||||
shop_sbar->setPosition(0);
|
||||
@@ -167,6 +198,11 @@ void end_shop_mode() {
|
||||
record_action("end_shop_mode", "");
|
||||
}
|
||||
|
||||
if(store_cur_pc >= 0){
|
||||
univ.cur_pc = store_cur_pc;
|
||||
store_cur_pc = -1;
|
||||
}
|
||||
|
||||
rectangle dummy_rect = {0,0,0,0};
|
||||
|
||||
// This would be a place to show the text box, if I add it (and if this is not an outdoor shop).
|
||||
@@ -427,8 +463,12 @@ void handle_sale(int i) {
|
||||
// This looks to be redundant, but I'm just preserving the previous behavior of the code.
|
||||
set_up_shop_array();
|
||||
draw_shop_graphics(false,false,{});
|
||||
}
|
||||
|
||||
// When buying from a healer, we want to select the next PC who needs healing
|
||||
if(shop_array.empty()){
|
||||
start_shop_mode_other_pc(true);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_info_request(int what_picked) {
|
||||
if(recording){
|
||||
@@ -899,12 +939,16 @@ void handle_talk_node(int which_talk_entry) {
|
||||
|
||||
case eTalkNode::SHOP:
|
||||
if(!start_shop_mode(b,a,save_talk_str1,true)){
|
||||
// Second string of shop talk node: Custom message for when shop is empty
|
||||
if(!save_talk_str2.empty()){
|
||||
save_talk_str1 = save_talk_str2;
|
||||
save_talk_str2 = "";
|
||||
}else{
|
||||
save_talk_str1 = "There is nothing available to buy.";
|
||||
if(!start_shop_mode_other_pc()){
|
||||
univ.cur_pc = store_cur_pc;
|
||||
|
||||
// Second string of shop talk node: Custom message for when shop is empty
|
||||
if(!save_talk_str2.empty()){
|
||||
save_talk_str1 = save_talk_str2;
|
||||
save_talk_str2 = "";
|
||||
}else{
|
||||
save_talk_str1 = "There is nothing available to buy.";
|
||||
}
|
||||
}
|
||||
}else{
|
||||
can_save_talk = false;
|
||||
|
@@ -5,7 +5,7 @@
|
||||
#include "dialogxml/dialogs/dialog.hpp"
|
||||
#include "scenario/shop.hpp"
|
||||
|
||||
bool start_shop_mode(short which,short cost_adj,std::string store_name, bool cancel_when_empty = false);
|
||||
bool start_shop_mode(short which,short cost_adj,std::string store_name, bool cancel_when_empty = false, bool already_started = false);
|
||||
void end_shop_mode();
|
||||
bool handle_shop_event(location p, cFramerateLimiter& fps_limiter);
|
||||
void handle_sale(int i);
|
||||
|
Reference in New Issue
Block a user