ソースを参照

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.
Lemongrass3110 11 年 前
コミット
ff9b6253c2
4 ファイル変更85 行追加74 行削除
  1. 46 40
      src/map/buyingstore.c
  2. 1 1
      src/map/buyingstore.h
  3. 37 32
      src/map/vending.c
  4. 1 1
      src/map/vending.h

+ 46 - 40
src/map/buyingstore.c

@@ -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;
 	char message_sql[MESSAGE_SIZE*2];
 
 	if( !result || count == 0 )
 	{// 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] )
 	{// disabled or invalid input
 		sd->buyingstore.slots = 0;
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
-		return;
+		return false;
 	}
 
 	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;
 		clif_displaymessage(sd->fd, msg_txt(sd,246));
 		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) )
 	{// custom: mute limitation
-		return;
+		return false;
 	}
 
 	if( map[sd->bl.m].flag.novending )
 	{// custom: no vending maps
 		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) )
 	{// custom: no vending cells
 		clif_displaymessage(sd->fd, msg_txt(sd,204)); // "You can't open a shop on this cell."
-		return;
+		return false;
 	}
 
 	weight = sd->weight;
@@ -202,14 +202,14 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
 	{// invalid item/amount/price
 		sd->buyingstore.slots = 0;
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
-		return;
+		return false;
 	}
 
 	if( (sd->max_weight*90)/100 < weight )
 	{// not able to carry all wanted items without getting overweight (90%)
 		sd->buyingstore.slots = 0;
 		clif_buyingstore_open_failed(sd, BUYINGSTORE_CREATE_OVERWEIGHT, weight);
-		return;
+		return false;
 	}
 
 	// success
@@ -233,6 +233,8 @@ void buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha
 
 	clif_buyingstore_myitemlist(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;
 }
 
-/** Open vending for Autotrader
+/** Open buyingstore for Autotrader
 * @param sd Player as autotrader
 */
 void buyingstore_reopen( struct map_session_data* sd ){
-	if (!sd || !autotrader_count || !autotraders)
-		return;
-	else { // Ready to open vending for this char
+	// Ready to open buyingstore for this char
+	if ( sd && autotrader_count > 0 && autotraders){
 		uint16 i;
 		uint8 *data, *p;
 		uint16 j, count;
@@ -554,7 +555,7 @@ void buyingstore_reopen( struct map_session_data* sd ){
 			return;
 		}
 		
-		// Init vending data for autotrader
+		// Init buyingstore data for autotrader
 		CREATE(data, uint8, autotraders[i]->count * 8);
 
 		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;
 		}
 
-		// Open the shop again
-		buyingstore_setup( sd, (unsigned char)autotraders[i]->count );
-		buyingstore_create( sd, autotraders[i]->limit, 1, autotraders[i]->title, data, autotraders[i]->count );
-		aFree(data);
+		// Open the buyingstore again
+		if( buyingstore_setup( sd, (unsigned char)autotraders[i]->count ) &&
+			buyingstore_create( sd, autotraders[i]->limit, 1, autotraders[i]->title, data, autotraders[i]->count ) )
+		{
+			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);
 
-		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 );
+			}
 
-		// 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);
 
-		// 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 );
 
-		if( battle_config.feature_autotrade_sit )
-			pc_setsit(sd);
+			map_quit( sd );
+		}
+
+		aFree(data);
 
 		//If the last autotrade is loaded, clear autotraders [Cydh]
 		if (i+1 >= autotrader_count)
@@ -606,7 +614,7 @@ void do_init_buyingstore_autotrade( void ) {
 		autotrader_count = 0;
 
 		// 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,
 			"SELECT `id`, `account_id`, `char_id`, `sex`, `title`, `limit` "
 			"FROM `%s` "
@@ -623,6 +631,12 @@ void do_init_buyingstore_autotrade( void ) {
 		// Init autotraders
 		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
 		i = 0;
 		while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) {
@@ -650,12 +664,6 @@ void do_init_buyingstore_autotrade( void ) {
 		}
 		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
 		for (i = 0; i < autotrader_count; i++){
 			struct s_autotrade *at = NULL;
@@ -714,9 +722,7 @@ void do_init_buyingstore_autotrade( void ) {
 * @author [Cydh]
 */
 void do_final_buyingstore_autotrade(void) {
-	if (!autotrader_count || !autotraders)
-		return;
-	else {
+	if (autotrader_count && autotraders){
 		uint16 i = 0;
 		while (i < autotrader_count) { //Free the autotrader
 			if (autotraders[i] == NULL)

+ 1 - 1
src/map/buyingstore.h

@@ -23,7 +23,7 @@ struct s_buyingstore
 };
 
 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_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);

+ 37 - 32
src/map/vending.c

@@ -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]
  * @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 vending_skill_lvl;
 	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);
 
 	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);
 	
 	// skill level and cart check
 	if( !vending_skill_lvl || !pc_iscarton(sd) ) {
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
-		return;
+		return false;
 	}
 
 	// check number of items in shop
 	if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl )
 	{	// invalid item count
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
-		return;
+		return false;
 	}
 
 	// 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
 		clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
-		return;
+		return false;
 	}
 	sd->state.prevend = 0;
 	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);
 
 	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
 */
 void vending_reopen( struct map_session_data* sd ){
-	if (!sd || !autotrader_count || !autotraders)
-		return;
-	else { // Ready to open vending for this char
+	// Ready to open vending for this char
+	if ( sd && autotrader_count > 0 && autotraders){
 		uint16 i;
 		uint8 *data, *p;
 		uint16 j, count;
@@ -502,25 +503,31 @@ void vending_reopen( struct map_session_data* sd ){
 		// Set him into a hacked prevend state
 		sd->state.prevend = 1;
 
-		// Open the shop again
-		vending_openvending(sd, autotraders[i]->title, data, count);
-		aFree(data);
+		// Open the vending again
+		if( vending_openvending(sd, autotraders[i]->title, data, count) ){
+			// 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",
-			sd->status.name,count,mapindex_id2name(sd->mapindex),sd->bl.x,sd->bl.y);
+			// Make him look perfect
+			unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
 
-		// 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 );
-		}
+			if( battle_config.feature_autotrade_sit )
+				pc_setsit(sd);
 
-		// Make him look perfect
-		unit_setdir(&sd->bl,battle_config.feature_autotrade_direction);
+			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",
+				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 );
+		}
 
-		if( battle_config.feature_autotrade_sit )
-			pc_setsit(sd);
+		aFree(data);
 
 		//If the last autotrade is loaded, clear autotraders [Cydh]
 		if (i+1 >= autotrader_count)
@@ -554,6 +561,12 @@ void do_init_vending_autotrade( void ) {
 		// Init autotraders
 		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
 		i = 0;
 		while (SQL_SUCCESS == Sql_NextRow(mmysql_handle) && i < autotrader_count) {
@@ -580,12 +593,6 @@ void do_init_vending_autotrade( void ) {
 		}
 		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
 		for (i = 0; i < autotrader_count; i++){
 			struct s_autotrade *at = NULL;
@@ -644,9 +651,7 @@ void do_init_vending_autotrade( void ) {
 * @author [Cydh]
 */
 void do_final_vending_autotrade(void) {
-	if (!autotrader_count || !autotraders)
-		return;
-	else {
+	if (autotrader_count && autotraders){
 		uint16 i = 0;
 		while (i < autotrader_count) { //Free the autotrader
 			if (autotraders[i] == NULL)

+ 1 - 1
src/map/vending.h

@@ -22,7 +22,7 @@ void do_init_vending_autotrade( void );
  
 void vending_reopen( 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_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);