improve portal gun perf
This commit is contained in:
1 parent
759f511b00
commit
0cad456efd
17 files changed
+348
-126
No files matched your search
+14
-4
@@ -2,6 +2,8 @@ package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.content.AntarchySoundEvents;
|
||||
import com.craisinlord.antarchy.content.entity.WormHookProjectileEntity;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil;
|
||||
import com.craisinlord.antarchy.content.util.WormHookRope;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -139,9 +141,9 @@ public final class WormHookTetherManager {
|
||||
// the max length (which alone has no effect until the rope goes taut).
|
||||
if (reeling && dist > MIN_LEN) {
|
||||
Vec3 pull = towardPivot.scale(-REEL_PULL_STRENGTH);
|
||||
Vec3 reelMotion = player.getDeltaMovement().add(pull);
|
||||
Vec3 reelMotion = getWorldMotion(player).add(pull);
|
||||
reelMotion = new Vec3(reelMotion.x, Mth.clamp(reelMotion.y, -0.6D, 0.6D), reelMotion.z);
|
||||
player.setDeltaMovement(reelMotion);
|
||||
setWorldMotion(player, reelMotion);
|
||||
player.hurtMarked = true;
|
||||
player.fallDistance = 0;
|
||||
}
|
||||
@@ -158,7 +160,7 @@ public final class WormHookTetherManager {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 motion = player.getDeltaMovement();
|
||||
Vec3 motion = getWorldMotion(player);
|
||||
double outward = motion.dot(towardPivot);
|
||||
if (outward > 0) {
|
||||
motion = motion.subtract(towardPivot.scale(outward));
|
||||
@@ -167,11 +169,19 @@ public final class WormHookTetherManager {
|
||||
Vec3 correction = towardPivot.scale(-overshoot * PULL_CORRECTION);
|
||||
Vec3 newMotion = motion.add(correction);
|
||||
newMotion = new Vec3(newMotion.x, Mth.clamp(newMotion.y, -1.0D, 1.0D), newMotion.z);
|
||||
player.setDeltaMovement(newMotion);
|
||||
setWorldMotion(player, newMotion);
|
||||
player.hurtMarked = true;
|
||||
player.fallDistance = 0;
|
||||
}
|
||||
|
||||
private static Vec3 getWorldMotion(ServerPlayer player) {
|
||||
return AntarchyGravityRotationUtil.vecPlayerToWorld(player.getDeltaMovement(), AntarchyGravityApi.getGravityDirection(player));
|
||||
}
|
||||
|
||||
private static void setWorldMotion(ServerPlayer player, Vec3 worldMotion) {
|
||||
player.setDeltaMovement(AntarchyGravityRotationUtil.vecWorldToPlayer(worldMotion, AntarchyGravityApi.getGravityDirection(player)));
|
||||
}
|
||||
|
||||
private static void tickFlyingSound(ServerPlayer player, TetherState state) {
|
||||
if (state.flyingSoundCooldown > 0) {
|
||||
state.flyingSoundCooldown--;
|
||||
|
||||
+25
-19
@@ -1,35 +1,41 @@
|
||||
package com.craisinlord.antarchy.mixins.gravity;
|
||||
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil;
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.ModifyVariable;
|
||||
|
||||
@Mixin(FireworkRocketEntity.class)
|
||||
/*
|
||||
* Fixes firework boost dir for inverted elytra flight.
|
||||
*/
|
||||
public abstract class FireworkRocketGravityMixin {
|
||||
|
||||
@Shadow
|
||||
@Nullable
|
||||
private LivingEntity attachedToEntity;
|
||||
@WrapOperation(method = "tick",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;"))
|
||||
private Vec3 antarchy$fixFireworkThrustDirection(LivingEntity entity, Operation<Vec3> original) {
|
||||
Vec3 look = original.call(entity);
|
||||
AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(entity);
|
||||
if (!direction.isInverted()) {
|
||||
return look;
|
||||
}
|
||||
return AntarchyGravityRotationUtil.vecWorldToPlayer(look, direction);
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "tick", at = @At(value = "STORE"), ordinal = 0)
|
||||
private Vec3 antarchy$fixFireworkThrustDirection(Vec3 velocity) {
|
||||
if (!(this.attachedToEntity instanceof Player player)) return velocity;
|
||||
if (!AntarchyGravityApi.isGravityInverted(player)) return velocity;
|
||||
return AntarchyGravityRotationUtil.vecWorldToPlayer(
|
||||
velocity,
|
||||
AntarchyGravityApi.getGravityDirection(player)
|
||||
);
|
||||
@WrapOperation(method = "tick",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/LivingEntity;getHandHoldingItemAngle(Lnet/minecraft/world/item/Item;)Lnet/minecraft/world/phys/Vec3;"))
|
||||
private Vec3 antarchy$rotateAttachedRocketOffset(LivingEntity entity, Item item, Operation<Vec3> original) {
|
||||
Vec3 offset = original.call(entity, item);
|
||||
AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(entity);
|
||||
if (!direction.isInverted()) {
|
||||
return offset;
|
||||
}
|
||||
return AntarchyGravityRotationUtil.vecPlayerToWorld(offset, direction);
|
||||
}
|
||||
}
|
||||
+9
@@ -39,6 +39,15 @@ public abstract class LivingEntityMixin {
|
||||
return AntarchyGravityRotationUtil.vecWorldToPlayer(entity.position(), direction).y;
|
||||
}
|
||||
|
||||
@WrapOperation(method = "travel",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;getLookAngle()Lnet/minecraft/world/phys/Vec3;"))
|
||||
private Vec3 antarchy$fixTravelLookAngle(LivingEntity entity, Operation<Vec3> original) {
|
||||
Vec3 look = original.call(entity);
|
||||
AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(entity);
|
||||
if (!direction.isInverted() || !entity.isFallFlying()) return look;
|
||||
return AntarchyGravityRotationUtil.vecWorldToPlayer(look, direction);
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "checkFallDamage", at = @At("HEAD"), ordinal = 0, argsOnly = true)
|
||||
private double antarchy$invertLivingFallDamageY(double worldY) {
|
||||
LivingEntity entity = (LivingEntity) (Object) this;
|
||||
|
||||
+8
@@ -53,10 +53,18 @@ public final class PortalGunPortalRim {
|
||||
}
|
||||
|
||||
static void drawHiddenOutlines(Minecraft minecraft, Vec3 cameraPos, Matrix4f viewMatrix, Matrix4f projectionMatrix, float partialTick) {
|
||||
drawHiddenOutlines(minecraft, cameraPos, viewMatrix, projectionMatrix, partialTick, null);
|
||||
}
|
||||
|
||||
static void drawHiddenOutlines(Minecraft minecraft, Vec3 cameraPos, Matrix4f viewMatrix, Matrix4f projectionMatrix, float partialTick,
|
||||
PortalGunPortalEntity excluded) {
|
||||
if (minecraft.level == null || minecraft.player == null) {
|
||||
return;
|
||||
}
|
||||
List<PortalGunPortalEntity> ownedPortals = collectOwnedPortals(minecraft);
|
||||
if (excluded != null) {
|
||||
ownedPortals.remove(excluded);
|
||||
}
|
||||
if (ownedPortals.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
+10
-3
@@ -14,6 +14,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexSorting;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Consumer;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -53,7 +54,8 @@ public final class PortalGunPortalSceneRenderer {
|
||||
|
||||
public static void render(Minecraft minecraft, Camera camera, float partialTick, Matrix4f viewMatrix,
|
||||
Matrix4f projection, Matrix4f skyProjection, Frustum frustum,
|
||||
PortalTerrain terrain, Consumer<PoseStack> crossingEntities) {
|
||||
PortalTerrain terrain, Consumer<PoseStack> crossingEntities,
|
||||
UUID sourceId, UUID destinationId, int viewLevel) {
|
||||
LevelRenderer renderer = minecraft.levelRenderer;
|
||||
LevelRendererPortalViewAreaAccessor state = (LevelRendererPortalViewAreaAccessor) renderer;
|
||||
LevelRendererPortalSceneInvoker scene = (LevelRendererPortalSceneInvoker) renderer;
|
||||
@@ -94,8 +96,10 @@ public final class PortalGunPortalSceneRenderer {
|
||||
RenderSystem.setProjectionMatrix(skyProjection, VertexSorting.DISTANCE_TO_ORIGIN);
|
||||
FogRenderer.setupFog(camera, FogRenderer.FogMode.FOG_SKY, renderDistance, foggy, partialTick);
|
||||
RenderSystem.setShader(GameRenderer::getPositionShader);
|
||||
renderer.renderSky(viewMatrix, skyProjection, partialTick, camera, foggy,
|
||||
() -> FogRenderer.setupFog(camera, FogRenderer.FogMode.FOG_SKY, renderDistance, foggy, partialTick));
|
||||
if (irisPipelineInstalled || PortalGunPortalSkyQueries.shouldRenderSky(sourceId, destinationId, viewLevel)) {
|
||||
renderer.renderSky(viewMatrix, skyProjection, partialTick, camera, foggy,
|
||||
() -> FogRenderer.setupFog(camera, FogRenderer.FogMode.FOG_SKY, renderDistance, foggy, partialTick));
|
||||
}
|
||||
}
|
||||
|
||||
RenderSystem.setProjectionMatrix(projection, VertexSorting.DISTANCE_TO_ORIGIN);
|
||||
@@ -144,6 +148,9 @@ public final class PortalGunPortalSceneRenderer {
|
||||
renderBlockEntity(minecraft, blockEntity, cameraX, cameraY, cameraZ, partialTick, poseStack, buffers));
|
||||
}
|
||||
buffers.endBatch();
|
||||
if (!irisPipelineInstalled) {
|
||||
PortalGunPortalSkyQueries.querySkyVisibility(sourceId, destinationId, viewLevel);
|
||||
}
|
||||
|
||||
{
|
||||
terrain.drawLayer(minecraft, RenderType.translucent(), cameraPosition, viewMatrix, projection);
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
package com.craisinlord.antarchy.content.client.renderer;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||
import com.mojang.blaze3d.vertex.BufferUploader;
|
||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||
import com.mojang.blaze3d.vertex.MeshData;
|
||||
import com.mojang.blaze3d.vertex.Tesselator;
|
||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||
import com.mojang.blaze3d.vertex.VertexSorting;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.client.renderer.GameRenderer;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Matrix4fStack;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
public final class PortalGunPortalSkyQueries {
|
||||
private static final int MAX_ENTRIES = 128;
|
||||
private static final LinkedHashMap<Key, QueryState> QUERIES = new LinkedHashMap<>(16, 0.75F, true);
|
||||
|
||||
private PortalGunPortalSkyQueries() {
|
||||
}
|
||||
|
||||
public static boolean shouldRenderSky(UUID source, UUID destination, int level) {
|
||||
QueryState state = QUERIES.get(new Key(source, destination, level));
|
||||
if (state == null) {
|
||||
return true;
|
||||
}
|
||||
poll(state);
|
||||
return !state.hasResult || state.visible;
|
||||
}
|
||||
|
||||
public static void querySkyVisibility(UUID source, UUID destination, int level) {
|
||||
Key key = new Key(source, destination, level);
|
||||
QueryState state = QUERIES.computeIfAbsent(key, ignored -> new QueryState(GL15.glGenQueries()));
|
||||
poll(state);
|
||||
if (state.inFlight) {
|
||||
trim();
|
||||
return;
|
||||
}
|
||||
MeshData mesh = buildFarPlane();
|
||||
if (mesh == null) {
|
||||
trim();
|
||||
return;
|
||||
}
|
||||
Matrix4fStack modelViewStack = RenderSystem.getModelViewStack();
|
||||
Matrix4f previousProjection = new Matrix4f(RenderSystem.getProjectionMatrix());
|
||||
VertexSorting previousSorting = RenderSystem.getVertexSorting();
|
||||
int previousDepthFunction = GL11.glGetInteger(GL11.GL_DEPTH_FUNC);
|
||||
modelViewStack.pushMatrix();
|
||||
GL15.glBeginQuery(GL15.GL_SAMPLES_PASSED, state.query);
|
||||
try {
|
||||
RenderSystem.enableDepthTest();
|
||||
RenderSystem.depthMask(false);
|
||||
RenderSystem.colorMask(false, false, false, false);
|
||||
RenderSystem.disableBlend();
|
||||
RenderSystem.disableCull();
|
||||
GL11.glDepthFunc(GL11.GL_LEQUAL);
|
||||
modelViewStack.identity();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
RenderSystem.setProjectionMatrix(new Matrix4f(), previousSorting);
|
||||
RenderSystem.setShader(GameRenderer::getPositionShader);
|
||||
BufferUploader.drawWithShader(mesh);
|
||||
} finally {
|
||||
GL15.glEndQuery(GL15.GL_SAMPLES_PASSED);
|
||||
state.inFlight = true;
|
||||
GL11.glDepthFunc(previousDepthFunction);
|
||||
RenderSystem.colorMask(true, true, true, true);
|
||||
RenderSystem.depthMask(true);
|
||||
RenderSystem.enableCull();
|
||||
RenderSystem.setProjectionMatrix(previousProjection, previousSorting);
|
||||
modelViewStack.popMatrix();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
}
|
||||
trim();
|
||||
}
|
||||
|
||||
public static void clear() {
|
||||
for (QueryState state : QUERIES.values()) {
|
||||
GL15.glDeleteQueries(state.query);
|
||||
}
|
||||
QUERIES.clear();
|
||||
}
|
||||
|
||||
private static void poll(QueryState state) {
|
||||
if (state.inFlight && GL15.glGetQueryObjecti(state.query, GL15.GL_QUERY_RESULT_AVAILABLE) != 0) {
|
||||
state.visible = GL15.glGetQueryObjecti(state.query, GL15.GL_QUERY_RESULT) != 0;
|
||||
state.hasResult = true;
|
||||
state.inFlight = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static MeshData buildFarPlane() {
|
||||
BufferBuilder buffer = Tesselator.getInstance().begin(VertexFormat.Mode.TRIANGLES, DefaultVertexFormat.POSITION);
|
||||
buffer.addVertex(-1.0F, -1.0F, 0.99999F);
|
||||
buffer.addVertex(3.0F, -1.0F, 0.99999F);
|
||||
buffer.addVertex(-1.0F, 3.0F, 0.99999F);
|
||||
return buffer.build();
|
||||
}
|
||||
|
||||
private static void trim() {
|
||||
Iterator<Map.Entry<Key, QueryState>> iterator = QUERIES.entrySet().iterator();
|
||||
while (QUERIES.size() > MAX_ENTRIES && iterator.hasNext()) {
|
||||
QueryState state = iterator.next().getValue();
|
||||
if (!state.inFlight) {
|
||||
GL15.glDeleteQueries(state.query);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private record Key(UUID source, UUID destination, int level) {
|
||||
}
|
||||
|
||||
private static final class QueryState {
|
||||
private final int query;
|
||||
private boolean inFlight;
|
||||
private boolean hasResult;
|
||||
private boolean visible = true;
|
||||
|
||||
private QueryState(int query) {
|
||||
this.query = query;
|
||||
}
|
||||
}
|
||||
}
|
||||
+8
-2
@@ -75,6 +75,7 @@ public final class PortalGunPortalViewRenderer {
|
||||
|
||||
public static void releaseTargets() {
|
||||
PortalGunPortalVisibilityQueries.clear();
|
||||
PortalGunPortalSkyQueries.clear();
|
||||
PortalGunPortalSectionViews.clear();
|
||||
if (offscreenTarget != null) {
|
||||
offscreenTarget.destroyBuffers();
|
||||
@@ -86,10 +87,10 @@ public final class PortalGunPortalViewRenderer {
|
||||
if (renderingPortalView) {
|
||||
return;
|
||||
}
|
||||
renderHiddenOutlines(camera, poseMatrix, projectionMatrix, tickCounter);
|
||||
if (isEnabled()) {
|
||||
renderViews(camera, poseMatrix, projectionMatrix, tickCounter);
|
||||
}
|
||||
renderHiddenOutlines(camera, poseMatrix, projectionMatrix, tickCounter);
|
||||
}
|
||||
|
||||
private static void renderHiddenOutlines(Camera camera, Matrix4f poseMatrix, Matrix4f projectionMatrix, DeltaTracker tickCounter) {
|
||||
@@ -244,6 +245,8 @@ public final class PortalGunPortalViewRenderer {
|
||||
RenderSystem.enableScissor(clip.x(), clip.y(), clip.width(), clip.height());
|
||||
renderScene(minecraft, cameraEntity, partialTick, transformed, rootProjection, clippedProjection,
|
||||
source, destination, clip, target.width, target.height, parentLevel + 1);
|
||||
PortalGunPortalRim.drawHiddenOutlines(minecraft, transformed.cameraPos(), transformed.viewMatrix(), clippedProjection,
|
||||
partialTick, destination);
|
||||
if (parentLevel + 1 < MAX_VIEW_LEVELS) {
|
||||
renderNestedViews(minecraft, cameraEntity, partialTick, transformed, rootProjection, clippedProjection,
|
||||
destination, parentLevel + 1, clip, budget, target.width, target.height);
|
||||
@@ -353,6 +356,8 @@ public final class PortalGunPortalViewRenderer {
|
||||
RenderSystem.enableScissor(clip.x(), clip.y(), clip.width(), clip.height());
|
||||
renderScene(minecraft, cameraEntity, partialTick, transformed, rootProjection, clippedProjection,
|
||||
source, destination, clip, target.width, target.height, 1);
|
||||
PortalGunPortalRim.drawHiddenOutlines(minecraft, transformed.cameraPos(), transformed.viewMatrix(), clippedProjection,
|
||||
partialTick, destination);
|
||||
} finally {
|
||||
RenderSystem.disableScissor();
|
||||
targetAccessor.antarchy$setMainRenderTarget(mainTarget);
|
||||
@@ -378,7 +383,8 @@ public final class PortalGunPortalViewRenderer {
|
||||
PortalTerrain terrain = PortalTerrain.prepare(minecraft, destination.getUUID(), exit.center(), exit.normal(), frustum);
|
||||
PortalGunPortalSceneRenderer.render(minecraft, portalCamera, partialTick, transformed.viewMatrix(), clippedProjection,
|
||||
rootProjection, frustum, terrain,
|
||||
poseStack -> renderCrossingEntities(minecraft, transformed.cameraPos(), partialTick, source, destination, poseStack));
|
||||
poseStack -> renderCrossingEntities(minecraft, transformed.cameraPos(), partialTick, source, destination, poseStack),
|
||||
source.getUUID(), destination.getUUID(), level);
|
||||
} finally {
|
||||
PortalGunPortalRenderState.popPortalView(false);
|
||||
}
|
||||
|
||||
+14
-4
@@ -2,6 +2,8 @@ package com.craisinlord.antarchy.content.item;
|
||||
|
||||
import com.craisinlord.antarchy.content.AntarchySoundEvents;
|
||||
import com.craisinlord.antarchy.content.entity.WormHookProjectileEntity;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil;
|
||||
import com.craisinlord.antarchy.content.util.WormHookRope;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@@ -125,9 +127,9 @@ public final class WormHookTetherManager {
|
||||
|
||||
if (reeling && dist > MIN_LEN) {
|
||||
Vec3 pull = towardPivot.scale(-REEL_PULL_STRENGTH);
|
||||
Vec3 reelMotion = player.getDeltaMovement().add(pull);
|
||||
Vec3 reelMotion = getWorldMotion(player).add(pull);
|
||||
reelMotion = new Vec3(reelMotion.x, Mth.clamp(reelMotion.y, -0.6D, 0.6D), reelMotion.z);
|
||||
player.setDeltaMovement(reelMotion);
|
||||
setWorldMotion(player, reelMotion);
|
||||
player.hurtMarked = true;
|
||||
player.fallDistance = 0;
|
||||
}
|
||||
@@ -144,7 +146,7 @@ public final class WormHookTetherManager {
|
||||
return;
|
||||
}
|
||||
|
||||
Vec3 motion = player.getDeltaMovement();
|
||||
Vec3 motion = getWorldMotion(player);
|
||||
double outward = motion.dot(towardPivot);
|
||||
if (outward > 0) {
|
||||
motion = motion.subtract(towardPivot.scale(outward));
|
||||
@@ -153,11 +155,19 @@ public final class WormHookTetherManager {
|
||||
Vec3 correction = towardPivot.scale(-overshoot * PULL_CORRECTION);
|
||||
Vec3 newMotion = motion.add(correction);
|
||||
newMotion = new Vec3(newMotion.x, Mth.clamp(newMotion.y, -1.0D, 1.0D), newMotion.z);
|
||||
player.setDeltaMovement(newMotion);
|
||||
setWorldMotion(player, newMotion);
|
||||
player.hurtMarked = true;
|
||||
player.fallDistance = 0;
|
||||
}
|
||||
|
||||
private static Vec3 getWorldMotion(ServerPlayer player) {
|
||||
return AntarchyGravityRotationUtil.vecPlayerToWorld(player.getDeltaMovement(), AntarchyGravityApi.getGravityDirection(player));
|
||||
}
|
||||
|
||||
private static void setWorldMotion(ServerPlayer player, Vec3 worldMotion) {
|
||||
player.setDeltaMovement(AntarchyGravityRotationUtil.vecWorldToPlayer(worldMotion, AntarchyGravityApi.getGravityDirection(player)));
|
||||
}
|
||||
|
||||
private static void tickFlyingSound(ServerPlayer player, TetherState state) {
|
||||
if (state.flyingSoundCooldown > 0) {
|
||||
state.flyingSoundCooldown--;
|
||||
|
||||
+21
-3
@@ -8,11 +8,13 @@ import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
|
||||
public final class PortalGunPortalRegistry {
|
||||
private static final Map<Level, Map<UUID, PortalGunPortalEntity>> LEVELS = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
private static final AtomicInteger TRACKED = new AtomicInteger();
|
||||
|
||||
private PortalGunPortalRegistry() {
|
||||
}
|
||||
@@ -26,17 +28,30 @@ public final class PortalGunPortalRegistry {
|
||||
synchronized (LEVELS) {
|
||||
portals = LEVELS.computeIfAbsent(level, ignored -> new ConcurrentHashMap<>());
|
||||
}
|
||||
portals.put(portal.getUUID(), portal);
|
||||
if (portals.put(portal.getUUID(), portal) == null) {
|
||||
TRACKED.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
static void untrack(PortalGunPortalEntity portal) {
|
||||
Map<UUID, PortalGunPortalEntity> portals = portalsIn(portal.level());
|
||||
if (portals != null) {
|
||||
portals.remove(portal.getUUID(), portal);
|
||||
if (portals != null && portals.remove(portal.getUUID(), portal)) {
|
||||
TRACKED.decrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasAny(Level level) {
|
||||
if (TRACKED.get() <= 0) {
|
||||
return false;
|
||||
}
|
||||
Map<UUID, PortalGunPortalEntity> portals = portalsIn(level);
|
||||
return portals != null && !portals.isEmpty();
|
||||
}
|
||||
|
||||
public static Collection<PortalGunPortalEntity> all(Level level) {
|
||||
if (TRACKED.get() <= 0) {
|
||||
return List.of();
|
||||
}
|
||||
Map<UUID, PortalGunPortalEntity> portals = portalsIn(level);
|
||||
return portals == null ? List.of() : portals.values();
|
||||
}
|
||||
@@ -54,6 +69,9 @@ public final class PortalGunPortalRegistry {
|
||||
}
|
||||
|
||||
public static List<PortalGunPortalEntity> near(Level level, AABB bounds) {
|
||||
if (TRACKED.get() <= 0) {
|
||||
return List.of();
|
||||
}
|
||||
Map<UUID, PortalGunPortalEntity> portals = portalsIn(level);
|
||||
if (portals == null || portals.isEmpty()) {
|
||||
return List.of();
|
||||
|
||||
+58
-8
@@ -7,10 +7,12 @@ import com.craisinlord.antarchy.content.gravity.AntarchyGravityTransition;
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
@@ -38,6 +40,7 @@ import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.Blocks;
|
||||
import net.minecraft.world.level.chunk.status.ChunkStatus;
|
||||
import net.minecraft.world.level.block.StainedGlassBlock;
|
||||
import net.minecraft.world.level.block.StainedGlassPaneBlock;
|
||||
import net.minecraft.world.level.block.TintedGlassBlock;
|
||||
@@ -53,6 +56,7 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
|
||||
private static final int MAX_TICKETED_PROJECTILES = 20;
|
||||
private static final int PROJECTILE_TICKET_LEVEL = 31;
|
||||
private static final int MAX_CHUNK_WAIT_TICKS = 200;
|
||||
private static final int GENERATED_CHECK_RADIUS = 3;
|
||||
private static final TicketType<UUID> PROJECTILE_TICKET = TicketType.create("antarchy_portal_projectile", Comparator.comparing(UUID::toString));
|
||||
private static final LinkedHashMap<UUID, ProjectileTicket> PROJECTILE_TICKETS = new LinkedHashMap<>();
|
||||
private static final EntityDataAccessor<Integer> SIDE = SynchedEntityData.defineId(PortalGunProjectileEntity.class, EntityDataSerializers.INT);
|
||||
@@ -79,6 +83,7 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
|
||||
private boolean spawnSynced;
|
||||
private boolean ticketRegistered;
|
||||
private int chunkWaitTicks;
|
||||
private final Map<Long, CompletableFuture<Boolean>> generatedChecks = new HashMap<>();
|
||||
public int portalWidth = 1;
|
||||
public int portalHeight = 2;
|
||||
|
||||
@@ -304,24 +309,69 @@ public class PortalGunProjectileEntity extends ThrowableItemProjectile {
|
||||
return false;
|
||||
}
|
||||
List<ChunkPos> path = chunksAlong(position, position.add(motion));
|
||||
boolean chunkload = AntarchySettings.portalGunCanPortalProjectilesChunkload();
|
||||
if (chunkload) {
|
||||
this.updateProjectileTicket(level, path);
|
||||
} else {
|
||||
boolean playerArea = true;
|
||||
for (ChunkPos chunk : path) {
|
||||
if (!level.isPositionEntityTicking(chunk.getMiddleBlockPosition(0))) {
|
||||
playerArea = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (playerArea) {
|
||||
this.releaseProjectileTicket();
|
||||
this.chunkWaitTicks = 0;
|
||||
return true;
|
||||
}
|
||||
if (!AntarchySettings.portalGunCanPortalProjectilesChunkload()) {
|
||||
this.releaseProjectileTicket();
|
||||
this.discard();
|
||||
return false;
|
||||
}
|
||||
for (ChunkPos chunk : path) {
|
||||
if (level.getChunkSource().getChunkNow(chunk.x, chunk.z) == null) {
|
||||
if (!chunkload || ++this.chunkWaitTicks > MAX_CHUNK_WAIT_TICKS) {
|
||||
this.discard();
|
||||
for (int dx = -GENERATED_CHECK_RADIUS; dx <= GENERATED_CHECK_RADIUS; dx++) {
|
||||
for (int dz = -GENERATED_CHECK_RADIUS; dz <= GENERATED_CHECK_RADIUS; dz++) {
|
||||
ChunkPos around = new ChunkPos(chunk.x + dx, chunk.z + dz);
|
||||
if (level.getChunkSource().getChunkNow(around.x, around.z) != null) {
|
||||
continue;
|
||||
}
|
||||
Boolean generated = this.isGenerated(level, around);
|
||||
if (generated == null) {
|
||||
return this.waitForChunks();
|
||||
}
|
||||
if (!generated) {
|
||||
this.discard();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.updateProjectileTicket(level, path);
|
||||
for (ChunkPos chunk : path) {
|
||||
if (!level.isPositionEntityTicking(chunk.getMiddleBlockPosition(0))) {
|
||||
return this.waitForChunks();
|
||||
}
|
||||
}
|
||||
this.chunkWaitTicks = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean waitForChunks() {
|
||||
if (++this.chunkWaitTicks > MAX_CHUNK_WAIT_TICKS) {
|
||||
this.discard();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Boolean isGenerated(ServerLevel level, ChunkPos chunk) {
|
||||
CompletableFuture<Boolean> check = this.generatedChecks.computeIfAbsent(chunk.toLong(), key -> level.getChunkSource().chunkMap.read(chunk)
|
||||
.thenApply(tag -> tag.map(PortalGunProjectileEntity::isFullChunk).orElse(false))
|
||||
.exceptionally(error -> false));
|
||||
return check.isDone() ? check.join() : null;
|
||||
}
|
||||
|
||||
private static boolean isFullChunk(CompoundTag tag) {
|
||||
return ChunkStatus.byName(tag.getString("Status")).isOrAfter(ChunkStatus.FULL);
|
||||
}
|
||||
|
||||
private static List<ChunkPos> chunksAlong(Vec3 start, Vec3 end) {
|
||||
int minX = SectionPos.blockToSectionCoord(Math.min(start.x, end.x));
|
||||
int maxX = SectionPos.blockToSectionCoord(Math.max(start.x, end.x));
|
||||
|
||||
+15
-4
@@ -2,6 +2,7 @@ package com.craisinlord.antarchy.mixins;
|
||||
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunCollisionHelper;
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunPortalEntity;
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunPortalRegistry;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
import net.minecraft.world.phys.AABB;
|
||||
@@ -24,12 +25,21 @@ public abstract class PortalGunEntityCollisionMixin {
|
||||
|
||||
@Inject(method = "move", at = @At("HEAD"))
|
||||
private void antarchy$capturePortalGunMovementStart(MoverType type, Vec3 movement, CallbackInfo ci) {
|
||||
this.antarchy$portalGunMoveStartBox = ((Entity) (Object) this).getBoundingBox();
|
||||
this.antarchy$portalGunMoveStartVelocity = ((Entity) (Object) this).getDeltaMovement();
|
||||
Entity entity = (Entity) (Object) this;
|
||||
if (!PortalGunPortalRegistry.hasAny(entity.level())) {
|
||||
this.antarchy$portalGunMoveStartBox = null;
|
||||
this.antarchy$portalGunMoveStartVelocity = null;
|
||||
return;
|
||||
}
|
||||
this.antarchy$portalGunMoveStartBox = entity.getBoundingBox();
|
||||
this.antarchy$portalGunMoveStartVelocity = entity.getDeltaMovement();
|
||||
}
|
||||
|
||||
@Inject(method = "move", at = @At("RETURN"))
|
||||
private void antarchy$teleportMobOnPortalCrossing(MoverType type, Vec3 movement, CallbackInfo ci) {
|
||||
if (this.antarchy$portalGunMoveStartBox == null) {
|
||||
return;
|
||||
}
|
||||
AABB startBox = this.antarchy$portalGunMoveStartBox;
|
||||
Vec3 startVelocity = this.antarchy$portalGunMoveStartVelocity;
|
||||
this.antarchy$portalGunMoveStartBox = null;
|
||||
@@ -41,15 +51,16 @@ public abstract class PortalGunEntityCollisionMixin {
|
||||
|
||||
@Inject(method = "collide", at = @At("HEAD"))
|
||||
private void antarchy$capturePortalGunStartBox(Vec3 movement, CallbackInfoReturnable<Vec3> cir) {
|
||||
this.antarchy$portalGunStartBox = ((Entity) (Object) this).getBoundingBox();
|
||||
Entity entity = (Entity) (Object) this;
|
||||
this.antarchy$portalGunStartBox = PortalGunPortalRegistry.hasAny(entity.level()) ? entity.getBoundingBox() : null;
|
||||
}
|
||||
|
||||
@Inject(method = "collide", at = @At("RETURN"), cancellable = true)
|
||||
private void antarchy$restorePortalCrossingMotion(Vec3 movement, CallbackInfoReturnable<Vec3> cir) {
|
||||
Entity entity = (Entity) (Object) this;
|
||||
if (this.antarchy$portalGunStartBox == null) {
|
||||
return;
|
||||
}
|
||||
Entity entity = (Entity) (Object) this;
|
||||
Vec3 collided = cir.getReturnValue();
|
||||
Vec3 adjusted = PortalGunCollisionHelper.resolveCollision(entity, this.antarchy$portalGunStartBox, movement, collided);
|
||||
if (adjusted != collided) {
|
||||
|
||||
+3
-2
@@ -1,6 +1,7 @@
|
||||
package com.craisinlord.antarchy.mixins;
|
||||
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunPortalEntity;
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunPortalRegistry;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
@@ -12,10 +13,10 @@ public abstract class PortalGunEntityInWallMixin {
|
||||
@Inject(method = "isInWall", at = @At("HEAD"), cancellable = true)
|
||||
private void antarchy$ignorePortalInWall(CallbackInfoReturnable<Boolean> cir) {
|
||||
Entity entity = (Entity) (Object) this;
|
||||
if (entity.level() == null) {
|
||||
if (entity.level() == null || !PortalGunPortalRegistry.hasAny(entity.level())) {
|
||||
return;
|
||||
}
|
||||
for (PortalGunPortalEntity portal : com.craisinlord.antarchy.content.portalgun.PortalGunPortalRegistry.near(entity.level(), entity.getBoundingBox().inflate(2.0D))) {
|
||||
for (PortalGunPortalEntity portal : PortalGunPortalRegistry.near(entity.level(), entity.getBoundingBox().inflate(2.0D))) {
|
||||
if (portal.intersectsEntityBounds(entity) || portal.getCollisionRemovalAabbForEntity(entity).intersects(entity.getBoundingBox())) {
|
||||
cir.setReturnValue(false);
|
||||
return;
|
||||
|
||||
+2
-1
@@ -1,6 +1,7 @@
|
||||
package com.craisinlord.antarchy.mixins;
|
||||
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunPortalEntity;
|
||||
import com.craisinlord.antarchy.content.portalgun.PortalGunPortalRegistry;
|
||||
import net.minecraft.network.protocol.game.ServerboundMovePlayerPacket;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.server.network.ServerGamePacketListenerImpl;
|
||||
@@ -29,7 +30,7 @@ public abstract class PortalGunPlayerMovePacketMixin {
|
||||
}
|
||||
this.antarchy$portalGunMoveStartBox = null;
|
||||
this.antarchy$portalGunMoveStartPosition = null;
|
||||
if (!packet.hasPosition() || ((ServerGamePacketListenerTeleportAccessor) this).antarchy$getAwaitingPositionFromClient() != null) {
|
||||
if (!packet.hasPosition() || !PortalGunPortalRegistry.hasAny(player.level()) || ((ServerGamePacketListenerTeleportAccessor) this).antarchy$getAwaitingPositionFromClient() != null) {
|
||||
return;
|
||||
}
|
||||
this.antarchy$portalGunMoveStartBox = player.getBoundingBox();
|
||||
|
||||
+14
-20
@@ -1,35 +1,29 @@
|
||||
package com.craisinlord.antarchy.mixins.gravity;
|
||||
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityDirection;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityRotationUtil;
|
||||
import com.craisinlord.antarchy.config.AntarchySettings;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.FireworkRocketEntity;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.ModifyVariable;
|
||||
|
||||
@Mixin(FireworkRocketEntity.class)
|
||||
/*
|
||||
* Fixes firework boost dir for inverted elytra flight.
|
||||
*/
|
||||
public abstract class FireworkRocketGravityMixin {
|
||||
|
||||
@Shadow
|
||||
@Nullable
|
||||
private LivingEntity attachedToEntity;
|
||||
|
||||
@ModifyVariable(method = "tick", at = @At(value = "STORE"), ordinal = 0)
|
||||
private Vec3 antarchy$fixFireworkThrustDirection(Vec3 velocity) {
|
||||
if (!(this.attachedToEntity instanceof Player player)) return velocity;
|
||||
if (!AntarchyGravityApi.isGravityInverted(player)) return velocity;
|
||||
return AntarchyGravityRotationUtil.vecWorldToPlayer(
|
||||
velocity,
|
||||
AntarchyGravityApi.getGravityDirection(player)
|
||||
);
|
||||
@WrapOperation(method = "tick",
|
||||
at = @At(value = "INVOKE",
|
||||
target = "Lnet/minecraft/world/entity/LivingEntity;getHandHoldingItemAngle(Lnet/minecraft/world/item/Item;)Lnet/minecraft/world/phys/Vec3;"))
|
||||
private Vec3 antarchy$rotateAttachedRocketOffset(LivingEntity entity, Item item, Operation<Vec3> original) {
|
||||
Vec3 offset = original.call(entity, item);
|
||||
AntarchyGravityDirection direction = AntarchyGravityApi.getGravityDirection(entity);
|
||||
if (!direction.isInverted()) {
|
||||
return offset;
|
||||
}
|
||||
return AntarchyGravityRotationUtil.vecPlayerToWorld(offset, direction);
|
||||
}
|
||||
}
|
||||
+6
-53
@@ -17,12 +17,6 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@Mixin(Camera.class)
|
||||
/*
|
||||
* Fixes camera pos/rot for inverted gravity and the flip anim.
|
||||
* Rotation is applied before move() so third-person pull-back uses the
|
||||
* correct gravity-adjusted forward direction. First-person falls through
|
||||
* to the TAIL inject since setup never calls move() in that case.
|
||||
*/
|
||||
public abstract class CameraGravityMixin {
|
||||
@Shadow
|
||||
private Entity entity;
|
||||
@@ -37,18 +31,13 @@ public abstract class CameraGravityMixin {
|
||||
private float eyeHeightOld;
|
||||
|
||||
private float antarchy$storedTickDelta;
|
||||
private boolean antarchy$gravityApplied;
|
||||
|
||||
@Shadow
|
||||
protected abstract void setPosition(double x, double y, double z);
|
||||
|
||||
@Shadow
|
||||
protected abstract void move(float forward, float up, float left);
|
||||
|
||||
@Inject(method = "setup", at = @At("HEAD"))
|
||||
private void antarchy$storeTickDelta(BlockGetter level, Entity entity, boolean detached, boolean mirrored, float partialTick, CallbackInfo ci) {
|
||||
this.antarchy$storedTickDelta = partialTick;
|
||||
this.antarchy$gravityApplied = false;
|
||||
}
|
||||
|
||||
@Redirect(
|
||||
@@ -88,53 +77,17 @@ public abstract class CameraGravityMixin {
|
||||
);
|
||||
}
|
||||
|
||||
/*
|
||||
* Intercept the move() call inside setup so the pull-back direction
|
||||
* already has gravity rotation applied. This covers detached (third-person)
|
||||
* and sleeping cameras. Sets a flag so the TAIL inject doesn't double-apply.
|
||||
*/
|
||||
@Redirect(
|
||||
method = "setup",
|
||||
at = @At(value = "INVOKE", target = "Lnet/minecraft/client/Camera;move(FFF)V")
|
||||
@Inject(
|
||||
method = "setRotation",
|
||||
at = @At(value = "INVOKE", target = "Lorg/joml/Quaternionf;rotationYXZ(FFF)Lorg/joml/Quaternionf;", shift = At.Shift.AFTER)
|
||||
)
|
||||
private void antarchy$moveWithGravity(
|
||||
Camera camera,
|
||||
float forward,
|
||||
float up,
|
||||
float left,
|
||||
BlockGetter level,
|
||||
Entity entity,
|
||||
boolean detached,
|
||||
boolean mirrored,
|
||||
float partialTick
|
||||
) {
|
||||
antarchy$applyGravityRotationOnce();
|
||||
this.move(forward, up, left);
|
||||
}
|
||||
|
||||
/*
|
||||
* First-person fallthrough: setup never calls move(), so gravity rotation
|
||||
* hasn't been applied yet when we reach the end of the method.
|
||||
*/
|
||||
@Inject(method = "setup", at = @At("TAIL"))
|
||||
private void antarchy$applyGravityAtTail(BlockGetter level, Entity entity, boolean detached, boolean mirrored, float partialTick, CallbackInfo ci) {
|
||||
antarchy$applyGravityRotationOnce();
|
||||
}
|
||||
|
||||
private void antarchy$applyGravityRotationOnce() {
|
||||
if (this.antarchy$gravityApplied) {
|
||||
return;
|
||||
}
|
||||
private void antarchy$applyGravityRotation(CallbackInfo ci) {
|
||||
if (this.entity == null) {
|
||||
return;
|
||||
}
|
||||
if (!AntarchyGravityApi.isGravityInverted(this.entity) && AntarchyGravityApi.getGravityFlipProgress(this.entity, this.antarchy$storedTickDelta) <= 0.0F) {
|
||||
this.rotation.premul(new Quaternionf().fromAxisAngleDeg(0.0F, 0.0F, -1.0F, PortalGunRollClientState.getRollDegrees(this.antarchy$storedTickDelta)));
|
||||
this.antarchy$gravityApplied = true;
|
||||
return;
|
||||
if (AntarchyGravityApi.isGravityInverted(this.entity) || AntarchyGravityApi.getGravityFlipProgress(this.entity, this.antarchy$storedTickDelta) > 0.0F) {
|
||||
this.rotation.premul(AntarchyGravityRotationUtil.getCameraRotationQuaternion(this.entity, this.antarchy$storedTickDelta));
|
||||
}
|
||||
this.rotation.premul(AntarchyGravityRotationUtil.getCameraRotationQuaternion(this.entity, this.antarchy$storedTickDelta));
|
||||
this.rotation.premul(new Quaternionf().fromAxisAngleDeg(0.0F, 0.0F, -1.0F, PortalGunRollClientState.getRollDegrees(this.antarchy$storedTickDelta)));
|
||||
this.antarchy$gravityApplied = true;
|
||||
}
|
||||
}
|
||||
+11
-2
@@ -2,11 +2,13 @@ package com.craisinlord.antarchy.forge.client;
|
||||
|
||||
import com.craisinlord.antarchy.Antarchy;
|
||||
import com.craisinlord.antarchy.content.gravity.AntarchyGravityApi;
|
||||
import net.minecraft.client.Camera;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ViewportEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
@Mod.EventBusSubscriber(modid = Antarchy.MODID, value = Dist.CLIENT)
|
||||
public final class GravityCameraRollHandler {
|
||||
@@ -15,7 +17,8 @@ public final class GravityCameraRollHandler {
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onComputeCameraAngles(ViewportEvent.ComputeCameraAngles event) {
|
||||
Entity entity = event.getCamera().getEntity();
|
||||
Camera camera = event.getCamera();
|
||||
Entity entity = camera.getEntity();
|
||||
if (entity == null) {
|
||||
return;
|
||||
}
|
||||
@@ -25,6 +28,12 @@ public final class GravityCameraRollHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setRoll(event.getRoll() + 180.0F * flipProgress);
|
||||
float gravityRoll = 180.0F * flipProgress;
|
||||
event.setRoll(event.getRoll() + gravityRoll);
|
||||
|
||||
Vector3f look = camera.getLookVector();
|
||||
float radians = (float) Math.toRadians(gravityRoll);
|
||||
camera.getUpVector().rotateAxis(radians, look.x(), look.y(), look.z());
|
||||
camera.getLeftVector().rotateAxis(radians, look.x(), look.y(), look.z());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@ org.gradle.configureondemand=true
|
||||
minecraft_version_1_21_1=1.21.1
|
||||
modid=antarchy
|
||||
mod_id=antarchy
|
||||
mod_version=2.2.1
|
||||
mod_version=2.2.2
|
||||
maven_group=com.craisinlord
|
||||
mixin_version=0.15.4+mixin.0.8.7
|
||||
|
||||
|
||||
Reference in new issue
Block a user