Jump to content

[LE] Brainstorming for Improvements


Recommended Posts

Hi everyone,

 

i created a little script mod that lets the player decide at which powerlevel/magnitude spells get cast on the fly

So to be able to Cast weaker but cheap or strong but expensive variants of the same spell as the situation requires.

 

How it works: press hotkey to up/down some unused ActorValue and have a Perk control the spell values.

Scriptname TTSpellScalerAliasScript extends ReferenceAlias 

int Property upKey = 0x108 Auto ;MW_Up
int Property downKey = 0x109 Auto ;MW_Down
int Property modKey = 0x38 Auto ;LAlt

string property AV = "WaitingForPlayer" Auto
float Property step = 10.0 Auto

bool Property bActive = false Auto

Actor PlayerRef

;########States######################

State Inactive
;Game should ignore these events when inactive
	Event OnPlayerLoadGame()
	EndEvent
	Event OnKeyDown(Int KeyCode)
	EndEvent
EndState

;########Events######################

Event Oninit()
	OnplayerLoadGame()
EndEvent

Event OnPlayerLoadGame() 
{Prepare for Button monitoring.}
	PlayerRef = Game.GetPlayer()
	PlayerRef.SetActorValue(AV, 100) ;100 = normal strength
	toggleActive(bActive)
EndEvent

Event OnKeyDown(Int KeyCode)
	;GoToState("Inactive") ;stop all event calls
	if Input.IsKeyPressed(modKey)
		if KeyCode == upKey
			PlayerRef.modActorValue(AV, step)
		else
			PlayerRef.modActorValue(AV, -step)
		endif
		;float stren = PlayerRef.GetActorValue(AV) * 0.01
		int stren = PlayerRef.GetActorValue(AV) as int
		debug.Notification("Spell Strength: " + stren + "%")
	endif
	;GoToState("") ;active event calls after
EndEvent

;########Functions######################

Function toggleActive(bool abState)
	if abState
		RegisterForKey(upKey)
		RegisterForKey(downKey)
		GoToState("")
	else
		UnregisterForAllKeys()
		GoToState("Inactive")
	endif
	bActive = abState
EndFunction

Function registerNewKey(int oldKey, int newKey)
	UnRegisterForKey(oldKey)
	if oldKey == upKey
		upKey = newKey
	elseif oldKey == downKey
		downKey = newKey
	elseif oldKey == modKey
		modKey = newKey
	endif
	RegisterForKey(newKey)
EndFunction

The script i have is working well functionality wise but i'd like to add some small qualityoflife features.

 

1. debug.notifications spam up the left corner too much when pressing the hotkeys fast

Id like a way wo clear the notifications if possible so that only the latest value gets displayed.

Alternatively if someone knows how to add a custom hud elememt like a slider or text this would also work

 

2. Id like to temporarily disable mapped controls

So for example if use Alt + MouseWheel to adjust the AV, i want to stop the zoom in/out control while i press alt without explicilty remapping the hotkeys

 

Any input is appreciated

 

Link to comment
Share on other sites

For the notifications, instead of displaying it directly, set a flag and register for an update out, say, a half second. On that update, if the flag's set, display the notification and clear the flag.

 

It'll impose a bit of a UI lag, but it means if someone's hammering the hotkey they won't get a notice until they're done.

Link to comment
Share on other sites

Not sure next code will be an improvement, who knows:

 

I assume your posted script is for player alias only. I registered for L-ALT only and added some more states.

The new GlobalVariable "myGlobalAV" is a replacement for PlayerRef.GetActorValue(AV) and PlayerRef.SetActorValue(AV, f)

 

TTSpellScalerPlayerAliasScript

 

Scriptname TTSpellScalerPlayerAliasScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/7694918-brainstorming-for-improvements/

  GlobalVariable PROPERTY myGlobalAV auto

  Float PROPERTY step = 10.0 auto
  Bool  PROPERTY bActive     auto        ; [default=False]


; -- EVENTs -- 3 + "Busy" + "InActive" + "Active"

; https://www.creationkit.com/index.php?title=OnKeyDown_-_Form

EVENT Oninit()                    ; first time run for new game or saved game, can be run twice!
    bActive = TRUE
    myF_Init(TRUE)
ENDEVENT


EVENT OnPlayerLoadGame()         ; every time a saved game has been loaded
    myF_Init(False)
ENDEVENT


EVENT OnKeyDown(Int KeyCode)
;IF Utility.IsMenuMode()
;ELSE
    gotoState("Active")                ; ### STATE ###
    RegisterForKey(0x108)                            ; mouse wheel UP
    RegisterForKey(0x109)                            ; mouse wheel DOWN
;ENDIF
ENDEVENT


;===============================
State Busy
;=========
  EVENT OnKeyDown(Int KeyCode)
  ENDEVENT
;=======
endState


;===============================
State Inactive    ; game should ignore next events
;=============
  EVENT OnPlayerLoadGame()
  ENDEVENT

  EVENT OnKeyDown(Int KeyCode)
  ENDEVENT
;=======
endState


;===============================
State Active
;===========
  EVENT OnKeyDown(Int KeyCode)
    gotoState("Busy")                ; ### STATE ###
    myF_Update(KeyCode, myGlobalAV.GetValue())
    Utility.Wait(0.1)                                ; just wait for a while
    gotoState("Active")                ; ### STATE ###
  ENDEVENT

  EVENT OnKeyUp(Int KeyCode, Float HoldTime)
    IF (KeyCode == 0x038)                            ; *** Left-ALT has been released
        myF_RegKey()
    ENDIF
  ENDEVENT
;=======
endState


; -- FUNCTIONs -- 4

;----------------------------
FUNCTION myF_Init(Bool bInit)  ; internal
;----------------------------
    IF ( bActive )
        float f
        IF ( myGlobalAV )                    ; test valid property
            f = myGlobalAV.GetValue()
        ENDIF

        IF (f == 0.0)
            myGlobalAV.SetValue(100)        ; 100 = normal strength, PlayerRef.SetActorValue(AV, 100)
        ENDIF
    ENDIF
;--------
    IF ( bInit )
        RegisterForKey(0x038)                        ; *** Left-ALT prepare for monitoring
        Debug.Trace("OnInit() - has been called.. " +self)
    ELSE
        Debug.Trace("OnLoadGame() - has been called.. " +self)
    ENDIF
ENDFUNCTION


;----------------------------------------
FUNCTION myF_Update(Int KeyCode, Float f)  ; internal
;----------------------------------------
    IF (KeyCode == 0x108)                ; UP
        f = f + step
    ELSE
        f = f - step
    ENDIF

    myGlobalAV.SetValue(f)
    Debug.Notification("Spell Strength: " + (f as Int) + "%")
ENDFUNCTION


;--------------------
FUNCTION myF_RegKey()  ; helper
;--------------------
    UnRegisterForAllKeys()
    RegisterForKey(0x038)                            ; *** Left-ALT
    gotoState("")                ; ### STATE ###
ENDFUNCTION


;----------------------------------
FUNCTION toggleActive(Bool abState)  ; external only
;----------------------------------
    IF ( abState )
        myF_RegKey()
    ELSE
        UnRegisterForAllKeys()
        gotoState("Inactive")        ; ### STATE ###
    ENDIF

    bActive = abState
ENDFUNCTION

 

 

 

Maybe you could deal with this https://www.creationkit.com/index.php?title=IsInMenuMode_-_Utility

bool bOK = Utility.IsInMenuMode()

IF ( bOK )
   ; in menu mode
ELSE
   ; in game mode
ENDIF

or SKSE based like this: https://www.creationkit.com/index.php?title=IsMenuOpen_-_UI

bool bOK = UI.IsMenuOpen("MapMenu")
Edited by ReDragon2013
Link to comment
Share on other sites

@Dragon

Unfortunately your idea for using a global doesn't work in this case because the governing PERK needs the entry point to use an actor value.

Introducing more states and menu-checks can always be introduced for speed optimizations later.

 

@foam

i managed to get a custom HUD widget working to display the value so its way cleaner and nicer. Debug.Notification is obsolete in this case.

I will remember your OnUpdate() idea though. This might be useful in other projects

 

So i managed to solve #1 but there remains the issue with overlapping hotkeys from #2

 

Are there any Events and/or registerFuncs firing when the user remappes keys in the vanilla menu?

How exactly does the game communicate with the controlmap.txt?

Link to comment
Share on other sites

  • Recently Browsing   0 members

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