From 98cdd80b545645fe8c5d398e37575f182fd0d4d8 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 02:58:13 +0200 Subject: Implement PACKET_ZC_PERSONAL_INFOMATION (0x097b) --- src/map/clif.c | 49 ++++++++++++++++++++++++++++++++++++++++++------ src/map/clif.h | 8 ++++++++ src/map/packets_struct.h | 18 ++++++++++++++++++ 3 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 649df3e33..f4e6cab80 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -20923,20 +20923,57 @@ static void clif_bank_withdraw(struct map_session_data *sd, enum e_BANKING_WITHD #endif } -/* TODO: official response packet (tried 0x8cb/0x97b but the display was quite screwed up.) */ -/* currently mimicing */ +/** + * Sends EXP, drop and death-penalty rates. + * 0x097b .W .L .L .L 13B (ZC_PERSONAL_INFOMATION2) + * .B .L .L .L (DETAIL_EXP_INFO) + * + * @param sd The character which should receive the messages. + * + **/ static void clif_show_modifiers(struct map_session_data *sd) { nullpo_retv(sd); - if( sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100 ) { +#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO) + int length = sizeof(struct PACKET_ZC_PERSONAL_INFOMATION) + 4 * sizeof(struct PACKET_ZC_PERSONAL_INFOMATION_SUB); + WFIFOHEAD(sd->fd, length); + struct PACKET_ZC_PERSONAL_INFOMATION *p = WFIFOP(sd->fd, 0); + + p->packetType = HEADER_ZC_PERSONAL_INFOMATION; + p->length = length; + // Single values. + p->details[0].type = PC_EXP_INFO; + p->details[0].exp = 0; + p->details[0].death = 0; + p->details[0].drop = 0; + p->details[1].type = TPLUS_EXP_INFO; + p->details[1].exp = 0; + p->details[1].death = 0; + p->details[1].drop = 0; + p->details[2].type = PREMIUM_EXP_INFO; + p->details[2].exp = (sd->status.mod_exp - 100) * 1000; + p->details[2].death = (sd->status.mod_death - 100) * 1000; + p->details[2].drop = (sd->status.mod_drop - 100) * 1000; + p->details[3].type = SERVER_EXP_INFO; + p->details[3].exp = battle_config.base_exp_rate * 1000; + p->details[3].death = battle_config.death_penalty_base * 10; + p->details[3].drop = battle_config.item_rate_common * 1000; + // Total values. + p->total_exp = (battle_config.base_exp_rate * sd->status.mod_exp / 100) * 1000; + p->total_death = (battle_config.base_exp_rate * sd->status.mod_death / 100) * 10; + p->total_drop = (battle_config.base_exp_rate * sd->status.mod_drop / 100) * 1000; + + WFIFOSET(sd->fd, length); +#else + if (sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100) { char output[128]; - snprintf(output,128, msg_sd(sd, 896), // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%% - sd->status.mod_exp,sd->status.mod_drop,sd->status.mod_death); + // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%% + safesnprintf(output, sizeof(output), msg_sd(sd, 896), sd->status.mod_exp, sd->status.mod_drop, sd->status.mod_death); clif->broadcast2(&sd->bl, output, (int)strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF); } - +#endif // PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO) } static void clif_notify_bounditem(struct map_session_data *sd, unsigned short index) diff --git a/src/map/clif.h b/src/map/clif.h index e43aad808..7d159d851 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -750,6 +750,14 @@ enum removeGear_flag { REMOVE_MOUNT_CART = 6, }; +/** Info types for PACKET_ZC_PERSONAL_INFOMATION (0x097b). **/ +enum detail_exp_info_type { + PC_EXP_INFO = 0x0, //!< PCBang internet cafe modifiers. (http://pcbang.gnjoy.com/) (Unused.) + PREMIUM_EXP_INFO = 0x1, //!< Premium user modifiers. Values aren't displayed in 20161207+ clients. + SERVER_EXP_INFO = 0x2, //!< Server rates. + TPLUS_EXP_INFO = 0x3, //!< Unknown. Values are displayed as "TPLUS" in kRO. (Unused.) +}; + /** * Clif.c Interface **/ diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h index 3129a05d9..031a23b6d 100644 --- a/src/map/packets_struct.h +++ b/src/map/packets_struct.h @@ -3927,6 +3927,24 @@ struct PACKET_CZ_LAPINEUPGRADE_MAKE_ITEM { DEFINE_PACKET_HEADER(CZ_LAPINEUPGRADE_MAKE_ITEM, 0x0ab6); #endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO) +#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO) +struct PACKET_ZC_PERSONAL_INFOMATION_SUB { + int8 type; + int32 exp; + int32 death; + int32 drop; +} __attribute__((packed)); +struct PACKET_ZC_PERSONAL_INFOMATION { + int16 packetType; + int16 length; + int32 total_exp; + int32 total_death; + int32 total_drop; + struct PACKET_ZC_PERSONAL_INFOMATION_SUB details[]; +} __attribute__((packed)); +DEFINE_PACKET_HEADER(ZC_PERSONAL_INFOMATION, 0x097b); +#endif // PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO) + #if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute #pragma pack(pop) #endif // not NetBSD < 6 / Solaris -- cgit v1.2.3-60-g2f50