Jump to content

Tutorial: tweaking anim positions on beds


Recommended Posts

Thinking about it, RefSurface works on statics as well as furniture, I used it for a billiards table after someone requested it. I suppose the offsets would work if they were figured out and added to the form lists.

 

Do you know if it is possible to change the angle in 3 dimensions? If so, I wonder if something similar could be used for uneven ground as well.

 

The SurfaceAngle var that Pride uses only adjusts the Z angle.

X and Y angle can probably be added, but I think the only real upshot would be in something like the Positioning mod, where players adjust manually based on what they're seeing, because it'd be hard to detect the unevenness of the ground through script.

 

Also, neither this tut nor the formlists provide offsets, just a method of calculating what "move x distance to the left" etc mean in terms of game trigonometry. Offsets can vary depending on both the anim and the actual ref's dimensions, which is why automatic bed positioning never got off the ground because we really needed a way to store x/y/z/angle offsets on a per-bed, per-anim basis if need be. With arrays, now we do, but it'd still be a lot of work getting the raw data in.

Link to comment

Great tutorial, since its pretty long winded and we have NVSE4 now, I wrote a UDF to do all the work, does this look correct (probably only the bottom 'what movement was requested is worth looking at'?

If so, perhaps Halstrom would be interested in adding it to SCR.

 

 

 

scn GetBedOffsets

; * Returns a stringmap containing all the offsets for the passed bed.
; * Note, it does all the validity checking you need, so you don''t need
; * to bother doing that yourself.
; * Example Usage:
;
; array_var Bed_Offsets
; ...
; let Bed_Offsets := call GetBedOffsets MyBedRef, "some direction", SomeDistance
; if Bed_Offsets
;     ; it worked, keys = "x", "y", "z", "a" (angle)
;     call fnSexoutActSetRef "RefSurface", MyBedRef
;     call fnSexoutActSetFloat "fSurfaceX", (SexoutNG.fSurfaceX + Bed_Offsets["x"])
;     call fnSexoutActSetFloat "fSurfaceY", (SexoutNG.fSurfaceY + Bed_Offsets["y"]0
;     call fnSexoutActSetFloat "fSurfaceZ", (SexoutNG.fSurfaceZ + Bed_Offsets["z"])
;     call fnSexoutActSetFloat "fSurfaceAngle", (SexoutNG.fSurfaceAngle + Bed_Offsets["a"])
; else
;     ; sorry, that furniture is invalid or unknown, you''ll have to screw in the dirt or make do.
; endif
; call fnSexoutActRun
;
; Written by Odessa based on the wisdom of DoctaSax (MD)


; * args
ref rBed              ; target furniture
string_var direction  ; "head", "left", "right", "feet", "vertical", "rotate" or "" (for just head angle)
float Dist            ; distance to move (or rotate)

; * local
float AngleHead
float AngleFeet
float AngleLeft
float AngleRight

float OffsetX
float OffsetY
float OffsetZ
float OffsetAngle


Begin Function { rBed, direction, Dist }

; * Validity Checking
    if eval !(IsFormValid rBed)
        DebugPrint "GetBedOffsets failed- passed invalid form"
        return
    elseif eval !(IsReference rBed)
        DebugPrint "GetBedOffsets failed- passed a non-reference: %n (%i)" rBed, rBed
        return
    elseif eval !(rBed.IsPersistent)
        DebugPrint "GetBedOffsets failed- passed a non-persistent ref: %n (%i)" rBed, rBed
        return
    elseif eval (GetType rBed) != 39
        DebugPrint "GetBedOffsets failed- passed a non-furniture: %n (%i)" rBed, rBed
        return
    endif
    
; * Is bed known?
    if rBed.IsInList SexoutSLFurnBedsHeadIsAngleZ
        let AngleHead := rBed.GetAngle Z
    elseif rBed.IsInList SexoutSLFurnBedsHeadIsAngleZ180
        let AngleHead := rBed.GetAngle Z + 180
    elseif rBed.IsInList SexoutSLFurnBedsHeadIsAngleZ90
        let AngleHead := rBed.GetAngle Z + 90
    elseif rBed.IsInList SexoutSLFurnBedsHeadIsAngleZ270
        let AngleHead := rBed.GetAngle Z + 270
    else
        DebugPrint "GetBedOffsets failed, unknown furniture: %n (%i)" rBed, rBed
        return
    endif
    let OffsetAngle := AngleHead

; * What movement was requested?
    if eval (direction == "")
        ; Pass
    elseif eval (direction == "Head")
        let OffsetX := Dist * (Sin AngleHead)
        let OffsetY := Dist * (Cos AngleHead)
    elseif eval (direction == "Left")
        let AngleLeft := AngleHead + 270
        let OffsetX := Dist * (Sin AngleLeft)
        let OffsetY := Dist * (Cos AngleLeft)
    elseif eval (direction == "Feet")
        let AngleFeet := AngleHead + 180
        let OffsetX := Dist * (Sin AngleFeet)
        let OffsetY := Dist * (Cos AngleFeet)
    elseif eval (direction == "Right")
        let AngleRight := AngleHead + 90
        let OffsetX := Dist * (Sin AngleRight)
        let OffsetY := Dist * (Cos AngleRight)
    elseif eval (direction == "Vertical")
        let OffsetZ := Dist
    elseif eval (direction == "Rotate")
        let OffsetAngle += Dist
    else
        Print "GetBedOffsets: Error - passed an unknown direction: '" + direction + "' by script: " + $(GetCallingScript)
        return
    endif

    SetFunctionValue (Ar_Map "x"::OffsetX, "y"::OffsetY, "z"::OffsetZ, "a"::OffsetAngle)

End

 

 

One thing I am a bit unsure about:

set sexoutNG.fSurfaceX to (sexoutNG.fSurfaceX + distance * sin fAngleRight)

 

Is the bold bit still valid/necessary?

 

(editted script slightly)

 

Could add it into SCR, I seem to recall having something about bed angles in there already or previously but not a UDF. But would it be better in Sexout itself or ZAZ?

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use