Jump to content

Quest script calling functions on a magic effect script...


Recommended Posts

Is it possible and how exactly does one go about accessing the script on the magic effect from outside? I know you can do it from a magic effect script to a quest script by pointing at the quest but I'm not sure - if at all possible - how to go about doing the reverse. Can anyone shed some light on this please?

Link to comment
Share on other sites

It isn't really feasible as the magic effect script may not always be there. The best route that I could suggest would be the mod events feature added by SKSE.

 

The magic effect script would register for the mod event when the effect starts and have the event code on the script.

The quest script would send the mod event whenever it needed to.

If the mod event gets sent but the magic effect is no longer active, nothing will happen as there will be no forms with the event registered.

 

Bare bones basics:

 

 

Active magic effect script

 

Scriptname SomeMagicEffectScript Extends ActiveMagicEffect
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
  RegisterForModEvent("QuestWantsSomething","OnQuestRequest")
EndEvent
 
Event OnQuestRequest(string eventName, string strArg, float numArg, Form sender)
  ;do something
EndEvent

 

Quest script

 

;inside some other function or event
SendModEvent("QuestWantsSomething")
;optionally include a string value or float value to be passed from the sending script to the receiving script.

 

 

 

Useful reads:

RegisterForModEvent

SendModEvent - basic event with generic parameters

 

ModEvent Script - see this for customized event creation with customized parameters

Link to comment
Share on other sites

You would need to first detect the active magic effect somehow. On your magic effect script, you can fill a property on your quest with onEffectStart() and then access the functions from your quest. The magic effect script would be something like this:

 

Scriptname TM_MagicEffectB extends ActiveMagicEffect 

TM_QuestScript Property QuestScript Auto 

Event OnEffectStart(Actor akTarget, Actor akCaster)
    QuestScript.MyActiveEffect = self 
EndEvent

function MyFunction()
    
EndFunction

And the quest script like this:

 

Scriptname TM_QuestScript extends Quest 

ActiveMagicEffect Property MyActiveEffect Auto Hidden 

Event SomeEvent() 
    (MyActiveEffect as TM_MagicEffectB).MyFunction()
EndEvent
Another way to detect an active magic effect, is by use Papyrus Extender: https://www.nexusmods.com/skyrimspecialedition/mods/22854 which has the function
MagicEffect[] function GetAllActiveEffectsOnActor(Actor akActor, bool showInactive = false) global native

Which you can then cycle through to detect if your magic effect is active on the actor

Link to comment
Share on other sites

Sorry I didn't see IsharaMeradin's post. That method would be perfect for calling functions on all actors that have the magic effect. My script would only work on the most recent effect to activate. If you want to do it on a specific actor using the Papyrus Extender function may be best.

Link to comment
Share on other sites

No problem, I actually thought of another solution to use the function on multiple actors without using skse. You can use an array to store the active effects.

 

So the quest script would look something like this:

Scriptname TM_QuestScript extends Quest 

ActiveMagicEffect[] Property MyActiveEffects Auto Hidden 

Event OnInit() 
    MyActiveEffects = New ActiveMagicEffect[128]
EndEvent 

Event SomeEvent()
    Int I = 0 
    While I < 128
        If MyActiveEffects[I] != None
            (MyActiveEffects[I] as TM_MagicEffectB).MyFunction()
        Endif
        I += 1
    EndWhile
EndEvent

 

And the magic effect script would look like this:

Scriptname TM_MagicEffectB extends ActiveMagicEffect 

TM_QuestScript Property QuestScript Auto 
Formlist Property MyActiveEffects Auto

Event OnEffectStart(Actor akTarget, Actor akCaster)
    
    Int I = QuestScript.MyActiveEffects.Find(None) 
    If I > -1 
        QuestScript.MyActiveEffects[I] = self 
    Endif
EndEvent

Event OnEffectFinish(Actor akTarget, Actor akCaster) 
    Int I = QuestScript.MyActiveEffects.Find(Self) 
    QuestScript.MyActiveEffects[I] = None
EndEvent

function MyFunction()
    
EndFunction

That's only if you don't want to use SKSE. Using the mod event would be better for performance.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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