227 lines
6.4 KiB
Plaintext
227 lines
6.4 KiB
Plaintext
Scriptname WispActorScript extends ActiveMagicEffect
|
|
{Abilities and FX for Wisp/Glimmerwitch}
|
|
;======================================================================================;
|
|
; IMPORTS /
|
|
;=============/
|
|
import utility
|
|
import form
|
|
import debug
|
|
;======================================================================================;
|
|
; PROPERTIES /
|
|
;=============/
|
|
keyword property wispChild01 auto
|
|
keyword property wispChild02 auto
|
|
keyword property wispChild03 auto
|
|
|
|
spell property Phase1ConcSpell auto
|
|
{A long range concentration spell for phase #1}
|
|
spell property Phase2ConcSpell auto
|
|
{Shorter range spell for phase #2}
|
|
|
|
actorBase property encWispShade auto
|
|
|
|
VisualEffect Property WispFXAttachEffect Auto
|
|
explosion property ExplosionIllusionLight01 auto
|
|
Activator property AshPileObject auto
|
|
{The object we use as a pile.}
|
|
|
|
float property PhaseThreeHPPercent auto
|
|
{At what % of HP should I spawn my dopplegangers?. DEFAULT: 0.2}
|
|
|
|
|
|
;======================================================================================;
|
|
; VARIABLES /
|
|
;=============/
|
|
;USKP 2.0.4 - All of these are Actors, so let's just dispense with all the type casting that's going on down below.
|
|
Actor selfRef
|
|
|
|
; let's refer to the witchlights as "orbs" to avoid confusion.
|
|
Actor orb01
|
|
Actor orb02
|
|
Actor orb03
|
|
|
|
Actor Shade01
|
|
Actor Shade02
|
|
|
|
;track number of living orb babies
|
|
int liveLights = 3
|
|
|
|
; have my FX been attached?
|
|
bool bFX = FALSE
|
|
;======================================================================================;
|
|
; EVENTS /
|
|
;=============/
|
|
EVENT onLoad()
|
|
;trace("Wisp: Has Loaded 3D ("+selfRef+")")
|
|
EVPall()
|
|
endEVENT
|
|
|
|
EVENT OnEffectStart(Actor Target, Actor Caster)
|
|
;trace("AbWisp Effect Start on: "+SelfRef+"")
|
|
selfRef = caster
|
|
|
|
;USKP 2.0.1 - Stop this from attaching to the player.
|
|
if selfRef == Game.GetPlayer()
|
|
Dispel()
|
|
Return
|
|
EndIf
|
|
|
|
if selfref.getLinkedRef() == NONE
|
|
; only attack FX at this point if I am not in an ambush link
|
|
if (WispFXAttachEffect != NONE)
|
|
WispFXAttachEffect.Play(selfRef, -1)
|
|
bFX = TRUE
|
|
Endif
|
|
endif
|
|
|
|
;USKP 2.0.4 - These should be cast as Actors
|
|
orb01 = selfRef.getLinkedRef(WispChild01) as Actor
|
|
orb02 = selfRef.getLinkedRef(WispChild02) as Actor
|
|
orb03 = selfRef.getLinkedRef(WispChild03) as Actor
|
|
EVPall()
|
|
|
|
if phaseThreeHPpercent > 1.0
|
|
; if we passed a high value, the user probably meant a whole number percentage like 30%
|
|
phaseThreeHPpercent = phaseThreeHPpercent/100
|
|
endif
|
|
ENDEVENT
|
|
|
|
EVENT onGetup(ObjectReference akFurniture)
|
|
;USKP 2.0.1 - Stop this from attaching to the player.
|
|
if( selfRef == Game.GetPlayer() )
|
|
Return
|
|
EndIf
|
|
|
|
if akFurniture == selfRef.getLinkedRef() && bFX == FALSE
|
|
; if I was in a furniture ambush, then add my FX when I leave it
|
|
WispFXAttachEffect.Play(selfRef, -1)
|
|
bFX = TRUE
|
|
endif
|
|
endEVENT
|
|
|
|
Event OnCombatStateChanged(Actor victim, int aeCombatState)
|
|
if aeCombatState != 0 ; 0 means not in combat, so non-zero means we entered combat
|
|
; debug.trace("Wisp began combat with "+victim+" ("+self+")")
|
|
if aeCombatState == 1
|
|
;USKP 2.0.6 - Dead actors throw errors when asked to start combat.
|
|
If orb01 && orb01.IsDead() == False
|
|
orb01.startCombat(victim)
|
|
Endif
|
|
If orb02 && orb02.IsDead() == False
|
|
orb02.startCombat(victim)
|
|
Endif
|
|
If orb03 && orb03.IsDead() == False
|
|
orb03.startCombat(victim)
|
|
Endif
|
|
; Start listening for critically low HP
|
|
registerforSingleupdate(1.0)
|
|
endif
|
|
endif
|
|
endEVENT
|
|
|
|
EVENT onActivate(objectReference actronaut)
|
|
; debug.trace("Wisp Activated")
|
|
if actronaut == orb01 || actronaut == orb02 || actronaut == orb03
|
|
utility.wait(0.1)
|
|
; debug.trace("Actronaut was one of my orbs")
|
|
liveLights -= 1
|
|
; debug.trace("Livelights = "+livelights)
|
|
if liveLights <= 0
|
|
; debug.trace("All child lights dead for "+selfref)
|
|
;Variable07 sets up the berserk package/combat style
|
|
selfRef.setActorValue("Variable07",1)
|
|
;also "eliminate" her ability to cast spells - take all her magicka away.
|
|
;trace("WISPS: move to combat phase 2")
|
|
; Take away her magicka (she'll regen) and shuffle her spell set
|
|
selfRef.damageActorValue("Magicka", -(selfRef.getActorValue("Magicka")))
|
|
selfRef.removeSpell(Phase1ConcSpell)
|
|
selfRef.addSpell(Phase2ConcSpell)
|
|
endif
|
|
endif
|
|
endEVENT
|
|
|
|
EVENT onUpdate()
|
|
; Check HP for Phase 3 Combat - Last ditch doppleganger attack!
|
|
if selfRef.getActorValuePercentage("health") > phaseThreeHPpercent
|
|
; HP still high, so hold off.
|
|
;utility.wait(0.5)
|
|
RegisterforSingleUpdate(0.5)
|
|
else
|
|
; create my dopplegangers and unregister for update
|
|
If EncWispShade
|
|
Shade01 = selfRef.placeAtMe(EncWispShade) as Actor
|
|
Shade02 = selfRef.placeAtMe(EncWispShade) as Actor
|
|
EndIf
|
|
|
|
;Set AV06 to 1 as a flag for being in this state (used in Frostmere Crypt)
|
|
selfRef.SetAV("Variable06", 1)
|
|
;/ selfRef.setActorValue("Variable07",1)
|
|
selfRef.damageActorValue("Magicka", -(selfRef.getActorValue("Magicka")))
|
|
selfRef.setAV("Magicka", 0.0)
|
|
Debug.Notification("Set variables!") /;
|
|
|
|
; Dump the orbs.
|
|
If (orb01 != NONE)
|
|
orb01.kill()
|
|
Endif
|
|
If (Orb02 != NONE)
|
|
orb02.kill()
|
|
Endif
|
|
If (Orb03 != NONE)
|
|
orb03.kill()
|
|
Endif
|
|
; restore her longer-range spell
|
|
If orb01 || orb02 || orb03
|
|
selfRef.addSpell(Phase1ConcSpell)
|
|
EndIf
|
|
endif
|
|
endEVENT
|
|
|
|
EVENT OnDying(Actor akKiller)
|
|
; Effects automatically finish onDeath so use this EVENT hook instead
|
|
;trace("Actor has died: "+selfref)
|
|
selfRef.SetCriticalStage(selfRef.CritStage_DisintegrateStart)
|
|
WispFXAttachEffect.Stop(selfRef)
|
|
utility.wait(0.90)
|
|
selfRef.placeatme(ExplosionIllusionLight01)
|
|
selfRef.AttachAshPile(AshPileObject)
|
|
; pause a second before killing inheritors - I've seen massive damage skip over this
|
|
utility.wait(0.5)
|
|
If (orb01 != NONE)
|
|
orb01.kill()
|
|
Endif
|
|
If (Orb02 != NONE)
|
|
orb02.kill()
|
|
Endif
|
|
If (Orb03 != NONE)
|
|
orb03.kill()
|
|
Endif
|
|
If (Shade01 != NONE)
|
|
Shade01.kill()
|
|
Endif
|
|
If (Shade02 != NONE)
|
|
Shade02.kill()
|
|
Endif
|
|
selfRef.SetCriticalStage(selfRef.CritStage_DisintegrateEnd)
|
|
ENDEVENT
|
|
|
|
|
|
FUNCTION EVPall()
|
|
;trace("Sending EVP to self and witchlight children ("+selfRef+")")
|
|
;trace("Witchlights are the Following:")
|
|
;trace("--------------------------------")
|
|
;trace(orb01)
|
|
;trace(orb02)
|
|
;trace(orb03)
|
|
;trace("--------------------------------")
|
|
If (orb01 != NONE)
|
|
orb01.evaluatePackage()
|
|
Endif
|
|
If (Orb02 != NONE)
|
|
orb02.evaluatePackage()
|
|
Endif
|
|
If (Orb03 != NONE)
|
|
orb03.evaluatePackage()
|
|
Endif
|
|
endFUNCTION
|
|
|