Jump to content

Recommended Posts

ThemisUtil

View File

Description for gamers

This is not what you need. This is a part of mod. It does nothing until modders integrate it into their code.

 

Description for modmakers

This is SKSE plugin

This library meant for speeding-up the mods scanning near NPCs (SLA SLAC SLApproach). It is not good when NPC starts to assault PC 20 seconds later after PC left for another town. On each calling native function the Papyrus switches threads, executes internal tasks or just wait. If you reduce the number of calls native functions you spead-up your mod.
The function "FindActors" allow to search all NPC in area and filter off by dozen characteristics.
It can to obtain lots of information about NPC as bits of an integer value and to validate all obtained data by one call Math.LogicalAnd().
MakeAnimation() gets an array of SL animations allowed for provided actors subject to plugged holes. One function for humans and creature animations. The function sorts the array of actors and returns only animations that match the sorted array.

The list of functions
RemoveTags, AddTags, IsTagsConform, HexToId,

GetActorName, TestActor, IsDead, CanPlayAnimation, IsFollower,

ActiveMod, GetWornKeywords, GetWornItems, Chance,

FindActors, FindCorpses, Rob,
GetBrokenDDItems,

GetGenderType, MakeAnimation, HasAnimations.

detailed https://www.loverslab.com/topic/201646-themisutil/?do=findComment&comment=3966395

 

Skyrim LE

Skyrim SE 1.5.97

 

Without restrictions. With source code.

I don't have AE so don't plan to make AE version.

 

Log

1.0.1 FindActors - improved. Chance - new.

1.0.2 RandomInt - new

1.0.3 GetWornItems - fix

1.0.4 ActiveMod - new


 

Link to comment
3 hours ago, Miller826 said:

Thanks for this. How do I install this with MO2? I get "The content of <data> does not look valid" and I can't seem to manually set any of the directories contained within you mod as a valid <data> directory.

 

I'm guessing the .pex file goes in /data/Scripts, and the .dll file goes in /SKSE/Plugins ? 

Link to comment
  • 2 weeks later...
On 12/13/2022 at 11:32 PM, no_way said:

So to clarify, this mod does nothing until modders integrate it into their code?

 

Obviously. Look at the source papyrus script and you see it adds a list of functions that are meant to be used instead of whatever construction is utilized by mods. It won't do anything - but if you have a working papyrus compiler installation you can integrate it on your own in most cases.

Link to comment

Greetings,

 

thank you for your work and for sharing it, as well as the source code.

 

I am very interested in getting involved with the creation of SKSE dll mods too. I have a basic understanding of setting up Visual Studio 2008 for compiling SKSE, but where would I put your provided source files in order to re-compile or even add some functions of my own?

Can you give me a pointer to how you learned to create dll mods?

 

Thank you in advance for any response.

Regards, s3ngine

Link to comment

Forget about 2008. Due to the fact that VC2015 has learned to optimize cycles very well all older compilers are hopelessly outdated.
The kernel of your dll is not any file of SKSE but main.cpp. So you would put the source files into new project adding files from SKSE as needed.
I had to add GameAPI.cpp, GameBSExtraData.cpp, GameData.cpp, GameExtraData.cpp, GameFormComponents.cpp, GameReferences.cpp, GameRTTI.cpp, GameTypes.cpp, GameUtilities.cpp, HashUtil.cpp, NiObjects.cpp, PapyrusArgs.cpp, PapyrusInterfaces.cpp, PapyrusNativeFunctions.cpp, PapyrusVM.cpp.

On 12/23/2022 at 1:40 PM, s3ngine said:

Can you give me a pointer to how you learned to create dll mods?

I collected all known information about TESV.exe from SKSE and github.com/DavidJCobb/skyrim-classic-re and put it into IDA database. Then I found some new facts by IDA disassembler and thought of how to use them. Most of the work is in debugger and not in VC.

Link to comment
  • 2 weeks later...

This looks promissing !

Did not download yet, just found it. Is there a description within download, like parameters for functions etc.

E.g.  does findactors scan the whole cell always or within a range ?

 

For my opinion it's the far better way to speed up things than forcing all scripts into the main threat as another approach does.

Later one might mess up the already fragile timing balance. Let windows itself handling the speedup and leave the scripts using the faster

availability of the data.

On this occasion, a reliable timer like utilwait() as dll function would be nice.

Edited by Tlam99
Link to comment
On 1/6/2023 at 9:39 AM, Tlam99 said:

does findactors scan the whole cell always or within a range ?

The game has an internal array of loaded actors. FindActors scans this array and filters out actors outside the given area.

Detailed description

Spoiler

;ThemisUtil does not require neither SexlabDefeat nor SexLab

;Enabled saparators: "," ";"
String function RemoveTags(String Tags, String TagsToRemove) global Native
;Concatenate and remove doubles
String function AddTags(String Tags1, String Tags2) global Native
;Is TargetTags contains all RequireTags, none of SuppressTags, at least one of AltTags
Bool function IsTagsConform(String TargetTags, String RequireTags, String SuppressTags, String AltTags) global Native

;Up to 8 chars
Int Function HexToId(String h) global native
;if c < 0.0
;  c = 0.0
;elseif c > 100.0
;  c = 100.0
;endif
;return RandomFloat(0.0, 100.0) < c

Bool Function Chance(Float c) global native

;XorShift32
Int Function RandomInt(Int st, Int en) global native

;String s
;if a
;    s = a.GetLeveledActorBase().GetName()
;    if !s
;        s = a.GetBase().GetName()
;    endif
;endif
;return s

String function GetActorName(Actor a) global Native

;                 Multitest an actor
;Input:
;    a - an actor to test
;    maxdist - max distance from the actor to the PC. 0.0 - don't check
;    out - Int[3]([4]) array to receive output data
;output:
;if !a || a.GetFormType() not in {43,44,62} || a.isDeleted || a.IsDisabled || race = ManakinRace ||race = carthorse||\
;         a.IsCommanded || a.IsChild || a.IsFlying || (maxdist>0.1 && dist(a, player) > maxdist || (a.IsDead && a.Health <= 0.0))
;    return 0
;else
;    out[0] = b0=1 - female; b1=2 - Race.HasKeyword(ActorTypeCreature); b2=4 - Race.HasKeyword(ActorTypeAnimal); b3=8 - Race.HasKeyword(ActorTypeNPC);
;        b4=0x10 - Race.HasKeyword(ActorTypeDaedra); b5=0x20 - unique; b6=0x40 - base essential; b7=0x80 - actor essential; b8=0x100 - bleedingout;
;        b9=0x200 - a.IsUnconsious; b10=0x400 - asleep; b11=0x800 - protected; b12=0x1000 - a.IsInCombat; b13=0x2000 - a.IsGuard; b14=0x4000 - a.IsPlayerTeammate;
;        b15=0x8000 - race.allowpickpocket; b16=0x10000 - follower; b17=0x20000 - CarriageSystemFaction; b18=0x40000 - IsGhost;
;        b19=0x80000 - voicetype=elder || Race=elder; b20=0x100000 - voicetype=child; b21=0x200000 - voicetype=none; b22=0x400000 - DefeatActive;
;        b23=0x800000 - keyword SexLabActive; b24=0x1000000 - IsSwimming; b25=0x2000000 - Health <= 0.0; b26=0x4000000 - IsDead;
;        b27=0x8000000 - IsOnMount/IsBeingRidden; b28=0x10000000 - IsTrespassing; b29=0x20000000 - not Is3dLoaded;
;        b30=0x40000000 - 1; b31=0x80000000 - 0
;    out[1] = a.LeveledActorBase.Race.FormId
;    out[2] = b0=1 - CurrentFollowerFaction; b1=2 - CurrentHireling; b2=4 - BanditFaction||MS07BanditFaction||MS07BanditSiblings||dunMistwatchFaction;b3=8 - ForswornFaction||DruadachRedoubtFaction;
;        b4=0x10 - SilverHandFaction; b5=0x20 - ThalmorFaction; b6=0x40 - VampireFaction||VampireThrallFaction; b7=0x80 - WarlockFaction;
;        b8=0x100 - NecromancerFaction; b9=0x200 - OrcFriendFaction; b10=0x400 - DLC2MoragTongFaction; b11=0x800 - DLC2ApocryphaFaction;
;        b12=0x1000 - PlayerMarriedFaction; b13=0x2000 - PlayerHousecarl; b14=0x4000 - b15=0x8000 - ;
;       b16=0x10000 - ; b17=0x20000 - ; b18=0x40000 - Invulnerable;
;        b24=0x1000000 - SLGenderFaction; b25=0x2000000 - SLGenderFaction rank & 1; b26=0x4000000 - ;
;        b28=0x10000000 - WINeverFillAliasesFaction(0xABDAE); b29=0x20000000 - Actor.id >= 0xff000000; b30=0x40000000 - SexLabActive faction; b31=0x80000000 - CarriageSystemFaction
;    out[3] - defeat specific
;    return out[0]

Int Function TestActor(Actor a, float maxdist, int[] out) global native

;!a || IsDead() || IsDisabled() || IsCommandedActor()
Bool Function IsDead(Actor a) global native

;a && !IsDead && !IsDisabled && Is3DLoaded && !HasKeyword(SexLabActive) && !HasMagicEffectWithKeyword(MagicParalysis)
Bool Function CanPlayAnimation(Actor a) global native

;IsPlayerTeammate || CurrentFollowerFaction || CurrentHirelingFaction || PlayerHousecarl || PlayerMarried
Bool Function IsFollower(Actor a) global native

;1 HasKeyword(SexLabActive), 2 IsInFaction(SexLabAnimatingFaction)
;4 HasKeyword(DefeatActive) || HasMagicEfectWithKeyword(DefeatActive)
;8 HasMagicEffect(SubmitCalm) 10 IsInFaction(DeviouslyHelplessFaction)
;20 IsInFaction(zadAnimatingFaction)

Int Function ActiveMod(Actor Ak) global Native

;mode=0 base keywords
;  1 ArmorBoots, 2 ArmorClothing, 4 ArmorCuirass, 8 ArmorGauntlets,
;  0x10 ArmorHelmet, 0x20 ArmorShield, 0x40 ClothingBody, 0x80 ClothingCirclet,
;  0x100 ClothingFeet, 0x200 ClothingHands, 0x400 ClothingHead, 0x800 ClothingNecklace,
;  0x1000 ClothingPoor, 0x2000 ClothingRich, 0x4000 ClothingRing, 0x8000 JewelryExpensive,
;  0x10000 WeapTypeBattleaxe, 0x20000 WeapTypeBoundArrow, 0x40000 WeapTypeBow, 0x80000 WeapTypeDagger,
;  0x100000 WeapTypeGreatsword, 0x200000 WeapTypeMace, 0x400000 WeapTypeStaff, 0x800000 WeapTypeSword,
;  0x1000000 WeapTypeWarAxe, 0x2000000 WeapTypeWarhammer
;mode=1 DD
;mode=2 ZAZ
;mode=3 DD&ZAZ (logical or)
;zad_DeviousGag=1 zad_DeviousCollar=2 zad_DeviousBelt=4 zad_DeviousHarness=8
;zad_DeviousPlug=0x10 zad_DeviousBra=0x20 zad_DeviousBlindfold=0x40 zad_DeviousLegCuffs=0x80
;zad_DeviousArmCuffs=0x100 zad_DeviousPiercingsNipple=0x200 zad_DeviousPiercingsVaginal=0x400
;zad_DeviousArmbinder=0x800 zad_DeviousYoke=0x1000 zad_DeviousCorset=0x2000
;zad_DeviousBoots=0x4000 zad_DeviousGloves=0x8000 zad_DeviousHood=0x1 0000
;zad_DeviousSuit=0x2 0000 zad_DeviousClamps=0x4 0000 zad_PermitOral=0x8 0000
;zad_PermitAnal=0x10 0000 zad_PermitVaginal=0x20 0000
;zbfWornGag=1 zbfWornCollar=2 zbfWornBelt=4 zbfWornPlug=0x10
;zbfWornBra=0x20 zbfWornBlindfold=0x40 zbfWornAnkles=0x80 zbfWornWrist=0x100
;zbfWornPiercingNipple=0x200 zbfWornPiercingLabia=0x400 zbfWornYoke=0x1000
;zbfWornHood=0x1 0000 zbfWornNippleClamps=0x4 0000 zbfWornPermitOral=0x8 0000
;zbfWornPiercing=0x40 0000 zbfWornPiercingNavel=0x80 0000 zbfWornPiercingNose=0x100 0000
;zbfWornPreventAnal=0x200 0000 zbfWornPreventBreast=0x400 0000 zbfWornPreventOral=0x1000 0000
;zbfWornPreventVaginal=0x2000 0000 zbfEffectGagSound=0x4000 0000
;mode=4 1 - prevent anal, 2- prevent vaginal, 4-prevent oral, 8-has bra

Int function GetWornKeywords(Actor a, Int mode) global Native

;returns equipped items with one of listed in KW keywords
;KW must have at least one keyword

Form[] Function GetWornItems(Actor a, Keyword[] KW) global Native

 

;always exluded: FAct, disabled, deleted, child, ManakinRace, CartHorseRace, not 3Dloaded
;Gender flags
;  ReguireFlags = 1 disable male npc and male daedra
;  DisableFlags = 1 disable female npc and female daedra
;Race types:
;  0x2 = creature, 0x4 = animal, 0x20 = dragon, 0x40 = dwarven,
;  0x8 = npc, 0x10 = daedra,
;  0x80 = undead, 0x100 = ghost.
;  ReguireFlags: The race must have one of given Race types.
;  DisableFlags: All given race types are disabled.
;ReguireFlags = 0x4000 0000 (distanceto Player < maxDistToPlayer && (distanceto FAct < maxdistToFAct || HasLOS to FAct))
;ReguireFlags = 0x2000 0000 allow player
;Other flags
;  0x200 Gost (Actor.IsGhost())
;  0x400 Aggressive (very aggressive or aggro radius behavior)
;  0x800 follower (teammate currenthireling follower housecarl spouse)
;  0x1000 in combat
;  0x2000 guard
;  0x4000 hostile to FAct
;  0x8000 elder voice or elder race
;  0x1 0000 Unconsious || asleep || bleedingout
;  0x2 0000 swimming || flying
;  0x4 0000 mounted/BeingRidden
;  0x8 0000 sexlabactive

;  0x10 0000 defeatactive
;  0x20 0000 hostile or combattarget==FAct
;  0x40 0000 aggressive or FactionReaction==enemy
;  0x80 0000 carriegeSystemFaction
;  0x100 0000 commanded
;  0x200 0000 dead
;  0x400 0000 in scene
;  0x800 0000 unique
;  0x1000 0000 HasLos(FAct)
;Does not check if heath < 0.
;maxdistToFAct == 0 signifies find nothing.
;maxDistToPlayer == 0 indicates to do not check this distance.
;returns a sorted by distance from FAct array

Actor[] Function FindActors(Actor FAct, float maxdistToFAct, float maxDistToPlayer, Int ReguireFlags, Int DisableFlags) global Native

;!disabled && !deleted && 3dloaded && isdead && isactor && !commanded
Actor[] Function FindCorpses() global Native

;returns indexes of bad actors in ar
;(== none) -> ignore
;!IsActor() -> set an array element to none
;commanded or deleted -> return index
;flags: 1 3dloaded 2 dead 4 disabled  -> return index

Int[] Function CheckActors(Actor[] ar, Int flags) global Native

;CalmFaction is 0xAA784
;if Aggressor
;    if Aggressor == Player
;        return
;    endif
;    if CalmFaction
;        Faction[] Factions = Aggressor.GetFactions(0, 100)
;        Int i = Factions.Length
;        While (i > 0)
;            i -= 1
;            Factions.SetAlly(CalmFaction, True, True)
;        EndWhile
;    endif
;    Aggressor.StopCombatAlarm()
;endif
;Victim.StopCombatAlarm()

Function AddCalmList(Actor Aggressor, Actor Victim, Faction CalmFaction) global Native

;Returns total cost of robbed items
;Doesn't rob items with SexLabNoStrip keyword
;correctly calculates the cost of user enchants.
;maxRobbedgold < 0 signifies 999999.

Int function Rob(Actor Victim, ObjectReference Destination, Int maxRobbedgold, Int minItemCost, bool AllowQuestItems, bool AllowWornItems) global Native

;same as DD DLL. More compact
Form function FindMatchingDevice(Actor a, Keyword k) global native
;Returns actually unequipped while logically equipped DD Items
Form[] function GetBrokenDDItems(Actor a) global native

;=================================================================
;                     Require initialised SexLab 1.61...1.64
;=================================================================
;On firts call one of these functions the dll reads and caches all races and sexlab animations.
;If user disables animation, installs animation, changes tags and make etc changes in SexLab you must
; make a save and load it or clear the cache by InvalidateSLData()

function InvalidateSLData() global native

;0-male 1-female 2-male creature 3- female creature 6-commanded disabled deleted none 5-disabled creature/has no animations
;use SL gender change
;SL require

Int Function GetGenderType(Actor Ak, String AllowedRK = "") global Native

;Actors: input: from 2 to 5 actors. Victims stand leading positions. The function sorts this array.
;The animations that don't match sorted array are suppressed.
;AllowedRK: A comma-separated list of SexLab Race Keys. AllowedRK == "All" indicates that all races enabled.
;Tags: [0]=Require Tags. The animation has all these tags.
;     [1]=Suppress Tags. Filter out all the animations that have these tags.
;     [2]=Alt Tags. The animation has at list one of tags.
;mode: 0=return maximum 20 animations, 1=return all animations, 2-return first animation

ReferenceAlias[] Function _MakeAnimation(Actor[] Actors, Int numVictims, Bool UseCreatureGender, String AllowedRK, String[] Tags, Int mode) global Native
sslBaseAnimation[] Function MakeAnimation(Actor[] VicAgg, Bool UseCreatureGender, String ARK, String[] Tags, Bool IsConsensual) global
    sslBaseAnimation[] out
    Int nv = 1
    if IsConsensual
        nv = 0
    endif
    ReferenceAlias[] ti = _MakeAnimation(VicAgg, nv, UseCreatureGender, ARK, Tags, 0)
    Int l = ti.Length
    if l == 0
        return out
    endif
    out = sslUtility.AnimationArray(l)
    while l
        l -= 1
        out[l] = ti[l] as sslBaseAnimation
    endwhile
    return out
Endfunction
bool Function HasAnimations2(Actor[] Actors, Int numVictims, Bool UseCreatureGender, String AllowedRK, String[] Tags) global
    ReferenceAlias[] ti = _MakeAnimation(Actors, numVictims, UseCreatureGender, AllowedRK, Tags, 2)
    return ti.Length > 0
Endfunction

;This function finds possible group animations, and returns the array of actors corresponded a random found animation.
;If only twosome animations possible returns the empty array.
;Allowed one or two victims.
;The order of returned actors: RVictim, additional victim, RAggressor, additional aggressors.
;Of course it supports creatures.
;Does not check if given actors has any doubles

Actor[] Function FindAdditionalActors(Actor RVictim, Actor RAggressor, Actor[] Victims, Actor[] Aggressors, Float MaxDist, Bool UseCreatureGender, String AllowedRK, String[] tags) global Native

 

 

Edited by feiw
1.0.4
Link to comment
  • 6 months later...

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