Jump to content

[LE] Need expert script help with mod idea


masternoxx

Recommended Posts

I really want to make this gameplay mod. The mod is to make only your top (5) highest skills, to raise your player xp, when the skills level up. It needs a compare function obviously, and to disable the bottom 13 skill multipliers. I am using elys uncapper for this, but unknown how to use the compare logic or functions, hopefully they exist in papyrus or skse.

So what I have so far is this, LOL

--------------------------------------------

 

;get base skill values
float alc = Game.GetPlayer().GetBaseActorValue("alchemy")
float alt = Game.GetPlayer().GetBaseActorValue("alteration")
float arc = Game.GetPlayer().GetBaseActorValue("archery")
float blo = Game.GetPlayer().GetBaseActorValue("block")
float con = Game.GetPlayer().GetBaseActorValue("conjuration")
float des = Game.GetPlayer().GetBaseActorValue("destruction")
float enc = Game.GetPlayer().GetBaseActorValue("enchanting")
float hea = Game.GetPlayer().GetBaseActorValue("heavy armor")
float ill = Game.GetPlayer().GetBaseActorValue("illusion")
float lig = Game.GetPlayer().GetBaseActorValue("light armor")
float loc = Game.GetPlayer().GetBaseActorValue("lockpicking")
float one = Game.GetPlayer().GetBaseActorValue("one handed")
float pic = Game.GetPlayer().GetBaseActorValue("pickpocket")
float res = Game.GetPlayer().GetBaseActorValue("restoration")
float smi = Game.GetPlayer().GetBaseActorValue("smithing")
float sne = Game.GetPlayer().GetBaseActorValue("sneak")
float spe = Game.GetPlayer().GetBaseActorValue("speech")
float two = Game.GetPlayer().GetBaseActorValue("two handed")

;compare and filter
;??????

;set [skillExpGainMults]
fAlchemy=1.0
fAlteration=1.0
fArchery=1.0
fBlock=1.0
fConjuration=1.0
fDestruction=1.0
fEnchanting=1.0
fHeavyArmor=1.0
fIllusion=1.0
fLightArmor=1.0
fLockpicking=1.0
fOneHanded=1.0
fPickpocket=1.0
fRestoration=1.0
fSmithing=1.0
fSneak=1.0
fSpeech=1.0
fTwoHanded=1.0

 

-------------------------------------------------

 

Obviously I have no idea how to set up the compare and filter part in the middle, LOL, and the end will of course not look like that, but,

Also I would like the top (5)<--- this number, to be able to be set by the user, but that's after I can get a working script in the first place.

Can anyone help me with this, thank you so much

The script will run on an start enabled quest which I am already familiar with how to set up.

 

Link to comment
Share on other sites

Your mod idea is in very raw stage. Maybe next script and links help you in mod development.

 

https://forums.nexusmods.com/index.php?/topic/840056-running-a-script-on-level-up/
sample mod with forum thread

http://www.gamesas.com/script-increase-healthmagickastamina-skill-leveling-t259897.html
with short sample as follow:

Scriptname WZTestOneHanded extends Quest

EVENT OnStoryIncreaseSkill(String OneHanded)
    IF (Game.GetPlayer().GetActorValue("OneHanded") == 101)
        Game.GetPlayer().SetActorValue("OneHanded", 100)
    ENDIF
ENDEVENT

Next script could be a begin to you. To catch player level up you need a quest which should be registered in the CK "story manager" to reach the special onstory events.

 

mnTopSkills_PlayerAliasScript

 

Scriptname mnTopSkills_PlayerAliasScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/7331096-need-expert-script-help-with-mod-idea/
; masternoxx wrote: "mod is to make only your top (5) highest skills, to raise your player xp, when the skills level up."

  Int[] PROPERTY aTS auto Hidden        ; will be filled on script runtime with Top5 skills
 ;Int iVer = 0


; -- EVENTs --

EVENT OnInit()
    myF_Init(0)
ENDEVENT

EVENT OnPlayerLoadGame()
    myF_Init(1)
ENDEVENT

EVENT OnUpdateGameTime()
    myF_GetTopFiveSkills()
ENDEVENT


; quest scripts only
; ********************************************************************************************
;Scriptname mnTopSkillsQuestScript extends Quest
;
;  mnTopSkills_PlayerAliasScript PROPERTY myAliasScript auto        ; have to be filled in CK

;Event OnStoryIncreaseLevel(int aiNewLevel)
; https://www.creationkit.com/index.php?title=OnStoryIncreaseLevel_-_Quest
;    Debug.Trace("Player just reached level " + aiNewLevel)
;    myAliasScript.myF_GetTopFiveSkills()
;endEvent

;Event OnStoryIncreaseSkill(string asSkill)
; https://www.creationkit.com/index.php?title=OnStoryIncreaseSkill_-_Quest
;    Debug.Trace("Player just increased the " + asSkill+ " skill")
;    myAliasScript.myF_GetTopFiveSkills()
;endEvent
; **********************************************************************************************

; -- FUNCTIONs -- 4

;-----------------------
FUNCTION myF_Init(Int i)
;-----------------------
    IF     (i == 0)
        Debug.Trace(" OnInit() - is running for " +self)
    ELSE
        Debug.Trace(" OnPlayerLoadGame() - is running for " +self)
    ENDIF

    RegisterForSingleUpdateGameTime(0.0)
ENDFUNCTION


;-------------------------------------
String FUNCTION myF_GetStringAV(Int i)  ; internal helper
;-------------------------------------
    string s

IF (i < 7)
    IF     (i == 0)
                    s = "Alchemy"
    ELSEIF (i == 1)
                    s = "Alteration"
    ELSEIF (i == 2)
                    s = "Archery"
    ELSEIF (i == 3)
                    s = "Block"
    ELSEIF (i == 4)
                    s = "Conjuration"
    ELSEIF (i == 5)
                    s = "Destruction"
    ELSE ;IF (i == 6)
                    s = "Enchanting"
    ENDIF
ELSEIF (i < 13)
    IF     (i == 7)
                    s = "Heavy armor"
    ELSEIF (i == 8)
                    s = "Illusion"
    ELSEIF (i == 9)
                    s = "Light armor"
    ELSEIF (i == 10)
                    s = "Lockpicking"
    ELSEIF (i == 11)
                    s = "One handed"
    ELSE ;IF (i == 12)
                    s = "Pickpocket"
    ENDIF
ELSE
    IF     (i == 13)
                    s = "Restoration"
    ELSEIF (i == 14)
                    s = "Smithing"
    ELSEIF (i == 15)
                    s = "Sneak"
    ELSEIF (i == 16)
                    s = "Speech"
    ELSE ;IF (i == 17)
                    s = "Two handed"
    ENDIF
ENDIF
    RETURN s
ENDFUNCTION


;------------------------------
FUNCTION myF_GetTopFiveSkills()
;------------------------------
    IF ( !aTS )
        aTS = new Int[5]            ; place for 5 entries, from [0] .. [4]
        aTS[0] = -1
        aTS[1] = -1
        aTS[2] = -1
        aTS[3] = -1
        aTS[4] = -1
    ENDIF

    float[] a = new Float[5]
    actor player = Game.GetPlayer()

int i = 0
    WHILE (i < 18)                                                  ; 18 perks
        float f = player.GetBaseActorValue( myF_GetStringAV(i) )    ; get player skills BaseActorValue depends on string
        IF     (f >= a[0])
;;;            aTS[4] = aTS[3]
;;;            aTS[3] = aTS[2]
;;;            aTS[2] = aTS[1]
;;;            aTS[1] = aTS[0]
;;;            a[4] = a[3]
;;;            a[3] = a[2]
;;;            a[2] = a[1]
;;;            a[1] = a[0]

            myF_Promote(0, a)
            aTS[0] = i
            a[0] = f
        
        ELSEIF (f >= a[1])
;;;            aTS[4] = aTS[3]
;;;            aTS[3] = aTS[2]
;;;            aTS[2] = aTS[1]
;;;            a[4] = a[3]
;;;            a[3] = a[2]
;;;            a[2] = a[1]

            myF_Promote(1, a)
            aTS[1] = i
            a[1] = f
        
        ELSEIF (f >= a[2])
;;;            aTS[4] = aTS[3]
;;;            aTS[3] = aTS[2]
;;;            a[4] = a[3]
;;;            a[3] = a[2]

            myF_Promote(2, a)
            aTS[2] = i
            a[2] = f

        ELSEIF (f >= a[3])
;;;            aTS[4] = aTS[3]
;;;            a[4] = a[3]

            myF_Promote(3, a)
            aTS[3] = i
            a[3] = f

        ELSEIF (f >  a[4])
            aTS[4] = i          ; store the skill, string s = myF_GetStringAV( aTS[4] )
            a[4] = f            ; store baseValue of this skill
        ENDIF

; *** DEBUGGING only
        Debug.Trace(" " +i+ " " + myF_GetStringAV(i) + " = " +f)
; ***
        i = i + 1
    ENDWHILE

; *** DEBUGGING only
    i = 0
    WHILE (i < a.Length)
        ; a[i] = player.GetBaseActorValue( myF_GetStringAV( aTS[i] ) )
        Debug.Trace(" aTS[" +i+ "] = " +aTS[i]+ ", " + myF_GetStringAV( aTS[i] ) + " = " +a[i])
        i = i + 1
    ENDWHILE
; ***
ENDFUNCTION


;----------------------------------------
FUNCTION myF_Promote(Int iMin, Float[] a)  ; move values down in array (top/down order)
;----------------------------------------
int m
int i = 4
    WHILE (i > iMin)
        m = i - 1
        aTS[i] = aTS[m]          ; "aTS" is global script variable
        a[i]   = a[m]            ; "a" is local function variable as parameter (array is a pointer to caller function variable)
        i = i - 1
    ENDWHILE
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

Gonna need SKSE to change the multipliers, and even then, no idea if they will effect Community Uncapper users' INIs.

That is correct, using Elys uncapper, he has informed me that the multipliers can't be changed in-game,

although it seems to me they must be residing in memory somewhere... how else could it function during the game... anyways seems doubtful to make that work.

 

Instead of that, restart the game after the INI is modified.

the mod would have to be started and then the script ran to modify the multipliers in the INI, and then the game restarted. Which would be fine.

Modifying an INI is obviously possible right it is done from vanilla skyrim menu, every time you change a setting.

 

Thank you redDragon for the script help, going to study that for a while, and try to figure it out xD, that is quite the script, thanks

Edited by masternoxx
Link to comment
Share on other sites

;get base skill values
float alc = Game.GetPlayer().GetBaseActorValue("alchemy")
float alt = Game.GetPlayer().GetBaseActorValue("alteration")
float arc = Game.GetPlayer().GetBaseActorValue("archery")
float blo = Game.GetPlayer().GetBaseActorValue("block")
float con = Game.GetPlayer().GetBaseActorValue("conjuration")
float des = Game.GetPlayer().GetBaseActorValue("destruction")
float enc = Game.GetPlayer().GetBaseActorValue("enchanting")
float hea = Game.GetPlayer().GetBaseActorValue("heavy armor")
float ill = Game.GetPlayer().GetBaseActorValue("illusion")
float lig = Game.GetPlayer().GetBaseActorValue("light armor")
float loc = Game.GetPlayer().GetBaseActorValue("lockpicking")
float one = Game.GetPlayer().GetBaseActorValue("one handed")
float pic = Game.GetPlayer().GetBaseActorValue("pickpocket")
float res = Game.GetPlayer().GetBaseActorValue("restoration")
float smi = Game.GetPlayer().GetBaseActorValue("smithing")
float sne = Game.GetPlayer().GetBaseActorValue("sneak")
float spe = Game.GetPlayer().GetBaseActorValue("speech")
float two = Game.GetPlayer().GetBaseActorValue("two handed")


int first
int second
int third
int fourth
int fifth

;x = skill values array
new x[alc,alt,arc,blo,con,des,enc,hea,ill,lig,loc,one,pic,res,smi,sne,spe,two]
If (x > first)
; This order of assignment is important
fifth = fourth
fourth = third
third = second
second = first
first = x
ElseIf (x > second)
fifth = fourth
fourth = third
third = second
second = x
ElseIf (x > third)
fifth = fourth
fourth = third
third = x
ElseIf (x > fourth)
fifth = fourth
fourth = x
ElseIf (x > fifth)
fifth = x

 

------------------------------------------------

 

I have this as kind of the function which will find the highest skills, I do not know the proper syntax for an array but it needs to go through each value one by one, then going to print to INI file all modifiers 0, then print to INI file top 5 highest skill modiefiers to 1.

learning slowly. but I'll get it

 

then perhaps

----------------------------------------------

 

;set [skillExpGainMults] all to zero (disabled)
Utility.SetINIFloat(fAlchemy,0.0)
Utility.SetINIFloat(fAlteration,0.0)
Utility.SetINIFloat(fArchery,0.0)
Utility.SetINIFloat(fBlock,0.0)
Utility.SetINIFloat(fConjuration,0.0)
Utility.SetINIFloat(fDestruction,0.0)
Utility.SetINIFloat(fEnchanting,0.0)
Utility.SetINIFloat(fHeavyArmor,0.0)
Utility.SetINIFloat(fIllusion,0.0)
Utility.SetINIFloat(fLightArmor,0.0)
Utility.SetINIFloat(fLockpicking,0.0)
Utility.SetINIFloat(fOneHanded,0.0)
Utility.SetINIFloat(fPickpocket,0.0)
Utility.SetINIFloat(fRestoration,0.0)
Utility.SetINIFloat(fSmithing,0.0)
Utility.SetINIFloat(fSneak,0.0)
Utility.SetINIFloat(fSpeech,0.0)
Utility.SetINIFloat(fTwoHanded,0.0)

;set top 5 to 1.0 (active, default)
Utility.SetINIFloat(GetAVstring, stringTofloat, x, 1.0)
Utility.SetINIFloat(GetAVstring, stringTofloat, second, 1.0)
Utility.SetINIFloat(GetAVstring, stringTofloat, third, 1.0)
Utility.SetINIFloat(GetAVstring, stringTofloat, fourth, 1.0)
Utility.SetINIFloat(GetAVstring, stringTofloat, fifth, 1.0)

 

 

incorrectly scripted but you see what I mean

apparently Utility.SetINIFloat may not even work but some say it does if the INI has the same name as the mod,

Edited by masternoxx
Link to comment
Share on other sites

You should test to see if changing them via ActorValueInfo will also change the ini setting. Actually, if you intend for this to only apply to the current game session, then it's an not issue, as it'd mean folks wont have to retweak their ini's every time a setting is altered.

Edited by Rasikko
Link to comment
Share on other sites

You should test to see if changing them via ActorValueInfo will also change the ini setting. Actually, if you intend for this to only apply to the current game session, then it's an not issue, as it'd mean folks wont have to retweak their ini's every time a setting is altered.

Are you talking about a console command?

 

[skillExpGainMults] (fSkillname) is an SKSE function only and must be run right before skyrim startup to have effect. Custom INI's can't be modified from in game. Sure you could do it easily with a pencil and pad just write down all your skills and set the modifiers in Elys_uncapper.ini. Unfortunately I tried that and it feels like cheating and also I want to make the process automatic. It is a relatively simple math operation for instance if you wrote the skill levels down you could see the top 5 easily. But in code it is proving to be more difficult since a compare function does not exist in the Papyrus script language, so one has to be written from scratch, sort of like doing a proof in algebra, kind of sucks but kind of interesting.

As my char gets higher level in skyrim it gets less imprortant to go to jail to reduce non-combat skills from leveling up, as leveling up lockpicking to 16 say, does not affect your player level as much as it used to early game.

Perhaps thats the way it should be played but mostly it irritates me that I can't sell much LOOT without my speechcraft raising my player lever so I store all my loot in chests and then go on combination selling/crime sprees where I sell a bunch of stuff, go to jail, sell more stuff, go to jail etc., until I am out of stuff to sell.

Of course every time I go to jail I have to check if one of the skills I actually want to go up, is about to go up, and then I have to dismiss my follower and irritatingly farm / spam until that skill goes up, then run away and stop using it...

Thats the way you have to play if you want to be as strong as possible... playing on expert also.

 

I'm not in that much of a rush, I will look at some FISS examples such as Skytweak Mod which uses it to store settings in an XML file. But would like to make a bit of progress every couple days otherwise I will forget about it

Link to comment
Share on other sites

  • Recently Browsing   0 members

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