Scriptname zbfUtil Hidden

; Returns the zbf script which holds all global data. See GetMain() for more info.
zbfBondageShell Function GetBS() Global
	Return zbfUtil.GetMain()
EndFunction

; Returns the zbf script which holds all global data. See GetMain() for more info.
zbfBondageShell Function GetShell() Global
	Return zbfUtil.GetMain()
EndFunction

; Returns the zbf script which holds all global data.
;
; Example:
; zbfUtil.GetMain().RetainAi()
; Makes the player ai driven. Is reference counted, so several instances can request ai control without interfering with each other.
zbfBondageShell Function GetMain() Global
	zbfBondageShell zbf
	
	zbf = Game.GetFormFromFile(0x020137E6, "ZaZAnimationPack.esm") as zbfBondageShell
	If zbf == None
		zbf = Game.GetFormFromFile(0x020137E6, "ZaZAnimationPack.esp") as zbfBondageShell
	EndIf
	
	Return zbf
EndFunction

; Returns the zbfSexLab script which handles SexLab compatibility
;
zbfSexLab Function GetSexLab() Global
	zbfSexLab zbfSL
	
	zbfSL = Game.GetFormFromFile(0x0200CD14, "ZaZAnimationPack.esm") as zbfSexLab
	If zbfSL == None
		zbfSL = Game.GetFormFromFile(0x0200CD14, "ZaZAnimationPack.esp") as zbfSexLab
	EndIf
	
	Return zbfSL
EndFunction

; Puts on an armor item on the actor. The item itself is duplicated onto the character, so it's not removed from it's original container.
; 
; akActor - Actor to wear the item
; akArmor - Armor to place on the actor. Duplicates the item, original is not removed from it's container.
; abForced - Prevents removal by the character.
;
; Example:
; zbfUtil.WearItem(PlayerRef, WristBindings, abForced = True)
; Forces the player to wear WristBindings, and they can't be removed through the normal inventory screen.
Function WearItem(Actor akActor, Form akItem, Bool abForced = False) Global
	akActor.AddItem(akItem, aiCount = 1, abSilent = True)
	akActor.EquipItem(akItem, abPreventRemoval = abForced, abSilent = True)
EndFunction

; Unequips an item on the actor. Opposite of WearItem. The item, or a similar item, is destroyed in the process.
;
; akActor - Actor to unequip the armor.
; akArmor - Armor type to unequip. The item is not placed in the characters actors inventory.
; 
; Example:
; zbfUtil.UnwearItem(PlayerRef, WristBindings)
; Frees the player from wrist bindings. The bindings are not retained in the inventory.
Function UnWearItem(Actor akActor, Form akItem, Bool abForced = False) Global
	akActor.UnequipItem(akItem, abPreventEquip = abForced, abSilent = True)
	akActor.RemoveItem(akItem, aiCount = 1, abSilent = True)
EndFunction

; Conditionally wears an item
;
; Wears the item if
; a) Item is not already worn
; b) abCond evaluates to True

Function WearItemCond(Actor akActor, Form akItem, Bool abForced = False, Bool abCond = True) Global
	If (akActor.IsEquipped(akItem) == False) && (abCond == True)
		akActor.AddItem(akItem, aiCount = 1, abSilent = True)
		akActor.EquipItem(akItem, abPreventRemoval = abForced, abSilent = True)
	EndIf
EndFunction

; Conditionally unwears an item
;
; Unwears the item if
; a) Item is worn
; b) abCond evaluates to True
Function UnWearItemCond(Actor akActor, Form akItem, Bool abForced = False, Bool abCond = True) Global
	If (akActor.IsEquipped(akItem) == True) && (abCond == True)
		akActor.UnequipItem(akItem, abPreventEquip = abForced, abSilent = True)
		akActor.RemoveItem(akItem, aiCount = 1, abSilent = True)
	EndIf
EndFunction

; Returns the current version of Zaz Animation Pack.
;
; Higher number means later versions.
Int Function GetVersion() Global
	Return 600
EndFunction

; Returns the current version of Zaz Animation Pack as a human readable string.
; 
String Function GetVersionStr() Global
	Return "6.00"
EndFunction

; Places akObjA behind akObjB, according to akObjB's facing
;
; Works well to use with the pillory animations.
; This function is identical to MoveToFront with a negative distance and different default distance.
Function MoveToBehind(ObjectReference akObjB, ObjectReference akObjA, Float afDistance = 45.0) Global
	akObjA.MoveTo(akObjB, -afDistance * Math.Sin(akObjB.GetAngleZ()), -afDistance * Math.Cos(akObjB.GetAngleZ()), 0.0)
EndFunction

; Places object A in front of object B at the specified distance.
;
; This function is identical to MoveToBehind with a negative distance and different default distance.
Function MoveToFront(ObjectReference akObjB, ObjectReference akObjA, Float afDistance = 120.0) Global
	akObjA.MoveTo(akObjB, afDistance * Math.Sin(akObjB.GetAngleZ()), afDistance * Math.Cos(akObjB.GetAngleZ()), 0.0)
EndFunction

; Convenience function to lock ai
Function RetainAi() Global
	GetMain().RetainAi()
EndFunction

; Convenience function to release ai
Function ReleaseAi() Global
	GetMain().ReleaseAi()
EndFunction

; Actor scale is composed of two parts, B (base from CK) and S (console scale from console or papyrus)
; D (display scale) = B * S
; 
; Sets an actor display scale to a specified value.
; 
; Returns the previous scale factor (S) to make restoration easy. (Use SetScale from console or papyrus.)
Float Function SetActorDisplayScale(Actor akActor, Float afScale) Global
	; Identities:
	; 
	; D = S * B
	; D' = S' * B'
	; B = B'
	; S' = 1.0
	; 
	Float D = akActor.GetScale()
	akActor.SetScale(1.0)
	Float Dprim = akActor.GetScale()
	; B = B' = D' / S' = D'
	
	akActor.SetScale(afScale / Dprim)
	Return D / Dprim ; S = D / B = D / D'
EndFunction

; Helper function to create an array of strings
; 
String[] Function StrList(String asS1 = "", String asS2 = "", String asS3 = "", String asS4 = "", String asS5 = "", String asS6 = "") Global
	String[] list
	If asS1 == ""
		Return list ; Just an empty list then ....
	ElseIf asS2 == ""
		list = New String[1]
		list[0] = asS1
	ElseIf asS3 == ""
		list = New String[2]
		list[0] = asS1
		list[1] = asS2
	ElseIf asS4 == ""
		list = New String[3]
		list[0] = asS1
		list[1] = asS2
		list[2] = asS3
	ElseIf asS5 == ""
		list = New String[4]
		list[0] = asS1
		list[1] = asS2
		list[2] = asS3
		list[3] = asS4
	ElseIf asS6 == ""
		list = New String[5]
		list[0] = asS1
		list[1] = asS2
		list[2] = asS3
		list[3] = asS4
		list[4] = asS5
	Else
		list = New String[6]
		list[0] = asS1
		list[1] = asS2
		list[2] = asS3
		list[3] = asS4
		list[4] = asS5
		list[5] = asS6
	EndIf
	Return list
EndFunction
