qwertypol012 Posted February 10, 2019 Share Posted February 10, 2019 (edited) I have a script which extends ActiveMagicEffect. The name is "qlRevertFormScript". This script is attached to a MGEF, which then casted from a spell and works to the player (ie. self casted). This script calls a function from another script, ie. "qlTransformScript". qlTransformScript is attached to 2 other MGEFs and both of them also self casted (casted to the player). The function to call from qlTransformScript is RevertForm(Actor player). I want to call this function from qlRevertFormScript. I've tried to google and followed some guidances on how to call a script's function from another script and if there are more than 1 instance using the same script, but still no luck. The script i made just won't compile. So i want to ask help for anyone here on how to make it work. Here are the relevant variables and infos for qlRevertFormScript: BerserkArmorBeastT (1st MGEF which qlTransformScript is attached to)BerserkArmorBeastTDanger (2nd MGEF which qlTransformScript is attached to)qlTransformScript (the script which contains the function i want to call from qlRevertFormScript)RevertForm(Actor player) (the function to be called) What i want to do is check if the player has either BerserkArmorBeastT or BerserkArmorBeastTDanger, and if he/she has then call the function. (pretty simple right? but i failed miserably :sweat: )I'm using event OnEffectStart(Actor akTarget, Actor akCaster) which the function is called inside it. If there's any additional infos needed, just tell me then i'll fill it. Thanks in advance :smile: Edited February 10, 2019 by qwertypol012 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted February 10, 2019 Share Posted February 10, 2019 (edited) Remember you posted the scripts https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ The way you go is impossible! You cannot call to functions in "ActiveMagicEffectScript" scripts. Store functions in a quest script to call them with cross scripting from AES scripts or any other type. qlBerserk_TransformScript Scriptname qlBerserk_TransformScript extends ActiveMagicEffect {Berserker Armor transformation} ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ Quest PROPERTY myQuest auto ; added here to reach outsourced functions Armor PROPERTY ArmorBerserkerCuirass auto ; body Armor PROPERTY ArmorBerserkerBoots auto ; legs Idle PROPERTY IdleVampireLordTransformation auto Explosion PROPERTY FXVampChangeExplosion auto Bool bRemoveGhost ;Bool abIsGhost ; -- EVENTs -- 3 EVENT OnEffectStart(Actor akTarget, Actor akCaster) IF (akTarget == Game.GetPlayer()) ELSE self.Dispel() RETURN ; - STOP - /0 failsafe, player is not the target ENDIF ;--------------------- IF akTarget.IsEquipped(ArmorBerserkerCuirass) && akTarget.IsEquipped(ArmorBerserkerBoots) ELSE self.Dispel() RETURN ; - STOP - /1 failsafe, not equipped desired armor ENDIF ;--------------------- IF akTarget.IsGhost() bRemoveGhost = False ; x = 0 as Bool ELSE bRemoveGhost = TRUE ; x = 1 as Bool akTarget.GetActorBase().SetInvulnerable() akTarget.SetGhost() ENDIF ; if abIsGhost == false ; akTarget.SetGhost() ; endif RegisterForAnimationEvent(akTarget as ObjectReference, "SetRace") akTarget.PlayIdle(IdleVampireLordTransformation) akTarget.RestoreActorValue("health", 5000) Utility.Wait(10.0) TransformIfNecessary(akTarget) (myQuest as qlBerserk_QuestScript).MakeForm(akTarget) ; external script function call ENDEVENT EVENT OnEffectFinish(Actor akTarget, Actor akCaster) (myQuest as qlBerserk_QuestScript).RevertForm(akTarget) ; external script function call ENDEVENT EVENT OnAnimationEvent(ObjectReference akSource, string asEventName) ;; Debug.Trace("VAMPIRE: Getting anim event -- " + akSource + " " + asEventName) IF (asEventName == "SetRace") TransformIfNecessary(akSource as Actor) ENDIF ENDEVENT ; -- FUNCTION -- ;------------------------------------------ FUNCTION TransformIfNecessary(Actor player) ;------------------------------------------ IF ( player ) ELSE RETURN ; - STOP - invalid parameter ENDIF ;--------------------- UnRegisterForAnimationEvent(player as ObjectReference, "SetRace") player.PlaceAtMe(FXVampChangeExplosion) ; place explosion now IF ( bRemoveGhost ) player.GetActorBase().SetInvulnerable(False) player.SetGhost(False) ENDIF ; if abIsGhost == true ; akTarget.SetGhost(false) ;it is possible that actor will lose ghost status even if his status is ghost by default ; endif ENDFUNCTION qlBerserk_QuestScript Scriptname qlBerserk_QuestScript extends Quest Conditional ; https://forums.nexusmods.com/index.php?/topic/7387716-help-to-make-this-script-to-compile-successfully/ ;; ; other implementations and code here ; https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/ ;; ; ########################################################### ; next was moved to here from "qlBerserk_TransformScript.psc" ; MAKE SURE next properties exist in this script ONCE only !! ; ########################################################### Spell PROPERTY BerserkerArmorBeastChange auto Spell PROPERTY BerserkerArmorRevertForm auto ;Idle PROPERTY IdleVampireLordTransformation auto ;Explosion PROPERTY FXVampChangeExplosion auto EffectShader PROPERTY Deintegrate auto ; desintegration Armor PROPERTY ArmorBerserkSHelmet auto ; head Armor PROPERTY ArmorBerserkWHelmet auto Armor PROPERTY ArmorBerserkerCuirass auto ; body Armor PROPERTY ArmorBerserkerWCuirass auto Armor PROPERTY ArmorBerserkerWCuirass2 auto Armor PROPERTY ArmorBerserkerGauntlets auto ; hands Armor PROPERTY ArmorBerserkerGauntlets2 auto Armor PROPERTY ArmorBerserkerBoots auto ; legs Armor PROPERTY ArmorBerserkerWBoots auto Armor PROPERTY ArmorBerserkerWBoots2 auto Actor PROPERTY PlayerEquipmentBrsk auto ;------------------------------ FUNCTION MakeForm(Actor player) ; outsourced code from OnEffectStart() ;------------------------------ IF ( player ) ELSE RETURN ; - STOP - invalid parameter ENDIF ;--------------------- ; if (akTarget.GetWornForm(0x00000008) != none) ; Debug.Messagebox("Gauntlets are equipped") ; else ; Debug.MessageBox("Gauntlets are not equipped or something is wrong") ; endif ;;; form fm ; check if gauntlets are being worn or not, then add and equip them to the dummy if they are myF_AE(player, 0x00000008) ;;; fm = player.GetWornForm(0x00000008) ; Gauntlets ;;; IF (fm as Armor) ;;; PlayerEquipmentBrsk.AddItem(fm, absilent=true) ;;; PlayerEquipmentBrsk.EquipItem(fm, true, true) ;;;; Debug.MessageBox(Gauntlets) ;;; ENDIF ; check if a full head helmet is being worn or not, then add and equip it to the dummy if it is myF_AE(player, 0x00000003) ;;; fm = player.GetWornForm(0x00000003) ; HeadHair ;;; IF (fm as Armor) ;;; PlayerEquipmentBrsk.AddItem(fm, absilent=true) ;;; PlayerEquipmentBrsk.EquipItem(fm, true, true) ;;;; else ;;;; Debug.MessageBox("You have nothing equipped on HeadHair") ;;; ENDIF ; check if a head only helmet is being worn or not, then add and equip it to the dummy if it is myF_AE(player, 0x00000001) ;;; fm = player.GetWornForm(0x00000001) ; Head ;;; IF (fm as Armor) ;;; PlayerEquipmentBrsk.AddItem(fm, absilent=true) ;;; PlayerEquipmentBrsk.EquipItem(fm, true, true) ;;; ENDIF ; check if a hair only helmet is being worn or not, then add and equip it to the dummy if it is myF_AE(player, 0x00000002) ;;; fm = player.GetWornForm(0x00000002) ; Hair ;;; IF (fm as Armor) ;;; PlayerEquipmentBrsk.AddItem(fm, absilent=true) ;;; PlayerEquipmentBrsk.EquipItem(fm, true, true) ;;; ENDIF ; if PlayerEquipmentBrsk.IsEquipped(Gauntlets) ; Debug.MessageBox(PlayerEquipmentBrsk + "has equipped" + Gauntlets) ; else ; Debug.MessageBox(PlayerEquipmentBrsk + "could not equip" + Gauntlets) ; endif ; This was to check if the NPC was equipping the stuff or not... ; PlayerEquipmentBrsk.Moveto(Game.GetPlayer()) player.EquipItem(ArmorBerserkerWBoots2, true, true) player.EquipItem(ArmorBerserkerWCuirass2, true, true) player.EquipItem(ArmorBerserkerGauntlets2, true, true) player.EquipItem(ArmorBerserkWHelmet, true, true) player.AddSpell(BerserkerArmorRevertForm) player.RemoveSpell(BerserkerArmorBeastChange) ENDFUNCTION ;----------------------------------------------------- FUNCTION myF_AE(Actor player, Int i, Bool bAdd = TRUE) ; internal helper (edited 2019/02/11) ;----------------------------------------------------- form fm IF ( bAdd ) fm = player.GetWornForm(i) ; called from MakeForm() ELSE fm = PlayerEquipmentBrsk.GetWornForm(i) ; called from RevertForm() ENDIF IF (fm as Armor) ELSE RETURN ; - STOP - nothing worn at this slot ENDIF ;--------------------- IF ( bAdd ) PlayerEquipmentBrsk.AddItem(fm, absilent=TRUE) ; (A)dd PlayerEquipmentBrsk.EquipItem(fm, TRUE, TRUE) ; (E)quip RETURN ; - STOP - ENDIF ;--------------------- player.EquipItem(fm, False, TRUE) ENDFUNCTION ;-------------------------------- FUNCTION RevertForm(Actor player) ;-------------------------------- IF ( player ) ELSE RETURN ; - STOP - invalid parameter ENDIF ;--------------------- Deintegrate.Play(player) ; *** effectShader Utility.Wait(2.0) player.UnEquipItem(ArmorBerserkerWBoots2, false, true) player.UnEquipItem(ArmorBerserkerWCuirass2, false, true) player.UnEquipItem(ArmorBerserkerGauntlets2, false, true) player.UnEquipItem(ArmorBerserkWHelmet, false, true) player.EquipItem(ArmorBerserkerCuirass, false, true) player.EquipItem(ArmorBerserkerBoots, false, true) ;;; form fm ;check if gauntlets are being worn or not myF_AE(player, 0x00000008, False) ;;; fm = PlayerEquipmentBrsk.GetWornForm(0x00000008) ; Gaunlets ;;; IF (fm as Armor) ;;; player.EquipItem(fm, false, true) ;;; ENDIF ;check if a full head helmet is being worn or not myF_AE(player, 0x00000003, False) ;;; fm = PlayerEquipmentBrsk.GetWornForm(0x00000003) ; HeadHair ;;; IF (fm as Armor) ;;; player.EquipItem(fm, false, true) ;;; ENDIF ;check if a head only helmet is being worn or not myF_AE(player, 0x00000001, False) ;;; fm = PlayerEquipmentBrsk.GetWornForm(0x00000001) ; Head ;;; IF (fm as Armor) ;;; player.EquipItem(fm, false, true) ;;; ENDIF ;check if a hair only helmet is being worn or not myF_AE(player, 0x00000002, False) ;;; fm = PlayerEquipmentBrsk.GetWornForm(0x00000002) ; Hair ;;; IF (fm as Armor) ;;; player.EquipItem(fm, false, true) ;;; ENDIF PlayerEquipmentBrsk.RemoveAllItems() ; Dangerous !!! ;Checking if it did remove them again ; PlayerEquipmentBrsk.MoveTo(Game.GetPlayer()) player.AddSpell(BerserkerArmorBeastChange) player.EquipSpell(BerserkerArmorBeastChange, 2) Deintegrate.Stop(player) ; *** player.RemoveSpell(BerserkerArmorRevertForm) player.RemoveItem(ArmorBerserkSHelmet, abSilent=true) player.RemoveItem(ArmorBerserkWHelmet, abSilent=true) player.RemoveItem(ArmorBerserkerWCuirass, abSilent=true) player.RemoveItem(ArmorBerserkerWCuirass2, abSilent=true) player.RemoveItem(ArmorBerserkerGauntlets, abSilent=true) player.RemoveItem(ArmorBerserkerGauntlets2, abSilent=true) player.RemoveItem(ArmorBerserkerWBoots, abSilent=true) player.RemoveItem(ArmorBerserkerWBoots2, abSilent=true) ENDFUNCTION Edited February 11, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
qwertypol012 Posted February 11, 2019 Author Share Posted February 11, 2019 (edited) Cheers man! You're truly a savior, hahaha :laugh: I suppose it's actually better if i posted this question under my original thead: https://forums.nexusmods.com/index.php?/topic/7301906-how-to-properly-script-a-custom-conditional-system-which-will-be-used-by-a-quest-script/It's just that this is a special case since it's the only script failed to compile among my other scripts. So, now i understand that it's impossible to call functions from ActiveMagicEffect type scripts. I did find a question regarding calling functions from other scripts (solved by Chesko and IsharaMeradin), but it was a script related with ObjectReference or RefAlias (if i'm not mistaken). I thought that it would also work for ActiveMagicEffect. Okay, now i guess i need to edit my quest script again and recompile it. Thanks for the help! :thumbsup: Edited February 11, 2019 by qwertypol012 Link to comment Share on other sites More sharing options...
Evangela Posted February 11, 2019 Share Posted February 11, 2019 It's not possible because ActiveMagicEffect scripts don't persist, they are the worse route to go for any sort of data holding/querying. Quests are extremely good for this. Link to comment Share on other sites More sharing options...
qwertypol012 Posted February 11, 2019 Author Share Posted February 11, 2019 (edited) @RasikkoI see. That makes sense. Thanks for the explanation. I assume that it works for ObjectRef, Form, and Actor type scripts, right? And the exact instance which the script is attached to needs to be referenced properly. Is this correct? @ReDragon2013I still fail to understand this function from your edited quest script: ;----------------------------------------------------- FUNCTION myF_AE(Actor player, Int i, Bool bAdd = TRUE) ; internal helper ;----------------------------------------------------- form fm IF ( bAdd ) ;*; fm = player.GetWornForm(i) ; called from MakeForm() ELSE ;*; fm = PlayerEquipmentBrsk.GetWornForm(i) ; called from RevertForm() ENDIF IF (fm as Armor) ELSE RETURN ; - STOP - nothing worn at this slot ENDIF ;--------------------- IF ( bAdd ) PlayerEquipmentBrsk.AddItem(fm, absilent=TRUE) ; (A)dd PlayerEquipmentBrsk.EquipItemEx(fm, 0, TRUE, TRUE) ; (E)quip RETURN ; - STOP - ENDIF ;--------------------- player.EquipItemEx(fm, 0, False, TRUE) ENDFUNCTION I have several questions regarding this. 1. As far as i can understand, the line "(fm as Armor)" identifies fm as Armor as a replacement for GetWornForm, correct? So, something like this work even if we don't use GetWornForm??When "Int i" is filled (or identified) with slotmask value (eg. 0x00000008, etc), how does "fm" take its value (or identified itself) from that "Int i"?? I still fail to understand relation between them. 2. Next, what about this part? IF ( bAdd ) ;*; fm = player.GetWornForm(i) ; called from MakeForm() ELSE ;*; fm = PlayerEquipmentBrsk.GetWornForm(i) ; called from RevertForm() ENDIF Does it really really do anything? The ELSE is not even filled with anything. I'm not sure what this part does and why does it exist? 3. Next, i noticed that the function calling it (ie. MakeForm) identifies above function like this: myF_AE(player, 0x00000008).This is just i'm asking. What's the function of "Int i" in myF_AE(Actor player, Int i, Bool bAdd = TRUE)? Is it supposed to be identified with "form fm"?Also, why this function has a Bool (bAdd = TRUE)? I noticed that this is not a Bool Function, so why does it contain a Bool?Edit: About this part, i think i've figured it out. This Bool is used when the function is called by RevertForm. But i still couldn't understand the relation between "Int i" and "fm". 4. Next, there's this line in the end of the function: player.EquipItem(fm, False, TRUE) What does it for? I couldn't remember a line like this in the previous version of the script (inside MakeForm and RevertForm functions).Edit: Just like above, i figured it out that this line will run when the Bool is False. Edited February 11, 2019 by qwertypol012 Link to comment Share on other sites More sharing options...
ReDragon2013 Posted February 11, 2019 Share Posted February 11, 2019 (edited) I edited my last posting. I removed the line with "GetWornForm()", because I didn't installed SKSE! I forgot to remove the semicolons. from MakeForm() myF_AE(player, 0x00000008) ; myF_AE(player, 0x00000008, TRUE) ;;; fm = player.GetWornForm(0x00000008) ; Gauntlets ;;; IF (fm as Armor) ;;; PlayerEquipmentBrsk.AddItem(fm, absilent=true) ;;; PlayerEquipmentBrsk.EquipItem(fm, true, true) ;;;; Debug.MessageBox(Gauntlets) ;;; ENDIFfrom RevertForm() myF_AE(player, 0x00000008, False) ;;; fm = PlayerEquipmentBrsk.GetWornForm(0x00000008) ; Gaunlets ;;; IF (fm as Armor) ;;; player.EquipItem(fm, false, true) ;;; ENDIFyou wrote: "4. Next, there's this line in the end of the function" "i" is function parameter which is filled with a hexnumber like 0x00000008. ;----------------------------------------------------- FUNCTION myF_AE(Actor player, Int i, Bool bAdd = TRUE) ; internal helper (edited 2019/02/11) ;----------------------------------------------------- form fm IF ( bAdd ) fm = player.GetWornForm(i) ; called from MakeForm() ELSE fm = PlayerEquipmentBrsk.GetWornForm(i) ; called from RevertForm() ENDIF IF (fm as Armor) ELSE RETURN ; - STOP - nothing worn at this slot ENDIF ;--------------------- IF ( bAdd ) PlayerEquipmentBrsk.AddItem(fm, absilent=TRUE) ; (A)dd PlayerEquipmentBrsk.EquipItem(fm, TRUE, TRUE) ; (E)quip ELSE player.EquipItem(fm, False, TRUE) ; equip only ENDIF ENDFUNCTION Edited February 11, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
qwertypol012 Posted February 12, 2019 Author Share Posted February 12, 2019 Now that makes sense! :laugh: I was super confused with the first version of your script, but after you edited it things become clear :teehee: Alright, thanks for the help. Let me work on my parts, and hopefully no more problems :smile: Link to comment Share on other sites More sharing options...
Recommended Posts