From e75052edeafed309e19e28e177d3e1dd94debffc Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Tue, 8 Mar 2022 02:50:08 +0000 Subject: [PATCH] No Fog, 'Hard' mode for Flight, failsafe for ImGui --- .../mixins/MixinBackgroundRenderer.java | 26 +++++++++ .../mixins/MixinClientPlayerEntity.java | 10 ++-- .../hibiscus/mixins/MixinMinecraftClient.java | 4 +- .../mixins/xray/MixinLightDataAccess.java | 19 +++++-- .../som/hibiscus/api/event/TypedListener.kt | 9 ++-- .../codes/som/hibiscus/api/feature/Feature.kt | 12 ++++- .../api/feature/values/ValueRegistry.kt | 4 +- .../codes/som/hibiscus/events/PlayerEvents.kt | 1 + .../codes/som/hibiscus/events/RenderEvents.kt | 2 + .../som/hibiscus/features/FeaturesRegistry.kt | 4 +- .../hibiscus/features/exploits/AntiGhost.kt | 4 +- .../som/hibiscus/features/exploits/Ghost.kt | 8 +-- .../som/hibiscus/features/movement/Flight.kt | 53 +++++++++++++------ .../som/hibiscus/features/movement/Speed.kt | 3 +- .../som/hibiscus/features/visual/Freecam.kt | 29 ++-------- .../som/hibiscus/features/visual/NoFog.kt | 15 ++++++ .../codes/som/hibiscus/gui/ImGuiRenderer.kt | 15 +++++- .../som/hibiscus/util/math/MovementVector.kt | 32 +++++++++++ src/main/resources/hibiscus.mixins.json | 1 + 19 files changed, 186 insertions(+), 65 deletions(-) create mode 100644 src/main/java/codes/som/hibiscus/mixins/MixinBackgroundRenderer.java create mode 100644 src/main/kotlin/codes/som/hibiscus/features/visual/NoFog.kt create mode 100644 src/main/kotlin/codes/som/hibiscus/util/math/MovementVector.kt diff --git a/src/main/java/codes/som/hibiscus/mixins/MixinBackgroundRenderer.java b/src/main/java/codes/som/hibiscus/mixins/MixinBackgroundRenderer.java new file mode 100644 index 0000000..3f0d709 --- /dev/null +++ b/src/main/java/codes/som/hibiscus/mixins/MixinBackgroundRenderer.java @@ -0,0 +1,26 @@ +package codes.som.hibiscus.mixins; + +import codes.som.hibiscus.Hibiscus; +import codes.som.hibiscus.events.RenderFogEvent; +import com.mojang.blaze3d.systems.RenderSystem; +import net.minecraft.client.render.BackgroundRenderer; +import net.minecraft.client.render.Camera; +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(BackgroundRenderer.class) +public abstract class MixinBackgroundRenderer { + @Inject(method = "applyFog", at = @At("HEAD"), cancellable = true) + private static void onApplyFog(Camera camera, BackgroundRenderer.FogType fogType, float viewDistance, boolean thickFog, CallbackInfo ci) { + var event = new RenderFogEvent(); + Hibiscus.bus().fire(event); + if (event.isCancelled()) { + RenderSystem.setShaderFogStart(1000.0f); + RenderSystem.setShaderFogEnd(8000.0f); + + ci.cancel(); + } + } +} diff --git a/src/main/java/codes/som/hibiscus/mixins/MixinClientPlayerEntity.java b/src/main/java/codes/som/hibiscus/mixins/MixinClientPlayerEntity.java index 5d121cd..d0d0d1e 100644 --- a/src/main/java/codes/som/hibiscus/mixins/MixinClientPlayerEntity.java +++ b/src/main/java/codes/som/hibiscus/mixins/MixinClientPlayerEntity.java @@ -1,10 +1,7 @@ package codes.som.hibiscus.mixins; import codes.som.hibiscus.Hibiscus; -import codes.som.hibiscus.events.MovePlayerEvent; -import codes.som.hibiscus.events.PlayerPreTickEvent; -import codes.som.hibiscus.events.PlayerTickEvent; -import codes.som.hibiscus.events.SendChatEvent; +import codes.som.hibiscus.events.*; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.entity.MovementType; import net.minecraft.util.math.Vec3d; @@ -49,4 +46,9 @@ public abstract class MixinClientPlayerEntity { Hibiscus.bus().fire(event); return new Vec3d(event.getX(), event.getY(), event.getZ()); } + + @Inject(method = "tickMovement", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/input/Input;tick(Z)V", shift = At.Shift.AFTER)) + private void onInputTick(CallbackInfo ci) { + Hibiscus.bus().fire(PlayerInputTickEvent.INSTANCE); + } } diff --git a/src/main/java/codes/som/hibiscus/mixins/MixinMinecraftClient.java b/src/main/java/codes/som/hibiscus/mixins/MixinMinecraftClient.java index 692e15f..90a50c0 100644 --- a/src/main/java/codes/som/hibiscus/mixins/MixinMinecraftClient.java +++ b/src/main/java/codes/som/hibiscus/mixins/MixinMinecraftClient.java @@ -43,7 +43,9 @@ public abstract class MixinMinecraftClient { @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gl/Framebuffer;endWrite()V", shift = At.Shift.BEFORE)) private void onPostRenderEverything(boolean tick, CallbackInfo ci) { float delta = this.paused ? this.pausedTickDelta : this.renderTickCounter.tickDelta; - Hibiscus.bus().fire(new PostRenderAllEvent(delta)); + if (!ImGuiRenderer.INSTANCE.getStalled()) + Hibiscus.bus().fire(new PostRenderAllEvent(delta)); + ImGuiRenderer.INSTANCE.finishFrame(delta); } diff --git a/src/main/java/codes/som/hibiscus/mixins/xray/MixinLightDataAccess.java b/src/main/java/codes/som/hibiscus/mixins/xray/MixinLightDataAccess.java index 82fa409..5175847 100644 --- a/src/main/java/codes/som/hibiscus/mixins/xray/MixinLightDataAccess.java +++ b/src/main/java/codes/som/hibiscus/mixins/xray/MixinLightDataAccess.java @@ -9,23 +9,36 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockRenderView; import net.minecraft.world.BlockView; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Redirect; @Mixin(LightDataAccess.class) public abstract class MixinLightDataAccess { + @Shadow + public static long packLM(int lm) { + return 0; + } + @Redirect(method = "compute", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;getAmbientOcclusionLightLevel(Lnet/minecraft/world/BlockView;Lnet/minecraft/util/math/BlockPos;)F")) private float getAOLevel(BlockState instance, BlockView blockView, BlockPos blockPos) { - if (XraySystem.shouldRenderXray() || FullbrightSystem.shouldRenderFullbright()) + if (XraySystem.shouldRenderXray()) return 1f; return instance.getAmbientOcclusionLightLevel(blockView, blockPos); } @Redirect(method = "compute", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;getLightmapCoordinates(Lnet/minecraft/world/BlockRenderView;Lnet/minecraft/block/BlockState;Lnet/minecraft/util/math/BlockPos;)I")) - private int getLMCoords(BlockRenderView world, BlockState state, BlockPos pos) { - if (XraySystem.shouldRenderXray() || FullbrightSystem.shouldRenderFullbright()) + private int getLMCoords1(BlockRenderView world, BlockState state, BlockPos pos) { + if (FullbrightSystem.shouldRenderFullbright()) return 15728832; return WorldRenderer.getLightmapCoordinates(world, state, pos); } + + @Redirect(method = "compute", at = @At(value = "INVOKE", target = "Lme/jellysquid/mods/sodium/client/model/light/data/LightDataAccess;packLM(I)J"), remap = false) + private long getLMCoords2(int lm) { + if (XraySystem.shouldRenderXray()) + return packLM(15728832); + return packLM(lm); + } } diff --git a/src/main/kotlin/codes/som/hibiscus/api/event/TypedListener.kt b/src/main/kotlin/codes/som/hibiscus/api/event/TypedListener.kt index 3470ed7..f73dbd3 100644 --- a/src/main/kotlin/codes/som/hibiscus/api/event/TypedListener.kt +++ b/src/main/kotlin/codes/som/hibiscus/api/event/TypedListener.kt @@ -2,12 +2,15 @@ package codes.som.hibiscus.api.event -abstract class TypedListener(val eventType: Class) : Listener +abstract class TypedListener( + val eventType: Class, + val phase: EventPhase = EventPhase.NORMAL +) : Listener inline fun EventBus.registerTyped(typedListener: TypedListener) { - register(typedListener.eventType, typedListener) + register(typedListener.eventType, typedListener, typedListener.phase) } inline fun EventBus.unregisterTyped(typedListener: TypedListener) { - unregister(typedListener.eventType, typedListener) + unregister(typedListener.eventType, typedListener, typedListener.phase) } diff --git a/src/main/kotlin/codes/som/hibiscus/api/feature/Feature.kt b/src/main/kotlin/codes/som/hibiscus/api/feature/Feature.kt index aa2a190..1dba2b8 100644 --- a/src/main/kotlin/codes/som/hibiscus/api/feature/Feature.kt +++ b/src/main/kotlin/codes/som/hibiscus/api/feature/Feature.kt @@ -8,8 +8,16 @@ import codes.som.hibiscus.api.feature.values.ValueRegistry abstract class Feature(val name: String, val category: FeatureCategory) { private val listeners = mutableListOf>() - protected inline fun on(listener: Listener) = - on(object : TypedListener(T::class.java), Listener by listener {}) + protected inline fun on( + crossinline cond: () -> Boolean = { true }, + phase: EventPhase = EventPhase.NORMAL, + listener: Listener + ) = + on(object : TypedListener(T::class.java, phase) { + override fun on(event: T) { + if (cond()) listener.on(event) + } + }) protected fun on(listener: TypedListener) = listeners.add(listener) diff --git a/src/main/kotlin/codes/som/hibiscus/api/feature/values/ValueRegistry.kt b/src/main/kotlin/codes/som/hibiscus/api/feature/values/ValueRegistry.kt index 6464635..ae37f6d 100644 --- a/src/main/kotlin/codes/som/hibiscus/api/feature/values/ValueRegistry.kt +++ b/src/main/kotlin/codes/som/hibiscus/api/feature/values/ValueRegistry.kt @@ -28,10 +28,10 @@ class ValueRegistry { FloatValue(name, default, min, max).also(this::register) fun > enum(name: String, default: E) = - EnumValue(name, default) + EnumValue(name, default).also(this::register) fun > optionalEnum(name: String, type: Class, default: E?) = - OptionalEnumValue(name, type, default) + OptionalEnumValue(name, type, default).also(this::register) inline fun > optionalEnum(name: String, default: E?) = optionalEnum(name, E::class.java, default) diff --git a/src/main/kotlin/codes/som/hibiscus/events/PlayerEvents.kt b/src/main/kotlin/codes/som/hibiscus/events/PlayerEvents.kt index 59bc30b..065ed01 100644 --- a/src/main/kotlin/codes/som/hibiscus/events/PlayerEvents.kt +++ b/src/main/kotlin/codes/som/hibiscus/events/PlayerEvents.kt @@ -8,3 +8,4 @@ object PlayerPreTickEvent : Event object PlayerTickEvent : Event class SendChatEvent(val message: String) : Cancellable(), Event data class MovePlayerEvent(var x: Double, var y: Double, var z: Double, val movementType: MovementType) : Event +object PlayerInputTickEvent : Event diff --git a/src/main/kotlin/codes/som/hibiscus/events/RenderEvents.kt b/src/main/kotlin/codes/som/hibiscus/events/RenderEvents.kt index f751644..0ae83ee 100644 --- a/src/main/kotlin/codes/som/hibiscus/events/RenderEvents.kt +++ b/src/main/kotlin/codes/som/hibiscus/events/RenderEvents.kt @@ -19,3 +19,5 @@ class PostRenderEntitiesEvent(val delta: Float) : Event class PostRenderWorldEvent(val delta: Float, val camera: Camera, val matrices: MatrixStack) : Event class RenderHandEvent(val delta: Float) : Cancellable(), Event + +class RenderFogEvent() : Cancellable(), Event diff --git a/src/main/kotlin/codes/som/hibiscus/features/FeaturesRegistry.kt b/src/main/kotlin/codes/som/hibiscus/features/FeaturesRegistry.kt index 0301b96..7dcdad8 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/FeaturesRegistry.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/FeaturesRegistry.kt @@ -12,6 +12,7 @@ import codes.som.hibiscus.features.player.NoSprintingPacket import codes.som.hibiscus.features.player.Nuker import codes.som.hibiscus.features.visual.Freecam import codes.som.hibiscus.features.visual.Fullbright +import codes.som.hibiscus.features.visual.NoFog import codes.som.hibiscus.features.visual.Xray import codes.som.hibiscus.util.Resettable @@ -29,6 +30,7 @@ fun FEATURE_CONSTRUCTORS(): Array<() -> Feature> = arrayOf( ::Xray, ::Nuker, ::Fullbright, + ::NoFog, ) class FeaturesRegistry : Resettable { @@ -47,7 +49,7 @@ class FeaturesRegistry : Resettable { getAllFeatures().first { it.javaClass == type } as T private fun registerFeatures() { - features.addAll(FEATURE_CONSTRUCTORS().map { it() }) + features.addAll(FEATURE_CONSTRUCTORS().map { it() }.sortedBy { it.name }) } override fun reset() { diff --git a/src/main/kotlin/codes/som/hibiscus/features/exploits/AntiGhost.kt b/src/main/kotlin/codes/som/hibiscus/features/exploits/AntiGhost.kt index ed778c5..289d83d 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/exploits/AntiGhost.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/exploits/AntiGhost.kt @@ -17,10 +17,10 @@ class AntiGhost : Feature("Anti Ghost", FeatureCategory.EXPLOITS) { if (player.health <= 0) { player.deathTime = -1 - + requireExtension(player) player.setRemovalReason(null) - + player.hurtTime = Int.MAX_VALUE player.prevHeadYaw = player.prevYaw diff --git a/src/main/kotlin/codes/som/hibiscus/features/exploits/Ghost.kt b/src/main/kotlin/codes/som/hibiscus/features/exploits/Ghost.kt index 9213c04..578cfc6 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/exploits/Ghost.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/exploits/Ghost.kt @@ -14,7 +14,7 @@ import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket class Ghost : Feature("Ghost", FeatureCategory.EXPLOITS) { var dead = false - + init { on { _: PlayerTickEvent -> if (player.health <= 0) { @@ -35,10 +35,10 @@ class Ghost : Feature("Ghost", FeatureCategory.EXPLOITS) { mc.setScreen(null) } } - + on { event: ReceivePacketEvent -> val (packet) = event - + if (packet is HealthUpdateS2CPacket) { if (packet.health <= 0) { event.cancel() @@ -53,7 +53,7 @@ class Ghost : Feature("Ghost", FeatureCategory.EXPLOITS) { // TODO: Render 0 health on the status bar when dead } - override fun createFeatureCommand() = super.createFeatureCommand().apply { + override fun createFeatureCommand() = super.createFeatureCommand().apply { branch("respawn") { player.requestRespawn() } diff --git a/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt b/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt index 72c781f..18fd1a5 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/movement/Flight.kt @@ -2,14 +2,14 @@ package codes.som.hibiscus.features.movement import codes.som.hibiscus.api.feature.Feature import codes.som.hibiscus.api.feature.FeatureCategory -import codes.som.hibiscus.events.NetworkMovingEvent -import codes.som.hibiscus.events.PlayerTickEvent -import codes.som.hibiscus.events.SendPacketEvent +import codes.som.hibiscus.events.* import codes.som.hibiscus.mc import codes.som.hibiscus.mixins.MixinExtUpdatePlayerAbilitiesC2SPacket import codes.som.hibiscus.player import codes.som.hibiscus.util.ext.requireExtension +import codes.som.hibiscus.util.math.constructMovementVectorFromKeyboard import codes.som.hibiscus.world +import net.minecraft.entity.MovementType import net.minecraft.network.packet.c2s.play.ClientCommandC2SPacket import net.minecraft.network.packet.c2s.play.UpdatePlayerAbilitiesC2SPacket import net.minecraft.util.shape.VoxelShape @@ -18,20 +18,38 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { private var flyKickCounter = 0 private var lockY = 0.0 + private val spoofAbilityPackets by values.bool("Spoof Outgoing Ability Packets", true) + private val vanillaKickBypass by values.bool("Vanilla Kick Bypass", true) + private val mode by values.enum("Mode", FlightMode.HARD) + init { - on { _: PlayerTickEvent -> + on(cond = { mode == FlightMode.VANILLA }) { _: PlayerTickEvent -> player.abilities.flying = true } - val spoofAbilityPackets by values.bool("Spoof Outgoing Ability Packets", true) - val vanillaKickBypass by values.bool("Vanilla Kick Bypass", true) - - on { event: SendPacketEvent -> - val (packet) = event - - if (!spoofAbilityPackets) + on(cond = { mode == FlightMode.HARD }) { event: MovePlayerEvent -> + if (event.movementType != MovementType.SELF) return@on + val movement = + constructMovementVectorFromKeyboard(player.yaw) + .multiply(if (player.isSprinting) 1.5 else 0.75) + .multiply(1.0, 0.75, 1.0) + + event.x = movement.x + event.y = movement.y + event.z = movement.z + + player.velocity = movement.multiply(0.25, 0.25, 0.25) + } + + on(cond = { mode == FlightMode.HARD }) { _: PlayerInputTickEvent -> + player.input.sneaking = false + } + + on(cond = { spoofAbilityPackets }) { event: SendPacketEvent -> + val (packet) = event + if (packet is UpdatePlayerAbilitiesC2SPacket) { requireExtension(packet) packet.setFlying(player.abilities.allowFlying) @@ -44,10 +62,7 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { } } - on { event: NetworkMovingEvent -> - if (!vanillaKickBypass) - return@on - + on(cond = { vanillaKickBypass }) { event: NetworkMovingEvent -> flyKickCounter++ if (flyKickCounter >= 16) { @@ -83,4 +98,12 @@ class Flight : Feature("Flight", FeatureCategory.MOVEMENT) { super.createFeatureCommand().apply { alias("fly") } + + enum class FlightMode { + VANILLA, HARD; + + override fun toString(): String { + return name[0] + name.substring(1).lowercase() + } + } } diff --git a/src/main/kotlin/codes/som/hibiscus/features/movement/Speed.kt b/src/main/kotlin/codes/som/hibiscus/features/movement/Speed.kt index 0cdecf9..b2b8cc5 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/movement/Speed.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/movement/Speed.kt @@ -1,5 +1,6 @@ package codes.som.hibiscus.features.movement +import codes.som.hibiscus.api.event.EventPhase import codes.som.hibiscus.api.feature.Feature import codes.som.hibiscus.api.feature.FeatureCategory import codes.som.hibiscus.events.MovePlayerEvent @@ -9,7 +10,7 @@ class Speed : Feature("Speed", FeatureCategory.MOVEMENT) { init { val speed by values.float("Speed", 2f, 0.05f, 10f) - on { event: MovePlayerEvent -> + on(phase = EventPhase.AFTER) { event: MovePlayerEvent -> if (event.movementType == MovementType.SELF) { event.x *= speed event.z *= speed diff --git a/src/main/kotlin/codes/som/hibiscus/features/visual/Freecam.kt b/src/main/kotlin/codes/som/hibiscus/features/visual/Freecam.kt index a5f2142..b38ec70 100644 --- a/src/main/kotlin/codes/som/hibiscus/features/visual/Freecam.kt +++ b/src/main/kotlin/codes/som/hibiscus/features/visual/Freecam.kt @@ -9,6 +9,7 @@ import codes.som.hibiscus.mixins.MixinExtPlayerInteractEntityC2SPacket import codes.som.hibiscus.player import codes.som.hibiscus.util.ext.requireExtension import codes.som.hibiscus.util.graphics.MinecraftRenderPipelineProgress +import codes.som.hibiscus.util.math.constructMovementVectorFromKeyboard import codes.som.hibiscus.world import net.minecraft.client.input.Input import net.minecraft.client.network.ClientPlayerEntity @@ -18,8 +19,6 @@ import net.minecraft.entity.EntityType import net.minecraft.entity.MovementType import net.minecraft.nbt.NbtCompound import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket -import net.minecraft.util.math.MathHelper -import net.minecraft.util.math.Vec3d import net.minecraft.world.World import org.lwjgl.glfw.GLFW.GLFW_KEY_TAB import org.lwjgl.glfw.GLFW.GLFW_PRESS @@ -78,30 +77,10 @@ class Freecam : Feature("Freecam", FeatureCategory.VISUAL) { } if (!isControllingPlayer) { - val yaw = MathHelper.RADIANS_PER_DEGREE * view.yaw - val lookVec = Vec3d(-MathHelper.sin(yaw).toDouble(), 0.0, MathHelper.cos(yaw).toDouble()) - var movement = Vec3d.ZERO - if (mc.options.forwardKey.isPressed) - movement = movement.add(0.0, 0.0, 1.0) - if (mc.options.backKey.isPressed) - movement = movement.add(0.0, 0.0, -1.0) - if (mc.options.rightKey.isPressed) - movement = movement.add(1.0, 0.0, 0.0) - if (mc.options.leftKey.isPressed) - movement = movement.add(-1.0, 0.0, 0.0) - if (mc.options.jumpKey.isPressed) - movement = movement.add(0.0, 1.0, 0.0) - if (mc.options.sneakKey.isPressed) - movement = movement.add(0.0, -1.0, 0.0) - - // one day i will learn the matrix math for this - movement = lookVec - .multiply(movement.z) - .add(lookVec.rotateY(-MathHelper.HALF_PI).multiply(movement.x)) - .add(0.0, movement.y, 0.0) + val movement = constructMovementVectorFromKeyboard(view.yaw) .multiply(speed.toDouble()) - - view.move(MovementType.SELF, movement) // Update entity positional state properly by calling move() + // Update entity positional state properly by calling move() + view.move(MovementType.SELF, movement) } } diff --git a/src/main/kotlin/codes/som/hibiscus/features/visual/NoFog.kt b/src/main/kotlin/codes/som/hibiscus/features/visual/NoFog.kt new file mode 100644 index 0000000..a7e89f2 --- /dev/null +++ b/src/main/kotlin/codes/som/hibiscus/features/visual/NoFog.kt @@ -0,0 +1,15 @@ +package codes.som.hibiscus.features.visual + +import codes.som.hibiscus.api.feature.Feature +import codes.som.hibiscus.api.feature.FeatureCategory +import codes.som.hibiscus.events.RenderFogEvent + +class NoFog : Feature("No Fog", FeatureCategory.VISUAL) { + init { + on { event: RenderFogEvent -> + event.cancel() + } + + enabled = true + } +} diff --git a/src/main/kotlin/codes/som/hibiscus/gui/ImGuiRenderer.kt b/src/main/kotlin/codes/som/hibiscus/gui/ImGuiRenderer.kt index 507ec74..e1954cb 100644 --- a/src/main/kotlin/codes/som/hibiscus/gui/ImGuiRenderer.kt +++ b/src/main/kotlin/codes/som/hibiscus/gui/ImGuiRenderer.kt @@ -11,6 +11,9 @@ object ImGuiRenderer { private val imGuiGlfw = ImGuiImplGlfw() private val imGuiGl3 = ImGuiImplGl3() + private var didRender = true + var stalled = false + fun setup() { ImGui.createContext() @@ -29,8 +32,15 @@ object ImGuiRenderer { } fun beginFrame(delta: Float) { - imGuiGlfw.newFrame() - ImGui.newFrame() + if (didRender) { + imGuiGlfw.newFrame() + ImGui.newFrame() + didRender = false + } else { + // If we run into an exception while the game is running (causing finishFrame() to not get hit), + // stall ImGui so that we have time to spit out a stack trace instead of crashing on an ImGui assert + stalled = true + } } fun finishFrame(delta: Float) { @@ -43,5 +53,6 @@ object ImGuiRenderer { ImGui.renderPlatformWindowsDefault() GLFW.glfwMakeContextCurrent(backupWindowPtr) } + didRender = true } } diff --git a/src/main/kotlin/codes/som/hibiscus/util/math/MovementVector.kt b/src/main/kotlin/codes/som/hibiscus/util/math/MovementVector.kt new file mode 100644 index 0000000..32ddaa8 --- /dev/null +++ b/src/main/kotlin/codes/som/hibiscus/util/math/MovementVector.kt @@ -0,0 +1,32 @@ +package codes.som.hibiscus.util.math + +import codes.som.hibiscus.mc +import net.minecraft.util.math.MathHelper +import net.minecraft.util.math.Vec3d + + +fun constructMovementVectorFromKeyboard(yawDeg: Float): Vec3d { + val yaw = MathHelper.RADIANS_PER_DEGREE * yawDeg + val lookVec = Vec3d(-MathHelper.sin(yaw).toDouble(), 0.0, MathHelper.cos(yaw).toDouble()) + + var movement = Vec3d.ZERO + if (mc.options.forwardKey.isPressed) + movement = movement.add(0.0, 0.0, 1.0) + if (mc.options.backKey.isPressed) + movement = movement.add(0.0, 0.0, -1.0) + if (mc.options.rightKey.isPressed) + movement = movement.add(1.0, 0.0, 0.0) + if (mc.options.leftKey.isPressed) + movement = movement.add(-1.0, 0.0, 0.0) + if (mc.options.jumpKey.isPressed) + movement = movement.add(0.0, 1.0, 0.0) + if (mc.options.sneakKey.isPressed) + movement = movement.add(0.0, -1.0, 0.0) + + movement = lookVec + .multiply(movement.z) + .add(lookVec.rotateY(-MathHelper.HALF_PI).multiply(movement.x)) + .add(0.0, movement.y, 0.0) + + return movement +} diff --git a/src/main/resources/hibiscus.mixins.json b/src/main/resources/hibiscus.mixins.json index cd17ac0..14f1ef8 100644 --- a/src/main/resources/hibiscus.mixins.json +++ b/src/main/resources/hibiscus.mixins.json @@ -6,6 +6,7 @@ "defaultRequire": 1 }, "mixins": [ + "MixinBackgroundRenderer", "MixinClientConnection", "MixinClientPlayerEntity", "MixinClientPlayNetworkHandler",