From 6ad669de61529415fc0a64f1cae5388ffc8900e8 Mon Sep 17 00:00:00 2001 From: csnv Date: Mon, 18 Sep 2023 01:06:16 +0200 Subject: [PATCH] Added option to synchronize flinch animation with walk delay Interrupts walking and applies walk delay at the same time as the client reproduces the flinch animation. Improves positional lag. --- src/config/core.h | 4 +++ src/map/battle.c | 4 ++- src/map/clif.c | 10 ++++++- src/map/status.c | 2 ++ src/map/unit.c | 13 +++++++++ src/map/unit.h | 1 + src/plugins/HPMHooking/HPMHooking.Defs.inc | 2 ++ .../HPMHooking_map.HPMHooksCore.inc | 4 +++ .../HPMHooking_map.HookingPoints.inc | 1 + .../HPMHooking/HPMHooking_map.Hooks.inc | 27 +++++++++++++++++++ 10 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/config/core.h b/src/config/core.h index 927a00fad4f..73ecb67be5e 100644 --- a/src/config/core.h +++ b/src/config/core.h @@ -100,6 +100,10 @@ /// Uncomment for use with Nemo patch ExtendOldCashShopPreview //#define ENABLE_OLD_CASHSHOP_PREVIEW_PATCH +/// Uncomment to allow flinch animation and walk delay to be synced +/// Reduces positional lag when getting hit +//#define WALKDELAY_SYNC + /** * No settings past this point **/ diff --git a/src/map/battle.c b/src/map/battle.c index 1f01e0889a8..7bb4e404076 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -350,7 +350,9 @@ static int battle_delay_damage(int64 tick, int amotion, struct block_list *src, if (src->type == BL_PC) { BL_UCAST(BL_PC, src)->delayed_damage++; } - +#ifdef WALKDELAY_SYNC + timer->add(tick + ddelay, unit->set_walkdelay_timer, target->id, ddelay); +#endif timer->add(tick+amotion, battle->delay_damage_sub, 0, (intptr_t)dat); return 0; diff --git a/src/map/clif.c b/src/map/clif.c index 61f33157663..57b91f296a0 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -5146,6 +5146,10 @@ static int clif_damage(struct block_list *src, struct block_list *dst, int sdela #endif type = clif_calc_delay(type,div,damage+damage2,ddelay); +#ifdef WALKDELAY_SYNC + // Send adjusted delay to client + ddelay = clif->calc_walkdelay(dst, ddelay, type, damage + damage2, div); +#endif p.PacketType = damageType; p.GID = src->id; @@ -5191,7 +5195,11 @@ static int clif_damage(struct block_list *src, struct block_list *dst, int sdela } //Return adjusted can't walk delay for further processing. - return clif->calc_walkdelay(dst,ddelay,type,damage+damage2,div); +#ifdef WALKDELAY_SYNC + return ddelay; +#else + return clif->calc_walkdelay(dst, ddelay, type, damage + damage2, div); +#endif } /*========================================== diff --git a/src/map/status.c b/src/map/status.c index 6ef2fea39c3..e0bd980e3aa 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -408,8 +408,10 @@ static int status_damage(struct block_list *src, struct block_list *target, int6 if (st->hp || (flag&8)) { //Still lives or has been dead before this damage. +#ifndef WALKDELAY_SYNC if (walkdelay) unit->set_walkdelay(target, timer->gettick(), walkdelay, 0); +#endif return (int)(hp+sp); } diff --git a/src/map/unit.c b/src/map/unit.c index b9080ac145d..592cf3829a9 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1345,6 +1345,18 @@ static int unit_resume_running(int tid, int64 tick, int id, intptr_t data) } +/*========================================== + * Apply walk delay timer + *------------------------------------------*/ +static int unit_set_walkdelay_timer(int tid, int64 tick, int id, intptr_t data) +{ + struct block_list* bl = map->id2bl(id); + if (bl == NULL) + return 1; + + unit->set_walkdelay(bl, tick, (int)data, 0); + return 0; +} /*========================================== * Applies walk delay to character, considering that @@ -3236,6 +3248,7 @@ void unit_defaults(void) unit->is_walking = unit_is_walking; unit->can_move = unit_can_move; unit->resume_running = unit_resume_running; + unit->set_walkdelay_timer = unit_set_walkdelay_timer; unit->set_walkdelay = unit_set_walkdelay; unit->skilluse_id2 = unit_skilluse_id2; unit->skilluse_pos = unit_skilluse_pos; diff --git a/src/map/unit.h b/src/map/unit.h index e5e0ed54284..1eaedaaba1d 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -129,6 +129,7 @@ struct unit_interface { int (*is_walking) (struct block_list *bl); int (*can_move) (struct block_list *bl); int (*resume_running) (int tid, int64 tick, int id, intptr_t data); + int (*set_walkdelay_timer) (int tid, int64 tick, int id, intptr_t data); int (*set_walkdelay) (struct block_list *bl, int64 tick, int delay, int type); int (*skilluse_id2) (struct block_list *src, int target_id, uint16 skill_id, uint16 skill_lv, int casttime, int castcancel); int (*skilluse_pos) (struct block_list *src, short skill_x, short skill_y, uint16 skill_id, uint16 skill_lv); diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc index 839f4855330..d112e4e19e8 100644 --- a/src/plugins/HPMHooking/HPMHooking.Defs.inc +++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc @@ -9596,6 +9596,8 @@ typedef int (*HPMHOOK_pre_unit_can_move) (struct block_list **bl); typedef int (*HPMHOOK_post_unit_can_move) (int retVal___, struct block_list *bl); typedef int (*HPMHOOK_pre_unit_resume_running) (int *tid, int64 *tick, int *id, intptr_t *data); typedef int (*HPMHOOK_post_unit_resume_running) (int retVal___, int tid, int64 tick, int id, intptr_t data); +typedef int (*HPMHOOK_pre_unit_set_walkdelay_timer) (int *tid, int64 *tick, int *id, intptr_t *data); +typedef int (*HPMHOOK_post_unit_set_walkdelay_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data); typedef int (*HPMHOOK_pre_unit_set_walkdelay) (struct block_list **bl, int64 *tick, int *delay, int *type); typedef int (*HPMHOOK_post_unit_set_walkdelay) (int retVal___, struct block_list *bl, int64 tick, int delay, int type); typedef int (*HPMHOOK_pre_unit_skilluse_id2) (struct block_list **src, int *target_id, uint16 *skill_id, uint16 *skill_lv, int *casttime, int *castcancel); diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index e0081109e37..adc7f7efa8d 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -7494,6 +7494,8 @@ struct { struct HPMHookPoint *HP_unit_can_move_post; struct HPMHookPoint *HP_unit_resume_running_pre; struct HPMHookPoint *HP_unit_resume_running_post; + struct HPMHookPoint *HP_unit_set_walkdelay_timer_pre; + struct HPMHookPoint *HP_unit_set_walkdelay_timer_post; struct HPMHookPoint *HP_unit_set_walkdelay_pre; struct HPMHookPoint *HP_unit_set_walkdelay_post; struct HPMHookPoint *HP_unit_skilluse_id2_pre; @@ -15025,6 +15027,8 @@ struct { int HP_unit_can_move_post; int HP_unit_resume_running_pre; int HP_unit_resume_running_post; + int HP_unit_set_walkdelay_timer_pre; + int HP_unit_set_walkdelay_timer_post; int HP_unit_set_walkdelay_pre; int HP_unit_set_walkdelay_post; int HP_unit_skilluse_id2_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index f2760cd22be..2b0b75955b0 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -3835,6 +3835,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(unit->is_walking, HP_unit_is_walking) }, { HP_POP(unit->can_move, HP_unit_can_move) }, { HP_POP(unit->resume_running, HP_unit_resume_running) }, + { HP_POP(unit->set_walkdelay_timer, HP_unit_set_walkdelay_timer) }, { HP_POP(unit->set_walkdelay, HP_unit_set_walkdelay) }, { HP_POP(unit->skilluse_id2, HP_unit_skilluse_id2) }, { HP_POP(unit->skilluse_pos, HP_unit_skilluse_pos) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index e5222e12297..a3f9eb55be2 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -100199,6 +100199,33 @@ int HP_unit_resume_running(int tid, int64 tick, int id, intptr_t data) { } return retVal___; } +int HP_unit_set_walkdelay_timer(int tid, int64 tick, int id, intptr_t data) { + int hIndex = 0; + int retVal___ = 0; + if (HPMHooks.count.HP_unit_set_walkdelay_timer_pre > 0) { + int (*preHookFunc) (int *tid, int64 *tick, int *id, intptr_t *data); + *HPMforce_return = false; + for (hIndex = 0; hIndex < HPMHooks.count.HP_unit_set_walkdelay_timer_pre; hIndex++) { + preHookFunc = HPMHooks.list.HP_unit_set_walkdelay_timer_pre[hIndex].func; + retVal___ = preHookFunc(&tid, &tick, &id, &data); + } + if (*HPMforce_return) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.unit.set_walkdelay_timer(tid, tick, id, data); + } + if (HPMHooks.count.HP_unit_set_walkdelay_timer_post > 0) { + int (*postHookFunc) (int retVal___, int tid, int64 tick, int id, intptr_t data); + for (hIndex = 0; hIndex < HPMHooks.count.HP_unit_set_walkdelay_timer_post; hIndex++) { + postHookFunc = HPMHooks.list.HP_unit_set_walkdelay_timer_post[hIndex].func; + retVal___ = postHookFunc(retVal___, tid, tick, id, data); + } + } + return retVal___; +} int HP_unit_set_walkdelay(struct block_list *bl, int64 tick, int delay, int type) { int hIndex = 0; int retVal___ = 0;