TheXXI Posted September 1 Share Posted September 1 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 More sharing options...
dylbill Posted September 2 Share Posted September 2 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 1 Link to comment Share on other sites More sharing options...
TheXXI Posted September 2 Author Share Posted September 2 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 More sharing options...
PeterMartyr Posted September 2 Share Posted September 2 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 Link to comment Share on other sites More sharing options...
TheXXI Posted September 2 Author Share Posted September 2 (edited) 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 September 2 by TheXXI Link to comment Share on other sites More sharing options...
PeterMartyr Posted September 2 Share Posted September 2 Ok here my advice, use the Sound array lose the single properties 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 If you need to access the Sound Array from another script? Move it to Quest Script Gimme Magic Effect needs to access Quest Script Other scripts need to access Quest Script to use the sounds 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 More sharing options...
Sphered Posted September 2 Share Posted September 2 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 More sharing options...
PeterMartyr Posted September 2 Share Posted September 2 @Sphered you do not know how formlist work, they do not have indexes they have nodes and iterators, your code would be as slow as... what faster lists or arrays he does not need the add or remove mechanism, so there no advantage, just a slow performance hit to your advice Link to comment Share on other sites More sharing options...
TheXXI Posted September 3 Author Share Posted September 3 15 hours ago, PeterMartyr said: Ok here my advice, use the Sound array lose the single properties 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 If you need to access the Sound Array from another script? Move it to Quest Script Gimme Magic Effect needs to access Quest Script Other scripts need to access Quest Script to use the sounds 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 More sharing options...
xkkmEl Posted September 3 Share Posted September 3 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. 1 Link to comment Share on other sites More sharing options...
Recommended Posts