<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://chronocrash.com/openbor/wiki/index.php?action=history&amp;feed=atom&amp;title=Onpainscript</id>
	<title>Onpainscript - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://chronocrash.com/openbor/wiki/index.php?action=history&amp;feed=atom&amp;title=Onpainscript"/>
	<link rel="alternate" type="text/html" href="https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;action=history"/>
	<updated>2026-09-12T10:17:12Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;diff=908&amp;oldid=prev</id>
		<title>Dcurrent at 23:28, 17 August 2026</title>
		<link rel="alternate" type="text/html" href="https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;diff=908&amp;oldid=prev"/>
		<updated>2026-08-17T23:28:04Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 19:28, 17 August 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l260&quot;&gt;Line 260:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 260:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[Didhitscript]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[Didhitscript]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[Script Overview]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;* [[Script Overview]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:Openbor]]&lt;/del&gt;&lt;/div&gt;&lt;/td&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-added&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Model]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Model]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Script]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Script]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Script Events]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Script Events]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:OpenBOR Index]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Dcurrent</name></author>
	</entry>
	<entry>
		<id>https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;diff=884&amp;oldid=prev</id>
		<title>Dcurrent at 21:58, 17 August 2026</title>
		<link rel="alternate" type="text/html" href="https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;diff=884&amp;oldid=prev"/>
		<updated>2026-08-17T21:58:10Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw-interface=&quot;&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;en&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Older revision&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Revision as of 17:58, 17 August 2026&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l264&quot;&gt;Line 264:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Line 264:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Model]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Model]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Script]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[Category:Script]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[Category:Script Events]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Dcurrent</name></author>
	</entry>
	<entry>
		<id>https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;diff=883&amp;oldid=prev</id>
		<title>Dcurrent: Created page with &quot;&lt;code&gt;onpainscript&lt;/code&gt; is OpenBOR&#039;s pain-reaction hook. It runs after the engine successfully selects and starts a pain or grabbed animation, stops the entity&#039;s movement, clears conflicting action states, and establishes the native pain response.  This placement lets creators inspect the requested attack type and immediately extend or replace the selected reaction. Typical uses include armor responses, custom hit stun, contextual flinches, retaliation, stagger systems...&quot;</title>
		<link rel="alternate" type="text/html" href="https://chronocrash.com/openbor/wiki/index.php?title=Onpainscript&amp;diff=883&amp;oldid=prev"/>
		<updated>2026-08-17T21:56:35Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;&amp;lt;code&amp;gt;onpainscript&amp;lt;/code&amp;gt; is OpenBOR&amp;#039;s pain-reaction hook. It runs after the engine successfully selects and starts a pain or grabbed animation, stops the entity&amp;#039;s movement, clears conflicting action states, and establishes the native pain response.  This placement lets creators inspect the requested attack type and immediately extend or replace the selected reaction. Typical uses include armor responses, custom hit stun, contextual flinches, retaliation, stagger systems...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;code&amp;gt;onpainscript&amp;lt;/code&amp;gt; is OpenBOR&amp;#039;s pain-reaction hook. It runs after the engine successfully selects and starts a pain or grabbed animation, stops the entity&amp;#039;s movement, clears conflicting action states, and establishes the native pain response.&lt;br /&gt;
&lt;br /&gt;
This placement lets creators inspect the requested attack type and immediately extend or replace the selected reaction. Typical uses include armor responses, custom hit stun, contextual flinches, retaliation, stagger systems, hit voices, reaction effects, AI state changes, and grabbed-state behavior.&lt;br /&gt;
&lt;br /&gt;
Onpain is not a general damage callback. Hits that cause no pain, resolve as blocks, knock the entity down, kill it, or never enter the native pain selector do not invoke the event. Use [[Takedamagescript]] for post-HP logic and [[Onfallscript]] for fall or knockdown reactions.&lt;br /&gt;
&lt;br /&gt;
== Syntax ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
onpainscript {path}&lt;br /&gt;
&lt;br /&gt;
# Default&lt;br /&gt;
# No Onpain script&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt; - Path to an OpenBOR Script source file.&lt;br /&gt;
* The command belongs in a model definition.&lt;br /&gt;
* OpenBOR loads and compiles the script with the model.&lt;br /&gt;
* The script&amp;#039;s return value is ignored.&lt;br /&gt;
&lt;br /&gt;
Example model definition:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
name example_character&lt;br /&gt;
type enemy&lt;br /&gt;
&lt;br /&gt;
onpainscript data/scripts/example_onpain.c&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Event code may also be embedded directly in the model:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
onpainscript @script&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    void self = getlocalvar(&amp;quot;self&amp;quot;);&lt;br /&gt;
    int attack_type = getlocalvar(&amp;quot;attacktype&amp;quot;);&lt;br /&gt;
    int reset = getlocalvar(&amp;quot;reset&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
@end_script&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Event Timing ==&lt;br /&gt;
&lt;br /&gt;
For an ordinary accepted hit that produces a standing pain reaction, OpenBOR performs the relevant operations in this order:&lt;br /&gt;
&lt;br /&gt;
# Resolves Ondoattack, block, counter, damage, Takedamage, lethal handling, and native death checks.&lt;br /&gt;
# Determines that the surviving recipient should enter pain rather than fall, remain frozen, or ignore the reaction.&lt;br /&gt;
# Selects guard-break, attack-type pain, back-pain, generic pain, grabbed, or idle fallback animation as applicable.&lt;br /&gt;
# Starts or retains the selected animation according to the reset flag.&lt;br /&gt;
# Stops velocity and clears idling, falling, rising, ducking, projectile, drop, attacking, getting, charging, jumping, and blocking states.&lt;br /&gt;
# Marks the entity as being in hit pain, except when the selected request represents the grabbed state.&lt;br /&gt;
# Removes frozen state when applicable.&lt;br /&gt;
# Runs &amp;lt;code&amp;gt;onpainscript&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Returns to the calling damage or grab path.&lt;br /&gt;
&lt;br /&gt;
For ordinary damage, Onpain runs after Takedamage and any Ondeath processing, but before the attacker&amp;#039;s [[Didhitscript]]. Damage and earlier hit effects have already occurred.&lt;br /&gt;
&lt;br /&gt;
The selected animation is active when Onpain begins. Scripts may inspect it, add effects, or replace the native reaction with creator-defined behavior. Normal standing damage performs no later pain-animation selection after the callback returns.&lt;br /&gt;
&lt;br /&gt;
Grab callers may still perform positioning or frame adjustments after Onpain returns. Grab-specific overrides should account for the surrounding grab system.&lt;br /&gt;
&lt;br /&gt;
== Native Pain Selection ==&lt;br /&gt;
&lt;br /&gt;
OpenBOR uses the following general selection order before invoking Onpain:&lt;br /&gt;
&lt;br /&gt;
# Select &amp;lt;code&amp;gt;ANI_GUARDBREAK&amp;lt;/code&amp;gt; when guard points are configured and depleted, then restore the native guard-point pool.&lt;br /&gt;
# Select &amp;lt;code&amp;gt;ANI_GRABBED&amp;lt;/code&amp;gt; when the requested type is &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Otherwise select the front or back pain animation associated with the requested attack type.&lt;br /&gt;
# Fall back through normal back-pain, requested-type pain, normal pain, and idle animations when needed.&lt;br /&gt;
# Abort without invoking Onpain when no valid fallback exists.&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;attacktype&amp;lt;/code&amp;gt; local contains the requested type passed into the selector, not the animation identifier ultimately chosen. Missing type-specific animation data may therefore produce a generic pain animation while the original type remains available to script.&lt;br /&gt;
&lt;br /&gt;
== Practical Uses ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Pattern&lt;br /&gt;
! Use of &amp;lt;code&amp;gt;onpainscript&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Armor or poise response&lt;br /&gt;
| Detect an armor state after damage, replace the ordinary flinch with an armored response, and add sparks, sound, meter loss, or temporary resistance feedback.&lt;br /&gt;
|-&lt;br /&gt;
| Contextual hit stun&lt;br /&gt;
| Choose a reaction duration or custom animation from attack type, health, combo state, attacker category saved by an earlier event, or entity-specific rules.&lt;br /&gt;
|-&lt;br /&gt;
| Reactive counter or burst&lt;br /&gt;
| Consume a defensive resource and replace pain with a counter, escape, shockwave, or invulnerable recovery when project conditions permit.&lt;br /&gt;
|-&lt;br /&gt;
| Type-specific feedback&lt;br /&gt;
| Add burn, freeze, shock, heavy-hit, weapon, or other creator-defined presentation after the native reaction has been established.&lt;br /&gt;
|-&lt;br /&gt;
| AI state transition&lt;br /&gt;
| Notify behavior logic that a true pain reaction occurred, then change aggression, retreat, target selection, phase state, or tactical priorities.&lt;br /&gt;
|-&lt;br /&gt;
| Grabbed-state behavior&lt;br /&gt;
| Detect &amp;lt;code&amp;gt;attacktype = -1&amp;lt;/code&amp;gt; and coordinate project-specific held, captured, mounted, restrained, or synchronized interaction logic.&lt;br /&gt;
|-&lt;br /&gt;
| Accessibility and combat readability&lt;br /&gt;
| Add configurable flashes, sounds, indicators, vibration logic, or other feedback only when the entity visibly enters pain.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Armor Response ===&lt;br /&gt;
&lt;br /&gt;
The following compact example replaces ordinary pain while a creator-defined armor state is active. Project helper &amp;lt;code&amp;gt;play_armor_response()&amp;lt;/code&amp;gt; may select an armor animation, adjust action state, and create the desired effects.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot; line&amp;gt;&lt;br /&gt;
void main()&lt;br /&gt;
{&lt;br /&gt;
    void self = getlocalvar(&amp;quot;self&amp;quot;);&lt;br /&gt;
    int attack_type = getlocalvar(&amp;quot;attacktype&amp;quot;);&lt;br /&gt;
    int armor_active = getentityvar(self, &amp;quot;armor_active&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if(attack_type &amp;gt;= 0 &amp;amp;&amp;amp; armor_active == 1)&lt;br /&gt;
    {&lt;br /&gt;
        play_armor_response(self, attack_type);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The damage remains applied because Onpain occurs after HP processing. Replacing the pain response changes presentation and action state rather than cancelling the hit.&lt;br /&gt;
&lt;br /&gt;
== Local Variables ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Local variable&lt;br /&gt;
! Type&lt;br /&gt;
! Value&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;self&amp;lt;/code&amp;gt;&lt;br /&gt;
| Entity pointer&lt;br /&gt;
| Entity that successfully entered the native pain or grabbed selector.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;attacktype&amp;lt;/code&amp;gt;&lt;br /&gt;
| Integer&lt;br /&gt;
| Requested attack-type identifier used to choose pain. Normal damage supplies the recipient&amp;#039;s recorded last damage type. Grab handling supplies &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;reset&amp;lt;/code&amp;gt;&lt;br /&gt;
| Integer&lt;br /&gt;
| Animation reset request supplied to the pain selector. &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; allows the selected animation to restart even when already active; &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; retains an already active matching animation.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;reset&amp;lt;/code&amp;gt; local describes the request passed into animation selection. It does not report whether an animation actually restarted, because the selector may choose a fallback or retain an existing animation.&lt;br /&gt;
&lt;br /&gt;
Onpain does not provide &amp;lt;code&amp;gt;attacker&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;damage&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;drop&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;tag&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;blocked&amp;lt;/code&amp;gt;, or &amp;lt;code&amp;gt;attack_id&amp;lt;/code&amp;gt;. Projects needing that context may save it to entity variables during Ondoattack or Takedamage before reaction selection reaches Onpain.&lt;br /&gt;
&lt;br /&gt;
Assignments to event locals do not alter native state. Use entity and animation functions or property interfaces when the reaction itself must change.&lt;br /&gt;
&lt;br /&gt;
== Event Scope ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Path&lt;br /&gt;
! Onpain event&lt;br /&gt;
! Notes&lt;br /&gt;
|-&lt;br /&gt;
| Accepted standing hit that passes pain eligibility&lt;br /&gt;
| Yes&lt;br /&gt;
| Runs after the pain animation and native pain state are established.&lt;br /&gt;
|-&lt;br /&gt;
| Hit ignored by pain threshold or defense&lt;br /&gt;
| No&lt;br /&gt;
| HP damage may still occur without a visible pain reaction.&lt;br /&gt;
|-&lt;br /&gt;
| Attack with no-pain behavior&lt;br /&gt;
| No&lt;br /&gt;
| Native damage handling deliberately skips pain selection.&lt;br /&gt;
|-&lt;br /&gt;
| Recipient with pain disabled&lt;br /&gt;
| No&lt;br /&gt;
| &amp;lt;code&amp;gt;PAIN_CONFIG_PAIN_DISABLE&amp;lt;/code&amp;gt; prevents ordinary pain selection.&lt;br /&gt;
|-&lt;br /&gt;
| Frozen recipient in the ordinary damage path&lt;br /&gt;
| No&lt;br /&gt;
| Normal pain selection is skipped while frozen.&lt;br /&gt;
|-&lt;br /&gt;
| Knockdown, fall, or lethal fall reaction&lt;br /&gt;
| No&lt;br /&gt;
| These paths use fall handling and [[Onfallscript]].&lt;br /&gt;
|-&lt;br /&gt;
| Successful native block or block pain&lt;br /&gt;
| No&lt;br /&gt;
| Block reactions use blocking events and the separate block-pain selector.&lt;br /&gt;
|-&lt;br /&gt;
| Grabbed animation request&lt;br /&gt;
| Yes&lt;br /&gt;
| Uses &amp;lt;code&amp;gt;attacktype = -1&amp;lt;/code&amp;gt; and commonly &amp;lt;code&amp;gt;reset = 0&amp;lt;/code&amp;gt;. Repeated grab maintenance may invoke Onpain again.&lt;br /&gt;
|-&lt;br /&gt;
| Biker pain handling&lt;br /&gt;
| Yes&lt;br /&gt;
| The specialized biker damage path explicitly enters the native pain selector.&lt;br /&gt;
|-&lt;br /&gt;
| Direct animation change to a pain animation&lt;br /&gt;
| No&lt;br /&gt;
| Onpain belongs to the pain selector, not to the animation identifier itself.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Onpain may therefore run without a new HP change during grab maintenance, and damage may occur without Onpain when the recipient does not visibly enter pain.&lt;br /&gt;
&lt;br /&gt;
== Changing the Reaction ==&lt;br /&gt;
&lt;br /&gt;
The native pain animation and state are already active when the callback begins. Scripts may replace them with another animation, begin an attack, return the entity to idle, change movement, or transfer control to a larger creator-defined state machine.&lt;br /&gt;
&lt;br /&gt;
Replacing only the animation may leave native pain action logic active. Project helpers should set the complete action state required by the replacement. Functions such as &amp;lt;code&amp;gt;executeanimation()&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;performattack()&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;setidle()&amp;lt;/code&amp;gt; establish broader native states in addition to changing animation.&lt;br /&gt;
&lt;br /&gt;
The script return value is ignored. Returning &amp;lt;code&amp;gt;0&amp;lt;/code&amp;gt; does not cancel pain, and returning &amp;lt;code&amp;gt;1&amp;lt;/code&amp;gt; does not confirm it.&lt;br /&gt;
&lt;br /&gt;
Changing &amp;lt;code&amp;gt;lasthitc&amp;lt;/code&amp;gt; during Onpain is too late to cancel the hit. Use [[Ondoattackscript]] when the collision and all native consequences should be rejected.&lt;br /&gt;
&lt;br /&gt;
== Attack Type and Grab State ==&lt;br /&gt;
&lt;br /&gt;
For ordinary damage, compare nonnegative &amp;lt;code&amp;gt;attacktype&amp;lt;/code&amp;gt; values with named &amp;lt;code&amp;gt;ATK_*&amp;lt;/code&amp;gt; constants from &amp;lt;code&amp;gt;openborconstant()&amp;lt;/code&amp;gt;. The value identifies the requested reaction type even when OpenBOR selected a fallback pain animation.&lt;br /&gt;
&lt;br /&gt;
The special value &amp;lt;code&amp;gt;-1&amp;lt;/code&amp;gt; requests &amp;lt;code&amp;gt;ANI_GRABBED&amp;lt;/code&amp;gt;. It is not an &amp;lt;code&amp;gt;ATK_*&amp;lt;/code&amp;gt; constant and should be tested before ordinary attack-type comparisons.&lt;br /&gt;
&lt;br /&gt;
== Global Model ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;onpainscript&amp;lt;/code&amp;gt; is not automatically forwarded through a model named &amp;lt;code&amp;gt;global_model&amp;lt;/code&amp;gt;. Only the script belonging to the entity entering pain runs. Shared project-wide behavior should be placed in a common script included by participating models or called from their individual Onpain scripts.&lt;br /&gt;
&lt;br /&gt;
== Related Events ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Event&lt;br /&gt;
! Entity&lt;br /&gt;
! Relative purpose&lt;br /&gt;
|-&lt;br /&gt;
| [[Ondoattackscript]]&lt;br /&gt;
| Recipient first, then conferrer&lt;br /&gt;
| Runs before native hit resolution and may cancel all native consequences through &amp;lt;code&amp;gt;lasthitc&amp;lt;/code&amp;gt;.&lt;br /&gt;
|-&lt;br /&gt;
| [[Takedamagescript]]&lt;br /&gt;
| Damage recipient&lt;br /&gt;
| Runs after HP processing regardless of whether a standing pain animation will follow.&lt;br /&gt;
|-&lt;br /&gt;
| [[Onpainscript]]&lt;br /&gt;
| Entity entering pain or grabbed selection&lt;br /&gt;
| Runs after a valid pain animation and native pain state are established.&lt;br /&gt;
|-&lt;br /&gt;
| [[Onfallscript]]&lt;br /&gt;
| Entity entering fall&lt;br /&gt;
| Runs after a valid fall animation and fall state are established.&lt;br /&gt;
|-&lt;br /&gt;
| [[Didblockscript]]&lt;br /&gt;
| Defender&lt;br /&gt;
| Runs after a successful native block rather than ordinary pain.&lt;br /&gt;
|-&lt;br /&gt;
| [[Didhitscript]]&lt;br /&gt;
| Conferrer&lt;br /&gt;
| Runs after accepted recipient take-damage handling, including Onpain when applicable.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Pain]]&lt;br /&gt;
* [[Animation]]&lt;br /&gt;
* [[Attack Type]]&lt;br /&gt;
* [[Damage Control]]&lt;br /&gt;
* [[Blocking]]&lt;br /&gt;
* [[Takedamagescript]]&lt;br /&gt;
* [[Onfallscript]]&lt;br /&gt;
* [[Didhitscript]]&lt;br /&gt;
* [[Script Overview]]&lt;br /&gt;
&lt;br /&gt;
[[Category:Openbor]]&lt;br /&gt;
[[Category:Model]]&lt;br /&gt;
[[Category:Script]]&lt;/div&gt;</summary>
		<author><name>Dcurrent</name></author>
	</entry>
</feed>