Reset pocket computer if family changes

When we upgrade a normal pocket computer to an advanced one, we need to
create a new ServerComputer instance (and destroy the old one).

On 1.20.1 the ComputerUpgradeRecipe does not preserve the
instance/session ID on the resulting stack. When the item is next
ticked, we create a new computer, with the old computer no longer being
kept alive and eventually dying.

On 1.21.1 we copy all components, *including* the the current computer
reference. This means a new computer is never created and so we continue
to use the old one (with the wrong family). We could exclude the
computer component from the recipe (and so have the same behaviour as
1.20.1), but by adding a hook in onCraftedBy we can destroy the old
computer immediately, ensuring it no longer continues to run.

Fixes #2479.
This commit is contained in:
Jonathan Coates
2026-07-12 16:30:46 +01:00
parent 1cf0ff299e
commit 6f16cd6b0e
@@ -304,15 +304,23 @@ public class PocketComputerItem extends Item implements IComputerItem, IColoured
var tag = stack.getTag();
if (tag == null) return;
// Normally we treat the computer instance as the source of truth, and copy the computer's state back to the
// item. However, if we've just crafted the computer with an upgrade, we should sync the other way, and update
// the computer.
var server = level.getServer();
if (server == null) return;
var computer = getServerComputer(server, stack);
if (computer == null) return;
// If the family of the computer has changed then destroy the old computer immediately.
if (computer.getFamily() != family) {
computer.close();
tag.remove(NBT_INSTANCE);
tag.remove(NBT_SESSION);
return;
}
// Normally we treat the computer instance as the source of truth, and copy the computer's state back to the
// item. However, if we've just crafted the computer with an upgrade, we should sync the other way, and update
// the computer.
var brain = computer.getBrain();
brain.setUpgrade(getUpgradeWithData(stack));
brain.setColour(getColour(stack));