Jump to content

Is it possible to logically split the code into several separate scripts and call the function of one script from another?


Recommended Posts

Is it possible to logically split the code into several separate scripts and call the function of one script from another? In my mod, a magic effect with a script hangs on the player, in this script I would like to call functions from another script. I suppose it is possible to create a quest and put a script in it, but is it good in terms of optimization? And if I need several scripts, do I need to create several quests and keep them active? What other options could there be?

Link to comment
Share on other sites

Short answer, yes, this is possible. I'd need more specifics though to be able to give better advice though. One trick I like to do with magic effects is to put two scripts on the magic effect. One that extends ActiveMagicEffect and one that extends MagicEffect. ActiveMagicEffect is a new script object that is created every time the effect starts while the MagicEffect is seperate and sits on the base object. It's similar to say having 2 scripts on a misc object. One that extends MiscObject and one that extends ObjectReference. 

Example, 2 scripts attached to the magic effect form in the creation kit. 

First script: 

scriptname TM_MagicEffectScript extends MagicEffect
 
Function SomeFunction()
 
EndFunction

Second script:

Scriptname TM_ActiveMagicEffectScript extends ActiveMagicEffect
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
    ;get the TM_MagicEffectScript attached to this activeMagicEffect's baseObject (which is a magicEffect form)
    TM_MagicEffectScript scriptRef = GetBaseObject() as TM_MagicEffectScript
 
    ;if the TM_MagicEffectScript ref was found
    if scriptRef
        scriptRef.SomeFunction()
    Endif
EndEvent
  • Like 1
Link to comment
Share on other sites

5 hours ago, dylbill said:

Short answer, yes, this is possible. I'd need more specifics though to be able to give better advice though. One trick I like to do with magic effects is to put two scripts on the magic effect. One that extends ActiveMagicEffect and one that extends MagicEffect. ActiveMagicEffect is a new script object that is created every time the effect starts while the MagicEffect is seperate and sits on the base object. It's similar to say having 2 scripts on a misc object. One that extends MiscObject and one that extends ObjectReference. 

Example, 2 scripts attached to the magic effect form in the creation kit. 

First script: 

scriptname TM_MagicEffectScript extends MagicEffect
 
Function SomeFunction()
 
EndFunction

Second script:

Scriptname TM_ActiveMagicEffectScript extends ActiveMagicEffect
 
Event OnEffectStart(Actor akTarget, Actor akCaster)
    ;get the TM_MagicEffectScript attached to this activeMagicEffect's baseObject (which is a magicEffect form)
    TM_MagicEffectScript scriptRef = GetBaseObject() as TM_MagicEffectScript
 
    ;if the TM_MagicEffectScript ref was found
    if scriptRef
        scriptRef.SomeFunction()
    Endif
EndEvent

I want to create something like player comments, the comments themselves are audio files.

An example of what I have:

Scriptname TXXIActiveCommentsScript extends ActiveMagicEffect  

function OnEffectStart(Actor akTarget, Actor akCaster)
	LocChangeSounds = new Sound[8]
	LocChangeSounds[0] = LocChangeSound01
	LocChangeSounds[1] = LocChangeSound02
	LocChangeSounds[2] = LocChangeSound03
	
	self.RegisterForTrackedStatsEvent()
endFunction

function OnLocationChange(Location akOldLoc, Location akNewLoc)
	;Debug.Notification("OnLocationChange")
	LocationChangeSounds[Utility.RandomInt(0, 2)].Play(Game.GetPlayer())
endFunction

Sound Property LocChangeSound01  Auto  
Sound Property LocChangeSound02  Auto  
Sound Property LocChangeSound03  Auto  

Sound[] LocChangeSounds

Depending on various events and checks, different sounds will be played, I would like to put the creation and work with sound in a separate script.

Link to comment
Share on other sites

59 minutes ago, PeterMartyr said:

LOL it is good practice to do so... please google

  • coupling and cohesion
  • separations of concerns

so you need a reason, just do not do it for doing It sake, that is pointless and not the mark of good code

I want to create more than 80 Sound Property. Do you think it's better to leave all this in one script?

Edited by TheXXI
Link to comment
Share on other sites

Ok here my advice,

  1. use the Sound array lose the single properties
  2. fill the array in the creation kit and if you DO NOT need to access it from another script? keep it in the magic effect
  3. If you need to access the Sound Array from another script? Move it to Quest Script
    1. Gimme Magic Effect needs to access Quest Script
    2. Other scripts need to access Quest Script to use the  sounds
  4. you seem to have a good handle on what your doing

So your Requirements dictate what you do,

BTW the only way you can access an Array in Magic Effect with another Script is a SKSE Mod Event, but only while it is active, so having the array in a Quest Script is more versatile, but I think you already knew or where starting to see it 😁😁👍🏽👍🏽

Just in case

Scriptname TXXIMainQuestScript extends Quest 

Sound[] Property LocChangeSounds auto

and

Scriptname TXXIActiveEffectsScript extends ActiveMagicEffect

TXXIMainQuestScript Property ScrMain auto

function OnLocationChange(Location akOldLoc, Location akNewLoc)
	;Debug.Notification("OnLocationChange")
	ScrMain.LocationChangeSounds[Utility.RandomInt(0, 2)].Play(Game.GetPlayer())
endFunction

you do not even need a function, you can access an array directly in a Quest Script from Magic Effect like so

 

Link to comment
Share on other sites

I'd use a formlist as our property instead. Add tons of sound files to it, and just point to it when wanted

(OurFormlist.GetAt(Utility.RandomInt(0,OurFormlist.GetSize() - 1)) as Sound).Play(Whoever)

Way easier to add/remove sounds to this list than to mess with a property array

Link to comment
Share on other sites

15 hours ago, PeterMartyr said:

Ok here my advice,

  1. use the Sound array lose the single properties
  2. fill the array in the creation kit and if you DO NOT need to access it from another script? keep it in the magic effect
  3. If you need to access the Sound Array from another script? Move it to Quest Script
    1. Gimme Magic Effect needs to access Quest Script
    2. Other scripts need to access Quest Script to use the  sounds
  4. you seem to have a good handle on what your doing

So your Requirements dictate what you do,

BTW the only way you can access an Array in Magic Effect with another Script is a SKSE Mod Event, but only while it is active, so having the array in a Quest Script is more versatile, but I think you already knew or where starting to see it 😁😁👍🏽👍🏽

Just in case

Scriptname TXXIMainQuestScript extends Quest 

Sound[] Property LocChangeSounds auto

and

Scriptname TXXIActiveEffectsScript extends ActiveMagicEffect

TXXIMainQuestScript Property ScrMain auto

function OnLocationChange(Location akOldLoc, Location akNewLoc)
 ;Debug.Notification("OnLocationChange")
 ScrMain.LocationChangeSounds[Utility.RandomInt(0, 2)].Play(Game.GetPlayer())
endFunction

you do not even need a function, you can access an array directly in a Quest Script from Magic Effect like so

 

I don't understand if I actually need to split the code. I'm going to refer to the script where I declared the sounds from just one magic effect script. Before that, I had experience working with other languages and frameworks, where all the code is divided into files, and when building everything is assembled into one file, I wanted to transfer similar logic to papyrus, but now it seems to me that I am doing the wrong thing.

Link to comment
Share on other sites

2 hours ago, TheXXI said:

I don't understand if I actually need to split the code. I'm going to refer to the script where I declared the sounds from just one magic effect script. Before that, I had experience working with other languages and frameworks, where all the code is divided into files, and when building everything is assembled into one file, I wanted to transfer similar logic to papyrus, but now it seems to me that I am doing the wrong thing.

You worry too much.  If it helps you read and/or maintain the code, it's a good thing.

Consider as well:

  • Properties on ActiveMagicEffect scripts are filled by the game engine each time the spell is cast.  A new array will be allocated and initialized every time the spell starts, incurring a performance hit.  But with such a small array, who cares.
  • Properties on Quest scripts are filled when the game starts, and won't be refreshed mid-game if you need to add/remove sounds.  Perhaps a minor inconvenience while debugging.
  • Multiple magic effect instances referring to a central quest could cause a bottle neck, as they will need to acquire a papyrus lock on the quest when referring to the shared property.  Overly concentrating code to refer to the same quest can degrade performance, though I seriously doubt this will be an issue in this case.
  • Like 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

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