diff --git a/settings.gradle.kts b/settings.gradle.kts index 72be57de..5efdabc3 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -17,7 +17,7 @@ stonecutter { centralScript = "build.gradle.kts" shared { - versions("1.21", "1.21.3", "1.21.4", "1.21.5") + versions("1.21.3", "1.21.4", "1.21.5") vcsVersion = "1.21.4" } create(rootProject) diff --git a/src/main/java/me/nobaboy/nobaaddons/ducks/EntityStateCaptureDuck.java b/src/main/java/me/nobaboy/nobaaddons/ducks/EntityStateCaptureDuck.java deleted file mode 100644 index c3a76560..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/ducks/EntityStateCaptureDuck.java +++ /dev/null @@ -1,11 +0,0 @@ -package me.nobaboy.nobaaddons.ducks; - -import net.minecraft.entity.Entity; -import org.jetbrains.annotations.Nullable; - -//? if >=1.21.2 { -public interface EntityStateCaptureDuck { - @Nullable Entity nobaaddons$getEntity(); - void nobaaddons$setEntity(@Nullable Entity entity); -} -//?} diff --git a/src/main/java/me/nobaboy/nobaaddons/ducks/FishingBobberTimerDuck.java b/src/main/java/me/nobaboy/nobaaddons/ducks/FishingBobberTimerDuck.java deleted file mode 100644 index b5ee3db4..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/ducks/FishingBobberTimerDuck.java +++ /dev/null @@ -1,8 +0,0 @@ -package me.nobaboy.nobaaddons.ducks; - -import java.time.Instant; - -public interface FishingBobberTimerDuck { - Instant nobaaddons$spawnedAt(); - void nobaaddons$markSpawnTime(); -} diff --git a/src/main/java/me/nobaboy/nobaaddons/ducks/ItemSkyblockDataCache.java b/src/main/java/me/nobaboy/nobaaddons/ducks/ItemSkyblockDataCache.java new file mode 100644 index 00000000..870cbdef --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/ducks/ItemSkyblockDataCache.java @@ -0,0 +1,15 @@ +package me.nobaboy.nobaaddons.ducks; + +import me.nobaboy.nobaaddons.utils.items.SkyBlockItemData; +import net.minecraft.component.ComponentHolder; +import net.minecraft.component.DataComponentTypes; +import org.jetbrains.annotations.NotNull; + +public interface ItemSkyblockDataCache extends ComponentHolder { + @SuppressWarnings("unused") // loud incorrect buzzer + @NotNull SkyBlockItemData nobaaddons$getSkyblockData(); + + default SkyBlockItemData nobaaddons$createSkyblockItemData() { + return new SkyBlockItemData(() -> get(DataComponentTypes.CUSTOM_DATA), () -> get(DataComponentTypes.LORE), this::hashCode); + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/ducks/StateDataHolder.java b/src/main/java/me/nobaboy/nobaaddons/ducks/StateDataHolder.java new file mode 100644 index 00000000..1a6fee1b --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/ducks/StateDataHolder.java @@ -0,0 +1,13 @@ +package me.nobaboy.nobaaddons.ducks; + +import me.nobaboy.nobaaddons.utils.render.EntityDataKey; + +import java.util.Map; + +/** + * @see EntityDataKey + */ +public interface StateDataHolder { + @SuppressWarnings("unused") // incorrect + Map, EntityDataKey.Value> nobaaddons$getData(); +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/accessors/DrawContextAccessor.java b/src/main/java/me/nobaboy/nobaaddons/mixins/accessors/DrawContextAccessor.java index ab08f77d..e2c0316a 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/accessors/DrawContextAccessor.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/accessors/DrawContextAccessor.java @@ -5,9 +5,7 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; -//? if >=1.21.2 { @Mixin(DrawContext.class) public interface DrawContextAccessor { @Accessor VertexConsumerProvider.Immediate getVertexConsumers(); } -//?} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/EntityStateCaptureDuckImpl.java b/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/EntityStateCaptureDuckImpl.java deleted file mode 100644 index e7820d90..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/EntityStateCaptureDuckImpl.java +++ /dev/null @@ -1,26 +0,0 @@ -package me.nobaboy.nobaaddons.mixins.duckimpl; - -//? if >=1.21.2 { -import me.nobaboy.nobaaddons.ducks.EntityStateCaptureDuck; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.Entity; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -@SuppressWarnings("unused") -@Mixin(EntityRenderState.class) -abstract class EntityStateCaptureDuckImpl implements EntityStateCaptureDuck { - private @Unique @Nullable Entity nobaaddons$entity; - - @Override - public @Nullable Entity nobaaddons$getEntity() { - return nobaaddons$entity; - } - - @Override - public void nobaaddons$setEntity(@Nullable Entity entity) { - nobaaddons$entity = entity; - } -} -//?} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/FishingBobberTimerDuckImpl.java b/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/FishingBobberTimerDuckImpl.java deleted file mode 100644 index a9df5ea5..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/FishingBobberTimerDuckImpl.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.nobaboy.nobaaddons.mixins.duckimpl; - -import me.nobaboy.nobaaddons.ducks.FishingBobberTimerDuck; -import net.minecraft.entity.projectile.FishingBobberEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Unique; - -import java.time.Instant; - -@SuppressWarnings("unused") -@Mixin(FishingBobberEntity.class) -abstract class FishingBobberTimerDuckImpl implements FishingBobberTimerDuck { - private @Unique Instant nobaaddons$spawnedAt; - - @Override - public Instant nobaaddons$spawnedAt() { - return nobaaddons$spawnedAt; - } - - @Override - public void nobaaddons$markSpawnTime() { - this.nobaaddons$spawnedAt = Instant.now(); - } -} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/ItemSkyblockDataCacheImpl.java b/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/ItemSkyblockDataCacheImpl.java new file mode 100644 index 00000000..d970bb2f --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/ItemSkyblockDataCacheImpl.java @@ -0,0 +1,21 @@ +package me.nobaboy.nobaaddons.mixins.duckimpl; + +import me.nobaboy.nobaaddons.ducks.ItemSkyblockDataCache; +import me.nobaboy.nobaaddons.utils.items.SkyBlockItemData; +import me.nobaboy.nobaaddons.utils.properties.Holding; +import net.minecraft.item.ItemStack; +import org.jetbrains.annotations.NotNull; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@SuppressWarnings("unused") +@Mixin(ItemStack.class) +abstract class ItemSkyblockDataCacheImpl implements ItemSkyblockDataCache { + @Unique + private final Holding nobaaddons$skyblockData = new Holding<>(); + + @Override + public @NotNull SkyBlockItemData nobaaddons$getSkyblockData() { + return nobaaddons$skyblockData.getOrSet(this::nobaaddons$createSkyblockItemData); + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/StateDataHolderImpl.java b/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/StateDataHolderImpl.java new file mode 100644 index 00000000..46aa03ac --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/duckimpl/StateDataHolderImpl.java @@ -0,0 +1,25 @@ +package me.nobaboy.nobaaddons.mixins.duckimpl; + +import it.unimi.dsi.fastutil.objects.Reference2ObjectArrayMap; +import me.nobaboy.nobaaddons.ducks.StateDataHolder; +import me.nobaboy.nobaaddons.utils.render.EntityDataKey; +import net.minecraft.client.render.entity.state.EntityRenderState; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import java.util.Map; + +@SuppressWarnings("unused") +@Mixin({Entity.class, EntityRenderState.class}) +class StateDataHolderImpl implements StateDataHolder { + // TODO it might be worth changing this to an Reference2ObjectOpenHashMap at some point if we start consistently + // adding enough things to this + @Unique + private final Reference2ObjectArrayMap, EntityDataKey.Value> nobaaddons$stateData = new Reference2ObjectArrayMap<>(32); + + @Override + public Map, EntityDataKey.Value> nobaaddons$getData() { + return nobaaddons$stateData; + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityEventsMixin_EntityRenderDispatcher.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityEventsMixin_EntityRenderDispatcher.java index 7146e249..3e4a881e 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityEventsMixin_EntityRenderDispatcher.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityEventsMixin_EntityRenderDispatcher.java @@ -1,15 +1,17 @@ package me.nobaboy.nobaaddons.mixins.events; //? if >=1.21.5 { -/*import me.nobaboy.nobaaddons.ducks.EntityStateCaptureDuck; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.entity.state.EntityRenderState; +/*import net.minecraft.client.MinecraftClient; *///?} +import com.llamalad7.mixinextras.sugar.Local; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalRef; import me.nobaboy.nobaaddons.events.impl.client.EntityEvents; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import org.spongepowered.asm.mixin.Mixin; @@ -17,22 +19,19 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -//? if >=1.21.2 { -// For whatever reason, the MC Dev plugin complains about this, but only on 1.21.2+. -// This is despite the fact that this is, in fact, a valid injector. -@SuppressWarnings("InvalidInjectorMethodSignature") -//?} @Mixin(EntityRenderDispatcher.class) abstract class EntityEventsMixin_EntityRenderDispatcher { @Inject( //? if >=1.21.5 { /*method = "render(Lnet/minecraft/client/render/entity/state/EntityRenderState;DDDLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", - *///?} else if >=1.21.2 { - method = "render(Lnet/minecraft/entity/Entity;DDDFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", - //?} else { - /*method = "render", - *///?} at = @At("HEAD"), + *///?} else { + method = "render(Lnet/minecraft/entity/Entity;DDDFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/render/entity/EntityRenderer;getPositionOffset(Lnet/minecraft/client/render/entity/state/EntityRenderState;)Lnet/minecraft/util/math/Vec3d;" + ), + //?} cancellable = true ) public void nobaaddons$cancelEntityRender( @@ -42,33 +41,27 @@ abstract class EntityEventsMixin_EntityRenderDispatcher { Entity entity, //?} double x, double y, double z, - //? if <1.21.2 { - /*float yaw, - *///?} //? if <1.21.5 { float tickDelta, //?} - MatrixStack matrices,VertexConsumerProvider vertexConsumers, + MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - //? if >=1.21.2 { EntityRenderer renderer, + CallbackInfo ci /*? if <1.21.5 {*/, + @Local EntityRenderState state //?} - CallbackInfo ci ) { - //? if >=1.21.5 { - /*Entity entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - *///?} - if(entity != null && EntityEvents.ALLOW_RENDER.dispatch(new EntityEvents.AllowRender(entity))) ci.cancel(); + if(EntityEvents.ALLOW_RENDER.dispatch(new EntityEvents.AllowRender(state))) { + ci.cancel(); + } } @Inject( //? if >=1.21.5 { /*method = "render(Lnet/minecraft/client/render/entity/state/EntityRenderState;DDDLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", - *///?} else if >=1.21.2 { + *///?} else { method = "render(Lnet/minecraft/entity/Entity;DDDFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", - //?} else { - /*method = "render", - *///?} + //?} at = @At( value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;push()V" @@ -82,34 +75,31 @@ abstract class EntityEventsMixin_EntityRenderDispatcher { Entity entity, //?} double x, double y, double z, - //? if <1.21.2 { - /*float yaw, - *///?} //? if <1.21.5 { float tickDelta, //?} - MatrixStack matrices,VertexConsumerProvider vertexConsumers, + MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, - //? if >=1.21.2 { EntityRenderer renderer, + CallbackInfo ci /*? if <1.21.5 {*/, + @Local EntityRenderState state, + @Share(value = "renderState", namespace = "nobaaddons") LocalRef stateRef //?} - CallbackInfo ci ) { //? if >=1.21.5 { /*float tickDelta = MinecraftClient.getInstance().getRenderTickCounter().getTickProgress(true); - Entity entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - *///?} - if(entity != null) EntityEvents.PRE_RENDER.dispatch(new EntityEvents.Render(entity, tickDelta)); + *///?} else { + stateRef.set(state); + //?} + EntityEvents.PRE_RENDER.dispatch(new EntityEvents.Render(state, tickDelta)); } @Inject( //? if >=1.21.5 { /*method = "render(Lnet/minecraft/client/render/entity/state/EntityRenderState;DDDLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", - *///?} else if >=1.21.2 { + *///?} else { method = "render(Lnet/minecraft/entity/Entity;DDDFLnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;ILnet/minecraft/client/render/entity/EntityRenderer;)V", - //?} else { - /*method = "render", - *///?} + //?} at = @At( value = "INVOKE", target = "Lnet/minecraft/client/util/math/MatrixStack;pop()V" @@ -123,23 +113,24 @@ abstract class EntityEventsMixin_EntityRenderDispatcher { Entity entity, //?} double x, double y, double z, - //? if <1.21.2 { - /*float yaw, - *///?} //? if <1.21.5 { float tickDelta, //?} MatrixStack matrices,VertexConsumerProvider vertexConsumers, int light, - //? if >=1.21.2 { EntityRenderer renderer, + CallbackInfo ci /*? if <1.21.5 {*/, + // either this mcdev plugin is bullshitting me, or @Local genuinely cannot find the render state + // that's within the same try block as this pop call. i don't know, and it's not that much effort + // to just work around the issue one way or another. + @Share(value = "renderState", namespace = "nobaaddons") LocalRef stateRef //?} - CallbackInfo ci ) { //? if >=1.21.5 { /*float tickDelta = MinecraftClient.getInstance().getRenderTickCounter().getTickProgress(true); - Entity entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - *///?} - if(entity != null) EntityEvents.POST_RENDER.dispatch(new EntityEvents.Render(entity, tickDelta)); + *///?} else { + var state = stateRef.get(); + //?} + EntityEvents.POST_RENDER.dispatch(new EntityEvents.Render(state, tickDelta)); } } \ No newline at end of file diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityTickEventMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityTickEventMixin.java new file mode 100644 index 00000000..567ec90a --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/EntityTickEventMixin.java @@ -0,0 +1,22 @@ +package me.nobaboy.nobaaddons.mixins.events; + +import me.nobaboy.nobaaddons.events.impl.entity.EntityTickEvent; +import net.minecraft.entity.Entity; +import net.minecraft.world.World; +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.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +@Mixin(Entity.class) +abstract class EntityTickEventMixin { + @Shadow + public abstract World getEntityWorld(); + + @Inject(method = "tick", at = @At("TAIL")) + public void nobaaddons$onEntityTick(CallbackInfo ci) { + if(!getEntityWorld().isClient()) return; + EntityTickEvent.EVENT.dispatch(new EntityTickEvent((Entity)(Object)this)); + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventMixin.java new file mode 100644 index 00000000..84f8e74a --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventMixin.java @@ -0,0 +1,61 @@ +package me.nobaboy.nobaaddons.mixins.events; + +import me.nobaboy.nobaaddons.utils.MixinKeys; +import net.minecraft.client.render.entity.state.EntityRenderState; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import me.nobaboy.nobaaddons.events.impl.render.EntityNametagRenderEvents; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(EntityRenderer.class) +abstract class NametagRenderEventMixin { + @Shadow + protected abstract void renderLabelIfPresent( + EntityRenderState state, + Text text, + MatrixStack matrices, + VertexConsumerProvider vertexConsumers, + int light + ); + + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/render/entity/EntityRenderer;renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V" + ) + ) + public void nobaaddons$nametagRender( + EntityRenderer instance, + EntityRenderState state, + Text text, + MatrixStack matrices, + VertexConsumerProvider vertexConsumers, + int light, + Operation original + ) { + boolean renderOriginal = MixinKeys.RENDER_ORIGINAL_ENTITY_NAME.get(state); + var event = new EntityNametagRenderEvents.Nametag(state); + EntityNametagRenderEvents.EVENT.dispatch(event); + matrices.push(); + for(int i = 0; i < event.getTags().size(); i++) { + var ntext = event.getTags().get(i); + // TODO this causes the scoreboard objective in the below name slot to render multiple times on players; + // we don't presently use this on players however, so this isn't an issue I'm too worried about right now. + renderLabelIfPresent(state, ntext, matrices, vertexConsumers, light); + if(i < event.getTags().size() - 1 || renderOriginal) { + matrices.translate(0f, 9f * 1.15f * 0.025f, 0f); + } + } + if(renderOriginal && text != null) { + original.call(instance, state, text, matrices, vertexConsumers, light); + } + matrices.pop(); + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventsMixin_ArmorStandEntityRenderer.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventsMixin_ArmorStandEntityRenderer.java deleted file mode 100644 index bb664684..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventsMixin_ArmorStandEntityRenderer.java +++ /dev/null @@ -1,24 +0,0 @@ -package me.nobaboy.nobaaddons.mixins.events; - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.llamalad7.mixinextras.sugar.Local; -import me.nobaboy.nobaaddons.events.impl.render.EntityNametagRenderEvents; -import net.minecraft.client.render.entity.ArmorStandEntityRenderer; -import net.minecraft.entity.decoration.ArmorStandEntity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(ArmorStandEntityRenderer.class) -abstract class NametagRenderEventsMixin_ArmorStandEntityRenderer { - @ModifyReturnValue( - //? if >=1.21.2 { - method = "hasLabel(Lnet/minecraft/entity/decoration/ArmorStandEntity;D)Z", - //?} else { - /*method = "hasLabel(Lnet/minecraft/entity/decoration/ArmorStandEntity;)Z", - *///?} - at = @At("RETURN") - ) - public boolean nobaaddons$modifyNametagVisibility(boolean original, @Local(argsOnly = true) ArmorStandEntity entity) { - return EntityNametagRenderEvents.VISIBILITY.dispatch(new EntityNametagRenderEvents.Visibility(entity, original)); - } -} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventsMixin_EntityRenderer.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventsMixin_EntityRenderer.java deleted file mode 100644 index bfcdb71a..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagRenderEventsMixin_EntityRenderer.java +++ /dev/null @@ -1,118 +0,0 @@ -package me.nobaboy.nobaaddons.mixins.events; - -//? if >=1.21.2 { -import me.nobaboy.nobaaddons.ducks.EntityStateCaptureDuck; -import net.minecraft.client.render.entity.state.EntityRenderState; -//?} - -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.llamalad7.mixinextras.sugar.Local; -import me.nobaboy.nobaaddons.events.impl.render.EntityNametagRenderEvents; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; -import net.minecraft.text.Text; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; - -@Mixin(EntityRenderer.class) -abstract class NametagRenderEventsMixin_EntityRenderer { - @Shadow - protected abstract void renderLabelIfPresent( - //? if >=1.21.2 { - EntityRenderState state, - //?} else { - /*Entity entity, - *///?} - Text text, - MatrixStack matrices, - VertexConsumerProvider vertexConsumers, - int light - /*? if <1.21.2 {*//*, float tickDelta*//*?}*/ - ); - - @ModifyReturnValue(method = "hasLabel", at = @At("RETURN")) - public boolean nobaaddons$modifyNametagVisibility(boolean original, @Local(argsOnly = true) Entity entity) { - var event = new EntityNametagRenderEvents.Visibility(entity, original); - EntityNametagRenderEvents.VISIBILITY.dispatch(event); - return event.getShouldRender(); - } - - //? if >=1.21.2 { - // For whatever reason, the MC Dev plugin complains about this, but only on 1.21.2+. - // This is despite the fact that this is, in fact, a valid injector. - @SuppressWarnings("InvalidInjectorMethodSignature") - //?} - @WrapOperation( - method = "render", - at = @At( - value = "INVOKE", - //? if >=1.21.2 { - target = "Lnet/minecraft/client/render/entity/EntityRenderer;renderLabelIfPresent(Lnet/minecraft/client/render/entity/state/EntityRenderState;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;I)V" - //?} else { - /*target = "Lnet/minecraft/client/render/entity/EntityRenderer;renderLabelIfPresent(Lnet/minecraft/entity/Entity;Lnet/minecraft/text/Text;Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider;IF)V" - *///?} - ) - ) - public void nobaaddons$nametagRender( - //? if >=1.21.2 { - EntityRenderer instance, - EntityRenderState state, - //?} else { - /*EntityRenderer instance, - Entity entity, - *///?} - Text text, - MatrixStack matrices, - VertexConsumerProvider vertexConsumers, - int light, - //? if <1.21.2 { - /*float tickDelta, - *///?} - Operation original - ) { - //? if >=1.21.2 { - Entity entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - if(entity == null) { - original.call(instance, state, text, matrices, vertexConsumers, light); - return; - } - //?} - - var event = new EntityNametagRenderEvents.Nametag(entity); - EntityNametagRenderEvents.EVENT.dispatch(event); - matrices.push(); - for(int i = 0; i < event.getTags().size(); i++) { - var ntext = event.getTags().get(i); - // TODO this causes the scoreboard objective in the below name slot to render multiple times on players; - // we don't presently use this on players however, so this isn't an issue I'm too worried about right now. - renderLabelIfPresent( - /*? if >=1.21.2 {*/state/*?} else {*//*entity*//*?}*/, - ntext, - matrices, - vertexConsumers, - light - /*? if <1.21.2 {*//*, tickDelta*//*?}*/ - ); - if(i < event.getTags().size() - 1 || event.getRenderEntityName()) { - matrices.translate(0f, 9f * 1.15f * 0.025f, 0f); - } - } - if(event.getRenderEntityName()) { - original.call( - instance, - /*? if >=1.21.2 {*/state/*?} else {*//*entity*//*?}*/, - text == null ? entity.getDisplayName() : text, - matrices, - vertexConsumers, - light - /*? if <1.21.2 {*//*, tickDelta*//*?}*/ - ); - } - matrices.pop(); - } -} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagVisibilityEventMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagVisibilityEventMixin.java new file mode 100644 index 00000000..24fc20bb --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/NametagVisibilityEventMixin.java @@ -0,0 +1,25 @@ +package me.nobaboy.nobaaddons.mixins.events; + +import com.llamalad7.mixinextras.injector.ModifyReturnValue; +import com.llamalad7.mixinextras.sugar.Local; +import me.nobaboy.nobaaddons.events.impl.render.EntityNametagRenderEvents; +import me.nobaboy.nobaaddons.utils.MixinKeys; +import net.minecraft.client.render.entity.ArmorStandEntityRenderer; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.LivingEntityRenderer; +import net.minecraft.client.render.entity.MobEntityRenderer; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Coerce; + +@Mixin({EntityRenderer.class, ArmorStandEntityRenderer.class, LivingEntityRenderer.class, MobEntityRenderer.class}) +abstract class NametagVisibilityEventMixin { + @ModifyReturnValue(method = "hasLabel(Lnet/minecraft/entity/Entity;D)Z", at = @At("RETURN")) + public boolean nobaaddons$modifyNametagVisibility(boolean original, @Local(argsOnly = true) @Coerce T entity) { + var event = new EntityNametagRenderEvents.Visibility(entity, original); + EntityNametagRenderEvents.VISIBILITY.dispatch(event); + MixinKeys.RENDER_ORIGINAL_ENTITY_NAME.put(entity, event.getRenderOriginalNametag()); + return event.getShouldRender(); + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/RenderStateUpdateEventMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/RenderStateUpdateEventMixin.java new file mode 100644 index 00000000..f3a6ca63 --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/RenderStateUpdateEventMixin.java @@ -0,0 +1,19 @@ +package me.nobaboy.nobaaddons.mixins.events; + +import me.nobaboy.nobaaddons.events.impl.render.RenderStateUpdateEvent; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.state.EntityRenderState; +import net.minecraft.entity.Entity; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(EntityRenderer.class) +abstract class RenderStateUpdateEventMixin { + @Inject(method = "getAndUpdateRenderState", at = @At("RETURN")) + public void nobaaddons$captureEntity(Entity entity, float tickDelta, CallbackInfoReturnable cir) { + var state = cir.getReturnValue(); + RenderStateUpdateEvent.EVENT.dispatch(new RenderStateUpdateEvent(entity, state)); + } +} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_HandledScreen.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_HandledScreen.java index fdf44e6f..792748ba 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_HandledScreen.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_HandledScreen.java @@ -21,11 +21,7 @@ protected ScreenRenderEventsMixin_HandledScreen(Text title) { method = "drawSlot", at = @At( value = "INVOKE", - //? if >=1.21.2 { target = "Lnet/minecraft/client/gui/DrawContext;drawStackOverlay(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V" - //?} else { - /*target = "Lnet/minecraft/client/gui/DrawContext;drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V" - *///?} ) ) public void nobaaddons$onDrawSlot(DrawContext context, Slot slot, CallbackInfo ci) { diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_InGameHud.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_InGameHud.java index 3a8816d2..b34dffeb 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_InGameHud.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/ScreenRenderEventsMixin_InGameHud.java @@ -22,11 +22,7 @@ abstract class ScreenRenderEventsMixin_InGameHud { method = "renderHotbarItem", at = @At( value = "INVOKE", - //? if >=1.21.2 { target = "Lnet/minecraft/client/gui/DrawContext;drawStackOverlay(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;II)V" - //?} else { - /*target = "Lnet/minecraft/client/gui/DrawContext;drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;II)V" - *///?} ) ) public void nobaaddons$onRenderHotbarItem(DrawContext context, int x, int y, RenderTickCounter tickCounter, PlayerEntity player, ItemStack itemStack, int seed, CallbackInfo ci) { diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/events/SoundEventsMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/events/SoundEventsMixin.java index 3dd7937b..7f9a88dc 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/events/SoundEventsMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/events/SoundEventsMixin.java @@ -45,13 +45,7 @@ abstract class SoundEventsMixin { var key = sound.getKeyOrValue(); var id = key.left() .map(RegistryKey::getValue) - .orElseGet(() -> key.right() - //? if >=1.21.2 { - .map(SoundEvent::id) - //?} else { - /*.map(SoundEvent::getId) - *///?} - .orElseThrow()); + .orElseGet(() -> key.right().map(SoundEvent::id).orElseThrow()); var location = new NobaVec(x, y, z); diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/fixes/FixSkyblockerHeadCache.java b/src/main/java/me/nobaboy/nobaaddons/mixins/fixes/FixSkyblockerHeadCache.java index 5521839d..c7270b7b 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/fixes/FixSkyblockerHeadCache.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/fixes/FixSkyblockerHeadCache.java @@ -19,7 +19,7 @@ @IfModLoaded(value = "skyblocker", maxVersion = "1.23.0-beta.2") @Mixin(targets = "de.hysky.skyblocker.skyblock.item.PlayerHeadHashCache") abstract class FixSkyblockerHeadCache { - @Dynamic + @SuppressWarnings("UnresolvedMixinReference") // i'm not adding a compile time dependency on skyblocker for this @WrapOperation( method = "loadSkins", at = @At( diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/io/HandledScreenMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/io/HandledScreenMixin.java index a073cd2d..bcbdd1f3 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/io/HandledScreenMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/io/HandledScreenMixin.java @@ -10,6 +10,7 @@ @Mixin(HandledScreen.class) abstract class HandledScreenMixin { + // TODO this should be made into an event @Inject(method = "keyPressed", at = @At("HEAD")) public void nobaaddons$copyItemData(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable cir) { if(DevFeatures.shouldCopy(keyCode)) { diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/io/KeyboardMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/io/KeyboardMixin.java index b91d8aa5..db7e2cc2 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/io/KeyboardMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/io/KeyboardMixin.java @@ -14,6 +14,7 @@ abstract class KeyboardMixin { @Shadow @Final private MinecraftClient client; + // TODO this should be made into an event @Inject(method = "onKey", at = @At("TAIL")) public void nobaaddons$onKeyPress(long window, int keyCode, int scancode, int action, int modifiers, CallbackInfo ci) { if(window != client.getWindow().getHandle()) return; diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/io/MouseMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/io/MouseMixin.java index bfe31cbb..a67ca370 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/io/MouseMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/io/MouseMixin.java @@ -17,6 +17,7 @@ abstract class MouseMixin { @Shadow @Final private MinecraftClient client; + // TODO this should be made into an event @Inject(method = "onMouseButton", at = @At("TAIL")) public void nobaaddons$onMouseButton(long window, int button, int action, int modifiers, CallbackInfo ci) { if(window != client.getWindow().getHandle()) return; diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/render/EntityRendererMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/render/EntityRendererMixin.java deleted file mode 100644 index 4a0bb9c0..00000000 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/render/EntityRendererMixin.java +++ /dev/null @@ -1,21 +0,0 @@ -package me.nobaboy.nobaaddons.mixins.render; - -//? if >=1.21.2 { -import me.nobaboy.nobaaddons.ducks.EntityStateCaptureDuck; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.EntityRenderState; -import net.minecraft.entity.Entity; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(EntityRenderer.class) -abstract class EntityRendererMixin { - @Inject(method = "updateRenderState", at = @At("TAIL")) - public void nobaaddons$captureEntity(Entity entity, EntityRenderState state, float tickDelta, CallbackInfo ci) { - var duck = (EntityStateCaptureDuck) state; - duck.nobaaddons$setEntity(entity); - } -} -//?} diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/render/InGameHudMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/render/InGameHudMixin.java index 0b3ab187..c3badcf1 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/render/InGameHudMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/render/InGameHudMixin.java @@ -1,9 +1,5 @@ package me.nobaboy.nobaaddons.mixins.render; -//? if <1.21.2 { -/*import org.spongepowered.asm.mixin.injection.Slice; -*///?} - import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import me.nobaboy.nobaaddons.api.skyblock.SkyBlockAPI; import me.nobaboy.nobaaddons.config.NobaConfig; @@ -19,19 +15,8 @@ @Mixin(InGameHud.class) abstract class InGameHudMixin { - //? if >=1.21.2 { @WrapWithCondition(method = "renderAirBubbles", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Ljava/util/function/Function;Lnet/minecraft/util/Identifier;IIII)V")) public boolean nobaaddons$hideAirBubbles(DrawContext instance, Function renderLayers, Identifier sprite, int x, int y, int width, int height) { - //?} else { - /*@WrapWithCondition( - method = "renderStatusBars", - at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V"), - slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/entity/player/PlayerEntity;isSubmergedIn(Lnet/minecraft/registry/tag/TagKey;)Z")), - require = 2, - allow = 2 - ) - public boolean nobaaddons$hideAirBubbles(DrawContext instance, Identifier texture, int x, int y, int width, int height) { - *///?} if(SkyBlockAPI.inSkyBlock()) { return !NobaConfig.INSTANCE.getUiAndVisuals().getRenderingTweaks().getHideAirBubbles(); } diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/render/ItemStackMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/render/ItemStackMixin.java index cf6b2d91..1904ec4f 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/render/ItemStackMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/render/ItemStackMixin.java @@ -1,9 +1,5 @@ package me.nobaboy.nobaaddons.mixins.render; -//? if <1.21.2 { -/*import net.minecraft.item.ArmorItem; -*///?} - //? if <1.21.5 { import org.spongepowered.asm.mixin.injection.Slice; //?} else { @@ -30,7 +26,7 @@ abstract class ItemStackMixin { @ModifyReturnValue(method = "hasGlint", at = @At("RETURN")) public boolean nobaaddons$modifyGlint(boolean original) { var item = (ItemStack) (Object) this; - boolean isArmor = /*? if >=1.21.2 {*/item.get(DataComponentTypes.EQUIPPABLE) != null/*?} else {*//*item.getItem() instanceof ArmorItem*//*?}*/; + boolean isArmor = item.get(DataComponentTypes.EQUIPPABLE) != null; if(!isArmor) return original; return ItemUtils.shouldArmorHaveEnchantGlint(item, original); diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/EquipmentRendererMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/EquipmentRendererMixin.java index a8fa4301..661bcff0 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/EquipmentRendererMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/EquipmentRendererMixin.java @@ -1,7 +1,5 @@ package me.nobaboy.nobaaddons.mixins.render.tint; -// TODO fix this for 1.21.1 (or just drop 1.21.1) -//? if >=1.21.2 { import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; @@ -45,5 +43,4 @@ abstract class EquipmentRendererMixin { public int nobaaddons$replaceUv(int original) { return EntityOverlay.getOverlay() != null ? OverlayTexture.packUv(15, 10) : original; } -} -//?} \ No newline at end of file +} \ No newline at end of file diff --git a/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/LivingEntityRendererMixin.java b/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/LivingEntityRendererMixin.java index ee2a4617..43e4caac 100644 --- a/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/LivingEntityRendererMixin.java +++ b/src/main/java/me/nobaboy/nobaaddons/mixins/render/tint/LivingEntityRendererMixin.java @@ -1,14 +1,7 @@ package me.nobaboy.nobaaddons.mixins.render.tint; -//? if >=1.21.2 { -import me.nobaboy.nobaaddons.ducks.EntityStateCaptureDuck; import net.minecraft.client.render.entity.state.LivingEntityRenderState; -//?} else { -/*import net.minecraft.entity.LivingEntity; -*///?} - import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.sugar.Local; import me.nobaboy.nobaaddons.utils.render.EntityOverlay; import net.minecraft.client.render.entity.LivingEntityRenderer; @@ -25,63 +18,16 @@ */ @Mixin(LivingEntityRenderer.class) abstract class LivingEntityRendererMixin { - @ModifyExpressionValue( - method = "getOverlay", - //? if >=1.21.2 { - at = @At( - value = "FIELD", - target = "Lnet/minecraft/client/render/entity/state/LivingEntityRenderState;hurt:Z" - ) - //?} else { - /*at = { - @At(value = "FIELD", target = "Lnet/minecraft/entity/LivingEntity;hurtTime:I"), - @At(value = "FIELD", target = "Lnet/minecraft/entity/LivingEntity;deathTime:I") - } - *///?} - ) - private static /*? if >=1.21.2 {*/boolean/*?} else {*//*int*//*?}*/ nobaaddons$suppressVanillaDamageOverlay( - /*? if >=1.21.2 {*/ - boolean original, - @Local(argsOnly = true) LivingEntityRenderState state - ) { - var entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - /*?} else {*/ - /*int original, - @Local(argsOnly = true) LivingEntity entity - ) { - *///?} - return (entity == null || !EntityOverlay.contains(entity)) && original/*? if <=1.21.1 {*/ /*> 0 ? original : 0*//*?}*/; - } - - //? if >=1.21.2 { @ModifyReturnValue(method = "getMixColor", at = @At("RETURN")) - private int nobaaddons$changeColor( - int original, - @Local(argsOnly = true) LivingEntityRenderState state - ) { - var entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - var overlay = Nullables.map(entity, EntityOverlay::getRgb); - if(overlay != null) { - return ColorHelper/*? if <1.21.2 {*//*.Argb*//*?}*/.fullAlpha(overlay); - } - return original; + private int nobaaddons$changeColor(int original, @Local(argsOnly = true) LivingEntityRenderState state) { + return Nullables.mapOrElse(EntityOverlay.getRgb(state), ColorHelper::fullAlpha, original); } - //?} @ModifyArg( method = "getOverlay", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/OverlayTexture;getU(F)I") ) - private static float nobaaddons$forceOverlay( - float whiteOverlayProgress, - //? if >=1.21.2 { - @Local(argsOnly = true) LivingEntityRenderState state - ) { - var entity = ((EntityStateCaptureDuck) state).nobaaddons$getEntity(); - /*?} else {*/ - /*@Local(argsOnly = true) LivingEntity entity - ) { - *///?} - return entity != null && EntityOverlay.contains(entity) ? 1f : whiteOverlayProgress; + private static float nobaaddons$forceOverlay(float whiteOverlayProgress, @Local(argsOnly = true) LivingEntityRenderState state) { + return EntityOverlay.contains(state) ? 1f : whiteOverlayProgress; } } \ No newline at end of file diff --git a/src/main/java/me/nobaboy/nobaaddons/utils/MixinKeys.java b/src/main/java/me/nobaboy/nobaaddons/utils/MixinKeys.java new file mode 100644 index 00000000..26c10ec9 --- /dev/null +++ b/src/main/java/me/nobaboy/nobaaddons/utils/MixinKeys.java @@ -0,0 +1,16 @@ +package me.nobaboy.nobaaddons.utils; + +import me.nobaboy.nobaaddons.events.impl.render.RenderStateUpdateEvent; +import me.nobaboy.nobaaddons.utils.render.EntityDataKey; + +public final class MixinKeys { + private MixinKeys() { + throw new UnsupportedOperationException(); + } + + public static final EntityDataKey RENDER_ORIGINAL_ENTITY_NAME = new EntityDataKey<>(() -> true); + + static { + RenderStateUpdateEvent.EVENT.register(event -> event.copyToRender(RENDER_ORIGINAL_ENTITY_NAME)); + } +} diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/NobaAddons.kt b/src/main/kotlin/me/nobaboy/nobaaddons/NobaAddons.kt index 2086f94f..5b2e76fb 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/NobaAddons.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/NobaAddons.kt @@ -62,5 +62,4 @@ object NobaAddons : ClientModInitializer { NobaAddonsApis NobaAddonsModules } - } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/api/skyblock/SlayerAPI.kt b/src/main/kotlin/me/nobaboy/nobaaddons/api/skyblock/SlayerAPI.kt index 38cbdfaa..e2051687 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/api/skyblock/SlayerAPI.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/api/skyblock/SlayerAPI.kt @@ -2,9 +2,9 @@ package me.nobaboy.nobaaddons.api.skyblock import me.nobaboy.nobaaddons.core.slayer.SlayerBoss import me.nobaboy.nobaaddons.events.impl.chat.ChatMessageEvents -import me.nobaboy.nobaaddons.events.impl.client.EntityEvents import me.nobaboy.nobaaddons.events.impl.client.PacketEvents import me.nobaboy.nobaaddons.events.impl.client.TickEvents +import me.nobaboy.nobaaddons.events.impl.entity.EntityTickEvent import me.nobaboy.nobaaddons.events.impl.skyblock.SkyBlockEvents import me.nobaboy.nobaaddons.events.impl.skyblock.SlayerEvents import me.nobaboy.nobaaddons.repo.Repo.fromRepo @@ -36,7 +36,7 @@ object SlayerAPI { SkyBlockEvents.ISLAND_CHANGE.register { reset() } TickEvents.TICK.register { onTick() } PacketEvents.POST_RECEIVE.register(this::onPacketReceive) - EntityEvents.POST_RENDER.register(this::onEntityRender) + EntityTickEvent.EVENT.register(this::onEntityTick) ChatMessageEvents.CHAT.register(this::onChatMessage) } @@ -83,7 +83,7 @@ object SlayerAPI { } } - private fun onEntityRender(event: EntityEvents.Render) { + private fun onEntityTick(event: EntityTickEvent) { if(!SkyBlockAPI.inSkyBlock) return val currentQuest = currentQuest ?: return diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/config/util/option.kt b/src/main/kotlin/me/nobaboy/nobaaddons/config/util/option.kt index 7b7a6ebd..711b287c 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/config/util/option.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/config/util/option.kt @@ -69,10 +69,8 @@ internal fun (AbstractNobaConfig.() -> KMutableProperty).binding(): Bindi setter = { config, value -> this(config).setter.call(value) } ) -internal fun (AbstractNobaConfig.() -> KMutableProperty).binding(biMapper: BiMapper): Binding = binding( - getter = { biMapper.to(this(it).getter.call()) }, - setter = { config, value -> this(config).setter.call(biMapper.from(value)) }, -) +internal fun (AbstractNobaConfig.() -> KMutableProperty).binding(biMapper: BiMapper): Binding = + binding().xmap(biMapper::to, biMapper::from) /** * Convenience parameter wrapping the provided [Text] in an [OptionDescription] diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/core/DebugFlag.kt b/src/main/kotlin/me/nobaboy/nobaaddons/core/DebugFlag.kt index ecefcd7c..906810ea 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/core/DebugFlag.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/core/DebugFlag.kt @@ -5,6 +5,7 @@ import kotlin.reflect.KProperty enum class DebugFlag : StringIdentifiable { COPY_RAW_CHAT_COMPONENT, + SHOW_OWN_NAMETAG, ; var enabled = false diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/client/EntityEvents.kt b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/client/EntityEvents.kt index 45533c9f..f5773974 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/client/EntityEvents.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/client/EntityEvents.kt @@ -3,7 +3,9 @@ package me.nobaboy.nobaaddons.events.impl.client import me.nobaboy.nobaaddons.events.CancelableEvent import me.nobaboy.nobaaddons.events.Event import me.nobaboy.nobaaddons.events.EventDispatcher +import me.nobaboy.nobaaddons.utils.render.EntityDataKey import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents +import net.minecraft.client.render.entity.state.EntityRenderState import net.minecraft.entity.Entity object EntityEvents { @@ -48,7 +50,7 @@ object EntityEvents { data class Spawn(val entity: Entity) : Event data class Despawn(val entity: Entity) : Event - data class Render(val entity: Entity, val delta: Float) : Event - data class AllowRender(val entity: Entity) : CancelableEvent() + data class Render(val state: EntityRenderState, val delta: Float) : Event + data class AllowRender(val state: EntityRenderState) : CancelableEvent() data class VehicleChange(val entity: Entity, val vehicle: Entity) : Event } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/entity/EntityTickEvent.kt b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/entity/EntityTickEvent.kt new file mode 100644 index 00000000..4a024d02 --- /dev/null +++ b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/entity/EntityTickEvent.kt @@ -0,0 +1,14 @@ +package me.nobaboy.nobaaddons.events.impl.entity + +import me.nobaboy.nobaaddons.events.Event +import me.nobaboy.nobaaddons.events.EventDispatcher +import net.minecraft.entity.Entity + +/** + * Event invoked when *any* entity ticks on the client + */ +data class EntityTickEvent(val entity: Entity) : Event { + companion object { + @JvmField val EVENT = EventDispatcher() + } +} diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/interact/ItemUseEvent.kt b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/interact/ItemUseEvent.kt index c3588f45..80bdd0b4 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/interact/ItemUseEvent.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/interact/ItemUseEvent.kt @@ -1,10 +1,6 @@ package me.nobaboy.nobaaddons.events.impl.interact -//? if <1.21.2 { -/*import net.minecraft.util.TypedActionResult -*///?} else { import net.minecraft.util.ActionResult -//?} import me.nobaboy.nobaaddons.events.EventDispatcher import net.fabricmc.fabric.api.event.player.UseItemCallback @@ -26,11 +22,7 @@ data class ItemUseEvent( if(player is ClientPlayerEntity) { EVENT.dispatch(ItemUseEvent(player, hand)) } - //? if <1.21.2 { - /*TypedActionResult.pass(player.getStackInHand(hand)) - *///?} else { ActionResult.PASS - //?} } } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/EntityNametagRenderEvents.kt b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/EntityNametagRenderEvents.kt index 82d3d9fb..aa68c3b6 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/EntityNametagRenderEvents.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/EntityNametagRenderEvents.kt @@ -2,6 +2,7 @@ package me.nobaboy.nobaaddons.events.impl.render import me.nobaboy.nobaaddons.events.Event import me.nobaboy.nobaaddons.events.EventDispatcher +import net.minecraft.client.render.entity.state.EntityRenderState import net.minecraft.entity.Entity import net.minecraft.text.Text @@ -22,17 +23,19 @@ object EntityNametagRenderEvents { // this uses a boolean var instead of being cancelable to allow for forcing name tags to render, // even if vanilla normally wouldn't render them - data class Visibility(val entity: Entity, var shouldRender: Boolean) : Event + data class Visibility(val entity: Entity, var shouldRender: Boolean) : Event { + var renderOriginalNametag: Boolean = shouldRender + set(value) { + if(value) shouldRender = true + field = value + } + } data class Nametag @JvmOverloads constructor( - val entity: Entity, + val state: EntityRenderState, /** * A list of [Text] to add under the entity's nametag */ val tags: MutableList = mutableListOf(), - /** - * If `false`, the entity's regular nametag will not be rendered. - */ - var renderEntityName: Boolean = true, ) : Event } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/RenderStateUpdateEvent.kt b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/RenderStateUpdateEvent.kt new file mode 100644 index 00000000..8d275d81 --- /dev/null +++ b/src/main/kotlin/me/nobaboy/nobaaddons/events/impl/render/RenderStateUpdateEvent.kt @@ -0,0 +1,42 @@ +package me.nobaboy.nobaaddons.events.impl.render + +import me.nobaboy.nobaaddons.events.Event +import me.nobaboy.nobaaddons.events.EventDispatcher +import me.nobaboy.nobaaddons.utils.render.EntityDataKey +import net.minecraft.client.render.entity.state.EntityRenderState +import net.minecraft.entity.Entity + +/** + * Event invoked when an [entity]'s [render state][state] is updated + * + * This event is invoked after all applicable vanilla code has modified the render state. + */ +data class RenderStateUpdateEvent(val entity: Entity, val state: EntityRenderState) : Event { + /** + * Get the value stored under the provided [key] from the [entity] + */ + fun getEntity(key: EntityDataKey): T = key.get(entity) + + /** + * Get the value stored under the provided [key] from the [render state][state] + */ + fun getState(key: EntityDataKey): T = key.get(state) + + /** + * Copy the value stored under the provided [key] from the [entity] to the [render state][state] + */ + fun copyToRender(key: EntityDataKey) { + key.copyToRender(entity, state) + } + + /** + * Set the stored value under the provided [key] on the [render state][state] + */ + fun set(key: EntityDataKey, value: T) { + key.put(state, value) + } + + companion object { + @JvmField val EVENT = EventDispatcher() + } +} diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/FishingBobberTweaks.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/FishingBobberTweaks.kt index cef500a0..5dfc49f4 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/FishingBobberTweaks.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/FishingBobberTweaks.kt @@ -5,13 +5,15 @@ import me.nobaboy.nobaaddons.api.skyblock.SkyBlockAPI import me.nobaboy.nobaaddons.api.skyblock.SkyBlockAPI.inIsland import me.nobaboy.nobaaddons.config.NobaConfig import me.nobaboy.nobaaddons.core.SkyBlockIsland -import me.nobaboy.nobaaddons.ducks.FishingBobberTimerDuck import me.nobaboy.nobaaddons.events.impl.client.EntityEvents import me.nobaboy.nobaaddons.events.impl.render.EntityNametagRenderEvents +import me.nobaboy.nobaaddons.events.impl.render.RenderStateUpdateEvent import me.nobaboy.nobaaddons.utils.MCUtils import me.nobaboy.nobaaddons.utils.NobaColor import me.nobaboy.nobaaddons.utils.NumberUtils.roundTo -import me.nobaboy.nobaaddons.utils.Timestamp.Companion.asTimestamp +import me.nobaboy.nobaaddons.utils.Timestamp +import me.nobaboy.nobaaddons.utils.render.EntityDataKey +import net.minecraft.client.render.entity.state.FishingBobberEntityState import me.owdding.ktmodules.Module import net.minecraft.entity.projectile.FishingBobberEntity import net.minecraft.text.Text @@ -19,27 +21,38 @@ import kotlin.time.DurationUnit @Module object FishingBobberTweaks { + private val SPAWNED_AT = EntityDataKey.nullable() + private val OUR_BOBBER = EntityDataKey { false } + private val config get() = NobaConfig.fishing private val GREEN = NobaColor.GREEN.rgb private val GOLD = NobaColor.GOLD.rgb init { + RenderStateUpdateEvent.EVENT.register(this::updateRenderState) EntityEvents.SPAWN.register(this::onEntitySpawn) EntityEvents.ALLOW_RENDER.register(this::onEntityRender) EntityNametagRenderEvents.VISIBILITY.register(this::allowNameTag) EntityNametagRenderEvents.EVENT.register(this::renderTimer) } + private fun updateRenderState(event: RenderStateUpdateEvent) { + if(event.entity is FishingBobberEntity) { + event.copyToRender(SPAWNED_AT) + event.set(OUR_BOBBER, event.entity.isOurs) + } + } + private fun onEntitySpawn(event: EntityEvents.Spawn) { - val entity = event.entity as? FishingBobberEntity ?: return - (entity as FishingBobberTimerDuck).`nobaaddons$markSpawnTime`() + if(event.entity is FishingBobberEntity) { + SPAWNED_AT.put(event.entity, Timestamp.now()) + } } private fun onEntityRender(event: EntityEvents.AllowRender) { - val entity = event.entity as? FishingBobberEntity ?: return if(!config.hideOtherPeopleFishing) return - if(entity.isOurs) return + if(!OUR_BOBBER.get(event.state)) return event.cancel() } @@ -49,19 +62,18 @@ object FishingBobberTweaks { if(!config.bobberTimer.enabled) return if(!SkyBlockAPI.inSkyBlock) return if(!SkyBlockIsland.CRIMSON_ISLE.inIsland() && config.bobberTimer.crimsonIsleOnly) return - if(!entity.isOurs) return - if((entity as FishingBobberTimerDuck).`nobaaddons$spawnedAt`() == null) return + if(!entity.isOurs || SPAWNED_AT.get(entity) == null) return event.shouldRender = true } private fun renderTimer(event: EntityNametagRenderEvents.Nametag) { - val entity = event.entity as? FishingBobberEntity ?: return + val state = event.state as? FishingBobberEntityState ?: return if(!config.bobberTimer.enabled) return - if(!entity.isOurs) return + if(!OUR_BOBBER.get(state)) return - val time = (entity as FishingBobberTimerDuck).`nobaaddons$spawnedAt`() ?: return - val seconds = time.asTimestamp().elapsedSince().toDouble(DurationUnit.SECONDS) + val time = SPAWNED_AT.get(state) ?: return + val seconds = time.elapsedSince().toDouble(DurationUnit.SECONDS) val slugTime = PetAPI.currentPet?.takeIf { it.id == "SLUG" }?.let { 20.0 - it.level * 0.1 @@ -69,7 +81,6 @@ object FishingBobberTweaks { val color: Int = if(seconds >= slugTime) GOLD else GREEN - event.renderEntityName = false event.tags.add(Text.literal(seconds.roundTo(1).toString()).withColor(color)) } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt index a4d7c8f2..2248b884 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/HotspotWaypoints.kt @@ -4,6 +4,7 @@ import me.nobaboy.nobaaddons.api.skyblock.SkyBlockAPI import me.nobaboy.nobaaddons.config.NobaConfig import me.nobaboy.nobaaddons.core.SkyBlockStat import me.nobaboy.nobaaddons.events.impl.client.EntityEvents +import me.nobaboy.nobaaddons.events.impl.entity.EntityTickEvent import me.nobaboy.nobaaddons.events.impl.skyblock.SkyBlockEvents import me.nobaboy.nobaaddons.utils.EntityUtils import me.nobaboy.nobaaddons.utils.MCUtils @@ -38,11 +39,11 @@ object HotspotWaypoints { init { SkyBlockEvents.ISLAND_CHANGE.register { hotspots.clear() } - EntityEvents.POST_RENDER.register(this::onEntityRender) + EntityTickEvent.EVENT.register(this::onEntityTick) WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderWaypoints) } - private fun onEntityRender(event: EntityEvents.Render) { + private fun onEntityTick(event: EntityTickEvent) { if(!enabled) return val armorStand = event.entity as? ArmorStandEntity ?: return diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt index 4b89ee2d..4aec4154 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/fishing/crimsonisle/HighlightThunderSparks.kt @@ -4,6 +4,7 @@ import me.nobaboy.nobaaddons.api.skyblock.SkyBlockAPI.inIsland import me.nobaboy.nobaaddons.config.NobaConfig import me.nobaboy.nobaaddons.core.SkyBlockIsland import me.nobaboy.nobaaddons.events.impl.client.EntityEvents +import me.nobaboy.nobaaddons.events.impl.entity.EntityTickEvent import me.nobaboy.nobaaddons.events.impl.skyblock.SkyBlockEvents import me.nobaboy.nobaaddons.repo.Repo.skullFromRepo import me.nobaboy.nobaaddons.utils.BlockUtils.getBlockStateAt @@ -27,11 +28,11 @@ object HighlightThunderSparks { init { SkyBlockEvents.ISLAND_CHANGE.register { thunderSparks.clear() } - EntityEvents.POST_RENDER.register(this::onEntityRender) + EntityTickEvent.EVENT.register(this::onEntityTick) WorldRenderEvents.AFTER_TRANSLUCENT.register(this::renderHighlights) } - private fun onEntityRender(event: EntityEvents.Render) { + private fun onEntityTick(event: EntityTickEvent) { if(!enabled) return val entity = event.entity as? ArmorStandEntity ?: return diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/general/DevFeatures.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/general/DevFeatures.kt index 7556223f..b51406b7 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/general/DevFeatures.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/general/DevFeatures.kt @@ -13,7 +13,7 @@ import net.minecraft.screen.ScreenHandler import org.lwjgl.glfw.GLFW object DevFeatures { - private val gson = GsonBuilder().setPrettyPrinting().serializeNulls().create() + private val gson = GsonBuilder().setPrettyPrinting().create() @JvmStatic @OptIn(UntranslatedMessage::class) @@ -21,25 +21,12 @@ object DevFeatures { val slot = (screen as HandledScreenAccessor).focusedSlot ?: return if(slot.stack.isEmpty) return - MCUtils.copyToClipboard(buildTextToCopy(slot.stack)) + // it's easier to just dump the item to json than to try to use any of minecraft's nbt pretty printing + val encoded = ItemStack.CODEC.encodeStart(MCUtils.player!!.registryManager.getOps(JsonOps.INSTANCE), slot.stack).orThrow + MCUtils.copyToClipboard(gson.toJson(encoded)) ChatUtils.addMessage("Copied item data to clipboard") } - private fun buildTextToCopy(item: ItemStack): String = buildString { - append("---- DATA COMPONENTS ----\n\n") - // ItemStack#hasChangedComponent(ComponentType<*>) doesn't exist on 1.21.1 - item.components.filter { item.defaultComponents[it.type] !== it.value }.forEach { - appendLine("${it.type}:") - appendLine(it.value.toString().prependIndent(" ")) - appendLine() - } - append("---- SERIALIZED ITEM ----\n\n") - // it *is* possible to dump this as nbt, but json is slightly better to read than even prettified nbt. - // (ItemStack#toNbt(RegistryWrapper.WrapperLookup) also doesn't exist on 1.21.1) - val encoded = ItemStack.CODEC.encodeStart(MCUtils.player!!.registryManager.getOps(JsonOps.INSTANCE), item).orThrow - append(gson.toJson(encoded)) - }.trim() - @JvmStatic fun shouldCopy(keyCode: Int): Boolean { return PersistentCache.devMode && keyCode == GLFW.GLFW_KEY_RIGHT_CONTROL diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/CorpseLocator.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/CorpseLocator.kt index e6b561cc..8ad5cf5f 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/CorpseLocator.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/mining/glacitemineshaft/CorpseLocator.kt @@ -88,11 +88,7 @@ object CorpseLocator { if(!enabled) return if(entity.isInvisible) return if(!entity.shouldShowArms()) return - //? if >=1.21.2 { if(entity.shouldShowBasePlate()) return - //?} else { - /*if(!entity.shouldHideBasePlate()) return - *///?} val item = entity.getEquippedStack(EquipmentSlot.HEAD).asSkyBlockItem ?: return val corpseType = CorpseType.getByHelmetOrNull(item.id) ?: return diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/qol/MouseLock.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/qol/MouseLock.kt index 4cd62dfe..8f43ac6c 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/features/qol/MouseLock.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/qol/MouseLock.kt @@ -1,9 +1,5 @@ package me.nobaboy.nobaaddons.features.qol -//? if <1.21.2 { -/*import me.nobaboy.nobaaddons.utils.NobaVec -*///?} - import me.nobaboy.nobaaddons.api.skyblock.SkyBlockAPI.inIsland import me.nobaboy.nobaaddons.config.NobaConfig import me.nobaboy.nobaaddons.core.SkyBlockIsland @@ -70,11 +66,7 @@ object MouseLock { val packet = event.packet as? PlayerPositionLookS2CPacket ?: return val playerLocation = LocationUtils.playerLocation.roundTo(2) - //? if >=1.21.2 { val packetLocation = packet.change.position.toNobaVec().roundTo(2) - //?} else { - /*val packetLocation = NobaVec(packet.x, packet.y, packet.z).roundTo(2) - *///?} if(packetLocation.distance(playerLocation) >= 5) lockMouse() } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/ShowOwnNametagFeature.kt b/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/ShowOwnNametagFeature.kt new file mode 100644 index 00000000..e699b3c6 --- /dev/null +++ b/src/main/kotlin/me/nobaboy/nobaaddons/features/visuals/ShowOwnNametagFeature.kt @@ -0,0 +1,19 @@ +package me.nobaboy.nobaaddons.features.visuals + +import me.nobaboy.nobaaddons.core.DebugFlag +import me.nobaboy.nobaaddons.events.impl.render.EntityNametagRenderEvents +import me.owdding.ktmodules.Module +import net.minecraft.client.network.ClientPlayerEntity + +@Module +object ShowOwnNametagFeature { + init { + EntityNametagRenderEvents.VISIBILITY.register { + // TODO make this into a proper feature? currently this only exists to verify the nametag render logic works properly + if(!DebugFlag.SHOW_OWN_NAMETAG.enabled) return@register + if(it.entity is ClientPlayerEntity) { + it.renderOriginalNametag = true + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt b/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt index 7c94574b..930ccd1f 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/screens/NobaMainScreen.kt @@ -59,13 +59,8 @@ class NobaMainScreen(private val parent: Screen? = null) : Screen(CommonText.NOB layout.forEachChild { addDrawableChild(it) } } - //? if >=1.21.2 { override fun refreshWidgetPositions() { super.refreshWidgetPositions() - //?} else { - /*override fun initTabNavigation() { - super.initTabNavigation() - *///?} layout.refreshPositions() } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt index a318e168..515d6a08 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/NobaColor.kt @@ -25,7 +25,7 @@ value class NobaColor(val rgb: Int) { fun toJavaColor(): Color = Color(rgb) - fun withAlpha(alpha: Int): Int = ColorHelper./*? if <1.21.2 {*//*Argb.*//*?}*/withAlpha(alpha, rgb) + fun withAlpha(alpha: Int): Int = ColorHelper.withAlpha(alpha, rgb) companion object { private val allColors: List = buildList { diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/ItemUtils.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/ItemUtils.kt index c187ba31..25961b8f 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/ItemUtils.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/ItemUtils.kt @@ -1,23 +1,13 @@ package me.nobaboy.nobaaddons.utils.items -import com.google.common.cache.CacheBuilder -import com.google.common.cache.CacheLoader -import com.google.common.cache.LoadingCache import me.nobaboy.nobaaddons.config.NobaConfig +import me.nobaboy.nobaaddons.ducks.ItemSkyblockDataCache import net.minecraft.component.DataComponentTypes import net.minecraft.component.type.LoreComponent import net.minecraft.component.type.NbtComponent import net.minecraft.item.ItemStack -import java.lang.ref.WeakReference object ItemUtils { - // TODO change this to store this on the ItemStack itself? - private val ITEM_CACHE: LoadingCache = CacheBuilder.newBuilder() - .weakKeys() - .build(object : CacheLoader() { - override fun load(key: ItemStack) = SkyBlockItemData(WeakReference(key)) - }) - val ItemStack.nbt: NbtComponent get() = this.getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT) val ItemStack.lore: LoreComponent get() = this.getOrDefault(DataComponentTypes.LORE, LoreComponent.DEFAULT) @@ -27,9 +17,10 @@ object ItemUtils { val ItemStack.isSkyBlockItem: Boolean get() = !isEmpty && getOrDefault(DataComponentTypes.CUSTOM_DATA, NbtComponent.DEFAULT).contains("id") + @Suppress("CAST_NEVER_SUCCEEDS") // this cast *can* succeed, believe it or not val ItemStack.asSkyBlockItem: SkyBlockItemData? get() { if(!isSkyBlockItem) return null - return ITEM_CACHE.getUnchecked(this) + return (this as ItemSkyblockDataCache).`nobaaddons$getSkyblockData`() } val ItemStack.skyBlockId: String? get() = asSkyBlockItem?.id diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/NbtCompoundWrapper.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/NbtCompoundWrapper.kt index 0eae3d32..69ef39c5 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/NbtCompoundWrapper.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/NbtCompoundWrapper.kt @@ -8,7 +8,8 @@ import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtElement import net.minecraft.nbt.NbtList -class NbtCompoundWrapper(private val nbt: NbtCompound) { +@JvmInline +value class NbtCompoundWrapper(private val nbt: NbtCompound) { val entries: Map get() { //? if >=1.21.5 { /*return nbt.entrySet().associate { it.key to it.value } diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/SkyBlockItemData.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/SkyBlockItemData.kt index f35a3c34..eebc4617 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/SkyBlockItemData.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/items/SkyBlockItemData.kt @@ -16,6 +16,7 @@ import me.nobaboy.nobaaddons.utils.items.ItemUtils.lore import me.nobaboy.nobaaddons.utils.items.ItemUtils.nbt import me.nobaboy.nobaaddons.utils.properties.CacheOf import net.minecraft.component.type.LoreComponent +import net.minecraft.component.type.NbtComponent import net.minecraft.item.ItemStack import net.minecraft.nbt.NbtCompound import net.minecraft.nbt.NbtInt @@ -23,10 +24,15 @@ import java.lang.ref.WeakReference private val ITEM_TAG_REGEX by Regex("^(?:a )?(?(?:UN)?COMMON|RARE|EPIC|LEGENDARY|MYTHIC|DIVINE|ULTIMATE|(?:VERY )?SPECIAL) ?(?[A-Z ]+)?(?: a)?$").fromRepo("skyblock.item_tag") -class SkyBlockItemData(private val item: WeakReference) { - private val realNbt: NbtCompound get() = item.get()!!.nbt.nbt +class SkyBlockItemData( + private val nbtSupplier: () -> NbtComponent?, + private val loreSupplier: () -> LoreComponent?, + private val hashSupplier: () -> Int, +) { + private val realNbt: NbtCompound get() = (nbtSupplier() ?: NbtComponent.DEFAULT).nbt + private val lore: LoreComponent get() = loreSupplier() ?: LoreComponent.DEFAULT + private val nbt: NbtCompoundWrapper by CacheOf(this::realNbt) { NbtCompoundWrapper(realNbt) } - private val lore: LoreComponent get() = item.get()!!.lore val attributes: Map by CacheOf(this::realNbt) { val compound = nbt.getCompound("attributes") ?: return@CacheOf emptyMap() @@ -139,7 +145,7 @@ class SkyBlockItemData(private val item: WeakReference) { val ranchersSpeed: Int? by CacheOf(this::realNbt) { nbt.getInt("ranchers_speed") } override operator fun equals(other: Any?): Boolean = other is SkyBlockItemData && id == other.id && uuid == other.uuid - override fun hashCode(): Int = item.get().hashCode() + override fun hashCode(): Int = hashSupplier() data class Gemstone(val type: String, val tier: String) data class Potion(val name: String, val level: Int, val ticks: Int) diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/properties/Holding.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/properties/Holding.kt index 2d0129d1..b03b5030 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/properties/Holding.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/properties/Holding.kt @@ -27,10 +27,22 @@ data class Holding(@Volatile private var value: T? = null) { value = null } + /** + * Clears the currently held value, and then runs the provided [cleanup] callable + * + * If there is no value stored, this method effectively acts as a noop. + */ + fun clearWithCleanup(cleanup: (T) -> Unit) = synchronized(lock) { + val removed = value ?: return + value = null + cleanup(removed) + } + /** * Get the currently held value, or create one with the provided [factory] if no value is currently stored. */ fun getOrSet(factory: () -> T): T = synchronized(lock) { + // we can't use set() here as it's synchronized as well, which would cause a deadlock value ?: factory().also { value = it } } } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityDataKey.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityDataKey.kt new file mode 100644 index 00000000..da47f914 --- /dev/null +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityDataKey.kt @@ -0,0 +1,133 @@ +package me.nobaboy.nobaaddons.utils.render + +import me.nobaboy.nobaaddons.ducks.StateDataHolder +import net.minecraft.client.render.entity.state.EntityRenderState +import net.minecraft.entity.Entity +import net.minecraft.util.math.MathHelper +import kotlin.collections.contains + +/** + * Utility class providing a way to store data on [Entity] and [EntityRenderState] instances, and facilitating + * transferring data from an entity to its associated render state. + * + * Instances of this class are assumed to be unique keys suitable for use in a [Map], and as such [equals] will + * *never* return `true` when comparing two different class instances. + * + * ## Example + * + * ```kt + * val DATA = EntityDataKey { ... } + * + * // copy data stored on an entity to the associated render state + * // note that this does not properly handle mutable types (such as MutableList and MutableMap); + * // you're responsible for properly handling such types as necessary. + * RenderStateUpdateEvent.EVENT.register { it.copyToRender(DATA) } + * + * // in some event somewhere... + * DATA.get(entity) // get the stored value on an entity + * DATA.get(state) // or from a render state + * + * DATA.put(entity, ...) // set the stored value + * ``` + * + * @see me.nobaboy.nobaaddons.events.impl.render.RenderStateUpdateEvent + */ +class EntityDataKey(private val initialValue: () -> T) { + // precompute the hash to avoid needing to do this relatively expensive operation every map lookup + private val id = MathHelper.randomUuid().hashCode() + + override fun equals(other: Any?): Boolean = this === other + override fun hashCode(): Int = id + + /** + * Class containing the stored value for the associated [EntityDataKey]. + * + * This class is not designed to be manually constructed. + */ + inner class Value(@Volatile var value: T = initialValue()) + + /** + * Get the [Value] instance stored in the provided [StateDataHolder], or `null` if none exists + */ + @Suppress("UNCHECKED_CAST") + private fun getDataOrNull(holder: StateDataHolder): EntityDataKey.Value? = + holder.`nobaaddons$getData`()[this] as EntityDataKey.Value? + + /** + * Get the [Value] instance stored in the provided [StateDataHolder], creating it if one doesn't exist + */ + @Suppress("UNCHECKED_CAST") + private fun getData(holder: StateDataHolder): EntityDataKey.Value = + holder.`nobaaddons$getData`().getOrPut(this, ::Value) as EntityDataKey.Value + + /** + * Returns the current stored value for the provided [render state][state] + */ + fun get(state: EntityRenderState): T = getData(state.asDataHolder).value + + /** + * Returns the current stored value for the provided [entity] + */ + fun get(entity: Entity): T = getData(entity.asDataHolder).value + + /** + * Returns the current stored value for the provided [render state][state] + */ + fun getOrNull(state: EntityRenderState): T? = getDataOrNull(state.asDataHolder)?.value + + /** + * Returns the current stored value for the provided [entity] + */ + fun getOrNull(entity: Entity): T? = getDataOrNull(entity.asDataHolder)?.value + + /** + * Set the stored value for this key on the provided [render state][state] + */ + fun put(state: EntityRenderState, value: T) { + getData(state.asDataHolder).value = value + } + + /** + * Set the stored value for this key on the provided [entity] + */ + fun put(entity: Entity, value: T) { + getData(entity.asDataHolder).value = value + } + + /** + * Reset the stored value for this key on the provided [render state][state] to the initial value for this key + */ + fun reset(state: EntityRenderState) { + getData(state.asDataHolder).value = initialValue() + } + + /** + * Reset the stored value for this key on the provided [entity] to the initial value for this key + */ + fun reset(entity: Entity) { + getData(entity.asDataHolder).value = initialValue() + } + + /** + * Copy the data stored under this key on the provided [Entity] to the provided [EntityRenderState] + */ + fun copyToRender(entity: Entity, state: EntityRenderState) { + if(this !in entity) return + put(state, get(entity)) + } + + companion object { + operator fun StateDataHolder.contains(key: EntityDataKey<*>): Boolean = `nobaaddons$getData`().contains(key) + operator fun Entity.contains(key: EntityDataKey<*>): Boolean = (this as StateDataHolder).contains(key) + operator fun EntityRenderState.contains(key: EntityDataKey<*>): Boolean = (this as StateDataHolder).contains(key) + + private inline val Entity.asDataHolder get() = this as StateDataHolder + private inline val EntityRenderState.asDataHolder get() = this as StateDataHolder + + /** + * Convenience constructor creating a [EntityDataKey] that returns `null` as its initial value + */ + @JvmStatic + fun nullable() = EntityDataKey { null } + } +} \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityOverlay.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityOverlay.kt index e02186d9..e08a52a1 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityOverlay.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/EntityOverlay.kt @@ -1,27 +1,32 @@ package me.nobaboy.nobaaddons.utils.render -import com.google.common.cache.CacheBuilder -import com.google.common.cache.RemovalNotification import me.nobaboy.nobaaddons.events.impl.client.EntityEvents +import me.nobaboy.nobaaddons.events.impl.render.RenderStateUpdateEvent import me.nobaboy.nobaaddons.utils.NobaColor +import me.nobaboy.nobaaddons.utils.properties.Holding import net.fabricmc.loader.api.FabricLoader import net.minecraft.client.render.OverlayTexture +import net.minecraft.client.render.entity.state.EntityRenderState +import net.minecraft.client.render.entity.state.LivingEntityRenderState import net.minecraft.entity.Entity object EntityOverlay { + @JvmField val OVERLAY_TEXTURE = EntityDataKey>(::Holding) + @get:JvmStatic var overlay: OverlayTexture? = null private set - private val entities = CacheBuilder.newBuilder() - .weakKeys() - .removalListener(this::teardown) - .build() - init { - EntityEvents.PRE_RENDER.register { overlay = entities.getIfPresent(it.entity) } + RenderStateUpdateEvent.EVENT.register { + it.copyToRender(OVERLAY_TEXTURE) + if(it.state is LivingEntityRenderState && contains(it.state)) { + it.state.hurt = false + } + } + EntityEvents.PRE_RENDER.register { overlay = OVERLAY_TEXTURE.get(it.state).get() } EntityEvents.POST_RENDER.register { overlay = null } - EntityEvents.DESPAWN.register { entities.invalidate(it.entity) } + EntityEvents.DESPAWN.register { remove(it.entity) } } fun Entity.highlight(color: NobaColor) { @@ -29,36 +34,25 @@ object EntityOverlay { } @JvmStatic - fun get(entity: Entity): NobaColor? = entities.getIfPresent(entity)?.lastColor + fun get(entity: Entity): NobaColor? = OVERLAY_TEXTURE.get(entity).get()?.lastColor + + @JvmStatic + fun get(state: EntityRenderState): NobaColor? = OVERLAY_TEXTURE.get(state).get()?.lastColor // java, for whatever reason, inexplicably refuses to acknowledge .get() as a valid method? // so the simple fix is to just do this, i guess. @JvmStatic - fun getRgb(entity: Entity): Int? = get(entity)?.rgb + fun getRgb(state: EntityRenderState): Int? = get(state)?.rgb - @JvmStatic - fun contains(entity: Entity): Boolean = entities.getIfPresent(entity) != null + @JvmStatic fun contains(entity: Entity): Boolean = get(entity) != null + @JvmStatic fun contains(entity: EntityRenderState): Boolean = get(entity) != null fun set(entity: Entity, color: NobaColor) { if(FabricLoader.getInstance().isModLoaded("iris")) return // TODO figure out how to make this play nicely with iris - val overlay: TintOverlayTexture = run { - val overlay = entities.getIfPresent(entity) - if(overlay == null) { - val created = TintOverlayTexture() - entities.put(entity, created) - created - } else { - overlay - } - } - overlay.setColor(color) - } - - private fun teardown(notification: RemovalNotification) { - notification.value?.close() + OVERLAY_TEXTURE.get(entity).getOrSet(::TintOverlayTexture).setColor(color) } fun remove(entity: Entity) { - entities.invalidate(entity) + OVERLAY_TEXTURE.getOrNull(entity)?.clearWithCleanup(OverlayTexture::close) } } \ No newline at end of file diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/NobaRenderLayers.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/NobaRenderLayers.kt index dd6bc36d..43ba9b4c 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/NobaRenderLayers.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/NobaRenderLayers.kt @@ -32,11 +32,7 @@ object NobaRenderLayers { .build(false) *///?} else { MultiPhaseParameters.builder() - //? if >=1.21.2 { .program(RenderPhase.POSITION_COLOR_PROGRAM) - //?} else { - /*.program(RenderPhase.COLOR_PROGRAM) - *///?} .transparency(RenderLayer.TRANSLUCENT_TRANSPARENCY) .depthTest(RenderLayer.LEQUAL_DEPTH_TEST) .cull(RenderLayer.DISABLE_CULLING) @@ -61,11 +57,7 @@ object NobaRenderLayers { .build(false) *///?} else { MultiPhaseParameters.builder() - //? if >=1.21.2 { .program(RenderPhase.POSITION_COLOR_PROGRAM) - //?} else { - /*.program(RenderPhase.COLOR_PROGRAM) - *///?} .transparency(RenderLayer.TRANSLUCENT_TRANSPARENCY) .depthTest(RenderLayer.ALWAYS_DEPTH_TEST) .cull(RenderLayer.DISABLE_CULLING) diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt index 8d6ed072..54fd5d08 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/RenderUtils.kt @@ -1,12 +1,7 @@ package me.nobaboy.nobaaddons.utils.render -//? if >=1.21.2 { import me.nobaboy.nobaaddons.mixins.accessors.DrawContextAccessor import net.minecraft.client.render.VertexRendering -//?} else { -/*import net.minecraft.client.render.WorldRenderer -import net.minecraft.client.render.GameRenderer -*///?} //? if >=1.21.5 { /*import kotlin.math.max @@ -98,9 +93,7 @@ object RenderUtils { applyScaling: Boolean = true, ) { if(applyScaling) startScale(context, scale) - val vertexConsumerProvider = context.let { - (it /*? if >=1.21.2 {*/ as DrawContextAccessor/*?}*/).vertexConsumers - } + val vertexConsumerProvider = (context as DrawContextAccessor).vertexConsumers MCUtils.textRenderer.drawWithOutline( text.asOrderedText(), x / scale, @@ -297,11 +290,7 @@ object RenderUtils { matrices.push() matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z) - //? if >=1.21.2 { VertexRendering.drawFilledBox( - //?} else { - /*WorldRenderer.renderFilledBox( - *///?} matrices, buffer, box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ, @@ -346,11 +335,7 @@ object RenderUtils { matrices.push() matrices.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z) - //? if >=1.21.2 { VertexRendering.drawBox( - //?} else { - /*WorldRenderer.drawBox( - *///?} matrices, buffer, box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ, @@ -365,7 +350,7 @@ object RenderUtils { location: NobaVec, text: Text, color: NobaColor = NobaColor.WHITE, - shadow: Boolean = /*? if >=1.21.2 {*/true/*?} else {*//*false*//*?}*/, + shadow: Boolean = true, yOffset: Float = 0f, scaleMultiplier: Float = 1f, hideThreshold: Double = 0.0, @@ -429,7 +414,7 @@ object RenderUtils { location: NobaVec, text: String, color: NobaColor = NobaColor.WHITE, - shadow: Boolean = /*? if >=1.21.2 {*/true/*?} else {*//*false*//*?}*/, + shadow: Boolean = true, yOffset: Float = 0f, scaleMultiplier: Float = 1f, hideThreshold: Double = 0.0, diff --git a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TintOverlayTexture.kt b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TintOverlayTexture.kt index 9072f8af..95ebfde4 100644 --- a/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TintOverlayTexture.kt +++ b/src/main/kotlin/me/nobaboy/nobaaddons/utils/render/TintOverlayTexture.kt @@ -35,13 +35,9 @@ class TintOverlayTexture : OverlayTexture() { 0xB2FF0000.toInt() } else { val alpha = ((1.0f - y.toFloat() / 15.0f * 0.75f) * 255.0f).toInt() - ColorHelper/*? if <1.21.2 {*//*.Argb*//*?}*/.withAlpha(alpha, color.rgb) + ColorHelper.withAlpha(alpha, color.rgb) } - //? if >=1.21.2 { image.setColorArgb(x, y, color) - //?} else { - /*image.setColor(x, y, color) - *///?} } } diff --git a/versions/1.21/gradle.properties b/versions/1.21/gradle.properties deleted file mode 100644 index 3787e8c9..00000000 --- a/versions/1.21/gradle.properties +++ /dev/null @@ -1,9 +0,0 @@ -mod.mc_dep=>=1.21 <1.21.2 -mod.mc_title=1.21 -mod.mc_targets=1.21 1.21.1 - -deps.yarn_build=9 -deps.fabric_api=0.102.0 -deps.yacl=3.6.2+1.21 -deps.modmenu=11.0.3 -deps.sodium=mc1.21.1-0.6.5