testiger2 Posted June 1, 2019 Share Posted June 1, 2019 Hi everyone, i created a little script mod that lets the player decide at which powerlevel/magnitude spells get cast on the flySo 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 fastId 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 controlsSo 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 More sharing options...
foamyesque Posted June 1, 2019 Share Posted June 1, 2019 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 More sharing options...
ReDragon2013 Posted June 1, 2019 Share Posted June 1, 2019 (edited) 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 June 1, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
testiger2 Posted June 2, 2019 Author Share Posted June 2, 2019 @DragonUnfortunately 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. @foami 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 More sharing options...
foamyesque Posted June 3, 2019 Share Posted June 3, 2019 @testiger2: How *do* you add custom UI bits, anyway? It's an area I haven't looked at. Link to comment Share on other sites More sharing options...
testiger2 Posted June 4, 2019 Author Share Posted June 4, 2019 This was a helpful read if you navigate through the distracting code snippets https://forums.bethsoft.com/topic/1509769-tuthow-to-create-widgets-using-flash-tools/ Link to comment Share on other sites More sharing options...
Recommended Posts