No Fog, 'Hard' mode for Flight, failsafe for ImGui
This commit is contained in:
parent
ea9d543d32
commit
e75052edea
19 changed files with 186 additions and 65 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
|
||||
package codes.som.hibiscus.api.event
|
||||
|
||||
abstract class TypedListener<T : Event>(val eventType: Class<T>) : Listener<T>
|
||||
abstract class TypedListener<T : Event>(
|
||||
val eventType: Class<T>,
|
||||
val phase: EventPhase = EventPhase.NORMAL
|
||||
) : Listener<T>
|
||||
|
||||
inline fun <T : Event> EventBus.registerTyped(typedListener: TypedListener<T>) {
|
||||
register(typedListener.eventType, typedListener)
|
||||
register(typedListener.eventType, typedListener, typedListener.phase)
|
||||
}
|
||||
|
||||
inline fun <T : Event> EventBus.unregisterTyped(typedListener: TypedListener<T>) {
|
||||
unregister(typedListener.eventType, typedListener)
|
||||
unregister(typedListener.eventType, typedListener, typedListener.phase)
|
||||
}
|
||||
|
|
|
@ -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<TypedListener<*>>()
|
||||
|
||||
protected inline fun <reified T : Event> on(listener: Listener<T>) =
|
||||
on(object : TypedListener<T>(T::class.java), Listener<T> by listener {})
|
||||
protected inline fun <reified T : Event> on(
|
||||
crossinline cond: () -> Boolean = { true },
|
||||
phase: EventPhase = EventPhase.NORMAL,
|
||||
listener: Listener<T>
|
||||
) =
|
||||
on(object : TypedListener<T>(T::class.java, phase) {
|
||||
override fun on(event: T) {
|
||||
if (cond()) listener.on(event)
|
||||
}
|
||||
})
|
||||
|
||||
protected fun <T : Event> on(listener: TypedListener<T>) =
|
||||
listeners.add(listener)
|
||||
|
|
|
@ -28,10 +28,10 @@ class ValueRegistry {
|
|||
FloatValue(name, default, min, max).also(this::register)
|
||||
|
||||
fun <E : Enum<E>> enum(name: String, default: E) =
|
||||
EnumValue(name, default)
|
||||
EnumValue(name, default).also(this::register)
|
||||
|
||||
fun <E : Enum<E>> optionalEnum(name: String, type: Class<E>, default: E?) =
|
||||
OptionalEnumValue(name, type, default)
|
||||
OptionalEnumValue(name, type, default).also(this::register)
|
||||
|
||||
inline fun <reified E : Enum<E>> optionalEnum(name: String, default: E?) =
|
||||
optionalEnum(name, E::class.java, default)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -17,10 +17,10 @@ class AntiGhost : Feature("Anti Ghost", FeatureCategory.EXPLOITS) {
|
|||
|
||||
if (player.health <= 0) {
|
||||
player.deathTime = -1
|
||||
|
||||
|
||||
requireExtension<MixinExtEntity>(player)
|
||||
player.setRemovalReason(null)
|
||||
|
||||
|
||||
player.hurtTime = Int.MAX_VALUE
|
||||
|
||||
player.prevHeadYaw = player.prevYaw
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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<MixinExtUpdatePlayerAbilitiesC2SPacket>(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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
src/main/kotlin/codes/som/hibiscus/features/visual/NoFog.kt
Normal file
15
src/main/kotlin/codes/som/hibiscus/features/visual/NoFog.kt
Normal file
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
"defaultRequire": 1
|
||||
},
|
||||
"mixins": [
|
||||
"MixinBackgroundRenderer",
|
||||
"MixinClientConnection",
|
||||
"MixinClientPlayerEntity",
|
||||
"MixinClientPlayNetworkHandler",
|
||||
|
|
Loading…
Reference in a new issue