Look ma, both threads!

- Movement of client-side trains is now controlled via network packets (Manual controls and Relocation not yet adjusted for sidedness)
- Modified train settings now get broadcasted to other players
- Cleaned up redundant delegation between classes involved in controlling the carriages
This commit is contained in:
simibubi 2022-03-08 03:51:03 +01:00
parent 3c64ada850
commit 9629cb84eb
87 changed files with 1145 additions and 437 deletions

View file

@ -174,9 +174,9 @@ import com.simibubi.create.content.logistics.block.vault.ItemVaultBlock;
import com.simibubi.create.content.logistics.block.vault.ItemVaultCTBehaviour; import com.simibubi.create.content.logistics.block.vault.ItemVaultCTBehaviour;
import com.simibubi.create.content.logistics.block.vault.ItemVaultItem; import com.simibubi.create.content.logistics.block.vault.ItemVaultItem;
import com.simibubi.create.content.logistics.item.LecternControllerBlock; import com.simibubi.create.content.logistics.item.LecternControllerBlock;
import com.simibubi.create.content.logistics.trains.management.StationBlock; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBlockItem; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBlock;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBlock; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationBlock;
import com.simibubi.create.content.logistics.trains.track.StandardBogeyBlock; import com.simibubi.create.content.logistics.trains.track.StandardBogeyBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlock; import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackBlockItem; import com.simibubi.create.content.logistics.trains.track.TrackBlockItem;

View file

@ -10,8 +10,8 @@ import com.simibubi.create.content.logistics.item.filter.AttributeFilterContaine
import com.simibubi.create.content.logistics.item.filter.AttributeFilterScreen; import com.simibubi.create.content.logistics.item.filter.AttributeFilterScreen;
import com.simibubi.create.content.logistics.item.filter.FilterContainer; import com.simibubi.create.content.logistics.item.filter.FilterContainer;
import com.simibubi.create.content.logistics.item.filter.FilterScreen; import com.simibubi.create.content.logistics.item.filter.FilterScreen;
import com.simibubi.create.content.logistics.trains.management.ScheduleContainer; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleContainer;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.content.schematics.block.SchematicTableContainer; import com.simibubi.create.content.schematics.block.SchematicTableContainer;
import com.simibubi.create.content.schematics.block.SchematicTableScreen; import com.simibubi.create.content.schematics.block.SchematicTableScreen;
import com.simibubi.create.content.schematics.block.SchematicannonContainer; import com.simibubi.create.content.schematics.block.SchematicannonContainer;

View file

@ -0,0 +1,18 @@
package com.simibubi.create;
import com.simibubi.create.content.logistics.trains.entity.CarriageSyncDataSerializer;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.registries.DataSerializerEntry;
import net.minecraftforge.registries.IForgeRegistry;
public class AllEntityDataSerializers {
public static final CarriageSyncDataSerializer CARRIAGE_DATA = new CarriageSyncDataSerializer();
public static void register(RegistryEvent.Register<DataSerializerEntry> event) {
IForgeRegistry<DataSerializerEntry> registry = event.getRegistry();
registry.register(new DataSerializerEntry(CARRIAGE_DATA).setRegistryName(Create.asResource("carriage_data")));
}
}

View file

@ -41,7 +41,7 @@ import com.simibubi.create.content.curiosities.weapons.PotatoCannonItem;
import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperItem; import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperItem;
import com.simibubi.create.content.logistics.item.LinkedControllerItem; import com.simibubi.create.content.logistics.item.LinkedControllerItem;
import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.content.logistics.item.filter.FilterItem;
import com.simibubi.create.content.logistics.trains.management.ScheduleItem; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleItem;
import com.simibubi.create.content.schematics.item.SchematicAndQuillItem; import com.simibubi.create.content.schematics.item.SchematicAndQuillItem;
import com.simibubi.create.content.schematics.item.SchematicItem; import com.simibubi.create.content.schematics.item.SchematicItem;
import com.simibubi.create.foundation.data.AssetLookup; import com.simibubi.create.foundation.data.AssetLookup;

View file

@ -171,10 +171,10 @@ import com.simibubi.create.content.logistics.block.vault.ItemVaultTileEntity;
import com.simibubi.create.content.logistics.item.LecternControllerRenderer; import com.simibubi.create.content.logistics.item.LecternControllerRenderer;
import com.simibubi.create.content.logistics.item.LecternControllerTileEntity; import com.simibubi.create.content.logistics.item.LecternControllerTileEntity;
import com.simibubi.create.content.logistics.trains.IBogeyTileEntityRenderer; import com.simibubi.create.content.logistics.trains.IBogeyTileEntityRenderer;
import com.simibubi.create.content.logistics.trains.management.StationRenderer; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalRenderer;
import com.simibubi.create.content.logistics.trains.management.StationTileEntity; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity;
import com.simibubi.create.content.logistics.trains.management.signal.SignalRenderer; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationRenderer;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity;
import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity; import com.simibubi.create.content.logistics.trains.track.StandardBogeyTileEntity;
import com.simibubi.create.content.logistics.trains.track.TrackInstance; import com.simibubi.create.content.logistics.trains.track.TrackInstance;
import com.simibubi.create.content.logistics.trains.track.TrackRenderer; import com.simibubi.create.content.logistics.trains.track.TrackRenderer;

View file

@ -52,6 +52,7 @@ import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.forge.event.lifecycle.GatherDataEvent; import net.minecraftforge.forge.event.lifecycle.GatherDataEvent;
import net.minecraftforge.registries.DataSerializerEntry;
@Mod(Create.ID) @Mod(Create.ID)
public class Create { public class Create {
@ -116,6 +117,7 @@ public class Create {
modEventBus.addGenericListener(RecipeSerializer.class, AllRecipeTypes::register); modEventBus.addGenericListener(RecipeSerializer.class, AllRecipeTypes::register);
modEventBus.addGenericListener(ParticleType.class, AllParticleTypes::register); modEventBus.addGenericListener(ParticleType.class, AllParticleTypes::register);
modEventBus.addGenericListener(SoundEvent.class, AllSoundEvents::register); modEventBus.addGenericListener(SoundEvent.class, AllSoundEvents::register);
modEventBus.addGenericListener(DataSerializerEntry.class, AllEntityDataSerializers::register);
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus)); DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> CreateClient.onCtorClient(modEventBus, forgeEventBus));
} }

View file

@ -34,7 +34,7 @@ import com.simibubi.create.content.logistics.block.vault.ItemVaultBlock;
import com.simibubi.create.content.logistics.block.vault.ItemVaultConnectivityHandler; import com.simibubi.create.content.logistics.block.vault.ItemVaultConnectivityHandler;
import com.simibubi.create.content.logistics.trains.IBogeyBlock; import com.simibubi.create.content.logistics.trains.IBogeyBlock;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.management.StationBlock; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationBlock;
import com.simibubi.create.foundation.config.ContraptionMovementSetting; import com.simibubi.create.foundation.config.ContraptionMovementSetting;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;

View file

@ -41,10 +41,7 @@ public class ControlsMovementBehaviour extends MovementBehaviour {
Collection<Integer> pressed = ControlsHandler.currentlyPressed; Collection<Integer> pressed = ControlsHandler.currentlyPressed;
equipAnimation.chase(1, .2f, Chaser.EXP); equipAnimation.chase(1, .2f, Chaser.EXP);
steering.chase((pressed.contains(3) ? 1 : 0) + (pressed.contains(2) ? -1 : 0), 0.2f, Chaser.EXP); steering.chase((pressed.contains(3) ? 1 : 0) + (pressed.contains(2) ? -1 : 0), 0.2f, Chaser.EXP);
if (context.contraption.entity instanceof CarriageContraptionEntity car) { speed.chase(0, 0.2f, Chaser.EXP); // TODO
Carriage carriage = car.getCarriage();
speed.chase(Math.abs(carriage.train.speed), 0.2f, Chaser.EXP);
}
} else } else
equipAnimation.chase(0, .2f, Chaser.EXP); equipAnimation.chase(0, .2f, Chaser.EXP);
float pt = AnimationTickHolder.getPartialTicks(context.world); float pt = AnimationTickHolder.getPartialTicks(context.world);

View file

@ -9,8 +9,8 @@ import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlo
import com.simibubi.create.content.logistics.trains.entity.CarriageContraption; import com.simibubi.create.content.logistics.trains.entity.CarriageContraption;
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.ScheduleItem;
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule; import com.simibubi.create.content.logistics.trains.management.schedule.Schedule;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleItem;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -30,9 +30,9 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
ItemStack itemInHand = player.getItemInHand(activeHand); ItemStack itemInHand = player.getItemInHand(activeHand);
if (!AllItems.SCHEDULE.isIn(itemInHand)) if (!AllItems.SCHEDULE.isIn(itemInHand))
return false; return false;
if (!(contraptionEntity instanceof CarriageContraptionEntity carriage)) if (!(contraptionEntity instanceof CarriageContraptionEntity carriageEntity))
return false; return false;
Contraption contraption = carriage.getContraption(); Contraption contraption = carriageEntity.getContraption();
if (!(contraption instanceof CarriageContraption carriageContraption)) if (!(contraption instanceof CarriageContraption carriageContraption))
return false; return false;
@ -49,7 +49,7 @@ public class BlazeBurnerInteractionBehaviour extends MovingInteractionBehaviour
Schedule schedule = ScheduleItem.getSchedule(itemInHand); Schedule schedule = ScheduleItem.getSchedule(itemInHand);
if (schedule == null) if (schedule == null)
return false; return false;
Train train = carriage.getCarriage().train; Train train = carriageEntity.getCarriage().train;
if (train == null) if (train == null)
return false; return false;
if (train.heldForAssembly) { if (train.heldForAssembly) {

View file

@ -9,8 +9,8 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonParseException; import com.google.gson.JsonParseException;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.SignalState; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity.SignalState;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;

View file

@ -10,12 +10,15 @@ import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableObject;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
import com.simibubi.create.AllKeys; import com.simibubi.create.AllKeys;
import com.simibubi.create.content.logistics.trains.entity.Carriage; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup; import com.simibubi.create.content.logistics.trains.entity.TrainPacket;
import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroup;
import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
@ -24,18 +27,19 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.dimension.DimensionType;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.network.PacketDistributor;
public class GlobalRailwayManager { public class GlobalRailwayManager {
public Map<UUID, TrackGraph> trackNetworks; public Map<UUID, TrackGraph> trackNetworks;
public Map<UUID, SignalEdgeGroup> signalEdgeGroups; public Map<UUID, SignalEdgeGroup> signalEdgeGroups;
public Map<UUID, Train> trains; public Map<UUID, Train> trains;
public Map<Integer, Carriage> carriageById;
private TrackSavedData trackData;
public TrackGraphSync sync; public TrackGraphSync sync;
// private RailwaySavedData savedData;
public GlobalRailwayManager() { public GlobalRailwayManager() {
cleanUp(); cleanUp();
@ -47,6 +51,9 @@ public class GlobalRailwayManager {
trackNetworks.values() trackNetworks.values()
.forEach(g -> sync.sendFullGraphTo(g, serverPlayer)); .forEach(g -> sync.sendFullGraphTo(g, serverPlayer));
sync.sendEdgeGroups(signalEdgeGroups.keySet(), serverPlayer); sync.sendEdgeGroups(signalEdgeGroups.keySet(), serverPlayer);
for (Train train : trains.values())
AllPackets.channel.send(PacketDistributor.PLAYER.with(() -> serverPlayer),
new TrainPacket(train, false));
} }
} }
@ -55,16 +62,16 @@ public class GlobalRailwayManager {
if (server == null || server.overworld() != level) if (server == null || server.overworld() != level)
return; return;
cleanUp(); cleanUp();
trackData = null; savedData = null;
loadTrackData(server); loadTrackData(server);
} }
private void loadTrackData(MinecraftServer server) { private void loadTrackData(MinecraftServer server) {
if (trackData != null) if (savedData != null)
return; return;
trackData = TrackSavedData.load(server); savedData = RailwaySavedData.load(server);
trackNetworks = trackData.getTrackNetworks(); trackNetworks = savedData.getTrackNetworks();
signalEdgeGroups = trackData.getSignalBlocks(); signalEdgeGroups = savedData.getSignalBlocks();
} }
public void levelUnloaded(LevelAccessor level) { public void levelUnloaded(LevelAccessor level) {
@ -78,13 +85,12 @@ public class GlobalRailwayManager {
trackNetworks = new HashMap<>(); trackNetworks = new HashMap<>();
signalEdgeGroups = new HashMap<>(); signalEdgeGroups = new HashMap<>();
trains = new HashMap<>(); trains = new HashMap<>();
carriageById = new HashMap<>();
sync = new TrackGraphSync(); sync = new TrackGraphSync();
} }
public void markTracksDirty() { public void markTracksDirty() {
if (trackData != null) if (savedData != null)
trackData.setDirty(); savedData.setDirty();
} }
// //
@ -168,4 +174,17 @@ public class GlobalRailwayManager {
.forEach(TrackGraph::debugViewNodes); .forEach(TrackGraph::debugViewNodes);
} }
public GlobalRailwayManager sided(LevelAccessor level) {
if (level != null && !level.isClientSide())
return this;
MutableObject<GlobalRailwayManager> m = new MutableObject<>();
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> clientManager(m));
return m.getValue();
}
@OnlyIn(Dist.CLIENT)
private void clientManager(MutableObject<GlobalRailwayManager> m) {
m.setValue(CreateClient.RAILWAYS);
}
} }

View file

@ -0,0 +1,11 @@
package com.simibubi.create.content.logistics.trains;
import com.simibubi.create.foundation.utility.Couple;
public class GraphLocation {
public TrackGraph graph;
public Couple<TrackNodeLocation> edge;
public double position;
}

View file

@ -11,7 +11,7 @@ import javax.annotation.Nullable;
import com.jozufozu.flywheel.core.PartialModel; import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.content.logistics.trains.track.TrackBlock; import com.simibubi.create.content.logistics.trains.track.TrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackShape; import com.simibubi.create.content.logistics.trains.track.TrackShape;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;

View file

@ -5,7 +5,7 @@ import java.util.Map;
import java.util.UUID; import java.util.UUID;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroup;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
@ -13,7 +13,7 @@ import net.minecraft.nbt.Tag;
import net.minecraft.server.MinecraftServer; import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.SavedData;
public class TrackSavedData extends SavedData { public class RailwaySavedData extends SavedData {
private Map<UUID, TrackGraph> trackNetworks = new HashMap<>(); private Map<UUID, TrackGraph> trackNetworks = new HashMap<>();
private Map<UUID, SignalEdgeGroup> signalEdgeGroups = new HashMap<>(); private Map<UUID, SignalEdgeGroup> signalEdgeGroups = new HashMap<>();
@ -26,8 +26,8 @@ public class TrackSavedData extends SavedData {
return nbt; return nbt;
} }
private static TrackSavedData load(CompoundTag nbt) { private static RailwaySavedData load(CompoundTag nbt) {
TrackSavedData sd = new TrackSavedData();//TODO load trains before everything else RailwaySavedData sd = new RailwaySavedData();//TODO load trains before everything else
sd.trackNetworks = new HashMap<>(); sd.trackNetworks = new HashMap<>();
sd.signalEdgeGroups = new HashMap<>(); sd.signalEdgeGroups = new HashMap<>();
NBTHelper.iterateCompoundList(nbt.getList("RailGraphs", Tag.TAG_COMPOUND), c -> { NBTHelper.iterateCompoundList(nbt.getList("RailGraphs", Tag.TAG_COMPOUND), c -> {
@ -49,12 +49,12 @@ public class TrackSavedData extends SavedData {
return signalEdgeGroups; return signalEdgeGroups;
} }
private TrackSavedData() {} private RailwaySavedData() {}
public static TrackSavedData load(MinecraftServer server) { public static RailwaySavedData load(MinecraftServer server) {
return server.overworld() return server.overworld()
.getDataStorage() .getDataStorage()
.computeIfAbsent(TrackSavedData::load, TrackSavedData::new, "create_tracks"); .computeIfAbsent(RailwaySavedData::load, RailwaySavedData::new, "create_tracks");
} }
} }

View file

@ -1,6 +1,6 @@
package com.simibubi.create.content.logistics.trains; package com.simibubi.create.content.logistics.trains;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;

View file

@ -23,14 +23,14 @@ import com.simibubi.create.Create;
import com.simibubi.create.CreateClient; import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointManager; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointManager;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointStorage; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointStorage;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroup;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
@ -217,6 +217,7 @@ public class TrackGraph {
if (train.graph != this) if (train.graph != this)
continue; continue;
train.graph = toOther; train.graph = toOther;
train.syncTrackGraphChanges();
} }
} }

View file

@ -6,7 +6,6 @@ import java.util.Map.Entry;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;

View file

@ -11,8 +11,8 @@ import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroupPacket; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroupPacket;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;

View file

@ -8,9 +8,9 @@ import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;

View file

@ -9,7 +9,7 @@ import java.util.Set;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.management.signal.SignalPropagator; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalPropagator;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.content.logistics.trains.entity; package com.simibubi.create.content.logistics.trains.entity;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function; import java.util.function.Function;
@ -8,20 +9,17 @@ import javax.annotation.Nullable;
import org.apache.commons.lang3.mutable.MutableDouble; import org.apache.commons.lang3.mutable.MutableDouble;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.Axis; import net.minecraft.nbt.CompoundTag;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
@ -31,17 +29,19 @@ public class Carriage {
public static final AtomicInteger netIdGenerator = new AtomicInteger(); public static final AtomicInteger netIdGenerator = new AtomicInteger();
public Train train; public Train train;
public CarriageContraption contraption;
public int bogeySpacing;
public int id; public int id;
public boolean blocked; public boolean blocked;
public Couple<Boolean> presentConductors;
public boolean hasForwardConductor; public int bogeySpacing;
public boolean hasBackwardConductor;
WeakReference<CarriageContraptionEntity> entity;
Couple<CarriageBogey> bogeys; Couple<CarriageBogey> bogeys;
CompoundTag serialisedEntity;
WeakReference<CarriageContraptionEntity> entity;
// client
public boolean pointsInitialised;
static final int FIRST = 0, MIDDLE = 1, LAST = 2, BOTH = 3; static final int FIRST = 0, MIDDLE = 1, LAST = 2, BOTH = 3;
public Carriage(CarriageBogey bogey1, @Nullable CarriageBogey bogey2, int bogeySpacing) { public Carriage(CarriageBogey bogey1, @Nullable CarriageBogey bogey2, int bogeySpacing) {
@ -49,6 +49,8 @@ public class Carriage {
this.bogeys = Couple.create(bogey1, bogey2); this.bogeys = Couple.create(bogey1, bogey2);
this.entity = new WeakReference<>(null); this.entity = new WeakReference<>(null);
this.id = netIdGenerator.incrementAndGet(); this.id = netIdGenerator.incrementAndGet();
this.serialisedEntity = new CompoundTag();
this.pointsInitialised = false;
bogey1.carriage = this; bogey1.carriage = this;
if (bogey2 != null) if (bogey2 != null)
@ -59,9 +61,13 @@ public class Carriage {
this.train = train; this.train = train;
} }
public void setContraption(CarriageContraption contraption) { public void setContraption(Level level, CarriageContraption contraption) {
this.contraption = contraption; CarriageContraptionEntity entity = CarriageContraptionEntity.create(level, contraption);
contraption.setCarriage(this); entity.setInitialOrientation(contraption.getAssemblyDirection()
.getClockWise());
entity.setCarriage(this);
contraption.startMoving(level);
serialisedEntity = entity.serializeNBT();
} }
public double travel(Level level, TrackGraph graph, double distance, public double travel(Level level, TrackGraph graph, double distance,
@ -121,35 +127,36 @@ public class Carriage {
bogey.updateAnchorPosition(); bogey.updateAnchorPosition();
} }
tickEntity(level); double actualMovement = distanceMoved.getValue();
return distanceMoved.getValue(); manageEntity(level, actualMovement);
return actualMovement;
} }
public void updateConductors() { public void updateConductors() {
CarriageContraptionEntity entity = this.entity.get(); CarriageContraptionEntity entity = this.entity.get();
if (entity == null || !entity.isAlive()) if (entity != null && entity.isAlive())
return; presentConductors = entity.checkConductors();
Couple<Boolean> sides = entity.checkConductors();
hasForwardConductor = sides.getFirst();
hasBackwardConductor = sides.getSecond();
} }
public void createEntity(Level level) { public void createEntity(Level level) {
contraption.startMoving(level); Optional<Entity> entityFromData = EntityType.create(serialisedEntity, level);
CarriageContraptionEntity entity = CarriageContraptionEntity.create(level, contraption); Entity entity = entityFromData.orElse(null);
if (!(entity instanceof CarriageContraptionEntity cce))
return;
Vec3 pos = leadingBogey().anchorPosition; Vec3 pos = leadingBogey().anchorPosition;
entity.setPos(pos); cce.setPos(pos);
entity.setInitialOrientation(contraption.getAssemblyDirection() cce.setCarriage(this);
.getClockWise()); cce.setGraph(train.graph == null ? null : train.graph.id);
level.addFreshEntity(entity); cce.syncCarriage();
this.entity = new WeakReference<>(entity); level.addFreshEntity(cce);
this.entity = new WeakReference<>(cce);
} }
public ChunkPos getChunk() { public ChunkPos getChunk() {
return new ChunkPos(new BlockPos(leadingBogey().anchorPosition)); return new ChunkPos(new BlockPos(leadingBogey().anchorPosition));
} }
protected void tickEntity(Level level) { protected void manageEntity(Level level, double actualMovement) {
CarriageContraptionEntity entity = this.entity.get(); CarriageContraptionEntity entity = this.entity.get();
if (entity == null) { if (entity == null) {
if (CarriageEntityHandler.isActiveChunk(level, getChunk())) if (CarriageEntityHandler.isActiveChunk(level, getChunk()))
@ -157,6 +164,7 @@ public class Carriage {
} else { } else {
CarriageEntityHandler.validateCarriageEntity(entity); CarriageEntityHandler.validateCarriageEntity(entity);
if (!entity.isAlive()) { if (!entity.isAlive()) {
serialisedEntity = entity.serializeNBT();
this.entity.clear(); this.entity.clear();
return; return;
} }
@ -165,11 +173,12 @@ public class Carriage {
entity = this.entity.get(); entity = this.entity.get();
if (entity == null) if (entity == null)
return; return;
if (!entity.level.isClientSide)
moveEntity(entity); alignEntity(entity);
entity.syncCarriage();
} }
public void moveEntity(CarriageContraptionEntity entity) { public void alignEntity(CarriageContraptionEntity entity) {
Vec3 positionVec = isOnTwoBogeys() ? leadingBogey().anchorPosition Vec3 positionVec = isOnTwoBogeys() ? leadingBogey().anchorPosition
: leadingBogey().leading() : leadingBogey().leading()
.getPosition(); .getPosition();
@ -215,93 +224,4 @@ public class Carriage {
return bogeys.getSecond() != null; return bogeys.getSecond() != null;
} }
public static class CarriageBogey {
Carriage carriage;
IBogeyBlock type;
Couple<TravellingPoint> points;
Vec3 anchorPosition;
LerpedFloat wheelAngle;
LerpedFloat yaw;
LerpedFloat pitch;
public Vec3 leadingCouplingAnchor;
public Vec3 trailingCouplingAnchor;
int derailAngle;
public CarriageBogey(IBogeyBlock type, TravellingPoint point, TravellingPoint point2) {
this.type = type;
points = Couple.create(point, point2);
wheelAngle = LerpedFloat.angular();
yaw = LerpedFloat.angular();
pitch = LerpedFloat.angular();
updateAnchorPosition();
derailAngle = Create.RANDOM.nextInt(90) - 45;
}
public void updateAngles(double distanceMoved) {
double angleDiff = 360 * distanceMoved / (Math.PI * 2 * type.getWheelRadius());
Vec3 positionVec = leading().getPosition();
Vec3 coupledVec = trailing().getPosition();
double diffX = positionVec.x - coupledVec.x;
double diffY = positionVec.y - coupledVec.y;
double diffZ = positionVec.z - coupledVec.z;
float yRot = AngleHelper.deg(Mth.atan2(diffZ, diffX)) + 90;
float xRot = AngleHelper.deg(Math.atan2(diffY, Math.sqrt(diffX * diffX + diffZ * diffZ)));
if (carriage.train.derailed)
yRot += derailAngle;
wheelAngle.setValue((wheelAngle.getValue() - angleDiff * Math.signum(carriage.train.speed)) % 360);
pitch.setValue(xRot);
yaw.setValue(-yRot);
}
public TravellingPoint leading() {
return points.getFirst();
}
public TravellingPoint trailing() {
return points.getSecond();
}
public double getStress() {
return type.getWheelPointSpacing() - leading().getPosition()
.distanceTo(trailing().getPosition());
}
public void updateAnchorPosition() {
anchorPosition = points.getFirst()
.getPosition()
.add(points.getSecond()
.getPosition())
.scale(.5);
}
public void updateCouplingAnchor(Vec3 entityPos, float entityXRot, float entityYRot, int bogeySpacing,
float partialTicks, boolean leading) {
Vec3 thisOffset = type.getConnectorAnchorOffset();
thisOffset = thisOffset.multiply(1, 1, leading ? -1 : 1);
thisOffset = VecHelper.rotate(thisOffset, pitch.getValue(partialTicks), Axis.X);
thisOffset = VecHelper.rotate(thisOffset, yaw.getValue(partialTicks), Axis.Y);
thisOffset = VecHelper.rotate(thisOffset, -entityYRot - 90, Axis.Y);
thisOffset = VecHelper.rotate(thisOffset, entityXRot, Axis.X);
thisOffset = VecHelper.rotate(thisOffset, -180, Axis.Y);
thisOffset = thisOffset.add(0, 0, leading ? 0 : -bogeySpacing);
thisOffset = VecHelper.rotate(thisOffset, 180, Axis.Y);
thisOffset = VecHelper.rotate(thisOffset, -entityXRot, Axis.X);
thisOffset = VecHelper.rotate(thisOffset, entityYRot + 90, Axis.Y);
if (leading)
leadingCouplingAnchor = entityPos.add(thisOffset);
else {
trailingCouplingAnchor = entityPos.add(thisOffset);
}
}
}
} }

View file

@ -0,0 +1,103 @@
package com.simibubi.create.content.logistics.trains.entity;
import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
import net.minecraft.core.Direction.Axis;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
public class CarriageBogey {
public Carriage carriage;
IBogeyBlock type;
Couple<TravellingPoint> points;
Vec3 anchorPosition;
LerpedFloat wheelAngle;
LerpedFloat yaw;
LerpedFloat pitch;
public Vec3 leadingCouplingAnchor;
public Vec3 trailingCouplingAnchor;
int derailAngle;
public CarriageBogey(IBogeyBlock type, TravellingPoint point, TravellingPoint point2) {
this.type = type;
points = Couple.create(point, point2);
wheelAngle = LerpedFloat.angular();
yaw = LerpedFloat.angular();
pitch = LerpedFloat.angular();
updateAnchorPosition();
derailAngle = Create.RANDOM.nextInt(90) - 45;
}
public void updateAngles(double distanceMoved) {
double angleDiff = 360 * distanceMoved / (Math.PI * 2 * type.getWheelRadius());
Vec3 positionVec = leading().getPosition();
Vec3 coupledVec = trailing().getPosition();
double diffX = positionVec.x - coupledVec.x;
double diffY = positionVec.y - coupledVec.y;
double diffZ = positionVec.z - coupledVec.z;
float yRot = AngleHelper.deg(Mth.atan2(diffZ, diffX)) + 90;
float xRot = AngleHelper.deg(Math.atan2(diffY, Math.sqrt(diffX * diffX + diffZ * diffZ)));
if (carriage.train.derailed)
yRot += derailAngle;
wheelAngle.setValue((wheelAngle.getValue() - angleDiff * Math.signum(carriage.train.speed)) % 360);
pitch.setValue(xRot);
yaw.setValue(-yRot);
}
public TravellingPoint leading() {
return points.getFirst();
}
public TravellingPoint trailing() {
return points.getSecond();
}
public double getStress() {
return type.getWheelPointSpacing() - leading().getPosition()
.distanceTo(trailing().getPosition());
}
public void updateAnchorPosition() {
if (points.getFirst().node1 == null)
return;
anchorPosition = points.getFirst()
.getPosition()
.add(points.getSecond()
.getPosition())
.scale(.5);
}
public void updateCouplingAnchor(Vec3 entityPos, float entityXRot, float entityYRot, int bogeySpacing,
float partialTicks, boolean leading) {
Vec3 thisOffset = type.getConnectorAnchorOffset();
thisOffset = thisOffset.multiply(1, 1, leading ? -1 : 1);
thisOffset = VecHelper.rotate(thisOffset, pitch.getValue(partialTicks), Axis.X);
thisOffset = VecHelper.rotate(thisOffset, yaw.getValue(partialTicks), Axis.Y);
thisOffset = VecHelper.rotate(thisOffset, -entityYRot - 90, Axis.Y);
thisOffset = VecHelper.rotate(thisOffset, entityXRot, Axis.X);
thisOffset = VecHelper.rotate(thisOffset, -180, Axis.Y);
thisOffset = thisOffset.add(0, 0, leading ? 0 : -bogeySpacing);
thisOffset = VecHelper.rotate(thisOffset, 180, Axis.Y);
thisOffset = VecHelper.rotate(thisOffset, -entityXRot, Axis.X);
thisOffset = VecHelper.rotate(thisOffset, entityYRot + 90, Axis.Y);
if (leading)
leadingCouplingAnchor = entityPos.add(thisOffset);
else
trailingCouplingAnchor = entityPos.add(thisOffset);
}
}

View file

@ -40,11 +40,7 @@ public class CarriageContraption extends Contraption {
public Couple<Boolean> blazeBurnerConductors; public Couple<Boolean> blazeBurnerConductors;
public Map<BlockPos, Couple<Boolean>> conductorSeats; public Map<BlockPos, Couple<Boolean>> conductorSeats;
// runtime // during assembly only
private Carriage carriage;
public int temporaryCarriageIdHolder = -1;
// for assembly only
private int bogeys; private int bogeys;
private boolean sidewaysControls; private boolean sidewaysControls;
private BlockPos secondBogeyPos; private BlockPos secondBogeyPos;
@ -138,8 +134,6 @@ public class CarriageContraption extends Contraption {
public CompoundTag writeNBT(boolean spawnPacket) { public CompoundTag writeNBT(boolean spawnPacket) {
CompoundTag tag = super.writeNBT(spawnPacket); CompoundTag tag = super.writeNBT(spawnPacket);
NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection()); NBTHelper.writeEnum(tag, "AssemblyDirection", getAssemblyDirection());
if (spawnPacket)
tag.putInt("CarriageId", carriage.id);
tag.putBoolean("FrontControls", forwardControls); tag.putBoolean("FrontControls", forwardControls);
tag.putBoolean("BackControls", backwardControls); tag.putBoolean("BackControls", backwardControls);
tag.putBoolean("FrontBlazeConductor", blazeBurnerConductors.getFirst()); tag.putBoolean("FrontBlazeConductor", blazeBurnerConductors.getFirst());
@ -159,8 +153,6 @@ public class CarriageContraption extends Contraption {
@Override @Override
public void readNBT(Level world, CompoundTag nbt, boolean spawnData) { public void readNBT(Level world, CompoundTag nbt, boolean spawnData) {
assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class); assemblyDirection = NBTHelper.readEnum(nbt, "AssemblyDirection", Direction.class);
if (spawnData)
temporaryCarriageIdHolder = nbt.getInt("CarriageId");
forwardControls = nbt.getBoolean("FrontControls"); forwardControls = nbt.getBoolean("FrontControls");
backwardControls = nbt.getBoolean("BackControls"); backwardControls = nbt.getBoolean("BackControls");
blazeBurnerConductors = blazeBurnerConductors =
@ -191,15 +183,6 @@ public class CarriageContraption extends Contraption {
return assemblyDirection; return assemblyDirection;
} }
public void setCarriage(Carriage carriage) {
this.carriage = carriage;
temporaryCarriageIdHolder = carriage.id;
}
public Carriage getCarriage() {
return carriage;
}
public boolean hasForwardControls() { public boolean hasForwardControls() {
return forwardControls; return forwardControls;
} }

View file

@ -1,17 +1,24 @@
package com.simibubi.create.content.logistics.trains.entity; package com.simibubi.create.content.logistics.trains.entity;
import java.util.Collection; import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
import javax.annotation.Nullable;
import org.apache.commons.lang3.tuple.MutablePair; import org.apache.commons.lang3.tuple.MutablePair;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.simibubi.create.AllEntityDataSerializers;
import com.simibubi.create.AllEntityTypes; import com.simibubi.create.AllEntityTypes;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext; import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.OrientedContraptionEntity;
import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock; import com.simibubi.create.content.contraptions.components.structureMovement.interaction.controls.ControlsBlock;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.Color; import com.simibubi.create.foundation.utility.Color;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
@ -23,8 +30,12 @@ import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.util.Mth; import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
@ -38,8 +49,20 @@ import net.minecraftforge.fml.DistExecutor;
public class CarriageContraptionEntity extends OrientedContraptionEntity { public class CarriageContraptionEntity extends OrientedContraptionEntity {
private static final EntityDataAccessor<CarriageSyncData> CARRIAGE_DATA =
SynchedEntityData.defineId(CarriageContraptionEntity.class, AllEntityDataSerializers.CARRIAGE_DATA);
private static final EntityDataAccessor<Optional<UUID>> TRACK_GRAPH =
SynchedEntityData.defineId(CarriageContraptionEntity.class, EntityDataSerializers.OPTIONAL_UUID);
public UUID trainId;
public int carriageIndex;
private Carriage carriage;
public boolean validForRender;
public CarriageContraptionEntity(EntityType<?> type, Level world) { public CarriageContraptionEntity(EntityType<?> type, Level world) {
super(type, world); super(type, world);
validForRender = false;
} }
@Override @Override
@ -47,6 +70,46 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
return true; return true;
} }
@Override
protected void defineSynchedData() {
super.defineSynchedData();
entityData.define(CARRIAGE_DATA, new CarriageSyncData());
entityData.define(TRACK_GRAPH, Optional.empty());
}
public void syncCarriage() {
CarriageSyncData carriageData = getCarriageData();
if (carriageData == null)
return;
if (carriage == null)
return;
carriageData.update(this, carriage);
}
@Override
public void onSyncedDataUpdated(EntityDataAccessor<?> key) {
super.onSyncedDataUpdated(key);
if (!level.isClientSide)
return;
if (key == TRACK_GRAPH)
updateTrackGraph();
if (key == CARRIAGE_DATA) {
CarriageSyncData carriageData = getCarriageData();
if (carriageData == null)
return;
if (carriage == null)
return;
carriageData.apply(this, carriage);
}
}
private CarriageSyncData getCarriageData() {
return entityData.get(CARRIAGE_DATA);
}
public static CarriageContraptionEntity create(Level world, CarriageContraption contraption) { public static CarriageContraptionEntity create(Level world, CarriageContraption contraption) {
CarriageContraptionEntity entity = CarriageContraptionEntity entity =
new CarriageContraptionEntity(AllEntityTypes.CARRIAGE_CONTRAPTION.get(), world); new CarriageContraptionEntity(AllEntityTypes.CARRIAGE_CONTRAPTION.get(), world);
@ -56,9 +119,97 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
return entity; return entity;
} }
@Override
protected void tickContraption() {
if (!(contraption instanceof CarriageContraption))
return;
if (carriage == null) {
if (level.isClientSide) {
Train train = Create.RAILWAYS.sided(level).trains.get(trainId);
if (train == null || train.carriages.size() <= carriageIndex)
return;
carriage = train.carriages.get(carriageIndex);
updateTrackGraph();
} else
discard();
return;
}
tickActors();
contraption.stalled = false;
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = pair.right;
context.stall = false;
}
CarriageSyncData carriageData = getCarriageData();
if (!level.isClientSide) {
if (tickCount % getType().updateInterval() == 0 && carriageData.isDirty()) {
entityData.set(CARRIAGE_DATA, null);
entityData.set(CARRIAGE_DATA, carriageData);
carriageData.setDirty(false);
}
return;
}
if (!carriage.pointsInitialised)
return;
carriageData.approach(this, carriage, 1f / getType().updateInterval());
carriage.bogeys.getFirst()
.updateAnchorPosition();
if (carriage.isOnTwoBogeys())
carriage.bogeys.getSecond()
.updateAnchorPosition();
xo = getX();
yo = getY();
zo = getZ();
carriage.alignEntity(this);
double distanceTo = position().distanceTo(new Vec3(xo, yo, zo));
carriage.bogeys.getFirst()
.updateAngles(distanceTo);
if (carriage.isOnTwoBogeys())
carriage.bogeys.getSecond()
.updateAngles(distanceTo);
if (carriage.train.derailed)
spawnDerailParticles(carriage);
validForRender = true;
}
Vec3 derailParticleOffset = VecHelper.offsetRandomly(Vec3.ZERO, Create.RANDOM, 1.5f)
.multiply(1, .25f, 1);
private void spawnDerailParticles(Carriage carriage) {
if (random.nextFloat() < 1 / 20f) {
Vec3 v = position().add(derailParticleOffset);
level.addParticle(ParticleTypes.CAMPFIRE_COSY_SMOKE, v.x, v.y, v.z, 0, .04, 0);
}
}
@Override
protected void writeAdditional(CompoundTag compound, boolean spawnPacket) {
super.writeAdditional(compound, spawnPacket);
compound.putUUID("TrainId", trainId);
compound.putInt("CarriageIndex", carriageIndex);
}
@Override
protected void readAdditional(CompoundTag compound, boolean spawnPacket) {
super.readAdditional(compound, spawnPacket);
trainId = compound.getUUID("TrainId");
carriageIndex = compound.getInt("CarriageIndex");
}
@Override @Override
public Component getContraptionName() { public Component getContraptionName() {
Carriage carriage = getCarriage();
if (carriage != null) if (carriage != null)
return carriage.train.name; return carriage.train.name;
Component contraptionName = super.getContraptionName(); Component contraptionName = super.getContraptionName();
@ -89,12 +240,11 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
@Override @Override
public boolean startControlling(BlockPos controlsLocalPos, Player player) { public boolean startControlling(BlockPos controlsLocalPos, Player player) {
Carriage carriage = getCarriage();
if (carriage == null) if (carriage == null)
return false; return false;
if (carriage.train.derailed) if (carriage.train.derailed)
return false; return false;
if (carriage.train.heldForAssembly) { if (!level.isClientSide && carriage.train.heldForAssembly) {
player.displayClientMessage(Lang.translate("schedule.train_still_assembling"), true); player.displayClientMessage(Lang.translate("schedule.train_still_assembling"), true);
return false; return false;
} }
@ -111,7 +261,6 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
@Override @Override
public boolean control(BlockPos controlsLocalPos, Collection<Integer> heldControls, Player player) { public boolean control(BlockPos controlsLocalPos, Collection<Integer> heldControls, Player player) {
Carriage carriage = getCarriage();
if (carriage == null) if (carriage == null)
return false; return false;
if (carriage.train.derailed) if (carriage.train.derailed)
@ -227,58 +376,21 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
stationMessage = false; stationMessage = false;
} }
@Override private void updateTrackGraph() {
protected void tickContraption() { if (carriage == null)
if (!(contraption instanceof CarriageContraption))
return; return;
Carriage carriage = getCarriage(); Optional<UUID> optional = entityData.get(TRACK_GRAPH);
if (carriage == null) { if (optional.isEmpty()) {
discard(); carriage.train.graph = null;
carriage.train.derailed = true;
return; return;
} }
tickActors(); TrackGraph graph = CreateClient.RAILWAYS.sided(level).trackNetworks.get(optional.get());
contraption.stalled = false; if (graph == null)
for (MutablePair<StructureBlockInfo, MovementContext> pair : contraption.getActors()) {
MovementContext context = pair.right;
context.stall = false;
}
if (!level.isClientSide)
return; return;
carriage.train.graph = graph;
xo = getX(); carriage.train.derailed = false;
yo = getY();
zo = getZ();
carriage.moveEntity(this);
double distanceTo = position().distanceTo(new Vec3(xo, yo, zo));
carriage.bogeys.getFirst()
.updateAngles(distanceTo);
if (carriage.isOnTwoBogeys())
carriage.bogeys.getSecond()
.updateAngles(distanceTo);
if (carriage.train.derailed)
spawnDerailParticles(carriage);
}
public Carriage getCarriage() {
int id = ((CarriageContraption) contraption).temporaryCarriageIdHolder;
Carriage carriage = Create.RAILWAYS.carriageById.get(id); // TODO: thread breach
return carriage;
}
Vec3 derailParticleOffset = VecHelper.offsetRandomly(Vec3.ZERO, Create.RANDOM, 1.5f)
.multiply(1, .25f, 1);
private void spawnDerailParticles(Carriage carriage) {
if (random.nextFloat() < 1 / 20f) {
Vec3 v = position().add(derailParticleOffset);
level.addParticle(ParticleTypes.CAMPFIRE_COSY_SMOKE, v.x, v.y, v.z, 0, .04, 0);
}
} }
@Override @Override
@ -286,4 +398,18 @@ public class CarriageContraptionEntity extends OrientedContraptionEntity {
return false; return false;
} }
public Carriage getCarriage() {
return carriage;
}
public void setCarriage(Carriage carriage) {
this.carriage = carriage;
this.trainId = carriage.train.id;
this.carriageIndex = carriage.train.carriages.indexOf(carriage);
}
public void setGraph(@Nullable UUID graphId) {
entityData.set(TRACK_GRAPH, Optional.ofNullable(graphId));
}
} }

View file

@ -20,7 +20,7 @@ public class CarriageContraptionEntityRenderer extends ContraptionEntityRenderer
double cameraY, double cameraZ) { double cameraY, double cameraZ) {
if (!super.shouldRender(entity, clippingHelper, cameraX, cameraY, cameraZ)) if (!super.shouldRender(entity, clippingHelper, cameraX, cameraY, cameraZ))
return false; return false;
return ((CarriageContraption) entity.getContraption()).temporaryCarriageIdHolder != -1; return entity.validForRender;
} }
@Override @Override

View file

@ -7,7 +7,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Carriage.CarriageBogey;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;

View file

@ -0,0 +1,281 @@
package com.simibubi.create.content.logistics.trains.entity;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Set;
import java.util.Vector;
import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.util.Mth;
import net.minecraft.world.phys.Vec3;
public class CarriageSyncData {
public Vector<Pair<Couple<Integer>, Float>> wheelLocations;
public float distanceToDestination;
// For Client interpolation
private TravellingPoint[] pointsToApproach;
private float[] pointDistanceSnapshot;
private float destinationDistanceSnapshot;
public CarriageSyncData() {
wheelLocations = new Vector<>(4);
pointDistanceSnapshot = new float[4];
pointsToApproach = new TravellingPoint[4];
destinationDistanceSnapshot = 0;
for (int i = 0; i < 4; i++) {
wheelLocations.add(null);
pointsToApproach[i] = new TravellingPoint();
}
}
public CarriageSyncData copy() {
CarriageSyncData data = new CarriageSyncData();
for (int i = 0; i < 4; i++)
data.wheelLocations.set(i, wheelLocations.get(i));
data.distanceToDestination = distanceToDestination;
return data;
}
public void write(FriendlyByteBuf buffer) {
for (Pair<Couple<Integer>, Float> pair : wheelLocations) {
buffer.writeBoolean(pair == null);
if (pair == null)
break;
pair.getFirst()
.forEach(buffer::writeInt);
buffer.writeFloat(pair.getSecond());
}
buffer.writeFloat(distanceToDestination);
}
public void read(FriendlyByteBuf buffer) {
for (int i = 0; i < 4; i++) {
if (buffer.readBoolean())
break;
wheelLocations.set(i, Pair.of(Couple.create(buffer::readInt), buffer.readFloat()));
}
distanceToDestination = buffer.readFloat();
}
public void update(CarriageContraptionEntity entity, Carriage carriage) {
TrackGraph graph = carriage.train.graph;
if (graph == null)
return;
for (boolean first : Iterate.trueAndFalse) {
if (!first && !carriage.isOnTwoBogeys())
break;
CarriageBogey bogey = carriage.bogeys.get(first);
for (boolean firstPoint : Iterate.trueAndFalse) {
TravellingPoint point = bogey.points.get(firstPoint);
int index = (first ? 0 : 2) + (firstPoint ? 0 : 1);
Pair<Couple<Integer>, Float> pair =
Pair.of(Couple.create(point.node1.getNetId(), point.node2.getNetId()), (float) point.position);
wheelLocations.set(index, pair);
}
}
distanceToDestination = (float) carriage.train.navigation.distanceToDestination;
setDirty(true);
}
public void apply(CarriageContraptionEntity entity, Carriage carriage) {
TrackGraph graph = carriage.train.graph;
if (graph == null)
return;
for (int i = 0; i < wheelLocations.size(); i++) {
Pair<Couple<Integer>, Float> pair = wheelLocations.get(i);
if (pair == null)
break;
CarriageBogey bogey = carriage.bogeys.get(i / 2 == 0);
TravellingPoint bogeyPoint = bogey.points.get(i % 2 == 0);
TravellingPoint point = carriage.pointsInitialised ? pointsToApproach[i] : bogeyPoint;
Couple<TrackNode> nodes = pair.getFirst()
.map(graph::getNode);
if (nodes.either(Objects::isNull))
continue;
TrackEdge edge = graph.getConnectionsFrom(nodes.getFirst())
.get(nodes.getSecond());
if (edge == null)
continue;
point.node1 = nodes.getFirst();
point.node2 = nodes.getSecond();
point.edge = edge;
point.position = pair.getSecond();
if (carriage.pointsInitialised) {
float foundDistance = -1;
boolean direction = false;
for (boolean forward : Iterate.trueAndFalse) {
float distanceTo = getDistanceTo(graph, bogeyPoint, point, foundDistance, forward);
if (distanceTo > 0 && (foundDistance == -1 || distanceTo < foundDistance)) {
foundDistance = distanceTo;
direction = forward;
}
}
if (foundDistance != -1) {
pointDistanceSnapshot[i] = (direction ? 1 : -1) * foundDistance;
} else {
// could not pathfind to server location
bogeyPoint.node1 = point.node1;
bogeyPoint.node2 = point.node2;
bogeyPoint.edge = point.edge;
bogeyPoint.position = point.position;
pointDistanceSnapshot[i] = 0;
}
}
}
if (!carriage.pointsInitialised) {
carriage.train.navigation.distanceToDestination = distanceToDestination;
carriage.pointsInitialised = true;
return;
}
destinationDistanceSnapshot = (float) (distanceToDestination - carriage.train.navigation.distanceToDestination);
}
public void approach(CarriageContraptionEntity entity, Carriage carriage, float partial) {
TrackGraph graph = carriage.train.graph;
if (graph == null)
return;
carriage.train.navigation.distanceToDestination += partial * destinationDistanceSnapshot;
for (boolean first : Iterate.trueAndFalse) {
if (!first && !carriage.isOnTwoBogeys())
break;
CarriageBogey bogey = carriage.bogeys.get(first);
for (boolean firstPoint : Iterate.trueAndFalse) {
int index = (first ? 0 : 2) + (firstPoint ? 0 : 1);
float f = pointDistanceSnapshot[index];
if (Mth.equal(f, 0))
continue;
TravellingPoint point = bogey.points.get(firstPoint);
MutableBoolean success = new MutableBoolean(true);
TravellingPoint toApproach = pointsToApproach[index];
point.travel(graph, partial * f,
point.follow(toApproach, b -> success.setValue(success.booleanValue() && b)),
point.ignoreSignals());
// could not pathfind to server location
if (!success.booleanValue()) {
point.node1 = toApproach.node1;
point.node2 = toApproach.node2;
point.edge = toApproach.edge;
point.position = toApproach.position;
pointDistanceSnapshot[index] = 0;
}
}
}
}
public float getDistanceTo(TrackGraph graph, TravellingPoint current, TravellingPoint target, float maxDistance,
boolean forward) {
if (maxDistance == -1)
maxDistance = 32;
Set<TrackEdge> visited = new HashSet<>();
Map<TrackEdge, Pair<Boolean, TrackEdge>> reachedVia = new IdentityHashMap<>();
PriorityQueue<Pair<Double, Pair<Couple<TrackNode>, TrackEdge>>> frontier =
new PriorityQueue<>((p1, p2) -> Double.compare(p1.getFirst(), p2.getFirst()));
TrackNode initialNode1 = forward ? current.node1 : current.node2;
TrackNode initialNode2 = forward ? current.node2 : current.node1;
TrackEdge initialEdge = graph.getConnectionsFrom(initialNode1)
.get(initialNode2);
TrackNode targetNode1 = forward ? target.node1 : target.node2;
TrackNode targetNode2 = forward ? target.node2 : target.node1;
TrackEdge targetEdge = graph.getConnectionsFrom(targetNode1)
.get(targetNode2);
double distanceToNode2 =
forward ? initialEdge.getLength(initialNode1, initialNode2) - current.position : current.position;
frontier.add(Pair.of(distanceToNode2, Pair.of(Couple.create(initialNode1, initialNode2), initialEdge)));
while (!frontier.isEmpty()) {
Pair<Double, Pair<Couple<TrackNode>, TrackEdge>> poll = frontier.poll();
double distance = poll.getFirst();
Pair<Couple<TrackNode>, TrackEdge> currentEntry = poll.getSecond();
TrackNode node1 = currentEntry.getFirst()
.getFirst();
TrackNode node2 = currentEntry.getFirst()
.getSecond();
TrackEdge edge = currentEntry.getSecond();
if (edge == targetEdge)
return (float) (distance
- (forward ? edge.getLength(node1, node2) - target.position : target.position));
if (distance > maxDistance)
continue;
List<Entry<TrackNode, TrackEdge>> validTargets = new ArrayList<>();
Map<TrackNode, TrackEdge> connectionsFrom = graph.getConnectionsFrom(node2);
for (Entry<TrackNode, TrackEdge> entry : connectionsFrom.entrySet()) {
TrackNode newNode = entry.getKey();
TrackEdge newEdge = entry.getValue();
Vec3 currentDirection = edge.getDirection(node1, node2, false);
Vec3 newDirection = newEdge.getDirection(node2, newNode, true);
if (currentDirection.dot(newDirection) < 3 / 4f)
continue;
if (!visited.add(entry.getValue()))
continue;
validTargets.add(entry);
}
if (validTargets.isEmpty())
continue;
for (Entry<TrackNode, TrackEdge> entry : validTargets) {
TrackNode newNode = entry.getKey();
TrackEdge newEdge = entry.getValue();
reachedVia.put(newEdge, Pair.of(validTargets.size() > 1, edge));
frontier.add(Pair.of(newEdge.getLength(node2, newNode) + distance,
Pair.of(Couple.create(node2, newNode), newEdge)));
}
}
return -1;
}
//
private boolean isDirty;
public void setDirty(boolean dirty) {
isDirty = dirty;
}
public boolean isDirty() {
return isDirty;
}
}

View file

@ -0,0 +1,25 @@
package com.simibubi.create.content.logistics.trains.entity;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.syncher.EntityDataSerializer;
public class CarriageSyncDataSerializer implements EntityDataSerializer<CarriageSyncData> {
@Override
public void write(FriendlyByteBuf buffer, CarriageSyncData data) {
data.write(buffer);
}
@Override
public CarriageSyncData read(FriendlyByteBuf buffer) {
CarriageSyncData data = new CarriageSyncData();
data.read(buffer);
return data;
}
@Override
public CarriageSyncData copy(CarriageSyncData data) {
return data.copy();
}
}

View file

@ -17,12 +17,12 @@ import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroup;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;

View file

@ -19,23 +19,22 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableObject; import org.apache.commons.lang3.mutable.MutableObject;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.CreateClient; import com.simibubi.create.content.logistics.trains.GraphLocation;
import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.entity.Carriage.CarriageBogey;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime.State;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroup;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroup; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleRuntime;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleRuntime.State;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
@ -49,6 +48,7 @@ import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Explosion.BlockInteraction; import net.minecraft.world.level.Explosion.BlockInteraction;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.PacketDistributor;
public class Train { public class Train {
@ -84,7 +84,9 @@ public class Train {
double[] stress; double[] stress;
public Train(UUID id, UUID owner, TrackGraph graph, List<Carriage> carriages, List<Integer> carriageSpacing) { public Train(UUID id, UUID owner, TrackGraph graph, List<Carriage> carriages, List<Integer> carriageSpacing,
boolean doubleEnded) {
this.id = id; this.id = id;
this.owner = owner; this.owner = owner;
this.graph = graph; this.graph = graph;
@ -94,14 +96,10 @@ public class Train {
this.stress = new double[carriageSpacing.size()]; this.stress = new double[carriageSpacing.size()];
this.name = Lang.translate("train.unnamed"); this.name = Lang.translate("train.unnamed");
this.status = new TrainStatus(this); this.status = new TrainStatus(this);
this.doubleEnded = doubleEnded;
carriages.forEach(c -> { carriages.forEach(c -> c.setTrain(this));
c.setTrain(this);
Create.RAILWAYS.carriageById.put(c.id, c);
});
doubleEnded = carriages.stream()
.anyMatch(c -> c.contraption.hasBackwardControls());
navigation = new Navigation(this); navigation = new Navigation(this);
runtime = new ScheduleRuntime(this); runtime = new ScheduleRuntime(this);
heldForAssembly = true; heldForAssembly = true;
@ -283,14 +281,14 @@ public class Train {
public boolean hasForwardConductor() { public boolean hasForwardConductor() {
for (Carriage carriage : carriages) for (Carriage carriage : carriages)
if (carriage.hasForwardConductor) if (carriage.presentConductors.getFirst())
return true; return true;
return false; return false;
} }
public boolean hasBackwardConductor() { public boolean hasBackwardConductor() {
for (Carriage carriage : carriages) for (Carriage carriage : carriages)
if (carriage.hasBackwardConductor) if (carriage.presentConductors.getSecond())
return true; return true;
return false; return false;
} }
@ -370,6 +368,8 @@ public class Train {
return; return;
speed = -Mth.clamp(speed, -.5, .5); speed = -Mth.clamp(speed, -.5, .5);
derailed = true; derailed = true;
graph = null;
syncTrackGraphChanges();
status.crash(); status.crash();
} }
@ -396,8 +396,6 @@ public class Train {
entity.setPos(Vec3 entity.setPos(Vec3
.atLowerCornerOf(pos.relative(assemblyDirection, backwards ? offset + carriage.bogeySpacing : offset))); .atLowerCornerOf(pos.relative(assemblyDirection, backwards ? offset + carriage.bogeySpacing : offset)));
entity.disassemble(); entity.disassemble();
Create.RAILWAYS.carriageById.remove(carriage.id);
CreateClient.RAILWAYS.carriageById.remove(carriage.id);
offset += carriage.bogeySpacing; offset += carriage.bogeySpacing;
@ -410,7 +408,7 @@ public class Train {
currentStation.cancelReservation(this); currentStation.cancelReservation(this);
Create.RAILWAYS.trains.remove(id); Create.RAILWAYS.trains.remove(id);
CreateClient.RAILWAYS.trains.remove(id); // TODO Thread breach AllPackets.channel.send(PacketDistributor.ALL.noArg(), new TrainPacket(this, false));
return true; return true;
} }
@ -428,7 +426,7 @@ public class Train {
navigation.cancelNavigation(); navigation.cancelNavigation();
forEachTravellingPoint(tp -> migratingPoints.add(new TrainMigration(tp))); forEachTravellingPoint(tp -> migratingPoints.add(new TrainMigration(tp)));
graph = null; graph = null;
syncTrackGraphChanges();
} }
public void forEachTravellingPoint(Consumer<TravellingPoint> callback) { public void forEachTravellingPoint(Consumer<TravellingPoint> callback) {
@ -497,6 +495,7 @@ public class Train {
migrationCooldown = 40; migrationCooldown = 40;
status.failedMigration(); status.failedMigration();
derailed = true; derailed = true;
syncTrackGraphChanges();
return; return;
} }
@ -516,10 +515,19 @@ public class Train {
if (currentStation != null) if (currentStation != null)
currentStation.reserveFor(this); currentStation.reserveFor(this);
updateSignalBlocks = true; updateSignalBlocks = true;
syncTrackGraphChanges();
return; return;
} }
} }
public void syncTrackGraphChanges() {
for (Carriage carriage : carriages) {
CarriageContraptionEntity entity = carriage.entity.get();
if (entity != null)
entity.setGraph(graph == null ? null : graph.id);
}
}
public int getTotalLength() { public int getTotalLength() {
int length = 0; int length = 0;
for (int i = 0; i < carriages.size(); i++) { for (int i = 0; i < carriages.size(); i++) {

View file

@ -2,11 +2,11 @@ package com.simibubi.create.content.logistics.trains.entity;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.simibubi.create.content.logistics.trains.GraphLocation;
import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;

View file

@ -0,0 +1,109 @@
package com.simibubi.create.content.logistics.trains.entity;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Supplier;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.IBogeyBlock;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.block.Block;
import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.registries.ForgeRegistries;
public class TrainPacket extends SimplePacketBase {
UUID trainId;
Train train;
boolean add;
public TrainPacket(Train train, boolean add) {
this.train = train;
this.add = add;
}
public TrainPacket(FriendlyByteBuf buffer) {
add = buffer.readBoolean();
trainId = buffer.readUUID();
if (!add)
return;
UUID owner = buffer.readUUID();
List<Carriage> carriages = new ArrayList<>();
List<Integer> carriageSpacing = new ArrayList<>();
int size = buffer.readVarInt();
for (int i = 0; i < size; i++) {
Couple<CarriageBogey> bogies = Couple.create(null, null);
for (boolean first : Iterate.trueAndFalse) {
if (!first && !buffer.readBoolean())
continue;
IBogeyBlock type = (IBogeyBlock) ForgeRegistries.BLOCKS.getValue(buffer.readResourceLocation());
bogies.set(first, new CarriageBogey(type, new TravellingPoint(), new TravellingPoint()));
}
int spacing = buffer.readVarInt();
carriages.add(new Carriage(bogies.getFirst(), bogies.getSecond(), spacing));
}
size = buffer.readVarInt();
for (int i = 0; i < size; i++)
carriageSpacing.add(buffer.readVarInt());
boolean doubleEnded = buffer.readBoolean();
train = new Train(trainId, owner, null, carriages, carriageSpacing, doubleEnded);
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeBoolean(add);
buffer.writeUUID(train.id);
if (!add)
return;
buffer.writeUUID(train.owner);
buffer.writeVarInt(train.carriages.size());
for (Carriage carriage : train.carriages) {
for (boolean first : Iterate.trueAndFalse) {
if (!first) {
boolean onTwoBogeys = carriage.isOnTwoBogeys();
buffer.writeBoolean(onTwoBogeys);
if (!onTwoBogeys)
continue;
}
CarriageBogey bogey = carriage.bogeys.get(first);
buffer.writeResourceLocation(((Block) bogey.type).getRegistryName());
}
buffer.writeVarInt(carriage.bogeySpacing);
}
buffer.writeVarInt(train.carriageSpacing.size());
train.carriageSpacing.forEach(buffer::writeVarInt);
buffer.writeBoolean(train.doubleEnded);
}
@Override
public void handle(Supplier<Context> context) {
context.get()
.enqueueWork(() -> {
Map<UUID, Train> trains = CreateClient.RAILWAYS.trains;
if (add)
trains.put(train.id, train);
else
trains.remove(trainId);
});
context.get()
.setPacketHandled(true);
}
}

View file

@ -13,6 +13,7 @@ import org.apache.commons.lang3.mutable.MutableBoolean;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandlerClient; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionHandlerClient;
import com.simibubi.create.content.logistics.trains.GraphLocation;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
@ -21,7 +22,6 @@ import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ISignalBoundaryListener;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.ITrackSelector;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint.SteerDirection;
import com.simibubi.create.content.logistics.trains.management.GraphLocation;
import com.simibubi.create.foundation.item.TooltipHelper; import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -35,6 +35,7 @@ import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
@ -72,7 +73,7 @@ public class TrainRelocator {
return; return;
if (mc.level == null) if (mc.level == null)
return; return;
Train relocating = getRelocating(); Train relocating = getRelocating(mc.level);
if (relocating != null) { if (relocating != null) {
Boolean relocate = relocateClient(relocating, false); // TODO send packet Boolean relocate = relocateClient(relocating, false); // TODO send packet
if (relocate != null && relocate.booleanValue()) { if (relocate != null && relocate.booleanValue()) {
@ -134,7 +135,7 @@ public class TrainRelocator {
tp -> recordedLocations.add(Pair.of(Couple.create(tp.node1, tp.node2), tp.position)); tp -> recordedLocations.add(Pair.of(Couple.create(tp.node1, tp.node2), tp.position));
ITrackSelector steer = probe.steer(SteerDirection.NONE, track.getUpNormal(level, pos, blockState)); ITrackSelector steer = probe.steer(SteerDirection.NONE, track.getUpNormal(level, pos, blockState));
MutableBoolean blocked = new MutableBoolean(false); MutableBoolean blocked = new MutableBoolean(false);
train.forEachTravellingPointBackwards((tp, d) -> { train.forEachTravellingPointBackwards((tp, d) -> {
if (blocked.booleanValue()) if (blocked.booleanValue())
return; return;
@ -145,10 +146,10 @@ public class TrainRelocator {
} }
recorder.accept(probe); recorder.accept(probe);
}); });
if (blocked.booleanValue()) if (blocked.booleanValue())
return false; return false;
if (simulate) if (simulate)
return true; return true;
@ -158,10 +159,10 @@ public class TrainRelocator {
train.occupiedSignalBlocks.clear(); train.occupiedSignalBlocks.clear();
train.graph = graph; train.graph = graph;
train.speed = 0; train.speed = 0;
if (train.navigation.destination != null) if (train.navigation.destination != null)
train.navigation.cancelNavigation(); train.navigation.cancelNavigation();
train.forEachTravellingPoint(tp -> { train.forEachTravellingPoint(tp -> {
Pair<Couple<TrackNode>, Double> last = recordedLocations.remove(recordedLocations.size() - 1); Pair<Couple<TrackNode>, Double> last = recordedLocations.remove(recordedLocations.size() - 1);
tp.node1 = last.getFirst() tp.node1 = last.getFirst()
@ -190,7 +191,7 @@ public class TrainRelocator {
return; return;
if (relocatingTrain != null) { if (relocatingTrain != null) {
Train relocating = getRelocating(); Train relocating = getRelocating(mc.level);
if (relocating == null) { if (relocating == null) {
relocatingTrain = null; relocatingTrain = null;
return; return;
@ -270,10 +271,8 @@ public class TrainRelocator {
return false; return false;
} }
private static Train getRelocating() { private static Train getRelocating(LevelAccessor level) {
if (relocatingTrain == null) return relocatingTrain == null ? null : Create.RAILWAYS.sided(level).trains.get(relocatingTrain);
return null;
return Create.RAILWAYS.trains.get(relocatingTrain); // TODO: thread breach
} }
private static Train getTrainFromEntity(CarriageContraptionEntity carriageContraptionEntity) { private static Train getTrainFromEntity(CarriageContraptionEntity carriageContraptionEntity) {

View file

@ -9,15 +9,18 @@ import java.util.UUID;
import java.util.Vector; import java.util.Vector;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.Consumer;
import javax.annotation.Nullable;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.GraphLocation;
import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.GraphLocation; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
@ -68,6 +71,10 @@ public class TravellingPoint {
} }
public ITrackSelector follow(TravellingPoint other) { public ITrackSelector follow(TravellingPoint other) {
return follow(other, null);
}
public ITrackSelector follow(TravellingPoint other, @Nullable Consumer<Boolean> success) {
return (graph, pair) -> { return (graph, pair) -> {
List<Entry<TrackNode, TrackEdge>> validTargets = pair.getSecond(); List<Entry<TrackNode, TrackEdge>> validTargets = pair.getSecond();
boolean forward = pair.getFirst(); boolean forward = pair.getFirst();
@ -75,8 +82,11 @@ public class TravellingPoint {
TrackNode secondary = forward ? other.node2 : other.node1; TrackNode secondary = forward ? other.node2 : other.node1;
for (Entry<TrackNode, TrackEdge> entry : validTargets) for (Entry<TrackNode, TrackEdge> entry : validTargets)
if (entry.getKey() == target || entry.getKey() == secondary) if (entry.getKey() == target || entry.getKey() == secondary) {
if (success != null)
success.accept(true);
return entry; return entry;
}
Vector<List<Entry<TrackNode, TrackEdge>>> frontiers = new Vector<>(validTargets.size()); Vector<List<Entry<TrackNode, TrackEdge>>> frontiers = new Vector<>(validTargets.size());
Vector<Set<TrackEdge>> visiteds = new Vector<>(validTargets.size()); Vector<Set<TrackEdge>> visiteds = new Vector<>(validTargets.size());
@ -107,15 +117,19 @@ public class TravellingPoint {
continue; continue;
TrackNode nextNode = nextEntry.getKey(); TrackNode nextNode = nextEntry.getKey();
if (nextNode == target) if (nextNode == target) {
if (success != null)
success.accept(true);
return entry; return entry;
}
frontier.add(nextEntry); frontier.add(nextEntry);
} }
} }
} }
Create.LOGGER.warn("Couldn't find follow target, choosing first"); if (success != null)
success.accept(false);
return validTargets.get(0); return validTargets.get(0);
}; };
} }

View file

@ -1,13 +0,0 @@
package com.simibubi.create.content.logistics.trains.management;
import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.foundation.utility.Couple;
public class GraphLocation {
public TrackGraph graph;
public Couple<TrackNodeLocation> edge;
public double position;
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -9,7 +9,7 @@ import javax.annotation.Nullable;
import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;

View file

@ -5,7 +5,7 @@ import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;

View file

@ -8,7 +8,7 @@ import java.util.UUID;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;

View file

@ -5,9 +5,9 @@ import java.util.Map;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint;
import java.util.UUID; import java.util.UUID;
@ -6,15 +6,14 @@ import javax.annotation.Nullable;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.GraphLocation;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.TrackEdge; import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackGraphHelper; import com.simibubi.create.content.logistics.trains.TrackGraphHelper;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SingleTileEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.EdgeData; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.TrackEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.SingleTileEdgePoint;
import com.simibubi.create.content.logistics.trains.management.signal.TrackEdgePoint;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
@ -98,9 +97,10 @@ public class TrackTargetingBehaviour<T extends TrackEdgePoint> extends TileEntit
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T createEdgePoint() { public T createEdgePoint() {
boolean isClientSide = getWorld().isClientSide; Level level = getWorld();
boolean isClientSide = level.isClientSide;
if (migrationData == null || isClientSide) if (migrationData == null || isClientSide)
for (TrackGraph trackGraph : Create.RAILWAYS.trackNetworks.values()) { // TODO thread breach for (TrackGraph trackGraph : Create.RAILWAYS.sided(level).trackNetworks.values()) {
T point = trackGraph.getPoint(edgePointType, id); T point = trackGraph.getPoint(edgePointType, id);
if (point == null) if (point == null)
continue; continue;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.Random; import java.util.Random;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -9,8 +9,8 @@ import com.google.common.base.Objects;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.OverlayState; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity.OverlayState;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.SignalState; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity.SignalState;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -17,6 +17,7 @@ import com.simibubi.create.content.logistics.trains.TrackGraphSync;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgeData;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -157,6 +158,8 @@ public class SignalPropagator {
// other/own boundary found // other/own boundary found
SignalBoundary nextBoundary = SignalBoundary nextBoundary =
signalData.next(EdgePointType.SIGNAL, currentNode, nextNode, currentEdge, 0); signalData.next(EdgePointType.SIGNAL, currentNode, nextNode, currentEdge, 0);
if (nextBoundary == null)
continue;
if (boundaryCallback.test(Pair.of(currentNode, nextBoundary))) { if (boundaryCallback.test(Pair.of(currentNode, nextBoundary))) {
notifyTrains(graph, edge, oppositeEdge); notifyTrains(graph, edge, oppositeEdge);
Create.RAILWAYS.sync.edgeDataChanged(graph, currentNode, nextNode, edge, oppositeEdge); Create.RAILWAYS.sync.edgeDataChanged(graph, currentNode, nextNode, edge, oppositeEdge);

View file

@ -1,12 +1,12 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.OverlayState; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity.OverlayState;
import com.simibubi.create.content.logistics.trains.management.signal.SignalTileEntity.SignalState; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalTileEntity.SignalState;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;
import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.AnimationTickHolder;

View file

@ -1,11 +1,11 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.List; import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.signal; package com.simibubi.create.content.logistics.trains.management.edgePoint.signal;
import java.util.UUID; import java.util.UUID;
@ -7,8 +7,8 @@ import com.simibubi.create.content.logistics.trains.TrackEdge;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;

View file

@ -1,10 +1,11 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
import com.jozufozu.flywheel.util.transform.TransformStack; import com.jozufozu.flywheel.util.transform.TransformStack;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.entity.Carriage; import com.simibubi.create.content.logistics.trains.entity.Carriage;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.entity.TrainIconType; import com.simibubi.create.content.logistics.trains.entity.TrainIconType;
@ -87,4 +88,12 @@ public abstract class AbstractStationScreen extends AbstractSimiScreen {
ms.popPose(); ms.popPose();
} }
protected Train getImminent() {
return te.imminentTrain == null ? null : CreateClient.RAILWAYS.trains.get(te.imminentTrain);
}
protected boolean trainPresent() {
return te.trainPresent;
}
} }

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
@ -105,7 +105,7 @@ public class AssemblyScreen extends AbstractStationScreen {
private void tickTrainDisplay() { private void tickTrainDisplay() {
Train train = displayedTrain.get(); Train train = displayedTrain.get();
Train imminentTrain = station.getPresentTrain(); Train imminentTrain = getImminent();
if (train == null) { if (train == null) {
if (imminentTrain != null) { if (imminentTrain != null) {

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
@ -6,7 +6,7 @@ import javax.annotation.Nullable;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.signal.SingleTileEdgePoint; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SingleTileEdgePoint;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.util.List; import java.util.List;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import com.simibubi.create.AllItems; import com.simibubi.create.AllItems;
import com.simibubi.create.AllShapes; import com.simibubi.create.AllShapes;
@ -62,10 +62,8 @@ public class StationBlock extends HorizontalDirectionalBlock implements ITE<Stat
ItemStack itemInHand = pPlayer.getItemInHand(pHand); ItemStack itemInHand = pPlayer.getItemInHand(pHand);
if (AllItems.WRENCH.isIn(itemInHand)) if (AllItems.WRENCH.isIn(itemInHand))
return InteractionResult.PASS; return InteractionResult.PASS;
if (itemInHand.getItem() == Items.SPONGE) { if (itemInHand.getItem() == Items.SPONGE)
Create.RAILWAYS.trains.clear(); Create.RAILWAYS.trains.clear();
Create.RAILWAYS.carriageById.clear();
}
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
() -> () -> withTileEntityDo(pLevel, pPos, te -> this.displayScreen(te, pPlayer))); () -> () -> withTileEntityDo(pLevel, pPos, te -> this.displayScreen(te, pPlayer)));
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;

View file

@ -1,6 +1,7 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import com.simibubi.create.Create; 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.content.logistics.trains.entity.Train;
import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket; import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket;

View file

@ -1,10 +1,11 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import com.jozufozu.flywheel.core.PartialModel; import com.jozufozu.flywheel.core.PartialModel;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer; import com.mojang.blaze3d.vertex.VertexConsumer;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.foundation.render.CachedBufferer; import com.simibubi.create.foundation.render.CachedBufferer;
import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.List; import java.util.List;
@ -125,7 +125,7 @@ public class StationScreen extends AbstractStationScreen {
leavingAnimation = 0; leavingAnimation = 0;
newTrainButton.active = true; newTrainButton.active = true;
newTrainButton.visible = true; newTrainButton.visible = true;
Train imminentTrain = station.getImminentTrain(); Train imminentTrain = getImminent();
if (imminentTrain != null) { if (imminentTrain != null) {
displayedTrain = new WeakReference<>(imminentTrain); displayedTrain = new WeakReference<>(imminentTrain);
@ -144,7 +144,7 @@ public class StationScreen extends AbstractStationScreen {
int trainIconWidth = getTrainIconWidth(imminentTrain); int trainIconWidth = getTrainIconWidth(imminentTrain);
int targetPos = background.width / 2 - trainIconWidth / 2; int targetPos = background.width / 2 - trainIconWidth / 2;
float f = (float) (imminentTrain.navigation.distanceToDestination / 15f); float f = (float) (imminentTrain.navigation.distanceToDestination / 15f);
if (imminentTrain.currentStation.equals(station.getId())) if (trainPresent())
f = 0; f = 0;
trainPosition.startWithValue(targetPos - (targetPos + 5) * f); trainPosition.startWithValue(targetPos - (targetPos + 5) * f);
} }
@ -169,14 +169,14 @@ public class StationScreen extends AbstractStationScreen {
return; return;
} }
boolean trainAtStation = train.currentStation != null && train.currentStation.equals(station.getId()); if (getImminent() != train) {
if (train.navigation.destination != station && !trainAtStation) {
leavingAnimation = 80; leavingAnimation = 80;
return; return;
} }
boolean trainAtStation = trainPresent();
disassembleTrainButton.active = trainAtStation; // TODO te.canAssemble disassembleTrainButton.active = trainAtStation; // TODO te.canAssemble
openScheduleButton.active = train.runtime.schedule != null; openScheduleButton.active = train.runtime.getSchedule() != null;
float f = trainAtStation ? 0 : (float) (train.navigation.distanceToDestination / 30f); float f = trainAtStation ? 0 : (float) (train.navigation.distanceToDestination / 30f);
trainPosition.setValue(targetPos - (targetPos + trainIconWidth) * f); trainPosition.setValue(targetPos - (targetPos + trainIconWidth) * f);

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -20,11 +21,14 @@ import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.TrackNode; import com.simibubi.create.content.logistics.trains.TrackNode;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.entity.Carriage; import com.simibubi.create.content.logistics.trains.entity.Carriage;
import com.simibubi.create.content.logistics.trains.entity.Carriage.CarriageBogey; import com.simibubi.create.content.logistics.trains.entity.CarriageBogey;
import com.simibubi.create.content.logistics.trains.entity.CarriageContraption; import com.simibubi.create.content.logistics.trains.entity.CarriageContraption;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.entity.TrainPacket;
import com.simibubi.create.content.logistics.trains.entity.TravellingPoint; import com.simibubi.create.content.logistics.trains.entity.TravellingPoint;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
@ -46,6 +50,7 @@ import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.network.PacketDistributor;
public class StationTileEntity extends SmartTileEntity { public class StationTileEntity extends SmartTileEntity {
@ -54,6 +59,10 @@ public class StationTileEntity extends SmartTileEntity {
protected int failedCarriageIndex; protected int failedCarriageIndex;
protected AssemblyException lastException; protected AssemblyException lastException;
// for display
UUID imminentTrain;
boolean trainPresent;
public StationTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) { public StationTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
super(type, pos, state); super(type, pos, state);
setLazyTickRate(20); setLazyTickRate(20);
@ -73,6 +82,17 @@ public class StationTileEntity extends SmartTileEntity {
failedCarriageIndex = tag.getInt("FailedCarriageIndex"); failedCarriageIndex = tag.getInt("FailedCarriageIndex");
super.read(tag, clientPacket); super.read(tag, clientPacket);
invalidateRenderBoundingBox(); invalidateRenderBoundingBox();
if (!clientPacket)
return;
if (!tag.contains("ImminentTrain")) {
imminentTrain = null;
trainPresent = false;
return;
}
imminentTrain = tag.getUUID("ImminentTrain");
trainPresent = tag.getBoolean("TrainPresent");
} }
@Override @Override
@ -80,8 +100,20 @@ public class StationTileEntity extends SmartTileEntity {
AssemblyException.write(tag, lastException); AssemblyException.write(tag, lastException);
tag.putInt("FailedCarriageIndex", failedCarriageIndex); tag.putInt("FailedCarriageIndex", failedCarriageIndex);
super.write(tag, clientPacket); super.write(tag, clientPacket);
if (!clientPacket)
return;
GlobalStation station = getStation();
if (station == null)
return;
Train imminentTrain = station.getImminentTrain();
if (imminentTrain == null)
return;
tag.putUUID("ImminentTrain", imminentTrain.id);
tag.putBoolean("TrainPresent", imminentTrain.getCurrentStation() == station);
} }
@Nullable @Nullable
public GlobalStation getStation() { public GlobalStation getStation() {
return edgePoint.getEdgePoint(); return edgePoint.getEdgePoint();
@ -109,6 +141,23 @@ public class StationTileEntity extends SmartTileEntity {
if (isAssembling() && level.isClientSide) if (isAssembling() && level.isClientSide)
refreshAssemblyInfo(); refreshAssemblyInfo();
super.tick(); super.tick();
if (level.isClientSide)
return;
GlobalStation station = getStation();
if (station == null)
return;
Train imminentTrain = station.getImminentTrain();
boolean trainPresent = imminentTrain != null && imminentTrain.getCurrentStation() == station;
UUID imminentID = imminentTrain != null ? imminentTrain.id : null;
if (this.trainPresent != trainPresent || !Objects.equals(imminentID, this.imminentTrain)) {
this.imminentTrain = imminentID;
this.trainPresent = trainPresent;
sendData();
}
} }
public void trackClicked(Player player, ITrackBlock track, BlockState state, BlockPos pos) { public void trackClicked(Player player, ITrackBlock track, BlockState state, BlockPos pos) {
@ -192,7 +241,7 @@ public class StationTileEntity extends SmartTileEntity {
} }
BlockState potentialBogeyState = level.getBlockState(bogeyOffset.offset(currentPos)); BlockState potentialBogeyState = level.getBlockState(bogeyOffset.offset(currentPos));
if (potentialBogeyState.getBlock() instanceof IBogeyBlock bogey && bogeyIndex < bogeyLocations.length) { if (potentialBogeyState.getBlock()instanceof IBogeyBlock bogey && bogeyIndex < bogeyLocations.length) {
bogeyTypes[bogeyIndex] = bogey; bogeyTypes[bogeyIndex] = bogey;
bogeyLocations[bogeyIndex] = i; bogeyLocations[bogeyIndex] = i;
bogeyIndex++; bogeyIndex++;
@ -412,9 +461,7 @@ public class StationTileEntity extends SmartTileEntity {
} }
contraptions.add(contraption); contraptions.add(contraption);
Carriage carriage = new Carriage(firstBogey, secondBogey, bogeySpacing); carriages.add(new Carriage(firstBogey, secondBogey, bogeySpacing));
carriage.setContraption(contraption);
carriages.add(carriage);
} }
if (!atLeastOneForwardControls) { if (!atLeastOneForwardControls) {
@ -427,15 +474,22 @@ public class StationTileEntity extends SmartTileEntity {
contraption.expandBoundsAroundAxis(Axis.Y); contraption.expandBoundsAroundAxis(Axis.Y);
} }
Train train = new Train(UUID.randomUUID(), playerUUID, graph, carriages, spacing); Train train = new Train(UUID.randomUUID(), playerUUID, graph, carriages, spacing, contraptions.stream()
.anyMatch(CarriageContraption::hasBackwardControls));
for (int i = 0; i < contraptions.size(); i++)
carriages.get(i)
.setContraption(level, contraptions.get(i));
GlobalStation station = getStation(); GlobalStation station = getStation();
if (station != null) { if (station != null) {
train.setCurrentStation(station); train.setCurrentStation(station);
station.reserveFor(train); station.reserveFor(train);
} }
train.collectInitiallyOccupiedSignalBlocks(); train.collectInitiallyOccupiedSignalBlocks();
Create.RAILWAYS.trains.put(train.id, train); Create.RAILWAYS.trains.put(train.id, train);
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new TrainPacket(train, true));
clearException(); clearException();
} }

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import java.util.UUID; import java.util.UUID;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -6,12 +6,16 @@ import java.util.function.Supplier;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.entity.TrainIconType; import com.simibubi.create.content.logistics.trains.entity.TrainIconType;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.SimplePacketBase; import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.network.FriendlyByteBuf; import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.network.chat.TextComponent; import net.minecraft.network.chat.TextComponent;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkEvent.Context; import net.minecraftforge.network.NetworkEvent.Context;
import net.minecraftforge.network.PacketDistributor;
public class TrainEditPacket extends SimplePacketBase { public class TrainEditPacket extends SimplePacketBase {
@ -44,18 +48,34 @@ public class TrainEditPacket extends SimplePacketBase {
@Override @Override
public void handle(Supplier<Context> context) { public void handle(Supplier<Context> context) {
context.get() Context ctx = context.get();
.enqueueWork(() -> { ctx.enqueueWork(() -> {
Train train = Create.RAILWAYS.trains.get(id); ServerPlayer sender = ctx.getSender();
if (train == null) Level level = sender == null ? null : sender.level;
return; Train train = Create.RAILWAYS.sided(level).trains.get(id);
if (!name.isBlank()) if (train == null)
train.name = new TextComponent(name); return;
train.icon = TrainIconType.byId(iconType); if (!name.isBlank())
train.heldForAssembly = heldForAssembly; train.name = new TextComponent(name);
}); train.icon = TrainIconType.byId(iconType);
context.get() train.heldForAssembly = heldForAssembly;
.setPacketHandled(true); if (sender != null)
AllPackets.channel.send(PacketDistributor.ALL.noArg(),
new TrainEditReturnPacket(id, name, heldForAssembly, iconType));
});
ctx.setPacketHandled(true);
}
public static class TrainEditReturnPacket extends TrainEditPacket {
public TrainEditReturnPacket(FriendlyByteBuf buffer) {
super(buffer);
}
public TrainEditReturnPacket(UUID id, String name, boolean heldForAssembly, ResourceLocation iconType) {
super(id, name, heldForAssembly, iconType);
}
} }
} }

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;

View file

@ -7,7 +7,6 @@ import javax.annotation.Nullable;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.client.gui.components.events.GuiEventListener; import net.minecraft.client.gui.components.events.GuiEventListener;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.schedule;
public class RunningScheduleScreen { public class RunningScheduleScreen {

View file

@ -5,6 +5,18 @@ import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.FluidThresholdCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.IdleCargoCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.ItemThresholdCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduledDelay;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.StationPoweredCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.StationUnloadedCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.TimeOfDayCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.destination.FilteredDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.destination.NearestDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.destination.RedstoneDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleDestination;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.schedule;
import com.simibubi.create.foundation.gui.container.GhostItemContainer; import com.simibubi.create.foundation.gui.container.GhostItemContainer;

View file

@ -3,6 +3,8 @@ package com.simibubi.create.content.logistics.trains.management.schedule;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleDestination;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.schedule;
import com.simibubi.create.AllContainerTypes; import com.simibubi.create.AllContainerTypes;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
@ -6,7 +6,6 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Con
import com.simibubi.create.content.logistics.trains.entity.CarriageContraption; import com.simibubi.create.content.logistics.trains.entity.CarriageContraption;
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule;
import com.simibubi.create.foundation.utility.Couple; import com.simibubi.create.foundation.utility.Couple;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
@ -79,7 +78,7 @@ public class ScheduleItem extends Item implements MenuProvider {
Contraption contraption = entity.getContraption(); Contraption contraption = entity.getContraption();
if (contraption instanceof CarriageContraption cc) { if (contraption instanceof CarriageContraption cc) {
Train train = cc.getCarriage().train; Train train = entity.getCarriage().train;
if (train == null) if (train == null)
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
if (train.heldForAssembly) { if (train.heldForAssembly) {

View file

@ -1,15 +1,14 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.schedule;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.schedule.FilteredDestination; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule; import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleDestination; import com.simibubi.create.content.logistics.trains.management.schedule.destination.FilteredDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEntry; import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleWaitCondition;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management; package com.simibubi.create.content.logistics.trains.management.schedule;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -16,15 +16,11 @@ import com.mojang.blaze3d.platform.InputConstants;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f; import com.mojang.math.Matrix4f;
import com.simibubi.create.content.logistics.trains.management.schedule.FilteredDestination; import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduleWaitCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput; import com.simibubi.create.content.logistics.trains.management.schedule.condition.ScheduledDelay;
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule; import com.simibubi.create.content.logistics.trains.management.schedule.condition.TimedWaitCondition.TimeUnit;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleDestination; import com.simibubi.create.content.logistics.trains.management.schedule.destination.FilteredDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket; import com.simibubi.create.content.logistics.trains.management.schedule.destination.ScheduleDestination;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEntry;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleWaitCondition;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduledDelay;
import com.simibubi.create.content.logistics.trains.management.schedule.TimedWaitCondition.TimeUnit;
import com.simibubi.create.foundation.gui.AllGuiTextures; import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.UIRenderHelper; import com.simibubi.create.foundation.gui.UIRenderHelper;

View file

@ -1,11 +1,12 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.Label;
import com.simibubi.create.foundation.gui.widget.ScrollInput; import com.simibubi.create.foundation.gui.widget.ScrollInput;
import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import com.simibubi.create.foundation.gui.widget.SelectionScrollInput;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -7,7 +7,8 @@ import com.google.common.collect.ImmutableList;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.contraptions.processing.EmptyingByBasin; import com.simibubi.create.content.contraptions.processing.EmptyingByBasin;
import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.content.logistics.item.filter.FilterItem;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.Label;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -6,7 +6,8 @@ import java.util.function.BiConsumer;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.item.filter.FilterItem; import com.simibubi.create.content.logistics.item.filter.FilterItem;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.Label;
import com.simibubi.create.foundation.gui.widget.ScrollInput; import com.simibubi.create.foundation.gui.widget.ScrollInput;
import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import com.simibubi.create.foundation.gui.widget.SelectionScrollInput;

View file

@ -1,9 +1,11 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;

View file

@ -1,8 +1,8 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;

View file

@ -1,8 +1,8 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -8,7 +8,8 @@ import com.mojang.blaze3d.systems.RenderSystem;
import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.Label;
import com.simibubi.create.foundation.gui.widget.ScrollInput; import com.simibubi.create.foundation.gui.widget.ScrollInput;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;

View file

@ -1,10 +1,11 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.condition;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.foundation.gui.widget.Label; import com.simibubi.create.foundation.gui.widget.Label;
import com.simibubi.create.foundation.gui.widget.ScrollInput; import com.simibubi.create.foundation.gui.widget.ScrollInput;
import com.simibubi.create.foundation.gui.widget.SelectionScrollInput; import com.simibubi.create.foundation.gui.widget.SelectionScrollInput;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.destination;
import java.util.List; import java.util.List;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -8,7 +8,8 @@ import org.apache.commons.lang3.StringUtils;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.ScheduleScreen; import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleScreen;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.destination;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.destination;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.Create; import com.simibubi.create.Create;

View file

@ -1,8 +1,10 @@
package com.simibubi.create.content.logistics.trains.management.schedule; package com.simibubi.create.content.logistics.trains.management.schedule.destination;
import java.util.function.Supplier; import java.util.function.Supplier;
import com.simibubi.create.Create; import com.simibubi.create.Create;
import com.simibubi.create.content.logistics.trains.management.schedule.IScheduleInput;
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;

View file

@ -23,8 +23,8 @@ import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation;
import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation; import com.simibubi.create.content.logistics.trains.TrackNodeLocation.DiscoveredLocation;
import com.simibubi.create.content.logistics.trains.TrackPropagator; import com.simibubi.create.content.logistics.trains.TrackPropagator;
import com.simibubi.create.content.logistics.trains.management.StationTileEntity; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBehaviour.RenderedTrackOverlayType;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBehaviour.RenderedTrackOverlayType; import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationTileEntity;
import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;

View file

@ -35,7 +35,7 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionP
import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler; import com.simibubi.create.content.logistics.item.LinkedControllerClientHandler;
import com.simibubi.create.content.logistics.trains.entity.CarriageCouplingRenderer; import com.simibubi.create.content.logistics.trains.entity.CarriageCouplingRenderer;
import com.simibubi.create.content.logistics.trains.entity.TrainRelocator; import com.simibubi.create.content.logistics.trains.entity.TrainRelocator;
import com.simibubi.create.content.logistics.trains.management.TrackTargetingBlockItem; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem;
import com.simibubi.create.content.logistics.trains.track.TrackPlacement; import com.simibubi.create.content.logistics.trains.track.TrackPlacement;
import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.config.ui.BaseConfigScreen; import com.simibubi.create.foundation.config.ui.BaseConfigScreen;

View file

@ -10,11 +10,11 @@ import com.simibubi.create.CreateClient;
import com.simibubi.create.content.logistics.trains.GlobalRailwayManager; import com.simibubi.create.content.logistics.trains.GlobalRailwayManager;
import com.simibubi.create.content.logistics.trains.TrackGraph; import com.simibubi.create.content.logistics.trains.TrackGraph;
import com.simibubi.create.content.logistics.trains.entity.Train; import com.simibubi.create.content.logistics.trains.entity.Train;
import com.simibubi.create.content.logistics.trains.management.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime;
import com.simibubi.create.content.logistics.trains.management.ScheduleRuntime.State;
import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType; import com.simibubi.create.content.logistics.trains.management.edgePoint.EdgePointType;
import com.simibubi.create.content.logistics.trains.management.signal.SignalBoundary; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalBoundary;
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.GlobalStation;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleRuntime;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleRuntime.State;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.commands.CommandSourceStack; import net.minecraft.commands.CommandSourceStack;

View file

@ -44,10 +44,12 @@ import com.simibubi.create.content.logistics.packet.ConfigureStockswitchPacket;
import com.simibubi.create.content.logistics.packet.FunnelFlapPacket; import com.simibubi.create.content.logistics.packet.FunnelFlapPacket;
import com.simibubi.create.content.logistics.packet.TunnelFlapPacket; import com.simibubi.create.content.logistics.packet.TunnelFlapPacket;
import com.simibubi.create.content.logistics.trains.TrackGraphSyncPacket; import com.simibubi.create.content.logistics.trains.TrackGraphSyncPacket;
import com.simibubi.create.content.logistics.trains.management.StationEditPacket; import com.simibubi.create.content.logistics.trains.entity.TrainPacket;
import com.simibubi.create.content.logistics.trains.management.TrainEditPacket; import com.simibubi.create.content.logistics.trains.management.edgePoint.signal.SignalEdgeGroupPacket;
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.StationEditPacket;
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.TrainEditPacket;
import com.simibubi.create.content.logistics.trains.management.edgePoint.station.TrainEditPacket.TrainEditReturnPacket;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket;
import com.simibubi.create.content.logistics.trains.management.signal.SignalEdgeGroupPacket;
import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket;
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
import com.simibubi.create.content.schematics.packet.SchematicPlacePacket; import com.simibubi.create.content.schematics.packet.SchematicPlacePacket;
@ -110,7 +112,7 @@ public enum AllPackets {
TOOLBOX_DISPOSE_ALL(ToolboxDisposeAllPacket.class, ToolboxDisposeAllPacket::new, PLAY_TO_SERVER), TOOLBOX_DISPOSE_ALL(ToolboxDisposeAllPacket.class, ToolboxDisposeAllPacket::new, PLAY_TO_SERVER),
CONFIGURE_SCHEDULE(ScheduleEditPacket.class, ScheduleEditPacket::new, PLAY_TO_SERVER), CONFIGURE_SCHEDULE(ScheduleEditPacket.class, ScheduleEditPacket::new, PLAY_TO_SERVER),
CONFIGURE_STATION(StationEditPacket.class, StationEditPacket::new, PLAY_TO_SERVER), CONFIGURE_STATION(StationEditPacket.class, StationEditPacket::new, PLAY_TO_SERVER),
CONFIGURE_TRAIN(TrainEditPacket.class, TrainEditPacket::new, PLAY_TO_SERVER), C_CONFIGURE_TRAIN(TrainEditPacket.class, TrainEditPacket::new, PLAY_TO_SERVER),
// Server to Client // Server to Client
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),
@ -135,7 +137,9 @@ public enum AllPackets {
SYNC_POTATO_PROJECTILE_TYPES(PotatoProjectileTypeManager.SyncPacket.class, PotatoProjectileTypeManager.SyncPacket::new, PLAY_TO_CLIENT), SYNC_POTATO_PROJECTILE_TYPES(PotatoProjectileTypeManager.SyncPacket.class, PotatoProjectileTypeManager.SyncPacket::new, PLAY_TO_CLIENT),
SYNC_RAIL_GRAPH(TrackGraphSyncPacket.class, TrackGraphSyncPacket::new, PLAY_TO_CLIENT), SYNC_RAIL_GRAPH(TrackGraphSyncPacket.class, TrackGraphSyncPacket::new, PLAY_TO_CLIENT),
SYNC_EDGE_GROUP(SignalEdgeGroupPacket.class, SignalEdgeGroupPacket::new, PLAY_TO_CLIENT), SYNC_EDGE_GROUP(SignalEdgeGroupPacket.class, SignalEdgeGroupPacket::new, PLAY_TO_CLIENT),
SYNC_TRAIN(TrainPacket.class, TrainPacket::new, PLAY_TO_CLIENT),
REMOVE_TE(RemoveTileEntityPacket.class, RemoveTileEntityPacket::new, PLAY_TO_CLIENT), REMOVE_TE(RemoveTileEntityPacket.class, RemoveTileEntityPacket::new, PLAY_TO_CLIENT),
S_CONFIGURE_TRAIN(TrainEditReturnPacket.class, TrainEditReturnPacket::new, PLAY_TO_CLIENT),
; ;