From 9fff7e84008c9fc7aaec33e6e21381c8f430eed3 Mon Sep 17 00:00:00 2001 From: DanteMC <68405877+DanteMinecraft@users.noreply.github.com> Date: Sun, 21 Jun 2026 05:17:28 +0200 Subject: [PATCH 01/13] updated logotype and readme --- README.md | 62 +++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 36c1cbd..4aa2d3c 100644 --- a/README.md +++ b/README.md @@ -1,28 +1,60 @@ -# đŸ› ïž Create: Maintenance Control ⚠ -![Modrinth](https://github.com/user-attachments/assets/ba69b03d-1f09-458c-9429-817854d7793a) +# đŸ› ïž Create: Maintenance Control +Logotype -Create: Maintenance Control is a small addon for Create that introduces maintenance mechanics to your train networks. +Create: Maintenance Control is a small addon for Create that lets you temporarily disable Train Stations, making trains skip them without having to edit their train schedules manually. + +Place a Maintenance Box next to a station to mark it as under maintenance. Trains with that station in their schedules will automatically skip it until maintenance is disabled again. ## âŹ‡ïž Download the mod -_Download links will be available once the mod is released_ +- Download from Modrinth [here](https://modrinth.com/mod/create-maintenance-control) +- Download from CurseForge [here](https://www.curseforge.com/minecraft/mc-mods/create-maintenance-control) ## đŸ› ïž Dependencies - This mod requires [Create](https://modrinth.com/mod/create) - Using a recipe viewer such as JEI or EMI is recommended ## 🔎 Features -### Maintenance Box block -The Maintenance Box block can be placed next to a Train Station block to mark it as being under maintenance. +### Maintenance Box +Place a Maintenance Box next to a Train Station to mark it as under maintenance. + +While maintenance is active: + +- trains will skip that station instead of stopping there +- train schedules do not need to be edited manually +- redstone can be used to temporarily disable the maintenance effect + +#### Example use cases +- Temporarily closing a platform during rebuilding +- Skipping a station during track work +- Toggling maintenance with redstone for operational events -When a station is under maintenance: +## Current behaviour / limitations +- If a disabled station is a terminus, trains may encounter route errors unless the network allows them to pathfind from the previous stop to the next scheduled one. + - This is currently the intended behavior rather than a bug/limitation. +- The mod currently focuses on skipping maintenance-marked stations rather than rerouting trains to alternative destinations. More advanced routing behaviour may be explored in future updates. +- Best results are achieved on networks where trains can still pathfind from the previous stop to the next one. -- đŸš« Trains with that station in their schedules will automatically skip it. -- 🚄 Depending on your railway network, trains may still pass through the station if no alternative route exists. However, when multiple paths are available, trains will prioritize routes that avoid stations under maintenance. -- 🚉 Existing railway networks continue operating normally. -- 🔧 Stations can be temporarily taken out of service without modifying train schedules. +## ⚠ Known issues +- Maintenance Boxes do not always behave correctly in unloaded chunks. + - This is tagged as a high-priority issue and will be addressed before any major new features are added. + +## đŸ€ Compatibility +The mod has been tested in larger Create-based modpacks and appears to work fine alongside many common Create addons. + +This includes initial testing with: +- Create: Aeronautics (MC 1.21.1) +- Sable (MC 1.21.1) +- Create Railways Navigator +- Steam 'n' Rails ## 📌 Planned -- Ponder scene for the Maintenance Box block -- Maintenance Box GUI -- Redstone input/output for the Maintenance Box block -- Expanded functionality for the Maintenance Box block + +### Maintenance Box GUI +Planned options include: + - a station name filter field + - a redstone behavior toggle (powered = maintenance / unpowered = maintenance) + - a "__Skip unreachable downstream stations__" toggle for more advanced network layouts + +### Documentation / Usability +- a Ponder scene for the Maintenance Box +- expanded documentation and examples on the Wiki page here on GitHub From 391e3c5aca67eea7d878d1dd090a4918fc10e322 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Tue, 23 Jun 2026 21:29:12 +0200 Subject: [PATCH 02/13] restructured maintenance box data for redstone modes and future GUI support and added support for create 6.0.8 and 6.0.9 --- gradle.properties | 3 +- .../maintenance_box/MaintenanceBoxBlock.java | 18 +++++- .../MaintenanceBoxBlockEntity.java | 2 +- .../MaintenanceRedstoneMode.java | 18 ++++++ .../content/maintenance_box/StationUtils.java | 2 +- .../gui/MaintenanceBoxScreen.java | 56 +++++++++++++++++++ .../mixin/DestinationInstructionMixin.java | 1 - .../railway/MaintenanceEntry.java | 4 +- .../railway/MaintenanceSavedData.java | 15 ++++- .../railway/OfflineStationManager.java | 38 ++++++++----- .../templates/META-INF/neoforge.mods.toml | 2 +- 11 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceRedstoneMode.java create mode 100644 src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java diff --git a/gradle.properties b/gradle.properties index 5e0e4cd..974e3da 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,8 @@ neo_version=21.1.233 loader_version_range=[1,) ## Dependencies -create_version = 6.0.10-280 +create_version = 6.0.8-168 +create_version_range = [6.0.8,6.1.0) ponder_version = 1.0.82 flywheel_version = 1.0.6 registrate_version = MC1.21-1.3.0+67 diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java index e6a6ba6..fc08a75 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java @@ -1,14 +1,17 @@ package net.dantemc.create_maintenance_control.content.maintenance_box; - import com.simibubi.create.content.trains.station.GlobalStation; import com.simibubi.create.foundation.block.IBE; import com.simibubi.create.foundation.block.WrenchableDirectionalBlock; +import net.createmod.catnip.gui.ScreenOpener; import net.dantemc.create_maintenance_control.CreateMaintenance; +import net.dantemc.create_maintenance_control.content.maintenance_box.gui.MaintenanceBoxScreen; import net.dantemc.create_maintenance_control.foundation.CreateMaintenanceShapes; import net.dantemc.create_maintenance_control.railway.OfflineStationManager; +import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; @@ -21,6 +24,8 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; public class MaintenanceBoxBlock extends WrenchableDirectionalBlock implements IBE { @@ -53,7 +58,7 @@ public void neighborChanged(BlockState state, Level level, BlockPos pos, Block b GlobalStation station = StationUtils.findNearbyStation(level, pos); if (station == null) return; - OfflineStationManager.registerBox(level, pos, station.name, !powered); + OfflineStationManager.refreshBox(level, pos, station.name, powered); } @Override @@ -76,7 +81,7 @@ public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldS GlobalStation station = StationUtils.findNearbyStation(level, pos); if (station == null) return; - OfflineStationManager.registerBox(level, pos, station.name, !powered); + OfflineStationManager.refreshBox(level, pos, station.name, powered); } @Override @@ -94,6 +99,13 @@ public void onRemove(BlockState state, Level level, BlockPos pos, BlockState new OfflineStationManager.unregisterBox(level, pos); } + @OnlyIn(value = Dist.CLIENT) + protected void displayScreen(MaintenanceBoxBlockEntity be, Player player) { + if (!(player instanceof LocalPlayer)) + return; + //ScreenOpener.open(new MaintenanceBoxScreen(be)); + } + @Override public Class getBlockEntityClass() { return MaintenanceBoxBlockEntity.class; diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java index ba9edc7..ee6427a 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java @@ -28,7 +28,7 @@ public void registerStation() { boolean powered = getBlockState().getValue(MaintenanceBoxBlock.POWERED); - OfflineStationManager.registerBox(level, getBlockPos(), station.name, !powered); + OfflineStationManager.refreshBox(level, getBlockPos(), station.name, powered); } @Override diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceRedstoneMode.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceRedstoneMode.java new file mode 100644 index 0000000..0da280a --- /dev/null +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceRedstoneMode.java @@ -0,0 +1,18 @@ +package net.dantemc.create_maintenance_control.content.maintenance_box; + +public enum MaintenanceRedstoneMode { + UNPOWERED_ACTIVE { + @Override + public boolean isMaintenanceActive(boolean powered) { + return !powered; + } + }, + POWERED_ACTIVE { + @Override + public boolean isMaintenanceActive(boolean powered) { + return powered; + } + }; + + public abstract boolean isMaintenanceActive(boolean powered); +} diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/StationUtils.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/StationUtils.java index 32622ff..eb466be 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/StationUtils.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/StationUtils.java @@ -19,4 +19,4 @@ public static GlobalStation findNearbyStation(Level level, BlockPos pos) { } return null; } -} +} \ No newline at end of file diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java new file mode 100644 index 0000000..6400218 --- /dev/null +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -0,0 +1,56 @@ +package net.dantemc.create_maintenance_control.content.maintenance_box.gui; + +public class MaintenanceBoxScreen { +} + +/*import com.simibubi.create.api.behaviour.display.DisplaySource; +import com.simibubi.create.api.behaviour.display.DisplayTarget; +import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockEntity; +import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.ModularGuiLine; +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 net.createmod.catnip.data.Couple; +import net.createmod.catnip.gui.AbstractSimiScreen; +import net.createmod.catnip.gui.widget.AbstractSimiWidget; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.block.state.BlockState; + +import java.util.Collections; +import java.util.List; + +public class MaintenanceBoxScreen extends AbstractSimiScreen { + + private static final ItemStack FALLBACK = new ItemStack(Items.BARRIER); + + private AllGuiTextures background; + private MaintenanceBoxBlockEntity blockEntity; + private IconButton confirmButton; + + BlockState sourceState; + BlockState targetState; + List sources; + DisplayTarget target; + + ScrollInput sourceTypeSelector; + Label sourceTypeLabel; + ScrollInput targetLineSelector; + Label targetLineLabel; + AbstractSimiWidget sourceWidget; + AbstractSimiWidget targetWidget; + + Couple configWidgets; + + public MaintenanceBoxScreen(MaintenanceBoxBlockEntity be) { + this.background = AllGuiTextures.DATA_GATHERER; + this.blockEntity = be; + sources = Collections.emptyList(); + configWidgets = Couple.create(ModularGuiLine::new); + target = null; + } + +}*/ diff --git a/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java b/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java index e41296f..b62c2db 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java +++ b/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java @@ -6,7 +6,6 @@ import com.simibubi.create.content.trains.station.GlobalStation; import net.dantemc.create_maintenance_control.CreateMaintenance; -import net.dantemc.create_maintenance_control.content.maintenance_box.StationUtils; import net.dantemc.create_maintenance_control.railway.OfflineStationManager; import net.minecraft.world.level.Level; import com.simibubi.create.content.trains.graph.EdgePointType; diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceEntry.java b/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceEntry.java index 6487eb6..cb4bb32 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceEntry.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceEntry.java @@ -1,4 +1,6 @@ package net.dantemc.create_maintenance_control.railway; -public record MaintenanceEntry(String stationFilter, boolean shouldSkip) { +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; + +public record MaintenanceEntry(String stationFilter, boolean shouldSkip, MaintenanceRedstoneMode redstoneMode, boolean skipDownstream) { } \ No newline at end of file diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSavedData.java b/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSavedData.java index 607e361..2e24b17 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSavedData.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSavedData.java @@ -1,5 +1,6 @@ package net.dantemc.create_maintenance_control.railway; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; import net.minecraft.core.BlockPos; import net.minecraft.core.HolderLookup; import net.minecraft.nbt.CompoundTag; @@ -57,8 +58,17 @@ public static MaintenanceSavedData load(CompoundTag tag, HolderLookup.Provider r String stationFilter = entryTag.getString("StationFilter"); boolean shouldSkip = entryTag.getBoolean("ShouldSkip"); + MaintenanceRedstoneMode redstoneMode; - MaintenanceEntry entry = new MaintenanceEntry(stationFilter, shouldSkip); + try { + redstoneMode = MaintenanceRedstoneMode.valueOf(entryTag.getString("RedstoneMode")); + } catch (IllegalArgumentException e) { + redstoneMode = MaintenanceRedstoneMode.UNPOWERED_ACTIVE; + } + + boolean skipDownstream = entryTag.getBoolean("SkipDownstream"); + + MaintenanceEntry entry = new MaintenanceEntry(stationFilter, shouldSkip, redstoneMode, skipDownstream); data.entries.put(boxPos, entry); } return data; @@ -79,6 +89,9 @@ public CompoundTag save(CompoundTag tag, HolderLookup.Provider registries) { entryTag.putString("StationFilter", entry.stationFilter()); entryTag.putBoolean("ShouldSkip", entry.shouldSkip()); + entryTag.putString("RedstoneMode", entry.redstoneMode().name()); + entryTag.putBoolean("SkipDownstream", entry.skipDownstream()); + entryList.add(entryTag); } diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java index a0b679c..cc0034d 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java @@ -1,11 +1,11 @@ package net.dantemc.create_maintenance_control.railway; import com.simibubi.create.content.trains.station.GlobalStation; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; -import java.util.Map; import java.util.Objects; @@ -20,29 +20,39 @@ private static MaintenanceSavedData getData(Level level) { return overworld.getDataStorage().computeIfAbsent(MaintenanceSavedData.factory(), MaintenanceSavedData.dataName()); } - public static void registerBox(Level level, BlockPos boxPos, String stationFilter, boolean shouldSkip) { - MaintenanceEntry entry = new MaintenanceEntry(stationFilter, shouldSkip); + public static MaintenanceEntry getEntry(Level level, BlockPos boxPos) { + return getData(level).getEntries().get(boxPos); + } + public static void setEntry(Level level, BlockPos boxPos, MaintenanceEntry entry) { getData(level).setEntry(boxPos, entry); } + public static void refreshBox(Level level, BlockPos boxPos, String defaultStationFilter, boolean powered) { + MaintenanceEntry entry = getEntry(level, boxPos); + + if (entry == null) { + entry = new MaintenanceEntry(defaultStationFilter, + false, MaintenanceRedstoneMode.UNPOWERED_ACTIVE, false + ); + } + + boolean shouldSkip = entry.redstoneMode().isMaintenanceActive(powered); + + MaintenanceEntry updated = new MaintenanceEntry(entry.stationFilter(), shouldSkip, entry.redstoneMode(), entry.skipDownstream()); + + setEntry(level, boxPos, updated); + } + public static void unregisterBox(Level level, BlockPos boxPos) { getData(level).removeEntry(boxPos); } public static boolean isStationSkipped(Level level, GlobalStation station) { - String stationName = station.name; - Map allData = getData(level).getEntries(); - - for (BlockPos boxPos : allData.keySet()) { - MaintenanceEntry entry = allData.get(boxPos); - - if (entry.shouldSkip()) { - - if (Objects.equals(entry.stationFilter(), stationName)) { - return true; - } + for (MaintenanceEntry entry : getData(level).getEntries().values()) { + if (entry.shouldSkip() && Objects.equals(entry.stationFilter(), stationName)) { + return true; } } return false; diff --git a/src/main/templates/META-INF/neoforge.mods.toml b/src/main/templates/META-INF/neoforge.mods.toml index 90fdbf8..536ede5 100644 --- a/src/main/templates/META-INF/neoforge.mods.toml +++ b/src/main/templates/META-INF/neoforge.mods.toml @@ -82,7 +82,7 @@ config="${mod_id}.mixins.json" [[dependencies.${mod_id}]] modId="create" type="required" - versionRange="[6.0.10,6.1.0)" + versionRange="[6.0.8,6.1.0)" ordering="NONE" side="BOTH" From 88f40619b524ae675bd1da62c70d5b59ca880fbb Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Tue, 23 Jun 2026 21:30:20 +0200 Subject: [PATCH 03/13] bumped version number --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 974e3da..cfa4da6 100644 --- a/gradle.properties +++ b/gradle.properties @@ -39,7 +39,7 @@ mod_name=Create: Maintenance Control # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GPL-3.0 License # The mod version. See https://semver.org/ -mod_version=1.1.2-mc1.21.1 +mod_version=1.2.0-mc1.21.1 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html From caf1111ffee7d27d078a5eefae8ec1e159145985 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Tue, 23 Jun 2026 21:56:40 +0200 Subject: [PATCH 04/13] added GUI (without direct functionality for now) --- .../maintenance_box/MaintenanceBoxBlock.java | 13 ++- .../MaintenanceBoxBlockEntity.java | 9 ++ .../gui/MaintenanceBoxScreen.java | 95 +++++++++++-------- .../railway/OfflineStationManager.java | 14 +++ 4 files changed, 91 insertions(+), 40 deletions(-) diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java index fc08a75..ed6faac 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java @@ -11,6 +11,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; @@ -22,6 +23,7 @@ import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.VoxelShape; import net.neoforged.api.distmarker.Dist; @@ -103,7 +105,7 @@ public void onRemove(BlockState state, Level level, BlockPos pos, BlockState new protected void displayScreen(MaintenanceBoxBlockEntity be, Player player) { if (!(player instanceof LocalPlayer)) return; - //ScreenOpener.open(new MaintenanceBoxScreen(be)); + ScreenOpener.open(new MaintenanceBoxScreen(be)); } @Override @@ -127,6 +129,15 @@ public VoxelShape getShape(BlockState State, BlockGetter Level, BlockPos Pos, Co return CreateMaintenanceShapes.MAINTENANCE_BOX.get(State.getValue(FACING)); } + @Override + protected InteractionResult useWithoutItem(BlockState state, Level level, BlockPos pos, Player player, BlockHitResult hitResult) { + if (level.isClientSide) { + withBlockEntityDo(level, pos, be -> displayScreen(be, player)); + } + + return InteractionResult.SUCCESS; + } + @Override protected void tick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java index ee6427a..4b20b44 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java @@ -2,6 +2,7 @@ import com.simibubi.create.content.trains.station.GlobalStation; import net.dantemc.create_maintenance_control.CreateMaintenance; +import net.dantemc.create_maintenance_control.railway.MaintenanceEntry; import net.dantemc.create_maintenance_control.railway.OfflineStationManager; import net.minecraft.core.BlockPos; import net.minecraft.world.level.Level; @@ -31,6 +32,14 @@ public void registerStation() { OfflineStationManager.refreshBox(level, getBlockPos(), station.name, powered); } + public MaintenanceEntry getEntry() { + Level level = getLevel(); + if (level == null || level.isClientSide) + return null; + + return OfflineStationManager.getEntry(level, worldPosition); + } + @Override public void onLoad() { super.onLoad(); diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index 6400218..7746fd4 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -1,56 +1,73 @@ package net.dantemc.create_maintenance_control.content.maintenance_box.gui; -public class MaintenanceBoxScreen { -} - -/*import com.simibubi.create.api.behaviour.display.DisplaySource; -import com.simibubi.create.api.behaviour.display.DisplayTarget; -import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlockEntity; import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllIcons; -import com.simibubi.create.foundation.gui.ModularGuiLine; 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 net.createmod.catnip.data.Couple; +import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import net.createmod.catnip.gui.AbstractSimiScreen; -import net.createmod.catnip.gui.widget.AbstractSimiWidget; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.components.EditBox; +import net.minecraft.network.chat.Component; -import java.util.Collections; import java.util.List; public class MaintenanceBoxScreen extends AbstractSimiScreen { - private static final ItemStack FALLBACK = new ItemStack(Items.BARRIER); + private final AllGuiTextures background = AllGuiTextures.DATA_GATHERER; + private final MaintenanceBoxBlockEntity blockEntity; - private AllGuiTextures background; - private MaintenanceBoxBlockEntity blockEntity; private IconButton confirmButton; + private EditBox stationFilterBox; + private SelectionScrollInput redstoneModeSelector; + + public MaintenanceBoxScreen(MaintenanceBoxBlockEntity blockEntity) { + this.blockEntity = blockEntity; + } + + @Override + protected void init() { + setWindowSize(background.getWidth(), background.getHeight()); + super.init(); + + int x = guiLeft; + int y = guiTop; + + // placeholders + String stationFilter = ""; + int redstoneModeIndex = 0; - BlockState sourceState; - BlockState targetState; - List sources; - DisplayTarget target; - - ScrollInput sourceTypeSelector; - Label sourceTypeLabel; - ScrollInput targetLineSelector; - Label targetLineLabel; - AbstractSimiWidget sourceWidget; - AbstractSimiWidget targetWidget; - - Couple configWidgets; - - public MaintenanceBoxScreen(MaintenanceBoxBlockEntity be) { - this.background = AllGuiTextures.DATA_GATHERER; - this.blockEntity = be; - sources = Collections.emptyList(); - configWidgets = Couple.create(ModularGuiLine::new); - target = null; + // station filter textbox + stationFilterBox = new EditBox(font, x + 24, y + 28, 120, 18, Component.literal("Station Filter")); + stationFilterBox.setValue(stationFilter); + stationFilterBox.setMaxLength(64); + addRenderableWidget(stationFilterBox); + + // redstone mode selector + redstoneModeSelector = (SelectionScrollInput) new SelectionScrollInput(x + 24, y + 70, 120, 18) + .forOptions(List.of( + Component.literal("Unpowered = Maintenance"), + Component.literal("Powered = Maintenance") + )); + redstoneModeSelector.setState(redstoneModeIndex); + addRenderableWidget(redstoneModeSelector); + + // Confirm button + confirmButton = new IconButton(x + background.getWidth() - 33, y + background.getHeight() - 24, AllIcons.I_CONFIRM); + confirmButton.withCallback(this::onConfirm); + addRenderableWidget(confirmButton); + } + + @Override + protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { + background.render(graphics, guiLeft, guiTop); + + graphics.drawString(font, "Maintenance Box", guiLeft + 24, guiTop + 10, 0x404040, false); + graphics.drawString(font, "Station Filter", guiLeft + 24, guiTop + 18, 0x575F7A, false); + graphics.drawString(font, "Redstone Mode", guiLeft + 24, guiTop + 58, 0x575F7A, false); } -}*/ + private void onConfirm() { + onClose(); + } +} \ No newline at end of file diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java index cc0034d..75c8b7c 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java @@ -1,6 +1,7 @@ package net.dantemc.create_maintenance_control.railway; import com.simibubi.create.content.trains.station.GlobalStation; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlock; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; import net.minecraft.core.BlockPos; import net.minecraft.server.level.ServerLevel; @@ -43,6 +44,19 @@ public static void refreshBox(Level level, BlockPos boxPos, String defaultStatio setEntry(level, boxPos, updated); } + public static void updateBoxSettings(Level level, BlockPos boxPos, String stationFilter, MaintenanceRedstoneMode redstoneMode) { + MaintenanceEntry current = getEntry(level, boxPos); + if (current == null) + return; + + boolean powered = level.getBlockState(boxPos).getValue(MaintenanceBoxBlock.POWERED); + boolean shouldSkip = redstoneMode.isMaintenanceActive(powered); + + MaintenanceEntry updated = new MaintenanceEntry(stationFilter, shouldSkip, redstoneMode, current.skipDownstream()); + + setEntry(level, boxPos, updated); + } + public static void unregisterBox(Level level, BlockPos boxPos) { getData(level).removeEntry(boxPos); } From 5cb089cd1a28b79bf5dc96b911adf9530dfe2072 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Wed, 24 Jun 2026 02:52:07 +0200 Subject: [PATCH 05/13] fixed GUI functionality, refactored block-class and offlinestationmanager a bit also cleared unnecessary lines in the config class --- .../create_maintenance_control/Config.java | 6 -- .../CreateMaintenance.java | 7 ++ .../ModPackets.java | 42 +++++++++++ .../maintenance_box/MaintenanceBoxBlock.java | 18 ++--- .../MaintenanceBoxBlockEntity.java | 70 +++++++++++++++---- .../MaintenanceBoxConfigurationPacket.java | 41 +++++++++++ .../gui/MaintenanceBoxScreen.java | 22 +++++- .../railway/OfflineStationManager.java | 25 +++++-- 8 files changed, 198 insertions(+), 33 deletions(-) create mode 100644 src/main/java/net/dantemc/create_maintenance_control/ModPackets.java create mode 100644 src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java diff --git a/src/main/java/net/dantemc/create_maintenance_control/Config.java b/src/main/java/net/dantemc/create_maintenance_control/Config.java index 6e3a015..e6f22b7 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/Config.java +++ b/src/main/java/net/dantemc/create_maintenance_control/Config.java @@ -1,7 +1,5 @@ package net.dantemc.create_maintenance_control; -import net.minecraft.core.registries.BuiltInRegistries; -import net.minecraft.resources.ResourceLocation; import net.neoforged.neoforge.common.ModConfigSpec; public class Config { @@ -12,8 +10,4 @@ public class Config { .define("debugLogs", false); static final ModConfigSpec SPEC = BUILDER.build(); - - private static boolean validateItemName(final Object obj) { - return obj instanceof String itemName && BuiltInRegistries.ITEM.containsKey(ResourceLocation.parse(itemName)); - } } diff --git a/src/main/java/net/dantemc/create_maintenance_control/CreateMaintenance.java b/src/main/java/net/dantemc/create_maintenance_control/CreateMaintenance.java index 57468ca..bdfdae3 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/CreateMaintenance.java +++ b/src/main/java/net/dantemc/create_maintenance_control/CreateMaintenance.java @@ -9,6 +9,7 @@ import net.dantemc.create_maintenance_control.foundation.IgnorePlacingRulesItem; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlock; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; +import net.minecraft.resources.ResourceLocation; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.SoundType; import net.neoforged.bus.api.IEventBus; @@ -54,9 +55,15 @@ public CreateMaintenance(IEventBus modEventBus, ModContainer modContainer) { NeoForge.EVENT_BUS.register(this); + ModPackets.register(); + modContainer.registerConfig(ModConfig.Type.COMMON, Config.SPEC); } + public static ResourceLocation asResource(String path) { + return ResourceLocation.fromNamespaceAndPath(MODID, path); + } + //helper method for loggers public static void debug(String message, Object... args) { if (Config.WRITE_DEBUG_LOGS.get()) { diff --git a/src/main/java/net/dantemc/create_maintenance_control/ModPackets.java b/src/main/java/net/dantemc/create_maintenance_control/ModPackets.java new file mode 100644 index 0000000..44bb471 --- /dev/null +++ b/src/main/java/net/dantemc/create_maintenance_control/ModPackets.java @@ -0,0 +1,42 @@ +package net.dantemc.create_maintenance_control; + +import java.util.Locale; + +import net.createmod.catnip.net.base.BasePacketPayload; +import net.createmod.catnip.net.base.CatnipPacketRegistry; +import net.dantemc.create_maintenance_control.content.maintenance_box.gui.MaintenanceBoxConfigurationPacket; +import net.minecraft.network.RegistryFriendlyByteBuf; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.network.protocol.common.custom.CustomPacketPayload; + +public enum ModPackets implements BasePacketPayload.PacketTypeProvider { + CONFIGURE_MAINTENANCE_BOX( + MaintenanceBoxConfigurationPacket.class, + MaintenanceBoxConfigurationPacket.STREAM_CODEC + ); + + private final CatnipPacketRegistry.PacketType type; + + ModPackets(Class clazz, StreamCodec codec) { + String name = this.name().toLowerCase(Locale.ROOT); + this.type = new CatnipPacketRegistry.PacketType<>( + new CustomPacketPayload.Type<>(CreateMaintenance.asResource(name)), + clazz, codec + ); + } + + @Override + @SuppressWarnings("unchecked") + public CustomPacketPayload.Type getType() { + return (CustomPacketPayload.Type) this.type.type(); + } + + public static void register() { + CatnipPacketRegistry packetRegistry = + new CatnipPacketRegistry(CreateMaintenance.MODID, "1.0.0"); + for (ModPackets packet : ModPackets.values()) { + packetRegistry.registerPacket(packet.type); + } + packetRegistry.registerAllPackets(); + } +} \ No newline at end of file diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java index ed6faac..415e801 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java @@ -38,6 +38,14 @@ public MaintenanceBoxBlock(Properties properties) { registerDefaultState(defaultBlockState().setValue(POWERED, false)); } + private void refreshAttachedStationBox(Level level, BlockPos pos, boolean powered) { + GlobalStation station = StationUtils.findNearbyStation(level, pos); + if (station == null) + return; + + OfflineStationManager.refreshBox(level, pos, powered); + } + @Override protected void createBlockStateDefinition(StateDefinition.Builder builder) { builder.add(POWERED); @@ -57,10 +65,7 @@ public void neighborChanged(BlockState state, Level level, BlockPos pos, Block b level.setBlock(pos, state.setValue(POWERED, powered), Block.UPDATE_ALL); - GlobalStation station = StationUtils.findNearbyStation(level, pos); - if (station == null) - return; - OfflineStationManager.refreshBox(level, pos, station.name, powered); + refreshAttachedStationBox(level, pos, powered); } @Override @@ -80,10 +85,7 @@ public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldS level.setBlock(pos, state, Block.UPDATE_ALL); } - GlobalStation station = StationUtils.findNearbyStation(level, pos); - if (station == null) - return; - OfflineStationManager.refreshBox(level, pos, station.name, powered); + refreshAttachedStationBox(level, pos, powered); } @Override diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java index 4b20b44..e8466f3 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java @@ -1,21 +1,34 @@ package net.dantemc.create_maintenance_control.content.maintenance_box; import com.simibubi.create.content.trains.station.GlobalStation; +import com.simibubi.create.foundation.blockEntity.SyncedBlockEntity; import net.dantemc.create_maintenance_control.CreateMaintenance; import net.dantemc.create_maintenance_control.railway.MaintenanceEntry; import net.dantemc.create_maintenance_control.railway.OfflineStationManager; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.nbt.CompoundTag; import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; -public class MaintenanceBoxBlockEntity extends BlockEntity { +public class MaintenanceBoxBlockEntity extends SyncedBlockEntity { public MaintenanceBoxBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { super(type, pos, state); } + private String stationFilter = ""; + private MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.UNPOWERED_ACTIVE; + + public String getStationFilter() { + return stationFilter; + } + + public MaintenanceRedstoneMode getRedstoneMode() { + return redstoneMode; + } + public void registerStation() { Level level = getLevel(); @@ -23,21 +36,37 @@ public void registerStation() { return; GlobalStation station = StationUtils.findNearbyStation(level, getBlockPos()); - if (station == null) return; boolean powered = getBlockState().getValue(MaintenanceBoxBlock.POWERED); - OfflineStationManager.refreshBox(level, getBlockPos(), station.name, powered); + MaintenanceEntry entry = OfflineStationManager.ensureBoxEntry(level, getBlockPos(), station.name); + + this.stationFilter = entry.stationFilter(); + this.redstoneMode = entry.redstoneMode(); + + OfflineStationManager.refreshBox(level, getBlockPos(), powered); + + setChanged(); + notifyUpdate(); } - public MaintenanceEntry getEntry() { + public void applySettings(String stationFilter, MaintenanceRedstoneMode redstoneMode) { Level level = getLevel(); if (level == null || level.isClientSide) - return null; + return; + + this.stationFilter = stationFilter; + this.redstoneMode = redstoneMode; + + OfflineStationManager.updateBoxSettings(level, getBlockPos(), stationFilter, redstoneMode); - return OfflineStationManager.getEntry(level, worldPosition); + boolean powered = getBlockState().getValue(MaintenanceBoxBlock.POWERED); + OfflineStationManager.refreshBox(level, getBlockPos(), powered); + + setChanged(); + notifyUpdate(); } @Override @@ -51,10 +80,27 @@ public void onLoad() { CreateMaintenance.debug("Scheduling station registration"); - level.scheduleTick( - getBlockPos(), - getBlockState().getBlock(), - 100 - ); + level.scheduleTick(getBlockPos(), getBlockState().getBlock(), 100); + } + + @Override + protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.saveAdditional(tag, registries); + + tag.putString("StationFilter", stationFilter); + tag.putString("RedstoneMode", redstoneMode.name()); + } + + @Override + protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + super.loadAdditional(tag, registries); + + stationFilter = tag.getString("StationFilter"); + + try { + redstoneMode = MaintenanceRedstoneMode.valueOf(tag.getString("RedstoneMode")); + } catch (IllegalArgumentException e) { + redstoneMode = MaintenanceRedstoneMode.UNPOWERED_ACTIVE; + } } } diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java new file mode 100644 index 0000000..37085ec --- /dev/null +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java @@ -0,0 +1,41 @@ +package net.dantemc.create_maintenance_control.content.maintenance_box.gui; + +import com.simibubi.create.foundation.networking.BlockEntityConfigurationPacket; +import io.netty.buffer.ByteBuf; +import net.dantemc.create_maintenance_control.ModPackets; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; +import net.minecraft.core.BlockPos; +import net.minecraft.network.codec.ByteBufCodecs; +import net.minecraft.network.codec.StreamCodec; +import net.minecraft.server.level.ServerPlayer; + +public class MaintenanceBoxConfigurationPacket extends BlockEntityConfigurationPacket { + + public static final StreamCodec STREAM_CODEC = StreamCodec.composite( + BlockPos.STREAM_CODEC, packet -> packet.pos, + ByteBufCodecs.STRING_UTF8, packet -> packet.stationFilter, + ByteBufCodecs.VAR_INT, packet -> packet.redstoneMode.ordinal(), + (pos, stationFilter, redstoneModeOrdinal) -> + new MaintenanceBoxConfigurationPacket(pos, stationFilter, MaintenanceRedstoneMode.values()[redstoneModeOrdinal]) + ); + + private final String stationFilter; + private final MaintenanceRedstoneMode redstoneMode; + + public MaintenanceBoxConfigurationPacket(BlockPos pos, String stationFilter, MaintenanceRedstoneMode redstoneMode) { + super(pos); + this.stationFilter = stationFilter; + this.redstoneMode = redstoneMode; + } + + @Override + protected void applySettings(ServerPlayer player, MaintenanceBoxBlockEntity be) { + be.applySettings(stationFilter, redstoneMode); + } + + @Override + public PacketTypeProvider getTypeProvider() { + return ModPackets.CONFIGURE_MAINTENANCE_BOX; + } +} diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index 7746fd4..31f601f 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -5,7 +5,10 @@ import com.simibubi.create.foundation.gui.widget.IconButton; import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import net.createmod.catnip.gui.AbstractSimiScreen; +import net.createmod.catnip.platform.CatnipServices; +import net.dantemc.create_maintenance_control.CreateMaintenance; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; +import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.EditBox; import net.minecraft.network.chat.Component; @@ -33,9 +36,8 @@ protected void init() { int x = guiLeft; int y = guiTop; - // placeholders - String stationFilter = ""; - int redstoneModeIndex = 0; + String stationFilter = blockEntity.getStationFilter(); + int redstoneModeIndex = blockEntity.getRedstoneMode().ordinal(); // station filter textbox stationFilterBox = new EditBox(font, x + 24, y + 28, 120, 18, Component.literal("Station Filter")); @@ -68,6 +70,20 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float } private void onConfirm() { + + String stationFilter = stationFilterBox.getValue().trim(); + + MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.values()[redstoneModeSelector.getState()]; + + boolean skipDownstream = false; // temporary until widget exist + + CatnipServices.NETWORK.sendToServer(new MaintenanceBoxConfigurationPacket(blockEntity.getBlockPos(), stationFilter, + redstoneMode)); + + CreateMaintenance.debug("Station filter: " + stationFilter); + CreateMaintenance.debug("Redstone mode: " + redstoneMode); + CreateMaintenance.debug("Skip downstream: " + skipDownstream); + onClose(); } } \ No newline at end of file diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java index 75c8b7c..79c2c40 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java @@ -28,18 +28,35 @@ public static void setEntry(Level level, BlockPos boxPos, MaintenanceEntry entry getData(level).setEntry(boxPos, entry); } - public static void refreshBox(Level level, BlockPos boxPos, String defaultStationFilter, boolean powered) { + public static MaintenanceEntry ensureBoxEntry(Level level, BlockPos boxPos, String defaultStationFilter) { MaintenanceEntry entry = getEntry(level, boxPos); if (entry == null) { - entry = new MaintenanceEntry(defaultStationFilter, - false, MaintenanceRedstoneMode.UNPOWERED_ACTIVE, false + entry = new MaintenanceEntry( + defaultStationFilter, + true, // shouldSkip is recalculated immediately by refreshBox so value here doesn't really matter + MaintenanceRedstoneMode.UNPOWERED_ACTIVE, + false ); + setEntry(level, boxPos, entry); } + return entry; + } + + public static void refreshBox(Level level, BlockPos boxPos, boolean powered) { + MaintenanceEntry entry = getEntry(level, boxPos); + if (entry == null) + return; + boolean shouldSkip = entry.redstoneMode().isMaintenanceActive(powered); - MaintenanceEntry updated = new MaintenanceEntry(entry.stationFilter(), shouldSkip, entry.redstoneMode(), entry.skipDownstream()); + MaintenanceEntry updated = new MaintenanceEntry( + entry.stationFilter(), + shouldSkip, + entry.redstoneMode(), + entry.skipDownstream() + ); setEntry(level, boxPos, updated); } From 2bad8f0dff12299515a1f88eede992ffbcf081c6 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Wed, 24 Jun 2026 03:41:57 +0200 Subject: [PATCH 06/13] changed gui to use create's ModularGuiLineBuilder.java elements and added skipDownstreamStation option --- .../maintenance_box/MaintenanceBoxBlock.java | 8 +- .../MaintenanceBoxBlockEntity.java | 19 +++- .../MaintenanceBoxConfigurationPacket.java | 11 ++- .../gui/MaintenanceBoxScreen.java | 86 ++++++++++++++----- .../railway/OfflineStationManager.java | 6 +- .../lang/en_us.json | 2 + 6 files changed, 97 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java index 415e801..ee0f432 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlock.java @@ -38,12 +38,12 @@ public MaintenanceBoxBlock(Properties properties) { registerDefaultState(defaultBlockState().setValue(POWERED, false)); } - private void refreshAttachedStationBox(Level level, BlockPos pos, boolean powered) { + private void refreshAttachedStationBox(Level level, BlockPos pos, boolean powered, boolean skipDownstream) { GlobalStation station = StationUtils.findNearbyStation(level, pos); if (station == null) return; - OfflineStationManager.refreshBox(level, pos, powered); + OfflineStationManager.refreshBox(level, pos, powered, skipDownstream); } @Override @@ -65,7 +65,7 @@ public void neighborChanged(BlockState state, Level level, BlockPos pos, Block b level.setBlock(pos, state.setValue(POWERED, powered), Block.UPDATE_ALL); - refreshAttachedStationBox(level, pos, powered); + refreshAttachedStationBox(level, pos, powered, false); } @Override @@ -85,7 +85,7 @@ public void onPlace(BlockState state, Level level, BlockPos pos, BlockState oldS level.setBlock(pos, state, Block.UPDATE_ALL); } - refreshAttachedStationBox(level, pos, powered); + refreshAttachedStationBox(level, pos, powered, false); } @Override diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java index e8466f3..b1dad30 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/MaintenanceBoxBlockEntity.java @@ -20,6 +20,7 @@ public MaintenanceBoxBlockEntity(BlockEntityType type, BlockPos pos, BlockSta private String stationFilter = ""; private MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.UNPOWERED_ACTIVE; + private boolean skipDownstream = false; public String getStationFilter() { return stationFilter; @@ -29,6 +30,10 @@ public MaintenanceRedstoneMode getRedstoneMode() { return redstoneMode; } + public boolean shouldSkipDownstream() { + return skipDownstream; + } + public void registerStation() { Level level = getLevel(); @@ -46,24 +51,25 @@ public void registerStation() { this.stationFilter = entry.stationFilter(); this.redstoneMode = entry.redstoneMode(); - OfflineStationManager.refreshBox(level, getBlockPos(), powered); + OfflineStationManager.refreshBox(level, getBlockPos(), powered, skipDownstream); setChanged(); notifyUpdate(); } - public void applySettings(String stationFilter, MaintenanceRedstoneMode redstoneMode) { + public void applySettings(String stationFilter, MaintenanceRedstoneMode redstoneMode, boolean skipDownstream) { Level level = getLevel(); if (level == null || level.isClientSide) return; this.stationFilter = stationFilter; this.redstoneMode = redstoneMode; + this.skipDownstream = skipDownstream; - OfflineStationManager.updateBoxSettings(level, getBlockPos(), stationFilter, redstoneMode); + OfflineStationManager.updateBoxSettings(level, getBlockPos(), stationFilter, redstoneMode, skipDownstream); boolean powered = getBlockState().getValue(MaintenanceBoxBlock.POWERED); - OfflineStationManager.refreshBox(level, getBlockPos(), powered); + OfflineStationManager.refreshBox(level, getBlockPos(), powered, skipDownstream); setChanged(); notifyUpdate(); @@ -89,6 +95,7 @@ protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) tag.putString("StationFilter", stationFilter); tag.putString("RedstoneMode", redstoneMode.name()); + tag.putBoolean("SkipDownstream", skipDownstream); } @Override @@ -102,5 +109,9 @@ protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) } catch (IllegalArgumentException e) { redstoneMode = MaintenanceRedstoneMode.UNPOWERED_ACTIVE; } + + if (tag.contains("SkipDownstream")) { + skipDownstream = tag.getBoolean("SkipDownstream"); + } } } diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java index 37085ec..42db196 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxConfigurationPacket.java @@ -16,22 +16,25 @@ public class MaintenanceBoxConfigurationPacket extends BlockEntityConfigurationP BlockPos.STREAM_CODEC, packet -> packet.pos, ByteBufCodecs.STRING_UTF8, packet -> packet.stationFilter, ByteBufCodecs.VAR_INT, packet -> packet.redstoneMode.ordinal(), - (pos, stationFilter, redstoneModeOrdinal) -> - new MaintenanceBoxConfigurationPacket(pos, stationFilter, MaintenanceRedstoneMode.values()[redstoneModeOrdinal]) + ByteBufCodecs.BOOL, packet -> packet.skipDownstream, + (pos, stationFilter, redstoneModeOrdinal, skipDownstream) -> + new MaintenanceBoxConfigurationPacket(pos, stationFilter, MaintenanceRedstoneMode.values()[redstoneModeOrdinal], skipDownstream) ); private final String stationFilter; private final MaintenanceRedstoneMode redstoneMode; + private final boolean skipDownstream; - public MaintenanceBoxConfigurationPacket(BlockPos pos, String stationFilter, MaintenanceRedstoneMode redstoneMode) { + public MaintenanceBoxConfigurationPacket(BlockPos pos, String stationFilter, MaintenanceRedstoneMode redstoneMode, boolean skipDownstream) { super(pos); this.stationFilter = stationFilter; this.redstoneMode = redstoneMode; + this.skipDownstream = skipDownstream; } @Override protected void applySettings(ServerPlayer player, MaintenanceBoxBlockEntity be) { - be.applySettings(stationFilter, redstoneMode); + be.applySettings(stationFilter, redstoneMode, skipDownstream); } @Override diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index 31f601f..0732d48 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -2,8 +2,12 @@ import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.gui.ModularGuiLine; +import com.simibubi.create.foundation.gui.ModularGuiLineBuilder; import com.simibubi.create.foundation.gui.widget.IconButton; +import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; +import com.simibubi.create.foundation.utility.CreateLang; import net.createmod.catnip.gui.AbstractSimiScreen; import net.createmod.catnip.platform.CatnipServices; import net.dantemc.create_maintenance_control.CreateMaintenance; @@ -11,7 +15,10 @@ import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.EditBox; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.MutableComponent; import java.util.List; @@ -21,8 +28,12 @@ public class MaintenanceBoxScreen extends AbstractSimiScreen { private final MaintenanceBoxBlockEntity blockEntity; private IconButton confirmButton; - private EditBox stationFilterBox; - private SelectionScrollInput redstoneModeSelector; + + private ModularGuiLine stationFilterLine; + private ModularGuiLine redstoneModeLine; + private ModularGuiLine skipDownstreamLine; + + private CompoundTag configData; public MaintenanceBoxScreen(MaintenanceBoxBlockEntity blockEntity) { this.blockEntity = blockEntity; @@ -36,23 +47,45 @@ protected void init() { int x = guiLeft; int y = guiTop; - String stationFilter = blockEntity.getStationFilter(); - int redstoneModeIndex = blockEntity.getRedstoneMode().ordinal(); + configData = new CompoundTag(); + configData.putString("StationFilter", blockEntity.getStationFilter()); + configData.putInt("RedstoneMode", blockEntity.getRedstoneMode().ordinal()); + configData.putBoolean("SkipDownstream", blockEntity.shouldSkipDownstream()); // station filter textbox - stationFilterBox = new EditBox(font, x + 24, y + 28, 120, 18, Component.literal("Station Filter")); - stationFilterBox.setValue(stationFilter); - stationFilterBox.setMaxLength(64); - addRenderableWidget(stationFilterBox); + stationFilterLine = new ModularGuiLine(); + new ModularGuiLineBuilder(font, stationFilterLine, x + 24, y + 28) + .addTextInput(0, 160, (editBox, tooltip) -> { + editBox.setMaxLength(64); + tooltip.withTooltip(List.of( + Component.literal("Station Name Filter") + )); + }, "StationFilter"); // redstone mode selector - redstoneModeSelector = (SelectionScrollInput) new SelectionScrollInput(x + 24, y + 70, 120, 18) - .forOptions(List.of( - Component.literal("Unpowered = Maintenance"), - Component.literal("Powered = Maintenance") - )); - redstoneModeSelector.setState(redstoneModeIndex); - addRenderableWidget(redstoneModeSelector); + redstoneModeLine = new ModularGuiLine(); + new ModularGuiLineBuilder(font, redstoneModeLine, x + 24, y + 68) + .addSelectionScrollInput(0, 160, (input, label) -> { + input.forOptions(List.of( + Component.literal("Unpowered = Maintenance"), + Component.literal("Powered = Maintenance") + )); + }, "RedstoneMode"); + + // Skip downstream stations selector + skipDownstreamLine = new ModularGuiLine(); + new ModularGuiLineBuilder(font, skipDownstreamLine, x + 24, y + 108) + .addSelectionScrollInput(0, 160, (input, label) -> { + input.forOptions(List.of( + Component.literal("Disabled"), + Component.literal("Enabled") + )); + }, "SkipDownstream"); + + // push initial values from configData into the widgets + stationFilterLine.loadValues(configData, this::addRenderableWidget, this::addRenderableOnly); + redstoneModeLine.loadValues(configData, this::addRenderableWidget, this::addRenderableOnly); + skipDownstreamLine.loadValues(configData, this::addRenderableWidget, this::addRenderableOnly); // Confirm button confirmButton = new IconButton(x + background.getWidth() - 33, y + background.getHeight() - 24, AllIcons.I_CONFIRM); @@ -64,21 +97,34 @@ protected void init() { protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { background.render(graphics, guiLeft, guiTop); - graphics.drawString(font, "Maintenance Box", guiLeft + 24, guiTop + 10, 0x404040, false); + int x = guiLeft; + int y = guiTop; + + MutableComponent header = Component.translatable("gui.maintenance_box.title"); + graphics.drawString(font, header, x + background.getWidth() / 2 - font.width(header) / 2, y + 4, 0x592424, false); + graphics.drawString(font, "Station Filter", guiLeft + 24, guiTop + 18, 0x575F7A, false); graphics.drawString(font, "Redstone Mode", guiLeft + 24, guiTop + 58, 0x575F7A, false); + graphics.drawString(font, "Skip Downstream Stations", guiLeft + 24, guiTop + 98, 0x575F7A, false); } private void onConfirm() { - String stationFilter = stationFilterBox.getValue().trim(); + CompoundTag tag = new CompoundTag(); + + stationFilterLine.saveValues(tag); + redstoneModeLine.saveValues(tag); + skipDownstreamLine.saveValues(tag); + + String stationFilter = tag.getString("StationFilter"); - MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.values()[redstoneModeSelector.getState()]; + int redstoneModeIndex = tag.getInt("RedstoneMode"); + MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.values()[redstoneModeIndex]; - boolean skipDownstream = false; // temporary until widget exist + boolean skipDownstream = tag.getBoolean("SkipDownstream"); CatnipServices.NETWORK.sendToServer(new MaintenanceBoxConfigurationPacket(blockEntity.getBlockPos(), stationFilter, - redstoneMode)); + redstoneMode, skipDownstream)); CreateMaintenance.debug("Station filter: " + stationFilter); CreateMaintenance.debug("Redstone mode: " + redstoneMode); diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java index 79c2c40..ad8fccd 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java @@ -44,7 +44,7 @@ public static MaintenanceEntry ensureBoxEntry(Level level, BlockPos boxPos, Stri return entry; } - public static void refreshBox(Level level, BlockPos boxPos, boolean powered) { + public static void refreshBox(Level level, BlockPos boxPos, boolean powered, boolean skipDownstream) { MaintenanceEntry entry = getEntry(level, boxPos); if (entry == null) return; @@ -61,7 +61,7 @@ public static void refreshBox(Level level, BlockPos boxPos, boolean powered) { setEntry(level, boxPos, updated); } - public static void updateBoxSettings(Level level, BlockPos boxPos, String stationFilter, MaintenanceRedstoneMode redstoneMode) { + public static void updateBoxSettings(Level level, BlockPos boxPos, String stationFilter, MaintenanceRedstoneMode redstoneMode, boolean skipDownstream) { MaintenanceEntry current = getEntry(level, boxPos); if (current == null) return; @@ -69,7 +69,7 @@ public static void updateBoxSettings(Level level, BlockPos boxPos, String statio boolean powered = level.getBlockState(boxPos).getValue(MaintenanceBoxBlock.POWERED); boolean shouldSkip = redstoneMode.isMaintenanceActive(powered); - MaintenanceEntry updated = new MaintenanceEntry(stationFilter, shouldSkip, redstoneMode, current.skipDownstream()); + MaintenanceEntry updated = new MaintenanceEntry(stationFilter, shouldSkip, redstoneMode, skipDownstream); setEntry(level, boxPos, updated); } diff --git a/src/main/resources/assets/create_maintenance_control/lang/en_us.json b/src/main/resources/assets/create_maintenance_control/lang/en_us.json index 5018f4d..55916d4 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/en_us.json +++ b/src/main/resources/assets/create_maintenance_control/lang/en_us.json @@ -8,6 +8,8 @@ "block.create_maintenance_control.maintenance_box.tooltip.behaviour1": "Trains with this station _in their schedules_ will _skip it_ while maintenance is active.", "block.create_maintenance_control.maintenance_box.tooltip.behaviour2": "When powered, maintenance is _temporarily disabled_ and trains will _stop at the station_ as usual.", + "gui.maintenance_box.title": "Maintenance Box", + "create_maintenance_control.configuration.title": "Create: Maintenance Control Configs", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml": "Create: Maintenance Control Configs", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml.title": "Create: Maintenance Control Configs", From 8d9615e5b4427c73842f1168da157da40b8e8f67 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Wed, 24 Jun 2026 04:26:12 +0200 Subject: [PATCH 07/13] added custom gui texture and updated default lang file --- .../gui/MaintenanceBoxGuiTexture.java | 66 ++++++++++++++++++ .../gui/MaintenanceBoxScreen.java | 54 +++++++++----- .../lang/en_us.json | 10 +++ .../textures/gui/maintenance_box.png | Bin 0 -> 1557 bytes 4 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxGuiTexture.java create mode 100644 src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxGuiTexture.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxGuiTexture.java new file mode 100644 index 0000000..454f23c --- /dev/null +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxGuiTexture.java @@ -0,0 +1,66 @@ +package net.dantemc.create_maintenance_control.content.maintenance_box.gui; + +import com.simibubi.create.Create; +import net.createmod.catnip.gui.TextureSheetSegment; +import net.createmod.catnip.gui.element.ScreenElement; +import net.dantemc.create_maintenance_control.CreateMaintenance; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.resources.ResourceLocation; +import net.neoforged.api.distmarker.Dist; +import net.neoforged.api.distmarker.OnlyIn; + +public enum MaintenanceBoxGuiTexture implements ScreenElement, TextureSheetSegment { + MAINTENANCE_BOX_INTERFACE("maintenance_box", 235, 162); + + public final ResourceLocation location; + private final int width; + private final int height; + private final int startX; + private final int startY; + + MaintenanceBoxGuiTexture(String location, int width, int height) { + this(location, 0, 0, width, height); + } + + MaintenanceBoxGuiTexture(String location, int startX, int startY, int width, int height) { + this(CreateMaintenance.MODID, location, startX, startY, width, height); + } + + MaintenanceBoxGuiTexture(String namespace, String location, int startX, int startY, int width, int height) { + this.location = ResourceLocation.fromNamespaceAndPath(namespace, "textures/gui/" + location + ".png"); + this.width = width; + this.height = height; + this.startX = startX; + this.startY = startY; + } + + @Override + public ResourceLocation getLocation() { + return location; + } + + @OnlyIn(Dist.CLIENT) + public void render(GuiGraphics graphics, int x, int y) { + graphics.blit(location, x, y, startX, startY, width, height); + } + + @Override + public int getStartX() { + return startX; + } + + @Override + public int getStartY() { + return startY; + } + + @Override + public int getWidth() { + return width; + } + + @Override + public int getHeight() { + return height; + } +} diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index 0732d48..ef759d4 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -1,22 +1,24 @@ package net.dantemc.create_maintenance_control.content.maintenance_box.gui; -import com.simibubi.create.foundation.gui.AllGuiTextures; +import com.google.common.collect.ImmutableList; +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlock; import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.ModularGuiLine; import com.simibubi.create.foundation.gui.ModularGuiLineBuilder; import com.simibubi.create.foundation.gui.widget.IconButton; -import com.simibubi.create.foundation.gui.widget.Label; -import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import com.simibubi.create.foundation.utility.CreateLang; +import dev.engine_room.flywheel.lib.transform.TransformStack; import net.createmod.catnip.gui.AbstractSimiScreen; +import net.createmod.catnip.gui.element.GuiGameElement; import net.createmod.catnip.platform.CatnipServices; import net.dantemc.create_maintenance_control.CreateMaintenance; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; +import net.minecraft.ChatFormatting; import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.EditBox; +import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.network.chat.MutableComponent; @@ -24,7 +26,7 @@ public class MaintenanceBoxScreen extends AbstractSimiScreen { - private final AllGuiTextures background = AllGuiTextures.DATA_GATHERER; + private final MaintenanceBoxGuiTexture background = MaintenanceBoxGuiTexture.MAINTENANCE_BOX_INTERFACE; private final MaintenanceBoxBlockEntity blockEntity; private IconButton confirmButton; @@ -54,31 +56,32 @@ protected void init() { // station filter textbox stationFilterLine = new ModularGuiLine(); - new ModularGuiLineBuilder(font, stationFilterLine, x + 24, y + 28) + new ModularGuiLineBuilder(font, stationFilterLine, x + 24, y + 32) .addTextInput(0, 160, (editBox, tooltip) -> { editBox.setMaxLength(64); - tooltip.withTooltip(List.of( - Component.literal("Station Name Filter") - )); + tooltip.withTooltip(ImmutableList.of(Component.translatable("gui.maintenance_box.station_filter.tooltip") + .withStyle(s -> s.withColor(0x5391E1)), + CreateLang.translateDirect("gui.schedule.lmb_edit") + .withStyle(ChatFormatting.DARK_GRAY, ChatFormatting.ITALIC))); }, "StationFilter"); // redstone mode selector redstoneModeLine = new ModularGuiLine(); - new ModularGuiLineBuilder(font, redstoneModeLine, x + 24, y + 68) + new ModularGuiLineBuilder(font, redstoneModeLine, x + 24, y + 72) .addSelectionScrollInput(0, 160, (input, label) -> { input.forOptions(List.of( - Component.literal("Unpowered = Maintenance"), - Component.literal("Powered = Maintenance") + Component.translatable("gui.maintenance_box.redstone_mode.default"),//Unpowered = Maintenance + Component.translatable("gui.maintenance_box.redstone_mode.inverted") //Powered = Maintenance )); }, "RedstoneMode"); // Skip downstream stations selector skipDownstreamLine = new ModularGuiLine(); - new ModularGuiLineBuilder(font, skipDownstreamLine, x + 24, y + 108) + new ModularGuiLineBuilder(font, skipDownstreamLine, x + 24, y + 112) .addSelectionScrollInput(0, 160, (input, label) -> { input.forOptions(List.of( - Component.literal("Disabled"), - Component.literal("Enabled") + Component.translatable("gui.maintenance_box.skip_downstream_stations.disabled"), + Component.translatable("gui.maintenance_box.skip_downstream_stations.enabled") )); }, "SkipDownstream"); @@ -103,9 +106,22 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float MutableComponent header = Component.translatable("gui.maintenance_box.title"); graphics.drawString(font, header, x + background.getWidth() / 2 - font.width(header) / 2, y + 4, 0x592424, false); - graphics.drawString(font, "Station Filter", guiLeft + 24, guiTop + 18, 0x575F7A, false); - graphics.drawString(font, "Redstone Mode", guiLeft + 24, guiTop + 58, 0x575F7A, false); - graphics.drawString(font, "Skip Downstream Stations", guiLeft + 24, guiTop + 98, 0x575F7A, false); + graphics.drawString(font, Component.translatable("gui.maintenance_box.station_filter"), guiLeft + 24, guiTop + 18, 0xB8B8B8, false); + graphics.drawString(font, Component.translatable("gui.maintenance_box.redstone_mode"), guiLeft + 24, guiTop + 58, 0xB8B8B8, false); + graphics.drawString(font, Component.translatable("gui.maintenance_box.skip_downstream_stations"), guiLeft + 24, guiTop + 98, 0xB8B8B8, false); + + PoseStack ms = graphics.pose(); + ms.pushPose(); + TransformStack.of(ms) + .pushPose() + .translate(x + background.getWidth() + 4, y + background.getHeight() + 4, 100) + .scale(40) + .rotateXDegrees(-22) + .rotateYDegrees(63); + GuiGameElement.of(blockEntity.getBlockState() + .setValue(DisplayLinkBlock.FACING, Direction.UP)) + .render(graphics); + ms.popPose(); } private void onConfirm() { diff --git a/src/main/resources/assets/create_maintenance_control/lang/en_us.json b/src/main/resources/assets/create_maintenance_control/lang/en_us.json index 55916d4..0bd55c6 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/en_us.json +++ b/src/main/resources/assets/create_maintenance_control/lang/en_us.json @@ -9,6 +9,16 @@ "block.create_maintenance_control.maintenance_box.tooltip.behaviour2": "When powered, maintenance is _temporarily disabled_ and trains will _stop at the station_ as usual.", "gui.maintenance_box.title": "Maintenance Box", + "gui.maintenance_box.station_filter": "Station Name Filter", + "gui.maintenance_box.station_filter.tooltip": "Apply maintenance to the station with this exact name", + + "gui.maintenance_box.redstone_mode": "Redstone Mode", + "gui.maintenance_box.redstone_mode.default": "Unpowered = Maintenance", + "gui.maintenance_box.redstone_mode.inverted": "Powered = Maintenance", + + "gui.maintenance_box.skip_downstream_stations": "Skip Downstream Stations", + "gui.maintenance_box.skip_downstream_stations.disabled": "Disabled", + "gui.maintenance_box.skip_downstream_stations.enabled": "Enabled", "create_maintenance_control.configuration.title": "Create: Maintenance Control Configs", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml": "Create: Maintenance Control Configs", diff --git a/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png b/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png new file mode 100644 index 0000000000000000000000000000000000000000..b3d00cf1861fc339b749175a9e3ae71ecee24a94 GIT binary patch literal 1557 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5D>38$lZxy-8q?;Kn_c~qpu?a z!^VE@KZ&eBenNmxh%1n0Wo2bzVq#-s`~SL!k&*Gq_T)$v6&4m2W@hFI6DCwtROIL9 z@7S@!)WpQi$;r~vGCVxo+}ymRq@=sM`~Uy{ix)3GcI;SaXlPnm+M`F0Zrr$ekY6xRF+RW$6C?c=sFt(9BeIx*f$ty)Gwzs}4HA?rag8Vm z&QB{TPb^Ah2uRG#E79|F4N)-FGt@IQ?BWnR2UN5pHNrE^(^HFq1IS@zkYZ#7hlv-E zCkVKlm}3=BZY3G56k zK(z)&#s-WFAm)PNfpr1ItZ6_t2rvOnW&*1Wva|rQpt=kV3_!Axnspn_zp1zaj3iA@ z7srr_xVLj(`$aj5xV1+!9`$zR)_C=Me`@iBQ+DyE5}Q6Jr@h}g>qc6*>itt*-rAj- zy_YPOdVW8~|M>8nyele8KRy@G^xZqTq`2Q?wqJc^nw@(?-n&Ky76k^zUxw=(7?=bW z%&so+Z~dAaV>tgjP}!7a#m{3j5+;iM%3m2Z^K9DYj}?1j^rm+oO)`<{RXdb3>C&4I z-+p|47`|(#`!65!?do}X;b)Vdm2|g#FK2r9PJUngoi%c^(^J3M+_|61Ver0wd)1%2 z7X8}0|0}vTe0}QJaMz#Fl4*@TKhv8!t`mX@wUq)1--8|c7+#-lX4pNSsfZ;aUXJC) z-|ONZu1LMkXDs{wmDR@9{FwJkrhg{KJR9!*Z)W? z=kPXwffbHKv>oPWUGw{h@WB+lhU=W$yjC*JYK1#Qe7*1zhQBRq9T`Qi293xBH;?+>95rhj(qS5Me|_n5$k_q`kzyYJ6z$ouoXPWi!~x_l-+w!Yu~Ol;qF z3m5!JUZ9?kvEQDtZE?fFzl Date: Wed, 24 Jun 2026 04:58:33 +0200 Subject: [PATCH 08/13] finalized gui (except texture) --- .../gui/MaintenanceBoxScreen.java | 76 +++++++++--------- .../lang/en_us.json | 7 +- .../textures/gui/maintenance_box.png | Bin 1557 -> 1949 bytes 3 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index ef759d4..49d2aad 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -7,6 +7,8 @@ import com.simibubi.create.foundation.gui.ModularGuiLine; import com.simibubi.create.foundation.gui.ModularGuiLineBuilder; import com.simibubi.create.foundation.gui.widget.IconButton; +import com.simibubi.create.foundation.gui.widget.Label; +import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import com.simibubi.create.foundation.utility.CreateLang; import dev.engine_room.flywheel.lib.transform.TransformStack; import net.createmod.catnip.gui.AbstractSimiScreen; @@ -32,8 +34,12 @@ public class MaintenanceBoxScreen extends AbstractSimiScreen { private IconButton confirmButton; private ModularGuiLine stationFilterLine; - private ModularGuiLine redstoneModeLine; - private ModularGuiLine skipDownstreamLine; + + private SelectionScrollInput redstoneModeSelector; + private Label redstoneModeLabel; + + private SelectionScrollInput skipDownstreamSelector; + private Label skipDownstreamLabel; private CompoundTag configData; @@ -51,12 +57,10 @@ protected void init() { configData = new CompoundTag(); configData.putString("StationFilter", blockEntity.getStationFilter()); - configData.putInt("RedstoneMode", blockEntity.getRedstoneMode().ordinal()); - configData.putBoolean("SkipDownstream", blockEntity.shouldSkipDownstream()); // station filter textbox stationFilterLine = new ModularGuiLine(); - new ModularGuiLineBuilder(font, stationFilterLine, x + 24, y + 32) + new ModularGuiLineBuilder(font, stationFilterLine, x + 24, y + 60) .addTextInput(0, 160, (editBox, tooltip) -> { editBox.setMaxLength(64); tooltip.withTooltip(ImmutableList.of(Component.translatable("gui.maintenance_box.station_filter.tooltip") @@ -66,29 +70,37 @@ protected void init() { }, "StationFilter"); // redstone mode selector - redstoneModeLine = new ModularGuiLine(); - new ModularGuiLineBuilder(font, redstoneModeLine, x + 24, y + 72) - .addSelectionScrollInput(0, 160, (input, label) -> { - input.forOptions(List.of( - Component.translatable("gui.maintenance_box.redstone_mode.default"),//Unpowered = Maintenance - Component.translatable("gui.maintenance_box.redstone_mode.inverted") //Powered = Maintenance - )); - }, "RedstoneMode"); + redstoneModeLabel = new Label(x + 29, y + 85, Component.empty()).withShadow(); + + redstoneModeSelector = (SelectionScrollInput) new SelectionScrollInput(x + 24, y + 85, 160, 18) + .forOptions(List.of( + Component.translatable("gui.maintenance_box.redstone_mode.default"), + Component.translatable("gui.maintenance_box.redstone_mode.inverted") + )) + .writingTo(redstoneModeLabel) + .titled(Component.translatable("gui.maintenance_box.redstone_mode.tooltip")) + .setState(blockEntity.getRedstoneMode().ordinal()); + + addRenderableWidget(redstoneModeSelector); + addRenderableWidget(redstoneModeLabel); // Skip downstream stations selector - skipDownstreamLine = new ModularGuiLine(); - new ModularGuiLineBuilder(font, skipDownstreamLine, x + 24, y + 112) - .addSelectionScrollInput(0, 160, (input, label) -> { - input.forOptions(List.of( - Component.translatable("gui.maintenance_box.skip_downstream_stations.disabled"), - Component.translatable("gui.maintenance_box.skip_downstream_stations.enabled") - )); - }, "SkipDownstream"); - - // push initial values from configData into the widgets + skipDownstreamLabel = new Label(x + 29, y + 110, Component.empty()).withShadow(); + + skipDownstreamSelector = (SelectionScrollInput) new SelectionScrollInput(x + 24, y + 110, 160, 18) + .forOptions(List.of( + Component.translatable("gui.maintenance_box.skip_downstream_stations.disabled"), + Component.translatable("gui.maintenance_box.skip_downstream_stations.enabled") + )) + .writingTo(skipDownstreamLabel) + .titled(Component.translatable("gui.maintenance_box.skip_downstream_stations.tooltip")) + .setState(blockEntity.shouldSkipDownstream() ? 1 : 0); + + addRenderableWidget(skipDownstreamSelector); + addRenderableWidget(skipDownstreamLabel); + + // push initial value from configData into the widget stationFilterLine.loadValues(configData, this::addRenderableWidget, this::addRenderableOnly); - redstoneModeLine.loadValues(configData, this::addRenderableWidget, this::addRenderableOnly); - skipDownstreamLine.loadValues(configData, this::addRenderableWidget, this::addRenderableOnly); // Confirm button confirmButton = new IconButton(x + background.getWidth() - 33, y + background.getHeight() - 24, AllIcons.I_CONFIRM); @@ -106,10 +118,6 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float MutableComponent header = Component.translatable("gui.maintenance_box.title"); graphics.drawString(font, header, x + background.getWidth() / 2 - font.width(header) / 2, y + 4, 0x592424, false); - graphics.drawString(font, Component.translatable("gui.maintenance_box.station_filter"), guiLeft + 24, guiTop + 18, 0xB8B8B8, false); - graphics.drawString(font, Component.translatable("gui.maintenance_box.redstone_mode"), guiLeft + 24, guiTop + 58, 0xB8B8B8, false); - graphics.drawString(font, Component.translatable("gui.maintenance_box.skip_downstream_stations"), guiLeft + 24, guiTop + 98, 0xB8B8B8, false); - PoseStack ms = graphics.pose(); ms.pushPose(); TransformStack.of(ms) @@ -127,17 +135,11 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float private void onConfirm() { CompoundTag tag = new CompoundTag(); - stationFilterLine.saveValues(tag); - redstoneModeLine.saveValues(tag); - skipDownstreamLine.saveValues(tag); String stationFilter = tag.getString("StationFilter"); - - int redstoneModeIndex = tag.getInt("RedstoneMode"); - MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.values()[redstoneModeIndex]; - - boolean skipDownstream = tag.getBoolean("SkipDownstream"); + MaintenanceRedstoneMode redstoneMode = MaintenanceRedstoneMode.values()[redstoneModeSelector.getState()]; + boolean skipDownstream = skipDownstreamSelector.getState() == 1; CatnipServices.NETWORK.sendToServer(new MaintenanceBoxConfigurationPacket(blockEntity.getBlockPos(), stationFilter, redstoneMode, skipDownstream)); diff --git a/src/main/resources/assets/create_maintenance_control/lang/en_us.json b/src/main/resources/assets/create_maintenance_control/lang/en_us.json index 0bd55c6..04bd0e2 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/en_us.json +++ b/src/main/resources/assets/create_maintenance_control/lang/en_us.json @@ -9,14 +9,13 @@ "block.create_maintenance_control.maintenance_box.tooltip.behaviour2": "When powered, maintenance is _temporarily disabled_ and trains will _stop at the station_ as usual.", "gui.maintenance_box.title": "Maintenance Box", - "gui.maintenance_box.station_filter": "Station Name Filter", - "gui.maintenance_box.station_filter.tooltip": "Apply maintenance to the station with this exact name", + "gui.maintenance_box.station_filter.tooltip": "Station name filter", - "gui.maintenance_box.redstone_mode": "Redstone Mode", + "gui.maintenance_box.redstone_mode.tooltip": "Redstone mode", "gui.maintenance_box.redstone_mode.default": "Unpowered = Maintenance", "gui.maintenance_box.redstone_mode.inverted": "Powered = Maintenance", - "gui.maintenance_box.skip_downstream_stations": "Skip Downstream Stations", + "gui.maintenance_box.skip_downstream_stations.tooltip": "Skip downstream stations", "gui.maintenance_box.skip_downstream_stations.disabled": "Disabled", "gui.maintenance_box.skip_downstream_stations.enabled": "Enabled", diff --git a/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png b/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png index b3d00cf1861fc339b749175a9e3ae71ecee24a94..cb5246766a7002ba1ae221b95b93088c8ef189a8 100644 GIT binary patch delta 1522 zcmchXX;6~~5Qe`a#2kc%0>u)6h$5j>31SGLC_%sz5u*)YnIt$$5s-j@2E=?HR4bPy ziik%MYTC*n3WF6fLZTTFr$H=gi*kjcV2D5jDMUijw2Yn3w14`i`)6l%cK3Z|=bbIF zEPGFqWoa^*m`r9`T3SIt!HHZa3~^`kY<=~|AYxI!F*tCCh&NhR!0q-Uhm^3-v4aLU znKryplW9+>W0ZqqcYbkbzC_}JK(&-wOU^^rY54P}@+Dn+{2C{_5eBALml$<$J|+9j-*RxY>J z=?1+FP5o=yFVwb8&J4!n0QDy2ZyNd8$!jHg=Sw(AOFWr6*#K_GY~V9+68%%u9s2gF z1E$T8sIUb)BS_G0v5z1h(9|GUaHZ)kNhA*I4`{8L)k=HNVOT>~;$=Mi3v4j_=;HBl zMoWnO3+y#*5-F5OZz+BGlY5EZhjZAOdwUC<`n6i~RzH#sYK?FV*s}ZJNPsMN;1P|f zmb_|n17GLu&$`rr**(3eud)X)4Ip)rBtqshrW>v;9p5&_x`k|$gS|geT=FA2g}HMJ zc{_sqld{U4I6KFci8KBqB%HIlR~otD%u?v&>Lazf;6Te{cL}o^1C&8JZ74-a$Y|l~n*PACT@=qYHvaC7s@_`-J0i^EN z5^OIvHzBPQDcYP1xx}0m+u(44R){j=rU>sP@(mptbAEWS7kyL3KUnG+d;Cy{$AZr$ zW)=o7B?Jye`LC?L@zTqDI6DXGX)S+q6PZl)d0SK_igTe}2&CIGRwt?z3Cs$jBL?F> z0mv7-vuAmYm!jW>7oKhbGOCiVoYMLTlI!nRCnHY%c~*BaT05S0I+o)$e851H;1w?Q z?-R(|rzgRbV=>AvUiz?$B9XJz-Kz?_25rr%0sGi%w<<)Fp3=wIRncx<;qh=w;Yo_l zwGK=~RUOz+YwF=ARQAy4@b_jXt&#~aeh9wfD6YG&7J?Su16oPon$Ps9>uDg4`|~0@ed+V6%zO- zWglQxd?zulRLKB@jLqwtK~Z++HX*>hoOX>uA9O|v+YG}@!Sy(X;QGIuk34(caJ;w` z8LkBBsX3{l^-+%ZEM5&gSYtCVRRYmdA&YP}1L~8M#>Q_{5Y^{2TJ52q*;CMg@o{Gs zJVop}ob}vtAz8uJT%()7K6KmCW>Kb zLa((?UW#mic)D_BGn!~Thp`L-ZQ15Wbi1ivKAoN#%AOMp9Wij>aKP$vAn03%wNN7p q2U`?Q_*>=wEpYxK`LDWPW`GE2o6Zp~6F(aU%&{>fEcnV=LC)`F$(gkP delta 1127 zcmbQsKb2=f4Uf6Gc}Yo0cX#*y|Nkd;$gw=$C2?lsDjmjp7EMnV$B>G+w{u_nMLCMN zwMR1^^>*dfc=daKYVm|qcJZeYn?5I}z27?PMq0S){Zn4v+MSxcmn@cgem}C&4I-+p|47`|(#`!65! z?do}X;b)Vdm2|g#FK2r9PJUngoi%c^(^J3M+_|61Ver0wd)1%27X8}0|0}vTe0}QJ zaMz#Fl4*@TKhv8!t`mX@wUq)1--8|c7+#-lX4pNSsfZ;aUXJC)-|O|_AFfEf&Sxz9 z|CQCo*8G_FOQwG&$2=SE{%>ab!kD$Zf^k;FTM>N+`2}Sf4NP#SUYpL&SZ2@qgk!@# z8;%XX>opaKaPa?MOkYwft{#5P;w`=)zG~InOYxFf5nxA}Y`moz*I?)HHh_T@jzqK_ z=4V~=`-t$u6upM)oZGxsGRrV%1HV2gV0Ad$-SxGM zzl`?0dRW@Dl>36d?Nz^*>v>Fd4!ryCNKDYxL&EOBYnJGxA&h68U@rOmPjUa_ln?JM zr5NtsQC6+Bd)RlH$!zUr*%=#dD>|5e2PUdJ92KG0?wU?&*g9d?>%8w~83*<@oV|U! z?nFa9_I{2AN-x*d4-_wV1HddBHY z`@TgpKIi=*^uhGcj{WKhyYC(o`0&1$!(#XSnGJb=zSk)~_*0k9#K+e6+nmIQW;5h3EZu{RfBY{F$!(y8qCfvH7rDg}v}Y(d@LzOjkXzKqVC%w+rh>K#+`+CO d-VP4^2l`vwZPL{?eD7rd0#8>zmvv4FO#s{R Date: Wed, 24 Jun 2026 14:42:56 +0200 Subject: [PATCH 09/13] changed 2 lang keys --- .../content/maintenance_box/gui/MaintenanceBoxScreen.java | 4 ++-- .../assets/create_maintenance_control/lang/en_us.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index 49d2aad..b7d7409 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -89,8 +89,8 @@ protected void init() { skipDownstreamSelector = (SelectionScrollInput) new SelectionScrollInput(x + 24, y + 110, 160, 18) .forOptions(List.of( - Component.translatable("gui.maintenance_box.skip_downstream_stations.disabled"), - Component.translatable("gui.maintenance_box.skip_downstream_stations.enabled") + Component.translatable("gui.maintenance_box.skip_downstream_stations.false"), + Component.translatable("gui.maintenance_box.skip_downstream_stations.true") )) .writingTo(skipDownstreamLabel) .titled(Component.translatable("gui.maintenance_box.skip_downstream_stations.tooltip")) diff --git a/src/main/resources/assets/create_maintenance_control/lang/en_us.json b/src/main/resources/assets/create_maintenance_control/lang/en_us.json index 04bd0e2..f91d094 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/en_us.json +++ b/src/main/resources/assets/create_maintenance_control/lang/en_us.json @@ -16,8 +16,8 @@ "gui.maintenance_box.redstone_mode.inverted": "Powered = Maintenance", "gui.maintenance_box.skip_downstream_stations.tooltip": "Skip downstream stations", - "gui.maintenance_box.skip_downstream_stations.disabled": "Disabled", - "gui.maintenance_box.skip_downstream_stations.enabled": "Enabled", + "gui.maintenance_box.skip_downstream_stations.false": "False", + "gui.maintenance_box.skip_downstream_stations.true": "True", "create_maintenance_control.configuration.title": "Create: Maintenance Control Configs", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml": "Create: Maintenance Control Configs", From a56720f665b28b14276fc7c9cc8b901967b43922 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Thu, 25 Jun 2026 00:23:59 +0200 Subject: [PATCH 10/13] finalized GUI look --- .../gui/MaintenanceBoxScreen.java | 38 +++++++++++++++--- .../lang/en_us.json | 4 +- .../textures/gui/maintenance_box.png | Bin 1949 -> 1807 bytes 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index b7d7409..5538b5c 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -2,6 +2,8 @@ import com.google.common.collect.ImmutableList; import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.AllItems; +import com.simibubi.create.Create; import com.simibubi.create.content.redstone.displayLink.DisplayLinkBlock; import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.ModularGuiLine; @@ -11,6 +13,8 @@ import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import com.simibubi.create.foundation.utility.CreateLang; import dev.engine_room.flywheel.lib.transform.TransformStack; +import net.createmod.catnip.animation.Force; +import net.createmod.catnip.animation.PhysicalFloat; import net.createmod.catnip.gui.AbstractSimiScreen; import net.createmod.catnip.gui.element.GuiGameElement; import net.createmod.catnip.platform.CatnipServices; @@ -18,6 +22,7 @@ import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceBoxBlockEntity; import net.dantemc.create_maintenance_control.content.maintenance_box.MaintenanceRedstoneMode; import net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.core.Direction; import net.minecraft.nbt.CompoundTag; @@ -26,6 +31,8 @@ import java.util.List; +import static net.createmod.catnip.config.ui.ConfigScreen.shadowState; + public class MaintenanceBoxScreen extends AbstractSimiScreen { private final MaintenanceBoxGuiTexture background = MaintenanceBoxGuiTexture.MAINTENANCE_BOX_INTERFACE; @@ -108,6 +115,8 @@ protected void init() { addRenderableWidget(confirmButton); } + public static final PhysicalFloat cogSpin = PhysicalFloat.create().withLimit(10f).withDrag(0.3).addForce(new Force.Static(.2f)); + @Override protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float partialTicks) { background.render(graphics, guiLeft, guiTop); @@ -116,11 +125,25 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float int y = guiTop; MutableComponent header = Component.translatable("gui.maintenance_box.title"); - graphics.drawString(font, header, x + background.getWidth() / 2 - font.width(header) / 2, y + 4, 0x592424, false); + graphics.drawString(font, header, (x + background.getWidth() / 2 - font.width(header) / 2) - 2, y + 4, 0x592424, false); + + //cog + partialTicks = Minecraft.getInstance().getTimer().getGameTimeDeltaPartialTick(false); + PoseStack poseStack = graphics.pose(); + poseStack.pushPose(); + + poseStack.translate(x + background.getWidth() / 2f - 18, y + 50, 0); + poseStack.scale(28, 28, 1); + GuiGameElement.of(shadowState) + .rotateBlock(22.5, cogSpin.getValue(partialTicks), 22.5) + .render(graphics); - PoseStack ms = graphics.pose(); - ms.pushPose(); - TransformStack.of(ms) + poseStack.popPose(); + + //block model + PoseStack ms2 = graphics.pose(); + ms2.pushPose(); + TransformStack.of(ms2) .pushPose() .translate(x + background.getWidth() + 4, y + background.getHeight() + 4, 100) .scale(40) @@ -129,7 +152,12 @@ protected void renderWindow(GuiGraphics graphics, int mouseX, int mouseY, float GuiGameElement.of(blockEntity.getBlockState() .setValue(DisplayLinkBlock.FACING, Direction.UP)) .render(graphics); - ms.popPose(); + ms2.popPose(); + } + + @Override + public void tick() { + cogSpin.tick(); } private void onConfirm() { diff --git a/src/main/resources/assets/create_maintenance_control/lang/en_us.json b/src/main/resources/assets/create_maintenance_control/lang/en_us.json index f91d094..62507d7 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/en_us.json +++ b/src/main/resources/assets/create_maintenance_control/lang/en_us.json @@ -16,8 +16,8 @@ "gui.maintenance_box.redstone_mode.inverted": "Powered = Maintenance", "gui.maintenance_box.skip_downstream_stations.tooltip": "Skip downstream stations", - "gui.maintenance_box.skip_downstream_stations.false": "False", - "gui.maintenance_box.skip_downstream_stations.true": "True", + "gui.maintenance_box.skip_downstream_stations.false": "Off", + "gui.maintenance_box.skip_downstream_stations.true": "On", "create_maintenance_control.configuration.title": "Create: Maintenance Control Configs", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml": "Create: Maintenance Control Configs", diff --git a/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png b/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png index cb5246766a7002ba1ae221b95b93088c8ef189a8..d670ad65f7781fc0a6517ea19cbca86ef5fbc8e8 100644 GIT binary patch literal 1807 zcmd5+Yfw{16yAH28zM0ZBa#qN1Eq!{k6=YYMF|K379sMGpqB6u6m1EGNKz~0inWe{ zKxaDmDuNm*IhFQYXg(Ad`$*al>TW3&Nf)nl`h9z`gT1S(t3)En%*-SR;>?*db#--NVPWy{ z@m*bAYITcRt!{2^RwxvZx}Wx^6bd^@a9{`w{;&a-6~Ed7SItWDi%0=rPK{wAJS@Zp z8Z9I~LP>}?ULuW7jst?|ghYvBpid~<#nIW(+4&IFyb%T|!7w^2E%d!TZA-aMCO8ugkf-clLTngCsR(!utNvEL%L)K=<{AMqjO8x- zl#3Kj=QZ>TE1b@i2eDzGFf%$88SKV`Xl9i&muv9Ge*gMp_RH={*vxT%Z_iL! zh_&8qztN8w=I5Q*1(zL0A59V-qw&8k{Z^;AurIQ{p}Hr*>qN!zJKwnXW`BIx>W!Dj zcbTIx2hzhhdB0Il5kF^|I9{Arnv%&?R!zhl>&!(wRl>L@(SBT0M9sZsPtDa= z;$}$G5ezB!VB}i!$I99KksdUd>?blO*H3QY9|FC%GeAoL&Cisb7Gc63PeDFG6;3pC ztK5<8gTIOM#QX1JiVsP~5vdfE6nc@%QEAF!EMQ3mD-C z77$-CyqWkbc~!wu*3ov2xP7c-^dqYG?s!rp6%i_xj3?d{AT z^d8rMj^ml`guB)+9L73s76f%ej07=l*|J}M_}G6eRU zAP?Nndv{{T9Ivz23Fp(*zCQbf&MmYvipYP-DyZ`Q_HSU*&YQnWuUgI zES&Sys^}!y9at6RQX`L}TWrYkG8PYrtTbsAm zNYcxS&2EttM;n?jnv-;Pq*S})eHF%pi7b<0cB->4f9#)o_K$n+IrrRqKi_lD_uM># z;*Z1}z{~e=)z@mZOeRwx5ai_KM&Ktkb<+RSaQH(JfgexfJdK8 zou)w6(DOXuEUTp|j^F%Dp1K2^Wu;?mQH(8=S3x9}LPV*Y&|XEi2sBa75)mgGmt@KH z?^cn!>d7L9FFvb$7X4G$x~a*@N#_ggduu{^p-Sp#&_o&1vq>f=Oy)_n77f~_;*C~* z1-2#4hAP#tqo!eCQ~SlLwwd|ihzzJkEBjs1d~W7uq1y5aUfdK-q0Q8SK&($V120y0 zqjs1dZkS=)G_g`+&>4)7G5bW$ylhBOi397k_sBw#-++5-#e%Y|7afHabQwXyCA`FW z!A~xooMJS2o4&-|RK}5gN%W?ovB!3WuAeUA=IZ*l z%%LZ?%t7(1HXHCd>rmR2TI{~L75(MCkah^E7RM1&pCe2gd|MKsZIX3oS2O7QnQE0C z+{w>eT+ZF?=@yq(ViB-sN)|isHcrM{4)&FW_?%shIkoXvmC9?y85>r9bFRaMk~baS z_oMUja8qu&z?$2Y02Gd%Z8zMOCQf>hXIMi+Z)%r0<-Qi5kXlIn++Z!kpn)BPdVqugO?IMS6%-9$^D2-v3 zlFYGKyJ@I-r5$^LTX!Ywt$*&BCMcyM9=U#6>CB6-d2lt}Vj#=lZc1xMcc*y?-sckr z8V9els`;2m37ne&2`3_CUynJn^FokwS9><(b`2ZrsO|^Z9y_JN8Hci`xD8=8j{ebb zQ|>9M%DNiFqVf)$uOaQ|Ga7s3EBLa`2^nZf;;^;O1RZ>7N4Qg&Kb+)FrF)}qO!&t}Hfvfk<%kHD4-lr0fIDnOITNxE`moA?ib!!ftq}En zLifO`pxSpTOl@^4c=xt#kpQQq5A%^ZL2x8V*Z8M(|8lNl1Bhk~vNZc^#Pmbq=3Q6}$J6oYr`U(QEa zxS%;%(29(f1A1acqHs&7`F*`tBM&zj4b2u}=!qCTe>MZtFD{CV-YO*xo>wT9M}A?? zVh&GDS+d|+QrFS67y8R7Vy1s3T32UFizy8N?Z2XkEpP5ME4tJV92BkO&8gL_y`|g0 z2~B{sKK(X!MaF_A3tbfPJ=t>*X7fz&no@%0Gzko=V~ie|snlht@6tGSekYuThAq9t z;_slbA{aBRR+`4IMs{GhsuEcv8oP8JtM3Vn*}6y6(lF3Gmz3zsUgV7&(*(i(2xM@L v16- Date: Thu, 25 Jun 2026 01:03:42 +0200 Subject: [PATCH 11/13] added functionality to the skipDownstream toggle, as well as improved the look of the GUI --- .../gui/MaintenanceBoxScreen.java | 1 + .../mixin/DestinationInstructionMixin.java | 114 +++++++++++++++--- .../railway/MaintenanceSkipState.java | 4 + .../railway/OfflineStationManager.java | 16 ++- .../lang/en_us.json | 1 + .../textures/gui/maintenance_box.png | Bin 1807 -> 1744 bytes 6 files changed, 112 insertions(+), 24 deletions(-) create mode 100644 src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSkipState.java diff --git a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java index 5538b5c..9772d82 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java +++ b/src/main/java/net/dantemc/create_maintenance_control/content/maintenance_box/gui/MaintenanceBoxScreen.java @@ -101,6 +101,7 @@ protected void init() { )) .writingTo(skipDownstreamLabel) .titled(Component.translatable("gui.maintenance_box.skip_downstream_stations.tooltip")) + .addHint(Component.translatable("gui.maintenance_box.skip_downstream_stations.explanation")) .setState(blockEntity.shouldSkipDownstream() ? 1 : 0); addRenderableWidget(skipDownstreamSelector); diff --git a/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java b/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java index b62c2db..2c3fcaa 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java +++ b/src/main/java/net/dantemc/create_maintenance_control/mixin/DestinationInstructionMixin.java @@ -6,10 +6,13 @@ import com.simibubi.create.content.trains.station.GlobalStation; import net.dantemc.create_maintenance_control.CreateMaintenance; +import net.dantemc.create_maintenance_control.railway.MaintenanceEntry; +import net.dantemc.create_maintenance_control.railway.MaintenanceSkipState; import net.dantemc.create_maintenance_control.railway.OfflineStationManager; import net.minecraft.world.level.Level; import com.simibubi.create.content.trains.graph.EdgePointType; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -61,38 +64,111 @@ public abstract class DestinationInstructionMixin { CallbackInfoReturnable cir) { String regex = getFilterForRegex(); + MaintenanceSkipState state = maintenance$analyzeMatchingStations(runtime, level, regex); - boolean foundMatch = false; - boolean allOffline = true; + if (!state.anyMatch()) + return; + + if (!state.allSkipped()) + return; + + int scheduleSize = runtime.schedule.entries.size(); + + CreateMaintenance.debug("All matching stations for '{}' are under maintenance", getFilter()); + + // skip 1 entry (default behavior) + if (!state.skipDownstream()) { + runtime.currentEntry = (runtime.currentEntry + 1) % scheduleSize; + cir.setReturnValue(null); + cir.cancel(); + return; + } + + // skipDownstream = true: + // search for next destination entry that train can pathfind to + int nextReachableEntry = maintenance$findNextReachableDestinationEntry(runtime, level); + + if (nextReachableEntry != -1) { + CreateMaintenance.debug("Skipping downstream to schedule entry {}", nextReachableEntry); + runtime.currentEntry = nextReachableEntry; + } else { + // fallback: if no stations work, only skip one + runtime.currentEntry = (runtime.currentEntry + 1) % scheduleSize; + } + + cir.setReturnValue(null); + cir.cancel(); + } + + @Unique + private MaintenanceSkipState maintenance$analyzeMatchingStations(ScheduleRuntime runtime, Level level, String regex) { + boolean anyMatch = false; + boolean allSkipped = true; + boolean skipDownstream = false; for (GlobalStation station : runtime.train.graph.getPoints(EdgePointType.STATION)) { if (!station.name.matches(regex)) continue; - foundMatch = true; + anyMatch = true; - if (!OfflineStationManager.isStationSkipped(level, station)) { - allOffline = false; - break; + MaintenanceEntry entry = OfflineStationManager.getMatchingEntry(level, station); + if (entry == null) { + allSkipped = false; + continue; + } + + if (entry.skipDownstream()) { + skipDownstream = true; } } - if (!foundMatch || !allOffline) { - return; + return new MaintenanceSkipState(anyMatch, allSkipped, skipDownstream); + } + + @Unique + private ArrayList maintenance$getValidStations(ScheduleRuntime runtime, Level level, String regex) { + ArrayList validStations = new ArrayList<>(); + + for (GlobalStation station : runtime.train.graph.getPoints(EdgePointType.STATION)) { + if (!station.name.matches(regex)) + continue; + + if (OfflineStationManager.isStationSkipped(level, station)) + continue; + + validStations.add(station); } - CreateMaintenance.debug( - "Skipping destination entry {} with filter '{}' for {} because matching stations are under maintenance", - runtime.currentEntry, - getFilterForRegex(), - runtime.train - ); + return validStations; + } + + @Unique + private boolean maintenance$destinationEntryHasPath(ScheduleRuntime runtime, Level level, DestinationInstruction instruction) { + ArrayList validStations = maintenance$getValidStations(runtime, level, instruction.getFilterForRegex()); - runtime.currentEntry = - (runtime.currentEntry + 1) - % runtime.schedule.entries.size(); + if (validStations.isEmpty()) + return false; - cir.setReturnValue(null); - cir.cancel(); + DiscoveredPath path = runtime.train.navigation.findPathTo(validStations, Double.MAX_VALUE); + return path != null; + } + + @Unique + private int maintenance$findNextReachableDestinationEntry(ScheduleRuntime runtime, Level level) { + int scheduleSize = runtime.schedule.entries.size(); + int originalEntry = runtime.currentEntry; + + for (int offset = 1; offset < scheduleSize; offset++) { + int candidateIndex = (originalEntry + offset) % scheduleSize; + + var scheduleEntry = runtime.schedule.entries.get(candidateIndex); + if (scheduleEntry.instruction instanceof DestinationInstruction destinationInstruction) { + if (maintenance$destinationEntryHasPath(runtime, level, destinationInstruction)) { + return candidateIndex; + } + } + } + return -1; } } \ No newline at end of file diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSkipState.java b/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSkipState.java new file mode 100644 index 0000000..75b725b --- /dev/null +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/MaintenanceSkipState.java @@ -0,0 +1,4 @@ +package net.dantemc.create_maintenance_control.railway; + +public record MaintenanceSkipState(boolean anyMatch, boolean allSkipped, boolean skipDownstream) { +} diff --git a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java index ad8fccd..6415d4a 100644 --- a/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java +++ b/src/main/java/net/dantemc/create_maintenance_control/railway/OfflineStationManager.java @@ -78,14 +78,20 @@ public static void unregisterBox(Level level, BlockPos boxPos) { getData(level).removeEntry(boxPos); } - public static boolean isStationSkipped(Level level, GlobalStation station) { + public static MaintenanceEntry getMatchingEntry(Level level, GlobalStation station) { String stationName = station.name; for (MaintenanceEntry entry : getData(level).getEntries().values()) { - if (entry.shouldSkip() && Objects.equals(entry.stationFilter(), stationName)) { - return true; - } + if (!entry.shouldSkip()) + continue; + + if (Objects.equals(entry.stationFilter(), stationName)) + return entry; } - return false; + return null; + } + + public static boolean isStationSkipped(Level level, GlobalStation station) { + return getMatchingEntry(level, station) != null; } } diff --git a/src/main/resources/assets/create_maintenance_control/lang/en_us.json b/src/main/resources/assets/create_maintenance_control/lang/en_us.json index 62507d7..ac1231b 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/en_us.json +++ b/src/main/resources/assets/create_maintenance_control/lang/en_us.json @@ -16,6 +16,7 @@ "gui.maintenance_box.redstone_mode.inverted": "Powered = Maintenance", "gui.maintenance_box.skip_downstream_stations.tooltip": "Skip downstream stations", + "gui.maintenance_box.skip_downstream_stations.explanation": "Note: When enabled, trains may skip downstream schedule entries until a reachable station is found.", "gui.maintenance_box.skip_downstream_stations.false": "Off", "gui.maintenance_box.skip_downstream_stations.true": "On", diff --git a/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png b/src/main/resources/assets/create_maintenance_control/textures/gui/maintenance_box.png index d670ad65f7781fc0a6517ea19cbca86ef5fbc8e8..b1af8fb533a3085e03c16b6e6e7003137d8a4b71 100644 GIT binary patch delta 1358 zcmeC@yTCiakuhPSlL@D}xw*T$dw6*G#JTD`{}dfL7#J87N`m}?Ctj3iWr&H9emn7B z4`*)~Bf|@328Q0rlNl51)12O3@px@`je&vXiKmNWNJZS+x!plhjsmXj;S8>-j?5ab z{{K(Snt0-k?##LF{AYabPu7~eD{$BED{E7FJ&(?qC@F3H^4^xiKPvpnuN;~2aXEML zvbD({p2?+|&Ha}(^XD8UAX~(N5r}>m`Z|K>isJrvffDx1G@pHztiN~X@Qjyx3fZJK z7;yiISrwAD`DTudoc{FFPm?xE^tvtPG?*=6Y`xF6w*HSGP;Jeu-M@{?zps9^@!U(j zqWkwbD=KP!{VUrZ6@LEIuIDd59&~Q_`j3D0*I(byuen~&b!g+WQ~Um(bZ>aOI-6nN zv(8C87Snw48eShQ?2mpJWw?{E{@rwarsqvBc_kzYs_(q!G)c%f(kmI^w}`RXIq&3! zEG1qExng5B@yVGD#~0i-*fTAFxyJ1-L;unxQV&eu-1@Ob5O!tkTniaXgV`1Z)v zz2-1GQ2u1_)s6y zvPR)v!-kKM98nJY7#q1y2%FhCGdqO~s1;Q7v9ahYdcJs}!^;ux-1FdIrIf(N4xWd} z#-<8sqKryy&$1k@7_B_gbLLvZj?zgTQZv>wPUJo+Y_6BgoD|-rQWSBH%|&0-`OS(o zydCk{GhR4WN>A7jA@MQU$Xp?HD}zwmle~I|OGW#Z^qjcYu;uF>52*?J89TZ8CV%@B zp5gGSi&Fec7EzdrMnILrxuDO+@F7eK_@;zWjZLul`McVi?$`08QVJv{d;X$U0;jHZUgf z9&kTE0OsI!|yt?1E3VZ3bYSw-SwZ2 zE6jfAyDgD!s6T&esq$Zyh>Z-t|FwV(0K4}FgINP_0#GlQIwIB3KMQI<#JeTTTK^7p zfIf?AdR~c=zM| z@6k+p_wUbYSloE|Z#rY&@7clyzfu>dA1JM_uV&KmW190_Tj0UI{k4qD-?ytIG}p`2 z2|d`eUzO3`8Ioc7lkM!va*b6M)BM1vZ3=FVdQ&MBb@0A3hIKL7v# delta 1417 zcmcb>+s`+_k+E)~lZm>erDb?{xKdw2y`uhx=WDKar6yl3KNDgjQyyO~Z>@hgV}-7c zxw-kodUcLB+$YN!7#OrBu2bg!4+jiJD?Y?byw=0Htc;Q21v3M~vdP(uiS@~CpXT+w zf4q}{f#tWSi(^Pd+}pXl{!+dot?W~p#8&Go%-^c}N$qu^>eF^{Ed0N`TR?BE@P^`UgB^SRB+Yy{foVfA zH`f9NAo?Q{9KgUDz)+Sa*njAU<+6GSKK2_sT{)&ZKi;#sAyDGs_n@6d5;Aub z^(xCm>TA{Bd#naKI1&T)UfUmDf9Rat&h2c7sF&OS@AC?V^>uv_^@8>L z|8)b|Wd+AreUkpBx`u2x@_K%v)a&(Hi<(5^?9WJw8{GW9o=1bb;&r^Fg;&Fy`ctev zX`8=B|9@I!J6~IB#=ZOb_kOJpn|)O2?t!0T1~b=wXO7TQ&yHoB{g)wZ^~+}(jGO*v ziYu@Qs4vi7@KRpApoih+|0CQdf+4=ChXjuQj)rf}4&Mzg)N#msm$10bl=T0ZgaAKN z6&sY{E@5$*Y1O~iVxPbI9Cx@{e>rL6PJhz{TN~al{kTC~;dgxvQG`012y5fAtvt-R^~aq$41D4;z+2i0RFj4VE;f&uNdmz+)-k&37qw~mhtwbo24NYHA@)Y+-YLcIMCCe{zP%vJQf=U#by2d z=jXDW;l5#KzrRFsgMPyAPnS{;G&bZhhq2n&nlf4ON{9-~XY6fwd-}B_vl(m1-`0k= zuV24rWL9JS^H!f##w@}6!2L(1|ED$F&3o>A;5Ijh#f|$j8Y1fM*T-{M+_^ui;grMO z{el-R-k;O(YklLihIRkGv2bKD&iyOP@#0;6`~mB~x||gU>iO2QmVDc;^58x!4p From 6a652854f8d464415962c8dbae1397680a404010 Mon Sep 17 00:00:00 2001 From: DanteMinecraft Date: Thu, 25 Jun 2026 01:06:55 +0200 Subject: [PATCH 12/13] updated swedish translation --- .../create_maintenance_control/lang/sv_se.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/main/resources/assets/create_maintenance_control/lang/sv_se.json b/src/main/resources/assets/create_maintenance_control/lang/sv_se.json index 28a5f1e..8c25e57 100644 --- a/src/main/resources/assets/create_maintenance_control/lang/sv_se.json +++ b/src/main/resources/assets/create_maintenance_control/lang/sv_se.json @@ -8,8 +8,20 @@ "block.create_maintenance_control.maintenance_box.tooltip.behaviour1": "TĂ„g som har denna station _i sina scheman_ kommer att _hoppa över den_ medan underhĂ„llet pĂ„gĂ„r.", "block.create_maintenance_control.maintenance_box.tooltip.behaviour2": "NĂ€r blocket _fĂ„r en redstonesignal_ kommer tĂ„g att _stanna vid stationen_ som vanligt.", + "gui.maintenance_box.title": "UnderhĂ„llsblock", + "gui.maintenance_box.station_filter.tooltip": "Stationsfilter", + + "gui.maintenance_box.redstone_mode.tooltip": "Redstone-lĂ€ge", + "gui.maintenance_box.redstone_mode.default": "Odriven = UnderhĂ„ll", + "gui.maintenance_box.redstone_mode.inverted": "Driven = UnderhĂ„ll", + + "gui.maintenance_box.skip_downstream_stations.tooltip": "Hoppa över efterföljande stationer", + "gui.maintenance_box.skip_downstream_stations.explanation": "Obs: NĂ€r detta Ă€r aktiverat kan tĂ„g hoppa över efterföljande schemaposter tills en nĂ„bar station hittas.", + "gui.maintenance_box.skip_downstream_stations.false": "Av", + "gui.maintenance_box.skip_downstream_stations.true": "PĂ„", + "create_maintenance_control.configuration.title": "Create: Maintenance Control-konfigurationer", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml": "Create: Maintenance Control-konfigurationer", "create_maintenance_control.configuration.section.create_maintenance_control.common.toml.title": "Create: Maintenance Control-konfigurationer", "create_maintenance_control.configuration.debugLogs": "Aktivera debug-loggar" -} +} \ No newline at end of file From fd9f49f4672212b999ef7ffd8ed5d1d173af7003 Mon Sep 17 00:00:00 2001 From: DanteMC <68405877+DanteMinecraft@users.noreply.github.com> Date: Thu, 25 Jun 2026 02:26:52 +0200 Subject: [PATCH 13/13] added roadmap link in README Removed planned options for Maintenance Box GUI from README. --- README.md | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/README.md b/README.md index 4aa2d3c..6e64ada 100644 --- a/README.md +++ b/README.md @@ -48,12 +48,7 @@ This includes initial testing with: - Steam 'n' Rails ## 📌 Planned - -### Maintenance Box GUI -Planned options include: - - a station name filter field - - a redstone behavior toggle (powered = maintenance / unpowered = maintenance) - - a "__Skip unreachable downstream stations__" toggle for more advanced network layouts +See [Roadmap](https://github.com/DanteMinecraft/Create-Maintenance/wiki/Roadmap) ### Documentation / Usability - a Ponder scene for the Maintenance Box