diff --git a/src/main/java/com/simibubi/create/compat/computercraft/events/StationTrainPresenceEvent.java b/src/main/java/com/simibubi/create/compat/computercraft/events/StationTrainPresenceEvent.java new file mode 100644 index 000000000..badb16036 --- /dev/null +++ b/src/main/java/com/simibubi/create/compat/computercraft/events/StationTrainPresenceEvent.java @@ -0,0 +1,30 @@ +package com.simibubi.create.compat.computercraft.events; + +import org.jetbrains.annotations.NotNull; + + +import com.simibubi.create.content.trains.entity.Train; + +public class StationTrainPresenceEvent implements ComputerEvent { + + public enum Type { + IMMINENT("train_imminent"), + ARRIVAL("train_arrival"), + DEPARTURE("train_departure"); + + public final String name; + + Type(String name) { + this.name = name; + } + } + + public Type type; + public @NotNull Train train; + + public StationTrainPresenceEvent(Type type, @NotNull Train train) { + this.type = type; + this.train = train; + } + +} diff --git a/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java b/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java index c50891fe3..fd881ed1d 100644 --- a/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java +++ b/src/main/java/com/simibubi/create/compat/computercraft/implementation/peripherals/StationPeripheral.java @@ -1,15 +1,22 @@ package com.simibubi.create.compat.computercraft.implementation.peripherals; +import java.util.ArrayList; import java.util.Map; - -import javax.annotation.Nullable; +import java.util.regex.PatternSyntaxException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + import com.simibubi.create.AllPackets; +import com.simibubi.create.compat.computercraft.events.ComputerEvent; +import com.simibubi.create.compat.computercraft.events.StationTrainPresenceEvent; import com.simibubi.create.compat.computercraft.implementation.CreateLuaTable; import com.simibubi.create.content.trains.entity.Train; +import com.simibubi.create.content.trains.graph.DiscoveredPath; +import com.simibubi.create.content.trains.graph.EdgePointType; import com.simibubi.create.content.trains.schedule.Schedule; +import com.simibubi.create.content.trains.schedule.destination.DestinationInstruction; import com.simibubi.create.content.trains.station.GlobalStation; import com.simibubi.create.content.trains.station.StationBlockEntity; import com.simibubi.create.content.trains.station.TrainEditPacket; @@ -19,6 +26,7 @@ import com.simibubi.create.foundation.utility.StringHelper; import dan200.computercraft.api.lua.IArguments; import dan200.computercraft.api.lua.LuaException; import dan200.computercraft.api.lua.LuaFunction; +import dan200.computercraft.api.lua.MethodResult; import net.minecraft.nbt.ByteTag; import net.minecraft.nbt.CollectionTag; import net.minecraft.nbt.CompoundTag; @@ -164,6 +172,33 @@ public class StationPeripheral extends SyncedPeripheral { train.runtime.setSchedule(schedule, autoSchedule); } + @LuaFunction + public MethodResult canTrainReach(String destinationFilter) throws LuaException { + Train train = getTrainOrThrow(); + + String regex = DestinationInstruction.getFilterForRegex(destinationFilter); + boolean anyMatch = false; + ArrayList validStations = new ArrayList<>(); + try { + for (GlobalStation globalStation : train.graph.getPoints(EdgePointType.STATION)) { + if (!globalStation.name.matches(regex)) + continue; + anyMatch = true; + validStations.add(globalStation); + } + } catch (PatternSyntaxException ignored) {} + + DiscoveredPath best = train.navigation.findPathTo(validStations, Double.MAX_VALUE); + if (best == null) { + if (anyMatch) + return MethodResult.of(false, "cannot-reach"); + else + return MethodResult.of(false, "no-target"); + } + + return MethodResult.of(true, null); + } + private @NotNull Train getTrainOrThrow() throws LuaException { GlobalStation station = blockEntity.getStation(); if (station == null) @@ -268,6 +303,13 @@ public class StationPeripheral extends SyncedPeripheral { throw new LuaException("unknown object type " + value.getClass().getName()); } + @Override + public void prepareComputerEvent(@NotNull ComputerEvent event) { + if (event instanceof StationTrainPresenceEvent stpe) { + queueEvent(stpe.type.name, stpe.train.name.getString()); + } + } + @NotNull @Override public String getType() { diff --git a/src/main/java/com/simibubi/create/content/trains/schedule/destination/DestinationInstruction.java b/src/main/java/com/simibubi/create/content/trains/schedule/destination/DestinationInstruction.java index ada430049..477876339 100644 --- a/src/main/java/com/simibubi/create/content/trains/schedule/destination/DestinationInstruction.java +++ b/src/main/java/com/simibubi/create/content/trains/schedule/destination/DestinationInstruction.java @@ -2,6 +2,8 @@ package com.simibubi.create.content.trains.schedule.destination; import java.util.List; +import org.jetbrains.annotations.NotNull; + import org.apache.commons.lang3.StringUtils; import com.google.common.collect.ImmutableList; @@ -44,9 +46,12 @@ public class DestinationInstruction extends TextScheduleInstruction { public String getFilter() { return getLabelText(); } - + public String getFilterForRegex() { - String filter = getFilter(); + return getFilterForRegex(getFilter()); + } + + public static String getFilterForRegex(@NotNull String filter) { if (filter.isBlank()) return filter; return "\\Q" + filter.replace("*", "\\E.*\\Q") + "\\E"; diff --git a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java index a164782e6..23873945f 100644 --- a/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/trains/station/StationBlockEntity.java @@ -13,8 +13,6 @@ import java.util.function.Consumer; import javax.annotation.Nullable; -import com.simibubi.create.content.trains.graph.DiscoveredPath; - import org.jetbrains.annotations.NotNull; import com.simibubi.create.AllBlocks; @@ -22,6 +20,7 @@ import com.simibubi.create.AllItems; import com.simibubi.create.AllPackets; import com.simibubi.create.AllSoundEvents; import com.simibubi.create.Create; +import com.simibubi.create.compat.computercraft.events.StationTrainPresenceEvent; import com.simibubi.create.compat.computercraft.AbstractComputerBehaviour; import com.simibubi.create.compat.computercraft.ComputerCraftProxy; import com.simibubi.create.content.contraptions.AssemblyException; @@ -38,6 +37,7 @@ import com.simibubi.create.content.trains.entity.CarriageContraption; import com.simibubi.create.content.trains.entity.Train; import com.simibubi.create.content.trains.entity.TrainPacket; import com.simibubi.create.content.trains.entity.TravellingPoint; +import com.simibubi.create.content.trains.graph.DiscoveredPath; import com.simibubi.create.content.trains.graph.EdgePointType; import com.simibubi.create.content.trains.graph.TrackEdge; import com.simibubi.create.content.trains.graph.TrackGraph; @@ -259,6 +259,21 @@ public class StationBlockEntity extends SmartBlockEntity implements ITransformab imminentTrain.runtime.displayLinkUpdateRequested = false; } + if (!level.isClientSide && computerBehaviour.hasAttachedComputer()) { + if (this.imminentTrain == null && imminentTrain != null) + computerBehaviour.prepareComputerEvent( + new StationTrainPresenceEvent(StationTrainPresenceEvent.Type.IMMINENT, imminentTrain)); + if (newlyArrived) { + if (trainPresent) + computerBehaviour.prepareComputerEvent( + new StationTrainPresenceEvent(StationTrainPresenceEvent.Type.ARRIVAL, imminentTrain)); + else + computerBehaviour.prepareComputerEvent( + new StationTrainPresenceEvent(StationTrainPresenceEvent.Type.DEPARTURE, + Create.RAILWAYS.trains.get(this.imminentTrain))); + } + } + if (newlyArrived) applyAutoSchedule();