146 lines
6.0 KiB
Java
146 lines
6.0 KiB
Java
|
package net.minecraft.client.renderer.item.properties.numeric;
|
||
|
|
||
|
import com.mojang.serialization.Codec;
|
||
|
import com.mojang.serialization.MapCodec;
|
||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||
|
import com.mojang.serialization.codecs.RecordCodecBuilder.Instance;
|
||
|
import javax.annotation.Nullable;
|
||
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||
|
import net.minecraft.core.BlockPos;
|
||
|
import net.minecraft.core.GlobalPos;
|
||
|
import net.minecraft.core.component.DataComponents;
|
||
|
import net.minecraft.util.Mth;
|
||
|
import net.minecraft.util.RandomSource;
|
||
|
import net.minecraft.util.StringRepresentable;
|
||
|
import net.minecraft.world.entity.Entity;
|
||
|
import net.minecraft.world.entity.player.Player;
|
||
|
import net.minecraft.world.item.ItemStack;
|
||
|
import net.minecraft.world.item.component.LodestoneTracker;
|
||
|
import net.minecraft.world.phys.Vec3;
|
||
|
import net.minecraftforge.api.distmarker.Dist;
|
||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||
|
|
||
|
@OnlyIn(Dist.CLIENT)
|
||
|
public class CompassAngleState extends NeedleDirectionHelper {
|
||
|
public static final MapCodec<CompassAngleState> MAP_CODEC = RecordCodecBuilder.mapCodec(
|
||
|
p_377373_ -> p_377373_.group(
|
||
|
Codec.BOOL.optionalFieldOf("wobble", true).forGetter(NeedleDirectionHelper::wobble),
|
||
|
CompassAngleState.CompassTarget.CODEC.fieldOf("target").forGetter(CompassAngleState::target)
|
||
|
)
|
||
|
.apply(p_377373_, CompassAngleState::new)
|
||
|
);
|
||
|
private final NeedleDirectionHelper.Wobbler wobbler;
|
||
|
private final NeedleDirectionHelper.Wobbler noTargetWobbler;
|
||
|
private final CompassAngleState.CompassTarget compassTarget;
|
||
|
private final RandomSource random = RandomSource.create();
|
||
|
|
||
|
public CompassAngleState(boolean p_375464_, CompassAngleState.CompassTarget p_375747_) {
|
||
|
super(p_375464_);
|
||
|
this.wobbler = this.newWobbler(0.8F);
|
||
|
this.noTargetWobbler = this.newWobbler(0.8F);
|
||
|
this.compassTarget = p_375747_;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
protected float calculate(ItemStack p_376712_, ClientLevel p_377258_, int p_377034_, Entity p_378312_) {
|
||
|
GlobalPos globalpos = this.compassTarget.get(p_377258_, p_376712_, p_378312_);
|
||
|
long i = p_377258_.getGameTime();
|
||
|
return !isValidCompassTargetPos(p_378312_, globalpos) ? this.getRandomlySpinningRotation(p_377034_, i) : this.getRotationTowardsCompassTarget(p_378312_, i, globalpos.pos());
|
||
|
}
|
||
|
|
||
|
private float getRandomlySpinningRotation(int p_375455_, long p_378047_) {
|
||
|
if (this.noTargetWobbler.shouldUpdate(p_378047_)) {
|
||
|
this.noTargetWobbler.update(p_378047_, this.random.nextFloat());
|
||
|
}
|
||
|
|
||
|
float f = this.noTargetWobbler.rotation() + hash(p_375455_) / 2.1474836E9F;
|
||
|
return Mth.positiveModulo(f, 1.0F);
|
||
|
}
|
||
|
|
||
|
private float getRotationTowardsCompassTarget(Entity p_375736_, long p_375437_, BlockPos p_376106_) {
|
||
|
float f = (float)getAngleFromEntityToPos(p_375736_, p_376106_);
|
||
|
float f1 = getWrappedVisualRotationY(p_375736_);
|
||
|
float f2;
|
||
|
if (p_375736_ instanceof Player player && player.isLocalPlayer() && player.level().tickRateManager().runsNormally()) {
|
||
|
if (this.wobbler.shouldUpdate(p_375437_)) {
|
||
|
this.wobbler.update(p_375437_, 0.5F - (f1 - 0.25F));
|
||
|
}
|
||
|
|
||
|
f2 = f + this.wobbler.rotation();
|
||
|
} else {
|
||
|
f2 = 0.5F - (f1 - 0.25F - f);
|
||
|
}
|
||
|
|
||
|
return Mth.positiveModulo(f2, 1.0F);
|
||
|
}
|
||
|
|
||
|
private static boolean isValidCompassTargetPos(Entity p_378772_, @Nullable GlobalPos p_376149_) {
|
||
|
return p_376149_ != null
|
||
|
&& p_376149_.dimension() == p_378772_.level().dimension()
|
||
|
&& !(p_376149_.pos().distToCenterSqr(p_378772_.position()) < 1.0E-5F);
|
||
|
}
|
||
|
|
||
|
private static double getAngleFromEntityToPos(Entity p_378685_, BlockPos p_375957_) {
|
||
|
Vec3 vec3 = Vec3.atCenterOf(p_375957_);
|
||
|
return Math.atan2(vec3.z() - p_378685_.getZ(), vec3.x() - p_378685_.getX()) / (float) (Math.PI * 2);
|
||
|
}
|
||
|
|
||
|
private static float getWrappedVisualRotationY(Entity p_376616_) {
|
||
|
return Mth.positiveModulo(p_376616_.getVisualRotationYInDegrees() / 360.0F, 1.0F);
|
||
|
}
|
||
|
|
||
|
private static int hash(int p_376466_) {
|
||
|
return p_376466_ * 1327217883;
|
||
|
}
|
||
|
|
||
|
protected CompassAngleState.CompassTarget target() {
|
||
|
return this.compassTarget;
|
||
|
}
|
||
|
|
||
|
@OnlyIn(Dist.CLIENT)
|
||
|
public static enum CompassTarget implements StringRepresentable {
|
||
|
NONE("none") {
|
||
|
@Nullable
|
||
|
@Override
|
||
|
public GlobalPos get(ClientLevel p_375914_, ItemStack p_376028_, Entity p_377752_) {
|
||
|
return null;
|
||
|
}
|
||
|
},
|
||
|
LODESTONE("lodestone") {
|
||
|
@Nullable
|
||
|
@Override
|
||
|
public GlobalPos get(ClientLevel p_376563_, ItemStack p_377548_, Entity p_378126_) {
|
||
|
LodestoneTracker lodestonetracker = p_377548_.get(DataComponents.LODESTONE_TRACKER);
|
||
|
return lodestonetracker != null ? lodestonetracker.target().orElse(null) : null;
|
||
|
}
|
||
|
},
|
||
|
SPAWN("spawn") {
|
||
|
@Override
|
||
|
public GlobalPos get(ClientLevel p_378146_, ItemStack p_377238_, Entity p_377273_) {
|
||
|
return GlobalPos.of(p_378146_.dimension(), p_378146_.getSharedSpawnPos());
|
||
|
}
|
||
|
},
|
||
|
RECOVERY("recovery") {
|
||
|
@Nullable
|
||
|
@Override
|
||
|
public GlobalPos get(ClientLevel p_375618_, ItemStack p_378046_, Entity p_376523_) {
|
||
|
return p_376523_ instanceof Player player ? player.getLastDeathLocation().orElse(null) : null;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
public static final Codec<CompassAngleState.CompassTarget> CODEC = StringRepresentable.fromEnum(CompassAngleState.CompassTarget::values);
|
||
|
private final String name;
|
||
|
|
||
|
CompassTarget(final String p_376851_) {
|
||
|
this.name = p_376851_;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String getSerializedName() {
|
||
|
return this.name;
|
||
|
}
|
||
|
|
||
|
@Nullable
|
||
|
abstract GlobalPos get(ClientLevel p_375459_, ItemStack p_375402_, Entity p_376061_);
|
||
|
}
|
||
|
}
|