Jump to content

[LE] Scripting Help - Calling Properties Between Scripts


Myst42

Recommended Posts

Anybody knows how to do this?

 

I have a "ScriptA" ActiveMagicEffect script, with a "Caster" Actor property that is kind of dynamic since the caster can be anyone who casts the spell.

Then I have a "ScriptB" ObjectReference script that needs to know who the Caster in script A is

 

How do I do this?

I can't for the life of me make "GetLinkedRef" function to work, compiler tells me every single iteration of it I've tried is wrong.

 

Link to comment
Share on other sites

You would want something like this for your MGE script (note, this is pseudocode since I'm not at my main computer):

ObjectReference Property MyObj Auto
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
   (MyObj As YourScriptNameHere).PropertyName = akCaster
endEvent
Edited by Reneer
Link to comment
Share on other sites

Having the property on the magic effect would cause your objectreference to pull invalid data should the magic effect cease to exist.

 

Here is another solution:

 

 

Script B:

ScriptName ScriptB Extends ObjectReference
 
Actor Property TheCaster Auto Hidden
;whatever else needed

Script A:

ScriptName ScriptA Extends ActiveMagicEffect
 
ScriptB Property SB Auto
;assign correct objectreference instance containing ScriptB that you wish to use. CK should give a list of appropriate objects
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
  SB.TheCaster = akCaster
  ;whatever else needed
EndEvent

 

 

With the actor property on the objectreference, it can be filled by the magic effect and remain filled even after the magic effect ends and ceases to exist.

 

Even with this, depending upon how and when you wish your script to function, it may be better to utilize a quest script to hold the property.

I can see the following as viable:

 

 

Script C:

Scriptname ScriptC Extends Quest
 
Actor Property TheCaster Auto Hidden

Script B:

ScriptName ScriptB Extends ActiveMagicEffect
 
ScriptC Property SC Auto
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
  SC.TheCaster = akCaster
  ;other stuff
EndEvent

Script A:

ScriptName ScriptA Extends ObjectReference
 
ScriptC Property SC Auto
 
;inside some function or event
  Actor MagicGuy = SC.TheCaster
;do other stuff

 

 

 

On the CK wiki the following discusses how to do this in regards to functions. https://www.creationkit.com/index.php?title=Function_Reference#Accessing_Functions_From_Other_Scripts

The process is the same only substituting property variables in place of functions.

Link to comment
Share on other sites

 

 

 

 

 

 

Ah. Thank you all very much.

I think now I get the mechanics of calling properties between scripts

It's really just a matter of "OtherScriptCall.RetrievedProperty right"?

Previous inclusion of the other script as a property itself ofc ("OtherScript'sRealName Property OtherScriptCall Auto")

Curiously, I've been calling functions just like that for a while, but functions use the () on their name so I didn't know the name was enough to get the property

 

Well, the compiling worked

Did the the swap thing, so now the magic effect fills the property on the object reference script instead

 

Found myself with another issue though

The magic effect I was using is strange since it's delivery is "target location" instead of an NPC or something, also the casting is type "Voice"

As a consequence, it generates no events

Been struggling with such thing for a while, I'm just finding out "OnEffectStart" needs to always hit something to exist

Some other issues I had with it relate to wanting a spell to generate a script effect even if the projectile hit no one.

 

As this thing itself proves, a placed object/explosion can call scripts from the ground, but I still have no idea how to make it know who the caster of the spell that placed them was.

Edited by Myst42
Link to comment
Share on other sites

Having the property on the magic effect would cause your objectreference to pull invalid data should the magic effect cease to exist.

No, it won't. Having the ScriptB Objectreference property in the ScriptA ActiveMagicEffect script will have no effect upon the ScriptB Objectreference script. There is no "invalid data." ScriptB won't magically lose the already-set property value when ScriptA's magic effect finishes.

Edited by Reneer
Link to comment
Share on other sites

You can skip the property and any issues it may or may not create due to persistence, timing, etc.

 

Create a function on the object reference script that has an actor parameter and pass in the akCaster.

Example:

 

 

ObjectReference Script

Actor MagicGuyLocalVar ;use this local variable throughout the script
Function WhoIsTheCaster(Actor MagicGuy)
  MagicGuyLocalVar = MagicGuy
EndFunction

ActiveMagicEffect Script

ObjectReferenceScript Property ORS Auto
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
  ORS.WhoIsTheCaster(akCaster)
EndEvent

 

 

 

But that doesn't solve the new issue of not getting any events to fire on the magic effect in question...

 

 

Link to comment
Share on other sites

Regarding your issue of not being able to get the caster from the magic effect due to its type. If you can create one of those "cloak ability" spells that can reach out and fill quest aliases with targets that match the targets of the magic effect, apply a script to those aliases using the OnHit event. Listen for the projectile from the magic effect and get the "caster" that way by using the akAgressor parameter.

Link to comment
Share on other sites

Myst42 wrote: "Been struggling with such thing for a while, I'm just finding out "OnEffectStart" needs to always hit something to exist"
That is impossible. Since the event "OnEffectStart" is called, it ends always with commandline "endevent".

The only way to hold alive the event "OnEffectStart" is using a while loop inside.

Myst42 wrote: "As this thing itself proves, a placed object/explosion can call scripts from the ground, but I still have no idea how to make it know who the caster of the spell that placed them was."

TestEffectScript

 

Scriptname TestEffectScript extends ActiveMagicEffect
{ReDragon 2018}
; https://forums.nexusmods.com/index.php?/topic/7137296-scripting-help-calling-properties-between-scripts/

  Quest PROPERTY myQuest auto            ; the quest you have created, fill with CK

; -- EVENTs --

;EVENT OnInit()
    ; this event will probably never be called here
;ENDEVENT


EVENT OnEffectStart(Actor akTarget, Actor akCaster)
; received when this effect is first started (OnInit may not have been run yet!)

    Debug.Trace("OnEffectStart() - Target = " +akTarget+ ", Caster = " +akCaster+ "  " +self)

; as IsharaMeradin wrote:
    (myQuest as TestQuestScript).myF_GetCasterFromEffect(akCaster)
ENDEVENT


EVENT OnEffectFinish(Actor akTarget, Actor akCaster)
; received when this effect is finished (effect may already be deleted, calling functions on this effect will fail)

    Debug.Trace("OnEffectFinish() - Target = " +akTarget+ ", Caster = " +akCaster+ "  " +self)

IF ( !akTarget )
; https://www.creationkit.com/index.php?title=GetTargetActor_-_ActiveMagicEffect
    Debug.Trace("OnEffectFinish() - Target was " +self.GetTargetActor())              ; The Actor this active effect is applied to.
ENDIF

IF ( !akCaster )
; https://www.creationkit.com/index.php?title=GetCasterActor_-_ActiveMagicEffect
    Debug.Trace("OnEffectFinish() - Caster was " +self.GetCasterActor())            ; The Actor that cast the spell this effect is from.
ENDIF
ENDEVENT

 

TestQuestScript

 

Scriptname TestQuestScript extends Quest
{ReDragon 2018}

  FormList PROPERTY actorList auto Hidden        ; empty list on quest start
 
  Bool bBusy    ; [default=False]
  Int  iCount    ; [default=0]


; -- EVENTs -- 3

EVENT OnInit()
    RegisterForSingleUpdate(0.1)                ; start registration
ENDEVENT


EVENT OnUpdate()
    IF (iCount > 0) and (!bBusy)
        RegisterForSingleUpdateGameTime(0.0)
    ENDIF

    IF (self as Quest)
        RegisterForSingleUpdate(1.0)            ; update chain every second
    ENDIF
ENDEVENT


EVENT OnUpdateGameTime()
    bBusy = TRUE
;    --------
    WHILE ( actorList.GetSize() )                        ; as long as the list is filled
        form fm = actorList.GetAt(0)
        actor aRef = fm as Form
        IF ( aRef )
            ; Do what you want here with the actor!
        ENDIF

        myF_UpdateList(fm, False)                ; ***
    ENDWHILE
;    --------
    bBusy = False
ENDEVENT


; -- FUNCTIONs -- 2

;------------------------------------------
FUNCTION myF_UpdateList(Form fm, Bool bAdd)  ; formlist action inside is thread safe
;------------------------------------------
; FormLists cannot contain duplicate entries.
; Using AddForm(...) with a form that is already in the list will not add a second copy to the list.

IF ( bAdd )
    actorList.AddForm(fm)        ; https://www.creationkit.com/index.php?title=AddForm_-_FormList
    iCount = iCount + 1
ELSE
    actorList.RemoveAddedForm(fm)
    iCount = iCount - 1
ENDIF
ENDFUNCTION


;-----------------------------------------------
FUNCTION myF_GetCasterFromEffect(Actor akCaster)
;-----------------------------------------------
    myF_UpdateList(akCaster as Form, TRUE)        ; ***
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

Well, thanks again for the help on this. I did learn some useful tricks.

 

Anyway, the goal was to set up the bases for a teleport blink effect that someday NPCs could use.

Basically, it throws a projectile that spawns a marker that calls the player to it's location.

Had I succeeded, the marker would call the caster of the spell Instead of the player all the time.

But looking at this it looks like way more trouble than I can get involved right now for so little.

 

It's not really that important, since it was just a thought. So I'm dropping it.

 

Finally being able to call and set properties between scripts was priceless though.

Link to comment
Share on other sites

  • Recently Browsing   0 members

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