diff --git a/src/main/java/com/simibubi/create/compat/computercraft/peripherals/StationPeripheral.java b/src/main/java/com/simibubi/create/compat/computercraft/peripherals/StationPeripheral.java index a9eeb352d..309058f5e 100644 --- a/src/main/java/com/simibubi/create/compat/computercraft/peripherals/StationPeripheral.java +++ b/src/main/java/com/simibubi/create/compat/computercraft/peripherals/StationPeripheral.java @@ -4,24 +4,27 @@ import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; -import org.jetbrains.annotations.NotNull; - import com.simibubi.create.compat.computercraft.CreateLuaTable; import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity; +import com.simibubi.create.content.logistics.trains.management.edgePoint.station.TrainEditPacket; import com.simibubi.create.content.logistics.trains.management.schedule.Schedule; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEntry; import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition; import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleInstruction; +import com.simibubi.create.foundation.networking.AllPackets; +import com.simibubi.create.foundation.utility.Components; import com.simibubi.create.foundation.utility.Pair; 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 net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; +import org.jetbrains.annotations.NotNull; + +import net.minecraftforge.network.PacketDistributor; public class StationPeripheral extends SyncedPeripheral { @@ -29,6 +32,101 @@ public class StationPeripheral extends SyncedPeripheral { super(tile); } + @LuaFunction(mainThread = true) + public final void assemble() throws LuaException { + if (!tile.isAssembling()) + throw new LuaException("station must be in assembly mode"); + + tile.assemble(null); + + if (tile.getStation() == null || tile.getStation().getPresentTrain() == null) + throw new LuaException("failed to assemble train"); + + if (!tile.exitAssemblyMode()) + throw new LuaException("failed to exit assembly mode"); + } + + @LuaFunction(mainThread = true) + public final void disassemble() throws LuaException { + GlobalStation station = tile.getStation(); + if (station == null) + throw new LuaException("train station does not exist"); + + Train train = station.getPresentTrain(); + if (train == null) + throw new LuaException("there is no train present"); + + if (!tile.enterAssemblyMode(null)) + throw new LuaException("could not disassemble train"); + } + + @LuaFunction(mainThread = true) + public final void setAssemblyMode(boolean assemblyMode) throws LuaException { + if (assemblyMode) { + if (!tile.enterAssemblyMode(null)) + throw new LuaException("failed to enter assembly mode"); + } else { + if (!tile.exitAssemblyMode()) + throw new LuaException("failed to exit assembly mode"); + } + } + + @LuaFunction + public final boolean inAssemblyMode() { + return tile.isAssembling(); + } + + @LuaFunction + public final String getStationName() throws LuaException { + GlobalStation station = tile.getStation(); + if (station == null) + throw new LuaException("train station does not exist"); + + return station.name; + } + + @LuaFunction(mainThread = true) + public final void setStationName(String name) throws LuaException { + if (!tile.updateName(name)) + throw new LuaException("could not set station name"); + } + + @LuaFunction + public final boolean isTrainPresent() throws LuaException { + GlobalStation station = tile.getStation(); + if (station == null) + throw new LuaException("train station does not exist"); + + return station.getPresentTrain() != null; + } + + @LuaFunction + public final String getTrainName() throws LuaException { + GlobalStation station = tile.getStation(); + if (station == null) + throw new LuaException("train station does not exist"); + + Train train = station.getPresentTrain(); + if (train == null) + throw new LuaException("there is no train present"); + + return train.name.getString(); + } + + @LuaFunction + public final void setTrainName(String name) throws LuaException { + GlobalStation station = tile.getStation(); + if (station == null) + throw new LuaException("train station does not exist"); + + Train train = station.getPresentTrain(); + if (train == null) + throw new LuaException("there is no train present"); + + train.name = Components.literal(name); + AllPackets.channel.send(PacketDistributor.ALL.noArg(), new TrainEditPacket.TrainEditReturnPacket(train.id, name, train.icon.getId())); + } + @LuaFunction(mainThread = true) public final void setSchedule(IArguments arguments) throws LuaException { GlobalStation station = tile.getStation(); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java index a5a371013..8c237ceaf 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/Train.java @@ -15,8 +15,6 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.BiConsumer; import java.util.function.Consumer; -import javax.annotation.Nullable; - import org.apache.commons.lang3.mutable.MutableBoolean; import org.apache.commons.lang3.mutable.MutableObject; @@ -51,7 +49,7 @@ import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.VecHelper; - +import javax.annotation.Nullable; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.Direction.Axis; @@ -67,6 +65,7 @@ import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Explosion.BlockInteraction; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; + import net.minecraftforge.common.ForgeHooks; import net.minecraftforge.fluids.FluidStack; import net.minecraftforge.fluids.capability.IFluidHandler; @@ -86,6 +85,7 @@ public class Train { public boolean honk = false; public UUID id; + @Nullable public UUID owner; public TrackGraph graph; public Navigation navigation; @@ -124,7 +124,7 @@ public class Train { public int honkPitch; public float accumulatedSteamRelease; - + int tickOffset; double[] stress; @@ -277,7 +277,7 @@ public class Train { int carriageCount = carriages.size(); boolean stalled = false; double maxStress = 0; - + if (carriageWaitingForChunks != -1) distance = 0; @@ -317,7 +317,7 @@ public class Train { entries++; } } - + if (entries > 0) actual = total / entries; @@ -369,7 +369,7 @@ public class Train { .getLeadingPoint(); double totalStress = derailed ? 0 : leadingStress + trailingStress; - + boolean first = i == 0; boolean last = i == carriageCount - 1; int carriageType = first ? last ? Carriage.BOTH : Carriage.FIRST : last ? Carriage.LAST : Carriage.MIDDLE; @@ -1087,7 +1087,8 @@ public class Train { public CompoundTag write(DimensionPalette dimensions) { CompoundTag tag = new CompoundTag(); tag.putUUID("Id", id); - tag.putUUID("Owner", owner); + if (owner != null) + tag.putUUID("Owner", owner); if (graph != null) tag.putUUID("Graph", graph.id); tag.put("Carriages", NBTHelper.writeCompoundList(carriages, c -> c.write(dimensions))); @@ -1133,7 +1134,7 @@ public class Train { public static Train read(CompoundTag tag, Map trackNetworks, DimensionPalette dimensions) { UUID id = tag.getUUID("Id"); - UUID owner = tag.getUUID("Owner"); + UUID owner = tag.contains("Owner") ? tag.getUUID("Owner") : null; UUID graphId = tag.contains("Graph") ? tag.getUUID("Graph") : null; TrackGraph graph = graphId == null ? null : trackNetworks.get(graphId); List carriages = new ArrayList<>(); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java index 479b2699e..ec43cd9f9 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/entity/TrainPacket.java @@ -12,7 +12,6 @@ import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.RegisteredObjects; - import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.chat.Component; import net.minecraft.world.level.block.Block; @@ -37,7 +36,10 @@ public class TrainPacket extends SimplePacketBase { if (!add) return; - UUID owner = buffer.readUUID(); + UUID owner = null; + if (buffer.readBoolean()) + owner = buffer.readUUID(); + List carriages = new ArrayList<>(); List carriageSpacing = new ArrayList<>(); @@ -73,7 +75,9 @@ public class TrainPacket extends SimplePacketBase { if (!add) return; - buffer.writeUUID(train.owner); + buffer.writeBoolean(train.owner != null); + if (train.owner != null) + buffer.writeUUID(train.owner); buffer.writeVarInt(train.carriages.size()); for (Carriage carriage : train.carriages) { diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationEditPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationEditPacket.java index e1ec084c7..2028aca9d 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationEditPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationEditPacket.java @@ -1,19 +1,11 @@ package com.simibubi.create.content.logistics.trains.management.edgePoint.station; -import com.simibubi.create.Create; -import com.simibubi.create.content.logistics.trains.GraphLocation; -import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket; -import com.simibubi.create.foundation.utility.VecHelper; - import net.minecraft.core.BlockPos; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.Vec3; public class StationEditPacket extends TileEntityConfigurationPacket { @@ -92,18 +84,12 @@ public class StationEditPacket extends TileEntityConfigurationPacket station.assembling = true); + GlobalStation station = getStation(); + if (station != null) { + for (Train train : Create.RAILWAYS.sided(level).trains.values()) { + if (train.navigation.destination != station) + continue; + + GlobalStation preferredDestination = train.runtime.startCurrentInstruction(); + train.navigation.startNavigation(preferredDestination != null ? preferredDestination : station, Double.MAX_VALUE, false); + } + } + + return true; + } + + public boolean exitAssemblyMode() { + if (!isAssembling()) + return false; + + cancelAssembly(); + BlockState newState = getBlockState().setValue(StationBlock.ASSEMBLING, false); + level.setBlock(getBlockPos(), newState, 3); + refreshBlockState(); + + return updateStationState(station -> station.assembling = false); + } + + public boolean tryDisassembleTrain(@Nullable ServerPlayer sender) { + GlobalStation station = getStation(); + if (station == null) + return false; + + Train train = station.getPresentTrain(); + if (train == null) + return false; + + BlockPos trackPosition = edgePoint.getGlobalPosition(); + if (!train.disassemble(getAssemblyDirection(), trackPosition.above())) + return false; + + dropSchedule(sender); + return true; + } + public boolean isAssembling() { BlockState state = getBlockState(); return state.hasProperty(StationBlock.ASSEMBLING) && state.getValue(StationBlock.ASSEMBLING); @@ -347,6 +409,42 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable return true; } + public void dropSchedule(@Nullable ServerPlayer sender) { + GlobalStation station = getStation(); + if (station == null) + return; + + Train train = station.getPresentTrain(); + if (train == null) + return; + + ItemStack schedule = train.runtime.returnSchedule(); + if (schedule.isEmpty()) + return; + if (sender != null && sender.getMainHandItem().isEmpty()) { + sender.getInventory() + .placeItemBackInInventory(schedule); + return; + } + + Vec3 v = VecHelper.getCenterOf(getBlockPos()); + ItemEntity itemEntity = new ItemEntity(getLevel(), v.x, v.y, v.z, schedule); + itemEntity.setDeltaMovement(Vec3.ZERO); + getLevel().addFreshEntity(itemEntity); + } + + private boolean updateStationState(Consumer updateState) { + GlobalStation station = getStation(); + GraphLocation graphLocation = edgePoint.determineGraphLocation(); + if (station == null || graphLocation == null) + return false; + + updateState.accept(station); + Create.RAILWAYS.sync.pointAdded(graphLocation.graph, station); + Create.RAILWAYS.markTracksDirty(); + return true; + } + public void refreshAssemblyInfo() { if (!edgePoint.hasValidTrack()) return; @@ -415,6 +513,14 @@ public class StationTileEntity extends SmartTileEntity implements ITransformable map.put(worldPosition, BoundingBox.fromCorners(startPosition, trackEnd)); } + public boolean updateName(String name) { + if (!updateStationState(station -> station.name = name)) + return false; + notifyUpdate(); + + return true; + } + public boolean isValidBogeyOffset(int i) { if ((i < 3 || bogeyCount == 0) && i != 0) return false;