Jump to content

[LE] No State changes ... I don't get it


Moltenhead

Recommended Posts

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

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

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

  • Recently Browsing   0 members

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