diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 5538c95fd..8771c019f 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -577,7 +577,7 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json 30815cc68ddf59924be78b1c37a0e374fafe552a assets/create/lang/en_ud.json -c1aabd0f4dfd58bbbb2618a367fc9b6b02bfb1b6 assets/create/lang/en_us.json +c6c72491c2586f70e72d7510b230e7307a4d7c99 assets/create/lang/en_us.json 487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json 3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 30af7eaf2..f29d41ad2 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -1070,20 +1070,41 @@ "create.contraptions.cart_movement_mode.rotate_paused": "Pause actors while rotating", "create.contraptions.cart_movement_mode.rotation_locked": "Lock rotation", "create.contraptions.windmill.rotation_direction": "Rotation Direction", - "create.contraptions.clockwork.clock_hands": "Clock Hands", + "create.contraptions.clockwork.clock_hands": "Clock Hand Arrangement", "create.contraptions.clockwork.hour_first": "Hour hand first", "create.contraptions.clockwork.minute_first": "Minute hand first", "create.contraptions.clockwork.hour_first_24": "24-Hour hand first", + "create.logistics.crafter.connected": "Connected Crafters", + "create.logistics.crafter.click_to_merge": "Click to merge Inventories", + "create.logistics.crafter.click_to_separate": "Click to separate Inventories", "create.logistics.filter": "Filter", "create.logistics.recipe_filter": "Recipe Filter", "create.logistics.fluid_filter": "Fluid Filter", - "create.logistics.firstFrequency": "Freq. #1", - "create.logistics.secondFrequency": "Freq. #2", - "create.logistics.filter.apply": "Applied filter to %1$s.", - "create.logistics.filter.apply_click_again": "Applied filter to %1$s, click again to copy the amount.", - "create.logistics.filter.apply_count": "Applied extraction count to filter.", + "create.logistics.firstFrequency": "Frequency #1", + "create.logistics.secondFrequency": "Frequency #2", + "create.logistics.filter.click_to_set": "Click with item to set", + "create.logistics.filter.click_to_replace": "Click with item to replace", + "create.logistics.filter.hold_to_set_amount": "Click and hold for amount", + "create.logistics.filter.extracted_amount": "Extracted Amount", + "create.logistics.filter.any_amount_short": "Any", + "create.logistics.filter.up_to": "Up to", + "create.logistics.filter.exactly": "Exactly", + "create.logistics.creative_crate.supply": "Infinite Supply", + "create.logistics.train_observer.cargo_filter": "Cargo Filter", + "create.kinetics.creative_motor.rotation_speed": "Generated Speed in RPM", + "create.kinetics.speed_controller.rotation_speed": "Targeted Speed in RPM", + + "create.logistics.redstone_interval": "Redstone Interval", + + "create.contraptions.contoller.target": "Targeted Component", + "create.contraptions.chassis.radius": "Radius when Sticky", + "create.contraptions.chassis.range": "Range of Sticky Sides", + "create.contraptions.chassis.distance": "Distance", + + "create.gui.value_settings.hold_to_edit": "Click and hold to edit", + "create.gui.value_settings.release_to_confirm": "Release %1$s to Confirm", "create.gui.goggles.generator_stats": "Generator Stats:", "create.gui.goggles.kinetic_stats": "Kinetic Stats:", "create.gui.goggles.at_current_speed": "at current speed", @@ -1374,7 +1395,7 @@ "create.weighted_ejector.targeting": "Ejecting to [%1$s,%2$s,%3$s]", "create.weighted_ejector.stack_size": "Ejected Stack Size", - "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available", + "create.logistics.when_multiple_outputs_available": "Distribution Method", "create.mechanical_arm.selection_mode.round_robin": "Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "Forced Round Robin", diff --git a/src/main/java/com/simibubi/create/AllSpriteShifts.java b/src/main/java/com/simibubi/create/AllSpriteShifts.java index 0c14f446a..6c33af044 100644 --- a/src/main/java/com/simibubi/create/AllSpriteShifts.java +++ b/src/main/java/com/simibubi/create/AllSpriteShifts.java @@ -42,8 +42,7 @@ public class AllSpriteShifts { VERTICAL_FRAMED_GLASS = getCT(AllCTTypes.VERTICAL, "palettes/framed_glass", "palettes/vertical_framed_glass"), ORNATE_IRON_WINDOW = vertical("palettes/ornate_iron_window"); - public static final CTSpriteShiftEntry CRAFTER_FRONT = - getCT(AllCTTypes.OMNIDIRECTIONAL, "crafter_top", "brass_casing"), CRAFTER_SIDE = vertical("crafter_side"), + public static final CTSpriteShiftEntry CRAFTER_SIDE = vertical("crafter_side"), CRAFTER_OTHERSIDE = horizontal("crafter_side"), ANDESITE_ENCASED_COGWHEEL_SIDE = vertical("andesite_encased_cogwheel_side"), ANDESITE_ENCASED_COGWHEEL_OTHERSIDE = horizontal("andesite_encased_cogwheel_side"), diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 937ec8b4c..5d9847548 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -20,6 +20,7 @@ import com.simibubi.create.content.schematics.ClientSchematicLoader; import com.simibubi.create.content.schematics.client.SchematicAndQuillHandler; import com.simibubi.create.content.schematics.client.SchematicHandler; import com.simibubi.create.foundation.ClientResourceReloadListener; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsClient; import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.ponder.content.PonderIndex; @@ -61,6 +62,7 @@ public class CreateClient { public static final PotatoCannonRenderHandler POTATO_CANNON_RENDER_HANDLER = new PotatoCannonRenderHandler(); public static final SoulPulseEffectHandler SOUL_PULSE_EFFECT_HANDLER = new SoulPulseEffectHandler(); public static final GlobalRailwayManager RAILWAYS = new GlobalRailwayManager(); + public static final ValueSettingsClient VALUE_SETTINGS_HANDLER = new ValueSettingsClient(); public static final ClientResourceReloadListener RESOURCE_RELOAD_LISTENER = new ClientResourceReloadListener(); @@ -106,6 +108,7 @@ public class CreateClient { OverlayRegistry.registerOverlayAbove(ForgeIngameGui.HOTBAR_ELEMENT, "Create's Linked Controller", LinkedControllerClientHandler.OVERLAY); OverlayRegistry.registerOverlayAbove(ForgeIngameGui.HOTBAR_ELEMENT, "Create's Schematics", SCHEMATIC_HANDLER.getOverlayRenderer()); OverlayRegistry.registerOverlayAbove(ForgeIngameGui.HOTBAR_ELEMENT, "Create's Toolboxes", ToolboxHandlerClient.OVERLAY); + OverlayRegistry.registerOverlayAbove(ForgeIngameGui.HOTBAR_ELEMENT, "Create's Value Settings", VALUE_SETTINGS_HANDLER); } public static void invalidateRenderers() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlockEntity.java index 09ae713ed..fd03b2cef 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsBlockEntity.java @@ -48,7 +48,8 @@ public class ContraptionControlsBlockEntity extends SmartBlockEntity { @Override public void addBehaviours(List behaviours) { - behaviours.add(filtering = new FilteringBehaviour(this, new ControlsSlot()).moveText(new Vec3(-30, 20, 10))); + behaviours.add(filtering = new FilteringBehaviour(this, new ControlsSlot())); + filtering.setLabel(Lang.translateDirect("contraptions.contoller.target")); } public void pressButton() { @@ -107,13 +108,13 @@ public class ContraptionControlsBlockEntity extends SmartBlockEntity { .color(DyeHelper.DYE_TABLE.get(enabled ? DyeColor.LIME : DyeColor.ORANGE) .getFirst()) .component(); - + if (filter.isEmpty()) { Lang.translate("contraption.controls.all_actor_toggle", state) .sendStatus(player); return; } - + Lang.translate("contraption.controls.specific_actor_toggle", filter.getHoverName() .getString(), state) .sendStatus(player); @@ -125,7 +126,7 @@ public class ContraptionControlsBlockEntity extends SmartBlockEntity { protected Vec3 getLocalOffset(BlockState state) { Direction facing = state.getValue(ControlsBlock.FACING); float yRot = AngleHelper.horizontalAngle(facing); - return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 10.875f, 5.1f), yRot, Axis.Y); + return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 12f, 5.5f), yRot, Axis.Y); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java index 4667bf690..4ec9dae3f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/controls/ContraptionControlsRenderer.java @@ -47,12 +47,14 @@ public class ContraptionControlsRenderer extends SmartBlockEntityRenderer type, BlockPos pos, BlockState state) { @@ -27,18 +34,12 @@ public class CreativeMotorBlockEntity extends GeneratingKineticBlockEntity { @Override public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); - Integer max = AllConfigs.server().kinetics.maxMotorSpeed.get(); - - CenteredSideValueBoxTransform slot = new CenteredSideValueBoxTransform( - (motor, side) -> motor.getValue(CreativeMotorBlock.FACING) == side.getOpposite()); - - generatedSpeed = new ScrollValueBehaviour(Lang.translateDirect("generic.speed"), this, slot); + int max = MAX_SPEED; + generatedSpeed = new KineticScrollValueBehaviour(Lang.translateDirect("kinetics.creative_motor.rotation_speed"), + this, new MotorValueBox()); generatedSpeed.between(-max, max); generatedSpeed.value = DEFAULT_SPEED; - generatedSpeed.scrollableValue = DEFAULT_SPEED; - generatedSpeed.withUnit(i -> Lang.translateDirect("generic.unit.rpm")); generatedSpeed.withCallback(i -> this.updateGeneratedRotation()); - generatedSpeed.withStepFunction(CreativeMotorBlockEntity::step); behaviours.add(generatedSpeed); } @@ -56,22 +57,40 @@ public class CreativeMotorBlockEntity extends GeneratingKineticBlockEntity { return convertToDirection(generatedSpeed.getValue(), getBlockState().getValue(CreativeMotorBlock.FACING)); } - public static int step(StepContext context) { - int current = context.currentValue; - int step = 1; + class MotorValueBox extends ValueBoxTransform.Sided { - if (!context.shift) { - int magnitude = Math.abs(current) - (context.forward == current > 0 ? 0 : 1); - - if (magnitude >= 4) - step *= 4; - if (magnitude >= 32) - step *= 4; - if (magnitude >= 128) - step *= 4; + @Override + protected Vec3 getSouthLocation() { + return VecHelper.voxelSpace(8, 8, 12.5); + } + + @Override + protected Vec3 getLocalOffset(BlockState state) { + Direction facing = state.getValue(CreativeMotorBlock.FACING); + return super.getLocalOffset(state).add(Vec3.atLowerCornerOf(facing.getNormal()) + .scale(-1 / 16f)); + } + + @Override + protected void rotate(BlockState state, PoseStack ms) { + super.rotate(state, ms); + Direction facing = state.getValue(CreativeMotorBlock.FACING); + if (facing.getAxis() == Axis.Y) + return; + if (getSide() != Direction.UP) + return; + TransformStack.cast(ms) + .rotateZ(-AngleHelper.horizontalAngle(facing) + 180); + } + + @Override + protected boolean isSideActive(BlockState state, Direction direction) { + Direction facing = state.getValue(CreativeMotorBlock.FACING); + if (facing.getAxis() != Axis.Y && direction == Direction.DOWN) + return false; + return direction.getAxis() != facing.getAxis(); } - return (int) (current + (context.forward ? step : -step) == 0 ? step + 1 : step); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/motor/KineticScrollValueBehaviour.java b/src/main/java/com/simibubi/create/content/contraptions/components/motor/KineticScrollValueBehaviour.java new file mode 100644 index 000000000..9467930e3 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/motor/KineticScrollValueBehaviour.java @@ -0,0 +1,55 @@ +package com.simibubi.create.content.contraptions.components.motor; + +import com.google.common.collect.ImmutableList; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter; +import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.ChatFormatting; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; + +public class KineticScrollValueBehaviour extends ScrollValueBehaviour { + + public KineticScrollValueBehaviour(Component label, SmartBlockEntity be, ValueBoxTransform slot) { + super(label, be, slot); + withFormatter(v -> String.valueOf(Math.abs(v))); + } + + @Override + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) { + ImmutableList rows = ImmutableList.of(Components.literal("\u27f3") + .withStyle(ChatFormatting.BOLD), + Components.literal("\u27f2") + .withStyle(ChatFormatting.BOLD)); + ValueSettingsFormatter formatter = new ValueSettingsFormatter(this::formatSettings); + return new ValueSettingsBoard(label, 256, 32, rows, formatter); + } + + @Override + public void setValueSettings(Player player, ValueSettings valueSetting, boolean ctrlHeld) { + int value = Math.max(1, valueSetting.value()); + if (!valueSetting.equals(getValueSettings())) + playFeedbackSound(this); + setValue(valueSetting.row() == 0 ? -value : value); + } + + @Override + public ValueSettings getValueSettings() { + return new ValueSettings(value < 0 ? 0 : 1, Math.abs(value)); + } + + public MutableComponent formatSettings(ValueSettings settings) { + return Lang.number(Math.max(1, Math.abs(settings.value()))) + .add(Lang.text(settings.row() == 0 ? "\u27f3" : "\u27f2") + .style(ChatFormatting.BOLD)) + .component(); + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawFilterSlot.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawFilterSlot.java index afdf2497c..539052ca9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawFilterSlot.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawFilterSlot.java @@ -15,8 +15,8 @@ public class SawFilterSlot extends ValueBoxTransform { protected Vec3 getLocalOffset(BlockState state) { if (state.getValue(SawBlock.FACING) != Direction.UP) return null; - Vec3 x = VecHelper.voxelSpace(8f, 12.5f, 12.25f); - Vec3 z = VecHelper.voxelSpace(12.25f, 12.5f, 8f); + Vec3 x = VecHelper.voxelSpace(8f, 12.5f, 11f); + Vec3 z = VecHelper.voxelSpace(11f, 12.5f, 8f); return state.getValue(SawBlock.AXIS_ALONG_FIRST_COORDINATE) ? z : x; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineValueBox.java b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineValueBox.java index 92f80c88e..0e591f358 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineValueBox.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/steam/SteamEngineValueBox.java @@ -40,7 +40,7 @@ public class SteamEngineValueBox extends ValueBoxTransform.Sided { if (engineFacing.getAxis() == Axis.Y) recessed ^= state.getValue(SteamEngineBlock.FACING).getAxis() == Axis.X; - Vec3 local = VecHelper.voxelSpace(8, recessed ? 13 : 15, 9); + Vec3 local = VecHelper.voxelSpace(8, recessed ? 12.5 : 14.5, 9); local = VecHelper.rotateCentered(local, roll, Axis.Z); local = VecHelper.rotateCentered(local, horizontalAngle, Axis.Y); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisBlockEntity.java index 45d20537f..eee392678 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisBlockEntity.java @@ -7,12 +7,18 @@ import java.util.LinkedList; import java.util.List; import java.util.Queue; import java.util.Set; +import java.util.function.Function; +import com.google.common.collect.ImmutableList; import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllKeys; import com.simibubi.create.content.contraptions.components.structureMovement.BlockMovementChecks; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.CenteredSideValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter; import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.BulkScrollValueBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueBehaviour; import com.simibubi.create.foundation.config.AllConfigs; @@ -23,17 +29,24 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; import net.minecraft.core.Direction.AxisDirection; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.phys.BlockHitResult; import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.fml.DistExecutor; public class ChassisBlockEntity extends SmartBlockEntity { ScrollValueBehaviour range; + public int currentlySelectedRange; + public ChassisBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } @@ -41,22 +54,30 @@ public class ChassisBlockEntity extends SmartBlockEntity { @Override public void addBehaviours(List behaviours) { int max = AllConfigs.server().kinetics.maxChassisRange.get(); - range = new BulkScrollValueBehaviour(Lang.translateDirect("generic.range"), this, new CenteredSideValueBoxTransform(), - be -> ((ChassisBlockEntity) be).collectChassisGroup()); + range = new ChassisScrollValueBehaviour(Lang.translateDirect("contraptions.chassis.range"), this, + new CenteredSideValueBoxTransform(), be -> ((ChassisBlockEntity) be).collectChassisGroup()); range.requiresWrench(); range.between(1, max); - range - .withClientCallback( - i -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ChassisRangeDisplay.display(this))); - range.value = max / 2; + range.withClientCallback( + i -> DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> ChassisRangeDisplay.display(this))); + range.setValue(max / 2); + range.withFormatter(s -> String.valueOf(currentlySelectedRange)); behaviours.add(range); + currentlySelectedRange = range.getValue(); } @Override public void initialize() { super.initialize(); if (getBlockState().getBlock() instanceof RadialChassisBlock) - range.setLabel(Lang.translateDirect("generic.radius")); + range.setLabel(Lang.translateDirect("contraptions.chassis.radius")); + } + + @Override + protected void read(CompoundTag tag, boolean clientPacket) { + super.read(tag, clientPacket); + if (clientPacket) + currentlySelectedRange = getRange(); } public int getRange() { @@ -67,11 +88,12 @@ public class ChassisBlockEntity extends SmartBlockEntity { if (!(getBlockState().getBlock() instanceof AbstractChassisBlock)) return Collections.emptyList(); return isRadial() ? getIncludedBlockPositionsRadial(forcedMovement, visualize) - : getIncludedBlockPositionsLinear(forcedMovement, visualize); + : getIncludedBlockPositionsLinear(forcedMovement, visualize); } protected boolean isRadial() { - return level.getBlockState(worldPosition).getBlock() instanceof RadialChassisBlock; + return level.getBlockState(worldPosition) + .getBlock() instanceof RadialChassisBlock; } public List collectChassisGroup() { @@ -149,7 +171,7 @@ public class ChassisBlockEntity extends SmartBlockEntity { AbstractChassisBlock block = (AbstractChassisBlock) state.getBlock(); Axis axis = state.getValue(AbstractChassisBlock.AXIS); Direction facing = Direction.get(AxisDirection.POSITIVE, axis); - int chassisRange = visualize ? range.scrollableValue : getRange(); + int chassisRange = visualize ? currentlySelectedRange : getRange(); for (int offset : new int[] { 1, -1 }) { if (offset == -1) @@ -183,7 +205,7 @@ public class ChassisBlockEntity extends SmartBlockEntity { BlockState state = level.getBlockState(worldPosition); Axis axis = state.getValue(AbstractChassisBlock.AXIS); AbstractChassisBlock block = (AbstractChassisBlock) state.getBlock(); - int chassisRange = visualize ? range.scrollableValue : getRange(); + int chassisRange = visualize ? currentlySelectedRange : getRange(); for (Direction facing : Iterate.directions) { if (facing.getAxis() == axis) @@ -229,4 +251,46 @@ public class ChassisBlockEntity extends SmartBlockEntity { return positions; } + class ChassisScrollValueBehaviour extends BulkScrollValueBehaviour { + + public ChassisScrollValueBehaviour(Component label, SmartBlockEntity be, ValueBoxTransform slot, + Function> groupGetter) { + super(label, be, slot, groupGetter); + } + + @Override + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) { + ImmutableList rows = ImmutableList.of(Lang.translateDirect("contraptions.chassis.distance")); + ValueSettingsFormatter formatter = + new ValueSettingsFormatter(vs -> new ValueSettings(vs.row(), vs.value() + 1).format()); + return new ValueSettingsBoard(label, max - 1, 1, rows, formatter); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void newSettingHovered(ValueSettings valueSetting) { + if (!level.isClientSide) + return; + if (!AllKeys.ctrlDown()) + currentlySelectedRange = valueSetting.value() + 1; + else + for (SmartBlockEntity be : getBulk()) + if (be instanceof ChassisBlockEntity cbe) + cbe.currentlySelectedRange = valueSetting.value() + 1; + ChassisRangeDisplay.display(ChassisBlockEntity.this); + } + + @Override + public void setValueSettings(Player player, ValueSettings vs, boolean ctrlHeld) { + super.setValueSettings(player, new ValueSettings(vs.row(), vs.value() + 1), ctrlHeld); + } + + @Override + public ValueSettings getValueSettings() { + ValueSettings vs = super.getValueSettings(); + return new ValueSettings(vs.row(), vs.value() - 1); + } + + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java index 93a6fd9ce..1d2526c7f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/chassis/ChassisRangeDisplay.java @@ -36,10 +36,10 @@ public class ChassisRangeDisplay { this.be = be; timer = DISPLAY_TIME; CreateClient.OUTLINER.showCluster(getOutlineKey(), createSelection(be)) - .colored(0xFFFFFF) - .disableNormals() - .lineWidth(1 / 16f) - .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED); + .colored(0xFFFFFF) + .disableNormals() + .lineWidth(1 / 16f) + .withFaceTexture(AllSpecialTextures.HIGHLIGHT_CHECKERED); } protected Object getOutlineKey() { @@ -173,7 +173,7 @@ public class ChassisRangeDisplay { GroupEntry hoveredGroup = new GroupEntry(chassis); for (ChassisBlockEntity included : hoveredGroup.includedBEs) - CreateClient.OUTLINER.remove(included.getBlockPos()); + CreateClient.OUTLINER.remove(Pair.of(included.getBlockPos(), 1)); groupEntries.forEach(entry -> CreateClient.OUTLINER.remove(entry.getOutlineKey())); groupEntries.clear(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlockEntity.java index 53378b5e3..7e7e7a467 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/mounted/CartAssemblerBlockEntity.java @@ -277,7 +277,7 @@ public class CartAssemblerBlockEntity extends SmartBlockEntity implements IDispl @Override protected Vec3 getSouthLocation() { - return VecHelper.voxelSpace(8, 8, 18); + return VecHelper.voxelSpace(8, 8, 17.5); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/SmartFluidPipeBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/SmartFluidPipeBlockEntity.java index c1676c5ab..956f59c30 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/SmartFluidPipeBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/pipes/SmartFluidPipeBlockEntity.java @@ -71,10 +71,15 @@ public class SmartFluidPipeBlockEntity extends SmartBlockEntity { @Override protected Vec3 getLocalOffset(BlockState state) { AttachFace face = state.getValue(SmartFluidPipeBlock.FACE); - float y = face == AttachFace.CEILING ? 0.3f : face == AttachFace.WALL ? 11.3f : 15.3f; - float z = face == AttachFace.CEILING ? 4.6f : face == AttachFace.WALL ? 0.6f : 4.6f; + float y = face == AttachFace.CEILING ? 0.55f : face == AttachFace.WALL ? 11.4f : 15.45f; + float z = face == AttachFace.CEILING ? 4.6f : face == AttachFace.WALL ? 0.55f : 4.625f; return VecHelper.rotateCentered(VecHelper.voxelSpace(8, y, z), angleY(state), Axis.Y); } + + @Override + protected float getScale() { + return super.getScale() * 1.02f; + } @Override protected void rotate(BlockState state, PoseStack ms) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlockEntity.java index 3416be867..4ff7e8e8f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/BasinBlockEntity.java @@ -123,8 +123,7 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf @Override public void addBehaviours(List behaviours) { behaviours.add(new DirectBeltInputBehaviour(this)); - filtering = new FilteringBehaviour(this, new BasinValueBox()).moveText(new Vec3(2, -8, 0)) - .withCallback(newFilter -> contentsChanged = true) + filtering = new FilteringBehaviour(this, new BasinValueBox()).withCallback(newFilter -> contentsChanged = true) .forRecipes(); behaviours.add(filtering); @@ -194,7 +193,7 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf visualizedOutputItems.clear(); visualizedOutputFluids.clear(); } - + @Override public void destroy() { super.destroy(); @@ -202,7 +201,7 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf ItemHelper.dropContents(level, worldPosition, outputInventory); spoutputBuffer.forEach(is -> Block.popResource(level, worldPosition, is)); } - + @Override public void remove() { super.remove(); @@ -212,7 +211,7 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf public void onEmptied() { getOperator().ifPresent(be -> be.basinRemoved = true); } - + @Override public void invalidate() { super.invalidate(); @@ -740,7 +739,7 @@ public class BasinBlockEntity extends SmartBlockEntity implements IHaveGoggleInf @Override protected Vec3 getSouthLocation() { - return VecHelper.voxelSpace(8, 12, 15.75); + return VecHelper.voxelSpace(8, 12, 16.05); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlockEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlockEntity.java index 435aaef3c..48519a129 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/advanced/SpeedControllerBlockEntity.java @@ -4,7 +4,7 @@ import java.util.List; import com.simibubi.create.content.contraptions.RotationPropagator; import com.simibubi.create.content.contraptions.base.KineticBlockEntity; -import com.simibubi.create.content.contraptions.components.motor.CreativeMotorBlockEntity; +import com.simibubi.create.content.contraptions.components.motor.KineticScrollValueBehaviour; import com.simibubi.create.content.contraptions.relays.elementary.CogWheelBlock; import com.simibubi.create.content.contraptions.relays.elementary.ICogWheel; import com.simibubi.create.foundation.advancement.AllAdvancements; @@ -44,16 +44,13 @@ public class SpeedControllerBlockEntity extends KineticBlockEntity { super.addBehaviours(behaviours); Integer max = AllConfigs.server().kinetics.maxRotationSpeed.get(); - targetSpeed = - new ScrollValueBehaviour(Lang.translateDirect("generic.speed"), this, new ControllerValueBoxTransform()); + targetSpeed = new KineticScrollValueBehaviour(Lang.translateDirect("kinetics.speed_controller.rotation_speed"), + this, new ControllerValueBoxTransform()); targetSpeed.between(-max, max); targetSpeed.value = DEFAULT_SPEED; - targetSpeed.moveText(new Vec3(9, 0, 10)); - targetSpeed.withUnit(i -> Lang.translateDirect("generic.unit.rpm")); targetSpeed.withCallback(i -> this.updateTargetRotation()); - targetSpeed.withStepFunction(CreativeMotorBlockEntity::step); behaviours.add(targetSpeed); - + registerAwardables(behaviours, AllAdvancements.SPEED_CONTROLLER); } @@ -63,7 +60,7 @@ public class SpeedControllerBlockEntity extends KineticBlockEntity { RotationPropagator.handleRemoved(level, worldPosition, this); removeSource(); attachKinetics(); - + if (isCogwheelPresent() && getSpeed() != 0) award(AllAdvancements.SPEED_CONTROLLER); } @@ -124,14 +121,15 @@ public class SpeedControllerBlockEntity extends KineticBlockEntity { private boolean isCogwheelPresent() { BlockState stateAbove = level.getBlockState(worldPosition.above()); return ICogWheel.isDedicatedCogWheel(stateAbove.getBlock()) && ICogWheel.isLargeCog(stateAbove) - && stateAbove.getValue(CogWheelBlock.AXIS).isHorizontal(); + && stateAbove.getValue(CogWheelBlock.AXIS) + .isHorizontal(); } private class ControllerValueBoxTransform extends ValueBoxTransform.Sided { @Override protected Vec3 getSouthLocation() { - return VecHelper.voxelSpace(8, 11f, 16); + return VecHelper.voxelSpace(8, 11f, 15.5f); } @Override @@ -144,7 +142,7 @@ public class SpeedControllerBlockEntity extends KineticBlockEntity { @Override protected float getScale() { - return 0.275f; + return 0.5f; } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlockEntity.java index 81d7dc82f..1cbc5346f 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/chute/SmartChuteBlockEntity.java @@ -32,7 +32,7 @@ public class SmartChuteBlockEntity extends ChuteBlockEntity { @Override protected ExtractionCountMode getExtractionMode() { - return filtering.isCountVisible() && !filtering.anyAmount() ? ExtractionCountMode.EXACTLY + return filtering.isCountVisible() && !filtering.anyAmount() && !filtering.upTo ? ExtractionCountMode.EXACTLY : ExtractionCountMode.UPTO; } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeBlock.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeBlock.java index 3956573df..b21562d06 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeBlock.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeBlock.java @@ -36,6 +36,11 @@ public class BrassDiodeBlock extends AbstractDiodeBlock implements IBE behaviours) { - maxState = new ScrollValueBehaviour(Lang.translateDirect("generic.delay"), this, new BrassDiodeScrollSlot()) - .between(2, 60 * 20 * 30); - maxState.withStepFunction(this::step); + maxState = new BrassDiodeScrollValueBehaviour(Lang.translateDirect("logistics.redstone_interval"), this, + new BrassDiodeScrollSlot()).between(2, 60 * 20 * 60); maxState.withFormatter(this::format); - maxState.withUnit(this::getUnit); maxState.withCallback(this::onMaxDelayChanged); + maxState.setValue(2); behaviours.add(maxState); } @@ -76,32 +73,12 @@ public abstract class BrassDiodeBlockEntity extends SmartBlockEntity { super.write(compound, clientPacket); } - private int step(StepContext context) { - int value = context.currentValue; - if (!context.forward) - value--; - - if (value < 20) - return 1; - if (value < 20 * 60) - return 20; - return 20 * 60; - } - private String format(int value) { - if (value < 20) + if (value < 60) return value + "t"; if (value < 20 * 60) return (value / 20) + "s"; return (value / 20 / 60) + "m"; } - private Component getUnit(int value) { - if (value < 20) - return Lang.translateDirect("generic.unit.ticks"); - if (value < 20 * 60) - return Lang.translateDirect("generic.unit.seconds"); - return Lang.translateDirect("generic.unit.minutes"); - } - } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollSlot.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollSlot.java index 6603746e5..c7ff8f1bc 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollSlot.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollSlot.java @@ -14,7 +14,7 @@ public class BrassDiodeScrollSlot extends ValueBoxTransform { @Override protected Vec3 getLocalOffset(BlockState state) { - return VecHelper.voxelSpace(8, 3f, 8); + return VecHelper.voxelSpace(8, 2.6f, 8); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollValueBehaviour.java b/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollValueBehaviour.java new file mode 100644 index 000000000..caa99c7cc --- /dev/null +++ b/src/main/java/com/simibubi/create/content/logistics/block/diodes/BrassDiodeScrollValueBehaviour.java @@ -0,0 +1,77 @@ +package com.simibubi.create.content.logistics.block.diodes; + +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter; +import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueBehaviour; +import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; + +public class BrassDiodeScrollValueBehaviour extends ScrollValueBehaviour { + + public BrassDiodeScrollValueBehaviour(Component label, SmartBlockEntity be, ValueBoxTransform slot) { + super(label, be, slot); + } + + @Override + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) { + return new ValueSettingsBoard(label, 60, 10, + Lang.translatedOptions("generic.unit", "ticks", "seconds", "minutes"), + new ValueSettingsFormatter(this::formatSettings)); + } + + @Override + public void onShortInteract(Player player, InteractionHand hand, Direction side) { + BlockState blockState = blockEntity.getBlockState(); + if (blockState.getBlock()instanceof BrassDiodeBlock bdb) + bdb.toggle(getWorld(), getPos(), blockState, player, hand); + } + + @Override + public void setValueSettings(Player player, ValueSettings valueSetting, boolean ctrlHeld) { + int value = valueSetting.value(); + int multiplier = switch (valueSetting.row()) { + case 0 -> 1; + case 1 -> 20; + default -> 60 * 20; + }; + if (!valueSetting.equals(getValueSettings())) + playFeedbackSound(this); + setValue(Math.max(2, Math.max(1, value) * multiplier)); + } + + @Override + public ValueSettings getValueSettings() { + int row = 0; + int value = this.value; + + if (value > 60 * 20) { + value = value / (60 * 20); + row = 2; + } else if (value > 60) { + value = value / 20; + row = 1; + } + + return new ValueSettings(row, value); + } + + public MutableComponent formatSettings(ValueSettings settings) { + int value = Math.max(1, settings.value()); + return Components.literal(switch (settings.row()) { + case 0 -> Math.max(2, value) + "t"; + case 1 -> "0:" + (value < 10 ? "0" : "") + value; + default -> value + ":00"; + }); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlockEntity.java index af62681d5..55bf7fa0d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelBlockEntity.java @@ -19,6 +19,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.belt.DirectBeltInput import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.inventory.InvManipulationBehaviour; import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.utility.BlockFace; import com.simibubi.create.foundation.utility.VecHelper; @@ -74,7 +75,8 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering BeltBlockEntity belt = BeltHelper.getSegmentBE(level, worldPosition.below()); if (belt != null) - return belt.getMovementFacing() == state.getValue(BeltFunnelBlock.HORIZONTAL_FACING) ? Mode.PUSHING_TO_BELT + return belt.getMovementFacing() == state.getValue(BeltFunnelBlock.HORIZONTAL_FACING) + ? Mode.PUSHING_TO_BELT : Mode.TAKING_FROM_BELT; return Mode.INVALID; } @@ -136,8 +138,9 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering // Find other entities blocking the extract (only if necessary) int amountToExtract = getAmountToExtract(); + ExtractionCountMode mode = getModeToExtract(); ItemStack stack = invManipulation.simulate() - .extract(amountToExtract); + .extract(mode, amountToExtract); if (stack.isEmpty()) return; for (ItemEntity itemEntity : level.getEntitiesOfClass(ItemEntity.class, area)) { @@ -146,7 +149,7 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering } // Extract - stack = invManipulation.extract(amountToExtract); + stack = invManipulation.extract(mode, amountToExtract); if (stack.isEmpty()) return; @@ -176,8 +179,7 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering startCooldown(); } - static final AABB coreBB = - new AABB(VecHelper.CENTER_OF_ORIGIN, VecHelper.CENTER_OF_ORIGIN).inflate(.75f); + static final AABB coreBB = new AABB(VecHelper.CENTER_OF_ORIGIN, VecHelper.CENTER_OF_ORIGIN).inflate(.75f); private AABB getEntityOverflowScanningArea() { Direction facing = AbstractFunnelBlock.getFunnelFacing(getBlockState()); @@ -199,8 +201,10 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering return; int amountToExtract = getAmountToExtract(); - ItemStack stack = invManipulation.extract(amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true) - .isEmpty()); + ExtractionCountMode mode = getModeToExtract(); + ItemStack stack = + invManipulation.extract(mode, amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true) + .isEmpty()); if (stack.isEmpty()) return; flap(false); @@ -211,13 +215,19 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering public int getAmountToExtract() { if (!supportsAmountOnFilter()) - return -1; + return 64; int amountToExtract = invManipulation.getAmountFromFilter(); if (!filtering.isActive()) amountToExtract = 1; return amountToExtract; } + public ExtractionCountMode getModeToExtract() { + if (!supportsAmountOnFilter() || !filtering.isActive()) + return ExtractionCountMode.UPTO; + return invManipulation.getModeFromFilter(); + } + private int startCooldown() { return extractionCooldown = AllConfigs.server().logistics.defaultExtractionTimer.get(); } @@ -284,7 +294,8 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering public void flap(boolean inward) { if (!level.isClientSide) { - AllPackets.getChannel().send(packetTarget(), new FunnelFlapPacket(this, inward)); + AllPackets.getChannel() + .send(packetTarget(), new FunnelFlapPacket(this, inward)); } else { flap.setValue(inward ? 1 : -1); AllSoundEvents.FUNNEL_FLAP.playAt(level, worldPosition, 1, 1, true); @@ -336,7 +347,7 @@ public class FunnelBlockEntity extends SmartBlockEntity implements IHaveHovering .onFunnelTransfer(level, worldPosition, stack); award(AllAdvancements.FUNNEL); } - + private LerpedFloat createChasingFlap() { return LerpedFloat.linear() .startWithValue(.25f) diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java index 0e0374502..4065cbdbd 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelFilterSlotPositioning.java @@ -28,7 +28,7 @@ public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided { return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 15.5f, 13), stateAngle, Axis.Y); case PULLING: case PUSHING: - return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 12.1, 8.7f), horizontalAngle, Axis.Y); + return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 12.0f, 8.675f), horizontalAngle, Axis.Y); default: case RETRACTED: return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 13, 7.5f), horizontalAngle, Axis.Y); @@ -41,7 +41,7 @@ public class FunnelFilterSlotPositioning extends ValueBoxTransform.Sided { return VecHelper.rotateCentered(southLocation, horizontalAngle, Axis.Y); } - return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 12.1, 8.7f), horizontalAngle, Axis.Y); + return VecHelper.rotateCentered(VecHelper.voxelSpace(8, 12.2, 8.55f), horizontalAngle, Axis.Y); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelMovementBehaviour.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelMovementBehaviour.java index 5c9258fd2..8770a757a 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelMovementBehaviour.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelMovementBehaviour.java @@ -5,7 +5,6 @@ import java.util.List; import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.logistics.item.filter.FilterItem; -import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.item.ItemHelper; import net.minecraft.core.BlockPos; @@ -74,11 +73,13 @@ public class FunnelMovementBehaviour implements MovementBehaviour { ItemStack filter = getFilter(context); int filterAmount = context.blockEntityData.getInt("FilterAmount"); + boolean upTo = context.blockEntityData.getBoolean("UpTo"); if (filterAmount <= 0) - filterAmount = hasFilter ? AllConfigs.server().logistics.defaultExtractionLimit.get() : 1; + filterAmount = hasFilter ? 64 : 1; ItemStack extract = ItemHelper.extract(context.contraption.getSharedInventory(), - s -> FilterItem.test(world, s, filter), ItemHelper.ExtractionCountMode.UPTO, filterAmount, false); + s -> FilterItem.test(world, s, filter), + upTo ? ItemHelper.ExtractionCountMode.UPTO : ItemHelper.ExtractionCountMode.EXACTLY, filterAmount, false); if (extract.isEmpty()) return; diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateBlockEntity.java index 38650b179..3777ca445 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateBlockEntity.java @@ -7,6 +7,7 @@ import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.utility.Lang; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; @@ -33,6 +34,7 @@ public class CreativeCrateBlockEntity extends CrateBlockEntity { @Override public void addBehaviours(List behaviours) { behaviours.add(filtering = createFilter()); + filtering.setLabel(Lang.translateDirect("logistics.creative_crate.supply")); } @Override @@ -60,11 +62,11 @@ public class CreativeCrateBlockEntity extends CrateBlockEntity { @Override protected Vec3 getLocalOffset(BlockState state) { - return new Vec3(0.5, 13 / 16d, 0.5); + return new Vec3(0.5, 13.5 / 16d, 0.5); } protected float getScale() { - return super.getScale() * 1.5f; + return super.getScale(); }; }); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmBlockEntity.java index daacdb7bb..30d87968e 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmBlockEntity.java @@ -598,14 +598,14 @@ public class ArmBlockEntity extends KineticBlockEntity implements ITransformable @Override protected Vec3 getLocalOffset(BlockState state) { int yPos = state.getValue(ArmBlock.CEILING) ? 16 - 3 : 3; - Vec3 location = VecHelper.voxelSpace(8, yPos, 15.95); + Vec3 location = VecHelper.voxelSpace(8, yPos, 15.5); location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(getSide()), Direction.Axis.Y); return location; } @Override protected float getScale() { - return .3f; + return super.getScale(); } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContentObserverBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContentObserverBlockEntity.java index bfa1cf8f0..4d46d511b 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContentObserverBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/ContentObserverBlockEntity.java @@ -19,7 +19,6 @@ import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; public class ContentObserverBlockEntity extends SmartBlockEntity { @@ -36,7 +35,7 @@ public class ContentObserverBlockEntity extends SmartBlockEntity { @Override public void addBehaviours(List behaviours) { - filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot()).moveText(new Vec3(0, 5, 0)); + filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot()); behaviours.add(filtering); InterfaceProvider towardBlockFacing = InterfaceProvider.towardBlockFacing(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlockEntity.java index 20843fb95..288aed25e 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/redstone/StockpileSwitchBlockEntity.java @@ -20,7 +20,6 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; import net.minecraft.world.ticks.TickPriority; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; @@ -101,10 +100,10 @@ public class StockpileSwitchBlockEntity extends SmartBlockEntity { if (targetBlockEntity instanceof StockpileSwitchObservable observable) { currentLevel = observable.getPercent() / 100f; - + } else if (StorageDrawers.isDrawer(targetBlockEntity) && observedInventory.hasInventory()) { currentLevel = StorageDrawers.getTrueFillLevel(observedInventory.getInventory(), filtering); - + } else if (observedInventory.hasInventory() || observedTank.hasInventory()) { if (observedInventory.hasInventory()) { // Item inventory @@ -154,7 +153,7 @@ public class StockpileSwitchBlockEntity extends SmartBlockEntity { currentLevel = Mth.clamp(currentLevel, 0, 1); changed = currentLevel != prevLevel; - + boolean previouslyPowered = redstoneState; if (redstoneState && currentLevel <= offWhenBelow) redstoneState = false; @@ -194,8 +193,8 @@ public class StockpileSwitchBlockEntity extends SmartBlockEntity { @Override public void addBehaviours(List behaviours) { - filtering = new FilteringBehaviour(this, new FilteredDetectorFilterSlot()).moveText(new Vec3(0, 5, 0)) - .withCallback($ -> updateCurrentLevel()); + filtering = + new FilteringBehaviour(this, new FilteredDetectorFilterSlot()).withCallback($ -> updateCurrentLevel()); behaviours.add(filtering); InterfaceProvider towardBlockFacing = InterfaceProvider.towardBlockFacing(); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/observer/TrackObserverBlockEntity.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/observer/TrackObserverBlockEntity.java index 814eb6add..431720763 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/observer/TrackObserverBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/observer/TrackObserverBlockEntity.java @@ -15,6 +15,7 @@ import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.utility.Lang; import net.minecraft.core.BlockPos; import net.minecraft.world.item.ItemStack; @@ -37,6 +38,7 @@ public class TrackObserverBlockEntity extends SmartBlockEntity implements ITrans public void addBehaviours(List behaviours) { behaviours.add(edgePoint = new TrackTargetingBehaviour<>(this, EdgePointType.OBSERVER)); behaviours.add(filtering = createFilter().withCallback(this::onFilterChanged)); + filtering.setLabel(Lang.translateDirect("logistics.train_observer.cargo_filter")); } private void onFilterChanged(ItemStack newFilter) { @@ -102,13 +104,9 @@ public class TrackObserverBlockEntity extends SmartBlockEntity implements ITrans @Override protected Vec3 getLocalOffset(BlockState state) { - return new Vec3(0.5, 15 / 16d, 0.5); + return new Vec3(0.5, 15.5 / 16d, 0.5); } - protected float getScale() { - return super.getScale() * 1.5f; - }; - }); } diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index f8d9ec75c..b2d313f12 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -112,7 +112,6 @@ public class ClientEvents { SoundScapes.tick(); AnimationTickHolder.tick(); - ScrollValueHandler.tick(); CreateClient.SCHEMATIC_SENDER.tick(); CreateClient.SCHEMATIC_AND_QUILL_HANDLER.tick(); @@ -160,6 +159,8 @@ public class ClientEvents { CameraDistanceModifier.tick(); CameraAngleAnimationService.tick(); TrainHUD.tick(); + CreateClient.VALUE_SETTINGS_HANDLER.tick(); + ScrollValueHandler.tick(); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/events/InputEvents.java b/src/main/java/com/simibubi/create/events/InputEvents.java index 81264ebd3..48f82ccb5 100644 --- a/src/main/java/com/simibubi/create/events/InputEvents.java +++ b/src/main/java/com/simibubi/create/events/InputEvents.java @@ -7,8 +7,6 @@ import com.simibubi.create.content.curiosities.toolbox.ToolboxHandlerClient; import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler; import com.simibubi.create.content.logistics.trains.entity.TrainRelocator; import com.simibubi.create.content.logistics.trains.track.CurvedTrackInteraction; -import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringHandler; -import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueHandler; import net.minecraft.client.KeyMapping; import net.minecraft.client.Minecraft; @@ -43,8 +41,7 @@ public class InputEvents { double delta = event.getScrollDelta(); // CollisionDebugger.onScroll(delta); boolean cancelled = CreateClient.SCHEMATIC_HANDLER.mouseScrolled(delta) - || CreateClient.SCHEMATIC_AND_QUILL_HANDLER.mouseScrolled(delta) || FilteringHandler.onScroll(delta) - || ScrollValueHandler.onScroll(delta) || TrainHUD.onScroll(delta) + || CreateClient.SCHEMATIC_AND_QUILL_HANDLER.mouseScrolled(delta) || TrainHUD.onScroll(delta) || ElevatorControlsHandler.onScroll(delta); event.setCanceled(cancelled); } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/SmartBlockEntity.java b/src/main/java/com/simibubi/create/foundation/blockEntity/SmartBlockEntity.java index 69d640d9f..b3924e081 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/SmartBlockEntity.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/SmartBlockEntity.java @@ -1,6 +1,7 @@ package com.simibubi.create.foundation.blockEntity; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -26,7 +27,8 @@ import net.minecraftforge.common.capabilities.Capability; import net.minecraftforge.fluids.capability.CapabilityFluidHandler; import net.minecraftforge.items.CapabilityItemHandler; -public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity implements IPartialSafeNBT, IInteractionChecker, ISpecialBlockEntityItemRequirement { +public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity + implements IPartialSafeNBT, IInteractionChecker, ISpecialBlockEntityItemRequirement { private final Map, BlockEntityBehaviour> behaviours = new HashMap<>(); private boolean initialized = false; @@ -51,8 +53,8 @@ public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity impleme public abstract void addBehaviours(List behaviours); /** - * Gets called just before reading block entity data for behaviours. Register anything - * here that depends on your custom BE data. + * Gets called just before reading block entity data for behaviours. Register + * anything here that depends on your custom BE data. */ public void addBehavioursDeferred(List behaviours) {} @@ -173,9 +175,12 @@ public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity impleme return (T) behaviours.get(type); } - protected void forEachBehaviour(Consumer action) { - behaviours.values() - .forEach(action); + public void forEachBehaviour(Consumer action) { + getAllBehaviours().forEach(action); + } + + public Collection getAllBehaviours() { + return behaviours.values(); } protected void attachBehaviourLate(BlockEntityBehaviour behaviour) { @@ -184,8 +189,7 @@ public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity impleme } public ItemRequirement getRequiredItems(BlockState state) { - return behaviours.values() - .stream() + return getAllBehaviours().stream() .reduce(ItemRequirement.NONE, (r, b) -> r.union(b.getRequiredItems()), (r, r1) -> r.union(r1)); } @@ -208,7 +212,7 @@ public abstract class SmartBlockEntity extends CachedRenderBBBlockEntity impleme public boolean isVirtual() { return virtualMode; } - + public boolean isChunkUnloaded() { return chunkUnloaded; } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/CenteredSideValueBoxTransform.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/CenteredSideValueBoxTransform.java index c8844a252..6ecd7615e 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/CenteredSideValueBoxTransform.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/CenteredSideValueBoxTransform.java @@ -22,7 +22,7 @@ public class CenteredSideValueBoxTransform extends ValueBoxTransform.Sided { @Override protected Vec3 getSouthLocation() { - return VecHelper.voxelSpace(8, 8, 16); + return VecHelper.voxelSpace(8, 8, 15.5); } @Override diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBox.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBox.java index 18cbfc60c..dd1a214ec 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBox.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBox.java @@ -6,21 +6,22 @@ import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform.Si import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.INamedIconOptions; import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.render.SuperRenderTypeBuffer; -import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Components; -import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.outliner.ChasingAABBOutline; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.Font; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.client.model.ItemMultiLayerBakedModel; public class ValueBox extends ChasingAABBOutline { @@ -37,10 +38,12 @@ public class ValueBox extends ChasingAABBOutline { protected ValueBoxTransform transform; protected BlockState blockState; + protected AllIcons outline = AllIcons.VALUE_BOX_HOVER_4PX; + public ValueBox(Component label, AABB bb, BlockPos pos) { this(label, bb, pos, Minecraft.getInstance().level.getBlockState(pos)); } - + public ValueBox(Component label, AABB bb, BlockPos pos, BlockState state) { super(bb); this.label = label; @@ -53,24 +56,8 @@ public class ValueBox extends ChasingAABBOutline { return this; } - public ValueBox offsetLabel(Vec3 offset) { - this.labelOffset = offset; - return this; - } - - public ValueBox subLabel(Component sublabel) { - this.sublabel = sublabel; - return this; - } - - public ValueBox scrollTooltip(Component scrollTip) { - this.scrollTooltip = scrollTip; - return this; - } - - public ValueBox withColors(int passive, int highlight) { - this.passiveColor = passive; - this.highlightColor = highlight; + public ValueBox wideOutline() { + this.outline = AllIcons.VALUE_BOX_HOVER_6PX; return this; } @@ -94,69 +81,82 @@ public class ValueBox extends ChasingAABBOutline { transformNormals = ms.last() .normal() .copy(); - params.colored(isPassive ? passiveColor : highlightColor); - super.render(ms, buffer, pt); - - float fontScale = hasTransform ? -transform.getFontScale() : -1 / 64f; - ms.scale(fontScale, fontScale, fontScale); - - ms.pushPose(); - renderContents(ms, buffer); - ms.popPose(); if (!isPassive) { ms.pushPose(); - ms.translate(17.5, -.5, 7); - ms.translate(labelOffset.x, labelOffset.y, labelOffset.z); - - renderHoveringText(ms, buffer, label); - if (!sublabel.getString().isEmpty()) { - ms.translate(0, 10, 0); - renderHoveringText(ms, buffer, sublabel); - } - if (!scrollTooltip.getString().isEmpty()) { - ms.translate(0, 10, 0); - renderHoveringText(ms, buffer, scrollTooltip, 0x998899, 0x111111); - } - + ms.scale(-2.01f, -2.01f, 2.01f); + ms.translate(-8 / 16.0, -8 / 16.0, -.5 / 16.0); + getOutline().render(ms, buffer, 0xffffff); ms.popPose(); } + float fontScale = hasTransform ? -transform.getFontScale() : -1 / 64f; + ms.scale(fontScale, fontScale, fontScale); + renderContents(ms, buffer); + ms.popPose(); } + public AllIcons getOutline() { + return outline; + } + public void renderContents(PoseStack ms, MultiBufferSource buffer) {} public static class ItemValueBox extends ValueBox { ItemStack stack; int count; + boolean upTo; - public ItemValueBox(Component label, AABB bb, BlockPos pos, ItemStack stack, int count) { + public ItemValueBox(Component label, AABB bb, BlockPos pos, ItemStack stack, int count, boolean upTo) { super(label, bb, pos); this.stack = stack; this.count = count; + this.upTo = upTo; + } + + @Override + public AllIcons getOutline() { + if (stack.getItem() instanceof FilterItem) + return AllIcons.VALUE_BOX_HOVER_8PX; + if (!stack.isEmpty()) + return AllIcons.VALUE_BOX_HOVER_6PX; + return super.getOutline(); } @Override public void renderContents(PoseStack ms, MultiBufferSource buffer) { super.renderContents(ms, buffer); + if (count == -1) + return; + Font font = Minecraft.getInstance().font; - Component countString = Components.literal(count == 0 ? "*" : count + ""); + boolean wildcard = count == 0 || upTo && count == stack.getMaxStackSize(); + Component countString = Components.literal(wildcard ? "*" : count + ""); ms.translate(17.5f, -5f, 7f); boolean isFilter = stack.getItem() instanceof FilterItem; boolean isEmpty = stack.isEmpty(); + + ItemRenderer itemRenderer = Minecraft.getInstance() + .getItemRenderer(); + BakedModel modelWithOverrides = itemRenderer.getModel(stack, null, null, 0); + boolean blockItem = + modelWithOverrides.isGui3d() && !(modelWithOverrides instanceof ItemMultiLayerBakedModel); + float scale = 1.5f; ms.translate(-font.width(countString), 0, 0); if (isFilter) - ms.translate(3, 8, 7.25f); + ms.translate(-5, 8, 7.25f); else if (isEmpty) { - ms.translate(-17, -2, 3f); - scale = 2f; - } - else - ms.translate(-7, 10, 10 + 1 / 4f); + ms.translate(-15, -1f, -2.75f); + scale = 1.65f; + } else + ms.translate(-7, 10, blockItem ? 10 + 1 / 4f : 0); + + if (wildcard) + ms.translate(-1, 3f, 0); ms.scale(scale, scale, scale); drawString(ms, buffer, countString, 0, 0, isFilter ? 0xFFFFFF : 0xEDEDED); @@ -173,7 +173,7 @@ public class ValueBox extends ChasingAABBOutline { super(label, bb, pos); this.text = text; } - + public TextValueBox(Component label, AABB bb, BlockPos pos, BlockState state, Component text) { super(label, bb, pos, state); this.text = text; @@ -183,7 +183,7 @@ public class ValueBox extends ChasingAABBOutline { public void renderContents(PoseStack ms, MultiBufferSource buffer) { super.renderContents(ms, buffer); Font font = Minecraft.getInstance().font; - float scale = 4; + float scale = 3; ms.scale(scale, scale, 1); ms.translate(-4, -4, 5); @@ -207,27 +207,20 @@ public class ValueBox extends ChasingAABBOutline { public IconValueBox(Component label, INamedIconOptions iconValue, AABB bb, BlockPos pos) { super(label, bb, pos); - subLabel(Lang.translateDirect(iconValue.getTranslationKey())); icon = iconValue.getIcon(); } @Override public void renderContents(PoseStack ms, MultiBufferSource buffer) { super.renderContents(ms, buffer); - float scale = 4 * 16; + float scale = 2 * 16; ms.scale(scale, scale, scale); - ms.translate(-.5f, -.5f, 1 / 32f); + ms.translate(-.5f, -.5f, 5 / 32f); icon.render(ms, buffer, 0xFFFFFF); } } - // util - - protected void renderHoveringText(PoseStack ms, MultiBufferSource buffer, Component text) { - renderHoveringText(ms, buffer, text, highlightColor, Color.mixColors(passiveColor, 0, 0.75f)); - } - protected void renderHoveringText(PoseStack ms, MultiBufferSource buffer, Component text, int color, int shadowColor) { ms.pushPose(); @@ -237,7 +230,8 @@ public class ValueBox extends ChasingAABBOutline { ms.popPose(); } - private static void drawString(PoseStack ms, MultiBufferSource buffer, Component text, float x, float y, int color) { + private static void drawString(PoseStack ms, MultiBufferSource buffer, Component text, float x, float y, + int color) { Minecraft.getInstance().font.drawInBatch(text, x, y, color, false, ms.last() .pose(), buffer, false, 0, LightTexture.FULL_BRIGHT); } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxRenderer.java index 0428b6e74..2e8df84f1 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxRenderer.java @@ -30,8 +30,8 @@ public class ValueBoxRenderer { .getItemRenderer(); BakedModel modelWithOverrides = itemRenderer.getModel(filter, null, null, 0); boolean blockItem = modelWithOverrides.isGui3d() && !(modelWithOverrides instanceof ItemMultiLayerBakedModel); - float scale = (!blockItem ? .5f : 1f) - 1 / 64f; - float zOffset = (!blockItem ? -.225f : 0) + customZOffset(filter.getItem()); + float scale = (!blockItem ? .5f : 1f) + 1 / 64f; + float zOffset = (!blockItem ? -.15f : 0) + customZOffset(filter.getItem()); ms.scale(scale, scale, scale); ms.translate(0, 0, zOffset); itemRenderer.renderStatic(filter, TransformType.FIXED, light, overlay, ms, buffer, 0); diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxTransform.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxTransform.java index 661e6882a..e3495d993 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxTransform.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueBoxTransform.java @@ -54,7 +54,7 @@ public abstract class ValueBoxTransform { } protected float getScale() { - return .4f; + return .5f; } protected float getFontScale() { diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsBehaviour.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsBehaviour.java new file mode 100644 index 000000000..d439be861 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsBehaviour.java @@ -0,0 +1,57 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.core.Direction; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; + +public interface ValueSettingsBehaviour { + + public static record ValueSettings(int row, int value) { + + public MutableComponent format() { + return Lang.number(value) + .component(); + } + + }; + + public boolean testHit(Vec3 hit); + + public boolean isActive(); + + default boolean onlyVisibleWithWrench() { + return false; + } + + default void newSettingHovered(ValueSettings valueSetting) {} + + public ValueBoxTransform getSlotPositioning(); + + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult); + + public void setValueSettings(Player player, ValueSettings valueSetting, boolean ctrlDown); + + public ValueSettings getValueSettings(); + + default boolean acceptsValueSettings() { + return true; + } + + default void playFeedbackSound(BlockEntityBehaviour origin) { + origin.getWorld() + .playSound(null, origin.getPos(), SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, 0.25f, 2f); + origin.getWorld() + .playSound(null, origin.getPos(), SoundEvents.NOTE_BLOCK_IRON_XYLOPHONE, SoundSource.BLOCKS, 0.03f, 1.125f); + } + + default void onShortInteract(Player player, InteractionHand hand, Direction side) {} + +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsBoard.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsBoard.java new file mode 100644 index 000000000..625e64e22 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsBoard.java @@ -0,0 +1,9 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import java.util.List; + +import net.minecraft.network.chat.Component; + +public record ValueSettingsBoard(Component title, int maxValue, int milestoneInterval, List rows, + ValueSettingsFormatter formatter) { +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsClient.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsClient.java new file mode 100644 index 000000000..1ce7d9f72 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsClient.java @@ -0,0 +1,143 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import java.util.List; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; +import com.simibubi.create.foundation.gui.ScreenOpener; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.Color; + +import net.minecraft.client.Minecraft; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraftforge.client.gui.ForgeIngameGui; +import net.minecraftforge.client.gui.IIngameOverlay; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; + +public class ValueSettingsClient implements IIngameOverlay { + + private Minecraft mc; + + public int interactHeldTicks = -1; + public BlockPos interactHeldPos = null; + public BehaviourType interactHeldBehaviour = null; + public InteractionHand interactHeldHand = null; + public Direction interactHeldFace = null; + + public List lastHoverTip; + public int hoverTicks; + public int hoverWarmup; + + public ValueSettingsClient() { + mc = Minecraft.getInstance(); + } + + public void cancelIfWarmupAlreadyStarted(PlayerInteractEvent.RightClickBlock event) { + if (interactHeldTicks != -1 && event.getPos() + .equals(interactHeldPos)) { + event.setCanceled(true); + event.setCancellationResult(InteractionResult.FAIL); + } + } + + public void startInteractionWith(BlockPos pos, BehaviourType behaviourType, InteractionHand hand, + Direction side) { + interactHeldTicks = 0; + interactHeldPos = pos; + interactHeldBehaviour = behaviourType; + interactHeldHand = hand; + interactHeldFace = side; + } + + public void cancelInteraction() { + interactHeldTicks = -1; + } + + public void tick() { + if (hoverWarmup > 0) + hoverWarmup--; + if (hoverTicks > 0) + hoverTicks--; + if (interactHeldTicks == -1) + return; + Player player = mc.player; + + if (!ValueSettingsInputHandler.canInteract(player)) { + cancelInteraction(); + return; + } + HitResult hitResult = mc.hitResult; + if (!(hitResult instanceof BlockHitResult blockHitResult) || !blockHitResult.getBlockPos() + .equals(interactHeldPos)) { + cancelInteraction(); + return; + } + BlockEntityBehaviour behaviour = BlockEntityBehaviour.get(mc.level, interactHeldPos, interactHeldBehaviour); + if (!(behaviour instanceof ValueSettingsBehaviour valueSettingBehaviour) + || !valueSettingBehaviour.testHit(blockHitResult.getLocation())) { + cancelInteraction(); + return; + } + if (!mc.options.keyUse.isDown()) { + AllPackets.getChannel() + .sendToServer( + new ValueSettingsPacket(interactHeldPos, 0, 0, interactHeldHand, interactHeldFace, false)); + cancelInteraction(); + return; + } + + if (interactHeldTicks > 3) + player.swinging = false; + if (interactHeldTicks++ < 5) + return; + ScreenOpener + .open(new ValueSettingsScreen(interactHeldPos, valueSettingBehaviour.createBoard(player, blockHitResult), + valueSettingBehaviour.getValueSettings(), valueSettingBehaviour::newSettingHovered)); + interactHeldTicks = -1; + } + + public void showHoverTip(List tip) { + if (mc.screen != null) + return; + if (hoverWarmup < 6) { + hoverWarmup += 2; + return; + } else + hoverWarmup++; + hoverTicks = hoverTicks == 0 ? 11 : Math.max(hoverTicks, 6); + lastHoverTip = tip; + } + + @Override + public void render(ForgeIngameGui gui, PoseStack poseStack, float partialTicks, int width, int height) { + Minecraft mc = Minecraft.getInstance(); + if (mc.options.hideGui || !ValueSettingsInputHandler.canInteract(mc.player)) + return; + if (hoverTicks == 0 || lastHoverTip == null) + return; + + int x = width / 2; + int y = height - 93; + float alpha = hoverTicks > 5 ? (11 - hoverTicks) / 5f : Math.min(1, hoverTicks / 5f); + + Color color = new Color(0xffffff); + Color titleColor = new Color(0xFBDC7D); + color.setAlpha(alpha); + titleColor.setAlpha(alpha); + + for (int i = 0; i < lastHoverTip.size(); i++) { + MutableComponent mutableComponent = lastHoverTip.get(i); + mc.font.drawShadow(poseStack, mutableComponent, x - mc.font.width(mutableComponent) / 2, y, + (i == 0 ? titleColor : color).getRGB()); + y += 12; + } + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsFormatter.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsFormatter.java new file mode 100644 index 000000000..d62cac2bf --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsFormatter.java @@ -0,0 +1,39 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import java.util.function.Function; + +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBehaviour.ValueSettings; +import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.INamedIconOptions; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.network.chat.MutableComponent; + +public class ValueSettingsFormatter { + + private Function formatter; + + public ValueSettingsFormatter(Function formatter) { + this.formatter = formatter; + } + + public MutableComponent format(ValueSettings valueSettings) { + return formatter.apply(valueSettings); + } + + public static class ScrollOptionSettingsFormatter extends ValueSettingsFormatter { + + private INamedIconOptions[] options; + + public ScrollOptionSettingsFormatter(INamedIconOptions[] options) { + super(v -> Lang.translateDirect(options[v.value()].getTranslationKey())); + this.options = options; + } + + public AllIcons getIcon(ValueSettings valueSettings) { + return options[valueSettings.value()].getIcon(); + } + + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsInputHandler.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsInputHandler.java new file mode 100644 index 000000000..cc69d88bb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsInputHandler.java @@ -0,0 +1,90 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import com.simibubi.create.AllTags.AllItemTags; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.filtering.SidedFilteringBehaviour; +import com.simibubi.create.foundation.utility.RaycastHelper; + +import net.minecraft.core.BlockPos; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber +public class ValueSettingsInputHandler { + + @SubscribeEvent + public static void onBlockActivated(PlayerInteractEvent.RightClickBlock event) { + Level world = event.getWorld(); + BlockPos pos = event.getPos(); + Player player = event.getPlayer(); + InteractionHand hand = event.getHand(); + + if (!canInteract(player)) + return; + if (!(world.getBlockEntity(pos)instanceof SmartBlockEntity sbe)) + return; + + if (event.getSide() == LogicalSide.CLIENT) + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, + () -> () -> CreateClient.VALUE_SETTINGS_HANDLER.cancelIfWarmupAlreadyStarted(event)); + + if (event.isCanceled()) + return; + + for (BlockEntityBehaviour behaviour : sbe.getAllBehaviours()) { + if (!(behaviour instanceof ValueSettingsBehaviour valueSettingsBehaviour)) + continue; + + BlockHitResult ray = RaycastHelper.rayTraceRange(world, player, 10); + if (ray == null) + return; + if (behaviour instanceof SidedFilteringBehaviour) { + behaviour = ((SidedFilteringBehaviour) behaviour).get(ray.getDirection()); + if (behaviour == null) + continue; + } + + if (!valueSettingsBehaviour.isActive()) + continue; + if (valueSettingsBehaviour.onlyVisibleWithWrench() + && !AllItemTags.WRENCH.matches(player.getItemInHand(hand))) + continue; + if (valueSettingsBehaviour.getSlotPositioning()instanceof ValueBoxTransform.Sided sidedSlot) + sidedSlot.fromSide(ray.getDirection()); + if (!valueSettingsBehaviour.testHit(ray.getLocation())) + continue; + + event.setCanceled(true); + event.setCancellationResult(InteractionResult.SUCCESS); + + if (!valueSettingsBehaviour.acceptsValueSettings()) { + valueSettingsBehaviour.onShortInteract(player, hand, ray.getDirection()); + return; + } + + if (event.getSide() == LogicalSide.CLIENT) { + BehaviourType type = behaviour.getType(); + DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.VALUE_SETTINGS_HANDLER + .startInteractionWith(pos, type, hand, ray.getDirection())); + } + + return; + } + } + + public static boolean canInteract(Player player) { + return player != null && !player.isSpectator() && !player.isShiftKeyDown(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsPacket.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsPacket.java new file mode 100644 index 000000000..8a4a4720d --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsPacket.java @@ -0,0 +1,78 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import javax.annotation.Nullable; + +import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; +import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBehaviour.ValueSettings; +import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.InteractionHand; + +public class ValueSettingsPacket extends BlockEntityConfigurationPacket { + + private int row; + private int value; + private InteractionHand interactHand; + private Direction side; + private boolean ctrlDown; + + public ValueSettingsPacket(BlockPos pos, int row, int value, @Nullable InteractionHand interactHand, Direction side, + boolean ctrlDown) { + super(pos); + this.row = row; + this.value = value; + this.interactHand = interactHand; + this.side = side; + this.ctrlDown = ctrlDown; + } + + public ValueSettingsPacket(FriendlyByteBuf buffer) { + super(buffer); + } + + @Override + protected void writeSettings(FriendlyByteBuf buffer) { + buffer.writeVarInt(value); + buffer.writeVarInt(row); + buffer.writeBoolean(interactHand != null); + if (interactHand != null) + buffer.writeBoolean(interactHand == InteractionHand.MAIN_HAND); + buffer.writeVarInt(side.ordinal()); + buffer.writeBoolean(ctrlDown); + } + + @Override + protected void readSettings(FriendlyByteBuf buffer) { + value = buffer.readVarInt(); + row = buffer.readVarInt(); + if (buffer.readBoolean()) + interactHand = buffer.readBoolean() ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND; + side = Direction.values()[buffer.readVarInt()]; + ctrlDown = buffer.readBoolean(); + } + + @Override + protected void applySettings(ServerPlayer player, SmartBlockEntity be) { + for (BlockEntityBehaviour behaviour : be.getAllBehaviours()) { + if (!(behaviour instanceof ValueSettingsBehaviour valueSettingsBehaviour)) + continue; + if (!valueSettingsBehaviour.acceptsValueSettings()) + continue; + if (interactHand != null) { + valueSettingsBehaviour.onShortInteract(player, interactHand, side); + return; + } + valueSettingsBehaviour.setValueSettings(player, new ValueSettings(row, value), ctrlDown); + return; + } + } + + @Override + protected void applySettings(SmartBlockEntity be) {} + +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsScreen.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsScreen.java new file mode 100644 index 000000000..cb7c76a70 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/ValueSettingsScreen.java @@ -0,0 +1,315 @@ +package com.simibubi.create.foundation.blockEntity.behaviour; + +import java.util.function.Consumer; + +import org.lwjgl.glfw.GLFW; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllKeys; +import com.simibubi.create.AllSoundEvents; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBehaviour.ValueSettings; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter.ScrollOptionSettingsFormatter; +import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueHandler; +import com.simibubi.create.foundation.gui.AbstractSimiScreen; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.UIRenderHelper; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Lang; + +import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec2; + +public class ValueSettingsScreen extends AbstractSimiScreen { + + private int ticksOpen; + private ValueSettingsBoard board; + private int maxLabelWidth; + private int valueBarWidth; + private BlockPos pos; + private ValueSettings initialSettings; + private ValueSettings lastHovered = new ValueSettings(-1, -1); + private Consumer onHover; + private boolean iconMode; + private int milestoneSize; + private int soundCoolDown; + + public ValueSettingsScreen(BlockPos pos, ValueSettingsBoard board, ValueSettings valueSettings, + Consumer onHover) { + this.pos = pos; + this.board = board; + this.initialSettings = valueSettings; + this.onHover = onHover; + this.iconMode = board.formatter() instanceof ScrollOptionSettingsFormatter; + this.milestoneSize = iconMode ? 8 : 4; + } + + @Override + protected void init() { + int maxValue = board.maxValue(); + maxLabelWidth = 0; + int milestoneCount = maxValue / board.milestoneInterval() + 1; + int scale = maxValue > 128 ? 1 : 2; + + for (Component component : board.rows()) + maxLabelWidth = Math.max(maxLabelWidth, font.width(component)); + if (iconMode) + maxLabelWidth = -18; + + valueBarWidth = (maxValue + 1) * scale + 1 + milestoneCount * milestoneSize; + int width = (maxLabelWidth + 14) + (valueBarWidth + 10); + int height = (board.rows() + .size() * 11); + + setWindowSize(width, height); + super.init(); + + Vec2 coordinateOfValue = getCoordinateOfValue(initialSettings.row(), initialSettings.value()); + setCursor(coordinateOfValue); + } + + private void setCursor(Vec2 coordinateOfValue) { + double guiScale = minecraft.getWindow() + .getGuiScale(); + GLFW.glfwSetCursorPos(minecraft.getWindow() + .getWindow(), coordinateOfValue.x * guiScale, coordinateOfValue.y * guiScale); + } + + public ValueSettings getClosestCoordinate(int mouseX, int mouseY) { + int row = 0; + int column = 0; + boolean milestonesOnly = hasShiftDown(); + + double bestDiff = Double.MAX_VALUE; + for (; row < board.rows() + .size(); row++) { + Vec2 coord = getCoordinateOfValue(row, 0); + double diff = Math.abs(coord.y - mouseY); + if (bestDiff < diff) + break; + bestDiff = diff; + } + row -= 1; + + bestDiff = Double.MAX_VALUE; + for (; column <= board.maxValue(); column++) { + Vec2 coord = getCoordinateOfValue(row, milestonesOnly ? column * board.milestoneInterval() : column); + double diff = Math.abs(coord.x - mouseX); + if (bestDiff < diff) + break; + bestDiff = diff; + } + column -= 1; + + return new ValueSettings(row, + milestonesOnly ? Math.min(column * board.milestoneInterval(), board.maxValue()) : column); + } + + public Vec2 getCoordinateOfValue(int row, int column) { + int scale = board.maxValue() > 128 ? 1 : 2; + float xOut = + guiLeft + ((Math.max(1, column) - 1) / board.milestoneInterval()) * milestoneSize + column * scale + 1.5f; + xOut += maxLabelWidth + 14 + 4; + + if (column % board.milestoneInterval() == 0) + xOut += milestoneSize / 2; + if (column > 0) + xOut += milestoneSize; + + float yOut = guiTop + (row + .5f) * 11 - .5f; + return new Vec2(xOut, yOut); + } + + @Override + protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) { + int x = guiLeft; + int y = guiTop; + int milestoneCount = board.maxValue() / board.milestoneInterval() + 1; + int blitOffset = getBlitOffset(); + int scale = board.maxValue() > 128 ? 1 : 2; + + Component title = board.title(); + Component tip = Lang.translateDirect("gui.value_settings.release_to_confirm", Components.keybind("key.use")); + double fadeIn = Math.pow(Mth.clamp((ticksOpen + partialTicks) / 4.0, 0, 1), 1); + + int fattestLabel = Math.max(font.width(tip), font.width(title)); + if (iconMode) + for (int i = 0; i <= board.maxValue(); i++) + fattestLabel = Math.max(fattestLabel, font.width(board.formatter() + .format(new ValueSettings(0, i)))); + + int fatTipOffset = Math.max(0, fattestLabel + 10 - (windowWidth + 13)) / 2; + int bgWidth = Math.max((windowWidth + 13), fattestLabel + 10); + int fadeInWidth = (int) (bgWidth * fadeIn); + int fadeInStart = (bgWidth - fadeInWidth) / 2 - fatTipOffset; + int additionalHeight = iconMode ? 46 : 33; + + UIRenderHelper.drawStretched(ms, x - 11 + fadeInStart, y - 17, fadeInWidth, windowHeight + additionalHeight, + blitOffset, AllGuiTextures.VALUE_SETTINGS_OUTER_BG); + UIRenderHelper.drawStretched(ms, x - 10 + fadeInStart, y - 18, fadeInWidth - 2, 1, blitOffset, + AllGuiTextures.VALUE_SETTINGS_OUTER_BG); + UIRenderHelper.drawStretched(ms, x - 10 + fadeInStart, y - 17 + windowHeight + additionalHeight, + fadeInWidth - 2, 1, blitOffset, AllGuiTextures.VALUE_SETTINGS_OUTER_BG); + + if (fadeInWidth > fattestLabel) { + int textX = x - 11 - fatTipOffset + bgWidth / 2; + font.draw(ms, title, textX - font.width(title) / 2, y - 14, 0xdddddd); + font.draw(ms, tip, textX - font.width(tip) / 2, y + windowHeight + additionalHeight - 27, 0xdddddd); + } + + renderBrassFrame(ms, x + maxLabelWidth + 14, y - 3, valueBarWidth + 8, board.rows() + .size() * 11 + 5); + UIRenderHelper.drawStretched(ms, x + maxLabelWidth + 17, y, valueBarWidth + 2, board.rows() + .size() * 11 - 1, blitOffset, AllGuiTextures.VALUE_SETTINGS_BAR_BG); + + int originalY = y; + for (Component component : board.rows()) { + int valueBarX = x + maxLabelWidth + 14 + 4; + + if (!iconMode) { + UIRenderHelper.drawCropped(ms, x - 4, y, maxLabelWidth + 8, 11, blitOffset, + AllGuiTextures.VALUE_SETTINGS_LABEL_BG); + for (int w = 0; w < valueBarWidth; w += AllGuiTextures.VALUE_SETTINGS_BAR.width - 1) + UIRenderHelper.drawCropped(ms, valueBarX + w, y + 1, + Math.min(AllGuiTextures.VALUE_SETTINGS_BAR.width - 1, valueBarWidth - w), 8, blitOffset, + AllGuiTextures.VALUE_SETTINGS_BAR); + font.draw(ms, component, x, y + 1, 0x442000); + } + + int milestoneX = valueBarX; + for (int milestone = 0; milestone < milestoneCount; milestone++) { + if (iconMode) + AllGuiTextures.VALUE_SETTINGS_WIDE_MILESTONE.render(ms, milestoneX, y + 1); + else + AllGuiTextures.VALUE_SETTINGS_MILESTONE.render(ms, milestoneX, y + 1); + milestoneX += milestoneSize + board.milestoneInterval() * scale; + } + + y += 11; + } + + if (!iconMode) + renderBrassFrame(ms, x - 7, originalY - 3, maxLabelWidth + 14, board.rows() + .size() * 11 + 5); + + if (ticksOpen < 1) + return; + + ValueSettings closest = getClosestCoordinate(mouseX, mouseY); + + if (!closest.equals(lastHovered)) { + onHover.accept(closest); + if (soundCoolDown == 0) { + float pitch = (closest.value()) / (float) (board.maxValue()); + pitch = Mth.lerp(pitch, 1.15f, 1.5f); + minecraft.getSoundManager() + .play(SimpleSoundInstance.forUI(AllSoundEvents.SCROLL_VALUE.getMainEvent(), pitch, 0.25F)); + ScrollValueHandler.wrenchCog.bump(3, -(closest.value() - lastHovered.value()) * 10); + soundCoolDown = 1; + } + } + lastHovered = closest; + + Vec2 coordinate = getCoordinateOfValue(closest.row(), closest.value()); + Component cursorText = board.formatter() + .format(closest); + + AllIcons cursorIcon = null; + if (board.formatter()instanceof ScrollOptionSettingsFormatter sosf) + cursorIcon = sosf.getIcon(closest); + + int cursorWidth = ((cursorIcon != null ? 16 : font.width(cursorText)) / 2) * 2 + 3; + int cursorX = ((int) (coordinate.x)) - cursorWidth / 2; + int cursorY = ((int) (coordinate.y)) - 7; + + if (cursorIcon != null) { + AllGuiTextures.VALUE_SETTINGS_CURSOR_ICON.render(ms, cursorX - 2, cursorY - 3); + RenderSystem.setShaderColor(0.265625f, 0.125f, 0, 1); + cursorIcon.render(ms, cursorX + 1, cursorY - 1); + RenderSystem.setShaderColor(1, 1, 1, 1); + if (fadeInWidth > fattestLabel) + font.draw(ms, cursorText, x - 11 - fatTipOffset + (bgWidth - font.width(cursorText)) / 2, + originalY + windowHeight + additionalHeight - 40, 0xFBDC7D); + return; + } + + AllGuiTextures.VALUE_SETTINGS_CURSOR_LEFT.render(ms, cursorX - 3, cursorY); + UIRenderHelper.drawCropped(ms, cursorX, cursorY, cursorWidth, 14, blitOffset, + AllGuiTextures.VALUE_SETTINGS_CURSOR); + AllGuiTextures.VALUE_SETTINGS_CURSOR_RIGHT.render(ms, cursorX + cursorWidth, cursorY); + + font.draw(ms, cursorText, cursorX + 2, cursorY + 3, 0x442000); + } + + protected void renderBrassFrame(PoseStack ms, int x, int y, int w, int h) { + AllGuiTextures.BRASS_FRAME_TL.render(ms, x, y); + AllGuiTextures.BRASS_FRAME_TR.render(ms, x + w - 4, y); + AllGuiTextures.BRASS_FRAME_BL.render(ms, x, y + h - 4); + AllGuiTextures.BRASS_FRAME_BR.render(ms, x + w - 4, y + h - 4); + + if (h > 8) { + UIRenderHelper.drawStretched(ms, x, y + 4, 3, h - 8, getBlitOffset(), AllGuiTextures.BRASS_FRAME_LEFT); + UIRenderHelper.drawStretched(ms, x + w - 3, y + 4, 3, h - 8, getBlitOffset(), + AllGuiTextures.BRASS_FRAME_RIGHT); + } + + if (w > 8) { + UIRenderHelper.drawCropped(ms, x + 4, y, w - 8, 3, getBlitOffset(), AllGuiTextures.BRASS_FRAME_TOP); + UIRenderHelper.drawCropped(ms, x + 4, y + h - 3, w - 8, 3, getBlitOffset(), + AllGuiTextures.BRASS_FRAME_BOTTOM); + } + + } + + @Override + public void renderBackground(PoseStack p_238651_1_, int p_238651_2_) { + int a = ((int) (0x50 * Math.min(1, (ticksOpen + AnimationTickHolder.getPartialTicks()) / 20f))) << 24; + fillGradient(p_238651_1_, 0, 0, this.width, this.height, 0x101010 | a, 0x101010 | a); + } + + @Override + public void tick() { + ticksOpen++; + if (soundCoolDown > 0) + soundCoolDown--; + super.tick(); + } + + @Override + public boolean mouseScrolled(double pMouseX, double pMouseY, double pDelta) { + ValueSettings closest = getClosestCoordinate((int) pMouseX, (int) pMouseY); + int column = closest.value() + ((int) Math.signum(pDelta)) * (hasShiftDown() ? board.milestoneInterval() : 1); + column = Mth.clamp(column, 0, board.maxValue()); + if (column == closest.value()) + return false; + setCursor(getCoordinateOfValue(closest.row(), column)); + return true; + } + + @Override + public boolean mouseReleased(double pMouseX, double pMouseY, int pButton) { + if (pButton == 1) { + ValueSettings closest = getClosestCoordinate((int) pMouseX, (int) pMouseY); + // FIXME: value settings may be face-sensitive on future components + AllPackets.getChannel() + .sendToServer(new ValueSettingsPacket(pos, closest.row(), closest.value(), null, Direction.UP, + AllKeys.ctrlDown())); + onClose(); + return true; + } + return super.mouseReleased(pMouseX, pMouseY, pButton); + } + + @Override + public void onClose() { + super.onClose(); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java index 935df664d..822e6b89d 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionHandler.java @@ -96,7 +96,7 @@ public class EdgeInteractionHandler { int x = vec.getX(); int y = vec.getY(); int z = vec.getZ(); - double margin = 12 / 16f; + double margin = 10 / 16f; double absX = Math.abs(x) * margin; double absY = Math.abs(y) * margin; double absZ = Math.abs(z) * margin; diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionRenderer.java index edc2fed7c..0705eaace 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/edgeInteraction/EdgeInteractionRenderer.java @@ -1,21 +1,26 @@ package com.simibubi.create.foundation.blockEntity.behaviour.edgeInteraction; +import java.util.ArrayList; import java.util.List; -import com.simibubi.create.AllSpecialTextures; +import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.CreateClient; +import com.simibubi.create.content.contraptions.components.crafter.CrafterHelper; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBox; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; -import net.minecraft.core.Direction.AxisDirection; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; @@ -52,8 +57,9 @@ public class EdgeInteractionRenderer { double bestDistance = Double.MAX_VALUE; Vec3 center = VecHelper.getCenterOf(pos); for (Direction direction : connectiveSides) { - double distance = Vec3.atLowerCornerOf(direction.getNormal()).subtract(target.getLocation() - .subtract(center)) + double distance = Vec3.atLowerCornerOf(direction.getNormal()) + .subtract(target.getLocation() + .subtract(center)) .length(); if (distance > bestDistance) continue; @@ -63,31 +69,51 @@ public class EdgeInteractionRenderer { AABB bb = EdgeInteractionHandler.getBB(pos, closestEdge); boolean hit = bb.contains(target.getLocation()); + Vec3 offset = Vec3.atLowerCornerOf(closestEdge.getNormal()) + .scale(.5) + .add(Vec3.atLowerCornerOf(face.getNormal()) + .scale(.469)) + .add(VecHelper.CENTER_OF_ORIGIN); - ValueBox box = new ValueBox(Components.immutableEmpty(), bb.move(-pos.getX(), -pos.getY(), -pos.getZ()), pos); - Vec3 textOffset = Vec3.ZERO; + ValueBox box = new ValueBox(Components.immutableEmpty(), bb, pos).passive(!hit) + .transform(new EdgeValueBoxTransform(offset)) + .wideOutline(); + CreateClient.OUTLINER.showValueBox("edge", box) + .highlightFace(face); - boolean positive = closestEdge.getAxisDirection() == AxisDirection.POSITIVE; - if (positive) { - if (face.getAxis() - .isHorizontal()) { - if (closestEdge.getAxis() - .isVertical()) - textOffset = textOffset.add(0, -128, 0); - else - textOffset = textOffset.add(-128, 0, 0); - } else - textOffset = textOffset.add(-128, 0, 0); + if (!hit) + return; + + List tip = new ArrayList<>(); + tip.add(Lang.translateDirect("logistics.crafter.connected")); + tip.add(Lang.translateDirect(CrafterHelper.areCraftersConnected(world, pos, pos.relative(closestEdge)) + ? "logistics.crafter.click_to_separate" + : "logistics.crafter.click_to_merge")); + CreateClient.VALUE_SETTINGS_HANDLER.showHoverTip(tip); + } + + static class EdgeValueBoxTransform extends ValueBoxTransform.Sided { + + private Vec3 add; + + public EdgeValueBoxTransform(Vec3 add) { + this.add = add; } - box.offsetLabel(textOffset) - .withColors(0x7A6A2C, 0xB79D64) - .passive(!hit); + @Override + protected Vec3 getSouthLocation() { + return Vec3.ZERO; + } - CreateClient.OUTLINER.showValueBox("edge", box) - .lineWidth(1 / 64f) - .withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null) - .highlightFace(face); + @Override + protected Vec3 getLocalOffset(BlockState state) { + return add; + } + + @Override + protected void rotate(BlockState state, PoseStack ms) { + super.rotate(state, ms); + } } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java index fdcb86f40..99a725438 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringBehaviour.java @@ -3,43 +3,55 @@ package com.simibubi.create.foundation.blockEntity.behaviour.filtering; import java.util.function.Consumer; import java.util.function.Supplier; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.AllItems; import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.content.schematics.ItemRequirement; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; -import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter; +import com.simibubi.create.foundation.utility.Components; +import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.VecHelper; +import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; +import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.items.ItemHandlerHelper; -public class FilteringBehaviour extends BlockEntityBehaviour { +public class FilteringBehaviour extends BlockEntityBehaviour implements ValueSettingsBehaviour { public static final BehaviourType TYPE = new BehaviourType<>(); + public MutableComponent customLabel; ValueBoxTransform slotPositioning; boolean showCount; - Vec3 textShift; private ItemStack filter; public int count; + public boolean upTo; + private Consumer callback; private Supplier isActive; private Supplier showCountPredicate; - int scrollableValue; - int ticksUntilScrollPacket; - boolean forceClientState; boolean recipeFilter; boolean fluidFilter; @@ -51,26 +63,23 @@ public class FilteringBehaviour extends BlockEntityBehaviour { callback = stack -> { }; isActive = () -> true; - textShift = Vec3.ZERO; - count = 0; - ticksUntilScrollPacket = -1; + count = 64; showCountPredicate = () -> showCount; recipeFilter = false; fluidFilter = false; + upTo = true; } @Override - public boolean isSafeNBT() { return true; } + public boolean isSafeNBT() { + return true; + } @Override public void write(CompoundTag nbt, boolean clientPacket) { nbt.put("Filter", getFilter().serializeNBT()); nbt.putInt("FilterAmount", count); - - if (clientPacket && forceClientState) { - nbt.putBoolean("ForceScrollable", true); - forceClientState = false; - } + nbt.putBoolean("UpTo", upTo); super.write(nbt, clientPacket); } @@ -78,30 +87,10 @@ public class FilteringBehaviour extends BlockEntityBehaviour { public void read(CompoundTag nbt, boolean clientPacket) { filter = ItemStack.of(nbt.getCompound("Filter")); count = nbt.getInt("FilterAmount"); - if (nbt.contains("ForceScrollable")) { - scrollableValue = count; - ticksUntilScrollPacket = -1; - } + upTo = nbt.getBoolean("UpTo"); super.read(nbt, clientPacket); } - @Override - public void tick() { - super.tick(); - - if (!getWorld().isClientSide) - return; - if (ticksUntilScrollPacket == -1) - return; - if (ticksUntilScrollPacket > 0) { - ticksUntilScrollPacket--; - return; - } - - AllPackets.getChannel().sendToServer(new FilteringCountUpdatePacket(getPos(), scrollableValue)); - ticksUntilScrollPacket = -1; - } - public FilteringBehaviour withCallback(Consumer filterCallback) { callback = filterCallback; return this; @@ -132,33 +121,38 @@ public class FilteringBehaviour extends BlockEntityBehaviour { return this; } - public FilteringBehaviour moveText(Vec3 shift) { - textShift = shift; - return this; - } - - @Override - public void initialize() { - super.initialize(); - scrollableValue = count; - } - public void setFilter(Direction face, ItemStack stack) { setFilter(stack); } + public void setLabel(MutableComponent label) { + this.customLabel = label; + } + public void setFilter(ItemStack stack) { - boolean confirm = ItemHandlerHelper.canItemStacksStack(stack, filter); filter = stack.copy(); callback.accept(filter); - count = !confirm ? 0 - : (filter.getItem() instanceof FilterItem) ? 0 : Math.min(stack.getCount(), stack.getMaxStackSize()); - forceClientState = true; - + count = Math.min(count, stack.getMaxStackSize()); blockEntity.setChanged(); blockEntity.sendData(); } + @Override + public void setValueSettings(Player player, ValueSettings settings, boolean ctrlDown) { + if (getValueSettings().equals(settings)) + return; + count = Mth.clamp(settings.value(), 1, filter.getMaxStackSize()); + upTo = settings.row() == 0; + blockEntity.setChanged(); + blockEntity.sendData(); + playFeedbackSound(this); + } + + @Override + public ValueSettings getValueSettings() { + return new ValueSettings(upTo ? 0 : 1, count == 0 ? filter.getMaxStackSize() : count); + } + @Override public void destroy() { if (filter.getItem() instanceof FilterItem) { @@ -166,7 +160,6 @@ public class FilteringBehaviour extends BlockEntityBehaviour { Level world = getWorld(); world.addFreshEntity(new ItemEntity(world, pos.x, pos.y, pos.z, filter.copy())); } - super.destroy(); } @@ -188,7 +181,7 @@ public class FilteringBehaviour extends BlockEntityBehaviour { } public boolean isCountVisible() { - return showCountPredicate.get(); + return showCountPredicate.get() && filter.getMaxStackSize() > 1; } public boolean test(ItemStack stack) { @@ -204,6 +197,7 @@ public class FilteringBehaviour extends BlockEntityBehaviour { return TYPE; } + @Override public boolean testHit(Vec3 hit) { BlockState state = blockEntity.getBlockState(); Vec3 localHit = hit.subtract(Vec3.atLowerCornerOf(blockEntity.getBlockPos())); @@ -218,8 +212,74 @@ public class FilteringBehaviour extends BlockEntityBehaviour { return count == 0; } + @Override + public boolean acceptsValueSettings() { + return isCountVisible(); + } + + @Override public boolean isActive() { return isActive.get(); } + @Override + public ValueBoxTransform getSlotPositioning() { + return slotPositioning; + } + + @Override + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) { + ItemStack filter = getFilter(hitResult.getDirection()); + int maxAmount = (filter.getItem() instanceof FilterItem) ? 64 : filter.getMaxStackSize(); + return new ValueSettingsBoard(Lang.translateDirect("logistics.filter.extracted_amount"), maxAmount, 16, + Lang.translatedOptions("logistics.filter", "up_to", "exactly"), + new ValueSettingsFormatter(this::formatValue)); + } + + public MutableComponent formatValue(ValueSettings value) { + if (value.row() == 0 && value.value() == filter.getMaxStackSize()) + return Components.literal("Any"); + return Components.literal(((value.row() == 0) ? "\u2264" : "=") + Math.max(1, value.value())); + } + + @Override + public void onShortInteract(Player player, InteractionHand hand, Direction side) { + Level level = getWorld(); + BlockPos pos = getPos(); + ItemStack toApply = player.getItemInHand(hand) + .copy(); + + if (AllItems.WRENCH.isIn(toApply)) + return; + if (AllBlocks.MECHANICAL_ARM.isIn(toApply)) + return; + if (level.isClientSide()) + return; + + if (!player.isCreative()) { + if (toApply.getItem() instanceof FilterItem) { + if (toApply.getCount() == 1) + player.setItemInHand(hand, ItemStack.EMPTY); + else + player.getItemInHand(hand) + .shrink(1); + } + if (getFilter().getItem() instanceof FilterItem) + player.getInventory() + .placeItemBackInInventory(getFilter()); + } + if (toApply.getItem() instanceof FilterItem) + toApply.setCount(1); + + setFilter(side, toApply); + level.playSound(null, pos, SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, .25f, .1f); + } + + public MutableComponent getLabel() { + if (customLabel != null) + return customLabel; + return Lang.translateDirect( + recipeFilter ? "logistics.recipe_filter" : fluidFilter ? "logistics.fluid_filter" : "logistics.filter"); + } + } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringCountUpdatePacket.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringCountUpdatePacket.java deleted file mode 100644 index 1a4d1313f..000000000 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringCountUpdatePacket.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.simibubi.create.foundation.blockEntity.behaviour.filtering; - -import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; -import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; - -public class FilteringCountUpdatePacket extends BlockEntityConfigurationPacket { - - int amount; - - public FilteringCountUpdatePacket(FriendlyByteBuf buffer) { - super(buffer); - } - - public FilteringCountUpdatePacket(BlockPos pos, int amount) { - super(pos); - this.amount = amount; - } - - @Override - protected void writeSettings(FriendlyByteBuf buffer) { - buffer.writeInt(amount); - } - - @Override - protected void readSettings(FriendlyByteBuf buffer) { - amount = buffer.readInt(); - } - - @Override - protected void applySettings(SmartBlockEntity be) { - FilteringBehaviour behaviour = be.getBehaviour(FilteringBehaviour.TYPE); - if (behaviour == null) - return; - behaviour.forceClientState = true; - behaviour.count = amount; - be.setChanged(); - be.sendData(); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringHandler.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringHandler.java deleted file mode 100644 index a71438220..000000000 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringHandler.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.simibubi.create.foundation.blockEntity.behaviour.filtering; - -import com.simibubi.create.AllBlocks; -import com.simibubi.create.AllItems; -import com.simibubi.create.AllKeys; -import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.content.logistics.item.filter.FilterItem; -import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; -import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; -import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform.Sided; -import com.simibubi.create.foundation.utility.Lang; -import com.simibubi.create.foundation.utility.RaycastHelper; - -import net.minecraft.ChatFormatting; -import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.util.Mth; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.event.entity.player.PlayerInteractEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.LogicalSide; -import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -import net.minecraftforge.items.ItemHandlerHelper; - -@EventBusSubscriber -public class FilteringHandler { - - @SubscribeEvent - public static void onBlockActivated(PlayerInteractEvent.RightClickBlock event) { - Level world = event.getWorld(); - BlockPos pos = event.getPos(); - Player player = event.getPlayer(); - InteractionHand hand = event.getHand(); - - if (player.isShiftKeyDown() || player.isSpectator()) - return; - - FilteringBehaviour behaviour = BlockEntityBehaviour.get(world, pos, FilteringBehaviour.TYPE); - if (behaviour == null) - return; - - BlockHitResult ray = RaycastHelper.rayTraceRange(world, player, 10); - if (ray == null) - return; - if (behaviour instanceof SidedFilteringBehaviour) { - behaviour = ((SidedFilteringBehaviour) behaviour).get(ray.getDirection()); - if (behaviour == null) - return; - } - if (!behaviour.isActive()) - return; - if (behaviour.slotPositioning instanceof ValueBoxTransform.Sided) - ((Sided) behaviour.slotPositioning).fromSide(ray.getDirection()); - if (!behaviour.testHit(ray.getLocation())) - return; - - ItemStack toApply = player.getItemInHand(hand) - .copy(); - - if (AllItems.WRENCH.isIn(toApply)) - return; - if (AllBlocks.MECHANICAL_ARM.isIn(toApply)) - return; - - if (event.getSide() != LogicalSide.CLIENT) { - if (!player.isCreative()) { - if (toApply.getItem() instanceof FilterItem) - player.getItemInHand(hand) - .shrink(1); - if (behaviour.getFilter() - .getItem() instanceof FilterItem) - player.getInventory().placeItemBackInInventory(behaviour.getFilter()); - } - if (toApply.getItem() instanceof FilterItem) - toApply.setCount(1); - behaviour.setFilter(toApply); - - } else { - ItemStack filter = behaviour.getFilter(); - String feedback = "apply_click_again"; - if (toApply.getItem() instanceof FilterItem || !behaviour.isCountVisible()) - feedback = "apply"; - else if (ItemHandlerHelper.canItemStacksStack(toApply, filter)) - feedback = "apply_count"; - Component formattedText = world.getBlockState(pos) - .getBlock() - .getName(); - player.displayClientMessage(Lang.translateDirect("logistics.filter." + feedback, formattedText) - .withStyle(ChatFormatting.WHITE), true); - } - - event.setCanceled(true); - event.setCancellationResult(InteractionResult.SUCCESS); - world.playSound(null, pos, SoundEvents.ITEM_FRAME_ADD_ITEM, SoundSource.BLOCKS, .25f, .1f); - } - - @OnlyIn(Dist.CLIENT) - public static boolean onScroll(double delta) { - HitResult objectMouseOver = Minecraft.getInstance().hitResult; - if (!(objectMouseOver instanceof BlockHitResult)) - return false; - - BlockHitResult result = (BlockHitResult) objectMouseOver; - Minecraft mc = Minecraft.getInstance(); - ClientLevel world = mc.level; - BlockPos blockPos = result.getBlockPos(); - - FilteringBehaviour filtering = BlockEntityBehaviour.get(world, blockPos, FilteringBehaviour.TYPE); - if (filtering == null) - return false; - if (mc.player.isShiftKeyDown()) - return false; - if (!mc.player.mayBuild()) - return false; - if (!filtering.isCountVisible()) - return false; - if (!filtering.isActive()) - return false; - if (filtering.slotPositioning instanceof ValueBoxTransform.Sided) - ((Sided) filtering.slotPositioning).fromSide(result.getDirection()); - if (!filtering.testHit(objectMouseOver.getLocation())) - return false; - - ItemStack filterItem = filtering.getFilter(); - filtering.ticksUntilScrollPacket = 10; - int maxAmount = (filterItem.getItem() instanceof FilterItem) ? 64 : filterItem.getMaxStackSize(); - int prev = filtering.scrollableValue; - filtering.scrollableValue = - (int) Mth.clamp(filtering.scrollableValue + delta * (AllKeys.ctrlDown() ? 16 : 1), 0, maxAmount); - - if (prev != filtering.scrollableValue) { - float pitch = (filtering.scrollableValue) / (float) (maxAmount); - pitch = Mth.lerp(pitch, 1.5f, 2f); - AllSoundEvents.SCROLL_VALUE.play(world, mc.player, blockPos, 1, pitch); - } - - return true; - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringRenderer.java index df3689f00..dcfede03d 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/filtering/FilteringRenderer.java @@ -1,5 +1,8 @@ package com.simibubi.create.foundation.blockEntity.behaviour.filtering; +import java.util.ArrayList; +import java.util.List; + import com.mojang.blaze3d.vertex.PoseStack; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllSpecialTextures; @@ -13,7 +16,6 @@ import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxRenderer; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform.Sided; import com.simibubi.create.foundation.config.AllConfigs; -import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Pair; @@ -25,6 +27,7 @@ import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.state.BlockState; @@ -66,28 +69,32 @@ public class FilteringRenderer { ItemStack filter = behaviour.getFilter(); boolean isFilterSlotted = filter.getItem() instanceof FilterItem; boolean showCount = behaviour.isCountVisible(); - boolean fluids = behaviour.fluidFilter; - Component label = isFilterSlotted ? Components.immutableEmpty() - : Lang.translateDirect(behaviour.recipeFilter ? "logistics.recipe_filter" - : fluids ? "logistics.fluid_filter" : "logistics.filter"); + Component label = behaviour.getLabel(); boolean hit = behaviour.slotPositioning.testHit(state, target.getLocation() .subtract(Vec3.atLowerCornerOf(pos))); AABB emptyBB = new AABB(Vec3.ZERO, Vec3.ZERO); AABB bb = isFilterSlotted ? emptyBB.inflate(.45f, .31f, .2f) : emptyBB.inflate(.25f); - ValueBox box = showCount ? new ItemValueBox(label, bb, pos, filter, behaviour.scrollableValue) - : new ValueBox(label, bb, pos); - - box.offsetLabel(behaviour.textShift) - .withColors(fluids ? 0x407088 : 0x7A6A2C, fluids ? 0x70adb5 : 0xB79D64) - .scrollTooltip(showCount && !isFilterSlotted ? Components.literal("[").append(Lang.translateDirect("action.scroll")).append("]") : Components.immutableEmpty()) - .passive(!hit); + ValueBox box = new ItemValueBox(label, bb, pos, filter, showCount ? behaviour.count : -1, behaviour.upTo); + box.passive(!hit); CreateClient.OUTLINER.showValueBox(Pair.of("filter", pos), box.transform(behaviour.slotPositioning)) - .lineWidth(1 / 64f) - .withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null) - .highlightFace(result.getDirection()); + .lineWidth(1 / 64f) + .withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null) + .highlightFace(result.getDirection()); + + if (!hit) + return; + + List tip = new ArrayList<>(); + tip.add(label.copy()); + tip.add(Lang + .translateDirect(filter.isEmpty() ? "logistics.filter.click_to_set" : "logistics.filter.click_to_replace")); + if (showCount) + tip.add(Lang.translateDirect("logistics.filter.hold_to_set_amount")); + + CreateClient.VALUE_SETTINGS_HANDLER.showHoverTip(tip); } public static void renderOnBlockEntity(SmartBlockEntity be, float partialTicks, PoseStack ms, @@ -100,7 +107,8 @@ public class FilteringRenderer { Entity cameraEntity = Minecraft.getInstance().cameraEntity; if (cameraEntity != null && be.getLevel() == cameraEntity.getLevel()) { float max = AllConfigs.client().filterItemRenderDistance.getF(); - if (cameraEntity.position().distanceToSqr(VecHelper.getCenterOf(be.getBlockPos())) > (max * max)) { + if (cameraEntity.position() + .distanceToSqr(VecHelper.getCenterOf(be.getBlockPos())) > (max * max)) { return; } } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java index 72bdb75e6..39043877d 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/inventory/CapManipulationBehaviourBase.java @@ -5,6 +5,7 @@ import javax.annotation.Nullable; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringBehaviour; +import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode; import com.simibubi.create.foundation.utility.BlockFace; import net.minecraft.core.BlockPos; @@ -101,6 +102,14 @@ public abstract class CapManipulationBehaviourBase filter) { - return extract(amount, filter, ItemStack::getMaxStackSize); - } - - public ItemStack extract(int amount, Predicate filter, Function amountThreshold) { + public ItemStack extract(ExtractionCountMode mode, int amount, Predicate filter) { boolean shouldSimulate = simulateNext; simulateNext = false; @@ -70,19 +66,10 @@ public class InvManipulationBehaviour extends CapManipulationBehaviourBase test = getFilterTest(filter); - - ItemStack simulatedItems = extractAmountOrThresh(inventory, test, amount, amountThreshold, true); + ItemStack simulatedItems = ItemHelper.extract(inventory, test, mode, amount, true); if (shouldSimulate || simulatedItems.isEmpty()) return simulatedItems; - - return extractAmountOrThresh(inventory, test, amount, amountThreshold, false); - } - - private static ItemStack extractAmountOrThresh(IItemHandler inventory, Predicate test, int amount, - Function amountThreshold, boolean shouldSimulate) { - if (amount == -1) - return ItemHelper.extract(inventory, test, amountThreshold, shouldSimulate); - return ItemHelper.extract(inventory, test, amount, shouldSimulate); + return ItemHelper.extract(inventory, test, mode, amount, false); } public ItemStack insert(ItemStack stack) { diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/linked/LinkRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/linked/LinkRenderer.java index e475a62f1..2031c0f1f 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/linked/LinkRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/linked/LinkRenderer.java @@ -1,8 +1,10 @@ package com.simibubi.create.foundation.blockEntity.behaviour.linked; +import java.util.ArrayList; +import java.util.List; + import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.datafixers.util.Pair; -import com.simibubi.create.AllSpecialTextures; import com.simibubi.create.CreateClient; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; @@ -19,6 +21,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.entity.Entity; import net.minecraft.world.item.ItemStack; import net.minecraft.world.phys.AABB; @@ -51,13 +54,26 @@ public class LinkRenderer { boolean hit = behaviour.testHit(first, target.getLocation()); ValueBoxTransform transform = first ? behaviour.firstSlot : behaviour.secondSlot; - ValueBox box = new ValueBox(label, bb, pos).withColors(0x601F18, 0xB73C2D) - .offsetLabel(behaviour.textShift) - .passive(!hit); + ValueBox box = new ValueBox(label, bb, pos).passive(!hit); + boolean empty = behaviour.getNetworkKey() + .get(first) + .getStack() + .isEmpty(); + + if (!empty) + box.wideOutline(); + CreateClient.OUTLINER.showValueBox(Pair.of(Boolean.valueOf(first), pos), box.transform(transform)) - .lineWidth(1 / 64f) - .withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null) - .highlightFace(result.getDirection()); + .highlightFace(result.getDirection()); + + if (!hit) + continue; + + List tip = new ArrayList<>(); + tip.add(label.copy()); + tip.add( + Lang.translateDirect(empty ? "logistics.filter.click_to_set" : "logistics.filter.click_to_replace")); + CreateClient.VALUE_SETTINGS_HANDLER.showHoverTip(tip); } } @@ -66,7 +82,7 @@ public class LinkRenderer { if (be == null || be.isRemoved()) return; - + Entity cameraEntity = Minecraft.getInstance().cameraEntity; float max = AllConfigs.client().filterItemRenderDistance.getF(); if (!be.isVirtual() && cameraEntity != null && cameraEntity.position() diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/BulkScrollValueBehaviour.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/BulkScrollValueBehaviour.java index dba4860f7..e65584a21 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/BulkScrollValueBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/BulkScrollValueBehaviour.java @@ -7,18 +7,34 @@ import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; public class BulkScrollValueBehaviour extends ScrollValueBehaviour { Function> groupGetter; public BulkScrollValueBehaviour(Component label, SmartBlockEntity be, ValueBoxTransform slot, - Function> groupGetter) { + Function> groupGetter) { super(label, be, slot); this.groupGetter = groupGetter; } - List getBulk() { + @Override + public void setValueSettings(Player player, ValueSettings valueSetting, boolean ctrlDown) { + if (!ctrlDown) { + super.setValueSettings(player, valueSetting, ctrlDown); + return; + } + if (!valueSetting.equals(getValueSettings())) + playFeedbackSound(this); + for (SmartBlockEntity be : getBulk()) { + ScrollValueBehaviour other = be.getBehaviour(ScrollValueBehaviour.TYPE); + if (other != null) + other.setValue(valueSetting.value()); + } + } + + public List getBulk() { return groupGetter.apply(blockEntity); } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollOptionBehaviour.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollOptionBehaviour.java index 57562088a..52f2633e0 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollOptionBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollOptionBehaviour.java @@ -1,9 +1,15 @@ package com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue; +import com.google.common.collect.ImmutableList; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter.ScrollOptionSettingsFormatter; +import com.simibubi.create.foundation.utility.Components; import net.minecraft.network.chat.Component; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; public class ScrollOptionBehaviour & INamedIconOptions> extends ScrollValueBehaviour { @@ -13,15 +19,20 @@ public class ScrollOptionBehaviour & INamedIconOptions> extend super(label, be, slot); options = enum_.getEnumConstants(); between(0, options.length - 1); - withStepFunction((c) -> -1); } INamedIconOptions getIconForSelected() { return get(); } - + public E get() { - return options[scrollableValue]; + return options[value]; + } + + @Override + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) { + return new ValueSettingsBoard(label, max, 1, ImmutableList.of(Components.literal("Select")), + new ScrollOptionSettingsFormatter(options)); } } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueBehaviour.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueBehaviour.java index a3d889487..d8ff66483 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueBehaviour.java @@ -4,19 +4,25 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; +import com.google.common.collect.ImmutableList; import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.BehaviourType; import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform; -import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBehaviour; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsBoard; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsFormatter; +import com.simibubi.create.foundation.utility.Components; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.chat.Component; import net.minecraft.util.Mth; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; -public class ScrollValueBehaviour extends BlockEntityBehaviour { +public class ScrollValueBehaviour extends BlockEntityBehaviour implements ValueSettingsBehaviour { public static final BehaviourType TYPE = new BehaviourType<>(); @@ -24,17 +30,12 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { Vec3 textShift; int min = 0; - int max = 1; + protected int max = 1; public int value; - public int scrollableValue; - int ticksUntilScrollPacket; - boolean forceClientState; - Component label; + public Component label; Consumer callback; Consumer clientCallback; Function formatter; - Function unit; - Function step; private Supplier isActive; boolean needsWrench; @@ -46,54 +47,28 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { }; clientCallback = i -> { }; - textShift = Vec3.ZERO; formatter = i -> Integer.toString(i); - step = (c) -> 1; value = 0; isActive = () -> true; - ticksUntilScrollPacket = -1; } @Override - public boolean isSafeNBT() { return true; } + public boolean isSafeNBT() { + return true; + } @Override public void write(CompoundTag nbt, boolean clientPacket) { nbt.putInt("ScrollValue", value); - if (clientPacket && forceClientState) { - nbt.putBoolean("ForceScrollable", true); - forceClientState = false; - } super.write(nbt, clientPacket); } @Override public void read(CompoundTag nbt, boolean clientPacket) { value = nbt.getInt("ScrollValue"); - if (nbt.contains("ForceScrollable")) { - ticksUntilScrollPacket = -1; - scrollableValue = value; - } super.read(nbt, clientPacket); } - @Override - public void tick() { - super.tick(); - - if (!getWorld().isClientSide) - return; - if (ticksUntilScrollPacket == -1) - return; - if (ticksUntilScrollPacket > 0) { - ticksUntilScrollPacket--; - return; - } - - AllPackets.getChannel().sendToServer(new ScrollValueUpdatePacket(getPos(), scrollableValue)); - ticksUntilScrollPacket = -1; - } - public ScrollValueBehaviour withClientCallback(Consumer valueCallback) { clientCallback = valueCallback; return this; @@ -110,11 +85,6 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { return this; } - public ScrollValueBehaviour moveText(Vec3 shift) { - textShift = shift; - return this; - } - public ScrollValueBehaviour requiresWrench() { this.needsWrench = true; return this; @@ -125,38 +95,19 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { return this; } - public ScrollValueBehaviour withUnit(Function unit) { - this.unit = unit; - return this; - } - public ScrollValueBehaviour onlyActiveWhen(Supplier condition) { isActive = condition; return this; } - public ScrollValueBehaviour withStepFunction(Function step) { - this.step = step; - return this; - } - - @Override - public void initialize() { - super.initialize(); - setValue(value); - scrollableValue = value; - } - public void setValue(int value) { value = Mth.clamp(value, min, max); if (value == this.value) return; this.value = value; - forceClientState = true; callback.accept(value); blockEntity.setChanged(); blockEntity.sendData(); - scrollableValue = value; } public int getValue() { @@ -164,7 +115,7 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { } public String formatValue() { - return formatter.apply(scrollableValue); + return formatter.apply(value); } @Override @@ -172,10 +123,12 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { return TYPE; } + @Override public boolean isActive() { return isActive.get(); } + @Override public boolean testHit(Vec3 hit) { BlockState state = blockEntity.getBlockState(); Vec3 localHit = hit.subtract(Vec3.atLowerCornerOf(blockEntity.getBlockPos())); @@ -193,4 +146,33 @@ public class ScrollValueBehaviour extends BlockEntityBehaviour { public boolean control; } + @Override + public ValueBoxTransform getSlotPositioning() { + return slotPositioning; + } + + @Override + public ValueSettingsBoard createBoard(Player player, BlockHitResult hitResult) { + return new ValueSettingsBoard(label, max, 10, ImmutableList.of(Components.literal("Value")), + new ValueSettingsFormatter(ValueSettings::format)); + } + + @Override + public void setValueSettings(Player player, ValueSettings valueSetting, boolean ctrlDown) { + if (valueSetting.equals(getValueSettings())) + return; + setValue(valueSetting.value()); + playFeedbackSound(this); + } + + @Override + public ValueSettings getValueSettings() { + return new ValueSettings(0, value); + } + + @Override + public boolean onlyVisibleWithWrench() { + return needsWrench; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueHandler.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueHandler.java index 29b0888e5..d3d9ce827 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueHandler.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueHandler.java @@ -1,82 +1,20 @@ package com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue; -import com.simibubi.create.AllItems; -import com.simibubi.create.AllKeys; -import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour; -import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; -import com.simibubi.create.foundation.blockEntity.behaviour.ValueBoxTransform.Sided; -import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueBehaviour.StepContext; import com.simibubi.create.foundation.utility.animation.PhysicalFloat; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -@EventBusSubscriber public class ScrollValueHandler { private static float lastPassiveScroll = 0.0f; private static float passiveScroll = 0.0f; private static float passiveScrollDirection = 1f; - private static final PhysicalFloat wrenchCog = PhysicalFloat.create() + public static final PhysicalFloat wrenchCog = PhysicalFloat.create() .withDrag(0.3); - @OnlyIn(Dist.CLIENT) - public static boolean onScroll(double delta) { - Minecraft mc = Minecraft.getInstance(); - HitResult objectMouseOver = mc.hitResult; - if (!(objectMouseOver instanceof BlockHitResult)) - return false; - - BlockHitResult result = (BlockHitResult) objectMouseOver; - ClientLevel world = mc.level; - BlockPos blockPos = result.getBlockPos(); - - ScrollValueBehaviour scrolling = BlockEntityBehaviour.get(world, blockPos, ScrollValueBehaviour.TYPE); - if (scrolling == null) - return false; - if (!scrolling.isActive()) - return false; - if (!mc.player.mayBuild()) - return false; - if (scrolling.needsWrench && !AllItems.WRENCH.isIn(mc.player.getMainHandItem())) - return false; - - passiveScrollDirection = (float) -delta; - wrenchCog.bump(3, -delta * 10); - int prev = scrolling.scrollableValue; - - if (scrolling.slotPositioning instanceof Sided) - ((Sided) scrolling.slotPositioning).fromSide(result.getDirection()); - if (!scrolling.testHit(objectMouseOver.getLocation())) - return false; - - if (scrolling instanceof BulkScrollValueBehaviour && AllKeys.ctrlDown()) { - BulkScrollValueBehaviour bulkScrolling = (BulkScrollValueBehaviour) scrolling; - for (SmartBlockEntity be : bulkScrolling.getBulk()) { - ScrollValueBehaviour other = be.getBehaviour(ScrollValueBehaviour.TYPE); - if (other != null) - applyTo(delta, other); - } - - } else - applyTo(delta, scrolling); - - if (prev != scrolling.scrollableValue) { - float pitch = (scrolling.scrollableValue - scrolling.min) / (float) (scrolling.max - scrolling.min); - pitch = Mth.lerp(pitch, 1.5f, 2f); - AllSoundEvents.SCROLL_VALUE.play(world, mc.player, blockPos, 1, pitch); - } - return true; - } - public static float getScroll(float partialTicks) { return wrenchCog.getValue(partialTicks) + Mth.lerp(partialTicks, lastPassiveScroll, passiveScroll); } @@ -91,21 +29,4 @@ public class ScrollValueHandler { } } - protected static void applyTo(double delta, ScrollValueBehaviour scrolling) { - scrolling.ticksUntilScrollPacket = 10; - int valueBefore = scrolling.scrollableValue; - - StepContext context = new StepContext(); - context.control = AllKeys.ctrlDown(); - context.shift = AllKeys.shiftDown(); - context.currentValue = scrolling.scrollableValue; - context.forward = delta > 0; - - double newValue = scrolling.scrollableValue + Math.signum(delta) * scrolling.step.apply(context); - scrolling.scrollableValue = (int) Mth.clamp(newValue, scrolling.min, scrolling.max); - - if (valueBefore != scrolling.scrollableValue) - scrolling.clientCallback.accept(scrolling.scrollableValue); - } - } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueRenderer.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueRenderer.java index f27298d13..ba6c421ff 100644 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueRenderer.java @@ -1,5 +1,8 @@ package com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue; +import java.util.ArrayList; +import java.util.List; + import com.simibubi.create.AllItems; import com.simibubi.create.AllKeys; import com.simibubi.create.CreateClient; @@ -16,6 +19,7 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.HitResult; @@ -52,6 +56,14 @@ public class ScrollValueRenderer { } } else addBox(world, pos, face, behaviour, highlight); + + if (!highlight) + return; + + List tip = new ArrayList<>(); + tip.add(behaviour.label.copy()); + tip.add(Lang.translateDirect("gui.value_settings.hold_to_edit")); + CreateClient.VALUE_SETTINGS_HANDLER.showHoverTip(tip); } protected static void addBox(ClientLevel world, BlockPos pos, Direction face, ScrollValueBehaviour behaviour, @@ -66,18 +78,13 @@ public class ScrollValueRenderer { box = new IconValueBox(label, ((ScrollOptionBehaviour) behaviour).getIconForSelected(), bb, pos); } else { box = new TextValueBox(label, bb, pos, Components.literal(behaviour.formatValue())); - if (behaviour.unit != null) - box.subLabel(Components.literal("(").append(behaviour.unit.apply(behaviour.scrollableValue)).append(")")); } - box.scrollTooltip(Components.literal("[").append(Lang.translateDirect("action.scroll")).append("]")); - box.offsetLabel(behaviour.textShift.add(20, -10, 0)) - .withColors(0x5A5D5A, 0xB5B7B6) - .passive(!highlight); + box.passive(!highlight) + .wideOutline(); CreateClient.OUTLINER.showValueBox(pos, box.transform(behaviour.slotPositioning)) - .lineWidth(1 / 64f) - .highlightFace(face); + .highlightFace(face); } } diff --git a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueUpdatePacket.java b/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueUpdatePacket.java deleted file mode 100644 index e81a6ee4b..000000000 --- a/src/main/java/com/simibubi/create/foundation/blockEntity/behaviour/scrollvalue/ScrollValueUpdatePacket.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue; - -import com.simibubi.create.foundation.blockEntity.SmartBlockEntity; -import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.FriendlyByteBuf; - -public class ScrollValueUpdatePacket extends BlockEntityConfigurationPacket { - - int value; - - public ScrollValueUpdatePacket(FriendlyByteBuf buffer) { - super(buffer); - } - - public ScrollValueUpdatePacket(BlockPos pos, int amount) { - super(pos); - this.value = amount; - } - - @Override - protected void writeSettings(FriendlyByteBuf buffer) { - buffer.writeInt(value); - } - - @Override - protected void readSettings(FriendlyByteBuf buffer) { - value = buffer.readInt(); - } - - @Override - protected void applySettings(SmartBlockEntity be) { - ScrollValueBehaviour behaviour = be.getBehaviour(ScrollValueBehaviour.TYPE); - if (behaviour == null) - return; - behaviour.setValue(value); - } - -} diff --git a/src/main/java/com/simibubi/create/foundation/config/CKinetics.java b/src/main/java/com/simibubi/create/foundation/config/CKinetics.java index d83174956..ee130cb8b 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CKinetics.java +++ b/src/main/java/com/simibubi/create/foundation/config/CKinetics.java @@ -1,6 +1,5 @@ package com.simibubi.create.foundation.config; -import com.simibubi.create.foundation.config.ui.ConfigAnnotations; import com.simibubi.create.foundation.utility.ContraptionData; public class CKinetics extends ConfigBase { @@ -8,7 +7,6 @@ public class CKinetics extends ConfigBase { public final ConfigBool disableStress = b(false, "disableStress", Comments.disableStress); public final ConfigInt maxBeltLength = i(20, 5, "maxBeltLength", Comments.maxBeltLength); public final ConfigInt crushingDamage = i(4, 0, "crushingDamage", Comments.crushingDamage); - public final ConfigInt maxMotorSpeed = i(256, 64, "maxMotorSpeed", Comments.rpm, Comments.maxMotorSpeed, ConfigAnnotations.RequiresRestart.BOTH.asComment()); public final ConfigInt maxRotationSpeed = i(256, 64, "maxRotationSpeed", Comments.rpm, Comments.maxRotationSpeed); public final ConfigEnum ignoreDeployerAttacks = e(DeployerAggroSetting.CREEPERS, "ignoreDeployerAttacks", Comments.ignoreDeployerAttacks); @@ -65,7 +63,6 @@ public class CKinetics extends ConfigBase { private static class Comments { static String maxBeltLength = "Maximum length in blocks of mechanical belts."; static String crushingDamage = "Damage dealt by active Crushing Wheels."; - static String maxMotorSpeed = "Maximum allowed speed of a configurable motor."; static String maxRotationSpeed = "Maximum allowed rotation speed for any Kinetic Block."; static String fanPushDistance = "Maximum distance in blocks Fans can push entities."; static String fanPullDistance = "Maximum distance in blocks from where Fans can pull entities."; diff --git a/src/main/java/com/simibubi/create/foundation/config/CLogistics.java b/src/main/java/com/simibubi/create/foundation/config/CLogistics.java index cde5fe2d3..49c60c5eb 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CLogistics.java +++ b/src/main/java/com/simibubi/create/foundation/config/CLogistics.java @@ -2,8 +2,6 @@ package com.simibubi.create.foundation.config; public class CLogistics extends ConfigBase { - public final ConfigInt defaultExtractionLimit = - i(64, 1, 64, "defaultExtractionLimit", Comments.defaultExtractionLimit); public final ConfigInt defaultExtractionTimer = i(8, 1, "defaultExtractionTimer", Comments.defaultExtractionTimer); public final ConfigInt psiTimeout = i(20, 1, "psiTimeout", Comments.psiTimeout); public final ConfigInt mechanicalArmRange = i(5, 1, "mechanicalArmRange", Comments.mechanicalArmRange); @@ -17,8 +15,6 @@ public class CLogistics extends ConfigBase { } private static class Comments { - static String defaultExtractionLimit = - "The maximum amount of items a funnel pulls at a time without an applied filter."; static String defaultExtractionTimer = "The amount of ticks a funnel waits between item transferrals, when it is not re-activated by redstone."; static String linkRange = "Maximum possible range in blocks of redstone link connections."; diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java index bcb832da5..51e4f65d8 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllGuiTextures.java @@ -48,10 +48,6 @@ public enum AllGuiTextures implements ScreenElement { STOCKSWITCH_UNPOWERED_LANE("logistics", 36, 18, 102, 18), STOCKSWITCH_POWERED_LANE("logistics", 36, 40, 102, 18), - ADJUSTABLE_CRATE("logistics_2", 124, 127), - ADJUSTABLE_DOUBLE_CRATE("logistics_2", 0, 127, 196, 127), - ADJUSTABLE_CRATE_LOCKED_SLOT("logistics_2", 125, 109, 18, 18), - FILTER("filters", 214, 97), ATTRIBUTE_FILTER("filters", 0, 97, 241, 83), @@ -77,12 +73,6 @@ public enum AllGuiTextures implements ScreenElement { LINKED_CONTROLLER("curiosities_2", 179, 109), BLUEPRINT("curiosities_2", 0, 109, 179, 109), - PROJECTOR("projector", 235, 185), - PROJECTOR_FILTER_STRENGTH("projector", 0, 14, 162, 22), - PROJECTOR_FILTER("projector", 0, 36, 162, 22), - PROJECTOR_END("projector", 0, 58, 162, 22), - PROJECTOR_EMPTY("projector", 0, 80, 162, 22), - DATA_GATHERER("display_link", 235, 162), DATA_AREA_START("display_link", 0, 163, 2, 18), DATA_AREA_SPEECH("display_link", 8, 163, 5, 18), @@ -134,6 +124,26 @@ public enum AllGuiTextures implements ScreenElement { ELEVATOR_CONTACT("display_link", 20, 172, 233, 82), + BRASS_FRAME_TL("value_settings", 65, 9, 4, 4), + BRASS_FRAME_TR("value_settings", 70, 9, 4, 4), + BRASS_FRAME_BL("value_settings", 65, 19, 4, 4), + BRASS_FRAME_BR("value_settings", 70, 19, 4, 4), + BRASS_FRAME_LEFT("value_settings", 65, 14, 3, 4), + BRASS_FRAME_RIGHT("value_settings", 71, 14, 3, 4), + BRASS_FRAME_TOP("value_settings", 0, 24, 256, 3), + BRASS_FRAME_BOTTOM("value_settings", 0, 27, 256, 3), + + VALUE_SETTINGS_MILESTONE("value_settings", 0, 0, 7, 8), + VALUE_SETTINGS_WIDE_MILESTONE("value_settings", 75, 14, 13, 8), + VALUE_SETTINGS_BAR("value_settings", 7, 0, 249, 8), + VALUE_SETTINGS_BAR_BG("value_settings", 75, 9, 1, 1), + VALUE_SETTINGS_OUTER_BG("value_settings", 80, 9, 1, 1), + VALUE_SETTINGS_CURSOR_LEFT("value_settings", 0, 9, 3, 14), + VALUE_SETTINGS_CURSOR("value_settings", 4, 9, 56, 14), + VALUE_SETTINGS_CURSOR_RIGHT("value_settings", 61, 9, 3, 14), + VALUE_SETTINGS_CURSOR_ICON("value_settings", 0, 44, 22, 20), + VALUE_SETTINGS_LABEL_BG("value_settings", 0, 31, 81, 11), + // JEI JEI_SLOT("jei/widgets", 18, 18), JEI_CHANCE_SLOT("jei/widgets", 20, 156, 18, 18), diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java index 3514e3246..900f04c6c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java @@ -126,6 +126,9 @@ public class AllIcons implements ScreenElement { I_SCHEMATIC = newRow(), I_SEQ_REPEAT = next(), + VALUE_BOX_HOVER_6PX = next(), + VALUE_BOX_HOVER_4PX = next(), + VALUE_BOX_HOVER_8PX = next(), I_MTD_LEFT = newRow(), I_MTD_CLOSE = next(), @@ -187,7 +190,7 @@ public class AllIcons implements ScreenElement { @OnlyIn(Dist.CLIENT) public void render(PoseStack ms, MultiBufferSource buffer, int color) { - VertexConsumer builder = buffer.getBuffer(RenderType.textSeeThrough(ICON_ATLAS)); + VertexConsumer builder = buffer.getBuffer(RenderType.text(ICON_ATLAS)); Matrix4f matrix = ms.last().pose(); Color rgb = new Color(color); int light = LightTexture.FULL_BRIGHT; diff --git a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java index b59168cd0..47fe1d567 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -252,6 +252,13 @@ public class UIRenderHelper { tex.startY / 256f, (tex.startY + tex.height) / 256f); } + public static void drawCropped(PoseStack ms, int left, int top, int w, int h, int z, AllGuiTextures tex) { + tex.bind(); + drawTexturedQuad(ms.last() + .pose(), Color.WHITE, left, left + w, top, top + h, z, tex.startX / 256f, (tex.startX + w) / 256f, + tex.startY / 256f, (tex.startY + h) / 256f); + } + private static void drawColoredTexture(PoseStack ms, Color c, int left, int right, int top, int bot, int z, int tex_width, int tex_height, float tex_left, float tex_top, int sheet_width, int sheet_height) { drawTexturedQuad(ms.last().pose(), c, left, right, top, bot, z, (tex_left + 0.0F) / (float) sheet_width, (tex_left + (float) tex_width) / (float) sheet_width, (tex_top + 0.0F) / (float) sheet_height, (tex_top + (float) tex_height) / (float) sheet_height); } diff --git a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java index d7627bcd5..1f4e09d18 100644 --- a/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java +++ b/src/main/java/com/simibubi/create/foundation/item/ItemHelper.java @@ -9,7 +9,6 @@ import javax.annotation.Nullable; import org.apache.commons.lang3.mutable.MutableInt; -import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.utility.Pair; import net.minecraft.core.BlockPos; @@ -148,8 +147,7 @@ public class ItemHelper { } public static ItemStack extract(IItemHandler inv, Predicate test, boolean simulate) { - return extract(inv, test, ExtractionCountMode.UPTO, AllConfigs.server().logistics.defaultExtractionLimit.get(), - simulate); + return extract(inv, test, ExtractionCountMode.UPTO, 64, simulate); } public static ItemStack extract(IItemHandler inv, Predicate test, int exactAmount, boolean simulate) { @@ -224,7 +222,7 @@ public class ItemHelper { public static ItemStack extract(IItemHandler inv, Predicate test, Function amountFunction, boolean simulate) { ItemStack extracting = ItemStack.EMPTY; - int maxExtractionCount = AllConfigs.server().logistics.defaultExtractionLimit.get(); + int maxExtractionCount = 64; for (int slot = 0; slot < inv.getSlots(); slot++) { if (extracting.isEmpty()) { diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index fc83111b0..7453ee3d6 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -80,8 +80,7 @@ import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; import com.simibubi.create.content.schematics.packet.SchematicSyncPacket; import com.simibubi.create.content.schematics.packet.SchematicUploadPacket; import com.simibubi.create.foundation.blockEntity.RemoveBlockEntityPacket; -import com.simibubi.create.foundation.blockEntity.behaviour.filtering.FilteringCountUpdatePacket; -import com.simibubi.create.foundation.blockEntity.behaviour.scrollvalue.ScrollValueUpdatePacket; +import com.simibubi.create.foundation.blockEntity.behaviour.ValueSettingsPacket; import com.simibubi.create.foundation.command.HighlightPacket; import com.simibubi.create.foundation.command.SConfigureConfigPacket; import com.simibubi.create.foundation.config.ui.CConfigureConfigPacket; @@ -111,8 +110,6 @@ public enum AllPackets { UPLOAD_SCHEMATIC(SchematicUploadPacket.class, SchematicUploadPacket::new, PLAY_TO_SERVER), CLEAR_CONTAINER(ClearMenuPacket.class, ClearMenuPacket::new, PLAY_TO_SERVER), CONFIGURE_FILTER(FilterScreenPacket.class, FilterScreenPacket::new, PLAY_TO_SERVER), - CONFIGURE_FILTERING_AMOUNT(FilteringCountUpdatePacket.class, FilteringCountUpdatePacket::new, PLAY_TO_SERVER), - CONFIGURE_SCROLLABLE(ScrollValueUpdatePacket.class, ScrollValueUpdatePacket::new, PLAY_TO_SERVER), EXTENDO_INTERACT(ExtendoGripInteractionPacket.class, ExtendoGripInteractionPacket::new, PLAY_TO_SERVER), CONTRAPTION_INTERACT(ContraptionInteractionPacket.class, ContraptionInteractionPacket::new, PLAY_TO_SERVER), CLIENT_MOTION(ClientMotionPacket.class, ClientMotionPacket::new, PLAY_TO_SERVER), @@ -157,6 +154,7 @@ public enum AllPackets { REQUEST_FLOOR_LIST(ElevatorFloorListPacket.RequestFloorList.class, ElevatorFloorListPacket.RequestFloorList::new, PLAY_TO_SERVER), ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::new, PLAY_TO_SERVER), + VALUE_SETTINGS(ValueSettingsPacket.class, ValueSettingsPacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), diff --git a/src/main/resources/assets/create/lang/default/interface.json b/src/main/resources/assets/create/lang/default/interface.json index 86887694b..e384e2ab2 100644 --- a/src/main/resources/assets/create/lang/default/interface.json +++ b/src/main/resources/assets/create/lang/default/interface.json @@ -193,21 +193,47 @@ "create.contraptions.cart_movement_mode.rotation_locked": "Lock rotation", "create.contraptions.windmill.rotation_direction": "Rotation Direction", - "create.contraptions.clockwork.clock_hands": "Clock Hands", + "create.contraptions.clockwork.clock_hands": "Clock Hand Arrangement", "create.contraptions.clockwork.hour_first": "Hour hand first", "create.contraptions.clockwork.minute_first": "Minute hand first", "create.contraptions.clockwork.hour_first_24": "24-Hour hand first", + "create.logistics.crafter.connected": "Connected Crafters", + "create.logistics.crafter.click_to_merge": "Click to merge Inventories", + "create.logistics.crafter.click_to_separate": "Click to separate Inventories", + "create.logistics.filter": "Filter", "create.logistics.recipe_filter": "Recipe Filter", "create.logistics.fluid_filter": "Fluid Filter", - "create.logistics.firstFrequency": "Freq. #1", - "create.logistics.secondFrequency": "Freq. #2", - - "create.logistics.filter.apply": "Applied filter to %1$s.", - "create.logistics.filter.apply_click_again": "Applied filter to %1$s, click again to copy the amount.", - "create.logistics.filter.apply_count": "Applied extraction count to filter.", + "create.logistics.firstFrequency": "Frequency #1", + "create.logistics.secondFrequency": "Frequency #2", + + "create.logistics.filter.click_to_set": "Click with item to set", + "create.logistics.filter.click_to_replace": "Click with item to replace", + "create.logistics.filter.hold_to_set_amount": "Click and hold for amount", + "create.logistics.filter.extracted_amount": "Extracted Amount", + "create.logistics.filter.any_amount_short": "Any", + "create.logistics.filter.up_to": "Up to", + "create.logistics.filter.exactly": "Exactly", + + "create.logistics.creative_crate.supply": "Infinite Supply", + "create.logistics.train_observer.cargo_filter": "Cargo Filter", + + "create.kinetics.creative_motor.rotation_speed": "Generated Speed in RPM", + "create.kinetics.speed_controller.rotation_speed": "Targeted Speed in RPM", + + "create.logistics.redstone_interval": "Redstone Interval", + + "create.contraptions.contoller.target": "Targeted Component", + + "create.contraptions.chassis.radius": "Radius when Sticky", + "create.contraptions.chassis.range": "Range of Sticky Sides", + "create.contraptions.chassis.distance": "Distance", + + "create.gui.value_settings.hold_to_edit": "Click and hold to edit", + "create.gui.value_settings.release_to_confirm": "Release %1$s to Confirm", + "create.gui.goggles.generator_stats": "Generator Stats:", "create.gui.goggles.kinetic_stats": "Kinetic Stats:", "create.gui.goggles.at_current_speed": "at current speed", @@ -515,7 +541,7 @@ "create.weighted_ejector.targeting": "Ejecting to [%1$s,%2$s,%3$s]", "create.weighted_ejector.stack_size": "Ejected Stack Size", - "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available", + "create.logistics.when_multiple_outputs_available": "Distribution Method", "create.mechanical_arm.selection_mode.round_robin": "Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "Forced Round Robin", diff --git a/src/main/resources/assets/create/models/block/creative_motor/block.json b/src/main/resources/assets/create/models/block/creative_motor/block.json index a2322aad2..da65b56cd 100644 --- a/src/main/resources/assets/create/models/block/creative_motor/block.json +++ b/src/main/resources/assets/create/models/block/creative_motor/block.json @@ -50,13 +50,13 @@ }, { "name": "Between Rims", - "from": [3.5, 3.5, 3], - "to": [12.5, 12.5, 6], + "from": [3.5, 3.5, 2], + "to": [12.5, 12.5, 5], "faces": { - "east": {"uv": [3, 10, 12, 13], "rotation": 270, "texture": "#6"}, - "west": {"uv": [3, 10, 12, 13], "rotation": 90, "texture": "#6"}, - "up": {"uv": [3, 10, 12, 13], "rotation": 180, "texture": "#6"}, - "down": {"uv": [3, 10, 12, 13], "texture": "#6"} + "east": {"uv": [3.5, 10, 12.5, 13], "rotation": 270, "texture": "#6"}, + "west": {"uv": [3.5, 10, 12.5, 13], "rotation": 90, "texture": "#6"}, + "up": {"uv": [3.5, 10, 12.5, 13], "rotation": 180, "texture": "#6"}, + "down": {"uv": [3.5, 10, 12.5, 13], "texture": "#6"} } }, { @@ -131,6 +131,30 @@ "up": {"uv": [1, 2, 8, 16], "rotation": 90, "texture": "#7"}, "down": {"uv": [1, 4, 15, 11], "texture": "#7"} } + }, + { + "from": [5, 7, 4], + "to": [11, 13, 10], + "faces": { + "north": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "east": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "south": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "west": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "up": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "down": {"uv": [10, 0, 16, 6], "texture": "#6"} + } + }, + { + "from": [3, 5, 4], + "to": [13, 11, 10], + "faces": { + "north": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "east": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "south": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "west": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "up": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "down": {"uv": [10, 0, 16, 6], "texture": "#6"} + } } ], "display": { @@ -155,6 +179,8 @@ "origin": [8, 8, 8], "color": 0, "children": [] - } + }, + 10, + 11 ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/creative_motor/block_vertical.json b/src/main/resources/assets/create/models/block/creative_motor/block_vertical.json index 6e0468f40..61552adbb 100644 --- a/src/main/resources/assets/create/models/block/creative_motor/block_vertical.json +++ b/src/main/resources/assets/create/models/block/creative_motor/block_vertical.json @@ -4,7 +4,6 @@ "textures": { "5": "create:block/creative_casing", "6": "create:block/creative_motor", - "7": "create:block/flap_display_front", "particle": "create:block/creative_casing", "1_0": "create:block/axis" }, @@ -74,6 +73,19 @@ "down": {"uv": [10, 0, 0, 10], "rotation": 180, "texture": "#6"} } }, + { + "name": "Back", + "from": [3, 0.1, 3], + "to": [13, 2.1, 13], + "faces": { + "north": {"uv": [3, 16, 13, 14], "rotation": 180, "texture": "#5"}, + "east": {"uv": [3, 16, 13, 14], "rotation": 180, "texture": "#5"}, + "south": {"uv": [3, 16, 13, 14], "rotation": 180, "texture": "#5"}, + "west": {"uv": [3, 16, 13, 14], "rotation": 180, "texture": "#5"}, + "up": {"uv": [10, 0, 0, 10], "texture": "#6"}, + "down": {"uv": [10, 0, 0, 10], "rotation": 180, "texture": "#6"} + } + }, { "name": "Between Rims", "from": [5, 9, 5], @@ -89,14 +101,14 @@ }, { "name": "Between Rims", - "from": [3.5, 5, 3.5], - "to": [12.5, 8, 12.5], + "from": [3.5, 2, 3.5], + "to": [12.5, 5, 12.5], "rotation": {"angle": 0, "axis": "y", "origin": [8, 10, 8]}, "faces": { - "north": {"uv": [3, 10, 12, 13], "texture": "#6"}, - "east": {"uv": [3, 10, 12, 13], "texture": "#6"}, - "south": {"uv": [3, 10, 12, 13], "texture": "#6"}, - "west": {"uv": [3, 10, 12, 13], "texture": "#6"} + "north": {"uv": [3.5, 10, 12.5, 13], "texture": "#6"}, + "east": {"uv": [3.5, 10, 12.5, 13], "texture": "#6"}, + "south": {"uv": [3.5, 10, 12.5, 13], "texture": "#6"}, + "west": {"uv": [3.5, 10, 12.5, 13], "texture": "#6"} } }, { @@ -113,15 +125,28 @@ } }, { - "from": [3, 0.2, 3], - "to": [13, 4, 13], + "from": [3, 4, 5], + "to": [13, 10, 11], "faces": { - "north": {"uv": [5, 0, 15, 4], "texture": "#7"}, - "east": {"uv": [5, 0, 15, 4], "texture": "#7"}, - "south": {"uv": [5, 0, 15, 4], "texture": "#7"}, - "west": {"uv": [3, 0, 13, 4], "rotation": 180, "texture": "#7"}, - "up": {"uv": [10, 10, 0, 0], "rotation": 90, "texture": "#6"}, - "down": {"uv": [10, 10, 0, 0], "rotation": 180, "texture": "#6"} + "north": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "east": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "south": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "west": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "up": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "down": {"uv": [10, 0, 16, 6], "texture": "#6"} + } + }, + { + "from": [5, 4, 3], + "to": [11, 10, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 7, 8]}, + "faces": { + "north": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "east": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "south": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "west": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "up": {"uv": [10, 0, 16, 6], "rotation": 90, "texture": "#6"}, + "down": {"uv": [10, 0, 16, 6], "rotation": 270, "texture": "#6"} } } ], @@ -146,6 +171,8 @@ "origin": [8, 8, 8], "color": 0, "children": [] - } + }, + 9, + 10 ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/creative_motor/item.json b/src/main/resources/assets/create/models/block/creative_motor/item.json index 96da6b25b..218ed3c79 100644 --- a/src/main/resources/assets/create/models/block/creative_motor/item.json +++ b/src/main/resources/assets/create/models/block/creative_motor/item.json @@ -5,11 +5,25 @@ "5": "create:block/creative_casing", "6": "create:block/creative_motor", "7": "create:block/flap_display_front", + "1_1": "create:block/axis_top", "particle": "create:block/creative_casing", - "1_0": "create:block/axis", - "1_1": "create:block/axis_top" + "1_0": "create:block/axis" }, "elements": [ + { + "name": "Axis", + "from": [6, 6, 6], + "to": [10, 10, 16], + "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#1_1"}, + "east": {"uv": [6, 0, 10, 10], "rotation": 270, "texture": "#1_0"}, + "south": {"uv": [6, 6, 10, 10], "texture": "#1_1"}, + "west": {"uv": [6, 0, 10, 10], "rotation": 90, "texture": "#1_0"}, + "up": {"uv": [6, 0, 10, 10], "rotation": 180, "texture": "#1_0"}, + "down": {"uv": [6, 0, 10, 10], "texture": "#1_0"} + } + }, { "name": "Back", "from": [3, 3, 0.1], @@ -51,13 +65,13 @@ }, { "name": "Between Rims", - "from": [3.5, 3.5, 3], - "to": [12.5, 12.5, 6], + "from": [3.5, 3.5, 2], + "to": [12.5, 12.5, 5], "faces": { - "east": {"uv": [3, 10, 12, 13], "rotation": 270, "texture": "#6"}, - "west": {"uv": [3, 10, 12, 13], "rotation": 90, "texture": "#6"}, - "up": {"uv": [3, 10, 12, 13], "rotation": 180, "texture": "#6"}, - "down": {"uv": [3, 10, 12, 13], "texture": "#6"} + "east": {"uv": [3.5, 10, 12.5, 13], "rotation": 270, "texture": "#6"}, + "west": {"uv": [3.5, 10, 12.5, 13], "rotation": 90, "texture": "#6"}, + "up": {"uv": [3.5, 10, 12.5, 13], "rotation": 180, "texture": "#6"}, + "down": {"uv": [3.5, 10, 12.5, 13], "texture": "#6"} } }, { @@ -134,17 +148,27 @@ } }, { - "name": "Axis", - "from": [6, 6, 6], - "to": [10, 10, 16], - "rotation": {"angle": 22.5, "axis": "z", "origin": [8, 8, 8]}, + "from": [5, 7, 4], + "to": [11, 13, 10], "faces": { - "north": {"uv": [6, 6, 10, 10], "rotation": 180, "texture": "#1_1"}, - "east": {"uv": [6, 0, 10, 10], "rotation": 270, "texture": "#1_0"}, - "south": {"uv": [6, 6, 10, 10], "texture": "#1_1"}, - "west": {"uv": [6, 0, 10, 10], "rotation": 90, "texture": "#1_0"}, - "up": {"uv": [6, 0, 10, 10], "rotation": 180, "texture": "#1_0"}, - "down": {"uv": [6, 0, 10, 10], "texture": "#1_0"} + "north": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "east": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "south": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "west": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "up": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "down": {"uv": [10, 0, 16, 6], "texture": "#6"} + } + }, + { + "from": [3, 5, 4], + "to": [13, 11, 10], + "faces": { + "north": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "east": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "south": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "west": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "up": {"uv": [10, 0, 16, 6], "texture": "#6"}, + "down": {"uv": [10, 0, 16, 6], "texture": "#6"} } } ], @@ -155,21 +179,36 @@ } }, "groups": [ - 0, - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, { "name": "shaft", "origin": [8, 8, 8], "color": 0, - "children": [10] + "children": [0] + }, + { + "name": "block", + "origin": [8, 8, 8], + "color": 0, + "children": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + { + "name": "shaft", + "origin": [8, 8, 8], + "color": 0, + "children": [] + }, + 11, + 12 + ] } ] } \ No newline at end of file diff --git a/src/main/resources/assets/create/models/block/mechanical_arm/block.json b/src/main/resources/assets/create/models/block/mechanical_arm/block.json index f993e6e31..1e184552f 100644 --- a/src/main/resources/assets/create/models/block/mechanical_arm/block.json +++ b/src/main/resources/assets/create/models/block/mechanical_arm/block.json @@ -2,7 +2,7 @@ "credit": "Made with Blockbench", "parent": "block/block", "textures": { - "3": "create:block/belt/brass_belt_casing_sideways", + "3": "create:block/mechanical_arm_side", "7": "create:block/brass_block", "particle": "create:block/crafter_top" }, @@ -12,10 +12,10 @@ "from": [0, 0, 0], "to": [16, 6, 16], "faces": { - "north": {"uv": [0, 6.5, 8, 9.5], "texture": "#3"}, - "east": {"uv": [0, 6.5, 8, 9.5], "texture": "#3"}, - "south": {"uv": [0, 6.5, 8, 9.5], "texture": "#3"}, - "west": {"uv": [0, 6.5, 8, 9.5], "texture": "#3"}, + "north": {"uv": [0, 0, 16, 6], "texture": "#3"}, + "east": {"uv": [0, 0, 16, 6], "texture": "#3"}, + "south": {"uv": [0, 0, 16, 6], "texture": "#3"}, + "west": {"uv": [0, 0, 16, 6], "texture": "#3"}, "up": {"uv": [0, 0, 16, 16], "texture": "#7"}, "down": {"uv": [0, 0, 16, 16], "texture": "#7"} } diff --git a/src/main/resources/assets/create/models/item/filter.json b/src/main/resources/assets/create/models/item/filter.json index 2ceff938f..d4ba74a71 100644 --- a/src/main/resources/assets/create/models/item/filter.json +++ b/src/main/resources/assets/create/models/item/filter.json @@ -8,103 +8,108 @@ "elements": [ { "name": "siderim", - "from": [13, 0, 3], - "to": [15, 2, 13], + "from": [5, -0.25, 6], + "to": [6, 0.75, 10], "faces": { - "north": {"uv": [14, 0, 16, 2], "texture": "#0"}, - "east": {"uv": [0, 0, 2, 10], "rotation": 90, "texture": "#0"}, - "south": {"uv": [14, 0, 16, 2], "rotation": 180, "texture": "#0"}, - "west": {"uv": [14, 10, 16, 0], "rotation": 270, "texture": "#0"}, - "up": {"uv": [14, 0, 16, 10], "rotation": 180, "texture": "#0"}, - "down": {"uv": [14, 0, 16, 10], "rotation": 180, "texture": "#0"} + "north": {"uv": [15, 0, 16, 1], "texture": "#0"}, + "east": {"uv": [14, 7, 15, 3], "rotation": 270, "texture": "#0"}, + "south": {"uv": [15, 0, 16, 1], "texture": "#0"}, + "west": {"uv": [15, 8, 16, 4], "rotation": 270, "texture": "#0"}, + "up": {"uv": [15, 4, 16, 8], "rotation": 180, "texture": "#0"}, + "down": {"uv": [15, 4, 14, 8], "rotation": 180, "texture": "#0"} } }, { "name": "siderim", - "from": [1, 0, 3], - "to": [3, 2, 13], + "from": [10, -0.25, 6], + "to": [11, 0.75, 10], "faces": { - "north": {"uv": [16, 0, 14, 2], "texture": "#0"}, - "east": {"uv": [14, 0, 16, 10], "rotation": 270, "texture": "#0"}, - "south": {"uv": [16, 0, 14, 2], "rotation": 180, "texture": "#0"}, - "west": {"uv": [0, 10, 2, 0], "rotation": 90, "texture": "#0"}, - "up": {"uv": [16, 0, 14, 10], "rotation": 180, "texture": "#0"}, - "down": {"uv": [16, 0, 14, 10], "rotation": 180, "texture": "#0"} + "north": {"uv": [15, 0, 16, 1], "texture": "#0"}, + "east": {"uv": [15, 8, 16, 4], "rotation": 270, "texture": "#0"}, + "south": {"uv": [15, 0, 16, 1], "texture": "#0"}, + "west": {"uv": [14, 7, 15, 3], "rotation": 270, "texture": "#0"}, + "up": {"uv": [15, 5, 16, 9], "rotation": 180, "texture": "#0"}, + "down": {"uv": [15, 4, 14, 8], "rotation": 180, "texture": "#0"} } }, { "name": "net", - "from": [3, 1, 4], - "to": [13, 1.1, 12], + "from": [6, 0.5, 6], + "to": [10, 0.6, 10], "faces": { - "north": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "east": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "south": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "west": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "up": {"uv": [2.5, 0.5, 12.5, 8.5], "texture": "#0"}, - "down": {"uv": [2.5, 0.5, 12.5, 8.5], "texture": "#0"} + "north": {"uv": [0, 0, 4, 0.1], "texture": "#0"}, + "east": {"uv": [0, 0, 4, 0.1], "texture": "#0"}, + "south": {"uv": [0, 0, 4, 0.1], "texture": "#0"}, + "west": {"uv": [0, 0, 4, 0.1], "texture": "#0"}, + "up": {"uv": [2, 0, 6, 4], "texture": "#0"}, + "down": {"uv": [2.5, 0.5, 6.5, 4.5], "texture": "#0"} } }, { "name": "toprim", - "from": [3, 0.5, 3], - "to": [13, 1.5, 4], + "from": [5, -0.25, 5], + "to": [11, 0.75, 6], "faces": { - "north": {"uv": [3, 9, 13, 10], "texture": "#0"}, - "east": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "south": {"uv": [3, 9, 13, 10], "rotation": 180, "texture": "#0"}, - "west": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "up": {"uv": [3, 9, 13, 10], "rotation": 180, "texture": "#0"}, - "down": {"uv": [3, 9, 13, 10], "rotation": 180, "texture": "#0"} + "north": {"uv": [3, 9, 9, 10], "texture": "#0"}, + "east": {"uv": [12, 9, 13, 10], "texture": "#0"}, + "south": {"uv": [3, 9, 9, 10], "rotation": 180, "texture": "#0"}, + "west": {"uv": [12, 9, 13, 10], "texture": "#0"}, + "up": {"uv": [3, 9, 9, 10], "rotation": 180, "texture": "#0"}, + "down": {"uv": [3, 9, 9, 10], "rotation": 180, "texture": "#0"} } }, { "name": "toprim", - "from": [3, 0.5, 12], - "to": [13, 1.5, 13], + "from": [5, -0.25, 10], + "to": [11, 0.75, 11], "faces": { - "north": {"uv": [3, 9, 13, 10], "texture": "#0"}, - "east": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "south": {"uv": [3, 9, 13, 10], "rotation": 180, "texture": "#0"}, - "west": {"uv": [0, 0, 0, 0], "texture": "#0"}, - "up": {"uv": [3, 9, 13, 10], "rotation": 180, "texture": "#0"}, - "down": {"uv": [3, 9, 13, 10], "rotation": 180, "texture": "#0"} + "north": {"uv": [3, 9, 9, 10], "texture": "#0"}, + "east": {"uv": [12, 9, 13, 10], "texture": "#0"}, + "south": {"uv": [5, 9, 11, 10], "rotation": 180, "texture": "#0"}, + "west": {"uv": [12, 9, 13, 10], "texture": "#0"}, + "up": {"uv": [5, 9, 11, 10], "rotation": 180, "texture": "#0"}, + "down": {"uv": [3, 9, 9, 10], "rotation": 180, "texture": "#0"} } } ], "display": { "thirdperson_righthand": { "rotation": [75, -180, 0], - "translation": [-2.75, 3.25, 3.25], - "scale": [0.5, 0.5, 0.5] + "translation": [-2.75, 2, 4.75], + "scale": [0.6, 0.6, 0.6] }, "thirdperson_lefthand": { "rotation": [75, -180, 0], - "translation": [-2.75, 3.25, 3.25], - "scale": [0.5, 0.5, 0.5] + "translation": [-2.75, 2, 4.75], + "scale": [0.6, 0.6, 0.6] }, "firstperson_righthand": { "rotation": [75, -180, 0], - "translation": [-2.75, 3.25, 3.25], - "scale": [0.5, 0.5, 0.5] + "translation": [2.25, 1.5, 4.75], + "scale": [1.35, 1.35, 1.35] }, "firstperson_lefthand": { "rotation": [75, -180, 0], - "translation": [-2.75, 3.25, 3.25], - "scale": [0.5, 0.5, 0.5] + "translation": [2.25, 1.5, 4.75], + "scale": [1.35, 1.35, 1.35] }, "ground": { "translation": [0, 3, 0], - "scale": [0.5, 0.5, 0.5] + "scale": [0.76, 0.76, 0.76] }, "gui": { "rotation": [30, 225, 0], - "translation": [0, 4.25, 0], - "scale": [0.75, 0.75, 0.75] + "translation": [0, 9.5, 0], + "scale": [1.5, 1.5, 1.5] + }, + "head": { + "translation": [0, 18.25, 0], + "scale": [1.43, 1.43, 1.43] }, "fixed": { - "rotation": [90, -180, 0], - "translation": [0, 0, 6.5] + "rotation": [90, 0, 179.5], + "translation": [0, 0, -15], + "scale": [2.04, 2.04, 2.04] } } } \ No newline at end of file diff --git a/src/main/resources/assets/create/textures/block/clockwork_bearing_side.png b/src/main/resources/assets/create/textures/block/clockwork_bearing_side.png index 1ba96af8e..745a1c534 100644 Binary files a/src/main/resources/assets/create/textures/block/clockwork_bearing_side.png and b/src/main/resources/assets/create/textures/block/clockwork_bearing_side.png differ diff --git a/src/main/resources/assets/create/textures/block/creative_motor.png b/src/main/resources/assets/create/textures/block/creative_motor.png index f621901d9..ad21b2f3f 100644 Binary files a/src/main/resources/assets/create/textures/block/creative_motor.png and b/src/main/resources/assets/create/textures/block/creative_motor.png differ diff --git a/src/main/resources/assets/create/textures/block/mechanical_arm_side.png b/src/main/resources/assets/create/textures/block/mechanical_arm_side.png new file mode 100644 index 000000000..a40927d0f Binary files /dev/null and b/src/main/resources/assets/create/textures/block/mechanical_arm_side.png differ diff --git a/src/main/resources/assets/create/textures/block/mechanical_bearing_side.png b/src/main/resources/assets/create/textures/block/mechanical_bearing_side.png index 961062887..e414bc159 100644 Binary files a/src/main/resources/assets/create/textures/block/mechanical_bearing_side.png and b/src/main/resources/assets/create/textures/block/mechanical_bearing_side.png differ diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 7e06ef746..6e1736439 100644 Binary files a/src/main/resources/assets/create/textures/gui/icons.png and b/src/main/resources/assets/create/textures/gui/icons.png differ diff --git a/src/main/resources/assets/create/textures/gui/logistics_2.png b/src/main/resources/assets/create/textures/gui/logistics_2.png deleted file mode 100644 index 91be00d6b..000000000 Binary files a/src/main/resources/assets/create/textures/gui/logistics_2.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/projector.png b/src/main/resources/assets/create/textures/gui/projector.png deleted file mode 100644 index 88229482b..000000000 Binary files a/src/main/resources/assets/create/textures/gui/projector.png and /dev/null differ diff --git a/src/main/resources/assets/create/textures/gui/value_settings.png b/src/main/resources/assets/create/textures/gui/value_settings.png new file mode 100644 index 000000000..1ff6889ef Binary files /dev/null and b/src/main/resources/assets/create/textures/gui/value_settings.png differ diff --git a/src/main/resources/assets/create/textures/item/filter.png b/src/main/resources/assets/create/textures/item/filter.png index 7eaf03887..fd7fad265 100644 Binary files a/src/main/resources/assets/create/textures/item/filter.png and b/src/main/resources/assets/create/textures/item/filter.png differ diff --git a/src/main/resources/assets/create/textures/item/property_filter.png b/src/main/resources/assets/create/textures/item/property_filter.png index 56f533110..695608a8a 100644 Binary files a/src/main/resources/assets/create/textures/item/property_filter.png and b/src/main/resources/assets/create/textures/item/property_filter.png differ