diff options
16 files changed, 311 insertions, 36 deletions
diff --git a/build.gradle b/build.gradle index c54dd44..ffeeb22 100644 --- a/build.gradle +++ b/build.gradle @@ -28,6 +28,7 @@ repositories { } maven { url "https://maven.shedaniel.me/" } maven { url "https://maven.terraformersmc.com/releases/" } + maven { url = "https://jitpack.io/" } } dependencies { @@ -40,8 +41,9 @@ dependencies { modRuntimeOnly("me.djtheredstoner:DevAuth-fabric:1.1.2") implementation "meteordevelopment:orbit:0.2.3" modApi "me.shedaniel.cloth:cloth-config-fabric:11.0.99" - implementation "com.github.LlamaLad7:MixinExtras:0.1.1" - annotationProcessor "com.github.LlamaLad7:MixinExtras:0.1.1" + include "com.github.llamalad7.mixinextras:mixinextras-fabric:0.2.0-beta.9" + implementation "com.github.llamalad7.mixinextras:mixinextras-fabric:0.2.0-beta.9" + annotationProcessor "com.github.llamalad7.mixinextras:mixinextras-fabric:0.2.0-beta.9" } loom { 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 |