Jump to content

Papyrus - Checking for player as owner of dropped item always returns false?


FiftyTifty

Recommended Posts

One of the hiccups with the Transfer Settlements mod, is that it doesn't export dropped inventory items that have not been interacted with through the workshop menu. Doing so links them to the workbench, which allows them to be exported.

 

So I thought of a solution; make a script that links all nearby player-owned items to the nearest workbench.

 

And it works, right up until I check if the player is the owner of an item. Whether I compare the result of GetActorOwner() to the player actor base record, or GetActorRefOwner() to the player actor ref, it always returns false.

 

The player definitely owns the items, and the items are being passed to the proper variables, so that's not the issue. And I know the player owns the items being processed, as the console command IsOwner shows the player is the owner

 

Any idea what's going weird 'ere?

 

Here's the function with the problem, rest of the script works fine:

 

 

Function LinkItemsToWorkbench()

    bIterating = true
    int iFormListIndex = 0
    ObjectReference objrefWorkshop = Game.FindClosestReferenceOfAnyTypeInListFromRef(AAAFyTy_WorkshopWorkbenchFormList, PlayerRef, 20000)

    While iFormListIndex < iNestedFormlistCount
        
        FormList formlistCurrent = AAAFyTy_PhysicsItemsMasterFormList.GetAt(iFormListIndex) as FormList
        ObjectReference[] objrefarrayFoundItems = PlayerRef.FindAllReferencesOfType(formlistCurrent, iDistance)

        int iFoundItemsCount = objrefarrayFoundItems.Length
        int iFoundItemIndex = 0

        Debug.MessageBox("Found items: "+ iFoundItemsCount as string)

        if iFoundItemsCount > 0
            
            While iFoundItemIndex < iFoundItemsCount
                
                Debug.MessageBox("Adding Item To Workshop At Index: "+ iFoundItemIndex as string)
                
                ObjectReference objrefFoundItem = objrefarrayFoundItems[iFoundItemIndex] as ObjectReference
                bool bPlayerOwnsItem = (objrefFoundItem.GetActorRefOwner() == PlayerRef)

                if bPlayerOwnsItem == true
                    Debug.MessageBox("Linking Item To Workshop")
                    objrefFoundItem.SetLinkedRef(objrefWorkshop, WorkshopItemKeyword)

                EndIf
                
                iFoundItemIndex += 1

            EndWhile

        EndIf
        
        iFormListIndex += 1

    EndWhile

    bIterating = false


EndFunction

 

 

 

All the debug messages before the if bPlayerOwnsItem == true block run just fine. The only one that doesn't display is the one a line up from objrefFoundItem.SetLinkedRef(objrefWorkshop, WorkshopItemKeyword), as bPlayerOwnsItem is always false.

 

Full script: https://pastebin.com/EFK6ejC5

 

So err, any idea why it's always returning false?

 

Edit: So for some reason, the GetActorRefOwner() and GetActorOwner() functions don't return a form on the items, despite them being owned by the player. Checked the FormIDs with the .FormID() function, and it always returns 0 on those two functions.

 

And for some reason, when there is no owner of an item, the game assumes the player owns it (IsOwner console command returns the player), despite the owner not being set.

 

So I need to figure out some way to set the player as the owner for these items.

Edited by FiftyTifty
Link to comment
Share on other sites

I found a less than ideal solution, but a solution nonetheless!

 

Since Papyrus uses 32 bit integers, the higher value FormIDs (e.g, FF000000) are in the negatives; they're signed integers. The behaviour is that past a certain point, the higher hex values start over from the smallest integer value. So FF000000 is the same as -16777216, and FF900000 is the same as -7340032. The higher these FormIDs, the closer to 0 they become. And since every object created at runtime (including spawned NPC's items, unfortunately) has their FormID starting with the FF prefix, we can just compare them.

 

 

if iFormID > FF000000 && iFormID < FFF00000 then
    DoStuff

 

Here's the modified function:

 

Function LinkItemsToWorkbench()

    bIterating = true
    int iFormListIndex = 0
    ObjectReference objrefWorkshop = Game.FindClosestReferenceOfAnyTypeInListFromRef(AAAFyTy_WorkshopWorkbenchFormList, PlayerRef, 20000)

    While iFormListIndex < iNestedFormlistCount
        
        FormList formlistCurrent = AAAFyTy_PhysicsItemsMasterFormList.GetAt(iFormListIndex) as FormList
        ObjectReference[] objrefarrayFoundItems = PlayerRef.FindAllReferencesOfType(formlistCurrent, iDistance)

        int iFoundItemsCount = objrefarrayFoundItems.Length
        int iFoundItemIndex = 0

        ;Debug.MessageBox("Found items: "+ iFoundItemsCount as string)

        if iFoundItemsCount > 0
            
            While iFoundItemIndex < iFoundItemsCount
                
                ;Debug.MessageBox("Adding Item To Workshop At Index: "+ iFoundItemIndex as string)
                
                ObjectReference objrefFoundItem = objrefarrayFoundItems[iFoundItemIndex] as ObjectReference
                ;Debug.MessageBox(objrefFoundItem.GetBaseObject().GetName() + " " + objrefFoundItem.GetFormID() as string)                
                
                int iItemFormID = objrefFoundItem.GetFormID()
                
                if (iItemFormID > iCreatedFormIDMin) && (iItemFormID < iCreatedFormIDMax)
                    ;Debug.MessageBox("Linking Item To Workshop")
                    objrefFoundItem.SetLinkedRef(objrefWorkshop, WorkshopItemKeyword)

                EndIf
                
                iFoundItemIndex += 1

            EndWhile

        EndIf
        
        iFormListIndex += 1

    EndWhile

    bIterating = false


EndFunction

 

And here's the pastebin for the full script: https://pastebin.com/CiaiEee9

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...