From 86b70dc7ea0a6d3aee6d99a0f802668fc9a0eb75 Mon Sep 17 00:00:00 2001 From: Jedzkie Date: Mon, 21 Mar 2016 23:55:30 +0800 Subject: Fixes #889 & #840 - Novice classes will never go below 50% hp when died. - Other classes will show 1 HP rather than 0 when died. - Added battle configuration. Signed-off-by: Haru --- conf/map/battle/client.conf | 12 +++++++++ src/map/battle.c | 1 + src/map/battle.h | 2 ++ src/map/clif.c | 7 ++++- src/map/status.c | 63 +++++++++++++++++++++++++++++++++++---------- src/map/status.h | 2 ++ 6 files changed, 72 insertions(+), 15 deletions(-) diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf index 35c585bf6..b7d4ac781 100644 --- a/conf/map/battle/client.conf +++ b/conf/map/battle/client.conf @@ -177,3 +177,15 @@ client_emblem_max_blank_percent: 100 // kRO removed the packet and this re-enables the message. // Official: false. mvp_exp_reward_message: false + +// Displays the same HP value as official servers do when a character is dead. +// (Note 1) +// On official servers, HP are never displayed as 0, but when dead, they +// display the value that will be shown after resurrection (50% HP for novice +// classes, 1 HP for other classes). Athena servers, instead, show the real +// value (0 when dead), to avoid confusion. +// Note: this is only a visual setting, and the server will internally handle +// it as 0 regardless of this. This means that scripts will know that the +// character has 0 HP when dead. +// Default: true (Official behavior) +display_fake_hp_when_dead: true diff --git a/src/map/battle.c b/src/map/battle.c index 44241bf23..ee9662c33 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -7407,6 +7407,7 @@ static const struct battle_data { { "features/feature_attendance_endtime",&battle_config.feature_attendance_endtime, 1, 0, 99999999, }, { "min_item_buy_price", &battle_config.min_item_buy_price, 1, 0, INT_MAX, }, { "min_item_sell_price", &battle_config.min_item_sell_price, 0, 0, INT_MAX, }, + { "display_fake_hp_when_dead", &battle_config.display_fake_hp_when_dead, 1, 0, 1, }, }; static bool battle_set_value_sub(int index, int value) diff --git a/src/map/battle.h b/src/map/battle.h index 02536e4a1..750753c08 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -574,6 +574,8 @@ struct Battle_Config { int min_item_buy_price; int min_item_sell_price; + + int display_fake_hp_when_dead; }; /* criteria for battle_config.idletime_critera */ diff --git a/src/map/clif.c b/src/map/clif.c index 44cefcd7e..d1ff201ad 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -3244,7 +3244,12 @@ static void clif_updatestatus(struct map_session_data *sd, int type) WFIFOL(fd,4)=sd->battle_status.max_sp; break; case SP_HP: - WFIFOL(fd,4)=sd->battle_status.hp; + if (sd->battle_status.hp == 0 && battle_config.display_fake_hp_when_dead) { + // On official servers, the HP displayed when dead is the HP that the character will have at respawn. + WFIFOL(fd, 4) = status->get_restart_hp(sd, &sd->battle_status); + } else { + WFIFOL(fd, 4) = sd->battle_status.hp; + } break; case SP_SP: WFIFOL(fd,4)=sd->battle_status.sp; diff --git a/src/map/status.c b/src/map/status.c index 370432ce7..b377a1f35 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2330,6 +2330,51 @@ static unsigned int status_get_base_maxhp(const struct map_session_data *sd, con return (unsigned int)cap_value(val,0,UINT_MAX); } +/** + * Calculates the HP that a character will have after death, on respawn. + * + * @param sd The character to calculate. + * @param st The character's status data. + */ +static unsigned int status_get_restart_hp(const struct map_session_data *sd, const struct status_data *st) +{ + unsigned int hp = 0; + + if (sd->special_state.restart_full_recover) + return st->max_hp; + + if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0 && battle_config.restart_hp_rate < 50) + hp = st->max_hp / 2; + else + hp = APPLY_RATE(st->max_hp, battle_config.restart_hp_rate); + + if (hp > 0) + return hp; + + return 1; +} + +/** + * Calculates the SP that a character will have after death, on respawn. + * + * @param sd The character to calculate. + * @param st The character's status data. + */ +static unsigned int status_get_restart_sp(const struct map_session_data *sd, const struct status_data *st) +{ + unsigned int sp = 0; + + if (sd->special_state.restart_full_recover) + return st->max_sp; + + sp = APPLY_RATE(st->max_sp, battle_config.restart_sp_rate); + + if (sp > 0) + return sp; + + return 1; // the minimum for the respawn setting is SP:1 +} + static void status_calc_pc_additional(struct map_session_data *sd, enum e_status_calc_opt opt) { /* Just used for Plugin to give bonuses. */ @@ -2884,20 +2929,8 @@ static int status_calc_pc_(struct map_session_data *sd, enum e_status_calc_opt o // ----- RESPAWN HP/SP ----- // //Calc respawn hp and store it on base_status - if (sd->special_state.restart_full_recover) - { - bstatus->hp = bstatus->max_hp; - bstatus->sp = bstatus->max_sp; - } else { - status->calc_pc_recover_hp(sd, bstatus); - if(!bstatus->hp) - bstatus->hp = 1; - - bstatus->sp = APPLY_RATE(bstatus->max_sp, battle_config.restart_sp_rate); - - if( !bstatus->sp ) /* the minimum for the respawn setting is SP:1 */ - bstatus->sp = 1; - } + bstatus->hp = status->get_restart_hp(sd, bstatus); + bstatus->sp = status->get_restart_sp(sd, bstatus); // ----- MISC CALCULATION ----- status->calc_misc(&sd->bl, bstatus, sd->status.base_level); @@ -13729,6 +13762,8 @@ void status_defaults(void) status->base_atk = status_base_atk; status->get_base_maxhp = status_get_base_maxhp; status->get_base_maxsp = status_get_base_maxsp; + status->get_restart_hp = status_get_restart_hp; + status->get_restart_sp = status_get_restart_sp; status->calc_npc_ = status_calc_npc_; status->calc_str = status_calc_str; status->calc_agi = status_calc_agi; diff --git a/src/map/status.h b/src/map/status.h index e7cd5e94c..532efce17 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -2384,6 +2384,8 @@ struct status_interface { unsigned short (*base_atk) (const struct block_list *bl, const struct status_data *st); unsigned int (*get_base_maxhp) (const struct map_session_data *sd, const struct status_data *st); unsigned int (*get_base_maxsp) (const struct map_session_data *sd, const struct status_data *st); + unsigned int (*get_restart_hp) (const struct map_session_data *sd, const struct status_data *st); + unsigned int (*get_restart_sp) (const struct map_session_data *sd, const struct status_data *st); int (*calc_npc_) (struct npc_data *nd, enum e_status_calc_opt opt); unsigned short (*calc_str) (struct block_list *bl, struct status_change *sc, int str); unsigned short (*calc_agi) (struct block_list *bl, struct status_change *sc, int agi); -- cgit v1.2.3-70-g09d2