Refactor in-world Scrollinputs
- Reworked Scollable inputs on blocks to use a unified TE behaviour & generic value box rendering
This commit is contained in:
parent
81a2e314bc
commit
fb046ddfb7
55 changed files with 1358 additions and 1102 deletions
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
@ -101,8 +101,8 @@ public class ClientEvents {
|
|||
|
||||
boolean cancelled = CreateClient.schematicHandler.mouseScrolled(delta)
|
||||
|| CreateClient.schematicAndQuillHandler.mouseScrolled(delta)
|
||||
|| IHaveScrollableValue.onScroll(delta)
|
||||
|| FilteringHandler.onScroll(delta);
|
||||
|| FilteringHandler.onScroll(delta)
|
||||
|| ScrollValueHandler.onScroll(delta);
|
||||
event.setCanceled(cancelled);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<BlockState, Direction> allowedDirections;
|
||||
|
||||
public CenteredSideValueBoxTransform() {
|
||||
this((b, d) -> true);
|
||||
}
|
||||
|
||||
public CenteredSideValueBoxTransform(BiPredicate<BlockState, Direction> 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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
@ -22,6 +24,16 @@ public class ValueBox {
|
|||
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;
|
||||
this.highlightColor = highlight;
|
||||
|
@ -40,4 +52,14 @@ 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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<ValueBoxTransform, ValueBoxTransform> makeSlots(Function<Boolean, ? extends Dual> 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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<FilteringBehaviour> TYPE = new IBehaviourType<FilteringBehaviour>() {
|
||||
};
|
||||
|
||||
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;
|
||||
|
@ -160,11 +155,8 @@ 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() {
|
||||
|
@ -175,23 +167,4 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
return count == 0;
|
||||
}
|
||||
|
||||
public static class SlotPositioning {
|
||||
Function<BlockState, Vec3d> offset;
|
||||
Function<BlockState, Vec3d> rotation;
|
||||
float scale;
|
||||
|
||||
public SlotPositioning(Function<BlockState, Vec3d> offsetForState,
|
||||
Function<BlockState, Vec3d> rotationForState) {
|
||||
offset = offsetForState;
|
||||
rotation = rotationForState;
|
||||
scale = 1;
|
||||
}
|
||||
|
||||
public SlotPositioning scale(float scale) {
|
||||
this.scale = scale;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,40 +30,39 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
|||
|
||||
Frequency frequencyFirst;
|
||||
Frequency frequencyLast;
|
||||
SlotPositioning slotPositioning;
|
||||
ValueBoxTransform firstSlot;
|
||||
ValueBoxTransform secondSlot;
|
||||
Vec3d textShift;
|
||||
|
||||
private Mode mode;
|
||||
private Supplier<Boolean> transmission;
|
||||
private Consumer<Boolean> signalCallback;
|
||||
|
||||
protected LinkBehaviour(SmartTileEntity te) {
|
||||
protected LinkBehaviour(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> 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<Boolean> signalCallback) {
|
||||
LinkBehaviour behaviour = new LinkBehaviour(te);
|
||||
public static LinkBehaviour receiver(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
|
||||
Consumer<Boolean> signalCallback) {
|
||||
LinkBehaviour behaviour = new LinkBehaviour(te, slots);
|
||||
behaviour.signalCallback = signalCallback;
|
||||
behaviour.mode = Mode.RECEIVE;
|
||||
return behaviour;
|
||||
}
|
||||
|
||||
public static LinkBehaviour transmitter(SmartTileEntity te, Supplier<Boolean> transmission) {
|
||||
LinkBehaviour behaviour = new LinkBehaviour(te);
|
||||
public static LinkBehaviour transmitter(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
|
||||
Supplier<Boolean> 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;
|
||||
|
@ -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<Vec3d, Vec3d> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Boolean> render) {
|
||||
Pair<Vec3d, Vec3d> 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<Boolean> render) {
|
||||
behaviour.firstSlot.renderTransformed(state, () -> render.accept(true));
|
||||
behaviour.secondSlot.renderTransformed(state, () -> render.accept(false));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ScrollValueBehaviour> TYPE = new IBehaviourType<ScrollValueBehaviour>() {
|
||||
};
|
||||
|
||||
ValueBoxTransform slotPositioning;
|
||||
Vec3d textShift;
|
||||
|
||||
int min = 0;
|
||||
int max = 1;
|
||||
public int value;
|
||||
int scrollableValue;
|
||||
int ticksUntilScrollPacket;
|
||||
boolean forceClientState;
|
||||
String label;
|
||||
Consumer<Integer> callback;
|
||||
Function<Integer, String> formatter;
|
||||
Function<Integer, String> unit;
|
||||
BiFunction<Integer, Boolean, Integer> 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<Integer> 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<Integer, String> formatter) {
|
||||
this.formatter = formatter;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollValueBehaviour withUnit(Function<Integer, String> unit) {
|
||||
this.unit = unit;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollValueBehaviour withStepFunction(BiFunction<Integer, Boolean, Integer> 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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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<SmartTileEntity> {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ChassisTileEntity>, 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<ItemStack> 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)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<TileEntityBehaviour> 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<ChassisTileEntity> {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TileEntityBehaviour> 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);
|
||||
|
|
|
@ -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<MechanicalMixerTileEntity> {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<MechanicalMixerTileEntity>, IHaveScrollableValue, IHaveCustomBlockItem {
|
||||
implements IWithTileEntity<MechanicalMixerTileEntity>, IHaveCustomBlockItem {
|
||||
|
||||
private static final Vec3d valuePos = new Vec3d(15.8f / 16f, 6 / 16f, 5 / 16f);
|
||||
|
||||
public MechanicalMixerBlock() {
|
||||
super(Properties.from(Blocks.ANDESITE));
|
||||
|
@ -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;
|
||||
|
|
|
@ -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<TileEntityBehaviour> 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 <C extends IInventory> boolean matchBasinRecipe(IRecipe<C> recipe) {
|
||||
if (recipe == null)
|
||||
return false;
|
||||
if (recipe.getIngredients().size() < minIngredients)
|
||||
if (recipe.getIngredients().size() < minIngredients.getValue())
|
||||
return false;
|
||||
|
||||
NonNullList<Ingredient> ingredients = recipe.getIngredients();
|
||||
|
|
|
@ -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<MotorTileEntity> {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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<MotorTileEntity>, 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;
|
||||
|
|
|
@ -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<TileEntityBehaviour> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TileEntityBehaviour> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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<ValueBoxTransform, ValueBoxTransform> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TileEntityBehaviour> behaviours) {
|
||||
filtering = new FilteringBehaviour(this, new BeltObserverFilterSlot()).moveText(new Vec3d(0, 5, 0));
|
||||
behaviours.add(filtering);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
@ -83,23 +83,4 @@ public class BeltObserverTileEntity extends SmartTileEntity {
|
|||
super.read(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TileEntityBehaviour> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<FlexpeaterTileEntity> {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
@ -12,14 +11,7 @@ public class FlexPulsepeaterTileEntity extends FlexpeaterTileEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
updateConfigurableValue();
|
||||
|
||||
boolean powered = getBlockState().get(POWERED);
|
||||
boolean powering = getBlockState().get(POWERING);
|
||||
boolean atMax = state >= maxState;
|
||||
boolean isReset = state == 0;
|
||||
|
||||
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;
|
||||
|
|
|
@ -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<FlexpeaterTileEntity>, 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));
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TileEntityBehaviour> 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<TileEntityBehaviour> behaviours) {
|
||||
if (slots == null)
|
||||
slots = new SlotPositioning(LinkedExtractorBlock::getFrequencySlotPosition,
|
||||
LinkedExtractorBlock::getFrequencySlotOrientation).scale(.4f);
|
||||
receiver = LinkBehaviour.receiver(this, this::setSignal).withSlotPositioning(slots);
|
||||
Pair<ValueBoxTransform, ValueBoxTransform> slots = ValueBoxTransform.Dual.makeSlots(ExtractorSlots.Link::new);
|
||||
receiver = LinkBehaviour.receiver(this, slots, this::setSignal);
|
||||
behaviours.add(receiver);
|
||||
super.addBehaviours(behaviours);
|
||||
}
|
||||
|
|
|
@ -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<TileEntityBehaviour> behaviours) {
|
||||
if (slots == null)
|
||||
slots = new SlotPositioning(LinkedExtractorBlock::getFrequencySlotPosition,
|
||||
LinkedExtractorBlock::getFrequencySlotOrientation).scale(.4f);
|
||||
receiver = LinkBehaviour.receiver(this, this::setSignal).withSlotPositioning(slots);
|
||||
Pair<ValueBoxTransform, ValueBoxTransform> slots = ValueBoxTransform.Dual.makeSlots(ExtractorSlots.Link::new);
|
||||
receiver = LinkBehaviour.receiver(this, slots, this::setSignal);
|
||||
behaviours.add(receiver);
|
||||
super.addBehaviours(behaviours);
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
|
@ -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": {}
|
||||
}
|
|
@ -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": {}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 533 B |
Binary file not shown.
After Width: | Height: | Size: 535 B |
Loading…
Reference in a new issue