Medabev Posted June 13, 2017 Share Posted June 13, 2017 Hey there everyone, hope all is well. A recent unfortunate event, has lead to the lost of my previous mod project, but I was able to salvage it. I've been working on some new scripts and I'm having an issue getting an Activator to "reset after the Timer is up",more specifically the in-game timer. I've tried "Utility.Wait" and then "()Reset" at the end, but it didn't work. I know GlobalVariableGametime plays a role here somewhere but I'm messing this up. I've read on here "RegisterForSingleUpdateGameTime" is probably better for "longer" wait times, but had the same results. This script is from "Aftershock" quest, anomaly attacks. I've been experimenting with it and it works, I would just like it if the trigger restart after a set amount of time has passed. Any help would be greatly appreciated. Scriptname TEST_AnomalySpawner extends ObjectReference {Handles the destruction stages and enemy spawning of the magic anomaly spawner object} ActorBase Property EncMagicAnomaly Auto {enemy to spawn} Explosion Property ExplosionIllusionLight01 Auto {explosion to play whne it opens} Explosion Property ExplosionIllusionMassiveLight01 Auto {explosion to play whne it opens} ; Enemy holders Actor myEncMagicAnomaly01 Actor myEncMagicAnomaly02 Actor myEncMagicAnomaly03 ; Blend values (how open it the portal 0-1) float fToggleBlendStart = 0.3 float fToggleBlendOpen = 0.9 float fToggleBlendFull = 1.0 float fToggleBlendGone = 0.0 ; Temporary blend value holder float myCurrentBlend ;Is player in trigger and the portal is not open int playerInTrigger ; Enemy count int numberOfEnemiesAlive ; Distances with 3000 unit trigger to test fade portal open float maxTestRange = 1500.0 Float minTestRange = 550.0 ; holder for player actor myPlayer ; gates for making the drath of each enemy affect script only once int Gate1 int Gate2 int Gate3 auto state waiting ; Set initial blend ab=mount for portal and get player locally Event onLoad() self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendStart) myPlayer = game.getPlayer() EndEvent ;waits for player to enter trigger once he does it tests for distance and triggers the portal to open if he gets close enough Event OnTriggerEnter(ObjectReference akActionRef) playerInTrigger = 1 self.SetAnimationVariableFloat("fDampRate", 0.3) while playerInTrigger == 1 ;&& playerLeftTrigger float myDistance = myPlayer.getDistance(self) ; debug.trace("myDistance = " + myDistance) if myDistance <= minTestRange ;player is close enoght to automatically open the portal goToState("opened") playerInTrigger = 0 elseIf myDistance <= maxTestRange Float animationValue = CalculateAnimationValue(myDistance, minTestRange,maxTestRange, fToggleBlendStart, fToggleBlendFull) ; debug.trace("animationValue = " + animationValue) self.SetAnimationVariableFloat("fToggleBlend", animationValue) utility.wait(0.05) endif endWhile EndEvent ;stop testing if player leaves trigger without opening portal Event OnTriggerLeave(ObjectReference akActionRef) playerInTrigger = 0 EndEvent endState state opened ;The portal is opened playe some explosions and spawn 3 enemies Event onBeginState() ; debug.trace("opened") int doOnce = 0 if doOnce == 0 self.placeAtMe(ExplosionIllusionLight01) utility.wait(0.75) self.placeAtMe(ExplosionIllusionMassiveLight01) self.KnockAreaEffect(1, 900) self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendFull) utility.wait(0.5) myEncMagicAnomaly01 = self.placeActorAtMe(EncMagicAnomaly) myEncMagicAnomaly01.setScale(utility.randomFloat(0.7, 1.25)) utility.wait(1.5) myEncMagicAnomaly02 = self.placeActorAtMe(EncMagicAnomaly) myEncMagicAnomaly02.setScale(utility.randomFloat(0.7, 1.25)) utility.wait(0.5) myEncMagicAnomaly03 = self.placeActorAtMe(EncMagicAnomaly) myEncMagicAnomaly03.setScale(utility.randomFloat(0.7, 1.25)) numberOfEnemiesAlive = 3 doOnce = 1 endIf utility.wait(3.5) self.SetAnimationVariableFloat("fDampRate", 0.03) self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendOpen) ; debug.trace("isDead " + myEncMagicAnomaly01.IsDead()) ;While ther are some enemies alive test each one to see if they are dead evey half second. If they are run the fade out function. while numberOfEnemiesAlive > 0 utility.wait(0.5) if Gate1 == 0 if myEncMagicAnomaly01.IsDead() == true anomalyDied() Gate1 = Gate1 + 1 endIf endIf if Gate2 == 0 if myEncMagicAnomaly02.IsDead() == true anomalyDied() Gate2 = Gate2 + 1 endIf endIf if Gate3 == 0 if myEncMagicAnomaly03.IsDead() == true anomalyDied() Gate3 = Gate3 + 1 endIf endIf endwhile EndEvent endState ; function to test the distance from the player to the portal and ramp up the art accordingly Float Function CalculateAnimationValue(float PlayerDistance, float NearDistance, float FarDistance, float AnimationMin, float AnimationMax) Float percent = 1-((PlayerDistance - NearDistance)/(FarDistance - NearDistance)) Float returnValue = (percent * (AnimationMax - AnimationMin)) + AnimationMin Return returnValue EndFunction ; Function to fade out the art each time an enemy dies finally disabling the art after the last enemy Function anomalyDied() ; debug.trace("running anomaly died") ; debug.trace("01 is dead = " + myEncMagicAnomaly01.IsDead()) ; debug.trace("02 is dead = " + myEncMagicAnomaly02.IsDead()) ; debug.trace("03 is dead = " + myEncMagicAnomaly03.IsDead()) myCurrentBlend = self.GetAnimationVariableFloat("fToggleBlend") ; debug.trace("myCurrentBlend = "+ myCurrentBlend) self.SetAnimationVariableFloat("fToggleBlend", myCurrentBlend - (fToggleBlendOpen / 3)) numberOfEnemiesAlive = numberOfEnemiesAlive - 1 if numberOfEnemiesAlive == 0 utility.wait(0.5) self.disable(true) endif EndFunction Link to comment Share on other sites More sharing options...
TheDungeonDweller Posted June 14, 2017 Share Posted June 14, 2017 (edited) I'm assuming based on what you've posted is all you want is a trigger that will be able to run a script again after a certain amount of time as passed. So I wrote a rather simple one for you. Scriptname DefaultResetTriggerScript extends ObjectReference { Basic script for resetting triggers. This can be applied to any trigger. } Float property fHours auto { The number of hours to pass before this trigger resets. } AUTO STATE FirstState Event OnTriggerEnter(ObjectReference akTriggerRef) if akTriggerRef == Game.GetPlayer() ; put script in its waiting phase. Code after GoToState will still run. GoToState("SecondState") ;-----spot for your desired code RegisterForSingleUpdateGameTime(fHours) endif EndEvent ENDSTATE STATE SecondState Event OnUpdateGameTime() ; put it back in its main state GoToState("FirstState") EndEvent ENDSTATE fHours can be any hour you want, or if not wanting to use a property, you can just pass a value to the function, like 24.0(24 hours). This can be used on any script for simple "resetting". Make sure the trigger in game reference's respawn box is not checked. Otherwise when it does reset due to the cell resetting, the script will reset with it. Depending on how you code, you'll need to adjust when you want the registering of the event to actually happen if you don't want to register as soon as the player enters the trigger.There is the issue of OnUpdateGameTime not taking into account for the player sleeping, waiting, fast traveling as any of these can potentially cause the event to run later than you expect, but I figure for this kind of thing, it's not important. Edited June 14, 2017 by TheDungeonDweller Link to comment Share on other sites More sharing options...
Medabev Posted June 14, 2017 Author Share Posted June 14, 2017 (edited) Ah, thanks a lot DungeonDweller! I'm assuming based on what you've posted is all you want is a trigger that will be able to run a script again after a certain amount of time as passed. So I wrote a rather simple one for you. ;-----spot for your desired code The script you posted compiled perfectly. (Something I'm not use to seeing for myself) and yes, you are spot on, I want the trigger to run again after a certain amount of time has passed. This particular line, "Spot for your desired code", I've tried putting the entire code in that segment and got errors, been fiddling around with it and realize that was wrong and tried configuring the "Waiting" part. Basically this "works", but I wanted to run this by you to make sure I wrote this right. Feels like I messed something up though but I'll be running some more test, since I know OnUpdateGametime doesn't take into account for waiting or sleeping. Once again thanks a lot for your help! Will post back results :laugh: Scriptname TEST_AnomalySpawner extends ObjectReference {Handles the destruction stages and enemy spawning of the magic anomaly spawner object} Float property fHours auto { The number of hours to pass before this trigger resets. } ActorBase Property EncMagicAnomaly Auto {enemy to spawn} Explosion Property ExplosionIllusionLight01 Auto {explosion to play whne it opens} Explosion Property ExplosionIllusionMassiveLight01 Auto {explosion to play whne it opens} ; Enemy holders Actor myEncMagicAnomaly01 Actor myEncMagicAnomaly02 Actor myEncMagicAnomaly03 ; Blend values (how open it the portal 0-1) float fToggleBlendStart = 0.3 float fToggleBlendOpen = 0.9 float fToggleBlendFull = 1.0 float fToggleBlendGone = 0.0 ; Temporary blend value holder float myCurrentBlend ;Is player in trigger and the portal is not open int playerInTrigger ; Enemy count int numberOfEnemiesAlive ; Distances with 3000 unit trigger to test fade portal open float maxTestRange = 1500.0 Float minTestRange = 550.0 ; holder for player actor myPlayer ; gates for making the drath of each enemy affect script only once int Gate1 int Gate2 int Gate3 STATE FirstState Event OnTriggerEnter(ObjectReference akTriggerRef) if akTriggerRef == Game.GetPlayer() ; put script in its waiting phase. Code after GoToState will still run. GoToState("SecondState") ;-----spot for your desired code {Feels like I did something wrong here} RegisterForSingleUpdateGameTime(fHours) endif EndEvent ENDSTATE auto state waiting ; Set initial blend ab=mount for portal and get player locally Event onLoad() self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendStart) myPlayer = game.getPlayer() EndEvent ;waits for player to enter trigger once he does it tests for distance and triggers the portal to open if he gets close enough Event OnTriggerEnter(ObjectReference akActionRef) playerInTrigger = 1 self.SetAnimationVariableFloat("fDampRate", 0.3) while playerInTrigger == 1 ;&& playerLeftTrigger float myDistance = myPlayer.getDistance(self) ; debug.trace("myDistance = " + myDistance) if myDistance <= minTestRange ;player is close enoght to automatically open the portal goToState("opened") playerInTrigger = 0 elseIf myDistance <= maxTestRange Float animationValue = CalculateAnimationValue(myDistance, minTestRange,maxTestRange, fToggleBlendStart, fToggleBlendFull) ; debug.trace("animationValue = " + animationValue) self.SetAnimationVariableFloat("fToggleBlend", animationValue) utility.wait(0.05) endif endWhile EndEvent ;stop testing if player leaves trigger without opening portal Event OnTriggerLeave(ObjectReference akActionRef) playerInTrigger = 0 EndEvent endState state opened ;The portal is opened playe some explosions and spawn 3 enemies Event onBeginState() ; debug.trace("opened") int doOnce = 0 if doOnce == 0 self.placeAtMe(ExplosionIllusionLight01) utility.wait(0.75) self.placeAtMe(ExplosionIllusionMassiveLight01) self.KnockAreaEffect(1, 900) self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendFull) utility.wait(0.5) myEncMagicAnomaly01 = self.placeActorAtMe(EncMagicAnomaly) myEncMagicAnomaly01.setScale(utility.randomFloat(0.7, 1.25)) utility.wait(1.5) myEncMagicAnomaly02 = self.placeActorAtMe(EncMagicAnomaly) myEncMagicAnomaly02.setScale(utility.randomFloat(0.7, 1.25)) utility.wait(0.5) myEncMagicAnomaly03 = self.placeActorAtMe(EncMagicAnomaly) myEncMagicAnomaly03.setScale(utility.randomFloat(0.7, 1.25)) numberOfEnemiesAlive = 3 doOnce = 1 endIf utility.wait(3.5) self.SetAnimationVariableFloat("fDampRate", 0.03) self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendOpen) ; debug.trace("isDead " + myEncMagicAnomaly01.IsDead()) ;While ther are some enemies alive test each one to see if they are dead evey half second. If they are run the fade out function. while numberOfEnemiesAlive > 0 utility.wait(0.5) if Gate1 == 0 if myEncMagicAnomaly01.IsDead() == true anomalyDied() Gate1 = Gate1 + 1 endIf endIf if Gate2 == 0 if myEncMagicAnomaly02.IsDead() == true anomalyDied() Gate2 = Gate2 + 1 endIf endIf if Gate3 == 0 if myEncMagicAnomaly03.IsDead() == true anomalyDied() Gate3 = Gate3 + 1 endIf endIf endwhile EndEvent endState STATE SecondState Event OnUpdateGameTime() ; put it back in its main state GoToState("FirstState") EndEvent ENDSTATE ; function to test the distance from the player to the portal and ramp up the art accordingly Float Function CalculateAnimationValue(float PlayerDistance, float NearDistance, float FarDistance, float AnimationMin, float AnimationMax) Float percent = 1-((PlayerDistance - NearDistance)/(FarDistance - NearDistance)) Float returnValue = (percent * (AnimationMax - AnimationMin)) + AnimationMin Return returnValue EndFunction ; Function to fade out the art each time an enemy dies finally disabling the art after the last enemy Function anomalyDied() ; debug.trace("running anomaly died") ; debug.trace("01 is dead = " + myEncMagicAnomaly01.IsDead()) ; debug.trace("02 is dead = " + myEncMagicAnomaly02.IsDead()) ; debug.trace("03 is dead = " + myEncMagicAnomaly03.IsDead()) myCurrentBlend = self.GetAnimationVariableFloat("fToggleBlend") ; debug.trace("myCurrentBlend = "+ myCurrentBlend) self.SetAnimationVariableFloat("fToggleBlend", myCurrentBlend - (fToggleBlendOpen / 3)) numberOfEnemiesAlive = numberOfEnemiesAlive - 1 if numberOfEnemiesAlive == 0 utility.wait(0.5) self.disable(true) endif EndFunction Edited June 14, 2017 by Juebev Link to comment Share on other sites More sharing options...
ReDragon2013 Posted June 14, 2017 Share Posted June 14, 2017 (edited) Maybe the following script is a good template for you. It should help to understand what is going on between the state changes. (no guarantee of working) Portal_AnomalySpawnerScript Scriptname Portal_AnomalySpawnerScript extends ObjectReference {rewritten by ReDragon 2017, support by TheDungeonDweller} ; Basic script for resetting triggers. This can be applied to any trigger. ; https://forums.nexusmods.com/index.php?/topic/5719767-trying-to-get-an-activator-reset-on-timer/ ; juebev wrote: "This script is from "Aftershock" quest, anomaly attacks." Explosion PROPERTY ExplosionIllusionLight01 auto ; {explosion to play, when it opens} Explosion PROPERTY ExplosionIllusionMassiveLight01 auto ; {explosion to play, when it opens} ActorBase PROPERTY EncMagicAnomaly auto ; {enemy base object to spawn} Float PROPERTY fHours auto ; The number of hours to pass before this trigger resets. ; Distances with 3000 unit trigger to test fade portal open Float maxTestRange = 1500.0 Float minTestRange = 550.0 ; Blend values (how much open is the portal 0-1) Float fToggleBlendStart = 0.3 Float fToggleBlendOpen = 0.9 Float fToggleBlendFull = 1.0 ;Float fToggleBlendGone = 0.0 ; Enemy holder Actor myEncMagicAnomaly01 Actor myEncMagicAnomaly02 Actor myEncMagicAnomaly03 ; replacement for playerInTrigger, Is player in trigger and the portal is not open Bool bPIT ; Enemy count Int numberOfEnemiesAlive ; gates for making the drath of each enemy affect script only once Int Gate1 Int Gate2 Int Gate3 ; -- EVENTs -- 2 + waiting + reset EVENT OnCellAttach() IF ( !bPIT ) gotoState("waiting") ; ### STATE ### ENDIF ENDEVENT EVENT OnCellDetach() bPIT = False ENDEVENT ;================================= state waiting ;============ EVENT OnLoad() self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendStart) ENDEVENT EVENT OnTriggerEnter(ObjectReference triggerRef) ; waits for player to enter trigger once he does it tests for distance and triggers the portal to open if he gets close enough IF ( bPIT ) RETURN ; - STOP - already triggered by the player ENDIF ;--------------------- IF (triggerRef == Game.GetPlayer() as ObjectReference) ELSE RETURN ; - STOP - not the player ENDIF ;--------------------- bPIT = TRUE self.SetAnimationVariableFloat("fDampRate", 0.3) myF_Action(triggerRef) ENDEVENT EVENT OnTriggerLeave(ObjectReference triggerRef) IF (triggerRef == Game.GetPlayer() as ObjectReference) bPIT = False ; stop testing, if player leaves trigger without opening portal ENDIF ENDEVENT ;======= endState ;================================= state opened ;=========== EVENT OnUpdate() RegisterForSingleUpdateGameTime(fHours) myF_Place() Utility.Wait(3.5) myF_Portal() ENDEVENT EVENT OnUpdateGameTime() gotoState("") ; ### STATE ### ENDEVENT ;======= endState ; -- FUNCTIONs -- 5 ;--------------------------------------------- FUNCTION myF_Action(ObjectReference playerRef) ;--------------------------------------------- WHILE ( bPIT ) ; playerInTrigger == 1 ;&& playerLeftTrigger float f = self.GetDistance(playerRef) ; f = myDistance Debug.Trace(self+" myF_Action() - distance = " +f) IF (f <= minTestRange) ; player is close enoght to automatically open the portal gotoState("opened") ; ### STATE ### bPIT = False ELSEIF (f <= maxTestRange) myF_Anim(f) Utility.Wait(0.05) ENDIF ENDWHILE IF self && self.Is3DLoaded() RegisterForSingleUpdate(0.0) ENDIF ENDFUNCTION ;------------------------- FUNCTION myF_Anim(Float f) ;------------------------- ; function to test the distance from the player to the portal and ramp up the art accordingly ; Float animationValue = CalculateAnimationValue(myDistance, minTestRange,maxTestRange, fToggleBlendStart, fToggleBlendFull) ; PlayerDistance = myDistance = f ; NearDistance = minTestRange ; FarDistance = maxTestRange ; AnimationMin = fToggleBlendStart ; AnimationMax = fToggleBlendFull float fp = 1 - ( (f - minTestRange) / (maxTestRange - minTestRange) ) float fa = ((fToggleBlendFull - fToggleBlendStart) * fp) + fToggleBlendStart Debug.Trace(self+" myF_Anim) - animationValue = " +fa) self.SetAnimationVariableFloat("fToggleBlend", fa) ENDFUNCTION ;------------------- FUNCTION myF_Place() ;------------------- ;The portal is opened play some explosions and spawn 3 enemies self.PlaceAtMe(ExplosionIllusionLight01) Utility.Wait(0.75) self.PlaceAtMe(ExplosionIllusionMassiveLight01) self.KnockAreaEffect(1, 900) self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendFull) Utility.Wait(0.5) float f = Utility.RandomFloat(0.7, 1.25) myEncMagicAnomaly01 = self.PlaceActorAtMe(EncMagicAnomaly) myEncMagicAnomaly01.SetScale(f) numberOfEnemiesAlive = 1 Utility.Wait(1.5) f = Utility.RandomFloat(0.7, 1.25) myEncMagicAnomaly02 = self.PlaceActorAtMe(EncMagicAnomaly) myEncMagicAnomaly02.SetScale(f) numberOfEnemiesAlive = numberOfEnemiesAlive + 1 Utility.Wait(0.5) f = Utility.RandomFloat(0.7, 1.25) myEncMagicAnomaly03 = self.PlaceActorAtMe(EncMagicAnomaly) myEncMagicAnomaly03.SetScale(f) numberOfEnemiesAlive = numberOfEnemiesAlive + 1 ENDFUNCTION ;-------------------- FUNCTION myF_Portal() ;-------------------- self.SetAnimationVariableFloat("fDampRate", 0.03) self.SetAnimationVariableFloat("fToggleBlend", fToggleBlendOpen) ; debug.trace("isDead " + myEncMagicAnomaly01.IsDead()) ; While ther are some enemies alive test each one, ; to see if they are dead evey half second. ; If someone has died, run the fade out function. WHILE (numberOfEnemiesAlive > 0) Utility.Wait(0.5) if (Gate1 == 0) if myEncMagicAnomaly01.IsDead() anomalyDied() Gate1 = Gate1 + 1 endIf endIf if (Gate2 == 0) if myEncMagicAnomaly02.IsDead() anomalyDied() Gate2 = Gate2 + 1 endIf endIf if (Gate3 == 0) if myEncMagicAnomaly03.IsDead() anomalyDied() Gate3 = Gate3 + 1 endIf endIf ENDWHILE ENDFUNCTION ;--------------------- FUNCTION anomalyDied() ;--------------------- ; to fade out the art each time an enemy dies finally disabling the art after the last enemy float f = self.GetAnimationVariableFloat("fToggleBlend") self.SetAnimationVariableFloat("fToggleBlend", f - (fToggleBlendOpen / 3)) numberOfEnemiesAlive = numberOfEnemiesAlive - 1 IF (numberOfEnemiesAlive == 0) Utility.Wait(0.25) self.Disable(TRUE) ENDIF ENDFUNCTION Edited June 14, 2017 by ReDragon2013 Link to comment Share on other sites More sharing options...
Medabev Posted June 15, 2017 Author Share Posted June 15, 2017 (edited) Maybe the following script is a good template for you. It should help to understand what is going on between the state changes. (no guarantee of working) Portal_AnomalySpawnerScript Ok wow, that is a REALLY well formatted script. Thanks a lot! The script compiled successfully! I'm going to test it and hope it works out. I definitely messed something up in my last attempt so I hope this time it finally works. Looking forward playing around with this, this is actually really exciting, minus the parts when the script is being difficult. But yeah I better understand whats going on now. I think this will help for sure EDIT: Bad news, doesn't seem to be restarting and mobs aren't deleted anymore, good news though is that the portal is completely invisible now, it actually caught me by surprise when I got into range. Will be playing around with this some more, feel we are getting really close to the desire results. Edited June 15, 2017 by Juebev Link to comment Share on other sites More sharing options...
TheDungeonDweller Posted June 15, 2017 Share Posted June 15, 2017 (edited) Hmm yeah I should have asked if you wanted a script similar to the vanilla one. Edited June 15, 2017 by TheDungeonDweller Link to comment Share on other sites More sharing options...
Medabev Posted June 15, 2017 Author Share Posted June 15, 2017 Hmm yeah I should have asked if you wanted a script similar to the vanilla one. No, it's my mistake. I should've been more clearer, Honestly your script has helped alot about the "states". This is so much scripting I hope at least if someone in the future is in need of a script like this they find this thread. Been thinking about at least making a Winrar or something of all the scripts I've dug up from the past so they are easier to find. I"m going to keep messing around with this script though, been experimenting and been having various results. Link to comment Share on other sites More sharing options...
Recommended Posts