scriptName MineOreScript extends objectReference ; ;This script handles the Ore Veins and handshakes with the mining furniture ;=================================================================== sound property DrScOreOpen auto {sound played when Ore is acquired} formlist property mineOreToolsList auto {Optional: Player must have at least one item from this formlist to interact} Message Property FailureMessage Auto {Message to say why you can't use this without RequiredWeapon} Message Property DepletedMessage Auto {Message to say that this vein is depleted} MiscObject Property Ore Auto {what you get from this Ore Vein} LeveledItem property lItemGems10 auto {Optional: Gems that may be mined along with ore} int Property ResourceCount = 1 Auto {how many resources you get per drop} int property ResourceCountTotal = 3 auto {how many resources this has before it is depleted} int property ResourceCountCurrent = -1 auto Hidden {Used to track the current remaining resources} int property StrikesBeforeCollection = 1 Auto {how many times this is struck before giving a resource} int property StrikesCurrent = -1 Auto hidden {Current number of strikes} int property AttackStrikesBeforeCollection = 3 Auto {how many times this is struck by attacks before giving a resource} int property AttackStrikesCurrent = -1 Auto hidden {Current number of attack strikes} Actor Property PlayerREF Auto GlobalVariable Property _00E_OreVeinsMined Auto Form[] EquippedTorches Bool PlayerIsInFurniture = False Bool PlayerActivationLocked = False ;=================================================================== ;;EVENT BLOCK ;=================================================================== event onCellAttach() ; debug.Trace(self + ": is running onCellAttach") blockActivation() SetNoFavorAllowed() If !PlayerREF ; Just in case PlayerREF = Game.GetPlayer() EndIf if !getLinkedRef() ; debug.Trace(self + ": does not have a linked ref, going to depleted state") depleteOreDueToFailure() endif ; Failsafes PlayerIsInFurniture = False PlayerActivationLocked = False Int iHand = 0 While iHand < EquippedTorches.Length EquippedTorches[iHand] = None iHand += 1 EndWhile endEvent Event OnUnload() ; Do not do here failsafes or safety measures. The event is triggered on the vein's depletion endEvent Function TryPlayerActivate(ObjectReference myLinkedRef) If PlayerIsInFurniture == False || myLinkedRef.isFurnitureInUse() == False ; Entering the furniture ; Fail if the player is in combat ; Yes, the furniture has a check for this built into the engine, but the furniture's code has no way to know about it, ; so if the player IS in combat, the furniture still enters the "busy" state and does not leave it until a second try by the player or until it's unloaded. ; The check is not a panacea for this bug, but it decreases the probability of it happening. ; As a bonus, this early check prevents useless fail messages, forced exit from sneaking, and so on. If PlayerREF.IsInCombat() Debug.Notification(Game.GetGameSettingString("sCombatCannotActivate")) Return EndIf If ResourceCountCurrent == 0 DepletedMessage.Show() Return EndIf If PlayerREF.GetItemCount(mineOreToolsList) < 1 FailureMessage.Show() Return EndIf ;USKP 1.3.0 FixStart - Deactivate sneaking before mining to prevent sneak issues. if PlayerREF.IsSneaking() PlayerREF.StartSneaking() EndIf ;USKP 1.3.0 FixEnd EquippedTorches = New Form[2] If (PlayerREF as _00E_PlayerFunctions).UnequipTorches(EquippedTorches) Utility.Wait(0.25) ; Give some time for torch unequip animations to settle EndIf ; Do combat check again (up to one third of a second may have passed since the previous check) If PlayerREF.IsInCombat() Debug.Notification(Game.GetGameSettingString("sCombatCannotActivate")) Return EndIf PlayerIsInFurniture = True EndIf (myLinkedRef as mineOreFurnitureScript).lastActivateRef = self myLinkedRef.activate(PlayerREF) ; Give some time for the animations to warm up/settle down before we can start reacting on OnActivate again. ; Without this the furniture (MineOreFurnitureScript) may get stuck in "reseting" state until it's unloaded. Utility.Wait(1) EndFunction event onActivate(objectReference akActivator) ; debug.Trace(self + ": onActivate by " + akActivator) ObjectReference myLinkedRef = GetLinkedRef() If !myLinkedRef Debug.Trace(self + " error: this ore does not have a linkedRef") Return EndIf ;Actor is attempting to mine if akActivator as actor ;if the actor is the player if akActivator == PlayerREF If PlayerActivationLocked == False PlayerActivationLocked = True TryPlayerActivate(myLinkedRef) PlayerActivationLocked = False EndIf Else myLinkedRef.Activate(akActivator) EndIf ;Furniture is telling ore it has been struck ElseIf akActivator == myLinkedRef ; debug.Trace(self + ": has been activated by" + akActivator) ProccessStrikes() ;Something unexpected has activated the ore Else ; debug.Trace(self + "has been activated by: " + akActivator + " why?") endif endEvent ;;;May add on hit with pickaxe here later Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) ; ADDED IN ENDERAL - FORGOTTEN STORIES if ResourceCountCurrent == -1 ResourceCountCurrent = ResourceCountTotal EndIf _00E_FS_ForgottenStories_Functions _00E_FS_ControlQuest = Game.GetFormFromFile(0x01016E89, "Enderal - Forgotten Stories.esm") as _00E_FS_ForgottenStories_Functions _00E_FS_ControlQuest.TransmuteOre(akSource, self as MineOreScript, ResourceCountCurrent) ; ADDED IN ENDERAL - FORGOTTEN STORIES ; debug.Trace(self + ": onHit - akAgressor = " + akAggressor + "; akSource = " + akSource) if akAggressor == PlayerREF if mineOreToolsList.hasForm(akSource) proccessAttackStrikes() endif endif endEvent event onReset() ; debug.Trace(self + ": is running onReset") ;THIS WASN'T WORKING RIGHT self.Reset() self.clearDestruction() self.setDestroyed(False) ; if getLinkedRef() resourceCountCurrent = -1 ; else ; depleteOreDueToFailure() ; endif ;USKP 1.3.0 FixStart - if ore is enabled then disable and enable to avoid becoming un-mineable upon respawn. if self.isEnabled() self.disable() self.enable() endif ;USKP 1.3.0 FixEnd endEvent ; Called from the linkedRef (MineOreFurnitureScript) Function OnFurnitureExit() ; Debug.Trace(self + ": OnFurnitureExit") If PlayerIsInFurniture PlayerIsInFurniture = False (PlayerREF as _00E_PlayerFunctions).ReequipTorches(EquippedTorches) EndIf EndFunction ;=================================================================== ;;FUNCTION BLOCK ;=================================================================== function proccessAttackStrikes() if AttackStrikesCurrent <= -1 AttackStrikesCurrent = AttackStrikesBeforeCollection EndIf AttackStrikesCurrent -= 1 if AttackStrikesCurrent == 0 AttackstrikesCurrent = AttackStrikesBeforeCollection giveOre() endIf endFunction function proccessStrikes() if StrikesCurrent <= -1 StrikesCurrent = StrikesBeforeCollection EndIf StrikesCurrent -= 1 if StrikesCurrent == 0 strikesCurrent = StrikesBeforeCollection giveOre() endIf endFunction function giveOre() ObjectReference myLinkedRef = GetLinkedRef() If !myLinkedRef Debug.Trace(self + " error: this ore does not have a linkedRef") Return EndIf if ResourceCountCurrent == -1 ResourceCountCurrent = ResourceCountTotal EndIf if ResourceCountCurrent > 0 ResourceCountCurrent -= 1 ; debug.Trace(self + ": ResourceCountCurrent = " + ResourceCountCurrent) if ResourceCountCurrent == 0 ; debug.Trace(self + ": ResourceCountCurrent == 0 - depleted" ) self.damageObject(50) myLinkedRef.activate(self) DrScOreOpen.play(self) self.setDestroyed(true) ; if this vein has ore and/or gems defined, give them. if ore PlayerREF.addItem(Ore, ResourceCount) endif if lItemGems10 PlayerREF.addItem(lItemGems10) endif _00E_OreVeinsMined.SetValueInt(_00E_OreVeinsMined.GetValueInt() +1) DepletedMessage.Show() else DrScOreOpen.play(self) ; if this vein has ore and/or gems defined, give them. if ore PlayerREF.addItem(Ore, ResourceCount) endif if lItemGems10 PlayerREF.addItem(lItemGems10) endif endif elseif ResourceCountCurrent == 0 myLinkedRef.activate(self) (myLinkedRef as MineOreFurnitureScript).goToDepletedState() DepletedMessage.Show() endif EndFunction function depleteOreDueToFailure() self.damageObject(50) ;THIS WASN'T WORKING RIGHT self.setDestroyed(true) ResourceCountCurrent = 0 endFunction