Jump to content

Recommended Posts

Sexout '95 Beta 1 in OP

 

- Now requires NVSE 5+ due to event support.
- Complete rewrite of the scanner to be much more efficient, use events, but retain backwards compatability.
--> Scanner frequency MCM option changed to 'minimum delay' and 'maximum delay'. Whenever the player changes cell, a new scan is made if after the minimum delay. If the player does not change cell, a new scan is made after the maximum delay.
--> Valid sex actors are now added to the 'SexoutScannerListN' formlists via OnLoad event as well as by scanner.
--> New UDF, usage: 'let My_Array := call fnSexoutGetLocalActors'. Returns all sexout-valid actors within a 1 cell range of the player. For performance, the result is cached- it returns the result of the last sexout scan, unless the player's cell has since changed. WARNING: the array returned is read-only, because it is shared by all users. If you want to modify the array, use Ar_Copy.
--> New Sexout Event 'Sexout-Scan' (Sender: 'Sexout.esm', args: none), dispatched whenever a scan is completed, meaning the cached value of fnSexoutGetLocalActors has been updated. (Untested)
- New Orientation UDF, usage: 'let my_string := call fnSexoutGetOrientationSt ActorREF'. Returns 'hetro', 'bi', 'homo'. If no orientation has been set for an NPC, it returns the MCM default option. (Untested)
 

----

 

Note, I haven't tested this much, although Tryouts approaches seem to work fine with the new scanner.  Wear and Tear and Slavery should work fine with new scanner too, and I am not aware of any other mods that use it (click the MCM option in 'scanner' to find out if you have any). If there are, please report if otherwise.

Link to comment

Just tested this and the scanner is extremely slow?  I rely on the scanner to process as rapidly as it used to in order to catch certain events and settings.  Now there are long delays in between scans that I'm adding via a quest every one second.  Please advise?

 

EDIT: NVM.  Solved by rolling my own scanner.

Edited by t3589
Link to comment

 

- New Orientation UDF, usage: 'let my_string := call fnSexoutGetOrientationSt ActorREF'. Returns 'hetro', 'bi', 'homo'. If no orientation has been set for an NPC, it returns the MCM default option. (Untested)

 

This looks like a handy function, I can never make sense of the current orientation system, I mean handling values between bi and hetero/homo can get really confusing.

 

Also, I don't know if it's already been found but I don't think fnSexoutGetOrientationSt will ever return "bi" since

if orientation >= 1
    SetFunctionValue "hetro"
elseif orientation <= 1
    SetFunctionValue "homo"
else
    SetFunctionValue "bi"
endif

I suppose that should be a <= -1 for homo.

Link to comment

Sexout '95 Beta 2 in OP

- Actor OnLoad event now actually added, although it seems less effective than I hoped and may be removed before '95 stable.
- GetOrientationSt fixed (thanks asdasfa)
- Get|SetOrientationSt now use 'hetero' instead of 'hetro' (technically you just need 'he' for Set, so its backward compatible) (thanks zippy57)
 

-----

 

@asdasfa: Oops, yes that is what I meant it to be. Thanks.

 

@t3589: If it doesn't work for you any more, I can reconfigure it- the point in betas is to get feedback ;). What events are you trying to catch?

 

A couple of things to note:

 

- The NPC formlists 'SexoutScannerListN' now use on actor OnLoad event as well as scanner (...But I forgot to include the script I wrote for it in Beta 1 :blush: ), although testing it there seem to be less OnLoad events than I expected. Maybe I can find a more useful event for this.

- If you call fnSexoutGetLocalActors you get fresh results if the cell has changed.

 

@zippy: I blame prideslayer ;).

Link to comment

Well it worked, but it didn't run every second like I needed it to (I had it adding the list and spell 1/second).  Custom events (not script Events events, just things that need to happen).  Initiate Approaches/Include NPCs/Stat tracking changes.  It's OK though I think I'm going to try this method for a while.

 

I think I've got mine running at a greater cell depth anyway.  Places like the yard at NCRCF are all sectioned off and require more than the current/last cell.  ie.  If you're only reading the current and last cell, you can stand on one side of those cell borders and never pick up the NPCs a few feet away from you because they're in another cell (if you didn't come from that cell).

 

My main concern is to remedy the problems CK is having with it.  I just rolled my own because I've been planning to for a long time and this seemed like a good opportunity (until yesterday I had never made one).

 

I'm thinking if the sexout scanner runs fine now for CK, and mine brings the old problem back, then between the two of us we can pin it down. So I may use the Sexout scanner again at some point.  Right now the main difference between them are that Sexouts scanner is more efficient, and that I'm using a cell depth of 1 to get the surrounding cells.  We'll see how it goes.

 

 

Link to comment

Is it normal for consensual sex to play sexout's custom moan sounds even when the "Use ingame voices" option is ticked on?

I'm using Unethical deeds and Sexout Assault(combat sex turned off ofc) and I can clearly hear the difference between the voices used. I'll try testing it out with Sex Lite first (right after posting this) with 95 beta 2 and see what happens.

 

Edit: Yes, the in-game voices are still not used on consensual sex (I used Sexout Sex w/o other Sexout mods running). I am rather sad as I use voice files that I prefer more than Sexout's moan voices. Rape on the other hand, plays the ingame voices smoothly.

 

Additional rants: Unethical registers submit as consensual, a rather sad comparison to Assault. Assault on the other hand, don't have multiple turns like Unethical. What a sad compromise. It's even sadder that Unethical's author isn't active anymore, and Assault being not updated too.

Link to comment

Sexout '95 Beta 3 in OP

- Reworked random picker and anims database, should be more robust and faster. (Now prioritizes/presorts by actor skeletons. Format of 'actors' anim_def data has changed).
- fnSexoutGetSkeleton now returns the effective gender ('M' or 'F', modified for strapon/genderbending effects) if called on a non-creature.
- New convenience UDF: 'call fnSexoutAnyInUse Actors:array' returns true if any actors in passed array are sexout in use.
- New Anim by DManXX2: 615.
- Fixed alignment of anims 232, Amra704.
- Refactored ActRunFull: Now returns 1 if it succeeds, else 0. You can check this result to save bothering to check ActorInUse on all actors yourself.
- Sexout spell target is now player if involved, instead of always actorA. This should prevent never ending animations if NPC ActorA dies mid-coital, or player teleports to another cell.
 

 

-----

@Lifariz: I think its always been that way, but I'll look into it. You may want to check out t3589 'Sexout Sound Replacer', I believe it has many features to help add custom sounds.

Link to comment

Having a problem with callback items.  Token isn't being handed out.  Dropped back to stable and it works.  I'm setting it via legacy NX.

 

EDIT: Not getting any errors either.  DontUndress isn't working either. Or designating rape.

 

EDITx2: Does GetAnimDef return the pen data yet?

Edited by t3589
Link to comment

Odessa, there seems to be an issue with the animation selection for ants. Instead of selecting the giant ant animation 1941 it chooses from some other set of animations and the ant seems to be cut from equation entirely. The player just ends up standing there doing nothing until the timer runs out. I turned on the debug & got you a log.

sexoutdebug.txt

Link to comment

Sexout '95 Beta 4 in OP

 

- Fixed issue when some of the actors were invalid, sexout now aborts if any are invalid rather than trying to play an animation with valid remainder- this used to be the case and was probably changed by accident. (thanks gamedude711)
- Giant Ant anim no longer counts as a placeholder, although it is. Like before.
- Fix alignment of Sexout.esm:706
- New UDF: "let Anim_Defs_array := call fnSexoutGetAnimsForActors Actors:array(eg: Ar_List SunnyREF, PlayerREF)". Returns all possible animations for the specified actor combination, specified in the order A, B , C, (D ;)).. Returns 0 if no animations available.
 

----

 

@t3589: I just tested CBItem, Raper and bDontUndressA|B via both NX call method and ActRunFull and they worked fine :-/ . Could you post your call script and upload a debug log?

 

GetAnimDef returns all the animation information sexout has, but only 3P animations have "pen" data.

Link to comment

I walked through the entries on a non Amra 3P anim and never saw any pen data with both call examples (on the actor and on the anim)?

 

I put the call I'm using at the bottom of the scof output.

 

EDIT: Works in stable.

sexout.txt

Edited by t3589
Link to comment

You can't mix call methods, if you want to use the NX method you should use:

 

rTarget.CIOS SexoutNGBegin

 

If you want to use ActRunFull you should include the the settings in its params. I guess it works with the stable because ActRunFull always casts the spell on ActorA, but now it casts on the player if present.

 

--

Looks like some of 3Ps have pen data defined but not actually included :blush: , I'll fix for next release.

Link to comment

These are the results so far.  I guess my question now is, how do I set flags without using the full call?  The reason I was mixing them is because that's the only way I could get it to work.

 

 

 

; Undresses, No Rape, No Token
    let Flags := Ar_List "Vaginal" "Miss"
    Call fnSexoutActSetRef "Raper" rActorA
    Call fnSexoutActSetRef "CBItemA" Token
    Call fnSexoutActSetInt "bDontUndressA" 1
    Call fnSexoutActRunFull (Ar_Map "ActorA"::rActorA, "ActorB"::rActorB, "Flags"::Flags)


; Doesn't even start sex.
    let Flags := Ar_List "Vaginal" "Miss"
    Call fnSexoutActSetRef "ActorA" rActorA
    Call fnSexoutActSetRef "ActorB" rActorB
    Call fnSexoutActSetRef "Raper" rActorA
    Call fnSexoutActSetRef "CBItemA" Token
    Call fnSexoutActSetInt "bDontUndressA" 1
    Call fnSexoutActRunFull (Ar_Map "Flags"::Flags)


; Works as expected, but no flags.
    Call fnSexoutActPrep
    Call fnSexoutActSetRef "Raper" rActorA
    Call fnSexoutActSetRef "CBItemA" Token
    Call fnSexoutActSetRef "ActorA" rActorA
    Call fnSexoutActSetInt "bDontUndressA" 1
    Call fnSexoutActSetRef "ActorB" rActorB
    Call fnSexoutActSetInt "isOral" bOral
    Call fnSexoutActSetInt "isAnal" bAnal
    Call fnSexoutActSetInt "isVaginal" bGent
    Call fnSexoutActRun

 

 

 

EDIT: I think I see what's up now.  I want to use flags, but most of the things I am setting are determined in a script.  Which means I would need to repeat the full call over and over in all of its variations if it cannot be used modularly.  Which is confusing because it renders the full call inconvenient to my purpose.  I think maybe I'm expecting the wrong kind of convenience?

 

 

Edited by t3589
Link to comment

Odessa, thanks for the fnSexoutGetAnimsForActors function, it's cool!

 

 

t3589, you can set all those values via a single fnSexoutActRunFull call, for example

let Flags := Ar_List "Vaginal" "Miss"
Call fnSexoutActSetRef "Raper" rActorA
Call fnSexoutActSetRef "CBItemA" Token
Call fnSexoutActSetInt "bDontUndressA" 1
Call fnSexoutActRunFull (Ar_Map "ActorA"::rActorA, "ActorB"::rActorB, "Flags"::Flags)
can be easily turned into:

let Flags := Ar_List "Vaginal" "Miss"
call fnSexoutActRunFull (Ar_Map "ActorA"::rActorA, "ActorB"::rActorB, "Flags"::Flags, "Raper"::rActorA, "CBItemA"::Token, "bDontUndressA"::1)
or pass rActorA, Token, 1, etc. as variables if they're supposed to be changing in dialogues or something. If some variable is null it will be automatically discarded I think, but haven't tested that.
Link to comment

Odessa, thanks for the fnSexoutGetAnimsForActors function, it's cool!

 

 

t3589, you can set all those values via a single fnSexoutActRunFull call, for example

let Flags := Ar_List "Vaginal" "Miss"
Call fnSexoutActSetRef "Raper" rActorA
Call fnSexoutActSetRef "CBItemA" Token
Call fnSexoutActSetInt "bDontUndressA" 1
Call fnSexoutActRunFull (Ar_Map "ActorA"::rActorA, "ActorB"::rActorB, "Flags"::Flags)
can be easily turned into:

let Flags := Ar_List "Vaginal" "Miss"
call fnSexoutActRunFull (Ar_Map "ActorA"::rActorA, "ActorB"::rActorB, "Flags"::Flags, "Raper"::rActorA, "CBItemA"::Token, "bDontUndressA"::1)
or pass rActorA, Token, 1, etc. as variables if they're supposed to be changing in dialogues or something. If some variable is null it will be automatically discarded I think, but haven't tested that.

 

 

I realize that.  My mistake was in thinking it could be used modularly.  ie. I had it in my head that I could just use that call once and fill it in (a convenience I assumed through the prism of how I'm using it, but which it never had).  However since it can't have null values (which I already knew), and it can't be mixed and matched (which I understand now, but didn't before).  That example only gets me one of the many variants that I need.

 

In other words your example doesn't fill my needs.  ie. What if ActorB is null in your example?  Since you can't have null values, you would have to make another full call with the actorB omitted.  At least, that's how I understood it.

 

EDIT: Answered my own question.  Read it in the API, the only method that works for flags is the full call.

 

Edited by t3589
Link to comment

In other words your example doesn't fill my needs.  ie. What if ActorB is null in your example?  Since you can't have null values, you would have to make another full call with the actorB omitted.  At least, that's how I understood it.

I believe in that case the best way would be to write your own "wrapper" function which will accept any kind of values you want it too, then filter out everything invalid for Sexout and build a proper RunFull call. That way you stay independent from the API in your other scripts and will have to make changes in only one place in case something in the API changes again.
Link to comment

 

In other words your example doesn't fill my needs.  ie. What if ActorB is null in your example?  Since you can't have null values, you would have to make another full call with the actorB omitted.  At least, that's how I understood it.

I believe in that case the best way would be to write your own "wrapper" function which will accept any kind of values you want it too, then filter out everything invalid for Sexout and build a proper RunFull call. That way you stay independent from the API in your other scripts and will have to make changes in only one place in case something in the API changes again.

 

 

This is what I'm already doing.  I just don't want to repeat the full call line in that wrapper for every variation of call I need.  Unless you're talking about building the actual call line itself, in which case, I'm just not that smart, or if I was I've forgotten it.

 

Link to comment

This is what I'm already doing.  I just don't want to repeat the full call line in that wrapper for every variation of call I need.  Unless you're talking about building the actual call line itself, in which case, I'm just not that smart, or if I was I've forgotten it.

Hmm, just use a stringmap array as an input arg, like in RunFull? And then just check if you have the particular key defined or not.

 

scn fnMyRunFull

; Args
array_var arrArgs

; Local vars
int iIndex
ref rActor
ref rItem
array_var arrActorRoles
array_var arrSexoutCall
string_var strTemp
string_var strActorRole


begin Function {arrArgs}
  let arrSexoutCall := Ar_Construct "stringmap"
  if eval !(arrArgs)
    SetFunctionValue 0
    return
  endif
  if eval !(Ar_Size arrArgs)
    SetFunctionValue 0
    return
  endif
  if eval !(Ar_HasKey arrArgs "Actors")
    SetFunctionValue 0
    return
  else
    if eval (Ar_Size arrArgs["Actors"]) < 1
      SetFunctionValue 0
      return
    endif
  endif
  ;; and many-many other boring checks...

  let arrActorRoles := Ar_List "A" "B" "C" "X"
  let iIndex := 0
  while iIndex < (Ar_Size arrArgs["Actors"])
    let rActor := arrArgs["Actors"][iIndex]
    let strActorRole := arrActorRoles[iIndex]
    let strTemp := Sv_Construct "Actor%z" strActorRole
    let arrSexoutCall[strTemp] := rActor
    let strTemp := Sv_Construct "bDontUndress%z" strActorRole
    let arrSexoutCall[strTemp] := arrArgs["DontUndress"][iIndex]
    let strTemp := Sv_Construct "CBItem%z" strActorRole
    if eval arrArgs["CBItems"][iIndex]
      let rItem := arrArgs["CBItems"][iIndex]
      if eval IsFormValid rItem
        let arrSexoutCall[strTemp] := arrArgs["CBItems"][iIndex]
      endif
    endif
    ;; etc, etc...
    let iIndex += 1
  loop
  Sv_Destruct strActorRole
  Sv_Destruct strTemp
  if eval (Ar_HasKey arrArgs "Flags")
    if eval (Ar_Size arrArgs["Flags"]) > 0
      arrSexoutCall["Flags"] := Ar_Copy arrArgs["Flags"]
    endif
  else
  ;; and so on, and so on...

  SetFunctionValue (call fnSexoutActRunFull (arrSexoutCall))
  
end

 

and use it somewhat like that:

 

 

;; some code
let arrMyCall := Ar_Construct "stringmap"
let arrMyCall["Actors"] := Ar_List rActorA rActorB
let arrMyCall["Raper"] := rActorA
let arrMyCall["DontUndress"] := Ar_List 1 0
let arrMyCall["CBItems"] := Ar_List Token 0
let arrMyCall["Flags"] := Ar_List "Vaginal" "Miss"
;; etc.
let bSuccess := call fnMyRunFull arrMyCall
;; some code

 

Obviously, quite sketchy and untested.

Link to comment

 

This is what I'm already doing.  I just don't want to repeat the full call line in that wrapper for every variation of call I need.  Unless you're talking about building the actual call line itself, in which case, I'm just not that smart, or if I was I've forgotten it.

Hmm, just use a stringmap array as an input arg, like in RunFull? And then just check if you have the particular key defined or not.

 

scn fnMyRunFull

; Args
array_var arrArgs

; Local vars
int iIndex
ref rActor
ref rItem
array_var arrActorRoles
array_var arrSexoutCall
string_var strTemp
string_var strActorRole


begin Function {arrArgs}
  let arrSexoutCall := Ar_Construct "stringmap"
  if eval !(arrArgs)
    SetFunctionValue 0
    return
  endif
  if eval !(Ar_Size arrArgs)
    SetFunctionValue 0
    return
  endif
  if eval !(Ar_HasKey arrArgs "Actors")
    SetFunctionValue 0
    return
  else
    if eval (Ar_Size arrArgs["Actors"]) < 1
      SetFunctionValue 0
      return
    endif
  endif
  ;; and many-many other boring checks...

  let arrActorRoles := Ar_List "A" "B" "C" "X"
  let iIndex := 0
  while iIndex < (Ar_Size arrArgs["Actors"])
    let rActor := arrArgs["Actors"][iIndex]
    let strActorRole := arrActorRoles[iIndex]
    let strTemp := Sv_Construct "Actor%z" strActorRole
    let arrSexoutCall[strTemp] := rActor
    let strTemp := Sv_Construct "bDontUndress%z" strActorRole
    let arrSexoutCall[strTemp] := arrArgs["DontUndress"][iIndex]
    let strTemp := Sv_Construct "CBItem%z" strActorRole
    if eval arrArgs["CBItems"][iIndex]
      let rItem := arrArgs["CBItems"][iIndex]
      if eval IsFormValid rItem
        let arrSexoutCall[strTemp] := arrArgs["CBItems"][iIndex]
      endif
    endif
    ;; etc, etc...
    let iIndex += 1
  loop
  Sv_Destruct strActorRole
  Sv_Destruct strTemp
  if eval (Ar_HasKey arrArgs "Flags")
    if eval (Ar_Size arrArgs["Flags"]) > 0
      arrSexoutCall["Flags"] := Ar_Copy arrArgs["Flags"]
    endif
  else
  ;; and so on, and so on...

  SetFunctionValue (call fnSexoutActRunFull (arrSexoutCall))
  
end

 

and use it somewhat like that:

 

 

;; some code
let arrMyCall := Ar_Construct "stringmap"
let arrMyCall["Actors"] := Ar_List rActorA rActorB
let arrMyCall["Raper"] := rActorA
let arrMyCall["DontUndress"] := Ar_List 1 0
let arrMyCall["CBItems"] := Ar_List Token 0
let arrMyCall["Flags"] := Ar_List "Vaginal" "Miss"
;; etc.
let bSuccess := call fnMyRunFull arrMyCall
;; some code

 

Obviously, quite sketchy and untested.

 

 

I like my solution better.  Just don't use flags, unless you're willing to duplicate the framework.  Solved.

 

Link to comment

im not sure whats my problem is but....
midway through ses animation, somehow, the npc(my partner) disappeared in mid animation. after he was gone, the animation keep on going until the timer end. then after ragdoll, the npc didnt even appear... it just gone forever...
oh, and in my inventory got a "sexout AC"

Link to comment

@t3589: Like nkAlex says, you can define the parameters on multiple lines if convenient. This is what I would use in your case:

array_var Params
...
    let Params := Ar_Construct "stringmap"
    let Params["flags"] := Ar_List "Vaginal" "Miss"
    let Params["Raper"] := rActorA
    let Params["CBItemA"] := Token
    let Params["bDontUndressA"] := 1
    if rActorB
       let Params["ActorB"] := rActorB
    endif
    Call fnSexoutActRunFull Params

Currently you can not set flags using the legacy APIs. I have been thinking of adding a way of setting them as a space seperated string, since the NX call method is useful for console testing- I don't think there is a good reason to use them otherwise though; they were replaced for a reason.

 

-----

@gundamwarcraft: Probably something (Eg: another mod) caused the NPC to teleport away. There should be some checks for this coming in the future.

Link to comment
Odessa, have you looked into the Player restrain/packages issue? I've posted a more detailed explanation in the Api thread. Especially the one where the PC is affected when he is not a participant, I think it may have something to do with the main spell being cast on the Player. Maybe some stuff is being executed on Self instead of NPCs?
Link to comment

The main spell is only cast on the player if they are Actor A, B or C. The actors are set from the NX vars, not GetSelf anyway, so even if it was cast on the player it wouldn't affect them.

 

I've searched through all the scripts with vimgrep, and:

 

- SetRestrained is only ever called on Actor A, B or C. It is then reset to original state when sexout cleans up.

 

- Sexout adds a package to actor A, B and C, but only if they are not the player.

 

- There is also DisablePlayerControls, which again is only called if the player is actor A, B or C. If so, each of the 7 controls is reset to the original value in clean up- if you upload a debug log I can verify if this happened. I've check all the logic, and it seems fine- however, I have noticed an engine bug in the past where EnablePlayerControls stops working correctly. I might be able to workaround this by adding a frame delay between status changes, I'll give it a try.

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