Jump to content

[LE] Best way to track actor's health ?


Recommended Posts

I'm about to finish the current mod's working circle, i'm 2 steps before i finally finished this !!!...

And i'll start working once again on the final boss, i've been working on this since the beginning of the creation of this project and trying different ideas.

And I ended up deciding to build my first original one since by now i've resolve all the issues that at the beginning it seemed impossible to accomplish.


But i will like to hear from other experienced modders which is the best way to 'Track The Actor's Health', this is absolutely crucial for this idea to work since all "Transformations of the Actor" will have to occur at a specific "Health Amount Remaining".


The easy way to do this is "OnHit", but when you have an actor with 5000 health > then transforms to a creature with 10000 health > and then the creature trasforms again to a higher creature form with 20000 health, the "OnHit" will be constantly fireing, at least until the last transformation finishes.

(and there might even be a 4th transformation - final one)


So, i was wondering if there is any other way to do this (track it), because i haven't find anything in 'creationkit.com' that can actually help me with this.


Thank you very much for reading all this, and stay home away from the virus !.

Link to comment
Share on other sites

Hey, I would use a spell ability with conditions on magic effects. You can use GetActorValue Health > xx, or GetActorValuePercent health > xx ect. Note that GetActorValuePercent is between 0.0 and 1.0, 1.0 being 100%. Then use OnEffectStart to do your script functions.

Link to comment
Share on other sites

Hey, I would use a spell ability with conditions on magic effects. You can use GetActorValue Health > xx, or GetActorValuePercent health > xx ect. Note that GetActorValuePercent is between 0.0 and 1.0, 1.0 being 100%. Then use OnEffectStart to do your script functions.

 

Basically this, although I'd be careful: I don't think it protects against oneshot kills. S'why I think the multistage bosses are in general essential or invincible until you trigger the last step.

Edited by foamyesque
Link to comment
Share on other sites

Thank you both for your reply.


@ dylbill

This was one of the 3 ideas i had.

1) Place a script on the actor with an "OnHit" event.

2) Place on the actor an "Ability Spell" with a scripted empty "Magic Effect" and a condition on the Spell.

3) Add to the "Master Controller Script" an "OnUpdate" function to check the actor's health every X sec, but this is worst from a pc's processing usage point of view compared to the "OnHit" event.


* I think there isn't any other way to do this, but you never know, that's why i'm asking.




@ foamyesque.

All actors will be essentials except the last one.


"I don't think it protects against oneshot kills"

Yeap..., this does concern me a lot !, and i'm still trying to find a simpler way to protect the "Essential Actors" from been killed by some 'Weapon' and 'Spell' mods out there that have this simple line.

akTarget.Kill()


You will probably say that this is not your problem but the player's issue, maybe... but having a mod like those will completely F*** the mod / quest.


My solution is to add to each essential actor's script a 'Fail Safe':

- "OnDying" event > check the "Master Controller" global just as a precaution in case it did trigger the transformation.

* Skyrim engine is not the most reliable.


- Then "OnDeath" > "Self.Resurrect()" > "SetGhost()" > "Activate Master Controller Script" to trigger the transformation.

* But this will look a little weird if you are staring at the dead actor.



Thank you both very much for your suggestions.

Edited by maxarturo
Link to comment
Share on other sites

Hey, no problem. With using the ability spell, you shouldn't need to use update events or the onHit event. As a fail safe, you could put the condition GetDead == 1 as well. So, you add the spell ability to your boss, put the condition GetActorValuePercent Health < xx, Or GetDead == 1. Then put a script on your magic effect, and use OnEffectStart. The effect will start when the boss's health percent is below what you set, or it is dead.

Link to comment
Share on other sites

I think you are both right, this is the cheapest (processing cost) and best approach to monitor the actor's health.

Although the "Dead State" must be handled by the actor's script, because if there is a chance that the player can kill the "Essential Actor" you need to first 'Resurrect' him and then 'SendAnimation' or 'PlayIdle' (for the necessary transformation animation), otherwise CTD !.

* You can not sendanimation or idle to a dead actor.


Thank you again !.

Link to comment
Share on other sites

just an approach with quest and aliases

; 1 - track the player mayb is useful in the fuute
; 2 - creature health 5000
; 3 - c.h. 10000
; 4 - c.h. 20000
; 5 etc.

1) creatures you want should be already made with Creation Kit
2) fill the aliases with actors (you know what I mean)
3) assign a script to the ReferenceAliases to track health

4) play a bit with events

 

max00PlayerAliasScript

 

Scriptname max00PlayerAliasScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/8505728-best-way-to-track-actors-health/

; -- EVENTs --

EVENT OnInit()
ENDEVENT

EVENT OnPlayerLoadGame()
ENDEVENT

EVENT OnCombatStateChanged(Actor akTarget, Int aeCombatState)
; 0: Not in combat, 1: In combat, 2: Searching

    IF (aeCombatState == 1)                     ; player is in combat
        actor aRef = self.GetActorReference()
        
        IF aRef.IsEssential()
            aRef.SetEssential(0)                ; remove flag "essential"
        ENDIF

        actorBase AB = aRef.GetActorBase()

        IF AB.IsProtected()
            AB.SetProtected(False)              ; remove flag "protection"
        ENDIF

        IF AB.IsInvulnerable()
            AB.SetInvulnerable(False)           ; remove flag "invulnerable"
        ENDIF

    ENDIF
ENDEVENT

 

 

max00CreatureBossAliasScript

 

Scriptname max00CreatureBossAliasScript extends ReferenceAlias
; https://forums.nexusmods.com/index.php?/topic/8505728-best-way-to-track-actors-health/

  Float fTimer = -1.0
  Bool  bLoaded


; -- EVENTs --

EVENT OnCellLoad()
    objectReference oRef = self.GetReference()
    Debug.Trace(oRef+" OnCellLoad() - in " + oRef.GetParentCell())

    bLoaded = TRUE
    RegisterForSingleUpdateGameTime(0.5)
ENDEVENT


EVENT OnUnLoad()
    UnRegisterForUpdateGameTime()
    bLoaded = False
    fTimer = -1.0
ENDEVENT


EVENT OnUpdateGameTime()
    actor aRef = self.GetActorReference()
    float f
    float P

WHILE (bLoaded)
    IF ( f )
        IF (!aRef) || (fLastHP < 0.1)
            RETURN    ; - STOP -    invalid actor or save death range occured
        ENDIF
;        ----------------------
        IF aRef.IsDead() && (fLastHP > 0.5)        ; cheating detected
            myF_Reset(aRef, f)
        ENDIF
    ENDIF

    f = aRef.GetActorValue("Health")
    P = aRef.GetActorValuePercentage("Health")
    Utility.Wait(0.25)
ENDWHILE
ENDEVENT


;--------------------------------------
FUNCTION myF_Reset(Actor aRef, Float f)
;--------------------------------------
    float fx = aRef.GetPositionX()
    float fy = aRef.GetPositionY()    
    float fz = aRef.GetPositionZ()
    float aZ = aRef.GetAngleZ()

    aRef.Reset()
    Utility.Wait(0.1)

    aRef.SetPosition(fx,fy,fz)
    aRef.SetAngle(0.0, 0.0, aZ)
    aRef.EvaluatePackage()

    aRef.SetActorValue("Health", f)        ; give it back last health status
ENDFUNCTION



EVENT OnCombatStateChanged(Actor akTarget, Int aeCombatState)
; 0: Not in combat, 1: In combat, 2: Searching

IF (aeCombatState == 1)
    IF (akTarget == Game.GetPlayer())
        fTimer = Utility.GetCurrentRealTime()
    ENDIF
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (aeCombatState == 0)                       ; creature left the combat
    actor aRef = self.GetActorReference()

    IF aRef.IsUnconcious()
        aRef.SetUnconscious(False)            ; remove unconcious
    ENDIF

    aRef.SetRestrained(False)                 ; remove restrain, if any

    IF aRef.IsCommandedActor()                ; someone made the boss to a zombie
        aRef.Disable(TRUE)
        Utility.Wait(0.25)
        aRef.Enable(TRUE)
        aRef.EvaluatePackage()                ; remove the effect
    ENDIF

;;;    IF aRef.HasMagicEffectWithKeyword()    ; paralyze for example
;;;    ENDIF
ENDIF
ENDEVENT


EVENT OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
    myF_Show(0, akCaster as Actor)
ENDEVENT


EVENT OnHit(ObjectReference akAggressor, Form akSource, Projectile akProj, Bool b1, Bool b2, Bool b3, Bool b4)
    myF_Show(1, akAggressor as Actor)
ENDEVENT


EVENT OnEnterBleedOut()
    myF_Show(2)
ENDEVENT


EVENT OnDying(Actor akKiller)
    myF_Show(3, akKiller)
ENDEVENT


EVENT OnDeath(Actor akKiller)
    myF_Show(4, akKiller)
ENDEVENT


; -- FUNCTION --

;-----------------------------------
FUNCTION myF_Show(Int i, Actor aRef)
;-----------------------------------
IF (i == 0)
    Debug.Trace(" OnMagicEffect() - from " +aRef)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (i == 1)
    Debug.Trace(" OnHit() - from " +aRef)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (i == 2)
    Debug.Trace(" OnEnterBleedOut() - has been reached..")
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (i == 3)
    Debug.Trace(" OnDying() - killed by " +aRef)
    RETURN    ; - STOP -
ENDIF
;---------------------
IF (i == 4)
    Debug.Trace(" OnDeath() - killed by " +aRef)
;;;    RETURN    ; - STOP -
ENDIF
;---------------------
ENDFUNCTION

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

Hey ReDragon.


If something goes wrong with the "Ab Spell - Monitor Actor's Health" (that i don't think it will), this will be the second approach i'll take, but i'll not create a new or merge it into the current running quest, instead i'll incorporate this logic to the already running big "Master Controller" script.


This gives me the advantage to delete everything when the whole fight scene is finish and the final "Master Boss" is dead, plus in the end it occupies 0% space on the 'Save File'.


Also... the quest doesn't end here...


Thank you for your suggestion.

Link to comment
Share on other sites

@ foamyesque.
All actors will be essentials except the last one.
"I don't think it protects against oneshot kills"
Yeap..., this does concern me a lot !, and i'm still trying to find a simpler way to protect the "Essential Actors" from been killed by some 'Weapon' and 'Spell' mods out there that have this simple line.
akTarget.Kill()
You will probably say that this is not your problem but the player's issue, maybe... but having a mod like those will completely F*** the mod / quest.
My solution is to add to each essential actor's script a 'Fail Safe':
- "OnDying" event > check the "Master Controller" global just as a precaution in case it did trigger the transformation.
* Skyrim engine is not the most reliable.
- Then "OnDeath" > "Self.Resurrect()" > "SetGhost()" > "Activate Master Controller Script" to trigger the transformation.
* But this will look a little weird if you are staring at the dead actor.
Thank you both very much for your suggestions.

 

If the various stages are essential I don't think it's a problem. The script Kill() function will not actually kill them in those cases, just force bleedout; they'd have to be set to non-essential before that in order for it to actually kill them.

 

At that point, I say you've done your due diligence, yes. :p

Link to comment
Share on other sites

  • Recently Browsing   0 members

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