Rewrite location classes and add Position, add packets for spawning entities
This commit is contained in:
parent
4d8a5ed603
commit
e7d5576269
38 changed files with 593 additions and 193 deletions
|
@ -17,5 +17,9 @@ allprojects {
|
|||
tasks.withType<KotlinCompile> {
|
||||
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"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<JsonAny>) {
|
||||
for (entity in entities) {
|
||||
private fun generateEntityTypes(types: List<JsonAny>) {
|
||||
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<JsonAny>) {
|
||||
private fun generateEntityStubs(types: List<JsonAny>) {
|
||||
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<JsonAny>) {
|
||||
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)
|
||||
|
|
|
@ -15,10 +15,6 @@ dependencies {
|
|||
}
|
||||
|
||||
tasks {
|
||||
compileKotlin {
|
||||
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.ExperimentalUnsignedTypes"
|
||||
}
|
||||
|
||||
shadowJar {
|
||||
archiveFileName.set("TestPlugin.jar")
|
||||
destinationDirectory.set(file("../serverData/plugins"))
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
38
uranos-api/src/main/kotlin/space/uranos/Location.kt
Normal file
38
uranos-api/src/main/kotlin/space/uranos/Location.kt
Normal file
|
@ -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, Location> = world to this
|
||||
|
||||
operator fun get(part: CoordinatePart): Double = when (part) {
|
||||
CoordinatePart.X -> x
|
||||
CoordinatePart.Y -> y
|
||||
CoordinatePart.Z -> z
|
||||
}
|
||||
}
|
53
uranos-api/src/main/kotlin/space/uranos/Position.kt
Normal file
53
uranos-api/src/main/kotlin/space/uranos/Position.kt
Normal file
|
@ -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, Position> = 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)
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <reified T : Entity> type(
|
||||
numericID: Int,
|
||||
id: String,
|
||||
width: Float,
|
||||
height: Float
|
||||
) : EntityType<T> = object : EntityType<T> {
|
||||
override val entityClass: KClass<T> = 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
|
||||
}
|
||||
|
|
|
@ -7,8 +7,7 @@ package space.uranos.entity
|
|||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
interface EntityType<T : Entity> {
|
||||
val entityClass: KClass<T>
|
||||
interface EntityType {
|
||||
val numericID: Int
|
||||
val id: String
|
||||
val width: Float
|
||||
|
@ -18,13 +17,7 @@ interface EntityType<T : Entity> {
|
|||
/**
|
||||
* 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 <T: Entity> byClass(entityClass: KClass<T>): EntityType<T>? = byClass[entityClass] as EntityType<T>?
|
||||
inline fun <reified T: Entity> byClass(): EntityType<T>? = byClass(T::class)
|
||||
val all = ENTITY_TYPES
|
||||
val byID = ENTITY_TYPES.map { it.id to it }.toMap()
|
||||
}
|
||||
}
|
||||
|
|
14
uranos-api/src/main/kotlin/space/uranos/entity/ItemEntity.kt
Normal file
14
uranos-api/src/main/kotlin/space/uranos/entity/ItemEntity.kt
Normal file
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
18
uranos-api/src/main/kotlin/space/uranos/entity/Mobile.kt
Normal file
18
uranos-api/src/main/kotlin/space/uranos/entity/Mobile.kt
Normal file
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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<World, Position>? = null
|
||||
|
||||
var maxViewDistance: Int = 32
|
||||
set(value) {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<T : AbstractLocation> {
|
||||
abstract val world: World
|
||||
abstract val location: T
|
||||
}
|
||||
|
||||
data class WorldAndLocation(
|
||||
override val world: World,
|
||||
override val location: Location
|
||||
) : AbstractWorldAndLocation<Location>()
|
||||
|
||||
data class WorldAndLocationWithRotation(
|
||||
override val world: World,
|
||||
override val location: LocationWithRotation
|
||||
) : AbstractWorldAndLocation<LocationWithRotation>()
|
||||
|
||||
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)
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
package space.uranos.world
|
||||
|
||||
import space.uranos.CoordinatePart
|
||||
import space.uranos.Location
|
||||
import space.uranos.Vector
|
||||
|
||||
/**
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
package space.uranos.world.block
|
||||
|
||||
import kotlin.annotation.Target
|
||||
|
||||
/**
|
||||
* @suppress
|
||||
*/
|
||||
|
|
|
@ -27,10 +27,6 @@ dependencies {
|
|||
}
|
||||
|
||||
tasks {
|
||||
compileKotlin {
|
||||
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ object JoinGamePacketCodec : OutgoingPacketCodec<JoinGamePacket>(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
|
||||
|
|
|
@ -26,6 +26,10 @@ object PlayProtocol : Protocol(
|
|||
ServerDifficultyPacketCodec,
|
||||
SetCompassTargetPacketCodec,
|
||||
SetSelectedHotbarSlotPacketCodec,
|
||||
SpawnExperienceOrbPacketCodec,
|
||||
SpawnLivingEntityPacketCodec,
|
||||
SpawnObjectEntityPacketCodec,
|
||||
SpawnPaintingPacketCodec,
|
||||
TagsPacketCodec,
|
||||
UpdateViewPositionPacketCodec
|
||||
)
|
||||
|
|
|
@ -13,11 +13,11 @@ import space.uranos.util.bitmask
|
|||
object PlayerPositionAndLookPacketCodec :
|
||||
OutgoingPacketCodec<PlayerPositionAndLookPacket>(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
|
||||
}
|
||||
|
|
|
@ -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<SpawnExperienceOrbPacket>(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())
|
||||
}
|
||||
}
|
|
@ -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<SpawnLivingEntityPacket>(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
|
||||
)
|
||||
}
|
|
@ -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<SpawnObjectEntityPacket>(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")
|
||||
}
|
||||
}
|
|
@ -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<SpawnPaintingPacket>(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
|
||||
)
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
|
@ -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()
|
|
@ -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()
|
|
@ -50,10 +50,6 @@ dependencies {
|
|||
}
|
||||
|
||||
tasks {
|
||||
compileKotlin {
|
||||
kotlinOptions.freeCompilerArgs += "-Xopt-in=kotlin.RequiresOptIn"
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Reference in a new issue