Scriptname wizCombatDummyXP extends ObjectReference  

;Script based upon Training Dummies and Targets by B1gBadDaddy at http://skyrim.nexusmods.com/mods/23698 with permissions given on the website and via PM

;A script that allows the player to train skills on an object, for this mod a practice dummy and archery target.

Actor Property Player  Auto  ;player properties are quick than game.getplayer
GlobalVariable Property wizOptionTrainingSpeed Auto
EffectShader Property wizTargetShader Auto

State Busy

	;The state wasn't working without identical event place holders?!?

	Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)
		;Place holder for busy state
	endEvent

	Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		;Place holder for busy state
	endEvent

EndState


Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)

	GoToState("Busy")

	if akAggressor == Player

		;SKSE GetWeaponType Integers
		;0=Fists
		;1=Swords
		;2=Daggers
		;3=War Axes
		;4=Maces
		;5=Greatswords
		;6=Battleaxes AND Warhammers
		;7=Bows
		;9=Crossbows

		;Checking if the player's weapon is a bow or crossbow, and checking the distance they are from the target

;		debug.messagebox(akSource  + " - " + (akSource AS Weapon).GetWeaponType() + " " + (akAggressor as Actor).GetEquippedItemType(0))

		If akSource != None ;It's a weapon
	
			if (akAggressor == Player) && ((akSource AS Weapon).GetWeaponType() == 7 || (akSource AS Weapon).GetWeaponType() == 9) && (Player.GetDistance(Self) < 130) && (Player.GetDistance(Self) >= 0)
				;Place holder?
			elseif (akAggressor == Player) && ((akSource AS Weapon).GetWeaponType() == 7 || (akSource AS Weapon).GetWeaponType() == 9) && (Player.GetDistance(Self) < 512) && (Player.GetDistance(Self) >= 130)
			       Debug.Notification("Too close to work on your skill.")

			elseif (akAggressor == Player) && ((akSource AS Weapon).GetWeaponType() == 7 || (akSource AS Weapon).GetWeaponType() == 9) && (Player.GetDistance(Self) < 1024) && (Player.GetDistance(Self) >= 512)
				;Half as effective
	       		Game.AdvanceSkill("Marksman", (akSource AS Weapon).GetBaseDamage() / 2 * (wizOptionTrainingSpeed.getValueInt()/100))  ;3


			elseif (akAggressor == Player) && ((akSource AS Weapon).GetWeaponType() == 7 || (akSource AS Weapon).GetWeaponType() == 9) && (Player.GetDistance(Self) >= 1024) && (Player.GetDistance(Self) < 2048)
				;Normal effectiveness
	      			Game.AdvanceSkill("Marksman", (akSource AS Weapon).GetBaseDamage() * (wizOptionTrainingSpeed.getValueInt()/100))  ;4

			elseif (akAggressor == Player) && ((akSource AS Weapon).GetWeaponType() == 7 || (akSource AS Weapon).GetWeaponType() == 9) && (Player.GetDistance(Self) >= 2048)
				;1.5 times effective
       			Game.AdvanceSkill("Marksman", (akSource AS Weapon).GetBaseDamage() * 1.5 * (wizOptionTrainingSpeed.getValueInt()/100))  ;8
				Debug.Notification("Nice shot!")


			;One handed or two handed?
			elseif akAggressor == Player && (akSource AS Weapon).GetWeaponType() == 0 ;Fists
				Game.AdvanceSkill("OneHanded", 4 * (wizOptionTrainingSpeed.getValueInt()/100)) ;7=Iron Sword, 4=Iron Dagger

			elseif akAggressor == Player && ((akSource AS Weapon).GetWeaponType() == 1 || (akSource AS Weapon).GetWeaponType() == 2 || (akSource AS Weapon).GetWeaponType() == 3 || (akSource AS Weapon).GetWeaponType() == 4)
				Game.AdvanceSkill("OneHanded", (akSource AS Weapon).GetBaseDamage() * (wizOptionTrainingSpeed.getValueInt()/100)) ;3
		
			elseif akAggressor == Player && ((akSource AS Weapon).GetWeaponType() == 5 || (akSource AS Weapon).GetWeaponType() == 6 || (akSource AS Weapon).GetWeaponType() == 8)
				Game.AdvanceSkill("TwoHanded", (akSource AS Weapon).GetBaseDamage() * (wizOptionTrainingSpeed.getValueInt()/100)) ;3


			else
				; Do Nothing - weapon unknown
				debug.notification("You don't feel yourself getting better while training with this weapon")
			endif

		else ;Check for shield or torch bash
			if (akAggressor as Actor).GetEquippedItemType(0) == 10 ;Shield
				;A shield bash is 5 XP
				Game.AdvanceSkill("Block", 5.0 * (wizOptionTrainingSpeed.getValueInt()/100)) ;A shield bash is 5 XP

			elseif (akAggressor as Actor).GetEquippedItemType(0) == 11 ;Torch
				;A torch bash adds 3 to destruction oddly enough
				game.advanceSkill("Destruction", 3.0 * (wizOptionTrainingSpeed.getValueInt()/100))
				debug.notification("There must be a more effective fire damage")

			endIf
		

		endIf

	endIf

	GoToState("")

endevent


;Now to check if the player casts a Destruction Spell

Event OnMagicEffectApply(ObjectReference akCaster, MagicEffect akEffect)

	GoToState("Busy")

	if akCaster == Player
		spell spellCast
		float duration = 0.0
		;Need to get the spell associated with the magic effect
		spell EquippedSpell = (akCaster AS actor).GetEquippedSpell(1) ;Right Hand First

		;Do we have a spell equipped on right hand?
		if EquippedSpell != None
			;Only check first effect - secondary effects are pointless
			MagicEffect effect = EquippedSpell.GetNthEffectMagicEffect(0)
			if effect == akEffect
				spellCast = EquippedSpell
				duration = EquippedSpell.GetNthEffectDuration(0) as float
			endIf
		endIf

		if spellCast == None ;KeepLooking
			EquippedSpell = (akCaster AS actor).GetEquippedSpell(0) ;Left Hand

			if EquippedSpell != None
				;Only check first effect - secondary effects are pointless
				MagicEffect effect = EquippedSpell.GetNthEffectMagicEffect(0)
				if effect == akEffect
					spellCast = EquippedSpell
					duration = EquippedSpell.GetNthEffectDuration(0) as float
				endIf
			endIf

		endIf

		int SpellCost
		;Did we find the spell in either hand?
		if spellCast != None
;			SpellCost = spellCast.getEffectiveMagickaCost(akCaster as actor) 
			SpellCost = spellCast.GetMagickaCost()
		else
			;Couldn't find the spell - most likely caused by a scroll
			debug.notification("I must not have been concentrating. I don't know how I just did that.")
			GoToState("")
			return ;exit
		endIf

;		debug.messagebox((akCaster as Actor).GetEquippedItemType(0) + " " + spellCast + " - " + spellCast.GetMagickaCost() + " - " + akEffect.GetAssociatedSkill() + " - " + EquippedSpell.GetNthEffectDuration(0) + " " + duration)

		if duration <= 1 
			duration = 0.5
		else
			;Play a shader to alert that dummy isn't available!
			wizTargetShader.Play(self)
		endIf

		if duration > 300 ;Limit timeout to five minutes
			duration = 300
		endIf

		;This wait makes range spells as effective as "concentration spells" like flames
		utility.wait(duration) ;Seemed to match with test results better

		if duration > 1
			wizTargetShader.Stop(self)
		endIf		

		;Advance skill after duration!
		game.advanceSkill(akEffect.GetAssociatedSkill(), SpellCost * (wizOptionTrainingSpeed.getValueInt()/100))

	endIf

	GoToState("")

EndEvent
