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 From 584f1e0797ae83fc760ec607ab134166f6426417 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 02:59:11 +0200 Subject: Show rate modifier messages after configuration messages --- src/map/clif.c | 2 ++ src/map/pc.c | 1 - 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/map/clif.c b/src/map/clif.c index f4e6cab80..03432c9e4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10958,6 +10958,8 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); #endif + clif->show_modifiers(sd); + bool flee_penalty = (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100); bool is_gvg = (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m)); bool is_bg = (map->list[sd->state.pmap].flag.battleground != 0 || map->list[sd->bl.m].flag.battleground != 0); diff --git a/src/map/pc.c b/src/map/pc.c index c1261c839..633d13075 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -12117,7 +12117,6 @@ static void pc_scdata_received(struct map_session_data *sd) { nullpo_retv(sd); pc->inventory_rentals(sd); - clif->show_modifiers(sd); if (sd->expiration_time != 0) { // don't display if it's unlimited or unknow value time_t exp_time = sd->expiration_time; -- cgit v1.2.3-60-g2f50 From edad604582cbe6b17de7f19a958c38710f5cf9ab Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:00:22 +0200 Subject: Add battle flag for rate modifier messages display --- conf/map/battle/client.conf | 8 ++++++++ src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/clif.c | 10 ++++++++-- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf index 5601dbc9e..aad4d7652 100644 --- a/conf/map/battle/client.conf +++ b/conf/map/battle/client.conf @@ -202,3 +202,11 @@ ping_time: 20 // Drop or not connection after client send disconnect request packet // Official is false drop_connection_on_quit: false + +// When to display the rate modifier messages? +// 0x0 - Never display rate modifier messages. +// 0x1 - Display rate modifier messages upon login. +// 0x2 - Display rate modifier messages upon map change. +// 0x4 - Display rate modifier messages upon teleporting (regardless of changing maps). +// Default: 0x1 (Official behavior.) +display_rate_messages: 0x1 diff --git a/src/map/battle.c b/src/map/battle.c index 611154953..7d85bf645 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7431,6 +7431,7 @@ static const struct battle_data { { "ping_time", &battle_config.ping_time, 20, 0, 99999999, }, { "option_drop_max_loop", &battle_config.option_drop_max_loop, 10, 1, 100000, }, { "drop_connection_on_quit", &battle_config.drop_connection_on_quit, 0, 0, 1, }, + { "display_rate_messages", &battle_config.display_rate_messages, 1, 0, 7, }, { "features/enable_refinery_ui", &battle_config.enable_refinery_ui, 1, 0, 1, }, { "features/replace_refine_npcs", &battle_config.replace_refine_npcs, 1, 0, 1, }, { "batk_min_limit", &battle_config.batk_min, 0, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index 55ee32445..a116506dd 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -590,6 +590,7 @@ struct Battle_Config { int option_drop_max_loop; int drop_connection_on_quit; + int display_rate_messages; int enable_refinery_ui; int replace_refine_npcs; diff --git a/src/map/clif.c b/src/map/clif.c index 03432c9e4..01f116cc7 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10945,6 +10945,8 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) } } + bool change_map = (sd->state.changemap != 0); + if (sd->state.changemap != 0) { // Restore information that gets lost on map-change. #if PACKETVER >= 20070918 clif->partyinvitationstate(sd); @@ -10958,8 +10960,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); #endif - clif->show_modifiers(sd); - bool flee_penalty = (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100); bool is_gvg = (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m)); bool is_bg = (map->list[sd->state.pmap].flag.battleground != 0 || map->list[sd->bl.m].flag.battleground != 0); @@ -11008,6 +11008,12 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) mail->clear(sd); clif->maptypeproperty2(&sd->bl, SELF); + if (((battle_config.display_rate_messages & 0x1) != 0 && first_time) + || ((battle_config.display_rate_messages & 0x2) != 0 && !first_time && change_map) + || (battle_config.display_rate_messages & 0x4) != 0) { + clif->show_modifiers(sd); + } + // Init guild aura. if (sd->state.gmaster_flag != 0) { guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP)); -- cgit v1.2.3-60-g2f50 From 7851f5044beba57396c8889df85401c944b415e1 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:01:19 +0200 Subject: Add missing configuration messages to clif_parse_LoadEndAck() --- src/map/clif.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/map/clif.c b/src/map/clif.c index 01f116cc7..4a34b1f0d 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10954,6 +10954,13 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) #endif #if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920 + clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call); + + if (sd->pd != NULL) + clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed); + else + clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false); + if (sd->hd != NULL) clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed); else -- cgit v1.2.3-60-g2f50 From 527c5a20676780954567d6a791f240933afde7f2 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:02:19 +0200 Subject: Add battle flag for configuration messages display --- conf/map/battle/client.conf | 18 ++++++++++++++++ src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/clif.c | 50 ++++++++++++++++++++++++++++----------------- 4 files changed, 51 insertions(+), 19 deletions(-) diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf index aad4d7652..722019fa7 100644 --- a/conf/map/battle/client.conf +++ b/conf/map/battle/client.conf @@ -210,3 +210,21 @@ drop_connection_on_quit: false // 0x4 - Display rate modifier messages upon teleporting (regardless of changing maps). // Default: 0x1 (Official behavior.) display_rate_messages: 0x1 + +// When to display the configuration messages and which? (Note 3) +// +// Flags for when to display the configuration messages: +// 0x000 - Never display configuration messages. +// 0x001 - Display configuration messages upon login. (Default. Should always be set.) +// 0x002 - Display configuration messages upon map change. +// 0x004 - Display configuration messages upon teleporting (regardless of changing maps). +// +// Flags for which configuration messages are displayed: +// 0x010 - Character's party invitation state. (Default.) +// 0x020 - Character's view equipment state. (Default.) +// 0x040 - Character's Urgent Call state. (Default.) +// 0x080 - Character's pet auto-feed state. (Default.) +// 0x100 - Character's homunculus auto-feed state. (Default.) +// +// Default: 0x1F1 (Official behavior.) +display_config_messages: 0x1F1 diff --git a/src/map/battle.c b/src/map/battle.c index 7d85bf645..dc2535052 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7432,6 +7432,7 @@ static const struct battle_data { { "option_drop_max_loop", &battle_config.option_drop_max_loop, 10, 1, 100000, }, { "drop_connection_on_quit", &battle_config.drop_connection_on_quit, 0, 0, 1, }, { "display_rate_messages", &battle_config.display_rate_messages, 1, 0, 7, }, + { "display_config_messages", &battle_config.display_config_messages, 0x1F1, 0, 0x1F7, }, { "features/enable_refinery_ui", &battle_config.enable_refinery_ui, 1, 0, 1, }, { "features/replace_refine_npcs", &battle_config.replace_refine_npcs, 1, 0, 1, }, { "batk_min_limit", &battle_config.batk_min, 0, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index a116506dd..5a039a8ed 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -591,6 +591,7 @@ struct Battle_Config { int drop_connection_on_quit; int display_rate_messages; + int display_config_messages; int enable_refinery_ui; int replace_refine_npcs; diff --git a/src/map/clif.c b/src/map/clif.c index 4a34b1f0d..3f9cc2659 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10948,25 +10948,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) bool change_map = (sd->state.changemap != 0); if (sd->state.changemap != 0) { // Restore information that gets lost on map-change. -#if PACKETVER >= 20070918 - clif->partyinvitationstate(sd); - clif->equpcheckbox(sd); -#endif - -#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920 - clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call); - - if (sd->pd != NULL) - clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed); - else - clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false); - - if (sd->hd != NULL) - clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed); - else - clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); -#endif - bool flee_penalty = (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100); bool is_gvg = (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m)); bool is_bg = (map->list[sd->state.pmap].flag.battleground != 0 || map->list[sd->bl.m].flag.battleground != 0); @@ -11015,6 +10996,37 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) mail->clear(sd); clif->maptypeproperty2(&sd->bl, SELF); + if (((battle_config.display_config_messages & 0x1) != 0 && first_time) + || ((battle_config.display_config_messages & 0x2) != 0 && !first_time && change_map) + || (battle_config.display_config_messages & 0x4) != 0) { +#if PACKETVER >= 20070918 + if ((battle_config.display_config_messages & 0x10) != 0) + clif->partyinvitationstate(sd); + + if ((battle_config.display_config_messages & 0x20) != 0) + clif->equpcheckbox(sd); +#endif + +#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920 + if ((battle_config.display_config_messages & 0x40) != 0) + clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call); + + if ((battle_config.display_config_messages & 0x80) != 0) { + if (sd->pd != NULL) + clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed); + else + clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false); + } + + if ((battle_config.display_config_messages & 0x100) != 0) { + if (sd->hd != NULL) + clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed); + else + clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); + } +#endif + } + if (((battle_config.display_rate_messages & 0x1) != 0 && first_time) || ((battle_config.display_rate_messages & 0x2) != 0 && !first_time && change_map) || (battle_config.display_rate_messages & 0x4) != 0) { -- cgit v1.2.3-60-g2f50 From 0f8a2df4dd40d522a69260b4d110d0ea2c14ba2a Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:04:46 +0200 Subject: Show guild notice after rate modifier messages --- src/map/clif.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 3f9cc2659..a580d6464 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10938,11 +10938,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) } else { sd->state.warp_clean = 1; } - - if (sd->guild != NULL && ((battle_config.guild_notice_changemap == 1 && sd->state.changemap != 0) - || battle_config.guild_notice_changemap == 2)) { - clif->guild_notice(sd, sd->guild); - } } bool change_map = (sd->state.changemap != 0); @@ -11033,12 +11028,21 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) clif->show_modifiers(sd); } - // Init guild aura. - if (sd->state.gmaster_flag != 0) { - guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP)); - guild->aura_refresh(sd, GD_GLORYWOUNDS, guild->checkskill(sd->guild, GD_GLORYWOUNDS)); - guild->aura_refresh(sd, GD_SOULCOLD, guild->checkskill(sd->guild, GD_SOULCOLD)); - guild->aura_refresh(sd, GD_HAWKEYES, guild->checkskill(sd->guild, GD_HAWKEYES)); + if (sd->guild != NULL) { + // Show guild notice. + if ((battle_config.guild_notice_changemap == 1 && change_map) + || battle_config.guild_notice_changemap == 2 + || first_time) { + clif->guild_notice(sd, sd->guild); + } + + // Init guild aura. + if (sd->state.gmaster_flag != 0) { + guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP)); + guild->aura_refresh(sd, GD_GLORYWOUNDS, guild->checkskill(sd->guild, GD_GLORYWOUNDS)); + guild->aura_refresh(sd, GD_SOULCOLD, guild->checkskill(sd->guild, GD_SOULCOLD)); + guild->aura_refresh(sd, GD_HAWKEYES, guild->checkskill(sd->guild, GD_HAWKEYES)); + } } if (sd->state.vending != 0) { // Character is vending. @@ -11063,10 +11067,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) clif->weather_check(sd); - // This should be displayed last. - if (sd->guild != NULL && first_time) - clif->guild_notice(sd, sd->guild); - // For automatic triggering of NPCs after map loading. (So you don't need to walk 1 step first.) if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNPC) != 0) npc->touch_areanpc(sd, sd->bl.m, sd->bl.x, sd->bl.y); -- cgit v1.2.3-60-g2f50 From 3dd482367675292233bf034bc8a38b2ab46b0aa3 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:06:00 +0200 Subject: Extend guild_notice_changemap battle flag with option for login --- conf/map/battle/guild.conf | 12 +++++++----- src/map/battle.c | 2 +- src/map/clif.c | 6 +++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/conf/map/battle/guild.conf b/conf/map/battle/guild.conf index 781f6555b..204c295c3 100644 --- a/conf/map/battle/guild.conf +++ b/conf/map/battle/guild.conf @@ -59,11 +59,13 @@ require_glory_guild: false // Default is 3 max_guild_alliance: 3 -// When to re-display the guild notice -// Upon teleporting (regardless of changing maps): 2 (official) -// Upon changing maps: 1 -// Do not re-display: 0 (disabled) -guild_notice_changemap: 2 +// When to display the guild notice? +// 0x0 - Never display guild notice. +// 0x1 - Display guild notice upon login. +// 0x2 - Display guild notice upon map change. +// 0x4 - Display guild notice upon teleporting (regardless of changing maps). +// Default: 0x7 (Official behavior.) +guild_notice_changemap: 0x7 // Can guild members invite/expel members inside guild castles in WoE/GvG? (Note 1) // default: false diff --git a/src/map/battle.c b/src/map/battle.c index dc2535052..ed5aa4cb9 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7383,7 +7383,7 @@ static const struct battle_data { { "packet_obfuscation", &battle_config.packet_obfuscation, 1, 0, 3, }, { "client_accept_chatdori", &battle_config.client_accept_chatdori, 0, 0, INT_MAX, }, { "snovice_call_type", &battle_config.snovice_call_type, 0, 0, 1, }, - { "guild_notice_changemap", &battle_config.guild_notice_changemap, 2, 0, 2, }, + { "guild_notice_changemap", &battle_config.guild_notice_changemap, 7, 0, 7, }, { "features/banking", &battle_config.feature_banking, 1, 0, 1, }, { "features/auction", &battle_config.feature_auction, 0, 0, 2, }, { "idletime_criteria", &battle_config.idletime_criteria, 0x25, 1, INT_MAX, }, diff --git a/src/map/clif.c b/src/map/clif.c index a580d6464..9eba9f4b4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -11030,9 +11030,9 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) if (sd->guild != NULL) { // Show guild notice. - if ((battle_config.guild_notice_changemap == 1 && change_map) - || battle_config.guild_notice_changemap == 2 - || first_time) { + if (((battle_config.guild_notice_changemap & 0x1) != 0 && first_time) + || ((battle_config.guild_notice_changemap & 0x2) != 0 && !first_time && change_map) + || (battle_config.guild_notice_changemap & 0x4) != 0) { clif->guild_notice(sd, sd->guild); } -- cgit v1.2.3-60-g2f50 From 7a2565af344a26275c0800f91d6c4aa3142827a8 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:07:05 +0200 Subject: Show party options on login and if options were changed --- src/map/clif.c | 31 +++++++++++++++++++++++++------ src/map/party.c | 23 ++++++++++++++++++++--- src/map/party.h | 2 ++ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 9eba9f4b4..c1e3750d4 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7301,8 +7301,10 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick, /// 2 = cannot change exp sharing /// /// flag: -/// 0 = send to party -/// 1 = send to sd +/// 0x01 = Cannot change EXP sharing. (Only set when tried to change options manually.) +/// 0x02 = Options changed manually. +/// 0x04 = Options changed automatically. +/// 0x20 = Character logged in. static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag) { unsigned char buf[16]; @@ -7314,7 +7316,7 @@ static void clif_party_option(struct party_data *p, struct map_session_data *sd, nullpo_retv(p); - if(!sd && flag==0){ + if (sd == NULL && (flag & 0x01) == 0) { int i; for(i=0;idata[i].sd;i++) ; @@ -7328,10 +7330,13 @@ static void clif_party_option(struct party_data *p, struct map_session_data *sd, WBUFB(buf,6)=(p->party.item&1)?1:0; WBUFB(buf,7)=(p->party.item&2)?1:0; #endif - if(flag==0) + if ((flag & 0x01) == 0 && ((flag & 0x04) != 0 || (flag & 0x02) != 0)) clif->send(buf,packet_len(cmd),&sd->bl,PARTY); else clif->send(buf,packet_len(cmd),&sd->bl,SELF); + + if ((flag & 0x04) != 0) + p->state.option_auto_changed = 0; } /// 0105 .L .24B .B (ZC_DELETE_MEMBER_FROM_GROUP). @@ -10764,9 +10769,16 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) map->addblock(&sd->bl); // Add the character to the map. clif->spawn(&sd->bl); // Spawn character client side. + struct party_data *p = NULL; + + if (sd->status.party_id != 0) + p = party->search(sd->status.party_id); + // Send character's party info to the client. Call this after clif->spawn() to show HP bars correctly. - if (sd->status.party_id != 0) { - party->send_movemap(sd); + if (p != NULL) { + if (sd->state.connect_new == 0) // Login is handled in party_member_joined(). + party->send_movemap(sd); + clif->party_hp(sd); // Show HP after displacement. [LuzZza] } @@ -11022,6 +11034,13 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) #endif } + if (p != NULL && first_time) { + if (p->state.option_auto_changed != 0) + clif->party_option(p, sd, 0x04); + else + clif->party_option(p, sd, 0x20); + } + if (((battle_config.display_rate_messages & 0x1) != 0 && first_time) || ((battle_config.display_rate_messages & 0x2) != 0 && !first_time && change_map) || (battle_config.display_rate_messages & 0x4) != 0) { diff --git a/src/map/party.c b/src/map/party.c index 8eeae2215..14e3df42f 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -349,7 +349,6 @@ static int party_recv_info(const struct party *sp, int char_id) continue;// not online clif->charnameupdate(sd); //Update other people's display. [Skotlex] clif->party_member_info(p,sd); - clif->party_option(p,sd,0x100); clif->party_info(p,NULL); for( j = 0; j < p->instances; j++ ) { if( p->instance[j] >= 0 ) { @@ -496,6 +495,8 @@ static void party_member_joined(struct map_session_data *sd) } } else sd->status.party_id = 0; //He does not belongs to the party really? + + party->send_movemap(sd); } /// Invoked (from char-server) when a new member is added to the party. @@ -733,6 +734,16 @@ static int party_optionchanged(int party_id, int account_id, int exp, int item, p->party.item=item; } + if (account_id == 0) { + flag |= 0x04; + p->state.option_auto_changed = 1; + + if (p->state.member_level_changed == 0) + return 0; // clif_party_option() is handled in clif_parse_LoadEndAck(). + } else { + flag |= 0x02; + } + clif->party_option(p,sd,flag); return 0; } @@ -811,7 +822,8 @@ static int party_recv_movemap(int party_id, int account_id, int char_id, unsigne ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id); return 0; } - + + p->state.member_level_changed = 0; m = &p->party.member[i]; m->map = mapid; m->online = online; @@ -860,7 +872,12 @@ static void party_send_movemap(struct map_session_data *sd) static void party_send_levelup(struct map_session_data *sd) { - intif->party_changemap(sd,1); + struct party_data *p = party->search(sd->status.party_id); + + if (p != NULL) + p->state.member_level_changed = 1; + + intif->party_changemap(sd, 1); } static int party_send_logout(struct map_session_data *sd) diff --git a/src/map/party.h b/src/map/party.h index c2306b7a8..5f3458cd4 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -51,6 +51,8 @@ struct party_data { unsigned sg : 1; ///< There's at least one Star Gladiator in party? unsigned snovice :1; ///< There's a Super Novice unsigned tk : 1; ///< There's a taekwon + unsigned option_auto_changed : 1; ///< Party options were changed automatically. (inter_party_check_lv()) + unsigned member_level_changed : 1; ///< A party member's level has changed. } state; struct hplugin_data_store *hdata; ///< HPM Plugin Data Store }; -- cgit v1.2.3-60-g2f50 From 36d001b4a491e6d1bd22c4398891de068066cbb2 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:08:07 +0200 Subject: Show party options when member was added --- src/map/clif.c | 1 + src/map/party.c | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/src/map/clif.c b/src/map/clif.c index c1e3750d4..e350948b2 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7304,6 +7304,7 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick, /// 0x01 = Cannot change EXP sharing. (Only set when tried to change options manually.) /// 0x02 = Options changed manually. /// 0x04 = Options changed automatically. +/// 0x08 = Member added. /// 0x20 = Character logged in. static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag) { diff --git a/src/map/party.c b/src/map/party.c index 14e3df42f..597325e7d 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -330,6 +330,8 @@ static int party_recv_info(const struct party *sp, int char_id) party->member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id); } + int option_auto_changed = p->state.option_auto_changed; // Preserve state. + memcpy(&p->party, sp, sizeof(struct party)); memset(&p->state, 0, sizeof(p->state)); memset(&p->data, 0, sizeof(p->data)); @@ -342,6 +344,7 @@ static int party_recv_info(const struct party *sp, int char_id) p->party.member[member_id].leader = 1; } party->check_state(p); + p->state.option_auto_changed = option_auto_changed; while( added_count > 0 ) { // new in party member_id = added[--added_count]; sd = p->data[member_id].sd; @@ -537,6 +540,11 @@ static int party_member_added(int party_id, int account_id, int char_id, int fla clif->party_member_info(p,sd); clif->party_info(p,sd); + if (p->state.option_auto_changed != 0) + clif->party_option(p, sd, 0x04); + else + clif->party_option(p, sd, 0x08); + if( sd2 != NULL ) clif->party_inviteack(sd2,sd->status.name,2); -- cgit v1.2.3-60-g2f50 From 1443ac5b3414ecc89869b7cfaa2598564ce83218 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:09:13 +0200 Subject: Remove check for unused flag 0x10 from party_optionchanged() --- src/map/party.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/map/party.c b/src/map/party.c index 597325e7d..88108d144 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -738,9 +738,8 @@ static int party_optionchanged(int party_id, int account_id, int exp, int item, //Flag&0x1: Exp change denied. Flag&0x10: Item change denied. if(!(flag&0x01) && p->party.exp != exp) p->party.exp=exp; - if(!(flag&0x10) && p->party.item != item) { + if (p->party.item != item) p->party.item=item; - } if (account_id == 0) { flag |= 0x04; -- cgit v1.2.3-60-g2f50 From a0fb73f998832db72c627d11bc3b0f04c392569a Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:10:03 +0200 Subject: Show party options when member was removed --- src/map/clif.c | 7 ++++--- src/map/party.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index e350948b2..8634925f0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7305,6 +7305,7 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick, /// 0x02 = Options changed manually. /// 0x04 = Options changed automatically. /// 0x08 = Member added. +/// 0x10 = Member removed. /// 0x20 = Character logged in. static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag) { @@ -7326,10 +7327,10 @@ static void clif_party_option(struct party_data *p, struct map_session_data *sd, } if(!sd) return; WBUFW(buf,0)=cmd; - WBUFL(buf,2)=((flag&0x01)?2:p->party.exp); + WBUFL(buf, 2) = ((flag & 0x10) != 0) ? 0 : (((flag & 0x01) != 0) ? 2 : p->party.exp); #if PACKETVER >= 20090603 - WBUFB(buf,6)=(p->party.item&1)?1:0; - WBUFB(buf,7)=(p->party.item&2)?1:0; + WBUFB(buf, 6) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 1) != 0) ? 1 : 0); + WBUFB(buf, 7) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 2) != 0) ? 1 : 0); #endif if ((flag & 0x01) == 0 && ((flag & 0x04) != 0 || (flag & 0x02) != 0)) clif->send(buf,packet_len(cmd),&sd->bl,PARTY); diff --git a/src/map/party.c b/src/map/party.c index 88108d144..957a45c14 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -631,6 +631,7 @@ static int party_member_withdraw(int party_id, int account_id, int char_id) prev_leader_accountId = p->party.member[i].account_id; } + clif->party_option(p, sd, 0x10); clif->party_withdraw(p,sd,account_id,p->party.member[i].name,0x0); memset(&p->party.member[i], 0, sizeof(p->party.member[0])); memset(&p->data[i], 0, sizeof(p->data[0])); -- cgit v1.2.3-60-g2f50 From fa14df7e5ba9f18c74f149fb3bcaee32dfd87f80 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:11:24 +0200 Subject: Add battle flag for sending party options --- conf/map/battle/party.conf | 27 ++++++++++++++++++ src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/clif.c | 70 ++++++++++++++++++++++++++++++++++++---------- 4 files changed, 85 insertions(+), 14 deletions(-) diff --git a/conf/map/battle/party.conf b/conf/map/battle/party.conf index e27a709fd..7713d5376 100644 --- a/conf/map/battle/party.conf +++ b/conf/map/battle/party.conf @@ -80,3 +80,30 @@ party_even_share_bonus: 0 // Display party name regardless if player is in a guild. // Official servers do not display party name unless the user is in a guild. (Note 1) display_party_name: false + +// When and how to send the party options? (Note 3) +// +// Flags for when to display the party options: +// 0x00000 - Never send party options. +// 0x00001 - Send party options upon login. (Default. Should always be set.) +// 0x00002 - Send party options upon map change. +// 0x00004 - Send party options upon teleporting (regardless of changing maps). +// 0x00008 - Send party options upon successfully changing options manually. (Default. Should always be set.) +// 0x00010 - Send party options upon unsuccessfully changing options manually. (Tried to enable EXP sharing if not allowed.) (Default.) +// 0x00020 - Send party options upon changing options automatically. (Default. Should always be set.) +// 0x00040 - Send party options upon joining party. (Default. Should always be set.) +// 0x00080 - Send party options upon leaving party. (Default.) +// +// Flags for how to send the party options: +// 0x00100 - Send party options to all party members upon unsuccessfully changing options manually. (Tried to enable EXP sharing if not allowed.) (Default.) +// 0x00200 - Send all party options upon login. +// 0x00400 - Send all party options upon map change. +// 0x00800 - Send all party options upon teleporting (regardless of changing maps). +// 0x01000 - Send all party options upon successfully changing options manually. (Default.) +// 0x02000 - Send all party options upon unsuccessfully changing options manually. (Tried to enable EXP sharing if not allowed.) (Default.) +// 0x04000 - Send all party options upon changing options automatically. +// 0x08000 - Send all party options upon joining party. +// 0x10000 - Send all party options upon leaving party. +// +// Default: 0x31F9 (Official behavior.) +send_party_options: 0x31F9 diff --git a/src/map/battle.c b/src/map/battle.c index ed5aa4cb9..e8d8e581f 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7345,6 +7345,7 @@ static const struct battle_data { { "searchstore_querydelay", &battle_config.searchstore_querydelay, 10, 0, INT_MAX, }, { "searchstore_maxresults", &battle_config.searchstore_maxresults, 30, 1, INT_MAX, }, { "display_party_name", &battle_config.display_party_name, 0, 0, 1, }, + { "send_party_options", &battle_config.send_party_options, 0x31F9, 0, 0x1FFFF, }, { "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, }, { "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, }, { "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, }, diff --git a/src/map/battle.h b/src/map/battle.h index 5a039a8ed..ceb94321e 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -471,6 +471,7 @@ struct Battle_Config { int searchstore_querydelay; int searchstore_maxresults; int display_party_name; + int send_party_options; int cashshop_show_points; int mail_show_status; int client_limit_unit_lv; diff --git a/src/map/clif.c b/src/map/clif.c index 8634925f0..a75fc0dc3 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7307,13 +7307,48 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick, /// 0x08 = Member added. /// 0x10 = Member removed. /// 0x20 = Character logged in. +/// 0x40 = Character changed map. +/// 0x80 = Character teleported. static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag) { + int conf = battle_config.send_party_options; + + if (((flag & 0x01) != 0 && (conf & 0x10) == 0) + || ((flag & 0x02) != 0 && (conf & 0x08) == 0) + || ((flag & 0x04) != 0 && (conf & 0x20) == 0) + || ((flag & 0x08) != 0 && (conf & 0x40) == 0) + || ((flag & 0x10) != 0 && (conf & 0x80) == 0) + || ((flag & 0x20) != 0 && (conf & 0x01) == 0) + || ((flag & 0x40) != 0 && (conf & 0x02) == 0) + || ((flag & 0x80) != 0 && (conf & 0x04) == 0)) { + return; + } + + enum send_target target = SELF; + + if (((flag & 0x01) != 0 && (conf & 0x100) != 0) + || ((flag & 0x01) == 0 && (flag & 0x02) != 0) + || (flag & 0x04) != 0) { + target = PARTY; + } + + int cmd = 0x101; + + if (((flag & 0x01) != 0 && (conf & 0x02000) != 0) + || ((flag & 0x02) != 0 && (conf & 0x01000) != 0) + || ((flag & 0x04) != 0 && (conf & 0x04000) != 0) + || ((flag & 0x08) != 0 && (conf & 0x08000) != 0) + || ((flag & 0x10) != 0 && (conf & 0x10000) != 0) + || ((flag & 0x20) != 0 && (conf & 0x00200) != 0) + || ((flag & 0x40) != 0 && (conf & 0x00400) != 0) + || ((flag & 0x80) != 0 && (conf & 0x00800) != 0)) { + cmd = 0x7d8; + } + unsigned char buf[16]; #if PACKETVER < 20090603 - const int cmd = 0x101; -#else - const int cmd = 0x7d8; + if (cmd == 0x7d8) + cmd = 0x101; #endif nullpo_retv(p); @@ -7328,14 +7363,13 @@ static void clif_party_option(struct party_data *p, struct map_session_data *sd, if(!sd) return; WBUFW(buf,0)=cmd; WBUFL(buf, 2) = ((flag & 0x10) != 0) ? 0 : (((flag & 0x01) != 0) ? 2 : p->party.exp); -#if PACKETVER >= 20090603 - WBUFB(buf, 6) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 1) != 0) ? 1 : 0); - WBUFB(buf, 7) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 2) != 0) ? 1 : 0); -#endif - if ((flag & 0x01) == 0 && ((flag & 0x04) != 0 || (flag & 0x02) != 0)) - clif->send(buf,packet_len(cmd),&sd->bl,PARTY); - else - clif->send(buf,packet_len(cmd),&sd->bl,SELF); + + if (cmd == 0x7d8) { + WBUFB(buf, 6) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 1) != 0) ? 1 : 0); + WBUFB(buf, 7) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 2) != 0) ? 1 : 0); + } + + clif->send(buf, packet_len(cmd), &sd->bl, target); if ((flag & 0x04) != 0) p->state.option_auto_changed = 0; @@ -11036,11 +11070,19 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) #endif } - if (p != NULL && first_time) { + if (p != NULL) { + int flag; + if (p->state.option_auto_changed != 0) - clif->party_option(p, sd, 0x04); + flag = 0x04; + else if (first_time) + flag = 0x20; + else if (change_map) + flag = 0x40; else - clif->party_option(p, sd, 0x20); + flag = 0x80; + + clif->party_option(p, sd, flag); } if (((battle_config.display_rate_messages & 0x1) != 0 && first_time) -- cgit v1.2.3-60-g2f50 From 196c182f11aa46056a70507fcd93c97db9be911e Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:12:18 +0200 Subject: Apply code style to clif_party_option() --- src/map/clif.c | 70 +++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index a75fc0dc3..f7f22f7b0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -7292,25 +7292,48 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick, #endif } -/// Updates party settings. -/// 0101 .L (ZC_GROUPINFO_CHANGE) -/// 07d8 .L .B .B (ZC_REQ_GROUPINFO_CHANGE_V2) -/// exp option: -/// 0 = exp sharing disabled -/// 1 = exp sharing enabled -/// 2 = cannot change exp sharing -/// -/// flag: -/// 0x01 = Cannot change EXP sharing. (Only set when tried to change options manually.) -/// 0x02 = Options changed manually. -/// 0x04 = Options changed automatically. -/// 0x08 = Member added. -/// 0x10 = Member removed. -/// 0x20 = Character logged in. -/// 0x40 = Character changed map. -/// 0x80 = Character teleported. +/** + * Sends party settings to the client. + * + * 0101 .L (ZC_GROUPINFO_CHANGE) + * 07d8 .L .B .B (ZC_REQ_GROUPINFO_CHANGE_V2) + * : + * 0 = EXP sharing disabled. + * 1 = EXP sharing enabled. + * 2 = Cannot change EXP sharing. + * + * @param p The related party. + * @param sd The related character. + * @param flag Reason for sending. + * @parblock + * Possible flags: + * 0x01 = Cannot change EXP sharing. (Only set when tried to change options manually.) + * 0x02 = Options changed manually. + * 0x04 = Options changed automatically. + * 0x08 = Member added. + * 0x10 = Member removed. + * 0x20 = Character logged in. + * 0x40 = Character changed map. + * 0x80 = Character teleported. + * @endparblock + * + **/ static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag) { + nullpo_retv(p); + + if (sd == NULL && (flag & 0x01) == 0) { + for (int i = 0; i < MAX_PARTY; i++) { + if (p->data[i].sd != NULL) { + sd = p->data[i].sd; + break; + } + } + } + + if (sd == NULL) + return; + int conf = battle_config.send_party_options; if (((flag & 0x01) != 0 && (conf & 0x10) == 0) @@ -7345,23 +7368,14 @@ static void clif_party_option(struct party_data *p, struct map_session_data *sd, cmd = 0x7d8; } - unsigned char buf[16]; #if PACKETVER < 20090603 if (cmd == 0x7d8) cmd = 0x101; #endif - nullpo_retv(p); + unsigned char buf[16]; - if (sd == NULL && (flag & 0x01) == 0) { - int i; - for(i=0;idata[i].sd;i++) - ; - if (i < MAX_PARTY) - sd = p->data[i].sd; - } - if(!sd) return; - WBUFW(buf,0)=cmd; + WBUFW(buf, 0) = cmd; WBUFL(buf, 2) = ((flag & 0x10) != 0) ? 0 : (((flag & 0x01) != 0) ? 2 : p->party.exp); if (cmd == 0x7d8) { -- cgit v1.2.3-60-g2f50 From f170e3487ec91f5f5a9e17acffc6cd499df373eb Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:13:25 +0200 Subject: Add battle flag for overweight messages display --- conf/map/battle/client.conf | 7 +++++++ src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/clif.c | 15 +++++++++++---- 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf index 722019fa7..f080e8375 100644 --- a/conf/map/battle/client.conf +++ b/conf/map/battle/client.conf @@ -228,3 +228,10 @@ display_rate_messages: 0x1 // // Default: 0x1F1 (Official behavior.) display_config_messages: 0x1F1 + +// When to display the overweight messages? +// 0x0 - Never display overweight messages. +// 0x1 - Display overweight messages upon login. (Default.) +// 0x2 - Display overweight messages upon map change. (Default.) +// Default: 0x3 (Official behavior.) +display_overweight_messages: 0x3 diff --git a/src/map/battle.c b/src/map/battle.c index e8d8e581f..0ef9c66e8 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7434,6 +7434,7 @@ static const struct battle_data { { "drop_connection_on_quit", &battle_config.drop_connection_on_quit, 0, 0, 1, }, { "display_rate_messages", &battle_config.display_rate_messages, 1, 0, 7, }, { "display_config_messages", &battle_config.display_config_messages, 0x1F1, 0, 0x1F7, }, + { "display_overweight_messages", &battle_config.display_overweight_messages, 3, 0, 3, }, { "features/enable_refinery_ui", &battle_config.enable_refinery_ui, 1, 0, 1, }, { "features/replace_refine_npcs", &battle_config.replace_refine_npcs, 1, 0, 1, }, { "batk_min_limit", &battle_config.batk_min, 0, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index ceb94321e..19cfd2748 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -593,6 +593,7 @@ struct Battle_Config { int drop_connection_on_quit; int display_rate_messages; int display_config_messages; + int display_overweight_messages; int enable_refinery_ui; int replace_refine_npcs; diff --git a/src/map/clif.c b/src/map/clif.c index f7f22f7b0..517b03add 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10787,10 +10787,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) // Check for and delete unavailable/disabled items. pc->checkitem(sd); - // Send the character's weight to the client. - clif->updatestatus(sd, SP_WEIGHT); - clif->updatestatus(sd, SP_MAXWEIGHT); - // Send character's guild info to the client. Call this before clif->spawn() to show guild emblems correctly. if (sd->status.guild_id != 0) guild->send_memberinfoshort(sd, 1); @@ -10819,6 +10815,17 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) map->addblock(&sd->bl); // Add the character to the map. clif->spawn(&sd->bl); // Spawn character client side. + if (((battle_config.display_overweight_messages & 0x1) != 0 && sd->state.connect_new != 0) + || ((battle_config.display_overweight_messages & 0x2) != 0 && sd->state.connect_new == 0 && sd->state.changemap != 0)) { + // Send the character's weight to the client. (With displaying overweight messages.) + clif->updatestatus(sd, SP_MAXWEIGHT); + clif->updatestatus(sd, SP_WEIGHT); + } else { + // Send the character's weight to the client. (Without displaying overweight messages.) + clif->updatestatus(sd, SP_WEIGHT); + clif->updatestatus(sd, SP_MAXWEIGHT); + } + struct party_data *p = NULL; if (sd->status.party_id != 0) -- cgit v1.2.3-60-g2f50 From 9719e96c066701e9cb78f63bd57f56fe06998005 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:14:23 +0200 Subject: Add clif_load_end_ack_sub_messages() function --- src/map/clif.c | 161 ++++++++++++++++++++++++++++++++------------------------- 1 file changed, 92 insertions(+), 69 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 517b03add..2eb2b903f 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -10667,6 +10667,97 @@ static void clif_parse_WantToConnection(int fd, struct map_session_data *sd) chrif->authreq(sd,false); } +/** + * Displays the common server messages upon login, chaning maps or teleporting to a character. + * + * @param sd The character who should receive the messages. + * @param connect_new Whether the character is logging in. + * @param change_map Whether the character is changing maps. + * + **/ +static void clif_load_end_ack_sub_messages(struct map_session_data *sd, bool connect_new, bool change_map) +{ + nullpo_retv(sd); + + /** Display overweight messages. **/ + if (((battle_config.display_overweight_messages & 0x1) != 0 && connect_new) + || ((battle_config.display_overweight_messages & 0x2) != 0 && !connect_new && change_map)) { + // Send the character's weight to the client. (With displaying overweight messages.) + clif->updatestatus(sd, SP_MAXWEIGHT); + clif->updatestatus(sd, SP_WEIGHT); + } else { + // Send the character's weight to the client. (Without displaying overweight messages.) + clif->updatestatus(sd, SP_WEIGHT); + clif->updatestatus(sd, SP_MAXWEIGHT); + } + + /** Display configuration messages. **/ + if (((battle_config.display_config_messages & 0x1) != 0 && connect_new) + || ((battle_config.display_config_messages & 0x2) != 0 && !connect_new && change_map) + || (battle_config.display_config_messages & 0x4) != 0) { +#if PACKETVER >= 20070918 + if ((battle_config.display_config_messages & 0x10) != 0) + clif->partyinvitationstate(sd); + + if ((battle_config.display_config_messages & 0x20) != 0) + clif->equpcheckbox(sd); +#endif + +#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920 + if ((battle_config.display_config_messages & 0x40) != 0) + clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call); + + if ((battle_config.display_config_messages & 0x80) != 0) { + if (sd->pd != NULL) + clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed); + else + clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false); + } + + if ((battle_config.display_config_messages & 0x100) != 0) { + if (sd->hd != NULL) + clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed); + else + clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); + } +#endif + } + + /** Display party options. **/ + struct party_data *p = NULL; + + if (sd->status.party_id != 0 && (p = party->search(sd->status.party_id)) != NULL) { + int flag; + + if (p->state.option_auto_changed != 0) + flag = 0x04; + else if (connect_new) + flag = 0x20; + else if (change_map) + flag = 0x40; + else + flag = 0x80; + + clif->party_option(p, sd, flag); + } + + /** Display rate modifier messages. **/ + if (((battle_config.display_rate_messages & 0x1) != 0 && connect_new) + || ((battle_config.display_rate_messages & 0x2) != 0 && !connect_new && change_map) + || (battle_config.display_rate_messages & 0x4) != 0) { + clif->show_modifiers(sd); + } + + /** Display guild notice. **/ + if (sd->guild != NULL) { + if (((battle_config.guild_notice_changemap & 0x1) != 0 && connect_new) + || ((battle_config.guild_notice_changemap & 0x2) != 0 && !connect_new && change_map) + || (battle_config.guild_notice_changemap & 0x4) != 0) { + clif->guild_notice(sd, sd->guild); + } + } +} + /** * Notification from the client, that it has finished map loading and is about to display player's character. (CZ_NOTIFY_ACTORINIT) * @@ -10815,16 +10906,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) map->addblock(&sd->bl); // Add the character to the map. clif->spawn(&sd->bl); // Spawn character client side. - if (((battle_config.display_overweight_messages & 0x1) != 0 && sd->state.connect_new != 0) - || ((battle_config.display_overweight_messages & 0x2) != 0 && sd->state.connect_new == 0 && sd->state.changemap != 0)) { - // Send the character's weight to the client. (With displaying overweight messages.) - clif->updatestatus(sd, SP_MAXWEIGHT); - clif->updatestatus(sd, SP_WEIGHT); - } else { - // Send the character's weight to the client. (Without displaying overweight messages.) - clif->updatestatus(sd, SP_WEIGHT); - clif->updatestatus(sd, SP_MAXWEIGHT); - } + clif_load_end_ack_sub_messages(sd, (sd->state.connect_new != 0), (sd->state.changemap != 0)); struct party_data *p = NULL; @@ -11060,66 +11142,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) mail->clear(sd); clif->maptypeproperty2(&sd->bl, SELF); - if (((battle_config.display_config_messages & 0x1) != 0 && first_time) - || ((battle_config.display_config_messages & 0x2) != 0 && !first_time && change_map) - || (battle_config.display_config_messages & 0x4) != 0) { -#if PACKETVER >= 20070918 - if ((battle_config.display_config_messages & 0x10) != 0) - clif->partyinvitationstate(sd); - - if ((battle_config.display_config_messages & 0x20) != 0) - clif->equpcheckbox(sd); -#endif - -#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920 - if ((battle_config.display_config_messages & 0x40) != 0) - clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call); - - if ((battle_config.display_config_messages & 0x80) != 0) { - if (sd->pd != NULL) - clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed); - else - clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false); - } - - if ((battle_config.display_config_messages & 0x100) != 0) { - if (sd->hd != NULL) - clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed); - else - clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false); - } -#endif - } - - if (p != NULL) { - int flag; - - if (p->state.option_auto_changed != 0) - flag = 0x04; - else if (first_time) - flag = 0x20; - else if (change_map) - flag = 0x40; - else - flag = 0x80; - - clif->party_option(p, sd, flag); - } - - if (((battle_config.display_rate_messages & 0x1) != 0 && first_time) - || ((battle_config.display_rate_messages & 0x2) != 0 && !first_time && change_map) - || (battle_config.display_rate_messages & 0x4) != 0) { - clif->show_modifiers(sd); - } - if (sd->guild != NULL) { - // Show guild notice. - if (((battle_config.guild_notice_changemap & 0x1) != 0 && first_time) - || ((battle_config.guild_notice_changemap & 0x2) != 0 && !first_time && change_map) - || (battle_config.guild_notice_changemap & 0x4) != 0) { - clif->guild_notice(sd, sd->guild); - } - // Init guild aura. if (sd->state.gmaster_flag != 0) { guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP)); -- cgit v1.2.3-60-g2f50 From bc4d22f7e0148f6b32eb420aa2bbee9b464b0381 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 03:15:21 +0200 Subject: Remove obsolete variables `first_time` and `change_map` from clif_parse_LoadEndAck() --- src/map/clif.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 2eb2b903f..92c599f51 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -11000,10 +11000,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) status_calc_bl(&sd->ed->bl, SCB_SPEED); // Elementals mimic their master's speed on each map change. } - bool first_time = false; - if (sd->state.connect_new != 0) { - first_time = true; sd->state.connect_new = 0; clif->skillinfoblock(sd); clif->hotkeysAll(sd); @@ -11091,8 +11088,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) } } - bool change_map = (sd->state.changemap != 0); - if (sd->state.changemap != 0) { // Restore information that gets lost on map-change. bool flee_penalty = (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100); bool is_gvg = (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m)); -- cgit v1.2.3-60-g2f50 From dfaaef415a0eb1e8490a60ad92e6389a16d4c4ea Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 04:15:26 +0200 Subject: Add clif_open_ui_send() function --- src/map/clif.c | 88 +++++++++++++++++++++++++++++++++++++++++----------------- src/map/clif.h | 1 + 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 92c599f51..20a9414c9 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -23125,61 +23125,65 @@ static void clif_parse_open_ui_request(int fd, struct map_session_data *sd) clif->open_ui(sd, p->UIType); } -static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType) +/** + * Does the actual packet sending for clif_open_ui(). + * + * @param sd The character who opens the UI. + * @param ui_type The UI which should be opened. + * + **/ +static void clif_open_ui_send(struct map_session_data *sd, enum zc_ui_types ui_type) { + nullpo_retv(sd); + #if PACKETVER >= 20150128 struct PACKET_ZC_OPEN_UI p; -#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411 - int claimed = 0; -#endif - - nullpo_retv(sd); p.PacketType = openUiType; - switch (uiType) { - case CZ_STYLIST_UI: - p.UIType = ZC_STYLIST_UI; -#if PACKETVER >= 20171122 - p.data = 0; -#endif - break; - case CZ_MACRO_REGISTER_UI: - p.UIType = ZC_CAPTCHA_UI; + p.UIType = ui_type; + + switch (ui_type) { + case ZC_BANK_UI: + case ZC_STYLIST_UI: + case ZC_CAPTCHA_UI: + case ZC_MACRO_UI: #if PACKETVER >= 20171122 p.data = 0; #endif break; - case CZ_MACRO_DETECTOR_UI: - p.UIType = ZC_MACRO_UI; #if PACKETVER >= 20171122 + case ZC_TIPBOX_UI: + case ZC_RENEWQUEST_UI: p.data = 0; -#endif break; - case CZ_ATTENDANCE_UI: - { + case ZC_ATTENDANCE_UI: + if (battle_config.feature_enable_attendance_system == 0) + return; + if (clif->attendance_getendtime() < time(NULL)) { #if PACKETVER >= 20180207 clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED); #endif return; } - if (battle_config.feature_enable_attendance_system != 1) - return; + #if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411 - if (clif->attendance_timediff(sd) != true) + int claimed = 0; + + if (!clif->attendance_timediff(sd)) ++claimed; else if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data)) sd->status.attendance_count = 0; - p.UIType = ZC_ATTENDANCE_UI; + p.data = sd->status.attendance_count * 10 + claimed; #else ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411.\n"); return; #endif break; - } +#endif default: - ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType); + ShowWarning("clif_open_ui_send: Requested UI (%u) is not implemented yet.\n", ui_type); return; } @@ -23187,6 +23191,37 @@ static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType) #endif } +static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType) +{ + nullpo_retv(sd); + + enum zc_ui_types send_ui_type; + + switch (uiType) { +#if PACKETVER >= 20150128 + case CZ_STYLIST_UI: + send_ui_type = ZC_STYLIST_UI; + break; + case CZ_MACRO_REGISTER_UI: + send_ui_type = ZC_CAPTCHA_UI; + break; + case CZ_MACRO_DETECTOR_UI: + send_ui_type = ZC_MACRO_UI; + break; +#endif +#if PACKETVER >= 20171122 + case CZ_ATTENDANCE_UI: + send_ui_type = ZC_ATTENDANCE_UI; + break; +#endif + default: + ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType); + return; + } + + clif->open_ui_send(sd, send_ui_type); +} + static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2))); static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) { @@ -25297,6 +25332,7 @@ void clif_defaults(void) clif->attendance_timediff = clif_attendance_timediff; clif->attendance_getendtime = clif_attendance_getendtime; clif->pOpenUIRequest = clif_parse_open_ui_request; + clif->open_ui_send = clif_open_ui_send; clif->open_ui = clif_open_ui; clif->pAttendanceRewardRequest = clif_parse_attendance_reward_request; clif->ui_action = clif_ui_action; diff --git a/src/map/clif.h b/src/map/clif.h index 7d159d851..ee76e62e8 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -1658,6 +1658,7 @@ struct clif_interface { bool (*attendance_timediff) (struct map_session_data *sd); time_t (*attendance_getendtime) (void); void (*pOpenUIRequest) (int fd, struct map_session_data *sd); + void (*open_ui_send) (struct map_session_data *sd, enum zc_ui_types ui_type); void (*open_ui) (struct map_session_data *sd, enum cz_ui_types uiType); void (*pAttendanceRewardRequest) (int fd, struct map_session_data *sd); void (*ui_action) (struct map_session_data *sd, int32 UIType, int32 data); -- cgit v1.2.3-60-g2f50 From b721e019717fe7254bdfd8e640847ad053d16eb1 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 04:19:05 +0200 Subject: Show tip of the day window upon login --- src/map/clif.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/map/clif.c b/src/map/clif.c index 20a9414c9..60dd18807 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -11065,6 +11065,10 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) // Notify everyone that this character logged in. [Skotlex] map->foreachpc(clif->friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 1); +#if PACKETVER >= 20171122 + clif->open_ui_send(sd, ZC_TIPBOX_UI); +#endif + // Run OnPCLoginEvent labels. npc->script_event(sd, NPCE_LOGIN); } else { -- cgit v1.2.3-60-g2f50 From ddf679b3808e56309a7352eead2cd1f93c9f99c9 Mon Sep 17 00:00:00 2001 From: Kenpachi Developer Date: Mon, 22 Jun 2020 04:24:20 +0200 Subject: Add battle flag for tip of the day window display --- conf/map/battle/client.conf | 3 +++ src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/clif.c | 3 ++- 4 files changed, 7 insertions(+), 1 deletion(-) diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf index f080e8375..d4c0f3e1a 100644 --- a/conf/map/battle/client.conf +++ b/conf/map/battle/client.conf @@ -235,3 +235,6 @@ display_config_messages: 0x1F1 // 0x2 - Display overweight messages upon map change. (Default.) // Default: 0x3 (Official behavior.) display_overweight_messages: 0x3 + +// Show tip of the day window upon login? +show_tip_window: true diff --git a/src/map/battle.c b/src/map/battle.c index 0ef9c66e8..4d07a2eb9 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7435,6 +7435,7 @@ static const struct battle_data { { "display_rate_messages", &battle_config.display_rate_messages, 1, 0, 7, }, { "display_config_messages", &battle_config.display_config_messages, 0x1F1, 0, 0x1F7, }, { "display_overweight_messages", &battle_config.display_overweight_messages, 3, 0, 3, }, + { "show_tip_window", &battle_config.show_tip_window, 1, 0, 1, }, { "features/enable_refinery_ui", &battle_config.enable_refinery_ui, 1, 0, 1, }, { "features/replace_refine_npcs", &battle_config.replace_refine_npcs, 1, 0, 1, }, { "batk_min_limit", &battle_config.batk_min, 0, 0, INT_MAX, }, diff --git a/src/map/battle.h b/src/map/battle.h index 19cfd2748..2e4209925 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -594,6 +594,7 @@ struct Battle_Config { int display_rate_messages; int display_config_messages; int display_overweight_messages; + int show_tip_window; int enable_refinery_ui; int replace_refine_npcs; diff --git a/src/map/clif.c b/src/map/clif.c index 60dd18807..3f1690aa0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -11066,7 +11066,8 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) map->foreachpc(clif->friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 1); #if PACKETVER >= 20171122 - clif->open_ui_send(sd, ZC_TIPBOX_UI); + if (battle_config.show_tip_window != 0) + clif->open_ui_send(sd, ZC_TIPBOX_UI); #endif // Run OnPCLoginEvent labels. -- cgit v1.2.3-60-g2f50