Jump to content

Help with OnHit script for spell.


Durai

Recommended Posts

To make a long story short, I'm trying to create a spell that damages enemies with custom spells after they've been hit (by fist or weapon). Currently I have it set to Fire and Forget, Self, with an area of 30 ft. Here's what I have so far:

 

 

Scriptname AC_FireFist001 extends activemagiceffect

Spell Property FireFist Auto

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

 

Actor TargetActor = GetTargetActor()
FireFist.Cast(akAggressor, TargetActor)

 

EndEvent

 

 

The problem being that it constantly casts the script spell without ever needing to hit the target, kiling them within seconds. Can anyone help me fix this?

 

P.S. To clarify how I want it to work, it should go:

 

Cast spell > target is now affected for 60 seconds > target gets hit > script casts custom spell to damage target even more

Link to comment
Share on other sites

Well obviously. Each time the target is hit, the target is hit with a spell, causing the target to get hit with a spell, causing the target to get hit with a spell, causing the target to get hit with a spell...

 

To prevent this, add a keyword to the magiceffect of your triggered spell and use If !akSource.HasKeyword(yourkeyword) /// EndIf.

 

Also because magical attacks hit multiple times (once for each magiceffect, projectile and explosion) your triggered spell will get spammed a ton of times. To fix this, make it instead store the aggressor in a variable and then register for a single update with a 0.5 sec delay or so. Each time the event goes off, it registers itself again and only the most recent one will stick.

Link to comment
Share on other sites

Well obviously. Each time the target is hit, the target is hit with a spell, causing the target to get hit with a spell, causing the target to get hit with a spell, causing the target to get hit with a spell...

 

To prevent this, add a keyword to the magiceffect of your triggered spell and use If !akSource.HasKeyword(yourkeyword) /// EndIf.

 

Also because magical attacks hit multiple times (once for each magiceffect, projectile and explosion) your triggered spell will get spammed a ton of times. To fix this, make it instead store the aggressor in a variable and then register for a single update with a 0.5 sec delay or so. Each time the event goes off, it registers itself again and only the most recent one will stick.

Thanks for the speedy reply, much appreciated.

 

Unfortunately I'm still quite inexperienced when it comes to scripting, so I'm afraid I don't know how to use the line of script you've given me. I can make educated guesses as to how I should use a code, but without training more I usually just fumble my way to the correct code. Here's how I implemented it into my current script:

 

 

 

Spell Property FireFist Auto

Keyword Property MSFireFist Auto

 

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

Actor TargetActor = GetTargetActor()

If !akSource.HasKeyword(MSFireFist)

Else

FireFist.Cast(akAggressor, TargetActor)

EndIf

EndEvent

 

 

 

It stopped the spell from outright killing the NPC, but now it won't cast the spell at all. I know I've done something incorrectly, but I haven't a clue what that is. If you see what mistake I've made, I'd love to hear it.

Link to comment
Share on other sites

If you want to make sure that spells do not trigger the OnHit event, add the following check at the beginning of the script:

 

if(akSource as weapon)

 

Now there is no need for an OnUpdate event, a keyword, etc., because only weapons will trigger the OnHit block.

 

Should look like this:

Scriptname AC_FireFist001 extends activemagiceffect  

Spell Property FireFist Auto

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
 
    if(akSource as weapon)
        FireFist.Cast(akAggressor, self)
    endif
EndEvent
Edited by lofgren
Link to comment
Share on other sites

Just to make sure - you do have the keyword on your spell, correct?

 

Also, take a look here to get a sense of what Enai is talking about.

Oh god that code.... :wallbash:

 

I understand maybe about a quarter of what was written there. :sweat:

 

Anyway I'll have to study it more to understand exactly what I need to use for my own script. Thanks for the speedy reply, much appreciated! :thumbsup:

Link to comment
Share on other sites

 

Just to make sure - you do have the keyword on your spell, correct?

 

Also, take a look here to get a sense of what Enai is talking about.

Oh god that code.... :wallbash:

 

I understand maybe about a quarter of what was written there. :sweat:

 

Anyway I'll have to study it more to understand exactly what I need to use for my own script. Thanks for the speedy reply, much appreciated! :thumbsup:

 

Well it's not entirely what you need, it's just to sort of explain how OnHit works.

 

I'm a far better scripter than I am a magic creator, so Enai or others can probably help you a whole lot more.

 

Also, I assume you've read the Papyrus Introduction and done the Papyrus Tutorials?

Link to comment
Share on other sites

 

If you want to make sure that spells do not trigger the OnHit event, add the following check at the beginning of the script:

 

if(akSource as weapon)

 

Now there is no need for an OnUpdate event, a keyword, etc., because only weapons will trigger the OnHit block.

 

Should look like this:

Scriptname AC_FireFist001 extends activemagiceffect  

Spell Property FireFist Auto

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
 
    if(akSource as weapon)
        FireFist.Cast(akAggressor, self)
    endif
EndEvent

That actually worked out like I had envisioned it! I love when simple code gives the best results, hah! Just a quick question, is there a way to restrict the OnHit function to only respond to unarmed strikes or is defining it as weapons as narrow as it gets?

 

 

 

 

Just to make sure - you do have the keyword on your spell, correct?

 

Also, take a look here to get a sense of what Enai is talking about.

Oh god that code.... :wallbash:

 

I understand maybe about a quarter of what was written there. :sweat:

 

Anyway I'll have to study it more to understand exactly what I need to use for my own script. Thanks for the speedy reply, much appreciated! :thumbsup:

 

Well it's not entirely what you need, it's just to sort of explain how OnHit works.

 

I'm a far better scripter than I am a magic creator, so Enai or others can probably help you a whole lot more.

 

Also, I assume you've read the Papyrus Introduction and done the Papyrus Tutorials?

 

I remember doing the hello world and one of the variables and conditionals, then just winging it from there. Most scripts that i wanted to produce were relatively simple so going any further didn't seem necessary at the time. However I might pick back up where I left at some point. I can't always rely on the kindness of strangers to help get me out of a jam XD. Thanks again for your help!

Link to comment
Share on other sites

 

 

If you want to make sure that spells do not trigger the OnHit event, add the following check at the beginning of the script:

 

if(akSource as weapon)

 

Now there is no need for an OnUpdate event, a keyword, etc., because only weapons will trigger the OnHit block.

 

Should look like this:

Scriptname AC_FireFist001 extends activemagiceffect  

Spell Property FireFist Auto

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
 
    if(akSource as weapon)
        FireFist.Cast(akAggressor, self)
    endif
EndEvent

That actually worked out like I had envisioned it! I love when simple code gives the best results, hah! Just a quick question, is there a way to restrict the OnHit function to only respond to unarmed strikes or is defining it as weapons as narrow as it gets?

 

What you can do is add the following property:

 

weapon property Unarmed auto

 

Then compare akSource to it:

Scriptname AC_FireFist001 extends activemagiceffect  

Spell Property FireFist Auto
weapon property Unarmed auto

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
 
    if(akSource == Unarmed)
        FireFist.Cast(akAggressor, self)
    endif
EndEvent

NB this will conflict with some popular mods' replacement of the unarmed weapon, for example SkyRe, SPERG, other unarmed fighting mods.

 

There is probably a better way of doing it, but I just don't know it.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...