ScriptName magicSoulTrapFXScript extends ActiveMagicEffect
{Scripted effect for the Soul Trap Visual FX}

import debug


;======================================================================================;
;  PROPERTIES  /
;=============/
ImageSpaceModifier property TrapImod auto
{IsMod applied when we trap a soul}
sound property TrapSoundFX auto ; create a sound property we'll point to in the editor
{Sound played when we trap a soul}
VisualEffect property TargetVFX auto
{Visual Effect on Target aiming at Caster}
VisualEffect property CasterVFX auto
{Visual Effect on Caster aming at Target}
EffectShader property CasterFXS auto
{Effect Shader on Caster during Soul trap}
EffectShader property TargetFXS auto
{Effect Shader on Target during Soul trap}
bool property bIsEnchantmentEffect = false auto
{Set this to true if this soul trap is on a weapon enchantment or a spell that can do damage to deal with a fringe case}

;======================================================================================;
;  VARIABLES   /
;=============/
; objectreference playerref
bool DeadAlready = FALSE
bool bUseWait = True
;======================================================================================;
;  EVENTS      /
;=============/


Event OnEffectStart(Actor akTarget, Actor akCaster)
	victim = akTarget
	caster = akCaster
	
	
	if(victim.HasKeyword(ActorTypeNPC))
		victimIsNPC = true
	endif
  
  
	if bIsEnchantmentEffect == False
		DeadAlready = Victim.IsDead()
	endif
	
	Countdown()
EndEvent


Event OnEffectFinish(Actor akTarget, Actor akCaster)
	Await()
	if victim
	
		; initiate lock to prevent multiple soul traps from processing at the same time:
		if(SoulTrapController != None)
			while(!SoulTrapController.SecurePermission(caster))
				Utility.Wait(0.1)
			endWhile
		endif
		
		
		if(!deadAlready && victim.IsDead() && victim.GetActorValue("PerceptionCondition") != 0)
			bool soulTrapped = false
			String soulType = "None"
			;if victim is not a humanoid, remove Black Soul Gems from inventory before trap begins:
			if(!victimIsNPC)
				
				numBlack = caster.GetItemCount(SoulGemBlack)
				caster.RemoveItem(SoulGemBlack, numBlack, true)
				
				numPetty = caster.GetItemCount(SoulGemPetty)
				numLesser = caster.GetItemCount(SoulGemLesser)
				numCommon = caster.GetItemCount(SoulGemCommon)
				numGreater = caster.GetItemCount(SoulGemGreater)
				numGrand = caster.GetItemCount(SoulGemGrand)
		
				int targetLevel = victim.GetLevel()
				if(targetLevel < Game.GetGameSettingInt("iLesserSoulActorLevel")) ;soul is petty
					soulType="Petty"
					if(numPetty > 0)
						caster.RemoveItem(SoulGemPetty, 1, true)
						caster.AddItem(SoulGemPettyFilled, 1, true)
						soulTrapped = true
					elseif (numLesser > 0)
						caster.RemoveItem(SoulGemLesser, 1, true)
						caster.AddItem(_00E_SoulGemLesserFilledPetty, 1, true)
						soulTrapped = true
					elseif(numCommon > 0)
						caster.RemoveItem(SoulGemCommon, 1, true)
						caster.AddItem(_00E_SoulGemCommonFilledPetty, 1, true)
						soulTrapped = true
					elseif(numGreater > 0)
						caster.RemoveItem(SoulGemGreater, 1, true)
						caster.AddItem(_00E_SoulGemGreaterFilledPetty, 1, true)
						soulTrapped = true
					elseif(numGrand > 0)
					caster.RemoveItem(SoulGemGrand, 1, true)
					caster.AddItem(_00E_SoulGemGrandFilledPetty, 1, true)
					soulTrapped = true
					endif
					
				elseif(targetLevel < Game.GetGameSettingInt("iCommonSoulActorLevel"));soul is lesser
					soulType="Lesser"
					if(numLesser > 0)
						caster.RemoveItem(SoulGemLesser, 1, true)
						caster.AddItem(SoulGemLesserFilled, 1, true)
						soulTrapped = true
					elseif (numCommon > 0)
						caster.RemoveItem(SoulGemCommon, 1, true)
						caster.AddItem(_00E_SoulGemCommonFilledLesser, 1, true)
						soulTrapped = true
					elseif(numGreater > 0)
						caster.RemoveItem(SoulGemGreater, 1, true)
						caster.AddItem(_00E_SoulGemGreaterFilledLesser, 1, true)
						soulTrapped = true
					elseif(numGrand > 0)
						caster.RemoveItem(SoulGemGrand, 1, true)
						caster.AddItem(_00E_SoulGemGrandFilledLesser, 1, true)
						soulTrapped = true
					endif
					
				elseif(targetLevel < Game.GetGameSettingInt("iGreaterSoulActorLevel")) ;soul is common
					soulType="Common"
					if(numCommon > 0)
						caster.RemoveItem(SoulGemCommon, 1, true)
						caster.AddItem(SoulGemCommonFilled, 1, true)
						soulTrapped = true
					elseif(numGreater > 0)
						caster.RemoveItem(SoulGemGreater, 1, true)
						caster.AddItem(_00E_SoulGemGreaterFilledCommon, 1, true)
						soulTrapped = true
					elseif(numGrand > 0)
						caster.RemoveItem(SoulGemGrand, 1, true)
						caster.AddItem(_00E_SoulGemGrandFilledCommon, 1, true)
						soulTrapped = true
					endif
					
				elseif(targetLevel < Game.GetGameSettingInt("iGrandSoulActorLevel")) ;soul is greater
					soulType="Greater"
					if(numGreater > 0)
						caster.RemoveItem(SoulGemGreater, 1, true)
						caster.AddItem(SoulGemGreaterFilled, 1, true)
						soulTrapped = true
					elseif(numGrand > 0)
						caster.RemoveItem(SoulGemGrand, 1, true)
						caster.AddItem(_00E_SoulGemGrandFilledGreater, 1, true)
						soulTrapped = true
					endif
					
				else 
					soulType="Grand"
					if(numGrand > 0)
					caster.RemoveItem(SoulGemGrand, 1, true)
					caster.AddItem(SoulGemGrandFilled, 1, true)
					soulTrapped = true
					endif
				endif
			
		
		
		
			; return Black Soul Gems:
			caster.AddItem(SoulGemBlack, numBlack, true)
			else
			soulTrapped = akCaster.TrapSoul(victim)
			endif
		
			; begin vanilla Soul Trap FX finale:
			if(soulTrapped == true)
				victim.SetActorValue("PerceptionCondition", 0)
				PlayEffects(caster, victim)
				if soulType=="Petty"
					Debug.Notification(_00E_SoulPetty.GetName()+" "+_00E_SuccessfulTrapping.GetName())
					SoulsCaught.SetValueInt(SoulsCaught.GetValueInt()+1)
				elseif soulType=="Lesser"
					Debug.Notification(_00E_SoulLesser.GetName()+" "+_00E_SuccessfulTrapping.GetName())
					SoulsCaught.SetValueInt(SoulsCaught.GetValueInt()+1)
				elseif soulType=="Common"
					Debug.Notification(_00E_SoulCommon.GetName()+" "+_00E_SuccessfulTrapping.GetName())
					SoulsCaught.SetValueInt(SoulsCaught.GetValueInt()+1)
				elseif soulType =="Greater"
					Debug.Notification(_00E_SoulGreater.GetName()+" "+_00E_SuccessfulTrapping.GetName())
					SoulsCaught.SetValueInt(SoulsCaught.GetValueInt()+1)
				elseif soulType =="Grand"
					Debug.Notification(_00E_SoulGrand.GetName()+" "+_00E_SuccessfulTrapping.GetName())
					SoulsCaught.SetValueInt(SoulsCaught.GetValueInt()+1)
				else
					_00E_SoulHuman.show()
				endif
			elseif (!victimIsNPC)
				_00E_FailedTrapping.Show()
				
			
			endif
		endif
		
		; release lock
		SoulTrapController.ReleasePermission(caster)
	endif
endEvent



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Functions;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Function PlayEffects(Actor akCaster, Actor akVictim)
  TrapSoundFX.Play(akCaster)              ; Play TrapSoundFX sound from player
  TrapImod.Apply()                        ; Apply isMod at full strength
  
  TargetVFX.Play(akVictim, 4.7, akCaster) ; Play TargetVFX and aim them at the player
  CasterVFX.Play(akCaster, 5.9, akVictim)
  
  TargetFXS.Play(akVictim, 2)             ; Play effect shaders
  CasterFXS.Play(akCaster, 3)
EndFunction

Function Countdown()
  latch -= 1
EndFunction

Function Await(int count = 0)
  while(latch > count)
    Utility.Wait(0.1)
  endwhile
EndFunction


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Properties + Variables;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

bool victimIsNPC

GlobalVariable Property SoulsCaught Auto

Actor caster
Actor victim

int latch = 1
int numPetty
int numLesser
int numCommon
int numGreater
int numGrand
int numBlack

_00E_SoulTrapController Property SoulTrapController Auto


Message Property _00E_FailedTrapping Auto
Message Property _00E_SuccessfulTrapping Auto

Message Property _00E_SoulPetty Auto
Message Property _00E_SoulLesser Auto
Message Property _00E_SoulCommon Auto
Message Property _00E_SoulGreater Auto
Message Property _00E_SoulGrand Auto
Message Property _00E_SoulHuman Auto

Actor Property PlayerREF Auto

Keyword Property ActorTypeNPC Auto

SoulGem Property SoulGemPetty Auto
SoulGem Property SoulGemPettyFilled Auto

SoulGem Property SoulGemLesser Auto
SoulGem Property SoulGemLesserFilled Auto
SoulGem Property _00E_SoulGemLesserFilledPetty Auto

SoulGem Property SoulGemCommon Auto
SoulGem Property SoulGemCommonFilled Auto
SoulGem Property _00E_SoulGemCommonFilledPetty Auto
SoulGem Property _00E_SoulGemCommonFilledLesser Auto

SoulGem Property SoulGemGreater Auto
SoulGem Property SoulGemGreaterFilled Auto
SoulGem Property _00E_SoulGemGreaterFilledPetty Auto
SoulGem Property _00E_SoulGemGreaterFilledLesser Auto
SoulGem Property _00E_SoulGemGreaterFilledCommon Auto

SoulGem Property SoulGemGrand Auto
SoulGem Property SoulGemGrandFilled Auto
SoulGem Property _00E_SoulGemGrandFilledPetty Auto
SoulGem Property _00E_SoulGemGrandFilledLesser Auto
SoulGem Property _00E_SoulGemGrandFilledCommon Auto
SoulGem Property _00E_SoulGemGrandFilledGreater Auto

SoulGem Property SoulGemBlack Auto