Scriptname _00E_ContainerBonusControl extends Quest Hidden
; This script sets up the sleight of hand loot of a chest upon activating it 

int function _GetScriptVersion() Global
    return 1
endFunction

;=====================================================================================
;              							FUNCTIONS                 					 
;=====================================================================================

function OnOpenContainer(ObjectReference targetContainer)

	; Lockpicking menu
	while targetContainer.IsLocked() && Utility.IsInMenuMode()
		Utility.WaitMenuMode(1.0)
	endwhile

	; Game mode and still locked
	if targetContainer.IsLocked()
		return
	endif

	; Wait for it to open
	int i
	while i < 20 && targetContainer.GetOpenState() == 2 && ! Utility.IsInMenuMode()
		Utility.Wait(0.1)
		i += 1
	endwhile

	; Leave if we are not in the container menu yet
	if SKSE.GetVersion()
		if ! UI.IsMenuOpen("ContainerMenu")
			return
		endif
	elseif ! Utility.IsInMenuMode()
		return
	endif

	if targetContainer.GetItemCount(_00E_HiddenSlotChecked)
		return
	endif

	targetContainer.AddItem(_00E_HiddenSlotChecked, 1, true)

	if targetContainer.GetItemCount(Gold001) >= 5
		IncrementGold(targetContainer)
	endif

	if _00E_ChestsWithHiddenSlots.HasForm(targetContainer.GetBaseObject())
		OpenHiddenSlot(targetContainer)
	endif

endfunction

Function IncrementGold(ObjectReference targetContainer)

	int iGoldMultiplicator = _00E_GoldMult.GetValue() as int
	
	if iGoldMultiplicator <= 0
		iGoldMultiplicator = 5
	endif

	float fIncrementPercentage = ( PlayerREF.GetActorValue("Lockpicking") / iGoldMultiplicator ) / 100
	int iGoldBuffAmount = ( targetContainer.GetItemCount(Gold001) * fIncrementPercentage ) as Int
	
	if iGoldBuffAmount <= 0
		return
	endif
	
	targetContainer.AddItem(Gold001, iGoldBuffAmount)
	
	if iGoldBuffAmount > 1
		_00E_FS_LockpickingGoldBuffMSG.Show(iGoldBuffAmount as Int)
	EndIf
	
EndFunction

function OpenHiddenSlot(ObjectReference currentContainer, bool bLootMenu = false)

	if ! SetUpHiddenSlot(currentContainer)
		return
	endif
	
	UILockpickingCylinderTurnM.Play(PlayerREF)
	messageToShow.Show()

	if bLootMenu
		containerToFill.RemoveAllItems(currentContainer, true, true)
	else
		; Open hidden container after the original one closes
		Utility.Wait(0.1)
		
		If IsOwned(currentContainer)
			containerToFill.SetFactionOwner(SleightOfHandOwnerFaction)
		Else
			containerToFill.SetFactionOwner(none)
		Endif
		
		containerToFill.lastContainer = currentContainer
		containerToFill.Activate(PlayerREF, false)
	endif
	
	If containerToFill == _00E_FS_SleightOfHand_HiddenSlot_BigSlotREF
		_00E_EPHandler.GiveEP(_00E_BigHiddenSlotExpReward.GetValue() as int)
		If _00E_HiddenSlotAchievementUnlocked.GetValueInt() == 0
			UIEnchantingLearnEffectM.Play(PlayerREF)
			_00E_HiddenSlotAchievementUnlocked.SetValueInt(1)
			Steam.UnlockAchievement("END_HIDDEN_SLOT_01")
		EndIf
	EndIf
	
endfunction

bool function SetUpHiddenSlot(ObjectReference aContainer)

	if ! DoesContainerHaveHiddenSlot()
		return false
	EndIf
	
	messageToShow = GetSlotMessage()
	int iHiddenSlotTier = GetHiddenSlotTier()
	
	int iFormlistIndexOffset = 8*(iHiddenSlotTier - 1)
	int iFormlistIndex
	
	if messageToShow == _00E_FS_SleightOfHand_HiddenSlot_sSmallSlotFound
	
		containerToFill = _00E_FS_SleightOfHand_HiddenSlot_SmallSlotREF as _00E_HiddenSlotContainer
		iFormlistIndex = Utility.RandomInt(0, 2) + iFormlistIndexOffset
		
	Elseif messageToShow == _00E_FS_SleightOfHand_HiddenSlot_sMediumSlotFound
	
		containerToFill = _00E_FS_SleightOfHand_HiddenSlot_MediumSlotREF as _00E_HiddenSlotContainer
		iFormlistIndex = Utility.RandomInt(3, 5) + iFormlistIndexOffset
	
	Elseif messageToShow == _00E_FS_SleightOfHand_HiddenSlot_sBigSlotFound
	
		containerToFill = _00E_FS_SleightOfHand_HiddenSlot_BigSlotREF as _00E_HiddenSlotContainer
		iFormlistIndex = Utility.RandomInt(6, 7) + iFormlistIndexOffset
	
	EndIf
	
	Formlist hiddenSlotFormlist = _00E_FS_HiddenSlotRewardFormlists.GetAt(iFormlistIndex) as Formlist
	AddItemsToContainer(hiddenSlotFormlist, iFormlistIndexOffset, iHiddenSlotTier)
	
	return true
	
EndFunction

Function AddItemsToContainer(Formlist itemsToAdd, int iFormlistIndexOffset, int iHiddenSlotTier)
	
	containerToFill.RemoveAllItems()

	if containerToFill == _00E_FS_SleightOfHand_HiddenSlot_BigSlotREF
	
		if ! itemsToAdd.HasForm(_00E_FS_SleightOfHand_HiddenSlotUsedMarker)
			itemsToAdd.AddForm(_00E_FS_SleightOfHand_HiddenSlotUsedMarker)
		Else
			int iFormlistIndex = Utility.RandomInt(3, 5) + iFormlistIndexOffset
			itemsToAdd = _00E_FS_HiddenSlotRewardFormlists.GetAt(iFormlistIndex) as Formlist
			messageToShow = _00E_FS_SleightOfHand_HiddenSlot_sMediumSlotFound
		EndIf
		
	EndIf

	containerToFill.AddItem(itemsToAdd, 1, true)
	
	if itemsToAdd.HasForm(Gold001)
		containerToFill.AddItem(Gold001, iHiddenSlotTier * 5 - 1, true)
	endif
	
EndFunction

bool Function DoesContainerHaveHiddenSlot()

	float fHiddenSlotChance = Utility.RandomInt(0, 100)
	
	int iPlayerPickpocketSkill = PlayerREF.GetActorValue("Pickpocket") as Int
	
	; raised the divider from 2 to 2.5, maybe we should raise it even further
	; otherwise too much loot might be given away
	float fPlayerChance = iPlayerPickpocketSkill/2.5
	
	If fPlayerChance < 15
		fPlayerChance = 15
	EndIf
	
	return (fHiddenSlotChance <= fPlayerChance)

EndFunction

int Function GetHiddenSlotTier()

	int iPlayerLevel = PlayerLevel.GetValueInt()

	if iPlayerLevel >= iTierCap_1 && iPlayerLevel < iTierCap_2
		Return 1
	Elseif iPlayerLevel >= iTierCap_2 && iPlayerLevel < iTierCap_3
		Return 2
	Elseif iPlayerLevel >= iTierCap_3 && iPlayerLevel < iTierCap_4
		Return 3
	Elseif iPlayerLevel >= iTierCap_4 && iPlayerLevel < iTierCap_5
		Return 4
	Else
		Return 5
	EndIf
	
EndFunction

Message Function GetSlotMessage()

	; This calculates whether the hidden slot will be filled with a small, a regular, or a rare reward

	int iSlotSize = Utility.RandomInt(1, 100)
	
	if iSlotSize <= iBigSlotChance && PlayerREF.GetActorValue("Pickpocket") >= 75
		return _00E_FS_SleightOfHand_HiddenSlot_sBigSlotFound

	Elseif (iSlotSize > iBigSlotChance) && (iSlotSize <= (iMediumSlotChance + iBigSlotChance)) && PlayerREF.GetActorValue("Pickpocket") >= 50
		return _00E_FS_SleightOfHand_HiddenSlot_sMediumSlotFound
	
	Else
		return _00E_FS_SleightOfHand_HiddenSlot_sSmallSlotFound
	
	EndIf
	
EndFunction

bool Function IsOwned(ObjectReference aContainer)

	If aContainer.GetActorOwner()
		return true
	EndIf
	
	Cell ContainerParentCell = aContainer.GetParentCell()
	
	return ContainerParentCell.GetActorOwner() || ContainerParentCell.GetFactionOwner()
	
EndFunction

;=====================================================================================
;              							PROPERTIES                 					 
;=====================================================================================

; These integers determine at which levels player can access the different tiers
int iTierCap_1 = 0
int iTierCap_2 = 15
int iTierCap_3 = 25
int iTierCap_4 = 35
int iTierCap_5 = 45

; These integers determine the likelihood of the different slot sizes
int iSmallSlotChance = 50
int iMediumSlotChance = 35
int iBigSlotChance = 15

; This formlist will be filled with the formlist containing the items that will actually be added into the container
Message messageToShow 
_00E_HiddenSlotContainer containerToFill

Actor Property PlayerRef  Auto  
ActorBase Property Player  Auto  

GlobalVariable Property PlayerLevel  Auto  
GlobalVariable Property _00E_HiddenSlotAchievementUnlocked  Auto  
GlobalVariable Property _00E_BigHiddenSlotExpReward Auto

; Use this to control how much the lockpicking skill increments the gold found in chest. When changing, remember to change in _00E_LootContainer.psc as well!
; Current calculation: Gold in chest*((Lockpicking/iGoldMultiplicator)/100)
GlobalVariable Property _00E_GoldMult  Auto  

; These REFs simply provide the containers that will be filled when finding a secret slot
ObjectReference Property _00E_FS_SleightOfHand_HiddenSlot_SmallSlotREF  Auto  
ObjectReference Property _00E_FS_SleightOfHand_HiddenSlot_MediumSlotREF  Auto  
ObjectReference Property _00E_FS_SleightOfHand_HiddenSlot_BigSlotREF  Auto  

MiscObject Property Gold001  Auto  
MiscObject Property _00E_FS_SleightOfHand_HiddenSlotUsedMarker  Auto  
MiscObject Property _00E_HiddenSlotChecked  Auto 

Sound Property UILockpickingCylinderTurnM  Auto  
Sound Property UIEnchantingLearnEffectM  Auto  

Message Property _00E_FS_SleightOfHand_HiddenSlot_sSmallSlotFound  Auto  
Message Property _00E_FS_SleightOfHand_HiddenSlot_sMediumSlotFound  Auto  
Message Property _00E_FS_SleightOfHand_HiddenSlot_sBigSlotFound  Auto  

; This contains all formlists with items for the rewards.For every tier, there are nine different treasures to be found, three in small and medium category, two in big.
FormList Property _00E_FS_HiddenSlotRewardFormlists  Auto  
FormList Property _00E_ChestsWithHiddenSlots Auto

Faction Property SleightOfHandOwnerFaction  Auto  

Message Property _00E_FS_LockpickingGoldBuffMSG  Auto