Jump to content

[LE] Limitations of OnEffectStart in a weapon enchantment effect


kingharvest

Recommended Posts

Is there any documentation on what you can/can't do from inside OnEffectStart for a weapon enchantment effect? I always assumed it was the same as from any spell effect, but now I've found that Actor.DispelSpell() consistently doesn't work there. Some experiments I ran:

 

Setup:

- SpellA has a single effect, EffectA.

e: For clarity here, SpellA was cast by the player on the player. EffectA is therefore an ActiveMagicEffect on the player.

- SpellB is FF/self, with script attached that prints debug message and then calls "PlayerRef.DispelSpell(SpellA)".

- e: Important note is that the enchanted weapon is a bound weapon, and SpellA is the spell that adds the bound weapon effect. See my subsequent posts for more information.

 

Experiment 1.

- Attach enchantment to weapon, enchantment effect has a script attached, script prints debug message and then calls "PlayerRef.DispelSpell(SpellA)".

- Hit something with weapon.

- Debug message prints

- EffectA effect is NOT dispelled from player.

 

Experiment 2.

- Cast SpellB.

- Debug message prints.

- EffectA effect IS dispelled from player.

 

Experiment 3.

- Attach enchantment to weapon, enchantment effect has a script attached, script prints debug message and then calls "SpellB.Cast(PlayerRef as ObjectReference, none)".

- Hit something with weapon.

- Debug message prints (from enchantment effect).

- Another debug message prints (from SpellB effect).

- Bar effect is NOT dispelled from player.

 

It seems somehow like DispelSpell() only works if the "root" event is the player casting a spell, or that it specifically doesn't work if the "root" event is a weapon hitting? Does this make any sense given the Skyrim script virtual machine, or how callbacks work?

 

If solid documentation of this stuff exists then please link me because I'm just doing trial and error to see what's possible and it really sucks :sad:

Link to comment
Share on other sites

From time to time its a good idea to go a step back and read the wiki notations. https://www.creationkit.com/index.php?title=DispelSpell_-_Actor

An actor is not an objectReference, that means any spell effect made to a weapon, shield or similiar item is applied to an objectReference.

That cannot be removed by using DispelSpell() function.

 

You wrote: "It seems somehow like DispelSpell() only works if the "root" event is the player casting a spell"

The player is an actor (like every NPC) and spellB has an effect that is using a script. The spell is of type FF and his target is self as you wrote.


You should use the Dispel() function instead.

 

You wrote: "I'm just doing trial and error to see what's possible and .."

Yes that is the way many people make a Skyrim mod.

Edited by ReDragon2013
Link to comment
Share on other sites

From time to time its a good idea to go a step back and read the wiki notations. https://www.creationkit.com/index.php?title=DispelSpell_-_Actor

That's definitely good advice! As it would happen, in this case I had the same idea and read everything related to this on the Creation Kit wiki several times while working through the problem myself :)

 

An actor is not an objectReference, that means any spell effect made to a weapon, shield or similiar item is applied to an objectReference.

That cannot be removed by using DispelSpell() function.

That's a good point, and in fact I hadn't even thought of that. In this case, that doesn't help us though, because the spell we are trying to dispel ("SpellA" with effect "EffectA") was cast by the player on itself. In other words, SpellA is affecting the player, an Actor. I'll edit my OP to make it clear whom is affected by SpellA.

 

You wrote: "I'm just doing trial and error to see what's possible and .."

Yes that is the way many people make a Skyrim mod.

 

For anyone who prefers that, no knock to them. I think the reasons why I'd prefer well-defined behavior are pretty obvious/uncontroversial.

Link to comment
Share on other sites

Update:

 

After testing all sorts of crazy alternatives, including:

1. Invoking Dispel() from the ActiveMagicEffect

2. RegisterForSingleUpdate() and then dispelling in OnUpdate

3. Using a quest script fragment to dispel triggered by a SetStage in the OnEffectStart

4. Having another ActiveMagicEffect poll global state in a RegisterForSingleUpdate loop and dispel in OnUpdate.

 

I accidentally figured out what was causing this behavior. The common theme in the above experiments (and more) was that dispelling a bound weapon effect from the player, while the player is in an attack animation, fails. The reason that dispelling from a separate spell (SpellB in my OP) works is that when you cast the separate spell you can't also be attacking with the bound weapon!

 

Alternative "4." above works, but only if it gets a chance to run OnUpdate when the player is not in an attack animation. If the player continuously does non-power swings then the dispel will never succeed! To work around that I added a DisablePlayerControls to the code that dispels the effect, which then re-enables controls once the effect is successfully dispelled, and voila it works every time.

 

I hope this helps someone in the future who comes up against this issue with dispelling bound weapons.

Link to comment
Share on other sites

You wrote: "common theme in the above experiments (and more) was that dispelling a bound weapon effect from the player"

Unfortunately its the first time you posted "bound weapon effect". Before and thread headline as well you wrote "weapon enchantment effect", which is not the same imho.

I am glad to see you got a way to solve your issue and yes the way is always "trial and error".

 

About your approach of polling OnUpdate() event to get the right time for "player is not in attack animation".

I would prefer a player ReferenceAlias script with using RegisterForAnimationEvent(self.GetReference(), "PowerAttackStop") to catch the OnAnimationEvent() event for this animation.

As a sample I took "PowerAttackStop", but is not confirmed. Others can be found here: https://www.creationkit.com/index.php?title=Animation_Events

Edited by ReDragon2013
Link to comment
Share on other sites

You wrote: "common theme in the above experiments (and more) was that dispelling a bound weapon effect from the player"

 

Unfortunately its the first time you posted "bound weapon effect". Before and thread headline as well you wrote "weapon enchantment effect", which is not the same imho.

I am glad to see you got a way to solve your issue and yes the way is always "trial and error".

 

About your approach of polling OnUpdate() event to get the right time for "player is not in attack animation".

I would prefer a player ReferenceAlias script with using RegisterForAnimationEvent(self.GetReference(), "PowerAttackStop") to catch the OnAnimationEvent() event for this animation.

As a sample I took "PowerAttackStop", but is not confirmed. Others can be found here: https://www.creationkit.com/index.php?title=Animation_Events

Good point. I edited the OP but I don't seem to be able to change the thread title. I've found threads on these forums from Google searches that matched on post bodies so hopefully it's still useful as a reference for someone searching for information on this topic.

 

The animation event idea is interesting, thanks!

Link to comment
Share on other sites

Indeed, having the ActiveMagicEffect of the bound weapon spell register for "attackStop" on the player gets us a callback at the exact right time (for both regular and power attacks) to dispel the spell! Thanks again for that great suggestion. I haven't done so yet but I also need to pick an earlier event in the attack animation to check for "should I lock controls to ensure a future attackStop event?" so that the player doesn't accidentally prevent the dispel from happening by spamming attacks.

 

I also found that registering for animations is a very useful way to get sheathe/draw/equip events for the player, especially since Skyrim doesn't have RegisterForRemoteEvent like Fo4 does :smile:

 

e: I found an even easier way to forcibly dispel a bound weapon. You can interrupt an attack by disabling player controls and then immediately re-enabling them. Once the attack is interrupted you can catch the "sheatheWeapon" animation event and immediately dispel. Much cleaner.

 

On a related note, there is a quirk to bound weapon spells where the "sheathe to dispel" mechanism doesn't work if the spell is cast via script. A good illustration of this is to use any of the "Ocato's" spells from Enai's Apocalypse or Odin, and store Bound Sword in it. When it triggers it will summon a bound sword to the right hand and an invisible weapon to the left hand, and sheathing won't dispel the bound sword spell. You can fix this behavior in your own bound weapon spell by catching sheath/equip animation events and manually dispelling the effect, similar to what I was trying to do above.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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