mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-05-19 20:13:53 +02:00
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
783 lines
25 KiB
Java
783 lines
25 KiB
Java
package com.simibubi.create.content.logistics.trains.track;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collection;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Set;
|
|
|
|
import com.jozufozu.flywheel.util.Color;
|
|
import com.simibubi.create.AllSpecialTextures;
|
|
import com.simibubi.create.AllTags;
|
|
import com.simibubi.create.CreateClient;
|
|
import com.simibubi.create.content.curiosities.tools.BlueprintOverlayRenderer;
|
|
import com.simibubi.create.content.logistics.trains.BezierConnection;
|
|
import com.simibubi.create.content.logistics.trains.ITrackBlock;
|
|
import com.simibubi.create.content.logistics.trains.TrackMaterial;
|
|
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.utility.AngleHelper;
|
|
import com.simibubi.create.foundation.utility.Couple;
|
|
import com.simibubi.create.foundation.utility.Iterate;
|
|
import com.simibubi.create.foundation.utility.Lang;
|
|
import com.simibubi.create.foundation.utility.Pair;
|
|
import com.simibubi.create.foundation.utility.VecHelper;
|
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat;
|
|
import com.simibubi.create.foundation.utility.animation.LerpedFloat.Chaser;
|
|
|
|
import net.minecraft.ChatFormatting;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.player.LocalPlayer;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.Direction.Axis;
|
|
import net.minecraft.core.Direction.AxisDirection;
|
|
import net.minecraft.nbt.CompoundTag;
|
|
import net.minecraft.nbt.NbtUtils;
|
|
import net.minecraft.nbt.Tag;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.world.InteractionHand;
|
|
import net.minecraft.world.entity.player.Inventory;
|
|
import net.minecraft.world.entity.player.Player;
|
|
import net.minecraft.world.item.BlockItem;
|
|
import net.minecraft.world.item.ItemStack;
|
|
import net.minecraft.world.item.context.UseOnContext;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.Block;
|
|
import net.minecraft.world.level.block.EntityBlock;
|
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.level.block.state.properties.Property;
|
|
import net.minecraft.world.phys.BlockHitResult;
|
|
import net.minecraft.world.phys.HitResult;
|
|
import net.minecraft.world.phys.HitResult.Type;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
import net.minecraftforge.items.ItemHandlerHelper;
|
|
|
|
public class TrackPlacement {
|
|
|
|
public static class PlacementInfo {
|
|
|
|
public PlacementInfo(TrackMaterial material) {
|
|
this.trackMaterial = material;
|
|
}
|
|
|
|
BezierConnection curve = null;
|
|
boolean valid = false;
|
|
int end1Extent = 0;
|
|
int end2Extent = 0;
|
|
String message = null;
|
|
|
|
public int requiredTracks = 0;
|
|
public boolean hasRequiredTracks = false;
|
|
|
|
public int requiredPavement = 0;
|
|
public boolean hasRequiredPavement = false;
|
|
public final TrackMaterial trackMaterial;
|
|
|
|
// for visualisation
|
|
Vec3 end1;
|
|
Vec3 end2;
|
|
Vec3 normal1;
|
|
Vec3 normal2;
|
|
Vec3 axis1;
|
|
Vec3 axis2;
|
|
BlockPos pos1;
|
|
BlockPos pos2;
|
|
|
|
public PlacementInfo withMessage(String message) {
|
|
this.message = "track." + message;
|
|
return this;
|
|
}
|
|
|
|
public PlacementInfo tooJumbly() {
|
|
curve = null;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
public static PlacementInfo cached;
|
|
|
|
static BlockPos hoveringPos;
|
|
static boolean hoveringMaxed;
|
|
static int hoveringAngle;
|
|
static ItemStack lastItem;
|
|
|
|
public static PlacementInfo tryConnect(Level level, Player player, BlockPos pos2, BlockState state2,
|
|
ItemStack stack, boolean girder, boolean maximiseTurn) {
|
|
Vec3 lookVec = player.getLookAngle();
|
|
int lookAngle = (int) (22.5 + AngleHelper.deg(Mth.atan2(lookVec.z, lookVec.x)) % 360) / 8;
|
|
int maxLength = AllConfigs.SERVER.trains.maxTrackPlacementLength.get();
|
|
|
|
if (level.isClientSide && cached != null && pos2.equals(hoveringPos) && stack.equals(lastItem)
|
|
&& hoveringMaxed == maximiseTurn && lookAngle == hoveringAngle)
|
|
return cached;
|
|
|
|
PlacementInfo info = new PlacementInfo(TrackMaterial.fromItem(stack.getItem()));
|
|
hoveringMaxed = maximiseTurn;
|
|
hoveringAngle = lookAngle;
|
|
hoveringPos = pos2;
|
|
lastItem = stack;
|
|
cached = info;
|
|
|
|
ITrackBlock track = (ITrackBlock) state2.getBlock();
|
|
Pair<Vec3, AxisDirection> nearestTrackAxis = track.getNearestTrackAxis(level, pos2, state2, lookVec);
|
|
Vec3 axis2 = nearestTrackAxis.getFirst()
|
|
.scale(nearestTrackAxis.getSecond() == AxisDirection.POSITIVE ? -1 : 1);
|
|
Vec3 normal2 = track.getUpNormal(level, pos2, state2)
|
|
.normalize();
|
|
Vec3 normedAxis2 = axis2.normalize();
|
|
Vec3 end2 = track.getCurveStart(level, pos2, state2, axis2);
|
|
|
|
CompoundTag itemTag = stack.getTag();
|
|
CompoundTag selectionTag = itemTag.getCompound("ConnectingFrom");
|
|
BlockPos pos1 = NbtUtils.readBlockPos(selectionTag.getCompound("Pos"));
|
|
Vec3 axis1 = VecHelper.readNBT(selectionTag.getList("Axis", Tag.TAG_DOUBLE));
|
|
Vec3 normedAxis1 = axis1.normalize();
|
|
Vec3 end1 = VecHelper.readNBT(selectionTag.getList("End", Tag.TAG_DOUBLE));
|
|
Vec3 normal1 = VecHelper.readNBT(selectionTag.getList("Normal", Tag.TAG_DOUBLE));
|
|
boolean front1 = selectionTag.getBoolean("Front");
|
|
BlockState state1 = level.getBlockState(pos1);
|
|
|
|
if (level.isClientSide) {
|
|
info.end1 = end1;
|
|
info.end2 = end2;
|
|
info.normal1 = normal1;
|
|
info.normal2 = normal2;
|
|
info.axis1 = axis1;
|
|
info.axis2 = axis2;
|
|
}
|
|
|
|
if (pos1.equals(pos2))
|
|
return info.withMessage("second_point");
|
|
if (pos1.distSqr(pos2) > maxLength * maxLength)
|
|
return info.withMessage("too_far")
|
|
.tooJumbly();
|
|
if (!state1.hasProperty(TrackBlock.HAS_TE))
|
|
return info.withMessage("original_missing");
|
|
|
|
if (axis1.dot(end2.subtract(end1)) < 0) {
|
|
axis1 = axis1.scale(-1);
|
|
normedAxis1 = normedAxis1.scale(-1);
|
|
front1 = !front1;
|
|
end1 = track.getCurveStart(level, pos1, state1, axis1);
|
|
if (level.isClientSide) {
|
|
info.end1 = end1;
|
|
info.axis1 = axis1;
|
|
}
|
|
}
|
|
|
|
double[] intersect = VecHelper.intersect(end1, end2, normedAxis1, normedAxis2, Axis.Y);
|
|
boolean parallel = intersect == null;
|
|
boolean skipCurve = false;
|
|
|
|
if ((parallel && normedAxis1.dot(normedAxis2) > 0) || (!parallel && (intersect[0] < 0 || intersect[1] < 0))) {
|
|
axis2 = axis2.scale(-1);
|
|
normedAxis2 = normedAxis2.scale(-1);
|
|
end2 = track.getCurveStart(level, pos2, state2, axis2);
|
|
if (level.isClientSide) {
|
|
info.end2 = end2;
|
|
info.axis2 = axis2;
|
|
}
|
|
}
|
|
|
|
Vec3 cross2 = normedAxis2.cross(new Vec3(0, 1, 0));
|
|
|
|
double a1 = Mth.atan2(normedAxis2.z, normedAxis2.x);
|
|
double a2 = Mth.atan2(normedAxis1.z, normedAxis1.x);
|
|
double angle = a1 - a2;
|
|
double ascend = end2.subtract(end1).y;
|
|
double absAscend = Math.abs(ascend);
|
|
boolean slope = !normal1.equals(normal2);
|
|
|
|
if (level.isClientSide) {
|
|
Vec3 offset1 = axis1.scale(info.end1Extent);
|
|
Vec3 offset2 = axis2.scale(info.end2Extent);
|
|
BlockPos targetPos1 = pos1.offset(offset1.x, offset1.y, offset1.z);
|
|
BlockPos targetPos2 = pos2.offset(offset2.x, offset2.y, offset2.z);
|
|
info.curve = new BezierConnection(Couple.create(targetPos1, targetPos2),
|
|
Couple.create(end1.add(offset1), end2.add(offset2)), Couple.create(normedAxis1, normedAxis2),
|
|
Couple.create(normal1, normal2), true, girder, TrackMaterial.fromItem(stack.getItem()));
|
|
}
|
|
|
|
// S curve or Straight
|
|
|
|
double dist = 0;
|
|
|
|
if (parallel) {
|
|
double[] sTest = VecHelper.intersect(end1, end2, normedAxis1, cross2, Axis.Y);
|
|
if (sTest != null) {
|
|
double t = Math.abs(sTest[0]);
|
|
double u = Math.abs(sTest[1]);
|
|
|
|
skipCurve = Mth.equal(u, 0);
|
|
|
|
if (!skipCurve && sTest[0] < 0)
|
|
return info.withMessage("perpendicular")
|
|
.tooJumbly();
|
|
|
|
if (skipCurve) {
|
|
dist = VecHelper.getCenterOf(pos1)
|
|
.distanceTo(VecHelper.getCenterOf(pos2));
|
|
info.end1Extent = (int) Math.round((dist + 1) / axis1.length());
|
|
|
|
} else {
|
|
if (!Mth.equal(ascend, 0))
|
|
return info.withMessage("ascending_s_curve");
|
|
|
|
double targetT = u <= 1 ? 3 : u * 2;
|
|
|
|
if (t < targetT)
|
|
return info.withMessage("too_sharp");
|
|
|
|
// This is for standardising s curve sizes
|
|
if (t > targetT) {
|
|
int correction = (int) ((t - targetT) / axis1.length());
|
|
info.end1Extent = maximiseTurn ? 0 : correction / 2 + (correction % 2);
|
|
info.end2Extent = maximiseTurn ? 0 : correction / 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Slope
|
|
|
|
if (slope) {
|
|
if (!skipCurve)
|
|
return info.withMessage("slope_turn");
|
|
if (Mth.equal(normal1.dot(normal2), 0))
|
|
return info.withMessage("opposing_slopes");
|
|
if ((axis1.y < 0 || axis2.y > 0) && ascend > 0)
|
|
return info.withMessage("leave_slope_ascending");
|
|
if ((axis1.y > 0 || axis2.y < 0) && ascend < 0)
|
|
return info.withMessage("leave_slope_descending");
|
|
|
|
skipCurve = false;
|
|
info.end1Extent = 0;
|
|
info.end2Extent = 0;
|
|
|
|
Axis plane = Mth.equal(axis1.x, 0) ? Axis.X : Axis.Z;
|
|
intersect = VecHelper.intersect(end1, end2, normedAxis1, normedAxis2, plane);
|
|
double dist1 = Math.abs(intersect[0] / axis1.length());
|
|
double dist2 = Math.abs(intersect[1] / axis2.length());
|
|
|
|
if (dist1 > dist2)
|
|
info.end1Extent = (int) Math.round(dist1 - dist2);
|
|
if (dist2 > dist1)
|
|
info.end2Extent = (int) Math.round(dist2 - dist1);
|
|
|
|
double turnSize = Math.min(dist1, dist2);
|
|
if (intersect[0] < 0 || intersect[1] < 0)
|
|
return info.withMessage("too_sharp")
|
|
.tooJumbly();
|
|
if (turnSize < 2)
|
|
return info.withMessage("too_sharp");
|
|
|
|
// This is for standardising curve sizes
|
|
if (turnSize > 2 && !maximiseTurn) {
|
|
info.end1Extent += turnSize - 2;
|
|
info.end2Extent += turnSize - 2;
|
|
turnSize = 2;
|
|
}
|
|
}
|
|
|
|
// Straight ascend
|
|
|
|
if (skipCurve && !Mth.equal(ascend, 0)) {
|
|
int hDistance = info.end1Extent;
|
|
if (axis1.y == 0 || !Mth.equal(absAscend + 1, dist / axis1.length())) {
|
|
|
|
if (axis1.y != 0 && axis1.y == -axis2.y)
|
|
return info.withMessage("ascending_s_curve");
|
|
|
|
info.end1Extent = 0;
|
|
double minHDistance = Math.max(absAscend < 4 ? absAscend * 4 : absAscend * 3, 6) / axis1.length();
|
|
if (hDistance < minHDistance)
|
|
return info.withMessage("too_steep");
|
|
if (hDistance > minHDistance) {
|
|
int correction = (int) (hDistance - minHDistance);
|
|
info.end1Extent = maximiseTurn ? 0 : correction / 2 + (correction % 2);
|
|
info.end2Extent = maximiseTurn ? 0 : correction / 2;
|
|
}
|
|
|
|
skipCurve = false;
|
|
}
|
|
}
|
|
|
|
// Turn
|
|
|
|
if (!parallel) {
|
|
float absAngle = Math.abs(AngleHelper.deg(angle));
|
|
if (absAngle < 60 || absAngle > 300)
|
|
return info.withMessage("turn_90")
|
|
.tooJumbly();
|
|
|
|
intersect = VecHelper.intersect(end1, end2, normedAxis1, normedAxis2, Axis.Y);
|
|
double dist1 = Math.abs(intersect[0]);
|
|
double dist2 = Math.abs(intersect[1]);
|
|
float ex1 = 0;
|
|
float ex2 = 0;
|
|
|
|
if (dist1 > dist2)
|
|
ex1 = (float) ((dist1 - dist2) / axis1.length());
|
|
if (dist2 > dist1)
|
|
ex2 = (float) ((dist2 - dist1) / axis2.length());
|
|
|
|
double turnSize = Math.min(dist1, dist2) - .1d;
|
|
boolean ninety = (absAngle + .25f) % 90 < 1;
|
|
|
|
if (intersect[0] < 0 || intersect[1] < 0)
|
|
return info.withMessage("too_sharp")
|
|
.tooJumbly();
|
|
|
|
double minTurnSize = ninety ? 7 : 3.25;
|
|
double turnSizeToFitAscend =
|
|
minTurnSize + (ninety ? Math.max(0, absAscend - 3) * 2f : Math.max(0, absAscend - 1.5f) * 1.5f);
|
|
|
|
if (turnSize < minTurnSize)
|
|
return info.withMessage("too_sharp");
|
|
if (turnSize < turnSizeToFitAscend)
|
|
return info.withMessage("too_steep");
|
|
|
|
// This is for standardising curve sizes
|
|
if (!maximiseTurn) {
|
|
ex1 += (turnSize - turnSizeToFitAscend) / axis1.length();
|
|
ex2 += (turnSize - turnSizeToFitAscend) / axis2.length();
|
|
}
|
|
info.end1Extent = Mth.floor(ex1);
|
|
info.end2Extent = Mth.floor(ex2);
|
|
turnSize = turnSizeToFitAscend;
|
|
}
|
|
|
|
Vec3 offset1 = axis1.scale(info.end1Extent);
|
|
Vec3 offset2 = axis2.scale(info.end2Extent);
|
|
BlockPos targetPos1 = pos1.offset(offset1.x, offset1.y, offset1.z);
|
|
BlockPos targetPos2 = pos2.offset(offset2.x, offset2.y, offset2.z);
|
|
|
|
info.curve = skipCurve ? null
|
|
: new BezierConnection(Couple.create(targetPos1, targetPos2),
|
|
Couple.create(end1.add(offset1), end2.add(offset2)), Couple.create(normedAxis1, normedAxis2),
|
|
Couple.create(normal1, normal2), true, girder, TrackMaterial.fromItem(stack.getItem()));
|
|
|
|
info.valid = true;
|
|
|
|
info.pos1 = pos1;
|
|
info.pos2 = pos2;
|
|
info.axis1 = axis1;
|
|
info.axis2 = axis2;
|
|
|
|
placeTracks(level, info, state1, state2, targetPos1, targetPos2, true);
|
|
|
|
ItemStack offhandItem = player.getOffhandItem()
|
|
.copy();
|
|
boolean shouldPave = offhandItem.getItem() instanceof BlockItem;
|
|
if (shouldPave) {
|
|
BlockItem paveItem = (BlockItem) offhandItem.getItem();
|
|
paveTracks(level, info, paveItem, true);
|
|
info.hasRequiredPavement = true;
|
|
}
|
|
|
|
info.hasRequiredTracks = true;
|
|
|
|
if (!player.isCreative()) {
|
|
for (boolean simulate : Iterate.trueAndFalse) {
|
|
if (level.isClientSide && !simulate)
|
|
break;
|
|
|
|
int tracks = info.requiredTracks;
|
|
int pavement = info.requiredPavement;
|
|
int foundTracks = 0;
|
|
int foundPavement = 0;
|
|
|
|
Inventory inv = player.getInventory();
|
|
int size = inv.items.size();
|
|
for (int j = 0; j <= size + 1; j++) {
|
|
int i = j;
|
|
boolean offhand = j == size + 1;
|
|
if (j == size)
|
|
i = inv.selected;
|
|
else if (offhand)
|
|
i = 0;
|
|
else if (j == inv.selected)
|
|
continue;
|
|
|
|
ItemStack stackInSlot = (offhand ? inv.offhand : inv.items).get(i);
|
|
boolean isTrack = AllTags.AllBlockTags.TRACKS.matches(stackInSlot) && stackInSlot.is(stack.getItem());
|
|
if (!isTrack && (!shouldPave || offhandItem.getItem() != stackInSlot.getItem()))
|
|
continue;
|
|
if (isTrack ? foundTracks >= tracks : foundPavement >= pavement)
|
|
continue;
|
|
|
|
int count = stackInSlot.getCount();
|
|
|
|
if (!simulate) {
|
|
int remainingItems =
|
|
count - Math.min(isTrack ? tracks - foundTracks : pavement - foundPavement, count);
|
|
if (i == inv.selected)
|
|
stackInSlot.setTag(null);
|
|
ItemStack newItem = ItemHandlerHelper.copyStackWithSize(stackInSlot, remainingItems);
|
|
if (offhand)
|
|
player.setItemInHand(InteractionHand.OFF_HAND, newItem);
|
|
else
|
|
inv.setItem(i, newItem);
|
|
}
|
|
|
|
if (isTrack)
|
|
foundTracks += count;
|
|
else
|
|
foundPavement += count;
|
|
}
|
|
|
|
if (simulate && foundTracks < tracks) {
|
|
info.valid = false;
|
|
info.tooJumbly();
|
|
info.hasRequiredTracks = false;
|
|
return info.withMessage("not_enough_tracks");
|
|
}
|
|
|
|
if (simulate && foundPavement < pavement) {
|
|
info.valid = false;
|
|
info.tooJumbly();
|
|
info.hasRequiredPavement = false;
|
|
return info.withMessage("not_enough_pavement");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (level.isClientSide())
|
|
return info;
|
|
if (shouldPave) {
|
|
BlockItem paveItem = (BlockItem) offhandItem.getItem();
|
|
paveTracks(level, info, paveItem, false);
|
|
}
|
|
|
|
if (info.curve != null && info.curve.getLength() > 29)
|
|
AllAdvancements.LONG_BEND.awardTo(player);
|
|
|
|
return placeTracks(level, info, state1, state2, targetPos1, targetPos2, false);
|
|
}
|
|
|
|
private static void paveTracks(Level level, PlacementInfo info, BlockItem blockItem, boolean simulate) {
|
|
Block block = blockItem.getBlock();
|
|
info.requiredPavement = 0;
|
|
if (block == null || block instanceof EntityBlock || block.defaultBlockState()
|
|
.getCollisionShape(level, info.pos1)
|
|
.isEmpty())
|
|
return;
|
|
|
|
Set<BlockPos> visited = new HashSet<>();
|
|
|
|
for (boolean first : Iterate.trueAndFalse) {
|
|
int extent = (first ? info.end1Extent : info.end2Extent) + (info.curve != null ? 1 : 0);
|
|
Vec3 axis = first ? info.axis1 : info.axis2;
|
|
BlockPos pavePos = first ? info.pos1 : info.pos2;
|
|
info.requiredPavement +=
|
|
TrackPaver.paveStraight(level, pavePos.below(), axis, extent, block, simulate, visited);
|
|
}
|
|
|
|
if (info.curve != null)
|
|
info.requiredPavement += TrackPaver.paveCurve(level, info.curve, block, simulate, visited);
|
|
}
|
|
|
|
private static BlockState copyProperties(BlockState from, BlockState onto) {
|
|
for (Property property : onto.getProperties()) {
|
|
if (from.hasProperty(property))
|
|
onto = onto.setValue(property, from.getValue(property));
|
|
}
|
|
return onto;
|
|
}
|
|
|
|
private static BlockState copyProperties(BlockState from, BlockState onto, boolean keepFrom) {
|
|
return keepFrom ? from : copyProperties(from, onto);
|
|
}
|
|
|
|
private static PlacementInfo placeTracks(Level level, PlacementInfo info, BlockState state1, BlockState state2,
|
|
BlockPos targetPos1, BlockPos targetPos2, boolean simulate) {
|
|
info.requiredTracks = 0;
|
|
|
|
for (boolean first : Iterate.trueAndFalse) {
|
|
int extent = first ? info.end1Extent : info.end2Extent;
|
|
Vec3 axis = first ? info.axis1 : info.axis2;
|
|
BlockPos pos = first ? info.pos1 : info.pos2;
|
|
BlockState state = first ? state1 : state2;
|
|
if (state.hasProperty(TrackBlock.HAS_TE) && !simulate)
|
|
state = state.setValue(TrackBlock.HAS_TE, false);
|
|
|
|
switch (state.getValue(TrackBlock.SHAPE)) {
|
|
case TE, TW:
|
|
state = state.setValue(TrackBlock.SHAPE, TrackShape.XO);
|
|
break;
|
|
case TN, TS:
|
|
state = state.setValue(TrackBlock.SHAPE, TrackShape.ZO);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
for (int i = 0; i < (info.curve != null ? extent + 1 : extent); i++) {
|
|
Vec3 offset = axis.scale(i);
|
|
BlockPos offsetPos = pos.offset(offset.x, offset.y, offset.z);
|
|
BlockState stateAtPos = level.getBlockState(offsetPos);
|
|
// copy over all shared properties from the shaped state to the correct track material block
|
|
BlockState toPlace = copyProperties(state, info.trackMaterial.getTrackBlock().get().defaultBlockState());
|
|
|
|
boolean canPlace = stateAtPos.getMaterial()
|
|
.isReplaceable();
|
|
if (canPlace)
|
|
info.requiredTracks++;
|
|
if (simulate)
|
|
continue;
|
|
|
|
if (stateAtPos.getBlock() instanceof ITrackBlock trackAtPos) {
|
|
toPlace = trackAtPos.overlay(level, offsetPos, stateAtPos, toPlace);
|
|
canPlace = true;
|
|
}
|
|
|
|
if (canPlace)
|
|
level.setBlock(offsetPos, ProperWaterloggedBlock.withWater(level, toPlace, offsetPos), 3);
|
|
}
|
|
}
|
|
|
|
if (info.curve == null)
|
|
return info;
|
|
|
|
if (!simulate) {
|
|
BlockState onto = info.trackMaterial.getTrackBlock().get().defaultBlockState();
|
|
BlockState stateAtPos = level.getBlockState(targetPos1);
|
|
level.setBlock(targetPos1, ProperWaterloggedBlock.withWater(level,
|
|
(AllTags.AllBlockTags.TRACKS.matches(stateAtPos) ? stateAtPos : copyProperties(state1, onto))
|
|
.setValue(TrackBlock.HAS_TE, true), targetPos1), 3);
|
|
|
|
stateAtPos = level.getBlockState(targetPos2);
|
|
level.setBlock(targetPos2, ProperWaterloggedBlock.withWater(level,
|
|
(AllTags.AllBlockTags.TRACKS.matches(stateAtPos) ? stateAtPos : copyProperties(state2, onto))
|
|
.setValue(TrackBlock.HAS_TE, true), targetPos2), 3);
|
|
}
|
|
|
|
BlockEntity te1 = level.getBlockEntity(targetPos1);
|
|
BlockEntity te2 = level.getBlockEntity(targetPos2);
|
|
int requiredTracksForTurn = (info.curve.getSegmentCount() + 1) / 2;
|
|
|
|
if (!(te1 instanceof TrackTileEntity) || !(te2 instanceof TrackTileEntity)) {
|
|
info.requiredTracks += requiredTracksForTurn;
|
|
return info;
|
|
}
|
|
|
|
TrackTileEntity tte1 = (TrackTileEntity) te1;
|
|
TrackTileEntity tte2 = (TrackTileEntity) te2;
|
|
|
|
if (!tte1.getConnections()
|
|
.containsKey(tte2.getBlockPos()))
|
|
info.requiredTracks += requiredTracksForTurn;
|
|
|
|
if (simulate)
|
|
return info;
|
|
|
|
tte1.addConnection(info.curve);
|
|
tte2.addConnection(info.curve.secondary());
|
|
return info;
|
|
}
|
|
|
|
static LerpedFloat animation = LerpedFloat.linear()
|
|
.startWithValue(0);
|
|
static int lastLineCount = 0;
|
|
|
|
static BlockPos hintPos;
|
|
static int hintAngle;
|
|
static Couple<List<BlockPos>> hints;
|
|
|
|
@OnlyIn(Dist.CLIENT)
|
|
public static void clientTick() {
|
|
LocalPlayer player = Minecraft.getInstance().player;
|
|
ItemStack stack = player.getMainHandItem();
|
|
HitResult hitResult = Minecraft.getInstance().hitResult;
|
|
|
|
if (hitResult == null)
|
|
return;
|
|
if (hitResult.getType() != Type.BLOCK)
|
|
return;
|
|
|
|
InteractionHand hand = InteractionHand.MAIN_HAND;
|
|
if (!AllTags.AllBlockTags.TRACKS.matches(stack)) {
|
|
stack = player.getOffhandItem();
|
|
hand = InteractionHand.OFF_HAND;
|
|
if (!AllTags.AllBlockTags.TRACKS.matches(stack))
|
|
return;
|
|
}
|
|
|
|
if (!stack.hasFoil())
|
|
return;
|
|
|
|
TrackBlockItem blockItem = (TrackBlockItem) stack.getItem();
|
|
Level level = player.level;
|
|
BlockHitResult bhr = (BlockHitResult) hitResult;
|
|
BlockPos pos = bhr.getBlockPos();
|
|
BlockState hitState = level.getBlockState(pos);
|
|
if (!(hitState.getBlock() instanceof TrackBlock) && !hitState.getMaterial()
|
|
.isReplaceable()) {
|
|
pos = pos.relative(bhr.getDirection());
|
|
hitState = blockItem.getPlacementState(new UseOnContext(player, hand, bhr));
|
|
if (hitState == null)
|
|
return;
|
|
}
|
|
|
|
if (!(hitState.getBlock() instanceof TrackBlock))
|
|
return;
|
|
|
|
boolean maxTurns = Minecraft.getInstance().options.keySprint.isDown();
|
|
PlacementInfo info = tryConnect(level, player, pos, hitState, stack, false, maxTurns);
|
|
if (!player.isCreative() && (info.valid || !info.hasRequiredTracks || !info.hasRequiredPavement))
|
|
BlueprintOverlayRenderer.displayTrackRequirements(info, player.getOffhandItem());
|
|
|
|
if (info.valid)
|
|
player.displayClientMessage(Lang.translateDirect("track.valid_connection")
|
|
.withStyle(ChatFormatting.GREEN), true);
|
|
else if (info.message != null)
|
|
player.displayClientMessage(Lang.translateDirect(info.message)
|
|
.withStyle(info.message.equals("track.second_point") ? ChatFormatting.WHITE : ChatFormatting.RED),
|
|
true);
|
|
|
|
if (bhr.getDirection() == Direction.UP) {
|
|
Vec3 lookVec = player.getLookAngle();
|
|
int lookAngle = (int) (22.5 + AngleHelper.deg(Mth.atan2(lookVec.z, lookVec.x)) % 360) / 8;
|
|
|
|
if (!pos.equals(hintPos) || lookAngle != hintAngle) {
|
|
hints = Couple.create(ArrayList::new);
|
|
hintAngle = lookAngle;
|
|
hintPos = pos;
|
|
|
|
for (int xOffset = -2; xOffset <= 2; xOffset++) {
|
|
for (int zOffset = -2; zOffset <= 2; zOffset++) {
|
|
BlockPos offset = pos.offset(xOffset, 0, zOffset);
|
|
PlacementInfo adjInfo = tryConnect(level, player, offset, hitState, stack, false, maxTurns);
|
|
hints.get(adjInfo.valid)
|
|
.add(offset.below());
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hints != null && !hints.either(Collection::isEmpty)) {
|
|
CreateClient.OUTLINER.showCluster("track_valid", hints.getFirst())
|
|
.withFaceTexture(AllSpecialTextures.THIN_CHECKERED)
|
|
.colored(0x95CD41)
|
|
.lineWidth(0);
|
|
CreateClient.OUTLINER.showCluster("track_invalid", hints.getSecond())
|
|
.withFaceTexture(AllSpecialTextures.THIN_CHECKERED)
|
|
.colored(0xEA5C2B)
|
|
.lineWidth(0);
|
|
}
|
|
}
|
|
|
|
animation.chase(info.valid ? 1 : 0, 0.25, Chaser.EXP);
|
|
animation.tickChaser();
|
|
|
|
if (!info.valid) {
|
|
info.end1Extent = 0;
|
|
info.end2Extent = 0;
|
|
}
|
|
|
|
int color = Color.mixColors(0xEA5C2B, 0x95CD41, animation.getValue());
|
|
Vec3 up = new Vec3(0, 4 / 16f, 0);
|
|
|
|
{
|
|
Vec3 v1 = info.end1;
|
|
Vec3 a1 = info.axis1.normalize();
|
|
Vec3 n1 = info.normal1.cross(a1)
|
|
.scale(15 / 16f);
|
|
Vec3 o1 = a1.scale(0.125f);
|
|
Vec3 ex1 =
|
|
a1.scale((info.end1Extent - (info.curve == null && info.end1Extent > 0 ? 2 : 0)) * info.axis1.length());
|
|
line(1, v1.add(n1)
|
|
.add(up), o1, ex1);
|
|
line(2, v1.subtract(n1)
|
|
.add(up), o1, ex1);
|
|
|
|
Vec3 v2 = info.end2;
|
|
Vec3 a2 = info.axis2.normalize();
|
|
Vec3 n2 = info.normal2.cross(a2)
|
|
.scale(15 / 16f);
|
|
Vec3 o2 = a2.scale(0.125f);
|
|
Vec3 ex2 = a2.scale(info.end2Extent * info.axis2.length());
|
|
line(3, v2.add(n2)
|
|
.add(up), o2, ex2);
|
|
line(4, v2.subtract(n2)
|
|
.add(up), o2, ex2);
|
|
}
|
|
|
|
BezierConnection bc = info.curve;
|
|
if (bc == null)
|
|
return;
|
|
|
|
Vec3 previous1 = null;
|
|
Vec3 previous2 = null;
|
|
int railcolor = color;
|
|
int segCount = bc.getSegmentCount();
|
|
|
|
float s = animation.getValue() * 7 / 8f + 1 / 8f;
|
|
float lw = animation.getValue() * 1 / 16f + 1 / 16f;
|
|
Vec3 end1 = bc.starts.getFirst();
|
|
Vec3 end2 = bc.starts.getSecond();
|
|
Vec3 finish1 = end1.add(bc.axes.getFirst()
|
|
.scale(bc.getHandleLength()));
|
|
Vec3 finish2 = end2.add(bc.axes.getSecond()
|
|
.scale(bc.getHandleLength()));
|
|
String key = "curve";
|
|
|
|
for (int i = 0; i <= segCount; i++) {
|
|
float t = i / (float) segCount;
|
|
Vec3 result = VecHelper.bezier(end1, end2, finish1, finish2, t);
|
|
Vec3 derivative = VecHelper.bezierDerivative(end1, end2, finish1, finish2, t)
|
|
.normalize();
|
|
Vec3 normal = bc.getNormal(t)
|
|
.cross(derivative)
|
|
.scale(15 / 16f);
|
|
Vec3 rail1 = result.add(normal)
|
|
.add(up);
|
|
Vec3 rail2 = result.subtract(normal)
|
|
.add(up);
|
|
|
|
if (previous1 != null) {
|
|
Vec3 middle1 = rail1.add(previous1)
|
|
.scale(0.5f);
|
|
Vec3 middle2 = rail2.add(previous2)
|
|
.scale(0.5f);
|
|
CreateClient.OUTLINER
|
|
.showLine(Pair.of(key, i * 2), VecHelper.lerp(s, middle1, previous1),
|
|
VecHelper.lerp(s, middle1, rail1))
|
|
.colored(railcolor)
|
|
.disableLineNormals()
|
|
.lineWidth(lw);
|
|
CreateClient.OUTLINER
|
|
.showLine(Pair.of(key, i * 2 + 1), VecHelper.lerp(s, middle2, previous2),
|
|
VecHelper.lerp(s, middle2, rail2))
|
|
.colored(railcolor)
|
|
.disableLineNormals()
|
|
.lineWidth(lw);
|
|
}
|
|
|
|
previous1 = rail1;
|
|
previous2 = rail2;
|
|
}
|
|
|
|
for (int i = segCount + 1; i <= lastLineCount; i++) {
|
|
CreateClient.OUTLINER.remove(Pair.of(key, i * 2));
|
|
CreateClient.OUTLINER.remove(Pair.of(key, i * 2 + 1));
|
|
}
|
|
|
|
lastLineCount = segCount;
|
|
}
|
|
|
|
@OnlyIn(Dist.CLIENT)
|
|
private static void line(int id, Vec3 v1, Vec3 o1, Vec3 ex) {
|
|
int color = Color.mixColors(0xEA5C2B, 0x95CD41, animation.getValue());
|
|
CreateClient.OUTLINER.showLine(Pair.of("start", id), v1.subtract(o1), v1.add(ex))
|
|
.lineWidth(1 / 8f)
|
|
.disableLineNormals()
|
|
.colored(color);
|
|
}
|
|
|
|
}
|