Wand copy/paste does not work for items with tag information
VictorColomb opened this issue · 1 comments
Description of the issue
Upon pasting using the Wand of the Lazy Builder, certain items do not get placed down.
It seems like this happens with items with a tag
NBT property.
Example 1: Immersive Engineering's conveyor belts.
Below is the NBT data of a number conveyor belts in my inventory.
In this example, no conveyor belts will be added to the world upon pasting.
{
"Inventory": [
// some items before
{
"tag": {
"conveyorType": "immersiveengineering:vertical"
},
"Count": 5,
"Damage": 0,
"id": "immersiveengineering:conveyor",
"Slot": 5
},
// some items after
]
}
Example 2: Mekanism's universal transporters.
Below is the NBT data of a number of Ultimate Logistical Transporters in my inventory.
In this example, only Mekanism pipes of the Basic tier will be added to the world ("tier": 0
), if you have some in your inventory.
The damage seems to work however: a Logistical Transporter (damage 3) will be pasted into the correct kind, and a Universal Cable (damage 0) as well.
{
"Inventory": [
// some items before
{
"tag": {
"tier": 3 // tier 3, for example, is Ultimate
},
"Count": 64,
"Damage": 3, // damage indicates the type of transmitter (here, Logistical Transporter)
"id": "mekanism:transmitter",
"Slot": 4
},
// some items after
]
}
Installation details
- Minecraft 1.12.2
- Forge 14.23.5.2860
- FML 8.0.99.99
- EnderUtilities 0.7.15
- Mekanism 1.12.2-9.8.3.390
- Immersive Engineering 0.12-98
Investigation
Something is definitely going wrong in ItemBuildersWand::getAndConsumeBuildItem
.
I suspect that the issue stems from BlockUtils::getPickBlockItemStack
not creating a Tile Entity before calling state.getBlock().getPickBlock()
.
- In the case of the Immersive Engineering conveyors, this would mean that without a Tile Entity, conveyors have no default pick block.
- In the case of the Mekanism transmitters, the type of transmitter (equivalent to the item damage) is probably stored in the
IBlockState
and the default pick block is that of tier 0.
Another clue maybe: RFTools's builder has a copy and paste function as well, which seems to work with at least Immersive Engineering conveyors. I will try to look into that.
If I find some time, I'll setup a full developer environment and see if I can find a fix. 🤞
This type of "build a schematic and consume the items" thing in survival mode is rather problematic with any blocks or items that involve NBT data. I don't really remember at all anymore how any of this code works, but I assume I'm not restoring any block entity NBT data when the paste is used in survival mode, as that would really easily lead to all kinds of item dupes and exploits.
And looks like the item consume thing also probably does an exact ItemStack match, including the NBT data? So the item returned from the attempted block to item conversion would exactly match the items in the player inventory. Even that is kind of problematic, as all blocks don't have an item associated with them directly, and the pick block stack might add some data but that might not match the items you have crafted or whatever. Even stuff like getting the correct number of items to consume for placing the block is already an issue. I don't remember if there is a method in 1.12.2 that tells how many items should drop when a block is broken? I think there is. So that should be used as a stack size override when consuming items. But then what about blocks that break into multiple different items, but those items can't be used to place back the same block...
Even trying to fetch the initial item for the block is already problematic, as some blocks may need world context, which means they would need to be placed to some world before querying the item. But placing the block temporarily to the actual world is dangerous, as some blocks may run a bunch of code when the block entity is created or added to the world... And even placing them to a separate fake world is problematic, because creating a server-wide fake world takes a bunch of steps to set up fake classes for various things and trying to keep it from crashing... It probably should just be a regular custom dimension at that point. And using a fake client-side world won't necessarily work correctly, as the block might not get set up fully there, or the pick block might not work from the client world.
Basically trying to get this all correct leads to a deep rabbit hole with tons of hard coded overrides for various things. And in general I want to avoid all that complexity and possibility for issues and exploits by just avoiding restoring any NBT data in survival mode.
In creative copy & pasting it's easier because the items are irrelevant, and the schematic can just directly be placed to the world and also all the NBT data can be directly restored to the block entities.