mirror of
https://gitlab.bixilon.de/bixilon/pixlyzer-physics.git
synced 2025-09-23 12:26:15 -04:00
port to 1.17
This commit is contained in:
parent
bc097213c0
commit
78fdfb7490
@ -6,13 +6,15 @@ import de.bixilon.pixlyzer.EntitySpawner.setDimension
|
|||||||
import de.bixilon.pixlyzer.physics.abstractions.MinecraftPlayer
|
import de.bixilon.pixlyzer.physics.abstractions.MinecraftPlayer
|
||||||
import de.bixilon.pixlyzer.physics.abstractions.MinecraftWorld
|
import de.bixilon.pixlyzer.physics.abstractions.MinecraftWorld
|
||||||
import de.bixilon.pixlyzer.physics.input.DummyBinding
|
import de.bixilon.pixlyzer.physics.input.DummyBinding
|
||||||
|
import de.bixilon.pixlyzer.util.ReflectionUtil.getClass
|
||||||
|
import de.bixilon.pixlyzer.util.ReflectionUtil.getField
|
||||||
import net.minecraft.client.MinecraftClient
|
import net.minecraft.client.MinecraftClient
|
||||||
import net.minecraft.client.input.Input
|
import net.minecraft.client.input.Input
|
||||||
|
import net.minecraft.client.network.AbstractClientPlayerEntity
|
||||||
import net.minecraft.client.network.ClientPlayNetworkHandler
|
import net.minecraft.client.network.ClientPlayNetworkHandler
|
||||||
import net.minecraft.client.network.ClientPlayerEntity
|
import net.minecraft.client.network.ClientPlayerEntity
|
||||||
import net.minecraft.client.network.PlayerListEntry
|
import net.minecraft.client.network.PlayerListEntry
|
||||||
import net.minecraft.client.option.GameOptions
|
import net.minecraft.client.option.GameOptions
|
||||||
import net.minecraft.client.option.SimpleOption
|
|
||||||
import net.minecraft.client.recipebook.ClientRecipeBook
|
import net.minecraft.client.recipebook.ClientRecipeBook
|
||||||
import net.minecraft.client.tutorial.TutorialManager
|
import net.minecraft.client.tutorial.TutorialManager
|
||||||
import net.minecraft.client.world.ClientChunkManager
|
import net.minecraft.client.world.ClientChunkManager
|
||||||
@ -32,10 +34,24 @@ import net.minecraft.world.biome.source.BiomeAccess
|
|||||||
import net.minecraft.world.border.WorldBorder
|
import net.minecraft.world.border.WorldBorder
|
||||||
import org.objenesis.ObjenesisStd
|
import org.objenesis.ObjenesisStd
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
|
|
||||||
object PhysicsUtil {
|
object PhysicsUtil {
|
||||||
private val OBJENESIS = ObjenesisStd()
|
private val OBJENESIS = ObjenesisStd()
|
||||||
|
private val SIMPLE_OPTION = getClass("net.minecraft.client.option.SimpleOption")
|
||||||
|
private val SIMPLE_OPTION_BOOLEAN = SIMPLE_OPTION?.getMethod("ofBoolean", String::class.java, Boolean::class.java)?.apply { isAccessible = true }
|
||||||
|
private val PLAYER_ENTRY = getField(AbstractClientPlayerEntity::class.java, "playerListEntry") ?: getField(ClientPlayerEntity::class.java, "playerListEntry", "cachedScoreboardEntry")
|
||||||
|
|
||||||
|
private val PROFILE_KEYS = getClass("net.minecraft.client.util.ProfileKeys")
|
||||||
|
private val PROFILE_KEYS_KEY_FUTURE = getField(PROFILE_KEYS, "keyFuture")
|
||||||
|
|
||||||
|
|
||||||
|
private val CLIENT_KEYS = getField(MinecraftClient::class.java, "profileKeys")
|
||||||
|
|
||||||
|
private val SPRINT_KEY = getField(GameOptions::class.java, "sprintKey", "sprintToggle", "keySprint")
|
||||||
|
|
||||||
|
private val REGISTRY_ENTRY = "net.minecraft.util.registry.RegistryEntry"
|
||||||
|
|
||||||
fun createChunkManager(native: ClientWorld): ClientChunkManager {
|
fun createChunkManager(native: ClientWorld): ClientChunkManager {
|
||||||
val chunkManager = OBJENESIS.newInstance(ClientChunkManager::class.java)
|
val chunkManager = OBJENESIS.newInstance(ClientChunkManager::class.java)
|
||||||
@ -62,6 +78,7 @@ object PhysicsUtil {
|
|||||||
native.entityManager = ClientEntityManager(Entity::class.java, native.ClientEntityHandler())
|
native.entityManager = ClientEntityManager(Entity::class.java, native.ClientEntityHandler())
|
||||||
|
|
||||||
native.biomeAccess = BiomeAccess(BiomeAccess.Storage { biomeX, biomeY, biomeZ -> return@Storage RegistryEntry.Direct<Biome>(null) }, 0L)
|
native.biomeAccess = BiomeAccess(BiomeAccess.Storage { biomeX, biomeY, biomeZ -> return@Storage RegistryEntry.Direct<Biome>(null) }, 0L)
|
||||||
|
//native.biomeAccess = BiomeAccess(BiomeAccess.Storage { biomeX, biomeY, biomeZ -> return@Storage null }, 0L, BiomeAccessType {_,_,_,_,_->null})
|
||||||
|
|
||||||
return MinecraftWorld(native)
|
return MinecraftWorld(native)
|
||||||
}
|
}
|
||||||
@ -71,16 +88,37 @@ object PhysicsUtil {
|
|||||||
handler.profile = GameProfile(UUID(1L, 1L), "physics")
|
handler.profile = GameProfile(UUID(1L, 1L), "physics")
|
||||||
handler.client = client
|
handler.client = client
|
||||||
handler.connection = ClientConnection(NetworkSide.CLIENTBOUND)
|
handler.connection = ClientConnection(NetworkSide.CLIENTBOUND)
|
||||||
|
handler.playerListEntries = mapOf()
|
||||||
|
// handler.positionLookSetup = true
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setBooleanOption(options: GameOptions, name: String, value: Boolean) {
|
||||||
|
val field = options::class.java.getDeclaredField(name)
|
||||||
|
field.isAccessible = true
|
||||||
|
if (field.type.isPrimitive) {
|
||||||
|
field.setBoolean(options, value)
|
||||||
|
} else {
|
||||||
|
val option = SIMPLE_OPTION_BOOLEAN?.invoke(null, name, value)
|
||||||
|
field.set(options, option)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun createGameOptions(): GameOptions? {
|
private fun createGameOptions(): GameOptions? {
|
||||||
val options = OBJENESIS.newInstance(GameOptions::class.java)
|
val options = OBJENESIS.newInstance(GameOptions::class.java)
|
||||||
options.autoJump = SimpleOption.ofBoolean("", false)
|
setBooleanOption(options, "autoJump", false)
|
||||||
|
|
||||||
|
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createProfileKeys(): Any {
|
||||||
|
val instance = OBJENESIS.newInstance(PROFILE_KEYS)
|
||||||
|
PROFILE_KEYS_KEY_FUTURE?.set(instance, CompletableFuture.completedFuture<Any>(Optional.empty<Any>()))
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
private fun createMinecraftClient(): MinecraftClient {
|
private fun createMinecraftClient(): MinecraftClient {
|
||||||
val client = OBJENESIS.newInstance(MinecraftClient::class.java)
|
val client = OBJENESIS.newInstance(MinecraftClient::class.java)
|
||||||
|
|
||||||
@ -88,24 +126,32 @@ object PhysicsUtil {
|
|||||||
client.thread = Thread.currentThread()
|
client.thread = Thread.currentThread()
|
||||||
client.options = createGameOptions()
|
client.options = createGameOptions()
|
||||||
client.tutorialManager = TutorialManager(client, client.options)
|
client.tutorialManager = TutorialManager(client, client.options)
|
||||||
client.options.sprintKey = DummyBinding()
|
CLIENT_KEYS?.set(client, createProfileKeys())
|
||||||
|
|
||||||
|
MinecraftClient.instance = client
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createPlayerListEntry(): PlayerListEntry {
|
||||||
|
return OBJENESIS.newInstance(PlayerListEntry::class.java)
|
||||||
|
}
|
||||||
|
|
||||||
fun createPlayer(world: MinecraftWorld): MinecraftPlayer {
|
fun createPlayer(world: MinecraftWorld): MinecraftPlayer {
|
||||||
val client = createMinecraftClient()
|
val client = createMinecraftClient()
|
||||||
val networkHandler = createNetworkHandler(client)
|
val networkHandler = createNetworkHandler(client)
|
||||||
val native = ClientPlayerEntity(client, world.level, networkHandler, StatHandler(), ClientRecipeBook(), false, false)
|
val native = ClientPlayerEntity(client, world.level, networkHandler, StatHandler(), ClientRecipeBook(), false, false)
|
||||||
|
|
||||||
client.player = native
|
client.player = native
|
||||||
native.playerListEntry = PlayerListEntry(networkHandler.profile, false)
|
PLAYER_ENTRY?.set(native, createPlayerListEntry())
|
||||||
native.input = Input()
|
native.input = Input()
|
||||||
native.shoulderEntityLeft = null
|
native.shoulderEntityLeft = null
|
||||||
native.shoulderEntityRight = null
|
native.shoulderEntityRight = null
|
||||||
|
|
||||||
client.cameraEntity = native
|
client.cameraEntity = native
|
||||||
|
|
||||||
return MinecraftPlayer(native)
|
val sprint = DummyBinding()
|
||||||
|
SPRINT_KEY?.set(client.options, sprint)
|
||||||
|
|
||||||
|
return MinecraftPlayer(native, sprint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,17 @@ package de.bixilon.pixlyzer.physics.abstractions
|
|||||||
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
import de.bixilon.kutil.cast.CastUtil.unsafeCast
|
||||||
import de.bixilon.pixlyzer.physics.input.CustomInput
|
import de.bixilon.pixlyzer.physics.input.CustomInput
|
||||||
import de.bixilon.pixlyzer.physics.input.DummyBinding
|
import de.bixilon.pixlyzer.physics.input.DummyBinding
|
||||||
|
import de.bixilon.pixlyzer.util.Util.nullCast
|
||||||
import net.minecraft.client.network.ClientPlayerEntity
|
import net.minecraft.client.network.ClientPlayerEntity
|
||||||
|
import net.minecraft.entity.Entity
|
||||||
|
import net.minecraft.entity.JumpingMount
|
||||||
import net.minecraft.network.Packet
|
import net.minecraft.network.Packet
|
||||||
import net.minecraft.network.listener.ClientPlayPacketListener
|
import net.minecraft.network.listener.ClientPlayPacketListener
|
||||||
import net.minecraft.util.math.Vec3d
|
import net.minecraft.util.math.Vec3d
|
||||||
|
|
||||||
class MinecraftPlayer(
|
class MinecraftPlayer(
|
||||||
val native: ClientPlayerEntity,
|
val native: ClientPlayerEntity,
|
||||||
|
private val sprint: DummyBinding,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun handlePacket(packet: Packet<ClientPlayPacketListener>) {
|
fun handlePacket(packet: Packet<ClientPlayPacketListener>) {
|
||||||
@ -43,7 +47,12 @@ class MinecraftPlayer(
|
|||||||
input.jumping = jump
|
input.jumping = jump
|
||||||
input.sneaking = sneak
|
input.sneaking = sneak
|
||||||
|
|
||||||
native.client.options.sprintKey.unsafeCast<DummyBinding>().value = sprint
|
this.sprint.value = sprint
|
||||||
native.input = input
|
native.input = input
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val jumpingMount: JumpingMount?
|
||||||
|
get() {
|
||||||
|
return native.vehicle?.nullCast()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,24 @@ package de.bixilon.pixlyzer.physics.input
|
|||||||
|
|
||||||
import net.minecraft.client.input.Input
|
import net.minecraft.client.input.Input
|
||||||
import net.minecraft.client.input.KeyboardInput
|
import net.minecraft.client.input.KeyboardInput
|
||||||
import net.minecraft.client.network.ClientPlayerEntity
|
|
||||||
|
|
||||||
class CustomInput : Input() {
|
class CustomInput : Input() {
|
||||||
|
|
||||||
override fun tick(slowDown: Boolean, multiplier: Float) {
|
override fun tick(slowDown: Boolean) {
|
||||||
movementForward = KeyboardInput.getMovementMultiplier(pressingForward, pressingBack)
|
tick(slowDown, 0.3f)
|
||||||
movementSideways = KeyboardInput.getMovementMultiplier(pressingLeft, pressingRight)
|
}
|
||||||
|
|
||||||
|
fun getMovementMultiplier(positive: Boolean, negative: Boolean): Float {
|
||||||
|
return if (positive == negative) {
|
||||||
|
0.0f
|
||||||
|
} else {
|
||||||
|
if (positive) 1.0f else -1.0f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun tick(slowDown: Boolean, multiplier: Float) {
|
||||||
|
movementForward = getMovementMultiplier(pressingForward, pressingBack)
|
||||||
|
movementSideways = getMovementMultiplier(pressingLeft, pressingRight)
|
||||||
if (slowDown) {
|
if (slowDown) {
|
||||||
movementSideways *= multiplier
|
movementSideways *= multiplier
|
||||||
movementForward *= multiplier
|
movementForward *= multiplier
|
||||||
|
@ -93,4 +93,20 @@ class GravityTest : AbstractTest() {
|
|||||||
player.tick(90)
|
player.tick(90)
|
||||||
storeBasic()
|
storeBasic()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PhysicsTest("positive_falling_37")
|
||||||
|
fun positiveFalling37() {
|
||||||
|
player.teleport(45.00, 178.0, 13.00)
|
||||||
|
player.setKeys(forwards = true, right = true)
|
||||||
|
player.tick(37)
|
||||||
|
storeBasic()
|
||||||
|
}
|
||||||
|
|
||||||
|
@PhysicsTest("negative_falling_124")
|
||||||
|
fun negativeFalling124() {
|
||||||
|
player.teleport(45.00, 178.0, 13.00)
|
||||||
|
player.setKeys(backwards = true, left = true)
|
||||||
|
player.tick(124)
|
||||||
|
storeBasic()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class PacketReceiveTest : AbstractTest() {
|
|||||||
val packet = createPacket(0.0, true, 0.0, true, 0.0, true, 0.0f, true, 0.0f, true, false)
|
val packet = createPacket(0.0, true, 0.0, true, 0.0, true, 0.0f, true, 0.0f, true, false)
|
||||||
player.handlePacket(packet)
|
player.handlePacket(packet)
|
||||||
storeBasic()
|
storeBasic()
|
||||||
result["mount"] = player.native.jumpingMount != null
|
result["mount"] = player.jumpingMount != null
|
||||||
}
|
}
|
||||||
|
|
||||||
@PhysicsTest("receive_relative")
|
@PhysicsTest("receive_relative")
|
||||||
@ -43,7 +43,7 @@ class PacketReceiveTest : AbstractTest() {
|
|||||||
|
|
||||||
player.handlePacket(packet)
|
player.handlePacket(packet)
|
||||||
storeBasic()
|
storeBasic()
|
||||||
result["mount"] = player.native.jumpingMount != null
|
result["mount"] = player.jumpingMount != null
|
||||||
}
|
}
|
||||||
|
|
||||||
@PhysicsTest("receive_absolute")
|
@PhysicsTest("receive_absolute")
|
||||||
@ -53,6 +53,6 @@ class PacketReceiveTest : AbstractTest() {
|
|||||||
|
|
||||||
player.handlePacket(packet)
|
player.handlePacket(packet)
|
||||||
storeBasic()
|
storeBasic()
|
||||||
result["mount"] = player.native.jumpingMount != null
|
result["mount"] = player.jumpingMount != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user