97 lines
2.9 KiB
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);
|
|
}
|
|
}
|