mirror of
https://github.com/Creators-of-Create/Create.git
synced 2025-01-14 08:16:42 +01:00
Don't open sesame
- Added door controls to elevator contact and train station UI
This commit is contained in:
parent
a3e7dd5ced
commit
68eccd1d51
19 changed files with 366 additions and 41 deletions
|
@ -566,7 +566,7 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
|
|||
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
|
||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||
3054a5519fbf91481b0c9c8160a20679fa9530da assets/create/lang/en_ud.json
|
||||
8db7da2dab7745aa409e536d7a36cbe9fcce21a4 assets/create/lang/en_us.json
|
||||
093dfa9846e481071cd27239b4d66760848b160e 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
|
||||
|
|
|
@ -1654,6 +1654,20 @@
|
|||
"create.contraption.controls.actor_toggle.on": "On",
|
||||
"create.contraption.controls.actor_toggle.off": "Off",
|
||||
"create.contraption.controls.floor_unreachable": "Unreachable",
|
||||
"create.contraption.door_control": "Onboard Door Control",
|
||||
"create.contraption.door_control.all": "Open All Doors",
|
||||
"create.contraption.door_control.all.short": "Open All",
|
||||
"create.contraption.door_control.north": "North Side Only",
|
||||
"create.contraption.door_control.north.short": "North",
|
||||
"create.contraption.door_control.east": "East Side Only",
|
||||
"create.contraption.door_control.east.short": "East",
|
||||
"create.contraption.door_control.south": "South Side Only",
|
||||
"create.contraption.door_control.south.short": "South",
|
||||
"create.contraption.door_control.west": "West Side Only",
|
||||
"create.contraption.door_control.west.short": "West",
|
||||
"create.contraption.door_control.none": "Keep Doors Closed",
|
||||
"create.contraption.door_control.none.short": "None",
|
||||
"create.contraption.door_control.player_facing": "You are facing: %1$s",
|
||||
|
||||
"create.display_link.set": "Targeted position selected",
|
||||
"create.display_link.success": "Successfully bound to targeted position",
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
package com.simibubi.create.content.contraptions.components.actors;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.simibubi.create.foundation.gui.widget.Label;
|
||||
import com.simibubi.create.foundation.gui.widget.ScrollInput;
|
||||
import com.simibubi.create.foundation.gui.widget.SelectionScrollInput;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public enum DoorControl {
|
||||
|
||||
ALL, NORTH, EAST, SOUTH, WEST, NONE;
|
||||
|
||||
private static String[] valuesAsString() {
|
||||
DoorControl[] values = values();
|
||||
return Arrays.stream(values)
|
||||
.map(dc -> Lang.asId(dc.name()))
|
||||
.toList()
|
||||
.toArray(new String[values.length]);
|
||||
}
|
||||
|
||||
public boolean matches(Direction doorDirection) {
|
||||
return switch (this) {
|
||||
case ALL -> true;
|
||||
case NORTH -> doorDirection == Direction.NORTH;
|
||||
case EAST -> doorDirection == Direction.EAST;
|
||||
case SOUTH -> doorDirection == Direction.SOUTH;
|
||||
case WEST -> doorDirection == Direction.WEST;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public static Pair<ScrollInput, Label> createWidget(int x, int y, Consumer<DoorControl> callback,
|
||||
DoorControl initial) {
|
||||
|
||||
DoorControl playerFacing = NONE;
|
||||
Entity cameraEntity = Minecraft.getInstance().cameraEntity;
|
||||
if (cameraEntity != null) {
|
||||
Direction direction = cameraEntity.getDirection();
|
||||
if (direction == Direction.EAST)
|
||||
playerFacing = EAST;
|
||||
if (direction == Direction.WEST)
|
||||
playerFacing = WEST;
|
||||
if (direction == Direction.NORTH)
|
||||
playerFacing = NORTH;
|
||||
if (direction == Direction.SOUTH)
|
||||
playerFacing = SOUTH;
|
||||
}
|
||||
|
||||
Label label = new Label(x + 4, y + 6, Components.empty()).withShadow();
|
||||
ScrollInput input = new SelectionScrollInput(x, y, 53, 16)
|
||||
.forOptions(Lang.translatedOptions("contraption.door_control", valuesAsString()))
|
||||
.titled(Lang.translateDirect("contraption.door_control"))
|
||||
.calling(s -> {
|
||||
DoorControl mode = values()[s];
|
||||
label.text = Lang.translateDirect("contraption.door_control." + Lang.asId(mode.name()) + ".short");
|
||||
callback.accept(mode);
|
||||
})
|
||||
.addHint(Lang.translateDirect("contraption.door_control.player_facing",
|
||||
Lang.translateDirect("contraption.door_control." + Lang.asId(playerFacing.name()) + ".short")))
|
||||
.setState(initial.ordinal());
|
||||
input.onChanged();
|
||||
return Pair.of(input, label);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.simibubi.create.content.contraptions.components.actors;
|
||||
|
||||
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.utility.NBTHelper;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class DoorControlBehaviour extends BlockEntityBehaviour {
|
||||
|
||||
public static final BehaviourType<DoorControlBehaviour> TYPE = new BehaviourType<>();
|
||||
|
||||
public DoorControl mode;
|
||||
|
||||
public DoorControlBehaviour(SmartBlockEntity be) {
|
||||
super(be);
|
||||
mode = DoorControl.ALL;
|
||||
}
|
||||
|
||||
public void set(DoorControl mode) {
|
||||
if (this.mode == mode)
|
||||
return;
|
||||
this.mode = mode;
|
||||
blockEntity.notifyUpdate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(CompoundTag nbt, boolean clientPacket) {
|
||||
NBTHelper.writeEnum(nbt, "DoorControl", mode);
|
||||
super.write(nbt, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void read(CompoundTag nbt, boolean clientPacket) {
|
||||
mode = NBTHelper.readEnum(nbt, "DoorControl", DoorControl.class);
|
||||
super.read(nbt, clientPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
|
@ -212,7 +212,8 @@ public class ElevatorContactBlock extends WrenchableDirectionalBlock
|
|||
@OnlyIn(value = Dist.CLIENT)
|
||||
protected void displayScreen(ElevatorContactBlockEntity be, Player player) {
|
||||
if (player instanceof LocalPlayer)
|
||||
ScreenOpener.open(new ElevatorContactScreen(be.getBlockPos(), be.shortName, be.longName));
|
||||
ScreenOpener
|
||||
.open(new ElevatorContactScreen(be.getBlockPos(), be.shortName, be.longName, be.doorControls.mode));
|
||||
}
|
||||
|
||||
public static int getLight(BlockState state) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.el
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControlBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn.ColumnCoords;
|
||||
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||
|
@ -16,6 +17,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
|||
|
||||
public class ElevatorContactBlockEntity extends SmartBlockEntity {
|
||||
|
||||
public DoorControlBehaviour doorControls;
|
||||
public ColumnCoords columnCoords;
|
||||
public boolean activateBlock;
|
||||
|
||||
|
@ -35,7 +37,9 @@ public class ElevatorContactBlockEntity extends SmartBlockEntity {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {}
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(doorControls = new DoorControlBehaviour(this));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void write(CompoundTag tag, boolean clientPacket) {
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
package com.simibubi.create.content.contraptions.components.structureMovement.elevator;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControl;
|
||||
import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.util.Mth;
|
||||
|
||||
public class ElevatorContactEditPacket extends BlockEntityConfigurationPacket<ElevatorContactBlockEntity> {
|
||||
|
||||
private String shortName;
|
||||
private String longName;
|
||||
private DoorControl doorControl;
|
||||
|
||||
public ElevatorContactEditPacket(BlockPos pos, String shortName, String longName) {
|
||||
public ElevatorContactEditPacket(BlockPos pos, String shortName, String longName, DoorControl doorControl) {
|
||||
super(pos);
|
||||
this.shortName = shortName;
|
||||
this.longName = longName;
|
||||
this.doorControl = doorControl;
|
||||
}
|
||||
|
||||
public ElevatorContactEditPacket(FriendlyByteBuf buffer) {
|
||||
|
@ -24,17 +28,20 @@ public class ElevatorContactEditPacket extends BlockEntityConfigurationPacket<El
|
|||
protected void writeSettings(FriendlyByteBuf buffer) {
|
||||
buffer.writeUtf(shortName, 4);
|
||||
buffer.writeUtf(longName, 30);
|
||||
buffer.writeVarInt(doorControl.ordinal());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readSettings(FriendlyByteBuf buffer) {
|
||||
shortName = buffer.readUtf(4);
|
||||
longName = buffer.readUtf(30);
|
||||
doorControl = DoorControl.values()[Mth.clamp(buffer.readVarInt(), 0, DoorControl.values().length)];
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applySettings(ElevatorContactBlockEntity be) {
|
||||
be.updateName(shortName, longName);
|
||||
be.doorControls.set(doorControl);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,15 +5,19 @@ import org.lwjgl.glfw.GLFW;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControl;
|
||||
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.element.GuiGameElement;
|
||||
import com.simibubi.create.foundation.gui.widget.IconButton;
|
||||
import com.simibubi.create.foundation.gui.widget.Label;
|
||||
import com.simibubi.create.foundation.gui.widget.ScrollInput;
|
||||
import com.simibubi.create.foundation.gui.widget.TooltipArea;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
|
@ -31,12 +35,14 @@ public class ElevatorContactScreen extends AbstractSimiScreen {
|
|||
|
||||
private String shortName;
|
||||
private String longName;
|
||||
private DoorControl doorControl;
|
||||
|
||||
private BlockPos pos;
|
||||
|
||||
public ElevatorContactScreen(BlockPos pos, String prevShortName, String prevLongName) {
|
||||
public ElevatorContactScreen(BlockPos pos, String prevShortName, String prevLongName, DoorControl prevDoorControl) {
|
||||
super(Lang.translateDirect("elevator_contact.title"));
|
||||
this.pos = pos;
|
||||
this.doorControl = prevDoorControl;
|
||||
background = AllGuiTextures.ELEVATOR_CONTACT;
|
||||
this.shortName = prevShortName;
|
||||
this.longName = prevLongName;
|
||||
|
@ -88,6 +94,10 @@ public class ElevatorContactScreen extends AbstractSimiScreen {
|
|||
.component(),
|
||||
rmbToEdit)));
|
||||
|
||||
Pair<ScrollInput, Label> doorControlWidgets =
|
||||
DoorControl.createWidget(x + 58, y + 57, mode -> doorControl = mode, doorControl);
|
||||
addRenderableWidget(doorControlWidgets.getFirst());
|
||||
addRenderableWidget(doorControlWidgets.getSecond());
|
||||
}
|
||||
|
||||
private int centerInput(int x) {
|
||||
|
@ -122,6 +132,7 @@ public class ElevatorContactScreen extends AbstractSimiScreen {
|
|||
.scale(5)
|
||||
.render(ms);
|
||||
|
||||
itemRenderer.renderGuiItem(AllBlocks.TRAIN_DOOR.asStack(), x + 37, y + 58);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -164,7 +175,8 @@ public class ElevatorContactScreen extends AbstractSimiScreen {
|
|||
}
|
||||
|
||||
private void confirm() {
|
||||
AllPackets.getChannel().sendToServer(new ElevatorContactEditPacket(pos, shortName, longName));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(new ElevatorContactEditPacket(pos, shortName, longName, doorControl));
|
||||
onClose();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
package com.simibubi.create.content.curiosities.deco;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Map;
|
||||
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControl;
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControlBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorColumn.ColumnCoords;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.elevator.ElevatorContraption;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
||||
import com.simibubi.create.content.logistics.trains.entity.CarriageSyncData;
|
||||
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
|
||||
import com.simibubi.create.foundation.blockEntity.BlockEntityBehaviour;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.AxisDirection;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.DoorBlock;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
|
||||
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate.StructureBlockInfo;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public class SlidingDoorMovementBehaviour implements MovementBehaviour {
|
||||
|
||||
|
@ -105,14 +119,90 @@ public class SlidingDoorMovementBehaviour implements MovementBehaviour {
|
|||
protected boolean shouldOpen(MovementContext context) {
|
||||
if (context.disabled)
|
||||
return false;
|
||||
if (context.contraption instanceof ElevatorContraption ec && ec.arrived)
|
||||
return true;
|
||||
if (context.contraption.entity instanceof CarriageContraptionEntity cce) {
|
||||
CarriageSyncData carriageData = cce.getCarriageData();
|
||||
if (Math.abs(carriageData.distanceToDestination) > 1)
|
||||
Contraption contraption = context.contraption;
|
||||
boolean canOpen = context.motion.length() < 1 / 128f && !contraption.entity.isStalled()
|
||||
|| contraption instanceof ElevatorContraption ec && ec.arrived;
|
||||
|
||||
if (!canOpen) {
|
||||
context.temporaryData = null;
|
||||
return false;
|
||||
}
|
||||
return context.motion.length() < 1 / 128f && !context.contraption.entity.isStalled();
|
||||
|
||||
if (context.temporaryData instanceof WeakReference<?> wr && wr.get()instanceof DoorControlBehaviour dcb)
|
||||
if (dcb.blockEntity != null && !dcb.blockEntity.isRemoved())
|
||||
return shouldOpenAt(dcb, context);
|
||||
|
||||
context.temporaryData = null;
|
||||
DoorControlBehaviour doorControls = null;
|
||||
|
||||
if (contraption instanceof ElevatorContraption ec)
|
||||
doorControls = getElevatorDoorControl(ec, context);
|
||||
if (context.contraption.entity instanceof CarriageContraptionEntity cce)
|
||||
doorControls = getTrainStationDoorControl(cce, context);
|
||||
|
||||
if (doorControls == null)
|
||||
return false;
|
||||
|
||||
context.temporaryData = new WeakReference<>(doorControls);
|
||||
return shouldOpenAt(doorControls, context);
|
||||
}
|
||||
|
||||
protected boolean shouldOpenAt(DoorControlBehaviour controller, MovementContext context) {
|
||||
if (controller.mode == DoorControl.ALL)
|
||||
return true;
|
||||
if (controller.mode == DoorControl.NONE)
|
||||
return false;
|
||||
return controller.mode.matches(getDoorFacing(context));
|
||||
}
|
||||
|
||||
protected DoorControlBehaviour getElevatorDoorControl(ElevatorContraption ec, MovementContext context) {
|
||||
Integer currentTargetY = ec.getCurrentTargetY(context.world);
|
||||
if (currentTargetY == null)
|
||||
return null;
|
||||
ColumnCoords columnCoords = ec.getGlobalColumn();
|
||||
if (columnCoords == null)
|
||||
return null;
|
||||
ElevatorColumn elevatorColumn = ElevatorColumn.get(context.world, columnCoords);
|
||||
if (elevatorColumn == null)
|
||||
return null;
|
||||
return BlockEntityBehaviour.get(context.world, elevatorColumn.contactAt(currentTargetY),
|
||||
DoorControlBehaviour.TYPE);
|
||||
}
|
||||
|
||||
protected DoorControlBehaviour getTrainStationDoorControl(CarriageContraptionEntity cce, MovementContext context) {
|
||||
Carriage carriage = cce.getCarriage();
|
||||
if (carriage == null || carriage.train == null)
|
||||
return null;
|
||||
GlobalStation currentStation = carriage.train.getCurrentStation();
|
||||
if (currentStation == null)
|
||||
return null;
|
||||
|
||||
BlockPos stationPos = currentStation.getBlockEntityPos();
|
||||
ResourceKey<Level> stationDim = currentStation.getBlockEntityDimension();
|
||||
MinecraftServer server = context.world.getServer();
|
||||
if (server == null)
|
||||
return null;
|
||||
ServerLevel stationLevel = server.getLevel(stationDim);
|
||||
if (stationLevel == null || !stationLevel.isLoaded(stationPos))
|
||||
return null;
|
||||
return BlockEntityBehaviour.get(stationLevel, stationPos, DoorControlBehaviour.TYPE);
|
||||
}
|
||||
|
||||
protected Direction getDoorFacing(MovementContext context) {
|
||||
Direction stateFacing = context.state.getValue(DoorBlock.FACING);
|
||||
Direction originalFacing = Direction.get(AxisDirection.POSITIVE, stateFacing.getAxis());
|
||||
Vec3 centerOfContraption = context.contraption.bounds.getCenter();
|
||||
Vec3 diff = Vec3.atCenterOf(context.localPos)
|
||||
.add(Vec3.atLowerCornerOf(stateFacing.getNormal())
|
||||
.scale(-.45f))
|
||||
.subtract(centerOfContraption);
|
||||
if (originalFacing.getAxis()
|
||||
.choose(diff.x, diff.y, diff.z) < 0)
|
||||
originalFacing = originalFacing.getOpposite();
|
||||
|
||||
Vec3 directionVec = Vec3.atLowerCornerOf(originalFacing.getNormal());
|
||||
directionVec = context.rotation.apply(directionVec);
|
||||
return Direction.getNearest(directionVec.x, directionVec.y, directionVec.z);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -65,14 +65,16 @@ public class AssemblyScreen extends AbstractStationScreen {
|
|||
toggleAssemblyButton.active = false;
|
||||
toggleAssemblyButton.setToolTip(Lang.translateDirect("station.assemble_train"));
|
||||
toggleAssemblyButton.withCallback(() -> {
|
||||
AllPackets.getChannel().sendToServer(StationEditPacket.tryAssemble(blockEntity.getBlockPos()));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.tryAssemble(blockEntity.getBlockPos()));
|
||||
});
|
||||
|
||||
quitAssembly = new IconButton(x + 73, by, AllIcons.I_DISABLE);
|
||||
quitAssembly.active = true;
|
||||
quitAssembly.setToolTip(Lang.translateDirect("station.cancel"));
|
||||
quitAssembly.withCallback(() -> {
|
||||
AllPackets.getChannel().sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, station.name));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, station.name, null));
|
||||
minecraft.setScreen(new StationScreen(blockEntity, station));
|
||||
});
|
||||
|
||||
|
@ -90,7 +92,8 @@ public class AssemblyScreen extends AbstractStationScreen {
|
|||
toggleAssemblyButton.active = blockEntity.bogeyCount > 0 || train != null;
|
||||
|
||||
if (train != null) {
|
||||
AllPackets.getChannel().sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, station.name));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, station.name, null));
|
||||
minecraft.setScreen(new StationScreen(blockEntity, station));
|
||||
for (Carriage carriage : train.carriages)
|
||||
carriage.updateConductors();
|
||||
|
@ -105,10 +108,12 @@ public class AssemblyScreen extends AbstractStationScreen {
|
|||
toggleAssemblyButton.setToolTip(Lang.translateDirect("station.assemble_train"));
|
||||
toggleAssemblyButton.setIcon(AllGuiTextures.I_ASSEMBLE_TRAIN);
|
||||
toggleAssemblyButton.withCallback(() -> {
|
||||
AllPackets.getChannel().sendToServer(StationEditPacket.tryAssemble(blockEntity.getBlockPos()));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.tryAssemble(blockEntity.getBlockPos()));
|
||||
});
|
||||
} else {
|
||||
AllPackets.getChannel().sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, station.name));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, station.name, null));
|
||||
minecraft.setScreen(new StationScreen(blockEntity, station));
|
||||
}
|
||||
}
|
||||
|
@ -128,8 +133,8 @@ public class AssemblyScreen extends AbstractStationScreen {
|
|||
font.draw(ms, text, x + 97 - font.width(text) / 2, y + 47, 0x775B5B);
|
||||
int offset = 0;
|
||||
if (blockEntity.failedCarriageIndex != -1) {
|
||||
font.draw(ms, Lang.translateDirect("station.carriage_number", blockEntity.failedCarriageIndex), x + 30, y + 67,
|
||||
0x7A7A7A);
|
||||
font.draw(ms, Lang.translateDirect("station.carriage_number", blockEntity.failedCarriageIndex), x + 30,
|
||||
y + 67, 0x7A7A7A);
|
||||
offset += 10;
|
||||
}
|
||||
font.drawWordWrap(lastAssemblyException.component, x + 30, y + 67 + offset, 134, 0x775B5B);
|
||||
|
@ -158,7 +163,8 @@ public class AssemblyScreen extends AbstractStationScreen {
|
|||
if (train != null) {
|
||||
ResourceLocation iconId = iconTypes.get(iconTypeScroll.getState());
|
||||
train.icon = TrainIconType.byId(iconId);
|
||||
AllPackets.getChannel().sendToServer(new TrainEditPacket(train.id, "", iconId));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(new TrainEditPacket(train.id, "", iconId));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import com.simibubi.create.AllBlocks;
|
|||
import com.simibubi.create.AllItems;
|
||||
import com.simibubi.create.AllSoundEvents;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControlBehaviour;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableBlockEntity;
|
||||
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
||||
|
@ -80,6 +81,7 @@ import net.minecraftforge.network.PacketDistributor;
|
|||
public class StationBlockEntity extends SmartBlockEntity implements ITransformableBlockEntity {
|
||||
|
||||
public TrackTargetingBehaviour<GlobalStation> edgePoint;
|
||||
public DoorControlBehaviour doorControls;
|
||||
public LerpedFloat flag;
|
||||
|
||||
protected int failedCarriageIndex;
|
||||
|
@ -111,6 +113,7 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab
|
|||
@Override
|
||||
public void addBehaviours(List<BlockEntityBehaviour> behaviours) {
|
||||
behaviours.add(edgePoint = new TrackTargetingBehaviour<>(this, EdgePointType.STATION));
|
||||
behaviours.add(doorControls = new DoorControlBehaviour(this));
|
||||
behaviours.add(depotBehaviour = new DepotBehaviour(this).onlyAccepts(AllItems.SCHEDULE::isIn)
|
||||
.withCallback(s -> applyAutoSchedule()));
|
||||
depotBehaviour.addSubBehaviours(behaviours);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControl;
|
||||
import com.simibubi.create.content.logistics.trains.GraphLocation;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket;
|
||||
|
@ -9,6 +10,7 @@ import com.simibubi.create.foundation.utility.VecHelper;
|
|||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.item.ItemEntity;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Level;
|
||||
|
@ -20,6 +22,7 @@ public class StationEditPacket extends BlockEntityConfigurationPacket<StationBlo
|
|||
boolean dropSchedule;
|
||||
boolean assemblyMode;
|
||||
Boolean tryAssemble;
|
||||
DoorControl doorControl;
|
||||
String name;
|
||||
|
||||
public static StationEditPacket dropSchedule(BlockPos pos) {
|
||||
|
@ -40,11 +43,12 @@ public class StationEditPacket extends BlockEntityConfigurationPacket<StationBlo
|
|||
return packet;
|
||||
}
|
||||
|
||||
public static StationEditPacket configure(BlockPos pos, boolean assemble, String name) {
|
||||
public static StationEditPacket configure(BlockPos pos, boolean assemble, String name, DoorControl doorControl) {
|
||||
StationEditPacket packet = new StationEditPacket(pos);
|
||||
packet.assemblyMode = assemble;
|
||||
packet.tryAssemble = null;
|
||||
packet.name = name;
|
||||
packet.doorControl = doorControl;
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
@ -61,6 +65,9 @@ public class StationEditPacket extends BlockEntityConfigurationPacket<StationBlo
|
|||
buffer.writeBoolean(dropSchedule);
|
||||
if (dropSchedule)
|
||||
return;
|
||||
buffer.writeBoolean(doorControl != null);
|
||||
if (doorControl != null)
|
||||
buffer.writeVarInt(doorControl.ordinal());
|
||||
buffer.writeBoolean(tryAssemble != null);
|
||||
if (tryAssemble != null) {
|
||||
buffer.writeBoolean(tryAssemble);
|
||||
|
@ -76,6 +83,8 @@ public class StationEditPacket extends BlockEntityConfigurationPacket<StationBlo
|
|||
dropSchedule = true;
|
||||
return;
|
||||
}
|
||||
if (buffer.readBoolean())
|
||||
doorControl = DoorControl.values()[Mth.clamp(buffer.readVarInt(), 0, DoorControl.values().length)];
|
||||
name = "";
|
||||
if (buffer.readBoolean()) {
|
||||
tryAssemble = buffer.readBoolean();
|
||||
|
@ -96,6 +105,9 @@ public class StationEditPacket extends BlockEntityConfigurationPacket<StationBlo
|
|||
return;
|
||||
}
|
||||
|
||||
if (doorControl != null)
|
||||
be.doorControls.set(doorControl);
|
||||
|
||||
if (!name.isBlank()) {
|
||||
GlobalStation station = be.getStation();
|
||||
GraphLocation graphLocation = be.edgePoint.determineGraphLocation();
|
||||
|
|
|
@ -8,7 +8,9 @@ import com.jozufozu.flywheel.core.PartialModel;
|
|||
import com.mojang.blaze3d.platform.InputConstants;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.AllPartialModels;
|
||||
import com.simibubi.create.content.contraptions.components.actors.DoorControl;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Carriage;
|
||||
import com.simibubi.create.content.logistics.trains.entity.Train;
|
||||
import com.simibubi.create.content.logistics.trains.entity.TrainIconType;
|
||||
|
@ -16,9 +18,12 @@ 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.gui.widget.IconButton;
|
||||
import com.simibubi.create.foundation.gui.widget.Label;
|
||||
import com.simibubi.create.foundation.gui.widget.ScrollInput;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
import com.simibubi.create.foundation.utility.Pair;
|
||||
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
||||
|
||||
import net.minecraft.ChatFormatting;
|
||||
|
@ -37,6 +42,7 @@ public class StationScreen extends AbstractStationScreen {
|
|||
|
||||
private int leavingAnimation;
|
||||
private LerpedFloat trainPosition;
|
||||
private DoorControl doorControl;
|
||||
|
||||
private boolean switchingToAssemblyMode;
|
||||
|
||||
|
@ -47,6 +53,7 @@ public class StationScreen extends AbstractStationScreen {
|
|||
trainPosition = LerpedFloat.linear()
|
||||
.startWithValue(0);
|
||||
switchingToAssemblyMode = false;
|
||||
doorControl = be.doorControls.mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,8 +95,8 @@ public class StationScreen extends AbstractStationScreen {
|
|||
dropScheduleButton = new IconButton(x + 73, y + 65, AllIcons.I_VIEW_SCHEDULE);
|
||||
dropScheduleButton.active = false;
|
||||
dropScheduleButton.visible = false;
|
||||
dropScheduleButton
|
||||
.withCallback(() -> AllPackets.getChannel().sendToServer(StationEditPacket.dropSchedule(blockEntity.getBlockPos())));
|
||||
dropScheduleButton.withCallback(() -> AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.dropSchedule(blockEntity.getBlockPos())));
|
||||
addRenderableWidget(dropScheduleButton);
|
||||
|
||||
onTextChanged = s -> trainNameBox.x = nameBoxX(s, trainNameBox);
|
||||
|
@ -103,6 +110,11 @@ public class StationScreen extends AbstractStationScreen {
|
|||
trainNameBox.active = false;
|
||||
|
||||
tickTrainDisplay();
|
||||
|
||||
Pair<ScrollInput, Label> doorControlWidgets =
|
||||
DoorControl.createWidget(x + 35, y + 102, mode -> doorControl = mode, doorControl);
|
||||
addRenderableWidget(doorControlWidgets.getFirst());
|
||||
addRenderableWidget(doorControlWidgets.getSecond());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -192,12 +204,13 @@ public class StationScreen extends AbstractStationScreen {
|
|||
}
|
||||
|
||||
boolean trainAtStation = trainPresent();
|
||||
disassembleTrainButton.active = trainAtStation && blockEntity.trainCanDisassemble && blockEntity.edgePoint.isOrthogonal();
|
||||
disassembleTrainButton.active =
|
||||
trainAtStation && blockEntity.trainCanDisassemble && blockEntity.edgePoint.isOrthogonal();
|
||||
dropScheduleButton.active = blockEntity.trainHasSchedule;
|
||||
|
||||
if (blockEntity.trainHasSchedule)
|
||||
dropScheduleButton.setToolTip(
|
||||
Lang.translateDirect(blockEntity.trainHasAutoSchedule ? "station.remove_auto_schedule" : "station.remove_schedule"));
|
||||
dropScheduleButton.setToolTip(Lang.translateDirect(
|
||||
blockEntity.trainHasAutoSchedule ? "station.remove_auto_schedule" : "station.remove_schedule"));
|
||||
else
|
||||
dropScheduleButton.getToolTip()
|
||||
.clear();
|
||||
|
@ -237,6 +250,8 @@ public class StationScreen extends AbstractStationScreen {
|
|||
if (!nameBox.isFocused())
|
||||
AllGuiTextures.STATION_EDIT_NAME.render(ms, nameBoxX(text, nameBox) + font.width(text) + 5, y + 1);
|
||||
|
||||
itemRenderer.renderGuiItem(AllBlocks.TRAIN_DOOR.asStack(), x + 14, y + 103);
|
||||
|
||||
Train train = displayedTrain.get();
|
||||
if (train == null) {
|
||||
MutableComponent header = Lang.translateDirect("station.idle");
|
||||
|
@ -333,32 +348,38 @@ public class StationScreen extends AbstractStationScreen {
|
|||
Train train = displayedTrain.get();
|
||||
if (train != null && !trainNameBox.getValue()
|
||||
.equals(train.name.getString()))
|
||||
AllPackets.getChannel().sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
|
||||
}
|
||||
|
||||
private void syncStationName() {
|
||||
if (!nameBox.getValue()
|
||||
.equals(station.name))
|
||||
AllPackets.getChannel().sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), false, nameBox.getValue()));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(
|
||||
StationEditPacket.configure(blockEntity.getBlockPos(), false, nameBox.getValue(), doorControl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
super.removed();
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), switchingToAssemblyMode, nameBox.getValue()));
|
||||
.sendToServer(StationEditPacket.configure(blockEntity.getBlockPos(), switchingToAssemblyMode,
|
||||
nameBox.getValue(), doorControl));
|
||||
Train train = displayedTrain.get();
|
||||
if (train == null)
|
||||
return;
|
||||
if (!switchingToAssemblyMode)
|
||||
AllPackets.getChannel().sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
|
||||
AllPackets.getChannel()
|
||||
.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
|
||||
else
|
||||
blockEntity.imminentTrain = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected PartialModel getFlag(float partialTicks) {
|
||||
return blockEntity.flag.getValue(partialTicks) > 0.75f ? AllPartialModels.STATION_ON : AllPartialModels.STATION_OFF;
|
||||
return blockEntity.flag.getValue(partialTicks) > 0.75f ? AllPartialModels.STATION_ON
|
||||
: AllPartialModels.STATION_OFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import net.minecraft.network.chat.Component;
|
|||
public abstract class AbstractSimiWidget extends AbstractWidget implements TickableGuiEventListener {
|
||||
|
||||
public static final int HEADER_RGB = 0x5391E1;
|
||||
public static final int HINT_RGB = 0x96B7E0;
|
||||
|
||||
protected float z;
|
||||
protected boolean wasHovered = false;
|
||||
|
|
|
@ -22,6 +22,7 @@ public class ScrollInput extends AbstractSimiWidget {
|
|||
protected Component title = Lang.translateDirect("gui.scrollInput.defaultTitle");
|
||||
protected final Component scrollToModify = Lang.translateDirect("gui.scrollInput.scrollToModify");
|
||||
protected final Component shiftScrollsFaster = Lang.translateDirect("gui.scrollInput.shiftScrollsFaster");
|
||||
protected Component hint = null;
|
||||
protected Label displayLabel;
|
||||
protected boolean inverted;
|
||||
protected Function<Integer, Component> formatter;
|
||||
|
@ -76,6 +77,12 @@ public class ScrollInput extends AbstractSimiWidget {
|
|||
return this;
|
||||
}
|
||||
|
||||
public ScrollInput addHint(MutableComponent hint) {
|
||||
this.hint = hint;
|
||||
updateTooltip();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ScrollInput withStepFunction(Function<StepContext, Integer> step) {
|
||||
this.step = step;
|
||||
return this;
|
||||
|
@ -128,7 +135,10 @@ public class ScrollInput extends AbstractSimiWidget {
|
|||
clampState();
|
||||
|
||||
if (priorState != state) {
|
||||
Minecraft.getInstance().getSoundManager().play(SimpleSoundInstance.forUI(AllSoundEvents.SCROLL_VALUE.getMainEvent(), 1.5f + 0.1f * (state-min)/(max-min)));
|
||||
Minecraft.getInstance()
|
||||
.getSoundManager()
|
||||
.play(SimpleSoundInstance.forUI(AllSoundEvents.SCROLL_VALUE.getMainEvent(),
|
||||
1.5f + 0.1f * (state - min) / (max - min)));
|
||||
onChanged();
|
||||
}
|
||||
|
||||
|
@ -160,6 +170,9 @@ public class ScrollInput extends AbstractSimiWidget {
|
|||
return;
|
||||
toolTip.add(title.plainCopy()
|
||||
.withStyle(s -> s.withColor(HEADER_RGB)));
|
||||
if (hint != null)
|
||||
toolTip.add(hint.plainCopy()
|
||||
.withStyle(s -> s.withColor(HINT_RGB)));
|
||||
toolTip.add(scrollToModify.plainCopy()
|
||||
.withStyle(ChatFormatting.ITALIC, ChatFormatting.DARK_GRAY));
|
||||
toolTip.add(shiftScrollsFaster.plainCopy()
|
||||
|
|
|
@ -43,7 +43,8 @@ public class SelectionScrollInput extends ScrollInput {
|
|||
if (this.min + 1 == min)
|
||||
min--;
|
||||
if (min > this.min)
|
||||
toolTip.add(Components.literal("> ...").withStyle(ChatFormatting.GRAY));
|
||||
toolTip.add(Components.literal("> ...")
|
||||
.withStyle(ChatFormatting.GRAY));
|
||||
if (this.max - 1 == max)
|
||||
max++;
|
||||
for (int i = min; i < max; i++) {
|
||||
|
@ -59,8 +60,12 @@ public class SelectionScrollInput extends ScrollInput {
|
|||
.withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
if (max < this.max)
|
||||
toolTip.add(Components.literal("> ...").withStyle(ChatFormatting.GRAY));
|
||||
toolTip.add(Components.literal("> ...")
|
||||
.withStyle(ChatFormatting.GRAY));
|
||||
|
||||
if (hint != null)
|
||||
toolTip.add(hint.plainCopy()
|
||||
.withStyle(s -> s.withColor(HINT_RGB)));
|
||||
toolTip.add(scrollToSelect.plainCopy()
|
||||
.withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.ITALIC));
|
||||
}
|
||||
|
|
|
@ -815,6 +815,21 @@
|
|||
"create.contraption.controls.actor_toggle.off": "Off",
|
||||
"create.contraption.controls.floor_unreachable": "Unreachable",
|
||||
|
||||
"create.contraption.door_control": "Onboard Door Control",
|
||||
"create.contraption.door_control.all": "Open All Doors",
|
||||
"create.contraption.door_control.all.short": "Open All",
|
||||
"create.contraption.door_control.north": "North Side Only",
|
||||
"create.contraption.door_control.north.short": "North",
|
||||
"create.contraption.door_control.east": "East Side Only",
|
||||
"create.contraption.door_control.east.short": "East",
|
||||
"create.contraption.door_control.south": "South Side Only",
|
||||
"create.contraption.door_control.south.short": "South",
|
||||
"create.contraption.door_control.west": "West Side Only",
|
||||
"create.contraption.door_control.west.short": "West",
|
||||
"create.contraption.door_control.none": "Keep Doors Closed",
|
||||
"create.contraption.door_control.none.short": "None",
|
||||
"create.contraption.door_control.player_facing": "You are facing: %1$s",
|
||||
|
||||
"create.display_link.set": "Targeted position selected",
|
||||
"create.display_link.success": "Successfully bound to targeted position",
|
||||
"create.display_link.clear": "Cleared position selection",
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 2.1 KiB |
Loading…
Reference in a new issue