Scriptname SuH_SuQuest extends Quest

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

ObjectReference Property SuH_sd_returnpointcell Auto 
WorldSpace property SuH_worldspace auto

GlobalVariable Property SuH_PCSdesire auto
GlobalVariable Property SuH_PCSforce auto
GlobalVariable Property SuH_PCSdesiregain auto
GlobalVariable Property SuH_PCSstacksex auto
GlobalVariable Property SuH_PCSstacksperm auto
GlobalVariable Property SuH_PCSstackmilk auto
GlobalVariable Property SuH_PCSstackmaxsex auto
GlobalVariable Property SuH_PCSstackmaxsperm auto
GlobalVariable Property SuH_PCSstackmaxmilk auto
GlobalVariable Property SuH_PCSbdsmspecial auto
GlobalVariable Property SuH_SETdesiredrain auto
GlobalVariable Property SuH_SETspecialdeath auto
GlobalVariable Property SuH_SETdesirecap auto
GlobalVariable Property SuH_SETrecoverbleed auto
GlobalVariable Property SuH_CHKsdinact auto
GlobalVariable Property SuH_rank_savingessenceCD auto
GlobalVariable Property SuH_rank_savingessence2 auto
GlobalVariable Property SuH_rank_formalbeauty auto
GlobalVariable Property SuH_rank_formalbeauty2 auto
GlobalVariable Property SuH_rank_regalglow auto
GlobalVariable Property SuH_rank_violenceCD auto
GlobalVariable Property SuH_SETcsbleedoutdelay auto
GlobalVariable property SuH_SETdisablehealthrecovery auto
GlobalVariable property SuH_SETdisablemagickarecovery auto
GlobalVariable property SuH_SETdisablestaminarecovery auto
GlobalVariable property SuH_CHKcsprocessing auto
GlobalVariable property SuH_SETadvancedchecking auto
GlobalVariable property SuH_PCScaphealth auto
GlobalVariable property SuH_PCScaphealthdown auto
GlobalVariable property SuH_PCScapmagicka auto
GlobalVariable property SuH_PCScapmagickadown auto
GlobalVariable property SuH_PCScapstamina auto
GlobalVariable property SuH_PCScapstaminadown auto
GlobalVariable property SuH_PCSdpoint auto
GlobalVariable property SuH_PCSmpoint auto

Actor Property PlayerRef auto
Spell Property SuH_dyna_ability auto
Spell Property SuH_dyna_player auto
Spell Property SuH_spell_sexualenrage auto
Spell Property SuH_spell_sexualentice auto
Spell property SuH_sex_inact auto
Armor property SuH_armor_regalglow auto

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

Event OnInit()
	PlayerRef.AddSpell(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()
	overcapCalc()
	if playerRef.IsInCombat()
		if nowincombat == false
			nowincombat = true
			formalBeautyCalc()
		endIf
	else
		nowincombat = false
	endIf
	
	if SuH_SETadvancedchecking.GetValue()
		disableRecoveryCalc()
	endIf
	
	;if 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(SuH_dyna_ability) ; If dynamic script is applying
		PlayerRef.RemoveSpell(SuH_dyna_ability) ; Remove dynamic run script
	else ; if dynamic script is not applying
		PlayerRef.AddSpell(SuH_dyna_ability, FALSE) ; AddSpell dynamic run script
	endIf
endFunction

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

;Desire Calculations
function desireCalc()
	desireDelay += 1
	if desireDelay > 4
		float desireV = (SuH_PCSdesiregain.GetValue()) + SuH_PCSdesire.GetValue()
		SuH_PCSdesire.SetValue(desireV)
		if desireV >= SuH_SETdesirecap.GetValue() && 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 = SuH_PCSforce.GetValue()
			SuH_PCSforce.SetValue(y+x)
		endIf
		desireDelay = 0
	endIf
endFunction

;Regal Glow Calculations
function regalGlowCalc()
	int RGarmor = SuH_rank_regalglow.GetValue() as int
	if RGarmor > 0
		int bodySlot = 0x00000004
		Armor bodyArmor = playerRef.GetWornForm(bodySlot) as Armor
		;if bodyArmor == SuH_armor_regalglow ;Regal Glow Active Already
		if (bodyArmor) ;Body Armor Found
			regalglowarmor = 0
			playerRef.UnequipItem(SuH_armor_regalglow, abSilent=true)
		elseif playerRef.IsEquipped(SuH_armor_regalglow) ;Regal Glow Active Already
			if RGarmor != regalglowarmor
				bodyArmor.SetArmorRating( Math.Floor(1 + (RGarmor * (SuH_PCSmpoint.GetValue() * 0.05))) )
				playerRef.UnequipItem(SuH_armor_regalglow, abSilent=true)
				playerRef.equipitem(SuH_armor_regalglow, false, true)
				regalglowarmor = RGarmor
			endIf
		else ;no body armor
			playerRef.equipitem(SuH_armor_regalglow, false, true)
			SuH_armor_regalglow.SetArmorRating(RGarmor)
			playerRef.UnequipItem(SuH_armor_regalglow, abSilent=true)
			playerRef.equipitem(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 = SuH_rank_formalbeauty.GetValue() as int
	if fb > 0
		int d = 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 > SuH_PCSstacksex.GetValue()
				if SuH_PCSstacksex.GetValue() > 0
					if consume > SuH_PCSstackmaxsex.GetValue()
						consume = SuH_PCSstackmaxsex.GetValue() as int
					else
						consume = SuH_PCSstacksex.GetValue() as int
					endIf
				else
					consume = 0
				endIf
			endIf
			if consume != 0
				playerRef.RestoreActorValue("health", recovery * consume)
				consume -= SuH_rank_formalbeauty2.GetValue() as int
				if consume < 1
					consume = 1
				endIf
				SuH_PCSstacksex.SetValue( Math.Floor(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 > SuH_PCSstacksperm.GetValue()
				if SuH_PCSstacksperm.GetValue() > 0
					if consume > SuH_PCSstackmaxsperm.GetValue()
						consume = SuH_PCSstackmaxsperm.GetValue() as int
					else
						consume = SuH_PCSstacksperm.GetValue() as int
					endIf
				else
					consume = 0
				endIf
			endIf
			if consume != 0
				playerRef.RestoreActorValue("magicka", recovery * consume)
				consume -= SuH_rank_formalbeauty2.GetValue() as int
				if consume < 1
					consume = 1
				endIf
				SuH_PCSstacksperm.SetValue( Math.Floor(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 > SuH_PCSstackmilk.GetValue()
				if SuH_PCSstackmilk.GetValue() > 0
					if consume > SuH_PCSstackmaxmilk.GetValue()
						consume = SuH_PCSstackmaxmilk.GetValue() as int
					else
						consume = SuH_PCSstackmilk.GetValue() as int
					endIf
				else
					consume = 0
				endIf
			endIf
			if consume != 0
				playerRef.RestoreActorValue("stamina", recovery * consume)
				consume -= SuH_rank_formalbeauty2.GetValue() as int
				if consume < 1
					consume = 1
				endIf
				SuH_PCSstackmilk.SetValue( Math.Floor(SuH_PCSstackmilk.GetValue() - consume) )
			endIf
		endIf
	endIf
endFunction

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

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

;Saving Essence Function
function savingEssenseCalc()
	int se = SuH_rank_savingessenceCD.GetValue() as int
	if se > 0
		savingessenseDelay += 1
		int ser2 = Math.Floor(1200 - (SuH_rank_savingessence2.GetValue()*60 ))
		if savingessenseDelay > ser2
			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 = SuH_rank_violenceCD.GetValue() as int
	if se > 0
		violenceDelay += 1
		if violenceDelay > 1
			SuH_rank_violenceCD.SetValue(0)
			violenceDelay = 0
		endIf
	else
		violenceDelay = 0
	endIf
endFunction

;Disable Recovery Function
Function disableRecoveryCalc()
	if SuH_SETdisablehealthrecovery.GetValue() > 0.0
		playerRef.SetActorValue("HealRate", 0)
	endIf
	if SuH_SETdisablemagickarecovery.GetValue() > 0.0
		playerRef.SetActorValue("MagickaRate", 0)
	endIf
	if 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((SuH_PCScaphealth.GetValue() + (plvl * 4)) - SuH_PCScaphealthdown.GetValue())
	if playerRef.GetBaseActorValue("Health") > x
		playerRef.SetActorValue("health", playerRef.GetBaseActorValue("health") - 1)
	endIf
	x = Math.Floor((SuH_PCScapmagicka.GetValue() + (plvl * 3)) - SuH_PCScapmagickadown.GetValue())
	if playerRef.GetBaseActorValue("magicka") > x
		playerRef.SetActorValue("magicka", playerRef.GetBaseActorValue("magicka") - 1)
	endIf
	x = Math.Floor((SuH_PCScapstamina.GetValue() + (plvl * 3)) - SuH_PCScapstaminadown.GetValue())
	if playerRef.GetBaseActorValue("Stamina") > x
		playerRef.SetActorValue("Stamina", playerRef.GetBaseActorValue("Stamina") - 1)
	endIf
endFunction