maxarturo Posted March 27, 2019 Share Posted March 27, 2019 (edited) I want to attach a simple "secondary" script to the final BOSS that when his health reaches 50% or below 50% will fire and enable a Link Ref - trigger box. Sounds simple but... i want to use "percentage" and not "set actor health value", the main reason behind this is that, i'm taking in account the different mods that changes the NPCs level and health like "Run Dragonborn Run" and many other mods like this. What's the logic behind the creation of such script ?. * I don't want to attach this to my main script, because it will also be use with an other boss with different "Primary" script. * creationkit.com hasn't been very helpful with this one. * I'm researching this before i finish the final cell. I still have a lot of work... * Please let it not be one of those things that can't be done.... Again.... Thank you very much for looking at this whoever you are !! Edited March 27, 2019 by maxarturo Link to comment Share on other sites More sharing options...
Reneer Posted March 27, 2019 Share Posted March 27, 2019 (edited) You would want something like this (haven't checked to see if it will compile) put on your Actor:Scriptname RenSpawnBoxLowHealth extends Actor Objectreference Property YourContainer Auto Event OnInit() Self.RegisterForSingleUpdate(1.0) endEvent Event OnUpdate() if (GetActorValuePercentage("Health") <= 0.5 || IsDead() == true) YourContainer.Enable() else Self.RegisterForSingleUpdate(1.0) endif endEvent Edit: Fixed a numerical mistake as noted by ReDragon2013. Edited March 28, 2019 by Reneer Link to comment Share on other sites More sharing options...
maxarturo Posted March 27, 2019 Author Share Posted March 27, 2019 You would want something like this (haven't checked to see if it will compile) put on your Actor: Scriptname RenSpawnBoxLowHealth extends Actor Objectreference Property YourContainer Auto Event OnInit() Self.RegisterForSingleUpdate(1.0) endEvent Event OnUpdate() if (GetActorValuePercentage("Health") <= 50 || IsDead() == true) YourContainer.Enable() else Self.RegisterForSingleUpdate(1.0) endif endEvent Thanks Reneer."GetActorValuePercentage" is nowhere in creationkit.com. my primary source of script information. Or, i completely missed it... Link to comment Share on other sites More sharing options...
Reneer Posted March 27, 2019 Share Posted March 27, 2019 It's on the Actor Script page of the Creation Kit wiki. Link to comment Share on other sites More sharing options...
maxarturo Posted March 27, 2019 Author Share Posted March 27, 2019 As i said.. i completely missed it... Thank you very much Reneer ! Link to comment Share on other sites More sharing options...
TobiaszPL Posted March 27, 2019 Share Posted March 27, 2019 O_o but Maxarturo... "GetActorValuePercentage" is useless... cant u just multiply ActorValue by value less than 1 ? for exampleHealth * 0.30 = 30% of Health ValueHealth * 0.75 = 75% of Health ValueHealth * 1.30 = 130 % of Health Value also i no trust threads and registers and i try to use them not very much << sry 4 my english trying to find words but can't xD while ( ... ) Utility.wait( ... ) endwhile and one loop w8ing for Unit to have 50% or less hp :xwell you can add OnActivate to Actor and idk what you think about this but it was working for me many times :x simple TriggerBox to activate Actor xD even if he is active :Dwell i was activating Sweetrol many times even if it was completly static object :P using register for single update isn't great idea for me... or too many threadsonce i was writing game in C++ and i write class to support images and i forgot to delete temp array and i got some problems with this and "WTF is wrong xD" after 5h of looking where is bad line of codei discover that i just forgot delete Image temp array after loading Bitmap :P Value in script can be stored even after save / loadand what if player save and load while for example script was registering new update and still had one? idk where but once i read that register for single update each 1 second is very bad idea but ok its just my opinion and how i would do it :x... Link to comment Share on other sites More sharing options...
maxarturo Posted March 27, 2019 Author Share Posted March 27, 2019 Hi Toby. As i said i have some work to do with the cell before the creation of this Script & the finalization of the "Primary" script, i'm in a research script situation right now. So i'm open for every & everyone's suggestion. Link to comment Share on other sites More sharing options...
Reneer Posted March 27, 2019 Share Posted March 27, 2019 (edited) o_O but Maxarturo... "GetActorValuePercentage" is useless... cant u just multiply ActorValue by value less than 1 ? for exampleHealth * 0.30 = 30% of Health ValueHealth * 0.75 = 75% of Health ValueHealth * 1.30 = 130 % of Health Value also i no trust threads and registers and i try to use them not very much << sry 4 my english trying to find words but can't xD while ( ... ) Utility.wait( ... ) endwhile and one loop w8ing for Unit to have 50% or less hp :xwell you can add OnActivate to Actor and idk what you think about this but it was working for me many times :x simple TriggerBox to activate Actor xD even if he is active :Dwell i was activating Sweetrol many times even if it was completly static object :tongue: using register for single update isn't great idea for me... or too many threadsonce i was writing game in C++ and i write class to support images and i forgot to delete temp array and i got some problems with this and "WTF is wrong xD" after 5h of looking where is bad line of codei discover that i just forgot delete Image temp array after loading Bitmap :tongue: Value in script can be stored even after save / loadand what if player save and load while for example script was registering new update and still had one? idk where but once i read that register for single update each 1 second is very bad idea but ok its just my opinion and how i would do it :x...Several important things: 1. RegisterForSingleUpdate is the preferred method of polling versus RegisterForUpdate. See here for more information. Using RegisterForSingleUpdate(1.0) will not have any adverse consequences here and won't cause any save / load issues, unlike RegisterForUpdate.2. Using a while loop as you suggested is a bad idea because it will essentially lock up the script until the actor's health is below 50% and nothing else could be done until that while loop exits. And if that actor spawns but their health doesn't drop below 50% the script will be locked forever.3. GetActorValuePercentage isn't "useless" it is simply a convenience function. Edited March 27, 2019 by Reneer Link to comment Share on other sites More sharing options...
TobiaszPL Posted March 28, 2019 Share Posted March 28, 2019 1. pff.. ok xD 2. you can always stop loop when player leave cell 3. for what you need function if you can use math ? its like usingint addthisformepls( int a , int b ) { return a + b ; }instead of using a+b lel... but ok, its not my script but if it would be my i will never use threads for this :Pcause its like little thread :x... Link to comment Share on other sites More sharing options...
ReDragon2013 Posted March 28, 2019 Share Posted March 28, 2019 (edited) Dear Reneer, you posted: if (GetActorValuePercentage("Health") <= 50 || IsDead() == true)I believe it should be as follow if (GetActorValuePercentage("Health") <= 0.5 || IsDead() == true)you give answer: 3. GetActorValuePercentage isn't "useless" it is simply a convenience function.GetActorValuePercentage is native function, GetAVPercentage is the convenience function I have rewritten your sample code as follow:EnableTrigger50pActorScript Scriptname EnableTrigger50pActorScript extends Actor ; https://forums.nexusmods.com/index.php?/topic/7517246-how-the-hell-do-i-script-this/ Objectreference PROPERTY myObject auto ; -- EVENTs -- 3 EVENT OnInit() RegisterForSingleUpdate(1.0) ENDEVENT EVENT OnDeath(Actor akKiller) UnRegisterForUpdate() myObject.Enable() ENDEVENT EVENT OnUpdate() IF (GetAVPercentageHealth() > 0.5) IF self.IsDead() ; see OnDeath() event ELSE RegisterForSingleUpdate(1.0) ENDIF ELSE ; actors health is equal or lower than 50 percentage myObject.Enable() ENDIF ENDEVENT ; -- FUNCTIONs -- 2 ; https://www.creationkit.com/index.php?title=GetActorValuePercentage_-_Actor ; "This function will always return 1.0, if the actor values maximum is Zero." ;------------------------------------- Float FUNCTION GetAVPercentageHealth() ; make your own function ;------------------------------------- ; Obtain the AV percentage of health ; This version does not take in account for buffed stats. float f = self.GetActorValue("Health") ; current actorValue of health ;;; float f = GetAVHealthMax() f = f / self.GetBaseActorValue("Health") RETURN f ENDFUNCTION ;------------------------------ Float FUNCTION GetAVHealthMax() ; make your own function ;------------------------------ ; Obtain the maximum AV of health ; This version takes in account for buffed stats. float B = self.GetBaseActorValue("Health") ; base actor value float f = self.GetActorValue("Health") ; current actor Value f = Math.Ceiling( f / self.GetActorValuePercentage("Health") ) as Float ; current max value IF (B < f) RETURN B ; base value ENDIF ;--------- RETURN f ; current value is bigger than base ENDFUNCTION EnableTrigger50pScript Scriptname EnableTrigger50pScript extends ReferenceAlias ; https://forums.nexusmods.com/index.php?/topic/7517246-how-the-hell-do-i-script-this/ Objectreference PROPERTY myObject auto ; -- EVENTs -- 3 EVENT OnInit() RegisterForSingleUpdate(1.0) ENDEVENT EVENT OnDeath(Actor akKiller) UnRegisterForUpdate() myObject.Enable() ENDEVENT EVENT OnUpdate() actor aRef = self.GetActorReference() IF (GetAVPercentageHealth() > 0.5) IF aRef.IsDead() ; see OnDeath() event ELSE RegisterForSingleUpdate(1.0) ENDIF ELSE ; actors health is equal or lower than 50 percentage myObject.Enable() ENDIF ENDEVENT ; -- FUNCTIONs -- 2 ; https://www.creationkit.com/index.php?title=GetActorValuePercentage_-_Actor ; "This function will always return 1.0, if the actor values maximum is Zero." ;------------------------------------- Float FUNCTION GetAVPercentageHealth() ; make your own function ;------------------------------------- ; Obtain the AV percentage of health ; This version does not take in account for buffed stats. actor aRef = self.GetActorReference() float f = aRef.GetActorValue("Health") ; current actorValue of health ;;; float f = GetAVHealthMax() f = f / aRef.GetBaseActorValue("Health") RETURN f ENDFUNCTION ;------------------------------ Float FUNCTION GetAVHealthMax() ; make your own function ;------------------------------ ; Obtain the maximum AV of health ; This version takes in account for buffed stats. actor aRef = self.GetActorReference() float B = aRef.GetBaseActorValue("Health") ; base actor value float f = aRef.GetActorValue("Health") ; current actor Value f = Math.Ceiling( f / aRef.GetActorValuePercentage("Health") ) as Float ; current max value IF (B < f) RETURN B ; base value ENDIF ;--------- RETURN f ; current value is bigger than base ENDFUNCTION Edited March 28, 2019 by ReDragon2013 Link to comment Share on other sites More sharing options...
Recommended Posts