Scriptname __LALLActorQuestScript extends Quest  
{Script for global LALL things and sex thread handling}

SexlabFramework Property Sexlab Auto
Actor Property PlayerRef Auto
zbfBondageShell Property Zaz Auto
zbfSexlab Property zsl Auto

Quest Property TrackedQuestToSet Auto Hidden
Int Property TrackedQuestStage Auto Hidden


;==============
;Functions
;==============
;Untracked thread
Function NormalThread(actor with = none,string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
	Actor[] ThreadActors
	if with != none
	ThreadActors = new Actor[2]
	else
	ThreadActors = new Actor[1]
	endif
ThreadActors[0] = PlayerRef
	if with != none
	ThreadActors[1] = with
	endif
Thread.AddActors(ThreadActors)
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(ThreadActors.Length,Tags,"",false)
endif
Thread.SetAnimations(anims)
Thread.StartThread()
EndFunction

;Untracked thread with actor array
Function NormalThreadArray(actor[] with,string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
Thread.AddActors(with)
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(with.Length,Tags,"",false)
endif
Thread.SetAnimations(anims)
Thread.StartThread()
EndFunction

;Tracked thread that sets a quest stage on finishing
Function TrackedThreadQuest(actor with = none,quest which,int stage, string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
Actor[] ThreadActors	
if with != none
	ThreadActors = new Actor[2]
	else
	ThreadActors = new Actor[1]
	endif
ThreadActors[0] = PlayerRef
	if with != none
	ThreadActors[1] = with
	endif
Thread.AddActors(ThreadActors)
Thread.SetAnimations(anims)
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(ThreadActors.Length,Tags,"",false)
endif
Thread.SetHook("TheHook")
RegisterForModEvent("HookAnimationEnd_TheHook","SexAnimEndedLALL")
TrackedQuestToSet = which
TrackedQuestStage = stage
Thread.StartThread()
EndFunction

;Tracked thread that sets a quest stage on finishing with array
;Youd think I'd be a smart potato and just make them all with arrays
Function TrackedThreadQuestArray(actor[] with,quest which,int stage, string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
Thread.AddActors(with)
Thread.SetAnimations(anims)
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(with.Length,Tags,"",false)
endif
Thread.SetHook("TheHook")
RegisterForModEvent("HookAnimationEnd_TheHook","SexAnimEndedLALL")
TrackedQuestToSet = which
TrackedQuestStage = stage
Thread.StartThread()
EndFunction

Message Property ReservedMessage Auto Hidden

;Tracked thread that shows a message when sex finishes
Function TrackedThreadMessage(actor with = none,message toShow = none,string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
Actor[] ThreadActors
if with != none
	ThreadActors = new Actor[2]
	else
	ThreadActors = new Actor[1]
	endif
ThreadActors[0] = PlayerRef
	if with != none
	ThreadActors[1] = with
	endif
Thread.AddActors(ThreadActors)
Thread.SetAnimations(anims)
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(ThreadActors.Length,Tags,"",false)
endif
Thread.SetHook("MessageHook")
RegisterForModEvent("HookAnimationEnd_MessageHookLALL","MessageSexAnimEnded")
ReservedMessage = toShow
Thread.StartThread()
EndFunction

;Non tracked thread that returns a desired integer
Int Function FillIntThread(actor with, int value, string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
Actor[] ThreadActors = new Actor[2]
ThreadActors[0] = PlayerRef
ThreadActors[1] = with
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(ThreadActors.Length,Tags,"",false)
endif
Thread.SetAnimations(anims)
Thread.AddActors(ThreadActors)
Thread.StartThread()
return value
EndFunction

;Non tracked thread that returns a desired integer but uses an actor array
Int Function FillIntThread2(actor[] with, int value, string tags = "")
sslThreadModel Thread = sexlab.NewThread()
sslBaseAnimation[] anims
if tags != ""
anims = (sexlab.AnimSlots).GetByTags(with.Length,Tags,"",false)
endif
Thread.SetAnimations(anims)
Thread.AddActors(with)
Thread.StartThread()
return value
EndFunction

;Binds NPC to a furniture and plays a sex scene. After the scene, they are released from the furniture. First actor is bound to furniture, second actor is in the sex scene
Function BindFurnitureScene(actor[] toBind,objectReference furn)
zaz.SlotActor(toBind[0])
zbfSlot zslot = zaz.FindSlot(toBind[0])
zslot.SetFurniture(furn)
zSlot.PinActor()

Actor[] actors = zbfUtil.ActorList(ToBind[0],ToBind[1])
zbfSexLabBaseEntry[] list = zsl.GetEntriesByTags(actors, "", aiMinActorCount = 2)  
Int success = zsl.StartSex(actors, list, Victim = ToBind[0], Hook = "MyHook")
RegisterForModEvent("AnimationEnding_MyHook","FurnitureSceneEnd")
int i = 0
while BoundActors[i] != none && i < 13
i += 1
endwhile
BoundActors[i] = toBind[0]
EndFunction

Actor[] Property BoundActors Auto


Function ReleaseFurniture(int tid)
int idx = 0
int controller = sexlab.FindActorController(BoundActors[idx])
while controller != tid && idx < 13
idx+= 1
controller = sexlab.FindActorController(BoundActors[idx])
endwhile
zbfSlot zSlot = zaz.FindSlot(BoundActors[idx])
zSlot.UnpinActor()
zslot.SetFurniture(none)
EndFunction

;==============
;Events
;==============

Event MessageSexAnimEndedLALL(int tid, bool hasPlayer)
int thr = Sexlab.FindActorController(PlayerRef)
if thr == tid
ReservedMessage.Show()
ReservedMessage = none
endif
UnregisterForModEvent("MessageSexAnimEnded")
UnregisterForModEvent("HookAnimationEnd_MessageHook")
endEvent

Event FurnitureSceneEnd(int tid, bool hasPlayer)
EndEvent

;Should only be called with tracked thread function
;Changed event name so it doesnt unregister sexlab music
Event SexAnimEndedLALL(int tid, bool hasPlayer)
TrackedQuestToSet.SetStage(TrackedQuestStage)
UnregisterForModEvent("SexAnimEndedLALL")
UnregisterForModEvent("HookAnimationEnd_TheHook")
EndEvent