Jump to content

am stuck with a script that doesn't seem to be wrong, but still doesn't work


ZeroCore

Recommended Posts

Hi.

 

I'm trying to essentially do the same thing that the J3X levitation script did; make two platforms move, one by one, beneath the player to create essentially a Morrowind-style levitation script.

 

And I'm stuck on something.

 

The script seems to have good logic, but it won't work and when the player tries to activate the greater power that uses the script in a spell effect, the platforms don't move.

 

I've tried using static objects, activators, and movable static objects as platforms, but still nothing.

 

If someone can help me with this, I'd appreciate it.

 

 

 

 

I have the motion type set to keyframed because currently I'm trying to use a pair of movable static objects as the platforms.

 

Originally I was trying to use a pair of static objects, namely two of the circular rugs you find in some homes in Skyrim (both of which had reference ID's given to them). When that didn't work I went to a pair of activators, a pair of disk-shaped plates that form the middle of the blood seal at Skyhaven Temple (also given reference ID's), and then finally this, a pair of movable static objects (namely a pair of scaled-up golden dining plates from Sovngarde, which are plates that move like plates, but cannot be picked up by the player).

 

Here is the script in a spoiler menu:

 

 

 

 

 

Scriptname _YetAnotherFlightAttempt extends activemagiceffect  





ObjectReference Property FlyingCarpetA  Auto                ;these two contain the invisible rugs (round rugs with the null texture set put on their meshes; they are static objects)

ObjectReference Property FlyingCarpetB  Auto  



ObjectReference LoadedCarpet                ;the carpet that is currently set to be moved and tilted by the script



Actor ThePlayer                                             ;the Player



int SwitchInt                                                    ;This int is for a sort of switch that lets you move the two rugs/platforms independantly of one another when used in conjunction with an update and a conditional statement (an "if" statement)



float space



Function SetLocalAngle(Float LocalX, Float LocalY, Float LocalZ)

    float AngleX = LocalX * Math.Cos(LocalZ) + LocalY * Math.Sin(LocalZ)

    float AngleY = LocalY * Math.Cos(LocalZ) - LocalX * Math.Sin(LocalZ)

    LoadedCarpet.SetAngle(AngleX, AngleY, LocalZ)

EndFunction                                                    ;THIS FUNCTION IS VERY IMPORTANT. It rotates the rugs to where the player is facing and tilts them in the direction the player is looking. This is NEEDED as measurements and position adjustments in Skyrim are local to THE WORLD SPACE, and NOT the PLAYER OR ANY NPC'S, so in order to get the things set and angled LOCAL TO THE PLAYER, this bit of trig is needed.



EVENT onEffectStart(Actor akTarget, Actor akCaster)



    ThePlayer = akCaster

    SwitchInt = 1

    FlyingCarpetA.enable()

    FlyingCarpetB.enable()

    LoadedCarpet = FlyingCarpetA

    RegisterForUpdate(0.1)



EndEvent





EVENT onUpdate()



    space = LoadedCarpet.getDistance(ThePlayer)



if (!ThePlayer.isSneaking() && space > 60)



        if (SwitchInt == 1)



            LoadedCarpet = FlyingCarpetA

            LoadedCarpet.SetMotionType(LoadedCarpet.Motion_Keyframed)

            LoadedCarpet.moveto(ThePlayer)

            LoadedCarpet.SetPosition(ThePlayer.GetPositionX(), ThePlayer.GetPositionY(), ThePlayer.GetPositionZ() - 10)

            SetLocalAngle(ThePlayer.GetAngleX(), 0, ThePlayer.GetAngleZ())

            SwitchInt = 2

            RegisterForUpdate(0.1)



        elseIf (SwitchInt == 2)



            LoadedCarpet = FlyingCarpetB

            LoadedCarpet.SetMotionType(LoadedCarpet.Motion_Keyframed)

            LoadedCarpet.moveto(ThePlayer)

            LoadedCarpet.SetPosition(ThePlayer.GetPositionX(), ThePlayer.GetPositionY(), ThePlayer.GetPositionZ() - 10)

            SetLocalAngle(ThePlayer.GetAngleX(), 0, ThePlayer.GetAngleZ())

            SwitchInt = 1

            RegisterForUpdate(0.1)

            

        endIf

    



elseIf (!ThePlayer.isSneaking() && space < 60)



        RegisterForUpdate(0.1)



elseIf (ThePlayer.isSneaking())



        FlyingCarpetA.disable()

        FlyingCarpetB.disable()



endif



EndEvent

 

 

 

 

It didn't work.

 

And I don't know why. I've had some other modders look over it, and they couldn't figure it out either. If anyone can offer some help with this, I'd appreciate it.

Edited by ZeroCore
Link to comment
Share on other sites

Most likely it's the Havok settings on those items. J3X modified the Sovngarde plates by deleting the visible mesh and changing it to use a Havok collsion layer of ANIMSTATIC, the KEYFRAMED Motion System and Quality Types, and the LOW Solver Deactivation setting as well as a few other minor edits for that levitation mod.

 

I have a levitation spell I've never published and created my own platform (mainly because I didn't like the J3X's platforms cause chaos if used indoors).

 

You can find my InvisiblePlatform.nif in my Dropbox WIP folder if you want to use it or look at it. My version uses the STAIRHELPER collision layer since that one won't interact with clutter.

 

https://www.dropbox.com/sh/usf77ua06h1qh8k/AAA64msQbDbTfe3URb0mmC9Qa?dl=0

 

 

You might also be running into a problem with duration. Your ActiveMagicEffect script can only register for events and be active while effect itself is active. If your power doesn't have a duration you'll have to put the actual code to control the platforms in some other script (like a quest script).

 

Here's my version of a script that works with a concentration Levitation spell (which helpfully prevents the player from sprinting off the edge of the platform).

ScriptName CDC_LevitationScript extends ActiveMagicEffect 

ObjectReference[] property CDC_InvisiblePlatform auto
{Must be filled with two persistent references. 
Needs a nif with a STAIRHELPER Havok Layer, KEYFRAMED Motion and Quality, 
LOW Solver Deactivation, and flat collision plane (like a rug but invisible).}

Actor property PlayerRef auto

int ipNum  ; allows alternating between the two platform objects
bool active ; used as a signal to avoid trying to register again after the spell finishes

Event OnEffectStart(Actor akTarget, Actor akCaster)
	active = true
	CDC_InvisiblePlatform[0].EnableNoWait()
	CDC_InvisiblePlatform[1].EnableNoWait()
	OnUpdate() ; get platform placement system started
EndEvent

Event OnUpdate()
	float direction = PlayerRef.GetAngleZ()  ; horizontal angle
	float elevation = PlayerRef.GetAngleX()  ; vertical angle
	if elevation < -45  ; player can't walk on vertical surfaces so limit the angle
		elevation = -45
	elseif elevation > 45
		elevation = 45
	endif
	ipNum = 1 - ipNum  ; alternates the platform used
	CDC_InvisiblePlatform[ipNum].MoveTo(PlayerRef,0,0,0,false) ; move it directly under the player
	CDC_InvisiblePlatform[ipNum].SetAngle(Math.Cos(direction)*elevation, -Math.Sin(direction)*elevation, direction)
	if active  ; this check is trying to avoid showing an error in log file (but still doesn't always work)
		RegisterForSingleUpdate(0.01)  ; registering on such a short interval so the player can't run off the platform
	endif
EndEvent


Event OnEffectFinish(Actor akTarget, Actor akCaster)
	active = false
	CDC_InvisiblePlatform[0].DisableNoWait()
	CDC_InvisiblePlatform[1].DisableNoWait()
EndEvent

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...