Difference between revisions of "OnHit - ObjectReference"

From the CreationKit Wiki
Jump to navigation Jump to search
imported>Candoran2
(Seperating discussion of code from code.)
imported>OpusGlass
m (Some sections of text were improperly flagged as code.)
Line 27: Line 27:
   Debug.Trace("We were hit by " + akAggressor)
   Debug.Trace("We were hit by " + akAggressor)
EndEvent
EndEvent
</source>


<source lang="papyrus">
To avoid the hits from enchantments running the code block one must compare the ''akSource'' to the actual reference that hit the actor/object.  
To avoid the hits from enchantments running the code block one must compare the ''akSource'' to the actual reference that hit the actor/object.  
For instance, say we have a weapon with 2 enchantments called "Fire/Ice Sword." When hit with this sword the hit registers as 3 separate hits, but you have code such as:
For instance, say we have a weapon with 2 enchantments called "Fire/Ice Sword." When hit with this sword the hit registers as 3 separate hits, but you have code such as:
Line 37: Line 39:
   Variable1 -= 100
   Variable1 -= 100
EndEvent
EndEvent
</source>
   
   
This would actually subtract 300 from Variable1 since the event was called 3 times simultaneously, even though the akSource has been cast as a weapon papyrus counts the hit from the enchantments as "weapons" too so the enchantments are reference as (akSource as Weapon) as well. So the solution is to be more explicit.
This would actually subtract 300 from Variable1 since the event was called 3 times simultaneously, even though the akSource has been cast as a weapon papyrus counts the hit from the enchantments as "weapons" too so the enchantments are reference as (akSource as Weapon) as well. So the solution is to be more explicit.


<source lang="papyrus">
Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
   bool abBashAttack, bool abHitBlocked)
   bool abBashAttack, bool abHitBlocked)
Line 73: Line 77:


EndEvent
EndEvent
</source>


With this code the Actor/Object with the OnHitEvent script could be hit by 5 different weapons but the onhit event will only fire when the weapon has ''TheEnchantment'' and it will only fire once.
With this code the Actor/Object with the OnHitEvent script could be hit by 5 different weapons but the onhit event will only fire when the weapon has ''TheEnchantment'' and it will only fire once.

Revision as of 11:12, 18 October 2018

Member of: ObjectReference Script

Event called when the object reference is hit by a weapon or projectile.

Syntax

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
  bool abBashAttack, bool abHitBlocked)

Parameters

  • akAggressor: The ObjectReference that attacked this reference.
  • akSource: The Weapon, Spell, Explosion, Ingredient, Potion, or Enchantment that hit this reference.
  • akProjectile: The Projectile that hit this reference.
  • abPowerAttack: Was the hit caused by a power attack?
  • abSneakAttack: Was the hit caused by a sneak attack?
  • abBashAttack: Was the hit caused by a bash attack?
  • abHitBlocked: Was the hit blocked?

Examples

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
  bool abBashAttack, bool abHitBlocked)
  Debug.Trace("We were hit by " + akAggressor)
EndEvent
To avoid the hits from enchantments running the code block one must compare the ''akSource'' to the actual reference that hit the actor/object. 
For instance, say we have a weapon with 2 enchantments called "Fire/Ice Sword." When hit with this sword the hit registers as 3 separate hits, but you have code such as:

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
  bool abBashAttack, bool abHitBlocked)

if(akSource as Weapon)
  Variable1 -= 100
EndEvent

This would actually subtract 300 from Variable1 since the event was called 3 times simultaneously, even though the akSource has been cast as a weapon papyrus counts the hit from the enchantments as "weapons" too so the enchantments are reference as (akSource as Weapon) as well. So the solution is to be more explicit.

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
  bool abBashAttack, bool abHitBlocked)

Form RightHandSword = akAggressor.GetEquippedWeapon(0); this gets the sword that the enemy had in their right hand and stores it as an object variable

if((akSource as weapon) == RightHandSword

;do code stuff

EndEvent

This will still call the event 3 times, but the code will only fire once when (akSource as weapon) == RightHandSword

  • 1st hit: Sword: (akSource as weapon) == RightHandSword - fires code
  • 2nd hit: Enchant1: (akSource as weapon) == SomeEnchant1 - nothing happens
  • 3rd hit: Enchant2: (akSource as weapon) == SomeEnchant2 - nothing happens

If you had the exact same script but only want the code to run when the actor/object that has the script with the OnHit Event is hit with a certain enchantment, regardless of the sword then:


Enchantment Property ''TheEnchantment'' Auto

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
  bool abBashAttack, bool abHitBlocked)

if((akSource as weapon) == ''TheEnchantment''

;do code stuff

EndEvent

With this code the Actor/Object with the OnHitEvent script could be hit by 5 different weapons but the onhit event will only fire when the weapon has TheEnchantment and it will only fire once.


</source>

Notes

akSource and akProjectile can be None under various circumstances:

  • If specifying akSource, for example as a Weapon, akSource must be cast to the form that corresponds to the type. For instance, if(akSource as Weapon)...akSource = Weapon will yield a compiler error.
  • This reference is an Actor:
    • akSource can be None if hit by a projectile attack where the projectile was not fired by a weapon or spell
    • akSource can be None if hit by a bash attack from a carried light object (e.g., a torch)
    • akProjectile can be None if hit by a melee attack.
  • This reference is not an Actor:
    • akSource can be None if hit by a projectile attack where the projectile was not fired by a weapon (for example, a magic spell with a projectile component).
    • akProjectile can be None if hit by a melee attack.

Also, if this reference is an Actor and the projectile was caused by a weapon enchant, the enchanted weapon will be in akSource.

  • This event is called multiple times when akSource has associated magic effects. If a sword has an enchantment with 2 effects, OnHit will be called 3 times - once for the physical damage of the sword and once for each magic effect. In all cases, akSource is the sword and not the enchantment. This also applies to spells (one hit for the spell projectile, and one for each associated magic effect).

See Also