CreateMod/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationScreen.java
caelwarner 94e3ed44ad
Added ComputerScreen
- ComputerScreen shows that tile entity currently has computers attached and therefore cannot be controlled manually
2022-10-26 16:57:12 -07:00

365 lines
12 KiB
Java

package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.function.Consumer;
import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials;
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;
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.networking.AllPackets;
import com.simibubi.create.foundation.utility.Components;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.util.Mth;
public class StationScreen extends AbstractStationScreen {
private EditBox nameBox;
private EditBox trainNameBox;
private IconButton newTrainButton;
private IconButton disassembleTrainButton;
private IconButton dropScheduleButton;
private int leavingAnimation;
private LerpedFloat trainPosition;
private boolean switchingToAssemblyMode;
public StationScreen(StationTileEntity te, GlobalStation station) {
super(te, station);
background = AllGuiTextures.STATION;
leavingAnimation = 0;
trainPosition = LerpedFloat.linear()
.startWithValue(0);
switchingToAssemblyMode = false;
}
@Override
protected void init() {
super.init();
int x = guiLeft;
int y = guiTop;
Consumer<String> onTextChanged;
onTextChanged = s -> nameBox.x = nameBoxX(s, nameBox);
nameBox = new EditBox(new NoShadowFontWrapper(font), x + 23, y + 4, background.width - 20, 10,
Components.literal(station.name));
nameBox.setBordered(false);
nameBox.setMaxLength(25);
nameBox.setTextColor(0x442000);
nameBox.setValue(station.name);
nameBox.changeFocus(false);
nameBox.mouseClicked(0, 0, 0);
nameBox.setResponder(onTextChanged);
nameBox.x = nameBoxX(nameBox.getValue(), nameBox);
addRenderableWidget(nameBox);
Runnable assemblyCallback = () -> {
switchingToAssemblyMode = true;
minecraft.setScreen(new AssemblyScreen(te, station));
};
newTrainButton = new WideIconButton(x + 84, y + 65, AllGuiTextures.I_NEW_TRAIN);
newTrainButton.withCallback(assemblyCallback);
addRenderableWidget(newTrainButton);
disassembleTrainButton = new WideIconButton(x + 94, y + 65, AllGuiTextures.I_DISASSEMBLE_TRAIN);
disassembleTrainButton.active = false;
disassembleTrainButton.visible = false;
disassembleTrainButton.withCallback(assemblyCallback);
addRenderableWidget(disassembleTrainButton);
dropScheduleButton = new IconButton(x + 73, y + 65, AllIcons.I_VIEW_SCHEDULE);
dropScheduleButton.active = false;
dropScheduleButton.visible = false;
dropScheduleButton
.withCallback(() -> AllPackets.channel.sendToServer(StationEditPacket.dropSchedule(te.getBlockPos())));
addRenderableWidget(dropScheduleButton);
onTextChanged = s -> trainNameBox.x = nameBoxX(s, trainNameBox);
trainNameBox = new EditBox(font, x + 23, y + 47, background.width - 75, 10, Components.immutableEmpty());
trainNameBox.setBordered(false);
trainNameBox.setMaxLength(35);
trainNameBox.setTextColor(0xC6C6C6);
trainNameBox.changeFocus(false);
trainNameBox.mouseClicked(0, 0, 0);
trainNameBox.setResponder(onTextChanged);
trainNameBox.active = false;
tickTrainDisplay();
}
@Override
public void tick() {
tickTrainDisplay();
if (getFocused() != nameBox) {
nameBox.setCursorPosition(nameBox.getValue()
.length());
nameBox.setHighlightPos(nameBox.getCursorPosition());
}
if (getFocused() != trainNameBox || trainNameBox.active == false) {
trainNameBox.setCursorPosition(trainNameBox.getValue()
.length());
trainNameBox.setHighlightPos(trainNameBox.getCursorPosition());
}
super.tick();
updateAssemblyTooltip(te.edgePoint.isOnCurve() ? "no_assembly_curve"
: !te.edgePoint.isOrthogonal() ? "no_assembly_diagonal"
: trainPresent() && !te.trainCanDisassemble ? "train_not_aligned" : null);
}
private void tickTrainDisplay() {
Train train = displayedTrain.get();
if (train == null) {
if (trainNameBox.active) {
trainNameBox.active = false;
removeWidget(trainNameBox);
}
leavingAnimation = 0;
newTrainButton.active = te.edgePoint.isOrthogonal();
newTrainButton.visible = true;
Train imminentTrain = getImminent();
if (imminentTrain != null) {
displayedTrain = new WeakReference<>(imminentTrain);
newTrainButton.active = false;
newTrainButton.visible = false;
disassembleTrainButton.active = false;
disassembleTrainButton.visible = true;
dropScheduleButton.active = te.trainHasSchedule;
dropScheduleButton.visible = true;
trainNameBox.active = true;
trainNameBox.setValue(imminentTrain.name.getString());
trainNameBox.x = nameBoxX(trainNameBox.getValue(), trainNameBox);
addRenderableWidget(trainNameBox);
int trainIconWidth = getTrainIconWidth(imminentTrain);
int targetPos = background.width / 2 - trainIconWidth / 2;
if (trainIconWidth > 130)
targetPos -= trainIconWidth - 130;
float f = (float) (imminentTrain.navigation.distanceToDestination / 15f);
if (trainPresent())
f = 0;
trainPosition.startWithValue(targetPos - (targetPos + 5) * f);
}
return;
}
int trainIconWidth = getTrainIconWidth(train);
int targetPos = background.width / 2 - trainIconWidth / 2;
if (trainIconWidth > 130)
targetPos -= trainIconWidth - 130;
if (leavingAnimation > 0) {
disassembleTrainButton.active = false;
float f = 1 - (leavingAnimation / 80f);
trainPosition.setValue(targetPos + f * f * f * (background.width - targetPos + 5));
leavingAnimation--;
if (leavingAnimation > 0)
return;
displayedTrain = new WeakReference<>(null);
disassembleTrainButton.visible = false;
dropScheduleButton.active = false;
dropScheduleButton.visible = false;
return;
}
if (getImminent() != train) {
leavingAnimation = 80;
return;
}
boolean trainAtStation = trainPresent();
disassembleTrainButton.active = trainAtStation && te.trainCanDisassemble && te.edgePoint.isOrthogonal();
dropScheduleButton.active = te.trainHasSchedule;
if (te.trainHasSchedule)
dropScheduleButton.setToolTip(
Lang.translateDirect(te.trainHasAutoSchedule ? "station.remove_auto_schedule" : "station.remove_schedule"));
else
dropScheduleButton.getToolTip()
.clear();
float f = trainAtStation ? 0 : (float) (train.navigation.distanceToDestination / 30f);
trainPosition.setValue(targetPos - (targetPos + trainIconWidth) * f);
}
private int nameBoxX(String s, EditBox nameBox) {
return guiLeft + background.width / 2 - (Math.min(font.width(s), nameBox.getWidth()) + 10) / 2;
}
private void updateAssemblyTooltip(String key) {
if (key == null) {
disassembleTrainButton.setToolTip(Lang.translateDirect("station.disassemble_train"));
newTrainButton.setToolTip(Lang.translateDirect("station.create_train"));
return;
}
for (IconButton ib : new IconButton[] { disassembleTrainButton, newTrainButton }) {
List<Component> toolTip = ib.getToolTip();
toolTip.clear();
toolTip.add(Lang.translateDirect("station." + key)
.withStyle(ChatFormatting.GRAY));
toolTip.add(Lang.translateDirect("station." + key + "_1")
.withStyle(ChatFormatting.GRAY));
}
}
@Override
protected void renderWindow(PoseStack ms, int mouseX, int mouseY, float partialTicks) {
super.renderWindow(ms, mouseX, mouseY, partialTicks);
int x = guiLeft;
int y = guiTop;
String text = nameBox.getValue();
if (!nameBox.isFocused())
AllGuiTextures.STATION_EDIT_NAME.render(ms, nameBoxX(text, nameBox) + font.width(text) + 5, y + 1);
Train train = displayedTrain.get();
if (train == null) {
MutableComponent header = Lang.translateDirect("station.idle");
font.draw(ms, header, x + 97 - font.width(header) / 2, y + 47, 0x7A7A7A);
return;
}
float position = trainPosition.getValue(partialTicks);
ms.pushPose();
RenderSystem.enableBlend();
ms.translate(position, 0, 0);
TrainIconType icon = train.icon;
int offset = 0;
List<Carriage> carriages = train.carriages;
for (int i = carriages.size() - 1; i > 0; i--) {
RenderSystem.setShaderColor(1, 1, 1, Math.min(1f,
Math.min((position + offset - 10) / 30f, (background.width - 40 - position - offset) / 30f)));
// if (i == carriages.size() - 1 && train.doubleEnded) {
// offset += icon.render(TrainIconType.FLIPPED_ENGINE, ms, x + offset, y + 20) + 1;
// continue;
// }
Carriage carriage = carriages.get(te.trainBackwards ? carriages.size() - i - 1 : i);
offset += icon.render(carriage.bogeySpacing, ms, x + offset, y + 20) + 1;
}
RenderSystem.setShaderColor(1, 1, 1,
Math.min(1f, Math.min((position + offset - 10) / 30f, (background.width - 40 - position - offset) / 30f)));
offset += icon.render(TrainIconType.ENGINE, ms, x + offset, y + 20);
RenderSystem.disableBlend();
ms.popPose();
RenderSystem.setShaderColor(1, 1, 1, 1);
UIRenderHelper.drawStretched(ms, x + 21, y + 43, 150, 46, -100, AllGuiTextures.STATION_TEXTBOX_MIDDLE);
AllGuiTextures.STATION_TEXTBOX_TOP.render(ms, x + 21, y + 42);
AllGuiTextures.STATION_TEXTBOX_BOTTOM.render(ms, x + 21, y + 86);
ms.pushPose();
ms.translate(Mth.clamp(position + offset - 13, 25, 159), 0, 0);
AllGuiTextures.STATION_TEXTBOX_SPEECH.render(ms, x, y + 38);
ms.popPose();
text = trainNameBox.getValue();
if (!trainNameBox.isFocused()) {
int buttonX = nameBoxX(text, trainNameBox) + font.width(text) + 5;
AllGuiTextures.STATION_EDIT_TRAIN_NAME.render(ms, Math.min(buttonX, guiLeft + 156), y + 44);
if (font.width(text) > trainNameBox.getWidth())
font.drawShadow(ms, "...", guiLeft + 26, guiTop + 47, 0xa6a6a6);
}
}
@Override
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
if (!nameBox.isFocused() && pMouseY > guiTop && pMouseY < guiTop + 14 && pMouseX > guiLeft
&& pMouseX < guiLeft + background.width) {
nameBox.setFocus(true);
nameBox.setHighlightPos(0);
setFocused(nameBox);
return true;
}
if (trainNameBox.active && !trainNameBox.isFocused() && pMouseY > guiTop + 45 && pMouseY < guiTop + 58
&& pMouseX > guiLeft + 25 && pMouseX < guiLeft + 168) {
trainNameBox.setFocus(true);
trainNameBox.setHighlightPos(0);
setFocused(trainNameBox);
return true;
}
return super.mouseClicked(pMouseX, pMouseY, pButton);
}
@Override
public boolean keyPressed(int pKeyCode, int pScanCode, int pModifiers) {
boolean hitEnter = getFocused() instanceof EditBox && (pKeyCode == 257 || pKeyCode == 335);
if (hitEnter && nameBox.isFocused()) {
nameBox.setFocus(false);
syncStationName();
return true;
}
if (hitEnter && trainNameBox.isFocused()) {
trainNameBox.setFocus(false);
syncTrainName();
return true;
}
return super.keyPressed(pKeyCode, pScanCode, pModifiers);
}
private void syncTrainName() {
Train train = displayedTrain.get();
if (train != null && !trainNameBox.getValue()
.equals(train.name.getString()))
AllPackets.channel.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
}
private void syncStationName() {
if (!nameBox.getValue()
.equals(station.name))
AllPackets.channel.sendToServer(StationEditPacket.configure(te.getBlockPos(), false, nameBox.getValue()));
}
@Override
public void removed() {
super.removed();
if (nameBox == null || trainNameBox == null)
return;
AllPackets.channel
.sendToServer(StationEditPacket.configure(te.getBlockPos(), switchingToAssemblyMode, nameBox.getValue()));
Train train = displayedTrain.get();
if (train == null)
return;
if (!switchingToAssemblyMode)
AllPackets.channel.sendToServer(new TrainEditPacket(train.id, trainNameBox.getValue(), train.icon.getId()));
else
te.imminentTrain = null;
}
@Override
protected PartialModel getFlag(float partialTicks) {
return te.flag.getValue(partialTicks) > 0.75f ? AllBlockPartials.STATION_ON : AllBlockPartials.STATION_OFF;
}
}