diff --git a/.gitignore b/.gitignore index 299156b30..e6b122f2a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,4 @@ forge*changelog.txt # Files generated for Fabric /fabric/src/generated/ +/.architectury-transformer/debug.log diff --git a/README.md b/README.md index c0ab5778b..5592c99ca 100644 --- a/README.md +++ b/README.md @@ -45,3 +45,11 @@ Occasionally forge will break in strange ways. When this occurs, delete all the `Error occurred during initialization of VM Could not reserve enough space for 4194304KB object heap` For patch the problem go to gradle.properties and change `org.gradle.jvmargs=-Xmx4096M` to `org.gradle.jvmargs=-Xmx1024` or `org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=1G` to `org.gradle.jvmargs=-Xmx1G -XX:MaxMetaspaceSize=1G` + +## Attributions + +Valkyrien Skies 2 was originally created by Triode and Rubydesic. You can check +other contributors by viewing the git history. + +The Create compatibility code was originally and largely written by [FluffyJenkins](https://github.com/FluffyJenkins/), +but the git history was clobbered when we transferred the code from Clockwork diff --git a/build.gradle b/build.gradle index 22d0e5286..b21a5193d 100644 --- a/build.gradle +++ b/build.gradle @@ -93,16 +93,6 @@ subprojects { includeModule "curse.maven", "kotlinforforge-351264" } } - maven { - name = "Valkyrien Skies Internal" - url = project.vs_maven_url ?: 'https://maven.valkyrienskies.org' - if (project.vs_maven_username && project.vs_maven_password) { - credentials { - username = project.vs_maven_username - password = project.vs_maven_password - } - } - } if (!project.block_external_repositories) { mavenLocal() maven { @@ -128,6 +118,16 @@ subprojects { maven { url = "https://maven.cafeteria.dev/releases" } // Fake Player API maven { url = "https://maven.jamieswhiteshirt.com/libs-release" } // Reach Entity Attributes } + maven { + name = "Valkyrien Skies Internal" + url = project.vs_maven_url ?: 'https://maven.valkyrienskies.org' + if (project.vs_maven_username && project.vs_maven_password) { + credentials { + username = project.vs_maven_username + password = project.vs_maven_password + } + } + } } // Remove automatically added repos diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/ValkyrienCommonMixinConfigPlugin.java b/common/src/main/java/org/valkyrienskies/mod/mixin/ValkyrienCommonMixinConfigPlugin.java index 3bc09f14e..ba5ad1b0a 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/ValkyrienCommonMixinConfigPlugin.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/ValkyrienCommonMixinConfigPlugin.java @@ -7,6 +7,7 @@ import org.spongepowered.asm.mixin.Mixins; import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin; import org.spongepowered.asm.mixin.extensibility.IMixinInfo; +import org.spongepowered.asm.service.MixinService; import org.valkyrienskies.mod.compat.VSRenderer; /** @@ -72,6 +73,15 @@ public boolean shouldApplyMixin(final String s, final String mixinClassName) { if (mixinClassName.contains("org.valkyrienskies.mod.mixin.feature.render_pathfinding")) { return PATH_FINDING_DEBUG; } + if (mixinClassName.contains("org.valkyrienskies.mod.mixin.mod_compat.create.client.trackOutlines")) { + //interactive has its own track outline stuff so disable fixed version of VS2's track outline stuff + if (classExists("org.valkyrienskies.create_interactive.mixin.client.MixinTrackBlockOutline")) { + MixinService.getService().getLogger("mixin") + .info("[VS2] found Interactive, disabling VS2's trackOutline Compat - " + + mixinClassName.substring(mixinClassName.lastIndexOf(".") + 1)); + return false; + } + } return true; } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/client/MixinMinecraft.java b/common/src/main/java/org/valkyrienskies/mod/mixin/client/MixinMinecraft.java index 424b4f52a..691fd4cda 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/client/MixinMinecraft.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/client/MixinMinecraft.java @@ -159,4 +159,14 @@ public void deleteShipObjectWorldClient() { shipObjectWorldCopy.destroyWorld(); shipObjectWorld = null; } + + @Inject( + method = "clearLevel", + at = @At("TAIL") + ) + private void postClearLevel(final CallbackInfo ci) { + if (shipObjectWorld != null) { + deleteShipObjectWorldClient(); + } + } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/client/renderer/MixinGameRenderer.java b/common/src/main/java/org/valkyrienskies/mod/mixin/client/renderer/MixinGameRenderer.java index 52a4e6772..ab7aebbd2 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/client/renderer/MixinGameRenderer.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/client/renderer/MixinGameRenderer.java @@ -25,14 +25,17 @@ 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.valkyrienskies.core.api.ships.ClientShip; import org.valkyrienskies.core.apigame.world.ClientShipWorldCore; import org.valkyrienskies.mod.client.IVSCamera; import org.valkyrienskies.mod.common.IShipObjectWorldClientProvider; +import org.valkyrienskies.mod.common.entity.ShipMountedToData; import org.valkyrienskies.mod.common.VSGameUtilsKt; import org.valkyrienskies.mod.common.util.EntityDraggingInformation; import org.valkyrienskies.mod.common.util.IEntityDraggingInformationProvider; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; import org.valkyrienskies.mod.common.world.RaycastUtilsKt; import org.valkyrienskies.mod.mixinducks.client.MinecraftDuck; @@ -91,17 +94,23 @@ public HitResult modifyCrosshairTargetBlocks(final Entity receiver, final double return pick.call(receiver, maxDistance, tickDelta, includeFluids); } - @WrapOperation( + @Redirect( method = "pick", at = @At( value = "INVOKE", target = "Lnet/minecraft/world/phys/Vec3;distanceToSqr(Lnet/minecraft/world/phys/Vec3;)D" ) ) - public double correctDistanceChecks(final Vec3 instance, final Vec3 vec, final Operation distanceToSqr) { - return VSGameUtilsKt.squaredDistanceBetweenInclShips(this.minecraft.level, - vec.x, vec.y, vec.z, - instance.x, instance.y, instance.z); + public double correctDistanceChecks(final Vec3 instance, final Vec3 vec) { + return VSGameUtilsKt.squaredDistanceBetweenInclShips( + this.minecraft.level, + vec.x, + vec.y, + vec.z, + instance.x, + instance.y, + instance.z + ); } @Inject(method = "render", at = @At("HEAD")) @@ -119,18 +128,20 @@ private void preRender(final float tickDelta, final long startTime, final boolea // Also update entity last tick positions, so that they interpolate correctly for (final Entity entity : clientWorld.entitiesForRendering()) { + if (!((IEntityDraggingInformationProvider) entity).vs$shouldDrag()) { + continue; + } // The position we want to render [entity] at for this frame // This is set when an entity is mounted to a ship, or an entity is being dragged by a ship Vector3dc entityShouldBeHere = null; - // First, try getting [entityShouldBeHere] from [shipMountedTo] - final ClientShip shipMountedTo = - VSGameUtilsKt.getShipObjectEntityMountedTo(clientWorld, entity); + // First, try getting the ship the entity is mounted to, if one exists + final ShipMountedToData shipMountedToData = VSGameUtilsKt.getShipMountedToData(entity, tickDelta); - if (shipMountedTo != null) { + if (shipMountedToData != null) { + final ClientShip shipMountedTo = (ClientShip) shipMountedToData.getShipMountedTo(); // If the entity is mounted to a ship then update their position - final Vector3dc passengerPos = - VSGameUtilsKt.getPassengerPos(entity.getVehicle(), entity.getMyRidingOffset(), tickDelta); + final Vector3dc passengerPos = shipMountedToData.getMountPosInShip(); entityShouldBeHere = shipMountedTo.getRenderTransform().getShipToWorld() .transformPosition(passengerPos, new Vector3d()); entity.setPos(entityShouldBeHere.x(), entityShouldBeHere.y(), entityShouldBeHere.z()); @@ -143,41 +154,39 @@ private void preRender(final float tickDelta, final long startTime, final boolea continue; } - if (entityShouldBeHere == null) { - final EntityDraggingInformation entityDraggingInformation = - ((IEntityDraggingInformationProvider) entity).getDraggingInformation(); - final Long lastShipStoodOn = entityDraggingInformation.getLastShipStoodOn(); - // Then try getting [entityShouldBeHere] from [entityDraggingInformation] - if (lastShipStoodOn != null && entityDraggingInformation.isEntityBeingDraggedByAShip()) { - final ClientShip shipObject = - VSGameUtilsKt.getShipObjectWorld(clientWorld).getLoadedShips().getById(lastShipStoodOn); - if (shipObject != null) { - entityDraggingInformation.setCachedLastPosition( - new Vector3d(entity.xo, entity.yo, entity.zo)); - entityDraggingInformation.setRestoreCachedLastPosition(true); - - // The velocity added to the entity by ship dragging - final Vector3dc entityAddedVelocity = entityDraggingInformation.getAddedMovementLastTick(); - - // The velocity of the entity before we added ship dragging - final double entityMovementX = entity.getX() - entityAddedVelocity.x() - entity.xo; - final double entityMovementY = entity.getY() - entityAddedVelocity.y() - entity.yo; - final double entityMovementZ = entity.getZ() - entityAddedVelocity.z() - entity.zo; - - // Without ship dragging, the entity would've been here - final Vector3dc entityShouldBeHerePreTransform = new Vector3d( - entity.xo + entityMovementX * tickDelta, - entity.yo + entityMovementY * tickDelta, - entity.zo + entityMovementZ * tickDelta - ); - - // Move [entityShouldBeHerePreTransform] with the ship, using the prev transform and the - // current render transform - entityShouldBeHere = shipObject.getRenderTransform().getShipToWorldMatrix() - .transformPosition( - shipObject.getPrevTickShipTransform().getWorldToShipMatrix() - .transformPosition(entityShouldBeHerePreTransform, new Vector3d())); - } + final EntityDraggingInformation entityDraggingInformation = + ((IEntityDraggingInformationProvider) entity).getDraggingInformation(); + final Long lastShipStoodOn = entityDraggingInformation.getLastShipStoodOn(); + // Then try getting [entityShouldBeHere] from [entityDraggingInformation] + if (lastShipStoodOn != null && entityDraggingInformation.isEntityBeingDraggedByAShip()) { + final ClientShip shipObject = + VSGameUtilsKt.getShipObjectWorld(clientWorld).getLoadedShips().getById(lastShipStoodOn); + if (shipObject != null) { + entityDraggingInformation.setCachedLastPosition( + new Vector3d(entity.xo, entity.yo, entity.zo)); + entityDraggingInformation.setRestoreCachedLastPosition(true); + + // The velocity added to the entity by ship dragging + final Vector3dc entityAddedVelocity = entityDraggingInformation.getAddedMovementLastTick(); + + // The velocity of the entity before we added ship dragging + final double entityMovementX = entity.getX() - entityAddedVelocity.x() - entity.xo; + final double entityMovementY = entity.getY() - entityAddedVelocity.y() - entity.yo; + final double entityMovementZ = entity.getZ() - entityAddedVelocity.z() - entity.zo; + + // Without ship dragging, the entity would've been here + final Vector3dc entityShouldBeHerePreTransform = new Vector3d( + entity.xo + entityMovementX * tickDelta, + entity.yo + entityMovementY * tickDelta, + entity.zo + entityMovementZ * tickDelta + ); + + // Move [entityShouldBeHerePreTransform] with the ship, using the prev transform and the + // current render transform + entityShouldBeHere = shipObject.getRenderTransform().getShipToWorldMatrix() + .transformPosition( + shipObject.getPrevTickShipTransform().getWorldToShipMatrix() + .transformPosition(entityShouldBeHerePreTransform, new Vector3d())); } } @@ -239,12 +248,13 @@ private void setupCameraWithMountedShip(final LevelRenderer instance, final Pose prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f); return; } - final ClientShip playerShipMountedTo = - VSGameUtilsKt.getShipObjectEntityMountedTo(clientLevel, player); - if (playerShipMountedTo == null) { + + final ShipMountedToData shipMountedToData = VSGameUtilsKt.getShipMountedToData(player, partialTicks); + if (shipMountedToData == null) { prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f); return; } + final Entity playerVehicle = player.getVehicle(); if (playerVehicle == null) { prepareCullFrustum.call(instance, matrixStack, vec3, matrix4f); @@ -252,8 +262,6 @@ private void setupCameraWithMountedShip(final LevelRenderer instance, final Pose } // Update [matrixStack] to mount the camera to the ship - final Vector3dc inShipPos = - VSGameUtilsKt.getPassengerPos(playerVehicle, player.getMyRidingOffset(), partialTicks); final Camera camera = this.mainCamera; if (camera == null) { @@ -261,20 +269,23 @@ private void setupCameraWithMountedShip(final LevelRenderer instance, final Pose return; } + final ClientShip clientShip = (ClientShip) shipMountedToData.getShipMountedTo(); + ((IVSCamera) camera).setupWithShipMounted( this.minecraft.level, this.minecraft.getCameraEntity() == null ? this.minecraft.player : this.minecraft.getCameraEntity(), !this.minecraft.options.getCameraType().isFirstPerson(), this.minecraft.options.getCameraType().isMirrored(), partialTicks, - playerShipMountedTo, - inShipPos + clientShip, + shipMountedToData.getMountPosInShip() ); // Apply the ship render transform to [matrixStack] - final Quaterniond invShipRenderRotation = - playerShipMountedTo.getRenderTransform().getShipToWorldRotation().conjugate(new Quaterniond()); - matrixStack.mulPose(new Quaternionf().set(invShipRenderRotation)); + final Quaternionf invShipRenderRotation = new Quaternionf( + clientShip.getRenderTransform().getShipToWorldRotation().conjugate(new Quaterniond()) + ); + matrixStack.mulPose(invShipRenderRotation); // We also need to recompute [inverseViewRotationMatrix] after updating [matrixStack] { diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/entity/MixinEntity.java b/common/src/main/java/org/valkyrienskies/mod/mixin/entity/MixinEntity.java index 59d5db09d..e8eb20a5d 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/entity/MixinEntity.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/entity/MixinEntity.java @@ -16,7 +16,6 @@ import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.Vec3; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.joml.Vector3d; import org.joml.Vector3dc; import org.joml.primitives.AABBd; @@ -33,6 +32,7 @@ import org.valkyrienskies.core.api.ships.Ship; import org.valkyrienskies.core.api.ships.properties.ShipTransform; import org.valkyrienskies.core.impl.game.ships.ShipObjectClient; +import org.valkyrienskies.mod.common.entity.ShipMountedToData; import org.valkyrienskies.mod.common.VSGameUtilsKt; import org.valkyrienskies.mod.common.util.EntityDraggingInformation; import org.valkyrienskies.mod.common.util.IEntityDraggingInformationProvider; @@ -105,11 +105,11 @@ private void originalCheckInside(final AABBd aABB) { */ @Inject(method = "getEyePosition(F)Lnet/minecraft/world/phys/Vec3;", at = @At("HEAD"), cancellable = true) private void preGetEyePosition(final float partialTicks, final CallbackInfoReturnable cir) { - final LoadedShip shipMountedTo = - VSGameUtilsKt.getShipObjectEntityMountedTo(level, Entity.class.cast(this)); - if (shipMountedTo == null) { + final ShipMountedToData shipMountedToData = VSGameUtilsKt.getShipMountedToData(Entity.class.cast(this), partialTicks); + if (shipMountedToData == null) { return; } + final LoadedShip shipMountedTo = shipMountedToData.getShipMountedTo(); final ShipTransform shipTransform; if (shipMountedTo instanceof ShipObjectClient) { @@ -118,8 +118,7 @@ private void preGetEyePosition(final float partialTicks, final CallbackInfoRetur shipTransform = shipMountedTo.getShipTransform(); } final Vector3dc basePos = shipTransform.getShipToWorldMatrix() - .transformPosition(VSGameUtilsKt.getPassengerPos(this.vehicle, getMyRidingOffset(), partialTicks), - new Vector3d()); + .transformPosition(shipMountedToData.getMountPosInShip(), new Vector3d()); final Vector3dc eyeRelativePos = shipTransform.getShipCoordinatesToWorldCoordinatesRotation().transform( new Vector3d(0.0, getEyeHeight(), 0.0) ); @@ -127,15 +126,12 @@ private void preGetEyePosition(final float partialTicks, final CallbackInfoRetur cir.setReturnValue(newEyePos); } - @Shadow - private Vec3 position; - /** * @reason Needed for players to pick blocks correctly when mounted to a ship */ @Inject(method = "calculateViewVector", at = @At("HEAD"), cancellable = true) private void preCalculateViewVector(final float xRot, final float yRot, final CallbackInfoReturnable cir) { - final LoadedShip shipMountedTo = VSGameUtilsKt.getShipObjectEntityMountedTo(level, Entity.class.cast(this)); + final LoadedShip shipMountedTo = VSGameUtilsKt.getShipMountedTo(Entity.class.cast(this)); if (shipMountedTo == null) { return; } @@ -180,9 +176,6 @@ private void preCalculateViewVector(final float xRot, final float yRot, final Ca @Shadow public abstract double getX(); - @Shadow - private @Nullable Entity vehicle; - @Shadow public abstract float getEyeHeight(); @@ -191,12 +184,14 @@ private void preCalculateViewVector(final float xRot, final float yRot, final Ca @Shadow public abstract EntityType getType(); - @Shadow - public abstract double getMyRidingOffset(); - @Override @NotNull public EntityDraggingInformation getDraggingInformation() { return draggingInformation; } + + @Override + public boolean vs$shouldDrag() { + return true; + } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/seamless_copy/MixinClientPacketListener.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/seamless_copy/MixinClientPacketListener.java index e065d72a6..049d4369d 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/seamless_copy/MixinClientPacketListener.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/seamless_copy/MixinClientPacketListener.java @@ -63,7 +63,7 @@ private void beforeClose(final CallbackInfo ci) { cancellable = true ) private void beforeHandleLevelChunk(final ClientboundLevelChunkWithLightPacket packet, final CallbackInfo ci) { - if (chunks.queue(packet.getX(), packet.getZ(), packet, level)) { + if (level != null && chunks.queue(packet.getX(), packet.getZ(), packet, level)) { ci.cancel(); } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinEntityRenderDispatcher.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinEntityRenderDispatcher.java index 18d24607e..adbf96503 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinEntityRenderDispatcher.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinEntityRenderDispatcher.java @@ -8,6 +8,10 @@ import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.world.entity.Entity; import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import org.joml.Quaternionf; +import org.joml.Vector3d; +import org.joml.Vector3dc; import org.joml.primitives.AABBd; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; @@ -15,7 +19,9 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.valkyrienskies.core.api.ships.ClientShip; +import org.valkyrienskies.core.api.ships.properties.ShipTransform; import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.entity.ShipMountedToData; import org.valkyrienskies.mod.common.entity.handling.VSEntityManager; import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; @@ -32,27 +38,53 @@ void render( final T entity, final double x, final double y, final double z, final float rotationYaw, final float partialTicks, final PoseStack matrixStack, final MultiBufferSource buffer, final int packedLight, final CallbackInfo ci, - final EntityRenderer entityRenderer) { + final EntityRenderer entityRenderer + ) { + final ShipMountedToData shipMountedToData = VSGameUtilsKt.getShipMountedToData(entity, partialTicks); - final ClientShip ship = - (ClientShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level(), entity.blockPosition()); - if (ship != null) { + if (shipMountedToData != null) { // Remove the earlier applied translation matrixStack.popPose(); matrixStack.pushPose(); - VSEntityManager.INSTANCE.getHandler(entity) - .applyRenderTransform(ship, entity, entityRenderer, x, y, z, - rotationYaw, partialTicks, matrixStack, - buffer, packedLight); - } else if (entity.isPassenger()) { - final ClientShip vehicleShip = - (ClientShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level(), - entity.getVehicle().blockPosition()); - // If the entity is a passenger and that vehicle is in ship space - if (vehicleShip != null) { - VSEntityManager.INSTANCE.getHandler(entity.getVehicle()) - .applyRenderOnMountedEntity(vehicleShip, entity.getVehicle(), entity, partialTicks, matrixStack); + final ShipTransform renderTransform = ((ClientShip) shipMountedToData.getShipMountedTo()).getRenderTransform(); + + final Vec3 entityPosition = entity.getPosition(partialTicks); + final Vector3dc transformed = renderTransform.getShipToWorld().transformPosition(shipMountedToData.getMountPosInShip(), new Vector3d()); + + final double camX = x - entityPosition.x; + final double camY = y - entityPosition.y; + final double camZ = z - entityPosition.z; + + final Vec3 offset = entityRenderer.getRenderOffset(entity, partialTicks); + final Vector3dc scale = renderTransform.getShipToWorldScaling(); + + matrixStack.translate(transformed.x() + camX, transformed.y() + camY, transformed.z() + camZ); + matrixStack.mulPose(new Quaternionf(renderTransform.getShipToWorldRotation())); + matrixStack.scale((float) scale.x(), (float) scale.y(), (float) scale.z()); + matrixStack.translate(offset.x, offset.y, offset.z); + } else { + final ClientShip ship = + (ClientShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level(), entity.blockPosition()); + if (ship != null) { + // Remove the earlier applied translation + matrixStack.popPose(); + matrixStack.pushPose(); + + VSEntityManager.INSTANCE.getHandler(entity) + .applyRenderTransform(ship, entity, entityRenderer, x, y, z, + rotationYaw, partialTicks, matrixStack, + buffer, packedLight); + } else if (entity.isPassenger()) { + final ClientShip vehicleShip = + (ClientShip) VSGameUtilsKt.getShipObjectManagingPos(entity.level(), + entity.getVehicle().blockPosition()); + // If the entity is a passenger and that vehicle is in ship space + if (vehicleShip != null) { + VSEntityManager.INSTANCE.getHandler(entity.getVehicle()) + .applyRenderOnMountedEntity(vehicleShip, entity.getVehicle(), entity, partialTicks, + matrixStack); + } } } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinPersistentEntitySectionManager.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinPersistentEntitySectionManager.java index fbbaf3831..0f7068745 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinPersistentEntitySectionManager.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/shipyard_entities/MixinPersistentEntitySectionManager.java @@ -1,17 +1,24 @@ package org.valkyrienskies.mod.mixin.feature.shipyard_entities; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.LongOpenHashSet; +import it.unimi.dsi.fastutil.longs.LongSet; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.Level; import net.minecraft.world.level.entity.EntitySectionStorage; import net.minecraft.world.level.entity.PersistentEntitySectionManager; +import net.minecraft.world.level.entity.Visibility; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; 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; import org.valkyrienskies.mod.mixinducks.world.OfLevel; @Mixin(PersistentEntitySectionManager.class) -public class MixinPersistentEntitySectionManager implements OfLevel { +public abstract class MixinPersistentEntitySectionManager implements OfLevel { @Shadow @Final EntitySectionStorage sectionStorage; @@ -29,4 +36,41 @@ public void setLevel(final Level level) { this.level = level; ((OfLevel) this.sectionStorage).setLevel(level); } + + @Shadow + @Final + private LongSet chunksToUnload; + + @Shadow + @Final + private Long2ObjectMap chunkVisibility; + + @Shadow + private boolean processChunkUnload(final long l) { + throw new IllegalStateException("This should not be invoked"); + } + + /** + * This fixes this function randomly crashing. I'm not sure why but the removeIf() function is buggy + */ + @Inject( + method = "processUnloads", at = @At(value = "HEAD"), cancellable = true + ) + private void replaceProcessUnloads(final CallbackInfo ci) { + // I don't know why this crashes, try-catch please help me! + try { + final LongSet toRemove = new LongOpenHashSet(); + for (final long key : this.chunksToUnload) { + if (this.chunkVisibility.get(key) != Visibility.HIDDEN) { + toRemove.add(key); + } else if (this.processChunkUnload(key)) { + toRemove.add(key); + } + } + chunksToUnload.removeAll(toRemove); + } catch (final Exception e) { + e.printStackTrace(); + } + ci.cancel(); + } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sound/client/MixinSoundEngine.java b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sound/client/MixinSoundEngine.java index 47fad3930..b0a30a022 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sound/client/MixinSoundEngine.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/feature/sound/client/MixinSoundEngine.java @@ -19,6 +19,8 @@ import org.valkyrienskies.core.api.ships.ClientShip; import org.valkyrienskies.mod.client.audio.VelocityTickableSoundInstance; import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.EntityDraggingInformation; +import org.valkyrienskies.mod.common.util.IEntityDraggingInformationProvider; import org.valkyrienskies.mod.mixinducks.com.mojang.blaze3d.audio.HasOpenALVelocity; @Mixin(SoundEngine.class) @@ -31,6 +33,7 @@ public abstract class MixinSoundEngine { protected abstract float calculatePitch(SoundInstance sound); // Applies the velocity provided by a VelocityTickableSoundInstance + @SuppressWarnings("unused") @WrapOperation( at = @At( value = "INVOKE", @@ -39,7 +42,7 @@ public abstract class MixinSoundEngine { ), method = "tickNonPaused" ) - private Object redirectGet(final Map instance, final Object obj, final Operation get) { + private Object redirectGet(final Map instance, final Object obj, final Operation get) { if (obj instanceof final VelocityTickableSoundInstance soundInstance) { final ChannelAccess.ChannelHandle handle = (ChannelAccess.ChannelHandle) instance.get(soundInstance); final float f = calculateVolume(soundInstance); @@ -59,6 +62,7 @@ private Object redirectGet(final Map instance, final Object obj, final Operation return get.call(instance, obj); } + @SuppressWarnings("unused") @WrapOperation( at = @At( value = "INVOKE", @@ -73,9 +77,15 @@ private void injectListenerVelocity(final Listener listener, final Vec3 position ((HasOpenALVelocity) listener).setVelocity(new Vector3d()); if (level != null && player != null) { - final ClientShip mounted = VSGameUtilsKt.getShipObjectEntityMountedTo(level, player); + final ClientShip mounted = (ClientShip) VSGameUtilsKt.getShipMountedTo(player); if (mounted != null) { ((HasOpenALVelocity) listener).setVelocity(mounted.getVelocity()); + } else { + final EntityDraggingInformation dragInfo = ((IEntityDraggingInformationProvider) player).getDraggingInformation(); + if (dragInfo.isEntityBeingDraggedByAShip()) { + final Vector3dc playerVel = dragInfo.getAddedMovementLastTick(); + ((HasOpenALVelocity) listener).setVelocity(playerVel); + } } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinAirCurrent.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinAirCurrent.java index 52f9d86f8..70c1592e9 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinAirCurrent.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/MixinAirCurrent.java @@ -94,7 +94,8 @@ private static void clipFlowLimit(Level level, BlockPos start, float max, Direct } } - @Redirect(method = "tickAffectedEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/AABB;intersects(Lnet/minecraft/world/phys/AABB;)Z")) + // Require 0 because this mixin doesn't work in create 0.5.1f + @Redirect(method = "tickAffectedEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/phys/AABB;intersects(Lnet/minecraft/world/phys/AABB;)Z"), require = 0) private boolean redirectIntersects(AABB instance, AABB other) { Ship ship = getShip(); if (ship != null) { @@ -104,13 +105,15 @@ private boolean redirectIntersects(AABB instance, AABB other) { } else return instance.intersects(other); } + // Require 0 because this mixin doesn't work in create 0.5.1f @Inject( - method = "tickAffectedEntities", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/world/entity/Entity;getDeltaMovement()Lnet/minecraft/world/phys/Vec3;" - ), - locals = LocalCapture.CAPTURE_FAILHARD + method = "tickAffectedEntities", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/world/entity/Entity;getDeltaMovement()Lnet/minecraft/world/phys/Vec3;" + ), + locals = LocalCapture.CAPTURE_FAILSOFT, + require = 0 ) private void harvester(Level world, Direction facing, CallbackInfo ci, Iterator iterator, Entity entity, Vec3 center, Vec3i flow, float sneakModifier, float speed, double entityDistance, float acceleration) { Ship ship = getShip(); @@ -122,8 +125,9 @@ private void harvester(Level world, Direction facing, CallbackInfo ci, Iterator< this.acceleration = acceleration; } + // Require 0 because this mixin doesn't work in create 0.5.1f @Redirect(method = "tickAffectedEntities", - at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V") + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setDeltaMovement(Lnet/minecraft/world/phys/Vec3;)V"), require = 0 ) private void redirectSetDeltaMovement(Entity instance, Vec3 motion) { Ship ship = getShip(); @@ -138,7 +142,8 @@ private void redirectSetDeltaMovement(Entity instance, Vec3 motion) { } } - @Redirect(method = "tickAffectedEntities", at = @At(value = "INVOKE", target = "Lcom/simibubi/create/foundation/utility/VecHelper;getCenterOf(Lnet/minecraft/core/Vec3i;)Lnet/minecraft/world/phys/Vec3;"), allow = 1) + // Require 0 because this mixin doesn't work in create 0.5.1f + @Redirect(method = "tickAffectedEntities", at = @At(value = "INVOKE", target = "Lcom/simibubi/create/foundation/utility/VecHelper;getCenterOf(Lnet/minecraft/core/Vec3i;)Lnet/minecraft/world/phys/Vec3;"), allow = 1, require = 0) private Vec3 redirectGetCenterOf(Vec3i pos) { Ship ship = getShip(); Vec3 result = VecHelper.getCenterOf(pos); diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/README.md b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/README.md new file mode 100644 index 000000000..2784f766a --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/README.md @@ -0,0 +1,8 @@ +# Create Compat + +This package contains the Create compatibility code + +## Attributions + +Most of this code was originally created by [FluffyJenkins](https://github.com/FluffyJenkins/). However, the git history +got clobbered when we transferred it over from the Clockwork repository, causing it to be attributed to StewStrong. diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/block/MixinStickerBlock.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/block/MixinStickerBlock.java index b939eed99..ab6a7a908 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/block/MixinStickerBlock.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/block/MixinStickerBlock.java @@ -18,23 +18,42 @@ @Mixin(StickerBlock.class) public abstract class MixinStickerBlock extends WrenchableDirectionalBlock implements IBE { - public MixinStickerBlock(Properties properties) { + public MixinStickerBlock(final Properties properties) { super(properties); } @Override - public void onRemove(@NotNull BlockState state, @NotNull Level world, @NotNull BlockPos pos, @NotNull BlockState newState, boolean isMoving) { + public void onRemove( + @NotNull final BlockState state, + @NotNull final Level world, + @NotNull final BlockPos pos, + @NotNull final BlockState newState, + final boolean isMoving + ) { IBE.onRemove(state, world, pos, newState); } - @Inject(method = "neighborChanged", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;", ordinal = 0), cancellable = true) - private void injectNeighbourChanged(BlockState state, Level worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving, CallbackInfo ci) { - StickerBlockEntity ste = getBlockEntity(worldIn, pos); - if (ste != null && ((IMixinStickerTileEntity) ste).isAlreadyPowered(false)) { + @Inject( + method = "neighborChanged", + at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/BlockState;getValue(Lnet/minecraft/world/level/block/state/properties/Property;)Ljava/lang/Comparable;", ordinal = 0), + cancellable = true + ) + private void injectNeighbourChanged( + final BlockState state, + final Level worldIn, + final BlockPos pos, + final Block blockIn, + final BlockPos fromPos, + final boolean isMoving, + final CallbackInfo ci + ) { + final StickerBlockEntity ste = getBlockEntity(worldIn, pos); + // By checking `instanceof IMixinStickerTileEntity` we only run this code if Clockwork is installed + if (ste instanceof final IMixinStickerTileEntity iMixinStickerTileEntity && iMixinStickerTileEntity.isAlreadyPowered(false)) { if (!worldIn.hasNeighborSignal(pos)) { ci.cancel(); } else { - ((IMixinStickerTileEntity) ste).isAlreadyPowered(true); + iMixinStickerTileEntity.isAlreadyPowered(true); } } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinOrientedContraptionEntity.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinOrientedContraptionEntity.java index 6b3a0ad4c..e69de29bb 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinOrientedContraptionEntity.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinOrientedContraptionEntity.java @@ -1,66 +0,0 @@ -package org.valkyrienskies.mod.mixin.mod_compat.create.client; - -import com.jozufozu.flywheel.util.transform.TransformStack; -import com.mojang.blaze3d.vertex.PoseStack; -import com.simibubi.create.content.contraptions.AbstractContraptionEntity; -import com.simibubi.create.content.contraptions.OrientedContraptionEntity; -import net.minecraft.client.Minecraft; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.phys.Vec3; -import org.joml.Quaterniond; -import org.joml.Vector3d; -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.Redirect; -import org.valkyrienskies.core.api.ships.ClientShip; -import org.valkyrienskies.mod.common.VSGameUtilsKt; -import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; - -@Mixin(OrientedContraptionEntity.class) -public class MixinOrientedContraptionEntity { - - @Shadow - private Vec3 getCartOffset(float partialTicks, Entity ridingEntity) { - return Vec3.ZERO; - } - - @Redirect(method = "applyLocalTransforms", at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/contraptions/OrientedContraptionEntity;repositionOnCart(Lcom/mojang/blaze3d/vertex/PoseStack;FLnet/minecraft/world/entity/Entity;)V")) - private void redirectRepositionOnCart(OrientedContraptionEntity instance, PoseStack matrixStack, float partialTicks, Entity ridingEntity) { - - Vec3 cartPos = getCartOffset(partialTicks, ridingEntity); - if (cartPos != Vec3.ZERO) matrixStack.translate(cartPos.x, cartPos.y, cartPos.z); - - ClientShip ship = (ClientShip) VSGameUtilsKt.getShipManagingPos(instance.getCommandSenderWorld(), ridingEntity.blockPosition()); - if (ship != null) { - Quaterniond quaternion = new Quaterniond(); - ship.getRenderTransform().getShipToWorld().getNormalizedRotation(quaternion); - TransformStack.cast(matrixStack).rotateCentered(VectorConversionsMCKt.toFloat(quaternion)); - } - } - - @Redirect(method = "repositionOnContraption", at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;translate(DDD)V", ordinal = 0)) - private void redirectTranslate(final PoseStack instance, final double pose, final double d, final double e) { - instance.translate(pose, d, e); - - ClientShip ship = (ClientShip) VSGameUtilsKt.getShipManagingPos(Minecraft.getInstance().level, ((AbstractContraptionEntity) (Object) this).getVehicle().blockPosition()); - if (ship != null) { - Quaterniond quaternion = new Quaterniond(); - ship.getRenderTransform().getShipToWorld().getNormalizedRotation(quaternion); - TransformStack.cast(instance).rotateCentered(VectorConversionsMCKt.toFloat(quaternion)); - } - } - - @Redirect(method = "getContraptionOffset", at = @At(value = "INVOKE", target = "Lcom/simibubi/create/content/contraptions/AbstractContraptionEntity;getPassengerPosition(Lnet/minecraft/world/entity/Entity;F)Lnet/minecraft/world/phys/Vec3;")) - private Vec3 redirectGetPassengerPosition(AbstractContraptionEntity instance, Entity passenger, float partialTicks) { - Vec3 result = instance.getPassengerPosition(passenger, partialTicks); - - ClientShip ship = (ClientShip) VSGameUtilsKt.getShipManagingPos(instance.getCommandSenderWorld(), instance.position()); - if (ship != null) { - Vector3d dest = new Vector3d(); - ship.getRenderTransform().getShipToWorld().transformPosition(VectorConversionsMCKt.toJOML(result), dest); - result = VectorConversionsMCKt.toMinecraft(dest); - } - return result; - } -} diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinTrackBlockOutline.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinTrackBlockOutline.java index 57496850d..0eb6df4d8 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinTrackBlockOutline.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/MixinTrackBlockOutline.java @@ -1,82 +1,93 @@ package org.valkyrienskies.mod.mixin.mod_compat.create.client; import com.simibubi.create.content.trains.track.TrackBlockOutline; +import com.simibubi.create.content.trains.track.TrackBlockOutline.BezierPointSelection; import com.simibubi.create.foundation.utility.RaycastHelper; -import java.util.List; import net.minecraft.client.Minecraft; import net.minecraft.client.player.LocalPlayer; import net.minecraft.core.BlockPos; import net.minecraft.world.entity.player.Player; import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult.Type; import net.minecraft.world.phys.Vec3; -import org.joml.Vector3d; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; 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.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.valkyrienskies.core.api.ships.Ship; import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; @Mixin(TrackBlockOutline.class) public class MixinTrackBlockOutline { + + @Shadow + public static BezierPointSelection result; + @Unique + private static boolean valkyrienskies$toShip = false; @Unique - private static boolean isShip = false; + private static Ship valkyrienskies$ship; @Unique - private static BlockPos shipBlockPos; + private static Vec3 valkyrienskies$originalOrigin; @Inject( - method = "pickCurves", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/player/LocalPlayer;getEyePosition(F)Lnet/minecraft/world/phys/Vec3;" - ), locals = LocalCapture.CAPTURE_FAILHARD + method = "pickCurves", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/player/LocalPlayer;getEyePosition(F)Lnet/minecraft/world/phys/Vec3;" + ), locals = LocalCapture.CAPTURE_FAILHARD ) private static void stuff(final CallbackInfo ci, final Minecraft mc) { - if (mc.hitResult != null && mc.level != null && mc.hitResult.getType() == Type.BLOCK) { - shipBlockPos = ((BlockHitResult) mc.hitResult).getBlockPos(); - - final List - ships = VSGameUtilsKt.transformToNearbyShipsAndWorld(mc.level, shipBlockPos.getX(), shipBlockPos.getY(), - shipBlockPos.getZ(), 10); - isShip = !ships.isEmpty(); + if (mc.hitResult != null && mc.level != null && mc.player != null) { + valkyrienskies$toShip = false; + final boolean playerOnShip = VSGameUtilsKt.isBlockInShipyard(mc.level, mc.player.getOnPos()); + final boolean hitResultOnShip = + VSGameUtilsKt.isBlockInShipyard(mc.level, ((BlockHitResult) mc.hitResult).getBlockPos()); + if (playerOnShip && !hitResultOnShip) { + valkyrienskies$ship = VSGameUtilsKt.getShipManagingPos(mc.level, mc.player.getOnPos()); + //if blockstate is air then transform to ship + valkyrienskies$toShip = mc.level.getBlockState(BlockPos.containing(mc.hitResult.location)).isAir(); + } else if (hitResultOnShip) { + valkyrienskies$toShip = true; + valkyrienskies$ship = + VSGameUtilsKt.getShipManagingPos(mc.level, ((BlockHitResult) mc.hitResult).getBlockPos()); + } } } @Redirect( - method = "pickCurves()V", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/player/LocalPlayer;getEyePosition(F)Lnet/minecraft/world/phys/Vec3;" - ) + method = "pickCurves", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/player/LocalPlayer;getEyePosition(F)Lnet/minecraft/world/phys/Vec3;" + ) ) private static Vec3 redirectedOrigin(final LocalPlayer instance, final float v) { final Vec3 eyePos = instance.getEyePosition(v); - if (isShip) { - final List - ships = VSGameUtilsKt.transformToNearbyShipsAndWorld(instance.level(), eyePos.x, eyePos.y, eyePos.z, 10); - if (ships.isEmpty()) { - return eyePos; - } - final Vector3d tempVec = ships.get(0); - return new Vec3(tempVec.x, tempVec.y, tempVec.z); + if (valkyrienskies$toShip) { + valkyrienskies$originalOrigin = eyePos; + return VectorConversionsMCKt.toMinecraft( + valkyrienskies$ship.getWorldToShip().transformPosition(VectorConversionsMCKt.toJOML(eyePos))); } else { return eyePos; } } @Redirect( - method = "pickCurves()V", - at = @At( - value = "INVOKE", - target = "Lcom/simibubi/create/foundation/utility/RaycastHelper;getTraceTarget(Lnet/minecraft/world/entity/player/Player;DLnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/phys/Vec3;" - ) + method = "pickCurves", + at = @At( + value = "INVOKE", + target = "Lcom/simibubi/create/foundation/utility/RaycastHelper;getTraceTarget(Lnet/minecraft/world/entity/player/Player;DLnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/phys/Vec3;" + ) ) private static Vec3 redirectedTarget(final Player playerIn, final double range, final Vec3 origin) { - if (isShip) { - return new Vec3(shipBlockPos.getX(), shipBlockPos.getY(), shipBlockPos.getZ()); + if (valkyrienskies$toShip) { + return VectorConversionsMCKt.toMinecraft( + valkyrienskies$ship.getWorldToShip().transformPosition(VectorConversionsMCKt.toJOML( + RaycastHelper.getTraceTarget(playerIn, range, valkyrienskies$originalOrigin)))); } else { return RaycastHelper.getTraceTarget(playerIn, range, origin); } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/trackOutlines/MixinBigOutlines.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/trackOutlines/MixinBigOutlines.java new file mode 100644 index 000000000..94ffa3406 --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/trackOutlines/MixinBigOutlines.java @@ -0,0 +1,92 @@ +package org.valkyrienskies.mod.mixin.mod_compat.create.client.trackOutlines; + +import com.simibubi.create.foundation.block.BigOutlines; +import com.simibubi.create.foundation.utility.RaycastHelper; +import net.minecraft.client.Minecraft; +import net.minecraft.client.player.LocalPlayer; +import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult.Type; +import net.minecraft.world.phys.Vec3; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.valkyrienskies.core.api.ships.Ship; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; + +@Mixin(BigOutlines.class) +public class MixinBigOutlines { + @Unique + private static boolean valkyrienskies$toShip = false; + + @Unique + private static Ship valkyrienskies$ship; + @Unique + private static Vec3 valkyrienskies$originalOrigin; + + @Inject( + method = "pick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/player/LocalPlayer;getEyePosition(F)Lnet/minecraft/world/phys/Vec3;" + ), locals = LocalCapture.CAPTURE_FAILHARD + ) + private static void stuff(final CallbackInfo ci, final Minecraft mc) { + if (mc.hitResult != null && mc.level != null && mc.player != null && mc.hitResult.getType() == Type.BLOCK) { + valkyrienskies$toShip = false; + final boolean playerOnShip = VSGameUtilsKt.isBlockInShipyard(mc.level, mc.player.getOnPos()); + final boolean hitResultOnShip = + VSGameUtilsKt.isBlockInShipyard(mc.level, ((BlockHitResult) mc.hitResult).getBlockPos()); + if (playerOnShip && !hitResultOnShip) { + valkyrienskies$ship = VSGameUtilsKt.getShipManagingPos(mc.level, mc.player.getOnPos()); + //if blockstate is air then transform to ship + valkyrienskies$toShip = mc.level.getBlockState(BlockPos.containing(mc.hitResult.location)).isAir(); + } else if (hitResultOnShip) { + valkyrienskies$toShip = true; + valkyrienskies$ship = + VSGameUtilsKt.getShipManagingPos(mc.level, ((BlockHitResult) mc.hitResult).getBlockPos()); + } + } + } + + @Redirect( + method = "pick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/player/LocalPlayer;getEyePosition(F)Lnet/minecraft/world/phys/Vec3;" + ) + ) + private static Vec3 redirectedOrigin(final LocalPlayer instance, final float v) { + final Vec3 eyePos = instance.getEyePosition(v); + if (valkyrienskies$toShip) { + valkyrienskies$originalOrigin = eyePos; + return VectorConversionsMCKt.toMinecraft( + valkyrienskies$ship.getWorldToShip().transformPosition(VectorConversionsMCKt.toJOML(eyePos))); + } else { + return eyePos; + } + } + + @Redirect( + method = "pick", + at = @At( + value = "INVOKE", + target = "Lcom/simibubi/create/foundation/utility/RaycastHelper;getTraceTarget(Lnet/minecraft/world/entity/player/Player;DLnet/minecraft/world/phys/Vec3;)Lnet/minecraft/world/phys/Vec3;" + ) + ) + private static Vec3 redirectedTarget(final Player playerIn, final double range, final Vec3 origin) { + if (valkyrienskies$toShip) { + return VectorConversionsMCKt.toMinecraft( + valkyrienskies$ship.getWorldToShip().transformPosition(VectorConversionsMCKt.toJOML( + RaycastHelper.getTraceTarget(playerIn, range, valkyrienskies$originalOrigin)))); + } else { + return RaycastHelper.getTraceTarget(playerIn, range, origin); + } + } +} diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/trackOutlines/MixinTrackBlockOutline.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/trackOutlines/MixinTrackBlockOutline.java new file mode 100644 index 000000000..1b8fbad96 --- /dev/null +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/client/trackOutlines/MixinTrackBlockOutline.java @@ -0,0 +1,134 @@ +package org.valkyrienskies.mod.mixin.mod_compat.create.client.trackOutlines; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.simibubi.create.content.trains.track.TrackBlockOutline; +import com.simibubi.create.content.trains.track.TrackBlockOutline.BezierPointSelection; +import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.LevelRenderer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; +import org.joml.Quaterniond; +import org.joml.Vector3d; +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.ModifyArg; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.valkyrienskies.core.api.ships.Ship; +import org.valkyrienskies.core.impl.game.ships.ShipObjectClient; +import org.valkyrienskies.mod.common.VSClientGameUtils; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; + +@Mixin(TrackBlockOutline.class) +public class MixinTrackBlockOutline { + @Unique + private static Vec3 valkyrienskies$cameraVec3; + @Unique + private static Vec3 valkyrienskies$vec; + @Unique + private static Vec3 valkyrienskies$angles; + + @Inject(method = "drawCurveSelection", + at = @At(value = "INVOKE", + target = "Lcom/simibubi/create/content/trains/track/TrackBlockOutline$BezierPointSelection;angles()Lnet/minecraft/world/phys/Vec3;"), + locals = LocalCapture.CAPTURE_FAILHARD) + private static void harvestDrawCurveSelection(final PoseStack ms, final MultiBufferSource buffer, final Vec3 camera, + final CallbackInfo ci, final Minecraft mc, + final BezierPointSelection result, final VertexConsumer vb, final Vec3 vec) { + valkyrienskies$cameraVec3 = camera; + valkyrienskies$vec = result.vec(); + valkyrienskies$angles = result.angles(); + } + @ModifyArg(method = "drawCurveSelection", + at = @At(value = "INVOKE", + target = "Lcom/simibubi/create/content/trains/track/TrackBlockOutline;renderShape(Lnet/minecraft/world/phys/shapes/VoxelShape;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Ljava/lang/Boolean;)V"), + index = 1) + private static PoseStack redirectTransformStackTranslate(final PoseStack ms) { + + final Level level = Minecraft.getInstance().level; + if (level != null && valkyrienskies$vec != null) { + final ShipObjectClient ship; + if ((ship = (ShipObjectClient) VSGameUtilsKt.getShipManagingPos(level, valkyrienskies$vec)) != null) { + final Quaterniond rotation = new Quaterniond().identity(); + final Quaterniond yawQuat = new Quaterniond().rotateY(valkyrienskies$angles.y); + final Quaterniond pitchQuat = new Quaterniond().rotateX(valkyrienskies$angles.x); + + yawQuat.mul(pitchQuat, rotation); + ship.getRenderTransform().getShipToWorldRotation().mul(rotation, rotation); + + final Vector3d worldVec = ship.getRenderTransform().getShipToWorld() + .transformPosition( + new Vector3d(valkyrienskies$vec.x, valkyrienskies$vec.y + .125, valkyrienskies$vec.z), + new Vector3d()); + + ms.popPose(); + ms.pushPose(); + ms.translate(worldVec.x - valkyrienskies$cameraVec3.x, + worldVec.y - valkyrienskies$cameraVec3.y, + worldVec.z - valkyrienskies$cameraVec3.z); + ms.mulPose(VectorConversionsMCKt.toFloat(rotation)); + ms.translate(-.5, -.125f, -.5); + } + } + return ms; + } + + @Unique + private static Camera valkyrienskies$info; + @Unique + private static BlockHitResult valkyrienskies$hitResult; + + @ModifyArg(method = "drawCustomBlockSelection", at = @At(value = "INVOKE", + target = "Lnet/minecraft/world/level/border/WorldBorder;isWithinBounds(Lnet/minecraft/core/BlockPos;)Z")) + private static BlockPos modIsWithinBounds(final BlockPos blockPos) { + final Level level = Minecraft.getInstance().level; + if (level != null) { + final Ship ship; + if ((ship = VSGameUtilsKt.getShipManagingPos(level, blockPos)) != null) { + return BlockPos.containing(VectorConversionsMCKt.toMinecraft(ship.getShipToWorld() + .transformPosition(VectorConversionsMCKt.toJOMLD(blockPos)))); + } + } + return blockPos; + } + + @Inject(method = "drawCustomBlockSelection", + at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;translate(DDD)V")) + private static void harvest(final LevelRenderer context, final Camera info, final HitResult hitResult, + final float partialTicks, + final PoseStack ms, final MultiBufferSource buffers, final CallbackInfoReturnable cir) { + valkyrienskies$info = info; + valkyrienskies$hitResult = (BlockHitResult) hitResult; + } + + @Redirect(method = "drawCustomBlockSelection", + at = @At(value = "INVOKE", target = "Lcom/mojang/blaze3d/vertex/PoseStack;translate(DDD)V")) + private static void redirectTranslate(final PoseStack instance, final double d, final double e, final double f) { + final Level level = Minecraft.getInstance().level; + if (level != null) { + final ShipObjectClient ship; + if ((ship = (ShipObjectClient) VSGameUtilsKt.getShipManagingPos(level, + valkyrienskies$hitResult.getBlockPos())) != null) { + final Vec3 camPos = valkyrienskies$info.getPosition(); + VSClientGameUtils.transformRenderWithShip(ship.getRenderTransform(), instance, + valkyrienskies$hitResult.getBlockPos(), + camPos.x, camPos.y, camPos.z); + } else { + instance.translate(d, e, f); + } + } else { + instance.translate(d, e, f); + } + } +} diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/entity/MixinAbstractContraptionEntity.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/entity/MixinAbstractContraptionEntity.java index 23a368f65..8c352d97b 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/entity/MixinAbstractContraptionEntity.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/entity/MixinAbstractContraptionEntity.java @@ -9,7 +9,6 @@ import com.simibubi.create.content.contraptions.OrientedContraptionEntity; import com.simibubi.create.content.contraptions.StructureTransform; import com.simibubi.create.content.contraptions.actors.harvester.HarvesterMovementBehaviour; -import com.simibubi.create.content.contraptions.actors.seat.SeatEntity; import com.simibubi.create.content.contraptions.behaviour.MovementBehaviour; import com.simibubi.create.content.contraptions.behaviour.MovementContext; import com.simibubi.create.content.kinetics.base.BlockBreakingMovementBehaviour; @@ -49,13 +48,14 @@ import org.valkyrienskies.core.api.ships.WingManager; import org.valkyrienskies.mod.common.CompatUtil; import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.IEntityDraggingInformationProvider; import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; import org.valkyrienskies.mod.compat.CreateConversionsKt; import org.valkyrienskies.mod.mixinducks.mod_compat.create.MixinAbstractContraptionEntityDuck; @Mixin(AbstractContraptionEntity.class) public abstract class MixinAbstractContraptionEntity extends Entity implements MixinAbstractContraptionEntityDuck, - ContraptionWingProvider { + ContraptionWingProvider, IEntityDraggingInformationProvider { public MixinAbstractContraptionEntity(EntityType entityType, Level level) { super(entityType, level); @@ -111,25 +111,6 @@ private void redirectTeleportTo(Entity instance, double x, double y, double z) { } } - //Region end - //Region start - fix entity rider position on ship contraptions - @Override - public void positionRider(@NotNull Entity passenger, MoveFunction callback) { - if (!hasPassenger(passenger)) - return; - Vec3 riderPos = getPassengerPosition(passenger, 1); - if (riderPos == null) - return; - if (!(passenger instanceof OrientedContraptionEntity)) { - Ship ship = VSGameUtilsKt.getShipManagingPos(passenger.level(), riderPos.x, riderPos.y, riderPos.z); - riderPos.add(0, SeatEntity.getCustomEntitySeatOffset(passenger) - 1 / 8f, 0); - if (ship != null) { - riderPos = toMinecraft(ship.getShipToWorld().transformPosition(toJOML(riderPos))); - } - } - passenger.setPos(riderPos); - } - @Inject(method = "toGlobalVector(Lnet/minecraft/world/phys/Vec3;FZ)Lnet/minecraft/world/phys/Vec3;", at = @At("HEAD"), cancellable = true) private void redirectToGlobalVector(Vec3 localVec, final float partialTicks, final boolean prevAnchor, final CallbackInfoReturnable cir) { @@ -309,8 +290,14 @@ private void postTick(final CallbackInfo ci) { final LoadedServerShip ship = VSGameUtilsKt.getShipObjectManagingPos(serverLevel, VectorConversionsMCKt.toJOML(thisAsAbstractContraptionEntity.position())); if (ship != null) { - // This can happen if a player moves a train contraption from ship to world using a wrench - ship.getAttachment(WingManager.class).setWingGroupTransform(wingGroupId, computeContraptionWingTransform()); + try { + // This can happen if a player moves a train contraption from ship to world using a wrench + ship.getAttachment(WingManager.class) + .setWingGroupTransform(wingGroupId, computeContraptionWingTransform()); + } catch (final Exception e) { + // I'm not sure why, but this fails sometimes. For now just catch the error and print it + e.printStackTrace(); + } } } } @@ -323,4 +310,9 @@ public Matrix4dc computeContraptionWingTransform() { final Vector3d pos = VectorConversionsMCKt.toJOML(thisAsAbstractContraptionEntity.getAnchorVec()); return new Matrix4d(rotationMatrix).setTranslation(pos); } + + @Override + public boolean vs$shouldDrag() { + return false; + } } diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/pr/MixinSeatBlock.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/pr/MixinSeatBlock.java index 50fb1f488..d5bd2167a 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/pr/MixinSeatBlock.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/create/pr/MixinSeatBlock.java @@ -40,8 +40,7 @@ private static void wrapSitDownSetPos(final SeatEntity seatEntity, final double at = @At( value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;blockPosition()Lnet/minecraft/core/BlockPos;" - ), - remap = false + ) ) private BlockPos wrapBlockPosInUpdateEntityAfterFallOn( final Entity entity, diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/sodium/MixinSodiumWorldRenderer.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/sodium/MixinSodiumWorldRenderer.java index fd894a38a..1ed8a2766 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/sodium/MixinSodiumWorldRenderer.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/sodium/MixinSodiumWorldRenderer.java @@ -6,7 +6,9 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectMap; import java.util.SortedSet; import me.jellysquid.mods.sodium.client.render.SodiumWorldRenderer; +import me.jellysquid.mods.sodium.client.render.chunk.RenderSectionManager; import net.minecraft.client.Camera; +import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderBuffers; @@ -17,9 +19,11 @@ import net.minecraft.world.phys.Vec3; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.valkyrienskies.core.api.ships.ClientShip; import org.valkyrienskies.mod.common.VSGameUtilsKt; @@ -30,6 +34,27 @@ public class MixinSodiumWorldRenderer { @Shadow private ClientLevel world; + @Shadow + private RenderSectionManager renderSectionManager; + + @Unique + private boolean vs$prevFrameHadShips = false; + + /** + * @reason Fix ship ghosts when ships are deleted and camera hasn't moved, and ships not rendering when teleported + * and camera hasn't moved + */ + @Inject(method = "updateChunks", at = @At("HEAD")) + private void preUpdateChunks(final CallbackInfo callbackInfo) { + final boolean curFrameHasShips = + !VSGameUtilsKt.getShipObjectWorld(Minecraft.getInstance()).getLoadedShips().isEmpty(); + // Mark the graph dirty if ships were loaded this frame or the previous one + if (vs$prevFrameHadShips || curFrameHasShips) { + this.renderSectionManager.markGraphDirty(); + } + vs$prevFrameHadShips = curFrameHasShips; + } + @Redirect(method = "renderTileEntities", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher;render(Lnet/minecraft/world/level/block/entity/BlockEntity;FLcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;)V")) private void renderShipChunkBlockEntity(final BlockEntityRenderDispatcher instance, final BlockEntity blockEntity, diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/vanilla_renderer/MixinLevelRendererVanilla.java b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/vanilla_renderer/MixinLevelRendererVanilla.java index 3d6c40e78..4c9e512a6 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/vanilla_renderer/MixinLevelRendererVanilla.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/mod_compat/vanilla_renderer/MixinLevelRendererVanilla.java @@ -94,7 +94,7 @@ private boolean needsFrustumUpdate(final boolean needsFrustumUpdate) { // force frustum update if default behaviour says to OR if the player is mounted to a ship return needsFrustumUpdate || - (player != null && VSGameUtilsKt.getShipObjectEntityMountedTo(level, player) != null); + (player != null && VSGameUtilsKt.getShipMountedTo(player) != null); } /** diff --git a/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/chunk/MixinChunkGenerator.java b/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/chunk/MixinChunkGenerator.java index d7590470e..f6bbff099 100644 --- a/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/chunk/MixinChunkGenerator.java +++ b/common/src/main/java/org/valkyrienskies/mod/mixin/world/level/chunk/MixinChunkGenerator.java @@ -23,6 +23,8 @@ @Mixin(ChunkGenerator.class) public class MixinChunkGenerator { + // TODO its pretty standard to extend this class, if they do super.whatever, these mixins will not work correctly + // tfc in forge part of the mod has a bandaid solution, if this is fixed please remove that @Inject(method = "findNearestMapStructure", at = @At("HEAD"), cancellable = true) private void preFindNearestMapFeature(ServerLevel serverLevel, HolderSet holderSet, BlockPos blockPos, int i, boolean bl, CallbackInfoReturnable>> cir) { if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(blockPos.getX() >> 4, blockPos.getZ() >> 4)) { diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt index 8fbae6f3d..7deaab3ea 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/VSGameUtils.kt @@ -36,6 +36,8 @@ import org.valkyrienskies.core.apigame.world.properties.DimensionId import org.valkyrienskies.core.game.ships.ShipObjectServer import org.valkyrienskies.core.impl.hooks.VSEvents.TickEndEvent import org.valkyrienskies.core.util.expand +import org.valkyrienskies.mod.common.entity.ShipMountedToData +import org.valkyrienskies.mod.common.entity.ShipMountedToDataProvider import org.valkyrienskies.mod.common.util.DimensionIdProvider import org.valkyrienskies.mod.common.util.MinecraftPlayer import org.valkyrienskies.mod.common.util.set @@ -246,11 +248,6 @@ fun Level?.getShipObjectManagingPos(posX: Double, posY: Double, posZ: Double) = fun Level?.getShipObjectManagingPos(chunkPos: ChunkPos) = getShipObjectManagingPos(chunkPos.x, chunkPos.z) -fun Level.getShipObjectEntityMountedTo(entity: Entity): LoadedShip? { - val vehicle = entity.vehicle ?: return null - return getShipObjectManagingPos(vehicle.position().toJOML()) -} - // ClientLevel fun ClientLevel?.getShipObjectManagingPos(chunkX: Int, chunkZ: Int) = getShipObjectManagingPosImpl(this, chunkX, chunkZ) as ClientShip? @@ -270,11 +267,6 @@ fun ClientLevel?.getShipObjectManagingPos(pos: Position) = fun ClientLevel?.getShipObjectManagingPos(chunkPos: ChunkPos) = getShipObjectManagingPos(chunkPos.x, chunkPos.z) -fun ClientLevel?.getShipObjectEntityMountedTo(entity: Entity): ClientShip? { - val vehicle = entity.vehicle ?: return null - return getShipObjectManagingPos(vehicle.position().toJOML()) -} - // ServerWorld fun ServerLevel?.getShipObjectManagingPos(chunkX: Int, chunkZ: Int) = getShipObjectManagingPosImpl(this, chunkX, chunkZ) as ShipObjectServer? @@ -421,7 +413,18 @@ fun Level.transformAabbToWorld(aabb: AABBdc, dest: AABBd): AABBd { return dest.set(aabb) } -fun Entity.getPassengerPos(myRidingOffset: Double, partialTicks: Float): Vector3dc { - return this.getPosition(partialTicks) - .add(0.0, this.passengersRidingOffset + myRidingOffset, 0.0).toJOML() +fun getShipMountedToData(passenger: Entity, partialTicks: Float? = null): ShipMountedToData? { + val vehicle = passenger.vehicle ?: return null + if (vehicle is ShipMountedToDataProvider) { + return vehicle.provideShipMountedToData(passenger, partialTicks) + } + val shipObjectEntityMountedTo = passenger.level().getShipObjectManagingPos(vehicle.position().toJOML()) ?: return null + val mountedPosInShip: Vector3dc = vehicle.getPosition(partialTicks ?: 0.0f) + .add(0.0, vehicle.passengersRidingOffset + passenger.myRidingOffset, 0.0).toJOML() + + return ShipMountedToData(shipObjectEntityMountedTo, mountedPosInShip) +} + +fun getShipMountedTo(entity: Entity): LoadedShip? { + return getShipMountedToData(entity)?.shipMountedTo } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt index d14b0ee8e..0fb4029ba 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/ValkyrienSkiesMod.kt @@ -77,6 +77,7 @@ object ValkyrienSkiesMod { output.accept(SHIP_CREATOR_ITEM) output.accept(SHIP_ASSEMBLER_ITEM) output.accept(SHIP_CREATOR_ITEM_SMALLER) + output.accept(PHYSICS_ENTITY_CREATOR_ITEM) } .build() } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/command/RelativeVector3.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/command/RelativeVector3.kt index f54cdb6d5..b935c2c63 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/command/RelativeVector3.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/command/RelativeVector3.kt @@ -6,10 +6,10 @@ import java.lang.Math.toRadians data class RelativeVector3(val x: RelativeValue, val y: RelativeValue, val z: RelativeValue) { fun toEulerRotation(sourcePitchDegrees: Double, sourceYawDegrees: Double, sourceRollDegrees: Double): Quaterniond = - Quaterniond().rotateXYZ( - toRadians(x.getRelativeValue(sourcePitchDegrees)), - toRadians(y.getRelativeValue(sourceYawDegrees)), + Quaterniond().rotateZYX( toRadians(z.getRelativeValue(sourceRollDegrees)), + toRadians(y.getRelativeValue(sourceYawDegrees)), + toRadians(x.getRelativeValue(sourcePitchDegrees)), ) fun toEulerRotationFromMCEntity(mcEntityPitch: Double, mcEntityYaw: Double) = diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountedToData.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountedToData.kt new file mode 100644 index 000000000..1cdd1996c --- /dev/null +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountedToData.kt @@ -0,0 +1,9 @@ +package org.valkyrienskies.mod.common.entity + +import org.joml.Vector3dc +import org.valkyrienskies.core.api.ships.LoadedShip + +data class ShipMountedToData( + val shipMountedTo: LoadedShip, + val mountPosInShip: Vector3dc, +) diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountedToDataProvider.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountedToDataProvider.kt new file mode 100644 index 000000000..852499f0b --- /dev/null +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/entity/ShipMountedToDataProvider.kt @@ -0,0 +1,7 @@ +package org.valkyrienskies.mod.common.entity + +import net.minecraft.world.entity.Entity + +interface ShipMountedToDataProvider { + fun provideShipMountedToData(passenger: Entity, partialTicks: Float?): ShipMountedToData? +} diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt index 95e0e8afe..b4ad34e82 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/item/ShipCreatorItem.kt @@ -1,6 +1,5 @@ package org.valkyrienskies.mod.common.item -import net.minecraft.Util import net.minecraft.network.chat.Component import net.minecraft.server.level.ServerLevel import net.minecraft.world.InteractionResult diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDragger.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDragger.kt index 4a2403548..a95c9c80d 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDragger.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDragger.kt @@ -4,7 +4,6 @@ import net.minecraft.server.level.ServerPlayer import net.minecraft.world.entity.Entity import org.joml.Vector3d import org.joml.Vector3dc -import org.valkyrienskies.mod.common.getShipObjectEntityMountedTo import org.valkyrienskies.mod.common.shipObjectWorld import kotlin.math.asin import kotlin.math.atan2 @@ -13,17 +12,13 @@ import kotlin.math.sin object EntityDragger { // How much we decay the addedMovement each tick after player hasn't collided with a ship for at least 10 ticks. - private const val addedMovementDecay = 0.9 + private const val ADDED_MOVEMENT_DECAY = 0.9 /** * Drag these entities with the ship they're standing on. */ fun dragEntitiesWithShips(entities: Iterable) { entities.forEach { entity -> - val shipMountedTo = entity.level().getShipObjectEntityMountedTo(entity) - // Don't drag entities that are already mounted to a ship - if (shipMountedTo != null) return@forEach - val entityDraggingInformation = (entity as IEntityDraggingInformationProvider).draggingInformation var dragTheEntity = false @@ -31,10 +26,12 @@ object EntityDragger { var addedYRot = 0.0 val shipDraggingEntity = entityDraggingInformation.lastShipStoodOn - if (shipDraggingEntity != null) { + + // Only drag entities that aren't mounted to vehicles + if (shipDraggingEntity != null && entity.vehicle == null) { if (entityDraggingInformation.isEntityBeingDraggedByAShip()) { // Compute how much we should drag the entity - val shipData = entity.level().shipObjectWorld.queryableShipData.getById(shipDraggingEntity) + val shipData = entity.level().shipObjectWorld.allShips.getById(shipDraggingEntity) if (shipData != null) { dragTheEntity = true @@ -87,8 +84,8 @@ object EntityDragger { } else { dragTheEntity = true addedMovement = entityDraggingInformation.addedMovementLastTick - .mul(addedMovementDecay, Vector3d()) - addedYRot = entityDraggingInformation.addedYawRotLastTick * addedMovementDecay + .mul(ADDED_MOVEMENT_DECAY, Vector3d()) + addedYRot = entityDraggingInformation.addedYawRotLastTick * ADDED_MOVEMENT_DECAY } } @@ -114,6 +111,7 @@ object EntityDragger { } } entityDraggingInformation.ticksSinceStoodOnShip++ + entityDraggingInformation.mountedToEntity = entity.vehicle != null } } } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDraggingInformation.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDraggingInformation.kt index e0b140942..353310f39 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDraggingInformation.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/EntityDraggingInformation.kt @@ -16,16 +16,24 @@ class EntityDraggingInformation { field = value } var ticksSinceStoodOnShip: Int = 0 + var mountedToEntity: Boolean = false // Used by the client rendering code only var cachedLastPosition: Vector3dc? = null var restoreCachedLastPosition = false fun isEntityBeingDraggedByAShip(): Boolean { - return (lastShipStoodOn != null) && (ticksSinceStoodOnShip < 10) + return (lastShipStoodOn != null) && (ticksSinceStoodOnShip < TICKS_TO_DRAG_ENTITIES) && !mountedToEntity + } + + companion object { + // Max number of ticks we will drag an entity after the entity has jumped off the ship + private const val TICKS_TO_DRAG_ENTITIES = 20 } } interface IEntityDraggingInformationProvider { val draggingInformation: EntityDraggingInformation + + fun `vs$shouldDrag`(): Boolean } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt index 75ec785d3..50cd358da 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/common/util/MinecraftPlayer.kt @@ -2,14 +2,11 @@ package org.valkyrienskies.mod.common.util import net.minecraft.world.entity.player.Player import org.joml.Vector3d -import org.joml.Vector3dc -import org.valkyrienskies.core.api.ships.properties.ShipId import org.valkyrienskies.core.apigame.world.IPlayer import org.valkyrienskies.core.apigame.world.PlayerState import org.valkyrienskies.core.apigame.world.properties.DimensionId import org.valkyrienskies.mod.common.dimensionId -import org.valkyrienskies.mod.common.getPassengerPos -import org.valkyrienskies.mod.common.getShipObjectEntityMountedTo +import org.valkyrienskies.mod.common.getShipMountedToData import org.valkyrienskies.mod.common.vsCore import java.lang.ref.WeakReference import java.util.UUID @@ -40,18 +37,13 @@ class MinecraftPlayer(playerObject: Player) : IPlayer { } override fun getPlayerState(): PlayerState { - var mountedShip: ShipId? = null - var mountedPos: Vector3dc? = null - player.level().getShipObjectEntityMountedTo(player)?.let { - mountedShip = it.id - mountedPos = player.vehicle!!.getPassengerPos(player.myRidingOffset, 0.0f) - } + val mountedShipAndPos = getShipMountedToData(player) return PlayerState( Vector3d(player.x, player.y, player.z), Vector3d(Vector3d(player.x - player.xo, player.y - player.yo, player.z - player.zo)), dimension, - mountedShip, - mountedPos, + mountedShipAndPos?.shipMountedTo?.id, + mountedShipAndPos?.mountPosInShip, ) } diff --git a/common/src/main/kotlin/org/valkyrienskies/mod/util/RelocationUtil.kt b/common/src/main/kotlin/org/valkyrienskies/mod/util/RelocationUtil.kt index 8dfc6199c..099b846a5 100644 --- a/common/src/main/kotlin/org/valkyrienskies/mod/util/RelocationUtil.kt +++ b/common/src/main/kotlin/org/valkyrienskies/mod/util/RelocationUtil.kt @@ -6,6 +6,7 @@ import net.minecraft.world.level.Level import net.minecraft.world.level.block.Blocks import net.minecraft.world.level.block.Rotation import net.minecraft.world.level.block.Rotation.NONE +import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.chunk.LevelChunk import org.valkyrienskies.core.api.ships.ServerShip @@ -40,6 +41,11 @@ fun relocateBlock( it.clearContent() } + // so loot containers dont drop its content + if (it is RandomizableContainerBlockEntity) { + it.setLootTable(null, 0) + } + tag } diff --git a/common/src/main/resources/assets/valkyrienskies/lang/en_us.json b/common/src/main/resources/assets/valkyrienskies/lang/en_us.json index ddd33df22..61876437a 100644 --- a/common/src/main/resources/assets/valkyrienskies/lang/en_us.json +++ b/common/src/main/resources/assets/valkyrienskies/lang/en_us.json @@ -20,5 +20,6 @@ "command.valkyrienskies.get_ship.fail": "No ship found", "command.valkyrienskies.get_ship.only_usable_by_entities": "/vs get-ship can only be run by entities!", "tooltip.valkyrienskies.mass": "Mass", - "command.valkyrienskies.scale.success": "Scaled %d ships!" + "command.valkyrienskies.scale.success": "Scaled %d ships!", + "itemGroup.valkyrienSkies": "Valkyrien Skies" } diff --git a/common/src/main/resources/data/valkyrienskies/vs_mass/1_19_blocks b/common/src/main/resources/data/valkyrienskies/vs_mass/1_19_blocks new file mode 100644 index 000000000..cee29a304 --- /dev/null +++ b/common/src/main/resources/data/valkyrienskies/vs_mass/1_19_blocks @@ -0,0 +1,132 @@ +[ + { + "block": "minecraft:pearlescent_froglight", + "mass": 3200.0, + "friction": 0.07, + "elasticity": 0.8 + }, + { + "block": "minecraft:verdant_froglight", + "mass": 3200.0, + "friction": 0.07, + "elasticity": 0.8 + }, + { + "block": "minecraft:ochre_froglight", + "mass": 3200.0, + "friction": 0.07, + "elasticity": 0.8 + }, + { + "block": "minecraft:frogspawn", + "mass": 1.0, + "friction": 0.03 + }, + { + "block": "minecraft:mangrove_log", + "mass": 900.0, + "friction": 0.6 + }, + { + "block": "minecraft:stripped_mangrove_log", + "mass": 900.0, + "friction": 0.4 + }, + { + "block": "minecraft:mangrove_wood", + "mass": 900.0, + "friction": 0.6 + }, + { + "block": "minecraft:stripped_mangrove_wood", + "mass": 900.0, + "friction": 0.4 + }, + { + "block": "minecraft:mangrove_planks", + "mass": 600.0, + "friction": 0.5 + }, + { + "block": "minecraft:mangrove_slab", + "mass": 300.0, + "friction": 0.5 + }, + { + "block": "minecraft:mangrove_stairs", + "mass": 450.0, + "friction": 0.5 + }, + { + "block": "minecraft:mangrove_propagule", + "mass": 15.0 + }, + { + "block": "minecraft:mangrove_roots", + "mass": 50.0, + "friction": 0.8 + }, + { + "block": "minecraft:muddy_mangrove_roots", + "mass": 1800.0, + "friction": 0.8 + }, + { + "block": "minecraft:mud", + "mass": 1800.0, + "friction": 0.9 + }, + { + "block": "minecraft:packed_mud", + "mass": 1450.0, + "friction": 0.7 + }, + { + "block": "minecraft:mud_bricks", + "mass": 1450.0, + "friction": 0.7 + }, + { + "block": "minecraft:mud_brick_wall", + "mass": 725.0, + "friction": 0.7 + }, + { + "block": "minecraft:mud_brick_slab", + "mass": 725.0, + "friction": 0.7 + }, + { + "block": "minecraft:mud_brick_stairs", + "mass": 1035.0, + "friction": 0.7 + }, + { + "block": "minecraft:reinforced_deepslate", + "mass": 3400.0, + "friction": 0.7 + }, + { + "block": "minecraft:sculk", + "mass": 400.0, + "friction": 0.2, + "elasticity": 0.3 + }, + { + "block": "minecraft:sculk_catalyst", + "mass": 600.0, + "friction": 0.2 + }, + { + "block": "minecraft:sculk_shrieker", + "mass": 200.0, + "friction": 0.2, + "elasticity": 0.3 + }, + { + "block": "minecraft:sculk_vein", + "mass": 8.0, + "friction": 0.2, + "elasticity": 0.03 + } +] diff --git a/common/src/main/resources/data/valkyrienskies/vs_mass/1_20_blocks b/common/src/main/resources/data/valkyrienskies/vs_mass/1_20_blocks new file mode 100644 index 000000000..4a443127c --- /dev/null +++ b/common/src/main/resources/data/valkyrienskies/vs_mass/1_20_blocks @@ -0,0 +1,133 @@ +[ + { + "tag": "minecraft:all_hanging_signs", + "mass": 20.0, + "friction": 0.5 + }, + { + "block": "minecraft:bamboo_block", + "mass": 150.0, + "friction": 0.6 + }, + { + "block": "minecraft:stripped_bamboo_block", + "mass": 150.0, + "friction": 0.4 + }, + { + "block": "minecraft:bamboo_planks", + "mass": 100.0, + "friction": 0.5 + }, + { + "block": "minecraft:bamboo_mosaic", + "mass": 100.0, + "friction": 0.5 + }, + { + "block": "minecraft:bamboo_mosaic_slab", + "mass": 50.0, + "friction": 0.5 + }, + { + "block": "minecraft:bamboo_slab", + "mass": 50.0, + "friction": 0.5 + }, + { + "block": "minecraft:bamboo_stairs", + "mass": 75.0, + "friction": 0.5 + }, + { + "block": "minecraft:bamboo_mosaic_stairs", + "mass": 75.0, + "friction": 0.5 + }, + { + "block": "minecraft:calibrated_sculk_sensor", + "mass": 230.0, + "friction": 0.9, + "elasticity": 0.3 + }, + { + "block": "minecraft:cherry_wood", + "mass": 640.0, + "friction": 0.6 + }, + { + "block": "minecraft:cherry_log", + "mass": 640.0, + "friction": 0.6 + }, + { + "block": "minecraft:stripped_cherry_wood", + "mass": 640.0, + "friction": 0.4 + }, + { + "block": "minecraft:stripped_cherry_log", + "mass": 640.0, + "friction": 0.4 + }, + { + "block": "minecraft:cherry_planks", + "mass": 425.0, + "friction": 0.5 + }, + { + "block": "minecraft:cherry_slab", + "mass": 210.0, + "friction": 0.5 + }, + { + "block": "minecraft:cherry_stairs", + "mass": 315.0, + "friction": 0.5 + }, + { + "block": "minecraft:chiseled_bookshelf", + "mass": 650.0, + "friction": 0.5 + }, + { + "block": "minecraft:decorated_pot", + "mass": 250.0, + "friction": 0.35 + }, + { + "block": "minecraft:piglin_head", + "mass": 5.0 + }, + { + "block": "minecraft:piglin_wall_head", + "mass": 5.0 + }, + { + "block": "minecraft:pink_petals", + "mass": 1.0 + }, + { + "block": "minecraft:sniffer_egg", + "mass": 980.0, + "friction": 0.1 + }, + { + "block": "minecraft:suspicious_sand", + "mass": 1565.0, + "friction": 0.4 + }, + { + "block": "minecraft:suspicious_gravel", + "mass": 1685.0, + "friction": 0.7 + }, + { + "block": "minecraft:torchflower_crop", + "mass": 2.0 + }, + { + "block": "minecraft:pitcher_crop", + "mass": 2.0 + } +] diff --git a/common/src/main/resources/data/valkyrienskies/vs_mass/masonry.json b/common/src/main/resources/data/valkyrienskies/vs_mass/masonry.json index bd5e2a265..a2a151ed6 100644 --- a/common/src/main/resources/data/valkyrienskies/vs_mass/masonry.json +++ b/common/src/main/resources/data/valkyrienskies/vs_mass/masonry.json @@ -4,6 +4,16 @@ "mass": 1300.0, "friction": 0.6 }, + { + "block": "minecraft:cut_red_sandstone", + "mass": 2300.0, + "friction": 0.6 + }, + { + "block": "minecraft:cut_sandstone", + "mass": 2300.0, + "friction": 0.6 + }, { "block": "minecraft:smooth_stone_slab", "mass": 1300.0, diff --git a/common/src/main/resources/valkyrienskies-common.mixins.json b/common/src/main/resources/valkyrienskies-common.mixins.json index ba96e2334..3627169c5 100644 --- a/common/src/main/resources/valkyrienskies-common.mixins.json +++ b/common/src/main/resources/valkyrienskies-common.mixins.json @@ -78,7 +78,6 @@ "mod_compat.create.blockentity.MixinCrushingWheelControllerTileEntity", "mod_compat.create.blockentity.MixinEjectorTileEntity", "mod_compat.create.blockentity.MixinEncasedFanTileEntity", - "mod_compat.create.client.MixinValueBox", "mod_compat.create.entity.MixinAbstractContraptionEntity", "mod_compat.create.entity.MixinCarriageContraptionEntity", "mod_compat.create.entity.MixinControlledContraptionEntity", @@ -156,13 +155,15 @@ "mod_compat.create.client.MixinLinkRenderer", "mod_compat.create.client.MixinMinecartInstance", "mod_compat.create.client.MixinMultiplePlacementHelpers", - "mod_compat.create.client.MixinOrientedContraptionEntity", "mod_compat.create.client.MixinOutline", "mod_compat.create.client.MixinPlacementHelpers", "mod_compat.create.client.MixinSoundScapes", "mod_compat.create.client.MixinTileEntityRenderHelper", "mod_compat.create.client.MixinTrackBlockOutline", "mod_compat.create.client.MixinTrainRelocator", + "mod_compat.create.client.trackOutlines.MixinBigOutlines", + "mod_compat.create.client.trackOutlines.MixinTrackBlockOutline", + "mod_compat.create.client.MixinValueBox", "mod_compat.flywheel.InstancingEngineAccessor", "mod_compat.flywheel.MixinBlockEntityInstanceManager", "mod_compat.flywheel.MixinInstanceManager", diff --git a/fabric/build.gradle b/fabric/build.gradle index 0f2c84234..888b16d0b 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -41,7 +41,8 @@ dependencies { include(modImplementation("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}")) modImplementation("maven.modrinth:sodium:${sodium_version}") - modRuntimeOnly("maven.modrinth:indium:${indium_version}") + // Disable indium until we update sodium to newer versions + // modRuntimeOnly("maven.modrinth:indium:${indium_version}") modImplementation("maven.modrinth:modmenu:${modmenu_version}") // Depend on the fabric API @@ -63,9 +64,9 @@ dependencies { } // CC Restitched - modImplementation("curse.maven:cc-restitched-462672:3908334"){ - exclude module: "jsonschema.module.addon" - } + //modImplementation("curse.maven:cc-restitched-462672:3908334"){ + // exclude module: "jsonschema.module.addon" + //} // CC Restitched //modImplementation("curse.maven:cc-tweaked-282001:${cc_tweaked_version}") @@ -82,8 +83,7 @@ dependencies { modImplementation("io.github.fabricators_of_create.Porting-Lib:$module:$port_lib_version") } - //modImplementation("me.alphamode:ForgeTags:${forge_tags_version}") - modImplementation("net.minecraftforge:forgeconfigapiport-fabric:${forge_config_api_port_version}") + modImplementation("curse.maven:forge-config-api-port-fabric-547434:$config_api_id") modImplementation("com.jamieswhiteshirt:reach-entity-attributes:${reach_entity_attributes_version}") modImplementation("dev.cafeteria:fake-player-api:${fake_player_api_version}") modImplementation("io.github.tropheusj:milk-lib:${milk_lib_version}") diff --git a/fabric/gradle.properties b/fabric/gradle.properties index 765de32ce..99711d555 100644 --- a/fabric/gradle.properties +++ b/fabric/gradle.properties @@ -11,7 +11,6 @@ reach_entity_attributes_version=2.4.0 # https://github.com/Fabricators-of-Create/Create/blob/4724359545de070788221dbb6387c31e582e9d45/gradle.properties#L32C14-L32C14 registrate_version=1.3.62-MC1.20.1 -forge_tags_version=2.1 # https://github.com/Fabricators-of-Create/Create/blob/4724359545de070788221dbb6387c31e582e9d45/gradle.properties#L33 milk_lib_version=1.2.60 # https://github.com/Fabricators-of-Create/Create/blob/4724359545de070788221dbb6387c31e582e9d45/gradle.properties#L35 diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 42091e2a0..248f4c0db 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -31,7 +31,7 @@ "depends": { "fabricloader": ">=0.14.9", "minecraft": "1.20.1", - "fabric": "*" + "fabric-api": "*" }, "breaks": { "sodium": ">=0.5.0" diff --git a/forge/build.gradle b/forge/build.gradle index 368b8faff..1ac96a971 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -78,6 +78,9 @@ dependencies { // TIS-3d modCompileOnly("maven.modrinth:tis3d:${tis3d_version}") + // Modular Routers + modCompileOnly("curse.maven:mr-250294:4696089") + // Add Kotlin for Forge (3.12.0) forgeRuntimeLibrary("maven.modrinth:kotlin-for-forge:${kotlin_version}") @@ -110,12 +113,12 @@ dependencies { transitive = false } - forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api_krunch:1.0.0+10c94b01e2") { + forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api_krunch:1.0.0+7db6a103f1") { exclude group: 'org.joml', module: 'joml' transitive = false } - forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api:1.0.0+94304c13aa") { + forgeRuntimeLibrary shadowCommon("org.valkyrienskies:physics_api:1.0.0+0ba0cc41e1") { exclude group: 'org.joml', module: 'joml' transitive = false } diff --git a/forge/gradle.properties b/forge/gradle.properties index 6c603eac6..aac779c6e 100644 --- a/forge/gradle.properties +++ b/forge/gradle.properties @@ -3,7 +3,7 @@ loom.platform=forge kotlin.stdlib.default.dependency=false #Deps kotlin_version = 4.3.0 -cloth_config_version = 8.3.103 +cloth_config_version = 11.1.106 #Compat # https://github.com/Creators-of-Create/Create/wiki/Depending-on-Create diff --git a/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/compat/modular_routers/MixinRouterMenu.java b/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/compat/modular_routers/MixinRouterMenu.java new file mode 100644 index 000000000..8d278bd20 --- /dev/null +++ b/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/compat/modular_routers/MixinRouterMenu.java @@ -0,0 +1,35 @@ +package org.valkyrienskies.mod.forge.mixin.compat.modular_routers; + +import me.desht.modularrouters.block.tile.ModularRouterBlockEntity; +import me.desht.modularrouters.container.RouterMenu; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import org.joml.Vector3d; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.valkyrienskies.core.api.ships.Ship; +import org.valkyrienskies.mod.common.VSGameUtilsKt; +import org.valkyrienskies.mod.common.util.VectorConversionsMCKt; + +@Pseudo +@Mixin(RouterMenu.class) +public class MixinRouterMenu { + @Shadow + @Final + private ModularRouterBlockEntity router; + + @Redirect(method = "stillValid", at = @At(target = "Lnet/minecraft/world/phys/Vec3;distanceToSqr(Lnet/minecraft/world/phys/Vec3;)D", value = "INVOKE")) + private double ValkyrienSkies$distanceCheck(final Vec3 instance, final Vec3 vec3) { + final Level level = router.getLevel(); + final Ship ship = VSGameUtilsKt.getShipManagingPos(level, instance); + if (ship == null) + return instance.distanceToSqr(vec3); + + final Vector3d newInstance = ship.getTransform().getShipToWorld().transformPosition(VectorConversionsMCKt.toJOML(instance)); + return VectorConversionsMCKt.toMinecraft(newInstance).distanceToSqr(vec3); + } +} diff --git a/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/compat/tfc/MixinTFCChunkGenerator.java b/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/compat/tfc/MixinTFCChunkGenerator.java new file mode 100644 index 000000000..16fc6dba0 --- /dev/null +++ b/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/compat/tfc/MixinTFCChunkGenerator.java @@ -0,0 +1,99 @@ +package org.valkyrienskies.mod.forge.mixin.compat.tfc; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.Executor; +import net.minecraft.core.RegistryAccess; +import net.minecraft.server.level.WorldGenRegion; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.LevelHeightAccessor; +import net.minecraft.world.level.NoiseColumn; +import net.minecraft.world.level.StructureManager; +import net.minecraft.world.level.WorldGenLevel; +import net.minecraft.world.level.biome.BiomeManager; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.ChunkGeneratorStructureState; +import net.minecraft.world.level.levelgen.GenerationStep; +import net.minecraft.world.level.levelgen.RandomState; +import net.minecraft.world.level.levelgen.blending.Blender; +import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Pseudo; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.valkyrienskies.mod.common.VS2ChunkAllocator; + +@Pseudo +@Mixin(targets = "net.dries007.tfc.world.TFCChunkGenerator") +public class MixinTFCChunkGenerator { + @Inject(method = "m_213609_", at = @At("HEAD"), cancellable = true) + private void preApplyBiomeDecoration( + WorldGenLevel worldGenLevel, ChunkAccess chunkAccess, StructureManager structureManager, CallbackInfo callbackInfo + ) { + final ChunkPos chunkPos = chunkAccess.getPos(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + callbackInfo.cancel(); + } + } + + @Inject(method = "m_255037_", at = @At("HEAD"), cancellable = true) + private void preCreateStructures( + RegistryAccess registryAccess, ChunkGeneratorStructureState chunkGeneratorStructureState, StructureManager structureManager, ChunkAccess chunkAccess, StructureTemplateManager structureTemplateManager, CallbackInfo callbackInfo + ) { + final ChunkPos chunkPos = chunkAccess.getPos(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + callbackInfo.cancel(); + } + } + + @Inject(method = "m_223076_", at = @At("HEAD"), cancellable = true) + private void preCreateReferences( + WorldGenLevel worldGenLevel, StructureManager structureManager, ChunkAccess chunkAccess, CallbackInfo callbackInfo + ) { + final ChunkPos chunkPos = chunkAccess.getPos(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + callbackInfo.cancel(); + } + } + + @Inject(method = "m_214184_", at = @At("HEAD"), cancellable = true) + private void preGetBaseColumn(int i, int j, LevelHeightAccessor levelHeightAccessor, CallbackInfoReturnable cir) { + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(i, j)) { + cir.setReturnValue(new NoiseColumn(0, new BlockState[0])); + } + } + + @Inject(method = "m_214194_", at = @At("HEAD"), cancellable = true) + private void preBuildSurface(WorldGenRegion worldGenRegion, StructureManager structureManager, RandomState randomState, ChunkAccess chunkAccess, CallbackInfo ci) { + final ChunkPos chunkPos = chunkAccess.getPos(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + ci.cancel(); + } + } + + @Inject(method = "m_213679_", at = @At("HEAD"), cancellable = true) + private void preApplyCarvers(WorldGenRegion worldGenRegion, long l, RandomState randomState, BiomeManager biomeManager, StructureManager structureManager, ChunkAccess chunkAccess, GenerationStep.Carving carving, CallbackInfo ci) { + final ChunkPos chunkPos = chunkAccess.getPos(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + ci.cancel(); + } + } + + @Inject(method = "m_213974_", at = @At("HEAD"), cancellable = true) + private void preFillFromNoise(Executor executor, Blender blender, RandomState randomState, StructureManager structureManager, ChunkAccess chunkAccess, CallbackInfoReturnable> cir) { + final ChunkPos chunkPos = chunkAccess.getPos(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + cir.setReturnValue(CompletableFuture.completedFuture(chunkAccess)); + } + } + + @Inject(method = "m_6929_", at = @At("HEAD"), cancellable = true) + private void preSpawnOriginalMobs(WorldGenRegion worldGenRegion, CallbackInfo ci) { + final ChunkPos chunkPos = worldGenRegion.getCenter(); + if (VS2ChunkAllocator.INSTANCE.isChunkInShipyardCompanion(chunkPos.x, chunkPos.z)) { + ci.cancel(); + } + } +} diff --git a/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/feature/forge_interact/MixinIForgePlayer.java b/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/feature/forge_interact/MixinIForgePlayer.java index aae6afa18..5ed417167 100644 --- a/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/feature/forge_interact/MixinIForgePlayer.java +++ b/forge/src/main/java/org/valkyrienskies/mod/forge/mixin/feature/forge_interact/MixinIForgePlayer.java @@ -18,13 +18,16 @@ public interface MixinIForgePlayer { @Shadow Player self(); + @Shadow + double getBlockReach(); + /** * Include ships in server-side distance check when player interacts with a block. */ @Overwrite(remap = false) default boolean canReach(final BlockPos pos, final double padding) { if (VSGameConfig.SERVER.getEnableInteractDistanceChecks()) { - final double reach = this.self().getEntityReach() + padding; + final double reach = this.getBlockReach() + padding; final Vec3 eyes = this.self().getEyePosition(); return VSGameUtilsKt.squaredDistanceBetweenInclShips(this.self().level(), pos.getX() + 0.5, diff --git a/forge/src/main/kotlin/org/valkyrienskies/mod/forge/common/ValkyrienSkiesModForge.kt b/forge/src/main/kotlin/org/valkyrienskies/mod/forge/common/ValkyrienSkiesModForge.kt index 354982fb0..58faea254 100644 --- a/forge/src/main/kotlin/org/valkyrienskies/mod/forge/common/ValkyrienSkiesModForge.kt +++ b/forge/src/main/kotlin/org/valkyrienskies/mod/forge/common/ValkyrienSkiesModForge.kt @@ -20,7 +20,6 @@ import net.minecraftforge.event.TagsUpdatedEvent import net.minecraftforge.fml.ModLoadingContext import net.minecraftforge.fml.common.Mod import net.minecraftforge.fml.common.Mod.EventBusSubscriber.Bus -import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent import net.minecraftforge.fml.loading.FMLEnvironment import net.minecraftforge.registries.DeferredRegister @@ -53,12 +52,12 @@ import org.valkyrienskies.mod.common.item.ShipAssemblerItem import org.valkyrienskies.mod.common.item.ShipCreatorItem import org.valkyrienskies.mod.compat.clothconfig.VSClothConfig -@Mod(ValkyrienSkiesMod.MOD_ID) +@Mod(MOD_ID) class ValkyrienSkiesModForge { - private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, ValkyrienSkiesMod.MOD_ID) - private val ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, ValkyrienSkiesMod.MOD_ID) - private val ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, ValkyrienSkiesMod.MOD_ID) - private val BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, ValkyrienSkiesMod.MOD_ID) + private val BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, MOD_ID) + private val ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MOD_ID) + private val ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MOD_ID) + private val BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, MOD_ID) private val TEST_CHAIR_REGISTRY: RegistryObject private val TEST_HINGE_REGISTRY: RegistryObject private val TEST_FLAP_REGISTRY: RegistryObject @@ -144,7 +143,7 @@ class ValkyrienSkiesModForge { ::ShipMountingEntity, MobCategory.MISC ).sized(.3f, .3f) - .build(ResourceLocation(ValkyrienSkiesMod.MOD_ID, "ship_mounting_entity").toString()) + .build(ResourceLocation(MOD_ID, "ship_mounting_entity").toString()) } PHYSICS_ENTITY_TYPE_REGISTRY = ENTITIES.register("vs_physics_entity") { @@ -154,7 +153,7 @@ class ValkyrienSkiesModForge { ).sized(.3f, .3f) .setUpdateInterval(1) .clientTrackingRange(10) - .build(ResourceLocation(ValkyrienSkiesMod.MOD_ID, "vs_physics_entity").toString()) + .build(ResourceLocation(MOD_ID, "vs_physics_entity").toString()) } SHIP_ASSEMBLER_ITEM_REGISTRY = @@ -163,7 +162,7 @@ class ValkyrienSkiesModForge { BlockEntityType.Builder.of(::TestHingeBlockEntity, TestHingeBlock).build(null) } - val deferredRegister = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MOD_ID); + val deferredRegister = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, MOD_ID) deferredRegister.register("general") { ValkyrienSkiesMod.createCreativeTab() } @@ -216,5 +215,6 @@ class ValkyrienSkiesModForge { ValkyrienSkiesMod.PHYSICS_ENTITY_TYPE = PHYSICS_ENTITY_TYPE_REGISTRY.get() ValkyrienSkiesMod.SHIP_ASSEMBLER_ITEM = SHIP_ASSEMBLER_ITEM_REGISTRY.get() ValkyrienSkiesMod.TEST_HINGE_BLOCK_ENTITY_TYPE = TEST_HINGE_BLOCK_ENTITY_TYPE_REGISTRY.get() + ValkyrienSkiesMod.PHYSICS_ENTITY_CREATOR_ITEM = PHYSICS_ENTITY_CREATOR_ITEM_REGISTRY.get() } } diff --git a/forge/src/main/resources/valkyrienskies-forge.mixins.json b/forge/src/main/resources/valkyrienskies-forge.mixins.json index 8446ba7f7..896f1f787 100644 --- a/forge/src/main/resources/valkyrienskies-forge.mixins.json +++ b/forge/src/main/resources/valkyrienskies-forge.mixins.json @@ -7,8 +7,10 @@ "compat.create.MixinBlocks", "compat.create.MixinControlledContraptionEntity", "compat.immersivengineering.MixinBlockEntityInventory", + "compat.tfc.MixinTFCChunkGenerator", "compat.thermalexpansion.MixinTileCoFH", "compat.tis3d.MixinInfraredPacketEntity", + "compat.modular_routers.MixinRouterMenu", "feature.forge_interact.MixinIForgePlayer", "feature.water_in_ships_entity.MixinEntity", "world.level.block.FireMixin" diff --git a/gradle.properties b/gradle.properties index f4c7db66a..dd33285cf 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=1G minecraft_version=1.20.1 enabled_platforms=quilt,fabric,forge archives_base_name=valkyrienskies-120 -mod_version=2.1.4 +mod_version=2.1.3-beta.2 maven_group=org.valkyrienskies.mod # https://www.curseforge.com/minecraft/mc-mods/architectury-api/files/ @@ -26,7 +26,7 @@ flywheel_version_fabric=0.6.9-6 # https://modrinth.com/mod/create-big-cannons/versions createbigcannons_version= 0.5.2.a -vs_core_version=1.1.0+e26d9059c0 +vs_core_version=1.1.0+7dbd2ee63a # Prevent kotlin from autoincluding stdlib as a dependency, which breaks # gradle's composite builds (includeBuild) for some reason. We'll add it manually kotlin.stdlib.default.dependency=false