Difference between revisions of "Talk:GetSecondsPassed"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>QQuix
(→‎Multiple uses whitin a script: Additional comments)
imported>QQuix
Line 224: Line 224:
:Yes, both, by leaving the cell (so the script stops running) and going back and by leaving the cell and moving the object to the player after a few seconds. Also tried going in and out of trigger zones scripted to print the value returned by GetSecondsPassed in their OnTrigger blocks. In all cases, the very first line printed when the object enters into scope reports the exact same value as a player token running every frame without interruption.
:Yes, both, by leaving the cell (so the script stops running) and going back and by leaving the cell and moving the object to the player after a few seconds. Also tried going in and out of trigger zones scripted to print the value returned by GetSecondsPassed in their OnTrigger blocks. In all cases, the very first line printed when the object enters into scope reports the exact same value as a player token running every frame without interruption.


:I did read that scruggsy text somewhere. He mentioned that the control war per script, not per object. So I tried 3 objects sharing the same script. Theoretically two of them should report 0. But all report the same 0.0xx value.
:I did read that scruggsy's text somewhere. He mentioned that the control was per script, not per object. So I tried 3 objects sharing the same script. Theoretically two of them should report 0. But all report the same 0.0xx value.


:As there are knowledgeable people, like scruggsy, saying otherwise, I wonder if some of the reports were written based on the original Oblivion version, Maybe one of the patches changed this function's behavior.  Or, again, ny game is different for some reason.
:As there are knowledgeable people, like scruggsy, saying otherwise, I wonder if some of the reports were written based on the original Oblivion version, Maybe one of the patches changed this function's behavior.  Or, again, my game is different/broken for some reason.


:It would be nice if you, or somebody, could confirm. It is just a matter of placing the following script on an object in an internal cell, go in and out and check the console to see what comes out.
:It would be nice if you, or somebody, could confirm. It is just a matter of placing the following script on an object in an internal cell, go in and out and check the console to see what comes out.

Revision as of 18:18, 9 August 2009

Example Discussion

--JustTim 18:26, 27 April 2006 (EDT) : Slserpent, you've messed up the Example! The old Version was correct, yours is not!

ok, i guess if you like counting backwards, it works. the only problem is timer isn't initialized, so it always goes to the else. and i should have put 'if timer < 2' in my version--my bad. -slserpent
In my opinion, the information in the article isnt extremely/comprehensively useful. It took me about 2 days worth of work to iron the kinks out of using a timer in my script. This coming from a fair self-taught, no programming/IT background scripting expertise (I've usually got the goods to get the job done) and a considerable help from the community here. I would like to extract information from the script posted below (Antares Complete Working Script) and put it in the article under Example 3. Thoughts? Anyone think that the article isnt as helpful as it could be?
--Antares 12:37, 5 September 2008 (EDT)

Help

Having trouble implementing this in my script. I am trying to make a statue of the player and I want to call the SkipAnim Command on him but only after any weapon has finished being drawn. (Thus the need for GetSecondsPassed. Here is my code

Begin GameMode
 
 If RSPlayerStatue.IsWeaponOut == 1 ;checks if the statue has weapon drawn before actor is set unconscious/destroyed
  RSPlayerStatue.setunconscious 1
   RSPlayerStatue.setdestroyed 1
 
 If DoOnce == 0
  Set AnimTimer to  GetSecondsPassed ; sets the timer once inside the Gamemode block instead of every frame
   Set DoOnce to 1
 endif
 endif
 
 If AnimTimer >= 3 ;should execute after GetSecondsPassed >= 3 seconds ????
  RSPlayerStatue.skipanim
 endif
 End

Many Thanks--Antares 09:05, 4 September 2008 (EDT)

GetSecondsPassed returns the time (in seconds) since the previous frame. AnimTimer, then, will never be >=3 unless you have a <1/3 FPS!
What you want to do is add up the times between frames until you get over three, like this:
set AnimTimer to AnimTimer + GetSecondsPassed
Does that make sense?
Dragoon Wraith TALK 09:53, 4 September 2008 (EDT)
I realised that shortly after I posted, I played around with the script but it still doesnt work. Here is the entire script. Do you know where its going wrong?
 scn RSPlayerStatueToggleScript
 
 float AnimTimer
 ref RSPlayerStatue
 short OneStatue
 short button
 
 Begin OnActivate
 MessageBox "Would you like a statue made in your current likeness?", "Yes", "No", "Remove Current Statue"
  Activate
 End
 
 Begin GameMode
 Set button to GetButtonPressed
 
 If RSPlayerStatue.IsWeaponOut == 1	
  RSPlayerStatue.setunconscious 1
   RSPlayerStatue.setdestroyed 1
 endif
 
 If AnimTimer > 2
  RSPlayerStatue.skipanim ; prevent him from breathing
 endif
 
 If OneStatue == 1
  RSPlayerStatue.pms EffectStone
 endif
 
 If ( button == 0 ) && ( OneStatue == 1 )
  Message "Please remove current statue first"
 endif
 
 If ( button == 0 ) && ( OneStatue == 0 )
  set RSPlayerStatue to player.CreateFullActorCopy
   RSPlayerStatue.setscale 2
   RSPlayerStatue.removeItem torch02 100
   RSPlayerStatue.moveto RSPlayerStatueHereRef
   RSPlayerStatue.SetAlert 1
   RSPlayerStatue.setghost 1
 Set OneStatue to 1
 Set AnimTimer to ( AnimTimer + GetSecondsPassed )
  Message "A statue has been made in your likeness"
 endif
 
 If ( button == 2 ) && ( OneStatue == 0 )
  Message "No statue to remove"
 endif
 
 If ( button == 2 ) && ( OneStatue == 1 )
  Message "Statue removed"
   Set OneStatue to 0
    RSPlayerStatue.DeleteFullActorCopy ;not sure which of these lines work as they act as a return function
     DeleteFullActorCopy ; but meh it achieves the desired effect
 endif
 
 If button == 1
  return
 endif
 End
That is my entire script for having a player statue that is updatable, ie will display whatever armor/weapons you are currently wearing. The whole skipanim dilemna comes about when I want the statue to have its weapon drawn but do not want the breathing animation. If you call skipanim inside the IsWeaponOut block the statue will not completely draw the weapon but get stuck halfway. Thus a delay is needed via GetSecondsPassed. Hope all that makes sense. Thanks heaps for the timely response.
--Antares 10:37, 4 September 2008 (EDT)
You only update the animtimer once -- you need to update the animtimer every frame in order for it to accurately track how many seconds have passed. You will also want to stop updating the animtimer once the script has done whatever it was waiting to do
--quetzilla 14:16, 4 September 2008 (EDT)

(Moving back over) Man I feel silly, I thought that if you ran a timer inside a gamemode block every frame (without some sort of DoOnce catch) it would get reset not updated. Thanks for the help I should have this nailed now. Up until this point in my modding endeavours I have tried extremely hard to avoid using timers, they were the one part of scripting I could never get my head around. Thank you very much I think I now have a sound understand of how timers are handled/executed by Oblivion.

--Antares 22:04, 4 September 2008 (EDT)

I believe I have now perfected the script. Here it is for those who wish to know. I may write a tutorial on making a player statue that can be updated and removed at will.

scn RSPlayerStatueToggleScript

float AnimTimer
ref RSPlayerStatue
short OneStatue
short button
short Frozen

Begin OnActivate
MessageBox "Would you like a statue made in your current likeness?", "Yes", "No", "Remove Current Statue"
	Activate
End

Begin GameMode
Set button to GetButtonPressed

If AnimTimer >= 4
	Set AnimTimer to 0
endif

If RSPlayerStatue.IsWeaponOut == 1
	RSPlayerStatue.setunconscious 1
	RSPlayerStatue.setdestroyed 1
endif

If AnimTimer >= 3
	RSPlayerStatue.skipanim
		set Frozen to 1
endif

If OneStatue == 1
	RSPlayerStatue.pms EffectStone
If Frozen == 0
	Set AnimTimer to ( AnimTimer + GetSecondsPassed )
endif
endif

If ( button == 0 ) && ( OneStatue == 1 )
	Message "Please remove current statue first"
endif

If ( button == 0 ) && ( OneStatue == 0 )
set RSPlayerStatue to player.CreateFullActorCopy
	RSPlayerStatue.setscale 2
	RSPlayerStatue.removeItem torch02 1000
	RSPlayerStatue.moveto RSPlayerStatueHereRef
	RSPlayerStatue.SetAlert 1
	RSPlayerStatue.setghost 1
Set OneStatue to 1
	Message "A statue has been made in your likeness"
Set Frozen to 0
endif

If ( button == 2 ) && ( OneStatue == 0 )
Message "No statue to remove"
endif

If ( button == 2 ) && ( OneStatue == 1 )
Message "Statue removed"
	Set OneStatue to 0
		Set AnimTimer to 0
		RSPlayerStatue.DeleteFullActorCopy
			DeleteFullActorCopy ; one of these lines is obselete, oh well
endif

If button == 1
return
endif
End

I will explain it so that anyone reading can have a better understanding.

1. When the statue is created and the short variable OneStatue is defined and set to 1. Frozen is also set to 0, this will be discussed later.

2.Inside the condition specifying that OneStatue has to equal 1 before the block is executed; a timer is initialised setting AnimTimer to ( Itself + GetSecondsPassed ). This will count how many seconds have passed since OneStatue == 1 but only if the Frozen == 0 argument remains true. Which it is for the time being.

3. As a precaution we have this line of code. It resets the timer if it goes outside of its intended range for application. That being 4 seconds in this instance.

If AnimTimer >= 4
 Set AnimTimer to 0

4. Now that we have established a timer with a range of 4 seconds, next we want some code to specify what happens when the desired amount of seconds have passed. If the amount of seconds that have passed is greater than or equal to 3 seconds the code is processed:

If AnimTimer >= 3
 RSPlayerStatue.skipanim
  set Frozen to 1

5. Now that Frozen == 1 our timer will no longer continue to be evaluated and the game will not have to process it. (This is done out of good practise).

Is it okay to have that on this page? Or should I move it somewhere more appropriate? Pretty sure thats all correct and hopefully simplifies the issue a bit. Personally I learn way better from seeing something like this in its application. If I'd had something like the above to look at I would have had it nailed long ago.
--Antares 00:16, 5 September 2008 (EDT)

Multiple uses whitin a script

I have just found that GetSecondsPassed DOES NOT reset to 0 when used. All calls within the same frame and script return the same value. Maybe the ‘reset to 0’ was true when the text was added in 2006. I changed the text and example. Although I am pretty sure of it, it would be good if somebody else confirmed it. QQuix 12:23, 5 September 2008 (EDT)

I am pretty sure you are correct here. My script wouldn't work as desired until I added a line of code to reset the timer to 0. See above Point 3 for more details.
--Antares 12:28, 5 September 2008 (EDT)
That's not what QQuix is talking about, Antares. He's referring to calling GetSecondsPassed more than once in a single frame. According to the note he removed, GetSecondsPassed would return 0 after the first time it was called. I don't remember who added that note, but I remember thinking it was odd but not bothering to test it.
Regardless, it's not really that big a deal. Caching the value of GetSecondsPassed would be good scripting habit, anyway.
Dragoon Wraith TALK 13:25, 5 September 2008 (EDT)
Belated confirmation, at least with object scripts in an onActivate block.
--Haama 20:38, 4 October 2008 (EDT)
As far as I can tell, at any given frame, GetSecondsPassed returns the same value to all object scripts. Next frame: different value, but the same different value to all scripts. For example: an object that is activated once per second should get a value around 1. Instead, it gets the same value as the calling ref. Another easy way to verify this is to create an object in an internal cell and script it to print GetSecondsPassed to the console every frame. Go in, check the console. Go out and come back in after a few seconds. The first run on the script should report a number compatible with the time you stayed out. But it always reports something like 0.0xxx.
Quest scripts do get a correct value, compatible with fQuestDelayTime, thou.
I also tried hard to get a 0 from GetSecondsPassed. Never did. No matter what: calling the same script several times in the same frame, several objects sharing the same script, etc.
As it is mostly used for timers running every frame, this may have passed unnoticed. Or maybe my game is broken, somehow. QQuix 23:31, 8 August 2009 (EDT)

Very strange indeed ! According to scruggsy, each script has a "time since last run" property that's actually what's being queried by getSecondsPassed. Have you tried moving a reference into scope ? That would start a previously stopped script, thereby returning a different value for getSecondsPassed ?
shadeMe TALK 17:06, 9 August 2009 (EDT)

Yes, both, by leaving the cell (so the script stops running) and going back and by leaving the cell and moving the object to the player after a few seconds. Also tried going in and out of trigger zones scripted to print the value returned by GetSecondsPassed in their OnTrigger blocks. In all cases, the very first line printed when the object enters into scope reports the exact same value as a player token running every frame without interruption.
I did read that scruggsy's text somewhere. He mentioned that the control was per script, not per object. So I tried 3 objects sharing the same script. Theoretically two of them should report 0. But all report the same 0.0xx value.
As there are knowledgeable people, like scruggsy, saying otherwise, I wonder if some of the reports were written based on the original Oblivion version, Maybe one of the patches changed this function's behavior. Or, again, my game is different/broken for some reason.
It would be nice if you, or somebody, could confirm. It is just a matter of placing the following script on an object in an internal cell, go in and out and check the console to see what comes out.
scn aaaTestSCRIPT float secs begin gamemode set secs to getsecondspassed printc "getsecondspassed = %0.4f" secs end
QQuix 19:16, 9 August 2009 (EDT)