Scriptname SuH_SuQuest extends Quest

SuH_Fun property _f auto
DialogueFollowerScript Property DialogueFollower Auto
Quest Property pDialogueFollower  Auto

Actor Property PlayerRef auto

int drainMessage
int desireDelay
int sdDelay
int petDelay
int sexstackDelay
int spermstackDelay
int milkstackDelay
int savingessenseDelay
int formalbeautyDelay
int violenceDelay
int masochistDelay
int regalglowarmor
bool nowincombat

Event OnInit()
	PlayerRef.AddSpell(_f.SuH_dyna_player, FALSE) ; Add dynamic player script
	RegisterForSingleUpdate(5.0) ; Tick in 5 seconds, giving time to initialize other scripts
endEvent

Event OnUpdate()
	dynamicScriptApply()
	deathOverrideCalc()
	desireCalc()
	regalGlowCalc()
	soulPetCalc()
	;stackDecay()
	savingEssenseCalc()
	violenceCalc()
	masochistCalc()
	overcapCalc()
	if playerRef.IsInCombat()
		if nowincombat == false
			nowincombat = true
			formalBeautyCalc()
		endIf
	else
		nowincombat = false
	endIf
	
	if _f.SuH_SETadvancedchecking.GetValue()
		disableRecoveryCalc()
	endIf
	
	;if _f.SuH_SETrecoverbleed.GetValue()
	;	If PlayerRef.IsBleedingOut() == True
	;		PlayerRef.RestoreAV("Health", 100)
	;	endIf
	;endIf
	RegisterForSingleUpdate(1.0) ; Tick in 1 seconds
endEvent

;Dynamics
function dynamicScriptApply()
	If PlayerRef.HasSpell(_f.SuH_dyna_ability) ; If dynamic script is applying
		PlayerRef.RemoveSpell(_f.SuH_dyna_ability) ; Remove dynamic run script
	else ; if dynamic script is not applying
		PlayerRef.AddSpell(_f.SuH_dyna_ability, FALSE) ; AddSpell dynamic run script
	endIf
endFunction

;Death Override Calculations
function deathOverrideCalc()
	if _f.SuH_CHKsdinact.GetValue() == 4
		_f.SDrespawn()
	else
		if _f.SuH_CHKsdinact.GetValue() || PlayerRef.IsBleedingOut() == True
			if _f.SuH_SETspecialdeath.GetValue()
				PlayerRef.SetNoBleedoutRecovery(true)
				if _f.SuH_CHKcsprocessing.GetValue()
					_f.SuH_CHKsdinact.SetValue(1)
				else
					_f.SuH_CHKsdinact.SetValue(2)
				endIf
			else
				PlayerRef.SetNoBleedoutRecovery(false)
			endIf
		endIf
		if _f.SuH_CHKsdinact.GetValue() == 2
			sdDelay += 1
			if sdDelay >= _f.SuH_SETcsbleedoutdelay.GetValue()
				_f.SDrespawn()
				sdDelay = 0
			endIf
		else
			sdDelay = 0
		endIf
	endIf
	; Place return point when leaving/entering interiors
	if playerRef.GetWorldSpace() != _f.SuH_worldspace
		if playerRef.GetWorldSpace() != _f.SuH_sd_returnpointcell.GetWorldSpace()
			_f.SuH_sd_returnpointcell.MoveTo(PlayerRef)
		endIf
	endIf
endFunction

;Desire Calculations
function desireCalc()
	desireDelay += 1
	if desireDelay > 4
		float desireV = (_f.SuH_PCSdesiregain.GetValue()) + _f.SuH_PCSdesire.GetValue()
		_f.SuH_PCSdesire.SetValue(desireV)
		if desireV >= _f.SuH_SETdesirecap.GetValue() && _f.SuH_SETdesiredrain.GetValue()
			if drainMessage == 0
				debug.notification("Succubus Heart : Desire has begun to drain status!")
				drainMessage = 1
			endIf
			float h = PlayerRef.GetBaseActorValue("health")
			float m = PlayerRef.GetBaseActorValue("magicka")
			float s = PlayerRef.GetBaseActorValue("stamina")
			float x = 0.0
			if h > 10.0
				PlayerRef.SetActorValue("health", h - 1.0)
				x += 1.0
			endIf
			if m > 10.0
				PlayerRef.SetActorValue("magicka", m - 1.0)
				x += 1.0
			endIf
			if s > 10.0
				PlayerRef.SetActorValue("stamina", s - 1.0)
				x += 1.0
			endIf
			float y = _f.SuH_PCSforce.GetValue()
			_f.SuH_PCSforce.SetValue(y+x)
		endIf
		desireDelay = 0
	endIf
endFunction

;Regal Glow Calculations
function regalGlowCalc()
	int RGarmor = _f.SuH_rank_regalglow.GetValue() as int
	if RGarmor > 0
		int bodySlot = 0x00000004
		Armor bodyArmor = playerRef.GetWornForm(bodySlot) as Armor
		;if bodyArmor == _f.SuH_armor_regalglow ;Regal Glow Active Already
		if (bodyArmor) ;Body Armor Found
			regalglowarmor = 0
			playerRef.UnequipItem(_f.SuH_armor_regalglow, abSilent=true)
		elseif playerRef.IsEquipped(_f.SuH_armor_regalglow) ;Regal Glow Active Already
			if RGarmor != regalglowarmor
				bodyArmor.SetArmorRating( Math.Floor(1 + (RGarmor * (_f.SuH_PCSmpoint.GetValue() * 0.05))) )
				playerRef.UnequipItem(_f.SuH_armor_regalglow, abSilent=true)
				playerRef.equipitem(_f.SuH_armor_regalglow, false, true)
				regalglowarmor = RGarmor
			endIf
		else ;no body armor
			playerRef.equipitem(_f.SuH_armor_regalglow, false, true)
			_f.SuH_armor_regalglow.SetArmorRating(RGarmor)
			playerRef.UnequipItem(_f.SuH_armor_regalglow, abSilent=true)
			playerRef.equipitem(_f.SuH_armor_regalglow, false, true)
			regalglowarmor = RGarmor
		endIf
	endIf
endFunction

;Formal Beauty Calculations
	; Stack Effects
		; Sex Stacks = Health
		; Sperm Stacks = Magicka
		; Milk Stacks = Stamina
function formalBeautyCalc()
	int fb = _f.SuH_rank_formalbeauty.GetValue() as int
	if fb > 0
		int d = _f.SuH_PCSdpoint.GetValue() as int
		float recovery = 1 + (fb * (d * 0.05))
		float x = PlayerRef.GetBaseActorValue("health")
		float y = PlayerRef.GetActorValue("health")
		if x > y
			x -= y
			int consume = Math.Ceiling(x / recovery)
			if consume > _f.SuH_PCSstacksex.GetValue()
				if _f.SuH_PCSstacksex.GetValue() > 0
					if consume > _f.SuH_PCSstackmaxsex.GetValue()
						consume = _f.SuH_PCSstackmaxsex.GetValue() as int
					else
						consume = _f.SuH_PCSstacksex.GetValue() as int
					endIf
				else
					consume = 0
				endIf
			endIf
			if consume != 0
				playerRef.RestoreActorValue("health", recovery * consume)
				consume -= _f.SuH_rank_formalbeauty2.GetValue() as int
				if consume < 1
					consume = 1
				endIf
				_f.SuH_PCSstacksex.SetValue( Math.Floor(_f.SuH_PCSstacksex.GetValue() - consume) )
			endIf
		endIf
		x = PlayerRef.GetBaseActorValue("magicka")
		y = PlayerRef.GetActorValue("magicka")
		if x > y
			x -= y
			int consume = Math.Ceiling(x / recovery)
			if consume > _f.SuH_PCSstacksperm.GetValue()
				if _f.SuH_PCSstacksperm.GetValue() > 0
					if consume > _f.SuH_PCSstackmaxsperm.GetValue()
						consume = _f.SuH_PCSstackmaxsperm.GetValue() as int
					else
						consume = _f.SuH_PCSstacksperm.GetValue() as int
					endIf
				else
					consume = 0
				endIf
			endIf
			if consume != 0
				playerRef.RestoreActorValue("magicka", recovery * consume)
				consume -= _f.SuH_rank_formalbeauty2.GetValue() as int
				if consume < 1
					consume = 1
				endIf
				_f.SuH_PCSstacksperm.SetValue( Math.Floor(_f.SuH_PCSstacksperm.GetValue() - consume) )
			endIf
		endIf
		x = PlayerRef.GetBaseActorValue("stamina")
		y = PlayerRef.GetActorValue("stamina")
		if x > y
			x -= y
			int consume = Math.Ceiling(x / recovery)
			if consume > _f.SuH_PCSstackmilk.GetValue()
				if _f.SuH_PCSstackmilk.GetValue() > 0
					if consume > _f.SuH_PCSstackmaxmilk.GetValue()
						consume = _f.SuH_PCSstackmaxmilk.GetValue() as int
					else
						consume = _f.SuH_PCSstackmilk.GetValue() as int
					endIf
				else
					consume = 0
				endIf
			endIf
			if consume != 0
				playerRef.RestoreActorValue("stamina", recovery * consume)
				consume -= _f.SuH_rank_formalbeauty2.GetValue() as int
				if consume < 1
					consume = 1
				endIf
				_f.SuH_PCSstackmilk.SetValue( Math.Floor(_f.SuH_PCSstackmilk.GetValue() - consume) )
			endIf
		endIf
	endIf
endFunction

;Pet Calculations
function soulPetCalc()
	petDelay += 1
	if petDelay > 4
		_f.SoulPetPosition()
		petDelay = 0
	endIf
endFunction

;Stack Decay Function
; function stackDecay()
	; sexstackDelay += 1
	; if sexstackDelay > 299
		; int cstack = _f.SuH_PCSstacksex.GetValue() as int
		; if cstack > 0
			; _f.SuH_PCSstacksex.SetValue(cstack - 1)
		; endIf
		; sexstackDelay = 0
	; endIf
	; spermstackDelay += 1
	; if spermstackDelay > 59
		; int cstack = _f.SuH_PCSstacksperm.GetValue() as int
		; if cstack > 0
			; _f.SuH_PCSstacksperm.SetValue(cstack - 1)
		; endIf
		; spermstackDelay = 0
	; endIf
	; milkstackDelay += 1
	; if milkstackDelay > 59
		; int cstack = _f.SuH_PCSstackmilk.GetValue() as int
		; if cstack > 0
			; _f.SuH_PCSstackmilk.SetValue(cstack - 1)
		; endIf
		; milkstackDelay = 0
	; endIf
; endFunction

;Saving Essence Function
function savingEssenseCalc()
	int se = _f.SuH_rank_savingessenceCD.GetValue() as int
	if se > 0
		savingessenseDelay += 1
		int ser2 = Math.Floor(1200 - (_f.SuH_rank_savingessence2.GetValue()*60 ))
		if savingessenseDelay > ser2
			_f.SuH_rank_savingessenceCD.SetValue(0)
			debug.Notification("Saving Essence can activate again.")
			savingessenseDelay = 0
		endIf
	else
		savingessenseDelay = 0
	endIf
endFunction

;Violence Function
function violenceCalc()
	int se = _f.SuH_rank_violenceCD.GetValue() as int
	if se > 0
		violenceDelay += 1
		if violenceDelay > 1
			_f.SuH_rank_violenceCD.SetValue(0)
			violenceDelay = 0
		endIf
	else
		violenceDelay = 0
	endIf
endFunction

;Masochist Function
function masochistCalc()
	int se = _f.SuH_rank_masochistCD.GetValue() as int
	if se > 0
		masochistDelay += 1
		if masochistDelay > 1
			_f.SuH_rank_masochistCD.SetValue(0)
			masochistDelay = 0
		endif
	else
		masochistDelay = 0
	endif
endFunction

;Disable Recovery Function
Function disableRecoveryCalc()
	if _f.SuH_SETdisablehealthrecovery.GetValue() > 0.0
		playerRef.SetActorValue("HealRate", 0)
	endIf
	if _f.SuH_SETdisablemagickarecovery.GetValue() > 0.0
		playerRef.SetActorValue("MagickaRate", 0)
	endIf
	if _f.SuH_SETdisablestaminarecovery.GetValue() > 0.0
		playerRef.SetActorValue("StaminaRate", 0)
	endIf
endFunction

;Over Status Cap Function
Function overcapCalc()
	int plvl = playerRef.GetLevel() as int
	int x = Math.Floor((_f.SuH_PCScaphealth.GetValue() + (plvl * 4)) - _f.SuH_PCScaphealthdown.GetValue())
	if playerRef.GetBaseActorValue("Health") > x
		playerRef.SetActorValue("health", playerRef.GetBaseActorValue("health") - 1)
	endIf
	x = Math.Floor((_f.SuH_PCScapmagicka.GetValue() + (plvl * 3)) - _f.SuH_PCScapmagickadown.GetValue())
	if playerRef.GetBaseActorValue("magicka") > x
		playerRef.SetActorValue("magicka", playerRef.GetBaseActorValue("magicka") - 1)
	endIf
	x = Math.Floor((_f.SuH_PCScapstamina.GetValue() + (plvl * 3)) - _f.SuH_PCScapstaminadown.GetValue())
	if playerRef.GetBaseActorValue("Stamina") > x
		playerRef.SetActorValue("Stamina", playerRef.GetBaseActorValue("Stamina") - 1)
	endIf
endFunction