diff --git a/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplaySource.java b/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplaySource.java index d7d7fcd4..8e3d81cc 100644 --- a/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplaySource.java +++ b/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplaySource.java @@ -7,7 +7,6 @@ import com.simibubi.create.content.redstone.displayLink.source.DisplaySource; import com.simibubi.create.content.redstone.displayLink.target.DisplayTargetStats; import com.simibubi.create.content.trains.station.GlobalStation; -import com.simibubi.create.content.trains.station.StationBlockEntity; import com.simibubi.create.foundation.gui.ModularGuiLineBuilder; import com.simibubi.create.foundation.utility.Lang; diff --git a/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplayTarget.java b/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplayTarget.java index e71ec518..c494913b 100644 --- a/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplayTarget.java +++ b/common/src/main/java/de/mrjulsen/crn/block/display/AdvancedDisplayTarget.java @@ -51,7 +51,7 @@ public static void start() { try { workerTasks.poll().run(); } catch (Exception e) { - CreateRailwaysNavigator.LOGGER.info("Error while process Advanced Display Data.", e); + CreateRailwaysNavigator.LOGGER.info("Error while process Advanced Display Data. " + e.getMessage(), e); } } try { diff --git a/common/src/main/java/de/mrjulsen/crn/client/ber/variants/AbstractAdvancedDisplayRenderer.java b/common/src/main/java/de/mrjulsen/crn/client/ber/variants/AbstractAdvancedDisplayRenderer.java index 62cab4a9..07e7b7d8 100644 --- a/common/src/main/java/de/mrjulsen/crn/client/ber/variants/AbstractAdvancedDisplayRenderer.java +++ b/common/src/main/java/de/mrjulsen/crn/client/ber/variants/AbstractAdvancedDisplayRenderer.java @@ -18,5 +18,4 @@ default T getDisplaySettings(AdvancedDisplayBlockEntity blockEntity) { throw new IllegalArgumentException("Could not get display data of display at " + blockEntity.getBlockPos(), e); } } - } diff --git a/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformDetailed.java b/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformDetailed.java index 61b3d84f..2855f9f9 100644 --- a/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformDetailed.java +++ b/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformDetailed.java @@ -98,7 +98,7 @@ public void render(BERGraphics graphics, float pPart @Override public void update(Level level, BlockPos pos, BlockState state, AdvancedDisplayBlockEntity blockEntity, AdvancedDisplayRenderInstance parent, EUpdateReason reason) { - List preds = blockEntity.getStops().stream().filter(x -> x.getStationData().getScheduledArrivalTime() < DragonLib.getCurrentWorldTime() + ModClientConfig.DISPLAY_LEAD_TIME.get() && (!x.getTrainData().isCancelled() || DragonLib.getCurrentWorldTime() < x.getStationData().getScheduledDepartureTime() + ModClientConfig.DISPLAY_LEAD_TIME.get())).toList(); + List preds = blockEntity.getStops().stream().filter(x -> x.getStationData().getRealTimeArrivalTime() < DragonLib.getCurrentWorldTime() + ModClientConfig.DISPLAY_LEAD_TIME.get() && (!x.getTrainData().isCancelled() || DragonLib.getCurrentWorldTime() < x.getStationData().getScheduledDepartureTime() + ModClientConfig.DISPLAY_LEAD_TIME.get())).toList(); showInfoLine = !preds.isEmpty() && preds.get(0).getStationData().isDepartureDelayed() && preds.get(0).getTrainData().hasStatusInfo(); if (showInfoLine) { diff --git a/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformSimple.java b/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformSimple.java index c607cbeb..0a6d6efc 100644 --- a/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformSimple.java +++ b/common/src/main/java/de/mrjulsen/crn/client/ber/variants/BERPlatformSimple.java @@ -65,7 +65,7 @@ public void render(BERGraphics graphics, float pPart @Override public void update(Level level, BlockPos pos, BlockState state, AdvancedDisplayBlockEntity blockEntity, AdvancedDisplayRenderInstance parent, EUpdateReason reason) { - List preds = blockEntity.getStops().stream().filter(x -> x.getStationData().getScheduledArrivalTime() < DragonLib.getCurrentWorldTime() + ModClientConfig.DISPLAY_LEAD_TIME.get() && (!x.getTrainData().isCancelled() || DragonLib.getCurrentWorldTime() < x.getStationData().getScheduledDepartureTime() + ModClientConfig.DISPLAY_LEAD_TIME.get())).toList(); + List preds = blockEntity.getStops().stream().filter(x -> x.getStationData().getRealTimeArrivalTime() < DragonLib.getCurrentWorldTime() + ModClientConfig.DISPLAY_LEAD_TIME.get() && (!x.getTrainData().isCancelled() || DragonLib.getCurrentWorldTime() < x.getStationData().getScheduledDepartureTime() + ModClientConfig.DISPLAY_LEAD_TIME.get())).toList(); label .setColor((0xFF << 24) | (getDisplaySettings(blockEntity).getFontColor() & 0x00FFFFFF)) @@ -88,10 +88,12 @@ public void update(Level level, BlockPos pos, BlockState state, AdvancedDisplayB text.append(", ").append(CustomLanguage.translate("block." + CreateRailwaysNavigator.MOD_ID + ".advanced_display.ber.cancelled2").getString()); } else if (x.getStationData().isDepartureDelayed()) { String delay = getDisplaySettings(blockEntity).getTimeDisplay() == ETimeDisplay.ETA ? ModUtils.timeRemainingString(x.getStationData().getDepartureTimeDeviation()) : String.valueOf(TimeUtils.formatToMinutes(x.getStationData().getDepartureTimeDeviation())); - text.append(", ").append(CustomLanguage.translate("block." + CreateRailwaysNavigator.MOD_ID + ".advanced_display.ber.delayed2", delay).getString()); - if (getDisplaySettings(blockEntity).getTimeDisplay() == ETimeDisplay.ABS) { - text.append(" ").append(CustomLanguage.translate("block." + CreateRailwaysNavigator.MOD_ID + ".advanced_display.ber.delay_abs_suffix")); - } + String timeUnitSuffix = getDisplaySettings(blockEntity).getTimeDisplay() == ETimeDisplay.ABS ? + " " + CustomLanguage.translate("block." + CreateRailwaysNavigator.MOD_ID + ".advanced_display.ber.delay_abs_suffix").getString() : + ""; + + text.append(", ").append(CustomLanguage.translate("block." + CreateRailwaysNavigator.MOD_ID + ".advanced_display.ber.delayed2", delay, timeUnitSuffix).getString()); + if (x.getTrainData().hasStatusInfo()) { text.append(" ").append(CustomLanguage.translate("block." + CreateRailwaysNavigator.MOD_ID + ".advanced_display.ber.reason").getString()).append(x.getTrainData().getStatus().get(0).text()); } diff --git a/common/src/main/java/de/mrjulsen/crn/client/gui/screen/TrainSeparationSettingsScreen.java b/common/src/main/java/de/mrjulsen/crn/client/gui/screen/TrainSeparationSettingsScreen.java index ddebd7d5..52e59bcd 100644 --- a/common/src/main/java/de/mrjulsen/crn/client/gui/screen/TrainSeparationSettingsScreen.java +++ b/common/src/main/java/de/mrjulsen/crn/client/gui/screen/TrainSeparationSettingsScreen.java @@ -56,24 +56,30 @@ public class TrainSeparationSettingsScreen extends DLScreen { private final CompoundTag nbt; //private String stationFilter; - private int time = 5; - private TimeUnit timeUnit = TimeUnit.SECONDS; + private int minutes = 0; + private int seconds = 5; + private int ticks = 0; private ETrainFilter filter = ETrainFilter.ANY; public TrainSeparationSettingsScreen(Screen lastScreen, CompoundTag nbt) { super(title); this.lastScreen = lastScreen; this.nbt = nbt; - this.time = nbt.getInt(TrainSeparationCondition.NBT_TIME); - this.timeUnit = TimeUnit.values()[nbt.getInt(TrainSeparationCondition.NBT_TIME_UNIT)]; + @SuppressWarnings("deprecation") + int t = nbt.contains(TrainSeparationCondition.NBT_TICKS) ? nbt.getInt(TrainSeparationCondition.NBT_TICKS) : nbt.getInt(TrainSeparationCondition.NBT_TIME) * TimeUnit.values()[nbt.getInt(TrainSeparationCondition.NBT_TIME_UNIT)].ticksPer; + ticks = t; + minutes = ticks / 1200; + ticks %= 1200; + seconds = ticks / 20; + ticks %= 20; + this.filter = ETrainFilter.getByIndex(nbt.getByte(TrainSeparationCondition.NBT_TRAIN_FILTER)); } @Override public void onClose() { super.onClose(); - nbt.putInt(TrainSeparationCondition.NBT_TIME, time); - nbt.putInt(TrainSeparationCondition.NBT_TIME_UNIT, timeUnit.ordinal()); + nbt.putInt(TrainSeparationCondition.NBT_TICKS, minutes * TimeUnit.MINUTES.ticksPer + seconds * TimeUnit.SECONDS.ticksPer + ticks); nbt.putByte(TrainSeparationCondition.NBT_TRAIN_FILTER, filter.getIndex()); Minecraft.getInstance().setScreen(lastScreen); } @@ -99,7 +105,55 @@ protected void init() { }); }); */ + + /* + builder.addLine("time_src", (line) -> { + line.add(new IconSlotWidget(line.getCurrentX(), line.y() + 2, ModGuiIcons.TIME.getAsSprite(16, 16))); + line.add(new DLCreateSelectionScrollInput(this, line.getCurrentX() + 6, line.getY() + 2, line.getRemainingWidth() - 6, 18) + .setRenderArrow(true) + .forOptions(Arrays.stream(ETimeSource.values()).map(x -> TextUtils.translate(x.getValueTranslationKey(CreateRailwaysNavigator.MOD_ID))).toList()) + .titled(TextUtils.translate(timeSource.getEnumTranslationKey(CreateRailwaysNavigator.MOD_ID))) + .setState(timeSource.getIndex()) + .calling((i) -> { + timeSource = ETimeSource.getByIndex(i); + }) + ); + }); + */ + builder.addLine("times", (line) -> { + line.add(new IconSlotWidget(line.getCurrentX(), line.y() + 2, ModGuiIcons.TIME.getAsSprite(16, 16))); + line.add(new DLCreateScrollInput(this, line.getCurrentX() + 6, line.getY() + 2, 30, 18) + .setRenderArrow(true) + .titled(Lang.translateDirect("generic.unit.minutes")) + .withShiftStep(10) + .withRange(0, 901) + .setState(minutes) + .calling(x -> { + minutes = x; + }) + ); + line.add(new DLCreateScrollInput(this, line.getCurrentX() + 2, line.getY() + 2, 30, 18) + .titled(Lang.translateDirect("generic.unit.seconds")) + .withShiftStep(10) + .withRange(0, 60) + .setState(seconds) + .calling(x -> { + seconds = x; + }) + ); + line.add(new DLCreateScrollInput(this, line.getCurrentX() + 2, line.getY() + 2, 30, 18) + .titled(Lang.translateDirect("generic.unit.ticks")) + .withShiftStep(5) + .withRange(0, 20) + .setState(ticks) + .calling(x -> { + ticks = x; + }) + ); + }); + + /* builder.addLine("time", (line) -> { line.add(new IconSlotWidget(line.getCurrentX(), line.y() + 2, ModGuiIcons.TIME.getAsSprite(16, 16))); line.add(new DLCreateScrollInput(this, line.getCurrentX() + 6, line.getY() + 2, 30, 18) @@ -107,9 +161,9 @@ protected void init() { .titled(Lang.translateDirect("generic.duration")) .withShiftStep(15) .withRange(0, 121) - .setState(time) + .setState(ticks) .calling(x -> { - time = x; + ticks = x; }) ); @@ -123,6 +177,7 @@ protected void init() { }) ); }); + */ builder.addLine("train_filter", (line) -> { line.add(new IconSlotWidget(line.getCurrentX(), line.y() + 2, ModGuiIcons.TRAIN.getAsSprite(16, 16))); diff --git a/common/src/main/java/de/mrjulsen/crn/config/ModClientConfig.java b/common/src/main/java/de/mrjulsen/crn/config/ModClientConfig.java index a6ca273b..7aced8a4 100644 --- a/common/src/main/java/de/mrjulsen/crn/config/ModClientConfig.java +++ b/common/src/main/java/de/mrjulsen/crn/config/ModClientConfig.java @@ -28,12 +28,12 @@ public class ModClientConfig { BUILDER.push("Create Railways Navigator Config"); /* CONFIGS */ - NEXT_STOP_ANNOUNCEMENT = BUILDER.comment(new String[] {"[in Ticks]", "The next stop or information about the start of the journey is announced in the specified number of ticks before the scheduled arrival at the next station. (Default: 500, 30 real life seconds)"}) - .defineInRange("general.next_stop_announcement", 500, 100, 1000); + NEXT_STOP_ANNOUNCEMENT = BUILDER.comment(new String[] {"[in Ticks]", "The next stop or information about the start of the journey is announced in the specified number of ticks before the scheduled arrival at the next station. (Default: 600, 30 real life seconds)"}) + .defineInRange("general.next_stop_announcement", 600, 100, 1000); REALTIME_PRECISION_THRESHOLD = BUILDER.comment(new String[] {"[in Ticks]", "This value indicates how accurately the real-time data should be displayed. By default, only deviations above 10 in-game minutes (167 ticks, approx. 8 real life seconds) are displayed. The lower the value, the more accurate the real-time data but also the more often deviations from the schedule occur. (Default: 167, 10 in-game minutes)"}) .defineInRange("general.realtime_precision_threshold", 167, 1, 1000); - DISPLAY_LEAD_TIME = BUILDER.comment(new String[] {"[in Ticks]", "How early a train should be shown on the display. (Default: 1000, 1 in-game hour)"}) - .defineInRange("general.display_lead_time", 1000, 100, 24000); + DISPLAY_LEAD_TIME = BUILDER.comment(new String[] {"[in Ticks]", "How early a train should be shown on the display. (Default: 1200, 1 real life minute)"}) + .defineInRange("general.display_lead_time", 1200, 100, 24000); OVERLAY_SCALE = BUILDER.comment("Scale of the route overlay UI. (Default: 0.75)") .defineInRange("route_overlay.scale", 0.75f, MIN_SCALE, MAX_SCALE); ROUTE_NOTIFICATIONS = BUILDER.comment("If active, you will receive short toasts about important events on your trip, e.g. delays, changes, ... (Default: ON)") diff --git a/common/src/main/java/de/mrjulsen/crn/data/ETimeSource.java b/common/src/main/java/de/mrjulsen/crn/data/ETimeSource.java new file mode 100644 index 00000000..ad938aca --- /dev/null +++ b/common/src/main/java/de/mrjulsen/crn/data/ETimeSource.java @@ -0,0 +1,39 @@ +package de.mrjulsen.crn.data; + +import java.util.Arrays; +import de.mrjulsen.mcdragonlib.core.ITranslatableEnum; + +public enum ETimeSource implements ITranslatableEnum { + REAL_LIFE((byte)0, "real_life"), + IN_GAME((byte)1, "in_game"); + + final byte index; + final String name; + + ETimeSource(byte index, String name) { + this.index = index; + this.name = name; + } + + public byte getIndex() { + return index; + } + + public String getName() { + return name; + } + + public static ETimeSource getByIndex(int index) { + return Arrays.stream(values()).filter(x -> x.getIndex() == index).findFirst().orElse(REAL_LIFE); + } + + @Override + public String getEnumName() { + return "time_source"; + } + + @Override + public String getEnumValueName() { + return name; + } +} diff --git a/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoute.java b/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoute.java index 7918695a..4b3af1f3 100644 --- a/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoute.java +++ b/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoute.java @@ -652,8 +652,8 @@ public void closeAll() { CRNEventsManager.getEvent(DefaultTrainDataRefreshEvent.class).unregister(CreateRailwaysNavigator.MOD_ID + "_" + id); clearEvents(); isClosed = true; - CreateRailwaysNavigator.LOGGER.info("Route listener closed."); - if (ModCommonConfig.ADVANCED_LOGGING.get()) CreateRailwaysNavigator.LOGGER.info("Closed " + this); + + if (ModCommonConfig.ADVANCED_LOGGING.get()) CreateRailwaysNavigator.LOGGER.info("Route listener closed."); } diff --git a/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoutePart.java b/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoutePart.java index 5b928a50..92f8e272 100644 --- a/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoutePart.java +++ b/common/src/main/java/de/mrjulsen/crn/data/navigation/ClientRoutePart.java @@ -14,6 +14,7 @@ import com.google.common.collect.ImmutableList; import de.mrjulsen.crn.CreateRailwaysNavigator; +import de.mrjulsen.crn.config.ModCommonConfig; import de.mrjulsen.crn.data.train.ClientTrainStop; import de.mrjulsen.crn.data.train.RoutePartProgressState; import de.mrjulsen.crn.data.train.TrainStop; @@ -272,7 +273,7 @@ public void update(TrainRealTimeData data) { } if (isCancelled()) { - CreateRailwaysNavigator.LOGGER.info("Train got cancelled. Closing route..."); + if (ModCommonConfig.ADVANCED_LOGGING.get()) CreateRailwaysNavigator.LOGGER.info("Train got cancelled. Closing route..."); notifyListeners(EVENT_TRAIN_CANCELLED, new ListenerNotificationData(this, nextStop)); close(); } @@ -304,7 +305,6 @@ public void close() { } } stopListeningAll(this); - CreateRailwaysNavigator.LOGGER.info("CLOSED " + this); } diff --git a/common/src/main/java/de/mrjulsen/crn/data/navigation/NavigatableGraph.java b/common/src/main/java/de/mrjulsen/crn/data/navigation/NavigatableGraph.java index 8497f60d..f618e607 100644 --- a/common/src/main/java/de/mrjulsen/crn/data/navigation/NavigatableGraph.java +++ b/common/src/main/java/de/mrjulsen/crn/data/navigation/NavigatableGraph.java @@ -65,12 +65,14 @@ public NavigatableGraph(UserSettings userSettings) throws RuntimeSideException { addTrain(train, TrainListener.data.get(train.id)); } - CreateRailwaysNavigator.LOGGER.info(String.format("Graph generated. Took %sms. Contains %s nodes and %s edges. %s train processed.", - System.currentTimeMillis() - startTime, - nodesByTag.size(), - edgesByTag.values().stream().flatMap(x -> x.values().stream().flatMap(y -> y.stream())).count(), - trains.size() - )); + if (ModCommonConfig.ADVANCED_LOGGING.get()) { + CreateRailwaysNavigator.LOGGER.info(String.format("Graph generated. Took %sms. Contains %s nodes and %s edges. %s train processed.", + System.currentTimeMillis() - startTime, + nodesByTag.size(), + edgesByTag.values().stream().flatMap(x -> x.values().stream().flatMap(y -> y.stream())).count(), + trains.size() + )); + } } protected GlobalSettings globalSettings() { @@ -419,10 +421,12 @@ public static List searchRoutes(StationTag start, StationTag destination, int minNumber = routes.stream().mapToInt(x -> x.getTransferCount()).min().orElse(0); routes = routes.stream().filter(x -> x.getTransferCount() == minNumber).toList(); - CreateRailwaysNavigator.LOGGER.info(String.format("%s route(s) calculated. Took %sms.", - routes.size(), - System.currentTimeMillis() - startTime - )); + if (ModCommonConfig.ADVANCED_LOGGING.get()) { + CreateRailwaysNavigator.LOGGER.info(String.format("%s route(s) calculated. Took %sms.", + routes.size(), + System.currentTimeMillis() - startTime + )); + } return routes.stream().sorted((a, b) -> Long.compare(a.getStart().getScheduledDepartureTime(), b.getStart().getScheduledDepartureTime())).toList(); } diff --git a/common/src/main/java/de/mrjulsen/crn/data/schedule/condition/TrainSeparationCondition.java b/common/src/main/java/de/mrjulsen/crn/data/schedule/condition/TrainSeparationCondition.java index 502b8757..a62ef544 100644 --- a/common/src/main/java/de/mrjulsen/crn/data/schedule/condition/TrainSeparationCondition.java +++ b/common/src/main/java/de/mrjulsen/crn/data/schedule/condition/TrainSeparationCondition.java @@ -11,6 +11,7 @@ import de.mrjulsen.crn.CreateRailwaysNavigator; import de.mrjulsen.crn.client.ClientWrapper; +import de.mrjulsen.crn.data.ETimeSource; import de.mrjulsen.crn.data.schedule.IConditionsRequiresInstruction; import de.mrjulsen.crn.data.schedule.INavigationExtension; import de.mrjulsen.crn.data.train.StationDepartureHistory; @@ -29,13 +30,16 @@ public class TrainSeparationCondition extends ScheduledDelay implements IDelayedWaitCondition, IConditionsRequiresInstruction { - public static final String NBT_TIME = "Value"; + @Deprecated public static final String NBT_TIME = "Value"; + @Deprecated public static final String NBT_TIME_UNIT = "TimeUnit"; + public static final String NBT_TICKS = "Ticks"; public static final String NBT_TRAIN_FILTER = "TrainFilter"; - public static final String NBT_TIME_UNIT = "TimeUnit"; + public static final String NBT_TIME_SOURCE = "TimeSource"; public TrainSeparationCondition() { super(); data.putByte(NBT_TRAIN_FILTER, ETrainFilter.ANY.getIndex()); + data.putInt(NBT_TICKS, 100); } @Override @@ -48,6 +52,28 @@ public ItemStack getSecondLineIcon() { return new ItemStack(Items.OBSERVER); } + @Override + public int totalWaitTicks() { + if (data.contains(NBT_TICKS)) { + return data.getInt(NBT_TICKS); + } + return super.totalWaitTicks(); + } + + @Override + protected Component formatTime(boolean compact) { + int remainingTicks = totalWaitTicks(); + int minutes = remainingTicks / 1200; + remainingTicks %= 1200; + int seconds = remainingTicks / 20; + remainingTicks %= 20; + + if (compact) { + return TextUtils.text(String.format("%d:%02d,%02d", minutes, seconds, remainingTicks)); + } + return TextUtils.text(String.format("%dm %ds %dt", minutes, seconds, remainingTicks)); + } + @Override public List getTitleAs(String type) { return ImmutableList.of( @@ -94,6 +120,10 @@ public ETrainFilter getTrainFilter() { return ETrainFilter.getByIndex(data.getByte(NBT_TRAIN_FILTER)); } + public ETimeSource getTimeSource() { + return ETimeSource.getByIndex(data.getByte(NBT_TIME_SOURCE)); + } + @Override @Environment(EnvType.CLIENT) public void initConfigurationWidgets(ModularGuiLineBuilder builder) { diff --git a/common/src/main/java/de/mrjulsen/crn/data/train/TrainData.java b/common/src/main/java/de/mrjulsen/crn/data/train/TrainData.java index 3cd094b2..c73d57d1 100644 --- a/common/src/main/java/de/mrjulsen/crn/data/train/TrainData.java +++ b/common/src/main/java/de/mrjulsen/crn/data/train/TrainData.java @@ -67,7 +67,12 @@ public class TrainData implements IListenable { private transient final Cache defaultSection = new Cache<>(() -> TrainTravelSection.def(this), ECachingPriority.LOW); private transient final List predictionsChronologically = new LockedList<>(); private transient final Set validPredictionEntries = new HashSet<>(); - private transient final Cache isDynamic = new Cache<>(() -> getTrain().runtime.getSchedule().entries.stream().anyMatch(x -> x.conditions.stream().flatMap(y -> y.stream()).anyMatch(y -> y instanceof DynamicDelayCondition c && c.minWaitTicks() < c.totalWaitTicks()))); + private transient final Cache isDynamic = new Cache<>(() -> + getTrain() != null && + getTrain().runtime != null && + getTrain().runtime.getSchedule() != null && + getTrain().runtime.getSchedule().entries.stream().anyMatch(x -> x.conditions.stream().flatMap(y -> y.stream()).anyMatch(y -> y instanceof DynamicDelayCondition c && c.minWaitTicks() < c.totalWaitTicks())) + ); private int currentScheduleIndex = INVALID; private transient int currentTravelSectionIndex = INVALID; @@ -635,6 +640,7 @@ public void leaveDestination() { public void onInitialize() { updateTotalDuration(); + isDynamic.clear(); } /** Checks and calculates a new total duration time if necessary. */ diff --git a/common/src/main/java/de/mrjulsen/crn/data/train/TrainListener.java b/common/src/main/java/de/mrjulsen/crn/data/train/TrainListener.java index efdf7881..46e26bdd 100644 --- a/common/src/main/java/de/mrjulsen/crn/data/train/TrainListener.java +++ b/common/src/main/java/de/mrjulsen/crn/data/train/TrainListener.java @@ -14,6 +14,7 @@ import com.simibubi.create.content.trains.entity.Train; import de.mrjulsen.crn.CreateRailwaysNavigator; +import de.mrjulsen.crn.config.ModCommonConfig; import de.mrjulsen.crn.data.schedule.INavigationExtension; import de.mrjulsen.crn.data.storage.GlobalSettings; import de.mrjulsen.crn.event.CRNEventsManager; @@ -48,49 +49,67 @@ public static void init() { // Register Event Listeners CRNEventsManager.getEvent(GlobalTrainDisplayDataRefreshEventPre.class).register(CreateRailwaysNavigator.MOD_ID, () -> { queueTrainListenerTask(() -> { - StationDepartureHistory.cleanUpDepartureHistory(); - TrainListener.refreshPre(); + try { + StationDepartureHistory.cleanUpDepartureHistory(); + TrainListener.refreshPre(); + } catch (Exception e) { + DragonLib.LOGGER.error("Cannot run train listener task 'TrainListener#GlobalTrainDisplayDataRefreshEventPre': " + e.getMessage(), e); + } }); }); CRNEventsManager.getEvent(GlobalTrainDisplayDataRefreshEventPost.class).register(CreateRailwaysNavigator.MOD_ID, () -> { - TrainUtils.refreshCache(); - queueTrainListenerTask(TrainListener::refreshPost); + queueTrainListenerTask(() -> { + try { + TrainUtils.refreshCache(); + TrainListener.refreshPost(); + } catch (Exception e) { + DragonLib.LOGGER.error("Cannot run train listener task 'TrainListener#GlobalTrainDisplayDataRefreshEventPost': " + e.getMessage(), e); + } + }); }); CRNEventsManager.getEvent(TrainDestinationChangedEvent.class).register(CreateRailwaysNavigator.MOD_ID, (train, current, next, nextIndex) -> { }); CRNEventsManager.getEvent(TotalDurationTimeChangedEvent.class).register(CreateRailwaysNavigator.MOD_ID, (train, old, newDuration) -> { - CreateRailwaysNavigator.LOGGER.warn("The total duration of the train " + train.name.getString() + " (" + train.id + ") has changed from " + old + " Ticks to " + newDuration + " Ticks. This will result in changes to the scheduled departure times!"); + if (ModCommonConfig.ADVANCED_LOGGING.get()) CreateRailwaysNavigator.LOGGER.info("The total duration of the train " + train.name.getString() + " (" + train.id + ") has changed from " + old + " Ticks to " + newDuration + " Ticks. This will result in changes to the scheduled departure times!"); }); CRNEventsManager.getEvent(TrainArrivalAndDepartureEvent.class).register(CreateRailwaysNavigator.MOD_ID, (train, station, isArrival) -> { queueTrainListenerTask(() -> { - if (data.containsKey(train.id)) { - if (isArrival) { - data.get(train.id).reachDestination(DragonLib.getCurrentWorldTime(), ((ScheduleRuntimeAccessor)train.runtime).crn$getTicksInTransit()); - } else { - data.get(train.id).leaveDestination(); + try { + if (data.containsKey(train.id) && train.runtime != null) { + if (isArrival) { + data.get(train.id).reachDestination(DragonLib.getCurrentWorldTime(), ((ScheduleRuntimeAccessor)train.runtime).crn$getTicksInTransit()); + } else { + data.get(train.id).leaveDestination(); + } } - } - - if (!isArrival && !((INavigationExtension)(Object)train.navigation).isDelayedWaitConditionPending()) { - // If not checking whether a delayed condition is pending, the train would block itself. - StationDepartureHistory.updateDepartureHistory(train, station.name); - } + + if (!isArrival && train.navigation != null && station.isPresent() && !((INavigationExtension)(Object)train.navigation).isDelayedWaitConditionPending()) { + // If not checking whether a delayed condition is pending, the train would block itself. + StationDepartureHistory.updateDepartureHistory(train, station.get().name); + } + } catch (Exception e) { + DragonLib.LOGGER.error("Cannot run train listener task 'TrainListener#TrainArrivalAndDepartureEvent': " + e.getMessage(), e); + } }); }); CRNEventsManager.getEvent(ScheduleResetEvent.class).register(CreateRailwaysNavigator.MOD_ID, (train, soft) -> { queueTrainListenerTask(() -> { - if (data.containsKey(train.id)) { - TrainData trainData = data.get(train.id); - if (soft) { - trainData.resetPredictions(); - } else { - trainData.hardResetPredictions(); + try { + if (data.containsKey(train.id)) { + TrainData trainData = data.get(train.id); + if (soft) { + trainData.resetPredictions(); + } else { + trainData.hardResetPredictions(); + } } + } catch (Exception e) { + DragonLib.LOGGER.error("Cannot run train listener task 'TrainListener#ScheduleResetEvent': " + e.getMessage(), e); } }); }); @@ -100,13 +119,17 @@ public static void init() { }); CRNEventsManager.getEvent(CreateTrainPredictionEvent.class).register(CreateRailwaysNavigator.MOD_ID, (train, schedule, predictables, index, stayDuration, minStayDuration, prediction) -> { - queueTrainListenerTask(() -> { - ScheduleRuntimeAccessor accessor = (ScheduleRuntimeAccessor)(Object)schedule; - UUID trainId = accessor.crn$getTrain().id; - if (data.containsKey(trainId) && prediction != null) { - TrainData trainData = data.get(trainId); - TrainPrediction pred = trainData.setPredictionData(index, schedule.currentEntry, schedule.getSchedule().entries.size(), stayDuration, minStayDuration, accessor.crn$predictionTicks().get(index), prediction); - predictables.values().forEach(x -> x.predictForStation(trainData, pred, schedule, index, accessor.crn$getTrain())); + queueTrainListenerTask(() -> { + try { + ScheduleRuntimeAccessor accessor = (ScheduleRuntimeAccessor)(Object)schedule; + UUID trainId = accessor.crn$getTrain().id; + if (data.containsKey(trainId) && prediction != null) { + TrainData trainData = data.get(trainId); + TrainPrediction pred = trainData.setPredictionData(index, schedule.currentEntry, schedule.getSchedule().entries.size(), stayDuration, minStayDuration, accessor.crn$predictionTicks().get(index), prediction); + predictables.values().forEach(x -> x.predictForStation(trainData, pred, schedule, index, accessor.crn$getTrain())); + } + } catch (Exception e) { + DragonLib.LOGGER.error("Cannot run train listener task 'TrainListener#CreateTrainPredictionEvent': " + e.getMessage(), e); } }); }); diff --git a/common/src/main/java/de/mrjulsen/crn/event/events/TrainArrivalAndDepartureEvent.java b/common/src/main/java/de/mrjulsen/crn/event/events/TrainArrivalAndDepartureEvent.java index 40bcde92..7797a5b7 100644 --- a/common/src/main/java/de/mrjulsen/crn/event/events/TrainArrivalAndDepartureEvent.java +++ b/common/src/main/java/de/mrjulsen/crn/event/events/TrainArrivalAndDepartureEvent.java @@ -1,12 +1,14 @@ package de.mrjulsen.crn.event.events; +import java.util.Optional; + import com.simibubi.create.content.trains.entity.Train; import com.simibubi.create.content.trains.station.GlobalStation; import de.mrjulsen.crn.event.CRNEventsManager.AbstractCRNEvent; public final class TrainArrivalAndDepartureEvent extends AbstractCRNEvent { - public void run(Train train, GlobalStation current, boolean arrival) { + public void run(Train train, Optional current, boolean arrival) { listeners.values().forEach(x -> x.run(train, current, arrival)); tickPost(); } @@ -18,6 +20,6 @@ public static interface ITrainApprochEventData { * @param current The current station. * @param departure {@code true} if the train is arriving at the current station, {@code false} when leaving. */ - void run(Train train, GlobalStation current, boolean arrival); + void run(Train train, Optional current, boolean arrival); } } diff --git a/common/src/main/java/de/mrjulsen/crn/mixin/TrainMixin.java b/common/src/main/java/de/mrjulsen/crn/mixin/TrainMixin.java index d7852c88..eb7ed34e 100644 --- a/common/src/main/java/de/mrjulsen/crn/mixin/TrainMixin.java +++ b/common/src/main/java/de/mrjulsen/crn/mixin/TrainMixin.java @@ -1,5 +1,7 @@ package de.mrjulsen.crn.mixin; +import java.util.Optional; + import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -22,14 +24,14 @@ public Train self() { @Inject(method = "arriveAt", remap = false, at = @At(value = "TAIL")) public void onArriveAt(GlobalStation station, CallbackInfo ci) { if (CRNEventsManager.isRegistered(TrainArrivalAndDepartureEvent.class)) { - CRNEventsManager.getEvent(TrainArrivalAndDepartureEvent.class).run(self(), station, true); + CRNEventsManager.getEvent(TrainArrivalAndDepartureEvent.class).run(self(), Optional.ofNullable(station), true); } } @Inject(method = "leaveStation", remap = false, at = @At(value = "TAIL"), locals = LocalCapture.CAPTURE_FAILHARD) public void onLeaveStation(CallbackInfo ci, GlobalStation currentStation) { if (CRNEventsManager.isRegistered(TrainArrivalAndDepartureEvent.class)) { - CRNEventsManager.getEvent(TrainArrivalAndDepartureEvent.class).run(self(), currentStation, false); + CRNEventsManager.getEvent(TrainArrivalAndDepartureEvent.class).run(self(), Optional.ofNullable(currentStation), false); } } } diff --git a/common/src/main/resources/assets/createrailwaysnavigator/lang/de_de.json b/common/src/main/resources/assets/createrailwaysnavigator/lang/de_de.json index 5765e4d8..75a47c43 100644 --- a/common/src/main/resources/assets/createrailwaysnavigator/lang/de_de.json +++ b/common/src/main/resources/assets/createrailwaysnavigator/lang/de_de.json @@ -377,7 +377,7 @@ "block.createrailwaysnavigator.advanced_display.ber.information_about_cancelled": "Information zu %s: Fällt heute aus!", "block.createrailwaysnavigator.advanced_display.ber.information_about_delayed": "Information zu %s: Verspätung ca. %s", "block.createrailwaysnavigator.advanced_display.ber.cancelled2": "fällt heute aus. Wir bitten um Entschuldigung.", - "block.createrailwaysnavigator.advanced_display.ber.delayed2": "heute circa %s später.", + "block.createrailwaysnavigator.advanced_display.ber.delayed2": "heute circa %s%s später.", "block.createrailwaysnavigator.advanced_display.ber.reason": "Grund dafür ist eine ", "gui.createrailwaysnavigator.route_widget.show_details": "Details ansehen", "gui.createrailwaysnavigator.route_widget.save": "Speichern", diff --git a/common/src/main/resources/assets/createrailwaysnavigator/lang/en_us.json b/common/src/main/resources/assets/createrailwaysnavigator/lang/en_us.json index f51299f8..a7f7869a 100644 --- a/common/src/main/resources/assets/createrailwaysnavigator/lang/en_us.json +++ b/common/src/main/resources/assets/createrailwaysnavigator/lang/en_us.json @@ -376,9 +376,8 @@ "block.createrailwaysnavigator.advanced_display.ber.delayed": "Delay approx. %s", "block.createrailwaysnavigator.advanced_display.ber.information_about_cancelled": "Information about %s: This train got cancelled", "block.createrailwaysnavigator.advanced_display.ber.information_about_delayed": "Information about %s: Delay approx. %s", - "block.createrailwaysnavigator.advanced_display.ber.information_about_delayed_with_unit": "Information about %s: Delay approx. %s", "block.createrailwaysnavigator.advanced_display.ber.cancelled2": "is cancelled today. We apologize for the inconvenience.", - "block.createrailwaysnavigator.advanced_display.ber.delayed2": "today approx. %s delayed.", + "block.createrailwaysnavigator.advanced_display.ber.delayed2": "today approx. %s%s delayed.", "block.createrailwaysnavigator.advanced_display.ber.reason": "Reason: ", "gui.createrailwaysnavigator.route_widget.show_details": "Show details", "gui.createrailwaysnavigator.route_widget.save": "Save", diff --git a/gradle.properties b/gradle.properties index dac97b84..912fc6c5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs=-Xmx8G org.gradle.parallel=true # Mod properties -mod_version = 0.7.0 +mod_version = 0.7.1 release_channel = beta maven_group = de.mrjulsen.crn archives_name = createrailwaysnavigator @@ -35,7 +35,7 @@ fabric_api_version = 0.77.0+1.19.2 forge_version = 1.19.2-43.3.13 forge_version_int = 43 -dragonlib_version = 2.2.21 +dragonlib_version = 2.2.22 modmenu_version = 4.1.2 forge_config_api_port_version = 4.2.11 create_fabric_version = 0.5.1-f-build.1416+mc1.19.2