Create/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/station/StationTileEntity.java
simibubi e5c6ca157c Squashed commit of the following:
commit 053dd09df6c426ab5e570f42a1edb5df3d0fbd01
Merge: 6d1e1c71d ecc645eba
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

commit ecc645eba7
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

commit 205e47352e
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Mon May 8 21:02:19 2023 -0700

    Fix up ItemOutline

commit 6cf204f6af
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

commit fe049bc771
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Mon May 8 20:26:16 2023 -0700

    Revert "Revert "Rewrite outline buffering""

    This reverts commit 726bfaf0

commit 435b4c1c16
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

commit 662da6bab1
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

commit 122fe77afa
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Mon May 8 20:15:46 2023 -0700

    Fix up upside down rendering

commit d83285e8a4
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

commit cdb0ad210b
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun May 7 10:15:47 2023 +0100

    Fixed merge artifact

commit 457d5f33ed
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

commit 00e953a585
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

commit a7a25896c1
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

commit 4e4e227a35
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun May 7 10:10:30 2023 +0100

    Cleanup to cycle groups

commit aa94fc97d1
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun May 7 09:50:50 2023 +0100

    Removed unused import of Railways

commit 7622128bec
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

commit 1e4d5504ee
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sat May 6 18:03:39 2023 -0700

    Don't revert non-buggy changes

commit b306cf2124
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sat May 6 18:00:59 2023 -0700

    Take materials into consideration when trains pathfind

commit fca02ae4bf
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sat May 6 10:25:51 2023 -0700

    Add materials to track graph

commit 726bfaf0b5
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Fri May 5 21:16:49 2023 -0700

    Revert "Rewrite outline buffering"

    This reverts commit d4106d545b.

commit 171897bed2
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Fri May 5 20:55:25 2023 -0700

    Fix up style cycling

commit cbd0cf20da
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Fri May 5 07:32:06 2023 -0700

    clean up nether portal carriage handling

commit d556f08876
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

commit da26c0ccbf
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

commit 81eeadb853
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon May 1 16:15:28 2023 +0100

    Small cleanup

commit c7e9df973c
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon May 1 16:13:51 2023 +0100

    Fixed issue raised in #1

commit 2f285b6eb7
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Mon May 1 08:13:27 2023 -0700

    add data gen

commit 206de01311
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

commit 6564f4fa73
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

commit e5d7595822
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon May 1 10:09:03 2023 +0100

    Connected Custom Bogey Particle Types To CarriageParticles

commit e91753a33c
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sun Apr 30 19:51:26 2023 -0700

    Fix up some problems

commit 9815f1490f
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 21:12:43 2023 +0100

    Implemented default data when shifting styles

commit da30e78815
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 21:12:14 2023 +0100

    Added Particles To Bogey Style (And Respective Builder)

commit 08c000b8ba
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 21:01:19 2023 +0100

    Added Backup Rendering If A Size Is Not Present

commit 2b76e8d7b3
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 21:00:40 2023 +0100

    Added Common Renderer To Remove Function

commit 411ec36f57
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:59:50 2023 +0100

    Added Display Name To Standard Bogey Style

commit 112306d5d4
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:59:30 2023 +0100

    Displayed new style name when changing betweeen them

commit 5634670b27
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:06:00 2023 +0100

    General Cleanup

commit 0f7a8b7b24
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:05:50 2023 +0100

    Implemented Changes To Remaining Classes

commit 8aedc00f96
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:02:06 2023 +0100

    Removed Bogey Style Handling From Registrate

commit edf8079abf
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:01:40 2023 +0100

    Removed Unused Registry Handling

commit 6a185c4e72
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:01:16 2023 +0100

    Refactored Bogey Sizes

commit e10d07ddc3
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 30 20:01:00 2023 +0100

    Overhauled Bogey Style

commit 74d98a2ad5
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

commit e629d02f50
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sun Apr 9 07:18:22 2023 -0700

    Track API

    Clean up code a bit

commit d9ce6ce995
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sun Apr 9 07:14:46 2023 -0700

    Track API?

    Fix placement

commit 7fbf08ba54
Author: techno-sam <linux.techno.sam@gmail.com>
Date:   Sat Apr 8 11:11:24 2023 -0700

    Track API?

    Fix up some placement issues

commit 35644f1434
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

commit f7c56b867a
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

commit 2a59fd7e8a
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

commit 5ba30d6a85
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

commit d52065808c
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

commit 53240bd42f
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon Apr 3 21:42:29 2023 +0100

    Corrected Bogey InteractionResult To Pass

commit 69326e361a
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon Apr 3 21:30:28 2023 +0100

    Fixed Default Values When Used Styles Are Removed

commit 4f176979de
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon Apr 3 19:33:17 2023 +0100

    Fixed Carriage Sounds (Again)

commit 1e80af3303
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon Apr 3 19:27:58 2023 +0100

    Refactored Bogey Sizes To Seperate Class

commit 129be61fee
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon Apr 3 17:20:17 2023 +0100

    Fixed Bogey Sound Loading

commit 2543185a55
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Mon Apr 3 09:45:23 2023 +0100

    Added Bogey Sound Customisation

commit 1ad5ae9514
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

commit 96566b1614
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

commit eedd984738
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 2 16:53:55 2023 +0100

    Fixed Large Bogey Size

commit 68ca0974c6
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 2 16:47:58 2023 +0100

    Implemented Style Cycling & Default Values

commit a55ba4267a
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 2 16:46:15 2023 +0100

    Implemented renderer instance creator

commit 43523302c2
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sun Apr 2 16:45:33 2023 +0100

    Removed Unused Standard Bogey Instance

commit 773e084422
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

commit 0c0b5a1ed6
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sat Apr 1 18:39:58 2023 +0100

    Linked Style Registry To Bogey Blocks

commit 71f839ee51
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sat Apr 1 18:39:03 2023 +0100

    Replaced size boolean with direct use of size enum

commit 50ff081704
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 30 18:47:13 2023 +0100

    Added Resource Location To NBT helper methods

commit d1e1f7ec5a
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 30 18:47:13 2023 +0100

    Re-worked BogeyStyles

commit da593fccb1
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 30 18:46:02 2023 +0100

    Refactored IBogeyBlock to AbstractBogeyBlock and extracted relevant StandardBogeyBlock implementations

commit 17432c9113
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Sat Mar 25 10:20:50 2023 +0000

    Fixed Incorrect Registry Loading

commit c7d899369a
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Fri Mar 24 23:44:03 2023 +0000

    Registered Registers

commit 6d862290d7
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Fri Mar 24 23:43:23 2023 +0000

    Added BogeyStyleBuilder To Registrate

commit 3dfb9e3b3b
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Fri Mar 24 23:43:08 2023 +0000

    Implemented AllBogeyStyles

commit c9e71b462d
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Fri Mar 24 23:42:56 2023 +0000

    Created BogeyStyleBuilder

commit a90977d642
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Fri Mar 24 23:42:25 2023 +0000

    Created AllRegistries and BogeyStyle Registry

commit 154d455f3f
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Fri Mar 24 23:41:56 2023 +0000

    Added BogeyStyle Wrapper

commit dfb7640bfc
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 18:50:41 2023 +0000

    Removed left over logging statement

commit 9920536cc3
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 18:50:18 2023 +0000

    Implemented Secondary Shaft To Large Renderer

commit 6cd40cc6f9
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

commit 06fb901144
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 18:39:11 2023 +0000

    Implemented Common Rendering For StandardBogeyRenderer

commit 435b0f8266
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 18:38:40 2023 +0000

    Added Common Renderer

commit 96a0623dab
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 18:38:29 2023 +0000

    Implemented BlockState Models For Rendering

commit 469d9d592b
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 17:42:28 2023 +0000

    Added Standard Bogey Instance (Might be redundant)

commit 2661d260d8
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 17:42:06 2023 +0000

    Refactored Changes To Existing Methods

commit 9ded16fbab
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 17:41:15 2023 +0000

    Integrated BogeyRenderer To BogeyInstance (Also Corrected Rendering In Contraption)

commit 4a82fcbca1
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 17:40:13 2023 +0000

    Implemented Changes To StandardBogeyBlock

commit 7238fb93f3
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Thu Mar 23 17:39:51 2023 +0000

    Added Renderer To IBogeyBlock

commit ded4c1f613
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

commit 91727cc84a
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Wed Mar 22 17:03:28 2023 +0000

    Implemented Model Data Initializer to StandardBogeyRenderer

commit 6d98a1f469
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Wed Mar 22 17:03:00 2023 +0000

    Added Contraption Model Instance Initializer

commit 3c02fe6ecc
Author: Rabbitminers <79579164+Rabbitminers@users.noreply.github.com>
Date:   Tue Mar 21 22:45:34 2023 +0000

    Added missing render type check

commit 6672c49649
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Tue Mar 21 22:37:36 2023 +0000

    Re-created standard bogey with test api

commit a8a9491fa0
Author: Rabbitminers <Rabbitminers2.0@gmail.com>
Date:   Tue Mar 21 22:34:54 2023 +0000

    Implemented Proof Of Concept Generic Bogey Renderer

commit e4e5ac1c40
Author: SpottyTheTurtle <69260662+SpottyTheTurtle@users.noreply.github.com>
Date:   Sat Mar 11 21:34:59 2023 +0000

    init
2023-05-09 18:23:47 +02:00

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);
}
}