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
This commit is contained in:
parent
4d4a959cfa
commit
1f06034b47
6 changed files with 97 additions and 44 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<UUID, Integer> mapping;
|
||||
private int entityID;
|
||||
private int dismountedID;
|
||||
|
||||
public ContraptionSeatMappingPacket(int entityID, Map<UUID, Integer> mapping) {
|
||||
this(entityID, mapping, -1);
|
||||
}
|
||||
|
||||
public ContraptionSeatMappingPacket(int entityID, Map<UUID, Integer> 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);
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue