Jump to content

I've Been Told It Cant Be Done: Pickaxe Animations


Recommended Posts

@Chris20201986

I know SKSE can change NIF assignments for armor and weapons via papyrus. But if there is a way to change it for animated objects, I do not know. If there is such a way, this is probably where it needs to be done. I wonder if an SKSE DLL plugin or Net Framework DLL plugin would have this kind of capability...

 

[00] Skyrim.esm (AF75991D) \ Animated Object \ 00031983 <AnimObjectPickAxeWall>

This uses the mesh:

AnimObjects\AnimObjectPickAxe.nif

 

And for completion sake:

[02] Dragonborn.esm (0EB10E82) \ Animated Object \ 0203A330 <DLC02AnimObjectPickAxeWall>

This uses the mesh:

AnimObjects\DLC02\DLC02AnimObjectPickaxeWall.nif

Link to comment
Share on other sites

  • Replies 43
  • Created
  • Last Reply

Top Posters In This Topic

Wait I had another thought. Change the animation art object so it uses null texture set (make it invisible) then just equip a pickaxe in inventory. Unequip after use. Youâd still need a way to detect when mining.
Link to comment
Share on other sites

Wait I had another thought. Change the animation art object so it uses null texture set (make it invisible) then just equip a pickaxe in inventory. Unequip after use. Youâd still need a way to detect when mining.

Would that even work? I would think that the player would end up using no axe during the animation (cause it is invisible). And then all NPCs would be using an invisible axe as well.

 

 

Ah I see your point. Still you could edit the vanilla script and place a new furniture that the player uses based on which axe they have in their inventory, then delete it after use.

The question still remains, how to get a new furniture to use a new animation object? Its simple enough to replace the default pickaxe with something else in the NIF file. But if it has a different name, how would the game know to use it? That is the original question.

Link to comment
Share on other sites

@dybill

Your two approaches will not work. The stock script already allows for any pickaxe in the MineOreToolsList to be used to obtain ore via the OnHit event. It is the OnActivate event and the animation event that is of concern here. There is no equipping of the pickaxe ever taking place. It is completely visually done within the animation event. This is why I suggested different animations.

 

@Chris20201986

See if you can tell a difference between the Stalhrim ore veins and base game ore veins (animations used etc). The Stalhrim requires a specific pickaxe in the un-modded game. I know there is a formlist for it that is assigned to the MineOreToolsList property (instead of auto-filling it), but if I recall correctly the animation uses the correct pickaxe for at least the Stalhrim veins.

@dylbill That would be more work than it was worth. Placing a new furniture for every pickaxe....there are 2 formlists: 1 for regular mining and one for stalhrim.

 

@isharameradin I found both scripts and all kinds of different things linking to this and that. What is frustrating is that the 2 scripts for ore mining doesn't make "plainly visible" where it draws its animation from nor where it actually "grabs" the animobject pickaxe01 (idr what the actual name is used off the top of my head for the animobject). Also there are 4 types of pickaxe furniture animations: pickaxetableroot, pickaxewallroot, pickaxefloorroot and pickaxeroot. So I may have alot of work either route lol. My thought was just to make siblings of every anim for each pickaxe type and since the animobject gets called upon to attach to the bone of the animation it should work that easy. The issue is finding THAT connection where SOMETHING calls upon the animobject. I even dove into the animsetdata files trying to find it in the text files.

Link to comment
Share on other sites

But the player doesn't need to equip the axe in order to play the animations. And if they have the axe equipped, in all likelihood they are going to attack it. In which case, the animation would never play. I do not see the benefit in using OnObjectEquipped in this scenario.

This is true. The animation 1st begins with equipping the pickaxe version as an animobject NOT what the player has in their inventory.

Link to comment
Share on other sites

It would not because of the animation that plays 1st before the mining animation. That 1st animation forces 3rd person to enequip players weapon.

I wonder if it might be defined in the hkx files which can be extracted from the BSA files

Meshes > Actors > Character > Animations > idlepickaxe_*.hkx

 

I did find these animations but I am ilequiped to access the .hkx files. I DO know that the .nif has a block for what bone to attach to on the skeleton during animation.

Link to comment
Share on other sites

I think you misunderstood me. All you need to do is make a new furniture base form for each new pickaxe, then have the script place the new furniture at the old one and have the player activate that instead. Make sure the mineOreToolsList and your furniture formlist index's line up. To edit the vanilla script I would do something like this:

 

 

 

;
;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}

mineOreFurnitureScript property myFurniture auto hidden
{the furniture for this piece of ore, set in script}

objectReference property objSelf auto hidden
{objectReference to self}

AchievementsScript property AchievementsQuest auto

Location Property CidhnaMineLocation Auto

Quest Property MS02 Auto

Quest Property DialogueCidhnaMine Auto

ObjectReference Property CidhnaMinePlayerBedREF Auto

;changed==================================================
Formlist Property PickaxeFurnitures Auto Hidden
{Formlist of Furniture base forms}

ObjectReference Property PickaxeFurniture Auto Hidden
{Furniture ObjectReference the player uses. Placed with this script.}
;changed===================================================================

;===================================================================
;;EVENT BLOCK
;===================================================================

event onCellAttach()
;   debug.Trace(self + ": is running onCellAttach")
    blockActivation()
    SetNoFavorAllowed()
    objSelf = self as objectReference
    if !getLinkedRef()
;       debug.Trace(self + ": does not have a linked ref, going to depleted state")
        depleteOreDueToFailure()
    endif
    
    ;changed===================================================================
    If PickaxeFurnitures == None 
        PickaxeFurnitures = Game.GetFormFromFile(0x345678, "MyMod.Esp") as formlist ;get formlist from mod
    Endif
    ;============================================================================
endEvent

event onActivate(objectReference akActivator)
;   debug.Trace(self + " has been activated by " + akActivator)
    
    ;Actor is attempting to mine
    if akActivator as actor
        ;if the actor is the player
        if akActivator == game.getPlayer()
            ;if this is not depleted and the player has the right item
            
            ;changed==================================
            Int PlayerToolIndex = GetPlayerToolIndex() 
            ;changed=================================

            If ResourceCountCurrent == 0
                DepletedMessage.Show()

            ;changed =========================
            elseif PlayerToolIndex < 0
                FailureMessage.Show()
            ;changed =========================

            ;enter the furniture
            else
                If Game.GetPlayer().GetCurrentLocation() == CidhnaMineLocation && MS02.ISRunning() == False
;                   debug.Trace(self + "Player is in Cidhna Mine, activate the bed to serve time")
                    CidhnaMinePlayerBedREF.Activate(Game.GetPlayer())
                    DialogueCidhnaMine.SetStage(45)
                    Return
                 EndIf
                 ;  debug.Trace(self + " should cause " + akActivator + " to activate " + getLinkedRef())
                 if getLinkedRef()
                     
                    ;changed==========================================================================
                    If PickaxeFurnitures != None
                        PickaxeFurniture = getLinkedRef().PlaceAtMe(PickaxeFurnitures.GetAt(PlayerToolIndex)) 
                        ;Place new invisible furniture for player to use at existing furniture 
                        
                        myFurniture = PickaxeFurniture as mineOreFurnitureScript
                        myFurniture.lastActivateRef = objSelf
                        PickaxeFurniture.activate(akActivator)
                        AchievementsQuest.incHardworker(2)
                        
                        While PickaxeFurniture.IsFurnitureInUse() ;wait till player stops using furniture
                            Utility.Wait(2) 
                        EndWhile
                        
                        ;delete new furniture
                        PickaxeFurniture.Disable()
                        PickaxeFurniture.Delete() 
                        PickaxeFurniture = None
                    ;=========================================================================================
                    
                    Else ;vanilla ==========================================================================
                        myFurniture = getLinkedRef() as mineOreFurnitureScript
                        myFurniture.lastActivateRef = objSelf
                        getLinkedRef().activate(akActivator)
                        AchievementsQuest.incHardworker(2)
                    Endif ;==================================================================================
                 Else
;                   debug.Trace(self + ": error this ore does not have a linkedRef")
                 EndIf
            endif
        Else
            if getLinkedRef()
                getLinkedRef().activate(akActivator)
            Else
;               debug.Trace(self + ": error this ore does not have a linkedRef")
            endif
        EndIf
        
    ;Furniture is telling ore it has been struck    
    ElseIf akActivator == GetLinkedRef()
;       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)
;   debug.Trace(self + ": onHit - akAgressor = " + akAggressor + "; akSource = " + akSource)
    if akAggressor == game.getPlayer()
        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
endEvent

;===================================================================
;;FUNCTION BLOCK
;===================================================================

;changed =================================================
Int function GetPlayerToolIndex()
    if Game.GetPlayer().GetItemCount(mineOreToolsList) > 0
;       debug.Trace(self + ": playerHasTools is returning true")
        Int M = mineOreToolsList.GetSize() 
        While M > 0 
            M -= 1 
            Form Tool = mineOreToolsList.GetAt(M) 
            If Game.GetPlayer().GetItemCount(Tool) > 0 
                Return M
            Endif 
        EndWhile 
        
        Return -1
    Else
;       debug.Trace(self + ": playerHasTools is returning false")
        return -1
    endIf
endFunction
;changed ===============================================================

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()
    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)
            getLinkedRef().activate(objSelf)
            DrScOreOpen.play(self)
            self.setDestroyed(true)
            ; if this vein has ore and/or gems defined, give them.
            if ore
                (game.getPlayer()).addItem(Ore, ResourceCount)
            endif
            if lItemGems10
                (game.getPlayer()).addItem(lItemGems10)
            endif
            DepletedMessage.Show()
        else
            DrScOreOpen.play(self)
            ; if this vein has ore and/or gems defined, give them.
            if ore
                (game.getPlayer()).addItem(Ore, ResourceCount)
            endif
            if lItemGems10
                (game.getPlayer()).addItem(lItemGems10)
            endif
        endif
    elseif ResourceCountCurrent == 0
        getLinkedRef().activate(objSelf)
        (getLinkedRef() as MineOreFurnitureScript).goToDepletedState()
        DepletedMessage.Show()
    endif

EndFunction

function depleteOreDueToFailure()
    self.damageObject(50)
    ;THIS WASN'T WORKING RIGHT
    self.setDestroyed(true)
    ResourceCountCurrent = 0
endFunction

I put the changes I made in between
;changed====================================================
;changed====================================================
You can compare with the vanilla script.
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...