diff --git a/build.gradle.kts b/build.gradle.kts index 5624237..1c49252 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -17,5 +17,9 @@ allprojects { tasks.withType { kotlinOptions.jvmTarget = "14" kotlinOptions.freeCompilerArgs += "-progressive" + kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalStdlibApi" + kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalUnsignedTypes" + kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.time.ExperimentalTime" + kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.contracts.ExperimentalContracts" } } diff --git a/buildSrc/src/main/kotlin/space/uranos/mdsp/generator/EntitiesGenerator.kt b/buildSrc/src/main/kotlin/space/uranos/mdsp/generator/EntitiesGenerator.kt index 672adf4..501def4 100644 --- a/buildSrc/src/main/kotlin/space/uranos/mdsp/generator/EntitiesGenerator.kt +++ b/buildSrc/src/main/kotlin/space/uranos/mdsp/generator/EntitiesGenerator.kt @@ -19,37 +19,44 @@ class EntitiesGenerator( ) { fun generate() { val entitiesJson = workingDir.resolve("entities.json").readText() - val entities = JsonIterator.deserialize(entitiesJson).asList() + val types = JsonIterator.deserialize(entitiesJson).asList() - generateEntityStubs(entities) - generateEntitiesList(entities) + generateEntityTypes(types) + generateEntityStubs(types) + generateEntityTypeList(types) } - private val typeLines = listOf("%L", "%S", "%Lf", "%Lf") - - private fun generateEntityStubs(entities: List) { - for (entity in entities) { + private fun generateEntityTypes(types: List) { + for (entity in types) { val name = - CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, entity.get("name").toString())!! + "Entity" - - val filePathRelativeToSourceRoot = "./${BLOCK_PACKAGE.replace(".", "/")}/$name.kt" - if (sourcesDir.resolve(filePathRelativeToSourceRoot).exists()) continue - - val typeArgs = arrayOf( - entity.get("id").toInt(), - "minecraft:" + entity.get("name").toString(), - entity.get("width").toFloat(), - entity.get("height").toFloat() - ) + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, entity.get("name").toString())!! + "EntityType" val type = TypeSpec.classBuilder(name) - .superclass(ENTITY_TYPE) - .addType( - TypeSpec.companionObjectBuilder() - .addSuperinterface( - ENTITY_TYPE_TYPE.parameterizedBy(ClassName(ENTITY_PACKAGE, name)), - CodeBlock.of("type(\n${typeLines.joinToString(",\n") { " $it" }}\n)", *typeArgs) - ) + .addModifiers(KModifier.ABSTRACT) + .primaryConstructor(FunSpec.constructorBuilder().addModifiers(KModifier.INTERNAL).build()) + .addSuperinterface(ENTITY_TYPE_TYPE) + .addProperty( + PropertySpec + .builder("numericID", Int::class, KModifier.OVERRIDE) + .initializer("%L", entity.get("id").toInt()) + .build() + ) + .addProperty( + PropertySpec + .builder("id", String::class, KModifier.OVERRIDE) + .initializer("%S", "minecraft:" + entity.get("name").toString()) + .build() + ) + .addProperty( + PropertySpec + .builder("width", Float::class, KModifier.OVERRIDE) + .initializer("%Lf", entity.get("width").toFloat()) + .build() + ) + .addProperty( + PropertySpec + .builder("height", Float::class, KModifier.OVERRIDE) + .initializer("%Lf", entity.get("height").toFloat()) .build() ) .build() @@ -61,19 +68,48 @@ class EntitiesGenerator( } } - private fun generateEntitiesList(entities: List) { + private fun generateEntityStubs(types: List) { + for (entity in types) { + val name = + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, entity.get("name").toString())!! + "Entity" + + val filePathRelativeToSourceRoot = "./${BLOCK_PACKAGE.replace(".", "/")}/$name.kt" + if (sourcesDir.resolve(filePathRelativeToSourceRoot).exists()) continue + + val type = TypeSpec.classBuilder(name) + .superclass(ENTITY_TYPE) + .addProperty( + PropertySpec.builder("type", ENTITY_TYPE_TYPE, KModifier.OVERRIDE, KModifier.FINAL) + .initializer("Type") + .build() + ) + .addType( + TypeSpec.companionObjectBuilder("Type") + .superclass(ClassName(ENTITY_PACKAGE, name + "Type")) + .build() + ) + .build() + + FileSpec.builder(ENTITY_PACKAGE, name) + .addType(type) + .build() + .writeTo(outputDir) + } + } + + private fun generateEntityTypeList(entities: List) { val names = entities .map { it.get("name").toString() } .map { CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, it) + "Entity" } val property = PropertySpec.builder( - "GENERATED_ENTITIES", - List::class.asTypeName().parameterizedBy(ENTITY_TYPE_TYPE.parameterizedBy(STAR)) + "ENTITY_TYPES", + List::class.asTypeName().parameterizedBy(ENTITY_TYPE_TYPE) ) .initializer("listOf(\n${names.joinToString(",\n")}\n)") .build() - FileSpec.builder(ENTITY_PACKAGE, "Entities") + FileSpec.builder(ENTITY_PACKAGE, "EntityTypes") .addProperty(property) .build() .writeTo(outputDir) diff --git a/test-plugin/build.gradle.kts b/test-plugin/build.gradle.kts index 2e69237..603bdb0 100644 --- a/test-plugin/build.gradle.kts +++ b/test-plugin/build.gradle.kts @@ -15,10 +15,6 @@ dependencies { } tasks { - compileKotlin { - kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalUnsignedTypes" - } - shadowJar { archiveFileName.set("TestPlugin.jar") destinationDirectory.set(file("../serverData/plugins")) diff --git a/test-plugin/src/main/kotlin/space/uranos/testplugin/TestPlugin.kt b/test-plugin/src/main/kotlin/space/uranos/testplugin/TestPlugin.kt index cd5cc98..90843fa 100644 --- a/test-plugin/src/main/kotlin/space/uranos/testplugin/TestPlugin.kt +++ b/test-plugin/src/main/kotlin/space/uranos/testplugin/TestPlugin.kt @@ -5,6 +5,7 @@ package space.uranos.testplugin +import space.uranos.Position import space.uranos.Uranos import space.uranos.chat.TextComponent import space.uranos.net.ServerListInfo @@ -15,7 +16,6 @@ import space.uranos.plugin.Plugin import space.uranos.testplugin.anvil.AnvilWorld import space.uranos.world.Dimension import space.uranos.world.VoxelLocation -import space.uranos.world.WorldAndLocationWithRotation import space.uranos.world.block.CraftingTableBlock import space.uranos.world.block.GreenWoolBlock import space.uranos.world.block.RedWoolBlock @@ -46,10 +46,11 @@ class TestPlugin: Plugin("Test", "1.0.0") { event.gameMode = GameMode.CREATIVE event.canFly = true event.flying = true - event.initialWorldAndLocation = WorldAndLocationWithRotation( - world, - VoxelLocation.of(0, 2, 0).atTopCenter().withRotation(0f, 0f) - ) + event.initialWorldAndLocation = VoxelLocation + .of(0, 2, 0) + .atTopCenter() + .withRotation(0f, 0f) + .inside(world) } } } diff --git a/uranos-api/build.gradle.kts b/uranos-api/build.gradle.kts index 2a93ad6..3e0ace4 100644 --- a/uranos-api/build.gradle.kts +++ b/uranos-api/build.gradle.kts @@ -35,21 +35,9 @@ dependencies { kotlin { sourceSets["main"].kotlin.srcDir("src/main/generatedKotlin") - - sourceSets.all { - languageSettings.enableLanguageFeature("InlineClasses") - } } tasks { - compileKotlin { - kotlinOptions.freeCompilerArgs += listOf( - "-Xopt-in=kotlin.contracts.ExperimentalContracts", - "-Xopt-in=kotlin.ExperimentalUnsignedTypes", - "-Xopt-in=kotlin.RequiresOptIn" - ) - } - test { useJUnitPlatform() } diff --git a/uranos-api/src/main/kotlin/space/uranos/Location.kt b/uranos-api/src/main/kotlin/space/uranos/Location.kt new file mode 100644 index 0000000..89ae63a --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/Location.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos + +import space.uranos.world.VoxelLocation +import space.uranos.world.World +import kotlin.math.roundToInt + +/** + * Represents a combination of x, y and z coordinates. + */ +data class Location(val x: Double, val y: Double, val z: Double) { + /** + * Converts this Location to a VoxelLocation by converting [x], [y] and [z] to integers using [Double.toInt], + * in contrast to [roundToBlock] which uses [Double.roundToInt]. + */ + fun toVoxelLocation(): VoxelLocation = VoxelLocation(x.toInt(), y.toInt().toUByte(), z.toInt()) + + /** + * Converts this Location to a VoxelLocation by converting [x], [y] and [z] to integers using [Double.roundToInt], + * in contrast to [toVoxelLocation] which uses [Double.toInt]. + */ + fun roundToBlock(): VoxelLocation = VoxelLocation(x.roundToInt(), y.roundToInt().toUByte(), z.roundToInt()) + + fun withRotation(yaw: Float, pitch: Float) = Position(x, y, z, yaw, pitch) + fun asVector() = Vector(x, y, z) + + infix fun inside(world: World): Pair = world to this + + operator fun get(part: CoordinatePart): Double = when (part) { + CoordinatePart.X -> x + CoordinatePart.Y -> y + CoordinatePart.Z -> z + } +} diff --git a/uranos-api/src/main/kotlin/space/uranos/Position.kt b/uranos-api/src/main/kotlin/space/uranos/Position.kt new file mode 100644 index 0000000..7028905 --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/Position.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos + +import space.uranos.world.VoxelLocation +import space.uranos.world.World +import java.lang.IllegalArgumentException +import kotlin.math.roundToInt + +/** + * A combination of x, y and z coordinates and an orientation (yaw and pitch). + * + * @param yaw The yaw rotation in degrees. Must be in `[0; 360[`. + * @param pitch The pitch rotation as a value between -90 (up) and 90 (down). + */ +data class Position(val x: Double, val y: Double, val z: Double, val yaw: Float, val pitch: Float) { + init { + if (yaw >= 360) throw IllegalArgumentException("yaw must be lower than 360") + if (yaw < 0) throw IllegalArgumentException("yaw must not be negative") + } + + /** + * Converts this Position to a VoxelLocation by converting [x], [y] and [z] to integers using [Double.toInt], + * in contrast to [roundToBlock] which uses [Double.roundToInt]. + */ + fun toVoxelLocation(): VoxelLocation = VoxelLocation(x.toInt(), y.toInt().toUByte(), z.toInt()) + + /** + * Converts this Position to a VoxelLocation by converting [x], [y] and [z] to integers using [Double.roundToInt], + * in contrast to [toVoxelLocation] which uses [Double.toInt]. + */ + fun roundToBlock(): VoxelLocation = VoxelLocation(x.roundToInt(), y.roundToInt().toUByte(), z.roundToInt()) + + fun toLocation(): Location = Location(x, y, z) + fun toVector() = Vector(x, y, z) + infix fun inside(world: World): Pair = world to this + + val yawIn256Steps get() = ((yaw / 360) * 256).toInt().toUByte() + val pitchIn256Steps get() = ((yaw / 360) * 256).toInt().toUByte() + + operator fun get(part: CoordinatePart): Double = when (part) { + CoordinatePart.X -> x + CoordinatePart.Y -> y + CoordinatePart.Z -> z + } + + companion object { + val ZERO = Position(0.0, 0.0, 0.0, 0f, 0f) + } +} diff --git a/uranos-api/src/main/kotlin/space/uranos/Vector.kt b/uranos-api/src/main/kotlin/space/uranos/Vector.kt index 496bc6f..23840e4 100644 --- a/uranos-api/src/main/kotlin/space/uranos/Vector.kt +++ b/uranos-api/src/main/kotlin/space/uranos/Vector.kt @@ -6,7 +6,6 @@ package space.uranos import space.uranos.util.clamp -import space.uranos.world.Location import space.uranos.world.VoxelLocation import kotlin.math.abs import kotlin.math.pow @@ -51,6 +50,8 @@ data class Vector(val x: Double, val y: Double, val z: Double) { return sqrt(sqrt(x.pow(2) + y.pow(2)) + z.pow(2)) } + + val ZERO = Vector(0.0, 0.0, 0.0) } } diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/Entity.kt b/uranos-api/src/main/kotlin/space/uranos/entity/Entity.kt index 3f747d6..88fbc6d 100644 --- a/uranos-api/src/main/kotlin/space/uranos/entity/Entity.kt +++ b/uranos-api/src/main/kotlin/space/uranos/entity/Entity.kt @@ -5,24 +5,13 @@ package space.uranos.entity +import space.uranos.Location import java.util.* import kotlin.reflect.KClass abstract class Entity internal constructor() { val uuid: UUID = UUID.randomUUID() - companion object { - internal inline fun type( - numericID: Int, - id: String, - width: Float, - height: Float - ) : EntityType = object : EntityType { - override val entityClass: KClass = T::class - override val numericID: Int = numericID - override val id: String = id - override val width: Float = width - override val height: Float = height - } - } + abstract val type: EntityType + val globallyUniqueNumericID: Int = 0 // TODO: Get a real value } diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/EntityType.kt b/uranos-api/src/main/kotlin/space/uranos/entity/EntityType.kt index 4cfdea4..2069b2e 100644 --- a/uranos-api/src/main/kotlin/space/uranos/entity/EntityType.kt +++ b/uranos-api/src/main/kotlin/space/uranos/entity/EntityType.kt @@ -7,8 +7,7 @@ package space.uranos.entity import kotlin.reflect.KClass -interface EntityType { - val entityClass: KClass +interface EntityType { val numericID: Int val id: String val width: Float @@ -18,13 +17,7 @@ interface EntityType { /** * All entity types, sorted by their numeric ID in ascending order. */ - val all = GENERATED_ENTITIES - val byID = GENERATED_ENTITIES.map { it.id to it }.toMap() - - private val byClass = GENERATED_ENTITIES.map { it.entityClass to it }.toMap() - - @Suppress("UNCHECKED_CAST") - fun byClass(entityClass: KClass): EntityType? = byClass[entityClass] as EntityType? - inline fun byClass(): EntityType? = byClass(T::class) + val all = ENTITY_TYPES + val byID = ENTITY_TYPES.map { it.id to it }.toMap() } } diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/ItemEntity.kt b/uranos-api/src/main/kotlin/space/uranos/entity/ItemEntity.kt new file mode 100644 index 0000000..379b06e --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/entity/ItemEntity.kt @@ -0,0 +1,14 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.entity + +import space.uranos.Position + +class ItemEntity(override var position: Position) : ObjectEntity() { + override val type: EntityType = Type + + companion object Type : ItemEntityType() +} diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/LivingEntity.kt b/uranos-api/src/main/kotlin/space/uranos/entity/LivingEntity.kt new file mode 100644 index 0000000..e3be770 --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/entity/LivingEntity.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.entity + +import space.uranos.Position +import space.uranos.Vector + +abstract class LivingEntity : Entity(), Mobile { + abstract val headPitch: Float + abstract override val position: Position + abstract override val velocity: Vector +} diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/Mobile.kt b/uranos-api/src/main/kotlin/space/uranos/entity/Mobile.kt new file mode 100644 index 0000000..9b4b5e0 --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/entity/Mobile.kt @@ -0,0 +1,18 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.entity + +import space.uranos.Position +import space.uranos.Vector + +interface Mobile { + val position: Position + + /** + * The velocity in blocks per tick. + */ + val velocity: Vector +} diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/ObjectEntity.kt b/uranos-api/src/main/kotlin/space/uranos/entity/ObjectEntity.kt new file mode 100644 index 0000000..211adc8 --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/entity/ObjectEntity.kt @@ -0,0 +1,15 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.entity + +import space.uranos.Position +import space.uranos.Vector + +abstract class ObjectEntity : Entity(), Mobile { + abstract override var position: Position + + final override var velocity: Vector = Vector.ZERO +} diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/PaintingEntity.kt b/uranos-api/src/main/kotlin/space/uranos/entity/PaintingEntity.kt new file mode 100644 index 0000000..cf07c65 --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/entity/PaintingEntity.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.entity + +import space.uranos.CardinalDirection +import space.uranos.world.VoxelLocation + +class PaintingEntity( + val topLeftLocation: VoxelLocation, + val direction: CardinalDirection, + val motive: PaintingMotive +) : Entity() { + override val type: EntityType = Type + + + + companion object Type : PaintingEntityType() +} diff --git a/uranos-api/src/main/kotlin/space/uranos/entity/PaintingMotive.kt b/uranos-api/src/main/kotlin/space/uranos/entity/PaintingMotive.kt new file mode 100644 index 0000000..2a3a9e0 --- /dev/null +++ b/uranos-api/src/main/kotlin/space/uranos/entity/PaintingMotive.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.entity + +enum class PaintingMotive(val width: Int, val height: Int) { + // Order is important + KEBAB(1, 1), + AZTEC(1, 1), + ALBAN(1, 1), + AZTEC2(1, 1), + BOMB(1, 1), + PLANT(1, 1), + WASTELAND(1, 1), + POOL(2, 1), + COURBET(2, 1), + SEA(2, 1), + SUNSET(2, 1), + CREEBET(2, 1), + WANDERER(1, 2), + GRAHAM(1, 2), + MATCH(2, 2), + BUST(2, 2), + STAGE(2, 2), + VOID(2, 2), + SKULL_AND_ROSES(2, 2), + WITHER(2, 2), + FIGHTERS(4, 2), + POINTER(4, 4), + PIGSCENE(4, 4), + BURNING_SKULL(4, 4), + SKELETON(4, 3), + DONKEY_KONG(4, 3); + + val numericID = ordinal +} diff --git a/uranos-api/src/main/kotlin/space/uranos/net/Session.kt b/uranos-api/src/main/kotlin/space/uranos/net/Session.kt index 06a5d24..b6d41cc 100644 --- a/uranos-api/src/main/kotlin/space/uranos/net/Session.kt +++ b/uranos-api/src/main/kotlin/space/uranos/net/Session.kt @@ -6,13 +6,14 @@ package space.uranos.net import io.netty.buffer.ByteBuf +import space.uranos.Position import space.uranos.chat.TextComponent import space.uranos.event.EventBusWrapper import space.uranos.net.packet.OutgoingPacket import space.uranos.net.packet.Protocol import space.uranos.player.GameMode import space.uranos.player.Player -import space.uranos.world.WorldAndLocationWithRotation +import space.uranos.world.World import java.net.InetAddress import java.util.* import kotlin.coroutines.CoroutineContext @@ -73,7 +74,8 @@ abstract class Session { val flyingSpeed: Float, val fieldOfView: Float, val gameMode: GameMode, - val initialWorldAndLocation: WorldAndLocationWithRotation, + val world: World, + val position: Position, val invulnerable: Boolean, val reducedDebugInfo: Boolean, val selectedHotbarSlot: Int diff --git a/uranos-api/src/main/kotlin/space/uranos/net/event/SessionAfterLoginEvent.kt b/uranos-api/src/main/kotlin/space/uranos/net/event/SessionAfterLoginEvent.kt index 52ec16d..caec52e 100644 --- a/uranos-api/src/main/kotlin/space/uranos/net/event/SessionAfterLoginEvent.kt +++ b/uranos-api/src/main/kotlin/space/uranos/net/event/SessionAfterLoginEvent.kt @@ -5,11 +5,12 @@ package space.uranos.net.event +import space.uranos.Position import space.uranos.event.Cancellable import space.uranos.net.Session import space.uranos.player.GameMode import space.uranos.player.Player -import space.uranos.world.WorldAndLocationWithRotation +import space.uranos.world.World /** * Emitted after a [Session] finished logging in. @@ -27,7 +28,7 @@ class SessionAfterLoginEvent(override val target: Session) : SessionEvent(), Can /** * The location where the player will spawn. If this is null after all handlers ran, the session is disconnected. */ - var initialWorldAndLocation: WorldAndLocationWithRotation? = null + var initialWorldAndLocation: Pair? = null var maxViewDistance: Int = 32 set(value) { diff --git a/uranos-api/src/main/kotlin/space/uranos/player/Player.kt b/uranos-api/src/main/kotlin/space/uranos/player/Player.kt index 4d64d8c..da08df7 100644 --- a/uranos-api/src/main/kotlin/space/uranos/player/Player.kt +++ b/uranos-api/src/main/kotlin/space/uranos/player/Player.kt @@ -5,10 +5,10 @@ package space.uranos.player +import space.uranos.Position import space.uranos.chat.TextComponent import space.uranos.net.Session import space.uranos.world.Chunk -import space.uranos.world.LocationWithRotation import space.uranos.world.VoxelLocation import space.uranos.world.World import java.util.* @@ -55,9 +55,9 @@ interface Player { ) /** - * The current location of this player. + * The current position of this player. */ - var location: LocationWithRotation + var position: Position /** * The world which currently contains this player. diff --git a/uranos-api/src/main/kotlin/space/uranos/world/Location.kt b/uranos-api/src/main/kotlin/space/uranos/world/Location.kt deleted file mode 100644 index 6fa133a..0000000 --- a/uranos-api/src/main/kotlin/space/uranos/world/Location.kt +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2020-2021 Moritz Ruth and Uranos contributors - * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file - */ - -package space.uranos.world - -import space.uranos.CoordinatePart -import space.uranos.Vector -import kotlin.math.roundToInt - -sealed class AbstractWorldAndLocation { - abstract val world: World - abstract val location: T -} - -data class WorldAndLocation( - override val world: World, - override val location: Location -) : AbstractWorldAndLocation() - -data class WorldAndLocationWithRotation( - override val world: World, - override val location: LocationWithRotation -) : AbstractWorldAndLocation() - -sealed class AbstractLocation { - abstract val x: Double - abstract val y: Double - abstract val z: Double - - /** - * Converts this Location to a VoxelLocation by converting [x], [y] and [z] to integers using [Double.toInt], - * in contrast to [roundToBlock] which uses [Double.roundToInt]. - */ - fun toVoxelLocation(): VoxelLocation = VoxelLocation(x.toInt(), y.toInt().toUByte(), z.toInt()) - - /** - * Converts this Location to a VoxelLocation by converting [x], [y] and [z] to integers using [Double.roundToInt], - * in contrast to [toVoxelLocation] which uses [Double.toInt]. - */ - fun roundToBlock(): VoxelLocation = VoxelLocation(x.roundToInt(), y.roundToInt().toUByte(), z.roundToInt()) - - /** - * Returns a LocationWithRotation composed of this location, [yaw] and [pitch]. - */ - fun withRotation(yaw: Float, pitch: Float) = LocationWithRotation(x, y, z, yaw, pitch) - - /** - * Returns a pair of [world] and this location. - */ - abstract infix fun inside(world: World): AbstractWorldAndLocation<*> - - operator fun get(part: CoordinatePart): Double = when (part) { - CoordinatePart.X -> x - CoordinatePart.Y -> y - CoordinatePart.Z -> z - } -} - -/** - * Represents a set of x, y and z coordinates. - * - * Whenever used as a type, [AbstractLocation] should be preferred so that [LocationWithRotation] is also a valid value. - */ -data class Location(override val x: Double, override val y: Double, override val z: Double) : AbstractLocation() { - override fun inside(world: World) = WorldAndLocation(world, this) - - fun asVector() = Vector(x, y, z) -} - -data class LocationWithRotation( - override val x: Double, - override val y: Double, - override val z: Double, - val yaw: Float, - val pitch: Float -) : AbstractLocation() { - override fun inside(world: World) = WorldAndLocationWithRotation(world, this) - - fun toVector() = Vector(x, y, z) -} diff --git a/uranos-api/src/main/kotlin/space/uranos/world/VoxelLocation.kt b/uranos-api/src/main/kotlin/space/uranos/world/VoxelLocation.kt index 6555d52..63c6d55 100644 --- a/uranos-api/src/main/kotlin/space/uranos/world/VoxelLocation.kt +++ b/uranos-api/src/main/kotlin/space/uranos/world/VoxelLocation.kt @@ -6,6 +6,7 @@ package space.uranos.world import space.uranos.CoordinatePart +import space.uranos.Location import space.uranos.Vector /** diff --git a/uranos-api/src/main/kotlin/space/uranos/world/block/Attribute.kt b/uranos-api/src/main/kotlin/space/uranos/world/block/Attribute.kt index 101a7ae..1d57d0a 100644 --- a/uranos-api/src/main/kotlin/space/uranos/world/block/Attribute.kt +++ b/uranos-api/src/main/kotlin/space/uranos/world/block/Attribute.kt @@ -5,6 +5,8 @@ package space.uranos.world.block +import kotlin.annotation.Target + /** * @suppress */ diff --git a/uranos-packet-codecs/build.gradle.kts b/uranos-packet-codecs/build.gradle.kts index 44f4d01..b96a61c 100644 --- a/uranos-packet-codecs/build.gradle.kts +++ b/uranos-packet-codecs/build.gradle.kts @@ -27,10 +27,6 @@ dependencies { } tasks { - compileKotlin { - kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" - } - test { useJUnitPlatform() } diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/JoinGamePacketCodec.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/JoinGamePacketCodec.kt index 7c8b011..1c8fa25 100644 --- a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/JoinGamePacketCodec.kt +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/JoinGamePacketCodec.kt @@ -25,7 +25,7 @@ object JoinGamePacketCodec : OutgoingPacketCodec(0x24, JoinGameP dst.writeVarInt(1) dst.writeString("uranos:world") - val dimensionsByID = Uranos.dimensionRegistry.items.values.mapIndexed { index, dimension -> + val dimensionsByID = Uranos.dimensionRegistry.items.values.map { dimension -> dimension.id to buildNBT { "natural" setAsByte !dimension.compassesSpinRandomly "ambient_light" set dimension.ambientLight diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayProtocol.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayProtocol.kt index 63f6204..3e3bd47 100644 --- a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayProtocol.kt +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayProtocol.kt @@ -26,6 +26,10 @@ object PlayProtocol : Protocol( ServerDifficultyPacketCodec, SetCompassTargetPacketCodec, SetSelectedHotbarSlotPacketCodec, + SpawnExperienceOrbPacketCodec, + SpawnLivingEntityPacketCodec, + SpawnObjectEntityPacketCodec, + SpawnPaintingPacketCodec, TagsPacketCodec, UpdateViewPositionPacketCodec ) diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacketCodec.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacketCodec.kt index cc90cd1..ef1d6f5 100644 --- a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacketCodec.kt +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacketCodec.kt @@ -13,11 +13,11 @@ import space.uranos.util.bitmask object PlayerPositionAndLookPacketCodec : OutgoingPacketCodec(0x34, PlayerPositionAndLookPacket::class) { override fun PlayerPositionAndLookPacket.encode(dst: ByteBuf) { - dst.writeDouble(locationWithRotation.x) - dst.writeDouble(locationWithRotation.y) - dst.writeDouble(locationWithRotation.z) - dst.writeFloat(locationWithRotation.yaw) - dst.writeFloat(locationWithRotation.pitch) + dst.writeDouble(position.x) + dst.writeDouble(position.y) + dst.writeDouble(position.z) + dst.writeFloat(position.yaw) + dst.writeFloat(position.pitch) dst.writeByte(bitmask(relativeX, relativeY, relativeZ, relativeYaw, relativePitch)) dst.writeVarInt(0) // Teleport ID, I am not sure why this is needed } diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnExperienceOrbPacketCodec.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnExperienceOrbPacketCodec.kt new file mode 100644 index 0000000..b1f56a3 --- /dev/null +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnExperienceOrbPacketCodec.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import io.netty.buffer.ByteBuf +import space.uranos.Difficulty +import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt +import space.uranos.net.packet.OutgoingPacketCodec + +object SpawnExperienceOrbPacketCodec : OutgoingPacketCodec(0x01, SpawnExperienceOrbPacket::class) { + override fun SpawnExperienceOrbPacket.encode(dst: ByteBuf) { + dst.writeVarInt(entityID) + dst.writeDouble(location.x) + dst.writeDouble(location.y) + dst.writeDouble(location.z) + dst.writeShort(amount.toInt()) + } +} diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnLivingEntityPacketCodec.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnLivingEntityPacketCodec.kt new file mode 100644 index 0000000..88231cb --- /dev/null +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnLivingEntityPacketCodec.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import io.netty.buffer.ByteBuf +import space.uranos.Difficulty +import space.uranos.entity.LivingEntity +import space.uranos.net.MinecraftProtocolDataTypes.writeUUID +import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt +import space.uranos.net.packet.OutgoingPacketCodec + +object SpawnLivingEntityPacketCodec : OutgoingPacketCodec(0x02, SpawnLivingEntityPacket::class) { + @Suppress("DuplicatedCode") + override fun SpawnLivingEntityPacket.encode(dst: ByteBuf) { + dst.writeVarInt(entityID) + dst.writeUUID(uuid) + dst.writeVarInt(type.numericID) + dst.writeDouble(position.x) + dst.writeDouble(position.y) + dst.writeDouble(position.z) + dst.writeByte(position.yawIn256Steps.toInt()) + dst.writeByte(position.pitchIn256Steps.toInt()) + dst.writeByte(((headPitch / 360) * 256).toInt()) + dst.writeShort((velocity.x * 8000).toInt().toShort().toInt()) + dst.writeShort((velocity.y * 8000).toInt().toShort().toInt()) + dst.writeShort((velocity.z * 8000).toInt().toShort().toInt()) + } + + fun getPacketFromEntity(entity: LivingEntity) = SpawnLivingEntityPacket( + entity.globallyUniqueNumericID, + entity.uuid, + entity.type, + entity.position, + entity.headPitch, + entity.velocity + ) +} diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnObjectEntityPacketCodec.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnObjectEntityPacketCodec.kt new file mode 100644 index 0000000..a07ad1c --- /dev/null +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnObjectEntityPacketCodec.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import io.netty.buffer.ByteBuf +import space.uranos.entity.Entity +import space.uranos.entity.ItemEntity +import space.uranos.entity.ObjectEntity +import space.uranos.net.MinecraftProtocolDataTypes.writeUUID +import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt +import space.uranos.net.packet.OutgoingPacketCodec +import java.lang.IllegalArgumentException + +object SpawnObjectEntityPacketCodec : OutgoingPacketCodec(0x00, SpawnObjectEntityPacket::class) { + @Suppress("DuplicatedCode") + override fun SpawnObjectEntityPacket.encode(dst: ByteBuf) { + dst.writeVarInt(entityID) + dst.writeUUID(uuid) + dst.writeVarInt(type.numericID) + dst.writeDouble(position.x) + dst.writeDouble(position.y) + dst.writeDouble(position.z) + dst.writeByte(position.yawIn256Steps.toInt()) + dst.writeByte(position.pitchIn256Steps.toInt()) + dst.writeInt(data) + dst.writeShort((velocity.x * 8000).toInt().toShort().toInt()) + dst.writeShort((velocity.y * 8000).toInt().toShort().toInt()) + dst.writeShort((velocity.z * 8000).toInt().toShort().toInt()) + } + + fun getPacketFromEntity(entity: ObjectEntity) = SpawnObjectEntityPacket( + entity.globallyUniqueNumericID, + entity.uuid, + entity.type, + entity.position, + getDataForEntity(entity), + entity.velocity + ) + + fun getDataForEntity(entity: ObjectEntity): Int = when(entity) { + is ItemEntity -> 1 + // TODO: Add remaining + else -> throw IllegalArgumentException("Unknown entity type") + } +} diff --git a/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnPaintingPacketCodec.kt b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnPaintingPacketCodec.kt new file mode 100644 index 0000000..c7f9b17 --- /dev/null +++ b/uranos-packet-codecs/src/main/kotlin/space/uranos/net/packet/play/SpawnPaintingPacketCodec.kt @@ -0,0 +1,48 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import io.netty.buffer.ByteBuf +import space.uranos.CardinalDirection +import space.uranos.Difficulty +import space.uranos.entity.PaintingEntity +import space.uranos.entity.PaintingMotive +import space.uranos.net.MinecraftProtocolDataTypes.writeUUID +import space.uranos.net.MinecraftProtocolDataTypes.writeVarInt +import space.uranos.net.MinecraftProtocolDataTypes.writeVoxelLocation +import space.uranos.net.packet.OutgoingPacketCodec +import space.uranos.world.Voxel +import space.uranos.world.VoxelLocation +import kotlin.math.max + +object SpawnPaintingPacketCodec : OutgoingPacketCodec(0x03, SpawnPaintingPacket::class) { + override fun SpawnPaintingPacket.encode(dst: ByteBuf) { + dst.writeVarInt(entityID) + dst.writeUUID(uuid) + dst.writeVarInt(motive.numericID) + dst.writeVoxelLocation(centerLocation) + dst.writeByte(when(direction) { + CardinalDirection.NORTH -> 2 + CardinalDirection.SOUTH -> 0 + CardinalDirection.WEST -> 1 + CardinalDirection.EAST -> 3 + }) + } + + fun getPacketFromEntity(entity: PaintingEntity) = SpawnPaintingPacket( + entity.globallyUniqueNumericID, + entity.uuid, + entity.motive, + getCenterLocation(entity.topLeftLocation, entity.motive), + entity.direction + ) + + private fun getCenterLocation(topLeftLocation: VoxelLocation, motive: PaintingMotive): VoxelLocation = + topLeftLocation.copy( + x = max(0, motive.width / 2) + topLeftLocation.x, + z = motive.height / 2 + topLeftLocation.z + ) +} diff --git a/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacket.kt b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacket.kt index ab9f012..c50adf5 100644 --- a/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacket.kt +++ b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/PlayerPositionAndLookPacket.kt @@ -5,15 +5,15 @@ package space.uranos.net.packet.play +import space.uranos.Position import space.uranos.net.packet.OutgoingPacket -import space.uranos.world.LocationWithRotation import kotlin.random.Random /** - * Teleports the receiving player to the specified location. + * Teleports the receiving player to the specified position. */ data class PlayerPositionAndLookPacket( - val locationWithRotation: LocationWithRotation, + val position: Position, val relativeX: Boolean = false, val relativeY: Boolean = false, val relativeZ: Boolean = false, diff --git a/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnExperienceOrbPacket.kt b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnExperienceOrbPacket.kt new file mode 100644 index 0000000..311f696 --- /dev/null +++ b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnExperienceOrbPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import space.uranos.Location +import space.uranos.Position +import space.uranos.Vector +import space.uranos.entity.EntityType +import space.uranos.net.packet.OutgoingPacket +import space.uranos.world.Chunk +import space.uranos.world.ChunkData +import java.util.* + +/** + * Sent to spawn experience orbs. + */ +data class SpawnExperienceOrbPacket( + val entityID: Int, + val location: Location, + val amount: Short +) : OutgoingPacket() diff --git a/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnLivingEntityPacket.kt b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnLivingEntityPacket.kt new file mode 100644 index 0000000..6d135d2 --- /dev/null +++ b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnLivingEntityPacket.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import space.uranos.Position +import space.uranos.Vector +import space.uranos.entity.EntityType +import space.uranos.net.packet.OutgoingPacket +import space.uranos.world.Chunk +import space.uranos.world.ChunkData +import java.util.* + +/** + * Sent to spawn **living** entities. + */ +data class SpawnLivingEntityPacket( + val entityID: Int, + val uuid: UUID, + val type: EntityType, + val position: Position, + val headPitch: Float, + /** + * Velocity in blocks per tick + */ + val velocity: Vector +) : OutgoingPacket() diff --git a/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnObjectEntityPacket.kt b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnObjectEntityPacket.kt new file mode 100644 index 0000000..9296490 --- /dev/null +++ b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnObjectEntityPacket.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import space.uranos.Position +import space.uranos.Vector +import space.uranos.entity.EntityType +import space.uranos.net.packet.OutgoingPacket +import space.uranos.world.Chunk +import space.uranos.world.ChunkData +import java.util.* + +/** + * Sent to spawn object entities. + */ +data class SpawnObjectEntityPacket( + val entityID: Int, + val uuid: UUID, + val type: EntityType, + val position: Position, + val data: Int, + val velocity: Vector +) : OutgoingPacket() diff --git a/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnPaintingPacket.kt b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnPaintingPacket.kt new file mode 100644 index 0000000..be7f9cc --- /dev/null +++ b/uranos-packets/src/main/kotlin/space/uranos/net/packet/play/SpawnPaintingPacket.kt @@ -0,0 +1,24 @@ +/* + * Copyright 2020-2021 Moritz Ruth and Uranos contributors + * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file + */ + +package space.uranos.net.packet.play + +import space.uranos.CardinalDirection +import space.uranos.Location +import space.uranos.entity.PaintingMotive +import space.uranos.net.packet.OutgoingPacket +import space.uranos.world.VoxelLocation +import java.util.* + +/** + * Sent to spawn **living** entities. + */ +data class SpawnPaintingPacket( + val entityID: Int, + val uuid: UUID, + val motive: PaintingMotive, + val centerLocation: VoxelLocation, + val direction: CardinalDirection +) : OutgoingPacket() diff --git a/uranos-server/build.gradle.kts b/uranos-server/build.gradle.kts index 3a59555..82c4460 100644 --- a/uranos-server/build.gradle.kts +++ b/uranos-server/build.gradle.kts @@ -50,10 +50,6 @@ dependencies { } tasks { - compileKotlin { - kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn" - } - test { useJUnitPlatform() } diff --git a/uranos-server/src/main/kotlin/space/uranos/net/LoginAndJoinProcedure.kt b/uranos-server/src/main/kotlin/space/uranos/net/LoginAndJoinProcedure.kt index cb372a6..927f065 100644 --- a/uranos-server/src/main/kotlin/space/uranos/net/LoginAndJoinProcedure.kt +++ b/uranos-server/src/main/kotlin/space/uranos/net/LoginAndJoinProcedure.kt @@ -99,7 +99,7 @@ class LoginAndJoinProcedure(val session: UranosSession) { 0, event.gameMode, event.hardcoreHearts, - initialWorldAndLocation.world, + initialWorldAndLocation.first, event.maxViewDistance, event.reducedDebugInfo, event.respawnScreenEnabled @@ -133,7 +133,8 @@ class LoginAndJoinProcedure(val session: UranosSession) { event.flyingSpeed, event.fieldOfView, event.gameMode, - initialWorldAndLocation, + initialWorldAndLocation.first, + initialWorldAndLocation.second, event.invulnerable, event.reducedDebugInfo, event.selectedHotbarSlot @@ -159,8 +160,8 @@ class LoginAndJoinProcedure(val session: UranosSession) { state.uuid, state.gameMode, settings, - state.initialWorldAndLocation.world, - state.initialWorldAndLocation.location, + state.world, + state.position, state.reducedDebugInfo, state.fieldOfView, state.canFly, @@ -181,7 +182,7 @@ class LoginAndJoinProcedure(val session: UranosSession) { // session.send(DeclareCommandsPacket(session.server.commandRegistry.items.values)) // UnlockRecipes - session.send(PlayerPositionAndLookPacket(state.initialWorldAndLocation.location)) + session.send(PlayerPositionAndLookPacket(state.position)) session.send(PlayerInfoPacket(PlayerInfoPacket.Action.AddPlayer((session.server.players + player).map { it.uuid to PlayerInfoPacket.Action.AddPlayer.Data( @@ -202,14 +203,14 @@ class LoginAndJoinProcedure(val session: UranosSession) { ) ) - session.send(UpdateViewPositionPacket(Chunk.Key.from(player.location.toVoxelLocation()))) + session.send(UpdateViewPositionPacket(Chunk.Key.from(player.position.toVoxelLocation()))) session.scheduleKeepAlivePacket(true) player.sendChunksAndLight() // WorldBorder session.send(SetCompassTargetPacket(player.compassTarget)) - session.send(PlayerPositionAndLookPacket(state.initialWorldAndLocation.location)) + session.send(PlayerPositionAndLookPacket(state.position)) // TODO: Wait for ClientStatus(action=0) packet } diff --git a/uranos-server/src/main/kotlin/space/uranos/player/UranosPlayer.kt b/uranos-server/src/main/kotlin/space/uranos/player/UranosPlayer.kt index 440cb26..a248f17 100644 --- a/uranos-server/src/main/kotlin/space/uranos/player/UranosPlayer.kt +++ b/uranos-server/src/main/kotlin/space/uranos/player/UranosPlayer.kt @@ -5,12 +5,12 @@ package space.uranos.player +import space.uranos.Position import space.uranos.chat.TextComponent import space.uranos.net.Session import space.uranos.net.packet.play.ChunkDataPacket import space.uranos.net.packet.play.ChunkLightDataPacket import space.uranos.world.Chunk -import space.uranos.world.LocationWithRotation import space.uranos.world.VoxelLocation import space.uranos.world.World import java.util.* @@ -23,7 +23,7 @@ class UranosPlayer( override var gameMode: GameMode, override var settings: Player.Settings, override val world: World, - override var location: LocationWithRotation, + override var position: Position, override var reducedDebugInfo: Boolean, override var fieldOfView: Float, override var canFly: Boolean, @@ -53,9 +53,8 @@ class UranosPlayer( /** * Sets [currentlyViewedChunks] to all chunks in the view distance. */ - @OptIn(ExperimentalStdlibApi::class) - fun updateCurrentlyViewedChunks() { - val (centerX, centerZ) = Chunk.Key.from(location.toVoxelLocation()) + private fun updateCurrentlyViewedChunks() { + val (centerX, centerZ) = Chunk.Key.from(position.toVoxelLocation()) val edgeLength = settings.viewDistance + 1