Stocks crashing

- Fixed crash when modifying pipe structures while they are transporting fluids #7515
- Fixed shift-inserting into toolboxes causing items to be voided #7519
- Fixed inconsistent component serialisation in backtank BE
- Fixed table cloths not showing tooltips and enchantment effect when configured
- Fixed shopping list tooltip expanding as its viewed #7503
- Fixed crash when selling enchanted items on a table cloth #7516 #7536
This commit is contained in:
simibubi 2025-03-02 13:28:44 +01:00
parent e5e2708c66
commit 2f7aa76a92
7 changed files with 39 additions and 24 deletions

View file

@ -125,7 +125,8 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable
if (this.customName != null) if (this.customName != null)
compound.putString("CustomName", Component.Serializer.toJson(this.customName, registries)); compound.putString("CustomName", Component.Serializer.toJson(this.customName, registries));
compound.put("Components", CatnipCodecUtils.encode(DataComponentPatch.CODEC, registries, componentPatch).orElseThrow()); compound.put("Components", CatnipCodecUtils.encode(DataComponentPatch.CODEC, registries, componentPatch)
.orElse(new CompoundTag()));
} }
@Override @Override
@ -139,7 +140,7 @@ public class BacktankBlockEntity extends KineticBlockEntity implements Nameable
if (compound.contains("CustomName", 8)) if (compound.contains("CustomName", 8))
this.customName = Component.Serializer.fromJson(compound.getString("CustomName"), registries); this.customName = Component.Serializer.fromJson(compound.getString("CustomName"), registries);
componentPatch = CatnipCodecUtils.decode(DataComponentPatch.CODEC, registries, compound).orElse(DataComponentPatch.EMPTY); componentPatch = CatnipCodecUtils.decode(DataComponentPatch.CODEC, registries, compound.getCompound("Components")).orElse(DataComponentPatch.EMPTY);
if (prev != 0 && prev != airLevel && airLevel == BacktankUtil.maxAir(capacityEnchantLevel) && clientPacket) if (prev != 0 && prev != airLevel && airLevel == BacktankUtil.maxAir(capacityEnchantLevel) && clientPacket)
playFilledEffect(); playFilledEffect();
} }

View file

@ -20,8 +20,6 @@ import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntity;
import net.neoforged.neoforge.items.SlotItemHandler;
public class ToolboxMenu extends MenuBase<ToolboxBlockEntity> { public class ToolboxMenu extends MenuBase<ToolboxBlockEntity> {
public ToolboxMenu(MenuType<?> type, int id, Inventory inv, RegistryFriendlyByteBuf extraData) { public ToolboxMenu(MenuType<?> type, int id, Inventory inv, RegistryFriendlyByteBuf extraData) {
@ -65,8 +63,9 @@ public class ToolboxMenu extends MenuBase<ToolboxBlockEntity> {
if (index < size) { if (index < size) {
success = !moveItemStackTo(stack, size, slots.size(), false); success = !moveItemStackTo(stack, size, slots.size(), false);
contentHolder.inventory.onContentsChanged(index); contentHolder.inventory.onContentsChanged(index);
} else } else {
success = !moveItemStackTo(stack, 0, size - 1, false); success = !moveItemStackTo(stack, 0, size - 1, false);
}
return success ? ItemStack.EMPTY : stack; return success ? ItemStack.EMPTY : stack;
} }
@ -137,11 +136,11 @@ public class ToolboxMenu extends MenuBase<ToolboxBlockEntity> {
int baseIndex = compartment * STACKS_PER_COMPARTMENT; int baseIndex = compartment * STACKS_PER_COMPARTMENT;
// Representative Slots // Representative Slots
addSlot(new ToolboxSlot(this, inventory, baseIndex, xOffsets[compartment], yOffsets[compartment])); addSlot(new ToolboxSlot(this, inventory, baseIndex, xOffsets[compartment], yOffsets[compartment], true));
// Hidden Slots // Hidden Slots
for (int i = 1; i < STACKS_PER_COMPARTMENT; i++) for (int i = 1; i < STACKS_PER_COMPARTMENT; i++)
addSlot(new SlotItemHandler(inventory, baseIndex + i, -10000, -10000)); addSlot(new ToolboxSlot(this, inventory, baseIndex + i, -10000, -10000, false));
} }
addPlayerSlots(8, 165); addPlayerSlots(8, 165);

View file

@ -1,20 +1,37 @@
package com.simibubi.create.content.equipment.toolbox; package com.simibubi.create.content.equipment.toolbox;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.items.IItemHandler; import net.neoforged.neoforge.items.IItemHandler;
import net.neoforged.neoforge.items.SlotItemHandler; import net.neoforged.neoforge.items.SlotItemHandler;
public class ToolboxSlot extends SlotItemHandler { public class ToolboxSlot extends SlotItemHandler {
private ToolboxMenu toolboxMenu; private ToolboxMenu toolboxMenu;
private boolean isVisible;
public ToolboxSlot(ToolboxMenu menu, IItemHandler itemHandler, int index, int xPosition, int yPosition) { public ToolboxSlot(ToolboxMenu menu, IItemHandler itemHandler, int index, int xPosition, int yPosition, boolean isVisible) {
super(itemHandler, index, xPosition, yPosition); super(itemHandler, index, xPosition, yPosition);
this.toolboxMenu = menu; this.toolboxMenu = menu;
this.isVisible = isVisible;
} }
@Override @Override
public boolean isActive() { public boolean isActive() {
return !toolboxMenu.renderPass && super.isActive(); return !toolboxMenu.renderPass && super.isActive() && isVisible;
}
@Override
public int getMaxStackSize(ItemStack stack) {
ItemStack maxAdd = stack.copy();
int maxInput = stack.getMaxStackSize();
maxAdd.setCount(maxInput);
IItemHandler handler = this.getItemHandler();
ItemStack currentStack = handler.getStackInSlot(index);
ItemStack remainder = handler.insertItem(index, maxAdd, true);
int current = currentStack.getCount();
int added = maxInput - remainder.getCount();
return current + added;
} }
} }

View file

@ -45,7 +45,7 @@ public class FluidNetwork {
Set<Pair<BlockFace, PipeConnection>> frontier; Set<Pair<BlockFace, PipeConnection>> frontier;
Set<BlockPos> visited; Set<BlockPos> visited;
FluidStack fluid; FluidStack fluid;
List<Pair<BlockFace, @Nullable ICapabilityProvider<IFluidHandler>>> targets; List<Pair<BlockFace, FlowSource>> targets;
Map<BlockPos, WeakReference<FluidTransportBehaviour>> cache; Map<BlockPos, WeakReference<FluidTransportBehaviour>> cache;
public FluidNetwork(Level world, BlockFace location, Supplier<@Nullable ICapabilityProvider<IFluidHandler>> sourceSupplier) { public FluidNetwork(Level world, BlockFace location, Supplier<@Nullable ICapabilityProvider<IFluidHandler>> sourceSupplier) {
@ -141,8 +141,7 @@ public class FluidNetwork {
if (adjacent.source.isPresent() && adjacent.source.get() if (adjacent.source.isPresent() && adjacent.source.get()
.isEndpoint()) { .isEndpoint()) {
targets.add(Pair.of(adjacentLocation, adjacent.source.get() targets.add(Pair.of(adjacentLocation, adjacent.source.get()));
.provideHandler()));
continue; continue;
} }
@ -169,7 +168,7 @@ public class FluidNetwork {
if (targets.isEmpty()) if (targets.isEmpty())
return; return;
for (Pair<BlockFace, @Nullable ICapabilityProvider<IFluidHandler>> pair : targets) { for (Pair<BlockFace, FlowSource> pair : targets) {
if (pair.getSecond() != null && world.getGameTime() % 40 != 0) if (pair.getSecond() != null && world.getGameTime() % 40 != 0)
continue; continue;
PipeConnection pipeConnection = get(pair.getFirst()); PipeConnection pipeConnection = get(pair.getFirst());
@ -177,7 +176,7 @@ public class FluidNetwork {
continue; continue;
pipeConnection.source.ifPresent(fs -> { pipeConnection.source.ifPresent(fs -> {
if (fs.isEndpoint()) if (fs.isEndpoint())
pair.setSecond(fs.provideHandler()); pair.setSecond(fs);
}); });
} }
@ -215,14 +214,13 @@ public class FluidNetwork {
if (simulate) if (simulate)
flowSpeed = transfer.getAmount(); flowSpeed = transfer.getAmount();
List<Pair<BlockFace, @Nullable ICapabilityProvider<IFluidHandler>>> availableOutputs = new ArrayList<>(targets); List<Pair<BlockFace, FlowSource>> availableOutputs = new ArrayList<>(targets);
while (!availableOutputs.isEmpty() && transfer.getAmount() > 0) { while (!availableOutputs.isEmpty() && transfer.getAmount() > 0) {
int dividedTransfer = transfer.getAmount() / availableOutputs.size(); int dividedTransfer = transfer.getAmount() / availableOutputs.size();
int remainder = transfer.getAmount() % availableOutputs.size(); int remainder = transfer.getAmount() % availableOutputs.size();
for (Iterator<Pair<BlockFace, @Nullable ICapabilityProvider<IFluidHandler>>> iterator = for (Iterator<Pair<BlockFace, FlowSource>> iterator = availableOutputs.iterator(); iterator.hasNext();) {
availableOutputs.iterator(); iterator.hasNext();) { Pair<BlockFace, FlowSource> pair = iterator.next();
Pair<BlockFace, @Nullable ICapabilityProvider<IFluidHandler>> pair = iterator.next();
int toTransfer = dividedTransfer; int toTransfer = dividedTransfer;
if (remainder > 0) { if (remainder > 0) {
toTransfer++; toTransfer++;
@ -231,7 +229,7 @@ public class FluidNetwork {
if (transfer.isEmpty()) if (transfer.isEmpty())
break; break;
@Nullable ICapabilityProvider<IFluidHandler> targetHandlerProvider = pair.getSecond(); @Nullable ICapabilityProvider<IFluidHandler> targetHandlerProvider = pair.getSecond().provideHandler();
if (targetHandlerProvider == null) { if (targetHandlerProvider == null) {
iterator.remove(); iterator.remove();
continue; continue;

View file

@ -129,7 +129,7 @@ public class ShoppingListItem extends Item {
(cost ? CreateLang.translate("table_cloth.total_cost") : CreateLang.text("")) (cost ? CreateLang.translate("table_cloth.total_cost") : CreateLang.text(""))
.style(ChatFormatting.GOLD) .style(ChatFormatting.GOLD)
.add(CreateLang.builder() .add(CreateLang.builder()
.add(entry.stack.getHoverName()) .add(entry.stack.getHoverName().plainCopy())
.text(" x") .text(" x")
.text(String.valueOf(entry.count)) .text(String.valueOf(entry.count))
.style(cost ? ChatFormatting.YELLOW : ChatFormatting.GRAY)) .style(cost ? ChatFormatting.YELLOW : ChatFormatting.GRAY))
@ -142,7 +142,7 @@ public class ShoppingListItem extends Item {
.addTo(tooltipComponents); .addTo(tooltipComponents);
for (BigItemStack entry : entries) { for (BigItemStack entry : entries) {
CreateLang.builder() CreateLang.builder()
.add(entry.stack.getHoverName()) .add(entry.stack.getHoverName().plainCopy())
.text(" x") .text(" x")
.text(String.valueOf(entry.count)) .text(String.valueOf(entry.count))
.style(cost ? ChatFormatting.YELLOW : ChatFormatting.GRAY) .style(cost ? ChatFormatting.YELLOW : ChatFormatting.GRAY)

View file

@ -294,7 +294,7 @@ public class TableClothBlockEntity extends SmartBlockEntity {
super.write(tag, registries, clientPacket); super.write(tag, registries, clientPacket);
tag.put("Items", NBTHelper.writeItemList(manuallyAddedItems, registries)); tag.put("Items", NBTHelper.writeItemList(manuallyAddedItems, registries));
tag.putInt("Facing", facing.get2DDataValue()); tag.putInt("Facing", facing.get2DDataValue());
tag.put("RequestData", CatnipCodecUtils.encode(AutoRequestData.CODEC, requestData).orElseThrow()); tag.put("RequestData", CatnipCodecUtils.encode(AutoRequestData.CODEC, registries, requestData).orElseThrow());
if (owner != null) if (owner != null)
tag.putUUID("OwnerUUID", owner); tag.putUUID("OwnerUUID", owner);
} }
@ -303,7 +303,7 @@ public class TableClothBlockEntity extends SmartBlockEntity {
protected void read(CompoundTag tag, HolderLookup.Provider registries, boolean clientPacket) { protected void read(CompoundTag tag, HolderLookup.Provider registries, boolean clientPacket) {
super.read(tag, registries, clientPacket); super.read(tag, registries, clientPacket);
manuallyAddedItems = NBTHelper.readItemList(tag.getList("Items", Tag.TAG_COMPOUND), registries); manuallyAddedItems = NBTHelper.readItemList(tag.getList("Items", Tag.TAG_COMPOUND), registries);
requestData = CatnipCodecUtils.decode(AutoRequestData.CODEC, tag.get("RequestData")) requestData = CatnipCodecUtils.decode(AutoRequestData.CODEC, registries, tag.get("RequestData"))
.orElse(new AutoRequestData()); .orElse(new AutoRequestData());
owner = tag.contains("OwnerUUID") ? tag.getUUID("OwnerUUID") : null; owner = tag.contains("OwnerUUID") ? tag.getUUID("OwnerUUID") : null;
facing = Direction.from2DDataValue(Mth.positiveModulo(tag.getInt("Facing"), 4)); facing = Direction.from2DDataValue(Mth.positiveModulo(tag.getInt("Facing"), 4));

View file

@ -21,7 +21,7 @@ public class TableClothBlockItem extends BlockItem {
@Override @Override
public boolean isFoil(ItemStack pStack) { public boolean isFoil(ItemStack pStack) {
return pStack.has(AllDataComponents.CLICK_TO_LINK_DATA); return pStack.has(AllDataComponents.AUTO_REQUEST_DATA);
} }
@Override @Override