aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/dulkirfabric/mixin/ItemMixin.java24
-rw-r--r--src/main/java/com/dulkirfabric/mixin/render/LivingEntityMixin.java44
-rw-r--r--src/main/java/com/dulkirfabric/mixin/render/MinecraftClientMixin.java14
-rw-r--r--src/main/java/com/dulkirfabric/mixin/render/WorldRendererMixin.java61
-rw-r--r--src/main/kotlin/com/dulkirfabric/Registrations.kt63
-rw-r--r--src/main/kotlin/com/dulkirfabric/events/EntityLoadEvent.kt10
-rw-r--r--src/main/kotlin/com/dulkirfabric/events/WorldLoadEvent.kt10
-rw-r--r--src/main/kotlin/com/dulkirfabric/features/CooldownDisplays.kt61
-rw-r--r--src/main/kotlin/com/dulkirfabric/features/RenderTest.kt6
-rw-r--r--src/main/kotlin/com/dulkirfabric/util/GlowingEntityInterface.kt13
-rw-r--r--src/main/kotlin/com/dulkirfabric/util/SoundInfo.kt7
-rw-r--r--src/main/kotlin/com/dulkirfabric/util/TrackedCooldown.kt8
-rw-r--r--src/main/kotlin/com/dulkirfabric/util/Utils.kt11
-rw-r--r--src/main/resources/1.0 TODO.txt2
-rw-r--r--src/main/resources/dulkirmod-fabric.mixins.json7
15 files changed, 307 insertions, 34 deletions
diff --git a/src/main/java/com/dulkirfabric/mixin/ItemMixin.java b/src/main/java/com/dulkirfabric/mixin/ItemMixin.java
new file mode 100644
index 0000000..53e637e
--- /dev/null
+++ b/src/main/java/com/dulkirfabric/mixin/ItemMixin.java
@@ -0,0 +1,24 @@
+package com.dulkirfabric.mixin;
+
+import com.dulkirfabric.features.CooldownDisplays;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+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(Item.class)
+public class ItemMixin {
+
+ @Inject(method = "isItemBarVisible(Lnet/minecraft/item/ItemStack;)Z",
+ at = @At("HEAD"), cancellable = true)
+ public void shouldDisplayDurabilityBar(ItemStack stack, CallbackInfoReturnable<Boolean> cir) {
+ CooldownDisplays.INSTANCE.shouldDisplay(stack, cir);
+ }
+ @Inject(method = "getItemBarStep(Lnet/minecraft/item/ItemStack;)I",
+ at = @At("HEAD"), cancellable = true)
+ public void calculateItemHealth(ItemStack stack, CallbackInfoReturnable<Integer> cir) {
+ CooldownDisplays.INSTANCE.calcDurability(stack, cir);
+ }
+}
diff --git a/src/main/java/com/dulkirfabric/mixin/render/LivingEntityMixin.java b/src/main/java/com/dulkirfabric/mixin/render/LivingEntityMixin.java
new file mode 100644
index 0000000..1b86f5c
--- /dev/null
+++ b/src/main/java/com/dulkirfabric/mixin/render/LivingEntityMixin.java
@@ -0,0 +1,44 @@
+package com.dulkirfabric.mixin.render;
+
+import com.dulkirfabric.util.GlowingEntityInterface;
+import net.minecraft.entity.LivingEntity;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Unique;
+
+import java.awt.*;
+
+@Mixin(LivingEntity.class)
+public class LivingEntityMixin implements GlowingEntityInterface {
+
+ @Unique
+ private boolean shouldGlow_DulkirMod;
+ @Unique
+ private Color glowColor_DulkirMod;
+ @Unique
+ private boolean shouldESP_DulkirMod;
+
+ @Override
+ public void setDulkirEntityGlow(boolean shouldGlow, @NotNull Color glowColor, boolean shouldESP) {
+ this.shouldGlow_DulkirMod = shouldGlow;
+ this.glowColor_DulkirMod = glowColor;
+ this.shouldESP_DulkirMod = shouldESP;
+ }
+
+ @Override
+ public boolean shouldDulkirEntityGlow() {
+ return shouldGlow_DulkirMod;
+ }
+
+ @Nullable
+ @Override
+ public Color getDulkirEntityGlowColor() {
+ return glowColor_DulkirMod;
+ }
+
+ @Override
+ public boolean shouldDulkirEntityESP() {
+ return shouldESP_DulkirMod;
+ }
+}
diff --git a/src/main/java/com/dulkirfabric/mixin/render/MinecraftClientMixin.java b/src/main/java/com/dulkirfabric/mixin/render/MinecraftClientMixin.java
index 9ab55ae..13285e3 100644
--- a/src/main/java/com/dulkirfabric/mixin/render/MinecraftClientMixin.java
+++ b/src/main/java/com/dulkirfabric/mixin/render/MinecraftClientMixin.java
@@ -1,9 +1,23 @@
package com.dulkirfabric.mixin.render;
+import com.dulkirfabric.util.GlowingEntityInterface;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.entity.Entity;
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.CallbackInfoReturnable;
@Mixin(MinecraftClient.class)
public class MinecraftClientMixin {
+ @Inject(method = "hasOutline(Lnet/minecraft/entity/Entity;)Z", at = @At("HEAD"), cancellable = true)
+ public void outlineCheck(Entity entity, CallbackInfoReturnable<Boolean> cir) {
+ if (entity instanceof GlowingEntityInterface gEntity) {
+ if (gEntity.shouldDulkirEntityGlow()) {
+ cir.setReturnValue(true);
+ }
+ }
+ }
}
diff --git a/src/main/java/com/dulkirfabric/mixin/render/WorldRendererMixin.java b/src/main/java/com/dulkirfabric/mixin/render/WorldRendererMixin.java
new file mode 100644
index 0000000..bb1a9be
--- /dev/null
+++ b/src/main/java/com/dulkirfabric/mixin/render/WorldRendererMixin.java
@@ -0,0 +1,61 @@
+package com.dulkirfabric.mixin.render;
+
+import com.dulkirfabric.util.GlowingEntityInterface;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import com.llamalad7.mixinextras.sugar.Local;
+import net.minecraft.client.gl.Framebuffer;
+import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.GameRenderer;
+import net.minecraft.client.render.LightmapTextureManager;
+import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.client.util.math.MatrixStack;
+import net.minecraft.entity.Entity;
+import org.jetbrains.annotations.Nullable;
+import org.joml.Matrix4f;
+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 static com.dulkirfabric.DulkirModFabric.mc;
+
+@Mixin(WorldRenderer.class)
+public class WorldRendererMixin {
+
+ @Shadow private @Nullable Framebuffer entityOutlinesFramebuffer;
+ @Unique
+ Framebuffer temp = this.entityOutlinesFramebuffer;
+ @ModifyExpressionValue(method = "render(Lnet/minecraft/client/util/math/MatrixStack;FJZLnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/GameRenderer;Lnet/minecraft/client/render/LightmapTextureManager;Lorg/joml/Matrix4f;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/entity/Entity;getTeamColorValue()I"))
+ public int getGlowColor(int existing, @Local Entity entity) {
+ if (entity instanceof GlowingEntityInterface dEntity) {
+ if (dEntity.getDulkirEntityGlowColor() != null) {
+ return dEntity.getDulkirEntityGlowColor().getRGB();
+ }
+ }
+ return existing;
+ }
+
+ @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;FJZLnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/GameRenderer;Lnet/minecraft/client/render/LightmapTextureManager;Lorg/joml/Matrix4f;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/BufferBuilderStorage;getEntityVertexConsumers()Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;", shift = At.Shift.AFTER))
+ public void saveDefaultBufferESP(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci) {
+ temp = this.entityOutlinesFramebuffer;
+ }
+
+ @Inject(method = "render(Lnet/minecraft/client/util/math/MatrixStack;FJZLnet/minecraft/client/render/Camera;Lnet/minecraft/client/render/GameRenderer;Lnet/minecraft/client/render/LightmapTextureManager;Lorg/joml/Matrix4f;)V",
+ at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/entity/EntityRenderDispatcher;shouldRender(Lnet/minecraft/entity/Entity;Lnet/minecraft/client/render/Frustum;DDD)Z"))
+ public void setOutlineESP(MatrixStack matrices, float tickDelta, long limitTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightmapTextureManager lightmapTextureManager, Matrix4f positionMatrix, CallbackInfo ci, @Local Entity entity) {
+ if (entity instanceof GlowingEntityInterface dEntity) {
+ if (dEntity.shouldDulkirEntityGlow() && !dEntity.shouldDulkirEntityESP()) {
+ if (this.entityOutlinesFramebuffer != null)
+ this.entityOutlinesFramebuffer.copyDepthFrom(mc.getFramebuffer());
+ }
+ } else {
+ // give esp back here
+ if (this.entityOutlinesFramebuffer != null)
+ this.entityOutlinesFramebuffer.copyDepthFrom(temp);
+ }
+ }
+}
diff --git a/src/main/kotlin/com/dulkirfabric/Registrations.kt b/src/main/kotlin/com/dulkirfabric/Registrations.kt
index 5fa7cd8..519319e 100644
--- a/src/main/kotlin/com/dulkirfabric/Registrations.kt
+++ b/src/main/kotlin/com/dulkirfabric/Registrations.kt
@@ -12,12 +12,14 @@ import com.dulkirfabric.features.*
import com.dulkirfabric.features.chat.AbiPhoneDND
import com.dulkirfabric.util.TablistUtils
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback
+import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents
import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents
import net.fabricmc.fabric.api.client.screen.v1.ScreenEvents
import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents
+import net.fabricmc.fabric.api.event.lifecycle.v1.ServerWorldEvents
/**
@@ -59,43 +61,44 @@ object Registrations {
EVENT_BUS.subscribe(EffigyDisplay)
EVENT_BUS.subscribe(TablistUtils)
EVENT_BUS.subscribe(CullExplosionParticles)
+ EVENT_BUS.subscribe(CooldownDisplays)
}
fun registerEvents() {
// Register Custom Tick event, so we can use it like 1.8.9 forge
- ClientTickEvents.START_CLIENT_TICK.register(
- ClientTickEvents.StartTick { _ ->
- ClientTickEvent.post()
- if (tickCount % 20 == 0) LongUpdateEvent.post()
- tickCount++
- }
- )
- ClientReceiveMessageEvents.ALLOW_GAME.register(
- ClientReceiveMessageEvents.AllowGame { message, overlay ->
- if (overlay) !OverlayReceivedEvent(message.toString()).post()
- else !ChatReceivedEvent(message).post()
- }
- )
- ClientSendMessageEvents.MODIFY_COMMAND.register(
- ClientSendMessageEvents.ModifyCommand { command ->
- ModifyCommandEvent(command).also { it.post() }.command
- }
- )
- WorldRenderEvents.END.register(
- WorldRenderEvents.End { context -> WorldRenderLastEvent(context).post()}
- )
+ ClientTickEvents.START_CLIENT_TICK.register { _ ->
+ ClientTickEvent.post()
+ if (tickCount % 20 == 0) LongUpdateEvent.post()
+ tickCount++
+ }
+ ClientReceiveMessageEvents.ALLOW_GAME.register { message, overlay ->
+ if (overlay) !OverlayReceivedEvent(message.toString()).post()
+ else !ChatReceivedEvent(message).post()
+ }
+
+ ClientSendMessageEvents.MODIFY_COMMAND.register { command ->
+ ModifyCommandEvent(command).also { it.post() }.command
+ }
+
+ WorldRenderEvents.END.register { context -> WorldRenderLastEvent(context).post() }
+
ScreenEvents.BEFORE_INIT.register(
ScreenEvents.BeforeInit { client, screen, scaledWidth, scaledHeight ->
- ScreenMouseEvents.beforeMouseScroll(screen).register(ScreenMouseEvents.BeforeMouseScroll {
- coolScreen, mouseX, mouseY, horizontalAmount, verticalAmount ->
- MouseScrollEvent(coolScreen, mouseX, mouseY, horizontalAmount, verticalAmount).post()
- })
- }
- )
- WorldRenderEvents.BLOCK_OUTLINE.register(
- WorldRenderEvents.BlockOutline { worldRenderContext, blockOutlineContext ->
- !BlockOutlineEvent(worldRenderContext, blockOutlineContext).post()
+ ScreenMouseEvents.beforeMouseScroll(screen)
+ .register(ScreenMouseEvents.BeforeMouseScroll { coolScreen, mouseX, mouseY, horizontalAmount, verticalAmount ->
+ MouseScrollEvent(coolScreen, mouseX, mouseY, horizontalAmount, verticalAmount).post()
+ })
}
)
+
+ WorldRenderEvents.BLOCK_OUTLINE.register { worldRenderContext, blockOutlineContext ->
+ !BlockOutlineEvent(worldRenderContext, blockOutlineContext).post()
+ }
+ ClientEntityEvents.ENTITY_LOAD.register { entity, world ->
+ EntityLoadEvent(entity, world)
+ }
+ ServerWorldEvents.LOAD.register { server, world ->
+ WorldLoadEvent(server, world)
+ }
}
} \ No newline at end of file
diff --git a/src/main/kotlin/com/dulkirfabric/events/EntityLoadEvent.kt b/src/main/kotlin/com/dulkirfabric/events/EntityLoadEvent.kt
new file mode 100644
index 0000000..e588ed2
--- /dev/null
+++ b/src/main/kotlin/com/dulkirfabric/events/EntityLoadEvent.kt
@@ -0,0 +1,10 @@
+package com.dulkirfabric.events
+
+import com.dulkirfabric.events.base.Event
+import net.minecraft.entity.Entity
+import net.minecraft.world.World
+
+data class EntityLoadEvent(
+ val entity: Entity,
+ val world: World
+): Event()
diff --git a/src/main/kotlin/com/dulkirfabric/events/WorldLoadEvent.kt b/src/main/kotlin/com/dulkirfabric/events/WorldLoadEvent.kt
new file mode 100644
index 0000000..d43f74b
--- /dev/null
+++ b/src/main/kotlin/com/dulkirfabric/events/WorldLoadEvent.kt
@@ -0,0 +1,10 @@
+package com.dulkirfabric.events
+
+import com.dulkirfabric.events.base.Event
+import net.minecraft.server.MinecraftServer
+import net.minecraft.world.World
+
+data class WorldLoadEvent(
+ val server: MinecraftServer,
+ val world: World
+): Event()
diff --git a/src/main/kotlin/com/dulkirfabric/features/CooldownDisplays.kt b/src/main/kotlin/com/dulkirfabric/features/CooldownDisplays.kt
new file mode 100644
index 0000000..86a3863
--- /dev/null
+++ b/src/main/kotlin/com/dulkirfabric/features/CooldownDisplays.kt
@@ -0,0 +1,61 @@
+package com.dulkirfabric.features
+
+import com.dulkirfabric.events.PlaySoundEvent
+import com.dulkirfabric.events.WorldLoadEvent
+import com.dulkirfabric.util.SoundInfo
+import com.dulkirfabric.util.TrackedCooldown
+import meteordevelopment.orbit.EventHandler
+import net.minecraft.item.ItemStack
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable
+
+object CooldownDisplays {
+ private val trackedCooldowns: Map<SoundInfo, TrackedCooldown> = mapOf(
+ Pair(
+ SoundInfo("mob.zombie.remedy", 1f, .5f),
+ TrackedCooldown("(REAPER_CHESTPLATE)|(REAPER_LEGGINGS)|(REAPER_BOOTS)".toRegex(), 25000, 0)
+ ),
+ Pair(
+ SoundInfo("mob.zombie.remedy", 0.6984127f, 1f),
+ TrackedCooldown("(HYPERION|ASTRAEA|SCYLLA|VALKYRIE)".toRegex(), 5000, 0)
+ )
+ )
+
+ fun shouldDisplay(stack: ItemStack, cir: CallbackInfoReturnable<Boolean>) {
+ val cooldown = fetchCooldownItem(stack) ?: return
+ cir.returnValue = true
+ // cir.returnValue = System.currentTimeMillis() - cooldown.lastUsage < cooldown.cooldownDuration
+ }
+
+ fun calcDurability(stack: ItemStack, cir: CallbackInfoReturnable<Int>) {
+ val cooldown = fetchCooldownItem(stack) ?: return
+ cir.returnValue = 300
+ }
+ @EventHandler
+ fun onSound(event: PlaySoundEvent) {
+ val path = event.sound.id.path
+ val pitch = event.sound.pitch
+ val volume = event.sound.volume
+
+ // Figure out if we have a match in trackedCooldowns
+ val matchResult = trackedCooldowns[SoundInfo(path, pitch, volume)] ?: return
+ matchResult.lastUsage = System.currentTimeMillis()
+ }
+
+ @EventHandler
+ fun onWorldLoad(event: WorldLoadEvent) {
+ trackedCooldowns.forEach {
+ it.value.lastUsage = 0
+ }
+ }
+
+ private fun fetchCooldownItem(stack: ItemStack): TrackedCooldown? {
+ val tag = stack.nbt ?: return null
+ val id = tag.getCompound("ExtraAttributes").get("id") ?: return null
+ val idStr = id.toString().trim('"')
+ trackedCooldowns.forEach {
+ if (idStr matches it.value.itemID)
+ return it.value
+ }
+ return null
+ }
+} \ No newline at end of file
diff --git a/src/main/kotlin/com/dulkirfabric/features/RenderTest.kt b/src/main/kotlin/com/dulkirfabric/features/RenderTest.kt
index 8ad270d..1f96a7b 100644
--- a/src/main/kotlin/com/dulkirfabric/features/RenderTest.kt
+++ b/src/main/kotlin/com/dulkirfabric/features/RenderTest.kt
@@ -17,4 +17,10 @@ object RenderTest {
Vec3d(-183.5, 79.0, -465.5)
)
}
+
+// @EventHandler
+// fun onLoadEnt(event: EntityLoadEvent) {
+// if (event.entity !is GlowingEntityInterface) return
+// event.entity.setDulkirEntityGlow(true, Color(255, 255, 255, 255), true)
+// }
} \ No newline at end of file
diff --git a/src/main/kotlin/com/dulkirfabric/util/GlowingEntityInterface.kt b/src/main/kotlin/com/dulkirfabric/util/GlowingEntityInterface.kt
new file mode 100644
index 0000000..5a76890
--- /dev/null
+++ b/src/main/kotlin/com/dulkirfabric/util/GlowingEntityInterface.kt
@@ -0,0 +1,13 @@
+package com.dulkirfabric.util
+
+import java.awt.Color
+
+interface GlowingEntityInterface {
+ fun setDulkirEntityGlow(shouldGlow: Boolean, glowColor: Color, shouldESP: Boolean = false)
+
+ fun shouldDulkirEntityGlow() : Boolean
+
+ fun getDulkirEntityGlowColor() : Color?
+
+ fun shouldDulkirEntityESP() : Boolean
+} \ No newline at end of file
diff --git a/src/main/kotlin/com/dulkirfabric/util/SoundInfo.kt b/src/main/kotlin/com/dulkirfabric/util/SoundInfo.kt
new file mode 100644
index 0000000..c9f339a
--- /dev/null
+++ b/src/main/kotlin/com/dulkirfabric/util/SoundInfo.kt
@@ -0,0 +1,7 @@
+package com.dulkirfabric.util
+
+data class SoundInfo(
+ val path: String,
+ val pitch: Float,
+ val volume: Float
+)
diff --git a/src/main/kotlin/com/dulkirfabric/util/TrackedCooldown.kt b/src/main/kotlin/com/dulkirfabric/util/TrackedCooldown.kt
new file mode 100644
index 0000000..9aa93d7
--- /dev/null
+++ b/src/main/kotlin/com/dulkirfabric/util/TrackedCooldown.kt
@@ -0,0 +1,8 @@
+package com.dulkirfabric.util
+
+// Currently, this will be used to create A list of items that have audible sounds associated with their usages
+data class TrackedCooldown (
+ val itemID: Regex,
+ val cooldownDuration: Int, // in millis
+ var lastUsage: Long, // from System.currentTimeMillis
+) \ No newline at end of file
diff --git a/src/main/kotlin/com/dulkirfabric/util/Utils.kt b/src/main/kotlin/com/dulkirfabric/util/Utils.kt
index ce6665b..ae98cf6 100644
--- a/src/main/kotlin/com/dulkirfabric/util/Utils.kt
+++ b/src/main/kotlin/com/dulkirfabric/util/Utils.kt
@@ -1,7 +1,18 @@
package com.dulkirfabric.util
+import com.dulkirfabric.events.PlaySoundEvent
+
object Utils {
fun isInSkyblock(): Boolean {
return ScoreBoardUtils.getLines() != null
}
+
+ /**
+ * Prints relevant information about a sound that is being displayed
+ */
+ fun debugSound(event: PlaySoundEvent) {
+ println("Path: ${event.sound.id.path}")
+ println("Pitch: ${event.sound.pitch}")
+ println("Volume: ${event.sound.volume}")
+ }
} \ No newline at end of file
diff --git a/src/main/resources/1.0 TODO.txt b/src/main/resources/1.0 TODO.txt
index 2100b33..8cd0f06 100644
--- a/src/main/resources/1.0 TODO.txt
+++ b/src/main/resources/1.0 TODO.txt
@@ -4,10 +4,8 @@ Hype Broken
Arachne Timer
Keeper Waypoints
Item Ability Cooldown displays
-Starred Mob glow
Trim Useless Messages
Tablist Utility
-Hide Scoreboard Numbers
Later:
Speed Display
diff --git a/src/main/resources/dulkirmod-fabric.mixins.json b/src/main/resources/dulkirmod-fabric.mixins.json
index bdf1721..110d9b4 100644
--- a/src/main/resources/dulkirmod-fabric.mixins.json
+++ b/src/main/resources/dulkirmod-fabric.mixins.json
@@ -19,9 +19,12 @@
"render.MinecraftClientMixin",
"render.ParticleManagerMixin",
"render.PerspectiveMixin",
- "render.ScreenMixin"
+ "render.ScreenMixin",
+ "render.WorldRendererMixin"
],
"mixins": [
- "ItemStackMixin"
+ "ItemMixin",
+ "ItemStackMixin",
+ "render.LivingEntityMixin"
]
} \ No newline at end of file