Jump to content

Didhitscript

From OpenBOR
Revision as of 16:28, 17 August 2026 by Dcurrent (talk | contribs) (Created page with "<code>didhitscript</code> is a model event that runs on the entity conferring a successfully accepted hit. It provides the attacker, recipient, and raw attack properties to script after OpenBOR has determined the collision will count as a hit. The event is hit confirmation rather than damage confirmation. It also runs when the recipient blocks, when an accepted hit produces no actual HP loss, when an item is collected, and when configured landing damage is applied. It d...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

didhitscript is a model event that runs on the entity conferring a successfully accepted hit. It provides the attacker, recipient, and raw attack properties to script after OpenBOR has determined the collision will count as a hit.

The event is hit confirmation rather than damage confirmation. It also runs when the recipient blocks, when an accepted hit produces no actual HP loss, when an item is collected, and when configured landing damage is applied. It does not run for misses, rejected collisions, counters, or attacks cancelled by ondoattackscript.

Syntax

didhitscript {path}

# Default
# No Didhit script
  • {path} - Path to an OpenBOR Script source file.
  • The command belongs in a model definition.
  • OpenBOR loads and compiles the script with the model.
  • The script's return value is ignored.

Example model definition:

name example_attacker
type enemy

didhitscript data/scripts/example_didhit.c

Event code may also be embedded directly in the model:

didhitscript @script
void main()
{
    void self        = getlocalvar("self");
    void recipient   = getlocalvar("damagetaker");
    int blocked      = getlocalvar("blocked");
}
@end_script

Event Scope

OpenBOR invokes didhitscript for the following native events.

Event self damagetaker Notes
Normal accepted hit Entity whose attack box supplied the hit Recipient Runs after the recipient's take-damage handling succeeds. blocked is 0.
Successful block Attacking entity Blocking entity A block still counts as a successful hit. blocked is 1.
Item collection Item entity Collecting entity OpenBOR supplies an otherwise empty attack object with type ATK_ITEM. Other numeric attack locals are normally 0.
Damage on landing Living opponent credited for the fall, or the landing entity when no valid opponent exists Landing entity Runs after landing damage and death checks. blocked is 0.

self is always the entity directly conferring the event. Projectiles therefore receive their own Didhit events; OpenBOR does not automatically substitute the projectile's owner. Scripts may inspect the entity's owner when they need to credit or notify the top-level character.

One attack may run the event several times when it legitimately hits several recipients. Normal attack-ID, next-hit-time, faction, vulnerability, ground-hit, juggle, and other collision rules still decide whether each candidate is accepted.

didhitscript is not a universal health-change callback. Direct script changes to health and unrelated damage paths do not automatically invoke it.

Execution Timing

Normal Hit

For an ordinary unblocked hit, OpenBOR performs the relevant operations in this order:

  1. Confirms collision, faction, timing, vulnerability, and other attack eligibility.
  2. Runs the recipient's ondoattackscript, followed by the attacker's ondoattackscript.
  3. Continues only when the shared last-hit confirmation remains enabled.
  4. Rejects blocking and counter actions.
  5. Runs the recipient's take-damage handling, including applicable offense, defense, HP, effect, pain, fall, and death processing.
  6. Runs the attacker's didhitscript with blocked = 0.
  7. Continues attacker-side hit counting, flash, pause, follow-up, combo, sound, and related processing.

The recipient's current state is therefore available when Didhit runs, including HP and the reaction selected by take-damage handling. The damage local still contains the attack's raw force rather than the final HP amount removed.

Blocked Hit

For a successful block, OpenBOR performs the following relevant sequence:

  1. Selects the native block reaction when applicable.
  2. Spawns the block flash.
  3. Runs the attacker's didhitscript with blocked = 1.
  4. Applies native blocking state, movement, and guard-cost handling when applicable.
  5. Counts the impact as a hit.
  6. Runs the defender's didblockscript.
  7. Applies configured chip damage and plays the block impact sound.

Consequently, blocked = 1 means the recipient successfully blocked the impact. It does not mean the recipient is guaranteed to lose no HP, because chip damage may follow.

Local Variables

Local variable Type Value
self Entity pointer Entity conferring the hit. Usually the attacker, projectile, or collected item.
damagetaker Entity pointer Entity receiving the hit, blocking it, collecting the item, or taking landing damage.
damage Integer Raw attack.damage.force at the time of the event. This is not the final HP loss after offense, defense, blocking, or other adjustments.
drop Integer Raw attack.reaction.fall.force - the attack's knockdown force.
attacktype Integer Internal attack-type identifier. Compare it with named ATK_* constants from openborconstant(), not creator-facing model-text numbers.
noblock Integer Raw attack.block.penetrate value. The local retains its legacy name.
guardcost Integer Raw attack.block.cost value.
jugglecost Integer Attack's juggle-point cost.
pauseadd Integer Raw attack.reaction.pause.time in logical clock ticks.
tag Integer Creator-defined attack.tag metadata.
blocked Integer 1 when the recipient successfully blocked the attack; otherwise 0.

The numeric locals are event values copied from the current attack. Assigning new values to these local variables does not write them back to native attack data or undo completed hit handling.

Use ondoattackscript and the last-hit interface when a script must inspect, modify, or cancel a collision before native hit resolution. Use didhitscript for reactions that should occur only after OpenBOR accepts the hit.

Global Model

Models loaded with the internal name global_model may provide a project-wide Didhit script.

# data/models.txt
load global_model data/chars/global_model.txt
# data/chars/global_model.txt
name global_model
didhitscript data/scripts/global_didhit.c

When an event occurs, OpenBOR executes scripts in this order:

  1. The loaded global_model Didhit script.
  2. The conferring entity's own Didhit script.

Both scripts receive the same event locals. Within the global script, self is the actual attacker, projectile, item, or landing-damage source - not a global_model entity. The global model must be loaded before its event script is available.

Example

The following script distinguishes ordinary hits, blocked hits, and item collection. The log calls are intentionally simple and may be replaced with project-specific functions.

void main()
{
    void self          = getlocalvar("self");
    void recipient     = getlocalvar("damagetaker");
    int attack_type    = getlocalvar("attacktype");
    int raw_force      = getlocalvar("damage");
    int was_blocked    = getlocalvar("blocked");

    if(attack_type == openborconstant("ATK_ITEM"))
    {
        log("Didhit: item collection");
        return;
    }

    if(was_blocked)
    {
        log("Didhit: blocked attack");
        return;
    }

    log("Didhit: accepted unblocked attack");
}

Unused locals in the example are retained to show the ordinary event setup. Real scripts may pass self, recipient, attack_type, and raw_force into creator-defined hit-confirm, resource, statistics, effect, or achievement systems.

Event Entity Relative purpose
Ondoattackscript Recipient first, then attacker Runs before block, counter, and take-damage resolution. May cancel native hit handling through the last-hit confirmation interface.
Takedamagescript Recipient Runs while native damage is being applied to the target.
Didhitscript Attacker or other conferring entity Runs after OpenBOR accepts a normal hit, block, item event, or landing-damage event.
Didblockscript Defender Runs after a successful block and after applicable native guard-cost deduction.

See Also