From 1f06034b47d6aabd86196e3673e6fafba9262a36 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Fri, 23 Sep 2022 23:04:49 +0200 Subject: [PATCH] Order of Interact - Fixed entity-specific interactions causing schedule interaction to be ignored - Fixed viewport jittering when pressing movement keys while seated - Fixed players dismounting trains/minecart contraptions causing them to be placed at incorrect locations --- .../AbstractContraptionEntity.java | 27 +++++-- .../structureMovement/ContraptionHandler.java | 16 ++--- .../sync/ContraptionSeatMappingPacket.java | 21 ++++++ .../management/schedule/ScheduleItem.java | 4 +- ...ava => ScheduleItemEntityInteraction.java} | 71 +++++++++++++------ .../EntityContraptionInteractionMixin.java | 2 + 6 files changed, 97 insertions(+), 44 deletions(-) rename src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/{ScheduleItemRetrieval.java => ScheduleItemEntityInteraction.java} (55%) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java index f36dda9b8..00af0d452 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/AbstractContraptionEntity.java @@ -33,6 +33,7 @@ import com.simibubi.create.content.curiosities.deco.SlidingDoorBlock; import com.simibubi.create.content.logistics.trains.entity.CarriageContraption; import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity; import com.simibubi.create.content.logistics.trains.entity.Train; +import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.collision.Matrix3d; import com.simibubi.create.foundation.mixin.accessor.ServerLevelAccessor; import com.simibubi.create.foundation.networking.AllPackets; @@ -181,16 +182,28 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit contraption.getSeatMapping() .remove(passenger.getUUID()); AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this), - new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping())); + new ContraptionSeatMappingPacket(getId(), contraption.getSeatMapping(), passenger.getId())); } @Override - public Vec3 getDismountLocationForPassenger(LivingEntity pLivingEntity) { - Vec3 loc = super.getDismountLocationForPassenger(pLivingEntity); - CompoundTag data = pLivingEntity.getPersistentData(); + public Vec3 getDismountLocationForPassenger(LivingEntity entityLiving) { + Vec3 position = super.getDismountLocationForPassenger(entityLiving); + CompoundTag data = entityLiving.getPersistentData(); if (!data.contains("ContraptionDismountLocation")) - return loc; - return VecHelper.readNBT(data.getList("ContraptionDismountLocation", Tag.TAG_DOUBLE)); + return position; + + position = VecHelper.readNBT(data.getList("ContraptionDismountLocation", Tag.TAG_DOUBLE)); + data.remove("ContraptionDismountLocation"); + entityLiving.setOnGround(false); + + if (!data.contains("ContraptionMountLocation")) + return position; + + Vec3 prevPosition = VecHelper.readNBT(data.getList("ContraptionMountLocation", Tag.TAG_DOUBLE)); + data.remove("ContraptionMountLocation"); + if (entityLiving instanceof Player player && !prevPosition.closerThan(position, 5000)) + AllAdvancements.LONG_TRAVEL.awardTo(player); + return position; } @Override @@ -204,7 +217,7 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit transformedVector.y + SeatEntity.getCustomEntitySeatOffset(passenger) - 1 / 8f, transformedVector.z); } - protected Vec3 getPassengerPosition(Entity passenger, float partialTicks) { + public Vec3 getPassengerPosition(Entity passenger, float partialTicks) { UUID id = passenger.getUUID(); if (passenger instanceof OrientedContraptionEntity) { BlockPos localPos = contraption.getBearingPosOf(id); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java index 84f6b2a49..298e9d596 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionHandler.java @@ -7,7 +7,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; -import com.simibubi.create.foundation.advancement.AllAdvancements; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.WorldAttached; @@ -17,7 +16,6 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.entity.player.Player; import net.minecraft.world.level.Level; import net.minecraft.world.phys.Vec3; @@ -65,24 +63,18 @@ public class ContraptionHandler { } public static void entitiesWhoJustDismountedGetSentToTheRightLocation(LivingEntity entityLiving, Level world) { - if (world.isClientSide) + if (!world.isClientSide) return; + CompoundTag data = entityLiving.getPersistentData(); if (!data.contains("ContraptionDismountLocation")) return; + Vec3 position = VecHelper.readNBT(data.getList("ContraptionDismountLocation", Tag.TAG_DOUBLE)); if (entityLiving.getVehicle() == null) - entityLiving.teleportTo(position.x, position.y, position.z); + entityLiving.absMoveTo(position.x, position.y, position.z, entityLiving.getYRot(), entityLiving.getXRot()); data.remove("ContraptionDismountLocation"); entityLiving.setOnGround(false); - - if (!data.contains("ContraptionMountLocation")) - return; - Vec3 prevPosition = VecHelper.readNBT(data.getList("ContraptionMountLocation", Tag.TAG_DOUBLE)); - data.remove("ContraptionMountLocation"); - - if (entityLiving instanceof Player player && !prevPosition.closerThan(position, 5000)) - AllAdvancements.LONG_TRAVEL.awardTo(player); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java index 42c6c1793..ac2582af3 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/sync/ContraptionSeatMappingPacket.java @@ -7,24 +7,33 @@ import java.util.function.Supplier; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.foundation.networking.SimplePacketBase; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.Minecraft; import net.minecraft.network.FriendlyByteBuf; import net.minecraft.world.entity.Entity; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.network.NetworkEvent.Context; public class ContraptionSeatMappingPacket extends SimplePacketBase { private Map mapping; private int entityID; + private int dismountedID; public ContraptionSeatMappingPacket(int entityID, Map mapping) { + this(entityID, mapping, -1); + } + + public ContraptionSeatMappingPacket(int entityID, Map mapping, int dismountedID) { this.entityID = entityID; this.mapping = mapping; + this.dismountedID = dismountedID; } public ContraptionSeatMappingPacket(FriendlyByteBuf buffer) { entityID = buffer.readInt(); + dismountedID = buffer.readInt(); mapping = new HashMap<>(); short size = buffer.readShort(); for (int i = 0; i < size; i++) @@ -34,6 +43,7 @@ public class ContraptionSeatMappingPacket extends SimplePacketBase { @Override public void write(FriendlyByteBuf buffer) { buffer.writeInt(entityID); + buffer.writeInt(dismountedID); buffer.writeShort(mapping.size()); mapping.forEach((k, v) -> { buffer.writeUUID(k); @@ -49,6 +59,17 @@ public class ContraptionSeatMappingPacket extends SimplePacketBase { if (!(entityByID instanceof AbstractContraptionEntity)) return; AbstractContraptionEntity contraptionEntity = (AbstractContraptionEntity) entityByID; + + if (dismountedID != -1) { + Entity dismountedByID = Minecraft.getInstance().level.getEntity(dismountedID); + if (Minecraft.getInstance().player != dismountedByID) + return; + Vec3 transformedVector = contraptionEntity.getPassengerPosition(dismountedByID, 1); + if (transformedVector != null) + dismountedByID.getPersistentData() + .put("ContraptionDismountLocation", VecHelper.writeNBT(transformedVector)); + } + contraptionEntity.getContraption() .setSeatMapping(mapping); }); diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItem.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItem.java index 66700cd8e..c103d2768 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItem.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItem.java @@ -66,8 +66,7 @@ public class ScheduleItem extends Item implements MenuProvider { return InteractionResultHolder.pass(heldItem); } - @Override - public InteractionResult interactLivingEntity(ItemStack pStack, Player pPlayer, LivingEntity pInteractionTarget, + public InteractionResult handScheduleTo(ItemStack pStack, Player pPlayer, LivingEntity pInteractionTarget, InteractionHand pUsedHand) { InteractionResult pass = InteractionResult.PASS; @@ -123,6 +122,7 @@ public class ScheduleItem extends Item implements MenuProvider { pStack.shrink(1); pPlayer.setItemInHand(pUsedHand, pStack.isEmpty() ? ItemStack.EMPTY : pStack); } + return InteractionResult.SUCCESS; } diff --git a/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItemRetrieval.java b/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItemEntityInteraction.java similarity index 55% rename from src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItemRetrieval.java rename to src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItemEntityInteraction.java index 3ff2d3395..f72275ffd 100644 --- a/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItemRetrieval.java +++ b/src/main/java/com/simibubi/create/content/logistics/trains/management/schedule/ScheduleItemEntityInteraction.java @@ -11,19 +11,20 @@ import com.simibubi.create.foundation.utility.Lang; import net.minecraft.core.BlockPos; import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.animal.Wolf; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; -import net.minecraftforge.event.entity.player.PlayerInteractEvent.EntityInteract; +import net.minecraftforge.event.entity.player.PlayerInteractEvent.EntityInteractSpecific; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.common.Mod.EventBusSubscriber; @EventBusSubscriber -public class ScheduleItemRetrieval { +public class ScheduleItemEntityInteraction { @SubscribeEvent - public static void removeScheduleFromConductor(EntityInteract event) { + public static void interactWithConductor(EntityInteractSpecific event) { Entity entity = event.getTarget(); Player player = event.getPlayer(); if (player == null || entity == null) @@ -34,16 +35,24 @@ public class ScheduleItemRetrieval { Entity rootVehicle = entity.getRootVehicle(); if (!(rootVehicle instanceof CarriageContraptionEntity)) return; + if (!(entity instanceof LivingEntity living)) + return; + if (player.getCooldowns() + .isOnCooldown(AllItems.SCHEDULE.get())) + return; ItemStack itemStack = event.getItemStack(); - if (AllItems.SCHEDULE.isIn(itemStack) && entity instanceof Wolf wolf) { - itemStack.getItem() - .interactLivingEntity(itemStack, player, wolf, event.getHand()); - return; + if (itemStack.getItem()instanceof ScheduleItem si) { + InteractionResult result = si.handScheduleTo(itemStack, player, living, event.getHand()); + if (result.consumesAction()) { + player.getCooldowns() + .addCooldown(AllItems.SCHEDULE.get(), 5); + event.setCancellationResult(result); + event.setCanceled(true); + return; + } } - if (player.level.isClientSide) - return; if (event.getHand() == InteractionHand.OFF_HAND) return; @@ -68,31 +77,47 @@ public class ScheduleItemRetrieval { if (directions == null) return; + boolean onServer = !event.getWorld().isClientSide; + if (train.runtime.paused && !train.runtime.completed) { - train.runtime.paused = false; - AllSoundEvents.CONFIRM.playOnServer(player.level, player.blockPosition(), 1, 1); - player.displayClientMessage(Lang.translateDirect("schedule.continued"), true); + if (onServer) { + train.runtime.paused = false; + AllSoundEvents.CONFIRM.playOnServer(player.level, player.blockPosition(), 1, 1); + player.displayClientMessage(Lang.translateDirect("schedule.continued"), true); + } + + player.getCooldowns() + .addCooldown(AllItems.SCHEDULE.get(), 5); + event.setCancellationResult(InteractionResult.SUCCESS); event.setCanceled(true); return; } ItemStack itemInHand = player.getItemInHand(event.getHand()); if (!itemInHand.isEmpty()) { - AllSoundEvents.DENY.playOnServer(player.level, player.blockPosition(), 1, 1); - player.displayClientMessage(Lang.translateDirect("schedule.remove_with_empty_hand"), true); + if (onServer) { + AllSoundEvents.DENY.playOnServer(player.level, player.blockPosition(), 1, 1); + player.displayClientMessage(Lang.translateDirect("schedule.remove_with_empty_hand"), true); + } + event.setCancellationResult(InteractionResult.SUCCESS); event.setCanceled(true); return; } - AllSoundEvents.playItemPickup(player); - player.displayClientMessage( - Lang.translateDirect( - train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"), - true); + if (onServer) { + AllSoundEvents.playItemPickup(player); + player.displayClientMessage( + Lang.translateDirect( + train.runtime.isAutoSchedule ? "schedule.auto_removed_from_train" : "schedule.removed_from_train"), + true); - player.getInventory() - .placeItemBackInInventory(train.runtime.returnSchedule()); -// player.setItemInHand(event.getHand(), train.runtime.returnSchedule()); + player.getInventory() + .placeItemBackInInventory(train.runtime.returnSchedule()); + } + + player.getCooldowns() + .addCooldown(AllItems.SCHEDULE.get(), 5); + event.setCancellationResult(InteractionResult.SUCCESS); event.setCanceled(true); return; } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/EntityContraptionInteractionMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/EntityContraptionInteractionMixin.java index efc48643b..27fe5f5cb 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/EntityContraptionInteractionMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/EntityContraptionInteractionMixin.java @@ -115,6 +115,8 @@ public abstract class EntityContraptionInteractionMixin extends CapabilityProvid return; if (self.isOnGround()) return; + if (self.isPassenger()) + return; Vec3 worldPos = self.position() .add(0, -0.2, 0);