Need help with some movement scripts

Post » Thu Dec 24, 2009 2:58 pm

It's a script that makes an elevator move up and down, but I use it as a template for anything that moves between two points. DEMNwelevator, as the elevator works by moving the actual walls and doors, not the car itself.

Begin DEM_Elevator_ButtonShort doonceIf (OnActivate == 1)	If (doonce == 0)		Set doonce to 1		Set DEMNwelevator to 1ElseIf (OnActivate == 1) If (doonce == 1)	Set DEMNwelevator to 2	Set doonce to 0EndifEndifEndifEndifEnd


And the code that controls the movement of the elevator

Begin DEM_Elevatorscriptfloat timerif ( MenuMode == 1 )	return	endifIf ( DEMNwelevator == 1)	Set timer to ( timer + GetSecondsPassed )If (timer <= 26)	MoveWorld Z -270If (timer == 27)	set timer to 0set DEMNwelevator to 0EndifendifendifIf ( DEMNwelevator == 2)	Set timer to ( timer + GetSecondsPassed )If (timer <= 26)	MoveWorld Z 270If (timer == 27)	set timer to 0set DEMNwelevator to 0Endifendifendifend



The elevator goes up fine, but doesn't go down at all, which is rather annoying.
I've tried multiple variations on this, but so far nothing works.
User avatar
Jake Easom
 
Posts: 3424
Joined: Sun Jul 29, 2007 4:33 am

Post » Fri Dec 25, 2009 1:19 am

In the elevator script, on line 14, I notice that you are checking the condition "timer == 27" which leaves the door open for the reset block below it to never run. Have you tried using "timer >= 27" (in both instances)?
User avatar
Alex [AK]
 
Posts: 3436
Joined: Fri Jun 15, 2007 10:01 pm

Post » Thu Dec 24, 2009 11:34 am

I see a few potential problems when viewing the code properly indented:

Begin DEM_Elevator_ButtonShort doonceIf (onactivate == 1)    If (doonce == 0)        Set doonce to 1        Set DEMNwelevator to 1    Else        If (onactivate == 1)            If (doonce == 1)                Set DEMNwelevator to 2                Set doonce to 0            Endif        Endif    EndifEndifEnd

Multiple OnActivate checks in the same script can be problematic. Since you nested one inside the other it may be that the second check does not occur preventing the global from being set to 2 (instructing the elevator to descend).

Even if that part is working there is an error in the elevator script that prevents the timer from being reset and allowing any time for the elevator to descend:

Begin DEM_Elevatorscriptfloat timerif ( MenuMode == 1 )    returnendifIf ( DEMNwelevator == 1)    Set timer to ( timer + GetSecondsPassed )    If (timer <= 26)        MoveWorld Z -270        If (timer == 27)	            set timer to 0            set DEMNwelevator to 0        Endif    endifendifIf ( DEMNwelevator == 2)    Set timer to ( timer + GetSecondsPassed )    If (timer <= 26)        MoveWorld Z 270        If (timer == 27)	            set timer to 0            set DEMNwelevator to 0        Endif    endifendifend

When timer exceeds 26 the first condition cannot be satisfied preventing the check for timer == 27. Also it is not a good idea to check a float variable for an integer value - it is very unlikely to be true.

Here is my suggestion for your two scripts:

Begin DEM_Elevator_Buttonshort doOnceif ( OnActivate == 1 )    if ( doOnce == 0 )        set doOnce to 1        set DEMNwelevator to 1 ; ascend    elseif ( doOnce == 1 )        set doOnce to 0        set DEMNwelevator to 2 ; descend    endifendifEnd DEM_Elevator_Button


Begin DEM_Elevatorscriptfloat timerif ( menumode == 1 )    returnendifif ( DEMNwelevator == 1 ) ; ascend    set timer to ( timer + GetSecondsPassed )    if (timer <= 26)        MoveWorld Z -270    else        set timer to 0        set DEMNwelevator to 0    endifendifif ( DEMNwelevator == 2 ); descend    set timer to ( timer + GetSecondsPassed )    if (timer <= 26)        MoveWorld Z 270    else        set timer to 0        set DEMNwelevator to 0    endifendifEnd DEM_Elevatorscript

You could accomplish this with a local variable declared in the elevator script rather then with the global DEMNwelevator.
User avatar
Astargoth Rockin' Design
 
Posts: 3450
Joined: Mon Apr 02, 2007 2:51 pm

Post » Thu Dec 24, 2009 12:44 pm

No dice, it moves up, but not down.
User avatar
Andrea P
 
Posts: 3400
Joined: Mon Feb 12, 2007 7:45 am

Post » Fri Dec 25, 2009 2:15 am

Been working on this all day, and nothing really seems to work.
All it truly does is travel up, but never down, that's what I've observed.
User avatar
Nany Smith
 
Posts: 3419
Joined: Sat Mar 17, 2007 5:36 pm

Post » Fri Dec 25, 2009 12:30 am

Do you use the same button for moving up and down, or two buttons with the same script at each end?
User avatar
stevie critchley
 
Posts: 3404
Joined: Sat Oct 28, 2006 4:36 pm

Post » Thu Dec 24, 2009 9:32 pm

Assuming that DEMNwelevator is a global variable and there is a button a the top and bottom of the elevator then modifying cyran0's script as follows should do it.
Begin DEM_Elevator_Button; DEMNwelevator == 0 for elevator at lower station; DEMNwelevator == 1 for elevator ascending; DEMNwelevator == 2 for elevator at upper station; DEMNwelevator == 3 for elevator descendingif ( OnActivate == 1 )    if ( DEMNwelevator == 0 )        set DEMNwelevator to 1 ; ascending    elseif ( DEMNwelevator  == 2 )        set DEMNwelevator to  3; descending    endifendifEnd DEM_Elevator_Button


Begin DEM_Elevatorscriptfloat timerif ( menumode == 1 )    returnendifif ( DEMNwelevator == 1 ) ; ascend    set timer to ( timer + GetSecondsPassed )    if (timer <= 26)        MoveWorld Z -270    else        set timer to 0        set DEMNwelevator to 2     endifendifif ( DEMNwelevator == 3 ); descend    set timer to ( timer + GetSecondsPassed )    if (timer <= 26)        MoveWorld Z 270    else        set timer to 0        set DEMNwelevator to 0    endifendifEnd DEM_Elevatorscript

User avatar
Kelvin
 
Posts: 3405
Joined: Sat Nov 17, 2007 10:22 am

Post » Thu Dec 24, 2009 11:06 pm

Also, it's better check the stopping condition not by timer but by terminal position, as it won't tend to drift after multiple launches:
Begin DEM_Elevatorscriptshort CurrentZif ( menumode == 1 )    returnendifif ( DEMNwelevator == 1 ) ; ascend    set CurrentZ to GetPos, z    if ( CurrentZ <= #TopZ ) && <= replace with number        MoveWorld Z 270    else        set timer to 0        set DEMNwelevator to 2     endifendifif ( DEMNwelevator == 3 ); descend    set CurrentZ to GetPos, z    if ( CurrentZ >= #BottomZ ) && <= replace with number        MoveWorld Z -270    else        set timer to 0        set DEMNwelevator to 0    endifendifEnd DEM_Elevatorscript

User avatar
joseluis perez
 
Posts: 3507
Joined: Thu Nov 22, 2007 7:51 am

Post » Fri Dec 25, 2009 2:35 am

Will that script work if it's acting on multiple objects though, because the position for each will be different.
User avatar
Add Meeh
 
Posts: 3326
Joined: Sat Jan 06, 2007 8:09 am

Post » Thu Dec 24, 2009 9:05 pm

Made an interesting observation. Used the code that Nicoliathan provided, except split

Begin DEM_Elevator_Button; DEMNwelevator == 0 for elevator at lower station; DEMNwelevator == 1 for elevator ascending; DEMNwelevator == 2 for elevator at upper station; DEMNwelevator == 3 for elevator descendingif ( onactivate == 1 )    if ( DEMNwelevator == 0 )        set DEMNwelevator to 1 ; ascending    elseif ( DEMNwelevator  == 2 )        set DEMNwelevator to  3; descending    endifendifEnd DEM_Elevator_Button


into two parts, one for the up button, the other for the down button.

Begin DEM_Elevator_Buttonif ( onactivate == 1 )    if ( DEMNwelevator == 0 )        set DEMNwelevator to 1 ; ascending    endifendifEnd DEM_Elevator_Button


Begin DEM_Elevator_Button2; DEMNwelevator == 0 for elevator at lower station; DEMNwelevator == 1 for elevator ascending; DEMNwelevator == 2 for elevator at upper station; DEMNwelevator == 3 for elevator descendingif ( onactivate == 1 )    if ( DEMNwelevator  == 2 )        set DEMNwelevator to  3; descending    endifendifEnd DEM_Elevator_Button2


What I also did, was set the elevator to play a sound when the descent or ascent finished.

Begin DEM_Elevatorscriptfloat timerif ( menumode == 1 )    returnendifif ( DEMNwelevator == 1 ) ; ascend    set timer to ( timer + GetSecondsPassed )    if (timer <= 26)        MoveWorld Z -270   else        PlaySound "Dingsound"        set timer to 0        set DEMNwelevator to 2 	    endifendifif ( DEMNwelevator == 3 ); descend    set timer to ( timer + GetSecondsPassed )    if (timer <= 26)        MoveWorld Z 270     else	PlaySound "windsound"        set timer to 0        set DEMNwelevator to 0	endif     endifendifEnd DEM_Elevatorscript


Now, here's the kicker. When it gets to the top, it plays the Dingsound, and when the up button is pressed again, it plays Dingsound.
And when the down button is pressed, it plays the windsound, and doesn't descend.
User avatar
carley moss
 
Posts: 3331
Joined: Tue Jun 20, 2006 5:05 pm

Post » Thu Dec 24, 2009 8:36 pm

Figured it out. Apparently the timer, while at the end of 26 seconds, resets to 0, it doesn't stop counting.
Adding a second timer allows it to go up or down, but only once for each.
User avatar
Stat Wrecker
 
Posts: 3511
Joined: Mon Sep 24, 2007 6:14 am

Post » Thu Dec 24, 2009 2:14 pm

Finally got it working.
Added a check that forces the timers to be 0 depending on the position. Works smoothly and perfectly.
User avatar
Shelby McDonald
 
Posts: 3497
Joined: Sat Jan 13, 2007 2:29 pm


Return to III - Morrowind