Jump to content

SL Triggers(v12) [2022-06-05]


Recommended Posts

Posted
47 minutes ago, hextun said:

Pinging @sirretinee as they were first to mention the issue, though anyone trying it out for the first time in the last week or so... ugh. Come back... 

Had a few minutes to check things out.

It's detecting Sexlab again and triggers are firing! Yay!
My script now fails at 'sl_isinslot'. Boo.
"Bigguy" and "is Bigguy" messages send, but not "Is in slot" so it must not be passing the slot check. Changing positions mid-scene also doesn't seem to get it to fire off.
Just to confirm i'm using it right:
image.png.d9ef55974bc1b6707d7daa1e47c8492a.png
This is the same script that was working before Triggers stopped detecting Sexlab, so it should be getting past the sl_isinslot part and be getting hung up on the console part.

I appreciate you looking into this.

Posted

Which brings us to v23.

 

23
	bugfix: fixed sl_isinslot - now appropriately checks parameter 2 for the slot number rather than expecting the Actor in parameter 1 to also be a slot number. The insanity.

 

So apparently the numbers 1 and 2 are distinct enough that the Papyrus VM cared which one I used. If you managed to get success I can only imagine it was due to a) accidentally using the trigger version (not the operation variant) and misattributing the success, b) using the variant version but hitting what I *think* was an extreme edge case where the right slot pick in the right situation might have given a false positive, but I'm not sure that was actually technically possible, or c) alien giraffe space pirates with reality warping abilities. I don't think it was b).

 

At this point, I'm going to promise that this version will cause a rip in the space-time continuum and probably cause all small dogs in a 23 foot radius to spontaneously become cotton balls, because it seems my assurances are as likely to cause the opposite to happen. So good luck with the rips in space-time and hide your small dogs when you install this version.

 

Will not require a new save.

sl_triggers23.zip

Posted

I haven't bumped into any issues on v23 with my current commands, but I stumbled over some old typos in the examples provided in sl_triggers_script_description.txt.

line 281: "actor_advkill" instead of "actor_advskill"
line 314: "actor_isquard" instead of "actor_isguard"

Went down a debugging rabbithole all night just to find out I copypasted a bad line. Also didn't need it in the end, woo, time well spent.

Posted
3 hours ago, hextun said:

Which brings us to v23.

 

23
	bugfix: fixed sl_isinslot - now appropriately checks parameter 2 for the slot number rather than expecting the Actor in parameter 1 to also be a slot number. The insanity.

 

So apparently the numbers 1 and 2 are distinct enough that the Papyrus VM cared which one I used. If you managed to get success I can only imagine it was due to a) accidentally using the trigger version (not the operation variant) and misattributing the success, b) using the variant version but hitting what I *think* was an extreme edge case where the right slot pick in the right situation might have given a false positive, but I'm not sure that was actually technically possible, or c) alien giraffe space pirates with reality warping abilities. I don't think it was b).

 

At this point, I'm going to promise that this version will cause a rip in the space-time continuum and probably cause all small dogs in a 23 foot radius to spontaneously become cotton balls, because it seems my assurances are as likely to cause the opposite to happen. So good luck with the rips in space-time and hide your small dogs when you install this version.

 

Will not require a new save.

sl_triggers23.zip 86.63 kB · 2 downloads

 

thanks. I can confirm cum vial collection & predator SMP mouth & throat still work.
But my custom made scripts don't work.

I've set them up to Any to make sure they trigger but they don't.

 

Could you help explain why it doesn't even display msg_notify messages? I'm new to this framework and a bit confused why when scripts break they don't even print messages

Posted
21 minutes ago, Fraying9981 said:

 

thanks. I can confirm cum vial collection & predator SMP mouth & throat still work.
But my custom made scripts don't work.

I've set them up to Any to make sure they trigger but they don't.

 

Could you help explain why it doesn't even display msg_notify messages? I'm new to this framework and a bit confused why when scripts break they don't even print messages

I've just tested the script you posted and the 'msg_notify' works fine for me, however the speech check fails because it's checking against 'Speech' when the AV is actually called 'Speechcraft'. Not sure why the first part is failing on your end though, are you by any chance using Papyrus Tweaks with bSpeedUpNativeCalls = true?

Posted
5 hours ago, hextun said:

Which brings us to v23.

 

23
	bugfix: fixed sl_isinslot - now appropriately checks parameter 2 for the slot number rather than expecting the Actor in parameter 1 to also be a slot number. The insanity.

 

So apparently the numbers 1 and 2 are distinct enough that the Papyrus VM cared which one I used. If you managed to get success I can only imagine it was due to a) accidentally using the trigger version (not the operation variant) and misattributing the success, b) using the variant version but hitting what I *think* was an extreme edge case where the right slot pick in the right situation might have given a false positive, but I'm not sure that was actually technically possible, or c) alien giraffe space pirates with reality warping abilities. I don't think it was b).

 

At this point, I'm going to promise that this version will cause a rip in the space-time continuum and probably cause all small dogs in a 23 foot radius to spontaneously become cotton balls, because it seems my assurances are as likely to cause the opposite to happen. So good luck with the rips in space-time and hide your small dogs when you install this version.

 

Will not require a new save.

sl_triggers23.zip 86.63 kB · 4 downloads

I can't believe you've done this to my dog!

Almost no complaints. My scaling triggers are firing off without issue. Each check is passed. Each command runs when appropriate. Debug messages are sent so I know what's happening. Works regardless of if i'm involved in a scene or not.
HOWEVER!
image.png.810b323ef0dd4e801594b2abdeea90ee.png
This section, the section that tells me the trigger has started, is being triggered outside of sexlab animations. It's failing at "sl_hastag" because it's not firing during a sexlab animation. (It does, however, work properly when a scene is going.)
Every 5 seconds I get notified "Trigger started".
The condition for the script is:
image.png.fb56f4ea97a3a5f3d7b1e48223579c7f.png
So maybe it's triggering when the game itself begins instead of when a scene begins?
That'd be my guess. You de-coupled Sexlab requirements so maybe 'begin' in this sense is no longer checking for a sexlab scene to start because they possibly won't due to Sexlab being optional.

Bit by bit we're getting there and, again, thanks for your efforts so far.

Posted (edited)
1 hour ago, sirretinee said:

I can't believe you've done this to my dog!

Almost no complaints. My scaling triggers are firing off without issue. Each check is passed. Each command runs when appropriate. Debug messages are sent so I know what's happening. Works regardless of if i'm involved in a scene or not.
HOWEVER!
image.png.810b323ef0dd4e801594b2abdeea90ee.png
This section, the section that tells me the trigger has started, is being triggered outside of sexlab animations. It's failing at "sl_hastag" because it's not firing during a sexlab animation. (It does, however, work properly when a scene is going.)
Every 5 seconds I get notified "Trigger started".
The condition for the script is:
image.png.fb56f4ea97a3a5f3d7b1e48223579c7f.png
So maybe it's triggering when the game itself begins instead of when a scene begins?
That'd be my guess. You de-coupled Sexlab requirements so maybe 'begin' in this sense is no longer checking for a sexlab scene to start because they possibly won't due to Sexlab being optional.

Bit by bit we're getting there and, again, thanks for your efforts so far.

Am I reading this right? You've got several 'if' statements that loops you back to the start of the script, triggering the 5 second 'util_wait', printing "Trigger started" again, running through the code and looping back to start again. Also I think the 'sl_hastag' parameter is meant to be bigguy with 2 g's? I'm also not sure how any part after 'sl_hastag' is even triggering because of this, but the loop you throw it into means it never stops, even after leaving the SexLab scene.

Edited by MannySauce
Posted (edited)
3 hours ago, sirretinee said:

I can't believe you've done this to my dog!

Almost no complaints. My scaling triggers are firing off without issue. Each check is passed. Each command runs when appropriate. Debug messages are sent so I know what's happening. Works regardless of if i'm involved in a scene or not.
HOWEVER!
image.png.810b323ef0dd4e801594b2abdeea90ee.png
This section, the section that tells me the trigger has started, is being triggered outside of sexlab animations. It's failing at "sl_hastag" because it's not firing during a sexlab animation. (It does, however, work properly when a scene is going.)
Every 5 seconds I get notified "Trigger started".
The condition for the script is:
image.png.fb56f4ea97a3a5f3d7b1e48223579c7f.png
So maybe it's triggering when the game itself begins instead of when a scene begins?
That'd be my guess. You de-coupled Sexlab requirements so maybe 'begin' in this sense is no longer checking for a sexlab scene to start because they possibly won't due to Sexlab being optional.

Bit by bit we're getting there and, again, thanks for your efforts so far.

 

EDIT: I'm a tired dumbass and didn't consider you wanted it to keep checking in case you swap animations and positions (as you stated too).

I think just fixing the typo in your 'sl_hastag' parameter should fix the problem.

 

Edited by MannySauce
Up too late.
Posted
1 hour ago, MannySauce said:

 

EDIT: I'm a tired dumbass and didn't consider you wanted it to keep checking in case you swap animations and positions (as you stated too).

I think just fixing the typo in your 'sl_hastag' parameter should fix the problem.

 

Fixing the typo seems to have fixed everything, but still doesn't explain why it was auto-firing when just... in the world.
Maybe I saved too soon after an animation or something? No idea.

For reference, here's an updated script. Checks if you're in an animation right there at the beginning and shuts it down if not. Ideally it wouldn't be needed but now i'm unreasonably superstitious about scripts firing randomly so it stays until I go back and clean up the unnecessary debug notifications.
image.png.e25c883c87814065220091a0195af7d6.png
I wasn't getting notified with "Trigger ended" every five seconds, so i'm just going to chalk up the script firing during normal gameplay to script weirdness and call it a day.
sl_triggers itself does what I need it to do now and that's what matters.

Posted (edited)
10 hours ago, MannySauce said:

I've just tested the script you posted and the 'msg_notify' works fine for me, however the speech check fails because it's checking against 'Speech' when the AV is actually called 'Speechcraft'. Not sure why the first part is failing on your end though, are you by any chance using Papyrus Tweaks with bSpeedUpNativeCalls = true?

 

Thanks!

Idk about this papyrus tweak setting, where can i find it? I will test and report back

Edit: bSpeedUpNativeCalls is set to false. is that OK?

 

Spoiler

[Fixes]

 

;Fixes ToggleScripts command not persisting when saving/stack dumping

;Scripts will now stay turned off when toggled off, and on when toggled on.

bFixToggleScriptsCommand = true

 

;Fix unintentionally allocating script pages when getting largest available page, but out of memory.

bFixScriptPageAllocation = true

 

;Fix crash when passing in NONE object to script function Actor.IsHostileToActor().

bFixIsHostileToActorCrash = true

 

;Fix scripts that don't load right away breaking completely if they reference an invalid object type (Ex: SuperSecretScript has a function that takes InvalidScript as a parameter).

bFixDelayedScriptBreakage = true

 

 

[VM Tweaks (Tweaks that directly alter the script engine)]

 

;Maximum papyrus operations per frame. Higher number means better script performance on average

;Has a very minor impact on framerate, and varies from script to script. (Default: 500, Vanilla value: 100). Recommended Range: 100-2000. Set to 0 to disable

iMaxOpsPerFrame = 500

 

;Modify how long Papyrus can be "overstressed" before dumping stacks, in milliseconds (Default value: 15000, Vanilla value: 5000).

;Set to 0 to disable the stack dump check, or -1 to disable this setting.

;See https://www.nexusmods.com/skyrimspecialedition/articles/4625 for information on what a stack dump is

iStackDumpTimeoutMS = 15000

 

;Enables loading of doc strings from scripts into the engine. Requires `bEnableDebugInformation` to be true in this INI

bEnableDocStrings = true

 

;Enables Skyrim to load debug information of scripts. This completely overrides bLoadDebugInformation in Skyrim.ini and is provided here for easier configuration

bEnableDebugInformation = true

 

 

[Logging Tweaks (Tweaks that affect script logging)]

 

;Disables `File " % s " does not exist or is not currently loaded.` logs from being printed when calling Game.GetFormFromFile().

;This only disables the logging of the error, the error itself will still occur

bDisableGetFormFromFileErrorLogs = false

 

;Improves Base Type Mismatch error to show inheritance hierarchy of scripts; Also clarifies if the script was a genuine mismatch, or if the script doesn't exist

bImproveBaseTypeMismatchLogs = true

 

;Improves several error logs relating to incompatible arguments to better clarify what is incompatible

bImproveValidateArgsLogs = true

 

;Disable "Property %s on script %s attached to %s cannot be initialized because the script no longer contains that property" log messages.

;This only disables the logging of the warning, the warning itself will still occur

bDisableNoPropertyOnScriptErrorLogs = false

 

;Disable "Cannot open store for class "%s", missing file?" errors being logged.

;This only disables the logging of the error, the error itself will still occur

bDisableMissingScriptError = false

 

;Adds a summary of events when dumping stacks to log

bSummarizeStackDumps = true

 

 

[Experimental]

 

;(Formerly bRunScriptsOnMainThreadOnly)

;Speeds up native calls by desyncing them from framerate and instead syncing script calls to a spinlock, greatly improving script performance while still preventing concurrent execution of native calls

bSpeedUpNativeCalls = false

 

;(Formerly sMainThreadClassesToExclude, requires bSpeedUpNativeCalls=true)

;List of script classes to exclude from being sped up by bSpeedUpNativeCalls.

;It is strongly recommended to leave at defaults unless you absolutely know what you're doing

sScriptClassExclusions = UI, ConsoleUtil, PO3_SKSEFunctions, MfgConsole, MFGConsoleFunc, Input, Debug, Utility, PapyrusTweaks, Quest

 

;(Formerly sMainThreadMethodsToExclude, requires bSpeedUpNativeCalls=true)

;List of script method prefixes to exclude from being sped up (ex: "Equip" excludes "EquipItem" and "EquipItemByID", but does NOT exclude "UnequipItem".

;It is strongly recommended to leave at defaults unless you absolutely know what you're doing

;as a lot of modifying functions like `EquipItem` do not work properly if executed more than once in a single frame.

; Defaults exclude everything except for read-only functions (ex: GetFormFromFile, HasKeyword, IsLoaded, etc.)

sScriptMethodPrefixesToExclude = Activate, Add, Advance, Allow, Attach, Apply, Block, Cast, Change, Clear, Close, Complete, Create, Damage, Delete, Disable, Disallow, Dismount, Dispel, DoCombatSpellApply, Draw, Drop, Enable, End, Equip, Evaluate, Fade, Fail, Fire, Force, GetAnimation, GetQuest, Hide, Hold, Ignore, Increment, Keep, Kill, Knock, Learn, Load, Lock, Mod, Move, Mute, Open, Place, Play, Pop, Precache, Process, Push, Queue, Quit, Regenerate, Register, Release, RemoteCast, Remove, Request, Reset, Restore, Resurrect, Revert, Save, Say, Send, Serve, Set, Shake, Sheath, Show, Start, Stop, Teach, TempClone, Tether, Toggle, Translate, Trap, Trigger, Try, Unequip, Unlock, UnMute, UnPause, Update, Unregister

 

;(VR-ONLY) Pauses all non-playroom scripts while in the VR playroom, so mod scripts only initialize once you actually enter a save/new game.

;This is only experimental as it intentionally alters script behavior

bDisableScriptsInPlayroomVR = false

 

;Stops the game from resetting when loading a corrupted save

;This will NOT fix a broken save, just allows you to load the save no matter what information is lost. ONLY USE AS A LAST RESORT TO RECOVER A SAVE YOU HAVE BEEN WARNED!!

bBypassCorruptSaveMessage = false

 

;Allows the Script Engine to use as much memory as needed, with no cap. This makes `iMaxAllocatedMemoryBytes` in Skyrim.ini useless/infinite

;Note: Skyrim already ignores memory limit when stressed, this setting just keeps it ignored.

bIgnoreMemoryLimit = false

 

Edited by Fraying9981
Posted
3 hours ago, sirretinee said:

Fixing the typo seems to have fixed everything, but still doesn't explain why it was auto-firing when just... in the world.
Maybe I saved too soon after an animation or something? No idea.

For reference, here's an updated script. Checks if you're in an animation right there at the beginning and shuts it down if not. Ideally it wouldn't be needed but now i'm unreasonably superstitious about scripts firing randomly so it stays until I go back and clean up the unnecessary debug notifications.
image.png.e25c883c87814065220091a0195af7d6.png
I wasn't getting notified with "Trigger ended" every five seconds, so i'm just going to chalk up the script firing during normal gameplay to script weirdness and call it a day.
sl_triggers itself does what I need it to do now and that's what matters.

 

For what it's worth, I suspect that your perpetually starting trigger was due to the original design of your script combined with what I suspect was a currently running effect at a save right when you either upgraded or quit to update your script. The original version of the script you posted went roughly:

 

:start

wait 5 seconds

msg_notify "Trigger started"

sl_hastag Biguy (typo, sure, but only contributing)

if not (and never will be because typo) go back to start

 

Just one instance of this would cause a single 'Trigger started' never ending loop, and if it was triggered once when, say, something like msg_notify wasn't working or something or all SexLab functions were failing because I had shipped a broken version, it would just sit there silently looping.

 

If the trigger had actually been firing off every 5 seconds (i.e. somehow receiving and acting on actual SexLab events) it wouldn't necessarily have been on a 5 second cadence. That it was and that that is what your wait is, suggests it was the first theory.

 

=====

 

On another note, I wanted to get some input from the userbase (there are several of us!) on some design thoughts.

 

I've been working on an upgrade, which I've alluded to previously. Aside from scratching my personal itch of just being interested in doing it, I have been working on making this mod more modular. The idea being that I wanted the SL Triggers part to basically be a command dispatcher, and have the actual commands belong in libraries that can be expanded on without needing to alter the core mod.

As part of this I also created a sort of "automated" MCM system whereby an extension author can use the API to describe the attributes they want managed via the MCM and it will handle it for them. I wanted to make it as simple as possible to expand the functionality.

 

If that was all that would change I wouldn't ask for input because for the most part that wouldn't impact most of how you use and manage the mod.

 

But for better management of data, in particular with the possibility, however remote, that actual extensions would be written (and not my "extensions", which are actual extensions but will be included in the base mod), I have taken the approach of breaking the trigger data out, not only out of the settings.json but into individual files per trigger, with individual folders per extension (including separate folders for the two "base" extensions that would ship, "Core" (for the Keymapping and TopOfTheHour, i.e. events that would be available in a SKSE/Vanilla setup) and "SexLab"). 

Between game sessions you could edit, delete, or add files to your hearts content. On launch it scans the folders, scoops up the trigger data and uses it. The MCM will remember which file belongs with which trigger (and displays it though I haven't allowed you to specify filenames) and will create new triggers with a file numbering scheme of trigger000-trigger999. I dare you to have 1000+ functioning triggers and if you do, you own the Internet. :) But once saved, again, you can pull it into your personal mod folder and rename it and so on.

 

Also, I'm strongly considering moving away from the .json format and to a homegrown parsed version of .ini files. I'm considering .ini files because the syntax highlighting matches up nicely, including escaped quoting and support for $-prefixed variable names. I would probably change the ":label" to be "[label]". But then a script like this:
 

{
    "cmd" : 
    [
        ["rnd_int", "-10", "0"],
        ["av_mod", "$self", "Health", "$$"],
        ["rnd_int", "-10", "0"],
        ["av_mod", "$self", "Magicka", "$$"],
        ["rnd_int", "-10", "0"],
        ["av_mod", "$self", "Stamina", "$$"],
        ["actor_name", "$self"],
        ["msg_notify", "$$", ": attributes dropped"]
    ]
}

 

could instead look like this:

 

; I can easily have comments
rnd_int -10 0
av_mod $self "Health" $$
rnd_int -10 -
av_mod $self "Magicka" $$
rnd_int -10 0
av_mod $self "Stamina" $$

; new label format for syntax highlighting
[gotolabel]
actor_name $self
msg_notify $$ ": attributes dropped"

 

Which purely from a readability standpoint helps me, but the syntax highlighting is what makes it shine. Here is the same file in default configurations of Notepad++ and Microsoft VSCode, both freely available:

 

Notepad++:

image.jpeg.b74887b2989f9c1f64728258795e5526.jpeg

 

VSCode:

image.jpeg.c4cd19c3e132ac4c79023324ede0c9ed.jpeg

 

I find both of those infinitely easier to work with.

 

Also, as a consequence of this change in structure, my current implementation for the overhauled MCM now lists each extension on the left as a page, and then uses a pagination setup on the right to swap between sets of 5 (or fewer) items displayed per page.

 

I cannot delete files, so there is a "soft delete" which marks the trigger as basically inactive, effectively the same as having chance set to 0 though not all triggers necessarily have a chance attribute, so this overrides that. Once soft deleted you could of course remove the file. Alternatively if you change your mind you can undelete so long as the trigger file remains there.

 

So... with that said... 

 

... are y'all cool with that?

 

I mean, the code I have now works with the .json format, so staying pat involves zero effort. It will actually be *more* effort for me to switch to the .ini format. I just think it would be worth it. More approachable too I think.

 

The separate trigger per file is already implemented but as much as it would be an annoying change, I could also switch that back to some sort of "all triggers in a single file" or perhaps "all triggers triggered by an extension's events are contained within that extensions settings file".

 

And if push came to shove I could also change the MCM layout back to pages of triggers on the left with the indicated five shown on the right.

 

Now, before you run off to github and start playing with the extensions branch, when I say "it's implemented" what I mean is:

- SLT and the Core and SexLab extensions launch and appear to coordinate correctly and hook to events correctly

- Trigger attributes are being accurately reported to the MCM and displayed and new triggers are being created correctly.

- Trigger data is being accurately read as is Settings data

 

What I have not completed

- MCM: pagination is still broken

- MCM: I have the design for the soft delete/undelete and partial implementation but it's not complete (still needs some back end work and I have UI changes to make to support it)

- Actual event handling (hooked up but not yet tested, probably not working)

 

Oh... and one more thing...

 

-- a tiny bit of backstory

I've mentioned ConsoleUtil Extended and I'm still pretty excited about it. If/when scrab pushes the patch to Nexus, it would effectively mean you could create an entire command script in Papyrus, compile it, and then run it via trigger, rather than having the trigger execute each command individually. To help explain the difference:

 

Currently:

Event

  Trigger

    For Each Line of Script

      Switch state/string lookup to compare function to actual operation to execute

        Actually run the one single line

        Perform all necessary bookkeeping (tracking return values, error states, variable values)

 

Versus:

Event

  Trigger

    Run precompiled Papyrus script

 

Done. Now for some things it wouldn't work. If it requires access to values that it can't reach as a global script without any context, you would have to somehow break that out into separate functions or something. But there is a huge performance gain that could be had.

-- backstory over

 

So part of my redesign, a big part, was wanting to be able to extend functionality with less impact to the core mod. You should be able to add performant command instructions to your library without requiring me to recompile and re-release. The CUE/"console" command approach gets one part way there. But I've been looking at the CUE code and think there is the possibility I could create a variant of the .DLL as a new part of sl_triggers, that would allow the following variation from my current extension architecture. Mind you I just thought of this this morning, though I have had my coffee, so... grains of salt everyone, grains of salt.

 

If I were able to create .pex files in a known set of locations with a known naming convention and with the assumption that any implementer will use a known function name, I believe that I could create a new SKSE plugin (.dll) that would allow me to scan a folder, gather those .pex filenames, inform the .dll and have it load them in to make them executable (the functionality CUE already implements, so the concept is proven), and have those functions be the implementations that are currently all contained in sl_triggersCmd.psc. This would mean one .pex file per command, so I might consider making the initial bundle a .bsa for performance if that becomes an issue, but from then on, you could imagine creating a .psc file with a function called, say "_SLT_CmdEntryPoint_" that accepts, again for example, "bool Function _SLT_CmdEntryPoint(sl_triggersCmdContext cc)". Now if the .dll lets the papyrus script in SLT ask to execute one of these based on the command name, the .dll could look up the script, return it, and then I could call it.

 

In this scenario, I wouldn't need "extensions" as such because right now I created extensions to give two features: a) expand your command library and b) send SLT requests in response to other mod events. If you wanted to create more commands, my current architecture would require you to actually ship an .esp or .esl with a quest object extending and implementing my base class and a bunch of other configuration. That is a steep barrier to entry for some. Especially if otherwise all you wanted was to just add a new command.

 

Unfortunately this means adding a new .dll dependency, which turns some people off.

 

I would appreciate anyone's feedback on this.

Posted
12 hours ago, MannySauce said:

I haven't bumped into any issues on v23 with my current commands, but I stumbled over some old typos in the examples provided in sl_triggers_script_description.txt.

line 281: "actor_advkill" instead of "actor_advskill"
line 314: "actor_isquard" instead of "actor_isguard"

Went down a debugging rabbithole all night just to find out I copypasted a bad line. Also didn't need it in the end, woo, time well spent.

 

I was aware of the actor_isquard typo. Funny thing is that's the actual function name, too. I have been meaning to patch that.

 

The advskill is correctly named in the code, so the correction will just be in the documentation.

Posted (edited)
3 hours ago, Fraying9981 said:

 

Thanks!

Idk about this papyrus tweak setting, where can i find it? I will test and report back

Edit: bSpeedUpNativeCalls is set to false. is that OK?

 

  Reveal hidden contents

[Fixes]

 

;Fixes ToggleScripts command not persisting when saving/stack dumping

;Scripts will now stay turned off when toggled off, and on when toggled on.

bFixToggleScriptsCommand = true

 

;Fix unintentionally allocating script pages when getting largest available page, but out of memory.

bFixScriptPageAllocation = true

 

;Fix crash when passing in NONE object to script function Actor.IsHostileToActor().

bFixIsHostileToActorCrash = true

 

;Fix scripts that don't load right away breaking completely if they reference an invalid object type (Ex: SuperSecretScript has a function that takes InvalidScript as a parameter).

bFixDelayedScriptBreakage = true

 

 

[VM Tweaks (Tweaks that directly alter the script engine)]

 

;Maximum papyrus operations per frame. Higher number means better script performance on average

;Has a very minor impact on framerate, and varies from script to script. (Default: 500, Vanilla value: 100). Recommended Range: 100-2000. Set to 0 to disable

iMaxOpsPerFrame = 500

 

;Modify how long Papyrus can be "overstressed" before dumping stacks, in milliseconds (Default value: 15000, Vanilla value: 5000).

;Set to 0 to disable the stack dump check, or -1 to disable this setting.

;See https://www.nexusmods.com/skyrimspecialedition/articles/4625 for information on what a stack dump is

iStackDumpTimeoutMS = 15000

 

;Enables loading of doc strings from scripts into the engine. Requires `bEnableDebugInformation` to be true in this INI

bEnableDocStrings = true

 

;Enables Skyrim to load debug information of scripts. This completely overrides bLoadDebugInformation in Skyrim.ini and is provided here for easier configuration

bEnableDebugInformation = true

 

 

[Logging Tweaks (Tweaks that affect script logging)]

 

;Disables `File " % s " does not exist or is not currently loaded.` logs from being printed when calling Game.GetFormFromFile().

;This only disables the logging of the error, the error itself will still occur

bDisableGetFormFromFileErrorLogs = false

 

;Improves Base Type Mismatch error to show inheritance hierarchy of scripts; Also clarifies if the script was a genuine mismatch, or if the script doesn't exist

bImproveBaseTypeMismatchLogs = true

 

;Improves several error logs relating to incompatible arguments to better clarify what is incompatible

bImproveValidateArgsLogs = true

 

;Disable "Property %s on script %s attached to %s cannot be initialized because the script no longer contains that property" log messages.

;This only disables the logging of the warning, the warning itself will still occur

bDisableNoPropertyOnScriptErrorLogs = false

 

;Disable "Cannot open store for class "%s", missing file?" errors being logged.

;This only disables the logging of the error, the error itself will still occur

bDisableMissingScriptError = false

 

;Adds a summary of events when dumping stacks to log

bSummarizeStackDumps = true

 

 

[Experimental]

 

;(Formerly bRunScriptsOnMainThreadOnly)

;Speeds up native calls by desyncing them from framerate and instead syncing script calls to a spinlock, greatly improving script performance while still preventing concurrent execution of native calls

bSpeedUpNativeCalls = false

 

;(Formerly sMainThreadClassesToExclude, requires bSpeedUpNativeCalls=true)

;List of script classes to exclude from being sped up by bSpeedUpNativeCalls.

;It is strongly recommended to leave at defaults unless you absolutely know what you're doing

sScriptClassExclusions = UI, ConsoleUtil, PO3_SKSEFunctions, MfgConsole, MFGConsoleFunc, Input, Debug, Utility, PapyrusTweaks, Quest

 

;(Formerly sMainThreadMethodsToExclude, requires bSpeedUpNativeCalls=true)

;List of script method prefixes to exclude from being sped up (ex: "Equip" excludes "EquipItem" and "EquipItemByID", but does NOT exclude "UnequipItem".

;It is strongly recommended to leave at defaults unless you absolutely know what you're doing

;as a lot of modifying functions like `EquipItem` do not work properly if executed more than once in a single frame.

; Defaults exclude everything except for read-only functions (ex: GetFormFromFile, HasKeyword, IsLoaded, etc.)

sScriptMethodPrefixesToExclude = Activate, Add, Advance, Allow, Attach, Apply, Block, Cast, Change, Clear, Close, Complete, Create, Damage, Delete, Disable, Disallow, Dismount, Dispel, DoCombatSpellApply, Draw, Drop, Enable, End, Equip, Evaluate, Fade, Fail, Fire, Force, GetAnimation, GetQuest, Hide, Hold, Ignore, Increment, Keep, Kill, Knock, Learn, Load, Lock, Mod, Move, Mute, Open, Place, Play, Pop, Precache, Process, Push, Queue, Quit, Regenerate, Register, Release, RemoteCast, Remove, Request, Reset, Restore, Resurrect, Revert, Save, Say, Send, Serve, Set, Shake, Sheath, Show, Start, Stop, Teach, TempClone, Tether, Toggle, Translate, Trap, Trigger, Try, Unequip, Unlock, UnMute, UnPause, Update, Unregister

 

;(VR-ONLY) Pauses all non-playroom scripts while in the VR playroom, so mod scripts only initialize once you actually enter a save/new game.

;This is only experimental as it intentionally alters script behavior

bDisableScriptsInPlayroomVR = false

 

;Stops the game from resetting when loading a corrupted save

;This will NOT fix a broken save, just allows you to load the save no matter what information is lost. ONLY USE AS A LAST RESORT TO RECOVER A SAVE YOU HAVE BEEN WARNED!!

bBypassCorruptSaveMessage = false

 

;Allows the Script Engine to use as much memory as needed, with no cap. This makes `iMaxAllocatedMemoryBytes` in Skyrim.ini useless/infinite

;Note: Skyrim already ignores memory limit when stressed, this setting just keeps it ignored.

bIgnoreMemoryLimit = false

 

 

Quick update: I had actually forgotten to move the json files to the new SL trigger 23 folder. 

 

So actually it works now for the most part! Thanks a lot for the updated SL trigger 23.

I just have a question: how do you make SLSO work? at the moment it triggers for both actors or none of them.
what i want: script triggers on partner SLSO orgasm, not on player SLSO orgasm. player is female in this case.

What i see now:

  • any-any-any-actor is male -> either actor SLSO event -> script triggered
  • partner not player SLSO + male condition -> no trigger
  • partner player SLSO -> triggered upon player SLSO (this one makes sense)
  • not player, SLSO -> triggered for both player and partner. kind of weird.
  • if i switch to orgasm trigger instead of SLSO trigger -> no trigger ever at all, whatever the parameters.

perhaps i don't understand what partner player/partner not player does. please explain 🙏

Edited by Fraying9981
Posted
On 10/26/2024 at 6:52 PM, nopse0 said:

$self isn't neccessarily the player, try $player instead. Have a look at slTriggersMain.psc, sl triggers traverts pairs of actors involved in a sex scene. $self is the one at the current index, and the second actor is the one at index+1 (the "partner") in the race conditions.

 

What I am missing, is, that you can define two race conditions for the self actor.

 

E.g.:

 

condition 1: Partner is player

condition 2: Self is race Humanoid

 

Command:

 

ok i think this answers my question, in part.

So basically it means $partner doesn't mean not player, it means whoever is at index 1. great...

then how do you reference player for sure inside the scripts?

 

here is waht i'm trying to achieve:

- trigger: SLSO by the partner of the player (for sure)

- effect: something on the player.

 

it seems $self, $player, $partner don't mean the same thing based on the situation. i get it for $self but I'm confused why $partner can sometimes refer to the player.

 

it is for this script below: its referencing my player name, not my partner's name

 

Spoiler
{
	"cmd" : 
	[
        ["msg_notify", "[Fuzoku] Begin START..."],

        ["actor_name", "$partner"],
        ["set", "$0", "$$"],

        ["actor_getrelation", "$player", "$partner"],
        ["set", "$1", "$$"],
        ["if", "$1", "=", "4", "lover"],
        ["if", "$1", "=", "3", "ally"],
        ["if", "$1", "=", "2", "confidant"],
        ["if", "$1", "=", "1", "friend"],
        ["if", "$1", "=", "0", "acquaintance"],
        ["goto", "end"],
        
        [":", "lover"],
        ["msg_notify", "$0", " is devoted to you. They'd pay any price for your time and have connections that could elevate your status."],
        ["goto", "end"],
        
        [":", "ally"],
        ["msg_notify", "$0", " is a faithful client. Don't disappoint and you might get rewarded. Unload these balls, they are made of gold."],
        ["goto", "end"],
        
        [":", "confidant"],
        ["msg_notify", "$0", " is a somewhat regular. They know what they want and expect decent service."],
        ["goto", "end"],
        
        [":", "friend"],
        ["msg_notify", "$0", " has had you in the past. You don't really like them, but you have to do your job."],
        ["goto", "end"],
        
        [":", "acquaintance"],
        ["msg_notify", "$0", " is a new client! Or, you never managed to create a lasting impression in the past and they don't care. You must be desperate."],
        
        [":", "speech_check"],
        ["util_wait", "3"],
        ["av_get", "$player", "Speechcraft"],
        ["set", "$5", "$$"],
        ["if", "$5", ">=", "100", "speech_100"],
        ["if", "$5", ">=", "90", "speech_90"],
        ["if", "$5", ">=", "80", "speech_80"],
        ["if", "$5", ">=", "70", "speech_70"],
        ["if", "$5", ">=", "60", "speech_60"],
        ["if", "$5", ">=", "50", "speech_50"],
        ["if", "$5", ">=", "40", "speech_40"],
        ["if", "$5", ">=", "30", "speech_30"],
        ["if", "$5", ">=", "20", "speech_20"],
        ["if", "$5", ">=", "10", "speech_10"],
        ["goto", "speech_0"],
        
        [":", "speech_100"],
        ["msg_notify", "$0", " finds you attractive like a goddess incarnate."],
        ["goto", "end"],
        
        [":", "speech_90"],
        ["msg_notify", "Your irresistible presence has ", "$0", " utterly mesmerized."],
        ["goto", "end"],
        
        [":", "speech_80"],
        ["msg_notify", "Your allure has ", "$0", " thinking about you long after they leave."],
        ["goto", "end"],
        
        [":", "speech_70"],
        ["msg_notify", "Your seductive skills have ", "$0", " completely captivated."],
        ["goto", "end"],
        
        [":", "speech_60"],
        ["msg_notify", "Your charm makes ", "$0", " noticeably excited to be with you."],
        ["goto", "end"],
        
        [":", "speech_50"],
        ["msg_notify", "You're attractive enough that ", "$0", " gives you a second glance."],
        ["goto", "end"],
        
        [":", "end"],
        ["msg_notify", "[Fuzoku] Begin END..."]

	]
}

 

 

Posted
2 minutes ago, Fraying9981 said:

 

ok i think this answers my question, in part.

So basically it means $partner doesn't mean not player, it means whoever is at index 1. great...

then how do you reference player for sure inside the scripts?

 

here is waht i'm trying to achieve:

- trigger: SLSO by the partner of the player (for sure)

- effect: something on the player.

 

it seems $self, $player, $partner don't mean the same thing based on the situation. i get it for $self but I'm confused why $partner can sometimes refer to the player.

 

it is for this script below: its referencing my player name, not my partner's name

 

  Reveal hidden contents
{
	"cmd" : 
	[
        ["msg_notify", "[Fuzoku] Begin START..."],

        ["actor_name", "$partner"],
        ["set", "$0", "$$"],

        ["actor_getrelation", "$player", "$partner"],
        ["set", "$1", "$$"],
        ["if", "$1", "=", "4", "lover"],
        ["if", "$1", "=", "3", "ally"],
        ["if", "$1", "=", "2", "confidant"],
        ["if", "$1", "=", "1", "friend"],
        ["if", "$1", "=", "0", "acquaintance"],
        ["goto", "end"],
        
        [":", "lover"],
        ["msg_notify", "$0", " is devoted to you. They'd pay any price for your time and have connections that could elevate your status."],
        ["goto", "end"],
        
        [":", "ally"],
        ["msg_notify", "$0", " is a faithful client. Don't disappoint and you might get rewarded. Unload these balls, they are made of gold."],
        ["goto", "end"],
        
        [":", "confidant"],
        ["msg_notify", "$0", " is a somewhat regular. They know what they want and expect decent service."],
        ["goto", "end"],
        
        [":", "friend"],
        ["msg_notify", "$0", " has had you in the past. You don't really like them, but you have to do your job."],
        ["goto", "end"],
        
        [":", "acquaintance"],
        ["msg_notify", "$0", " is a new client! Or, you never managed to create a lasting impression in the past and they don't care. You must be desperate."],
        
        [":", "speech_check"],
        ["util_wait", "3"],
        ["av_get", "$player", "Speechcraft"],
        ["set", "$5", "$$"],
        ["if", "$5", ">=", "100", "speech_100"],
        ["if", "$5", ">=", "90", "speech_90"],
        ["if", "$5", ">=", "80", "speech_80"],
        ["if", "$5", ">=", "70", "speech_70"],
        ["if", "$5", ">=", "60", "speech_60"],
        ["if", "$5", ">=", "50", "speech_50"],
        ["if", "$5", ">=", "40", "speech_40"],
        ["if", "$5", ">=", "30", "speech_30"],
        ["if", "$5", ">=", "20", "speech_20"],
        ["if", "$5", ">=", "10", "speech_10"],
        ["goto", "speech_0"],
        
        [":", "speech_100"],
        ["msg_notify", "$0", " finds you attractive like a goddess incarnate."],
        ["goto", "end"],
        
        [":", "speech_90"],
        ["msg_notify", "Your irresistible presence has ", "$0", " utterly mesmerized."],
        ["goto", "end"],
        
        [":", "speech_80"],
        ["msg_notify", "Your allure has ", "$0", " thinking about you long after they leave."],
        ["goto", "end"],
        
        [":", "speech_70"],
        ["msg_notify", "Your seductive skills have ", "$0", " completely captivated."],
        ["goto", "end"],
        
        [":", "speech_60"],
        ["msg_notify", "Your charm makes ", "$0", " noticeably excited to be with you."],
        ["goto", "end"],
        
        [":", "speech_50"],
        ["msg_notify", "You're attractive enough that ", "$0", " gives you a second glance."],
        ["goto", "end"],
        
        [":", "end"],
        ["msg_notify", "[Fuzoku] Begin END..."]

	]
}

 

 

 

$player always resolves to the player in all situations on all commands

$self always resolves to whomever the script is executing on

   (note that if your script will end up running on every member of a scene, then in each instance, $self will resolve to that specific Actor)

$actor, $actor2, $actor3, $actor4 resolve to SexLab actors in positions 1-4 respectively

 

====

two examples:

 

SexLab scene starts.

Position 1 - Follower (Humanoid)

Position 2 - Player

 

if trigger condition is:   if_player == "Not Player"

script runs on: Follower

$self: Follower

$actor: Follower

$actor2: Player

 

if trigger condition is: if_player == "Player"

script runs on: Player

$self: Player

$actor: Follower

$actor2: Player

 

Different SexLab scene starts.

Position 1 - Player

Position 2 - Follower (Humanoid)

 

if trigger condition is:   if_player == "Not Player"

script runs on: Follower

$self: Follower

$actor: Player

$actor2: Follower

 

if trigger condition is: if_player == "Player"

script runs on: Player

$self: Player

$actor: Player

$actor2: Follower

 

 

Posted
8 hours ago, sirretinee said:

Fixing the typo seems to have fixed everything, but still doesn't explain why it was auto-firing when just... in the world.
Maybe I saved too soon after an animation or something? No idea.

For reference, here's an updated script. Checks if you're in an animation right there at the beginning and shuts it down if not. Ideally it wouldn't be needed but now i'm unreasonably superstitious about scripts firing randomly so it stays until I go back and clean up the unnecessary debug notifications.
image.png.e25c883c87814065220091a0195af7d6.png
I wasn't getting notified with "Trigger ended" every five seconds, so i'm just going to chalk up the script firing during normal gameplay to script weirdness and call it a day.
sl_triggers itself does what I need it to do now and that's what matters.

 

Sorry, I didn't even try to fix the loop despite pointing it out. My bad, I was that damn tired. 🫥

I made this edit and tested it (and removed the debug messages), from what I could tell this scales correctly when both changing animation and when ending animations.

 

        [":", "start"],
        ["util_wait", "5"],
        ["sl_isin", "$self"],
            ["if", "$$", "=", "0", "rescale"],
        ["sl_hastag", "Bigguy"],
            ["if", "$$", "=", "0", "rescale"],
        ["sl_isinslot", "$self", "1"],
            ["if", "$$", "=", "0", "rescale"],
        ["console", "$self", "setscale 1.15"],
        ["goto", "start"],
        [":", "rescale"],
        ["console", "$self", "setscale 1.0"],
        ["sl_isin", "$self"],
            ["if", "$$", "=", "1", "start"]

Posted
1 minute ago, hextun said:

 

$player always resolves to the player in all situations on all commands

$self always resolves to whomever the script is executing on

   (note that if your script will end up running on every member of a scene, then in each instance, $self will resolve to that specific Actor)

$actor, $actor2, $actor3, $actor4 resolve to SexLab actors in positions 1-4 respectively

 

====

two examples:

 

SexLab scene starts.

Position 1 - Follower (Humanoid)

Position 2 - Player

 

if trigger condition is:   if_player == "Not Player"

script runs on: Follower

$self: Follower

$actor: Follower

$actor2: Player

 

if trigger condition is: if_player == "Player"

script runs on: Player

$self: Player

$actor: Follower

$actor2: Player

 

Different SexLab scene starts.

Position 1 - Player

Position 2 - Follower (Humanoid)

 

if trigger condition is:   if_player == "Not Player"

script runs on: Follower

$self: Follower

$actor: Player

$actor2: Follower

 

if trigger condition is: if_player == "Player"

script runs on: Player

$self: Player

$actor: Player

$actor2: Follower

 

 

 

Forgot to add, you asked about the meaning behind "Player"/"Not Player"/"Partner Player"/"Partner Not Player". And it goes into the triggers generally.

 

So as you may already know, when you define a SexLab trigger and a scene starts, the trigger conditions get checked for each member of the scene. And $self is always contextually whomever is being considered. So for any given trigger condition, phrase it like "As a member of the SexLab scene, if I am.." and that should help you work out the context of who the trigger will end up actually executing on.

 

So in this case, with the "Player" value, you're asking "As a member of the SexLab scene, If I am... the Player... or Not the Player.... or a Partner to the Player... or Not a Partner to the Player".

 

"If I am the Player": will only run on the Player

"If I am not the Player": will run on every member of that specific scene *except* for the Player

"If I am Partner to the Player": will run on everyone in the scene *if* they are a partner to the player and not the player themselves... so if a scene is NPC on NPC, it would not fire on either of them

"If I am Not Partner to the Player": will run on everyone in the scene if they *are* a partner to the player and not the player themselves... so if a scene is NPC on NPC, it would not fire on any of them

 

And by "SexLab scene" I'm referring to a specific animation instance with interacting partners. For example situations like Scrappies or other mods that fire off orgies result in one scene per sex act. Which is why you might get, or even want, hits on NPC-NPC scenes.

Posted
6 minutes ago, hextun said:

 

$player always resolves to the player in all situations on all commands

$self always resolves to whomever the script is executing on

   (note that if your script will end up running on every member of a scene, then in each instance, $self will resolve to that specific Actor)

$actor, $actor2, $actor3, $actor4 resolve to SexLab actors in positions 1-4 respectively

 

====

two examples:

 

SexLab scene starts.

Position 1 - Follower (Humanoid)

Position 2 - Player

 

if trigger condition is:   if_player == "Not Player"

script runs on: Follower

$self: Follower

$actor: Follower

$actor2: Player

 

if trigger condition is: if_player == "Player"

script runs on: Player

$self: Player

$actor: Follower

$actor2: Player

 

Different SexLab scene starts.

Position 1 - Player

Position 2 - Follower (Humanoid)

 

if trigger condition is:   if_player == "Not Player"

script runs on: Follower

$self: Follower

$actor: Player

$actor2: Follower

 

if trigger condition is: if_player == "Player"

script runs on: Player

$self: Player

$actor: Player

$actor2: Follower

 

 

 

thank you!

damn it's so powerful. ok I know what to try now.

Posted

Out of curiosity, would you all prefer using this scripting approach or would you prefer if you actually had the ability to precompile your own .psc functions to perform bundles of activity with a performance improvement? Albeit with the requirement that you now can set up a Papyrus compilation environment?

 

Posted (edited)

I'm aboard with the overhauled version, but does that mean we need to compile scripts with the Creation Kit?

 

EDIT: My preference is still .json/.ini, only just because I'm too stubborn to set up a Creation Kit install.

Edited by MannySauce
Timing
Posted
5 minutes ago, hextun said:

 

Forgot to add, you asked about the meaning behind "Player"/"Not Player"/"Partner Player"/"Partner Not Player". And it goes into the triggers generally.

 

So as you may already know, when you define a SexLab trigger and a scene starts, the trigger conditions get checked for each member of the scene. And $self is always contextually whomever is being considered. So for any given trigger condition, phrase it like "As a member of the SexLab scene, if I am.." and that should help you work out the context of who the trigger will end up actually executing on.

 

So in this case, with the "Player" value, you're asking "As a member of the SexLab scene, If I am... the Player... or Not the Player.... or a Partner to the Player... or Not a Partner to the Player".

 

"If I am the Player": will only run on the Player

"If I am not the Player": will run on every member of that specific scene *except* for the Player

"If I am Partner to the Player": will run on everyone in the scene *if* they are a partner to the player and not the player themselves... so if a scene is NPC on NPC, it would not fire on either of them

"If I am Not Partner to the Player": will run on everyone in the scene if they *are* a partner to the player and not the player themselves... so if a scene is NPC on NPC, it would not fire on any of them

 

And by "SexLab scene" I'm referring to a specific animation instance with interacting partners. For example situations like Scrappies or other mods that fire off orgies result in one scene per sex act. Which is why you might get, or even want, hits on NPC-NPC scenes.

 

what about SLSO trigger?

 

if player + SLSO -> when player SLSO, run on player?

if not player + SLSO -> when not player, run on not player?

It seems SLSO trigger is a global trigger right? on both actors?

It's not individual SLSO right?

Which means atm it's impossible to have a script running only based on 1 actor's SLSO, NOT both?

Posted
9 minutes ago, hextun said:

Out of curiosity, would you all prefer using this scripting approach or would you prefer if you actually had the ability to precompile your own .psc functions to perform bundles of activity with a performance improvement? Albeit with the requirement that you now can set up a Papyrus compilation environment?

 

 

I don't know how to use papyrus script or creation lab and this is the reason why I'm using this mod :)

So I'm actually a fan of what it is now, because I don't need to learn papyrus scripting & compiling, it's json that I can understand. Thanks again for your great work!

Posted
2 minutes ago, Fraying9981 said:

 

what about SLSO trigger?

 

if player + SLSO -> when player SLSO, run on player?

if not player + SLSO -> when not player, run on not player?

It seems SLSO trigger is a global trigger right? on both actors?

It's not individual SLSO right?

Which means atm it's impossible to have a script running only based on 1 actor's SLSO, NOT both?

 

When you go to the SexLab MCM, as you know, you can toggle whether to use separate orgasms or not. Depending on which selection you pick determines which type of event gets sent and sl_triggers registers for both kinds and handles them separately. So when you say a trigger is "SexLab Orgasm" that will only fire if the toggle is not set to Separate. "SLSO Orgasm" will only fire if it is.

 

In both cases it is only fired one time per orgasm. But of course without separate orgasms, you would only get the event the one time.

 

However, when the event runs, for either type of orgasm, each trigger for that type of orgasm is checked for all of its trigger properties against every actor in the scene. And any actor that matches all of the conditions will have the script run on them, with $self set to that Actor.

 

In a scene in which, say, only the aggressor is receiving enjoyment and therefore (in SLSO) would be the only one to orgasm, SLSO reduces to the same case as non-SLSO. Only one orgasm would happen, the trigger would be checked against both/all actors and the associated command(s) run against neither/both/either/all based on if each actor meets all relevant criteria. 

 

In a scene in which both would have orgasmed separately in SLSO, I believe you would get two SLSO orgasm events and thus two possibilities for all SLSO orgasm related triggers to check their conditions and possibly run their commands. Versus for the non-separate orgasms, presumably even if "both" would orgasm, only one event fires. To be fair, I have never played without SLSO so I'm fuzzy on that, but reading the code suggests this is the case.

 

Regardless, once the event fires... it's all about checking the trigger conditions on each actor again.

 

So... let's say you have SLSO (i.e. SexLab is configured for separate orgasms). 

 

If you configure a trigger as:

On event SLSO Orgasm

 

along with, for example:

player - "Is Player" : it will only run when the player orgasms in the SLSO scene

player - "Is Not Player": runs for everyone *but* the player in the scene; for example in a gang bang, when *anyone* in the SLSO scene orgasms (player or not), the triggers get checked. So if the *player* orgasms but you have it set for "Is Not Player", the trigger commands would then run on all of the attackers

player - "Is Not Player" / race - "Is Creature" : and in the scene the player is pleasuring two horses (I've had this scene pop up for me... creative to say the least) and the player orgasms, the script would run on both horses.

Posted
15 minutes ago, Fraying9981 said:

 

I don't know how to use papyrus script or creation lab and this is the reason why I'm using this mod :)

So I'm actually a fan of what it is now, because I don't need to learn papyrus scripting & compiling, it's json that I can understand. Thanks again for your great work!

 

That's fair and a good reason for me not to push a full .psc style approach. Have to know your userbase. :)

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...