ScriptName LevitationEffectScript ;******************************* ; Author: Saltare ; Email: Saltare_ferocan@hotmail.com ; Date: 26-09-2006 ; Version: 0.2 ; ; You may alter, rip, crush & destroy this piece of script as much as you want ^_~ ; ; Description: ; This script makes the player able to fly around ; It aims at having a good new movement feeling with clipping ; However certain velocity forces are lost (such as impact on hit) ; After experimenting with setting the position of the player i came to the following order of events ; ; new frame ; Oblivion adjusts the player position using, ; -intension of player to go ; -is in water/sneaking/jumping/stunned (change gravity, en movement speeds) ; -is hit by target (with additional force info), or other forces ; -add gravity and other forces ; Later then this script is runned ; ; The problem here is, that in scripting there is no way to access these pieces of info seperatly ; It all comes packed into a new xyz. ; Therefore this script tries to determine according to its own forces if there was a force change which doesn't ; comply with the previous frames position and intension of direction. ; If so then it assumes it was a collision with the world and resets the position for a certain axis ; ; Detecting clipping the gravity example ; if the player wants to go down it overrides the current Z with a new value ; At the next frame when the script is runned check if the player really did go down, ; if not then there was a collision ; ; Problems: ; Due to the simplicity of collision detection, the xy collision detection/response isn't really working. ; Resulting in weird behaviour and has been commented out for such. ; ; Requirements: ; Oblivion script extender. (Script was made using version v0008) ; Alexanders Wing. (visual effect of wings on the player) ;******************************* ;******************************* ; Note the axis in Oblivion are specified as follows ; X = Horizontal ; Y = Depth ; Z = Altitude Vertical ; XY are the 2D position on the map so to say ; and Z is the height of the character ;******************************* ;******************************* ; Positional data variables ;******************************* float velocityX float X float posX float velocityY float Y float posY float flowSpeed float customSpeedAdjuster float zAngle float zAngleCross float Z float velocityZ float oldZ float newZ float xAngle float posZ ;******************************* ;Indication if flying ;******************************* short isNotFlying ;******************************* ; Cell information ;******************************* short isInInteriorLocal ref CellLastFrame ;******************************* ; References ;******************************* ref self ref worldRef float changeTimer ;a quick and dirty solution for not changing wings too fast short forward short backward short strafeLeft short strafeRight short activateFlying short deactivateFlying short increaseSpeed short decreaseSpeed ;******************************* ; A timer to use as accellerator for indepent frame movement ; Get the passed time between frames. ;******************************* float timePassed short jumpCode ;******************************* ; Block: ScriptEffectStart (Constructor) ; Description: Initial start of the script ; Sets the initial values to the variables in use. ; Adjust game setting parameters. ;******************************* begin ScriptEffectStart set isInInteriorLocal to 0 ;******************************* ; initialize variables ;******************************* set oldZ to getPos z set X to getPos x set Y to getPos y set customSpeedAdjuster to 1 set isNotFlying to 1 set self to GetSelf set CellLastFrame to self.GetParentCell set worldRef to Tamriel ;CellLastFrame.GetParentRef set changeTimer to 0.5 ; 0.5 seconds ;******************************* ; Try to find out the current assigned jump key ; Note: doesn't seem to work, getting a 0 as value returned ; Using hardcoded keycodes ;******************************* ;set jumpCode to GetControl 13 ;message "jumpcode is %i", jumpCode ;******************************* ; Key bindings ;******************************* set forward to 17 set backward to 31 set strafeLeft to 30 set strafeRight to 32 set activateFlying to 22 set deactivateFlying to 36 set increaseSpeed to 33 set decreaseSpeed to 34 ;******************************* ;Note: ;function GetAngle ;X angle returns a value (theorically) from -90 to 90. The true in-game range is -89 to 89, ;with -89 if the player is looking above himself, and 89 if player is looking at his feet. ;******************************* end ;******************************* ; Block: ScriptEffectFinish ; Description: Stops the script (Destructor) ; Reset certain game setting values ;******************************* begin ScriptEffectFinish end ;******************************* ; Block: ScriptEffectUpdate ; Description: Loop the script ; Unleashes the flying algoritm ^_~ ;******************************* begin ScriptEffectUpdate ;******************************* ;get the time passed from the last frame ;returns a nice float with good enough accurancy ;******************************* set timePassed to GetSecondsPassed set Z to getPos z set velocityZ to 0 ;******************************* ; Check if we have changed from cell, then we need to adjust the position ;******************************* if( CellLastFrame != self.GetParentCell ) set CellLastFrame to self.GetParentCell if(isNotFlying == 0) if(isInInteriorLocal == 0 && IsInInterior == 0) ;changing from exterior cell to another (however the new cell can belong to another worldspace ;A crude workaround for not being able to get the Worldspace ID ;Currently i don't know a way to detect if the player changed from world space type ;okay i do know one, but that solution sucks even more (by using handtyped checks on all possible worldspaces) ;i know this is also ridiculous crappy, but i hope it is only temporary >_< set newZ to getPos x - X ;reusing the variable newZ (is going to be set later on anyway) if( newZ > 200 || newZ < -200 ) ;detect a sudden change on the x-axis set oldZ to getPos z + 20 set X to getPos x set Y to getPos y endif set newZ to getPos y - Y if( newZ > 200 || newZ < -200 ) ;detect a sudden change on the y-axis set oldZ to getPos z + 20 set X to getPos x set Y to getPos y endif else set isInInteriorLocal to IsInInterior set oldZ to getPos z+20 set X to getPos x set Y to getPos y Message "Entering new cell - in/out", 10 endif endif endif ;******************************* ; Check if we want to go flying, if so set initial vars ;******************************* if ( iskeypressed2 activateFlying && isNotFlying) set isNotFlying to 0 set oldZ to Z set X to getPos x set Y to getPos y endif ;******************************* ; If not flying stop script for current frame ;******************************* if( isNotFlying) return endif ;******************************* ; If Key T is pressed or is gone swimming .. then stop flying ;******************************* if(iskeypressed2 deactivateFlying || isSwimming ) set isNotFlying to 1 return endif set zAngle to GetAngle z set xAngle to GetAngle x set velocityX to 0 set velocityY to 0 ;******************************* ;Movement ;******************************* if( isKeyPressed2 forward) ;******************************* ; adjust fly behaviour ;******************************* if ( xAngle < 0 ) set flowSpeed to 1 + xAngle * 0.01111111 ; else if (xAngle <= 45) set flowSpeed to 1 + xAngle * 0.0222222 ; else set flowSpeed to 2 - ((xAngle - 44) * 0.0444444) ; endif endif set flowSpeed to flowSpeed * customSpeedAdjuster set velocityX to Sin zAngle * flowSpeed set velocityY to Cos zAngle * flowSpeed set velocityZ to timePassed * -20 * xAngle endif if( isKeyPressed2 strafeLeft ) set zAngleCross to zAngle - 90 ;going left set velocityX to velocityX + Sin zAngleCross set velocityY to velocityY + Cos zAngleCross endif if( isKeyPressed2 backward ) set zAngleCross to zAngle + 180 ;going back around set velocityX to velocityX + Sin zAngleCross set velocityY to velocityY + Cos zAngleCross set velocityZ to timePassed * 10 * xAngle endif if( isKeyPressed2 strafeRight ) set zAngleCross to zAngle + 90 ; going right set velocityX to velocityX + Sin zAngleCross set velocityY to velocityY + Cos zAngleCross endif if ( iskeypressed2 activateFlying ) set velocityZ to velocityZ + 20 ; going up endif if( iskeypressed increaseSpeed) set customSpeedAdjuster to customSpeedAdjuster + 0.1 elseif( iskeypressed decreaseSpeed) set customSpeedAdjuster to customSpeedAdjuster - 0.1 if ( customSpeedAdjuster <= 1 ) set customSpeedAdjuster to 1 endif endif set velocityX to velocityX * timePassed * 500 ; 500 a fixed multiplyer for the time value set velocityY to velocityY * timePassed * 500 ;set posX to getPos x - X ;set posY to getPos y - Y ;******************************* ;some failed attempt to have some sort of collosion detection ;uncomment to see what happens, only works when flying slow :/ ;******************************* ; if ( velocityX >=0 && posX <= 0) || ( velocityX <=0 && posX >= 0) ; set X to getPos x ; else set X to X + velocityX ; endif ; if ( velocityY >=0 && posY <= 0) || ( velocityY <=0 && posY >= 0) ; set Y to getPos y ; else set Y to Y + velocityY ; endif ;******************************* ;simple collision detection on height ;if going down and prevFrameZ is lower then getPos z then assume collision ;******************************* if ( velocityZ < 0 && oldZ < Z) Set velocityZ to 0 set isNotFlying to 1 endif set newZ to oldZ + velocityZ ;******************************* ;if hanging around or going up and the newZ is still lower then the getPos z then assume being to low (collision) ;******************************* if ( velocityZ >= 0 && newZ < Z) set isNotFlying to 1 set newZ to Z endif ;******************************* ; Set new xyz position ;******************************* setPos y, Y setPos x, X setPos z, newZ set oldZ to newZ ;For some reason setScale prevent you from falling down (thus no gravity), but it also completly resets the animation ;self.setscale 1.0 resetFallDamageTimer end