#include "data/scripts/dc_timing/master_config.h"
/*
* dc_pause_adjust
*
* Adjusts stun-related timers on a target entity to modify how long they're paused (unable to act),
* usually following an attack.
*
* Intended to be called during the `didhit` event of the attacking entity.
*
* Combines two sources of timing delay:
* 1. `time_adjust_param` - An explicit value passed into the function.
* 2. A temporary per-entity value stored in a custom entity variable
* (`DC_TIMING_VARKEY_PAUSE_ADJUST`) on the attacking entity.
*
* Once both values are added together, it extends the stun timers on the target entity,
* then clears the temporary variable from the attacker to avoid double application.
*
* Note: The engine applies native attack pause **after** the `didhit` script runs.
* This means any adjustment made here is **added on top** of the default hitpause.
*
* Some of Valis's armed attacks have a bit of lag compared to others to balance his reach
* and initial execution speed. The stun times, however, are tuned for near-instant
* combo execution. Adjusting the stun time for hit entities lets us keep his attack lag
* while still allowing him to complete his combos reliably on a struck opponent.
*
* Also – you know, he's hitting them with a BFS, so let's make it *feel* like it hurt. :)
*
* This mechanic exists because we can't simply increase Valis's native attack stun because
* that pause affects both him and the enemy. Doing so would make his attacks feel sluggish
* and visually clumsy. Instead, we isolate and extend the *enemy's* pause window here
* while leaving Valis free to recover and continue his combo.
*
* Parameters:
* - acting_entity: The attacker (must be a valid entity pointer).
* - acting_target: The target who receives the adjusted stun.
* - time_adjust_param: Additional time to add to stun timers.
*/
void dc_pause_adjust_apply(void acting_entity, void acting_target, int time_adjust_param){
// Validate that the acting entity is a valid pointer
if(!acting_entity || typeof(acting_entity) != openborconstant("VT_PTR")) {
return;
}
// Validate that the target entity is a valid pointer
if(!acting_target || typeof(acting_target) != openborconstant("VT_PTR")) {
return;
}
// If no time adjustment parameter is passed, default to zero
if(!time_adjust_param){
time_adjust_param = 0;
}
// Retrieve current stun-related timer values from the target entity
int next_move_time = getentityproperty(acting_target, "nextmove");
int next_anim_time = getentityproperty(acting_target, "nextanim");
int next_think_time = getentityproperty(acting_target, "nextthink");
int toss_time = getentityproperty(acting_target, "tosstime");
// Read the attacker's temporary pause adjustment value
int time_adjust_setup = getentityvar(acting_entity, DC_TIMING_VARKEY_PAUSE_ADJUST);
// Default to zero if the attacker has no pause adjustment value set
if(!time_adjust_setup){
time_adjust_setup = 0;
}
// 0 the temporary variable on the attacking entity so it doesn't apply again.
// We don't NULL() it so the variable stays in placy. This is slightly
// more optimal since we will almost certainly use the variable again and
// so there's no reason to make engine re-initialize it over and over.
setentityvar(acting_entity, DC_TIMING_VARKEY_PAUSE_ADJUST, 0);
// Calculate final time adjustment by summing the param and the temp variable
int final_adjust = time_adjust_setup + time_adjust_param;
// If no adjustment is needed, do nothing
if(!final_adjust) {
return;
}
// Apply the final adjustment to all relevant timers on the target
next_anim_time += final_adjust;
next_move_time += final_adjust;
next_think_time += final_adjust;
toss_time += final_adjust;
// Update the target's timers with the new adjusted values
changeentityproperty(acting_target, "nextmove", next_move_time);
changeentityproperty(acting_target, "nextanim", next_anim_time);
changeentityproperty(acting_target, "nextthink", next_think_time);
changeentityproperty(acting_target, "tosstime", toss_time);
}
/*
* dc_pause_adjust_setup
*
* Stores a temporary pause adjustment value on the acting entity. This value is picked up later
* by the `dc_pause_adjust` function during the `didhit` event to extend the target's stun window.
*
* Parameters:
* - pause_adjustment: The number of ticks to add to the target's stun when hit.
* This value is stored temporarily and cleared after use.
*
* Important:
* This should be called before the attack connects—typically early in the attack animation.
* Be sure to call this function again later in the animation with a value of 0 to turn the effect off.
*
* Also run this in the takedamage script to clear the value early if the attacker gets interrupted
* before the hit connects — this avoids stale values accidentally carrying over to the next hit.
*/
void dc_pause_adjust_setup(int pause_adjustment){
void acting_entity = getlocalvar("self");
// Validate that 'self' is a proper entity pointer
if(!acting_entity || typeof(acting_entity) != openborconstant("VT_PTR")) {
return;
}
// Store the pause adjustment value in the attacker's entity vars
setentityvar(acting_entity, DC_TIMING_VARKEY_PAUSE_ADJUST, pause_adjustment);
}