mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-13 05:54:17 +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.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
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.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.HarvesterMovementBehaviour;
|
||||
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.logistics.trains.entity.CarriageContraptionEntity;
|
||||
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 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.RemotePlayer;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
import net.minecraft.core.Direction.Axis;
|
||||
@ -65,6 +72,7 @@ public class ContraptionCollider {
|
||||
}
|
||||
|
||||
private static MutablePair<WeakReference<AbstractContraptionEntity>, Double> safetyLock = new MutablePair<>();
|
||||
private static Map<AbstractContraptionEntity, Map<Player, Double>> remoteSafetyLocks = new WeakHashMap<>();
|
||||
|
||||
static void collideEntities(AbstractContraptionEntity contraptionEntity) {
|
||||
Level world = contraptionEntity.getCommandSenderWorld();
|
||||
@ -95,8 +103,13 @@ public class ContraptionCollider {
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
entity.getSelfAndPassengers()
|
||||
.forEach(e -> {
|
||||
@ -354,7 +367,8 @@ public class ContraptionCollider {
|
||||
entity.fallDistance = 0;
|
||||
for (Entity rider : entity.getIndirectPassengers())
|
||||
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;
|
||||
if (canWalk || !rotation.hasVerticalRotation()) {
|
||||
if (canWalk)
|
||||
@ -378,7 +392,8 @@ public class ContraptionCollider {
|
||||
float limbSwing = Mth.sqrt((float) (d0 * d0 + d1 * d1)) * 4.0F;
|
||||
if (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) {
|
||||
safetyLock.setLeft(new WeakReference<>(contraptionEntity));
|
||||
@ -388,19 +403,32 @@ public class ContraptionCollider {
|
||||
|
||||
}
|
||||
|
||||
private static int packetCooldown = 0;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
private static void saveClientPlayerFromClipping(AbstractContraptionEntity contraptionEntity,
|
||||
Vec3 contraptionMotion) {
|
||||
Player entity = Minecraft.getInstance().player;
|
||||
|
||||
LocalPlayer entity = Minecraft.getInstance().player;
|
||||
if (entity.isPassenger())
|
||||
return;
|
||||
|
||||
|
||||
double prevDiff = safetyLock.right;
|
||||
double currentDiff = entity.getY() - contraptionEntity.getY();
|
||||
double motion = contraptionMotion.subtract(entity.getDeltaMovement()).y;
|
||||
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)
|
||||
return;
|
||||
if (trend == Math.signum(motion))
|
||||
@ -412,10 +440,43 @@ public class ContraptionCollider {
|
||||
return;
|
||||
if (speed < 0.05)
|
||||
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 yStart = entity.getStepHeight() + contraptionEntity.getY() + prevDiff;
|
||||
double yStart = entity.getStepHeight() + contraptionEntity.getY() + yStartOffset;
|
||||
double rayLength = Math.max(5, Math.abs(entity.getY() - yStart));
|
||||
|
||||
for (int rayIndex = 0; rayIndex < 4; rayIndex++) {
|
||||
@ -432,12 +493,10 @@ public class ContraptionCollider {
|
||||
shortestDistance = hitDiff;
|
||||
}
|
||||
|
||||
if (shortestDistance > rayLength) {
|
||||
safetyLock.setLeft(null);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shortestDistance > rayLength)
|
||||
return false;
|
||||
entity.setPos(entity.getX(), yStart - shortestDistance, entity.getZ());
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Vec3 handleDamageFromTrain(Level world, AbstractContraptionEntity contraptionEntity,
|
||||
@ -477,7 +536,8 @@ public class ContraptionCollider {
|
||||
return entityMotion;
|
||||
|
||||
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,
|
||||
SoundSource.NEUTRAL, 1, .75f);
|
||||
} 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.content.contraptions.components.actors.controls.ContraptionDisableActorPacket;
|
||||
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.ContraptionRelocationPacket;
|
||||
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),
|
||||
VALUE_SETTINGS(ValueSettingsPacket.class, ValueSettingsPacket::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
|
||||
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),
|
||||
UPDATE_ELEVATOR_FLOORS(ElevatorFloorListPacket.class, ElevatorFloorListPacket::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