Jump to content

Help with spell scripts


Recommended Posts

If you can make do with integers (for things like counting the number of times an NPC has been hit) you're much better off using faction membership or even inventory token items. Every faction can have many ranks so you can create a HitByMyFireball faction and have your script test for faction rank. And since it's simply a faction it will be automatically cleaned up with the NPC so no need to worry about save game bloat. I would avoid those AVs. In some cases they reset whenever you reload the game.

 

There's also at least one SKSE plugin that supposedly lets you attach arbitrary data to NPCs but I've never actually tried using it.

Link to comment
Share on other sites

If you can make do with integers (for things like counting the number of times an NPC has been hit) you're much better off using faction membership or even inventory token items. Every faction can have many ranks so you can create a HitByMyFireball faction and have your script test for faction rank. And since it's simply a faction it will be automatically cleaned up with the NPC so no need to worry about save game bloat. I would avoid those AVs. In some cases they reset whenever you reload the game.

 

There's also at least one SKSE plugin that supposedly lets you attach arbitrary data to NPCs but I've never actually tried using it.

I like this approach. Especially the part about avoiding save game bloat.

 

So attaching ints to actors without conflicts or bloating is doable. That means that we can also assign more complex data, like a custom struct (does papyrus support those?) if we can have queue of structs somewhere, and use the faction rank variable as indices to access the queue. Could I attach an object script to a rock in a test cell , and use that script to hold and manage all the data?

 

Link to comment
Share on other sites

Update: Faction rank values show some weird behavior at values over 100. When increased above a value somewhere around 130 (probably 127), the actor is removed from the faction altogether.

There's a lot you can do with numbers between 0 and 127, but it falls pretty far short of an int.

Link to comment
Share on other sites

Not possible because ActiveMagicEffects are removed too quickly to track them.

I need to point out that this is not necessarily true, as you can have a 0 duration toggle-able or kept-until-dispelled effect.

 

Sadly there isn't much capability to get data between scripts. It would have been great to have public accessible variables.

 

Faction rank is a good general way for something like that. Depending on the situation you could also make use of the OnHit Event to check the projectile or spell hitting a target.

 

 

Text example:

For the firebolt explosion example you could have it check if an effect is on the target, if not apply a magic effect without duration or hit event.

The applied magic effect would start at a hit count of 1 and when the hit event is triggered with the projectile from the firebolt (which you would want to duplicate or create your own to avoid issues) would check to see if the value is greater or equal to 3, if not, +1,

 

 

Code Example:

 

Projectile:

Check for HasMagicEffect being explosion counter effect in conditions of spell. (separate effect from damage of course)
Counter Effect:
Projectile Property FireboltProjectile Auto
int HitCount = 1
event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    if akProjectile == FireboltProjectile
        HitCount += 1
        if HitCount >= 3
            Cast Explosion
            Self.Dispel()
        endIf
    endIf
EndEvent

Note: Untested and mostly psuedo code but should work once adjusted.

 

This method would work for anything triggering a hit event from a specific projectile. You could also trigger it from a certain source or actor firing it, though that has other weirdness possible. Check the page on OnHit for more info.

Edited by Himeki
Link to comment
Share on other sites

 

Not possible because ActiveMagicEffects are removed too quickly to track them.

I need to point out that this is not necessarily true, as you can have a 0 duration toggle-able or kept-until-dispelled effect.

 

And I need to point out that it is still isn't necessarily reliable.

 

OnHit isn't either but I'm not going to bother explaining why.

Edited by Terra Nova
Link to comment
Share on other sites

 

If you can make do with integers (for things like counting the number of times an NPC has been hit) you're much better off using faction membership or even inventory token items. Every faction can have many ranks so you can create a HitByMyFireball faction and have your script test for faction rank. And since it's simply a faction it will be automatically cleaned up with the NPC so no need to worry about save game bloat. I would avoid those AVs. In some cases they reset whenever you reload the game.

 

There's also at least one SKSE plugin that supposedly lets you attach arbitrary data to NPCs but I've never actually tried using it.

I like this approach. Especially the part about avoiding save game bloat.

 

So attaching ints to actors without conflicts or bloating is doable. That means that we can also assign more complex data, like a custom struct (does papyrus support those?) if we can have queue of structs somewhere, and use the faction rank variable as indices to access the queue. Could I attach an object script to a rock in a test cell , and use that script to hold and manage all the data?

 

You could create a self-starting, forever running quest, attach a script to it and then fill that quest as a property on your magic effect(s). Then, you can cast the quest to its script type and access any properties from that script in the magic effect script. Essentially, your quest script becomes a global complex data type to store your junk.

 

Then, you could setup a series of arrays in your quest script to keep track of the actors and how many times they got hit. SKSE can be used to resize arrays as needed. It's a cumbersome solution with some iteration and housekeeping, but it'll getcha there.

Link to comment
Share on other sites

Or you can use some SKSE plugins, like the extremely stable and useful PapyrusUtil that in its part Storageutil, allows you to add variables to objects (and so Actors)

And all info you edit is stored in the SKSE co-save.

High performance and low to carry about it.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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