Custom Machinery

Custom Machinery

3M Downloads

Issues with mergeEntityData and /data merge command

Nemirel345 opened this issue ยท 1 comments

commented

Trying to edit the machine's nbt with commands does nothing.

Using /data get to read the machine's data works, but using /data merge to modify the data says it successfully wrote the new data but using /data get again shows nothing has changed.

The same behaviour is observed using KubeJS event.block.entityData and event.block.mergeEntityData().

Example

My custom machine has a single tank which holds a fluid called kubejs:tree_sap.
using /data get on my machine yields

{componentManager:{active:0b,data_component:{},fluids:[{config:{BACK:1b,BOTTOM:1b,FRONT:1b,LEFT:1b,RIGHT:1b,TOP:1b,input:0b,output:0b},id:"sap",stack:{Amount:500,FluidName:"kubejs:tree_sap"}}],fuel:0,maxFuel:0,radius:1},craftingManager:{phase:"ENDING",recipeProgressTime:0.0d,type:"custommachinery:machine"},id:"custommachinery:custom_machine_tile",machineID:"custommachinery:sap_extractor",message:'{"text":"","strikethrough":false,"obfuscated":false,"font":"minecraft:default","bold":false,"italic":false,"underlined":false,"childrens":[]}',status:"idle",x:330,y:142,z:-14}

I want to right-click the machine with an empty bottle and extract 250mb of fluid and get a filled bottle, thus I have the following KubeJS script:

BlockEvents.rightClicked (event => {
	switch(event.block.id)
	{
		case 'kubejs:sap_extractor':
			if  (event.item == Item.of('minecraft:glass_bottle'))
			{
				//console.log(event.block.entityData)
				var amount = event.block.entityData.componentManager.fluids[0].stack.Amount;
				var fluid = event.block.entityData.FluidName;
				if (amount >= 250)
				{
					event.item.count--;
					event.block.mergeEntityData({"componentManager.fluids[0].stack.Amount":amount-250});
					event.player.giveInHand("kubejs:tree_sap_bottle");
					event.cancel()
				}
			}
			break;
		default:
			break;
	}
})

Written differently to replace the entire array at once:

BlockEvents.rightClicked (event => {
	switch(event.block.id)
	{
		case 'kubejs:sap_extractor':
			if  (event.item == Item.of('minecraft:glass_bottle'))
			{
				//console.log(event.block.entityData)
				var amount = event.block.entityData.componentManager.fluids[0].stack.Amount;
				var fluid = event.block.entityData.componentManager.fluids;
				if (amount >= 250)
				{
					fluid[0].stack.Amount = amount-250;
					//console.log(fluid);
					event.item.count--;
					event.block.mergeEntityData({"componentManager.fluids":fluid});
					event.player.giveInHand("kubejs:tree_sap_bottle");
					event.cancel()
				}
			}
			break;
		default:
			break;
	}
})

While I do get a filled bottle when right-clicking my machine, it doesn't reduce the amount stored inside the tank.

To explore the issue I tried replicating the behaviour using the /data command, using /data merge to attempt reducing the fluid in the tank. While /data merge won't let me modify an array directly, I tried replacing it entirely using /data merge block ~ ~-1 ~ {componentManager.fluids:[{config:{BACK:1b,BOTTOM:1b,FRONT:1b,LEFT:1b,RIGHT:1b,TOP:1b,input:0b,output:0b},id:"sap",stack:{Amount:250,FluidName:"kubejs:tree_sap"}}]}

Hovever, using /data get again shows the command was ineffective even though the command outputs a success message.

In all cases, we can read the data but not write to it.

commented

You should never manipulate a BlockEntity's nbt, mainly because the nbt doesn't exist when the machine is loaded, only when the chunk containing the machine is saved to disk.
So what you're currently doing is serialize the machine to nbt, modifying it and then loading a new machine from this modified nbt.
This is not only very bad performance wise, but also really prone to issues (like the one you're having).
If you want to interact with the content of a machine use the KubeJS integration :
https://frinn.gitbook.io/custom-machinery-1.19/mod-integrations/kubejs/recipes/function/machine#of
If you need help come to the discord.