- Holding ctrl while placing track curves causes it to choose the biggest possible radius
This commit is contained in:
simibubi 2022-04-16 20:30:11 +02:00
parent 5c9f2c66ab
commit 423bb407f7
8 changed files with 120 additions and 25 deletions

View file

@ -4,7 +4,6 @@ import org.apache.commons.lang3.mutable.MutableObject;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllSoundEvents; 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.management.edgePoint.TrackTargetingBlockItem.OverlapResult;
import com.simibubi.create.content.logistics.trains.track.BezierTrackPointLocation; import com.simibubi.create.content.logistics.trains.track.BezierTrackPointLocation;
import com.simibubi.create.content.logistics.trains.track.TrackTileEntity; import com.simibubi.create.content.logistics.trains.track.TrackTileEntity;
@ -56,12 +55,6 @@ public class CurvedTrackSelectionPacket extends TileEntityConfigurationPacket<Tr
@Override @Override
protected void applySettings(ServerPlayer player, TrackTileEntity te) { protected void applySettings(ServerPlayer player, TrackTileEntity te) {
if (!te.getBlockPos()
.closerThan(player.blockPosition(), 48)) {
Create.LOGGER.warn(player.getScoreboardName() + " too far away from targeted track");
return;
}
if (player.getInventory().selected != slot) if (player.getInventory().selected != slot)
return; return;
ItemStack stack = player.getInventory() ItemStack stack = player.getInventory()
@ -102,6 +95,11 @@ public class CurvedTrackSelectionPacket extends TileEntityConfigurationPacket<Tr
AllSoundEvents.CONTROLLER_CLICK.play(player.level, null, pos, 1, 1); AllSoundEvents.CONTROLLER_CLICK.play(player.level, null, pos, 1, 1);
} }
@Override
protected int maxRange() {
return 64;
}
@Override @Override
protected void applySettings(TrackTileEntity te) {} protected void applySettings(TrackTileEntity te) {}

View file

@ -108,13 +108,15 @@ public class TrackTargetingBlockItem extends BlockItem {
BlockPos placedPos = pos.relative(pContext.getClickedFace(), state.getMaterial() BlockPos placedPos = pos.relative(pContext.getClickedFace(), state.getMaterial()
.isReplaceable() ? 0 : 1); .isReplaceable() ? 0 : 1);
if (!selectedPos.closerThan(placedPos, 16)) { boolean bezier = tag.contains("Bezier");
if (!selectedPos.closerThan(placedPos, bezier ? 64 + 16 : 16)) {
player.displayClientMessage(Lang.translate("track_target.too_far") player.displayClientMessage(Lang.translate("track_target.too_far")
.withStyle(ChatFormatting.RED), true); .withStyle(ChatFormatting.RED), true);
return InteractionResult.FAIL; return InteractionResult.FAIL;
} }
if (tag.contains("Bezier")) if (bezier)
teTag.put("Bezier", tag.getCompound("Bezier")); teTag.put("Bezier", tag.getCompound("Bezier"));
teTag.put("TargetTrack", NbtUtils.writeBlockPos(selectedPos.subtract(placedPos))); teTag.put("TargetTrack", NbtUtils.writeBlockPos(selectedPos.subtract(placedPos)));

View file

@ -42,7 +42,7 @@ public class CurvedTrackDestroyPacket extends TileEntityConfigurationPacket<Trac
@Override @Override
protected void applySettings(ServerPlayer player, TrackTileEntity te) { protected void applySettings(ServerPlayer player, TrackTileEntity te) {
if (!te.getBlockPos() if (!te.getBlockPos()
.closerThan(player.blockPosition(), 48)) { .closerThan(player.blockPosition(), 128)) {
Create.LOGGER.warn(player.getScoreboardName() + " too far away from destroyed Curve track"); Create.LOGGER.warn(player.getScoreboardName() + " too far away from destroyed Curve track");
return; return;
} }
@ -63,6 +63,11 @@ public class CurvedTrackDestroyPacket extends TileEntityConfigurationPacket<Trac
(soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F); (soundtype.getVolume() + 1.0F) / 2.0F, soundtype.getPitch() * 0.8F);
} }
@Override
protected int maxRange() {
return 64;
}
@Override @Override
protected void applySettings(TrackTileEntity te) {} protected void applySettings(TrackTileEntity te) {}

View file

@ -0,0 +1,51 @@
package com.simibubi.create.content.logistics.trains.track;
import java.util.function.Supplier;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.item.ItemStack;
import net.minecraftforge.network.NetworkEvent.Context;
public class PlaceExtendedCurvePacket extends SimplePacketBase {
boolean mainHand;
boolean ctrlDown;
public PlaceExtendedCurvePacket(boolean mainHand, boolean ctrlDown) {
this.mainHand = mainHand;
this.ctrlDown = ctrlDown;
}
public PlaceExtendedCurvePacket(FriendlyByteBuf buffer) {
mainHand = buffer.readBoolean();
ctrlDown = buffer.readBoolean();
}
@Override
public void write(FriendlyByteBuf buffer) {
buffer.writeBoolean(mainHand);
buffer.writeBoolean(ctrlDown);
}
@Override
public void handle(Supplier<Context> 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);
}
}

View file

@ -3,16 +3,19 @@ package com.simibubi.create.content.logistics.trains.track;
import com.simibubi.create.AllBlocks; import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.logistics.trains.ITrackBlock; import com.simibubi.create.content.logistics.trains.ITrackBlock;
import com.simibubi.create.content.logistics.trains.track.TrackPlacement.PlacementInfo; 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.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair; import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.ChatFormatting; import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction.AxisDirection; import net.minecraft.core.Direction.AxisDirection;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtUtils; import net.minecraft.nbt.NbtUtils;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.BlockItem; 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.EntityBlock;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3; 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 class TrackBlockItem extends BlockItem {
public TrackBlockItem(Block pBlock, Properties pProperties) { public TrackBlockItem(Block pBlock, Properties pProperties) {
@ -67,6 +76,10 @@ public class TrackBlockItem extends BlockItem {
} }
boolean placing = !(state.getBlock() instanceof ITrackBlock); boolean placing = !(state.getBlock() instanceof ITrackBlock);
CompoundTag tag = stack.getTag();
boolean extend = tag.getBoolean("ExtendCurve");
tag.remove("ExtendCurve");
if (placing) { if (placing) {
if (!state.getMaterial() if (!state.getMaterial()
.isReplaceable()) .isReplaceable())
@ -77,8 +90,8 @@ public class TrackBlockItem extends BlockItem {
} }
ItemStack offhandItem = player.getOffhandItem(); ItemStack offhandItem = player.getOffhandItem();
PlacementInfo info = boolean hasGirder = AllBlocks.METAL_GIRDER.isIn(offhandItem);
TrackPlacement.tryConnect(level, pos, state, lookAngle, stack, AllBlocks.METAL_GIRDER.isIn(offhandItem)); PlacementInfo info = TrackPlacement.tryConnect(level, pos, state, lookAngle, stack, hasGirder, extend);
if (info.message != null && !level.isClientSide) if (info.message != null && !level.isClientSide)
player.displayClientMessage(Lang.translate(info.message), true); player.displayClientMessage(Lang.translate(info.message), true);
@ -87,7 +100,7 @@ public class TrackBlockItem extends BlockItem {
stack.setTag(null); stack.setTag(null);
if (level.isClientSide) if (level.isClientSide)
return InteractionResult.SUCCESS; return InteractionResult.SUCCESS;
if (offhandItem.getItem() instanceof BlockItem blockItem) { if (offhandItem.getItem() instanceof BlockItem blockItem) {
@ -137,6 +150,17 @@ public class TrackBlockItem extends BlockItem {
return true; 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 @Override
public boolean isFoil(ItemStack stack) { public boolean isFoil(ItemStack stack) {
return stack.hasTag() && stack.getTag() return stack.hasTag() && stack.getTag()

View file

@ -75,15 +75,21 @@ public class TrackPlacement {
static PlacementInfo cached; static PlacementInfo cached;
static BlockPos hoveringPos; static BlockPos hoveringPos;
static boolean hoveringMaxed;
static int hoveringAngle;
static ItemStack lastItem; static ItemStack lastItem;
public static PlacementInfo tryConnect(Level level, BlockPos pos2, BlockState state2, Vec3 lookVec, ItemStack stack, 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; return cached;
PlacementInfo info = new PlacementInfo(); PlacementInfo info = new PlacementInfo();
hoveringMaxed = maximiseTurn;
hoveringAngle = lookAngle;
hoveringPos = pos2; hoveringPos = pos2;
lastItem = stack; lastItem = stack;
cached = info; cached = info;
@ -200,8 +206,8 @@ public class TrackPlacement {
// This is for standardising s curve sizes // This is for standardising s curve sizes
if (t > targetT) { if (t > targetT) {
int correction = (int) ((t - targetT) / axis1.length()); int correction = (int) ((t - targetT) / axis1.length());
info.end1Extent = correction / 2 + (correction % 2); info.end1Extent = maximiseTurn ? 0 : correction / 2 + (correction % 2);
info.end2Extent = correction / 2; info.end2Extent = maximiseTurn ? 0 : correction / 2;
} }
} }
} }
@ -240,7 +246,7 @@ public class TrackPlacement {
return info.withMessage("too_sharp"); return info.withMessage("too_sharp");
// This is for standardising curve sizes // This is for standardising curve sizes
if (turnSize > 2) { if (turnSize > 2 && !maximiseTurn) {
info.end1Extent += turnSize - 2; info.end1Extent += turnSize - 2;
info.end2Extent += turnSize - 2; info.end2Extent += turnSize - 2;
turnSize = 2; turnSize = 2;
@ -258,8 +264,8 @@ public class TrackPlacement {
return info.withMessage("too_steep"); return info.withMessage("too_steep");
if (hDistance > minHDistance) { if (hDistance > minHDistance) {
int correction = (int) (hDistance - minHDistance); int correction = (int) (hDistance - minHDistance);
info.end1Extent = correction / 2 + (correction % 2); info.end1Extent = maximiseTurn ? 0 : correction / 2 + (correction % 2);
info.end2Extent = correction / 2; info.end2Extent = maximiseTurn ? 0 : correction / 2;
} }
skipCurve = false; skipCurve = false;
@ -302,8 +308,10 @@ public class TrackPlacement {
return info.withMessage("too_steep"); return info.withMessage("too_steep");
// This is for standardising curve sizes // This is for standardising curve sizes
ex1 += (turnSize - turnSizeToFitAscend) / axis1.length(); if (!maximiseTurn) {
ex2 += (turnSize - turnSizeToFitAscend) / axis2.length(); ex1 += (turnSize - turnSizeToFitAscend) / axis1.length();
ex2 += (turnSize - turnSizeToFitAscend) / axis2.length();
}
info.end1Extent = Mth.floor(ex1); info.end1Extent = Mth.floor(ex1);
info.end2Extent = Mth.floor(ex2); info.end2Extent = Mth.floor(ex2);
turnSize = turnSizeToFitAscend; turnSize = turnSizeToFitAscend;
@ -418,7 +426,8 @@ public class TrackPlacement {
if (!(hitState.getBlock() instanceof TrackBlock)) if (!(hitState.getBlock() instanceof TrackBlock))
return; 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) if (info.valid)
player.displayClientMessage(Lang.translate("track.valid_connection") player.displayClientMessage(Lang.translate("track.valid_connection")
@ -437,7 +446,7 @@ public class TrackPlacement {
for (int zOffset = -2; zOffset <= 2; zOffset++) { for (int zOffset = -2; zOffset <= 2; zOffset++) {
BlockPos offset = pos.offset(xOffset, 0, zOffset); BlockPos offset = pos.offset(xOffset, 0, zOffset);
PlacementInfo adjInfo = PlacementInfo adjInfo =
tryConnect(level, offset, hitState, player.getLookAngle(), stack, false); tryConnect(level, offset, hitState, player.getLookAngle(), stack, false, maxTurns);
hints.get(adjInfo.valid) hints.get(adjInfo.valid)
.add(offset.below()); .add(offset.below());
} }

View file

@ -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.edgePoint.station.TrainEditPacket.TrainEditReturnPacket;
import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket; import com.simibubi.create.content.logistics.trains.management.schedule.ScheduleEditPacket;
import com.simibubi.create.content.logistics.trains.track.CurvedTrackDestroyPacket; 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.logistics.trains.track.TrackRemovalPacket;
import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket; import com.simibubi.create.content.schematics.packet.ConfigureSchematicannonPacket;
import com.simibubi.create.content.schematics.packet.InstantSchematicPacket; import com.simibubi.create.content.schematics.packet.InstantSchematicPacket;
@ -126,6 +127,7 @@ public enum AllPackets {
CONFIGURE_DATA_GATHERER(DataGathererConfigurationPacket.class, DataGathererConfigurationPacket::new, PLAY_TO_SERVER), CONFIGURE_DATA_GATHERER(DataGathererConfigurationPacket.class, DataGathererConfigurationPacket::new, PLAY_TO_SERVER),
DESTROY_CURVED_TRACK(CurvedTrackDestroyPacket.class, CurvedTrackDestroyPacket::new, PLAY_TO_SERVER), DESTROY_CURVED_TRACK(CurvedTrackDestroyPacket.class, CurvedTrackDestroyPacket::new, PLAY_TO_SERVER),
SELECT_CURVED_TRACK(CurvedTrackSelectionPacket.class, CurvedTrackSelectionPacket::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 // Server to Client
SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT), SYMMETRY_EFFECT(SymmetryEffectPacket.class, SymmetryEffectPacket::new, PLAY_TO_CLIENT),

View file

@ -42,7 +42,7 @@ public abstract class TileEntityConfigurationPacket<TE extends SyncedTileEntity>
Level world = player.level; Level world = player.level;
if (world == null || !world.isLoaded(pos)) if (world == null || !world.isLoaded(pos))
return; return;
if (!pos.closerThan(player.blockPosition(), 20)) if (!pos.closerThan(player.blockPosition(), maxRange()))
return; return;
BlockEntity tileEntity = world.getBlockEntity(pos); BlockEntity tileEntity = world.getBlockEntity(pos);
if (tileEntity instanceof SyncedTileEntity) { if (tileEntity instanceof SyncedTileEntity) {
@ -56,6 +56,10 @@ public abstract class TileEntityConfigurationPacket<TE extends SyncedTileEntity>
} }
protected int maxRange() {
return 20;
}
protected abstract void writeSettings(FriendlyByteBuf buffer); protected abstract void writeSettings(FriendlyByteBuf buffer);
protected abstract void readSettings(FriendlyByteBuf buffer); protected abstract void readSettings(FriendlyByteBuf buffer);