Fixed rubberbanding when flying in multiplayer

This commit is contained in:
Sollace 2021-08-26 18:51:58 +02:00
parent 3e3dd63362
commit 27b14dc06f
5 changed files with 68 additions and 2 deletions

View file

@ -0,0 +1,5 @@
package com.minelittlepony.unicopia.entity;
public interface MotionChecker {
void setPreventMotionChecks(boolean enabled);
}

View file

@ -20,9 +20,9 @@ import com.minelittlepony.unicopia.entity.PonyContainer;
import com.minelittlepony.unicopia.entity.behaviour.Disguise; import com.minelittlepony.unicopia.entity.behaviour.Disguise;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.entity.Equine; import com.minelittlepony.unicopia.entity.Equine;
import com.minelittlepony.unicopia.entity.ItemWielder;
import com.minelittlepony.unicopia.entity.Jumper; import com.minelittlepony.unicopia.entity.Jumper;
import com.minelittlepony.unicopia.entity.Leaner; import com.minelittlepony.unicopia.entity.Leaner;
import com.minelittlepony.unicopia.entity.ItemWielder;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;

View file

@ -0,0 +1,53 @@
package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.unicopia.entity.MotionChecker;
import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.network.NetworkThreadUtils;
import net.minecraft.network.listener.ServerPlayPacketListener;
import net.minecraft.network.packet.c2s.play.PlayerMoveC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.EntityTrackingListener;
@Mixin(ServerPlayNetworkHandler.class)
abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener, ServerPlayPacketListener {
@Shadow private boolean floating;
@Shadow private int floatingTicks;
private boolean flyingSurvival;
private boolean prevMotionChecks;
@Inject(method = "onPlayerMove(Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;)V", at = @At("HEAD"))
private void beforePlayerMove(PlayerMoveC2SPacket packet, CallbackInfo info) {
ServerPlayerEntity player = ((ServerPlayNetworkHandler)(Object)this).player;
NetworkThreadUtils.forceMainThread(packet, this, player.getServerWorld());
flyingSurvival = Pony.of(player).getPhysics().isFlyingSurvival;
if (flyingSurvival) {
setPreventMotionChecks(true);
}
}
@Inject(method = "onPlayerMove(Lnet/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket;)V", at = @At("RETURN"))
private void afterPlayerMove(PlayerMoveC2SPacket packet, CallbackInfo info) {
if (flyingSurvival) {
setPreventMotionChecks(prevMotionChecks);
}
}
private void setPreventMotionChecks(boolean motionChecks) {
ServerPlayerEntity player = ((ServerPlayNetworkHandler)(Object)this).player;
prevMotionChecks = player.isInTeleportationState();
((MotionChecker)player).setPreventMotionChecks(motionChecks);
player.fallDistance = 0;
floating = false;
floatingTicks = 0;
}
}

View file

@ -1,11 +1,13 @@
package com.minelittlepony.unicopia.mixin; package com.minelittlepony.unicopia.mixin;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import com.minelittlepony.unicopia.entity.PonyContainer; import com.minelittlepony.unicopia.entity.PonyContainer;
import com.minelittlepony.unicopia.entity.MotionChecker;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -13,12 +15,17 @@ import net.minecraft.screen.ScreenHandlerListener;
import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.network.ServerPlayerEntity;
@Mixin(ServerPlayerEntity.class) @Mixin(ServerPlayerEntity.class)
abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHandlerListener, PonyContainer<Pony> { abstract class MixinServerPlayerEntity extends PlayerEntity implements ScreenHandlerListener, PonyContainer<Pony>, MotionChecker {
MixinServerPlayerEntity() {super(null, null, 0, null);} MixinServerPlayerEntity() {super(null, null, 0, null);}
@Override
@Accessor("inTeleportationState")
public abstract void setPreventMotionChecks(boolean enabled);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Inject(method = "copyFrom(Lnet/minecraft/server/network/ServerPlayerEntity;Z)V", at = @At("HEAD")) @Inject(method = "copyFrom(Lnet/minecraft/server/network/ServerPlayerEntity;Z)V", at = @At("HEAD"))
private void onCopyFrom(ServerPlayerEntity oldPlayer, boolean alive, CallbackInfo info) { private void onCopyFrom(ServerPlayerEntity oldPlayer, boolean alive, CallbackInfo info) {
get().copyFrom(((PonyContainer<Pony>)oldPlayer).get()); get().copyFrom(((PonyContainer<Pony>)oldPlayer).get());
} }
} }

View file

@ -23,6 +23,7 @@
"MixinPlayerEntity", "MixinPlayerEntity",
"MixinProjectileEntity", "MixinProjectileEntity",
"MixinServerPlayerEntity", "MixinServerPlayerEntity",
"MixinServerPlayNetworkHandler",
"MixinServerWorld", "MixinServerWorld",
"MixinSheepEntity", "MixinSheepEntity",
"MixinShulkerEntity", "MixinShulkerEntity",