Minor bug fix

If a player did not meet the requirements to reopen the buyingstore/vending for whatever reason the character is now set offline.

A possible examples I have tested with is to change the area where the player's shop was to novending, which will not allow him to open the shop in this area.
This commit is contained in:
Lemongrass3110 2014-02-05 09:21:22 +01:00
parent b3506fb8f5
commit ff9b6253c2
4 changed files with 86 additions and 75 deletions

View File

@ -107,21 +107,21 @@ bool buyingstore_setup(struct map_session_data* sd, unsigned char slots){
} }
void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count) bool buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count)
{ {
unsigned int i, weight, listidx; unsigned int i, weight, listidx;
char message_sql[MESSAGE_SIZE*2]; char message_sql[MESSAGE_SIZE*2];
if( !result || count == 0 ) if( !result || count == 0 )
{// canceled, or no items {// canceled, or no items
return; return false;
} }
if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] ) if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] )
{// disabled or invalid input {// disabled or invalid input
sd->buyingstore.slots = 0; sd->buyingstore.slots = 0;
clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0); clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
return; return false;
} }
if( !pc_can_give_items(sd) ) if( !pc_can_give_items(sd) )
@ -129,24 +129,24 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
sd->buyingstore.slots = 0; sd->buyingstore.slots = 0;
clif_displaymessage(sd->fd, msg_txt(sd,246)); clif_displaymessage(sd->fd, msg_txt(sd,246));
clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0); clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
return; return false;
} }
if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) ) if( sd->sc.data[SC_NOCHAT] && (sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM) )
{// custom: mute limitation {// custom: mute limitation
return; return false;
} }
if( map[sd->bl.m].flag.novending ) if( map[sd->bl.m].flag.novending )
{// custom: no vending maps {// custom: no vending maps
clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map"
return; return false;
} }
if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) ) if( map_getcell(sd->bl.m, sd->bl.x, sd->bl.y, CELL_CHKNOVENDING) )
{// custom: no vending cells {// custom: no vending cells
clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell." clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
return; return false;
} }
weight = sd->weight; weight = sd->weight;
@ -202,14 +202,14 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
{// invalid item/amount/price {// invalid item/amount/price
sd->buyingstore.slots = 0; sd->buyingstore.slots = 0;
clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0); clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
return; return false;
} }
if( (sd->max_weight*90)/100 < weight ) if( (sd->max_weight*90)/100 < weight )
{// not able to carry all wanted items without getting overweight (90%) {// not able to carry all wanted items without getting overweight (90%)
sd->buyingstore.slots = 0; sd->buyingstore.slots = 0;
clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight); clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
return; return false;
} }
// success // success
@ -233,6 +233,8 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
clif_buyingstore_myitemlist(sd); clif_buyingstore_myitemlist(sd);
clif_buyingstore_entry(sd); clif_buyingstore_entry(sd);
return true;
} }
@ -538,13 +540,12 @@ bool buyingstore_searchall(struct map_session_data* sd, const struct s_search_st
return true; return true;
} }
/** Open vending for Autotrader /** Open buyingstore for Autotrader
* @param sd Player as autotrader * @param sd Player as autotrader
*/ */
void buyingstore_reopen( struct map_session_data* sd ){ void buyingstore_reopen( struct map_session_data* sd ){
if (!sd || !autotrader_count || !autotraders) // Ready to open buyingstore for this char
return; if ( sd && autotrader_count > 0 && autotraders){
else { // Ready to open vending for this char
uint16 i; uint16 i;
uint8 *data, *p; uint8 *data, *p;
uint16 j, count; uint16 j, count;
@ -554,7 +555,7 @@ void buyingstore_reopen( struct map_session_data* sd ){
return; return;
} }
// Init vending data for autotrader // Init buyingstore data for autotrader
CREATE(data, uint8, autotraders[i]->count * 8); CREATE(data, uint8, autotraders[i]->count * 8);
for (j = 0, p = data, count = autotraders[i]->count; j < autotraders[i]->count; j++) { for (j = 0, p = data, count = autotraders[i]->count; j < autotraders[i]->count; j++) {
@ -570,26 +571,33 @@ void buyingstore_reopen( struct map_session_data* sd ){
p += 8; p += 8;
} }
// Open the shop again // Open the buyingstore again
buyingstore_setup( sd, (unsigned char)autotraders[i]->count ); if( buyingstore_setup( sd, (unsigned char)autotraders[i]->count ) &&
buyingstore_create( sd, autotraders[i]->limit, 1, autotraders[i]->title, data, autotraders[i]->count ); buyingstore_create( sd, autotraders[i]->limit, 1, autotraders[i]->title, data, autotraders[i]->count ) )
aFree(data);
ShowInfo("Loaded autotrade buyingstore data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items at "CL_WHITE"%s (%d,%d)"CL_RESET"\n",
sd->status.name,count,mapindex_id2name(sd->mapindex),sd->bl.x,sd->bl.y);
// Set him to autotrade
if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
buyingstore_db, sd->buyer_id ) != SQL_SUCCESS )
{ {
Sql_ShowDebug( mmysql_handle ); ShowInfo("Loaded autotrade buyingstore data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items at "CL_WHITE"%s (%d,%d)"CL_RESET"\n",
sd->status.name,count,mapindex_id2name(sd->mapindex),sd->bl.x,sd->bl.y);
// Set him to autotrade
if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
buyingstore_db, sd->buyer_id ) != SQL_SUCCESS )
{
Sql_ShowDebug( mmysql_handle );
}
// Make him look perfect
unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
if( battle_config.feature_autotrade_sit )
pc_setsit(sd);
}else{
// Failed to open the buyingstore, set him offline
ShowWarning("Failed to load autotrade buyingstore data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items\n", sd->status.name, count );
map_quit( sd );
} }
// Make him look perfect aFree(data);
unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
if( battle_config.feature_autotrade_sit )
pc_setsit(sd);
//If the last autotrade is loaded, clear autotraders [Cydh] //If the last autotrade is loaded, clear autotraders [Cydh]
if (i+1 >= autotrader_count) if (i+1 >= autotrader_count)
@ -606,7 +614,7 @@ void do_init_buyingstore_autotrade( void ) {
autotrader_count = 0; autotrader_count = 0;
// Get autotrader from table. `map`, `x`, and `y`, aren't used here // Get autotrader from table. `map`, `x`, and `y`, aren't used here
// Just read player that has data at vending_items [Cydh] // Just read player that has data at buyingstore_items [Cydh]
if (Sql_Query(mmysql_handle, if (Sql_Query(mmysql_handle,
"SELECT `id`, `account_id`, `char_id`, `sex`, `title`, `limit` " "SELECT `id`, `account_id`, `char_id`, `sex`, `title`, `limit` "
"FROM `%s` " "FROM `%s` "
@ -623,6 +631,12 @@ void do_init_buyingstore_autotrade( void ) {
// Init autotraders // Init autotraders
CREATE(autotraders, struct s_autotrade *, autotrader_count); CREATE(autotraders, struct s_autotrade *, autotrader_count);
if (autotraders == NULL) { //This is shouldn't happen [Cydh]
ShowError("Failed to initialize buyingstore autotraders!\n");
Sql_FreeResult(mmysql_handle);
return;
}
// Init each autotrader data // Init each autotrader data
i = 0; i = 0;
while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) { while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) {
@ -650,12 +664,6 @@ void do_init_buyingstore_autotrade( void ) {
} }
Sql_FreeResult(mmysql_handle); Sql_FreeResult(mmysql_handle);
if (autotraders == NULL) { //This is shouldn't happen [Cydh]
ShowError("Failed to initialize autotraders!\n");
do_final_buyingstore_autotrade();
return;
}
//Init items on vending list each autotrader //Init items on vending list each autotrader
for (i = 0; i < autotrader_count; i++){ for (i = 0; i < autotrader_count; i++){
struct s_autotrade *at = NULL; struct s_autotrade *at = NULL;
@ -714,9 +722,7 @@ void do_init_buyingstore_autotrade( void ) {
* @author [Cydh] * @author [Cydh]
*/ */
void do_final_buyingstore_autotrade(void) { void do_final_buyingstore_autotrade(void) {
if (!autotrader_count || !autotraders) if (autotrader_count && autotraders){
return;
else {
uint16 i = 0; uint16 i = 0;
while (i < autotrader_count) { //Free the autotrader while (i < autotrader_count) { //Free the autotrader
if (autotraders[i] == NULL) if (autotraders[i] == NULL)

View File

@ -23,7 +23,7 @@ struct s_buyingstore
}; };
bool buyingstore_setup(struct map_session_data* sd, unsigned char slots); bool buyingstore_setup(struct map_session_data* sd, unsigned char slots);
void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count); bool buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned char result, const char* storename, const uint8* itemlist, unsigned int count);
void buyingstore_close(struct map_session_data* sd); void buyingstore_close(struct map_session_data* sd);
void buyingstore_open(struct map_session_data* sd, int account_id); void buyingstore_open(struct map_session_data* sd, int account_id);
void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count); void buyingstore_trade(struct map_session_data* sd, int account_id, unsigned int buyer_id, const uint8* itemlist, unsigned int count);

View File

@ -297,7 +297,7 @@ void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const ui
* data := {<index>.w <amount>.w <value>.l}[count] * data := {<index>.w <amount>.w <value>.l}[count]
* @param count : number of different items * @param count : number of different items
*/ */
void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) { bool vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count) {
int i, j; int i, j;
int vending_skill_lvl; int vending_skill_lvl;
char message_sql[MESSAGE_SIZE*2]; char message_sql[MESSAGE_SIZE*2];
@ -305,21 +305,21 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
nullpo_retv(sd); nullpo_retv(sd);
if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd)) if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once return false; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
vending_skill_lvl = pc_checkskill(sd, MC_VENDING); vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
// skill level and cart check // skill level and cart check
if( !vending_skill_lvl || !pc_iscarton(sd) ) { if( !vending_skill_lvl || !pc_iscarton(sd) ) {
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
return; return false;
} }
// check number of items in shop // check number of items in shop
if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
{ // invalid item count { // invalid item count
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
return; return false;
} }
// filter out invalid items // filter out invalid items
@ -353,7 +353,7 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
if( i == 0 ) { // no valid item found if( i == 0 ) { // no valid item found
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
return; return false;
} }
sd->state.prevend = 0; sd->state.prevend = 0;
sd->state.vending = true; sd->state.vending = true;
@ -377,6 +377,8 @@ void vending_openvending(struct map_session_data* sd, const char* message, const
clif_showvendingboard(&sd->bl,message,0); clif_showvendingboard(&sd->bl,message,0);
idb_put(vending_db, sd->status.char_id, sd); idb_put(vending_db, sd->status.char_id, sd);
return true;
} }
/** /**
@ -463,9 +465,8 @@ bool vending_searchall(struct map_session_data* sd, const struct s_search_store_
* @param sd Player as autotrader * @param sd Player as autotrader
*/ */
void vending_reopen( struct map_session_data* sd ){ void vending_reopen( struct map_session_data* sd ){
if (!sd || !autotrader_count || !autotraders) // Ready to open vending for this char
return; if ( sd && autotrader_count > 0 && autotraders){
else { // Ready to open vending for this char
uint16 i; uint16 i;
uint8 *data, *p; uint8 *data, *p;
uint16 j, count; uint16 j, count;
@ -502,25 +503,31 @@ void vending_reopen( struct map_session_data* sd ){
// Set him into a hacked prevend state // Set him into a hacked prevend state
sd->state.prevend = 1; sd->state.prevend = 1;
// Open the shop again // Open the vending again
vending_openvending(sd, autotraders[i]->title, data, count); if( vending_openvending(sd, autotraders[i]->title, data, count) ){
aFree(data); // Set him to autotrade
if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;",
vendings_db, sd->vender_id ) != SQL_SUCCESS )
{
Sql_ShowDebug( mmysql_handle );
}
ShowInfo("Loaded autotrade vending data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items at "CL_WHITE"%s (%d,%d)"CL_RESET"\n", // Make him look perfect
sd->status.name,count,mapindex_id2name(sd->mapindex),sd->bl.x,sd->bl.y); unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
// Set him to autotrade if( battle_config.feature_autotrade_sit )
if (Sql_Query( mmysql_handle, "UPDATE `%s` SET `autotrade` = 1 WHERE `id` = %d;", pc_setsit(sd);
vendings_db, sd->vender_id ) != SQL_SUCCESS )
{ ShowInfo("Loaded autotrade vending data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items at "CL_WHITE"%s (%d,%d)"CL_RESET"\n",
Sql_ShowDebug( mmysql_handle ); sd->status.name,count,mapindex_id2name(sd->mapindex),sd->bl.x,sd->bl.y);
}else{
// Failed to open the vending, set him offline
ShowWarning("Failed to load autotrade vending data for '"CL_WHITE"%s"CL_RESET"' with '"CL_WHITE"%d"CL_RESET"' items\n", sd->status.name, count );
map_quit( sd );
} }
// Make him look perfect aFree(data);
unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
if( battle_config.feature_autotrade_sit )
pc_setsit(sd);
//If the last autotrade is loaded, clear autotraders [Cydh] //If the last autotrade is loaded, clear autotraders [Cydh]
if (i+1 >= autotrader_count) if (i+1 >= autotrader_count)
@ -554,6 +561,12 @@ void do_init_vending_autotrade( void ) {
// Init autotraders // Init autotraders
CREATE(autotraders, struct s_autotrade *, autotrader_count); CREATE(autotraders, struct s_autotrade *, autotrader_count);
if (autotraders == NULL) { //This is shouldn't happen [Cydh]
ShowError("Failed to initialize vending autotraders!\n");
Sql_FreeResult(mmysql_handle);
return;
}
// Init each autotrader data // Init each autotrader data
i = 0; i = 0;
while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) { while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) {
@ -580,12 +593,6 @@ void do_init_vending_autotrade( void ) {
} }
Sql_FreeResult(mmysql_handle); Sql_FreeResult(mmysql_handle);
if (autotraders == NULL) { //This is shouldn't happen [Cydh]
ShowError("Failed to initialize autotraders!\n");
do_final_vending_autotrade();
return;
}
//Init items on vending list each autotrader //Init items on vending list each autotrader
for (i = 0; i < autotrader_count; i++){ for (i = 0; i < autotrader_count; i++){
struct s_autotrade *at = NULL; struct s_autotrade *at = NULL;
@ -644,9 +651,7 @@ void do_init_vending_autotrade( void ) {
* @author [Cydh] * @author [Cydh]
*/ */
void do_final_vending_autotrade(void) { void do_final_vending_autotrade(void) {
if (!autotrader_count || !autotraders) if (autotrader_count && autotraders){
return;
else {
uint16 i = 0; uint16 i = 0;
while (i < autotrader_count) { //Free the autotrader while (i < autotrader_count) { //Free the autotrader
if (autotraders[i] == NULL) if (autotraders[i] == NULL)

View File

@ -22,7 +22,7 @@ void do_init_vending_autotrade( void );
void vending_reopen( struct map_session_data* sd ); void vending_reopen( struct map_session_data* sd );
void vending_closevending(struct map_session_data* sd); void vending_closevending(struct map_session_data* sd);
void vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count); bool vending_openvending(struct map_session_data* sd, const char* message, const uint8* data, int count);
void vending_vendinglistreq(struct map_session_data* sd, int id); void vending_vendinglistreq(struct map_session_data* sd, int id);
void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count); void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count);
bool vending_search(struct map_session_data* sd, unsigned short nameid); bool vending_search(struct map_session_data* sd, unsigned short nameid);