Jump to content

[LE] How the hell do i Script this ?


Recommended Posts

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 by maxarturo
Link to comment
Share on other sites

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 by Reneer
Link to comment
Share on other sites

 

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

O_o but Maxarturo...

 

"GetActorValuePercentage" is useless...

 

cant u just multiply ActorValue by value less than 1 ?

 

for example

Health * 0.30 = 30% of Health Value

Health * 0.75 = 75% of Health Value

Health * 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 :x

well 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 :D

well 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 threads

once 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 code

i discover that i just forgot delete Image temp array after loading Bitmap :P

 

 

 

Value in script can be stored even after save / load

and 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

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

o_O but Maxarturo...

 

"GetActorValuePercentage" is useless...

 

cant u just multiply ActorValue by value less than 1 ?

 

for example

Health * 0.30 = 30% of Health Value

Health * 0.75 = 75% of Health Value

Health * 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 :x

well 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 :D

well 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 threads

once 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 code

i discover that i just forgot delete Image temp array after loading Bitmap :tongue:

 

 

 

Value in script can be stored even after save / load

and 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 by Reneer
Link to comment
Share on other sites

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 using

int 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 :P

cause its like little thread :x...

Link to comment
Share on other sites

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 by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

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