The edge case files, Part II

- Right-clicking a conductor now resumes a previously paused schedule
- Players now wear a conductor head when sitting in driver seats
- Players no longer wear a conductor head while wearing another helmet
- Manual train controls no longer allow approaching an occupied station
- Limited train status message dump to 3 latest entries
- Trains now communicate when no station on a graph actually matches the targeted filter
- Fixed Destination instruction not escaping regex characters
- Schedule autocomplete now defaults to listing all destinations when graph filtering leaves an otherwise empty set
This commit is contained in:
simibubi 2022-06-07 23:48:04 +02:00
parent d969adb233
commit 4e9e37ffd2
26 changed files with 115 additions and 55 deletions

View file

@ -554,22 +554,22 @@ bf2b0310500213ff853c748c236eb5d01f61658e assets/create/blockstates/yellow_toolbo
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
50f7862ded2d9a955c259a12685906a9ec9ad97a assets/create/lang/en_ud.json
b8ef69f9d7a670363f8adcc294c890c9d4265955 assets/create/lang/en_us.json
389ca4ecd1ff00ed2a211f6c07b0cf359098a49f assets/create/lang/unfinished/de_de.json
6e7e9849785c878046cd2b582a461aef95b7ce20 assets/create/lang/unfinished/es_cl.json
dbbb124039358f0a19af2f13e40e2767ed502976 assets/create/lang/unfinished/es_es.json
9a17028a587007778503582a53a3055a969f05c4 assets/create/lang/unfinished/fr_fr.json
b153f0c6d252ee91ca57751630268f40fd9aa9eb assets/create/lang/unfinished/it_it.json
292ace9dd69adc7028dfd551038dd612f1a62f34 assets/create/lang/unfinished/ja_jp.json
fdc062986ad47205b33c16f4339f9eb11ed89f3e assets/create/lang/unfinished/ko_kr.json
81a2447f877c072cb8709570482c5b98ba18f45f assets/create/lang/unfinished/nl_nl.json
79f443acec9320796a140b6ca53c399b639c516f assets/create/lang/unfinished/pl_pl.json
df1f85f1762ad26c4ab33eb0e52ab0516c227d27 assets/create/lang/unfinished/pt_br.json
6e54230dee02119d3deef8668f815dfe095285fe assets/create/lang/unfinished/pt_pt.json
7495c140ed817cc02a68e9ada4a2867a33260411 assets/create/lang/unfinished/ro_ro.json
53896d6fd85c2f6bd7fb4376bb4ce41aa1b12f38 assets/create/lang/unfinished/ru_ru.json
a049b20621987947fc060c94b912f3afd90abe9e assets/create/lang/unfinished/zh_cn.json
a41da0cb6db644b9e13531ded820857a7811c7c7 assets/create/lang/unfinished/zh_tw.json
8b387eecbadbf8ddf744422baabf223c84268de8 assets/create/lang/en_us.json
f162f6cfe17b1fcbb1303b84545cd3d0c9ce25f5 assets/create/lang/unfinished/de_de.json
b72060f9fc6cf1da5682ceed2ba69ab4c0c30184 assets/create/lang/unfinished/es_cl.json
5ede822fae8b2189db97633c8303c96decd2091f assets/create/lang/unfinished/es_es.json
60618a73865a24d2b8e2f3bfafd5411be725d1ce assets/create/lang/unfinished/fr_fr.json
086ca3a74d4c5c129d83360b0acc8dbdf65e5bb2 assets/create/lang/unfinished/it_it.json
9345b75ecfc27f4c2f25d0b5badbb2801bd1b88b assets/create/lang/unfinished/ja_jp.json
6f4d78f63f63f9b870494c771bba36bd4bddfe38 assets/create/lang/unfinished/ko_kr.json
7f271a3685fc8b100046cf87ceb21e569e356ea9 assets/create/lang/unfinished/nl_nl.json
bba14b1077fe530c9f627792f7b16b104d00623d assets/create/lang/unfinished/pl_pl.json
0ad3218fc001b8031578b4cafa4b1d931badd28f assets/create/lang/unfinished/pt_br.json
285d85ae57a1d9225240a2761b0ac241b47f501c assets/create/lang/unfinished/pt_pt.json
dda44f8eca5de56c4ccb14019c06b0e1c381801a assets/create/lang/unfinished/ro_ro.json
351534ba02df3ce3688e48471981955ac662dce4 assets/create/lang/unfinished/ru_ru.json
5391940638ecc6590d755663db05d138140db0b5 assets/create/lang/unfinished/zh_cn.json
5ec6d587ead9ecf3cf4348422903d5926cf1c8ab assets/create/lang/unfinished/zh_tw.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

View file

@ -1421,6 +1421,7 @@
"create.schedule.auto_removed_from_train": "Auto-Schedule discarded",
"create.schedule.removed_from_train": "Schedule retrieved from Train",
"create.schedule.no_stops": "This Schedule does not have any Stops yet",
"create.schedule.continued": "Schedule resumed",
"create.track.selection_cleared": "Selection Cleared",
"create.track.valid_connection": "Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 942",
"_": "Missing Localizations: 943",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 592",
"_": "Missing Localizations: 593",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 256",
"_": "Missing Localizations: 257",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1830",
"_": "Missing Localizations: 1831",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1519",
"_": "Missing Localizations: 1520",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 258",
"_": "Missing Localizations: 259",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 258",
"_": "Missing Localizations: 259",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 2182",
"_": "Missing Localizations: 2183",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 631",
"_": "Missing Localizations: 632",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1126",
"_": "Missing Localizations: 1127",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 1804",
"_": "Missing Localizations: 1805",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 259",
"_": "Missing Localizations: 260",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 636",
"_": "Missing Localizations: 637",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 256",
"_": "Missing Localizations: 257",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -1,5 +1,5 @@
{
"_": "Missing Localizations: 650",
"_": "Missing Localizations: 651",
"_": "->------------------------] Game Elements [------------------------<-",
@ -1422,6 +1422,7 @@
"create.schedule.auto_removed_from_train": "UNLOCALIZED: Auto-Schedule discarded",
"create.schedule.removed_from_train": "UNLOCALIZED: Schedule retrieved from Train",
"create.schedule.no_stops": "UNLOCALIZED: This Schedule does not have any Stops yet",
"create.schedule.continued": "UNLOCALIZED: Schedule resumed",
"create.track.selection_cleared": "UNLOCALIZED: Selection Cleared",
"create.track.valid_connection": "UNLOCALIZED: Can Connect ✔",

View file

@ -55,6 +55,13 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
return true;
if (train.runtime.getSchedule() != null) {
if (train.runtime.paused) {
train.runtime.paused = false;
AllSoundEvents.CONFIRM.playOnServer(player.level, player.blockPosition(), 1, 1);
player.displayClientMessage(Lang.translate("schedule.continued"), true);
return true;
}
if (!itemInHand.isEmpty()) {
AllSoundEvents.DENY.playOnServer(player.level, player.blockPosition(), 1, 1);
player.displayClientMessage(Lang.translate("schedule.remove_with_empty_hand"), true);

View file

@ -469,9 +469,6 @@ public class Navigation {
results.set(forward, new DiscoveredPath((forward ? 1 : -1) * distanceToDestination, cost, currentPath));
return true;
});
if (!train.doubleEnded || !train.manualTick && !train.hasBackwardConductor())
break;
}
DiscoveredPath front = results.getFirst();
@ -479,20 +476,13 @@ public class Navigation {
boolean frontEmpty = front == null;
boolean backEmpty = back == null;
if (backEmpty)
return front;
if (frontEmpty)
return back;
boolean canDriveForward = train.hasForwardConductor() || train.runtime.paused;
boolean canDriveBackward = train.hasBackwardConductor() || train.runtime.paused;
if (!canDriveBackward)
return front;
if (!canDriveForward)
return back;
boolean canDriveBackward = train.doubleEnded && train.hasBackwardConductor() || train.runtime.paused;
// Debug.debugChat("Front: " + front.distance + ", Back: " + back.distance);
// Debug.debugChat("FrontCost: " + front.cost + ", BackCost: " + back.cost);
if (backEmpty || !canDriveBackward)
return canDriveForward ? front : null;
if (frontEmpty || !canDriveForward)
return canDriveBackward ? back : null;
boolean frontBetter = maxCost == -1 ? -back.distance > front.distance : back.cost > front.cost;
return frontBetter ? front : back;
@ -528,6 +518,9 @@ public class Navigation {
double position = edge.getLength() - globalStation.getLocationOn(edge);
if (distance - position < minDistance)
return false;
Train presentTrain = globalStation.getPresentTrain();
if (presentTrain != null && presentTrain != train)
return false;
result.setValue(globalStation);
return true;
});

View file

@ -31,6 +31,13 @@ public class TrainStatus {
navigation = true;
}
public void failedNavigationNoTarget(String filter) {
if (navigation)
return;
displayInformation("No Station on graph matches '" + filter + "'", false);
navigation = true;
}
public void successfulNavigation() {
if (!navigation)
return;
@ -55,7 +62,7 @@ public class TrainStatus {
public void missingBackwardsConductor() { // missingCorrectConductor
if (conductor)
return;
displayInformation("Path requires driver on the other controls block", false);
displayInformation("Path requires a driver facing the opposite direction", false);
conductor = true;
}
@ -124,6 +131,8 @@ public class TrainStatus {
public void displayInformation(String key, boolean itsAGoodThing, Object... args) {
queued.add(new TextComponent(" - ").withStyle(ChatFormatting.GRAY)
.append(new TextComponent(key).withStyle(st -> st.withColor(itsAGoodThing ? 0xD5ECC2 : 0xFFD3B4))));
if (queued.size() > 3)
queued.remove(0);
}
public void newSchedule() {

View file

@ -66,6 +66,14 @@ public class ScheduleItemRetrieval {
if (directions == null)
return;
if (train.runtime.paused) {
train.runtime.paused = false;
AllSoundEvents.CONFIRM.playOnServer(player.level, player.blockPosition(), 1, 1);
player.displayClientMessage(Lang.translate("schedule.continued"), true);
event.setCanceled(true);
return;
}
ItemStack itemInHand = player.getItemInHand(event.getHand());
if (!itemInHand.isEmpty()) {
AllSoundEvents.DENY.playOnServer(player.level, player.blockPosition(), 1, 1);

View file

@ -156,14 +156,21 @@ public class ScheduleRuntime {
ScheduleInstruction instruction = entry.instruction;
if (instruction instanceof DestinationInstruction destination) {
String regex = destination.getFilter()
.replace("*", ".*");
String regex = destination.getFilterForRegex();
GlobalStation best = null;
double bestCost = Double.MAX_VALUE;
boolean anyMatch = false;
if (!train.hasForwardConductor() && !train.hasBackwardConductor()) {
train.status.missingConductor();
cooldown = INTERVAL;
return null;
}
for (GlobalStation globalStation : train.graph.getPoints(EdgePointType.STATION)) {
if (!globalStation.name.matches(regex))
continue;
anyMatch = true;
boolean matchesCurrent = train.currentStation != null && train.currentStation.equals(globalStation.id);
double cost = matchesCurrent ? 0 : train.navigation.startNavigation(globalStation, bestCost, true);
if (cost < 0)
@ -175,7 +182,10 @@ public class ScheduleRuntime {
}
if (best == null) {
train.status.failedNavigation();
if (anyMatch)
train.status.failedNavigation();
else
train.status.failedNavigationNoTarget(destination.getFilter());
cooldown = INTERVAL;
return null;
}

View file

@ -314,8 +314,7 @@ public class ScheduleScreen extends AbstractSimiContainerScreen<ScheduleContaine
continue;
if (destination == field)
continue;
String filter = destination.getFilter()
.replace("*", ".*");
String filter = destination.getFilterForRegex();
if (filter.isBlank())
continue;
Graphs: for (Iterator<TrackGraph> iterator = viableGraphs.iterator(); iterator.hasNext();) {
@ -328,6 +327,9 @@ public class ScheduleScreen extends AbstractSimiContainerScreen<ScheduleContaine
}
}
if (viableGraphs.isEmpty())
viableGraphs = new HashSet<>(railwayManager.trackNetworks.values());
Vec3 position = minecraft.player.position();
Set<String> visited = new HashSet<>();

View file

@ -29,8 +29,10 @@ import net.minecraft.client.renderer.entity.RenderLayerParent;
import net.minecraft.client.renderer.entity.layers.RenderLayer;
import net.minecraft.core.BlockPos;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
@ -125,10 +127,15 @@ public class TrainHatArmorLayer<T extends LivingEntity, M extends EntityModel<T>
return false;
if (!entity.isPassenger())
return false;
if (entity instanceof Player p) {
ItemStack headItem = p.getItemBySlot(EquipmentSlot.HEAD);
if (!headItem.isEmpty())
return false;
}
Entity vehicle = entity.getVehicle();
if (!(vehicle instanceof CarriageContraptionEntity cce))
return false;
if (!cce.hasSchedule())
if (!cce.hasSchedule() && !(entity instanceof Player))
return false;
Contraption contraption = cce.getContraption();
if (!(contraption instanceof CarriageContraption cc))

View file

@ -45,6 +45,13 @@ public class DestinationInstruction extends TextScheduleInstruction {
return getLabelText();
}
public String getFilterForRegex() {
String filter = getFilter();
if (filter.isBlank())
return filter;
return "\\Q" + filter.replace("*", "\\E.*\\Q") + "\\E";
}
@Override
public List<Component> getSecondLineTooltip(int slot) {
return ImmutableList.of(Lang.translate("schedule.instruction.filter_edit_box"),

View file

@ -633,6 +633,7 @@
"create.schedule.auto_removed_from_train": "Auto-Schedule discarded",
"create.schedule.removed_from_train": "Schedule retrieved from Train",
"create.schedule.no_stops": "This Schedule does not have any Stops yet",
"create.schedule.continued": "Schedule resumed",
"create.track.selection_cleared": "Selection Cleared",
"create.track.valid_connection": "Can Connect \u2714",