Jump to content

Recommended Posts

Posted

I'm trying to grab the ID of an actor's equipped weapon(s), but there seems to be an issue with:

 

actor_dofunction $system.self GetEquippedWeapon RightHand

 

As trying to set it into a variable fails and prints this in the log:

 

Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value

 

Also if you remove the last parameter (in this case RightHand, which I initially forgot to include) you get a questionable math-aint-mathing error:

 

insufficient parameters (needed at least 3 but only provided 3)

(bruh)

Posted (edited)
8 hours ago, MannySauce said:

I'm trying to grab the ID of an actor's equipped weapon(s), but there seems to be an issue with:

 

actor_dofunction $system.self GetEquippedWeapon RightHand

 

As trying to set it into a variable fails and prints this in the log:

 

Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value

 

Also if you remove the last parameter (in this case RightHand, which I initially forgot to include) you get a questionable math-aint-mathing error:

 

insufficient parameters (needed at least 3 but only provided 3)

(bruh)

 

Okay, fun shenanigans all the way around. :)

 

Bug #1: The error messages are wrong. The math mathed, but the words did not word. I'll fix that for next release. Well, I mean, that and the next one, too.

 

Bug #2: While I do try to take into account defaults in most cases, and tend to handle them correctly, I'm going to have to take a quick pass at the *_dofunction and *_doconsumer functions to make sure that I allow for defaults *there*. As I said, the length includes the function name (i.e. 'actor_dofunction'). And the *_dofunction class of *sigh* functions have arguments. So for optimization I do a check before even looking at the function names: is the command length at least 4? Because I was assuming the parameter would be required. But when a default is available, obviously that is wrong. So in this case, it's saying "hey, I expected something after the first 3 blobs of text on that line, probably a 3rd parameter for a function" even though it should work because the default value.

 

Bug #3: Like I said, I really do make an effort to respect defaults. Except, apparently, for GetEquippedWeapon specifically *smh*. So that one requires (for now, again fixed soon) the argument, as you surmised.

 

Bug #4: This one is minor in impact but still a bug. The return value from the "GetEquippedWeapon" subcommand treats the valid 'none' result as a failure condition, emitting the error you see. When you specified "RightHand" as the parameter, bare, it treats that as an "unresolved result". Most of the time it tries to treat it like a string. And when you convert a string to a bool, as with Papyrus, all it does is check if the string is empty or not. If it's empty, false; true otherwise. So you were specifying 'RightHand', which was translated to a bool true, which meant you were actually retrieving left hand data. That's not the bug: the reason why you were getting an error about RT_INVALID when trying to use RightHand (which resolved to true) as the parameter is because I am assuming you did not, in fact, have a Weapon (i.e. a Shield or Spell would not count) in your left hand. The bug is that in that case I should quietly return none and mark it as properly resolved. Instead I really sort of behave like it's a failure condition; attempting to resolve the returned Form(Weapon) would still give the expected result, namely 'none', but the bug is that the return value in the none case isn't treated as valid.

 

Instead it just doesn't re

 

Subsequent attempts to use that value assuming it had valid data would result in being unable to resolve it and in many cases functions will not return a value at all, giving you an RT_INVALID somewhere along the way because something expected a value and didn't get one.

 

But, the argument For Actor.GetEquippedWeapon is (bool abLeftHand = false) according to Creation Kit. Although you may be able to work it out from here, for the sake of anyone else who comes along with a similar problem with the *_doaction/*_dogetter/*_doconsumer/*_dofunction commands.

 

Here's my wiki docs for actor_dofunction: https://github.com/lynnpye/sl_triggers/wiki/Function-Libraries#actor_dofunction

 

I include the link to the CreationKit wiki documentation for the relevant script for each of these, so in this case it links you to https://ck.uesp.net/wiki/Actor_Script.

 

From there you would search for your function i.e. "GetEquippedWeapon". You can see it has the following signature:

    Weapon Function GetEquippedWeapon(bool abLeftHand = false) native

 

You can ignore the "native" bit.

 

It returns a "Weapon" which you can search around and see is a type of Form, which SLTScript understands. That will wind up in "$$" or be what comes back from "set/resultfrom".

 

It expects one argument, a boolean (i.e. true or false) which determines whether to check the left (if true) or right hand (if false, or by default, i.e. with no parameter specified).

 

So the following two lines should retrieve the left hand ($lh_weapon) and right hand ($rh_weapon) weapons that the Actor has equipped. These should work in the latest shipping version of SLTR. 

 

set $rh_weapon resultfrom actor_dofunction $system.self GetEquippedWeapon false
set $lh_weapon resultfrom actor_dofunction $system.self GetEquippedWeapon true

 

 

Here's my test script:

deb_msg "Zb04 Start"

set $self_name resultfrom actor_name $system.self
deb_msg $"Script running for {$self_name}"

set $eq_weapon resultfrom actor_dofunction $system.self GetEquippedWeapon
set $eq_name resultfrom form_dogetter $eq_weapon GetName
deb_msg $"1: eq_weapon({$eq_weapon}) eq_name({$eq_name})"

set $eq_weapon resultfrom actor_dofunction $system.self GetEquippedWeapon RightHand
set $eq_name resultfrom form_dogetter $eq_weapon GetName
deb_msg $"2: eq_weapon({$eq_weapon}) eq_name({$eq_name})"

set $rh_weapon resultfrom actor_dofunction $system.self GetEquippedWeapon false
set $lh_weapon resultfrom actor_dofunction $system.self GetEquippedWeapon true
set $rh_name resultfrom form_dogetter $rh_weapon GetName
set $lh_name resultfrom form_dogetter $lh_weapon GetName
deb_msg $"3: rh_weapon({$rh_weapon}) rh_name({$rh_name}) / lh_weapon({$lh_weapon}) lh_name({$lh_name})"

deb_msg "Zb04 Stop"

It makes the calls you do (without the parameter, which definitely doesn't work; using "RightHand"; and then using true and false).

 

I ran the script twice.

 

Run #1: RH: Imperial Sword of Long-Embers / LH: Iron Dagger

Run #2: RH: Imperial Sword of Long-Embers / Empty

 

I also ran it with Flames in the left hand and got the same (literally the same) output as when nothing was equipped, so did not include that run's output.

 

The output in the log:

 

Main.DequeueScriptForTarget: requestString(1|2|zb04)
DebMsg> Zb04 Start
DebMsg> Script running for khvb
SLTR:(zb04.sltscript)[6]: insufficient parameters (needed at least 3 but only provided 3)
SLTR:(zb04.sltscript)[6]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
[2025-09-07 07:32:20.385] [log] [warning] [util.cpp:495] GetForm: invalid form specifier ()
SLTR:(zb04.sltscript)[7]: Form not found ()
SLTR:(zb04.sltscript)[7]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
DebMsg> 1: eq_weapon() eq_name()
DebMsg> 2: eq_weapon(Skyrim.esm:80254) eq_name(Iron Dagger)
DebMsg> 3: rh_weapon(quick start - se.esp:14466) rh_name(Imperial Sword of Long-Embers) / lh_weapon(Skyrim.esm:80254) lh_name(Iron Dagger)
DebMsg> Zb04 Stop
Main.DequeueScriptForTarget: requestString(4|5|zb04)
DebMsg> Zb04 Start
DebMsg> Script running for khvb
SLTR:(zb04.sltscript)[6]: insufficient parameters (needed at least 3 but only provided 3)
SLTR:(zb04.sltscript)[6]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
[2025-09-07 07:32:52.434] [log] [warning] [util.cpp:495] GetForm: invalid form specifier ()
SLTR:(zb04.sltscript)[7]: Form not found ()
SLTR:(zb04.sltscript)[7]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
DebMsg> 1: eq_weapon() eq_name()
SLTR:(zb04.sltscript)[10]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
[2025-09-07 07:32:53.282] [log] [warning] [util.cpp:495] GetForm: invalid form specifier ()
SLTR:(zb04.sltscript)[11]: Form not found ()
SLTR:(zb04.sltscript)[11]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
DebMsg> 2: eq_weapon() eq_name()
SLTR:(zb04.sltscript)[15]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
[2025-09-07 07:32:54.536] [log] [warning] [util.cpp:495] GetForm: invalid form specifier ()
SLTR:(zb04.sltscript)[17]: Form not found ()
SLTR:(zb04.sltscript)[17]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value
DebMsg> 3: rh_weapon(quick start - se.esp:14466) rh_name(Imperial Sword of Long-Embers) / lh_weapon() lh_name()
DebMsg> Zb04 Stop

 

So on line 6, the script tries to set the resultfrom GetEquippedWeapon, but the function failed due to parameter length bug and nothing was returned. resultfrom uses '$$' and since nothing was returned, you get the RT_INVALID error.

 

Line 7, another resultfrom referencing a function that fails, this time because it used the expected output without checking it against 'none' (i.e. if $eq_weapon == none).

 

Line 10, the error comes from Bug #4 but it is operating as expected: 'RightHand' becomes "RightHand" which coerced to bool is true, thus you are actually looking at the left hand.

 

Line 11, the error stems from attempting to use a none value.

 

And lines 15 and 17 are solely because there is nothing in the left hand as a Weapon.

Edited by hextun
Posted

v0.941 released. Not much to say. Bugs be gone!

 

Savegame compatible
Reminder: Note that logging output is all sent to <My Documents>\My Games\Skyrim Special Edition\SKSE\sl-triggers.log 
    (or whichever folder you have your SKSE logs directed to)
bugfix: *_dofunction/*_doconsumer class functions not allowing for default parameters
bugfix: argument length related error messages are misleading
bugfix: actor_dofunction $$ GetEquippedWeapon not allowing for default parameter
bugfix: actor_dofunction $$ GetEquippedWeapon; none value is valid return value but behaves as if invalid

Posted (edited)

I'm trying to get an LL club set up where anyone could join and folks could share scripts, mini-games, whatever they've put together. Presumably that way it could be kept organized and such. Pending approval.

 

Correction: I have setup an LL club for SLTR. Overkill? Probably. Convenient method to let LL users share content without me stepping in? Absolutely. :) Get your share on.

Edited by hextun
Posted

v0.950 is available for your entertainment. The changelog is lengthy but boils down to:

- SexLab Survival integration

- Further PetCollar integration

- new intrinsics: typeid and typename; typeid of 0 in particular means the variable is not set

- new system variable: $system.forms.sltr_main - usable when other mods need a "key" form to associate changes with e.g. NIO, SLS

 

The changelog:

Spoiler

Savegame compatible
Reminder: Note that logging output is all sent to <My Documents>\My Games\Skyrim Special Edition\SKSE\sl-triggers.log 
    (or whichever folder you have your SKSE logs directed to)
enhancement: new system variable: $system.forms.sltr_main - Form: the SLTR Main Quest; useful for functions requiring tracking Forms
enhancement: integration: SexLab Survival:
    new functions
        sls_block_license_purchase
        sls_revoke_license
        sls_send_to_kennel
        sls_evict_from_home
        sls_unevict_from_home
        sls_increase_ground_time
        sls_remove_magic_curse
        sls_add_magic_curse
        sls_swallow_cum
        sls_get_creature_corruption
        sls_is_enjoying_cum
        sls_get_load_tier
        sls_get_load_size
        sls_get_load_size_actual
        sls_get_load_fullness
        sls_get_cum_stuffed_factor
        sls_is_drugged
        sls_is_high_on_skooma
        sls_is_high_on_skooma_whore_drugs
        sls_is_high_on_lactacid
        sls_get_skooma_junkie_level
        sls_do_female_pain_sound
        sls_do_hit_sound
        sls_do_trauma_hit_sound
    new SLTScripts:
        SLS Evict from Markarth/Riften/Solitude/Whiterun/Windhelm
        SLS UnEvict from Markarth/Riften/Solitude/Whiterun/Windhelm
        SLS Send to Kennel - Markarth/Riften/Solitude/Whiterun/Windhelm
        SLS Magic Curse Add/Remove
        SLS Revoke All/Random Licenses
enhancement: typeid: intrinsic command that returns an int representing the type of the variable
    This can be used to determine if a value has ever been set before, including globals.
    Because system variables are more akin to macros rather than actual variables, they also have no type ID. But you can
    obtain it by setting a variable to the value of the system variable.
    Possible values:
    - 0 - Invalid (meaning that it has no data)
    - 1 - string
    - 2 - bool
    - 3 - int
    - 4 - float
    - 5 - Form (or Form sub-type e.g. ObjectReference, Actor)
    - 6 - Label - a goto target e.g. [label]
    - 7 - Map
    - 8 - Alias (or ReferenceAlias)
    - 101 - string[] (i.e. string list)
    - 102 - bool[]
    - 103 - int[]
    - 104 - float[]
    - 105 - Form[]
    - 106 - Label[]
    - ; there is no list of maps
    - 108 - Alias[]
enhancement: typename: intrinsic command that returns a string representing the type of the variable
    Returns the name associated with the id from `typeid`.
    Possible values:
    - "Invalid"
    - "string"
    - "int"
    - "float"
    - "bool"
    - "Form"
    - "Label"
    - "Map"
    - "Alias"
    - "string[]"
    - "bool[]"
    - "int[]"
    - "float[]"
    - "Form[]"
    - "Label[]"
    - "Alias[]"
bugfix: PetCollarGame: after sending the PetCollar event for removal, now sits in a 1 second wait loop until the player is no longer wearing the collar before removing it from inventory
enhancement: integration: PetCollar:
    new SLTScripts:
        PetCollar - Add
        PetCollar - Add Keyless
        PetCollar - Remove
        PetCollar - Remove Keyless

 

Posted

Roadmapping to 1.0

At this point I consider SLTR to be feature complete for a 1.0 release. By "feature complete" I'm referring to the SLTScript features. There is ample room for optimization, but for now the script itself is fit enough for purpose. And if I've done things correctly, those optimizations shouldn't affect script syntax, just make things faster. That can either go in pre or post 1.0 but isn't what I would call a roadblock.

 

I primarily want to let things simmer a bit before taking it off the cooktop, see what amazing new (or old) bugs y'all find! At some point in the near future, if this state of things doesn't change, I'll pick a point in time, slap a 1.0 on things and make a release.

 

After that, but before a possible 2.0

Once 1.0 is out, it would of course receive fixes. Otherwise, new integrations, add-ons, SLTScripts, and so on would still be able to be added.

 

Ideas for 2.0

What would go into a 2.0?

 

While the point of 1.0 was to make SLTScript as capable as possible, 2.0 would be all about that performance, that sweet, sweet performance.

 

Trigger-direct-to-Papyrus: at the moment triggers are allowed up to 4 SLTScripts that can be run as a result of a successful trigger. This feature would let you specify a Papyrus script and function name (for a global script) and that would be called instead of an SLTScript.

Purpose: By creating hand-crafted Papyrus functions which are called in response to triggers, you can perform far more complex activities with much less overhead. It also lets you link up mods in ways they don't now e.g. responding to a trigger from one mod with a function that performs actions in another mod). The same things you do now in your SLTScript but now targeting your far more efficient Papyrus script.

 

Papyrus-auto-compile-on-startup: The caprica Papyrus compiler is an open-source console application capable of compiling .psc files to .pex suitable for use with Skyrim. In a nutshell, you will place .psc files into an SLTR sub-folder (e.g. 'auto_build_psc\'), and you will place any required "header only" .psc files into another SLTR sub-folder (e.g. 'auto_build_import\'). Then you'll place a copy of caprica.exe into the caprica\ sub-folder. When the game starts and runs the SLTR plugin, it will look for caprica.exe and run it on the .psc files in your folder. The resulting .pex files will be placed into the scripts\ subfolder (likely in 'overwrite\' if using MO2). Then the plugin tells the game to load each of those scripts. My initial tests worked, although there was, as you might expect, a lurch at the start of the game because, hey, surprise compiling. I also would want to make it smart enough not to recompile things that it detects are already built. That said, I have gotten it to work on my install. You're still having to write Papyrus, and if you don't include the correct supporting import files, the build is going to fail, though it won't otherwise impede the launch of the game besides the build time itself.

 

Memory-management-in-plugin: Right now I use StorageUtil for a lot of memory management, and a lot of reliance on PapyrusUtil and list manipulation for the rest of it. This results in, I think, a lot of extra effort when custom objects implemented in the SLTR plugin itself could make things far more optimized and better organized.

 

Script-execution-in-plugin: I had actually implemented this one; execution of a script resulted in everything happening on a detached C++ thread in the plugin, performing all logic in the plugin until it came time to call functions (i.e. 'util_wait', 'sl_isin'), whereupon it would call back to the VM. The problem I encountered was, as it happens, saves. I didn't have a good way to save the current state of the plugin's execution, taking into account when calls have been made into the VM and it's waiting on them, and have it resume on loading the save. And since I want these scripts to survive save reloading, I couldn't have that. I also tried a version where execution was "driven" by the Papyrus side of things, but each command was run by the plugin. Either way, I'm looking for ways to make execution faster.

 

Ad-hoc-event-listening: Wouldn't it be nice if, inside your SLTScript, you could say "listenfor 'On_SomeEvent'" and it would wait until that event was received and then proceed? Yeah, me too. There are *huge* caveats to being able to do that, namely how to handle custom events, but this could be achievable for standard mod events.

 

Dynamic-Papyrus-invocation: This is sort of my holy grail. I want to give SLTScript users the ability to write something like: "dyna_call actor getname $system.self" and have it know to look for the Actor script (in Papyrus), the GetName function (on that script), and that the first parameter is the instance for it (if it's an instance function) and that any remaining required parameters would be provided. All the rails would be off here. The object? No more needing to wait for me to implement an integration; if you see Papyrus script, you can call it. This is... not likely. Or if it happens it's going to come with some caveats. 

 

Anything else to add?

Not really. Thanks for using SLTR. :)

Posted (edited)

Ran into some more issues. 🥺

This is valid, right?

 

av_getmax $system.player Stamina
av_damage $system.player Stamina $$

 

It breaks and logs:

 

[error] [sl_triggers.cpp:729] SLTR:(FunnyScriptName.sltscript)[2]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value

 

I mostly use "resultfrom" now, so I dunno if I messed up some basic $$ stuff here.

 

And another issue with "av_getpercentage" not existing?

 

set $local.MagickaPercentage resultfrom av_getpercentage $system.player Magicka

 

[error] [engine.cpp:22] RunOperationOnActor: Unable to find operation av_getpercentage in function library cache

 

I should probably do all of this with "actor_do" stuff, but the old functions are burned into memory by now. 😩

 

EDIT:

 

Forgot one. This works, but the log prints this every time it runs:

 

snd_play "MannyResources.esm:2058" $system.self

 

!!!!!!!!!!!!!!!!!

				FormPortableStringFromForm: unable to get modName from theForm()<[Actor < (FF00101E)>]> formID(4126) modIndex(255) light modIndex(0) lightShift(0)

!!!!!!!!!!!!!!!!!

 

 

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

Ran into some more issues. 🥺

This is valid, right?

 

av_getmax $system.player Stamina
av_damage $system.player Stamina $$

 

It breaks and logs:

 

[error] [sl_triggers.cpp:729] SLTR:(FunnyScriptName.sltscript)[2]: Invalid MostRecentResultType value(0)[<invalid RT type: 0>](note: if invalid status is not indicated, please report a bug); likely due to using $$ after calling a function that has no return value

 

I mostly use "resultfrom" now, so I dunno if I messed up some basic $$ stuff here.

 

And another issue with "av_getpercentage" not existing?

 

set $local.MagickaPercentage resultfrom av_getpercentage $system.player Magicka

 

[error] [engine.cpp:22] RunOperationOnActor: Unable to find operation av_getpercentage in function library cache

 

I should probably do all of this with "actor_do" stuff, but the old functions are burned into memory by now. 😩

 

EDIT:

 

Forgot one. This works, but the log prints this every time it runs:

 

snd_play "MannyResources.esm:2058" $system.self

 

!!!!!!!!!!!!!!!!!

				FormPortableStringFromForm: unable to get modName from theForm()<[Actor < (FF00101E)>]> formID(4126) modIndex(255) light modIndex(0) lightShift(0)

!!!!!!!!!!!!!!!!!

 

 

 

I'm still looking at the last one, but just posted a fix, v0.951, that addresses the first issues with.

 

Bug #1: av_getpercentage was not named correctly but was documented correctly. I hadn't set the name properly (and I won't mention it because it's close and I don't want to confuse folks) but had set the documentation to what I wanted. I probably forgot to change the name. Anyway, the name is changed now; av_getpercentage should be recognized now.

 

Bug #2: $$ couldn't be used as a function argument. At some point in a sense of overzealous type purity, I probably got fed up with something to do with return types bleeding through when functions didn't return something. My "fix" was to invalid the return value just prior to calling the function. Great, right? Except the function implementation needs to be able to resolve "$$" along with any other variable name. So now $$ is only invalidated if you call a function (i.e. not an intrinsic) that fails to return something. Otherwise, it will remain valid. Which is to say, your two liner to empty a player of their stamina should now work. It should have worked in the first place. :/

 

Bug #3: it's related to the change I made to store form identification as it's form id string (i.e. "relative formid|modname") to handle changes to modlists affecting stored form references. Well not Reference references, just, you know "hey, I know a Form" references. I'm still looking into this. Aaaaand it's gone. v0.952 should address this problem. Basically the mod 0xFF forms are temporary forms and need to fallback to absolute FormID storage. Should be fixed now.

 

Thanks for the bug report. :)

 

Edited by hextun
Posted

Cheers for the quick fixes, I'll undoubtedly come crying back once I hit my head again on some more faulty behaviours.
Waaaah

Also something veeeery minor with the documentation (again sorry).

I noticed the example given for "av_getmax" is using "av_get" instead - looking through my backups, that one snuck in around v114. Yes I still have them, I don't know why.

Posted
2 hours ago, MannySauce said:

Cheers for the quick fixes, I'll undoubtedly come crying back once I hit my head again on some more faulty behaviours.
Waaaah

Also something veeeery minor with the documentation (again sorry).

I noticed the example given for "av_getmax" is using "av_get" instead - looking through my backups, that one snuck in around v114. Yes I still have them, I don't know why.

 

Add-ressed. :)  at least on the wiki :)

 

Posted

I'm playing around with an SLTR based replacement for the SexLab Survival feature that destroys licenses due to swimming.

 

From what I understand, the SLS feature:

- used Frostfall

- kicked in when you were wet to some extent

- automatically destroyed licenses if you were fully submerged

- which implies there was only a "chance" with lower levels of submergence

- but I don't know what that chance per second was

 

I'm still toying with numbers but:

trigger: water entry; 100%

while we're in the same "swim session" (i.e. we haven't left and come back into the water)

  if we aren't "max wetness"

    if we are in at least 0.35 submergence (roughly knee deep)

      accrue wetness based on the time slice and current submergence level

  if we haven't destroyed the max number of licenses for this "wetness session" (i.e. you can get in, get out, get back in, get back out and not have dried out thoroughly, that's one "wetness session")

    if we are over 0.98 submergence (practically fully submerged)

      destroy a random SLS license

    else if we are over 0.35 submergence (at least knee deep)

      if random0-100 < (current wetness 0-100) * (current submergence level 0-1.0)

        destroy a random SLS license

  wait 0.5 seconds

 

trigger: water exit; 100%

while last time we got in the water hasn't changed (i.e. we haven't re-entered and then left)

  wait 1 second

  reduce wetness by 1.0

  if wetness <= 0

    reset the license destroyed count and quit

 

So each time you enter or leave, the prior running script will exit and a new copy picks up. If you happen to dip in and out (i.e. running along a shoreline) it will unfortunately spawn a number of enter and exit scripts, but they should be state aware enough to not step on each others toes (after all, that's so shallow there wouldn't be any action taken anyway). But for a trudge across a deep river? Two script calls, in and out.

 

So far I've had to slow down the license destruction rate, because once you've gotten wet enough, slogging through even knee deep water starts to represent a significant chance to loose a license, which I ascribe to accumulated dampness and the fact that standing in a certain amount of water isn't conducive to drying off to reverse the process. Thus, risk. 

 

But I don't know how fast you would end up losing your license with SLS+Frostfall. Anyhow, I'm still playing with the numbers, but here are the scripts as they currently sit. Oh, there's also a script for the removal itself. It *could* be embedded directly into the waterentry script, but a) I'll be adding it as a shipped script anyway and b) there may be reason to want to do this outside of this context. Feel free to modify it for yourself.

 

Wetness-WaterEntry.sltscript

Spoiler
set $water_session $system.player.in_water_session
if $water_session == 0
	return
endif
set $water_time $system.gametime
while $water_session == $system.player.in_water_session
	set $current_submergence $system.player.submerged_level
	if $global.sltr_wetness_current < 100.0
		if $current_submergence > 0.35
			set $gametime_slice $system.gametime - $water_time
			set $water_time $system.gametime
			set $accrued_wetness $gametime_slice * 14400 ; 24 hr * 60 min * 60 sec / 6 sec (weird little math I did to sync it to *something*; in this case roughly 1/10th of in-game minute; tweak the 14400 here upward to increase rapidity of wetness gain)
			set $accrued_wetness $accrued_wetness * $current_submergence
			inc $global.sltr_wetness_current $accrued_wetness
			if $global.sltr_wetness_current > 100.0 ; some arbitrary "max wetness"
				set $global.sltr_wetness_current 100.0
			endif
		endif
	endif
	if $global.sltr_wetness_sls_licenses_destroyed < 3
		if $current_submergence > 0.98
			call "SLS Destroy Random License"
			inc $global.sltr_wetness_sls_licenses_destroyed
		elseif $current_submergence > 0.35
			set $under_this_removes $global.sltr_wetness_current * $current_submergence
			if $system.random.100 < $under_this_removes
				call "SLS Destroy Random License"
				inc $global.sltr_wetness_sls_licenses_destroyed
			endif
		endif
	endif
	util_wait 0.5
endwhile

 

 

Wetness-WaterExit.sltscript

Spoiler
set $dry_start $system.player.in_water_last_start_gametime
if $system.player.is_in_water == true
	goto [end_of_script]
endif
while $global.sltr_wetness_current > 0.0
	if $dry_start != $system.player.in_water_last_start_gametime
		goto [end_of_script]
	endif
	if $system.player.is_in_water == true
		goto [end_of_script]
	endif
	util_wait 1.0
	inc $global.sltr_wetness_current -1.0
	if $global.sltr_wetness_current < 0.0
		set $global.sltr_wetness_current 0.0
	endif
endwhile
[end_of_script]
if $global.sltr_wetness_current <= 0.0
	set $global.sltr_wetness_sls_licenses_destroyed 0
endif

 

 

SLS Destroy Random License.sltscript

Spoiler
beginsub destroy_form
	inc $checked_count 1
	set $count resultfrom objectreference_dofunction $system.player GetItemCount $destroy_form_id
	if $count > 0
        item_remove $system.player $destroy_form_id $count false
        return
	endif
	if $checked_count >= 9
		return
	endif
endsub
set $start_license resultfrom rnd_int 1 9
set $start_label $"license_{$start_license}"
goto $start_label
[license_1]
set $destroy_form_id "_SLS_LicenceMagic"
gosub destroy_form
[license_2]
set $destroy_form_id "_SLS_LicenceArmor"
gosub destroy_form
[license_3]
set $destroy_form_id "_SLS_LicenceWeapon"
gosub destroy_form
[license_4]
set $destroy_form_id "_SLS_LicenceBikini"
gosub destroy_form
[license_5]
set $destroy_form_id "_SLS_LicenceClothes"
gosub destroy_form
[license_6]
set $destroy_form_id "_SLS_LicenceWhore"
gosub destroy_form
[license_7]
set $destroy_form_id "_SLS_LicenceCurfew"
gosub destroy_form
[license_8]
set $destroy_form_id "_SLS_LicenceFreedom"
gosub destroy_form
[license_9]
set $destroy_form_id "_SLS_LicenceProperty"
gosub destroy_form
goto [license_1]

 

 

 

Posted (edited)

Hi guys, I'm trying to detect if aggressor is vampire (which seemingly works) but I can't get it to change the scene to a different tag:

 

msg_notify "DEBUG: Scene Detected"
actor_haskeyword $system.self Vampire  

if $$ = true
	msg_notify "Is vampire"
	if actor_getgender $system.self == 0
		msg_notify "Is male"
		Form[] $sceneActors
				
		listadd $sceneActors $system.self
		listadd $sceneActors $system.partner 
				
		msg_notify "DEBUG: Attempting new scene"
				
		sl_startsex $sceneActors $system.sceneActors[1] "Vamp" 0
	endif
endif


I know I'm probably doing something really stupid but any help would be appreciated! (Vamp is a custom tag that works from SL Tools, I did also try normal tags)

Once a defeat happens, the script runs and all debug messages show up, but the scene doesn't change

Edited by Bananaman11508
Posted
12 minutes ago, Bananaman11508 said:

Hi guys, I'm trying to detect if aggressor is vampire (which seemingly works) but I can't get it to change the scene to a different tag:

 

msg_notify "DEBUG: Scene Detected"
actor_haskeyword $system.self Vampire  

if $$ = true
	msg_notify "Is vampire"
	if actor_getgender $system.self == 0
		msg_notify "Is male"
		Form[] $sceneActors
				
		listadd $sceneActors $system.self
		listadd $sceneActors $system.partner 
				
		msg_notify "DEBUG: Attempting new scene"
				
		sl_startsex $sceneActors $system.sceneActors[1] "Vamp" 0
	endif
endif


I know I'm probably doing something really stupid but any help would be appreciated! (Vamp is a custom tag that works from SL Tools, I did also try normal tags)

Once a defeat happens, the script runs and all debug messages show up, but the scene doesn't change

 

There is a problem on line 6 of your script. I catch myself doing it too because normal languages would let you. :)

 

You'll need to fetch the value of actor_getgender and then compare it. Can't do both in one swell foop. Try this version:

 

msg_notify "DEBUG: Scene Detected"
actor_haskeyword $system.self Vampire  

if $$ = true
	msg_notify "Is vampire"
	actor_getgender $system.self
	if $$ == 0
		msg_notify "Is male"
		Form[] $sceneActors
				
		listadd $sceneActors $system.self
		listadd $sceneActors $system.partner 
				
		msg_notify "DEBUG: Attempting new scene"
				
		sl_startsex $sceneActors $system.sceneActors[1] "Vamp" 0
	endif
endif

 

I will mention, however, that sl_startsex is intended to start a sex scene for actors when they are not currently in one. As far as I'm aware, the underlying function it binds to is not meant to switch a currently running scene to a different tag.

 

Since your script references "$system.partner", and you mention defeat happening, I'm assuming you have this triggered on Sex Start with the intent of switching the animation to the "Vamp" tagged animation that presumably gets selected.

 

If that's not the case, let me know what it is you're trying to do and what trigger you are using, please?

 

If it *is* the case, I'm not sure "sl_startsex" is going to be able to switch an ongoing scene like I think you're trying to do. Of course, give it a shot and let me know how it works out.

 

 

Posted (edited)
21 hours ago, hextun said:

 

I will mention, however, that sl_startsex is intended to start a sex scene for actors when they are not currently in one. As far as I'm aware, the underlying function it binds to is not meant to switch a currently running scene to a different tag.

 

Since your script references "$system.partner", and you mention defeat happening, I'm assuming you have this triggered on Sex Start with the intent of switching the animation to the "Vamp" tagged animation that presumably gets selected.

 

If that's not the case, let me know what it is you're trying to do and what trigger you are using, please?

 

If it *is* the case, I'm not sure "sl_startsex" is going to be able to switch an ongoing scene like I think you're trying to do. Of course, give it a shot and let me know how it works out.

 

 


Hey, I really appreciate the time you took to respond!

Yeah I was trying to wrap my head around the if statements but even though I did it wrong, the script was still running all the code. (debug message shows)

Unfortunately the scene just doesn't change anyways.

Trigger setup:
 

Event: BEGIN
Partner Sex: Female
Partner Role: Victim
Script 1: The code above
Chance: 100

Everything else is default, at least until I could get something working.


The idea of what I'm trying to achieve is basically to play "Vampire" animations. (Various can be found from other authors that typically have a neck bite animation with it)
I wanted it to work along SL Defeat, but unfortunately it doesn't let you chose animation tag based on aggressor being a vampire for example.

I know I could technically use the source code but honestly with just basic knowledge in standard languages, I have no hope reading and changing Payprus Scripts lol

With that in mind, I'm wondering if maybe it would be possible to directly call a function within SexLab from a Triggers script?

Edit: Just to clarify, the script was to detect a SL Defeat scene and change the tags if aggressor is a vampire, further changes to infect the player with vampirism when scene ends too.

Thanks again for your help

Edited by Bananaman11508
Posted

hey, thanks for the mod, I've been banging my head with it for the past 4 hours.

I'm trying to do something very simple, equip and unequip an item, mostly because I'm trying to force DAV to update the state of the armor after a SL scene. (which would be unnecessary if we get 2.0 and I could just call their ResetAllVariants() papyrus 😅)

 

No matter what I try everything seems fine in the debug but nothing ever gets added or equipped on my characters even when I try something as simple as this

 

 

Spoiler

set $clothes resultfrom form_getbyid "DBClothesJesterHatCicero"  
deb_msg "naked1"
deb_msg $clothes
actor_doconsumer $system.self AddItem $clothes 1 true
item_add $system.self $clothes 1 0
util_wait 1
deb_msg "naked2"
item_equip $system.self $clothes false false
;actor_doconsumer $system.self EquipItem $clothes false true 
deb_msg "naked3"    


The log seems fine, but nothing happens
 

Spoiler

    [2025-09-13 02:12:23.717] [log] [debug] [sl_triggers.cpp:725] Main.StartCommand targetForm([Actor < (FF001CA2)>]) initialScriptName(re_equip32)
    [2025-09-13 02:12:23.726] [log] [debug] [sl_triggers.cpp:725] Main.StartCommandWithThreadId targetForm([Actor < (FF001CA2)>]) initialScriptName(re_equip32) requestId(316) threadId(317)
    [2025-09-13 02:12:23.744] [log] [debug] [sl_triggers.cpp:725] Calling sl_triggers_internal.StartScript(actualTarget=<[Actor < (FF001CA2)>]>, initialScriptName=<re_equip32>)
    [2025-09-13 02:12:23.779] [log] [debug] [sl_triggers.cpp:725] sl_triggers_internal.StartScript(actualTarget=<[Actor < (FF001CA2)>]>, initialScriptName=<re_equip32>) reported success
    [2025-09-13 02:12:23.972] [log] [info] [sl_triggers.cpp:733] >IncrementRequestCounter requestId(316): reached (1); sukey(SLTR:request:316)
    [2025-09-13 02:12:24.168] [log] [debug] [sl_triggers.cpp:725] DebMsg> naked1
    [2025-09-13 02:12:24.388] [log] [debug] [sl_triggers.cpp:725] DebMsg> Skyrim.esm:411950
    [2025-09-13 02:12:26.271] [log] [debug] [sl_triggers.cpp:725] DebMsg> naked2
    [2025-09-13 02:12:26.586] [log] [debug] [sl_triggers.cpp:725] DebMsg> naked3
    [2025-09-13 02:12:26.692] [log] [info] [sl_triggers.cpp:733] <DecrementRequestCounter requestId(316): reached (0); sukey prefix (SLTR:request:316); clearing all
 


He clearly found the hat, 411950 = 0x0006492E but why cant I get it to go into the inventory or end up equipped on either character?



 

Posted
9 hours ago, mnonyhc said:

hey, thanks for the mod, I've been banging my head with it for the past 4 hours.

I'm trying to do something very simple, equip and unequip an item, mostly because I'm trying to force DAV to update the state of the armor after a SL scene. (which would be unnecessary if we get 2.0 and I could just call their ResetAllVariants() papyrus 😅)

 

No matter what I try everything seems fine in the debug but nothing ever gets added or equipped on my characters even when I try something as simple as this

 

 

  Hide contents

set $clothes resultfrom form_getbyid "DBClothesJesterHatCicero"  
deb_msg "naked1"
deb_msg $clothes
actor_doconsumer $system.self AddItem $clothes 1 true
item_add $system.self $clothes 1 0
util_wait 1
deb_msg "naked2"
item_equip $system.self $clothes false false
;actor_doconsumer $system.self EquipItem $clothes false true 
deb_msg "naked3"    


The log seems fine, but nothing happens
 

  Hide contents

    [2025-09-13 02:12:23.717] [log] [debug] [sl_triggers.cpp:725] Main.StartCommand targetForm([Actor < (FF001CA2)>]) initialScriptName(re_equip32)
    [2025-09-13 02:12:23.726] [log] [debug] [sl_triggers.cpp:725] Main.StartCommandWithThreadId targetForm([Actor < (FF001CA2)>]) initialScriptName(re_equip32) requestId(316) threadId(317)
    [2025-09-13 02:12:23.744] [log] [debug] [sl_triggers.cpp:725] Calling sl_triggers_internal.StartScript(actualTarget=<[Actor < (FF001CA2)>]>, initialScriptName=<re_equip32>)
    [2025-09-13 02:12:23.779] [log] [debug] [sl_triggers.cpp:725] sl_triggers_internal.StartScript(actualTarget=<[Actor < (FF001CA2)>]>, initialScriptName=<re_equip32>) reported success
    [2025-09-13 02:12:23.972] [log] [info] [sl_triggers.cpp:733] >IncrementRequestCounter requestId(316): reached (1); sukey(SLTR:request:316)
    [2025-09-13 02:12:24.168] [log] [debug] [sl_triggers.cpp:725] DebMsg> naked1
    [2025-09-13 02:12:24.388] [log] [debug] [sl_triggers.cpp:725] DebMsg> Skyrim.esm:411950
    [2025-09-13 02:12:26.271] [log] [debug] [sl_triggers.cpp:725] DebMsg> naked2
    [2025-09-13 02:12:26.586] [log] [debug] [sl_triggers.cpp:725] DebMsg> naked3
    [2025-09-13 02:12:26.692] [log] [info] [sl_triggers.cpp:733] <DecrementRequestCounter requestId(316): reached (0); sukey prefix (SLTR:request:316); clearing all
 


He clearly found the hat, 411950 = 0x0006492E but why cant I get it to go into the inventory or end up equipped on either character?



 

 

Quick note to explain something: the item_add and actor_doconsumer/AddItem both bind to the same function, and I'll be keeping item_add. As a result, in my testing, I was ending up with two hats in inventory. I recommend you just use item_add.

 

I was unable to replicate the issue.

 

You say "after a SL scene", so I'm assuming this would be run after sex is done, presumably in response to the SL End event?

 

I tested on versions 0.951 and 0.960 (latest), on both Skyrim Modding Essentials and Nefaram (latest):

  - Outside of a Scene, Player: hat equipped, stays equipped

  - Outside of a Scene, NPC: hat equipped, stays equipped

SME doesn't have SexLab, so on Nefaram:

  - During a Scene, Player: hat equipped, stays equipped

  - During a Scene, NPC: hat equipped, stays equipped (had to disable the NFF hat hider before I realized what was happening)

  - After a Scene, triggered, Player: hat equipped, stays equipped

  - After a Scene, triggered, NPC: hat equipped, stays equipped

 

For console testing:

  prid player (or click-select your scene partner)

  slt run "yourcicerohatscript" (or whatever your script name is)

 

The results came up pretty quickly, even on the highly unoptimized SME.

 

I tried with both your script and this alternative which uses item_addex and item_equipex as an alternative (though again, yours worked, as is, for me, in both SME and Nefaram). Some folks have better success with the -ex variants when having problems with NPC item adding and equippage.

 

Spoiler
deb_msg $"{$system.currentScriptName} Start"

set $inv_count resultfrom objectreference_dogetter $system.self GetNumItems
set $clothes resultfrom form_getbyid "DBClothesJesterHatCicero"
set $c_name resultfrom form_dogetter $clothes GetName

; don't need this since it's identical to item_add; I just added it for completeness because why skip *that* particular function, y'know?
;actor_doconsumer $system.self AddItem $clothes 1 true
; and some folks have success with item_addex when they have issues with item_add and NPCs
;item_add $system.self $clothes 1 0
; instead maybe try item_addex
item_addex $system.self $clothes 1 false
set $inv_count2 resultfrom objectreference_dogetter $system.self GetNumItems

deb_msg $"naked1: clothes({$clothes}) c_name({$c_name}) inv_count({$inv_count}) inv_count2({$inv_count2})"

util_wait 1

; similarly, item_equipex is a SKSE specific variant that might help? idk
;item_equip $system.self $clothes false true
item_equipex $system.self $clothes 30 false false
;actor_doconsumer $system.self EquipItem $clothes false true 

deb_msg $"{$system.currentScriptName} Stop"

 

 

When you run it on an NPC, sl-triggers.log will show an awful looking message that I need to fix, that it cannot resolve "$system.self". That's not at all an accurate description of what's going on; it's SUPPOSED to just say something like "hey, this NPC only thing we do isn't going to happen because you ran this on the Player". Instead it's all like "AAAAAHHH THE HOUSE IS ON FIRE", which, you know, it *might* be, but that isn't the root cause of this issue.

 

Anyhow, you can, of course, do this during a scene, and you can target other than the player by selecting them in the console, so if you are intending to run this script on the partner of the player, for example, then you could test your script during the scene by opening the console, click-selecting the target actor, and running 'slt run "whatever_script"'.

 

But in your case you are saying the form resolves (i.e. as you point out, it returns the appropriate formID, so the form_getbyid seems to work. But the AddItem calls fail and of course item_equip has nothing to equip. In my tests, item_add/item_addex and even item_equip/item_equipex works; it's only during a scene with an NPC that my NPC rejected the new hat, and even put his armor back on mid-coitus in protest. I'm really not sure what the expected behavior here should be during a scene.

 

Next place to start would be to check which version of SLTR you're running and whether you can reproduce the result I'm seeing outside of a scene, or even during a scene but from the console (though it really shouldn't matter). Try using my alternate version which outputs item counts before and after.

 

If you're on latest SLTR and my alternative version also does nothing, even when run from the console as I did, i.e. "prid player/slt run yourcicerohatscript", then if you wouldn't mind, please post a zip or 7z with sl-triggers.log and things like your modlist and load order. I'm not sure what's going on if this sort of low-level functionality isn't working for you.

Posted
15 hours ago, Bananaman11508 said:


Hey, I really appreciate the time you took to respond!

Yeah I was trying to wrap my head around the if statements but even though I did it wrong, the script was still running all the code. (debug message shows)

Unfortunately the scene just doesn't change anyways.

Trigger setup:
 

Event: BEGIN
Partner Sex: Female
Partner Role: Victim
Script 1: The code above
Chance: 100

Everything else is default, at least until I could get something working.


The idea of what I'm trying to achieve is basically to play "Vampire" animations. (Various can be found from other authors that typically have a neck bite animation with it)
I wanted it to work along SL Defeat, but unfortunately it doesn't let you chose animation tag based on aggressor being a vampire for example.

I know I could technically use the source code but honestly with just basic knowledge in standard languages, I have no hope reading and changing Payprus Scripts lol

With that in mind, I'm wondering if maybe it would be possible to directly call a function within SexLab from a Triggers script?

Edit: Just to clarify, the script was to detect a SL Defeat scene and change the tags if aggressor is a vampire, further changes to infect the player with vampirism when scene ends too.

Thanks again for your help

 

Yeah, although the engine may not have know what to do with your if block, it's a "permissive" engine, so script flow never stops. You could theoretically copy a .gif into place, slap an .sltscript extension on it, and it will do it's best to try to run that nonsense (though I imagine it would fail pretty fast). It would load each "line" (anything broken up by newlines) in the binary, then attempt to parse it. And each time it fails it just moves on until it runs out of lines or gets told to leave early (like if the bare string "return " happened to directly follow the binary equivalent of a carriage return, I've no doubt the "script" would exit early.

 

So for example, if you changed your if logic to reverse it, and inside the if block added a goto to skip past the code you would have originally run inside the if block, that block skipping code would have just been plowed into and the logic would have failed. It makes feature testing extra spicy! Did the script arrive at this line intentionally or accidentally? WHO KNOWS??

 

Anyhow, If I'm reading you correctly, ultimately what you want is "play this vampire tagged scene during a defeat instead of the scene SL Defeat chooses"? And it seems you were attempting to implement this via a "Start" trigger, with detection logic, followed by the attempt to use "sl_startsex"? Out of curiosity, was the detection logic implemented and working (i.e. were you able to detect that you are in an SL Defeat scene)?

 

In which case, my analysis stands: I don't think the sl_startsex binding is what you want since at this point the scene has already started and the actors are in it. What you want is to somehow change the currently running scene and/or animation (and this gets very much into where I haven't tried yet to learn further and thus proclaim ignorance; are scenes animations? or are they compositions of individual stages? is an animation just a set of stages that can be picked apart and shuffled together? I get the impression that may be the goal with SexLab P+ and it's Scene Builder, but again, me am ignorant).

 

To answer what I believe to be the spirit of your question, no there is (not yet anyway) a way in SLTScript to run arbitrary Papyrus script or to call arbitrary Papyrus script functions. The various *_dogetter/*_doaction/*_doconsumer/*_dofunction commands are me brute forcing bindings into place and that's mostly been for the base CK bits. Integrations like with SexLab I implement as I can but it becomes a question of weighing whether any users would ever bother using a given class of functions vs. the amount of time it takes to implement bindings.

 

The hilarious part is that recently I expanded the SexLab function library and opted not to do a deep dive into exposing the API because, in my own words (in my head) "who is going to bother trying to load individual animations and operate on the scene at that level? nah, advance is good enough and hey, they'll be happy now to be able to start a sex scene". So thank you for letting me witness the folly of my own lack of vision in virtual real-time. :) In fact, as mentioned up thread, the Alias implementation (as a supported type in SLTScript) was added specifically when I started investigating adding bindings for more of the SL API. I added the language feature but backed away from all of the binding implementations!

 

I'll poke at it a bit more, and to be honest, implementing most of these tends to mostly be me setting up the boiler plate, making sure the parameters in/out all match up, and the expected parameter counts are right, knocking out some documentation, and calling it done. I literally *cannot* test all of these APIs. Sorry, welcome to the sausage factory, here's how I make it. :/ So I may be able to stand up some interfaces and they may even be the right ones necessary for you to do what you want, but it's possible that until my understanding of the API (for anything) is fuller, I may miss adding important bindings.

Posted
1 hour ago, hextun said:

 

Quick note to explain something: the item_add and actor_doconsumer/AddItem both bind to the same function, and I'll be keeping item_add. As a result, in my testing, I was ending up with two hats in inventory. I recommend you just use item_add.

 

I was unable to replicate the issue.

 

You say "after a SL scene", so I'm assuming this would be run after sex is done, presumably in response to the SL End event?

 

I tested on versions 0.951 and 0.960 (latest), on both Skyrim Modding Essentials and Nefaram (latest):

  - Outside of a Scene, Player: hat equipped, stays equipped

  - Outside of a Scene, NPC: hat equipped, stays equipped

SME doesn't have SexLab, so on Nefaram:

  - During a Scene, Player: hat equipped, stays equipped

  - During a Scene, NPC: hat equipped, stays equipped (had to disable the NFF hat hider before I realized what was happening)

  - After a Scene, triggered, Player: hat equipped, stays equipped

  - After a Scene, triggered, NPC: hat equipped, stays equipped

 

For console testing:

  prid player (or click-select your scene partner)

  slt run "yourcicerohatscript" (or whatever your script name is)

 

The results came up pretty quickly, even on the highly unoptimized SME.

 

I tried with both your script and this alternative which uses item_addex and item_equipex as an alternative (though again, yours worked, as is, for me, in both SME and Nefaram). Some folks have better success with the -ex variants when having problems with NPC item adding and equippage.

 

  Reveal hidden contents
deb_msg $"{$system.currentScriptName} Start"

set $inv_count resultfrom objectreference_dogetter $system.self GetNumItems
set $clothes resultfrom form_getbyid "DBClothesJesterHatCicero"
set $c_name resultfrom form_dogetter $clothes GetName

; don't need this since it's identical to item_add; I just added it for completeness because why skip *that* particular function, y'know?
;actor_doconsumer $system.self AddItem $clothes 1 true
; and some folks have success with item_addex when they have issues with item_add and NPCs
;item_add $system.self $clothes 1 0
; instead maybe try item_addex
item_addex $system.self $clothes 1 false
set $inv_count2 resultfrom objectreference_dogetter $system.self GetNumItems

deb_msg $"naked1: clothes({$clothes}) c_name({$c_name}) inv_count({$inv_count}) inv_count2({$inv_count2})"

util_wait 1

; similarly, item_equipex is a SKSE specific variant that might help? idk
;item_equip $system.self $clothes false true
item_equipex $system.self $clothes 30 false false
;actor_doconsumer $system.self EquipItem $clothes false true 

deb_msg $"{$system.currentScriptName} Stop"

 

 

When you run it on an NPC, sl-triggers.log will show an awful looking message that I need to fix, that it cannot resolve "$system.self". That's not at all an accurate description of what's going on; it's SUPPOSED to just say something like "hey, this NPC only thing we do isn't going to happen because you ran this on the Player". Instead it's all like "AAAAAHHH THE HOUSE IS ON FIRE", which, you know, it *might* be, but that isn't the root cause of this issue.

 

Anyhow, you can, of course, do this during a scene, and you can target other than the player by selecting them in the console, so if you are intending to run this script on the partner of the player, for example, then you could test your script during the scene by opening the console, click-selecting the target actor, and running 'slt run "whatever_script"'.

 

But in your case you are saying the form resolves (i.e. as you point out, it returns the appropriate formID, so the form_getbyid seems to work. But the AddItem calls fail and of course item_equip has nothing to equip. In my tests, item_add/item_addex and even item_equip/item_equipex works; it's only during a scene with an NPC that my NPC rejected the new hat, and even put his armor back on mid-coitus in protest. I'm really not sure what the expected behavior here should be during a scene.

 

Next place to start would be to check which version of SLTR you're running and whether you can reproduce the result I'm seeing outside of a scene, or even during a scene but from the console (though it really shouldn't matter). Try using my alternate version which outputs item counts before and after.

 

If you're on latest SLTR and my alternative version also does nothing, even when run from the console as I did, i.e. "prid player/slt run yourcicerohatscript", then if you wouldn't mind, please post a zip or 7z with sl-triggers.log and things like your modlist and load order. I'm not sure what's going on if this sort of low-level functionality isn't working for you.

I'm on the latest 952 (after wasting a few hours in 951 also having issues)
My objective is to call it on sexend but it has maybe be a bit delayed since I need the sl_animating keyword  to be gone from all human NPC actors when the inventory is updated so DAV can see that it's gone and replace clothes with the regular variant. 
So the targets for the code is as said, every human (female just because I have no male DAV included) participants in a sexlab P+ scene

image.png.0c3b25345b6c0e2d6719142f85cd8132.png


I might be misunderstanding which actors the script is being run on, but I expected a copy of the script to run once for each valid target at the end of the scene, including the player but atm, neither version is triggering on the player when I test a basic 2P scene and I was looking for the hat on the player when it was probably adding them all to the NPC and not equipping because of NFF...
 

The script works if I call it with console, though doing it during a scene causes the hat to not show up until the scene is over, probably hidden by p+ stripper, and infuriatingly, doing it then doesnt update the DAVs, they equip the hat at the end but remain with lewd variants. They do update outside a scene, so I have to add a delay on the end trigger to make sure p+ is rly done with its schenanigances,


I need to test more when I have the time, and replace the code with an actual equip/remove and requip old item, then test if a ring is enough.

Posted
1 hour ago, mnonyhc said:

I'm on the latest 952 (after wasting a few hours in 951 also having issues)
My objective is to call it on sexend but it has maybe be a bit delayed since I need the sl_animating keyword  to be gone from all human NPC actors when the inventory is updated so DAV can see that it's gone and replace clothes with the regular variant. 
So the targets for the code is as said, every human (female just because I have no male DAV included) participants in a sexlab P+ scene

image.png.0c3b25345b6c0e2d6719142f85cd8132.png


I might be misunderstanding which actors the script is being run on, but I expected a copy of the script to run once for each valid target at the end of the scene, including the player but atm, neither version is triggering on the player when I test a basic 2P scene and I was looking for the hat on the player when it was probably adding them all to the NPC and not equipping because of NFF...
 

The script works if I call it with console, though doing it during a scene causes the hat to not show up until the scene is over, probably hidden by p+ stripper, and infuriatingly, doing it then doesnt update the DAVs, they equip the hat at the end but remain with lewd variants. They do update outside a scene, so I have to add a delay on the end trigger to make sure p+ is rly done with its schenanigances,


I need to test more when I have the time, and replace the code with an actual equip/remove and requip old item, then test if a ring is enough.

 

So, first, you're right, 0.952 *is* the latest release. I've been playing around with 0.960 and it missed me to recall I hadn't released it yet. :)

 

The trigger as pictured should, as you surmised, run for any humanoid actor (including the player unless you've done something... odd) at the end of a SexLab scene, with a 100% chance of occurring. You mentioned adding the Sex: filter, and yes, that should also factor in and also prevent running on any Actor not male.

 

I would have expected that by the time the script is running in response to "End" the faction keyword would be gone, but if not, you could throw this in at the start:
    util_waitforend $system.self
which will loop until the faction keyword is gone, reducing to effectively a NOP when the faction is already missing. :)

 

When you say "not triggering" do you mean the script literally never runs, or that it runs to no effect as you have described earlier. If the former, I am very alarmed; if the latter, then we're on the right track.

 

For now, try adding that "util_waitforend" at the top to see if that helps.

Posted (edited)
7 hours ago, hextun said:

 

So, first, you're right, 0.952 *is* the latest release. I've been playing around with 0.960 and it missed me to recall I hadn't released it yet. :)

 

The trigger as pictured should, as you surmised, run for any humanoid actor (including the player unless you've done something... odd) at the end of a SexLab scene, with a 100% chance of occurring. You mentioned adding the Sex: filter, and yes, that should also factor in and also prevent running on any Actor not male.

 

I would have expected that by the time the script is running in response to "End" the faction keyword would be gone, but if not, you could throw this in at the start:
    util_waitforend $system.self
which will loop until the faction keyword is gone, reducing to effectively a NOP when the faction is already missing. :)

 

When you say "not triggering" do you mean the script literally never runs, or that it runs to no effect as you have described earlier. If the former, I am very alarmed; if the latter, then we're on the right track.

 

For now, try adding that "util_waitforend" at the top to see if that helps.


util_waitforend works, if I run the script on the player during the scene, it will wait and equip it at the right time at the end, 😀
 

Heres the simple trigger, log and script I ran atm. I'm doing a simple test with the p+ matchmaker spell on random npc/potentialfollower on the starting room of Alternate Perspective

 

trigger001.json
re_equip32.txt (extension changed to txt from sltscript so it could be attached)
sl-triggers.log ran twice 2nd time with debugs

The run with debugs shows the problem, something is clearly wrong with the race filter it seems, as it thinks my nord human isnt humanoid....

image.thumb.png.ab299dc005758721a6874cc5965e1a97.png

 

 

Thats for you to deal with now 😆.

On my end, the script is working now after cutting the humanoid filter from the script (though I'd eventually like to not have it run on creatures before a release 🤣)
It's doing the main goal, the hat is being equipped and DAV is behaving and updating whenever it's equipped (though the equip does still have a small 4-6sec lag it's still miles ahead of waiting forever for DAV)
I'll work on getting a proper script tomorrow to either just reequip some existing gear and test if it will refresh with the equipping a non-3D equip like a base skyrim ring.

Thanks for the help.

 

image.png


had a gander at the code and seems humanoid filter is excluding player in all sex cases since they are ActorRaceType(1) 


image.png.2b71390396f83f46c2288c85e625c940.png

Edited by mnonyhc
bug found
Posted
12 hours ago, mnonyhc said:


util_waitforend works, if I run the script on the player during the scene, it will wait and equip it at the right time at the end, 😀
 

Heres the simple trigger, log and script I ran atm. I'm doing a simple test with the p+ matchmaker spell on random npc/potentialfollower on the starting room of Alternate Perspective

 

trigger001.json
re_equip32.txt (extension changed to txt from sltscript so it could be attached)
sl-triggers.log ran twice 2nd time with debugs

The run with debugs shows the problem, something is clearly wrong with the race filter it seems, as it thinks my nord human isnt humanoid....

image.thumb.png.ab299dc005758721a6874cc5965e1a97.png

 

 

Thats for you to deal with now 😆.

On my end, the script is working now after cutting the humanoid filter from the script (though I'd eventually like to not have it run on creatures before a release 🤣)
It's doing the main goal, the hat is being equipped and DAV is behaving and updating whenever it's equipped (though the equip does still have a small 4-6sec lag it's still miles ahead of waiting forever for DAV)
I'll work on getting a proper script tomorrow to either just reequip some existing gear and test if it will refresh with the equipping a non-3D equip like a base skyrim ring.

Thanks for the help.

 

image.png


had a gander at the code and seems humanoid filter is excluding player in all sex cases since they are ActorRaceType(1) 


image.png.2b71390396f83f46c2288c85e625c940.png

 

Thank you for your gander! Fantastic catch! I've got the fix implemented and will run through some tests and do a release later I think.

 

For your gander, a goose:

 

Spoiler
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣤⣄⡀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⣿⣿⣏⣹⣿⠄⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⠿⠋⢠⣷⣦⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣧⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣆⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣿⣿⣿⣿⡆⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⠛⣿⣿⣿⣧⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣾⣿⣿⣿⣿⣿⣿⡇⢸⣿⣿⣿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⢸⣿⣿⡿⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⣠⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⣠⣿⣿⣿⠇⠀⠀⠀⠀⠀⠀
⠀⠀⠰⢾⣿⣿⣿⡟⠿⠿⣿⣿⠿⠿⠛⠋⣁⣴⣾⣿⣿⠿⠋⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠉⠛⠻⠷⣶⣤⣤⣤⣤⣶⣾⣿⡿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⢀⣶⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠛⠛⠛⠛⠛⠂⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀

 

 

Posted (edited)

I have a question and I made a genuine effort to read the wiki documentation but couldn't find the info (maybe I looked in the wrong place?). The question is that I've found that my Toggle Detection script no longer gets triggered properly. I'll attach a screenshot of how it is set up:

 

Spoiler

image.png.f76b95e882dbb3cbb48f0048d2a7afd3.png

 

The issue is related to the trigger itself, not the script. It seems that if Player Relationship is set to "Player" the trigger never fires, but it does fire if it is set to "Any". I interpret Player Relationship: Player as meaning "run this trigger if the actor is the Player" which is what I want, I want a script to be fired once on Ostim scene start, so it running on the player just makes sense. Is this an issue of misunderstanding on my part or an issue with SLTriggers itself? Thank you!

 

For now I have modified the script to only take action if the actor is the Player so hopefully that prevents it from firing multiple times if the scene has more than one person.

Edited by just let me download
Posted (edited)
18 hours ago, just let me download said:

I have a question and I made a genuine effort to read the wiki documentation but couldn't find the info (maybe I looked in the wrong place?). The question is that I've found that my Toggle Detection script no longer gets triggered properly. I'll attach a screenshot of how it is set up:

 

  Reveal hidden contents

image.png.f76b95e882dbb3cbb48f0048d2a7afd3.png

 

The issue is related to the trigger itself, not the script. It seems that if Player Relationship is set to "Player" the trigger never fires, but it does fire if it is set to "Any". I interpret Player Relationship: Player as meaning "run this trigger if the actor is the Player" which is what I want, I want a script to be fired once on Ostim scene start, so it running on the player just makes sense. Is this an issue of misunderstanding on my part or an issue with SLTriggers itself? Thank you!

 

For now I have modified the script to only take action if the actor is the Player so hopefully that prevents it from firing multiple times if the scene has more than one person.

 

Your trigger is configured correctly to do what you are trying to do, namely, run a script in response to the Player starting an OStim scene. I'll double check on my end but that's surprising. And you said "no longer"... so it was working at one point? Any changes of note between working and not working, like an update of SLTR versions? Load order or modlist changes?

 

In the meantime, would you mind going into the main page of the MCM and enabling the OStim debug flag and then trying your trigger again with the desired configuration and report back the output from sl-triggers.log?

 

I know I just released 0.960 so by all means update, though I wouldn't expect anything in this release to affect that trigger.

Edited by hextun
Posted
20 hours ago, Dm0n said:

I know it was pro'lly asked a lot of times here, but how do I convert skyrim hex id for items/etc. to use in json?

 

No worries; it's actually fairly common for a number of mods, because that conversion can be tricky if you're not used to it. :)

 

First, here's a wiki page I have for relative FormIDs and FormID strings. I added a bit just a moment ago by way of some examples. It has sections covering how to determine the relative FormID as well as the supported strings. Let me know if that page sorts you out or not. I'm open to feedback on the documentation. :)

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