Merge branch 'mc1.20.1/feature-dev' into mc1.21.1/dev

# Conflicts:
#	gradle.properties
#	src/generated/resources/.cache/3055aa55530438925fbff1670d3e8dc6cc209bf3
#	src/main/java/com/simibubi/create/content/logistics/box/PackageItem.java
#	src/main/java/com/simibubi/create/content/logistics/factoryBoard/FactoryPanelBehaviour.java
#	src/main/java/com/simibubi/create/content/logistics/factoryBoard/FactoryPanelConnectionHandler.java
#	src/main/java/com/simibubi/create/content/logistics/factoryBoard/FactoryPanelConnectionPacket.java
#	src/main/java/com/simibubi/create/content/logistics/packager/PackageDefragmenter.java
This commit is contained in:
IThundxr 2025-01-25 15:12:06 -05:00
commit e3b5732539
Failed to generate hash of commit
24 changed files with 321 additions and 83 deletions

View file

@ -28,12 +28,12 @@ flywheel_minecraft_version = 1.21.1
flywheel_version = 1.0.0-beta-fork.16
flywheel_version_range = [1.0.0-alpha,2.0)
# Optional Dependencies
# Dependency Versions
jei_minecraft_version = 1.21
jei_version = 19.5.0.33
curios_minecraft_version = 1.21.1
curios_version = 9.2.2
ponder_version = 0.9.18
ponder_version = 0.9.20
cc_tweaked_enable = true
cc_tweaked_minecraft_version = 1.21.1

View file

@ -1108,6 +1108,7 @@
"create.factory_panel.cannot_add_more_inputs": "ǝbnɐb sıɥʇ oʇ sʇnduı ǝɹoɯ ppɐ ʇouuɐƆ",
"create.factory_panel.click_second_panel": "˙˙˙ʇɔǝuuoɔ oʇ ǝbnɐb puoɔǝs ɐ ʞɔıןƆ",
"create.factory_panel.click_to_configure": "ǝɹnbıɟuoɔ oʇ ʞɔıןƆ",
"create.factory_panel.click_to_relocate": "˙˙˙oʇ ןǝuɐd sıɥʇ ǝʇɐɔoןǝɹ oʇ ʇods ɐ ʞɔıןƆ",
"create.factory_panel.connection_aborted": "pǝʇɹoqɐ uoıʇɔǝuuoɔ ʇnduI",
"create.factory_panel.cycled_arrow_path": "%1$s ǝpoɯ buıɥʇɐd ʍoɹɹɐ pǝןɔʎƆ",
"create.factory_panel.hold_to_set_amount": "ʇunoɯɐ ʇǝbɹɐʇ ɹoɟ pןoɥ puɐ ʞɔıןƆ",
@ -1118,6 +1119,8 @@
"create.factory_panel.no_item": "ʇsɹıɟ ɯǝʇı uɐ ǝʌɐɥ ʇsnɯ ǝbnɐb ʇnduI",
"create.factory_panel.panels_connected": "%2$s ǝʇɐǝɹɔ oʇ %1$s buısn ʍoN",
"create.factory_panel.redstone_paused": ")pǝsnɐԀ ǝuoʇspǝᴚ(",
"create.factory_panel.relocated": "uoıʇısod ʍǝu oʇ pǝʌoɯ ǝbnɐ⅁",
"create.factory_panel.relocation_aborted": "pǝʇɹoqɐ uoıʇɐɔoןǝɹ ǝbnɐ⅁",
"create.factory_panel.same_orientation": "uoıʇɐʇuǝıɹo ǝɯɐs ǝɥʇ ǝʌɐɥ ʇsnɯ sʞɔoןᗺ",
"create.factory_panel.same_surface": "ǝɔɐɟɹns ǝɯɐs ǝɥʇ uo ǝq ʇsnɯ sʞɔoןᗺ",
"create.factory_panel.some_links_unloaded": "pǝpɐoן ʇou ǝɹɐ sʞuıן ǝɯoS",
@ -1227,6 +1230,7 @@
"create.gui.factory_panel.recipe_address_tip_1": "˙pǝʇɟɐɹɔ sı ǝdıɔǝɹ sıɥʇ",
"create.gui.factory_panel.recipe_promises_tip": "ǝsıɯoɹd ɐ 'ʇuǝs ǝɹɐ sʇnduı uǝɥM",
"create.gui.factory_panel.recipe_promises_tip_1": "˙ǝʌıɹɹɐ sʇndʇno ןıʇun pןǝɥ sı",
"create.gui.factory_panel.relocate": "ǝbnɐb sıɥʇ ǝʌoW",
"create.gui.factory_panel.reset": "sbuıʇʇǝs ןןɐ ʇǝsǝᴚ",
"create.gui.factory_panel.restocker_address": "˙˙˙oʇ sɯǝʇı puǝS",
"create.gui.factory_panel.restocker_address_given": "oʇ buıpuǝS",

View file

@ -1108,6 +1108,7 @@
"create.factory_panel.cannot_add_more_inputs": "Cannot add more inputs to this gauge",
"create.factory_panel.click_second_panel": "Click a second gauge to connect...",
"create.factory_panel.click_to_configure": "Click to configure",
"create.factory_panel.click_to_relocate": "Click a spot to relocate this panel to...",
"create.factory_panel.connection_aborted": "Input connection aborted",
"create.factory_panel.cycled_arrow_path": "Cycled arrow pathing mode %1$s",
"create.factory_panel.hold_to_set_amount": "Click and hold for target amount",
@ -1118,6 +1119,8 @@
"create.factory_panel.no_item": "Input gauge must have an item first",
"create.factory_panel.panels_connected": "Now using %1$s to create %2$s",
"create.factory_panel.redstone_paused": "(Redstone Paused)",
"create.factory_panel.relocated": "Gauge moved to new position",
"create.factory_panel.relocation_aborted": "Gauge relocation aborted",
"create.factory_panel.same_orientation": "Blocks must have the same orientation",
"create.factory_panel.same_surface": "Blocks must be on the same surface",
"create.factory_panel.some_links_unloaded": "Some links are not loaded",
@ -1227,6 +1230,7 @@
"create.gui.factory_panel.recipe_address_tip_1": "this recipe is crafted.",
"create.gui.factory_panel.recipe_promises_tip": "When inputs are sent, a promise",
"create.gui.factory_panel.recipe_promises_tip_1": "is held until outputs arrive.",
"create.gui.factory_panel.relocate": "Move this gauge",
"create.gui.factory_panel.reset": "Reset all settings",
"create.gui.factory_panel.restocker_address": "Send items to...",
"create.gui.factory_panel.restocker_address_given": "Sending to",

View file

@ -16,6 +16,7 @@ import com.simibubi.create.content.logistics.box.PackageStyles.PackageStyle;
import com.simibubi.create.content.logistics.stockTicker.PackageOrder;
import com.simibubi.create.foundation.item.ItemHelper;
import net.createmod.catnip.data.Glob;
import net.createmod.catnip.codecs.stream.CatnipStreamCodecBuilders;
import net.createmod.catnip.lang.Components;
import net.createmod.catnip.math.VecHelper;
@ -149,8 +150,8 @@ public class PackageItem extends Item {
return boxAddress.isBlank();
if (address.equals("*") || boxAddress.equals("*"))
return true;
String matcher = "\\Q" + address.replace("*", "\\E.*\\Q") + "\\E";
String boxMatcher = "\\Q" + boxAddress.replace("*", "\\E.*\\Q") + "\\E";
String matcher = Glob.toRegexPattern(address, "");
String boxMatcher = Glob.toRegexPattern(boxAddress, "");
return address.matches(boxMatcher) || boxAddress.matches(matcher);
}

View file

@ -13,6 +13,7 @@ import java.util.UUID;
import javax.annotation.Nullable;
import org.jetbrains.annotations.NotNull;
import org.joml.Math;
import com.google.common.collect.HashMultimap;
@ -36,6 +37,7 @@ import com.simibubi.create.content.logistics.packagerLink.RequestPromiseQueue;
import com.simibubi.create.content.logistics.stockTicker.PackageOrder;
import com.simibubi.create.content.schematics.requirement.ItemRequirement;
import com.simibubi.create.foundation.advancement.AllAdvancements;
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType;
import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour;
import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard;
@ -60,11 +62,15 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.Tag;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.BlockHitResult;
import net.neoforged.api.distmarker.Dist;
@ -174,6 +180,95 @@ public class FactoryPanelBehaviour extends FilteringBehaviour {
return BlockEntityBehaviour.get(world, pos.pos(), FactoryPanelSupportBehaviour.TYPE);
}
public void moveTo(FactoryPanelPosition newPos, ServerPlayer player) {
Level level = getWorld();
BlockState existingState = level.getBlockState(newPos.pos());
// Check if target pos is valid
if (FactoryPanelBehaviour.at(level, newPos) != null)
return;
boolean isAddedToOtherGauge = AllBlocks.FACTORY_GAUGE.has(existingState);
if (!existingState.isAir() && !isAddedToOtherGauge)
return;
if (isAddedToOtherGauge && existingState != blockEntity.getBlockState())
return;
if (!isAddedToOtherGauge)
level.setBlock(newPos.pos(), blockEntity.getBlockState(), 3);
for (BlockPos blockPos : targetedByLinks.keySet())
if (!blockPos.closerThan(newPos.pos(), 24))
return;
for (FactoryPanelPosition blockPos : targetedBy.keySet())
if (!blockPos.pos().closerThan(newPos.pos(), 24))
return;
for (FactoryPanelPosition blockPos : targeting)
if (!blockPos.pos().closerThan(newPos.pos(), 24))
return;
// Disconnect links
for (BlockPos pos : targetedByLinks.keySet()) {
FactoryPanelSupportBehaviour at = linkAt(level, new FactoryPanelPosition(pos, slot));
if (at != null)
at.disconnect(this);
}
SmartBlockEntity oldBE = blockEntity;
FactoryPanelPosition oldPos = getPanelPosition();
slot = newPos.slot();
// Add to new BE
if (level.getBlockEntity(newPos.pos()) instanceof FactoryPanelBlockEntity fpbe) {
fpbe.attachBehaviourLate(this);
fpbe.panels.put(slot, this);
fpbe.redraw = true;
fpbe.lastShape = null;
fpbe.notifyUpdate();
}
// Remove from old BE
if (oldBE instanceof FactoryPanelBlockEntity fpbe) {
FactoryPanelBehaviour newBehaviour = new FactoryPanelBehaviour(fpbe, oldPos.slot());
fpbe.attachBehaviourLate(newBehaviour);
fpbe.panels.put(oldPos.slot(), newBehaviour);
fpbe.redraw = true;
fpbe.lastShape = null;
fpbe.notifyUpdate();
}
// Rewire connections
for (FactoryPanelPosition position : targeting) {
FactoryPanelBehaviour at = at(level, position);
if (at != null) {
FactoryPanelConnection connection = at.targetedBy.remove(oldPos);
connection.from = newPos;
at.targetedBy.put(newPos, connection);
at.blockEntity.sendData();
}
}
for (FactoryPanelPosition position : targetedBy.keySet()) {
FactoryPanelBehaviour at = at(level, position);
if (at != null) {
at.targeting.remove(oldPos);
at.targeting.add(newPos);
}
}
// Reconnect links
for (BlockPos pos : targetedByLinks.keySet()) {
FactoryPanelSupportBehaviour at = linkAt(level, new FactoryPanelPosition(pos, slot));
if (at != null)
at.connect(this);
}
// Tell player
player.displayClientMessage(CreateLang.translate("factory_panel.relocated")
.style(ChatFormatting.GREEN)
.component(), true);
player.level()
.playSound(null, newPos.pos(), SoundEvents.COPPER_BREAK, SoundSource.BLOCKS, 1.0f, 1.0f);
}
@Override
public void initialize() {
super.initialize();
@ -440,7 +535,7 @@ public class FactoryPanelBehaviour extends FilteringBehaviour {
return;
}
if (AllItemTags.WRENCH.matches(player.getItemInHand(hand))) {
if (targeting.size() + targetedByLinks.size() > 0 && AllItemTags.WRENCH.matches(player.getItemInHand(hand))) {
int sharedMode = -1;
boolean notifySelf = false;
@ -484,9 +579,6 @@ public class FactoryPanelBehaviour extends FilteringBehaviour {
return;
if (getFilter().isEmpty()) {
if (AllBlocks.FACTORY_GAUGE.isIn(player.getItemInHand(hand)))
return;
super.onShortInteract(player, hand, side, hitResult);
return;
}
@ -882,4 +974,18 @@ public class FactoryPanelBehaviour extends FilteringBehaviour {
: ItemRequirement.NONE;
}
@Override
public boolean canShortInteract(ItemStack toApply) {
return true;
}
@Override
public boolean readFromClipboard(@NotNull HolderLookup.Provider registries, CompoundTag tag, Player player, Direction side, boolean simulate) {
return false;
}
@Override
public boolean writeToClipboard(@NotNull HolderLookup.Provider registries, CompoundTag tag, Direction side) {
return false;
}
}

View file

@ -348,7 +348,7 @@ public class FactoryPanelBlock extends FaceAttachedHorizontalDirectionalBlock
IBE.onRemove(pState, pLevel, pPos, pNewState);
}
public PanelSlot getTargetedSlot(BlockPos pos, BlockState blockState, Vec3 clickLocation) {
public static PanelSlot getTargetedSlot(BlockPos pos, BlockState blockState, Vec3 clickLocation) {
double bestDistance = Double.MAX_VALUE;
PanelSlot bestSlot = PanelSlot.BOTTOM_LEFT;
Vec3 localClick = clickLocation.subtract(Vec3.atLowerCornerOf(pos));

View file

@ -37,8 +37,7 @@ public class FactoryPanelBlockEntity extends SmartBlockEntity {
public boolean redraw;
public boolean restocker;
private VoxelShape lastShape;
public VoxelShape lastShape;
public AdvancementBehaviour advancements;

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.factoryBoard;
import javax.annotation.Nullable;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.content.logistics.factoryBoard.FactoryPanelBlock.PanelSlot;
import com.simibubi.create.foundation.block.WrenchableDirectionalBlock;
@ -9,9 +10,9 @@ import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour
import com.simibubi.create.foundation.utility.CreateLang;
import net.createmod.catnip.animation.AnimationTickHolder;
import net.createmod.catnip.platform.CatnipServices;
import net.createmod.catnip.math.VecHelper;
import net.createmod.catnip.outliner.Outliner;
import net.createmod.catnip.platform.CatnipServices;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;
@ -34,6 +35,9 @@ public class FactoryPanelConnectionHandler {
static FactoryPanelPosition connectingFrom;
static AABB connectingFromBox;
static boolean relocating;
static FactoryPanelPosition validRelocationTarget;
public static boolean panelClicked(LevelAccessor level, Player player, FactoryPanelBehaviour panel) {
if (connectingFrom == null)
return false;
@ -61,7 +65,7 @@ public class FactoryPanelConnectionHandler {
ItemStack filterFrom = panel.getFilter();
ItemStack filterTo = at.getFilter();
CatnipServices.NETWORK.sendToServer(new FactoryPanelConnectionPacket(panel.getPanelPosition(), connectingFrom));
CatnipServices.NETWORK.sendToServer(new FactoryPanelConnectionPacket(panel.getPanelPosition(), connectingFrom, false));
player.displayClientMessage(CreateLang.translate("factory_panel.panels_connected", filterFrom.getHoverName()
.getString(),
@ -158,12 +162,50 @@ public class FactoryPanelConnectionHandler {
return;
}
Outliner.getInstance().showAABB(connectingFrom, connectingFromBox)
Outliner.getInstance()
.showAABB(connectingFrom, connectingFromBox)
.colored(AnimationTickHolder.getTicks() % 16 > 8 ? 0x38b764 : 0xa7f070)
.lineWidth(1 / 16f);
mc.player.displayClientMessage(CreateLang.translate("factory_panel.click_second_panel")
.component(), true);
mc.player.displayClientMessage(
CreateLang.translate(relocating ? "factory_panel.click_to_relocate" : "factory_panel.click_second_panel")
.component(),
true);
if (!relocating)
return;
validRelocationTarget = null;
if (!(mc.hitResult instanceof BlockHitResult bhr) || bhr.getType() == Type.MISS)
return;
Vec3 offsetPos = bhr.getLocation()
.add(Vec3.atLowerCornerOf(bhr.getDirection()
.getNormal())
.scale(1 / 32f));
BlockPos pos = BlockPos.containing(offsetPos);
BlockState blockState = at.blockEntity.getBlockState();
PanelSlot slot = FactoryPanelBlock.getTargetedSlot(pos, blockState, offsetPos);
BlockPos diff = pos.subtract(connectingFrom.pos());
Direction facing = FactoryPanelBlock.connectedDirection(blockState);
if (facing.getAxis()
.choose(diff.getX(), diff.getY(), diff.getZ()) != 0)
return;
if (!AllBlocks.FACTORY_GAUGE.get()
.canSurvive(blockState, mc.level, pos))
return;
if (AllBlocks.PACKAGER.has(mc.level.getBlockState(pos.relative(facing.getOpposite()))))
return;
validRelocationTarget = new FactoryPanelPosition(pos, slot);
Outliner.getInstance()
.showAABB("target", getBB(blockState, validRelocationTarget))
.colored(0xeeeeee)
.disableLineNormals()
.lineWidth(1 / 16f);
}
public static boolean onRightClick() {
@ -172,6 +214,24 @@ public class FactoryPanelConnectionHandler {
Minecraft mc = Minecraft.getInstance();
boolean missed = false;
if (relocating) {
if (mc.player.isShiftKeyDown())
validRelocationTarget = null;
if (validRelocationTarget != null)
CatnipServices.NETWORK.sendToServer(new FactoryPanelConnectionPacket(validRelocationTarget, connectingFrom, true));
connectingFrom = null;
connectingFromBox = null;
if (validRelocationTarget == null)
mc.player.displayClientMessage(CreateLang.translate("factory_panel.relocation_aborted")
.component(), true);
relocating = false;
validRelocationTarget = null;
return true;
}
if (mc.hitResult instanceof BlockHitResult bhr && bhr.getType() != Type.MISS) {
BlockEntity blockEntity = mc.level.getBlockEntity(bhr.getBlockPos());
FactoryPanelSupportBehaviour behaviour =
@ -205,7 +265,7 @@ public class FactoryPanelConnectionHandler {
bestPosition = panelPosition;
}
CatnipServices.NETWORK.sendToServer(new FactoryPanelConnectionPacket(bestPosition, connectingFrom));
CatnipServices.NETWORK.sendToServer(new FactoryPanelConnectionPacket(bestPosition, connectingFrom, false));
mc.player.displayClientMessage(CreateLang
.translate("factory_panel.link_connected", blockEntity.getBlockState()
@ -235,15 +295,22 @@ public class FactoryPanelConnectionHandler {
return true;
}
public static void startRelocating(FactoryPanelBehaviour behaviour) {
startConnection(behaviour);
relocating = true;
}
public static void startConnection(FactoryPanelBehaviour behaviour) {
relocating = false;
connectingFrom = behaviour.getPanelPosition();
BlockState blockState = behaviour.blockEntity.getBlockState();
Vec3 location = behaviour.getSlotPositioning()
.getLocalOffset(behaviour.getWorld(), behaviour.getPos(), blockState)
.add(Vec3.atLowerCornerOf(behaviour.getPos()));
connectingFromBox = getBB(behaviour.blockEntity.getBlockState(), connectingFrom);
}
public static AABB getBB(BlockState blockState, FactoryPanelPosition factoryPanelPosition) {
Vec3 location = FactoryPanelSlotPositioning.getCenterOfSlot(blockState, factoryPanelPosition.slot())
.add(Vec3.atLowerCornerOf(factoryPanelPosition.pos()));
Vec3 plane = VecHelper.axisAlingedPlaneOf(FactoryPanelBlock.connectedDirection(blockState));
connectingFromBox =
new AABB(location, location).inflate(plane.x * 3 / 16f, plane.y * 3 / 16f, plane.z * 3 / 16f);
return new AABB(location, location).inflate(plane.x * 3 / 16f, plane.y * 3 / 16f, plane.z * 3 / 16f);
}
}

View file

@ -4,6 +4,7 @@ import com.simibubi.create.AllPackets;
import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.server.level.ServerPlayer;
@ -11,16 +12,19 @@ public class FactoryPanelConnectionPacket extends BlockEntityConfigurationPacket
public static final StreamCodec<ByteBuf, FactoryPanelConnectionPacket> STREAM_CODEC = StreamCodec.composite(
FactoryPanelPosition.STREAM_CODEC, packet -> packet.fromPos,
FactoryPanelPosition.STREAM_CODEC, packet -> packet.toPos,
ByteBufCodecs.BOOL, packet -> packet.relocate,
FactoryPanelConnectionPacket::new
);
private final FactoryPanelPosition fromPos;
private final FactoryPanelPosition toPos;
private boolean relocate;
public FactoryPanelConnectionPacket(FactoryPanelPosition fromPos, FactoryPanelPosition toPos) {
public FactoryPanelConnectionPacket(FactoryPanelPosition fromPos, FactoryPanelPosition toPos, boolean relocate) {
super(toPos.pos());
this.fromPos = fromPos;
this.toPos = toPos;
this.relocate = relocate;
}
@Override
@ -32,7 +36,10 @@ public class FactoryPanelConnectionPacket extends BlockEntityConfigurationPacket
protected void applySettings(ServerPlayer player, FactoryPanelBlockEntity be) {
FactoryPanelBehaviour behaviour = FactoryPanelBehaviour.at(be.getLevel(), toPos);
if (behaviour != null)
behaviour.addConnection(fromPos);
if (relocate)
behaviour.moveTo(fromPos, player);
else
behaviour.addConnection(fromPos);
}
@Override

View file

@ -55,6 +55,7 @@ public class FactoryPanelScreen extends AbstractSimiScreen {
private IconButton confirmButton;
private IconButton deleteButton;
private IconButton newInputButton;
private IconButton relocateButton;
private IconButton activateCraftingButton;
private ScrollInput promiseExpiration;
private FactoryPanelBehaviour behaviour;
@ -177,19 +178,30 @@ public class FactoryPanelScreen extends AbstractSimiScreen {
promiseExpiration.setState(behaviour.promiseClearingInterval);
addRenderableWidget(promiseExpiration);
newInputButton = new IconButton(x + 31, y + 67, AllIcons.I_ADD);
newInputButton = new IconButton(x + 31, y + 47, AllIcons.I_ADD);
newInputButton.withCallback(() -> {
FactoryPanelConnectionHandler.startConnection(behaviour);
minecraft.setScreen(null);
});
newInputButton.setToolTip(CreateLang.translate("gui.factory_panel.connect_input")
.component());
if (!restocker)
relocateButton = new IconButton(x + 31, y + 67, AllIcons.I_MOVE_GAUGE);
relocateButton.withCallback(() -> {
FactoryPanelConnectionHandler.startRelocating(behaviour);
minecraft.setScreen(null);
});
relocateButton.setToolTip(CreateLang.translate("gui.factory_panel.relocate")
.component());
if (!restocker) {
addRenderableWidget(newInputButton);
addRenderableWidget(relocateButton);
}
activateCraftingButton = null;
if (availableCraftingRecipe != null) {
activateCraftingButton = new IconButton(x + 31, y + 47, AllIcons.I_3x3);
activateCraftingButton = new IconButton(x + 31, y + 27, AllIcons.I_3x3);
activateCraftingButton.withCallback(() -> {
craftingActive = !craftingActive;
init();

View file

@ -24,6 +24,10 @@ class FactoryPanelSlotPositioning extends ValueBoxTransform {
@Override
public Vec3 getLocalOffset(LevelAccessor level, BlockPos pos, BlockState state) {
return getCenterOfSlot(state, slot);
}
public static Vec3 getCenterOfSlot(BlockState state, PanelSlot slot) {
Vec3 vec = new Vec3(.25 + slot.xOffset * .5, 1.5 / 16f, .25 + slot.yOffset * .5);
vec = VecHelper.rotateCentered(vec, 180, Axis.Y);
vec = VecHelper.rotateCentered(vec, Mth.RAD_TO_DEG * FactoryPanelBlock.getXRot(state) + 90, Axis.X);

View file

@ -70,9 +70,13 @@ public class PackageDefragmenter {
}
List<BigItemStack> orderedStacks = new ArrayList<>();
if (orderContext != null)
for (BigItemStack stack : orderContext.stacks())
List<BigItemStack> originalContext = new ArrayList<>();
if (orderContext != null) {
for (BigItemStack stack : orderContext.stacks()) {
orderedStacks.add(new BigItemStack(stack.stack, stack.count));
originalContext.add(new BigItemStack(stack.stack, stack.count));
}
}
List<ItemStack> outputSlots = new ArrayList<>();
@ -134,8 +138,11 @@ public class PackageDefragmenter {
for (ItemStack box : exportingPackages)
PackageItem.addAddress(box, address);
if (!exportingPackages.isEmpty())
PackageItem.addOrderContext(exportingPackages.get(0), orderContext);
for (int i = 0; i < exportingPackages.size(); i++) {
ItemStack box = exportingPackages.get(i);
boolean isfinal = i == exportingPackages.size() - 1;
PackageItem.setOrder(box, orderId, 0, true, 0, true, isfinal ? new PackageOrder(originalContext) : null);
}
return exportingPackages;
}

View file

@ -76,6 +76,12 @@ public class RepackagerBlockEntity extends PackagerBlockEntity {
return;
attemptToDefrag(targetInv);
if (heldBox.isEmpty())
return;
updateSignAddress();
if (!signBasedAddress.isBlank())
PackageItem.addAddress(heldBox, signBasedAddress);
}
protected void attemptToDefrag(IItemHandler targetInv) {

View file

@ -83,7 +83,11 @@ public class LogisticsManager {
public static Multimap<PackagerBlockEntity, PackagingRequest> findPackagersForRequest(UUID freqId,
PackageOrder order, @Nullable PackageOrder customContext, @Nullable IItemHandler ignoredHandler,
String address) {
List<BigItemStack> stacks = order.stacks();
List<BigItemStack> stacks = new ArrayList<>();
for (BigItemStack stack : order.stacks())
if (!stack.stack.isEmpty() && stack.count > 0)
stacks.add(stack);
Multimap<PackagerBlockEntity, PackagingRequest> requests = HashMultimap.create();
// Packages need to track their index and successors for successful defrag

View file

@ -8,7 +8,6 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.AllTags.AllItemTags;
import com.simibubi.create.content.fluids.tank.FluidTankBlock;
import com.simibubi.create.content.logistics.stockTicker.StockTickerBlock;
import com.simibubi.create.content.logistics.stockTicker.StockTickerBlockEntity;
import com.simibubi.create.content.processing.basin.BasinBlock;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
@ -128,8 +127,7 @@ public class BlazeBurnerBlockEntity extends SmartBlockEntity {
if (level instanceof Level l && !l.isLoaded(pos))
return null;
BlockState blockState = level.getBlockState(pos.relative(direction));
if (!AllBlocks.STOCK_TICKER.has(blockState)
|| blockState.getValue(StockTickerBlock.FACING) == direction.getOpposite())
if (!AllBlocks.STOCK_TICKER.has(blockState))
continue;
if (level.getBlockEntity(pos.relative(direction)) instanceof StockTickerBlockEntity stbe)
return stbe;

View file

@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable;
import com.simibubi.create.AllPartialModels;
import com.simibubi.create.AllSpriteShifts;
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.foundation.render.AllInstanceTypes;
import dev.engine_room.flywheel.api.instance.Instance;
@ -29,14 +30,16 @@ import net.minecraft.util.Mth;
public class BlazeBurnerVisual extends AbstractBlockEntityVisual<BlazeBurnerBlockEntity> implements SimpleDynamicVisual, SimpleTickableVisual {
private final BlazeBurnerBlock.HeatLevel heatLevel;
private BlazeBurnerBlock.HeatLevel heatLevel;
private final TransformedInstance head;
private final TransformedInstance smallRods;
private final TransformedInstance largeRods;
private final boolean isInert;
@Nullable
private TransformedInstance smallRods;
@Nullable
private TransformedInstance largeRods;
@Nullable
private ScrollInstance flame;
@Nullable
@ -49,7 +52,7 @@ public class BlazeBurnerVisual extends AbstractBlockEntityVisual<BlazeBurnerBloc
public BlazeBurnerVisual(VisualizationContext ctx, BlazeBurnerBlockEntity blockEntity, float partialTick) {
super(ctx, blockEntity, partialTick);
heatLevel = blockEntity.getHeatLevelForRender();
heatLevel = HeatLevel.SMOULDERING;
validBlockAbove = blockEntity.isValidBlockAbove();
PartialModel blazeModel = BlazeBurnerRenderer.getBlazeModel(heatLevel, validBlockAbove);
@ -60,24 +63,6 @@ public class BlazeBurnerVisual extends AbstractBlockEntityVisual<BlazeBurnerBloc
head.light(LightTexture.FULL_BRIGHT);
if (heatLevel.isAtLeast(BlazeBurnerBlock.HeatLevel.FADING)) {
PartialModel rodsModel = heatLevel == BlazeBurnerBlock.HeatLevel.SEETHING ? AllPartialModels.BLAZE_BURNER_SUPER_RODS
: AllPartialModels.BLAZE_BURNER_RODS;
PartialModel rodsModel2 = heatLevel == BlazeBurnerBlock.HeatLevel.SEETHING ? AllPartialModels.BLAZE_BURNER_SUPER_RODS_2
: AllPartialModels.BLAZE_BURNER_RODS_2;
smallRods = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(rodsModel))
.createInstance();
largeRods = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(rodsModel2))
.createInstance();
smallRods.light(LightTexture.FULL_BRIGHT);
largeRods.light(LightTexture.FULL_BRIGHT);
} else {
smallRods = null;
largeRods = null;
}
animate(partialTick);
}
@ -99,13 +84,42 @@ public class BlazeBurnerVisual extends AbstractBlockEntityVisual<BlazeBurnerBloc
float animation = blockEntity.headAnimation.getValue(partialTicks) * .175f;
boolean validBlockAbove = animation > 0.125f;
HeatLevel heatLevel = blockEntity.getHeatLevelForRender();
if (validBlockAbove != this.validBlockAbove) {
if (validBlockAbove != this.validBlockAbove || heatLevel != this.heatLevel) {
this.validBlockAbove = validBlockAbove;
PartialModel blazeModel = BlazeBurnerRenderer.getBlazeModel(heatLevel, validBlockAbove);
instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(blazeModel))
.stealInstance(head);
boolean needsRods = heatLevel.isAtLeast(BlazeBurnerBlock.HeatLevel.FADING);
boolean hasRods = this.heatLevel.isAtLeast(HeatLevel.FADING);
if (needsRods && !hasRods) {
PartialModel rodsModel = heatLevel == BlazeBurnerBlock.HeatLevel.SEETHING ? AllPartialModels.BLAZE_BURNER_SUPER_RODS
: AllPartialModels.BLAZE_BURNER_RODS;
PartialModel rodsModel2 = heatLevel == BlazeBurnerBlock.HeatLevel.SEETHING ? AllPartialModels.BLAZE_BURNER_SUPER_RODS_2
: AllPartialModels.BLAZE_BURNER_RODS_2;
smallRods = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(rodsModel))
.createInstance();
largeRods = instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(rodsModel2))
.createInstance();
smallRods.light(LightTexture.FULL_BRIGHT);
largeRods.light(LightTexture.FULL_BRIGHT);
} else if (!needsRods && hasRods) {
if (smallRods != null)
smallRods.delete();
if (largeRods != null)
largeRods.delete();
smallRods = null;
largeRods = null;
}
this.heatLevel = heatLevel;
}
// Switch between showing/hiding the flame
@ -168,15 +182,8 @@ public class BlazeBurnerVisual extends AbstractBlockEntityVisual<BlazeBurnerBloc
if (hat != null) {
hat.setIdentityTransform()
.translate(getVisualPosition())
.translateY(headY);
if (isInert) {
hat.translateY(0.5f)
.center()
.scale(0.75f)
.uncenter();
} else {
hat.translateY(0.75f);
}
.translateY(headY)
.translateY(0.75f);
hat.rotateCentered(horizontalAngle + Mth.PI, Direction.UP)
.translate(0.5f, 0, 0.5f)
.light(LightTexture.FULL_BRIGHT);

View file

@ -9,6 +9,8 @@ import java.util.Map;
import com.simibubi.create.Create;
import com.simibubi.create.content.trains.entity.Train;
import net.createmod.catnip.data.Glob;
import net.minecraft.network.chat.MutableComponent;
public class GlobalTrainDisplayData {
@ -30,7 +32,7 @@ public class GlobalTrainDisplayData {
}
public static List<TrainDeparturePrediction> prepare(String filter, int maxLines) {
String regex = filter.isBlank() ? filter : "\\Q" + filter.replace("*", "\\E.*\\Q") + "\\E";
String regex = Glob.toRegexPattern(filter, "");
return statusByDestination.entrySet()
.stream()
.filter(e -> e.getKey()

View file

@ -6,6 +6,8 @@ import java.util.regex.PatternSyntaxException;
import javax.annotation.Nullable;
import net.createmod.catnip.data.Glob;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.ImmutableList;
@ -55,10 +57,7 @@ public class DestinationInstruction extends TextScheduleInstruction {
}
public String getFilterForRegex() {
String filter = getFilter();
if (filter.isBlank())
return filter;
return "\\Q" + filter.replace("*", "\\E.*\\Q") + "\\E";
return Glob.toRegexPattern(getFilter(), "");
}
@Override

View file

@ -5,6 +5,8 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.regex.PatternSyntaxException;
import net.createmod.catnip.data.Glob;
import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.ImmutableList;
@ -66,10 +68,7 @@ public class FetchPackagesInstruction extends TextScheduleInstruction {
}
public String getFilterForRegex() {
String filter = getFilter();
if (filter.isBlank())
return filter;
return "\\Q" + filter.replace("*", "\\E.*\\Q") + "\\E";
return Glob.toRegexPattern(getFilter(), "");
}
@Override

View file

@ -185,8 +185,9 @@ public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity
return behaviours.values();
}
protected void attachBehaviourLate(BlockEntityBehaviour behaviour) {
public void attachBehaviourLate(BlockEntityBehaviour behaviour) {
behaviours.put(behaviour.getType(), behaviour);
behaviour.blockEntity = this;
behaviour.initialize();
}
@ -195,7 +196,7 @@ public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity
.reduce(ItemRequirement.NONE, (r, b) -> r.union(b.getRequiredItems()), ItemRequirement::union);
}
protected void removeBehaviour(BehaviourType<?> type) {
public void removeBehaviour(BehaviourType<?> type) {
BlockEntityBehaviour remove = behaviours.remove(type);
if (remove != null) {
remove.unload();

View file

@ -283,9 +283,7 @@ public class FilteringBehaviour extends BlockEntityBehaviour implements ValueSet
ItemStack itemInHand = player.getItemInHand(hand);
ItemStack toApply = itemInHand.copy();
if (AllItems.WRENCH.isIn(toApply))
return;
if (AllBlocks.MECHANICAL_ARM.isIn(toApply))
if (!canShortInteract(toApply))
return;
if (level.isClientSide())
return;
@ -320,6 +318,14 @@ public class FilteringBehaviour extends BlockEntityBehaviour implements ValueSet
level.playSound(null, pos, SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, .25f, .1f);
}
public boolean canShortInteract(ItemStack toApply) {
if (AllItems.WRENCH.isIn(toApply))
return false;
if (AllBlocks.MECHANICAL_ARM.isIn(toApply))
return false;
return true;
}
public MutableComponent getLabel() {
if (customLabel != null)
return customLabel;

View file

@ -166,7 +166,8 @@ public class AllIcons implements ScreenElement {
I_SEND_ONLY = newRow(),
I_SEND_AND_RECEIVE = next(),
I_PARTIAL_REQUESTS = next(),
I_FULL_REQUESTS = next();
I_FULL_REQUESTS = next(),
I_MOVE_GAUGE = next();
;
public AllIcons(int x, int y) {

View file

@ -1054,6 +1054,7 @@
"create.gui.factory_panel.title_as_recipe": "Recipe Settings",
"create.gui.factory_panel.title_as_restocker": "Restocker Settings",
"create.gui.factory_panel.connect_input": "Add new connection",
"create.gui.factory_panel.relocate": "Move this gauge",
"create.gui.factory_panel.reset": "Reset all settings",
"create.gui.factory_panel.save_and_close": "Save and close",
"create.gui.factory_panel.no_open_promises": "No open promises",
@ -1121,8 +1122,11 @@
"create.factory_panel.no_item": "Input gauge must have an item first",
"create.factory_panel.panels_connected": "Now using %1$s to create %2$s",
"create.factory_panel.link_connected": "Gauge connected to %1$s",
"create.factory_panel.relocated": "Gauge moved to new position",
"create.factory_panel.click_second_panel": "Click a second gauge to connect...",
"create.factory_panel.click_to_relocate": "Click a spot to relocate this panel to...",
"create.factory_panel.connection_aborted": "Input connection aborted",
"create.factory_panel.relocation_aborted": "Gauge relocation aborted",
"create.factory_panel.cannot_add_more_inputs": "Cannot add more inputs to this gauge",
"create.factory_panel.already_connected": "Gauges are already connected",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 4 KiB