Jump to content

Recommended Posts

Could someone remove the bloody hand from the stage 4 slave tat? It gets large and a little distorted on large breasts. I tried editing it myself, but I'm not very good with photoshop and couldn't remove it while keeping the bruises blended end with the rest of the texture

Link to comment

im using jcontainers 3.3 will this still work correctly? .... the requirements state 3.2. just wanted to make sure since ive had a TON of CTD problems with attempting to use mods that require and out of date jcontainer.

Link to comment
58 minutes ago, xyzxyz said:

Hi, I have the problem that I get no messages when the player has sex. It happens only to female player+male NPC, I think. It works fine with NPCs but no reaction to the player.

Two things off the top of my head:

1.  Something funny has happened to your Sexlab gender assignment

2.  Sexlab doesn't recognize your (custom...?) race as being assigned to FemaleActor

Can you get a snapshot of the console when stage transition occurs?  That should give some indicator of what's happening.

Link to comment

Another idea I have for ap2 (not sure if its already been suggested): npcs do not refer to your character by name unless they are above or below acquaintance with relationship rank (seems weird that some stranger in the middle of nowhere would know your name doesn't it?), so {PRIMARY} would instead of your name just display something from a list of alternatives, like your race, generalized gender terms (hansom guy, sexy lady, ect) or generalized belittling type terms (slut, ect) or even mix and match.

Link to comment

Posting this here because I am done with this project and the author of this mod hasn't replied back to me in over a week.

 

As with everything that I've uploaded in here, you are free to do as you please.

This project includes nlohmann's json for general purpose parsing of json files. Make sure to include its MIT license if you plan to redistribute this project (the license is included within the json.hpp header for the attached source code below).

 

The project will compile against SKSE and SKSE64 without any further changes needed. If your intention is to move reading and formatting of Apropos' messages away from the PapyrusVM, then the plugin is all done and all that you need to do is mess with Apropos2's Papyrus scripts.

 

The plugin registers two global Papyrus functions, which you will need to write as a Papyrus script and compile:

Scriptname Apropos2SKSE hidden

string Function GetMessageText(string file, int perspective, Actor primary, int[] primaryParams, Actor active, int[] activeParams) global native
int Function SetMessageText(int widgetID, string file, int perspective, Actor primary, int[] primaryParams, Actor active, int[] activeParams) global native

Note: SetMessageText is not available for SSE. If you are compiling it for SSE, make sure to not declare SetMessageText. You will still have to deal with getting your formatted string cached when it's returned by GetMessageText, but since you are now caching the whole formatted string, the chances of case-insensitive collision will be much smaller.

The reason I've not written it for SSE is that I would need to find an address to hook the widget call in. Since I don't have SSE myself (nor will I ever have it), I can't do this task.

 

The parameters for the functions are:

widgetID: The ID of the SkyUI widget that the plugin will call SetMessageText on with the formatted string.

file: Apropos' json message file relative to Data\Apropos\db\. Example: "MaleActor\\MaleActor_Masturbation.txt"

perspective: 1 for "1st Person", 2 for "2nd Person" and 3 for "3rd Person"; any other value will default to "3rd Person".

primary: Apropos' primary actor.

primaryParams: This is a fixed-length array of 3 elements containing formatting information for the primary actor. Index 0: gender (0 for male or 1 for female; anything else will be treated as unknown), Index 1: Apropos' arousal level, Index 2: Apropos' wear and tear level.

active: Apropos' active actor.

activeParams: This is a fixed-length array of 3 elements containing formatting information for the active actor. Index 0: gender (0 for male or 1 for female; anything else will be treated as unknown), Index 1: Apropos' arousal level, Index 2: Apropos' wear and tear level.

 

Return values for the functions:

GetMessageText: Formatted string or an empty string on error.

SetMessageText: Status code: 0 = Success, 1 = Invalid parameters, 2 = Invalid file, 3 = Invalid message, 4 = Widget error.

 

Synonyms.txt, Arousal_Descriptors.txt and WearAndTear_Descriptors.txt will be cached after their first use. This allows us to avoid having to parse those files every time we need to translate a token, and also allows us to save memory by only caching them if they are actually required in our current game session.

 

Plugin errors and json parsing errors will be written to "My Documents\My Games\Skyrim\SKSE\Apropos2 SKSE.log" or "My Documents\My Games\Skyrim Special Edition\SKSE\Apropos2 SKSE.log".

 

To make it work with Apropos2, you will have to edit some of its scripts to change how it queues messages for the widget. Instead of queuing a string parameter, you will want to queue the parameters for one of the functions above.

You also want to change the function responsible for taking the message from the queue and sending it to the widget. For LE, you want to use SetMessageText with the queued parameters instead of calling UI.InvokeString; for SSE, you want to get the formatted string via GetMessageText and then call UI.InvokeString with the returned message.

I would also recommend adding some code to clean up anything from Synonyms.txt, Arousal_Descriptors.txt and WearAndTear_Descriptors.txt currently written to your save.

 

Project files are "Apropos2 SKSE.vcxproj.SKSE" for LE and "Apropos2 SKSE.vcxproj.SKSE64" for SSE. Just rename them to .vcxproj.

 

P.S. This is a polished version of the code I'd written sometime ago. I've also attached a compiled DLL for LE.

Apropos2SKSE.dll Apropos2 SKSE - Source.7z

Link to comment
5 hours ago, Hawk9969 said:

Posting this here because I am done with this project and the author of this mod hasn't replied back to me in over a week.

 

As with everything that I've uploaded in here, you are free to do as you please.

This project includes nlohmann's json for general purpose parsing of json files. Make sure to include its MIT license if you plan to redistribute this project (the license is included within the json.hpp header for the attached source code below).

 

The project will compile against SKSE and SKSE64 without any further changes needed. If your intention is to move reading and formatting of Apropos' messages away from the PapyrusVM, then the plugin is all done and all that you need to do is mess with Apropos2's Papyrus scripts.

 

The plugin registers two global Papyrus functions, which you will need to write as a Papyrus script and compile:


Scriptname Apropos2SKSE hidden

string Function GetMessageText(string file, int perspective, Actor primary, int[] primaryParams, Actor active, int[] activeParams) global native
int Function SetMessageText(int widgetID, string file, int perspective, Actor primary, int[] primaryParams, Actor active, int[] activeParams) global native

Note: SetMessageText is not available for SSE. If you are compiling it for SSE, make sure to not declare SetMessageText. You will still have to deal with getting your formatted string cached when it's returned by GetMessageText, but since you are now caching the whole formatted string, the chances of case-insensitive collision will be much smaller.

The reason I've not written it for SSE is that I would need to find an address to hook the widget call in. Since I don't have SSE myself (nor will I ever have it), I can't do this task.

 

The parameters for the functions are:

widgetID: The ID of the SkyUI widget that the plugin will call SetMessageText on with the formatted string.

file: Apropos' json message file relative to Data\Apropos\db\. Example: "MaleActor\\MaleActor_Masturbation.txt"

perspective: 1 for "1st Person", 2 for "2nd Person" and 3 for "3rd Person"; any other value will default to "3rd Person".

primary: Apropos' primary actor.

primaryParams: This is a fixed-length array of 3 elements containing formatting information for the primary actor. Index 0: gender (0 for male or 1 for female; anything else will be treated as unknown), Index 1: Apropos' arousal level, Index 2: Apropos' wear and tear level.

active: Apropos' active actor.

activeParams: This is a fixed-length array of 3 elements containing formatting information for the active actor. Index 0: gender (0 for male or 1 for female; anything else will be treated as unknown), Index 1: Apropos' arousal level, Index 2: Apropos' wear and tear level.

 

Return values for the functions:

GetMessageText: Formatted string or an empty string on error.

SetMessageText: Status code: 0 = Success, 1 = Invalid parameters, 2 = Invalid file, 3 = Invalid message, 4 = Widget error.

 

Synonyms.txt, Arousal_Descriptors.txt and WearAndTear_Descriptors.txt will be cached after their first use. This allows us to avoid having to parse those files every time we need to translate a token, and also allows us to save memory by only caching them if they are actually required in our current game session.

 

Plugin errors and json parsing errors will be written to "My Documents\My Games\Skyrim\SKSE\Apropos2 SKSE.log" or "My Documents\My Games\Skyrim Special Edition\SKSE\Apropos2 SKSE.log".

 

To make it work with Apropos2, you will have to edit some of its scripts to change how it queues messages for the widget. Instead of queuing a string parameter, you will want to queue the parameters for one of the functions above.

You also want to change the function responsible for taking the message from the queue and sending it to the widget. For LE, you want to use SetMessageText with the queued parameters instead of calling UI.InvokeString; for SSE, you want to get the formatted string via GetMessageText and then call UI.InvokeString with the returned message.

I would also recommend adding some code to clean up anything from Synonyms.txt, Arousal_Descriptors.txt and WearAndTear_Descriptors.txt currently written to your save.

 

Project files are "Apropos2 SKSE.vcxproj.SKSE" for LE and "Apropos2 SKSE.vcxproj.SKSE64" for SSE. Just rename them to .vcxproj.

 

P.S. This is a polished version of the code I'd written sometime ago. I've also attached a compiled DLL for LE.

Apropos2SKSE.dll 331.5 kB · 0 downloads Apropos2 SKSE - Source.7z 123.36 kB · 0 downloads

 

Looks good. I'm sorry but I have been too busy with work, pandemic, and protests to get to this as quickly as you would like. I want to thank you for your contribution. 

Link to comment
7 hours ago, gooser said:

 

Looks good. I'm sorry but I have been too busy with work, pandemic, and protests to get to this as quickly as you would like. I want to thank you for your contribution. 

I understand; but I too haven't gotten much free time (haven't played for over 2 weeks now), that's why I've polished it, wrote a relatively decent documentation and made it public, so you and others can continue it without me.

The way I've written it, implementations can be branched off via the __SKSE64__ macro and templates, and if you eventually decide to move the whole json functionality away from JContainers as to avoid having to refresh the database on updates or bloating your saves, you can do it easily by subclassing Plugin::JSON::Base.

 

By the way, I think there is a lazier way to do it for now.

You can create a PackMessage function within Apropos2Descriptions.psc and pass the parameters to this function at every place calling PresentMessage. PackMessage will simply pack all parameters together as a string (Actor objects will be packed by calling Actor.GetFormID()) and then returning the packed string as the message.

On UpdateWidgetText, we can then unpack the message, and if it unpacked successfully (all parameters were there), we call Apropos2SKSE.SetMessageText, if not, we call UI.InvokeString as usual.

Link to comment
2 hours ago, nilead said:

Is there a simple way to change W&T gain? 

Yes.  Edit the file WearAndTear_Damage.txt in Data\Apropos\db.  Change the wear amounts as you like.  Note that "AggressiveOrRape" is different from all the other values in that it's a multiplier applied to any rape or animation tagged as aggressive.  In the MCM under Message Preferences, click Refresh from Database.

Link to comment
11 hours ago, HexBolt8 said:

Yes.  Edit the file WearAndTear_Damage.txt in Data\Apropos\db.  Change the wear amounts as you like.  Note that "AggressiveOrRape" is different from all the other values in that it's a multiplier applied to any rape or animation tagged as aggressive.  In the MCM under Message Preferences, click Refresh from Database.

Thank you very much.

Link to comment
On 5/19/2020 at 11:17 PM, gooser said:

Thanks. Something I explored with the JContainers author years ago, possibly handing string management at the SKSE/C++ level but we never found a real solution.

I think you could pass JC data (arrays, maps) and concatenate strings on Lua side - doing that will completely remove Papyrus from text "assembly" process.

 

 

Link to comment
2 hours ago, Earen said:

I think you could pass JC data (arrays, maps) and concatenate strings on Lua side - doing that will completely remove Papyrus from text "assembly" process.

Even if you can implement the whole Apropos string mangling within JC's Lua interface, you will still not avoid Creation Engine's string caching because you will eventually need to pass that string to UI.InvokeString, which takes a BSFixedString and will cache the string on BSFixedString's ctor.

This would be the same behavior as I've it now for the C++ code for SSE, but not the same behavior as I've for its LE code, which does all the string mangling and communicates with Scaleform directly via a hook. The author can use Xbyak and branch trampoline (both already included with SKSE64) to implement the same behavior for SSE.

 

There are other shortcomings from using JC over its own tailored SKSE plugin, such as speed (using either Papyrus or Lua to parse and format strings will be exponentially slower than machine code), Creation Engine's use of CRC16 for its string map hash algorithm (making it very collision prone when a mod caches lots of strings), non-volatile cache vs an on demand volatile cache and the lack of modularity.

Link to comment
On 6/21/2020 at 7:28 PM, Hawk9969 said:

Even if you can implement the whole Apropos string mangling within JC's Lua interface, you will still not avoid Creation Engine's string caching because you will eventually need to pass that string to UI.InvokeString, which takes a BSFixedString and will cache the string on BSFixedString's ctor.

This would be the same behavior as I've it now for the C++ code for SSE, but not the same behavior as I've for its LE code, which does all the string mangling and communicates with Scaleform directly via a hook. The author can use Xbyak and branch trampoline (both already included with SKSE64) to implement the same behavior for SSE.

 

There are other shortcomings from using JC over its own tailored SKSE plugin, such as speed (using either Papyrus or Lua to parse and format strings will be exponentially slower than machine code), Creation Engine's use of CRC16 for its string map hash algorithm (making it very collision prone when a mod caches lots of strings), non-volatile cache vs an on demand volatile cache and the lack of modularity.

I'm not against the use of native solutions, if that simplifies things.

Btw, Lua is being compiled with JIT compiler

 

Link to comment
1 hour ago, Earen said:

I'm not against the use of native solutions, if that simplifies things.

Well, my point was that you will have to use a hook to invoke a Scaleform function within the widget's action script. You cannot invoke them at will because of race conditions, which will eventually lead to a crash.

All of SKSE's UI functions invoking action scripts functions use a queue that is consumed by a thread-safe hook at a specific region of the virtual code.

UI.InvokeString will just queue into this hook, with the downside of BSFixedString's ctor caching the message string.

 

1 hour ago, Earen said:

Btw, Lua is being compiled with JIT compiler

If you are using LuaJIT and its translating Lua bytecode into machine code, then yeah, you can cross out the performance downside I'd previously mentioned.

Link to comment
  • 2 weeks later...
On 7/7/2020 at 9:01 AM, 579435 said:

Hello,

Does anyone know how to target the player or an actor in Apropos2 to view their stats?
Thanks

Try the MCM under "Wear and Tear Actors".  It's not precisely what you're looking for, but it's pretty darn close.

Link to comment

Does this mod cause my character to moan occasionally? Perhaps when wear and tear heals? I'm opting for a playthrough that can go from NSFW to SFW with only a couple changes to MCM settings. So far, that's proving reasonably simple to accomplish if not for her randomly making sex noises without warning lol.

Link to comment
35 minutes ago, ShenGo said:

Does this mod cause my character to moan occasionally? Perhaps when wear and tear heals? I'm opting for a playthrough that can go from NSFW to SFW with only a couple changes to MCM settings. So far, that's proving reasonably simple to accomplish if not for her randomly making sex noises without warning lol.

Yup.  Triggers a mild Sexlab moan when WT state changes.

Link to comment
5 hours ago, ShenGo said:

Hmm... I wish there was a way to disable that... Oh well.

Open Scripts/Source/Apropos2ActorAlias.psc with a text editor and either remove or comment lines 367 and/or 368.

Line 367: Stagger

Line 368: Moan

 

Then follow the instructions at the bottom of this post on how to compile it.

 

Link to comment
  • 3 weeks later...
On 11/14/2018 at 7:21 AM, gooser said:

Well, without a log file, I can only look in to my Crystal Ball. 

Let's have a look at your Papyrus0.log and Apropos0.log files.

Sorry for my late report. I looked into Apropos2ActorAlias.psc, and found its reduce abuse logic is wrong. It has three parts, first reduce base abuse, then if creature cuts enabled, reduce creature abuse, then "elseif" daedric scars enabled, reduce daedric abuse. That means if you have creature abuse enabled, daedric abuse never going to take into account.

 

I use a personal Apropos2ActorAlias.psc, changed some lines to use with "Pigeons CBBE Apropos2 Replacer 2k v1.0", don't remember what exactly I changed, but I hope someone may find it useful.

Apropos2ActorAlias.psc Apropos2ActorAlias.pex

Link to comment

Hi,

 

in my installation Apropos 2 don't show the names of the npc's or my character instead there is is only empty space. The screenshots show that is possible to include the names. Any ideas what the problem is and how it can't be fixed (installed new, changed load order and remove all old trace from old Apropos "1").

 

Thx for ur help,

 

Josh 

Link to comment
On 11/15/2018 at 6:04 PM, gooser said:

FYI, 

I'm currently exploring a new option for generating message descriptions - a hybrid approach between unique animation descriptions and pure tag-based descriptions.


What I am doing is adding a new control file "AnimationHints.txt" that will contain entries for unique animations, and then subentries/children to indicate what is happening during each stage. A classic example is an animation that is MF with Vaginal, and Boobjob tags. The animation could start off as a Boobjob, but transition to Vaginal sex in later stages. So my new idea would allow the highlights of each stage to be indicated in this new file, and if a regular unique animation hasn't been authored, will check for hints for the animation, and use those to generate more appropriate descriptions. I think this addresses on of the biggest immersion breaking issues with tag-based descriptions.

 

E.g (Fictional MF animation):
 


    "B_Billyy_SomeMFAnim1": {
        "1": "V",
        "2": "O",
        "3+": "A"
    }

(^ indicate Stage 1 is Vaginal, stage 2 is Oral, and stages 3 onwards are Anal)

So the animation described above (Boobjob, Vaginal) would actually be reading several files:

FemaleActor_Male/FemaleActor_Male_BoobJob_Stage1.txt
...
FemaleActor_Male/FemaleActor_Male_Oral_Stage4.txt
..
FemaleActor_Male/FemaleActor_Male_Anal_Orgasm.txt.

Basically. 

Hey there, reading through old posts for new ideas - I ran across this!

Is it still present in code?  If so, I want to start adding content here...

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

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

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. For more information, see our Privacy Policy & Terms of Use