Jump to content

[Papyrus] How to reference an item's components in for use with the additem function?


Guest

Recommended Posts

I'm working on a mod that needs to have several Constructible Objects that give the player multiple of several types of item. Having failed to get this to work using FLSTs and LLs, I'm going to have to use a script instead.


 


So the plan is to have the created object be a misc item with a script to give the final items to the player, and then delete it's parent object. I've already done a script that has the items it gives hard coded; but I want this mod to be easily expandable by other modders.


 


Having a script that instead looks at the components declared under the misc item means that not only do I have to write less code, but anyone wanting to expand it doesn't need to write any code, just attach this script and declare the items they want it to give in the components section.


 


The issue is that I have no idea how to reference an items components when calling the additem function. I've been unable to find any up to date or detailed Papyrus references for FO4, and either my Google-Fu is weak, or there is no info on how to do this.


 


I am using Sublime Text 3 with the official PapyrusF4 plugin.


Link to comment

I haven't actually tried this yet but something along these lines might do what you want. I stole this snipped from a decompiled pex from Portable Recycler. The function in it's most basic form takes the misc object CS and scraps it returning at least 1 component of C. So you could have your mod craft the misc item. Attach the script to the misc item passing its own id a a property to the script as a MiscObject. Then you'd have to pass the script at least 1 of the components of the misc item. Then have the script call the recycle function with the component and misc references. The RecyclerReference is actually a container that it uses, but you can replace it with the player ref since you'd typically be carrying the item.

Function Recycle(component C, MiscObject CS)
int numComponents = RecyclerReference.getComponentCount(C as Form)
RecyclerReference.removeComponents(C, numComponents, True)
RecyclerReference.addItem(CS as Form, numComponents, True)
EndFunction

From the ObjectReference file there's 2 functions you can use. One of which I just noted.

; Removes the specified count of component from the container, scrapping items, and returning the remainder to said container
Function RemoveComponents(Component akComponent, int aiCount, bool abSilent = false) native

; Removes items from this object reference's inventory containing up to aiCount components
Function RemoveItemByComponent(Form akComponentToRemove, int aiCount = 1, bool abSilent = false, ObjectReference akOtherContainer = None) native
It would appear that either of these would allow you to have a multiple count of components. Using a formlist would require that you either assume 1 of each item in the list. Or choose some multiple. You could iterate through a form list easily enough just adding each referenced item with something like

int iter = 0
While (iter < pFLST.GetSize())
  PlayerRef.AddItem(pFLST.GetAt(iter), 1, True)
  iter += 1
EndWhile
One could just add multiple of the same item to the form list then and the script would iterate through giving one each while loop round. Not the most efficient but should be functional.
Link to comment

I haven't actually tried this yet but something along these lines might do what you want. I stole this snipped from a decompiled pex from Portable Recycler. The function in it's most basic form takes the misc object CS and scraps it returning at least 1 component of C. So you could have your mod craft the misc item. Attach the script to the misc item passing its own id a a property to the script as a MiscObject. Then you'd have to pass the script at least 1 of the components of the misc item. Then have the script call the recycle function with the component and misc references. The RecyclerReference is actually a container that it uses, but you can replace it with the player ref since you'd typically be carrying the item.

Function Recycle(component C, MiscObject CS)
int numComponents = RecyclerReference.getComponentCount(C as Form)
RecyclerReference.removeComponents(C, numComponents, True)
RecyclerReference.addItem(CS as Form, numComponents, True)
EndFunction

From the ObjectReference file there's 2 functions you can use. One of which I just noted.

; Removes the specified count of component from the container, scrapping items, and returning the remainder to said container
Function RemoveComponents(Component akComponent, int aiCount, bool abSilent = false) native

; Removes items from this object reference's inventory containing up to aiCount components
Function RemoveItemByComponent(Form akComponentToRemove, int aiCount = 1, bool abSilent = false, ObjectReference akOtherContainer = None) native
It would appear that either of these would allow you to have a multiple count of components. Using a formlist would require that you either assume 1 of each item in the list. Or choose some multiple. You could iterate through a form list easily enough just adding each referenced item with something like

int iter = 0
While (iter < pFLST.GetSize())
  PlayerRef.AddItem(pFLST.GetAt(iter), 1, True)
  iter += 1
EndWhile
One could just add multiple of the same item to the form list then and the script would iterate through giving one each while loop round. Not the most efficient but should be functional.

 

 

I've had a different idea on how to implement this, but it goes beyond my knowledge of Papyrus.

 

The idea is to have a constructible object make a misc item with a generic script attached (I'm going to need many of them).

 

Let's say I call the misc item "MiscItem01", I want the script attached to it to look at that name and then be able to spawn items from a leveled list called "LL_MiscItem01". That way I can use the same script for all the misc items provided that the leveled lists follow the correct naming scheme so that the script doesn't need to be aware of which leveled list goes with which item, it can just work it out as needed.

Link to comment

I've had a different idea on how to implement this, but it goes beyond my knowledge of Papyrus.

 

The idea is to have a constructible object make a misc item with a generic script attached (I'm going to need many of them).

 

Let's say I call the misc item "MiscItem01", I want the script attached to it to look at that name and then be able to spawn items from a leveled list called "LL_MiscItem01". That way I can use the same script for all the misc items provided that the leveled lists follow the correct naming scheme so that the script doesn't need to be aware of which leveled list goes with which item, it can just work it out as needed.

AFAIK you can't get the editor id's from papyrus. You'd have to pass form ID's as properties. That could fairly easily do what you want with a generic type script. It would go something like this: Create your COBJ to make the MISC item. On the misc item attach a script and give it some property, name it something like pLVL_List. Then in the OnInit event in the script you have it remove the misc item referenced like PlayerRef.removeitem(Self as Form) then use the property to add the items. I'm not sure how multiple item lists work but something like PlayerRef.Additem(pLVL_List, 1) would work for a list that returns 1 item. You would need to assign the PlayerRef in the script or pass it as a property also.

Link to comment

Archived

This topic is now archived and is closed to further replies.

  • Recently Browsing   0 members

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