Jump to content

Is there a way to simulate a follower/NPC carrying the player?


Recommended Posts

Dear LL Community,

 

I'm working on a giantess/shrinking themed mod and it would be neat if I could have the follower "pickup" the player and carry them to a different location.

 

Could this be simulated by moving the player camera to a node on the follower skeleton, then disabling player controls or putting them under AI control? I have been able to approximate this using the follower procedure applied to the player but cannot get the player close enough to look like they are being "carried".

 

I also tried the moveto command but the player did not stay at the x/y/z specified near the follower and after being teleported there fell down to the ground. I also tried hover and orbit procedures applied to the player but not sure if these don't work or I incorrectly attempted to give the player the ability to fly first. Any other ideas?

 

Ideally, I would like the follower to be able to pickup the player and carry them in a fixed location on their skeleton node or inventory slot, while moving through a cell and while the player retains the ability to look around or even cast spells.

 

Is this even feasible through Papyrus?

 

Thanks!

 

 

Link to comment
  • 4 weeks later...

Thanks for mentioning that mod, will check it out. I was hoping there would be a "simple" solution that could fake it, like moving the camera or teleporting the player to an XYZ offset or node.

 

I've tried this (as well as other nodes) in an OnUpdate loop but it's glitchy as the player continuously falls down until placed back on the node by the loop. Have not been able to disable gravity for the player. Also, the NPC's body clips to invisible with the player camera moved so close. But it's kind of a step in the right direction, except I'm sure an intensive cloak script like this is a bad idea, right?

Quote

PlayerRef.SplineTranslateToRefNode(akFollower,"R Breast03", 2.0, 5000, 50)

 

Link to comment

Thanks, Traison! Very much appreciate your help. I will release this mod one day...

 

This bit of code is working more or less in an OnUpdate loop for positioning the player in the NPC cleavage:

 

float nodeX = NetImmerse.GetNodeWorldPositionX(akFollower,"NPC Belly",true)
float nodeY = NetImmerse.GetNodeWorldPositionY(akFollower,"NPC Belly",true)
float nodeZ = NetImmerse.GetNodeWorldPositionZ(akFollower,"NPC Belly",true)
float offsetX = nodeX + 7 * Math.Sin(akFollower.GetAngleZ())
float offsetY = nodeY + 7 * Math.Cos(akFollower.GetAngleZ())
PlayerRef.SplineTranslateTo(offsetX,offsetY,nodeZ + 12.0,0.0,0.0,0.0,1.0,5000,50.0)

 

It's a little wonky when the NPC moves as the SplineTranslateTo function can't really keep up but looks great as long as the NPC is stationary. Is there a low-latency way to check if the NPC is moving (short of using the XYZ from skeleton nodes?), then trigger moving the player between a NPC node for stationary use and one better for movement? (like the player is a pet on a leash dragged along behind while the NPC is walking and then picked up when stopped).

 

Also, the player is still playing the falling animation even though SetMotionType is '4' and even though trying to call a different Idle with PlayIdle. Not sure I'm applying Idles correctly.

 

PlayerRef.SetMotionType(PlayerRef.Motion_Keyframed)
PlayerRef.PlayIdle(TheIdle)

 

I was able to solve near body parts clipping by setting fNearDistance=1 in skyrimprefs.ini, but it would probably be better to enable/disable this as needed using ConsoleUtilSSE. I'm using this mod for the FOV console command to alter the player FOV dependent on scale.

 

I think these functions will cause a considerable papyrus performance hit, but this mod will be incompatible with the SexLab ecosystem anyway for necessary reasons.

 

player attached to node R Breast03

Link to comment

Papyrus generally is not low-latency anything, it wasn't made to do anything on-frame. Some functions are bound to the frame rate, as in, the function will return after the next frame has been processed. These are called latent functions. Some very unexpected functions are latent, such as some of the random number generators and Game.GetPlayer() if I'm not mistaken. The wiki has a whole page on these if you need it. I wouldn't be surprised if the timer precision behind the OnUpdate event was more along the lines of 0.5 seconds, rather than ~0.01 seconds which would be necessary to somewhat accurately hit the 0.016ms delay between frames (60 fps (only)).

 

There's this mod you can use to remove the hardcoded ops limit, allowing papyrus to run a lot faster (as percieved by a human) but in terms of programming languages its still insanely slow. Disable other options in that mod's ini (if it ain't broke, don't fix it), and set iMaxOpsPerFrame to a higher number (or 0). I have mine at 1500 right now, and all MCM menus are very fast (among other things).

 

I have never tried to detect actor movement on the skeleton level. The only situation where I had to do something similar, was when detecting whether a horse is walking, running or sprinting and for that I had to use x,y,z coordinates (i.e. DIY) and it was not a time-critical operation so I was able to do it in OnUpdate.

 

Edit: On the other hand, I haven't intentionally tried to run an infinite loop in Papyrus. Its probably not a good idea either, as you'll always have a stack frame stuck in the save, and one thread is pretty much always going to be working on this one script etc. However, if we assume your script is a magic effect, what happens if you start a While loop in EffectStart and do your updates there? You probably should have some very short Wait calls in there, but that may still be several times faster than waiting for OnUpdate.

 

Event OnEffectStart(Actor target, Actor caster)
  Running = true ; Defined in a higher scope
  While Running
    Utility.Wait(0.01) ; Latent, i.e. it will always wait for the next frame minimum, 0.01 should be enough for 60 fps
    
    ; TODO Do things here
  EndWhile
EndEvent

 

Edited by traison
Link to comment
  • 3 months later...

Hi Traison, not to necro this thread, but your suggestion to use a While loop was revolutionary... I've since converted most of the script logic to MagicEffect while loops and noticed a significant speed boost. Still not perfect but better than it was previously. Also, moving the player directly to the node instead of using an offset sped things up as well. Turns out there were way more useful nodes than I thought once I actually had a look in the skeleton nif with NifScope.

 

Thanks for your help!

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