maxarturo Posted March 18, 2020 Share Posted March 18, 2020 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 More sharing options...
dylbill Posted March 18, 2020 Share Posted March 18, 2020 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 More sharing options...
foamyesque Posted March 19, 2020 Share Posted March 19, 2020 (edited) 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 March 19, 2020 by foamyesque Link to comment Share on other sites More sharing options...
maxarturo Posted March 19, 2020 Author Share Posted March 19, 2020 (edited) 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 March 19, 2020 by maxarturo Link to comment Share on other sites More sharing options...
dylbill Posted March 19, 2020 Share Posted March 19, 2020 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 More sharing options...
dylbill Posted March 19, 2020 Share Posted March 19, 2020 I forgot to add, if you're going to use the GetDead condition, make sure your magic effect has the No Death Dispel box checked. Link to comment Share on other sites More sharing options...
maxarturo Posted March 19, 2020 Author Share Posted March 19, 2020 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 More sharing options...
ReDragon2013 Posted March 19, 2020 Share Posted March 19, 2020 (edited) 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 March 19, 2020 by ReDragon2013 Link to comment Share on other sites More sharing options...
maxarturo Posted March 19, 2020 Author Share Posted March 19, 2020 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 More sharing options...
foamyesque Posted March 20, 2020 Share Posted March 20, 2020 @ 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 More sharing options...
Recommended Posts