diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/CurvedTrackSelectionPacket.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/CurvedTrackSelectionPacket.java index 2cb285077..8e6e0aacc 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/CurvedTrackSelectionPacket.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/edgePoint/CurvedTrackSelectionPacket.java @@ -4,7 +4,6 @@ import org.apache.commons.lang3.mutable.MutableObject; import com.simibubi.create.AllBlocks; import com.simibubi.create.AllSoundEvents; -import com.simibubi.create.Create; import com.simibubi.create.content.logistics.trains.management.edgePoint.TrackTargetingBlockItem.OverlapResult; import com.simibubi.create.content.logistics.trains.track.BezierTrackPointLocation; import com.simibubi.create.content.logistics.trains.track.TrackTileEntity; @@ -56,12 +55,6 @@ public class CurvedTrackSelectionPacket extends TileEntityConfigurationPacket context) { + Context ctx = context.get(); + ctx.enqueueWork(() -> { + ServerPlayer sender = ctx.getSender(); + ItemStack stack = sender.getItemInHand(mainHand ? InteractionHand.MAIN_HAND : InteractionHand.OFF_HAND); + if (!AllBlocks.TRACK.isIn(stack) || !stack.hasTag()) + return; + CompoundTag tag = stack.getTag(); + tag.putBoolean("ExtendCurve", true); + stack.setTag(tag); + }); + ctx.setPacketHandled(true); + } + +} diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlockItem.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlockItem.java index 84bb35603..0a65a7fdb 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlockItem.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackBlockItem.java @@ -3,16 +3,19 @@ package com.simibubi.create.content.logistics.trains.track; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.track.TrackPlacement.PlacementInfo; +import com.simibubi.create.foundation.networking.AllPackets; 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 net.minecraft.ChatFormatting; +import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction.AxisDirection; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; +import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.BlockItem; @@ -25,7 +28,13 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; +@EventBusSubscriber(Dist.CLIENT) public class TrackBlockItem extends BlockItem { public TrackBlockItem(Block pBlock, Properties pProperties) { @@ -67,6 +76,10 @@ public class TrackBlockItem extends BlockItem { } boolean placing = !(state.getBlock() instanceof ITrackBlock); + CompoundTag tag = stack.getTag(); + boolean extend = tag.getBoolean("ExtendCurve"); + tag.remove("ExtendCurve"); + if (placing) { if (!state.getMaterial() .isReplaceable()) @@ -77,8 +90,8 @@ public class TrackBlockItem extends BlockItem { } ItemStack offhandItem = player.getOffhandItem(); - PlacementInfo info = - TrackPlacement.tryConnect(level, pos, state, lookAngle, stack, AllBlocks.METAL_GIRDER.isIn(offhandItem)); + boolean hasGirder = AllBlocks.METAL_GIRDER.isIn(offhandItem); + PlacementInfo info = TrackPlacement.tryConnect(level, pos, state, lookAngle, stack, hasGirder, extend); if (info.message != null && !level.isClientSide) player.displayClientMessage(Lang.translate(info.message), true); @@ -87,7 +100,7 @@ public class TrackBlockItem extends BlockItem { stack.setTag(null); - if (level.isClientSide) + if (level.isClientSide) return InteractionResult.SUCCESS; if (offhandItem.getItem() instanceof BlockItem blockItem) { @@ -137,6 +150,17 @@ public class TrackBlockItem extends BlockItem { return true; } + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void sendExtenderPacket(PlayerInteractEvent.RightClickBlock event) { + ItemStack stack = event.getItemStack(); + if (!AllBlocks.TRACK.isIn(stack) || !stack.hasTag()) + return; + if (Minecraft.getInstance().options.keySprint.isDown()) + AllPackets.channel + .sendToServer(new PlaceExtendedCurvePacket(event.getHand() == InteractionHand.MAIN_HAND, true)); + } + @Override public boolean isFoil(ItemStack stack) { return stack.hasTag() && stack.getTag() diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackPlacement.java b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackPlacement.java index d44fc7617..3b4795669 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackPlacement.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/track/TrackPlacement.java @@ -75,15 +75,21 @@ public class TrackPlacement { static PlacementInfo cached; static BlockPos hoveringPos; + static boolean hoveringMaxed; + static int hoveringAngle; static ItemStack lastItem; public static PlacementInfo tryConnect(Level level, BlockPos pos2, BlockState state2, Vec3 lookVec, ItemStack stack, - boolean girder) { + boolean girder, boolean maximiseTurn) { + int lookAngle = (int) (22.5 + AngleHelper.deg(Mth.atan2(lookVec.z, lookVec.x)) % 360) / 8; - if (cached != null && pos2.equals(hoveringPos) && stack.equals(lastItem)) + if (level.isClientSide && cached != null && pos2.equals(hoveringPos) && stack.equals(lastItem) + && hoveringMaxed == maximiseTurn && lookAngle == hoveringAngle) return cached; PlacementInfo info = new PlacementInfo(); + hoveringMaxed = maximiseTurn; + hoveringAngle = lookAngle; hoveringPos = pos2; lastItem = stack; cached = info; @@ -200,8 +206,8 @@ public class TrackPlacement { // This is for standardising s curve sizes if (t > targetT) { int correction = (int) ((t - targetT) / axis1.length()); - info.end1Extent = correction / 2 + (correction % 2); - info.end2Extent = correction / 2; + info.end1Extent = maximiseTurn ? 0 : correction / 2 + (correction % 2); + info.end2Extent = maximiseTurn ? 0 : correction / 2; } } } @@ -240,7 +246,7 @@ public class TrackPlacement { return info.withMessage("too_sharp"); // This is for standardising curve sizes - if (turnSize > 2) { + if (turnSize > 2 && !maximiseTurn) { info.end1Extent += turnSize - 2; info.end2Extent += turnSize - 2; turnSize = 2; @@ -258,8 +264,8 @@ public class TrackPlacement { return info.withMessage("too_steep"); if (hDistance > minHDistance) { int correction = (int) (hDistance - minHDistance); - info.end1Extent = correction / 2 + (correction % 2); - info.end2Extent = correction / 2; + info.end1Extent = maximiseTurn ? 0 : correction / 2 + (correction % 2); + info.end2Extent = maximiseTurn ? 0 : correction / 2; } skipCurve = false; @@ -302,8 +308,10 @@ public class TrackPlacement { return info.withMessage("too_steep"); // This is for standardising curve sizes - ex1 += (turnSize - turnSizeToFitAscend) / axis1.length(); - ex2 += (turnSize - turnSizeToFitAscend) / axis2.length(); + if (!maximiseTurn) { + ex1 += (turnSize - turnSizeToFitAscend) / axis1.length(); + ex2 += (turnSize - turnSizeToFitAscend) / axis2.length(); + } info.end1Extent = Mth.floor(ex1); info.end2Extent = Mth.floor(ex2); turnSize = turnSizeToFitAscend; @@ -418,7 +426,8 @@ public class TrackPlacement { if (!(hitState.getBlock() instanceof TrackBlock)) return; - PlacementInfo info = tryConnect(level, pos, hitState, player.getLookAngle(), stack, false); + boolean maxTurns = Minecraft.getInstance().options.keySprint.isDown(); + PlacementInfo info = tryConnect(level, pos, hitState, player.getLookAngle(), stack, false, maxTurns); if (info.valid) player.displayClientMessage(Lang.translate("track.valid_connection") @@ -437,7 +446,7 @@ public class TrackPlacement { for (int zOffset = -2; zOffset <= 2; zOffset++) { BlockPos offset = pos.offset(xOffset, 0, zOffset); PlacementInfo adjInfo = - tryConnect(level, offset, hitState, player.getLookAngle(), stack, false); + tryConnect(level, offset, hitState, player.getLookAngle(), stack, false, maxTurns); hints.get(adjInfo.valid) .add(offset.below()); } diff --git a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java index d412c64b7..45ad7bdfb 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java +++ b/src/main/java/com/simibubi/create/foundation/networking/AllPackets.java @@ -56,6 +56,7 @@ import com.simibubi.create.content.logistics.trains.management.edgePoint.station import com.simibubi.create.content.logistics.trains.management.edgePoint.station.TrainEditPacket.TrainEditReturnPacket; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket; import com.simibubi.create.content.logistics.trains.track.CurvedTrackDestroyPacket; +import com.simibubi.create.content.logistics.trains.track.PlaceExtendedCurvePacket; import com.simibubi.create.content.logistics.trains.track.TrackRemovalPacket; import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; @@ -126,6 +127,7 @@ public enum AllPackets { CONFIGURE_DATA_GATHERER(DataGathererConfigurationPacket.class, DataGathererConfigurationPacket::new, PLAY_TO_SERVER), DESTROY_CURVED_TRACK(CurvedTrackDestroyPacket.class, CurvedTrackDestroyPacket::new, PLAY_TO_SERVER), SELECT_CURVED_TRACK(CurvedTrackSelectionPacket.class, CurvedTrackSelectionPacket::new, PLAY_TO_SERVER), + PLACE_CURVED_TRACK(PlaceExtendedCurvePacket.class, PlaceExtendedCurvePacket::new, PLAY_TO_SERVER), // Server to Client SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), diff --git a/src/main/java/com/simibubi/create/foundation/networking/TileEntityConfigurationPacket.java b/src/main/java/com/simibubi/create/foundation/networking/TileEntityConfigurationPacket.java index b841b852a..c6f1c7856 100644 --- a/src/main/java/com/simibubi/create/foundation/networking/TileEntityConfigurationPacket.java +++ b/src/main/java/com/simibubi/create/foundation/networking/TileEntityConfigurationPacket.java @@ -42,7 +42,7 @@ public abstract class TileEntityConfigurationPacket Level world = player.level; if (world == null || !world.isLoaded(pos)) return; - if (!pos.closerThan(player.blockPosition(), 20)) + if (!pos.closerThan(player.blockPosition(), maxRange())) return; BlockEntity tileEntity = world.getBlockEntity(pos); if (tileEntity instanceof SyncedTileEntity) { @@ -56,6 +56,10 @@ public abstract class TileEntityConfigurationPacket } + protected int maxRange() { + return 20; + } + protected abstract void writeSettings(FriendlyByteBuf buffer); protected abstract void readSettings(FriendlyByteBuf buffer);