This repository has been archived on 2023-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
Gestus/src/main/java/com/thebrokenrail/gestus/mixin/MixinServerPlayerEntity.java

97 lines
2.9 KiB
Java

package com.thebrokenrail.gestus.mixin;
import com.mojang.authlib.GameProfile;
import com.thebrokenrail.gestus.Gestus;
import com.thebrokenrail.gestus.entity.FakePlayerEntity;
import com.thebrokenrail.gestus.util.ServerPlayerEntityExtension;
import net.minecraft.entity.effect.StatusEffects;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.EulerAngle;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ServerPlayerEntity.class)
public abstract class MixinServerPlayerEntity extends PlayerEntity implements ServerPlayerEntityExtension {
@Unique
private FakePlayerEntity shadow;
public MixinServerPlayerEntity(World world, BlockPos pos, float yaw, GameProfile profile) {
super(world, pos, yaw, profile);
}
private void updateShadow() {
if (shadow != null && (shadow.getEntityWorld() != getEntityWorld() || shadow.removed)) {
if (!shadow.removed) {
shadow.remove();
}
shadow = null;
}
boolean spawn = false;
if (shadow == null) {
shadow = new FakePlayerEntity(Gestus.FAKE_PLAYER_ENTITY_TYPE, getEntityWorld(), getDisplayName(), (ServerPlayerEntity) (Object) this);
spawn = true;
}
boolean invisible = hasStatusEffect(StatusEffects.INVISIBILITY);
boolean glowing = hasStatusEffect(StatusEffects.GLOWING);
shadow.setInvisible(invisible);
shadow.setGlowing(glowing);
shadow.setWorld(getEntityWorld());
shadow.refreshPositionAndAngles(getX(), getY(), getZ(), yaw, pitch);
shadow.setHeadRotation(new EulerAngle(pitch, getHeadYaw() - yaw, 0f));
shadow.setVelocity(getVelocity());
shadow.setCustomNameVisible(!invisible && !isSneaking());
shadow.update();
if (spawn) {
getEntityWorld().spawnEntity(shadow);
}
}
@Unique
private Vec3d lastPos = null;
@Inject(at = @At("HEAD"), method = "tick")
public void tick(CallbackInfo info) {
setInvisible(true);
setGlowing(false);
updateShadow();
lastPos = getPos();
}
@Override
public Vec3d getLastPos() {
return lastPos;
}
@Override
public FakePlayerEntity getShadow() {
return shadow;
}
@Override
public void remove() {
super.remove();
shadow.remove();
}
@Override
public void swingHand(Hand hand, boolean bl) {
super.swingHand(hand, bl);
shadow.hit(hand);
}
}