150 lines
5.1 KiB
Kotlin
150 lines
5.1 KiB
Kotlin
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.*
|
|
import codes.som.hibiscus.mc
|
|
import codes.som.hibiscus.mixins.MixinExtUpdatePlayerAbilitiesC2SPacket
|
|
import codes.som.hibiscus.player
|
|
import codes.som.hibiscus.subsystems.tps.TPSDetectionSubsystem
|
|
import codes.som.hibiscus.util.ext.requireExtension
|
|
import codes.som.hibiscus.util.math.calcMoveVec
|
|
import codes.som.hibiscus.util.math.getMoveInputVecFromPlayerInput
|
|
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.math.Vec3d
|
|
import net.minecraft.util.shape.VoxelShape
|
|
|
|
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)
|
|
private val speed by values.float("Speed", 1.0f, 0.01f, 50.0f)
|
|
|
|
init {
|
|
on(cond = { mode == FlightMode.VANILLA }) { _: PlayerTickEvent ->
|
|
player.abilities.flying = true
|
|
player.abilities.flySpeed = speed * 0.05f
|
|
}
|
|
|
|
on(cond = { mode == FlightMode.HARD }) { event: MovePlayerEvent ->
|
|
if (event.movementType != MovementType.SELF)
|
|
return@on
|
|
|
|
val movement =
|
|
calcMoveVec(getMoveInputVecFromPlayerInput(player.input), player.yaw)
|
|
.multiply(if (player.isSprinting) 1.5 else 0.75)
|
|
.multiply(1.0, 0.75, 1.0)
|
|
.multiply(speed.toDouble())
|
|
// TODO: Some form of acceleration
|
|
|
|
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.VANILLA }) { _: PlayerInputTickEvent ->
|
|
// player.input.sneaking = false
|
|
}
|
|
|
|
var lastMoveTime: Long = -1
|
|
on(cond = { mode == FlightMode.MAXIMUM }, phase = EventPhase.AFTER) { event: MovePlayerEvent ->
|
|
if (event.movementType != MovementType.SELF)
|
|
return@on
|
|
|
|
var tpsMultiplier = TPSDetectionSubsystem.average().coerceAtMost(1.0)
|
|
if (tpsMultiplier < 1) {
|
|
tpsMultiplier = 1 - (1 - tpsMultiplier) * 4.0
|
|
}
|
|
|
|
val currTime = System.currentTimeMillis()
|
|
val movement =
|
|
if (lastMoveTime == -1L || currTime - lastMoveTime >= (1000.0 / 21.0) * tpsMultiplier) {
|
|
calcMoveVec(getMoveInputVecFromPlayerInput(player.input), player.yaw)
|
|
.normalize()
|
|
.multiply(speed.toDouble() * (10.0 - 1 / 8))
|
|
.multiply(1.0, 0.5, 1.0)
|
|
} else {
|
|
Vec3d.ZERO
|
|
}
|
|
|
|
if (movement != Vec3d.ZERO)
|
|
lastMoveTime = currTime
|
|
|
|
event.x = movement.x
|
|
event.y = movement.y
|
|
event.z = movement.z
|
|
|
|
player.velocity = Vec3d.ZERO
|
|
}
|
|
|
|
on(cond = { spoofAbilityPackets }) { event: SendPacketEvent ->
|
|
val (packet) = event
|
|
|
|
if (packet is UpdatePlayerAbilitiesC2SPacket) {
|
|
requireExtension<MixinExtUpdatePlayerAbilitiesC2SPacket>(packet)
|
|
packet.setFlying(player.abilities.allowFlying)
|
|
}
|
|
|
|
if (packet is ClientCommandC2SPacket) {
|
|
if (packet.mode == ClientCommandC2SPacket.Mode.PRESS_SHIFT_KEY) {
|
|
event.cancel()
|
|
}
|
|
}
|
|
}
|
|
|
|
on(cond = { vanillaKickBypass }) { event: NetworkMovingEvent ->
|
|
flyKickCounter++
|
|
|
|
if (flyKickCounter >= 16) {
|
|
if (flyKickCounter == 16)
|
|
lockY = event.y - 0.0625
|
|
|
|
val playerNotColliding = world.getBlockCollisions(
|
|
null, player.boundingBox
|
|
.offset(0.0, lockY - player.y, 0.0)
|
|
.expand(0.0625)
|
|
.stretch(0.0, -0.55, 0.0)
|
|
).all(VoxelShape::isEmpty)
|
|
|
|
if (playerNotColliding)
|
|
event.y = lockY
|
|
}
|
|
|
|
if (flyKickCounter >= 24)
|
|
flyKickCounter = 0
|
|
}
|
|
}
|
|
|
|
override fun onEnable() {
|
|
if (mc.player != null)
|
|
lockY = player.y - 0.03126
|
|
}
|
|
|
|
override fun onDisable() {
|
|
player.abilities.flying = false
|
|
player.abilities.flySpeed = 0.05f
|
|
}
|
|
|
|
override fun createFeatureCommand() =
|
|
super.createFeatureCommand().apply {
|
|
alias("fly")
|
|
}
|
|
|
|
enum class FlightMode {
|
|
VANILLA, HARD, MAXIMUM;
|
|
|
|
override fun toString(): String {
|
|
return name[0] + name.substring(1).lowercase()
|
|
}
|
|
}
|
|
}
|