e5c6ca157c
commit 053dd09df6c426ab5e570f42a1edb5df3d0fbd01 Merge: 6d1e1c71decc645eba
Author: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue May 9 18:22:42 2023 +0200 Merge branch '1.18/api' of https://github.com/Layers-of-Railways/Create into pr/4692 commitecc645eba7
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Tue May 9 11:24:11 2023 +0100 Implemented support for creating and removing individual blockstate models commit 6d1e1c71de7ce20f6fd9fc8ed4ed9bdd1072829a Author: simibubi <31564874+simibubi@users.noreply.github.com> Date: Tue May 9 12:16:54 2023 +0200 Less error logging when migrating old worlds commit205e47352e
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 8 21:02:19 2023 -0700 Fix up ItemOutline commit6cf204f6af
Merge:fe049bc77
2e3c906ce
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 8 20:28:56 2023 -0700 Merge remote-tracking branch 'upstream/mc1.18/dev' into 1.18/api # Conflicts: # src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageCouplingRenderer.java commitfe049bc771
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 8 20:26:16 2023 -0700 Revert "Revert "Rewrite outline buffering"" This reverts commit726bfaf0
commit435b4c1c16
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 8 20:20:23 2023 -0700 Clean up last bits of upside down rendering commit662da6bab1
Merge:122fe77af
d83285e8a
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 8 20:16:32 2023 -0700 Merge remote-tracking branch 'origin/1.18/api' into 1.18/api # Conflicts: # src/main/java/com/simibubi/create/content/logistics/trains/StandardBogeyRenderer.java commit122fe77afa
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 8 20:15:46 2023 -0700 Fix up upside down rendering commitd83285e8a4
Merge:00e953a58
cdb0ad210
Author: techno-sam <77073745+techno-sam@users.noreply.github.com> Date: Sun May 7 07:02:18 2023 -0700 Merge pull request #3 from Layers-of-Railways/1.18/bogey-api Cleanup cycle groups and unused imports commitcdb0ad210b
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun May 7 10:15:47 2023 +0100 Fixed merge artifact commit457d5f33ed
Merge:4e4e227a3
00e953a58
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun May 7 10:14:07 2023 +0100 Merge remote-tracking branch 'origin/1.18/api' into 1.18/api commit00e953a585
Merge:1e4d5504e
a7a25896c
Author: Rabbitminers <79579164+Rabbitminers@users.noreply.github.com> Date: Sun May 7 10:13:49 2023 +0100 Merge pull request #2 from Rabbitminers/mc1.18/dev Added Return Values and Small Cleanup commita7a25896c1
Merge:7622128be
1e4d5504e
Author: Rabbitminers <79579164+Rabbitminers@users.noreply.github.com> Date: Sun May 7 10:13:40 2023 +0100 Merge branch '1.18/api' into mc1.18/dev commit4e4e227a35
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun May 7 10:10:30 2023 +0100 Cleanup to cycle groups commitaa94fc97d1
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun May 7 09:50:50 2023 +0100 Removed unused import of Railways commit7622128bec
Merge:81eeadb85
d52065808
Author: Rabbitminers <79579164+Rabbitminers@users.noreply.github.com> Date: Sun May 7 09:11:59 2023 +0100 Merge branch 'Layers-of-Railways:mc1.18/dev' into mc1.18/dev commit1e4d5504ee
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sat May 6 18:03:39 2023 -0700 Don't revert non-buggy changes commitb306cf2124
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sat May 6 18:00:59 2023 -0700 Take materials into consideration when trains pathfind commitfca02ae4bf
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sat May 6 10:25:51 2023 -0700 Add materials to track graph commit726bfaf0b5
Author: techno-sam <linux.techno.sam@gmail.com> Date: Fri May 5 21:16:49 2023 -0700 Revert "Rewrite outline buffering" This reverts commitd4106d545b
. commit171897bed2
Author: techno-sam <linux.techno.sam@gmail.com> Date: Fri May 5 20:55:25 2023 -0700 Fix up style cycling commitcbd0cf20da
Author: techno-sam <linux.techno.sam@gmail.com> Date: Fri May 5 07:32:06 2023 -0700 clean up nether portal carriage handling commitd556f08876
Author: techno-sam <linux.techno.sam@gmail.com> Date: Fri May 5 07:06:02 2023 -0700 upside down bogeys work in nether portals fixed coupling anchor offsets commitda26c0ccbf
Author: techno-sam <linux.techno.sam@gmail.com> Date: Thu May 4 09:32:53 2023 -0700 working on upside down bogeys in nether portals commit81eeadb853
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon May 1 16:15:28 2023 +0100 Small cleanup commitc7e9df973c
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon May 1 16:13:51 2023 +0100 Fixed issue raised in #1 commit2f285b6eb7
Author: techno-sam <linux.techno.sam@gmail.com> Date: Mon May 1 08:13:27 2023 -0700 add data gen commit206de01311
Merge:e91753a33
6564f4fa7
Author: techno-sam <77073745+techno-sam@users.noreply.github.com> Date: Mon May 1 06:49:21 2023 -0700 Merge pull request #1 from Rabbitminers/mc1.18/dev Bogey API commit6564f4fa73
Merge:e5d759582
e91753a33
Author: Rabbitminers <79579164+Rabbitminers@users.noreply.github.com> Date: Mon May 1 10:40:32 2023 +0100 Merge branch '1.18/api' into mc1.18/dev commite5d7595822
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon May 1 10:09:03 2023 +0100 Connected Custom Bogey Particle Types To CarriageParticles commite91753a33c
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sun Apr 30 19:51:26 2023 -0700 Fix up some problems commit9815f1490f
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 21:12:43 2023 +0100 Implemented default data when shifting styles commitda30e78815
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 21:12:14 2023 +0100 Added Particles To Bogey Style (And Respective Builder) commit08c000b8ba
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 21:01:19 2023 +0100 Added Backup Rendering If A Size Is Not Present commit2b76e8d7b3
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 21:00:40 2023 +0100 Added Common Renderer To Remove Function commit411ec36f57
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:59:50 2023 +0100 Added Display Name To Standard Bogey Style commit112306d5d4
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:59:30 2023 +0100 Displayed new style name when changing betweeen them commit5634670b27
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:06:00 2023 +0100 General Cleanup commit0f7a8b7b24
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:05:50 2023 +0100 Implemented Changes To Remaining Classes commit8aedc00f96
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:02:06 2023 +0100 Removed Bogey Style Handling From Registrate commitedf8079abf
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:01:40 2023 +0100 Removed Unused Registry Handling commit6a185c4e72
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:01:16 2023 +0100 Refactored Bogey Sizes commite10d07ddc3
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 30 20:01:00 2023 +0100 Overhauled Bogey Style commit74d98a2ad5
Merge:e629d02f5
4ebcf8201
Author: techno-sam <77073745+techno-sam@users.noreply.github.com> Date: Sun Apr 23 07:16:33 2023 -0700 Merge branch 'Creators-of-Create:mc1.18/dev' into 1.18/api commite629d02f50
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sun Apr 9 07:18:22 2023 -0700 Track API Clean up code a bit commitd9ce6ce995
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sun Apr 9 07:14:46 2023 -0700 Track API? Fix placement commit7fbf08ba54
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sat Apr 8 11:11:24 2023 -0700 Track API? Fix up some placement issues commit35644f1434
Author: techno-sam <linux.techno.sam@gmail.com> Date: Sat Apr 8 08:11:13 2023 -0700 Track API maybe? Datagen Seems to be working commitf7c56b867a
Author: techno-sam <linux.techno.sam@gmail.com> Date: Thu Apr 6 21:24:31 2023 -0700 Track API maybe? Fix build - broken generic Not yet tested, but it is progress commit2a59fd7e8a
Author: techno-sam <linux.techno.sam@gmail.com> Date: Thu Apr 6 21:13:54 2023 -0700 Track API maybe? Not yet tested, but it is progress commit5ba30d6a85
Merge:e4e5ac1c4
c2977bbff
Author: techno-sam <77073745+techno-sam@users.noreply.github.com> Date: Thu Apr 6 17:10:39 2023 -0700 Merge branch 'Creators-of-Create:mc1.18/dev' into 1.18/api commitd52065808c
Merge:e4e5ac1c4
c2977bbff
Author: techno-sam <77073745+techno-sam@users.noreply.github.com> Date: Thu Apr 6 17:10:26 2023 -0700 Merge branch 'Creators-of-Create:mc1.18/dev' into mc1.18/dev commit53240bd42f
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 21:42:29 2023 +0100 Corrected Bogey InteractionResult To Pass commit69326e361a
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 21:30:28 2023 +0100 Fixed Default Values When Used Styles Are Removed commit4f176979de
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 19:33:17 2023 +0100 Fixed Carriage Sounds (Again) commit1e80af3303
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 19:27:58 2023 +0100 Refactored Bogey Sizes To Seperate Class commit129be61fee
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 17:20:17 2023 +0100 Fixed Bogey Sound Loading commit2543185a55
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 09:45:23 2023 +0100 Added Bogey Sound Customisation commit1ad5ae9514
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Mon Apr 3 00:44:53 2023 +0100 Added Size Transforms If Size Is Not Available For New Style commit96566b1614
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 2 23:02:02 2023 +0100 Moved Bogey Style Inside Of Bogey Data And Implemented Bogey Data Communication commiteedd984738
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 2 16:53:55 2023 +0100 Fixed Large Bogey Size commit68ca0974c6
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 2 16:47:58 2023 +0100 Implemented Style Cycling & Default Values commita55ba4267a
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 2 16:46:15 2023 +0100 Implemented renderer instance creator commit43523302c2
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sun Apr 2 16:45:33 2023 +0100 Removed Unused Standard Bogey Instance commit773e084422
Merge:0c0b5a1ed
d1e1f7ec5
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sat Apr 1 18:50:15 2023 +0100 Merge remote-tracking branch 'origin/mc1.18/dev' into mc1.18/dev # Conflicts: # src/main/java/com/simibubi/create/AllBogeyStyles.java # src/main/java/com/simibubi/create/content/logistics/trains/BogeyTileEntityRenderer.java # src/main/java/com/simibubi/create/content/logistics/trains/entity/BogeyStyle.java # src/main/java/com/simibubi/create/content/logistics/trains/entity/CarriageContraptionEntityRenderer.java # src/main/java/com/simibubi/create/content/logistics/trains/entity/StandardBogeyInstance.java # src/main/java/com/simibubi/create/foundation/data/BogeyStyleBuilder.java commit0c0b5a1ed6
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sat Apr 1 18:39:58 2023 +0100 Linked Style Registry To Bogey Blocks commit71f839ee51
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sat Apr 1 18:39:03 2023 +0100 Replaced size boolean with direct use of size enum commit50ff081704
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 30 18:47:13 2023 +0100 Added Resource Location To NBT helper methods commitd1e1f7ec5a
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 30 18:47:13 2023 +0100 Re-worked BogeyStyles commitda593fccb1
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 30 18:46:02 2023 +0100 Refactored IBogeyBlock to AbstractBogeyBlock and extracted relevant StandardBogeyBlock implementations commit17432c9113
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Sat Mar 25 10:20:50 2023 +0000 Fixed Incorrect Registry Loading commitc7d899369a
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Fri Mar 24 23:44:03 2023 +0000 Registered Registers commit6d862290d7
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Fri Mar 24 23:43:23 2023 +0000 Added BogeyStyleBuilder To Registrate commit3dfb9e3b3b
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Fri Mar 24 23:43:08 2023 +0000 Implemented AllBogeyStyles commitc9e71b462d
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Fri Mar 24 23:42:56 2023 +0000 Created BogeyStyleBuilder commita90977d642
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Fri Mar 24 23:42:25 2023 +0000 Created AllRegistries and BogeyStyle Registry commit154d455f3f
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Fri Mar 24 23:41:56 2023 +0000 Added BogeyStyle Wrapper commitdfb7640bfc
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 18:50:41 2023 +0000 Removed left over logging statement commit9920536cc3
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 18:50:18 2023 +0000 Implemented Secondary Shaft To Large Renderer commit6cd40cc6f9
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 18:49:56 2023 +0000 Prevented Overwrite When Using Two BlockStates Of The Same Type With Different Properties commit06fb901144
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 18:39:11 2023 +0000 Implemented Common Rendering For StandardBogeyRenderer commit435b0f8266
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 18:38:40 2023 +0000 Added Common Renderer commit96a0623dab
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 18:38:29 2023 +0000 Implemented BlockState Models For Rendering commit469d9d592b
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 17:42:28 2023 +0000 Added Standard Bogey Instance (Might be redundant) commit2661d260d8
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 17:42:06 2023 +0000 Refactored Changes To Existing Methods commit9ded16fbab
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 17:41:15 2023 +0000 Integrated BogeyRenderer To BogeyInstance (Also Corrected Rendering In Contraption) commit4a82fcbca1
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 17:40:13 2023 +0000 Implemented Changes To StandardBogeyBlock commit7238fb93f3
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Thu Mar 23 17:39:51 2023 +0000 Added Renderer To IBogeyBlock commitded4c1f613
Merge:91727cc84
3c02fe6ec
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Wed Mar 22 17:03:37 2023 +0000 Merge remote-tracking branch 'origin/mc1.18/dev' into mc1.18/dev commit91727cc84a
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Wed Mar 22 17:03:28 2023 +0000 Implemented Model Data Initializer to StandardBogeyRenderer commit6d98a1f469
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Wed Mar 22 17:03:00 2023 +0000 Added Contraption Model Instance Initializer commit3c02fe6ecc
Author: Rabbitminers <79579164+Rabbitminers@users.noreply.github.com> Date: Tue Mar 21 22:45:34 2023 +0000 Added missing render type check commit6672c49649
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Tue Mar 21 22:37:36 2023 +0000 Re-created standard bogey with test api commita8a9491fa0
Author: Rabbitminers <Rabbitminers2.0@gmail.com> Date: Tue Mar 21 22:34:54 2023 +0000 Implemented Proof Of Concept Generic Bogey Renderer commite4e5ac1c40
Author: SpottyTheTurtle <69260662+SpottyTheTurtle@users.noreply.github.com> Date: Sat Mar 11 21:34:59 2023 +0000 init
812 lines
28 KiB
Java
812 lines
28 KiB
Java
package com.simibubi.create.content.logistics.trains.management.edgePoint.station;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.Map.Entry;
|
|
import java.util.Objects;
|
|
import java.util.UUID;
|
|
|
|
import javax.annotation.Nullable;
|
|
|
|
import com.simibubi.create.AllBlocks;
|
|
import com.simibubi.create.AllItems;
|
|
import com.simibubi.create.AllSoundEvents;
|
|
import com.simibubi.create.Create;
|
|
import com.simibubi.create.content.contraptions.components.structureMovement.AssemblyException;
|
|
import com.simibubi.create.content.contraptions.components.structureMovement.ITransformableTE;
|
|
import com.simibubi.create.content.contraptions.components.structureMovement.StructureTransform;
|
|
import com.simibubi.create.content.logistics.block.depot.DepotBehaviour;
|
|
import com.simibubi.create.content.logistics.block.display.DisplayLinkBlock;
|
|
import com.simibubi.create.content.logistics.trains.AbstractBogeyBlock;
|
|
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
|
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.content.logistics.trains.TrackNodeLocation;
|
|
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.CarriageBogey;
|
|
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.TrainPacket;
|
|
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.TrackTargetingBehaviour;
|
|
import com.simibubi.create.content.logistics.trains.management.schedule.Schedule;
|
|
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleItem;
|
|
import com.simibubi.create.content.logistics.trains.track.AbstractBogeyTileEntity;
|
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
|
import com.simibubi.create.foundation.block.ProperWaterloggedBlock;
|
|
import com.simibubi.create.foundation.config.AllConfigs;
|
|
import com.simibubi.create.foundation.networking.AllPackets;
|
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
|
import com.simibubi.create.foundation.utility.Iterate;
|
|
import com.simibubi.create.foundation.utility.Lang;
|
|
import com.simibubi.create.foundation.utility.NBTHelper;
|
|
import com.simibubi.create.foundation.utility.WorldAttached;
|
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
|
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.BlockPos.MutableBlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.Direction.Axis;
|
|
import net.minecraft.core.Direction.AxisDirection;
|
|
import net.minecraft.core.particles.ParticleTypes;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.network.chat.Component;
|
|
import net.minecraft.server.level.ServerLevel;
|
|
import net.minecraft.sounds.SoundSource;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.level.block.SoundType;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.levelgen.structure.BoundingBox;
|
|
import net.minecraft.world.phys.AABB;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
import net.minecraftforge.common.capabilities.Capability;
|
|
import net.minecraftforge.common.util.LazyOptional;
|
|
import net.minecraftforge.network.PacketDistributor;
|
|
|
|
public class StationTileEntity extends SmartTileEntity implements ITransformableTE {
|
|
|
|
public TrackTargetingBehaviour<GlobalStation> edgePoint;
|
|
public LerpedFloat flag;
|
|
|
|
protected int failedCarriageIndex;
|
|
protected AssemblyException lastException;
|
|
protected DepotBehaviour depotBehaviour;
|
|
|
|
// for display
|
|
UUID imminentTrain;
|
|
boolean trainPresent;
|
|
boolean trainBackwards;
|
|
boolean trainCanDisassemble;
|
|
boolean trainHasSchedule;
|
|
boolean trainHasAutoSchedule;
|
|
|
|
int flagYRot = -1;
|
|
boolean flagFlipped;
|
|
|
|
public Component lastDisassembledTrainName;
|
|
|
|
public StationTileEntity(BlockEntityType<?> type, BlockPos pos, BlockState state) {
|
|
super(type, pos, state);
|
|
setLazyTickRate(20);
|
|
lastException = null;
|
|
failedCarriageIndex = -1;
|
|
flag = LerpedFloat.linear()
|
|
.startWithValue(0);
|
|
}
|
|
|
|
@Override
|
|
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
|
behaviours.add(edgePoint = new TrackTargetingBehaviour<>(this, EdgePointType.STATION));
|
|
behaviours.add(depotBehaviour = new DepotBehaviour(this).onlyAccepts(AllItems.SCHEDULE::isIn)
|
|
.withCallback(s -> applyAutoSchedule()));
|
|
depotBehaviour.addSubBehaviours(behaviours);
|
|
registerAwardables(behaviours, AllAdvancements.CONTRAPTION_ACTORS, AllAdvancements.TRAIN,
|
|
AllAdvancements.LONG_TRAIN, AllAdvancements.CONDUCTOR);
|
|
}
|
|
|
|
@Override
|
|
protected void read(CompoundTag tag, boolean clientPacket) {
|
|
lastException = AssemblyException.read(tag);
|
|
failedCarriageIndex = tag.getInt("FailedCarriageIndex");
|
|
super.read(tag, clientPacket);
|
|
invalidateRenderBoundingBox();
|
|
|
|
if (tag.contains("ForceFlag"))
|
|
trainPresent = tag.getBoolean("ForceFlag");
|
|
if (tag.contains("PrevTrainName"))
|
|
lastDisassembledTrainName = Component.Serializer.fromJson(tag.getString("PrevTrainName"));
|
|
|
|
if (!clientPacket)
|
|
return;
|
|
if (!tag.contains("ImminentTrain")) {
|
|
imminentTrain = null;
|
|
trainPresent = false;
|
|
trainCanDisassemble = false;
|
|
trainBackwards = false;
|
|
return;
|
|
}
|
|
|
|
imminentTrain = tag.getUUID("ImminentTrain");
|
|
trainPresent = tag.contains("TrainPresent");
|
|
trainCanDisassemble = tag.contains("TrainCanDisassemble");
|
|
trainBackwards = tag.contains("TrainBackwards");
|
|
trainHasSchedule = tag.contains("TrainHasSchedule");
|
|
trainHasAutoSchedule = tag.contains("TrainHasAutoSchedule");
|
|
}
|
|
|
|
@Override
|
|
protected void write(CompoundTag tag, boolean clientPacket) {
|
|
AssemblyException.write(tag, lastException);
|
|
tag.putInt("FailedCarriageIndex", failedCarriageIndex);
|
|
|
|
if (lastDisassembledTrainName != null)
|
|
tag.putString("PrevTrainName", Component.Serializer.toJson(lastDisassembledTrainName));
|
|
|
|
super.write(tag, clientPacket);
|
|
|
|
if (!clientPacket)
|
|
return;
|
|
if (imminentTrain == null)
|
|
return;
|
|
|
|
tag.putUUID("ImminentTrain", imminentTrain);
|
|
|
|
if (trainPresent)
|
|
NBTHelper.putMarker(tag, "TrainPresent");
|
|
if (trainCanDisassemble)
|
|
NBTHelper.putMarker(tag, "TrainCanDisassemble");
|
|
if (trainBackwards)
|
|
NBTHelper.putMarker(tag, "TrainBackwards");
|
|
if (trainHasSchedule)
|
|
NBTHelper.putMarker(tag, "TrainHasSchedule");
|
|
if (trainHasAutoSchedule)
|
|
NBTHelper.putMarker(tag, "TrainHasAutoSchedule");
|
|
}
|
|
|
|
@Nullable
|
|
public GlobalStation getStation() {
|
|
return edgePoint.getEdgePoint();
|
|
}
|
|
|
|
// Train Assembly
|
|
|
|
public static WorldAttached<Map<BlockPos, BoundingBox>> assemblyAreas = new WorldAttached<>(w -> new HashMap<>());
|
|
|
|
Direction assemblyDirection;
|
|
int assemblyLength;
|
|
int[] bogeyLocations;
|
|
AbstractBogeyBlock<?>[] bogeyTypes;
|
|
boolean[] upsideDownBogeys;
|
|
int bogeyCount;
|
|
|
|
@Override
|
|
public void lazyTick() {
|
|
if (isAssembling() && !level.isClientSide)
|
|
refreshAssemblyInfo();
|
|
super.lazyTick();
|
|
}
|
|
|
|
@Override
|
|
public void tick() {
|
|
if (isAssembling() && level.isClientSide)
|
|
refreshAssemblyInfo();
|
|
super.tick();
|
|
|
|
if (level.isClientSide) {
|
|
float currentTarget = flag.getChaseTarget();
|
|
if (currentTarget == 0 || flag.settled()) {
|
|
int target = trainPresent || isAssembling() ? 1 : 0;
|
|
if (target != currentTarget) {
|
|
flag.chase(target, 0.1f, Chaser.LINEAR);
|
|
if (target == 1)
|
|
AllSoundEvents.CONTRAPTION_ASSEMBLE.playAt(level, worldPosition, 1, 2, true);
|
|
}
|
|
}
|
|
boolean settled = flag.getValue() > .15f;
|
|
flag.tickChaser();
|
|
if (currentTarget == 0 && settled != flag.getValue() > .15f)
|
|
AllSoundEvents.CONTRAPTION_DISASSEMBLE.playAt(level, worldPosition, 0.75f, 1.5f, true);
|
|
return;
|
|
}
|
|
|
|
GlobalStation station = getStation();
|
|
if (station == null)
|
|
return;
|
|
|
|
Train imminentTrain = station.getImminentTrain();
|
|
boolean trainPresent = imminentTrain != null && imminentTrain.getCurrentStation() == station;
|
|
boolean canDisassemble = trainPresent && imminentTrain.canDisassemble();
|
|
UUID imminentID = imminentTrain != null ? imminentTrain.id : null;
|
|
boolean trainHasSchedule = trainPresent && imminentTrain.runtime.getSchedule() != null;
|
|
boolean trainHasAutoSchedule = trainHasSchedule && imminentTrain.runtime.isAutoSchedule;
|
|
boolean newlyArrived = this.trainPresent != trainPresent;
|
|
|
|
if (trainPresent && imminentTrain.runtime.displayLinkUpdateRequested) {
|
|
DisplayLinkBlock.notifyGatherers(level, worldPosition);
|
|
imminentTrain.runtime.displayLinkUpdateRequested = false;
|
|
}
|
|
|
|
if (newlyArrived)
|
|
applyAutoSchedule();
|
|
|
|
if (newlyArrived || this.trainCanDisassemble != canDisassemble
|
|
|| !Objects.equals(imminentID, this.imminentTrain) || this.trainHasSchedule != trainHasSchedule
|
|
|| this.trainHasAutoSchedule != trainHasAutoSchedule) {
|
|
|
|
this.imminentTrain = imminentID;
|
|
this.trainPresent = trainPresent;
|
|
this.trainCanDisassemble = canDisassemble;
|
|
this.trainBackwards = imminentTrain != null && imminentTrain.currentlyBackwards;
|
|
this.trainHasSchedule = trainHasSchedule;
|
|
this.trainHasAutoSchedule = trainHasAutoSchedule;
|
|
|
|
notifyUpdate();
|
|
}
|
|
}
|
|
|
|
public boolean trackClicked(Player player, InteractionHand hand, ITrackBlock track, BlockState state,
|
|
BlockPos pos) {
|
|
refreshAssemblyInfo();
|
|
BoundingBox bb = assemblyAreas.get(level)
|
|
.get(worldPosition);
|
|
if (bb == null || !bb.isInside(pos))
|
|
return false;
|
|
|
|
BlockPos up = new BlockPos(track.getUpNormal(level, pos, state));
|
|
BlockPos down = new BlockPos(track.getUpNormal(level, pos, state).scale(-1));
|
|
int bogeyOffset = pos.distManhattan(edgePoint.getGlobalPosition()) - 1;
|
|
|
|
if (!isValidBogeyOffset(bogeyOffset)) {
|
|
for (boolean upsideDown : Iterate.falseAndTrue) {
|
|
for (int i = -1; i <= 1; i++) {
|
|
BlockPos bogeyPos = pos.relative(assemblyDirection, i)
|
|
.offset(upsideDown ? down : up);
|
|
BlockState blockState = level.getBlockState(bogeyPos);
|
|
if (!(blockState.getBlock() instanceof AbstractBogeyBlock<?> bogey))
|
|
continue;
|
|
BlockEntity be = level.getBlockEntity(bogeyPos);
|
|
if (!(be instanceof AbstractBogeyTileEntity oldTE))
|
|
continue;
|
|
CompoundTag oldData = oldTE.getBogeyData();
|
|
BlockState newBlock = bogey.getNextSize(oldTE);
|
|
if (newBlock.getBlock() == bogey)
|
|
player.displayClientMessage(Lang.translateDirect("bogey.style.no_other_sizes")
|
|
.withStyle(ChatFormatting.RED), true);
|
|
level.setBlock(bogeyPos, newBlock, 3);
|
|
BlockEntity newEntity = level.getBlockEntity(bogeyPos);
|
|
if (!(newEntity instanceof AbstractBogeyTileEntity newTE))
|
|
continue;
|
|
newTE.setBogeyData(oldData);
|
|
bogey.playRotateSound(level, bogeyPos);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
ItemStack handItem = player.getItemInHand(hand);
|
|
if (!player.isCreative() && !AllBlocks.RAILWAY_CASING.isIn(handItem)) {
|
|
player.displayClientMessage(Lang.translateDirect("train_assembly.requires_casing"), true);
|
|
return false;
|
|
}
|
|
|
|
boolean upsideDown = (player.getViewXRot(1.0F) < 0 && (track.getBogeyAnchor(level, pos, state)).getBlock() instanceof AbstractBogeyBlock<?> bogey && bogey.canBeUpsideDown());
|
|
|
|
BlockPos targetPos = upsideDown ? pos.offset(down) : pos.offset(up);
|
|
if (level.getBlockState(targetPos)
|
|
.getDestroySpeed(level, targetPos) == -1) {
|
|
return false;
|
|
}
|
|
|
|
level.destroyBlock(targetPos, true);
|
|
|
|
BlockState bogeyAnchor = track.getBogeyAnchor(level, pos, state);
|
|
if (bogeyAnchor.getBlock() instanceof AbstractBogeyBlock<?> bogey) {
|
|
bogeyAnchor = bogey.getVersion(bogeyAnchor, upsideDown);
|
|
}
|
|
bogeyAnchor = ProperWaterloggedBlock.withWater(level, bogeyAnchor, pos);
|
|
level.setBlock(targetPos, bogeyAnchor, 3);
|
|
player.displayClientMessage(Lang.translateDirect("train_assembly.bogey_created"), true);
|
|
SoundType soundtype = bogeyAnchor.getBlock()
|
|
.getSoundType(state, level, pos, player);
|
|
level.playSound(null, pos, soundtype.getPlaceSound(), SoundSource.BLOCKS, (soundtype.getVolume() + 1.0F) / 2.0F,
|
|
soundtype.getPitch() * 0.8F);
|
|
|
|
if (!player.isCreative()) {
|
|
ItemStack itemInHand = player.getItemInHand(hand);
|
|
itemInHand.shrink(1);
|
|
if (itemInHand.isEmpty())
|
|
player.setItemInHand(hand, ItemStack.EMPTY);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public boolean isAssembling() {
|
|
BlockState state = getBlockState();
|
|
return state.hasProperty(StationBlock.ASSEMBLING) && state.getValue(StationBlock.ASSEMBLING);
|
|
}
|
|
|
|
public boolean tryEnterAssemblyMode() {
|
|
if (!edgePoint.hasValidTrack())
|
|
return false;
|
|
|
|
BlockPos targetPosition = edgePoint.getGlobalPosition();
|
|
BlockState trackState = edgePoint.getTrackBlockState();
|
|
ITrackBlock track = edgePoint.getTrack();
|
|
Vec3 trackAxis = track.getTrackAxes(level, targetPosition, trackState)
|
|
.get(0);
|
|
|
|
boolean axisFound = false;
|
|
for (Axis axis : Iterate.axes) {
|
|
if (trackAxis.get(axis) == 0)
|
|
continue;
|
|
if (axisFound)
|
|
return false;
|
|
axisFound = true;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void refreshAssemblyInfo() {
|
|
if (!edgePoint.hasValidTrack())
|
|
return;
|
|
|
|
if (!isVirtual()) {
|
|
GlobalStation station = getStation();
|
|
if (station == null || station.getPresentTrain() != null)
|
|
return;
|
|
}
|
|
|
|
int prevLength = assemblyLength;
|
|
BlockPos targetPosition = edgePoint.getGlobalPosition();
|
|
BlockState trackState = edgePoint.getTrackBlockState();
|
|
ITrackBlock track = edgePoint.getTrack();
|
|
getAssemblyDirection();
|
|
|
|
MutableBlockPos currentPos = targetPosition.mutable();
|
|
currentPos.move(assemblyDirection);
|
|
|
|
BlockPos bogeyOffset = new BlockPos(track.getUpNormal(level, targetPosition, trackState));
|
|
|
|
int MAX_LENGTH = AllConfigs.SERVER.trains.maxAssemblyLength.get();
|
|
int MAX_BOGEY_COUNT = AllConfigs.SERVER.trains.maxBogeyCount.get();
|
|
|
|
int bogeyIndex = 0;
|
|
int maxBogeyCount = MAX_BOGEY_COUNT;
|
|
if (bogeyLocations == null)
|
|
bogeyLocations = new int[maxBogeyCount];
|
|
if (bogeyTypes == null)
|
|
bogeyTypes = new AbstractBogeyBlock[maxBogeyCount];
|
|
if (upsideDownBogeys == null)
|
|
upsideDownBogeys = new boolean[maxBogeyCount];
|
|
Arrays.fill(bogeyLocations, -1);
|
|
Arrays.fill(bogeyTypes, null);
|
|
Arrays.fill(upsideDownBogeys, false);
|
|
|
|
for (int i = 0; i < MAX_LENGTH; i++) {
|
|
if (i == MAX_LENGTH - 1) {
|
|
assemblyLength = i;
|
|
break;
|
|
}
|
|
if (!track.trackEquals(trackState, level.getBlockState(currentPos))) {
|
|
assemblyLength = Math.max(0, i - 1);
|
|
break;
|
|
}
|
|
|
|
BlockState potentialBogeyState = level.getBlockState(bogeyOffset.offset(currentPos));
|
|
BlockPos upsideDownBogeyOffset = new BlockPos(bogeyOffset.getX(), bogeyOffset.getY()*-1, bogeyOffset.getZ());
|
|
if (bogeyIndex < bogeyLocations.length) {
|
|
if (potentialBogeyState.getBlock() instanceof AbstractBogeyBlock<?> bogey && !bogey.isUpsideDown(potentialBogeyState)) {
|
|
bogeyTypes[bogeyIndex] = bogey;
|
|
bogeyLocations[bogeyIndex] = i;
|
|
upsideDownBogeys[bogeyIndex] = false;
|
|
bogeyIndex++;
|
|
} else if ((potentialBogeyState = level.getBlockState(upsideDownBogeyOffset.offset(currentPos))).getBlock() instanceof AbstractBogeyBlock<?> bogey && bogey.isUpsideDown(potentialBogeyState)) {
|
|
bogeyTypes[bogeyIndex] = bogey;
|
|
bogeyLocations[bogeyIndex] = i;
|
|
upsideDownBogeys[bogeyIndex] = true;
|
|
bogeyIndex++;
|
|
}
|
|
}
|
|
|
|
currentPos.move(assemblyDirection);
|
|
}
|
|
|
|
bogeyCount = bogeyIndex;
|
|
|
|
if (level.isClientSide)
|
|
return;
|
|
if (prevLength == assemblyLength)
|
|
return;
|
|
if (isVirtual())
|
|
return;
|
|
|
|
Map<BlockPos, BoundingBox> map = assemblyAreas.get(level);
|
|
BlockPos startPosition = targetPosition.relative(assemblyDirection);
|
|
BlockPos trackEnd = startPosition.relative(assemblyDirection, assemblyLength - 1);
|
|
map.put(worldPosition, BoundingBox.fromCorners(startPosition, trackEnd));
|
|
}
|
|
|
|
public boolean isValidBogeyOffset(int i) {
|
|
if ((i < 3 || bogeyCount == 0) && i != 0)
|
|
return false;
|
|
for (int j : bogeyLocations) {
|
|
if (j == -1)
|
|
break;
|
|
if (i >= j - 2 && i <= j + 2)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
public Direction getAssemblyDirection() {
|
|
if (assemblyDirection != null)
|
|
return assemblyDirection;
|
|
if (!edgePoint.hasValidTrack())
|
|
return null;
|
|
BlockPos targetPosition = edgePoint.getGlobalPosition();
|
|
BlockState trackState = edgePoint.getTrackBlockState();
|
|
ITrackBlock track = edgePoint.getTrack();
|
|
AxisDirection axisDirection = edgePoint.getTargetDirection();
|
|
Vec3 axis = track.getTrackAxes(level, targetPosition, trackState)
|
|
.get(0)
|
|
.normalize()
|
|
.scale(axisDirection.getStep());
|
|
return assemblyDirection = Direction.getNearest(axis.x, axis.y, axis.z);
|
|
}
|
|
|
|
@Override
|
|
public void remove() {
|
|
assemblyAreas.get(level)
|
|
.remove(worldPosition);
|
|
super.remove();
|
|
}
|
|
|
|
public void assemble(UUID playerUUID) {
|
|
refreshAssemblyInfo();
|
|
|
|
if (bogeyLocations == null)
|
|
return;
|
|
|
|
if (bogeyLocations[0] != 0) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.frontmost_bogey_at_station")), -1);
|
|
return;
|
|
}
|
|
|
|
if (!edgePoint.hasValidTrack())
|
|
return;
|
|
|
|
BlockPos trackPosition = edgePoint.getGlobalPosition();
|
|
BlockState trackState = edgePoint.getTrackBlockState();
|
|
ITrackBlock track = edgePoint.getTrack();
|
|
BlockPos bogeyOffset = new BlockPos(track.getUpNormal(level, trackPosition, trackState));
|
|
|
|
TrackNodeLocation location = null;
|
|
Vec3 centre = Vec3.atBottomCenterOf(trackPosition)
|
|
.add(0, track.getElevationAtCenter(level, trackPosition, trackState), 0);
|
|
Collection<DiscoveredLocation> ends = track.getConnected(level, trackPosition, trackState, true, null);
|
|
Vec3 targetOffset = Vec3.atLowerCornerOf(assemblyDirection.getNormal());
|
|
for (DiscoveredLocation end : ends)
|
|
if (Mth.equal(0, targetOffset.distanceToSqr(end.getLocation()
|
|
.subtract(centre)
|
|
.normalize())))
|
|
location = end;
|
|
if (location == null)
|
|
return;
|
|
|
|
List<Double> pointOffsets = new ArrayList<>();
|
|
int iPrevious = -100;
|
|
for (int i = 0; i < bogeyLocations.length; i++) {
|
|
int loc = bogeyLocations[i];
|
|
if (loc == -1)
|
|
break;
|
|
|
|
if (loc - iPrevious < 3) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.bogeys_too_close", i, i + 1)), -1);
|
|
return;
|
|
}
|
|
|
|
double bogeySize = bogeyTypes[i].getWheelPointSpacing();
|
|
pointOffsets.add(Double.valueOf(loc + .5 - bogeySize / 2));
|
|
pointOffsets.add(Double.valueOf(loc + .5 + bogeySize / 2));
|
|
iPrevious = loc;
|
|
}
|
|
|
|
List<TravellingPoint> points = new ArrayList<>();
|
|
Vec3 directionVec = Vec3.atLowerCornerOf(assemblyDirection.getNormal());
|
|
TrackGraph graph = null;
|
|
TrackNode secondNode = null;
|
|
|
|
for (int j = 0; j < assemblyLength * 2 + 40; j++) {
|
|
double i = j / 2d;
|
|
if (points.size() == pointOffsets.size())
|
|
break;
|
|
|
|
TrackNodeLocation currentLocation = location;
|
|
location = new TrackNodeLocation(location.getLocation()
|
|
.add(directionVec.scale(.5))).in(location.dimension);
|
|
|
|
if (graph == null)
|
|
graph = Create.RAILWAYS.getGraph(level, currentLocation);
|
|
if (graph == null)
|
|
continue;
|
|
TrackNode node = graph.locateNode(currentLocation);
|
|
if (node == null)
|
|
continue;
|
|
|
|
for (int pointIndex = points.size(); pointIndex < pointOffsets.size(); pointIndex++) {
|
|
double offset = pointOffsets.get(pointIndex);
|
|
if (offset > i)
|
|
break;
|
|
double positionOnEdge = i - offset;
|
|
|
|
Map<TrackNode, TrackEdge> connectionsFromNode = graph.getConnectionsFrom(node);
|
|
|
|
if (secondNode == null)
|
|
for (Entry<TrackNode, TrackEdge> entry : connectionsFromNode.entrySet()) {
|
|
TrackEdge edge = entry.getValue();
|
|
TrackNode otherNode = entry.getKey();
|
|
if (edge.isTurn())
|
|
continue;
|
|
Vec3 edgeDirection = edge.getDirection(true);
|
|
if (Mth.equal(edgeDirection.normalize()
|
|
.dot(directionVec), -1d))
|
|
secondNode = otherNode;
|
|
}
|
|
|
|
if (secondNode == null) {
|
|
Create.LOGGER.warn("Cannot assemble: No valid starting node found");
|
|
return;
|
|
}
|
|
|
|
TrackEdge edge = connectionsFromNode.get(secondNode);
|
|
|
|
if (edge == null) {
|
|
Create.LOGGER.warn("Cannot assemble: Missing graph edge");
|
|
return;
|
|
}
|
|
|
|
points.add(new TravellingPoint(node, secondNode, edge, positionOnEdge, false));
|
|
}
|
|
|
|
secondNode = node;
|
|
}
|
|
|
|
if (points.size() != pointOffsets.size()) {
|
|
Create.LOGGER.warn("Cannot assemble: Not all Points created");
|
|
return;
|
|
}
|
|
|
|
if (points.size() == 0) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.no_bogeys")), -1);
|
|
return;
|
|
}
|
|
|
|
List<CarriageContraption> contraptions = new ArrayList<>();
|
|
List<Carriage> carriages = new ArrayList<>();
|
|
List<Integer> spacing = new ArrayList<>();
|
|
boolean atLeastOneForwardControls = false;
|
|
|
|
for (int bogeyIndex = 0; bogeyIndex < bogeyCount; bogeyIndex++) {
|
|
int pointIndex = bogeyIndex * 2;
|
|
if (bogeyIndex > 0)
|
|
spacing.add(bogeyLocations[bogeyIndex] - bogeyLocations[bogeyIndex - 1]);
|
|
CarriageContraption contraption = new CarriageContraption(assemblyDirection);
|
|
BlockPos bogeyPosOffset = trackPosition.offset(bogeyOffset);
|
|
BlockPos upsideDownBogeyPosOffset = trackPosition.offset(new BlockPos(bogeyOffset.getX(), bogeyOffset.getY() * -1, bogeyOffset.getZ()));
|
|
|
|
try {
|
|
int offset = bogeyLocations[bogeyIndex] + 1;
|
|
boolean success = contraption.assemble(level, upsideDownBogeys[bogeyIndex] ? upsideDownBogeyPosOffset.relative(assemblyDirection, offset) : bogeyPosOffset.relative(assemblyDirection, offset));
|
|
atLeastOneForwardControls |= contraption.hasForwardControls();
|
|
contraption.setSoundQueueOffset(offset);
|
|
if (!success) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.nothing_attached", bogeyIndex + 1)),
|
|
-1);
|
|
return;
|
|
}
|
|
} catch (AssemblyException e) {
|
|
exception(e, contraptions.size() + 1);
|
|
return;
|
|
}
|
|
|
|
AbstractBogeyBlock<?> typeOfFirstBogey = bogeyTypes[bogeyIndex];
|
|
boolean firstBogeyIsUpsideDown = upsideDownBogeys[bogeyIndex];
|
|
BlockPos firstBogeyPos = contraption.anchor;
|
|
AbstractBogeyTileEntity firstBogeyTileEntity = (AbstractBogeyTileEntity) level.getBlockEntity(firstBogeyPos);
|
|
CarriageBogey firstBogey =
|
|
new CarriageBogey(typeOfFirstBogey, firstBogeyIsUpsideDown, firstBogeyTileEntity.getBogeyData(), points.get(pointIndex), points.get(pointIndex + 1));
|
|
CarriageBogey secondBogey = null;
|
|
BlockPos secondBogeyPos = contraption.getSecondBogeyPos();
|
|
int bogeySpacing = 0;
|
|
|
|
if (secondBogeyPos != null) {
|
|
if (bogeyIndex == bogeyCount - 1 || !secondBogeyPos
|
|
.equals((upsideDownBogeys[bogeyIndex + 1] ? upsideDownBogeyPosOffset : bogeyPosOffset).relative(assemblyDirection, bogeyLocations[bogeyIndex + 1] + 1))) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.not_connected_in_order")),
|
|
contraptions.size() + 1);
|
|
return;
|
|
}
|
|
AbstractBogeyTileEntity secondBogeyTileEntity =
|
|
(AbstractBogeyTileEntity) level.getBlockEntity(secondBogeyPos);
|
|
bogeySpacing = bogeyLocations[bogeyIndex + 1] - bogeyLocations[bogeyIndex];
|
|
secondBogey = new CarriageBogey(bogeyTypes[bogeyIndex + 1], upsideDownBogeys[bogeyIndex + 1], secondBogeyTileEntity.getBogeyData(),
|
|
points.get(pointIndex + 2), points.get(pointIndex + 3));
|
|
bogeyIndex++;
|
|
|
|
} else if (!typeOfFirstBogey.allowsSingleBogeyCarriage()) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.single_bogey_carriage")),
|
|
contraptions.size() + 1);
|
|
return;
|
|
}
|
|
|
|
contraptions.add(contraption);
|
|
carriages.add(new Carriage(firstBogey, secondBogey, bogeySpacing));
|
|
}
|
|
|
|
if (!atLeastOneForwardControls) {
|
|
exception(new AssemblyException(Lang.translateDirect("train_assembly.no_controls")), -1);
|
|
return;
|
|
}
|
|
|
|
for (CarriageContraption contraption : contraptions) {
|
|
contraption.removeBlocksFromWorld(level, BlockPos.ZERO);
|
|
contraption.expandBoundsAroundAxis(Axis.Y);
|
|
}
|
|
|
|
Train train = new Train(UUID.randomUUID(), playerUUID, graph, carriages, spacing, contraptions.stream()
|
|
.anyMatch(CarriageContraption::hasBackwardControls));
|
|
|
|
if (lastDisassembledTrainName != null) {
|
|
train.name = lastDisassembledTrainName;
|
|
lastDisassembledTrainName = null;
|
|
}
|
|
|
|
for (int i = 0; i < contraptions.size(); i++) {
|
|
CarriageContraption contraption = contraptions.get(i);
|
|
Carriage carriage = carriages.get(i);
|
|
carriage.setContraption(level, contraption);
|
|
if (contraption.containsBlockBreakers())
|
|
award(AllAdvancements.CONTRAPTION_ACTORS);
|
|
}
|
|
|
|
GlobalStation station = getStation();
|
|
if (station != null) {
|
|
train.setCurrentStation(station);
|
|
station.reserveFor(train);
|
|
}
|
|
|
|
train.collectInitiallyOccupiedSignalBlocks();
|
|
Create.RAILWAYS.addTrain(train);
|
|
AllPackets.channel.send(PacketDistributor.ALL.noArg(), new TrainPacket(train, true));
|
|
clearException();
|
|
|
|
award(AllAdvancements.TRAIN);
|
|
if (contraptions.size() >= 6)
|
|
award(AllAdvancements.LONG_TRAIN);
|
|
}
|
|
|
|
public void cancelAssembly() {
|
|
assemblyLength = 0;
|
|
assemblyAreas.get(level)
|
|
.remove(worldPosition);
|
|
clearException();
|
|
}
|
|
|
|
private void clearException() {
|
|
exception(null, -1);
|
|
}
|
|
|
|
private void exception(AssemblyException exception, int carriage) {
|
|
failedCarriageIndex = carriage;
|
|
lastException = exception;
|
|
sendData();
|
|
}
|
|
|
|
@Override
|
|
@OnlyIn(Dist.CLIENT)
|
|
public AABB getRenderBoundingBox() {
|
|
if (isAssembling())
|
|
return INFINITE_EXTENT_AABB;
|
|
return super.getRenderBoundingBox();
|
|
}
|
|
|
|
@Override
|
|
protected AABB createRenderBoundingBox() {
|
|
return new AABB(worldPosition, edgePoint.getGlobalPosition()).inflate(2);
|
|
}
|
|
|
|
public ItemStack getAutoSchedule() {
|
|
return depotBehaviour.getHeldItemStack();
|
|
}
|
|
|
|
@Override
|
|
public <T> LazyOptional<T> getCapability(Capability<T> cap, Direction side) {
|
|
if (isItemHandlerCap(cap))
|
|
return depotBehaviour.getItemCapability(cap, side);
|
|
return super.getCapability(cap, side);
|
|
}
|
|
|
|
private void applyAutoSchedule() {
|
|
ItemStack stack = getAutoSchedule();
|
|
if (!AllItems.SCHEDULE.isIn(stack))
|
|
return;
|
|
Schedule schedule = ScheduleItem.getSchedule(stack);
|
|
if (schedule == null || schedule.entries.isEmpty())
|
|
return;
|
|
GlobalStation station = getStation();
|
|
if (station == null)
|
|
return;
|
|
Train imminentTrain = station.getImminentTrain();
|
|
if (imminentTrain == null || imminentTrain.getCurrentStation() != station)
|
|
return;
|
|
|
|
award(AllAdvancements.CONDUCTOR);
|
|
imminentTrain.runtime.setSchedule(schedule, true);
|
|
AllSoundEvents.CONFIRM.playOnServer(level, worldPosition, 1, 1);
|
|
|
|
if (!(level instanceof ServerLevel server))
|
|
return;
|
|
|
|
Vec3 v = Vec3.atBottomCenterOf(worldPosition.above());
|
|
server.sendParticles(ParticleTypes.HAPPY_VILLAGER, v.x, v.y, v.z, 8, 0.35, 0.05, 0.35, 1);
|
|
server.sendParticles(ParticleTypes.END_ROD, v.x, v.y + .25f, v.z, 10, 0.05, 1, 0.05, 0.005f);
|
|
}
|
|
|
|
public boolean resolveFlagAngle() {
|
|
if (flagYRot != -1)
|
|
return true;
|
|
|
|
BlockState target = edgePoint.getTrackBlockState();
|
|
if (!(target.getBlock() instanceof ITrackBlock def))
|
|
return false;
|
|
|
|
Vec3 axis = null;
|
|
BlockPos trackPos = edgePoint.getGlobalPosition();
|
|
for (Vec3 vec3 : def.getTrackAxes(level, trackPos, target))
|
|
axis = vec3.scale(edgePoint.getTargetDirection()
|
|
.getStep());
|
|
if (axis == null)
|
|
return false;
|
|
|
|
Direction nearest = Direction.getNearest(axis.x, 0, axis.z);
|
|
flagYRot = (int) (-nearest.toYRot() - 90);
|
|
|
|
Vec3 diff = Vec3.atLowerCornerOf(trackPos.subtract(worldPosition))
|
|
.multiply(1, 0, 1);
|
|
if (diff.lengthSqr() == 0)
|
|
return true;
|
|
|
|
flagFlipped = diff.dot(Vec3.atLowerCornerOf(nearest.getClockWise()
|
|
.getNormal())) > 0;
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void transform(StructureTransform transform) {
|
|
edgePoint.transform(transform);
|
|
}
|
|
|
|
}
|