mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-14 06:24:29 +01:00
Banter on the Lift
- Pulley contraptions will now make an effort to place remote players at y values sensible to the client
This commit is contained in:
parent
ffa85dc889
commit
ce108ad786
@ -4,7 +4,10 @@ import static net.minecraft.world.entity.Entity.collideBoundingBox;
|
|||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
import org.apache.commons.lang3.mutable.MutableFloat;
|
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||||
@ -17,6 +20,7 @@ import com.simibubi.create.AllMovementBehaviours;
|
|||||||
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour;
|
import com.simibubi.create.content.contraptions.components.actors.BlockBreakingMovementBehaviour;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.HarvesterMovementBehaviour;
|
import com.simibubi.create.content.contraptions.components.actors.HarvesterMovementBehaviour;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity.ContraptionRotationState;
|
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity.ContraptionRotationState;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.sync.ClientMotionPacket;
|
||||||
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
import com.simibubi.create.content.logistics.trains.entity.CarriageContraptionEntity;
|
||||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||||
@ -30,7 +34,10 @@ import com.simibubi.create.foundation.utility.Iterate;
|
|||||||
import com.simibubi.create.foundation.utility.VecHelper;
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
import net.minecraft.client.multiplayer.ClientPacketListener;
|
||||||
import net.minecraft.client.player.LocalPlayer;
|
import net.minecraft.client.player.LocalPlayer;
|
||||||
|
import net.minecraft.client.player.RemotePlayer;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
import net.minecraft.core.Direction.Axis;
|
import net.minecraft.core.Direction.Axis;
|
||||||
@ -65,6 +72,7 @@ public class ContraptionCollider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static MutablePair<WeakReference<AbstractContraptionEntity>, Double> safetyLock = new MutablePair<>();
|
private static MutablePair<WeakReference<AbstractContraptionEntity>, Double> safetyLock = new MutablePair<>();
|
||||||
|
private static Map<AbstractContraptionEntity, Map<Player, Double>> remoteSafetyLocks = new WeakHashMap<>();
|
||||||
|
|
||||||
static void collideEntities(AbstractContraptionEntity contraptionEntity) {
|
static void collideEntities(AbstractContraptionEntity contraptionEntity) {
|
||||||
Level world = contraptionEntity.getCommandSenderWorld();
|
Level world = contraptionEntity.getCommandSenderWorld();
|
||||||
@ -95,8 +103,13 @@ public class ContraptionCollider {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
PlayerType playerType = getPlayerType(entity);
|
PlayerType playerType = getPlayerType(entity);
|
||||||
if (playerType == PlayerType.REMOTE)
|
if (playerType == PlayerType.REMOTE) {
|
||||||
|
if (!(contraption instanceof TranslatingContraption))
|
||||||
|
continue;
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||||
|
() -> () -> saveRemotePlayerFromClipping((Player) entity, contraptionEntity, contraptionMotion));
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
entity.getSelfAndPassengers()
|
entity.getSelfAndPassengers()
|
||||||
.forEach(e -> {
|
.forEach(e -> {
|
||||||
@ -354,7 +367,8 @@ public class ContraptionCollider {
|
|||||||
entity.fallDistance = 0;
|
entity.fallDistance = 0;
|
||||||
for (Entity rider : entity.getIndirectPassengers())
|
for (Entity rider : entity.getIndirectPassengers())
|
||||||
if (getPlayerType(rider) == PlayerType.CLIENT)
|
if (getPlayerType(rider) == PlayerType.CLIENT)
|
||||||
AllPackets.getChannel().sendToServer(new ClientMotionPacket(rider.getDeltaMovement(), true, 0));
|
AllPackets.getChannel()
|
||||||
|
.sendToServer(new ClientMotionPacket(rider.getDeltaMovement(), true, 0));
|
||||||
boolean canWalk = bounce != 0 || slide == 0;
|
boolean canWalk = bounce != 0 || slide == 0;
|
||||||
if (canWalk || !rotation.hasVerticalRotation()) {
|
if (canWalk || !rotation.hasVerticalRotation()) {
|
||||||
if (canWalk)
|
if (canWalk)
|
||||||
@ -378,7 +392,8 @@ public class ContraptionCollider {
|
|||||||
float limbSwing = Mth.sqrt((float) (d0 * d0 + d1 * d1)) * 4.0F;
|
float limbSwing = Mth.sqrt((float) (d0 * d0 + d1 * d1)) * 4.0F;
|
||||||
if (limbSwing > 1.0F)
|
if (limbSwing > 1.0F)
|
||||||
limbSwing = 1.0F;
|
limbSwing = 1.0F;
|
||||||
AllPackets.getChannel().sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
|
AllPackets.getChannel()
|
||||||
|
.sendToServer(new ClientMotionPacket(entityMotion, true, limbSwing));
|
||||||
|
|
||||||
if (entity.isOnGround() && contraption instanceof TranslatingContraption) {
|
if (entity.isOnGround() && contraption instanceof TranslatingContraption) {
|
||||||
safetyLock.setLeft(new WeakReference<>(contraptionEntity));
|
safetyLock.setLeft(new WeakReference<>(contraptionEntity));
|
||||||
@ -388,19 +403,32 @@ public class ContraptionCollider {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int packetCooldown = 0;
|
||||||
|
|
||||||
@OnlyIn(Dist.CLIENT)
|
@OnlyIn(Dist.CLIENT)
|
||||||
private static void saveClientPlayerFromClipping(AbstractContraptionEntity contraptionEntity,
|
private static void saveClientPlayerFromClipping(AbstractContraptionEntity contraptionEntity,
|
||||||
Vec3 contraptionMotion) {
|
Vec3 contraptionMotion) {
|
||||||
Player entity = Minecraft.getInstance().player;
|
LocalPlayer entity = Minecraft.getInstance().player;
|
||||||
|
|
||||||
if (entity.isPassenger())
|
if (entity.isPassenger())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
double prevDiff = safetyLock.right;
|
double prevDiff = safetyLock.right;
|
||||||
double currentDiff = entity.getY() - contraptionEntity.getY();
|
double currentDiff = entity.getY() - contraptionEntity.getY();
|
||||||
double motion = contraptionMotion.subtract(entity.getDeltaMovement()).y;
|
double motion = contraptionMotion.subtract(entity.getDeltaMovement()).y;
|
||||||
double trend = Math.signum(currentDiff - prevDiff);
|
double trend = Math.signum(currentDiff - prevDiff);
|
||||||
|
|
||||||
|
ClientPacketListener handler = entity.connection;
|
||||||
|
if (handler.getOnlinePlayers()
|
||||||
|
.size() > 1) {
|
||||||
|
if (packetCooldown > 0)
|
||||||
|
packetCooldown--;
|
||||||
|
if (packetCooldown == 0) {
|
||||||
|
AllPackets.getChannel()
|
||||||
|
.sendToServer(new ContraptionColliderLockPacketRequest(contraptionEntity.getId(), currentDiff));
|
||||||
|
packetCooldown = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (trend == 0)
|
if (trend == 0)
|
||||||
return;
|
return;
|
||||||
if (trend == Math.signum(motion))
|
if (trend == Math.signum(motion))
|
||||||
@ -412,10 +440,43 @@ public class ContraptionCollider {
|
|||||||
return;
|
return;
|
||||||
if (speed < 0.05)
|
if (speed < 0.05)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AABB bb = entity.getBoundingBox().deflate(1/4f, 0, 1/4f);
|
if (!savePlayerFromClipping(entity, contraptionEntity, contraptionMotion, prevDiff))
|
||||||
|
safetyLock.setLeft(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static void lockPacketReceived(int contraptionId, int remotePlayerId, double suggestedOffset) {
|
||||||
|
ClientLevel level = Minecraft.getInstance().level;
|
||||||
|
if (!(level.getEntity(contraptionId) instanceof ControlledContraptionEntity contraptionEntity))
|
||||||
|
return;
|
||||||
|
if (!(level.getEntity(remotePlayerId) instanceof RemotePlayer player))
|
||||||
|
return;
|
||||||
|
remoteSafetyLocks.computeIfAbsent(contraptionEntity, $ -> new WeakHashMap<>())
|
||||||
|
.put(player, suggestedOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private static void saveRemotePlayerFromClipping(Player entity, AbstractContraptionEntity contraptionEntity,
|
||||||
|
Vec3 contraptionMotion) {
|
||||||
|
if (entity.isPassenger())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Map<Player, Double> locksOnThisContraption =
|
||||||
|
remoteSafetyLocks.getOrDefault(contraptionEntity, Collections.emptyMap());
|
||||||
|
double prevDiff = locksOnThisContraption.getOrDefault(entity, entity.getY() - contraptionEntity.getY());
|
||||||
|
if (!savePlayerFromClipping(entity, contraptionEntity, contraptionMotion, prevDiff))
|
||||||
|
if (locksOnThisContraption.containsKey(entity))
|
||||||
|
locksOnThisContraption.remove(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private static boolean savePlayerFromClipping(Player entity, AbstractContraptionEntity contraptionEntity,
|
||||||
|
Vec3 contraptionMotion, double yStartOffset) {
|
||||||
|
AABB bb = entity.getBoundingBox()
|
||||||
|
.deflate(1 / 4f, 0, 1 / 4f);
|
||||||
double shortestDistance = Double.MAX_VALUE;
|
double shortestDistance = Double.MAX_VALUE;
|
||||||
double yStart = entity.getStepHeight() + contraptionEntity.getY() + prevDiff;
|
double yStart = entity.getStepHeight() + contraptionEntity.getY() + yStartOffset;
|
||||||
double rayLength = Math.max(5, Math.abs(entity.getY() - yStart));
|
double rayLength = Math.max(5, Math.abs(entity.getY() - yStart));
|
||||||
|
|
||||||
for (int rayIndex = 0; rayIndex < 4; rayIndex++) {
|
for (int rayIndex = 0; rayIndex < 4; rayIndex++) {
|
||||||
@ -432,12 +493,10 @@ public class ContraptionCollider {
|
|||||||
shortestDistance = hitDiff;
|
shortestDistance = hitDiff;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shortestDistance > rayLength) {
|
if (shortestDistance > rayLength)
|
||||||
safetyLock.setLeft(null);
|
return false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.setPos(entity.getX(), yStart - shortestDistance, entity.getZ());
|
entity.setPos(entity.getX(), yStart - shortestDistance, entity.getZ());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vec3 handleDamageFromTrain(Level world, AbstractContraptionEntity contraptionEntity,
|
private static Vec3 handleDamageFromTrain(Level world, AbstractContraptionEntity contraptionEntity,
|
||||||
@ -477,7 +536,8 @@ public class ContraptionCollider {
|
|||||||
return entityMotion;
|
return entityMotion;
|
||||||
|
|
||||||
if (playerType == PlayerType.CLIENT) {
|
if (playerType == PlayerType.CLIENT) {
|
||||||
AllPackets.getChannel().sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
|
AllPackets.getChannel()
|
||||||
|
.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
|
||||||
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
||||||
SoundSource.NEUTRAL, 1, .75f);
|
SoundSource.NEUTRAL, 1, .75f);
|
||||||
} else {
|
} else {
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
package com.simibubi.create.content.contraptions.components.structureMovement;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.networking.AllPackets;
|
||||||
|
import com.simibubi.create.foundation.networking.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.network.NetworkEvent.Context;
|
||||||
|
import net.minecraftforge.network.PacketDistributor;
|
||||||
|
|
||||||
|
public class ContraptionColliderLockPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
protected int contraption;
|
||||||
|
protected double offset;
|
||||||
|
private int sender;
|
||||||
|
|
||||||
|
public ContraptionColliderLockPacket(int contraption, double offset, int sender) {
|
||||||
|
this.contraption = contraption;
|
||||||
|
this.offset = offset;
|
||||||
|
this.sender = sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContraptionColliderLockPacket(FriendlyByteBuf buffer) {
|
||||||
|
contraption = buffer.readVarInt();
|
||||||
|
offset = buffer.readDouble();
|
||||||
|
sender = buffer.readVarInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeVarInt(contraption);
|
||||||
|
buffer.writeDouble(offset);
|
||||||
|
buffer.writeVarInt(sender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(Context context) {
|
||||||
|
DistExecutor.unsafeRunWhenOn(Dist.CLIENT,
|
||||||
|
() -> () -> ContraptionCollider.lockPacketReceived(contraption, sender, offset));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ContraptionColliderLockPacketRequest extends SimplePacketBase {
|
||||||
|
|
||||||
|
protected int contraption;
|
||||||
|
protected double offset;
|
||||||
|
|
||||||
|
public ContraptionColliderLockPacketRequest(int contraption, double offset) {
|
||||||
|
this.contraption = contraption;
|
||||||
|
this.offset = offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContraptionColliderLockPacketRequest(FriendlyByteBuf buffer) {
|
||||||
|
contraption = buffer.readVarInt();
|
||||||
|
offset = buffer.readDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(FriendlyByteBuf buffer) {
|
||||||
|
buffer.writeVarInt(contraption);
|
||||||
|
buffer.writeDouble(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean handle(Context context) {
|
||||||
|
AllPackets.getChannel()
|
||||||
|
.send(PacketDistributor.TRACKING_ENTITY.with(context::getSender),
|
||||||
|
new ContraptionColliderLockPacket(contraption, offset, context.getSender()
|
||||||
|
.getId()));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,6 +10,8 @@ import java.util.function.Supplier;
|
|||||||
import com.simibubi.create.Create;
|
import com.simibubi.create.Create;
|
||||||
import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionDisableActorPacket;
|
import com.simibubi.create.content.contraptions.components.actors.controls.ContraptionDisableActorPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionBlockChangedPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionBlockChangedPacket;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionColliderLockPacket;
|
||||||
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionColliderLockPacket.ContraptionColliderLockPacketRequest;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionDisassemblyPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRelocationPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionRelocationPacket;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionStallPacket;
|
||||||
@ -157,6 +159,8 @@ public enum AllPackets {
|
|||||||
ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::new, PLAY_TO_SERVER),
|
ELEVATOR_SET_FLOOR(ElevatorTargetFloorPacket.class, ElevatorTargetFloorPacket::new, PLAY_TO_SERVER),
|
||||||
VALUE_SETTINGS(ValueSettingsPacket.class, ValueSettingsPacket::new, PLAY_TO_SERVER),
|
VALUE_SETTINGS(ValueSettingsPacket.class, ValueSettingsPacket::new, PLAY_TO_SERVER),
|
||||||
CLIPBOARD_EDIT(ClipboardEditPacket.class, ClipboardEditPacket::new, PLAY_TO_SERVER),
|
CLIPBOARD_EDIT(ClipboardEditPacket.class, ClipboardEditPacket::new, PLAY_TO_SERVER),
|
||||||
|
CONTRAPTION_COLLIDER_LOCK_REQUEST(ContraptionColliderLockPacketRequest.class,
|
||||||
|
ContraptionColliderLockPacketRequest::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),
|
||||||
@ -195,7 +199,9 @@ public enum AllPackets {
|
|||||||
TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT),
|
TRACK_GRAPH_ROLL_CALL(TrackGraphRollCallPacket.class, TrackGraphRollCallPacket::new, PLAY_TO_CLIENT),
|
||||||
UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket::new, PLAY_TO_CLIENT),
|
UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket::new, PLAY_TO_CLIENT),
|
||||||
CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT),
|
CONTRAPTION_ACTOR_TOGGLE(ContraptionDisableActorPacket.class, ContraptionDisableActorPacket::new, PLAY_TO_CLIENT),
|
||||||
SET_FIRE_IMMUNE(NetheriteDivingHandler.SetFireImmunePacket.class, NetheriteDivingHandler.SetFireImmunePacket::new, PLAY_TO_CLIENT),
|
SET_FIRE_IMMUNE(NetheriteDivingHandler.SetFireImmunePacket.class, NetheriteDivingHandler.SetFireImmunePacket::new,
|
||||||
|
PLAY_TO_CLIENT),
|
||||||
|
CONTRAPTION_COLLIDER_LOCK(ContraptionColliderLockPacket.class, ContraptionColliderLockPacket::new, PLAY_TO_CLIENT),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user