Noggog Posted January 28, 2011 Share Posted January 28, 2011 (edited) So, I have a custom Turn Undead script that lowers the stats of the undead victim, as well as some other things. I wanted to make it so that the stats wouldn't come back at the snap of a finger once the spell ended, but rather slowly creep back throughout the spell duration. I started using this (messy and unpolished) script in the scriptEffectFinish area of my spell effect: ;loop is my loop timer, initially 0 Label 0 set loop to (loop + getSecondsPassed) printc "timer is %.2f", loop if ( loop < 5 ) GoTo 0 endif When I run this beast, it goes through and finishes the loop in a fraction of a second. I'm guessing it's because this loop is running every frame it can, and even if the getSecondsPassed is only .01, it'll keep adding .01 to the loop until it reaches 5. So I decided to do this script instead: ;loop is my loop timer, initially 0 Label 0 set loop getSecondsPassed printc "timer is %.2f", loop if ( loop < 5 ) GoTo 0 endif It seemed to work in my head, because getSecondsPassed would initially be 0, and then when one second had passed, getSecondsPassed would be 1, and then loop would be set to 1. This would continue until 5 seconds had passed.Instead, my game freezes, probably because of an infinite loop. What am I fundamentally getting wrong here? How do I just get a loop that lasts X seconds long? Edited January 28, 2011 by Leviathan1753 Link to comment Share on other sites More sharing options...
InAComaDial999 Posted January 28, 2011 Share Posted January 28, 2011 (edited) What am I fundamentally getting wrong here? How do I just get a loop that lasts X seconds long? What you're missing is that GetSecondsPassed represents the time elapsed since the last frame your script ran in and the beginning of the current frame. It does not change within a frame. The other thing to keep in mind, is that your entire script is run in one frame, regardless of how long it takes. If you were to make a script that really took 5 seconds to run, then the game would freeze for 5 seconds. Label 0 set loop to (loop + getSecondsPassed) printc "timer is %.2f", loop if ( loop < 5 ) GoTo 0 endif What's happening in the above snippet is that this entire loop is running in one frame. If your game is running at 60fps, then getSecondsPassed is about 0.17, and your loop is being run 294 times. Of course it runs very quickly since it's not doing anything within the loop. Label 0 set loop getSecondsPassed printc "timer is %.2f", loop if ( loop < 5 ) GoTo 0 endif In the above code, you have created an infinite loop. GetSecondsPassed does not change within a frame, no matter how long that frame takes to process. And since it will not increment inside your script, loop will never increment either. So your loop will never end. The proper way to do this is not to do it in the ScriptEffectFinish block at all. ScriptEffectFinish runs only once, at the very end of the spell duration. The better way to do it is to set the spell's duration to however long you want the effect to last, and use the ScriptEffectUpdate block to make whatever you want happen after X number of seconds. ScriptEffectUpdate runs every frame that the spell is active. The timer then looks like this: float timer begin ScriptEffectUpdate if ( timer < 5 ) set timer to timer + getSecondsPassed else ; insert block of code that has to run after 5 seconds endif end The above will increment timer every frame until 5 seconds has passed, after which your block of code will run. If you want the loop to run every 5 seconds while the spell is running, rather than just once, set timer = 0 in that block of code. As far as what you are trying to do, I guess my take on it would be something like this: float timer float timelimit begin ScriptEffectStart set timelimit to 25 ; other stuff end begin ScriptEffectUpdate if ( timer < timelimit ) set timer to timer + getSecondsPassed else if (timelimit == 25) ; insert block of code that has to run after the first 25 seconds set timelimit to 5 set timer to 0 else ; insert block of code that runs every 5 seconds until the end of the spell duration set timer to 0 endif endif end The above will do nothing for the first 25 seconds of the spell duration. After that, it will do the first block of code, and then the second block of code every 5 seconds until the end of the spell. Edited January 28, 2011 by InAComaDial999 Link to comment Share on other sites More sharing options...
Noggog Posted January 28, 2011 Author Share Posted January 28, 2011 Thanks a ton! I'll give it a spin. Link to comment Share on other sites More sharing options...
Noggog Posted January 28, 2011 Author Share Posted January 28, 2011 (edited) Works like a charm! 8) Thanks Any chance you know offhand the commands to retrieve the script effect's magnitude and duration numbers? Edited January 28, 2011 by Leviathan1753 Link to comment Share on other sites More sharing options...
InAComaDial999 Posted January 30, 2011 Share Posted January 30, 2011 (edited) There aren't commands to get those in the vanilla CS. You can do it with OBSE functions though. I believe it would go like this: int spellindex int spellduration int spellmagnitude begin ScriptEffectStart set spellindex to GetScriptActiveEffectIndex set spellduration to (GetNthActiveEffectDuration spellindex) set spellmagnitude to (GetNthActiveEffectMagnitude spellindex) ... end Edited January 30, 2011 by InAComaDial999 Link to comment Share on other sites More sharing options...
mma75online Posted May 25, 2020 Share Posted May 25, 2020 (edited) just what i am also looking for .... i use this code as u say and work great float timer begin ScriptEffectUpdate if ( timer < 5 ) set timer to timer + getSecondsPassed else ; insert block of code that has to run after 5 secondsendif end now is it possible to add a key to stop the whole script ... i try to use ( getbuttonpressed ) but no success Edited May 25, 2020 by mma75online Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted May 25, 2020 Share Posted May 25, 2020 GetButtonPressed is only for use with message boxes. It's not for detecting the pressing of keyboard keys. I'm afraid this will require OBSE instead. Either OnKeyDown or IsKeyPressed, 2, 3 could be used. I personally prefer IsKeyPressed2 for things like this. But now we need to know what kind of spell this is. If it's of only temporary effect, like an actual Spell or Power or Potion, and has to be re-cast every time, the loop could be broken via a stop flag variable perhaps. Though if it's more like an Ability and endlessly running, it cannot be stopped unless forever, and then it can't be made working again, unless by another trigger somehow. Provided it is a Spell and will cease running after a time, the stop flag will also be cleared the next time it's casted. Then a script like this could do: float timer short stopTimer Begin ScriptEffectUpdate if IsKeyPressed2 <yourKeyCode> set stopTimer to 1 endif if stopTimer return ; abort script run here endif if ( timer < 5 ) set timer to timer + getSecondsPassed else ; insert block of code that has to run after 5 seconds endif End Link to comment Share on other sites More sharing options...
mma75online Posted May 26, 2020 Share Posted May 26, 2020 thank u for fast replay & thank u more for this information it will great help me for some mod i wanna improve the script i was work in it is a spell that trigger several random animation in certain condition ... I try IsKeyPressed2 as u instruct but not break the loop the animation stay repeated until the end of the spell duration .. Link to comment Share on other sites More sharing options...
DrakeTheDragon Posted May 26, 2020 Share Posted May 26, 2020 Hmm, can I see the whole script here, so everything's in context, check the order in which things happen and where stuff can go wrong? Link to comment Share on other sites More sharing options...
mma75online Posted May 26, 2020 Share Posted May 26, 2020 Hmm, can I see the whole script here, so everything's in context, check the order in which things happen and where stuff can go wrong?sorry to bother U .. it work the error was mine i set a key used by other mod ... when i change it script work fine .. thank u very much Link to comment Share on other sites More sharing options...
Recommended Posts