Having a script constantly run while the player is in the ce

Post » Wed Jun 20, 2012 2:31 pm

Simple question, say I want a script to run as long as that player is in the cell (in this case, the script should constantly scroll the landscape).
How would I do that?
User avatar
..xX Vin Xx..
 
Posts: 3531
Joined: Sun Jun 18, 2006 6:33 pm

Post » Wed Jun 20, 2012 11:46 am

http://www.creationkit.com/GetParentCell_-_ObjectReference, http://www.creationkit.com/RegisterForUpdate_-_Form, http://www.creationkit.com/UnregisterForUpdate_-_Form

	Bool bQuickening	If bQuickening != (Game.GetPlayer().GetParentCell() == SpinningGearREF.GetParentCell())		bQuickening = !bQuickening		If bQuickening			RegisterForUpdate(Math.Pow(10, -23)) ; 0.000000000000000000000001		Else			UnregisterForUpdate()		EndIf	EndIf

Edit: RegisterForUpdate(0.01) is as fast as you'd really want to update. That is skip the Math.Pow part or change the -23 to -2.
User avatar
Jade Muggeridge
 
Posts: 3439
Joined: Mon Nov 20, 2006 6:51 pm

Post » Wed Jun 20, 2012 9:16 am

Alright, and where would I put my code to scroll the landscape in this?
User avatar
Stacyia
 
Posts: 3361
Joined: Mon Jul 24, 2006 12:48 am

Post » Wed Jun 20, 2012 3:42 pm

This is what I was trying to use for it, it'll initialize the variables, but it doesn't scroll the landscape, testing shows that it doesn't even use that piece of code.


Spoiler

Scriptname _movescripttest extends ObjectReference  {Should be the thing that scrolls the landscape}int initdone float xlimitfloat xstartfloat xnowBool bQuickeningEvent OnCellLoad()	if  (initdone == 0)		xstart = self.GetPositionY()		xlimit = xstart - 3000		initdone = 1	endIfEndEventFunction FunctionForUpdating()                         If bQuickening != (Game.GetPlayer().GetParentCell() == self.GetParentCell())                bQuickening = !bQuickening                If bQuickening                        RegisterForUpdate(Math.Pow(10, -23)) ; 000000000000000000000001                Else                        UnregisterForUpdate()                EndIf        EndIfEndFunctionEvent OnUpdate()	self.setPosition(self.GetPositionX(), (self.GetPositionY() - 2) ,self.GetPositionZ())	xnow = self.GetPositionY()	if (xnow > xlimit)		xnow = xlimit + 3000		self.setPosition(self.GetPositionX(), (xnow) ,self.GetPositionZ())	endifEndEvent
User avatar
Jon O
 
Posts: 3270
Joined: Wed Nov 28, 2007 9:48 pm

Post » Wed Jun 20, 2012 1:18 pm

I don't know what you mean by scrolling. From your code, you seem to want to quickly move the scripted object out of the player's current cell along the y axis.

But the reason it's not working is because your function isn't being called. Everything is supposed to be triggered through events. So you would need the OnInit even to call your FunctionForUpdating function...

Actually, you should just use RegisterForUpdate in your OnInit and put what you have in your function right now inside the OnUpdate.
User avatar
Skivs
 
Posts: 3550
Joined: Sat Dec 01, 2007 10:06 pm

Post » Wed Jun 20, 2012 12:53 pm

I don't know what you mean by scrolling. From your code, you seem to want to quickly move the scripted object out of the player's current cell along the y axis.

But the reason it's not working is because your function isn't being called. Everything is supposed to be triggered through events. So you would need the OnInit even to call your FunctionForUpdating function...

Actually, you should just use RegisterForUpdate in your OnInit and put what you have in your function right now inside the OnUpdate.

Scrolling as in the object moves a certain length, then resets, constantly. Done in say, a tunnel, it gives players the illusion that they are moving down the tunnel, when they're staying in place.
And by "OnInit" you mean the OnCellLoad part, correct? Or is it better to use OnInit in its place?
User avatar
naomi
 
Posts: 3400
Joined: Tue Jul 11, 2006 2:58 pm

Post » Wed Jun 20, 2012 9:27 pm

Well to move "Scenery" you will need to make a MovableStatic version of the object (Statics normally can't be moved) Once you have such a moveable static, you can use TranslateTo functions to move it around.
User avatar
Dezzeh
 
Posts: 3414
Joined: Sat Jun 16, 2007 2:49 am

Post » Wed Jun 20, 2012 9:01 am

Well to move "Scenery" you will need to make a MovableStatic version of the object (Statics normally can't be moved) Once you have such a moveable static, you can use TranslateTo functions to move it around.
I made the tunnel an activator, as I saw no option to attach a script to a Moveable Static. How would I do this otherwise?
User avatar
Portions
 
Posts: 3499
Joined: Thu Jun 14, 2007 1:47 am

Post » Wed Jun 20, 2012 4:12 pm

Ohhh... so you're going to put the player on a train or something inside a tunnel, then move the tunnel walls to give the illusion of the train moving?

And sorry, yes I meant OnCellLoad. And RedwoodElf is right, using TranslateTo would be much smoother, would not require so many checks and such, and the objects don't fade in and out.

I made the tunnel an activator, as I saw no option to attach a script to a Moveable Static. How would I do this otherwise?

Making it an activator is fine, but remember to use SetDestroyed so the player does not see the activation prompt. If you had it as a moveable static, then you would have needed to put the script on something else, reference the moveable static as a property, and perform functions on that property.
User avatar
Jack
 
Posts: 3483
Joined: Sat Oct 20, 2007 8:08 am

Post » Wed Jun 20, 2012 4:39 pm

I would used SetDestroyed when first initializing it correct?
User avatar
Tinkerbells
 
Posts: 3432
Joined: Sat Jun 24, 2006 10:22 pm

Post » Wed Jun 20, 2012 8:45 pm

I made the tunnel an activator, as I saw no option to attach a script to a Moveable Static. How would I do this otherwise?

You can attach scripts to them by making them aliases in a quest whose job is just to move the pieces around, and put the scripts on the aliases. I like using activators too, and for the same reason, you can attach scripts directly...If you are making a train, I'd put a periodic random camera shake script in there too to simulate rough spots in the "track" - the real trick will be making sure the wall sections all move at exactly the same speed and orientation so that gaps won't become visible between the pieces.

I'd probably put two wall sections ahead and behind of the player's possible field of view, and use OnTranslationFinish() to move each section back to the first one and start it moving again. By using the TranslateToRef functions, you can just MoveTo each one to it's starting point and set it going to the ending one.
User avatar
Sabrina Steige
 
Posts: 3396
Joined: Mon Aug 20, 2007 9:51 pm

Post » Wed Jun 20, 2012 10:02 am



You can attach scripts to them by making them aliases in a quest whose job is just to move the pieces around, and put the scripts on the aliases. I like using activators too, and for the same reason, you can attach scripts directly...If you are making a train, I'd put a periodic random camera shake script in there too to simulate rough spots in the "track" - the real trick will be making sure the wall sections all move at exactly the same speed and orientation so that gaps won't become visible between the pieces.

I'd probably put two wall sections ahead and behind of the player's possible field of view, and use OnTranslationFinish() to move each section back to the first one and start it moving again. By using the TranslateToRef functions, you can just MoveTo each one to it's starting point and set it going to the ending one.

Yep, that's the plan
User avatar
Jennifer May
 
Posts: 3376
Joined: Thu Aug 16, 2007 3:51 pm

Post » Wed Jun 20, 2012 12:23 pm

You could put this script on each of your wall sections:

Scriptname TunnelWallScript extends ObjectReferenceFloat property Speed autoObjectReference property StartPoint autoObjectReference property EndPoint autoBool Toggle = TrueEvent OnInit()    SetDestroyed()EndEventFunction ToggleMoving()    if (Toggle)        TranslateToRef(EndPoint, Speed, 0)    else        StopTranslation()    endif    Toggle = !ToggleEndFunctionEvent OnTranslationComplete()    MoveTo(StartPoint)    Toggle = True    ToggleMoving()EndEvent

Just have a trigger somewhere to call the 'ToggleMoving' function and begin the whole process.
User avatar
Emerald Dreams
 
Posts: 3376
Joined: Sun Jan 07, 2007 2:52 pm

Post » Wed Jun 20, 2012 11:11 am

Stopping them smoothly would be the hard part...Papyrus is slow, so stopping them all at the same time would be impossible. However, you could have each piece move to it's editor location on it's final move once the toggle is off instead of just stopping.
User avatar
David Chambers
 
Posts: 3333
Joined: Fri May 18, 2007 4:30 am

Post » Wed Jun 20, 2012 10:04 am

I'm not really clear on how triggers work, I'm going to guess it's another event. So I'm assuming I would use OnCellLoad?
User avatar
Ebou Suso
 
Posts: 3604
Joined: Thu May 03, 2007 5:28 am

Post » Wed Jun 20, 2012 11:58 am

Trainwiz: Don't actually use the Math.Pow(10, -23) for your RegisterForUpdate(). 0.1 is about as fast as you'd really want to go. Sorry, that part was a quickening joke.

Also, if that snippet is attached to an object reference, the function calls can be implicit, that is you can yank the 'Self' in all instances.
User avatar
Dean Ashcroft
 
Posts: 3566
Joined: Wed Jul 25, 2007 1:20 am

Post » Wed Jun 20, 2012 11:28 pm

Okay, for the StartPoint and EndPoint object references, what would I select or set them to?
User avatar
Emily abigail Villarreal
 
Posts: 3433
Joined: Mon Aug 27, 2007 9:38 am

Post » Wed Jun 20, 2012 6:13 pm

Okay, for the StartPoint and EndPoint object references, what would I select or set them to?

They would just be disabled copies of the wall sections, one at the position you want the wall pieces to start at, and one at the position you want them to finish up at. Something ilke this:

Scriptname MoveLoopObject Extends ObjectReferenceObjectReference Property StartPoint AutoObjectReference Property EndPoint AutoFloat Property Speed AutoBool Property ToggleFloat Property StartX AutoFloat Property StartY AutoFloat Property StartZ AutoFloat Property RotX AutoFloat Property RotY AutoFloat Property RotZ AutoEvent OnInit()   StartX = X   StartY = Y   StartZ = Z   RotX = GetAngleX()   RotY = GetAngleY()   RotZ = GetAngleZ() ; Saves editor location for final step.Event OnTranslationComplete()   MoveTo(StartPoint)   If Toggle	   TranslateToRef(EndPoint,Speed)   else	   TranslateTo(StartX,StartY,StartZ,RotX,RotY,RotZ,Speed) ; Go back to your start location.   endifEndEventEvent OnActivate()   If Toggle	  Toggle = False   else	  Toggle = True      TranslateToRef(EndPoint,Speed)   endifEndEvent

Set up a trigger when the player enters the area where he can almost (but not quite) see the moving walls. Set that trigger as the Activate parent of all your wall pieces. Select the disabled wall sections at the end and beginning of the movement path in the properties tab.

Have the trigger also hit the player with a small pushActorAway (enough to make the player stagger, but not knock him/her down) and start the camera shake and whatever sound loop you're going to use.
User avatar
Johanna Van Drunick
 
Posts: 3437
Joined: Tue Jun 20, 2006 11:40 am

Post » Wed Jun 20, 2012 4:14 pm

c:\program files (x86)\steam\steamapps\common\skyrim\Data\Scripts\Source\temp\MoveLoopObject.psc(8,6): mismatched input 'Property' expecting FUNCTION
c:\program files (x86)\steam\steamapps\common\skyrim\Data\Scripts\Source\temp\MoveLoopObject.psc(0,0): error while attempting to read script MoveLoopObject: Object reference not set to an instance of an object.

When compiling.

Nevermind, fixed that.
User avatar
SEXY QUEEN
 
Posts: 3417
Joined: Mon Aug 13, 2007 7:54 pm

Post » Wed Jun 20, 2012 5:24 pm

Alright, it sort of works. The thing scrolls.However, after a while huge gaps start to appear, probably has something to do with how they're reset.
User avatar
Veronica Flores
 
Posts: 3308
Joined: Mon Sep 11, 2006 5:26 pm

Post » Wed Jun 20, 2012 5:05 pm

More likely it has to do with a variation in the running speed of the various threads. Some threads may not be getting to the OnTranslationFinished() as quickly as others. You could set the ambient environment as pitch black and have the tunnel very poorly lit, that should make any gaps less obvious, hopefully.
User avatar
Rhi Edwards
 
Posts: 3453
Joined: Fri Jul 28, 2006 1:42 am

Post » Wed Jun 20, 2012 4:40 pm

The gaps are probably because of the delay from Papyrus processing the scripts... You can try to hide it by moving the walls back into position during the shaking camera from "bumps".

Modified version of the Redwood Elf's script:

Spoiler
Scriptname MoveLoopObject Extends ObjectReferenceObjectReference Property StartPoint AutoObjectReference Property EndPoint AutoFloat Property Speed AutoBool Property Toggle AutoEvent OnTranslationComplete()	MoveTo(StartPoint)	If Toggle		TranslateToRef(EndPoint,Speed)	else		MoveToMyEditorLocation()	endifEndEventEvent OnActivate()	If Toggle		Toggle = False		MoveToMyEditorLocation()	else		Toggle = True		TranslateToRef(EndPoint,Speed)	endifEndEvent

Instead of using the defaultActivateSelfTrig, use this custom script:

Spoiler
Scriptname TriggerScript extends ObjectReferenceSound Property MySound AutoFloat Property MaxInterval AutoFloat Property MinInterval AutoFunction SimulateBump(Bool bActivate = True)    if (bActivate)        Activate(Self)    endif    Game.GetPlayer().PushActorAway(Game.GetPlayer(), 1)    MySound.Play(Self)    Game.ShakeCamera()    if (bActivate)        Utility.Wait(0.1)        Activate(Self)    endifEndFunctionAuto State Inactive        Event OnBeginState()        Activate(Self)        SimulateBump(False)    EndEvent    Event OnTriggerEnter(ObjectReference TriggerRef)        if (TriggerRef == Game.GetPlayer())            GoToState("Active")        endif    EndEvent        Event OnUpdate()    EndEventEndStateState Active    Event OnBeginState()        Activate(Self)        SimulateBump(False)        RegisterForSingleUpdate(Utility.RandomFloat(MinInterval, MaxInterval))    EndEvent    Event OnTriggerLeave(ObjectReference TriggerRef)        if (TriggerRef == Game.GetPlayer())            GoToState("Inactive")        endif    EndEvent        Event OnUpdate()        SimulateBump()        RegisterForSingleUpdate(Utility.RandomFloat(MinInterval, MaxInterval))    EndEventEndState
User avatar
Miss K
 
Posts: 3458
Joined: Sat Jan 20, 2007 2:33 pm

Post » Wed Jun 20, 2012 11:54 pm

The gaps are far too big to hide with camera shaking. I remember a thing like this with the Morrowind version, I'm going to see if the same solution I used there works here.
User avatar
Darlene Delk
 
Posts: 3413
Joined: Mon Aug 27, 2007 3:48 am

Post » Wed Jun 20, 2012 5:53 pm

Is there any way to measure the length of a mesh?
User avatar
Nitol Ahmed
 
Posts: 3321
Joined: Thu May 03, 2007 7:35 am

Post » Wed Jun 20, 2012 11:25 am

Maybe the scripting functions GetLength or GetWidth. If those don't work, I guess you'll just have to load up the mesh in NifSkope or something.
User avatar
Melung Chan
 
Posts: 3340
Joined: Sun Jun 24, 2007 4:15 am

Next

Return to V - Skyrim