diff --git a/src/main/java/com/simibubi/create/AllPackets.java b/src/main/java/com/simibubi/create/AllPackets.java index 60126b718..f8822fffa 100644 --- a/src/main/java/com/simibubi/create/AllPackets.java +++ b/src/main/java/com/simibubi/create/AllPackets.java @@ -5,17 +5,14 @@ import java.util.function.Function; import java.util.function.Supplier; import com.simibubi.create.foundation.behaviour.filtering.FilteringCountUpdatePacket; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueUpdatePacket; import com.simibubi.create.foundation.command.ConfigureConfigPacket; import com.simibubi.create.foundation.packet.NbtPacket; import com.simibubi.create.foundation.packet.SimplePacketBase; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket; -import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ConfigureChassisPacket; -import com.simibubi.create.modules.contraptions.components.mixer.ConfigureMixerPacket; -import com.simibubi.create.modules.contraptions.components.motor.ConfigureMotorPacket; import com.simibubi.create.modules.curiosities.blockzapper.BlockzapperBeamPacket; import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket; -import com.simibubi.create.modules.logistics.block.diodes.ConfigureFlexpeaterPacket; import com.simibubi.create.modules.logistics.item.filter.FilterScreenPacket; import com.simibubi.create.modules.logistics.packet.ConfigureFlexcratePacket; import com.simibubi.create.modules.logistics.packet.ConfigureStockswitchPacket; @@ -36,14 +33,11 @@ public enum AllPackets { CONFIGURE_SCHEMATICANNON(ConfigureSchematicannonPacket.class, ConfigureSchematicannonPacket::new), CONFIGURE_FLEXCRATE(ConfigureFlexcratePacket.class, ConfigureFlexcratePacket::new), CONFIGURE_STOCKSWITCH(ConfigureStockswitchPacket.class, ConfigureStockswitchPacket::new), - CONFIGURE_CHASSIS(ConfigureChassisPacket.class, ConfigureChassisPacket::new), - CONFIGURE_MOTOR(ConfigureMotorPacket.class, ConfigureMotorPacket::new), - CONFIGURE_FLEXPEATER(ConfigureFlexpeaterPacket.class, ConfigureFlexpeaterPacket::new), - CONFIGURE_MIXER(ConfigureMixerPacket.class, ConfigureMixerPacket::new), PLACE_SCHEMATIC(SchematicPlacePacket.class, SchematicPlacePacket::new), UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new), CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new), CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new), + CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new), diff --git a/src/main/java/com/simibubi/create/ClientEvents.java b/src/main/java/com/simibubi/create/ClientEvents.java index c2ecd4a6b..81e38cbc2 100644 --- a/src/main/java/com/simibubi/create/ClientEvents.java +++ b/src/main/java/com/simibubi/create/ClientEvents.java @@ -5,7 +5,7 @@ import java.util.List; import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.behaviour.filtering.FilteringHandler; -import com.simibubi.create.foundation.block.IHaveScrollableValue; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueHandler; import com.simibubi.create.foundation.gui.ScreenOpener; import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -100,9 +100,9 @@ public class ClientEvents { double delta = event.getScrollDelta(); boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta) - || CreateClient.schematicAndQuillHandler.mouseScrolled(delta) - || IHaveScrollableValue.onScroll(delta) - || FilteringHandler.onScroll(delta); + || CreateClient.schematicAndQuillHandler.mouseScrolled(delta) + || FilteringHandler.onScroll(delta) + || ScrollValueHandler.onScroll(delta); event.setCanceled(cancelled); } @@ -135,7 +135,7 @@ public class ClientEvents { TooltipHelper.getTooltip(stack).addInformation(toolTip); itemTooltip.addAll(0, toolTip); } - + } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/CenteredSideValueBoxTransform.java b/src/main/java/com/simibubi/create/foundation/behaviour/CenteredSideValueBoxTransform.java new file mode 100644 index 000000000..7198b8553 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/CenteredSideValueBoxTransform.java @@ -0,0 +1,33 @@ +package com.simibubi.create.foundation.behaviour; + +import java.util.function.BiPredicate; + +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public class CenteredSideValueBoxTransform extends ValueBoxTransform.Sided { + + private BiPredicate allowedDirections; + + public CenteredSideValueBoxTransform() { + this((b, d) -> true); + } + + public CenteredSideValueBoxTransform(BiPredicate allowedDirections) { + this.allowedDirections = allowedDirections; + } + + @Override + protected Vec3d getSouthLocation() { + return VecHelper.voxelSpace(8, 8, 16); + } + + @Override + protected boolean isSideActive(BlockState state, Direction direction) { + return allowedDirections.test(state, direction); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBox.java b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBox.java index 225d9d0d4..4c73d4b51 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBox.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBox.java @@ -7,6 +7,8 @@ import net.minecraft.util.math.Vec3d; public class ValueBox { String label = "Value Box"; + String sublabel = ""; + String scrollTooltip = ""; Vec3d labelOffset = Vec3d.ZERO; int passiveColor; int highlightColor; @@ -21,6 +23,16 @@ public class ValueBox { this.labelOffset = offset; return this; } + + public ValueBox subLabel(String sublabel) { + this.sublabel = sublabel; + return this; + } + + public ValueBox scrollTooltip(String scrollTip) { + this.scrollTooltip = scrollTip; + return this; + } public ValueBox withColors(int passive, int highlight) { this.passiveColor = passive; @@ -39,5 +51,15 @@ public class ValueBox { } } + + public static class TextValueBox extends ValueBox { + String text; + + public TextValueBox(String label, AxisAlignedBB bb, String text) { + super(label, bb); + this.text = text; + } + + } } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java index 751ffb929..93c162c76 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxRenderer.java @@ -2,6 +2,7 @@ package com.simibubi.create.foundation.behaviour; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox; +import com.simibubi.create.foundation.behaviour.ValueBox.TextValueBox; import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.modules.contraptions.relays.elementary.ShaftBlock; @@ -52,23 +53,30 @@ public class ValueBoxRenderer { float fontScale = -1 / 64f; Vec3d shift = box.labelOffset; - GlStateManager.scaled(fontScale, fontScale, fontScale); - GlStateManager.translated(17.5f, -5f, 7f); - GlStateManager.translated(shift.x, shift.y, shift.z); - GlStateManager.rotated(0, 1, 0, 0); FontRenderer font = Minecraft.getInstance().fontRenderer; + GlStateManager.scaled(fontScale, fontScale, fontScale); if (highlighted) { - String text = box.label; - font.drawString(text, 0, 0, box.highlightColor); - GlStateManager.translated(0, 0, -1 / 4f); - font.drawString(text, 1, 1, ColorHelper.mixColors(box.passiveColor, 0, 0.75f)); - GlStateManager.translated(0, 0, 1 / 4f); + GlStateManager.pushMatrix(); + GlStateManager.translated(17.5f, -5f, 7f); + GlStateManager.translated(shift.x, shift.y, shift.z); +// GlStateManager.rotated(0, 1, 0, 0); + renderText(box, font, box.label); + if (!box.sublabel.isEmpty()) { + GlStateManager.translated(0, 10, 0); + renderText(box, font, box.sublabel); + } + if (!box.scrollTooltip.isEmpty()) { + GlStateManager.translated(0, 10, 0); + renderText(font, box.scrollTooltip, 0x998899, 0x111111); + } + GlStateManager.popMatrix(); } if (box instanceof ItemValueBox) { ItemValueBox itemValueBox = (ItemValueBox) box; String count = itemValueBox.count == 0 ? "*" : itemValueBox.count + ""; + GlStateManager.translated(17.5f, -5f, 7f); boolean isFilter = itemValueBox.stack.getItem() instanceof FilterItem; if (isFilter) @@ -77,11 +85,44 @@ public class ValueBoxRenderer { GlStateManager.translated(-7 - font.getStringWidth(count), 10, 10 + 1 / 4f); double scale = 1.5; + GlStateManager.rotated(0, 1, 0, 0); GlStateManager.scaled(scale, scale, scale); font.drawString(count, 0, 0, isFilter ? 0xFFFFFF : 0xEDEDED); GlStateManager.translated(0, 0, -1 / 16f); font.drawString(count, 1 - 1 / 8f, 1 - 1 / 8f, 0x4F4F4F); } + + if (box instanceof TextValueBox) { + double scale = 4; + GlStateManager.scaled(scale, scale, 1); + GlStateManager.translated(-4, -4, 5); + + String text = ((TextValueBox) box).text; + int stringWidth = font.getStringWidth(text); + float numberScale = (float) font.FONT_HEIGHT / stringWidth; + boolean singleDigit = stringWidth < 10; + if (singleDigit) + numberScale = numberScale / 2; + float verticalMargin = (stringWidth - font.FONT_HEIGHT) / 2f; + + GlStateManager.scaled(numberScale, numberScale, numberScale); + GlStateManager.translated(singleDigit ? stringWidth / 2 : 0, singleDigit ? -verticalMargin : verticalMargin, + 0); + + renderText(font, text, 0xEDEDED, 0x4f4f4f); + } + + } + + public static void renderText(ValueBox box, FontRenderer font, String text) { + renderText(font, text, box.highlightColor, ColorHelper.mixColors(box.passiveColor, 0, 0.75f)); + } + + public static void renderText(FontRenderer font, String text, int color, int shadowColor) { + font.drawString(text, 0, 0, color); + GlStateManager.translated(0, 0, -1 / 4f); + font.drawString(text, 1, 1, shadowColor); + GlStateManager.translated(0, 0, 1 / 4f); } public static void renderItemIntoValueBox(ItemStack filter) { diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxTransform.java b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxTransform.java new file mode 100644 index 000000000..9feb2c2f5 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/ValueBoxTransform.java @@ -0,0 +1,121 @@ +package com.simibubi.create.foundation.behaviour; + +import java.util.function.Function; + +import org.apache.commons.lang3.tuple.Pair; + +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.GlHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; + +public abstract class ValueBoxTransform { + + protected float scale = getScale(); + + protected abstract Vec3d getLocation(BlockState state); + + protected abstract Vec3d getOrientation(BlockState state); + + public boolean testHit(BlockState state, Vec3d localHit) { + Vec3d offset = getLocation(state); + if (offset == null) + return false; + return localHit.distanceTo(offset) < scale / 2; + } + + public void renderTransformed(BlockState state, Runnable render) { + Vec3d position = getLocation(state); + Vec3d rotation = getOrientation(state); + GlHelper.renderTransformed(position, rotation, scale, render); + } + + protected Vec3d rotateHorizontally(BlockState state, Vec3d vec) { + float yRot = 0; + if (state.has(BlockStateProperties.FACING)) + yRot = AngleHelper.horizontalAngle(state.get(BlockStateProperties.FACING)); + if (state.has(BlockStateProperties.HORIZONTAL_FACING)) + yRot = AngleHelper.horizontalAngle(state.get(BlockStateProperties.HORIZONTAL_FACING)); + return VecHelper.rotateCentered(vec, yRot, Axis.Y); + } + + protected float getScale() { + return .4f; + } + + public static abstract class Dual extends ValueBoxTransform { + + protected boolean first; + + public Dual(boolean first) { + this.first = first; + } + + public boolean isFirst() { + return first; + } + + public static Pair makeSlots(Function factory) { + return Pair.of(factory.apply(true), factory.apply(false)); + } + + public boolean testHit(BlockState state, Vec3d localHit) { + Vec3d offset = getLocation(state); + if (offset == null) + return false; + return localHit.distanceTo(offset) < scale / 3.5f; + } + + } + + public static abstract class Sided extends ValueBoxTransform { + + Direction direction = Direction.UP; + + public Sided fromSide(Direction direction) { + this.direction = direction; + return this; + } + + @Override + protected Vec3d getLocation(BlockState state) { + Vec3d location = getSouthLocation(); + location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(direction), Axis.Y); + location = VecHelper.rotateCentered(location, AngleHelper.verticalAngle(direction), Axis.Z); + return location; + } + + protected abstract Vec3d getSouthLocation(); + + @Override + protected Vec3d getOrientation(BlockState state) { + float yRot = AngleHelper.horizontalAngle(direction) + 180; + float zRot = direction == Direction.UP ? 90 : direction == Direction.DOWN ? 270 : 0; + return new Vec3d(0, yRot, zRot); + } + + @Override + public void renderTransformed(BlockState state, Runnable render) { + if (!isSideActive(state, direction)) + return; + super.renderTransformed(state, render); + } + + @Override + public boolean testHit(BlockState state, Vec3d localHit) { + return isSideActive(state, direction) && super.testHit(state, localHit); + } + + protected boolean isSideActive(BlockState state, Direction direction) { + return true; + } + + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java index d10e3e888..c4469ea1e 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringBehaviour.java @@ -1,9 +1,9 @@ package com.simibubi.create.foundation.behaviour.filtering; import java.util.function.Consumer; -import java.util.function.Function; import com.simibubi.create.AllPackets; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.behaviour.base.IBehaviourType; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; @@ -22,7 +22,7 @@ public class FilteringBehaviour extends TileEntityBehaviour { public static IBehaviourType TYPE = new IBehaviourType() { }; - SlotPositioning slotPositioning; + ValueBoxTransform slotPositioning; boolean showCount; Vec3d textShift; @@ -34,10 +34,10 @@ public class FilteringBehaviour extends TileEntityBehaviour { int ticksUntilScrollPacket; boolean forceClientState; - public FilteringBehaviour(SmartTileEntity te) { + public FilteringBehaviour(SmartTileEntity te, ValueBoxTransform slot) { super(te); filter = ItemStack.EMPTY; - slotPositioning = new SlotPositioning(state -> Vec3d.ZERO, state -> Vec3d.ZERO); + slotPositioning = slot; showCount = false; callback = stack -> { }; @@ -95,11 +95,6 @@ public class FilteringBehaviour extends TileEntityBehaviour { return this; } - public FilteringBehaviour withSlotPositioning(SlotPositioning mapping) { - this.slotPositioning = mapping; - return this; - } - public FilteringBehaviour showCount() { showCount = true; return this; @@ -109,7 +104,7 @@ public class FilteringBehaviour extends TileEntityBehaviour { textShift = shift; return this; } - + @Override public void initialize() { super.initialize(); @@ -125,7 +120,7 @@ public class FilteringBehaviour extends TileEntityBehaviour { else count = stack.getCount(); forceClientState = true; - + tileEntity.markDirty(); tileEntity.sendData(); } @@ -137,10 +132,10 @@ public class FilteringBehaviour extends TileEntityBehaviour { World world = getWorld(); world.addEntity(new ItemEntity(world, pos.x, pos.y, pos.z, filter.copy())); } - + super.remove(); } - + public ItemStack getFilter() { return filter.copy(); } @@ -160,38 +155,16 @@ public class FilteringBehaviour extends TileEntityBehaviour { public boolean testHit(Vec3d hit) { BlockState state = tileEntity.getBlockState(); - Vec3d offset = slotPositioning.offset.apply(state); - if (offset == null) - return false; Vec3d localHit = hit.subtract(new Vec3d(tileEntity.getPos())); - return localHit.distanceTo(offset) < slotPositioning.scale / 2; + return slotPositioning.testHit(state, localHit); } - + public int getAmount() { return count; } - + public boolean anyAmount() { return count == 0; } - public static class SlotPositioning { - Function offset; - Function rotation; - float scale; - - public SlotPositioning(Function offsetForState, - Function rotationForState) { - offset = offsetForState; - rotation = rotationForState; - scale = 1; - } - - public SlotPositioning scale(float scale) { - this.scale = scale; - return this; - } - - } - } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringRenderer.java index ff73ab21c..bf5f1cfe9 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/filtering/FilteringRenderer.java @@ -6,8 +6,6 @@ import com.simibubi.create.foundation.behaviour.ValueBox.ItemValueBox; import com.simibubi.create.foundation.behaviour.ValueBoxRenderer; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; -import com.simibubi.create.foundation.utility.GlHelper; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.modules.logistics.item.filter.FilterItem; @@ -49,16 +47,18 @@ public class FilteringRenderer { TessellatorHelper.prepareForDrawing(); GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); - SlotPositioning slotPositioning = behaviour.slotPositioning; - renderTransformed(state, slotPositioning, () -> { + behaviour.slotPositioning.renderTransformed(state, () -> { AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.25f); String label = Lang.translate("logistics.filter"); ItemStack filter = behaviour.getFilter(); if (filter.getItem() instanceof FilterItem) label = ""; - ValueBox box = behaviour.isCountVisible() ? new ItemValueBox(label, bb, filter, behaviour.scrollableValue) - : new ValueBox(label, bb); + boolean showCount = behaviour.isCountVisible(); + ValueBox box = + showCount ? new ItemValueBox(label, bb, filter, behaviour.scrollableValue) : new ValueBox(label, bb); + if (showCount) + box.scrollTooltip("[" + Lang.translate("action.scroll") + "]"); box.offsetLabel(behaviour.textShift).withColors(0x7777BB, 0xCCBBFF); ValueBoxRenderer.renderBox(box, behaviour.testHit(target.getHitVec())); @@ -79,24 +79,15 @@ public class FilteringRenderer { return; BlockState state = tileEntityIn.getBlockState(); - SlotPositioning slotPositioning = behaviour.slotPositioning; - TessellatorHelper.prepareForDrawing(); BlockPos pos = tileEntityIn.getPos(); GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); - renderTransformed(state, slotPositioning, () -> { + behaviour.slotPositioning.renderTransformed(state, () -> { ValueBoxRenderer.renderItemIntoValueBox(behaviour.getFilter()); }); TessellatorHelper.cleanUpAfterDrawing(); } - private static void renderTransformed(BlockState state, SlotPositioning positioning, Runnable render) { - Vec3d position = positioning.offset.apply(state); - Vec3d rotation = positioning.rotation.apply(state); - float scale = positioning.scale; - GlHelper.renderTransformed(position, rotation, scale, render); - } - } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java index 2868f6fb0..1a3310a6c 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkBehaviour.java @@ -7,6 +7,7 @@ import java.util.function.Supplier; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.Create; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.behaviour.base.IBehaviourType; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; @@ -29,45 +30,44 @@ public class LinkBehaviour extends TileEntityBehaviour { Frequency frequencyFirst; Frequency frequencyLast; - SlotPositioning slotPositioning; + ValueBoxTransform firstSlot; + ValueBoxTransform secondSlot; Vec3d textShift; private Mode mode; private Supplier transmission; private Consumer signalCallback; - protected LinkBehaviour(SmartTileEntity te) { + protected LinkBehaviour(SmartTileEntity te, Pair slots) { super(te); - slotPositioning = new SlotPositioning(state -> Pair.of(Vec3d.ZERO, Vec3d.ZERO), state -> Vec3d.ZERO); frequencyFirst = new Frequency(ItemStack.EMPTY); frequencyLast = new Frequency(ItemStack.EMPTY); + firstSlot = slots.getLeft(); + secondSlot = slots.getRight(); textShift = Vec3d.ZERO; } - public static LinkBehaviour receiver(SmartTileEntity te, Consumer signalCallback) { - LinkBehaviour behaviour = new LinkBehaviour(te); + public static LinkBehaviour receiver(SmartTileEntity te, Pair slots, + Consumer signalCallback) { + LinkBehaviour behaviour = new LinkBehaviour(te, slots); behaviour.signalCallback = signalCallback; behaviour.mode = Mode.RECEIVE; return behaviour; } - public static LinkBehaviour transmitter(SmartTileEntity te, Supplier transmission) { - LinkBehaviour behaviour = new LinkBehaviour(te); + public static LinkBehaviour transmitter(SmartTileEntity te, Pair slots, + Supplier transmission) { + LinkBehaviour behaviour = new LinkBehaviour(te, slots); behaviour.transmission = transmission; behaviour.mode = Mode.TRANSMIT; return behaviour; } - public LinkBehaviour withSlotPositioning(SlotPositioning mapping) { - this.slotPositioning = mapping; - return this; - } - public LinkBehaviour moveText(Vec3d shift) { textShift = shift; return this; } - + public void copyItemsFrom(LinkBehaviour behaviour) { if (behaviour == null) return; @@ -129,8 +129,8 @@ public class LinkBehaviour extends TileEntityBehaviour { stack = stack.copy(); stack.setCount(1); ItemStack toCompare = first ? frequencyFirst.getStack() : frequencyLast.getStack(); - boolean changed = !ItemStack.areItemsEqual(stack, toCompare) - || !ItemStack.areItemStackTagsEqual(stack, toCompare); + boolean changed = + !ItemStack.areItemsEqual(stack, toCompare) || !ItemStack.areItemStackTagsEqual(stack, toCompare); if (changed) getHandler().removeFromNetwork(this); @@ -177,12 +177,8 @@ public class LinkBehaviour extends TileEntityBehaviour { public boolean testHit(Boolean first, Vec3d hit) { BlockState state = tileEntity.getBlockState(); - Pair pair = slotPositioning.offsets.apply(state); - Vec3d offset = first ? pair.getKey() : pair.getValue(); - if (offset == null) - return false; Vec3d localHit = hit.subtract(new Vec3d(tileEntity.getPos())); - return localHit.distanceTo(offset) < slotPositioning.scale / 3.5f; + return (first ? firstSlot : secondSlot).testHit(state, localHit); } } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkRenderer.java index 884fb9f32..83590ce16 100644 --- a/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/behaviour/linked/LinkRenderer.java @@ -2,15 +2,11 @@ package com.simibubi.create.foundation.behaviour.linked; import java.util.function.Consumer; -import org.apache.commons.lang3.tuple.Pair; - import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.foundation.behaviour.ValueBox; import com.simibubi.create.foundation.behaviour.ValueBoxRenderer; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; -import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour.SlotPositioning; -import com.simibubi.create.foundation.utility.GlHelper; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.TessellatorHelper; @@ -48,11 +44,10 @@ public class LinkRenderer { TessellatorHelper.prepareForDrawing(); GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); - SlotPositioning slotPositioning = behaviour.slotPositioning; String freq1 = Lang.translate("logistics.firstFrequency"); String freq2 = Lang.translate("logistics.secondFrequency"); - renderEachSlot(state, slotPositioning, first -> { + renderEachSlot(state, behaviour, first -> { AxisAlignedBB bb = new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.25f); String label = first ? freq2 : freq1; ValueBox box = new ValueBox(label, bb).withColors(0x992266, 0xFF55AA).offsetLabel(behaviour.textShift); @@ -72,13 +67,11 @@ public class LinkRenderer { return; BlockState state = tileEntityIn.getBlockState(); - SlotPositioning slotPositioning = behaviour.slotPositioning; - TessellatorHelper.prepareForDrawing(); BlockPos pos = tileEntityIn.getPos(); GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); - renderEachSlot(state, slotPositioning, first -> { + renderEachSlot(state, behaviour, first -> { ValueBoxRenderer.renderItemIntoValueBox( first ? behaviour.frequencyFirst.getStack() : behaviour.frequencyLast.getStack()); }); @@ -86,13 +79,9 @@ public class LinkRenderer { TessellatorHelper.cleanUpAfterDrawing(); } - private static void renderEachSlot(BlockState state, SlotPositioning positioning, Consumer render) { - Pair position = positioning.offsets.apply(state); - Vec3d rotation = positioning.rotation.apply(state); - float scale = positioning.scale; - - GlHelper.renderTransformed(position.getKey(), rotation, scale, () -> render.accept(true)); - GlHelper.renderTransformed(position.getValue(), rotation, scale, () -> render.accept(false)); + private static void renderEachSlot(BlockState state, LinkBehaviour behaviour, Consumer render) { + behaviour.firstSlot.renderTransformed(state, () -> render.accept(true)); + behaviour.secondSlot.renderTransformed(state, () -> render.accept(false)); } } diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java new file mode 100644 index 000000000..080b724aa --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueBehaviour.java @@ -0,0 +1,171 @@ +package com.simibubi.create.foundation.behaviour.scrollvalue; + +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.function.Function; + +import com.simibubi.create.AllPackets; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.IBehaviourType; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; + +import net.minecraft.block.BlockState; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +public class ScrollValueBehaviour extends TileEntityBehaviour { + + public static IBehaviourType TYPE = new IBehaviourType() { + }; + + ValueBoxTransform slotPositioning; + Vec3d textShift; + + int min = 0; + int max = 1; + public int value; + int scrollableValue; + int ticksUntilScrollPacket; + boolean forceClientState; + String label; + Consumer callback; + Function formatter; + Function unit; + BiFunction step; + boolean needsWrench; + + public ScrollValueBehaviour(String label, SmartTileEntity te, ValueBoxTransform slot) { + super(te); + this.setLabel(label); + slotPositioning = slot; + callback = i -> { + }; + textShift = Vec3d.ZERO; + formatter = i -> Integer.toString(i); + step = (i, b) -> 1; + value = 0; + ticksUntilScrollPacket = -1; + } + + @Override + public void writeNBT(CompoundNBT nbt) { + nbt.putInt("ScrollValue", value); + super.writeNBT(nbt); + } + + @Override + public void readNBT(CompoundNBT nbt) { + value = nbt.getInt("ScrollValue"); + if (nbt.contains("ForceScrollable")) { + ticksUntilScrollPacket = -1; + scrollableValue = value; + } + super.readNBT(nbt); + } + + @Override + public CompoundNBT writeToClient(CompoundNBT compound) { + if (forceClientState) { + compound.putBoolean("ForceScrollable", true); + forceClientState = false; + } + return super.writeToClient(compound); + } + + @Override + public void tick() { + super.tick(); + + if (!getWorld().isRemote) + return; + if (ticksUntilScrollPacket == -1) + return; + if (ticksUntilScrollPacket > 0) { + ticksUntilScrollPacket--; + return; + } + + AllPackets.channel.sendToServer(new ScrollValueUpdatePacket(getPos(), scrollableValue)); + ticksUntilScrollPacket = -1; + } + + public ScrollValueBehaviour withCallback(Consumer valueCallback) { + callback = valueCallback; + return this; + } + + public ScrollValueBehaviour between(int min, int max) { + this.min = min; + this.max = max; + return this; + } + + public ScrollValueBehaviour moveText(Vec3d shift) { + textShift = shift; + return this; + } + + public ScrollValueBehaviour requiresWrench() { + this.needsWrench = true; + return this; + } + + public ScrollValueBehaviour withFormatter(Function formatter) { + this.formatter = formatter; + return this; + } + + public ScrollValueBehaviour withUnit(Function unit) { + this.unit = unit; + return this; + } + + public ScrollValueBehaviour withStepFunction(BiFunction step) { + this.step = step; + return this; + } + + @Override + public void initialize() { + super.initialize(); + setValue(value); + scrollableValue = value; + } + + public void setValue(int value) { + value = MathHelper.clamp(value, min, max); + if (value == this.value) + return; + this.value = value; + forceClientState = true; + callback.accept(value); + tileEntity.markDirty(); + tileEntity.sendData(); + } + + public int getValue() { + return value; + } + + public String formatValue() { + return formatter.apply(scrollableValue); + } + + @Override + public IBehaviourType getType() { + return TYPE; + } + + public boolean testHit(Vec3d hit) { + BlockState state = tileEntity.getBlockState(); + Vec3d localHit = hit.subtract(new Vec3d(tileEntity.getPos())); + return slotPositioning.testHit(state, localHit); + } + + public void setLabel(String label) { + this.label = label; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java new file mode 100644 index 000000000..ef49c2671 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueHandler.java @@ -0,0 +1,52 @@ +package com.simibubi.create.foundation.behaviour.scrollvalue; + +import com.simibubi.create.AllItems; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.RayTraceResult; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber +public class ScrollValueHandler { + + @OnlyIn(Dist.CLIENT) + public static boolean onScroll(double delta) { + RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; + if (!(objectMouseOver instanceof BlockRayTraceResult)) + return false; + + BlockRayTraceResult result = (BlockRayTraceResult) objectMouseOver; + Minecraft mc = Minecraft.getInstance(); + ClientWorld world = mc.world; + BlockPos blockPos = result.getPos(); + + ScrollValueBehaviour scrolling = TileEntityBehaviour.get(world, blockPos, ScrollValueBehaviour.TYPE); + if (scrolling == null) + return false; + if (!mc.player.isAllowEdit()) + return false; + if (scrolling.needsWrench && !AllItems.WRENCH.typeOf(mc.player.getHeldItemMainhand())) + return false; + if (scrolling.slotPositioning instanceof Sided) + ((Sided) scrolling.slotPositioning).fromSide(result.getFace()); + if (!scrolling.testHit(objectMouseOver.getHitVec())) + return false; + + scrolling.ticksUntilScrollPacket = 10; + scrolling.scrollableValue = (int) MathHelper.clamp( + scrolling.scrollableValue + + Math.signum(delta) * scrolling.step.apply(scrolling.scrollableValue, delta > 0), + scrolling.min, scrolling.max); + + return true; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java new file mode 100644 index 000000000..ddeb8ec4b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueRenderer.java @@ -0,0 +1,68 @@ +package com.simibubi.create.foundation.behaviour.scrollvalue; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.AllItems; +import com.simibubi.create.foundation.behaviour.ValueBox; +import com.simibubi.create.foundation.behaviour.ValueBox.TextValueBox; +import com.simibubi.create.foundation.behaviour.ValueBoxRenderer; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.TessellatorHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.client.event.DrawBlockHighlightEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber(value = Dist.CLIENT) +public class ScrollValueRenderer { + + @SubscribeEvent + public static void renderBlockHighlight(DrawBlockHighlightEvent event) { + RayTraceResult target = event.getTarget(); + if (target == null || !(target instanceof BlockRayTraceResult)) + return; + + BlockRayTraceResult result = (BlockRayTraceResult) target; + ClientWorld world = Minecraft.getInstance().world; + BlockPos pos = result.getPos(); + BlockState state = world.getBlockState(pos); + + ScrollValueBehaviour behaviour = TileEntityBehaviour.get(world, pos, ScrollValueBehaviour.TYPE); + if (behaviour == null) + return; + if (behaviour.needsWrench && !AllItems.WRENCH.typeOf(Minecraft.getInstance().player.getHeldItemMainhand())) + return; + + TessellatorHelper.prepareForDrawing(); + GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); + + if (behaviour.slotPositioning instanceof Sided) + ((Sided) behaviour.slotPositioning).fromSide(result.getFace()); + behaviour.slotPositioning.renderTransformed(state, () -> { + + AxisAlignedBB bb = + new AxisAlignedBB(Vec3d.ZERO, Vec3d.ZERO).grow(.5f).contract(0, 0, -.5f).offset(0, 0, -.125f); + String label = behaviour.label; + ValueBox box = new TextValueBox(label, bb, behaviour.formatValue()); + if (behaviour.unit != null) + box.subLabel("(" + behaviour.unit.apply(behaviour.scrollableValue) + ")"); + box.scrollTooltip("[" + Lang.translate("action.scroll") + "]"); + box.offsetLabel(behaviour.textShift.add(20, -10, 0)).withColors(0xbe970b, 0xffe75e); + ValueBoxRenderer.renderBox(box, behaviour.testHit(target.getHitVec())); + + }); + + TessellatorHelper.cleanUpAfterDrawing(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueUpdatePacket.java b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueUpdatePacket.java new file mode 100644 index 000000000..f444c8968 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/behaviour/scrollvalue/ScrollValueUpdatePacket.java @@ -0,0 +1,41 @@ +package com.simibubi.create.foundation.behaviour.scrollvalue; + +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; + +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.math.BlockPos; + +public class ScrollValueUpdatePacket extends TileEntityConfigurationPacket { + + int value; + + public ScrollValueUpdatePacket(PacketBuffer buffer) { + super(buffer); + } + + public ScrollValueUpdatePacket(BlockPos pos, int amount) { + super(pos); + this.value = amount; + } + + @Override + protected void writeSettings(PacketBuffer buffer) { + buffer.writeInt(value); + } + + @Override + protected void readSettings(PacketBuffer buffer) { + value = buffer.readInt(); + } + + @Override + protected void applySettings(SmartTileEntity te) { + ScrollValueBehaviour behaviour = TileEntityBehaviour.get(te, ScrollValueBehaviour.TYPE); + if (behaviour == null) + return; + behaviour.setValue(value); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/block/IHaveScrollableValue.java b/src/main/java/com/simibubi/create/foundation/block/IHaveScrollableValue.java deleted file mode 100644 index 9c0086dbb..000000000 --- a/src/main/java/com/simibubi/create/foundation/block/IHaveScrollableValue.java +++ /dev/null @@ -1,223 +0,0 @@ -package com.simibubi.create.foundation.block; - -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.AllItems; -import com.simibubi.create.foundation.utility.Lang; -import com.simibubi.create.foundation.utility.TessellatorHelper; -import com.simibubi.create.foundation.utility.VecHelper; - -import net.minecraft.block.BlockState; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.Tessellator; -import net.minecraft.client.renderer.WorldRenderer; -import net.minecraft.client.renderer.vertex.DefaultVertexFormats; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.RayTraceResult; -import net.minecraft.util.math.Vec3d; -import net.minecraft.util.text.TextFormatting; -import net.minecraft.world.IWorld; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.DrawBlockHighlightEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod.EventBusSubscriber; - -@EventBusSubscriber(value = Dist.CLIENT) -public interface IHaveScrollableValue { - - public static final AxisAlignedBB VALUE_BB = new AxisAlignedBB(0, 0, 0, 2 / 16f, 6 / 16f, 6 / 16f); - - public int getCurrentValue(BlockState state, IWorld world, BlockPos pos); - - public void onScroll(BlockState state, IWorld world, BlockPos pos, double delta); - - public String getValueName(BlockState state, IWorld world, BlockPos pos); - - public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos); - - public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos); - - public default boolean isValueOnMultipleFaces() { - return false; - } - - public default boolean requiresWrench() { - return false; - } - - public default boolean isValueOnFace(Direction face) { - return true; - } - - public default String getValueSuffix(BlockState state, IWorld world, BlockPos pos) { - return ""; - } - - @SubscribeEvent - @OnlyIn(Dist.CLIENT) - public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) { - if (event.getTarget() == null || !(event.getTarget() instanceof BlockRayTraceResult)) - return; - - BlockRayTraceResult result = (BlockRayTraceResult) event.getTarget(); - Minecraft mc = Minecraft.getInstance(); - ClientWorld world = mc.world; - BlockPos blockPos = result.getPos(); - BlockState state = world.getBlockState(blockPos); - - if (!(state.getBlock() instanceof IHaveScrollableValue)) - return; - if (!mc.player.isAllowEdit()) - return; - - IHaveScrollableValue block = (IHaveScrollableValue) state.getBlock(); - Vec3d pos = new Vec3d(blockPos); - - if (block.requiresWrench() && !AllItems.WRENCH.typeOf(mc.player.getHeldItemMainhand())) - return; - - Vec3d valueBoxPosition = block.getValueBoxPosition(state, world, blockPos); - AxisAlignedBB bb = VALUE_BB.offset(valueBoxPosition); - bb = bb.grow(1 / 128f); - Direction facing = block.isValueOnMultipleFaces() ? result.getFace() - : block.getValueBoxDirection(state, world, blockPos); - if (block.isValueOnMultipleFaces() && !block.isValueOnFace(result.getFace())) - return; - - Vec3d cursor = result.getHitVec().subtract(VecHelper.getCenterOf(blockPos)); - cursor = VecHelper.rotate(cursor, facing.getHorizontalAngle() + 90, Axis.Y); - cursor = VecHelper.rotate(cursor, facing == Direction.UP ? -90 : facing == Direction.DOWN ? 90 : 0, Axis.Z) - .add(.5, .5, .5); - boolean contains = bb.contains(cursor); - - TessellatorHelper.prepareForDrawing(); - GlStateManager.enableBlend(); - GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, - GlStateManager.DestFactor.ZERO); - GlStateManager.disableTexture(); - GlStateManager.depthMask(false); - - Tessellator tessellator = Tessellator.getInstance(); - BufferBuilder bufferbuilder = tessellator.getBuffer(); - bufferbuilder.begin(3, DefaultVertexFormats.POSITION_COLOR); - - GlStateManager.translated(pos.x, pos.y, pos.z); - GlStateManager.translated(.5f, .5f, .5f); - GlStateManager.rotated(-facing.getHorizontalAngle() - 90, 0, 1, 0); - GlStateManager.rotated(facing == Direction.UP ? 90 : facing == Direction.DOWN ? -90 : 0, 0, 0, 1); - GlStateManager.translated(-.5f, -.5f, -.5f); - - GlStateManager.pushMatrix(); - - if (contains) { - GlStateManager.lineWidth(2); - WorldRenderer.drawBoundingBox(bufferbuilder, bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ, 1, .5f, - .75f, 1f); - } else { - GlStateManager.lineWidth(2); - WorldRenderer.drawBoundingBox(bufferbuilder, bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ, .5f, - .25f, .35f, 1f); - } - - tessellator.draw(); - GlStateManager.popMatrix(); - - GlStateManager.enableTexture(); - GlStateManager.depthMask(true); - - float textScale = 1 / 128f; - - GlStateManager.rotated(90, 0, 1, 0); - GlStateManager.translated(1 - valueBoxPosition.z - bb.getZSize(), valueBoxPosition.y + bb.getYSize(), - valueBoxPosition.x); - GlStateManager.translated(-1, 0, 3 / 32f); - - if (contains) { - GlStateManager.pushMatrix(); - GlStateManager.translated(bb.getZSize() + 1 / 32f, -1 / 16f, 0); - GlStateManager.scaled(textScale, -textScale, textScale); - - String text = block.getValueName(state, world, blockPos); - mc.fontRenderer.drawString(text, 0, 0, 0xFF88BB); - GlStateManager.translated(0, 0, -1 / 4f); - mc.fontRenderer.drawString(text, 1, 1, 0x224433); - GlStateManager.translated(0, 0, 1 / 4f); - - text = TextFormatting.ITALIC + "<" + Lang.translate("action.scroll") + ">"; - mc.fontRenderer.drawString(text, 0, 10, 0xCCBBCC); - GlStateManager.translated(0, 0, -1 / 4f); - mc.fontRenderer.drawString(text, 1, 11, 0x111111); - GlStateManager.translated(0, 0, 1 / 4f); - - GlStateManager.popMatrix(); - } - - String numberText = block.getCurrentValue(state, world, blockPos) - + block.getValueSuffix(state, world, blockPos); - int stringWidth = mc.fontRenderer.getStringWidth(numberText); - float numberScale = 4 / 128f * ((float) mc.fontRenderer.FONT_HEIGHT / stringWidth); - boolean singleDigit = stringWidth < 10; - if (singleDigit) - numberScale = numberScale / 2; - GlStateManager.translated(4 / 64f, -5 / 64f, 0); - - GlStateManager.scaled(numberScale, -numberScale, numberScale); - float verticalMargin = (stringWidth - mc.fontRenderer.FONT_HEIGHT) / 2f; - GlStateManager.translated(singleDigit ? stringWidth / 2 : 0, singleDigit ? -verticalMargin : verticalMargin, 0); - - mc.fontRenderer.drawString(numberText, 0, 0, 0xFFFFFF); - GlStateManager.translated(0, 0, -1 / 4f); - mc.fontRenderer.drawString(numberText, 1, 1, 0x224433); - - GlStateManager.disableBlend(); - - GlStateManager.lineWidth(1); - TessellatorHelper.cleanUpAfterDrawing(); - } - - public static boolean onScroll(double delta) { - RayTraceResult objectMouseOver = Minecraft.getInstance().objectMouseOver; - if (!(objectMouseOver instanceof BlockRayTraceResult)) - return false; - - BlockRayTraceResult result = (BlockRayTraceResult) objectMouseOver; - Minecraft mc = Minecraft.getInstance(); - ClientWorld world = mc.world; - BlockPos blockPos = result.getPos(); - BlockState state = world.getBlockState(blockPos); - - if (!(state.getBlock() instanceof IHaveScrollableValue)) - return false; - if (!mc.player.isAllowEdit()) - return false; - - IHaveScrollableValue block = (IHaveScrollableValue) state.getBlock(); - - if (block.requiresWrench() && !AllItems.WRENCH.typeOf(mc.player.getHeldItemMainhand())) - return false; - - Vec3d valueBoxPosition = block.getValueBoxPosition(state, world, blockPos); - AxisAlignedBB bb = VALUE_BB.offset(valueBoxPosition); - bb = bb.grow(1 / 128f); - Direction facing = block.isValueOnMultipleFaces() ? result.getFace() - : block.getValueBoxDirection(state, world, blockPos); - - Vec3d cursor = result.getHitVec().subtract(VecHelper.getCenterOf(blockPos)); - cursor = VecHelper.rotate(cursor, facing.getHorizontalAngle() + 90, Axis.Y); - cursor = VecHelper.rotate(cursor, facing == Direction.UP ? -90 : facing == Direction.DOWN ? 90 : 0, Axis.Z) - .add(.5, .5, .5); - if (!bb.contains(cursor)) - return false; - - block.onScroll(state, world, blockPos, delta); - return true; - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java index dd5aa1c3d..b1cf7e3b7 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/AbstractChassisBlock.java @@ -3,9 +3,6 @@ package com.simibubi.create.modules.contraptions.components.contraptions.chassis import java.util.List; import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.foundation.block.IHaveScrollableValue; -import com.simibubi.create.foundation.block.IWithTileEntity; -import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -23,14 +20,10 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.Vec3d; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; import net.minecraft.world.World; import net.minecraftforge.common.Tags; -public abstract class AbstractChassisBlock extends RotatedPillarBlock - implements IWithTileEntity, IHaveScrollableValue { - - private static final Vec3d valuePos = new Vec3d(15 / 16f, 9 / 16f, 9 / 16f); +public abstract class AbstractChassisBlock extends RotatedPillarBlock { public AbstractChassisBlock(Properties properties) { super(properties); @@ -81,34 +74,6 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock public abstract BooleanProperty getGlueableSide(BlockState state, Direction face); - @Override - public int getCurrentValue(BlockState state, IWorld world, BlockPos pos) { - ChassisTileEntity tileEntity = (ChassisTileEntity) world.getTileEntity(pos); - if (tileEntity == null) - return 0; - return tileEntity.getRange(); - } - - @Override - public String getValueName(BlockState state, IWorld world, BlockPos pos) { - return Lang.translate("generic.range"); - } - - @Override - public boolean requiresWrench() { - return true; - } - - @Override - public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos) { - return valuePos; - } - - @Override - public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) { - return null; - } - @Override public List getDrops(BlockState state, net.minecraft.world.storage.loot.LootContext.Builder builder) { @SuppressWarnings("deprecation") @@ -121,14 +86,4 @@ public abstract class AbstractChassisBlock extends RotatedPillarBlock return drops; } - @Override - public boolean isValueOnMultipleFaces() { - return true; - } - - @Override - public void onScroll(BlockState state, IWorld world, BlockPos pos, double value) { - withTileEntityDo(world, pos, te -> te.setRangeLazily((int) (te.getRange() + value))); - } - } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java index 3da4d9b89..1aa202ca9 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ChassisTileEntity.java @@ -1,65 +1,42 @@ package com.simibubi.create.modules.contraptions.components.contraptions.chassis; -import com.simibubi.create.AllPackets; +import java.util.List; + import com.simibubi.create.AllTileEntities; import com.simibubi.create.config.AllConfigs; -import com.simibubi.create.foundation.block.SyncedTileEntity; +import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.Lang; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.ITickableTileEntity; -import net.minecraft.util.math.MathHelper; +public class ChassisTileEntity extends SmartTileEntity { -public class ChassisTileEntity extends SyncedTileEntity implements ITickableTileEntity { - - private int range; - public int newRange; - public int lastModified; + ScrollValueBehaviour range; public ChassisTileEntity() { super(AllTileEntities.CHASSIS.type); - newRange = range = AllConfigs.SERVER.kinetics.maxChassisRange.get() / 2; } @Override - public CompoundNBT write(CompoundNBT compound) { - compound.putInt("Range", range); - return super.write(compound); + public void addBehaviours(List behaviours) { + int max = AllConfigs.SERVER.kinetics.maxChassisRange.get(); + range = new ScrollValueBehaviour(Lang.translate("generic.range"), this, new CenteredSideValueBoxTransform()); + range.requiresWrench(); + range.between(1, max); + range.value = max / 2; + behaviours.add(range); } @Override - public void read(CompoundNBT compound) { - newRange = range = compound.getInt("Range"); - super.read(compound); + public void initialize() { + super.initialize(); + if (getBlockState().getBlock() instanceof RadialChassisBlock) + range.setLabel(Lang.translate("generic.radius")); } public int getRange() { - if (world.isRemote) - return newRange; - return range; - } - - public void setRange(int range) { - this.range = range; - sendData(); - } - - public void setRangeLazily(int range) { - this.newRange = MathHelper.clamp(range, 1, AllConfigs.SERVER.kinetics.maxChassisRange.get()); - if (newRange == this.range) - return; - this.lastModified = 0; - } - - @Override - public void tick() { - if (!world.isRemote) - return; - if (lastModified == -1) - return; - if (lastModified++ > 10) { - lastModified = -1; - AllPackets.channel.sendToServer(new ConfigureChassisPacket(pos, newRange)); - } + return range.getValue(); } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ConfigureChassisPacket.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ConfigureChassisPacket.java deleted file mode 100644 index 6d917a7e5..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/ConfigureChassisPacket.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.simibubi.create.modules.contraptions.components.contraptions.chassis; - -import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.BlockPos; - -public class ConfigureChassisPacket extends TileEntityConfigurationPacket { - - private int range; - - public ConfigureChassisPacket(BlockPos pos, int range) { - super(pos); - this.range = range; - } - - public ConfigureChassisPacket(PacketBuffer buffer) { - super(buffer); - } - - @Override - protected void writeSettings(PacketBuffer buffer) { - buffer.writeInt(range); - } - - @Override - protected void readSettings(PacketBuffer buffer) { - range = buffer.readInt(); - } - - @Override - protected void applySettings(ChassisTileEntity te) { - te.setRange(range); - te.markDirty(); - te.sendData(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java index ad901312a..1477cc566 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/contraptions/chassis/RadialChassisBlock.java @@ -1,7 +1,5 @@ package com.simibubi.create.modules.contraptions.components.contraptions.chassis; -import com.simibubi.create.foundation.utility.Lang; - import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -9,8 +7,6 @@ import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IWorld; public class RadialChassisBlock extends AbstractChassisBlock { @@ -31,11 +27,6 @@ public class RadialChassisBlock extends AbstractChassisBlock { super.fillStateContainer(builder); } - @Override - public String getValueName(BlockState state, IWorld world, BlockPos pos) { - return Lang.translate("generic.radius"); - } - @Override public BooleanProperty getGlueableSide(BlockState state, Direction face) { Axis axis = state.get(AXIS); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java index e852ccc20..26627a54f 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerBlock.java @@ -3,8 +3,6 @@ package com.simibubi.create.modules.contraptions.components.deployer; import com.simibubi.create.AllItems; import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.utility.AllShapes; -import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.base.DirectionalAxisKineticBlock; import com.simibubi.create.modules.contraptions.components.contraptions.IPortableBlock; import com.simibubi.create.modules.contraptions.components.contraptions.MovementBehaviour; @@ -17,12 +15,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ActionResultType; -import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; -import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; @@ -108,25 +103,6 @@ public class DeployerBlock extends DirectionalAxisKineticBlock return true; } - public static Vec3d getFilterSlotPosition(BlockState state) { - Direction facing = state.get(FACING); - Vec3d vec = VecHelper.voxelSpace(8f, 13.5f, 11.5f); - - float yRot = AngleHelper.horizontalAngle(facing); - float zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; - vec = VecHelper.rotateCentered(vec, yRot, Axis.Y); - vec = VecHelper.rotateCentered(vec, zRot, Axis.Z); - - return vec; - } - - public static Vec3d getFilterSlotOrientation(BlockState state) { - Direction facing = state.get(FACING); - float yRot = AngleHelper.horizontalAngle(facing) + 180; - float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0; - return new Vec3d(0, yRot, zRot); - } - @Override public MovementBehaviour getMovementBehaviour() { return MOVEMENT; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFilterSlot.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFilterSlot.java new file mode 100644 index 000000000..f9ff55edc --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerFilterSlot.java @@ -0,0 +1,35 @@ +package com.simibubi.create.modules.contraptions.components.deployer; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; + +public class DeployerFilterSlot extends ValueBoxTransform { + + @Override + protected Vec3d getLocation(BlockState state) { + Direction facing = state.get(DeployerBlock.FACING); + Vec3d vec = VecHelper.voxelSpace(8f, 13.5f, 11.5f); + + float yRot = AngleHelper.horizontalAngle(facing); + float zRot = facing == Direction.UP ? 270 : facing == Direction.DOWN ? 90 : 0; + vec = VecHelper.rotateCentered(vec, yRot, Axis.Y); + vec = VecHelper.rotateCentered(vec, zRot, Axis.Z); + + return vec; + } + + @Override + protected Vec3d getOrientation(BlockState state) { + Direction facing = state.get(DeployerBlock.FACING); + float yRot = AngleHelper.horizontalAngle(facing) + 180; + float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0; + return new Vec3d(0, yRot, zRot); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java index ad2f0eb09..77d2c2e62 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/deployer/DeployerTileEntity.java @@ -16,7 +16,6 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.advancement.AllCriterionTriggers; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour; import com.simibubi.create.foundation.item.ItemHelper; import com.simibubi.create.foundation.utility.NBTHelper; @@ -81,9 +80,7 @@ public class DeployerTileEntity extends KineticTileEntity { @Override public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); - filtering = new FilteringBehaviour(this).withSlotPositioning( - new SlotPositioning(DeployerBlock::getFilterSlotPosition, DeployerBlock::getFilterSlotOrientation) - .scale(.4f)); + filtering = new FilteringBehaviour(this, new DeployerFilterSlot()); extracting = new ExtractingBehaviour(this, this::getExtractingLocations, this::onExtract); behaviours.add(filtering); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/ConfigureMixerPacket.java b/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/ConfigureMixerPacket.java deleted file mode 100644 index b23bd1651..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/ConfigureMixerPacket.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.simibubi.create.modules.contraptions.components.mixer; - -import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.BlockPos; - -public class ConfigureMixerPacket extends TileEntityConfigurationPacket { - - private int value; - - public ConfigureMixerPacket(BlockPos pos, int value) { - super(pos); - this.value = value; - } - - public ConfigureMixerPacket(PacketBuffer buffer) { - super(buffer); - } - - @Override - protected void writeSettings(PacketBuffer buffer) { - buffer.writeInt(value); - } - - @Override - protected void readSettings(PacketBuffer buffer) { - value = buffer.readInt(); - } - - @Override - protected void applySettings(MechanicalMixerTileEntity te) { - te.minIngredients = value; - te.markDirty(); - te.sendData(); - te.checkBasin = true; - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerBlock.java index f0c7f87f6..d4c979e7a 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerBlock.java @@ -2,10 +2,8 @@ package com.simibubi.create.modules.contraptions.components.mixer; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.block.IHaveCustomBlockItem; -import com.simibubi.create.foundation.block.IHaveScrollableValue; import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.utility.AllShapes; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.KineticBlock; import net.minecraft.block.BlockState; @@ -17,17 +15,14 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; public class MechanicalMixerBlock extends KineticBlock - implements IWithTileEntity, IHaveScrollableValue, IHaveCustomBlockItem { + implements IWithTileEntity, IHaveCustomBlockItem { - private static final Vec3d valuePos = new Vec3d(15.8f / 16f, 6 / 16f, 5 / 16f); public MechanicalMixerBlock() { super(Properties.from(Blocks.ANDESITE)); @@ -42,7 +37,7 @@ public class MechanicalMixerBlock extends KineticBlock protected boolean hasStaticPart() { return true; } - + @Override public boolean isValidPosition(BlockState state, IWorldReader worldIn, BlockPos pos) { return !AllBlocks.BASIN.typeOf(worldIn.getBlockState(pos.down())); @@ -76,49 +71,6 @@ public class MechanicalMixerBlock extends KineticBlock return face.getAxis().isHorizontal(); } - @Override - public String getValueName(BlockState state, IWorld world, BlockPos pos) { - return Lang.translate("mechanical_mixer.min_ingredients"); - } - - @Override - public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos) { - return valuePos; - } - - @Override - public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) { - return null; - } - - @Override - public boolean isValueOnMultipleFaces() { - return true; - } - - @Override - public boolean requiresWrench() { - return true; - } - - @Override - public boolean isValueOnFace(Direction face) { - return face.getAxis().isHorizontal(); - } - - @Override - public void onScroll(BlockState state, IWorld world, BlockPos pos, double value) { - withTileEntityDo(world, pos, te -> te.setMinIngredientsLazily((int) (te.currentValue + value))); - } - - @Override - public int getCurrentValue(BlockState state, IWorld world, BlockPos pos) { - MechanicalMixerTileEntity tileEntity = (MechanicalMixerTileEntity) world.getTileEntity(pos); - if (tileEntity == null) - return 0; - return tileEntity.currentValue; - } - @Override public float getParticleTargetRadius() { return .85f; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerTileEntity.java index 260aabc93..beaea8308 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/mixer/MechanicalMixerTileEntity.java @@ -4,9 +4,12 @@ import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import com.simibubi.create.AllPackets; import com.simibubi.create.AllRecipes; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.components.press.MechanicalPressTileEntity; import com.simibubi.create.modules.contraptions.processing.BasinOperatingTileEntity; @@ -35,15 +38,29 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { public int processingTicks; public boolean running; - public int minIngredients; - public int currentValue; - public int lastModified; + public ScrollValueBehaviour minIngredients; public MechanicalMixerTileEntity() { super(AllTileEntities.MECHANICAL_MIXER.type); - minIngredients = currentValue = 1; - lastModified = -1; - processingTicks = -1; + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + CenteredSideValueBoxTransform slot = + new CenteredSideValueBoxTransform((state, direction) -> direction.getAxis().isHorizontal()) { + + @Override + protected Vec3d getSouthLocation() { + return super.getSouthLocation().add(0, 4/16f, 0); + } + + }; + minIngredients = new ScrollValueBehaviour(Lang.translate("mechanical_mixer.min_ingredients"), this, slot); + minIngredients.between(1, 9); + minIngredients.withCallback(i -> checkBasin = true); + minIngredients.requiresWrench(); + behaviours.add(minIngredients); } public float getRenderedHeadOffset(float partialTicks) { @@ -92,7 +109,6 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { public void read(CompoundNBT compound) { running = compound.getBoolean("Running"); runningTicks = compound.getInt("Ticks"); - currentValue = minIngredients = compound.getInt("MinIngredients"); super.read(compound); } @@ -100,27 +116,11 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { public CompoundNBT write(CompoundNBT compound) { compound.putBoolean("Running", running); compound.putInt("Ticks", runningTicks); - compound.putInt("MinIngredients", minIngredients); return super.write(compound); } - public void setMinIngredientsLazily(int minIngredients) { - this.currentValue = MathHelper.clamp(minIngredients, 1, 9); - if (currentValue == this.minIngredients) - return; - this.lastModified = 0; - } - @Override public void tick() { - - if (world.isRemote && lastModified != -1) { - if (lastModified++ > 10) { - lastModified = -1; - AllPackets.channel.sendToServer(new ConfigureMixerPacket(pos, currentValue)); - } - } - super.tick(); if (runningTicks >= 40) { @@ -187,7 +187,7 @@ public class MechanicalMixerTileEntity extends BasinOperatingTileEntity { protected boolean matchBasinRecipe(IRecipe recipe) { if (recipe == null) return false; - if (recipe.getIngredients().size() < minIngredients) + if (recipe.getIngredients().size() < minIngredients.getValue()) return false; NonNullList ingredients = recipe.getIngredients(); diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/ConfigureMotorPacket.java b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/ConfigureMotorPacket.java deleted file mode 100644 index 7c3186b8a..000000000 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/ConfigureMotorPacket.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.simibubi.create.modules.contraptions.components.motor; - -import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.BlockPos; - -public class ConfigureMotorPacket extends TileEntityConfigurationPacket { - - private int speed; - - public ConfigureMotorPacket(BlockPos pos, int speed) { - super(pos); - this.speed = speed; - } - - public ConfigureMotorPacket(PacketBuffer buffer) { - super(buffer); - } - - @Override - protected void writeSettings(PacketBuffer buffer) { - buffer.writeInt(speed); - } - - @Override - protected void readSettings(PacketBuffer buffer) { - speed = buffer.readInt(); - } - - @Override - protected void applySettings(MotorTileEntity te) { - te.generatedSpeed = speed; - te.updateGeneratedRotation(); - } - -} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java index 8af12a905..79b9a7492 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorBlock.java @@ -1,9 +1,6 @@ package com.simibubi.create.modules.contraptions.components.motor; -import com.simibubi.create.foundation.block.IHaveScrollableValue; -import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.utility.AllShapes; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.HorizontalKineticBlock; import net.minecraft.block.BlockState; @@ -13,17 +10,12 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; import net.minecraft.world.IWorldReader; -public class MotorBlock extends HorizontalKineticBlock - implements IWithTileEntity, IHaveScrollableValue { - - private static final Vec3d valuePos = new Vec3d(15 / 16f, 5 / 16f, 5 / 16f); +public class MotorBlock extends HorizontalKineticBlock { public MotorBlock() { super(Properties.from(Blocks.IRON_BLOCK)); @@ -64,54 +56,6 @@ public class MotorBlock extends HorizontalKineticBlock return true; } - @Override - public int getCurrentValue(BlockState state, IWorld world, BlockPos pos) { - MotorTileEntity tileEntity = (MotorTileEntity) world.getTileEntity(pos); - if (tileEntity == null) - return 0; - return tileEntity.newGeneratedSpeed; - } - - @Override - public void onScroll(BlockState state, IWorld world, BlockPos pos, double delta) { - withTileEntityDo(world, pos, te -> { - boolean forward = delta > 0; - int step = forward ? 1 : -1; - int currentSpeed = te.newGeneratedSpeed; - - if (world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ()).isSneaking()){ - te.setSpeedValueLazily(currentSpeed + step); - return; - } - - int magnitude = Math.abs(currentSpeed) - (forward == currentSpeed > 0 ? 0 : 1); - - if (magnitude >= 4) - step *= 4; - if (magnitude >= 32) - step *= 4; - if (magnitude >= 128) - step *= 4; - - te.setSpeedValueLazily(currentSpeed + step); - }); - } - - @Override - public String getValueName(BlockState state, IWorld world, BlockPos pos) { - return Lang.translate("generic.speed") + " (" + Lang.translate("generic.unit.rpm") + ")"; - } - - @Override - public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos) { - return valuePos; - } - - @Override - public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) { - return state.get(HORIZONTAL_FACING).getOpposite(); - } - @Override public boolean hideStressImpact() { return true; diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java index 363d996c2..8e47bc9cf 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/motor/MotorTileEntity.java @@ -1,74 +1,64 @@ package com.simibubi.create.modules.contraptions.components.motor; +import java.util.List; import java.util.UUID; -import com.simibubi.create.AllPackets; import com.simibubi.create.AllTileEntities; import com.simibubi.create.config.AllConfigs; +import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity; -import net.minecraft.nbt.CompoundNBT; -import net.minecraft.util.math.MathHelper; - public class MotorTileEntity extends GeneratingKineticTileEntity { public static final int DEFAULT_SPEED = 16; - public int newGeneratedSpeed; - public int generatedSpeed; - public int lastModified; + protected ScrollValueBehaviour generatedSpeed; public MotorTileEntity() { super(AllTileEntities.MOTOR.type); - speed = generatedSpeed = newGeneratedSpeed = DEFAULT_SPEED; updateNetwork = true; newNetworkID = UUID.randomUUID(); - lastModified = -1; + speed = DEFAULT_SPEED; + } + + @Override + public void addBehaviours(List behaviours) { + super.addBehaviours(behaviours); + Integer max = AllConfigs.SERVER.kinetics.maxMotorSpeed.get(); + + CenteredSideValueBoxTransform slot = new CenteredSideValueBoxTransform((motor, side) -> { + return motor.get(MotorBlock.HORIZONTAL_FACING) == side.getOpposite(); + }); + + generatedSpeed = new ScrollValueBehaviour(Lang.translate("generic.speed"), this, slot); + generatedSpeed.between(-max, max); + generatedSpeed.value = DEFAULT_SPEED; + generatedSpeed.withUnit(i -> Lang.translate("generic.unit.rpm")); + generatedSpeed.withCallback(i -> this.updateGeneratedRotation()); + generatedSpeed.withStepFunction(this::step); + behaviours.add(generatedSpeed); } @Override public float getGeneratedSpeed() { - return generatedSpeed; + return generatedSpeed.getValue(); } - @Override - public boolean hasFastRenderer() { - return true; - } + private int step(int current, boolean forward) { + if (world.getClosestPlayer(pos.getX(), pos.getY(), pos.getZ()).isSneaking()) + return 1; - @Override - public CompoundNBT write(CompoundNBT compound) { - compound.putInt("GeneratedSpeed", generatedSpeed); - return super.write(compound); - } - - @Override - public void read(CompoundNBT compound) { - generatedSpeed = compound.getInt("GeneratedSpeed"); - if (lastModified == -1) - newGeneratedSpeed = generatedSpeed; - super.read(compound); - } - - public void setSpeedValueLazily(int speed) { - if (newGeneratedSpeed == speed) - return; - Integer max = AllConfigs.SERVER.kinetics.maxMotorSpeed.get(); - newGeneratedSpeed = MathHelper.clamp(speed, -max, max); - this.lastModified = 0; - } - - @Override - public void tick() { - super.tick(); - - if (!world.isRemote) - return; - if (lastModified == -1) - return; - if (lastModified++ > 10) { - lastModified = -1; - AllPackets.channel.sendToServer(new ConfigureMotorPacket(pos, newGeneratedSpeed)); - } + int magnitude = Math.abs(current) - (forward == current > 0 ? 0 : 1); + int step = 1; + if (magnitude >= 4) + step *= 4; + if (magnitude >= 32) + step *= 4; + if (magnitude >= 128) + step *= 4; + return step; } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawFilterSlot.java b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawFilterSlot.java new file mode 100644 index 000000000..43fbb9fdf --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawFilterSlot.java @@ -0,0 +1,26 @@ +package com.simibubi.create.modules.contraptions.components.saw; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public class SawFilterSlot extends ValueBoxTransform { + + @Override + protected Vec3d getLocation(BlockState state) { + if (state.get(SawBlock.FACING) != Direction.UP) + return null; + Vec3d x = VecHelper.voxelSpace(8f, 12.5f, 12.25f); + Vec3d z = VecHelper.voxelSpace(12.25f, 12.5f, 8f); + return state.get(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? z : x; + } + + @Override + protected Vec3d getOrientation(BlockState state) { + return new Vec3d(0, state.get(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? 270 : 180, 90); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java index 69f90f7dc..a4d60f409 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/components/saw/SawTileEntity.java @@ -12,7 +12,6 @@ import com.simibubi.create.AllRecipes; import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.TreeCutter; import com.simibubi.create.foundation.utility.TreeCutter.Tree; @@ -50,7 +49,6 @@ import net.minecraftforge.items.IItemHandler; public class SawTileEntity extends BlockBreakingKineticTileEntity { private static final Object cuttingRecipesKey = new Object(); - private static FilteringBehaviour.SlotPositioning slots; public ProcessingInventory inventory; private int recipeIndex; @@ -68,9 +66,7 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { @Override public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); - if (slots == null) - createSlotPositioning(); - filtering = new FilteringBehaviour(this).withSlotPositioning(slots); + filtering = new FilteringBehaviour(this, new SawFilterSlot()); behaviours.add(filtering); } @@ -389,16 +385,4 @@ public class SawTileEntity extends BlockBreakingKineticTileEntity { return super.canBreak(stateToBreak, blockHardness) && stateToBreak.isIn(BlockTags.LOGS); } - protected void createSlotPositioning() { - slots = new SlotPositioning(state -> { - if (state.get(SawBlock.FACING) != Direction.UP) - return null; - Vec3d x = VecHelper.voxelSpace(8f, 12.5f, 12.25f); - Vec3d z = VecHelper.voxelSpace(12.25f, 12.5f, 8f); - return state.get(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? z : x; - }, state -> { - return new Vec3d(0, state.get(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? 270 : 180, 90); - }).scale(.4f); - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkFrequencySlot.java b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkFrequencySlot.java new file mode 100644 index 000000000..99c9b8a2f --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkFrequencySlot.java @@ -0,0 +1,52 @@ +package com.simibubi.create.modules.logistics.block; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; + +public class RedstoneLinkFrequencySlot extends ValueBoxTransform.Dual { + + public RedstoneLinkFrequencySlot(boolean first) { + super(first); + } + + Vec3d horizontal = VecHelper.voxelSpace(10f, 5.5f, 2.5f); + Vec3d vertical = VecHelper.voxelSpace(10f, 2.5f, 5.5f); + + @Override + protected Vec3d getLocation(BlockState state) { + Direction facing = state.get(RedstoneLinkBlock.FACING); + Vec3d location = vertical; + + if (facing.getAxis().isHorizontal()) { + location = horizontal; + if (!isFirst()) + location = location.add(0, 5 / 16f, 0); + return rotateHorizontally(state, location); + } + + if (!isFirst()) + location = location.add(0, 0, 5 / 16f); + location = VecHelper.rotateCentered(location, facing == Direction.DOWN ? 180 : 0, Axis.X); + return location; + } + + @Override + protected Vec3d getOrientation(BlockState state) { + Direction facing = state.get(RedstoneLinkBlock.FACING); + float yRot = facing.getAxis().isVertical() ? 180 : AngleHelper.horizontalAngle(facing); + float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0; + return new Vec3d(0, yRot + 180, zRot); + } + + @Override + protected float getScale() { + return .5f; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java index 2db7812e6..7a9a01693 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneLinkTileEntity.java @@ -7,23 +7,18 @@ import java.util.List; import org.apache.commons.lang3.tuple.Pair; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour; -import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour.SlotPositioning; -import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; public class RedstoneLinkTileEntity extends SmartTileEntity { - private static LinkBehaviour.SlotPositioning slots; private boolean receivedSignal; private boolean transmittedSignal; private LinkBehaviour link; @@ -49,13 +44,10 @@ public class RedstoneLinkTileEntity extends SmartTileEntity { } protected void createLink() { - if (slots == null) - createSlotPositioning(); - if (transmitter) - link = LinkBehaviour.transmitter(this, this::getSignal); - else - link = LinkBehaviour.receiver(this, this::setSignal); - link.withSlotPositioning(slots); + Pair slots = + ValueBoxTransform.Dual.makeSlots(RedstoneLinkFrequencySlot::new); + link = transmitter ? LinkBehaviour.transmitter(this, slots, this::getSignal) + : LinkBehaviour.receiver(this, slots, this::setSignal); } public boolean getSignal() { @@ -117,39 +109,4 @@ public class RedstoneLinkTileEntity extends SmartTileEntity { return !getBlockState().get(RedstoneLinkBlock.RECEIVER); } - protected void createSlotPositioning() { - slots = new SlotPositioning(state -> { - Direction facing = state.get(RedstoneLinkBlock.FACING); - Vec3d first = Vec3d.ZERO; - Vec3d second = Vec3d.ZERO; - - if (facing.getAxis().isHorizontal()) { - first = VecHelper.voxelSpace(10f, 5.5f, 2.5f); - second = VecHelper.voxelSpace(10f, 10.5f, 2.5f); - - float angle = facing.getHorizontalAngle(); - if (facing.getAxis() == Axis.X) - angle = -angle; - - first = VecHelper.rotateCentered(first, angle, Axis.Y); - second = VecHelper.rotateCentered(second, angle, Axis.Y); - - } else { - first = VecHelper.voxelSpace(10f, 2.5f, 5.5f); - second = VecHelper.voxelSpace(10f, 2.5f, 10.5f); - - if (facing == Direction.DOWN) { - first = VecHelper.rotateCentered(first, 180, Axis.X); - second = VecHelper.rotateCentered(second, 180, Axis.X); - } - } - return Pair.of(first, second); - }, state -> { - Direction facing = state.get(RedstoneLinkBlock.FACING); - float yRot = facing.getAxis().isVertical() ? 180 : AngleHelper.horizontalAngle(facing); - float zRot = facing == Direction.UP ? 90 : facing == Direction.DOWN ? 270 : 0; - return new Vec3d(0, yRot + 180, zRot); - }).scale(.5f); - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverFilterSlot.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverFilterSlot.java new file mode 100644 index 000000000..cb8a12023 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverFilterSlot.java @@ -0,0 +1,26 @@ +package com.simibubi.create.modules.logistics.block.belts; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.block.HorizontalBlock; +import net.minecraft.util.math.Vec3d; + +public class BeltObserverFilterSlot extends ValueBoxTransform { + + Vec3d position = VecHelper.voxelSpace(8f, 14.5f, 16f); + + @Override + protected Vec3d getLocation(BlockState state) { + return rotateHorizontally(state, position); + } + + @Override + protected Vec3d getOrientation(BlockState state) { + float yRot = AngleHelper.horizontalAngle(state.get(HorizontalBlock.HORIZONTAL_FACING)); + return new Vec3d(0, 180 + yRot, 90); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverTileEntity.java index 7aa8351f0..aecb0662a 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/BeltObserverTileEntity.java @@ -6,21 +6,15 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; -import com.simibubi.create.foundation.utility.AngleHelper; -import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.logistics.block.belts.BeltObserverBlock.Mode; -import net.minecraft.block.HorizontalBlock; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.Vec3d; public class BeltObserverTileEntity extends SmartTileEntity { - private static FilteringBehaviour.SlotPositioning slots; private FilteringBehaviour filtering; public int turnOffTicks = 0; @@ -29,6 +23,12 @@ public class BeltObserverTileEntity extends SmartTileEntity { setLazyTickRate(20); } + @Override + public void addBehaviours(List behaviours) { + filtering = new FilteringBehaviour(this, new BeltObserverFilterSlot()).moveText(new Vec3d(0, 5, 0)); + behaviours.add(filtering); + } + @Override public void tick() { super.tick(); @@ -51,7 +51,7 @@ public class BeltObserverTileEntity extends SmartTileEntity { BeltTileEntity controllerTE = belt.getControllerTE(); if (controllerTE == null) return; - + controllerTE.getInventory().forEachWithin(belt.index + .5f, .45f, stack -> { if (filtering.test(stack.stack) && turnOffTicks != 6) { world.setBlockState(pos, getBlockState().with(BeltObserverBlock.POWERED, true)); @@ -83,23 +83,4 @@ public class BeltObserverTileEntity extends SmartTileEntity { super.read(compound); } - @Override - public void addBehaviours(List behaviours) { - if (slots == null) - createSlotPositioning(); - filtering = new FilteringBehaviour(this).withSlotPositioning(slots).moveText(new Vec3d(0, 5, 0)); - behaviours.add(filtering); - } - - protected void createSlotPositioning() { - slots = new SlotPositioning(state -> { - float yRot = AngleHelper.horizontalAngle(state.get(HorizontalBlock.HORIZONTAL_FACING)); - Vec3d position = VecHelper.voxelSpace(8f, 14.5f, 16f); - return VecHelper.rotateCentered(position, yRot, Axis.Y); - }, state -> { - float yRot = AngleHelper.horizontalAngle(state.get(HorizontalBlock.HORIZONTAL_FACING)); - return new Vec3d(0, 180 + yRot, 90); - }).scale(.4f); - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelFilterSlot.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelFilterSlot.java new file mode 100644 index 000000000..b3d4d3867 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelFilterSlot.java @@ -0,0 +1,47 @@ +package com.simibubi.create.modules.logistics.block.belts; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; + +public class FunnelFilterSlot extends ValueBoxTransform { + + Vec3d offsetForHorizontal = VecHelper.voxelSpace(8f, 14f, 13.5f); + Vec3d offsetForBelt = VecHelper.voxelSpace(8f, 8.5f, 14f); + Vec3d offsetForUpward = VecHelper.voxelSpace(8f, 13.5f, 2f); + Vec3d offsetForDownward = VecHelper.voxelSpace(8f, 2.5f, 2f); + + @Override + protected Vec3d getLocation(BlockState state) { + Vec3d vec = offsetForHorizontal; + float yRot = AngleHelper.horizontalAngle(state.get(ExtractorBlock.HORIZONTAL_FACING)); + if (AttachedLogisticalBlock.isVertical(state)) + vec = state.get(AttachedLogisticalBlock.UPWARD) ? offsetForUpward : offsetForDownward; + else if (state.get(FunnelBlock.BELT)) + vec = offsetForBelt; + + return VecHelper.rotateCentered(vec, yRot, Axis.Y); + } + + @Override + protected Vec3d getOrientation(BlockState state) { + Direction blockFacing = AttachedLogisticalBlock.getBlockFacing(state); + boolean vertical = AttachedLogisticalBlock.isVertical(state); + float horizontalAngle = AngleHelper.horizontalAngle(state.get(ExtractorBlock.HORIZONTAL_FACING)); + + float yRot = blockFacing == Direction.DOWN ? horizontalAngle + 180 : horizontalAngle; + float zRot = (vertical || state.get(FunnelBlock.BELT)) ? 90 : 0; + + if (blockFacing == Direction.UP) + zRot += 180; + + return new Vec3d(0, yRot, zRot); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java index 640e54271..6f8122117 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/belts/FunnelTileEntity.java @@ -8,13 +8,10 @@ import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; import com.simibubi.create.foundation.behaviour.inventory.InsertingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.InventoryManagementBehaviour.Attachments; -import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; -import com.simibubi.create.modules.logistics.block.extractor.ExtractorBlock; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; @@ -23,7 +20,6 @@ import net.minecraft.particles.ParticleTypes; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; -import net.minecraft.util.Direction.Axis; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @@ -31,7 +27,6 @@ import net.minecraft.util.math.Vec3i; public class FunnelTileEntity extends SmartTileEntity { - private static FilteringBehaviour.SlotPositioning slots; private FilteringBehaviour filtering; private InsertingBehaviour inserting; private ItemStack justEaten; @@ -42,9 +37,7 @@ public class FunnelTileEntity extends SmartTileEntity { @Override public void addBehaviours(List behaviours) { - if (slots == null) - createSlotPositioning(); - filtering = new FilteringBehaviour(this).withCallback(this::filterChanged).withSlotPositioning(slots); + filtering = new FilteringBehaviour(this, new FunnelFilterSlot()).withCallback(this::filterChanged); behaviours.add(filtering); inserting = new InsertingBehaviour(this, Attachments.toward(() -> AttachedLogisticalBlock.getBlockFacing(getBlockState()))); @@ -125,35 +118,4 @@ public class FunnelTileEntity extends SmartTileEntity { 1 / 6f, zSpeed); } - protected void createSlotPositioning() { - slots = new SlotPositioning(state -> { - Vec3d offsetForHorizontal = VecHelper.voxelSpace(8f, 14f, 13.5f); - Vec3d offsetForBelt = VecHelper.voxelSpace(8f, 8.5f, 14f); - Vec3d offsetForUpward = VecHelper.voxelSpace(8f, 13.5f, 2f); - Vec3d offsetForDownward = VecHelper.voxelSpace(8f, 2.5f, 2f); - Vec3d vec = offsetForHorizontal; - - float yRot = AngleHelper.horizontalAngle(state.get(ExtractorBlock.HORIZONTAL_FACING)); - if (AttachedLogisticalBlock.isVertical(state)) - vec = state.get(AttachedLogisticalBlock.UPWARD) ? offsetForUpward : offsetForDownward; - else if (state.get(FunnelBlock.BELT)) - vec = offsetForBelt; - - return VecHelper.rotateCentered(vec, yRot, Axis.Y); - - }, state -> { - Direction blockFacing = AttachedLogisticalBlock.getBlockFacing(state); - boolean vertical = AttachedLogisticalBlock.isVertical(state); - float horizontalAngle = AngleHelper.horizontalAngle(state.get(ExtractorBlock.HORIZONTAL_FACING)); - - float yRot = blockFacing == Direction.DOWN ? horizontalAngle + 180 : horizontalAngle; - float zRot = (vertical || state.get(FunnelBlock.BELT)) ? 90 : 0; - - if (blockFacing == Direction.UP) - zRot += 180; - - return new Vec3d(0, yRot, zRot); - }).scale(.4f); - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/ConfigureFlexpeaterPacket.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/ConfigureFlexpeaterPacket.java deleted file mode 100644 index b68759606..000000000 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/ConfigureFlexpeaterPacket.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.simibubi.create.modules.logistics.block.diodes; - -import com.simibubi.create.foundation.packet.TileEntityConfigurationPacket; - -import net.minecraft.network.PacketBuffer; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.MathHelper; - -public class ConfigureFlexpeaterPacket extends TileEntityConfigurationPacket { - - private int maxState; - - public ConfigureFlexpeaterPacket(BlockPos pos, int newMaxState) { - super(pos); - this.maxState = newMaxState; - } - - public ConfigureFlexpeaterPacket(PacketBuffer buffer) { - super(buffer); - } - - @Override - protected void writeSettings(PacketBuffer buffer) { - buffer.writeInt(maxState); - } - - @Override - protected void readSettings(PacketBuffer buffer) { - maxState = buffer.readInt(); - } - - @Override - protected void applySettings(FlexpeaterTileEntity te) { - te.maxState = maxState; - te.state = MathHelper.clamp(te.state, 0, maxState); - te.forceClientState = true; - te.sendData(); - te.forceClientState = false; - } - -} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexPulsepeaterTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexPulsepeaterTileEntity.java index 863634803..1f15bf71b 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexPulsepeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexPulsepeaterTileEntity.java @@ -1,7 +1,6 @@ package com.simibubi.create.modules.logistics.block.diodes; import static com.simibubi.create.modules.logistics.block.diodes.FlexpeaterBlock.POWERING; -import static net.minecraft.block.RedstoneDiodeBlock.POWERED; import com.simibubi.create.AllTileEntities; @@ -10,16 +9,9 @@ public class FlexPulsepeaterTileEntity extends FlexpeaterTileEntity { public FlexPulsepeaterTileEntity() { super(AllTileEntities.FLEXPULSEPEATER.type); } - - @Override - public void tick() { - updateConfigurableValue(); - - boolean powered = getBlockState().get(POWERED); - boolean powering = getBlockState().get(POWERING); - boolean atMax = state >= maxState; - boolean isReset = state == 0; + @Override + protected void updateState(boolean powered, boolean powering, boolean atMax, boolean atMin) { if (!charging && powered && !atMax) charging = true; @@ -37,7 +29,7 @@ public class FlexPulsepeaterTileEntity extends FlexpeaterTileEntity { if (!charging && powered) return; - if (!charging && !isReset) { + if (!charging && !atMin) { if (!world.isRemote) world.setBlockState(pos, getBlockState().with(POWERING, false)); state = 0; diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterBlock.java index 0373b3bb6..dc2d0ca72 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterBlock.java @@ -1,9 +1,6 @@ package com.simibubi.create.modules.logistics.block.diodes; import com.simibubi.create.AllBlocks; -import com.simibubi.create.foundation.block.IHaveScrollableValue; -import com.simibubi.create.foundation.block.IWithTileEntity; -import com.simibubi.create.foundation.utility.Lang; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -14,15 +11,11 @@ import net.minecraft.state.StateContainer.Builder; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Vec3d; import net.minecraft.world.IBlockReader; -import net.minecraft.world.IWorld; -public class FlexpeaterBlock extends RedstoneDiodeBlock - implements IWithTileEntity, IHaveScrollableValue { +public class FlexpeaterBlock extends RedstoneDiodeBlock { public static BooleanProperty POWERING = BooleanProperty.create("powering"); - private static Vec3d VALUE_POS = new Vec3d(2 / 16f, 5 / 16f, 5 / 16f); public FlexpeaterBlock() { super(Properties.from(Blocks.REPEATER)); @@ -59,7 +52,7 @@ public class FlexpeaterBlock extends RedstoneDiodeBlock protected int getDelay(BlockState p_196346_1_) { return 0; } - + @Override public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) { if (side == null) @@ -67,43 +60,4 @@ public class FlexpeaterBlock extends RedstoneDiodeBlock return side.getAxis() == state.get(HORIZONTAL_FACING).getAxis(); } - @Override - public int getCurrentValue(BlockState state, IWorld world, BlockPos pos) { - FlexpeaterTileEntity te = (FlexpeaterTileEntity) world.getTileEntity(pos); - if (te == null) - return 0; - return te.getDisplayValue(); - } - - @Override - public void onScroll(BlockState state, IWorld world, BlockPos pos, double delta) { - withTileEntityDo(world, pos, te -> te.increment((int) Math.signum(delta))); - } - - @Override - public String getValueName(BlockState state, IWorld world, BlockPos pos) { - FlexpeaterTileEntity te = (FlexpeaterTileEntity) world.getTileEntity(pos); - if (te == null) - return ""; - return Lang.translate("generic.delay") + " (" + Lang.translate("generic.unit." + te.getUnit()) + ")"; - } - - @Override - public String getValueSuffix(BlockState state, IWorld world, BlockPos pos) { - FlexpeaterTileEntity te = (FlexpeaterTileEntity) world.getTileEntity(pos); - if (te == null) - return ""; - return "" + te.getUnit().charAt(0); - } - - @Override - public Vec3d getValueBoxPosition(BlockState state, IWorld world, BlockPos pos) { - return VALUE_POS; - } - - @Override - public Direction getValueBoxDirection(BlockState state, IWorld world, BlockPos pos) { - return Direction.UP; - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterScrollSlot.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterScrollSlot.java new file mode 100644 index 000000000..f1fc8cc02 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterScrollSlot.java @@ -0,0 +1,23 @@ +package com.simibubi.create.modules.logistics.block.diodes; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.util.math.Vec3d; + +public class FlexpeaterScrollSlot extends ValueBoxTransform { + + @Override + protected Vec3d getLocation(BlockState state) { + return VecHelper.voxelSpace(8, 3f, 8); + } + + @Override + protected Vec3d getOrientation(BlockState state) { + return new Vec3d(0, AngleHelper.horizontalAngle(state.get(BlockStateProperties.HORIZONTAL_FACING)) + 180, 90); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java index 870c61a96..ad99bdf1d 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntity.java @@ -3,23 +3,22 @@ package com.simibubi.create.modules.logistics.block.diodes; import static com.simibubi.create.modules.logistics.block.diodes.FlexpeaterBlock.POWERING; import static net.minecraft.block.RedstoneDiodeBlock.POWERED; -import com.simibubi.create.AllPackets; +import java.util.List; + import com.simibubi.create.AllTileEntities; -import com.simibubi.create.foundation.block.SyncedTileEntity; +import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; +import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; +import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.Lang; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.TileEntityType; -import net.minecraft.util.math.MathHelper; -public class FlexpeaterTileEntity extends SyncedTileEntity implements ITickableTileEntity { +public class FlexpeaterTileEntity extends SmartTileEntity { public int state; - public int maxState; - public int newMaxState; - public int lastModified; public boolean charging; - public boolean forceClientState; + ScrollValueBehaviour maxState; public FlexpeaterTileEntity() { this(AllTileEntities.FLEXPEATER.type); @@ -27,67 +26,67 @@ public class FlexpeaterTileEntity extends SyncedTileEntity implements ITickableT protected FlexpeaterTileEntity(TileEntityType type) { super(type); - lastModified = -1; - maxState = newMaxState = 1; + } + + @Override + public void addBehaviours(List behaviours) { + maxState = new ScrollValueBehaviour(Lang.translate("generic.delay"), this, new FlexpeaterScrollSlot()) + .between(1, 60 * 20 * 30); + maxState.withStepFunction(this::step); + maxState.withFormatter(this::format); + maxState.withUnit(this::getUnit); + behaviours.add(maxState); } @Override public void read(CompoundNBT compound) { - readClientUpdate(compound); - newMaxState = maxState; - super.read(compound); - } - - @Override - public void readClientUpdate(CompoundNBT compound) { state = compound.getInt("State"); charging = compound.getBoolean("Charging"); - maxState = compound.getInt("MaxState"); - state = MathHelper.clamp(state, 0, maxState - 1); - if (compound.contains("Force")) - newMaxState = maxState; - } - - @Override - public CompoundNBT writeToClient(CompoundNBT tag) { - if (forceClientState) - tag.putBoolean("Force", true); - return super.writeToClient(tag); + super.read(compound); } @Override public CompoundNBT write(CompoundNBT compound) { compound.putInt("State", state); - compound.putInt("MaxState", maxState); compound.putBoolean("Charging", charging); return super.write(compound); } - public void increment(int amount) { + private int step(int value, boolean positive) { + if (!positive) + value--; - if (amount > 0) { - if (newMaxState < 20) { - newMaxState += amount; - } else if (newMaxState < 20 * 60) { - newMaxState += amount * 20; - } else { - newMaxState += amount * 20 * 60; - } - lastModified = 0; - } + if (value < 20) + return 1; + if (value < 20 * 60) + return 20; + return 20 * 60; + } - if (amount < 0) { - if (newMaxState <= 20) { - newMaxState += amount; - } else if (newMaxState <= 20 * 60) { - newMaxState += amount * 20; - } else { - newMaxState += amount * 20 * 60; - } - lastModified = 0; - } + private String format(int value) { + if (value < 20) + return value + "t"; + if (value < 20 * 60) + return (value / 20) + "s"; + return (value / 20 / 60) + "m"; + } - newMaxState = MathHelper.clamp(newMaxState, 1, 60 * 20 * 30); + private String getUnit(int value) { + if (value < 20) + return Lang.translate("generic.unit.ticks"); + if (value < 20 * 60) + return Lang.translate("generic.unit.seconds"); + return Lang.translate("generic.unit.minutes"); + } + + @Override + public void tick() { + super.tick(); + boolean powered = getBlockState().get(POWERED); + boolean powering = getBlockState().get(POWERING); + boolean atMax = state >= maxState.getValue(); + boolean atMin = state <= 0; + updateState(powered, powering, atMax, atMin); } @Override @@ -95,30 +94,7 @@ public class FlexpeaterTileEntity extends SyncedTileEntity implements ITickableT return true; } - public int getDisplayValue() { - if (newMaxState < 20) - return newMaxState; - if (newMaxState < 20 * 60) - return newMaxState / 20; - return newMaxState / 20 / 60; - } - - public String getUnit() { - if (newMaxState < 20) - return "ticks"; - if (newMaxState < 20 * 60) - return "seconds"; - return "minutes"; - } - - @Override - public void tick() { - updateConfigurableValue(); - boolean powered = getBlockState().get(POWERED); - boolean powering = getBlockState().get(POWERING); - boolean atMax = state >= maxState; - boolean atMin = state <= 0; - + protected void updateState(boolean powered, boolean powering, boolean atMax, boolean atMin) { if (!charging && powered) charging = true; @@ -139,15 +115,4 @@ public class FlexpeaterTileEntity extends SyncedTileEntity implements ITickableT state += charging ? 1 : -1; } - public void updateConfigurableValue() { - if (!world.isRemote) - return; - if (lastModified == -1) - return; - if (lastModified++ > 10) { - lastModified = -1; - AllPackets.channel.sendToServer(new ConfigureFlexpeaterPacket(pos, newMaxState)); - } - } - } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntityRenderer.java index e7fedd434..9ddd0e39f 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/diodes/FlexpeaterTileEntityRenderer.java @@ -9,7 +9,7 @@ public class FlexpeaterTileEntityRenderer extends ColoredOverlayTileEntityRender @Override protected int getColor(FlexpeaterTileEntity te, float partialTicks) { - return ColorHelper.mixColors(0x2C0300, 0xCD0000, te.state / (float) te.maxState); + return ColorHelper.mixColors(0x2C0300, 0xCD0000, te.state / (float) te.maxState.getValue()); } @Override diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorSlots.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorSlots.java new file mode 100644 index 000000000..bc80c142c --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorSlots.java @@ -0,0 +1,82 @@ +package com.simibubi.create.modules.logistics.block.extractor; + +import static net.minecraft.block.HorizontalBlock.HORIZONTAL_FACING; + +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.utility.AngleHelper; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.logistics.block.belts.AttachedLogisticalBlock; +import com.simibubi.create.modules.logistics.block.transposer.TransposerBlock; + +import net.minecraft.block.BlockState; +import net.minecraft.util.Direction.Axis; +import net.minecraft.util.math.Vec3d; + +public class ExtractorSlots { + + static class Filter extends ValueBoxTransform { + + Vec3d offsetForHorizontal = VecHelper.voxelSpace(8f, 10.5f, 14f); + Vec3d offsetForUpward = VecHelper.voxelSpace(8f, 14.15f, 3.5f); + Vec3d offsetForDownward = VecHelper.voxelSpace(8f, 1.85f, 3.5f); + + @Override + protected Vec3d getLocation(BlockState state) { + Vec3d location = offsetForHorizontal; + if (state.getBlock() instanceof TransposerBlock) + location = location.add(0, 2/16f, 0); + if (AttachedLogisticalBlock.isVertical(state)) + location = state.get(AttachedLogisticalBlock.UPWARD) ? offsetForUpward : offsetForDownward; + return rotateHorizontally(state, location); + } + + @Override + protected Vec3d getOrientation(BlockState state) { + float yRot = AngleHelper.horizontalAngle(state.get(HORIZONTAL_FACING)); + float zRot = (AttachedLogisticalBlock.isVertical(state)) ? 0 : 90; + return new Vec3d(0, yRot, zRot); + } + + } + + public static class Link extends ValueBoxTransform.Dual { + + public Link(boolean first) { + super(first); + } + + Vec3d offsetForHorizontal = VecHelper.voxelSpace(11.5f, 4f, 14f); + Vec3d offsetForUpward = VecHelper.voxelSpace(10f, 14f, 11.5f); + Vec3d offsetForDownward = VecHelper.voxelSpace(10f, 2f, 11.5f); + + @Override + protected Vec3d getLocation(BlockState state) { + Vec3d location = offsetForHorizontal; + if (state.getBlock() instanceof TransposerBlock) + location = location.add(0, 2/16f, 0); + if (!isFirst()) + location = location.add(0, 4/16f, 0); + + if (AttachedLogisticalBlock.isVertical(state)) { + location = state.get(AttachedLogisticalBlock.UPWARD) ? offsetForUpward : offsetForDownward; + if (!isFirst()) + location = location.add(-4/16f, 0, 0); + } + + float yRot = AngleHelper.horizontalAngle(state.get(HORIZONTAL_FACING)); + location = VecHelper.rotateCentered(location, yRot, Axis.Y); + return location; + } + + @Override + protected Vec3d getOrientation(BlockState state) { + float horizontalAngle = AngleHelper.horizontalAngle(state.get(HORIZONTAL_FACING)); + boolean vertical = AttachedLogisticalBlock.isVertical(state); + float xRot = vertical ? (state.get(AttachedLogisticalBlock.UPWARD) ? 90 : 270) : 0; + float yRot = vertical ? horizontalAngle + 180 : horizontalAngle + 270; + return new Vec3d(xRot, yRot, 0); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java index 83de2c4c9..6adcc3a4d 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/ExtractorTileEntity.java @@ -8,7 +8,6 @@ import com.simibubi.create.config.AllConfigs; import com.simibubi.create.foundation.behaviour.base.SmartTileEntity; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour; -import com.simibubi.create.foundation.behaviour.filtering.FilteringBehaviour.SlotPositioning; import com.simibubi.create.foundation.behaviour.inventory.AutoExtractingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.ExtractingBehaviour; import com.simibubi.create.foundation.behaviour.inventory.SingleTargetAutoExtractingBehaviour; @@ -31,8 +30,6 @@ import net.minecraft.util.math.Vec3d; public class ExtractorTileEntity extends SmartTileEntity { - protected static FilteringBehaviour.SlotPositioning slots; - protected ExtractingBehaviour extracting; protected FilteringBehaviour filtering; protected boolean extractingToBelt; @@ -53,11 +50,8 @@ public class ExtractorTileEntity extends SmartTileEntity { this::onExtract, delay).pauseWhen(this::isPowered).waitUntil(this::canExtract); behaviours.add(extracting); - if (slots == null) - slots = new SlotPositioning(ExtractorBlock::getFilterSlotPosition, ExtractorBlock::getFilterSlotOrientation) - .scale(.4f); - filtering = - new FilteringBehaviour(this).withCallback(this::filterChanged).withSlotPositioning(slots).showCount(); + filtering = new FilteringBehaviour(this, new ExtractorSlots.Filter()).withCallback(this::filterChanged); + filtering.showCount(); behaviours.add(filtering); } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/LinkedExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/LinkedExtractorTileEntity.java index 974e949d2..49619e7e1 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/extractor/LinkedExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/extractor/LinkedExtractorTileEntity.java @@ -4,14 +4,15 @@ import static net.minecraft.state.properties.BlockStateProperties.POWERED; import java.util.List; +import org.apache.commons.lang3.tuple.Pair; + import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour; -import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour.SlotPositioning; public class LinkedExtractorTileEntity extends ExtractorTileEntity { - private static LinkBehaviour.SlotPositioning slots; public boolean receivedSignal; public LinkBehaviour receiver; @@ -21,10 +22,8 @@ public class LinkedExtractorTileEntity extends ExtractorTileEntity { @Override public void addBehaviours(List behaviours) { - if (slots == null) - slots = new SlotPositioning(LinkedExtractorBlock::getFrequencySlotPosition, - LinkedExtractorBlock::getFrequencySlotOrientation).scale(.4f); - receiver = LinkBehaviour.receiver(this, this::setSignal).withSlotPositioning(slots); + Pair slots = ValueBoxTransform.Dual.makeSlots(ExtractorSlots.Link::new); + receiver = LinkBehaviour.receiver(this, slots, this::setSignal); behaviours.add(receiver); super.addBehaviours(behaviours); } @@ -41,5 +40,5 @@ public class LinkedExtractorTileEntity extends ExtractorTileEntity { if (receivedSignal != getBlockState().get(POWERED)) world.setBlockState(pos, getBlockState().cycle(POWERED)); } - + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/LinkedTransposerTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/LinkedTransposerTileEntity.java index 11d4ff4f9..fed4747aa 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/transposer/LinkedTransposerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/transposer/LinkedTransposerTileEntity.java @@ -4,15 +4,16 @@ import static net.minecraft.state.properties.BlockStateProperties.POWERED; import java.util.List; +import org.apache.commons.lang3.tuple.Pair; + import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour; import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour; -import com.simibubi.create.foundation.behaviour.linked.LinkBehaviour.SlotPositioning; -import com.simibubi.create.modules.logistics.block.extractor.LinkedExtractorBlock; +import com.simibubi.create.modules.logistics.block.extractor.ExtractorSlots; public class LinkedTransposerTileEntity extends TransposerTileEntity { - private static LinkBehaviour.SlotPositioning slots; public boolean receivedSignal; public LinkBehaviour receiver; @@ -22,10 +23,8 @@ public class LinkedTransposerTileEntity extends TransposerTileEntity { @Override public void addBehaviours(List behaviours) { - if (slots == null) - slots = new SlotPositioning(LinkedExtractorBlock::getFrequencySlotPosition, - LinkedExtractorBlock::getFrequencySlotOrientation).scale(.4f); - receiver = LinkBehaviour.receiver(this, this::setSignal).withSlotPositioning(slots); + Pair slots = ValueBoxTransform.Dual.makeSlots(ExtractorSlots.Link::new); + receiver = LinkBehaviour.receiver(this, slots, this::setSignal); behaviours.add(receiver); super.addBehaviours(behaviours); } diff --git a/src/main/resources/assets/create/lang/en_us.json b/src/main/resources/assets/create/lang/en_us.json index 9255ffa37..fbaef3b38 100644 --- a/src/main/resources/assets/create/lang/en_us.json +++ b/src/main/resources/assets/create/lang/en_us.json @@ -311,6 +311,7 @@ "create.gui.scrollInput.defaultTitle": "Choose an Option:", "create.gui.scrollInput.scrollToModify": "Scroll to Modify", + "create.gui.scrollInput.scrollToAdjustAmount": "Scroll to Adjust Amount", "create.gui.scrollInput.scrollToSelect": "Scroll to Select", "create.gui.scrollInput.shiftScrollsFaster": "Shift to Scroll faster", diff --git a/src/main/resources/assets/create/models/block/repeaters/flexpeater.json b/src/main/resources/assets/create/models/block/repeaters/flexpeater.json index 6e9b73073..6ba760111 100644 --- a/src/main/resources/assets/create/models/block/repeaters/flexpeater.json +++ b/src/main/resources/assets/create/models/block/repeaters/flexpeater.json @@ -3,7 +3,6 @@ "parent": "block/block", "textures": { "flexpeater_off": "create:block/flexpeater_off", - "torch": "minecraft:block/redstone_torch_off", "smooth_stone": "minecraft:block/smooth_stone", "particle": "create:block/flexpeater_off" }, diff --git a/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered.json b/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered.json index 47ed33237..21f3a5015 100644 --- a/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered.json +++ b/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered.json @@ -1,7 +1,7 @@ { "parent": "create:block/repeaters/flexpeater", "textures": { - "flexpeater_off": "create:block/flexpeater_on", - "particle": "create:block/flexpeater_on" + "flexpeater_off": "create:block/flexpeater_charging", + "particle": "create:block/flexpeater_charging" } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered_powering.json b/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered_powering.json index 1d0b26f6f..5dbda982e 100644 --- a/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered_powering.json +++ b/src/main/resources/assets/create/models/block/repeaters/flexpeater_powered_powering.json @@ -1,6 +1,7 @@ { - "parent": "create:block/repeaters/flexpeater_powered", + "parent": "create:block/repeaters/flexpeater", "textures": { - "torch": "minecraft:block/redstone_torch" + "flexpeater_off": "create:block/flexpeater_on", + "particle": "create:block/flexpeater_on" } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/repeaters/flexpeater_powering.json b/src/main/resources/assets/create/models/block/repeaters/flexpeater_powering.json index 013b2b3af..b4d71106f 100644 --- a/src/main/resources/assets/create/models/block/repeaters/flexpeater_powering.json +++ b/src/main/resources/assets/create/models/block/repeaters/flexpeater_powering.json @@ -1,6 +1,7 @@ { "parent": "create:block/repeaters/flexpeater", "textures": { - "torch": "minecraft:block/redstone_torch" + "flexpeater_off": "create:block/flexpeater_powering", + "particle": "create:block/flexpeater_powering" } } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/rotation_speed_controller.json b/src/main/resources/assets/create/models/block/rotation_speed_controller.json new file mode 100644 index 000000000..e87640f75 --- /dev/null +++ b/src/main/resources/assets/create/models/block/rotation_speed_controller.json @@ -0,0 +1,132 @@ +{ + "credit": "Made with Blockbench", + "parent": "create:block/large_wheels", + "textures": { + "4": "create:block/brass_gearbox", + "5": "create:block/brass_casing_side", + "6": "create:block/brass_casing", + "7": "create:block/extractor", + "8": "create:block/encased_belt_middle", + "9": "create:block/brass_block", + "particle": "create:block/brass_casing" + }, + "elements": [ + { + "from": [1, 2, 10], + "to": [5, 15, 15], + "faces": { + "north": {"uv": [12, 1, 16, 14], "texture": "#5"}, + "east": {"uv": [4, 1, 9, 14], "texture": "#6"}, + "south": {"uv": [1, 1, 5, 14], "texture": "#6"}, + "west": {"uv": [10, 1, 15, 14], "texture": "#4"}, + "up": {"uv": [1, 10, 5, 15], "texture": "#9"}, + "down": {"uv": [0, 0, 14, 5], "texture": "#missing"} + } + }, + { + "from": [1, 2, 1], + "to": [5, 15, 6], + "faces": { + "north": {"uv": [5, 1, 1, 14], "texture": "#6"}, + "east": {"uv": [9, 1, 4, 14], "texture": "#6"}, + "south": {"uv": [16, 1, 12, 14], "texture": "#5"}, + "west": {"uv": [15, 1, 10, 14], "texture": "#4"}, + "up": {"uv": [1, 1, 5, 6], "texture": "#9"}, + "down": {"uv": [0, 5, 14, 0], "texture": "#missing"} + } + }, + { + "from": [11, 2, 10], + "to": [15, 15, 15], + "faces": { + "north": {"uv": [0, 1, 4, 14], "texture": "#5"}, + "east": {"uv": [1, 1, 6, 14], "texture": "#4"}, + "south": {"uv": [11, 1, 15, 14], "texture": "#6"}, + "west": {"uv": [4, 1, 9, 14], "texture": "#6"}, + "up": {"uv": [11, 10, 15, 15], "texture": "#9"}, + "down": {"uv": [0, 0, 14, 5], "texture": "#missing"} + } + }, + { + "from": [11, 2, 1], + "to": [15, 15, 6], + "faces": { + "north": {"uv": [15, 1, 11, 14], "texture": "#6"}, + "east": {"uv": [6, 1, 1, 14], "texture": "#4"}, + "south": {"uv": [4, 1, 0, 14], "texture": "#5"}, + "west": {"uv": [9, 1, 4, 14], "texture": "#6"}, + "up": {"uv": [11, 1, 15, 6], "texture": "#9"}, + "down": {"uv": [0, 5, 14, 0], "texture": "#missing"} + } + }, + { + "from": [5, 2, 10], + "to": [11, 8, 15], + "faces": { + "east": {"uv": [0, 0, 5, 16], "texture": "#missing"}, + "south": {"uv": [5, 8, 11, 14], "texture": "#6"}, + "west": {"uv": [10, 1, 15, 14], "texture": "#4"}, + "up": {"uv": [5, 3, 11, 8], "texture": "#6"}, + "down": {"uv": [0, 0, 14, 5], "texture": "#missing"} + } + }, + { + "from": [5, 2, 1], + "to": [11, 8, 6], + "faces": { + "north": {"uv": [11, 8, 5, 14], "texture": "#6"}, + "east": {"uv": [5, 0, 0, 16], "texture": "#missing"}, + "west": {"uv": [15, 1, 10, 14], "texture": "#4"}, + "up": {"uv": [5, 8, 11, 3], "texture": "#6"}, + "down": {"uv": [0, 5, 14, 0], "texture": "#missing"} + } + }, + { + "from": [5, 9, 10], + "to": [11, 14, 14], + "faces": { + "north": {"uv": [6, 9, 12, 14], "texture": "#7"}, + "east": {"uv": [0, 0, 5, 16], "texture": "#missing"}, + "south": {"uv": [6, 9, 12, 14], "texture": "#7"}, + "west": {"uv": [10, 1, 15, 14], "texture": "#4"}, + "up": {"uv": [6, 8, 12, 12], "texture": "#7"}, + "down": {"uv": [6, 8, 12, 12], "texture": "#7"} + } + }, + { + "from": [5, 9, 2], + "to": [11, 14, 6], + "faces": { + "north": {"uv": [6, 10, 12, 15], "texture": "#7"}, + "east": {"uv": [5, 0, 0, 16], "texture": "#missing"}, + "south": {"uv": [6, 8, 12, 13], "texture": "#7"}, + "west": {"uv": [15, 1, 10, 14], "texture": "#4"}, + "up": {"uv": [6, 12, 12, 8], "texture": "#7"}, + "down": {"uv": [6, 8, 12, 12], "texture": "#7"} + } + }, + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "east": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "west": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#4"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#6"} + } + }, + { + "from": [1, 2, 6], + "to": [15, 11, 10], + "faces": { + "east": {"uv": [6, 5, 10, 14], "texture": "#4"}, + "west": {"uv": [6, 5, 10, 14], "texture": "#4"}, + "up": {"uv": [1, 6, 15, 10], "texture": "#8"}, + "down": {"uv": [0, 0, 14, 6], "texture": "#missing"} + } + } + ], + "display": {} +} \ No newline at end of file diff --git a/src/main/resources/assets/create/models/item/rotation_speed_controller.json b/src/main/resources/assets/create/models/item/rotation_speed_controller.json new file mode 100644 index 000000000..08ca33c06 --- /dev/null +++ b/src/main/resources/assets/create/models/item/rotation_speed_controller.json @@ -0,0 +1,148 @@ +{ + "credit": "Made with Blockbench", + "parent": "create:block/large_wheels", + "textures": { + "0": "create:block/axis", + "3": "create:block/axis_top", + "4": "create:block/brass_gearbox", + "5": "create:block/brass_casing_side", + "6": "create:block/brass_casing", + "7": "create:block/extractor", + "8": "create:block/encased_belt_middle", + "9": "create:block/brass_block", + "particle": "create:block/stripped_spruce_log" + }, + "elements": [ + { + "from": [1, 2, 10], + "to": [5, 15, 15], + "faces": { + "north": {"uv": [12, 1, 16, 14], "texture": "#5"}, + "east": {"uv": [4, 1, 9, 14], "texture": "#6"}, + "south": {"uv": [1, 1, 5, 14], "texture": "#6"}, + "west": {"uv": [10, 1, 15, 14], "texture": "#4"}, + "up": {"uv": [1, 10, 5, 15], "texture": "#9"}, + "down": {"uv": [0, 0, 14, 5], "texture": "#missing"} + } + }, + { + "from": [1, 2, 1], + "to": [5, 15, 6], + "faces": { + "north": {"uv": [5, 1, 1, 14], "texture": "#6"}, + "east": {"uv": [9, 1, 4, 14], "texture": "#6"}, + "south": {"uv": [16, 1, 12, 14], "texture": "#5"}, + "west": {"uv": [15, 1, 10, 14], "texture": "#4"}, + "up": {"uv": [1, 1, 5, 6], "texture": "#9"}, + "down": {"uv": [0, 5, 14, 0], "texture": "#missing"} + } + }, + { + "from": [11, 2, 10], + "to": [15, 15, 15], + "faces": { + "north": {"uv": [0, 1, 4, 14], "texture": "#5"}, + "east": {"uv": [1, 1, 6, 14], "texture": "#4"}, + "south": {"uv": [11, 1, 15, 14], "texture": "#6"}, + "west": {"uv": [4, 1, 9, 14], "texture": "#6"}, + "up": {"uv": [11, 10, 15, 15], "texture": "#9"}, + "down": {"uv": [0, 0, 14, 5], "texture": "#missing"} + } + }, + { + "from": [11, 2, 1], + "to": [15, 15, 6], + "faces": { + "north": {"uv": [15, 1, 11, 14], "texture": "#6"}, + "east": {"uv": [6, 1, 1, 14], "texture": "#4"}, + "south": {"uv": [4, 1, 0, 14], "texture": "#5"}, + "west": {"uv": [9, 1, 4, 14], "texture": "#6"}, + "up": {"uv": [11, 1, 15, 6], "texture": "#9"}, + "down": {"uv": [0, 5, 14, 0], "texture": "#missing"} + } + }, + { + "from": [5, 2, 10], + "to": [11, 8, 15], + "faces": { + "east": {"uv": [0, 0, 5, 16], "texture": "#missing"}, + "south": {"uv": [5, 8, 11, 14], "texture": "#6"}, + "west": {"uv": [10, 1, 15, 14], "texture": "#4"}, + "up": {"uv": [5, 3, 11, 8], "texture": "#6"}, + "down": {"uv": [0, 0, 14, 5], "texture": "#missing"} + } + }, + { + "from": [5, 2, 1], + "to": [11, 8, 6], + "faces": { + "north": {"uv": [11, 8, 5, 14], "texture": "#6"}, + "east": {"uv": [5, 0, 0, 16], "texture": "#missing"}, + "west": {"uv": [15, 1, 10, 14], "texture": "#4"}, + "up": {"uv": [5, 8, 11, 3], "texture": "#6"}, + "down": {"uv": [0, 5, 14, 0], "texture": "#missing"} + } + }, + { + "from": [5, 9, 10], + "to": [11, 14, 14], + "faces": { + "north": {"uv": [6, 9, 12, 14], "texture": "#7"}, + "east": {"uv": [0, 0, 5, 16], "texture": "#missing"}, + "south": {"uv": [6, 9, 12, 14], "texture": "#7"}, + "west": {"uv": [10, 1, 15, 14], "texture": "#4"}, + "up": {"uv": [6, 8, 12, 12], "texture": "#7"}, + "down": {"uv": [6, 8, 12, 12], "texture": "#7"} + } + }, + { + "from": [5, 9, 2], + "to": [11, 14, 6], + "faces": { + "north": {"uv": [6, 10, 12, 15], "texture": "#7"}, + "east": {"uv": [5, 0, 0, 16], "texture": "#missing"}, + "south": {"uv": [6, 8, 12, 13], "texture": "#7"}, + "west": {"uv": [15, 1, 10, 14], "texture": "#4"}, + "up": {"uv": [6, 12, 12, 8], "texture": "#7"}, + "down": {"uv": [6, 8, 12, 12], "texture": "#7"} + } + }, + { + "name": "Axis", + "from": [0, 6, 6], + "to": [16, 10, 10], + "shade": false, + "faces": { + "north": {"uv": [6, 0, 10, 16], "rotation": 90, "texture": "#0"}, + "east": {"uv": [6, 6, 10, 10], "texture": "#3"}, + "south": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#0"}, + "west": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#3"}, + "up": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#0"}, + "down": {"uv": [6, 0, 10, 16], "rotation": 270, "texture": "#0"} + } + }, + { + "from": [0, 0, 0], + "to": [16, 2, 16], + "faces": { + "north": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "east": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "south": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "west": {"uv": [0, 14, 16, 16], "texture": "#5"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#4"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#6"} + } + }, + { + "from": [1, 2, 6], + "to": [15, 11, 10], + "faces": { + "east": {"uv": [6, 5, 10, 14], "texture": "#4"}, + "west": {"uv": [6, 5, 10, 14], "texture": "#4"}, + "up": {"uv": [1, 6, 15, 10], "texture": "#8"}, + "down": {"uv": [0, 0, 14, 6], "texture": "#missing"} + } + } + ], + "display": {} +} \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/flexpeater_charging.png b/src/main/resources/assets/create/textures/block/flexpeater_charging.png new file mode 100644 index 000000000..825eaf988 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/flexpeater_charging.png differ diff --git a/src/main/resources/assets/create/textures/block/flexpeater_powering.png b/src/main/resources/assets/create/textures/block/flexpeater_powering.png new file mode 100644 index 000000000..82cb9e229 Binary files /dev/null and b/src/main/resources/assets/create/textures/block/flexpeater_powering.png differ