Jump to content

Do something while a SexLab animation is running?


Recommended Posts

Posted

Working on getting JUGs to integrate with SGO.

 

darkconsole gave me some code to hook into SGO's API without having SGO as a master and it works! (yay!)

But it only removes 1 milk. It actually transfers 1 from giver to receiver. (yay!)

 

So I do this in dialogue and script fragments.

 

Right now I have this:

;BEGIN CODE
actor[] sexActors = new actor[2]
sexActors[0] = akSpeaker
sexActors[1] = Game.GetPlayer()
sslBaseAnimation[] anims
anims = new sslBaseAnimation[1]
anims[0] = SexLab.GetAnimationByName("3J Straight Breastfeeding")
SexLab.StartSex(sexActors, anims)


If(Game.GetModByName("soulgem-oven.esp") != 255)
    sgo_QuestController SGO = Game.GetFormFromFile(0x12c6,"soulgem-oven.esp") as sgo_QuestController
    SGO.GiveMilk(akSpeaker,Game.GetPlayer(),1,false)
EndIf
;END CODE

with SexLab property declaration and JUGs declared etc, but above is the meat of the fragment.

 

What I'd LIKE to have happen, is for 1 milk to be transferred like every 3 to 5 seconds for as long as the animation is playing (or until the tank is empty so to speak)

 

Waiting for darkconsole to get back to me in PMs, but I'm an impatient bastard and thought I'd ask here in case someone just plain knew how to do it easily. :)

 

Posted

Hello Chajapa,

 

you can do it in a couple of ways, but you require a little bit more coding.

 

Option 1: using SexLab events.

Option 2: using a timer event based cycle to check if the animatin is still running and then do the milk-swap with SGO.

 

In both cases you need a little script, my recommendation is to put it inside your main quest (the one is holding your dialogues, for example.)

 

If this is ok for you, I can write an example code for you.

Please keep in mind that I don't know too much SGO, so probably I will write just code wrappers to invoke SGO functions.

 

Posted

Anything is ok with me. :) 

 

I was going to try something like this:

If(Game.GetModByName("soulgem-oven.esp") != 255)
    sgo_QuestController SGO = Game.GetFormFromFile(0x12c6,"soulgem-oven.esp") as sgo_QuestController

while (SGO.GetMilkCount >= 1)
      SGO.GiveMilk(akSpeaker,Game.GetPlayer(),1,false)
      Utility.Wait(3.0)
endwhile
endif

But you're right about me needing to check and see if the animation is still running.

Posted

This code has not maximum efficiency.

 

I will give you some example of code way more efficient that you can use.

 

But probably tomorrow.

Posted

What I'd LIKE to have happen, is for 1 milk to be transferred like every 3 to 5 seconds for as long as the animation is playing (or until the tank is empty so to speak)

 

 

One way would be to cycle through OnUpdate events until one of the participating actors has ceased (sexlab) animating. So when you begin the animation, call the DuringAnimation function from below:

Function DuringAnimation()
    GotoState("MilkCollection")
    RegisterForSingleUpdate(5.0)
endfunction


State MilkCollection
    Event OnUpdate()

        Bool bKeepUpdating = True

        if (SexLabUtil.IsActorActive(Actor))
            ;your code to tranfer milk(!?)
        else
            bKeepUpdating = false
        endif

        If bKeepUpdating
            RegisterForSingleUpdate(5.0)
        Endif

    EndEvent
EndState

I've used a similar method before to vibrate the controller every few seconds during an animation but you could do whatever you wished.

Posted

one thing that comes up here is my "code to transfer milk" currently has to be written at least 3 different ways

 

PlayerRef to akSpeaker

akSpeaker to PlayerRef

Alias_Follower to akSpeaker

 

I'm looking at this and thinking.... if I look at the animation actors, actor[0] is always the "giver" and actor[1] is always the receiver.

 

So if I have:

SGO.GiveMilk(akSpeaker,Game.GetPlayer(),1,false)

in that example, akSpeaker is the "giver" and the Player is the "receiver". SGO.GiveMilk(from who, to whom, how many, DoAnimation true/false)

 

Is there an easy way to get actor[0] and actor[1] to always be in those spots?

 

 

Posted

 

What I'd LIKE to have happen, is for 1 milk to be transferred like every 3 to 5 seconds for as long as the animation is playing (or until the tank is empty so to speak)

 

 

One way would be to cycle through OnUpdate events until one of the participating actors has ceased (sexlab) animating. So when you begin the animation, call the DuringAnimation function from below:

Function DuringAnimation()
    GotoState("MilkCollection")
    RegisterForSingleUpdate(5.0)
endfunction


State MilkCollection
    Event OnUpdate()

        Bool bKeepUpdating = True

        if (SexLabUtil.IsActorActive(Actor))
            ;your code to tranfer milk(!?)
        else
            bKeepUpdating = false
        endif

        If bKeepUpdating
            RegisterForSingleUpdate(5.0)
        Endif

    EndEvent
EndState

I've used a similar method before to vibrate the controller every few seconds during an animation but you could do whatever you wished.

 

 

I like this idea, but can you elaborate a little?

This would all go in my mod's main script, I'm assuming. And in the dialogue script fragment I call the function. I'd have to look up how to call a function from within a script fragment again. But.... whatever...

 

in this line:

if (SexLabUtil.IsActorActive(Actor))

..would I change (Actor) to something like (akSpeaker)?

 

In the different scenarios, akSpeaker is always part of the action either milking the player or an Alias_Follower, OR akSpeaker sometimes IS a follower or a member of JUGs who is BEING milked, so akSpeaker is always involved as EITHER the "giver of milk" or the "receiver of milk"

Posted

 

 

 

 

I like this idea, but can you elaborate a little?

This would all go in my mod's main script, I'm assuming. And in the dialogue script fragment I call the function. I'd have to look up how to call a function from within a script fragment again. But.... whatever...

 

in this line:

if (SexLabUtil.IsActorActive(Actor))

..would I change (Actor) to something like (akSpeaker)?

 

In the different scenarios, akSpeaker is always part of the action either milking the player or an Alias_Follower, OR akSpeaker sometimes IS a follower or a member of JUGs who is BEING milked, so akSpeaker is always involved as EITHER the "giver of milk" or the "receiver of milk"

 

 

Ok, let's do a quick tutorial:

 

Let's suppose your main quest is called Juggs, and there is a script inside called JuggsScript (these names are just my idea, you can use whatever names you like.)

 

Now, you start the animation through a dialogue, so your code is inside a TopicFragment (and you get from here the akSpeaker that is the NPC that is speaking to the player.)

 

In the main script code add two functions (similar to the ones laurall wrote.

bool Property isMilkTransfered Auto ; "This property let you understand if the milk is being tranfered and let you to stop if required"
Actor Property theMilkGiver Auto
Actor Property theMilkReceiver Auto
Form SGO ; this is a sgo_QuestController, no special cast here to avoid dependencies
Faction Property SexLabAnimatingFaction Auto

; "This is called at the bagin of the code, and checks if SGO is available"
Event OnInit()
  SGO = None  If(Game.GetModByName("soulgem-oven.esp") != 255)
    SGO = Game.GetFormFromFile(0x12c6,"soulgem-oven.esp")
  EndIfEndEvent

; "This is your function-to-call just after the animation starts"
Function StartMilkTransfer(Actor giver, Actor receiver)
  isMilkTransfered = True ; "Let's start the milk transfer"
  theMilkGiver = giver  ; "This will set the actors passed as parameter of the function (receiver)"
  theMilkReceiver = receiver ; "This will set the actors passed as parameter of the function (receiver)"
  RegisterForSingleUpdate(1.0) ; "This will call the OnUpdate event in one second"
EndFunction

; "This event is internal and it is used to transfer one unit of milk every 3 to 5 seconds."
Event OnUpdate()
  ; "We will stop if the variable is false, or the milk giver or the milk receiver are no more animating"
  if !isMilkTransfered || !theMilkGiver.isInFaction(SexLabAnimatingFaction) || !theMilkReceiver.isInFaction(SexLabAnimatingFaction)
    unregisterForUpdates()
    Return ; " This will stop until the next cycle"
  endIf

  if SGO ; "SGO is here because it is not None"
    ; "Transfer the milk using SGO"
    (SGO as sgo_QuestController).GiveMilk(theMilkGiver,theMilkReceiver,1,false)

    ; " Here you may want to understand if the giver has still milk, ... if not you can set the varaible isMilkTransfered to false and exit"

    RegisterForSingleUpdate(Utility.RandomFloat(3.0, 5.0)) ; "This will call again the OnUpdate in an amount of time between 3 secs and 5 secs."
  endIf
EndEvent

Now, in your TopicFragments, you should know who is the giver and who is the receiver. E.g. a dialogue like "Can you give some milk to the follower?" the giver will be the akSpeaker, and the Follower will be the receiver.

In a dialogue like "Do you want some milk from me?", the Player will be the giver and the akSpeaker will be the receiver.

 

 

So, in a topic fragment, just add a new magical property:

JuggsScript property jgs Auto

And set it to your main quest.

 

 

Then inside the topic fragment, maybe just after you start the animation (Ashal just added the breastfeeding tags), add this line:

jgs.StartMilkTransfer(akSpeaker, PlayerRef) ; "in case the speaker gives milk to the player"

or

jgs.StartMilkTransfer(Follower_Ref.getActorRef(), akSpeaker) ; "in case your follower gives milk to the speaker"

or

jgs.StartMilkTransfer(PlayerRef, akSpeaker) ; "in case the player gives milk to the speaker"

The milk transfer will end when the animation is completed. (Because the actors will be no more in the SexLabAnimatingFaction.)

You may want to use another SGO function to understand if the give has still enough milk... If not you can stop the milk transfer or also stop the animation...

 

 

Hope this helps.

 

 

 

Posted

 

I like this idea, but can you elaborate a little?

This would all go in my mod's main script, I'm assuming. And in the dialogue script fragment I call the function. I'd have to look up how to call a function from within a script fragment again. But.... whatever...

 

in this line:

if (SexLabUtil.IsActorActive(Actor))

..would I change (Actor) to something like (akSpeaker)?

 

In the different scenarios, akSpeaker is always part of the action either milking the player or an Alias_Follower, OR akSpeaker sometimes IS a follower or a member of JUGs who is BEING milked, so akSpeaker is always involved as EITHER the "giver of milk" or the "receiver of milk"

 

 

I would have a seperate script attached to the quest which contains most of the logic, it is better for reuse. You would have to pass the akspeaker actor value. The Actor value can be any actor involved in the animation. You can add scripts as properties of other scripts to gain access to their functions.

 

 

Posted

OK, I know I'm going backwards a bit here, but....

 

If I have THIS:

;BEGIN CODE
actor[] sexActors = new actor[2]
sexActors[0] = akSpeaker
sexActors[1] = Game.GetPlayer()
sslBaseAnimation[] anims
anims = new sslBaseAnimation[1]
anims[0] = SexLab.GetAnimationByName("3J Straight Breastfeeding")
SexLab.StartSex(sexActors, anims)

Can I use sexActors[] like THIS:

If(Game.GetModByName("soulgem-oven.esp") != 255)
    sgo_QuestController SGO = Game.GetFormFromFile(0x12c6,"soulgem-oven.esp") as sgo_QuestController
    SGO.GiveMilk(SexLab.sexActors[0],SexLab.sexActors[1],1,false)
EndIf

The parameters for that SGO.GiveMilk function are (Giver, Receiver, HowMany, Animate true/false) since we're already animating when I call this it's always false for the animate parameter.

 

sexActors[0] is always giver

sexActors[1] is always receiver

 

I have the SexLab property declared as follows:

 

SexLabFramework Property SexLab  Auto
JugsMain Property Jugs Auto

If I can find a way to directly use sexActors[0] and [1] like this, then it doesn't matter who the reference is, it should always be correct.... in theory :)

 

Posted

The sexActors you are defining in the first piece of code, is NOT the SexLab.sexActors.

You should really put all this code in a single function somewhere else and just call it inside the Topic Fragment.

 

Posted

The sexActors you are defining in the first piece of code, is NOT the SexLab.sexActors.

You should really put all this code in a single function somewhere else and just call it inside the Topic Fragment.

 

Understood. I'm trying to figure out a way to not need 3 or 4 different variations on the GiveMilk function.

 

In these dialogues sexActors[0] is always the giver, but could be:

sexActors[0] = akspeaker

or

sexActors[0] = Alias_Follower

or

sexActors[0] = PlayerRef

 

receiver is always sexActors[1], but could be akSpeaker or PlayerRef

 

So in order to put all this in a single function which I know I should do, I STILL have to get the GiveMilk function filled in with the correct parameters.

 

OR I have to write the function with a lot of IFs in it until it hits the right combination of actors in the correct position. AND I still have to figure out how to get the information about who is slotted as sexActors[0] and [1]

 

Player gives to akSpeaker

Alias_Follower gives to akspeaker

akSpeaker gives to Player

 

OR... I write 3 functions and name them so I know which is which and call them each by hand coding them in the correct dialogue.

 

I think Apropos does this.... finds the actor in each slot and then uses them. Maybe I should have a look at Gooser's code and see how he's handling this.... if it's the same as what I'm trying to do...

Posted

The best way is the simplest way.

Just use a function you will write that has two parameters: a GIVER actor and a RECEIVER actor.

And then, depending on your dialogues, you call the function passing the correct GIVER and RECEIVER.

 

Posted

OK, well.... how close am I?

Function JugsSGOMilker(Actor giver, Actor receiver)

   If(Game.GetModByName("soulgem-oven.esp") != 255)
    sgo_QuestController SGO = Game.GetFormFromFile(0x12c6,"soulgem-oven.esp") as sgo_QuestController
    
      while (SGO.GetMilkCount >= 1)
         SGO.GiveMilk(giver,receiver,1,false)
         Utility.Wait(3.0)
     EndWhile
  EndIf
EndFunction

And then in my script fragment, I would start the animation as I usually do.

If I use:

;BEGIN CODE
actor[] sexActors = new actor[2]
sexActors[0] = akSpeaker
sexActors[1] = Game.GetPlayer()
sslBaseAnimation[] anims
anims = new sslBaseAnimation[1]
anims[0] = SexLab.GetAnimationByName("3J Straight Breastfeeding")
SexLab.StartSex(sexActors, anims)

then I would use my new function like this?:

JugsSGOMilker(akSpeaker, Game.getPlayer())

AND.... if that's anywhere near close :) ... do I have to set properties of something somewhere? Or declare giver and receiver somewhere?

 

Yes I know this isn't in the format of "do this while animating"... I can get to that. In fact I'd only really need to include a check to see if akSpeaker is in an animation because akSpeaker is ALWAYS in every different combination and part of the animation, whether it's as giver or receiver.

 

I'm just seeing if I'm learning to write functions! (yes... I'm a total freakin' n00b)

 

 

 

 

 

 

 

Posted

You are close.

 

Where are you putting the function JugsSGOMilker(Actor giver, Actor receiver) ?

 

I suppose you are putting it in the script associated to your main quest.

 

If so, then just change it a little to be more efficient:

sgo_QuestController SGO
Actor theGiver
Actor theReceiver
Faction Property SexLabAnimatingFaction Auto

Function JugsSGOMilker(Actor giver, Actor receiver)


   If(Game.GetModByName("soulgem-oven.esp") != 255)
     If !SGO
        SGO = Game.GetFormFromFile(0x12c6,"soulgem-oven.esp") as sgo_QuestController
     EndIf
     theGiver = giver
     theReceiver = receiver
     RegisterForSingleUpdate(1.0)
  EndIf
EndFunction
Event OnUpdate()  SGO.GiveMilk(theGiver, theReceiver,1,false)
  if (SGO.GetMilkCount >= 1 && theGiver.isInFaction(SexLabAnimatingFaction) && theReceiver.isInFaction(SexLabAnimatingFaction)
     RegisterForSingleUpdate(Utility.RandomFloat(3.0, 5.0))

  endIf
EndEvent

Then in your topic fragment, just after you start the animation you can use something like:

JuggsQuestS.JugsSGOMilkerakSpeaker, Game.getPlayer())

And you have to add something like

JuggsQuestScript Property JuggsQuestS Auto

As property of the Topic Fragment.

 

 

in this code I suppose the name of the script of your main quest is called JuggsQuestScript, change it with your actual name.

 

 

 

 

 

P.S. I think I will change my avatar title to: the tutorial-man.

 

 

Posted

In the script fragment I'm using as a test, I already have this:

SexLabFramework Property SexLab  Auto
JugsMain Property Jugs Auto

JugsMain is the name of my main quest script (it's EXTREMELY small... 15 lines)

 

So my function call in the fragment would be:

Jugs.JugsSGOMilker(akSpeaker, Game.getPlayer())

... right?

 

And yes, you seem always willing to help others with this stuff and believe me it is very much appreciated. ALL of the people that have helped .... very nice to be part of a place like this.

laurall has helped... and in another thread even Ashal takes time to answer questions (not like this one but questions specific to SexLab operation as you have seen).

People are BUSY.... but they still take time to help. That's a big deal to me. 

 

So... thank you.

 

Posted

You are right for your code.

If JugsMain is the name of the script, then the code you wrote is right.

 

You are welcome. I love to help people.

Posted

First it wouldn't compile... then it didn't work once I figured out why it wouldn't compile. :)

 

this line:

 

if (SGO.GetMilkCount >= 1 && theGiver.isInFaction(SexLabAnimatingFaction) && theReceiver.isInFaction(SexLabAnimatingFaction)

 

had to be changed a little to this

 

if (SGO.GetMilkCount(theGiver) >= 1 && theGiver.isInFaction(SexLabAnimatingFaction) && theReceiver.isInFaction(SexLabAnimatingFaction))

 

...was missing a ")" at the very end and I had to add in "(theGiver)" so we know WHO we're getting a milkCount for.

 

Those little things got it to compile clean.

 

Then I put the function call in the fragment. It compiled fine. Saved and then tested and.... didn't work.

 

I had to set the property for the SexLabAnimatingFaction in the main script properties (I should have known that was going to happen. It is the mistake I made most often when I started doing this. :)  )

 

NOW IT WORKS!

 

Thank you, thank you, thank you!

 

I tested it when she was full with 10 milks. Normally she could be milked to empty during one breastfeeding animation, but I advanced quickly through the animation so it would end.

 

Milking stopped.  PERFECT!

 

Now I can move on to making the animation selection work in both 1.59c and 1.60 ... then go through every Topic that has the animation start and clean everything up. Should be simpler... work better... and be easier to update.

 

Thanks again, my friend.

 

 

 

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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