Moltenhead Posted February 2, 2019 Share Posted February 2, 2019 So ... I Have this : Scriptname HelloWorldScript extends ObjectReference {Testing scripting} Actor Property PlayerRef auto Sound[] Property ExhaustionSounds auto Float FirstTreshold = 0.7490 Float Property ExhaustionStart Float Function Get () return FirstTreshold EndFunction EndProperty Float Interval = 0.1875 Float Property ExhaustionInterval Float Function Get () return Interval EndFunction EndProperty Float[] Property ExhaustionTresholds Auto ;State index and previous index tracker Get/Set Int PrivateExhaustionIndex = -1 Int Property ExhaustionIndex Function Set (Int StateIndexTarget) if (StateIndexTarget < ExhaustionTresholds.Length && StateIndexTarget >= -1) PrivateExhaustionIndex = StateIndexTarget endIf EndFunction Int Function Get () return PrivateExhaustionIndex EndFunction EndProperty ;CHMOD like system to check which sounds are still playing Int PrivateModalTracker = 0 Int Property ModalTracker Function Set(int RequestedIndex) Int[] ModalToBinary = IntToBinary(PrivateModalTracker) Int TargetedBit = ModalToBinary[RequestedIndex] Int PowTwo = Math.Pow(2, RequestedIndex) as Int if (TargetedBit == 0) PrivateModalTracker += PowTwo elseIf (TargetedBit == 1) PrivateModalTracker -= PowTwo endIf EndFunction Int Function Get() return PrivateModaltracker EndFunction EndProperty Int[] Property PlayingSounds auto ;MaxVolume Get/Set Float PrivateMaxSFxVolume = 1.0 Float Property MaxSFxVolume Function Set(Float VolumeTarget) if (VolumeTarget >= 0.3 && VolumeTarget < 1) PrivateMaxSFxVolume = VolumeTarget endIf EndFunction Float Function Get() return PrivateMaxSFxVolume EndFunction EndProperty Float PrivateTransitionInterval = 0.01 Float Property TransitionInterval Function Set(Float IntervalTarget) if (IntervalTarget > 0.01 && IntervalTarget <= 0.10) PrivatetransitionInterval = IntervalTarget endIf EndFunction Float Function Get() return PrivateTransitionInterval EndFunction EndProperty Float PrivateTransitioner = 0.0 Float Property Transitioner Function Set(Float Target) if (Target >= 0 && Target <= 1) PrivateTransitioner = Target endIf EndFunction Float Function Get() return Privatetransitioner EndFunction EndProperty ;END OF GLOBAL PRIVATE VARIABLES AND PROPERTIES DECLARATIONS ----------------------- Event OnInit() PlayerRef = Game.GetPlayer() ExhaustionTresholds = new Float[4] ExhaustionTresholds[0] = ExhaustionStart - ExhaustionInterval ;Construct and store nth needed tresholds based on ExhaustionTresholds.Length Int i = 1 while (i < ExhaustionTresholds.Length) ExhaustionTresholds[i] = ExhaustionTresholds[i - 1] - ExhaustionInterval i += 1 endWhile PlayingSounds = new Int[8] GotoState("TrackChanges") EndEvent ;END OF INIT ----------------------------------------------------------------------------------------------- State TrackChanges Event OnBeginState() Debug.Notification(GetState()) RegisterForSingleUpdate(0.10) EndEvent Event OnUpdate() Int ActualExhaustionIndex = GetExhaustionIndex(GetPcStmPercentage()) if (ActualExhaustionIndex != ExhaustionIndex) ExhaustionIndex = ActualExhaustionIndex Debug.Notification("ExhaustionIndex is " + ExhaustionIndex) GotoState("SFxTransitions") else RegisterForSingleUpdate(0.10) return endIf EndEvent EndState ;Handle SFx transitions State SFxTransitions Event OnBeginState() Debug.Notification(GetState()) while (Transitioner < MaxSFxVolume) ManageExhaustionSFx(ExhaustionIndex) Transitioner += TransitionInterval endWhile Debug.Notification("Getting Back to Tracking") Transitioner = 0 UnregisterForUpdate() GotoState("TrackChanges") EndEvent EndState ;END OF STATES DECLARATIONS ------------------------------------------------------------------------ Int[] Function IntToBinary(Int i) Int[] Binarray = new Int[8] String BinaryString = "" Int ModuloStep = i while (ModuloStep > 0) Int Modulo = ModuloStep % 2 BinaryString = BinaryString + Modulo as String ModuloStep = Math.Floor(ModuloStep / 2) endWhile Int StringLength = StringUtil.GetLength(BinaryString) if (StringLength < 1) Binarray[0] = 0 else Int count = 0 while (count < StringLength) Int IndexTarget = StringLength - 1 - count Binarray[IndexTarget] = StringUtil.GetNthChar(BinaryString, IndexTarget) as Int count += 1 endWhile endIf return Binarray EndFunction Int[] Function GetBinarrayKeys(Int[] Binarray) Int[] ExistingKeys String KeysString = "" Int i = 0 while (i < Binarray.Length) if (Binarray[i] == 1) KeysString = KeysString + i as String endIf i += 1 endWhile Int KeysQuantity = StringUtil.GetLength(KeysString) if (KeysQuantity == 1) ExistingKeys = new Int[1] elseif (KeysQuantity == 2) ExistingKeys = new Int[2] elseif (KeysQuantity == 3) ExistingKeys = new Int[3] elseif (KeysQuantity == 4) ExistingKeys = new Int[4] elseif (KeysQuantity == 5) ExistingKeys = new Int[5] elseif (KeysQuantity == 6) ExistingKeys = new Int[6] elseif (KeysQuantity == 7) ExistingKeys = new Int[7] elseif (KeysQuantity == 8) ExistingKeys = new Int[8] endIf i = 0 while(i < KeysQuantity) ExistingKeys[i] = StringUtil.GetNthChar(KeysString, i) as Int i += 1 endWhile return ExistingKeys EndFunction Float Function GetPlayerStaminaPercentage() native Float Function GetPcStmPercentage() return PlayerRef.getAVPercentage("Stamina") EndFunction Int Function GetExhaustionIndex(Float StaminaPercentage) Int i = 0 while (i < ExhaustionTresholds.Length) if (StaminaPercentage > ExhaustionTresholds[i] && StaminaPercentage < GetTresholdCeiling(i)) return i endIf i += 1 endWhile return -1 endFunction Float Function GetTresholdCeiling(Int IterationIndex) if (IterationIndex == 0) return ExhaustionStart else return ExhaustionTresholds[IterationIndex - 1] endIf EndFunction Function ManageExhaustionSFx(Int StateIndex) Int[] Binarray = IntToBinary(ModalTracker) Int[] BinarrayTrueKeys if (Binarray.Length > 0) BinarrayTrueKeys = GetBinarrayKeys(Binarray) endIf if (StateIndex >= 0) if (BinarrayTrueKeys.find(StateIndex) < 0) PlayingSounds[StateIndex] = StartExhaustionSFx(StateIndex) as Int ModalTracker = StateIndex endIf ModulateExhaustionSFx(PlayingSounds[StateIndex], Transitioner) endIf if (ModalTracker > 0) if (Transitioner >= 1) Int i = 0 while (i < BinarrayTrueKeys.Length) Int TrueKey = BinarrayTrueKeys[i] EndExhaustionSFx(PlayingSounds[TrueKey]) ;Adjust needed values PlayingSounds[TrueKey] = 0 ModalTracker = TrueKey i += 1 endWhile else Int i = 0 while (i < BinarrayTrueKeys.Length) ModulateExhaustionSFx(PlayingSounds[BinarrayTrueKeys[i]], MaxSFxVolume - Transitioner) i += 1 endWhile endIf endIf EndFunction Int Function StartExhaustionSFx(Int SFxID) Int SoundId = ExhaustionSounds[SFxID].Play(PlayerRef) as Int return SoundId EndFunction Function EndExhaustionSFx(Int SFxID) Sound.StopInstance(SFxID) EndFunction Function ModulateExhaustionSFx(Int SFxID, Float Volume) Sound.SetInstanceVolume(SFxID, Volume) EndFunction The SFxTransitions State (line 114) never change back to trackChanges State ... Sound doesn't work also but that's not my concern right now.I Don't get what is going on, this is as if the source code just don't want to get pass by a certain point.Is There a way to check when Skyrim cease to read a script ??? Also I was using Update system previously but it only updated twice then completely stoped working.Is it too heavy ? Am I doing something wrong ? Link to comment Share on other sites More sharing options...
Moltenhead Posted February 2, 2019 Author Share Posted February 2, 2019 Exhaustion that is !!!!Sorry to bother I just forgot to add the famous 'i += 1', never ending loops are bad !!!Anyway, I let you check the code : I fyou have some good willed criticism I'm all open. Link to comment Share on other sites More sharing options...
ReDragon2013 Posted February 4, 2019 Share Posted February 4, 2019 You posted a script, which made trouble. Well you got the error. "you have some good willed criticism I'm all open."I do not really understand the sense of the script, but maybe next will give you some new ideas to rewrite your code. I do not use SKSE. HelloWorldScript Scriptname HelloWorldScript extends ObjectReference {Test scripting} ; https://forums.nexusmods.com/index.php?/topic/7362846-no-state-changes-i-dont-get-it/ ; Moltenhead wrote: "" ; ------------------------------------ Modaltracker -- Int PrivateModalTracker = 0 Int PROPERTY ModalTracker ; CHMOD like system to check which sounds are still playing Int Function Get() RETURN PrivateModalTracker EndFunction Function SET(Int i) ; i = RequestedIndex int[] b = myF_IntToBin() ; b = ModalToBinary int p = i * i IF (b[i] == 0) ; b[i] = TargetedBit i = PrivateModalTracker + p ELSEIF (b[i] == 1) i = PrivateModalTracker - p ENDIF PrivateModalTracker = i EndFunction endPROPERTY ; ------------------------------------ Exhaustion -- Float FirstTreshold = 0.7490 Float PROPERTY ExhaustionStart ; start Float Function GET() RETURN FirstTreshold EndFunction endPROPERTY ;----- Float Interval = 0.1875 Float PROPERTY ExhaustionInterval ; interval Float Function GET() RETURN Interval EndFunction endPROPERTY ;----- Int PrivateExhaustionIndex = -1 Int PROPERTY ExhaustionIndex ; index, State index and previous index tracker Get/Set Int Function GET() RETURN PrivateExhaustionIndex EndFunction Function SET(Int i) ; i = StateIndexTarget IF (i < ExhaustionTresholds.Length) && (i >= -1) PrivateExhaustionIndex = i ENDIF EndFunction endPROPERTY ; ------------------------------------ SFxVolume -- Float PrivateMaxSFxVolume = 1.0 Float PROPERTY MaxSFxVolume ; MaxVolume Get/Set Float Function GET() RETURN PrivateMaxSFxVolume EndFunction Function SET(Float f) ; f = VolumeTarget IF (f >= 0.3) && (f < 1.0) PrivateMaxSFxVolume = f ENDIF EndFunction endPROPERTY ; ------------------------------------ Transition -- Float PrivateTransitioner = 0.0 Float PROPERTY Transitioner ; transitioner Float Function GET() RETURN Privatetransitioner EndFunction Function SET(Float f) ; f = Target IF (f >= 0.0) && (f <= 1.0) PrivateTransitioner = f ENDIF EndFunction endPROPERTY ;----- Float PrivateTransitionInterval = 0.01 Float PROPERTY TransitionInterval ; transition interval Float Function Get() RETURN PrivateTransitionInterval EndFunction Function SET(Float f) ; f = IntervalTarget IF (f > 0.01) && (f <= 0.10) PrivatetransitionInterval = f ENDIF EndFunction endPROPERTY ; Int PROPERTY ModalTracker ; Float PROPERTY ExhaustionStart ; Float PROPERTY ExhaustionInterval ; Int PROPERTY ExhaustionIndex ; Float PROPERTY MaxSFxVolume ; Float PROPERTY Transitioner ; Float PROPERTY TransitionInterval Sound[] PROPERTY ExhaustionSounds auto Float[] PROPERTY ExhaustionTresholds auto Int[] PROPERTY PlayingSounds auto ;Actor Property PlayerRef auto ;------------------------------------------------------------------ ; -- EVENTs -- 2 + "TrackChanges" + "SFxTransitions" ;------------------------------------------------------------------ EVENT OnInit() ;;; PlayerRef = Game.GetPlayer() myF_InitArrays() RegisterForSingleUpdate(0.0) ; do not overwhelming the OnInit() event ENDEVENT EVENT OnUpdate() Utility.Wait(0.1) gotoState("TrackChanges") ; ### STATE ### RegisterForSingleUpdateGameTime(0.0) ENDEVENT ;================================== State TrackChanges ;================= EVENT OnUpdateGameTime() int i = GetExhaustionIndex() ; i = ActualExhaustionIndex IF (ExhaustionIndex == i) ; compare with old value ; no different ELSE ExhaustionIndex = i gotoState("SFxTransitions") ; ### STATE ### myF_Transitions() gotoState("TrackChanges") ; ### STATE ### ENDIF Utility.Wait(0.1) RegisterForSingleUpdateGameTime(0.0) ; try exhaustion again ENDEVENT ;======= endState ;================================== State SFxTransitions ; Handle SFx transitions ;=================== endState ; -- FUNCTIONs -- 2 + 3 + 6 ;------------------------ FUNCTION myF_InitArrays() ;------------------------ PlayingSounds = new Int[8] ; zero filled array for 8 entries of type int ExhaustionTresholds = new Float[4] ;Construct and store the needed tresholds based on ExhaustionTresholds.Length float f = ExhaustionStart - ExhaustionInterval int i = 0 WHILE (i < 4) ; ExhaustionTresholds.Length ExhaustionTresholds[i] = f f = f - ExhaustionInterval i = i + 1 ENDWHILE ENDFUNCTION ;-------------------------------- Int FUNCTION GetExhaustionIndex() ;-------------------------------- float f = Game.GetPlayer().GetActorValuePercentage("Stamina") ; f = StaminaPercentage int i = 0 WHILE (i < ExhaustionTresholds.Length) IF (f > ExhaustionTresholds[i]) ; && (f < GetTresholdCeiling(i)) IF (i > 0) IF (f < ExhaustionTresholds[i - 1]) RETURN i ENDIF ELSE IF (f < ExhaustionStart) RETURN i ENDIF ENDIF ENDIF i = i + 1 ENDWHILE RETURN -1 ENDFUNCTION ;Float Function GetPlayerStaminaPercentage() native ;;---------------------------------- ;Float FUNCTION GetPcStmPercentage() ;;---------------------------------- ; float f = Game.GetPlayer().GetActorValuePercentage("Stamina") ; RETURN f ;ENDFUNCTION ;;--------------------------------------- ;Float Function GetTresholdCeiling(Int i) ; i = IterationIndex ;;--------------------------------------- ;IF (i == 0) ; RETURN ExhaustionStart ;ENDIF ;;--------- ; RETURN ExhaustionTresholds[i - 1] ;ENDFUNCTION ;################## ;### BinaryUtil ############################################################################ ;################## 3 ;-------------------------------------------------------- Int FUNCTION myF_StrUtil(String s, Bool bLength, Int n=0) ; SKSE library used here !!! ;-------------------------------------------------------- IF ( bLength ) RETURN StringUtil.GetLength(s) ENDIF ;--------- ; https://www.creationkit.com/index.php?title=GetNthChar_-_StringUtil RETURN StringUtil.GetNthChar(s, n) as Int ; "0" -> 0, "1" -> 1 ;## RETURN 0 ; ### -- FOR COMPILING ONLY -- ### ENDFUNCTION ;;--------------------------- ;Int[] FUNCTION IntToBinary() ; internal helper ;;--------------------------- ; int[] a = new Int[8] ; a = Binarray ; int i = PrivateModalTracker ; string s ; s = BinaryString ; ; WHILE (i > 0) ;;;; Int Modulo = ModuloStep % 2 ;;;; BinaryString = BinaryString + Modulo as String ;;;; ModuloStep = Math.Floor(ModuloStep / 2) ; ; s = s + (i % 2) as String ; modulo 2 returns "0" or "1", depends on "i" is it even or odd ; i = i / 2 ; update the counter by idivide of two ; ; Debug.Trace(" IntToBinary(" +i+ ") - s = " +s) ; ENDWHILE ; ; int iMax = myF_StrUtil(s, TRUE) ; get length of string ; ;IF (iMax < 1) ;;;; a[0] = 0 ; RETURN a ; array initialized with a length of 8, every entry is Zero ;ENDIF ;;--------- ; i = 0 ; i = count ; WHILE (i < iMax) ; int n = (iMax - 1) - i ; a[n] = myF_StrUtil(s, False, n) ; Returns the chr at the given index in the given string. (as Int) ; i = i + 1 ; ENDWHILE ; RETURN a ;ENDFUNCTION ;---------------------------- Int[] FUNCTION myF_IntToBin() ; internal helper ;---------------------------- int[] b = new Int[128] ; the binary storage initialized by maximum size int T = PrivateModalTracker ; How big is it? int i = 0 WHILE (T > 0) b[i] = T % 2 ; modulo 2 returns "0" or "1", depends on "i" is it even or odd T = T / 2 ; update the counter by idivide of two i = i + 1 ENDWHILE int[] a = new Int[8] ; a = Binarray IF (i < 1) RETURN a ; array initialized with a length of 8, every entry is Zero ENDIF ;--------- int iMax = i i = 0 WHILE (i < iMax) int n = (iMax - 1) - i a[n] = b[n] ; Returns the chr at the given index in the given string. (as Int) i = i + 1 ENDWHILE RETURN a ENDFUNCTION ;------------------------------- Int[] FUNCTION GetBinarrayKeys() ;------------------------------- int[] a = myF_IntToBin() ; a = Binarray int[] b ; b = ExistingKeys IF (a.Length == 0) RETURN b ; give back uninitialized array ENDIF ;--------- string s ; s = KeysString int i = 0 WHILE (i < a.Length) IF (a[i] == 1) s = s + (i as String) ENDIF i = i + 1 ENDWHILE int iMax = myF_StrUtil(s, TRUE) ; iMax = KeysQuantity IF (iMax == 1) b = new Int[1] ELSEIF (iMax == 2) b = new Int[2] ELSEIF (iMax == 3) b = new Int[3] ELSEIF (iMax == 4) b = new Int[4] ELSEIF (iMax == 5) b = new Int[5] ELSEIF (iMax == 6) b = new Int[6] ELSEIF (iMax == 7) b = new Int[7] ELSEIF (iMax == 8) b = new Int[8] ENDIF i = 0 WHILE (i < iMax) b[i] = myF_StrUtil(s, False, i) i = i + 1 ENDWHILE RETURN b ; array filled with keys ENDFUNCTION ;################## ;### Exhaustion ############################################################################ ;################## 6 ;------------------------- FUNCTION myF_Transitions() ; see OnUpdate() ;------------------------- Debug.Notification("Now ExhaustionIndex is " + ExhaustionIndex) WHILE (Transitioner < MaxSFxVolume) ; maxVolume (0.3 .. 1.0) ManageExhaustionSFx() Transitioner += TransitionInterval ; interval (0.01 .. 0.1) ENDWHILE Transitioner = 0 Debug.Notification("Getting Back to Tracking") ENDFUNCTION ;----------------------------- FUNCTION ManageExhaustionSFx() ;----------------------------- int[] b = GetBinarrayKeys() ; b = BinarrayTrueKeys int n = ExhaustionIndex myF_PlaySFX(b.Find(n), n) IF (ModalTracker <= 0) RETURN ; - STOP - ENDIF ;--------------------- IF (Transitioner >= 1) myF_StopAllSFX(b) RETURN ; - STOP - ENDIF ;--------------------- int i = 0 WHILE (i < b.Length) n = b[i] ; TrueKey myF_VolumeSFX(PlayingSounds[n], MaxSFxVolume - Transitioner) i = i + 1 ENDWHILE ENDFUNCTION ;------------------------------------- ModulateExhaustionSFx() FUNCTION myF_VolumeSFX(Int i, Float f) ; i = SFxID, f = Volume ;------------------------------------- IF (i > 0) Sound.SetInstanceVolume(i, f) ENDIF ENDFUNCTION ;--------------------------------- FUNCTION myF_PlaySFX(Int i, Int n) ; n = StateIndex = ExhaustionIndex ;--------------------------------- IF (i >= 0) myF_VolumeSFX(i, Transitioner) RETURN ; - STOP - already playing this, sound not stopped ENDIF ;--------------------- IF (n < 0) RETURN ; - STOP - negative index ENDIF ;--------------------- StartExhaustionSFx() i = ExhaustionSounds[n].Play(Game.GetPlayer() as ObjectReference) ; i = SoundId IF (i > 0) ModalTracker = n ; update Tracker, if valid sound is playing PlayingSounds[n] = i ; store the SoundID myF_VolumeSFX(i, Transitioner) ENDIF ENDFUNCTION ;-------------------------- EndExhaustionSFx() FUNCTION myF_StopSFX(Int n) ;-------------------------- IF (n < 0) RETURN ; - STOP - out of array, min ENDIF ;--------------------- IF (n >= PlayingSounds.Length) RETURN ; - STOP - out of array, max ENDIF ;--------------------- int i = PlayingSounds[n] IF (i > 0) Sound.StopInstance(i) ; i = SFxID ENDIF PlayingSounds[n] = 0 ; Adjust needed values ENDFUNCTION ;------------------------------- FUNCTION myF_StopAllSFX(Int[] b) ;------------------------------- int i = 0 WHILE (i < b.Length) ModalTracker = b[i] ; b[i] = TrueKey myF_StopSFX(ModalTracker) i = i + 1 ENDWHILE ENDFUNCTION Link to comment Share on other sites More sharing options...
Recommended Posts