ScriptName zzzSXPController Extends Quest

import StorageUtil

GlobalVariable Property GV_XP Auto
GlobalVariable Property GV_RP Auto
Book Property zzzSXPDummyNote Auto
Message Property zzzSXPNotificationMessage Auto
zzzSXPConfig Property XPConfig Auto

float Property GV_StoredXP Auto Hidden
float Property fPlayerLevelBonus = 1.0 Auto Hidden
string Property SXPNotificationColorString Auto Hidden

string[] Property SXPMessageNotification Auto
bool[] Property SXPToggle Auto Hidden

float fStealRecord
float fPrevStealRecord

bool IsLessIntrusiveHUDInstalled

Function GameInit()
	GameReloaded()
EndFunction

Function GameReloaded()
	StartEventListener()
	IsLessIntrusiveHUDInstalled = GetLessIntrusiveHUDInstalled()
EndFunction

Function StartEventListener()
	RegisterForModEvent( "SXP", "EventHandler" )
EndFunction

Event EventHandler( string eventName, string strArg, float numArg, Form sender )
	if ( eventName != "SXP" )
		return
	endif
	GainModXPMessage(numArg, strArg)
EndEvent

float Function GetXP()
	return GV_XP.GetValue()
EndFunction

float Function GetRestPoint()
	return GV_RP.GetValue()
EndFunction

float Function CalcRestPoint( float f_arg )
	float f_rp = GV_RP.GetValue()
	float f_arg1 = (f_arg * (XPConfig.SXPGeneral[6] - 1.0))
	if ( f_rp <= f_arg1 )
		GV_RP.SetValue( 0.0 )
		return f_rp
	endif
	
	GV_RP.Mod(f_arg1 * -1.0)
	return f_arg1
EndFunction

Function GainModXPMessage(float f, string Msg = "", bool bShow = True)
	float XpRate = XPConfig.SXPGeneral[0] * fPlayerLevelBonus
	bool b_bShow = bShow
	

	if b_bShow != SXPToggle[57]
		b_bShow = SXPToggle[57]
	endif
	
	float fXP = f * XpRate
	if fXP == 0.0
		return
	endif
	
	fXP += CalcRestPoint( fXP )
	GainXP(fXP)
	if b_bShow
		if Msg != ""
			if IsLessIntrusiveHUDInstalled
				zzzSXPDummyNote.SetName(Msg)
				zzzSXPNotificationMessage.Show(fXP)
			else
				((Self as Form) as UILIB_1).ShowNotification("$XPGainMessage{" + Msg + "}{ " + fXP as int + "}", SXPNotificationColorString)
			endif
		endif
	endif
EndFunction

Function GainXPMessage(int Index, float f, string Msg = "", bool bShow = True)
	float XpRate = XPConfig.SXPGeneral[0]
	bool b_bShow = bShow
	
	if Index == 55
		XpRate *= (XPConfig.SXPGeneral[2])
	else
		XpRate *= (XPConfig.SXPGeneral[1]) * fPlayerLevelBonus
	endif
	
	if Msg == ""
		Msg = SXPMessageNotification[Index]
	endif
	
	if b_bShow != SXPToggle[Index]
		b_bShow = SXPToggle[Index]
	endif
	
	float fXP = f * XpRate
	if fXP == 0.0
		return
	endif
	
	fXP += CalcRestPoint( fXP )
	GainXP(fXP)
	if b_bShow
		if Msg != ""
			if IsLessIntrusiveHUDInstalled
				zzzSXPDummyNote.SetName(Msg)
				zzzSXPNotificationMessage.Show(fXP)
			else
				((Self as Form) as UILIB_1).ShowNotification("$XPGainMessage{" + Msg + "}{ " + fXP as int + "}", SXPNotificationColorString)
			endif
		endif
	endif
	ClearAllSkillProgress()
EndFunction

Function ClearAllSkillProgress()
	ActorValueInfo.GetActorValueInfobyName("Marksman").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Block").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("HeavyArmor").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("OneHanded").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Smithing").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("TwoHanded").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Alteration").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Conjuration").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Destruction").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Enchanting").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Illusion").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Restoration").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Alchemy").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("LightArmor").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Lockpicking").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Pickpocket").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Sneak").SetSkillExperience(0.0)
	ActorValueInfo.GetActorValueInfobyName("Speechcraft").SetSkillExperience(0.0)
EndFunction

Function DevilsTradeGainXPMessage(float f)
	string Msg = SXPMessageNotification[55]
	
	GainXP(f)
	if SXPToggle[57]
		if Msg != ""
			if IsLessIntrusiveHUDInstalled
				zzzSXPDummyNote.SetName(Msg)
				zzzSXPNotificationMessage.Show(f)
			else
				((Self as Form) as UILIB_1).ShowNotification("$XPGainMessage{" + Msg + "}{ " + f as int + "}", SXPNotificationColorString)
			endif
		endif
	endif
EndFunction

State Empty
EndState

State Counting
Event OnBeginState()
	RegisterForSingleUpdate(1.0)
EndEvent

Event OnUpdate()
	if fPrevStealRecord == fStealRecord
		GainXPMessage(51, fStealRecord)
		GoToState("Empty")
	else
		fPrevStealRecord = fStealRecord
		RegisterForSingleUpdate(1.0)
	endif
EndEvent

Event OnEndState()
	UnregisterForUpdate()
	fStealRecord = 0.0
	fPrevStealRecord = 0.0
EndEvent
EndState

Function IncreaseStealRecord(float f)
	fStealRecord += f
	if GetState() != "Counting"
		GoToState("Counting")
	endif
EndFunction

Function GainXP( float f_exp )
	if ( f_exp < 0.0 )
		return
	endif
	;GV_XP.Mod( f_exp )
	if StorageUtil.HasIntValue(none, "volatileSkillXP")
		StorageUtil.AdjustIntValue(none, "volatileSkillXP", Math.Floor(f_exp))
	else
		StorageUtil.SetIntValue(none, "volatileSkillXP", Math.Floor(f_exp))
	endif
	
EndFunction

Function TransferXP( float percentage )
	if percentage >= 1.0
		int toAward = StorageUtil.GetIntValue(none, "volatileSkillXP")
		StorageUtil.SetIntValue(none, "volatileSkillXP", 0)
		GV_XP.Mod( toAward )
	elseif percentage > 0.0
		int toAward = Math.Floor(StorageUtil.GetIntValue(none, "volatileSkillXP") * percentage)
		if toAward > 0
			StorageUtil.AdjustIntValue(none, "volatileSkillXP", -1 * toAward)
			GV_XP.Mod( toAward )
		endif
	endif
EndFunction

Function UseXP( float f_exp )
	if ( f_exp < 0.0 )
		return
	endif
	float f_rev = f_exp * -1.0
	GV_XP.Mod( f_rev )
	GV_StoredXP += f_exp
EndFunction

bool Function GetLessIntrusiveHUDInstalled()
	if Game.GetModByName("LessIntrusiveHUD.esp") != 255
		return True
	else
		return False
	endif
EndFunction