DoctaSax Posted September 8, 2014 Author Posted September 8, 2014 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.
Halstrom Posted September 8, 2014 Posted September 8, 2014 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?
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now