Files
SableGravity/src/main/java/dev/nightly/sablegravity/mixin/EntityCustomOrientationMixin.java
T

92 lines
3.0 KiB
Java

package dev.nightly.sablegravity.mixin;
import dev.nightly.sablegravity.GravityEntityState;
import dev.nightly.sablegravity.SableGravityState;
import dev.nightly.sablegravity.physics.GravityFrames;
import dev.nightly.sablegravity.physics.SableFrameOrientation;
import dev.nightly.sablegravity.physics.SableLocalPlayerPhysics;
import dev.ryanhcode.sable.api.entity.EntitySubLevelUtil;
import dev.ryanhcode.sable.sublevel.SubLevel;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.Player;
import org.joml.Quaterniondc;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/** Supplies Sable with a substep-interpolated full quaternion OBB orientation. */
@Mixin(value = EntitySubLevelUtil.class, priority = 3000, remap = false)
public abstract class EntityCustomOrientationMixin {
@Inject(
method = "getCustomEntityOrientation",
at = @At("HEAD"),
cancellable = true,
remap = false
)
private static void sablegravity$getCustomOrientation(
Entity entity,
float partialTicks,
CallbackInfoReturnable<Quaterniondc> cir
) {
GravityEntityState state = (GravityEntityState) entity;
if (state.sablegravity$isInLocalSimulation()) {
return;
}
SubLevel frame = resolveFrame(entity);
if (frame == null || frame.isRemoved()) {
return;
}
cir.setReturnValue(
SableFrameOrientation.getFrameOrientation(frame, partialTicks)
);
}
@Inject(
method = "hasCustomEntityOrientation",
at = @At("HEAD"),
cancellable = true,
remap = false
)
private static void sablegravity$hasCustomOrientation(
Entity entity,
CallbackInfoReturnable<Boolean> cir
) {
GravityEntityState state = (GravityEntityState) entity;
if (state.sablegravity$isInLocalSimulation()) {
return;
}
SubLevel frame = resolveFrame(entity);
if (frame == null || frame.isRemoved()) {
return;
}
cir.setReturnValue(true);
}
private static SubLevel resolveFrame(Entity entity) {
if (entity instanceof Player player) {
if (!player.isLocalPlayer()) {
return null;
}
SableGravityState state = (SableGravityState) player;
if (!state.sablegravity$isEnabled()) {
return null;
}
SubLevel attached = SableLocalPlayerPhysics.getAttachedFrameIfPresent(player);
if (attached != null
&& !attached.isRemoved()
&& attached.getLevel() == player.level()) {
return attached;
}
return null;
}
return GravityFrames.resolveSable(entity)
.map(dev.nightly.sablegravity.physics.SableSubLevelGravityFrame::subLevel)
.orElse(null);
}
}