PeterMartyr Posted June 7 Share Posted June 7 @dylbill that much better))) but it is still way unnecessary complicated, mine vanilla, even negative is possible with vanilla. So nothing changed... and I still stand by that, you could that with out SKSE Spoiler string Function DecimalToHexadecimalVanilla(int decimal) Global bool bNegative if (decimal < 0) decimal * -1 bNegative = true ElseIf decimal == 0 Return "0x0" EndIf string[] letters = new string[6] letters[0]="A" letters[1]="B" letters[2]="C" letters[3]="D" letters[4]="E" letters[5]="F" string hexadecimal = "" while (decimal > 0) int remainder = decimal % 16 if remainder < 10 hexadecimal = remainder As string + hexadecimal Else hexadecimal = letters[remainder - 10] + hexadecimal EndIf decimal /= 16 endwhile If !bNegative return "0x" + hexadecimal EndIf return "-0x" + hexadecimal EndFunction a vanilla one what returns a negative with one loop, here my go to comment I always use, your all over thinking stuff.. good code is simple. . your using four loops and call four SKSE functions respectively Just for fun a SKSE one I hope you notice I am NOT using a string, but the ascii table.. and math.. ( had to explain that cos that code missing on the creation kit wikki) so it is all me, just take my word for it, if you trust me https://www.ibm.com/docs/en/aix/7.2?topic=adapters-ascii-decimal-hexadecimal-octal-binary-conversion-table Spoiler string Function DecimalToHexadecimalSKSE(int decimal) Global bool bNegative if (decimal < 0) decimal * -1 bNegative = true ElseIf decimal == 0 Return "0x0" EndIf string hexadecimal = "" while (decimal > 0) int remainder = decimal % 16 if remainder < 10 hexadecimal = remainder As string + hexadecimal Else hexadecimal = StringUtil.AsChar(remainder + 55) + hexadecimal EndIf decimal /= 16 endwhile If !bNegative return "0x" + hexadecimal EndIf return "-0x" + hexadecimal EndFunction I do not care if offend you again they were writing code like children, see the difference when it is done right with the ascii table Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 7 Share Posted June 7 @dylbill here a hint for you what the difference between upper case and lower case ? 1 flipped bit, they did that intentionally to make it easy to change it)))) 1000001 = A 1100001 = a but it works for all of them, just the second from the left is flipped There more to coding than Bethesda Link to comment Share on other sites More sharing options...
vn524135 Posted June 11 Author Share Posted June 11 (edited) I'm almost done with the mod, and I want to share the final scripts with you. The scripts seem to be working well. After running for 60 seconds, the player can't run for 180 seconds, but this can be ended by sleeping or using options in the Magic > Powers menu. These options include animations like sitting and lying down, which also apply to followers. Please let me know if you have any comments or suggestions. Scriptname modRunningFatiguePlayerScript extends ReferenceAlias Actor PlayerRef Float currentCarryWeight Int runningCounter Int fatigueCounter Bool bOnFatigue Function StartFatigue() currentCarryWeight = PlayerRef.GetActorValue("CarryWeight") PlayerRef.DamageActorValue("CarryWeight", currentCarryWeight) runningCounter = 0 bOnFatigue = true EndFunction Function StopFatigue() PlayerRef.RestoreActorValue("CarryWeight", currentCarryWeight) runningCounter = 0 fatigueCounter = 0 bOnFatigue = false EndFunction Function StartWarningFatigue() ;This is to warn the player when they are close to entering the fatigue state. currentCarryWeight = PlayerRef.GetActorValue("CarryWeight") PlayerRef.DamageActorValue("CarryWeight", currentCarryWeight) Utility.Wait(4) PlayerRef.RestoreActorValue("CarryWeight", currentCarryWeight) EndFunction Event OnInit() PlayerRef = Game.GetPlayer() bOnFatigue = false runningCounter = 0 fatigueCounter = 0 RegisterForSleep() RegisterForSingleUpdate(3.0) EndEvent Event OnUpdate() if bOnFatigue == true fatigueCounter+=5 elseif PlayerRef.IsRunning() && !PlayerRef.IsInCombat() && !PlayerRef.IsSneaking() runningCounter+=5 endif if runningCounter == 45 runningCounter = 50 ;If the player doesn't run and, therefore, the counter doesn't increase, then startWarningFatigue will be executed in every update. Setting runningCounter to 50 prevents this. StartWarningFatigue() endif if runningCounter >= 60 ;The player can exceed the 60-second time limit by sprinting. However, once sprinting stops, they enter the fatigue state. if !PlayerRef.IsSprinting() StartFatigue() endif endif if fatigueCounter == 180 StopFatigue() endif RegisterForSingleUpdate(5.0) EndEvent Event OnSleepStop(bool abInterrupted) StopFatigue() EndEvent This is the script of one of the resting options accessible from the Magic > Powers menu. Scriptname aaaModRestSpellAScript extends activemagiceffect Idle Property IdleSitCrossLeggedExit Auto modRunningFatiguePlayerScript Property pModRunningFatiguePlayerScript Auto FollowerAliasScript Property pFollowerAliasScript Auto Actor PlayerRef Event OnInit() PlayerRef = Game.GetPlayer() EndEvent Event OnEffectStart(Actor akTarget, Actor akCaster) Game.SetPlayerAIDriven() Game.DisablePlayerControls(0,1,0,0,1,0,1) Debug.SendAnimationEvent(PlayerRef, "IdleSitCrossLeggedEnter") Utility.Wait(0.7) ;This is to make it realistic, by playing the follower's animation shortly after the player's. Actor FollowerActor = pFollowerAliasScript.GetActorRef() as Actor Debug.SendAnimationEvent(FollowerActor, "IdleSitCrossLeggedEnter") EndEvent Event OnEffectFinish(Actor akTarget, Actor akCaster) pModRunningFatiguePlayerScript.StopFatigue() PlayerRef.PlayIdle(IdleSitCrossLeggedExit) Game.SetPlayerAIDriven(false) Game.EnablePlayerControls() Utility.Wait(0.5) Actor FollowerActor = pFollowerAliasScript.GetActorRef() as Actor Debug.SendAnimationEvent(FollowerActor, "IdleChairExitStart") EndEvent Edited June 11 by vn524135 Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 11 Share Posted June 11 all I am gonna say is Yeah... your getting there mate... btw if you need to call the same function or fire the same event in a script twice, but require a different result, that when you need a state, always keep that in mind, now the script is two different states Just asking, who is the caster or the target in the magic effect? (Actor akTarget, Actor akCaster) use the variables passed to you to your advantage, I see no akTarget or akCaster in your code, let's chat about that, tell me who they are? Link to comment Share on other sites More sharing options...
vn524135 Posted June 11 Author Share Posted June 11 (edited) 2 hours ago, PeterMartyr said: all I am gonna say is Yeah... your getting there mate... btw if you need to call the same function or fire the same event in a script twice, but require a different result, that when you need a state, always keep that in mind, now the script is two different states Just asking, who is the caster or the target in the magic effect? (Actor akTarget, Actor akCaster) use the variables passed to you to your advantage, I see no akTarget or akCaster in your code, let's chat about that, tell me who they are? Unfortunately, I don't have much knowledge. According to wiki, akTarget is "the Actor this effect was applied to", and akCaster is "the Actor that cast the spell this effect was from.". Both can be the player or an NPC. I can use them in the code like this; if akCaster == Game.GetPlayer() endif if akTarget == Game.GetPlayer() endif But I didn't see the need to use them because the player is the only actor with the magic. Edit: The caster and the target is the player. Casts itself by pressing the Z key. Edited June 11 by vn524135 Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 11 Share Posted June 11 you define who the are when you cast the spell, give me some time I will show an example Link to comment Share on other sites More sharing options...
vn524135 Posted June 12 Author Share Posted June 12 (edited) 17 hours ago, PeterMartyr said: you define who the are when you cast the spell, give me some time I will show an example Then, as I understand it, if it is defined as akCaster = FollowerActor, the follower is considered the caster, even if the player or a non-follower NPC casts the spell. 20 hours ago, PeterMartyr said: all I am gonna say is Yeah... your getting there mate... btw if you need to call the same function or fire the same event in a script twice, but require a different result, that when you need a state, always keep that in mind, now the script is two different states Just asking, who is the caster or the target in the magic effect? (Actor akTarget, Actor akCaster) use the variables passed to you to your advantage, I see no akTarget or akCaster in your code, let's chat about that, tell me who they are? Following your information, I changed the script so there will not be unnecessary updates every five seconds when the player is fatigued and can't run. This is a big improvement, and I thank you very much for your help. Here is the current version of the script: Spoiler Scriptname modRunningFatiguePlayerScript extends ReferenceAlias Actor PlayerRef Float currentCarryWeight Int runningCounter Function StartFatigue() currentCarryWeight = PlayerRef.GetActorValue("CarryWeight") PlayerRef.DamageActorValue("CarryWeight", currentCarryWeight) GotoState("Fatigued") EndFunction Function StopFatigue() PlayerRef.RestoreActorValue("CarryWeight", currentCarryWeight) runningCounter = 0 GotoState("Counting") EndFunction Function StartWarningFatigue() currentCarryWeight = PlayerRef.GetActorValue("CarryWeight") PlayerRef.DamageActorValue("CarryWeight", currentCarryWeight) Utility.Wait(4) PlayerRef.RestoreActorValue("CarryWeight", currentCarryWeight) EndFunction Event OnInit() PlayerRef = Game.GetPlayer() runningCounter = 0 GotoState("Counting") RegisterForSleep() RegisterForSingleUpdate(3.0) EndEvent State Counting Event OnBeginState() RegisterForSingleUpdate(3.0) EndEvent Event OnUpdate() if PlayerRef.IsRunning() && !PlayerRef.IsInCombat() && !PlayerRef.IsSneaking() runningCounter+=5 endif if runningCounter == 45 runningCounter = 50 StartWarningFatigue() endif if runningCounter >= 60 if !PlayerRef.IsSprinting() StartFatigue() endif else RegisterForSingleUpdate(5.0) endif EndEvent Event OnSleepStop(bool abInterrupted) StopFatigue() EndEvent EndState State Fatigued Event OnBeginState() RegisterForSingleUpdate(180.0) EndEvent Event OnUpdate() StopFatigue() EndEvent Event OnSleepStop(bool abInterrupted) StopFatigue() EndEvent EndState Edited June 12 by vn524135 Link to comment Share on other sites More sharing options...
Evangela Posted June 26 Share Posted June 26 For the sake of speed and efficiency, I'll only suggest you avoid using function wrappers like RestoreAV and instead of using Game.GetPlayer(), you have 2 faster options: 1. Use the Actor PlayerRef property, or 2: Use an Actor player variable and assign Game.GetPlayer() to it in OnInit so that it is called exactly once and then used throughout the script. As you're using a complex update, speed is very important IMO. RestorAV/DamageAV etc just calls RestoreActorValue. It's more efficient to use RestoreActorValue, etc instead. Link to comment Share on other sites More sharing options...
vn524135 Posted June 28 Author Share Posted June 28 On 6/26/2024 at 10:08 PM, Evangela said: For the sake of speed and efficiency, I'll only suggest you avoid using function wrappers like RestoreAV and instead of using Game.GetPlayer(), you have 2 faster options: 1. Use the Actor PlayerRef property, or 2: Use an Actor player variable and assign Game.GetPlayer() to it in OnInit so that it is called exactly once and then used throughout the script. As you're using a complex update, speed is very important IMO. RestorAV/DamageAV etc just calls RestoreActorValue. It's more efficient to use RestoreActorValue, etc instead. I apologize for replying to your message late. I thought the forum notifications appeared in the non-forum notifications of the site. Many thanks for your message and this information. While working on the script, I learned these improvements when searching the forum and made the adjustments to the script. The final version of the script is in my last message. It would have been better to edit my first message and add the final version of the script to avoid confusions, I apologize for not doing that. Here is the final version of the script: Spoiler Scriptname modRunningFatiguePlayerScript extends ReferenceAlias Actor PlayerRef Float currentCarryWeight Int runningCounter Function StartFatigue() currentCarryWeight = PlayerRef.GetActorValue("CarryWeight") PlayerRef.DamageActorValue("CarryWeight", currentCarryWeight) GotoState("Fatigued") EndFunction Function StopFatigue() PlayerRef.RestoreActorValue("CarryWeight", currentCarryWeight) runningCounter = 0 GotoState("Counting") EndFunction Function StartWarningFatigue() currentCarryWeight = PlayerRef.GetActorValue("CarryWeight") PlayerRef.DamageActorValue("CarryWeight", currentCarryWeight) Utility.Wait(4) PlayerRef.RestoreActorValue("CarryWeight", currentCarryWeight) EndFunction Event OnInit() PlayerRef = Game.GetPlayer() runningCounter = 0 GotoState("Counting") RegisterForSleep() RegisterForSingleUpdate(3.0) EndEvent State Counting Event OnBeginState() RegisterForSingleUpdate(3.0) EndEvent Event OnUpdate() if PlayerRef.IsRunning() && !PlayerRef.IsInCombat() && !PlayerRef.IsSneaking() runningCounter+=5 endif if runningCounter == 45 runningCounter = 50 StartWarningFatigue() endif if runningCounter >= 60 if !PlayerRef.IsSprinting() StartFatigue() endif else RegisterForSingleUpdate(5.0) endif EndEvent Event OnSleepStop(bool abInterrupted) StopFatigue() EndEvent EndState State Fatigued Event OnBeginState() RegisterForSingleUpdate(180.0) EndEvent Event OnUpdate() StopFatigue() EndEvent Event OnSleepStop(bool abInterrupted) StopFatigue() EndEvent EndState And I want to say that I published the mod here; https://www.nexusmods.com/skyrim/mods/118622 Thank you again! Link to comment Share on other sites More sharing options...
PeterMartyr Posted June 29 Share Posted June 29 On 6/27/2024 at 4:38 AM, Evangela said: For the sake of speed and efficiency, I'll only suggest you avoid using function wrappers like RestoreAV and instead of using Game.GetPlayer(), you have 2 faster options: 1. Use the Actor PlayerRef property, or 2: Use an Actor player variable and assign Game.GetPlayer() to it in OnInit so that it is called exactly once and then used throughout the script. As you're using a complex update, speed is very important IMO. RestorAV/DamageAV etc just calls RestoreActorValue. It's more efficient to use RestoreActorValue, etc instead. @Evangela dude the saving in a modern gaming rig is what, 1 ten thousands of a second or less? Pfft you can run your bad code 10, 000 or more time in 1 second.... how is that a insignificant improvement ??? and guess what PC are getting faster too... Edit in a shitty PC it still would be measured in milliseconds Edit#2 what your sayin had merit 15, 20, years ago.. I will admit that, when they started preaching it.. but I think we have move on and it is no importance in this day and age, you need to let it go... Link to comment Share on other sites More sharing options...
Recommended Posts