Scriptname SLApproachBaseQuestScript extends Quest

Actor Property PlayerRef Auto
Int Property index = -1 Auto Hidden
Int Property maxTime = 60 Auto Hidden
bool Property approachEnding = false Auto Hidden
bool Property isSkipMode = false Auto Hidden
Globalvariable Property SLAFactorScore Auto
slapp_util Property slappUtil Auto

ObjectReference Property SLAPMiscReferences Auto
Package Property DoNothing Auto
Package Property SLAppDoNothing Auto
Bool Isplaying = false

bool Property dhlpSuspendStatus Auto Hidden Conditional
formlist property SLApproachChildRaceList auto
Formlist Property SLApproachExcludeFaction Auto
Armor Property SLAppApproachRing Auto

Function register()
	index = -1
	while(index == -1)
		Utility.Wait(1.0)
		index = SLApproachMain.RegisterQuest(ApproachQuest, self, ApproachName)
	endwhile
EndFunction

Event OnUpdate()
if SLApproachMain.debugLogFlag
	Debug.notification("Parent: Onupdate")
endif
	endApproach()
endEvent

Function ready()
	self.Reset()
	self.SetStage(10)
EndFunction

Function startApproach(Actor akRef)
	;Debug.notification("Start Approach Base")
	RegisterForSingleUpdate(maxTime)
EndFunction

;#########################
;##########Motion#########
;#########################

Idle Property BaboKissLoveS01_A1 Auto
Idle Property BaboKissLoveS01_A2 Auto
Idle Property BaboKissLoveS02_A1 Auto
Idle Property BaboKissLoveS02_A2 Auto

Idle Property SLAPForcedKiss01_A1_S01 Auto
Idle Property SLAPForcedKiss01_A2_S01 Auto
Idle Property SLAPForcedKiss01_A1_Loop Auto
Idle Property SLAPForcedKiss01_A2_Loop Auto
Idle Property SLAPForcedKiss01_A1_Resist Auto
Idle Property SLAPForcedKiss01_A2_Resist Auto
Idle Property SLAPForcedKiss01_A1_Stop Auto
Idle Property SLAPForcedKiss01_A2_Stop Auto

Idle Property SLA_Flirt_A01 Auto
Idle Property SLA_Flirt_A02 Auto
Idle Property SLA_FlirtFace_A01 Auto
Idle Property SLA_FlirtFaceEnd_A01 Auto
Idle Property SLA_FlirtFace_A02 Auto
Idle Property SLA_FlirtFaceEnd_A02 Auto
Idle Property SLA_Flirt_A02D Auto
Idle Property SLA_FlirtBreast_A01 Auto
Idle Property SLA_FlirtBreast_A02 Auto
Idle Property SLA_FlirtPussy_A01 Auto
Idle Property SLA_FlirtPussy_A02 Auto

Faction Property slapp_AnimatingFaction Auto
Faction Property slapp_IgnoreUniqueFaction Auto
Faction Property slapp_RapeCountFaction Auto
Faction Property slapp_SexRejectCountFaction Auto
Actor ActorMale
Scene Property SLApproachSpankingScene Auto
GlobalVariable Property SLA_SpankingScenarioGlobal Auto
Spell Property SLApproachSpankAura Auto
Spell Property SLApproachSpankAura2nd Auto
Spell Property SLApproachAuraBDViceCaptain Auto
Spell Property SLApproachMolestAura Auto
Potion Property Ale Auto

Function PrecisionCheck(Actor akactor, bool switch)
	Precision_Utility.ToggleDisableActor(PlayerRef, switch);Precision
	Precision_Utility.ToggleDisableActor(akactor, switch);Precision
EndFunction

Bool Function AcyclePairedMotion(Actor akactor, int angle, int Xaxis, int Yaxis, int MotionType)
if !akactor.isinfaction(slapp_AnimatingFaction)
	PrecisionCheck(akactor, true)
 	ActorUtil.AddPackageOverride(akactor, SLAppDoNothing, 100, 1)
	ActorMale = akactor
	akactor.EvaluatePackage()
	akactor.SetRestrained(True)
	akactor.SetDontMove(True)
	;Game.DisablePlayerControls(true, true, false, false, false, false, false, false, 0)
	Game.DisablePlayerControls(true, true, true, false, true, true, false, false)
	Game.SetPlayerAIDriven()
	if Game.GetCameraState() == 0
		Game.ForceThirdPerson()
	endIf
	if MotionType >= 2
		SLApproachMain.RemoveHeelEffect(PlayerRef)
	endif
	Utility.Wait(0.5)
	Float AngleZ = PlayerRef.GetAngleZ()
	Float rMoveX = (Math.sin(AngleZ) * Yaxis) + (Math.cos(AngleZ) * Xaxis)
	Float rMoveY = (Math.cos(AngleZ) * Yaxis) - (Math.sin(AngleZ) * Xaxis)
	
	SLAPMiscReferences.MoveTo(PlayerRef, rMoveX, rMoveY)
	
	Utility.Wait(0.5)
	akactor.MoveTo(SLAPMiscReferences)
	akactor.setangle(0, 0, AngleZ + angle)
	Utility.Wait(0.5)


	if MotionType == 1
		Debug.sendanimationevent(akactor, "BaboSpankingM")
		Debug.sendanimationevent(PlayerRef, "BaboSpankingF")
		
		SLApproachSpankingScene.stop()
		akactor.SetRestrained(False)
		akactor.SetDontMove(False)
		ActorUtil.RemovePackageOverride(akactor, SLAppDoNothing)
		Utility.wait(3.0)
		If SLApproachMain.enableBDFlag
			if (akactor.isinfaction(SLApproachMain.BaboViceGuardCaptainFaction))
				SLApproachAuraBDViceCaptain.cast(PlayerRef, akactor)
			else
				SLApproachSpankAura.cast(PlayerRef, akactor)
			endif
		else
			SLApproachSpankAura.cast(PlayerRef, akactor)
		endif
		PrecisionCheck(akactor, false)
		PlayerRef.SetVehicle(None)
		Game.EnablePlayerControls()
		Game.SetPlayerAIDriven(false)
	elseif MotionType == 2
		Game.EnablePlayerControls(true, false, false, false, false, false, false, false) ; To display the hud
		Debug.sendanimationevent(akactor, "BaboBackHugStartM")
		Debug.sendanimationevent(PlayerRef, "BaboBackHugStartF")
		SLApproachSpankingScene.stop()
	elseif MotionType == 3
		Game.EnablePlayerControls(true, false, false, false, false, false, false, false) ; To display the hud
		Debug.sendanimationevent(akactor, "BaboBackHugMolestStartM")
		Debug.sendanimationevent(PlayerRef, "BaboBackHugMolestStartF")
		SLApproachSpankingScene.stop()
	endif

	if SLApproachMain.debugLogFlag
		Debug.notification("BaboSpanking Motion Starts")
	endif

	Return true
else
	Return false
endif
EndFunction


Bool Function PreparePairedmotion(Actor akactor, int angle)

if !akactor.isinfaction(slapp_AnimatingFaction)
	PrecisionCheck(akactor, true)
 	ActorUtil.AddPackageOverride(akactor, SLAppDoNothing, 100, 1)
	akactor.EvaluatePackage()
	akactor.SetRestrained(True)
	akactor.SetDontMove(True)
	Game.DisablePlayerControls(true, true, true, false, true, true, false, false)
	Game.SetPlayerAIDriven(); 
	if Game.GetCameraState() == 0
		Game.ForceThirdPerson()
	endIf
	SLApproachMain.RemoveHeelEffect(PlayerRef)
	SLAPMiscReferences.MoveTo(PlayerRef)
	Float AngleZ = PlayerRef.GetAngleZ()
		
	PlayerRef.SetVehicle(SLAPMiscReferences) ; PosRef
	akactor.SetVehicle(SLAPMiscReferences) ; PosRef
	akactor.MoveTo(PlayerRef)
	Utility.Wait(1.0)
	akactor.setangle(0, 0, AngleZ + angle)
	Utility.Wait(1.0)
	
	PlayerRef.addtofaction(slapp_AnimatingFaction)
	akactor.addtofaction(slapp_AnimatingFaction)
	
	Game.EnablePlayerControls(true, false, false, false, false, false, false, false) ; To display the hud
endif

Return true;Always concludes in True even if the actors are not aligned properly
EndFunction

Function FlirtAnim(Actor akactor, Bool FirstTrigger, int Animnum)
if FirstTrigger == true
	if PreparePairedmotion(akactor, 0)
		FlirtAnimPlay(akactor, Animnum)
	endif
else	
	FlirtAnimPlay(akactor, Animnum)
endif
EndFunction

Function FlirtAnimPlay(Actor akactor, int Animnum)
	if Animnum == 1
		Debug.SendAnimationEvent(PlayerRef, "Babo_Flirt_A01")
		Debug.SendAnimationEvent(akactor, "Babo_Flirt_A02")
	elseif Animnum == 2
		Debug.SendAnimationEvent(PlayerRef, "Babo_FlirtBreast_A01")
		Debug.SendAnimationEvent(akactor, "Babo_FlirtBreast_A02")
	elseif Animnum == 3
		Debug.SendAnimationEvent(PlayerRef, "Babo_FlirtPussy_A01")
		Debug.SendAnimationEvent(akactor, "Babo_FlirtPussy_A02")
	elseif Animnum == 4
		Debug.SendAnimationEvent(PlayerRef, "Babo_FlirtFace_A01")
		Debug.SendAnimationEvent(akactor, "Babo_FlirtFace_A02")	
	elseif Animnum == 5
		Debug.SendAnimationEvent(PlayerRef, "Babo_FlirtFaceEnd_A01")
		Debug.SendAnimationEvent(akactor, "Babo_FlirtFaceEnd_A02")
	else
		Debug.SendAnimationEvent(akactor, "Babo_Flirt_A02D")
	endif
EndFunction

Function KissAnim(Actor akactor, int AnimType)
;Animtype 1: ForcedKiss
;Animtype 2: Not Ready
;Animtype 3: SweetKiss01
;Animtype 4: SweetKiss02
	If PreparePairedmotion(akactor, 180)
		if AnimType == 1
			PlayerRef.Playidle(SLAPForcedKiss01_A1_S01)
			akactor.Playidle(SLAPForcedKiss01_A2_S01)
		elseif AnimType == 2
			PlayerRef.Playidle(SLAPForcedKiss01_A1_S01)
			akactor.Playidle(SLAPForcedKiss01_A2_S01)
		elseif AnimType == 3
			PlayerRef.Playidle(BaboKissLoveS01_A1)
			akactor.Playidle(BaboKissLoveS01_A2)
		elseif AnimType == 4
			PlayerRef.Playidle(BaboKissLoveS02_A1)
			akactor.Playidle(BaboKissLoveS02_A2)
		endif
	endif
	PlayKissSound()
EndFunction

Function KissAnimResist(Actor akactor)
	PlayerRef.Playidle(SLAPForcedKiss01_A1_Resist)
	akactor.Playidle(SLAPForcedKiss01_A2_Resist)
	Utility.Wait(3.0)
	RestoreControl(akactor)
EndFunction

Function KissAnimStop(Actor akactor)
	PlayerRef.Playidle(SLAPForcedKiss01_A1_Stop)
	akactor.Playidle(SLAPForcedKiss01_A2_Stop)
	Utility.Wait(3.0)
	RestoreControl(akactor)
EndFunction

Function PlayKissSound()
	SLAPPMarker_DeepKiss.play(PlayerRef)
EndFunction

Function RestoreControl(actor akactor)
	PrecisionCheck(akactor, false)
	PlayerRef.SetVehicle(None)
	akactor.SetVehicle(None)
	Game.EnablePlayerControls()
	Game.SetPlayerAIDriven(false)
	Game.ForceThirdPerson()
	PlayerRef.SetRestrained(False)
	PlayerRef.SetDontMove(False)
	akactor.SetRestrained(False)
	akactor.SetDontMove(False)
	ActorUtil.RemovePackageOverride(akactor, SLAppDoNothing)
	Debug.SendAnimationEvent(akactor, "IdleForceDefaultState")
	Debug.SendAnimationEvent(PlayerRef, "IdleForceDefaultState")
	SLApproachMain.ResetHeelEffect(PlayerRef)
	PlayerRef.RemoveFromfaction(slapp_AnimatingFaction)
	akactor.RemoveFromfaction(slapp_AnimatingFaction)
EndFunction

bool Function isSituationValid(Actor akRef);Check if the situation is valid for a npc approach
	ActorBase akRefbase = akRef.GetLeveledActorBase()

;#########################
;##########Add-on#########
;#########################
	If (dhlpSuspendStatus)	;lg added to respect scenes
		slappUtil.log("isSituationValid: false - dhlpSuspendStatus")
		return false
	endif
	
	int iindex
	iindex = SLApproachExcludeFaction.getsize()
	While iindex > 0
		iindex -= 1
		if akRef.isinfaction(SLApproachExcludeFaction.GetAt(iindex) as faction)
			return false
		endif
	EndWhile
	
	
	if SLApproachMain.enableSexlabSurvivalFlag
		(SLApproach_ExternalMods as SLApproachExternalScript).SLSurvivalLicenseCheck()
		if  (akRef.isinfaction((SLApproach_ExternalMods as SLApproachExternalScript).SLTollCollectorFaction) || akRef.isinfaction((SLApproach_ExternalMods as SLApproachExternalScript).SLKennelKeeperFaction) || akRef.isinfaction((SLApproach_ExternalMods as SLApproachExternalScript).SLLicenseQuarterMasterFaction))
			return false
		endif
	endif

	if SLApproachMain.enableBDFlag
		if (SLApproachMain.enableHirelingFlag == false)
			if  (akRef.isinfaction(SLApproachMain.BaboPotentialHireling))
				return false
			endif
		endif

		if akRef.isinfaction(SLApproachMain.BaboWasHireling)
			akRef.addtofaction(slapp_washiringfaction)
			BaboDialogueMercenaryCall(akRef)
			return false
		elseif !akRef.isinfaction(SLApproachMain.BaboWasHireling) && akRef.isinfaction(slapp_washiringfaction)
			akRef.removefromfaction(slapp_washiringfaction)
			return false
		endif

		if akRef.isinfaction(SLApproachMain.BaboDialogueFaction)
			if (akRef.isinfaction(SLApproachMain.BaboViceGuardCaptainFaction))
				if akRef.getactorvalue("Variable06") == 5
					return true
				endif
			endif
			return false
		endif

		if SLApproachMain.enableFollowerFlag == false
			if (akRef.isinfaction(SLApproachMain.BaboCurrentHireling))
				return false
			endif
		endif
	endif

	if (SLApproachMain.enableHirelingFlag == false)
		if (akRef.isinfaction(CurrentHireling)) || (akRef.isinfaction(PotentialHireling))
			return false
		endif
	endif
	if SLApproachMain.enableFollowerFlag == false
		if (akref.isinfaction(CurrentFollowerFaction)) || (akRef.isinfaction(CurrentHireling)) || (akref.IsPlayerTeammate())
			return false
		endif
	endif

;#########################
;######Unique Actor#######
;#########################

	if akref.isinfaction(slapp_IgnoreUniqueFaction) || akref.getitemcount(SLAppApproachRing) >= 1
		return true
	endif

	if (SLApproachMain.SLAUniqueActor == true) && (akRefbase.isUnique());Check if an actor happens to be unique.
		return true
	elseif (SLApproachMain.SLAUniqueActor == false) && (akRefbase.isUnique())
		if SLApproachMain.enableBDFlag
			if (akref.isinfaction(SLApproachMain.BaboViceGuardCaptainFaction))
				return true
			endif
		endif
		return false
	EndIf

;#########################
;#Humanoid identification#
;#########################
;	if (SLApproachMain.enableVisitorFlag == false) && (akRef.isinfaction(slapp_VisitingFaction))
;		return false
;	endif

;#########################
;########Creature######### WIP
;#########################
;		if (SLApproachMain.enablePetsFlag && akRef.IsPlayerTeammate()) ; WIP disabled
;			return true
;		elseif (akRace == HorseRace)
;			if (SLApproachMain.enablePlayerHorseFlag && slappUtil.ValidateHorse(akRef))
;				return true
;			else
;				return false
;			endif
;		endif

	return true
EndFunction

bool Function chanceRoll(Actor akRef, Actor akActor, float baseChanceMultiplier)
	return false
EndFunction

Function isPrecheckValid(Actor akRef, Actor akRef2, bool isplayer = false)
;	if (!slappUtil.ValidatePromise(akRef, akRef2) || !slappUtil.ValidateShyness(akRef, akRef2))
;		string debugstr = akRef.GetActorBase().GetName() + " => " + akRef2.GetActorBase().GetName()
;		slappUtil.log(ApproachName + " blocked by Promise or Shyness: " + debugstr)
;		return false
;	if !(slappUtil.ValidateGender(akRef, akRef2, isplayer))
;		string debugstr = akRef.GetActorBase().GetName() + " => " + akRef2.GetActorBase().GetName()
;		slappUtil.log(ApproachName + " blocked by Gender check: " + debugstr)
;		return false
;	endif
EndFunction
	
Bool Function PrecheckShota(Actor akRef)
	int i = SLApproachChildRaceList.getsize()
	
	if akRef.ischild()
		SLApproachMain.SLACurrentActorisChild = true
		if SLApproachMain.debugLogFlag
			debug.notification("SLACurrentActorisChild: True")
		endif
		return true
	else
		While i > 0
			i -= 1
			if akRef.GetLeveledActorBase().getrace() == SLApproachChildRaceList.getat(i) as race
				SLApproachMain.SLACurrentActorisChild = true
				if SLApproachMain.debugLogFlag
					debug.notification("SLACurrentActorisChild: True")
				endif
				return true
			endif
		Endwhile
	endif
	if SLApproachMain.debugLogFlag
		debug.notification("SLACurrentActorisChild: False")
	endif
	SLApproachMain.SLACurrentActorisChild = false
	return false
EndFunction

bool Function isSceneValid(Actor akRef)
	Scene aks = akRef.GetCurrentScene()
	
	if (aks)
		string akscene = aks.GetOwningQuest().GetId()
		string log = ApproachName + ": blocked by another Scene: "
		slappUtil.log(log + akRef.GetActorBase().GetName() + " : " + akscene)
		return false
	endif
	
	return true
EndFunction

int Function GetResult(int chance, int extpoint, float baseChanceMultiplier)
int result
	if extpoint > 0
		result = slappUtil.ValidateChance((chance * baseChanceMultiplier) as Int)
		result += extpoint*2
	else
		result = 0
	endif
	return result
EndFunction

int Function GetDiceRoll()
	return Utility.RandomInt(0, 100)
EndFunction

Function endApproach(bool force = false)
	if SLApproachMain.debugLogFlag
		Debug.notification("Parent: endApproach")
	endif
	ChangeStateStage(0)
	SLApproachMain.EndtInitOfQuestByIndex(index)
EndFunction

Function endApproachForce(ReferenceAlias akRef = None) ; for debug and Sex To PC's follow Scene
	slappUtil.log(ApproachName + ": endApproachForce!!")
	if (akRef)
		Actor fordebugact = akRef.GetReference() as Actor
		if (fordebugact)
			ActorBase fordebugname = fordebugact.GetActorBase()
			if (fordebugname)
				slappUtil.log(ApproachName + " Force Stop: " + fordebugname.GetName())
			endif
		endif
	endif
	self.endApproach(true)
EndFunction

Function endApproachDetachCell()
	self.endApproach(true)
EndFunction

Function sexRelationshipDown(Actor akRef, Actor akActor, int Possibility)
int relationship = akRef.GetRelationshipRank(akActor) - 1
Int DiceRoll = Self.GetDiceRoll()
; debug.notification("[slapp] " + relationship)
	If DiceRoll <= possibility
		if (relationship < -2)
			relationship = -2
		endif
		akRef.SetRelationshipRank(akActor, relationship)
	EndIf
EndFunction

Function sexRelationshipUp(Actor akRef, Actor akActor, int Possibility)
int relationship = akRef.GetRelationshipRank(akActor) + 1
Int DiceRoll = Self.GetDiceRoll()
	If DiceRoll <= possibility
		if (relationship > 4)
			relationship = 4
		endif
		akRef.SetRelationshipRank(akActor, relationship)
	endif
EndFunction

Function AddtoReconciliationFaction(actor akRef)
bool infaction = akRef.isinfaction(slapp_ReconciliationFaction)
Int DiceRoll = Self.GetDiceRoll()
Int Rank = akRef.GetfactionRank(slapp_ReconciliationFaction)
		If infaction == false
			akRef.addtofaction(slapp_ReconciliationFaction)
			akRef.setfactionrank(slapp_ReconciliationFaction, 0)
		Elseif (Rank == 0)
			akRef.setfactionrank(slapp_ReconciliationFaction, 1)
		ElseIf (Rank == 1)
			akRef.setfactionrank(slapp_ReconciliationFaction, 2)
		Elseif (Rank == 2)
			akRef.setfactionrank(slapp_ReconciliationFaction, 3)
		;Elseif (Rank == 3)
			;akRef.setfactionrank(slapp_ReconciliationFaction, 4)
		Endif
EndFunction

Function AddtoNoSpankFaction(actor akRef)
	akRef.addtofaction(slapp_NoSpankFaction)
EndFunction

Function AddtoNoMolestFaction(actor akRef)
	akRef.addtofaction(slapp_NoMolestFaction)
EndFunction

int Function RankDownDislikeFaction(actor akRef)

if akRef.isinfaction(slapp_DislikeFaction)
	Int Rank = akRef.GetfactionRank(slapp_DislikeFaction)
	if Rank
		akRef.setfactionrank(slapp_DislikeFaction, Rank - 1)
	else
		akRef.removefromfaction(slapp_DislikeFaction)
	endif
	return Rank
endif

Return 0
EndFunction

Function AddtoVisitiedFaction(actor akRef)

bool infaction = akRef.isinfaction(slapp_VisitedFaction)
Int Rank = akRef.GetfactionRank(slapp_VisitedFaction)
	If infaction == false
		akRef.addtofaction(slapp_VisitedFaction)
		akRef.setfactionrank(slapp_VisitedFaction, 0);DislikeFaction
	Else
		akRef.setfactionrank(slapp_VisitedFaction, Rank + 1)
	Endif
EndFunction

Function AddtoStayedFaction(actor akRef)

bool infaction = akRef.isinfaction(slapp_StayedFaction)
Int Rank = akRef.GetfactionRank(slapp_StayedFaction)
	If infaction == false
		akRef.addtofaction(slapp_StayedFaction)
		akRef.setfactionrank(slapp_StayedFaction, 0);DislikeFaction
	Else
		akRef.setfactionrank(slapp_StayedFaction, Rank + 1)
	Endif
EndFunction

Function AddtoVisitiedFailedFaction(actor akRef)

bool infaction = akRef.isinfaction(slapp_VisitedFailedFaction)
Int Rank = akRef.GetfactionRank(slapp_VisitedFailedFaction)
	If infaction == false
		akRef.addtofaction(slapp_VisitedFailedFaction)
		akRef.setfactionrank(slapp_VisitedFailedFaction, 0);DislikeFaction
	Else
		akRef.setfactionrank(slapp_VisitedFailedFaction, Rank + 1)
	Endif
EndFunction

Function AddtoDislikeFaction(actor akRef, int possibility, bool Uprank = false)

bool infaction = akRef.isinfaction(slapp_DislikeFaction)
Int DiceRoll = Self.GetDiceRoll()
Int Rank = akRef.GetfactionRank(slapp_DislikeFaction)

	If DiceRoll <= possibility
	
		If infaction == false
			akRef.addtofaction(slapp_DislikeFaction)
			akRef.setfactionrank(slapp_DislikeFaction, 0);DislikeFaction
		Elseif (Rank >= 0) && (Rank < 2)
			akRef.setfactionrank(slapp_DislikeFaction, 1);HateFaction
		EndIf
		
		If (Rank < 2) && (Uprank == True)
			akRef.setfactionrank(slapp_DislikeFaction, 2);RapistFaction
		Elseif (Rank == 2) && (Uprank == True)
			akRef.setfactionrank(slapp_DislikeFaction, 3);ConstantRapistFaction
		;Elseif (Rank == 3) && (Uprank == True)
			;akRef.setfactionrank(slapp_DislikeFaction, 4);SlaveMasterFaction not yet
		Endif

	EndIf
EndFunction

Function AddtoDisappointedFaction(actor akRef, int possibility, int Uprank)

bool infaction = akRef.isinfaction(slapp_DisappointedFaction)
Int DiceRoll = Self.GetDiceRoll()
Int Rank = akRef.GetfactionRank(slapp_DisappointedFaction)

	If DiceRoll <= possibility
	
		If infaction == false && (Uprank == 0)
			akRef.addtofaction(slapp_DisappointedFaction)
			akRef.setfactionrank(slapp_DisappointedFaction, 0);Player No honor
		Elseif (Rank >= 0) && (Rank < 2)
			akRef.setfactionrank(slapp_DisappointedFaction, 1);Player Exhibitionist
		EndIf
		
		If infaction == true && Uprank == 1
			akRef.setfactionrank(slapp_DisappointedFaction, 2);Player Raped
		Elseif (Rank == 2) || (Uprank == 2)
			akRef.setfactionrank(slapp_DisappointedFaction, 3);Player Slut
		Elseif (Rank == 3) || (Uprank == 2)
			akRef.setfactionrank(slapp_DisappointedFaction, 4);Player Public Toilet
		Endif

	EndIf
EndFunction

Function AddtoProstitutionFaction(actor akRef)

bool infaction = akRef.isinfaction(slapp_ProstitutionFaction)

	If infaction == false
		akRef.addtofaction(slapp_ProstitutionFaction)
	else
		akRef.SetfactionRank(slapp_ProstitutionFaction, akRef.Getfactionrank(slapp_ProstitutionFaction) + 1)
	EndIf
	
EndFunction

Function AddtoAquaintanceFactionSimple(actor akRef, int possibility)

bool infaction = akRef.isinfaction(slapp_AquaintedFaction)
Int DiceRoll = Self.GetDiceRoll()

	If DiceRoll <= possibility
		If infaction == false
			akRef.addtofaction(slapp_AquaintedFaction)
			akRef.setfactionrank(slapp_AquaintedFaction, 0);Aquaintance
		EndIf
	EndIf
	
EndFunction

Function AddtoAquaintanceFaction(actor akRef, int possibility, bool Uprank = false)

bool infaction = akRef.isinfaction(slapp_AquaintedFaction)
Int DiceRoll = Self.GetDiceRoll()
Int Rank = akRef.GetfactionRank(slapp_AquaintedFaction)

	If DiceRoll <= possibility
		If infaction == false
			akRef.addtofaction(slapp_AquaintedFaction)
			akRef.setfactionrank(slapp_AquaintedFaction, 0);Aquaintance
		Elseif (Rank == 0)
			akRef.setfactionrank(slapp_AquaintedFaction, 1);AleFriend
		Elseif (Rank == 1)
			akRef.setfactionrank(slapp_AquaintedFaction, 2);Affectionate
		EndIf
		
		If (Rank < 3) && (Uprank == True)
			akRef.setfactionrank(slapp_AquaintedFaction, 3);SexFriend
		Elseif (Rank == 3) && (Uprank == True)
			akRef.setfactionrank(slapp_AquaintedFaction, 4);SexPartner
		;Elseif (Rank == 4) && (Uprank == True)
			;akRef.setfactionrank(slapp_AquaintedFaction, 5);Lover Not Yet
		Endif
		
	Else
	EndIf
EndFunction

Function CountRapeTime(actor akRef)
bool infaction = akRef.isinfaction(slapp_RapeCountFaction)
	If infaction == false
		akRef.addtofaction(slapp_RapeCountFaction)
		akRef.setfactionrank(slapp_RapeCountFaction, 1)
	else
		akRef.setfactionrank(slapp_RapeCountFaction, akRef.getfactionrank(slapp_RapeCountFaction) + 1)
	endif
EndFunction

Function ResetRapeCount(actor akRef)
	akRef.setfactionrank(slapp_RapeCountFaction, 0)
EndFunction

Function CountSexRejectTime(actor akRef)
bool infaction = akRef.isinfaction(slapp_SexRejectCountFaction)
	If infaction == false
		akRef.addtofaction(slapp_SexRejectCountFaction)
		akRef.setfactionrank(slapp_SexRejectCountFaction, 1)
	else
		akRef.setfactionrank(slapp_SexRejectCountFaction, akRef.getfactionrank(slapp_SexRejectCountFaction) + 1)
	endif
EndFunction

Function ResetSexRejectCount(actor akRef)
	akRef.setfactionrank(slapp_SexRejectCountFaction, 0)
EndFunction

Function AddtoKissFaction(actor akRef, int rank)
bool infaction = akRef.isinfaction(slapp_KissFaction)
	If infaction == false
		akRef.addtofaction(slapp_KissFaction)
	endif
EndFunction

Function AddtoRapeFailFaction(actor akRef, int possibility, bool Uprank = false)

bool infaction = akRef.isinfaction(slapp_RapeFailFaction)
Int DiceRoll = Self.GetDiceRoll()
Int Rank = akRef.GetfactionRank(slapp_RapeFailFaction)

	If DiceRoll <= possibility
		If infaction == false
			akRef.addtofaction(slapp_RapeFailFaction)
			akRef.setfactionrank(slapp_RapeFailFaction, 0);RapeFail Once

;			Elseif (Rank >= 0) && (Rank < 2)
;			akRef.setfactionrank(slapp_AquaintedFaction, 1);AleFriend
		EndIf
;		
;		If (Rank < 2) && (Uprank == True)
;			akRef.setfactionrank(slapp_AquaintedFaction, 2);SexFriend
;		Elseif (Rank == 2) && (Uprank == True)
;			akRef.setfactionrank(slapp_AquaintedFaction, 3);SexPartner
;		Elseif (Rank == 3) && (Uprank == True)
;			akRef.setfactionrank(slapp_AquaintedFaction, 4);Lover Not Yet
;		Endif
;		
	Else
	EndIf
EndFunction

Function GiftFaction(actor akRef)
Int Rank = akRef.GetfactionRank(slapp_GiftGiverFaction)
	if (Rank == 0)
		akRef.setfactionrank(slapp_GiftGiverFaction, 1)
	Elseif (Rank >= 1)
		akRef.setfactionrank(slapp_GiftGiverFaction, (Rank + 1))
	EndIf
EndFunction

Bool Function DrinkEvent(Actor Woman, Bool Rape)

if SLApproachMain.enableConsumeAlcholFlag
	Woman.equipitem(ale)
endif

	if Rape
		Woman.playidle(BaboDrinkBlackOut)
		Return True
	else
		Woman.Playidle(BaboDrinkNormal)
		Return False
	endif
EndFunction

Event OnInit() ; RegisteringModEvent
	RegisterExternalModEvent()
EndEvent

Bool Function KnockKnock()
Return False
EndFunction

Bool Function iGetFormIndex()
Return False
EndFunction

Function ChangeStateStage(int StateStage)
if StateStage == 1
	gotostate("SearchingPlace")
else
	gotostate("")
endif
EndFunction

State SearchingPlace

Function endApproachDetachCell()
	return
EndFunction

EndState


;-----------------External ModEvent---------------------

;####################################################
;################### SLHH MOD #######################
;####################################################

Function SLHHActivate(Actor pTarget, Actor pTargetFriend = None); Basically you don't need pTargetFriend. pTarget will become a criminal, who will try to rape you.
	Keyword SLHHScriptEventKeyword = Game.GetFormFromFile(0x0000C510, "SexLabHorribleHarassment.esp") as Keyword
    SLHHScriptEventKeyword.SendStoryEvent(None, pTarget, pTargetFriend)
endFunction

Function SLHHChokeActivate(Actor pTarget, Actor pTargetFriend = None, int Sex)
    Keyword SLHHScriptEventBCKeyword = Game.GetFormFromFile(0x0233C6, "SexLabHorribleHarassment.esp") as Keyword
	SLHHScriptEventBCKeyword.SendStoryEvent(None, pTarget, pTargetFriend, Sex, 0)
endFunction 

Function SLHHDrinkActivate(Actor pTarget, Actor pTargetFriend = None, int Sex);When escape fail -> 0 = Sex 1 = NoSex, only knockout animation
    Keyword SLHHScriptEventDrinkKeyword = Game.GetFormFromFile(0x02495B, "SexLabHorribleHarassment.esp") as Keyword
	SLHHScriptEventDrinkKeyword.SendStoryEvent(None, pTarget, pTargetFriend, Sex, 0)
endFunction 


;####################################################
;################# BABODIALOGUE #####################
;####################################################


;Faction Function BDBaboAggressiveBoyFriend()
;	Faction BaboAggressiveBoyFriend = Game.GetFormFromFile(0x00BA9DDA, "BabointeractiveDia.esp") as Faction
;Return BaboAggressiveBoyFriend
;EndFunction


;Faction Function BDBaboViceGuardCaptainFaction()
;	Faction BaboViceGuardCaptainFaction = Game.GetFormFromFile(0x00B71E3E, "BabointeractiveDia.esp") as Faction
;Return BaboViceGuardCaptainFaction
;EndFunction


Function BaboAggressiveBoyFriendStack(Actor pTarget)
If !(pTarget.isinfaction(slapp_AggressiveBFFaction))
	pTarget.addtofaction(slapp_AggressiveBFFaction)
Endif
EndFunction

Function BaboDialogueTrigger(Actor Rapist, Bool Worse = false, int Possibility)
int Randomi = Utility.randomint(1,100)
	If Worse
		if Possibility >= Randomi
			BaboDialogueEventRegister(Rapist, True); SLHHConsequneceWorse, Rape
		endif
	Else
		if Possibility >= Randomi
			BaboDialogueEventRegister(Rapist, False); SLHHConsequneceBad, No Rape
		endif
	EndIf
EndFunction

Function BaboDialogueSLAPPTrigger(Actor Rapist, Bool Worse = false, int Possibility)
int Randomi = Utility.randomint(1,100)
	If Worse
		if Possibility >= Randomi
			BaboDialogueSLAPPEventRegister(Rapist, True)
		endif
	Else
		if Possibility >= Randomi
			BaboDialogueSLAPPEventRegister(Rapist, False)
		endif
	EndIf
EndFunction

Function BaboDialogueEventRegister(Actor Rapist, Bool Worse)
	int handle = ModEvent.Create("BaboDialogue_ConsequenceEvent")
	if (handle)
		ModEvent.Pushform(handle, Rapist)
		ModEvent.PushBool(handle, Worse)
		ModEvent.PushString(handle, "SLAPP activated BaboDialogueConsequence")
		ModEvent.Send(handle)
	endIf
EndFunction

Function BaboDialogueSLAPPEventRegister(Actor Rapist, Bool Worse)
	int handle = ModEvent.Create("BaboDialogue_SLAPPConsequenceEvent")
	if (handle)
		ModEvent.Pushform(handle, Rapist)
		ModEvent.PushBool(handle, Worse)
		ModEvent.PushString(handle, "SLAPP activated SLAPPConsequenceEvent")
		ModEvent.Send(handle)
	endIf
EndFunction


Function RegisterAnimationEvent()
	;RegisterForAnimationEvent(PlayerRef, "BaboSpankingF")
	;RegisterForModEvent("SLAPP_SpankingEvent", "SLAPPSpankingEvent")
EndFunction

Function RegisterExternalModEvent()
	RegisterForModEvent("SLAPP_ConsequenceEvent", "SLAPPConsequenceEvent")
	RegisterForModEvent("SLAPP_ConsequenceChokeEvent", "SLAPPConsequenceChokeEvent")
	RegisterForModEvent("SLAPP_ConsequenceChokeNREvent", "SLAPPConsequenceChokeNREvent")
	RegisterForModEvent("SLAPP_AcquaintanceEvent", "SLAPPAcquaintanceEvent")
	RegisterForModEvent("SLAPP_HateEvent", "SLAPPHateEvent")
	RegisterForModEvent("dhlp-Suspend", "OnSuspend")	;lg added
	RegisterForModEvent("dhlp-Resume", "OnResume")
	RegisterAnimationEvent()
EndFunction

Event OnSuspend(string eventName, string strArg, float numArg, Form sender)
	dhlpSuspendStatus = true
EndEvent
Event OnResume(string eventName, string strArg, float numArg, Form sender)
	dhlpSuspendStatus = false
EndEvent

Event SLAPPHateEvent(form akSpeakerform, Bool HadSex = false, string results)
Actor akspeaker = akspeakerform as actor
int Chance = SLApproachMain.SLADislikeChance + 20
	AddtoDislikeFaction(akSpeaker, Chance, Hadsex)
	sexRelationshipDown(akSpeaker, PlayerRef, SLApproachMain.SLARelationshipChance)
EndEvent

Event SLAPPAcquaintanceEvent(Form akSpeakerform, Bool HadSex = false, string results)
Actor akspeaker = akspeakerform as actor
Int AcquaintanceChance = SLApproachMain.SLAAquaintanceChance + 20
Int RelationshipChance = SLApproachMain.SLARelationshipChance + 20
	AddtoAquaintanceFaction(akSpeaker, AcquaintanceChance, Hadsex)
	SexRelationshipUp(akSpeaker, PlayerRef, RelationshipChance)
EndEvent


Event SLAPPConsequenceEvent(Form akRef, Bool Worse, string results)
if SLApproachMain.debugLogFlag
	Debug.notification(results)
endif
	SLAppPCSex.ExternalTrigger(akRef, Worse, 1)
EndEvent

Event SLAPPConsequenceChokeEvent(Form akRef, Bool Worse, string results)
if SLApproachMain.debugLogFlag
	Debug.notification(results)
endif
	SLAppPCSex.ExternalTrigger(akRef, Worse, 2)
EndEvent

Event SLAPPConsequenceChokeNREvent(Form akRef, Bool Worse, string results)
if SLApproachMain.debugLogFlag
	Debug.notification(results)
endif
	SLAppPCSex.ExternalTrigger(akRef, Worse, 3)
EndEvent


Function BaboDialogueReputationMod(float iMod)
GlobalVariable BaboReputation
if SLA_BaboDialogue.getvalue() == 1
	BaboReputation = Game.GetFormFromFile(0x00772769, "BaboInteractiveDia.esp") as GlobalVariable
	float BR = BaboReputation.getvalue()
	BaboReputation.setvalue(BR + iMod)
	SLA_BaboReputation.setvalue(BR + iMod)
endif	
EndFunction

Function BaboDialogueReputationBitchMod(float iMod)
GlobalVariable BaboReputationBitch
if SLA_BaboDialogue.getvalue() == 1
	BaboReputationBitch = Game.GetFormFromFile(0x003CD6F1, "BaboInteractiveDia.esp") as GlobalVariable
	float BR = BaboReputationBitch.getvalue()
	BaboReputationBitch.setvalue(BR + iMod)
	SLA_BaboReputationBitch.setvalue(BR + iMod)
endif	
EndFunction

Function BaboDialogueMercenaryCall(actor MercenaryRef); Instead call the function from SLAPP, BaboDialogue will handle a mercenary.
	int handle = ModEvent.Create("Babo_SLAPPMercenaryEvent")
	form MercenaryRefFrom = MercenaryRef as form
	if (handle)
		ModEvent.PushForm(handle, MercenaryRef)
		ModEvent.Send(handle)
	endIf
EndFunction

Function TakeArmor(Actor Victim, Actor Pervert, Keyword ArmorKeyword)
	Armor ThisArmor = FindArmor(Victim, True, ArmorKeyword)
	;BaboPropertyRegister()
	Victim.removeitem(ThisArmor, 1, SLApproachMain.BaboChestWhiterunRef)
EndFunction

Armor Function FindArmor(Actor target, Bool Keywordswitch = False, Keyword TargetArmor)
	int slotsChecked
	slotsChecked += 0x00100000
	slotsChecked += 0x00200000 ;ignore reserved slots
	slotsChecked += 0x80000000

	int thisSlot = 0x01
	while (thisSlot < 0x80000000)
		if (Math.LogicalAnd(slotsChecked, thisSlot) != thisSlot)
			Armor thisArmor = target.GetWornForm(thisSlot) as Armor
			if (thisArmor && thisArmor.HasKeyword(TargetArmor))
				return thisarmor
			Else
				slotsChecked += thisSlot
			EndIf
		endif
		thisSlot *= 2 ;double the number to move on to the next slot
	endWhile
EndFunction

;Function BaboPropertyRegister()
;	BaboChestWhiterunRef = Game.GetFormFromFile(0x00e46567, "BabointeractiveDia.esp") as objectreference
;Endfunction


SexLabFramework Property SexLab  Auto  
SLApproachMainScript Property SLApproachMain auto
SLAppPCSexQuestScript Property SLAppPCSex auto

; overwrite by real approach quests
Quest Property ApproachQuest  Auto
string Property ApproachName Auto
Quest Property HelperQuest  Auto
Quest Property SLApproach_ExternalMods auto
ReferenceAlias Property HelperRef  Auto  
ReferenceAlias Property HelpRaperRef  Auto  
;------

Location Property BYOHHouse1LocationInterior Auto
Location Property BYOHHouse2LocationInterior Auto
Location Property BYOHHouse3LocationInterior Auto
Location Property WhiterunBreezehomelocation Auto
Location Property SolitudeProudspireManorLocation Auto
Location Property MarkarthVlindrelHallLocation Auto
Location Property RiftenHoneysideLocation Auto
Location Property WindhelmHjerimLocation Auto

Keyword Property LocTypePlayerHouse Auto
Formlist Property SLApproachPlayerHouse Auto
Formlist Property SLApproachPlayerHouseBYOH01 Auto
Formlist Property SLApproachPlayerHouseBYOH02 Auto
Formlist Property SLApproachPlayerHouseBYOH03 Auto
Formlist Property SLApproachPlayerHouseWhiterun Auto
Formlist Property SLApproachPlayerHouseMarkarth Auto
Formlist Property SLApproachPlayerHouseRiften Auto
Formlist Property SLApproachPlayerHouseSolitude Auto
Formlist Property SLApproachPlayerHouseWindhelm Auto
Formlist Property SLApproachPotentialHouseVisitors Auto

Faction Property isguardfaction  Auto  
Race Property ElderRace  Auto  
Race Property HorseRace  Auto  
Race Property ManakinRace  Auto  
Race Property DremoraRace  Auto  

Armor Property SLAppRingShame  Auto  
Armor Property SLAppRingFamily  Auto  

Faction Property JobJarlFaction  Auto
Faction Property Banditfaction  Auto
Faction Property WINeverFillAliasesFaction  Auto

Faction Property slapp_ProstitutionFaction Auto
Faction Property slapp_Characterfaction Auto
Faction Property SLAX_AggressiveFaction Auto
Faction Property slapp_washiringfaction Auto
Faction Property slapp_AquaintedFaction Auto
Faction Property slapp_DislikeFaction Auto
Faction property slapp_DisappointedFaction auto
Faction Property slapp_RapeFailFaction Auto
Faction Property slapp_ReconciliationFaction Auto
Faction Property slapp_NoSpankFaction Auto
Faction Property slapp_NoMolestFaction Auto
Faction Property slapp_GiftGiverFaction Auto
Faction Property slapp_VisitedFaction Auto
Faction Property slapp_StayedFaction Auto
Faction Property slapp_VisitedFailedFaction Auto
Faction Property SexLabAnimatingFaction Auto
Faction Property ThalmorFaction Auto
Faction Property CurrentFollowerFaction Auto
Faction Property PlayerFaction Auto
Faction Property PlayerMarriedFaction Auto
Faction Property CurrentHireling Auto
Faction Property PotentialHireling Auto
Faction Property slapp_VisitingFaction Auto
Faction Property slapp_VisitingEventFaction Auto
Faction Property slapp_VisitingScenePlayFaction Auto
Faction property slapp_KissFaction Auto
Faction Property sla_Exposure Auto
Faction Property GuardDialogueFaction Auto
Faction Property slapp_SpankFaction Auto
Faction Property slapp_MolestFaction Auto
Faction Property slapp_DidSpankFaction Auto
Faction Property slapp_AggressiveBFFaction  Auto
Faction Property slapp_KidFaction  Auto
Faction Property slapp_HaveSeenBody  Auto

LeveledItem Property SLAPPAffectionMiscLVL Auto

GlobalVariable Property SLAStandardLevelMaximumNPCGlobal Auto
GlobalVariable Property SLAStandardLevelMinimumNPCGlobal Auto
GlobalVariable Property SLApproachMoralGlobal Auto
GlobalVariable Property SLA_BaboReputation Auto
GlobalVariable Property SLA_BaboReputationBitch Auto
GlobalVariable Property SLA_BaboDialogue Auto
GlobalVariable Property SLABreastsSlide Auto
GlobalVariable Property SLAAppearanceSlide Auto
GlobalVariable Property SLAButtsSlide Auto

Idle property BaboDrinkNormal auto
Idle property BaboDrinkBlackOut auto
Idle property BaboDrinkBlackOutLoop auto
Sound Property SLAPPMarker_DeepKiss  Auto  

Quest Property sla_Framework Auto
