Inhibiting Contraption Placement

- Pistons, Bearings and Pulleys now have a ScrollInput for selecting when to place moved structures back into the world
- Added copper blocks with oxidation effect
- Pistons and Pulleys no longer move inconsistently when disassembled and assembled at intermediate offsets
This commit is contained in:
simibubi 2020-02-19 14:08:49 +01:00
parent fb046ddfb7
commit c7e8698ce8
94 changed files with 708 additions and 166 deletions

View file

@ -272,6 +272,8 @@ public enum AllBlocks {
__MATERIALS__(),
COPPER_ORE(new OxidizingBlock(Properties.from(Blocks.IRON_ORE), 1)),
ZINC_ORE(new Block(Properties.from(Blocks.GOLD_ORE).harvestLevel(2).harvestTool(ToolType.PICKAXE))),
COPPER_BLOCK(new OxidizingBlock(Properties.from(Blocks.IRON_BLOCK), 1/32f)),
COPPER_SHINGLES(new OxidizingBlock(Properties.from(Blocks.IRON_BLOCK), 1/32f)),
;

View file

@ -94,59 +94,63 @@ public enum ScreenResources {
BLUEPRINT_SLOT("widgets.png", 90, 0, 24, 24),
// Icons
I_NONE(16, 16),
I_ADD(0, 0),
I_TRASH(16, 0),
I_3x3(32, 0),
I_TARGET(48, 0),
I_CONFIRM(0, 16),
I_OPEN_FOLDER(32, 16),
I_REFRESH(48, 16),
I_DONT_REPLACE(0, 32),
I_REPLACE_SOLID(16, 32),
I_REPLACE_ANY(32, 32),
I_REPLACE_EMPTY(48, 32),
I_TOOL_DEPLOY(0, 48),
I_SKIP_MISSING(16, 48),
I_SKIP_TILES(32, 48),
I_TOOL_MOVE_XZ(0, 64),
I_TOOL_MOVE_Y(16, 64),
I_TOOL_ROTATE(32, 64),
I_TOOL_MIRROR(48, 64),
I_PLAY(0, 80),
I_PAUSE(16, 80),
I_STOP(32, 80),
I_PATTERN_SOLID(0, 96),
I_PATTERN_CHECKERED(16, 96),
I_PATTERN_CHECKERED_INVERSED(32, 96),
I_PATTERN_CHANCE_25(48, 96),
I_PATTERN_CHANCE_50(0, 112),
I_PATTERN_CHANCE_75(16, 112),
I_FOLLOW_DIAGONAL(32, 112),
I_FOLLOW_MATERIAL(48, 112),
I_PRIORITY_VERY_LOW(64, 0),
I_PRIORITY_LOW(80, 0),
I_PRIORITY_HIGH(96, 0),
I_PRIORITY_VERY_HIGH(112, 0),
I_ACTIVE(64, 16),
I_PASSIVE(80, 16),
I_TRASH(1, 0),
I_3x3(2, 0),
I_TARGET(3, 0),
I_PRIORITY_VERY_LOW(4, 0),
I_PRIORITY_LOW(5, 0),
I_PRIORITY_HIGH(6, 0),
I_PRIORITY_VERY_HIGH(7, 0),
I_BLACKLIST(8, 0),
I_WHITELIST(9, 0),
I_WHITELIST_OR(10, 0),
I_WHITELIST_AND(11, 0),
I_WHITELIST_NOT(12, 0),
I_RESPECT_NBT(13, 0),
I_IGNORE_NBT(14, 0),
I_BLACKLIST(128, 0),
I_WHITELIST(144, 0),
I_WHITELIST_OR(160, 0),
I_WHITELIST_AND(176, 0),
I_WHITELIST_NOT(192, 0),
I_CONFIRM(0, 1),
I_NONE(1, 1),
I_OPEN_FOLDER(2, 1),
I_REFRESH(3, 1),
I_ACTIVE(4, 1),
I_PASSIVE(5, 1),
I_ROTATE_PLACE(6, 1),
I_ROTATE_PLACE_RETURNED(7, 1),
I_ROTATE_NEVER_PLACE(8, 1),
I_MOVE_PLACE(9, 1),
I_MOVE_PLACE_RETURNED(10, 1),
I_MOVE_NEVER_PLACE(11, 1),
I_RESPECT_NBT(208, 0),
I_IGNORE_NBT(224, 0),
I_DONT_REPLACE(0, 2),
I_REPLACE_SOLID(4, 2),
I_REPLACE_ANY(2, 2),
I_REPLACE_EMPTY(3, 2),
I_TOOL_DEPLOY(0, 3),
I_SKIP_TILES(2, 3),
I_SKIP_MISSING(4, 3),
I_TOOL_MOVE_XZ(0, 4),
I_TOOL_MOVE_Y(4, 4),
I_TOOL_ROTATE(2, 4),
I_TOOL_MIRROR(3, 4),
I_PLAY(0, 5),
I_PAUSE(4, 5),
I_STOP(2, 5),
I_PATTERN_SOLID(0, 6),
I_PATTERN_CHECKERED(4, 6),
I_PATTERN_CHECKERED_INVERSED(2, 6),
I_PATTERN_CHANCE_25(3, 6),
I_PATTERN_CHANCE_50(0, 7),
I_PATTERN_CHANCE_75(4, 7),
I_FOLLOW_DIAGONAL(2, 7),
I_FOLLOW_MATERIAL(3, 7),
;
public static final int FONT_COLOR = 0x575F7A;
@ -162,7 +166,7 @@ public enum ScreenResources {
}
private ScreenResources(int startX, int startY) {
this("icons.png", startX, startY, 16, 16);
this("icons.png", startX * 16, startY * 16, 16, 16);
}
private ScreenResources(String location, int startX, int startY, int width, int height) {

View file

@ -1,5 +1,13 @@
package com.simibubi.create.foundation.behaviour;
import com.mojang.blaze3d.platform.GlStateManager;
import com.simibubi.create.ScreenResources;
import com.simibubi.create.foundation.behaviour.scrollvalue.INamedIconOptions;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.modules.logistics.item.filter.FilterItem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
@ -23,12 +31,12 @@ public class ValueBox {
this.labelOffset = offset;
return this;
}
public ValueBox subLabel(String sublabel) {
this.sublabel = sublabel;
return this;
}
public ValueBox scrollTooltip(String scrollTip) {
this.scrollTooltip = scrollTip;
return this;
@ -40,6 +48,10 @@ public class ValueBox {
return this;
}
public void render(boolean highlighted) {
}
public static class ItemValueBox extends ValueBox {
ItemStack stack;
int count;
@ -50,8 +62,29 @@ public class ValueBox {
this.count = count;
}
@Override
public void render(boolean highlighted) {
super.render(highlighted);
FontRenderer font = Minecraft.getInstance().fontRenderer;
String countString = count == 0 ? "*" : count + "";
GlStateManager.translated(17.5f, -5f, 7f);
boolean isFilter = stack.getItem() instanceof FilterItem;
if (isFilter)
GlStateManager.translated(3, 8, 7.25f);
else
GlStateManager.translated(-7 - font.getStringWidth(countString), 10, 10 + 1 / 4f);
double scale = 1.5;
GlStateManager.rotated(0, 1, 0, 0);
GlStateManager.scaled(scale, scale, scale);
font.drawString(countString, 0, 0, isFilter ? 0xFFFFFF : 0xEDEDED);
GlStateManager.translated(0, 0, -1 / 16f);
font.drawString(countString, 1 - 1 / 8f, 1 - 1 / 8f, 0x4F4F4F);
}
}
public static class TextValueBox extends ValueBox {
String text;
@ -59,7 +92,53 @@ public class ValueBox {
super(label, bb);
this.text = text;
}
@Override
public void render(boolean highlighted) {
super.render(highlighted);
FontRenderer font = Minecraft.getInstance().fontRenderer;
double scale = 4;
GlStateManager.scaled(scale, scale, 1);
GlStateManager.translated(-4, -4, 5);
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);
ValueBoxRenderer.renderText(font, text, 0xEDEDED, 0x4f4f4f);
}
}
public static class IconValueBox extends ValueBox {
ScreenResources icon;
public IconValueBox(String label, INamedIconOptions iconValue, AxisAlignedBB bb) {
super(label, bb);
subLabel(Lang.translate(iconValue.getTranslationKey()));
icon = iconValue.getIcon();
}
@Override
public void render(boolean highlighted) {
super.render(highlighted);
double scale = 4;
GlStateManager.scaled(scale, scale, 1);
GlStateManager.translated(-8, -8, 3/2f);
icon.draw(0, 0);
GlStateManager.color4f(.25f, .25f, .25f, 1);
GlStateManager.translated(.5f, .5f, -1);
icon.draw(0, 0);
GlStateManager.color4f(1, 1, 1, 1);
}
}
}

View file

@ -1,8 +1,6 @@
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;
@ -60,7 +58,6 @@ public class ValueBoxRenderer {
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);
@ -73,45 +70,7 @@ public class ValueBoxRenderer {
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)
GlStateManager.translated(3, 8, 7.25f);
else
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);
}
box.render(highlighted);
}
public static void renderText(ValueBox box, FontRenderer font, String text) {

View file

@ -75,7 +75,7 @@ public abstract class ValueBoxTransform {
public static abstract class Sided extends ValueBoxTransform {
Direction direction = Direction.UP;
protected Direction direction = Direction.UP;
public Sided fromSide(Direction direction) {
this.direction = direction;

View file

@ -0,0 +1,8 @@
package com.simibubi.create.foundation.behaviour.scrollvalue;
import com.simibubi.create.ScreenResources;
public interface INamedIconOptions {
ScreenResources getIcon();
String getTranslationKey();
}

View file

@ -0,0 +1,25 @@
package com.simibubi.create.foundation.behaviour.scrollvalue;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.behaviour.base.SmartTileEntity;
public class ScrollOptionBehaviour<E extends Enum<E> & INamedIconOptions> extends ScrollValueBehaviour {
private E[] options;
public ScrollOptionBehaviour(Class<E> enum_, String label, SmartTileEntity te, ValueBoxTransform slot) {
super(label, te, slot);
options = enum_.getEnumConstants();
between(0, options.length - 1);
withStepFunction((i, b) -> -1);
}
INamedIconOptions getIconForSelected() {
return get();
}
public E get() {
return options[scrollableValue];
}
}

View file

@ -143,6 +143,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
callback.accept(value);
tileEntity.markDirty();
tileEntity.sendData();
scrollableValue = value;
}
public int getValue() {

View file

@ -3,6 +3,7 @@ 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.IconValueBox;
import com.simibubi.create.foundation.behaviour.ValueBox.TextValueBox;
import com.simibubi.create.foundation.behaviour.ValueBoxRenderer;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform.Sided;
@ -49,13 +50,19 @@ public class ScrollValueRenderer {
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) + ")");
ValueBox box;
if (behaviour instanceof ScrollOptionBehaviour) {
box = new IconValueBox(label, ((ScrollOptionBehaviour<?>) behaviour).getIconForSelected(), bb);
} else {
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()));

View file

@ -32,6 +32,8 @@ public class HarvesterTileEntityRenderer extends SafeTileEntityRendererFast<Harv
float speed = (float) (!VecHelper.isVecPointingTowards(context.relativeMotion, facing.getOpposite())
? context.getAnimationSpeed() * offset
: 0);
if (context.contraption.stalled)
speed = 0;
float time = AnimationTickHolder.getRenderTick() / 20;
float angle = (float) (((time * speed) % 360) / 180 * (float) Math.PI);

View file

@ -331,6 +331,9 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
IControlContraption controllerTE = (IControlContraption) te;
this.controllerTE = controllerTE;
controllerTE.attach(this);
if (world.isRemote)
setPosition(posX, posY, posZ);
}
}
@ -405,7 +408,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
public void setMotion(Vec3d motionIn) {
// Make sure nothing can move contraptions out of the way
}
public void setContraptionMotion(Vec3d vec) {
super.setMotion(vec);
}

View file

@ -0,0 +1,32 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import java.util.function.BiPredicate;
import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.block.BlockState;
import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.util.Direction;
import net.minecraft.util.math.Vec3d;
public class DirectionalExtenderScrollOptionSlot extends CenteredSideValueBoxTransform {
public DirectionalExtenderScrollOptionSlot(BiPredicate<BlockState, Direction> allowedDirections) {
super(allowedDirections);
}
@Override
protected Vec3d getLocation(BlockState state) {
return super.getLocation(state)
.add(new Vec3d(state.get(BlockStateProperties.FACING).getDirectionVec()).scale(-2 / 16f));
}
@Override
protected Vec3d getOrientation(BlockState state) {
Vec3d orientation = super.getOrientation(state);
if (direction.getAxis().isHorizontal())
return orientation;
return orientation.add(0, AngleHelper.horizontalAngle(state.get(BlockStateProperties.FACING)) - 90, 0);
}
}

View file

@ -1,12 +1,71 @@
package com.simibubi.create.modules.contraptions.components.contraptions;
import com.simibubi.create.ScreenResources;
import com.simibubi.create.foundation.behaviour.scrollvalue.INamedIconOptions;
import com.simibubi.create.foundation.utility.Lang;
public interface IControlContraption {
public void attach(ContraptionEntity contraption);
default void onStall() {
}
public void onStall();
public boolean isValid();
static enum MovementMode implements INamedIconOptions {
MOVE_PLACE(ScreenResources.I_MOVE_PLACE),
MOVE_PLACE_RETURNED(ScreenResources.I_MOVE_PLACE_RETURNED),
MOVE_NEVER_PLACE(ScreenResources.I_MOVE_NEVER_PLACE),
;
private String translationKey;
private ScreenResources icon;
private MovementMode(ScreenResources icon) {
this.icon = icon;
translationKey = "contraptions.movement_mode." + Lang.asId(name());
}
@Override
public ScreenResources getIcon() {
return icon;
}
@Override
public String getTranslationKey() {
return translationKey;
}
}
static enum RotationMode implements INamedIconOptions {
ROTATE_PLACE(ScreenResources.I_ROTATE_PLACE),
ROTATE_PLACE_RETURNED(ScreenResources.I_ROTATE_PLACE_RETURNED),
ROTATE_NEVER_PLACE(ScreenResources.I_ROTATE_NEVER_PLACE),
;
private String translationKey;
private ScreenResources icon;
private RotationMode(ScreenResources icon) {
this.icon = icon;
translationKey = "contraptions.movement_mode." + Lang.asId(name());
}
@Override
public ScreenResources getIcon() {
return icon;
}
@Override
public String getTranslationKey() {
return translationKey;
}
}
}

View file

@ -1,11 +1,18 @@
package com.simibubi.create.modules.contraptions.components.contraptions.bearing;
import java.util.List;
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.scrollvalue.ScrollOptionBehaviour;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.modules.contraptions.base.GeneratingKineticTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.Contraption;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.DirectionalExtenderScrollOptionSlot;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.state.properties.BlockStateProperties;
@ -24,6 +31,7 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
protected boolean running;
protected boolean assembleNextTick;
protected float clientAngleDiff;
protected ScrollOptionBehaviour<RotationMode> movementMode;
public MechanicalBearingTileEntity() {
super(AllTileEntities.MECHANICAL_BEARING.type);
@ -31,6 +39,15 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
setLazyTickRate(3);
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
movementMode = new ScrollOptionBehaviour<>(RotationMode.class, Lang.translate("contraptions.movement_mode"),
this, getMovementModeSlot());
movementMode.requiresWrench();
behaviours.add(movementMode);
}
@Override
public float getAddedStressCapacity() {
return isWindmill ? super.getAddedStressCapacity() : 0;
@ -178,7 +195,8 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
if (!world.isRemote && assembleNextTick) {
assembleNextTick = false;
if (running) {
boolean canDisassemble = Math.abs(angle) < 45 || Math.abs(angle) > 7 * 45;
boolean canDisassemble = movementMode.get() == RotationMode.ROTATE_PLACE
|| (isNearInitialAngle() && movementMode.get() == RotationMode.ROTATE_PLACE_RETURNED);
if (speed == 0 && (canDisassemble || movedContraption == null
|| movedContraption.getContraption().blocks.isEmpty())) {
if (movedContraption != null)
@ -206,6 +224,10 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
applyRotation();
}
public boolean isNearInitialAngle() {
return Math.abs(angle) < 45 || Math.abs(angle) > 7 * 45;
}
@Override
public void lazyTick() {
super.lazyTick();
@ -245,4 +267,12 @@ public class MechanicalBearingTileEntity extends GeneratingKineticTileEntity imp
return !isRemoved();
}
protected ValueBoxTransform getMovementModeSlot() {
return new DirectionalExtenderScrollOptionSlot((state, d) -> {
Axis axis = d.getAxis();
Axis bearingAxis = state.get(MechanicalBearingBlock.FACING).getAxis();
return bearingAxis != axis;
});
}
}

View file

@ -1,5 +1,11 @@
package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import java.util.List;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.behaviour.base.TileEntityBehaviour;
import com.simibubi.create.foundation.behaviour.scrollvalue.ScrollOptionBehaviour;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
@ -10,13 +16,15 @@ import net.minecraft.tileentity.TileEntityType;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public abstract class LinearActuatorTileEntity extends KineticTileEntity implements IControlContraption {
public float offset;
public boolean running;
protected boolean assembleNextTick;
public ContraptionEntity movedContraption;
protected boolean forceMove;
protected ScrollOptionBehaviour<MovementMode> movementMode;
protected boolean waitingForSpeedChange;
// Custom position sync
protected float clientOffsetDiff;
@ -24,6 +32,24 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
public LinearActuatorTileEntity(TileEntityType<?> typeIn) {
super(typeIn);
setLazyTickRate(3);
forceMove = true;
}
// @Override
// public void initialize() {
// super.initialize();
// if (!world.isRemote)
//
// }
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
movementMode = new ScrollOptionBehaviour<>(MovementMode.class, Lang.translate("contraptions.movement_mode"),
this, getMovementModeSlot());
movementMode.requiresWrench();
movementMode.withCallback(t -> waitingForSpeedChange = false);
behaviours.add(movementMode);
}
@Override
@ -38,11 +64,17 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
if (world.isRemote)
clientOffsetDiff *= .75f;
if (waitingForSpeedChange) {
movedContraption.setContraptionMotion(Vec3d.ZERO);
// movedContraption.setMotion(Vec3d.ZERO);
return;
}
if (!world.isRemote && assembleNextTick) {
assembleNextTick = false;
if (running) {
if (getSpeed() == 0)
disassembleConstruct();
tryDisassemble();
else
sendData();
return;
@ -69,8 +101,14 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
int extensionRange = getExtensionRange();
if (offset <= 0 || offset >= extensionRange) {
offset = offset <= 0 ? 0 : extensionRange;
if (!world.isRemote)
disassembleConstruct();
if (!world.isRemote) {
applyContraptionMotion();
tryDisassemble();
if (waitingForSpeedChange) {
forceMove = true;
sendData();
}
}
return;
}
}
@ -96,6 +134,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
public void onSpeedChanged(float prevSpeed) {
super.onSpeedChanged(prevSpeed);
assembleNextTick = true;
waitingForSpeedChange = false;
}
@Override
@ -109,6 +148,7 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
@Override
public CompoundNBT write(CompoundNBT tag) {
tag.putBoolean("Running", running);
tag.putBoolean("Waiting", waitingForSpeedChange);
tag.putFloat("Offset", offset);
return super.write(tag);
}
@ -125,23 +165,31 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
@Override
public void read(CompoundNBT tag) {
running = tag.getBoolean("Running");
waitingForSpeedChange = tag.getBoolean("Waiting");
offset = tag.getFloat("Offset");
super.read(tag);
}
@Override
public void readClientUpdate(CompoundNBT tag) {
boolean forceMovement = tag.contains("ForceMovement");
float offsetBefore = offset;
super.readClientUpdate(tag);
if (running) {
clientOffsetDiff = offset - offsetBefore;
offset = offsetBefore;
} else
if (forceMovement) {
if (movedContraption != null) {
applyContraptionPosition();
}
} else {
if (running) {
clientOffsetDiff = offset - offsetBefore;
offset = offsetBefore;
}
}
if (!running)
movedContraption = null;
if (tag.contains("ForceMovement"))
if (movedContraption != null)
applyContraptionPosition();
}
protected abstract void assembleConstruct();
@ -150,12 +198,33 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
protected abstract int getExtensionRange();
protected abstract int getInitialOffset();
protected abstract ValueBoxTransform getMovementModeSlot();
protected abstract void visitNewPosition();
protected abstract Vec3d toMotionVector(float speed);
protected abstract Vec3d toPosition(float offset);
protected void tryDisassemble() {
if (removed) {
disassembleConstruct();
return;
}
if (movementMode.get() == MovementMode.MOVE_NEVER_PLACE) {
waitingForSpeedChange = true;
return;
}
int initial = getInitialOffset();
if ((int) (offset + .5f) != initial && movementMode.get() == MovementMode.MOVE_PLACE_RETURNED) {
waitingForSpeedChange = true;
return;
}
disassembleConstruct();
}
protected void applyContraptionMotion() {
if (movedContraption.isStalled())
movedContraption.setContraptionMotion(Vec3d.ZERO);
@ -166,6 +235,8 @@ public abstract class LinearActuatorTileEntity extends KineticTileEntity impleme
protected void applyContraptionPosition() {
Vec3d vec = toPosition(offset);
movedContraption.setPosition(vec.x, vec.y, vec.z);
if (getSpeed() == 0 || waitingForSpeedChange)
movedContraption.setContraptionMotion(Vec3d.ZERO);
}
public float getMovementSpeed() {

View file

@ -2,8 +2,11 @@ package com.simibubi.create.modules.contraptions.components.contraptions.piston;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.modules.contraptions.base.IRotate;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.DirectionalExtenderScrollOptionSlot;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
import net.minecraft.nbt.CompoundNBT;
@ -11,6 +14,7 @@ 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.MathHelper;
import net.minecraft.util.math.Vec3d;
public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
@ -54,6 +58,7 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
running = true;
offset = contraption.initialExtensionProgress;
sendData();
clientOffsetDiff = 0;
BlockPos startPos = BlockPos.ZERO.offset(direction, contraption.initialExtensionProgress);
contraption.removeBlocksFromWorld(world, startPos);
@ -89,7 +94,11 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
Direction pistonDirection = getBlockState().get(BlockStateProperties.FACING);
int movementModifier =
pistonDirection.getAxisDirection().getOffset() * (pistonDirection.getAxis() == Axis.Z ? -1 : 1);
return movementSpeed * -movementModifier + clientOffsetDiff / 2f;
movementSpeed = movementSpeed * -movementModifier + clientOffsetDiff / 2f;
int extensionRange = getExtensionRange();
movementSpeed = MathHelper.clamp(movementSpeed, 0 - offset, extensionRange - offset);
return movementSpeed;
}
@Override
@ -113,6 +122,22 @@ public class MechanicalPistonTileEntity extends LinearActuatorTileEntity {
return position.add(new Vec3d(movedContraption.getContraption().getAnchor()));
}
@Override
protected ValueBoxTransform getMovementModeSlot() {
return new DirectionalExtenderScrollOptionSlot((state, d) -> {
Axis axis = d.getAxis();
Axis extensionAxis = state.get(MechanicalPistonBlock.FACING).getAxis();
Axis shaftAxis = ((IRotate) state.getBlock()).getRotationAxis(state);
return extensionAxis != axis && shaftAxis != axis;
});
}
@Override
protected int getInitialOffset() {
return movedContraption == null ? 0
: ((PistonContraption) movedContraption.getContraption()).initialExtensionProgress;
}
// private boolean hasBlockCollisions(float newOffset) {
// if (PistonContraption.isFrozen())
// return true;

View file

@ -3,17 +3,23 @@ package com.simibubi.create.modules.contraptions.components.contraptions.pulley;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllTileEntities;
import com.simibubi.create.config.AllConfigs;
import com.simibubi.create.foundation.behaviour.CenteredSideValueBoxTransform;
import com.simibubi.create.foundation.behaviour.ValueBoxTransform;
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
import com.simibubi.create.modules.contraptions.components.contraptions.piston.LinearActuatorTileEntity;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public class PulleyTileEntity extends LinearActuatorTileEntity {
protected int initialOffset;
public PulleyTileEntity() {
super(AllTileEntities.ROPE_PULLEY.type);
}
@ -35,15 +41,16 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
// Collect Construct
if (!world.isRemote) {
BlockPos anchor = pos.down((int) (offset + 1));
initialOffset = (int) (offset);
PulleyContraption contraption = PulleyContraption.assemblePulleyAt(world, anchor, (int) offset);
if (contraption == null && getSpeed() > 0)
return;
for (int i = ((int) offset); i > 0; i--) {
BlockPos offset = pos.down(i);
world.setBlockState(offset, Blocks.AIR.getDefaultState(), 66);
}
if (contraption != null && !contraption.blocks.isEmpty()) {
contraption.removeBlocksFromWorld(world, BlockPos.ZERO);
movedContraption = ContraptionEntity.createStationary(world, contraption).controlledBy(this);
@ -53,6 +60,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
}
}
clientOffsetDiff = 0;
running = true;
sendData();
}
@ -87,6 +95,7 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
if (movedContraption != null)
movedContraption.remove();
movedContraption = null;
initialOffset = 0;
running = false;
sendData();
}
@ -119,14 +128,36 @@ public class PulleyTileEntity extends LinearActuatorTileEntity {
assembleNextTick = true;
}
@Override
public void read(CompoundNBT tag) {
initialOffset = tag.getInt("InitialOffset");
super.read(tag);
}
@Override
public CompoundNBT write(CompoundNBT tag) {
tag.putInt("InitialOffset", initialOffset);
return super.write(tag);
}
@Override
protected int getExtensionRange() {
return Math.min(AllConfigs.SERVER.kinetics.maxRopeLength.get(), pos.getY() - 1);
}
@Override
protected int getInitialOffset() {
return initialOffset;
}
@Override
protected Vec3d toMotionVector(float speed) {
return new Vec3d(0, -speed, 0);
}
@Override
protected ValueBoxTransform getMovementModeSlot() {
return new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP);
}
}

View file

@ -0,0 +1,15 @@
{
"forge_marker": 1,
"variants": {
"oxidization": {
"0": { "model": "create:block/oxidized/copper_block/0" },
"1": { "model": "create:block/oxidized/copper_block/1" },
"2": { "model": "create:block/oxidized/copper_block/2" },
"3": { "model": "create:block/oxidized/copper_block/3" },
"4": { "model": "create:block/oxidized/copper_block/4" },
"5": { "model": "create:block/oxidized/copper_block/5" },
"6": { "model": "create:block/oxidized/copper_block/6" },
"7": { "model": "create:block/oxidized/copper_block/7" }
}
}
}

View file

@ -1,12 +1,15 @@
{
"forge_marker": 1,
"variants": {
"oxidization=0": { "model": "create:block/copper_ore_oxidization0" },
"oxidization=1": { "model": "create:block/copper_ore_oxidization1" },
"oxidization=2": { "model": "create:block/copper_ore_oxidization2" },
"oxidization=3": { "model": "create:block/copper_ore_oxidization3" },
"oxidization=4": { "model": "create:block/copper_ore_oxidization4" },
"oxidization=5": { "model": "create:block/copper_ore_oxidization5" },
"oxidization=6": { "model": "create:block/copper_ore_oxidization6" },
"oxidization=7": { "model": "create:block/copper_ore_oxidization7" }
"oxidization": {
"0": { "model": "create:block/oxidized/copper_ore/0" },
"1": { "model": "create:block/oxidized/copper_ore/1" },
"2": { "model": "create:block/oxidized/copper_ore/2" },
"3": { "model": "create:block/oxidized/copper_ore/3" },
"4": { "model": "create:block/oxidized/copper_ore/4" },
"5": { "model": "create:block/oxidized/copper_ore/5" },
"6": { "model": "create:block/oxidized/copper_ore/6" },
"7": { "model": "create:block/oxidized/copper_ore/7" }
}
}
}

View file

@ -0,0 +1,15 @@
{
"forge_marker": 1,
"variants": {
"oxidization": {
"0": { "model": "create:block/oxidized/copper_shingles/0" },
"1": { "model": "create:block/oxidized/copper_shingles/1" },
"2": { "model": "create:block/oxidized/copper_shingles/2" },
"3": { "model": "create:block/oxidized/copper_shingles/3" },
"4": { "model": "create:block/oxidized/copper_shingles/4" },
"5": { "model": "create:block/oxidized/copper_shingles/5" },
"6": { "model": "create:block/oxidized/copper_shingles/6" },
"7": { "model": "create:block/oxidized/copper_shingles/7" }
}
}
}

View file

@ -73,6 +73,8 @@
"item.create.rose_quartz_sword": "Gilded Quartz Blade",
"block.create.copper_ore": "Copper Ore",
"block.create.copper_block": "Copper Block",
"block.create.copper_shingles": "Copper Shingles",
"block.create.zinc_ore": "Zinc Ore",
"block.create.andesite_casing": "Andesite Casing",
@ -356,6 +358,14 @@
"create.blockzapper.leftClickToSet": "Left-Click a Block to set Material",
"create.blockzapper.empty": "Out of Blocks!",
"create.contraptions.movement_mode": "Movement Mode",
"create.contraptions.movement_mode.move_place": "Always Place when Stopped",
"create.contraptions.movement_mode.move_place_returned": "Only Place in Starting Position",
"create.contraptions.movement_mode.move_never_place": "Only Place when Anchor Destroyed",
"create.contraptions.movement_mode.rotate_place": "Always Place when Stopped",
"create.contraptions.movement_mode.rotate_place_returned": "Only Place near Initial Angle",
"create.contraptions.movement_mode.rotate_never_place": "Only Place when Anchor Destroyed",
"create.logistics.filter": "Filter",
"create.logistics.firstFrequency": "Freq. #1",
"create.logistics.secondFrequency": "Freq. #2",

View file

@ -1,6 +0,0 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization3"
}
}

View file

@ -1,6 +0,0 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization4"
}
}

View file

@ -1,6 +0,0 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization5"
}
}

View file

@ -1,6 +0,0 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization6"
}
}

View file

@ -1,6 +0,0 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization7"
}
}

View file

@ -1,6 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization0"
"all": "create:block/oxidized/copper_block_0"
}
}

View file

@ -1,6 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization1"
"all": "create:block/oxidized/copper_block_1"
}
}

View file

@ -1,6 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidization2"
"all": "create:block/oxidized/copper_block_2"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_block_3"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_block_4"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_block_5"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_block_6"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_block_7"
}
}

View file

@ -1,6 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore"
"all": "create:block/oxidized/copper_ore_0"
}
}

View file

@ -1,6 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/copper_ore_oxidized"
"all": "create:block/oxidized/copper_ore_1"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_ore_2"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_ore_3"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_ore_4"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_ore_5"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_ore_6"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_ore_7"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_0"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_1"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_2"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_3"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_4"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_5"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_6"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "block/cube_all",
"textures": {
"all": "create:block/oxidized/copper_shingles_7"
}
}

View file

@ -4,6 +4,7 @@
"textures": {
"3": "create:block/gearbox_top",
"4": "create:block/gearbox",
"5": "create:block/andesite_casing_short",
"particle": "create:block/pulley_rope"
},
"elements": [
@ -190,6 +191,18 @@
"up": {"uv": [14, 14, 2, 16], "rotation": 90, "texture": "#3"},
"down": {"uv": [14, 0, 2, 2], "rotation": 90, "texture": "#3"}
}
},
{
"name": "top",
"from": [3, 14, 2],
"to": [13, 16, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"east": {"uv": [2, 14, 14, 16], "texture": "#3"},
"west": {"uv": [2, 14, 14, 16], "texture": "#3"},
"up": {"uv": [2, 5, 14, 15], "rotation": 90, "texture": "#5"},
"down": {"uv": [2, 5, 14, 15], "rotation": 90, "texture": "#5"}
}
}
]
}

View file

@ -8,6 +8,7 @@
"4": "create:block/gearbox",
"5": "create:block/pulley_rope",
"6": "create:block/pulley_magnet",
"7": "create:block/andesite_casing_short",
"particle": "create:block/pulley_magnet"
},
"elements": [
@ -275,6 +276,20 @@
"up": {"uv": [0, 0, 10, 10], "texture": "#6"},
"down": {"uv": [0, 0, 10, 10], "texture": "#6"}
}
},
{
"name": "top",
"from": [3, 14, 2],
"to": [13, 16, 14],
"rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]},
"faces": {
"north": {"uv": [0, 0, 0, 0], "texture": "#7"},
"east": {"uv": [2, 14, 14, 16], "texture": "#7"},
"south": {"uv": [0, 0, 0, 0], "texture": "#7"},
"west": {"uv": [2, 14, 14, 16], "texture": "#7"},
"up": {"uv": [2, 5, 14, 15], "rotation": 90, "texture": "#7"},
"down": {"uv": [2, 5, 14, 15], "rotation": 90, "texture": "#7"}
}
}
],
"display": {
@ -318,6 +333,5 @@
"name": "rope_half_magnet",
"origin": [8, 8, 8],
"children": [18, 19]
}
]
}, 20]
}

View file

@ -0,0 +1,3 @@
{
"parent": "create:block/oxidized/copper_block/0"
}

View file

@ -1,3 +1,3 @@
{
"parent": "create:block/copper_ore_oxidization0"
"parent": "create:block/oxidized/copper_ore/0"
}

View file

@ -0,0 +1,3 @@
{
"parent": "create:block/oxidized/copper_shingles/0"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 640 B

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 823 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 509 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 514 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 731 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 743 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 787 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 658 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 649 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 689 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"###",
"###",
"###"
],
"key": {
"#": {
"tag": "forge:ingots/copper"
}
},
"result": {
"item": "create:copper_block"
}
}

View file

@ -0,0 +1,16 @@
{
"type": "minecraft:crafting_shaped",
"pattern": [
"##",
"##"
],
"key": {
"#": {
"tag": "forge:plates/copper"
}
},
"result": {
"item": "create:copper_shingles",
"count": 8
}
}

View file

@ -0,0 +1,12 @@
{
"type": "minecraft:crafting_shapeless",
"ingredients": [
{
"item": "create:copper_block"
}
],
"result": {
"item": "create:copper_ingot",
"count": 9
}
}