Fixed vending_over_max behavior to match official (#8469)

Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
Daegaladh 2024-07-05 02:35:41 +02:00 committed by GitHub
parent 29a63820fd
commit 0a977c1fd7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 53 additions and 9 deletions

View File

@ -12,8 +12,10 @@
// The highest value at which an item can be sold via the merchant vend skill. (in zeny)
vending_max_value: 1000000000
// Whether to allow buying from vending chars that are at their max. zeny limit.
// If set to yes, the rest of the zeny above the char's capacity will disappear.
// Whether to allow placing items on a vending store when the player's zeny plus the total price
// of the items exceeds the maximum zeny allowed. (Note 1)
// If set to "yes", the items will be placed in the store but other players will not be able to buy them.
// Official behavior is "yes", but on some official servers the client doesn't allow this.
vending_over_max: yes
// Tax to apply to all vending transactions (eg: 10000 = 100%, 50 = 0.50%)

View File

@ -7674,15 +7674,12 @@ void clif_buyvending( map_session_data& sd, uint16 index, uint16 amount, e_pc_pu
/// Show's vending player its list of items for sale.
/// 0a28 <result>.B (ZC_ACK_OPENSTORE2)
/// result:
/// 0 = Success
/// 1 = Failed
void clif_openvending_ack( map_session_data& sd, bool failure ){
void clif_openvending_ack( map_session_data& sd, e_ack_openstore2 result ){
#if PACKETVER >= 20141022
PACKET_ZC_ACK_OPENSTORE2 packet{};
packet.packetType = HEADER_ZC_ACK_OPENSTORE2;
packet.result = failure;
packet.result = static_cast<decltype(packet.result)>(result);
clif_send( &packet, sizeof( packet ), &sd.bl, SELF );
#endif
@ -7722,7 +7719,7 @@ void clif_openvending( map_session_data& sd ){
clif_send( p, p->packetLength, &sd.bl, SELF );
clif_openvending_ack( sd, false );
clif_openvending_ack( sd, OPENSTORE2_SUCCESS );
}

View File

@ -639,6 +639,9 @@ enum clif_messages : uint16_t {
// Currently there is no attendance check event.
MSI_CHECK_ATTENDANCE_NOT_EVENT = 3474,
// The total amount of items to sell exceeds the amount of Zeny you can have. \nPlease modify the quantity and price.
MSI_MERCHANTSHOP_TOTA_LOVER_ZENY_ERR = 3826,
// It weighs more than 70%. Decrease the Weight and try again.
MSI_ENCHANT_FAILED_OVER_WEIGHT = 3837,
@ -784,6 +787,21 @@ enum e_pc_purchase_result_frommc : uint8 {
PURCHASEMC_NO_SALES_INFO = 7,
};
enum e_ack_openstore2 : uint8 {
// Success
OPENSTORE2_SUCCESS = 0,
// (Pop-up) Failed to open stalls. (MSI_MERCHANTSHOP_MAKING_FAIL / 2639)
OPENSTORE2_FAILED = 1,
// 2 is unused
#if PACKETVER >= 20170419
// Unable to open a shop at the current location. (MSI_MERCHANTSHOP_FAIL_POSITION / 3229)
OPENSTORE2_NOVENDING = 3,
#endif
};
enum e_ack_whisper : uint8 {
ACKWHISPER_SUCCESS = 0,
ACKWHISPER_TARGET_OFFLINE = 1,
@ -998,6 +1016,7 @@ void clif_closevendingboard(struct block_list* bl, int fd);
void clif_vendinglist( map_session_data& sd, map_session_data& vsd );
void clif_buyvending( map_session_data& sd, uint16 index, uint16 amount, e_pc_purchase_result_frommc result );
void clif_openvending( map_session_data& sd );
void clif_openvending_ack(map_session_data& sd, e_ack_openstore2 result);
void clif_vendingreport( map_session_data& sd, uint16 index, uint16 amount, uint32 char_id, int32 zeny );
void clif_movetoattack( map_session_data& sd, block_list& bl );

View File

@ -175,7 +175,7 @@ void vending_purchasereq(map_session_data* sd, int aid, int uid, const uint8* da
clif_buyvending( *sd, idx, amount, PURCHASEMC_NO_ZENY ); // you don't have enough zeny
return;
}
if( z + (double)vsd->status.zeny > (double)MAX_ZENY && !battle_config.vending_over_max ) {
if( z + (double)vsd->status.zeny > (double)MAX_ZENY ) {
clif_buyvending( *sd, idx, vsd->vending[j].amount, PURCHASEMC_OUT_OF_STOCK ); // too much zeny = overflow
return;
@ -310,12 +310,18 @@ int8 vending_openvending( map_session_data& sd, const char* message, const uint8
// skill level and cart check
if( !vending_skill_lvl || !pc_iscarton(&sd) ) {
clif_skill_fail( sd, MC_VENDING );
sd.state.prevend = 0;
sd.state.workinprogress = WIP_DISABLE_NONE;
clif_openvending_ack( sd, OPENSTORE2_FAILED );
return 2;
}
// 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 );
sd.state.prevend = 0;
sd.state.workinprogress = WIP_DISABLE_NONE;
clif_openvending_ack( sd, OPENSTORE2_FAILED );
return 3;
}
@ -324,6 +330,7 @@ int8 vending_openvending( map_session_data& sd, const char* message, const uint8
// filter out invalid items
i = 0;
int64 total = 0;
for( j = 0; j < count; j++ ) {
short index = *(uint16*)(data + 8*j + 0);
short amount = *(uint16*)(data + 8*j + 2);
@ -344,17 +351,36 @@ int8 vending_openvending( map_session_data& sd, const char* message, const uint8
sd.vending[i].index = index;
sd.vending[i].amount = amount;
sd.vending[i].value = min(value, (unsigned int)battle_config.vending_max_value);
total += static_cast<int64>(sd.vending[i].value) * amount;
i++; // item successfully added
}
// check if the total value of the items plus the current zeny is over the limit
if ( !battle_config.vending_over_max && (static_cast<int64>(sd.status.zeny) + total) > MAX_ZENY ) {
#if PACKETVER >= 20200819
clif_msg_color( &sd, MSI_MERCHANTSHOP_TOTA_LOVER_ZENY_ERR, color_table[COLOR_RED] );
#endif
clif_skill_fail( sd, MC_VENDING );
sd.state.prevend = 0;
sd.state.workinprogress = WIP_DISABLE_NONE;
clif_openvending_ack( sd, OPENSTORE2_FAILED );
return 1;
}
if (i != j) {
clif_displaymessage(sd.fd, msg_txt(&sd, 266)); //"Some of your items cannot be vended and were removed from the shop."
clif_skill_fail( sd, MC_VENDING ); // custom reply packet
sd.state.prevend = 0;
sd.state.workinprogress = WIP_DISABLE_NONE;
clif_openvending_ack( sd, OPENSTORE2_FAILED );
return 5;
}
if( i == 0 ) { // no valid item found
clif_skill_fail( sd, MC_VENDING ); // custom reply packet
sd.state.prevend = 0;
sd.state.workinprogress = WIP_DISABLE_NONE;
clif_openvending_ack( sd, OPENSTORE2_FAILED );
return 5;
}