Useshield
Overview
UseShield is a behaviour node (inheriting from BehaviourNode) responsible for managing shield activation and deactivation logic for an entity. It evaluates incoming threats—including direct damage, projectile fire, fire damage, and epic fear events—and transitions the entity’s state machine into a shielded state when thresholds or conditions are met. Once shielded, the node monitors conditions to determine when the shield should be lowered (i.e., when threats subside for a configured duration).
It integrates closely with the health component to assess death status and fire damage, and supports custom logic via optional callbacks (shouldshieldfn) and animation/data overrides. It is typically used in AI decision trees to enable tactical defensive postures (e.g., as seen in playable characters like Wendy or enemy behaviours like the Boss Bee).
Dependencies & Tags
- Components used:
health(accessed viaself.inst.components.health)- Reads
IsDead()andtakingfiredamage
- Reads
- Tags:
- Checks via
inst.sg:HasStateTag(...):"busy","caninterrupt","frozen","electrocute","shield","shield_end" - Pushes
"entershield"and"exitshield"events to trigger state machine transitions.
- Checks via
Properties
| Property | Type | Default | Description |
|---|---|---|---|
damageforshield | number | 100 | Minimum cumulative damage taken in a single encounter required to trigger shield. |
shieldtime | number | 2 | Seconds of cooldown elapsed after last attack before shield can end. |
hidefromprojectiles | boolean | false | If true, incoming projectiles reset or extend the shield timer. |
scareendtime | number | 0 | Timestamp after which fear-based shielding ends. Updated via "epicscare" events. |
damagetaken | number | 0 | Accumulated damage since last shield entry. Reset on entry. |
timelastattacked | number | 1 | Timestamp of the last attack. Used with shieldtime to decide when to end shielding. |
projectileincoming | boolean | false | Set true when a hostile projectile is detected (if hidefromprojectiles is true). |
dontupdatetimeonattack | boolean? | nil | If true, do not update timelastattacked on attack—instead, set it on node start. |
usecustomanims | boolean? | nil | If true, skip default "hit_shield" + "hide_loop" animation on attack during shielding. |
dontshieldforfire | boolean? | nil | If true, ignore fire damage in ShouldShield() logic. |
checkstategraph | boolean? | nil | If true, prevent shield activation during "busy" states unless "caninterrupt". |
shouldshieldfn | function? | nil | Optional custom predicate (inst) → (bool, time?) allowing per-entity control over shielding. |
Main Functions
TimeToEmerge()
- Description: Determines whether enough time has elapsed since the last attack, fear event, and any custom shield end time to exit the shield state.
- Parameters: None.
- Returns:
boolean—trueif all cooldowns have expired;falseotherwise.
ShouldShield()
- Description: Evaluates all triggers and custom logic to decide if the entity should begin or remain in a shielded state. Called before entering or while running the shield node.
- Parameters: None.
- Returns:
boolean, number?—- First return:
trueif shielding is warranted;falseotherwise. - Second return (optional): A duration to extend the shield (passed from
shouldshieldfn).
- First return:
- Logic: Returns
falseif dead, or ifcheckstategraphis enabled and the current state is"busy"without"caninterrupt". Otherwise, checks:- Damage threshold exceeded (
damagetaken > damageforshield), - Fire damage active (unless
dontshieldforfire), - Projectile incoming,
- Fear effect active (
GetTime() < scareendtime), - Or custom
shouldshieldfnreturningtrue.
- Damage threshold exceeded (
OnAttacked(attacker, damage, projectile)
- Description: Callback invoked on
"attacked","hostileprojectile","firedamage","startfiredamage", and"startelectrocute"events. Accumulates damage, updates timers, and controls shield-specific animations. - Parameters:
attacker(Instancer?): Attacking entity.damage(number?): Damage amount.projectile(boolean?): Whether the damage originated from a projectile.
- Returns:
nil. - Notes:
- If
dontupdatetimeonattackisnil/false, updatestimelastattackedand clearsshieldendtime. - Resets
damagetakenonly on entry to the shield state (inVisit()), not here. - Plays
"hit_shield"→"hide_loop"animations unlessusecustomanimsis set or the node is not in"shield"state. - Sets
projectileincoming = trueonly ifhidefromprojectilesistrueand projectile istrue.
- If
Visit()
- Description: Core
BehaviourNodemethod invoked each tick to drive state transitions. Handles entering, maintaining, and exiting the shield. - Parameters: None.
- Returns:
nil. - Logic:
- On
READY: CallsShouldShield(). Iftrue(or already in"shield"state), resetsdamagetaken, clearsprojectileincoming, optionally setsshieldendtime, updatestimelastattackedif needed, and pushes"entershield"event → sets status toRUNNING. - On
RUNNING:- Aborts to
FAILEDif"electrocute"state tag is active. - Maintains
RUNNINGif eitherTimeToEmerge()isfalseor fire damage is still active (unlessdontshieldforfire). - Otherwise, pushes
"exitshield"and sets status toSUCCESS.
- Aborts to
- On
Events & Listeners
-
Listens to:
"attacked"→self.onattackedfn"hostileprojectile"→self.onhostileprojectilefn(which callsOnAttacked(..., true))"firedamage"&"startfiredamage"→self.onfiredamagefn"startelectrocute"→self.onelectrocutefn(which forces a brain update)"epicscare"(ifhidewhenscaredistrue) →self.onepicscarefn(extendsscareendtime)
-
Pushes:
"entershield"→ Signals state machine to enter shielded state."exitshield"→ Signals state machine to exit shielded state.