mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 01:16:46 -04:00
block entity ticking, campfire block game logic
This commit is contained in:
parent
1f791378ec
commit
820cf347f7
@ -13,11 +13,15 @@
|
||||
|
||||
package de.bixilon.minosoft.data.entities.block
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
abstract class BlockEntity(
|
||||
val connection: PlayConnection,
|
||||
) {
|
||||
|
||||
open fun updateNBT(nbt: Map<String, Any>) {}
|
||||
|
||||
open fun realTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) {}
|
||||
}
|
||||
|
@ -15,10 +15,16 @@ package de.bixilon.minosoft.data.entities.block
|
||||
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.blocks.types.CampfireBlock
|
||||
import de.bixilon.minosoft.gui.rendering.RenderConstants
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.nullCast
|
||||
import de.bixilon.minosoft.util.nbt.tag.NBTUtil.listCast
|
||||
import glm_.vec3.Vec3i
|
||||
import kotlin.random.Random
|
||||
|
||||
class CampfireBlockEntity(connection: PlayConnection) : BlockEntity(connection) {
|
||||
val items: Array<ItemStack?> = arrayOfNulls(RenderConstants.CAMPFIRE_ITEMS)
|
||||
@ -38,6 +44,23 @@ class CampfireBlockEntity(connection: PlayConnection) : BlockEntity(connection)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun realTick(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) {
|
||||
val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer) ?: return
|
||||
if (blockState.properties[BlockProperties.LIT] != true) {
|
||||
return
|
||||
}
|
||||
if (blockState.block !is CampfireBlock) {
|
||||
return
|
||||
}
|
||||
|
||||
if (Random.nextFloat() < 0.11f) {
|
||||
for (i in 0 until Random.nextInt(2) + 2) {
|
||||
blockState.block.spawnSmokeParticles(connection, particleRenderer, blockState, blockPosition, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object : BlockEntityFactory<CampfireBlockEntity> {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("minecraft:campfire")
|
||||
|
||||
|
@ -81,7 +81,7 @@ open class Block(
|
||||
return true
|
||||
}
|
||||
|
||||
open fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
open fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
if (blockEntityType == null) {
|
||||
return BlockUsages.PASS
|
||||
}
|
||||
@ -107,6 +107,7 @@ open class Block(
|
||||
"NoteBlock" -> NoteBlock(resourceLocation, mappings, data)
|
||||
"RepeaterBlock" -> RepeaterBlock(resourceLocation, mappings, data)
|
||||
"ComparatorBlock" -> ComparatorBlock(resourceLocation, mappings, data)
|
||||
"CampfireBlock" -> CampfireBlock(resourceLocation, mappings, data)
|
||||
else -> Block(resourceLocation, mappings, data)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Minosoft
|
||||
* Copyright (C) 2021 Moritz Zwerger
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.data.mappings.blocks.types
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.inventory.ItemStack
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockUsages
|
||||
import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties
|
||||
import de.bixilon.minosoft.data.mappings.items.tools.ShovelItem
|
||||
import de.bixilon.minosoft.data.mappings.versions.Registries
|
||||
import de.bixilon.minosoft.data.player.Hands
|
||||
import de.bixilon.minosoft.gui.rendering.input.camera.RaycastHit
|
||||
import de.bixilon.minosoft.gui.rendering.particle.ParticleRenderer
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import glm_.vec3.Vec3
|
||||
import glm_.vec3.Vec3i
|
||||
import kotlin.random.Random
|
||||
|
||||
open class CampfireBlock(resourceLocation: ResourceLocation, mappings: Registries, data: JsonObject) : Block(resourceLocation, mappings, data) {
|
||||
|
||||
private fun extinguish(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i) {
|
||||
val particleRenderer = connection.rendering?.renderWindow?.get(ParticleRenderer) ?: return
|
||||
for (i in 0 until 20) {
|
||||
spawnSmokeParticles(connection, particleRenderer, blockState, blockPosition, true)
|
||||
}
|
||||
}
|
||||
|
||||
fun spawnSmokeParticles(connection: PlayConnection, particleRenderer: ParticleRenderer, blockState: BlockState, blockPosition: Vec3i, extinguished: Boolean) {
|
||||
val horizontal = { 0.5f + Random.nextFloat() / 3.0f * if (Random.nextBoolean()) 1.0f else -1.0f }
|
||||
val position = Vec3(
|
||||
blockPosition.x + horizontal(),
|
||||
blockPosition.y + Random.nextFloat() + Random.nextFloat(),
|
||||
blockPosition.z + horizontal()
|
||||
)
|
||||
val isSignal = blockState.properties[BlockProperties.CAMPFIRE_SIGNAL_FIRE] == true
|
||||
|
||||
val data = connection.registries.particleTypeRegistry[if (isSignal) {
|
||||
CampfireSmokeParticle.SignalSmokeParticleFactory
|
||||
} else {
|
||||
CampfireSmokeParticle.CosySmokeParticleFactory
|
||||
}]!!
|
||||
|
||||
particleRenderer.add(CampfireSmokeParticle(connection, particleRenderer, position, Vec3(0.0f, 0.07f, 0.0f), data.simple(), isSignal))
|
||||
|
||||
if (extinguished) {
|
||||
// ToDo: Spawn smoke particles
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
if (itemStack?.item !is ShovelItem || blockState.properties[BlockProperties.LIT] != true) {
|
||||
return super.onUse(connection, blockState, blockPosition, raycastHit, hands, itemStack)
|
||||
}
|
||||
connection.world.setBlockState(blockPosition, blockState.withProperties(BlockProperties.LIT to false))
|
||||
extinguish(connection, blockState, blockPosition)
|
||||
return BlockUsages.SUCCESS
|
||||
}
|
||||
}
|
@ -18,7 +18,7 @@ open class ComparatorBlock(resourceLocation: ResourceLocation, mappings: Registr
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
connection.world[blockPosition] = blockState.cycle(BlockProperties.STRUCTURE_BLOCK_MODE)
|
||||
|
||||
return BlockUsages.SUCCESS
|
||||
|
@ -32,7 +32,7 @@ open class DoorBlock(resourceLocation: ResourceLocation, mappings: Registries, d
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
if (blockState.material.resourceLocation == DefaultMaterials.METAL) {
|
||||
return BlockUsages.CONSUME
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ open class LeverBlock(resourceLocation: ResourceLocation, mappings: Registries,
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
connection.world[blockPosition] = blockState.cycle(BlockProperties.POWERED)
|
||||
|
||||
return BlockUsages.SUCCESS
|
||||
|
@ -26,7 +26,7 @@ import glm_.vec3.Vec3i
|
||||
|
||||
open class NoteBlock(resourceLocation: ResourceLocation, mappings: Registries, data: JsonObject) : Block(resourceLocation, mappings, data) {
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
return BlockUsages.SUCCESS
|
||||
}
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ open class RepeaterBlock(resourceLocation: ResourceLocation, mappings: Registrie
|
||||
TODO()
|
||||
}
|
||||
|
||||
override fun use(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
override fun onUse(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack?): BlockUsages {
|
||||
connection.world[blockPosition] = blockState.cycle(BlockProperties.REPEATER_DELAY)
|
||||
|
||||
return BlockUsages.SUCCESS
|
||||
|
@ -16,8 +16,13 @@ import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.world.biome.source.BiomeSource
|
||||
import de.bixilon.minosoft.data.world.light.LightAccessor
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.EMPTY
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkSectionPosition
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.of
|
||||
import de.bixilon.minosoft.gui.rendering.util.VecUtil.sectionHeight
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
/**
|
||||
@ -90,6 +95,18 @@ class Chunk(
|
||||
}
|
||||
}
|
||||
|
||||
fun realTick(connection: PlayConnection, chunkPosition: Vec2i) {
|
||||
if (!isFullyLoaded) {
|
||||
return
|
||||
}
|
||||
val sections = sections
|
||||
sections ?: return
|
||||
for ((height, section) in sections.toSynchronizedMap()) {
|
||||
section.realTick(connection, Vec3i.of(chunkPosition, height, Vec3i.EMPTY))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun getBlockEntity(inChunkPosition: Vec3i): BlockEntity? {
|
||||
return sections?.get(inChunkPosition.sectionHeight)?.getBlockEntity(inChunkPosition.inChunkSectionPosition)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.world.block.entities.ArrayBlockEntityProvider
|
||||
import de.bixilon.minosoft.data.world.block.entities.BlockEntityProvider
|
||||
import de.bixilon.minosoft.data.world.block.entities.MapBlockEntityProvider
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
@ -55,6 +56,12 @@ class ChunkSection(
|
||||
}
|
||||
}
|
||||
|
||||
fun realTick(connection: PlayConnection, chunkSectionPosition: Vec3i) {
|
||||
blockEntities.forEach { entity, inChunkSectionPosition ->
|
||||
entity.realTick(connection, blocks[inChunkSectionPosition.index]!!, chunkSectionPosition + inChunkSectionPosition)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val Vec3i.index: Int
|
||||
get() = getIndex(x, y, z)
|
||||
|
@ -30,6 +30,7 @@ import de.bixilon.minosoft.modding.event.events.BlockSetEvent
|
||||
import de.bixilon.minosoft.modding.event.events.ChunkUnloadEvent
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import glm_.vec2.Vec2i
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
@ -155,6 +156,12 @@ class World(
|
||||
return biomeAccessor.getBiome(blockPosition)
|
||||
}
|
||||
|
||||
fun realTick() {
|
||||
for ((chunkPosition, chunk) in chunks.toSynchronizedMap()) {
|
||||
chunk.realTick(connection, chunkPosition)
|
||||
}
|
||||
}
|
||||
|
||||
fun getBlocks(start: Vec3i, end: Vec3i): Map<Vec3i, BlockState> {
|
||||
val blocks: MutableMap<Vec3i, BlockState> = mutableMapOf()
|
||||
|
||||
|
@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.world.block.entities
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.world.ChunkSection.Companion.index
|
||||
import de.bixilon.minosoft.data.world.ChunkSection.Companion.indexPosition
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
@ -47,4 +48,11 @@ class ArrayBlockEntityProvider(
|
||||
override fun clone(): ArrayBlockEntityProvider {
|
||||
return ArrayBlockEntityProvider(blockEntities.clone())
|
||||
}
|
||||
|
||||
override fun forEach(lambda: (entity: BlockEntity, inChunkSectionPosition: Vec3i) -> Unit) {
|
||||
for ((index, blockEntity) in blockEntities.withIndex()) {
|
||||
blockEntity ?: continue
|
||||
lambda(blockEntity, index.indexPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,8 @@ interface BlockEntityProvider {
|
||||
|
||||
fun clone(): BlockEntityProvider
|
||||
|
||||
fun forEach(lambda: (entity: BlockEntity, inChunkSectionPosition: Vec3i) -> Unit)
|
||||
|
||||
companion object {
|
||||
const val BLOCK_ENTITY_MAP_LIMIT_UP = 15
|
||||
const val BLOCK_ENTITY_MAP_LIMIT_DOWN = 5
|
||||
|
@ -15,10 +15,12 @@ package de.bixilon.minosoft.data.world.block.entities
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.world.ChunkSection.Companion.indexPosition
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedMapOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedMap
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
class MapBlockEntityProvider(
|
||||
var blockEntities: MutableMap<Vec3i, BlockEntity> = mutableMapOf(),
|
||||
var blockEntities: MutableMap<Vec3i, BlockEntity> = synchronizedMapOf(),
|
||||
) : BlockEntityProvider {
|
||||
override val size: Int
|
||||
get() = blockEntities.size
|
||||
@ -47,4 +49,10 @@ class MapBlockEntityProvider(
|
||||
override fun clone(): MapBlockEntityProvider {
|
||||
return MapBlockEntityProvider(blockEntities.toMutableMap())
|
||||
}
|
||||
|
||||
override fun forEach(lambda: (entity: BlockEntity, inChunkSectionPosition: Vec3i) -> Unit) {
|
||||
for ((position, blockEntity) in blockEntities.toSynchronizedMap()) {
|
||||
lambda(blockEntity, position)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class RightClickHandler(
|
||||
val usage = if (renderWindow.inputHandler.camera.sneaking) {
|
||||
BlockUsages.PASS
|
||||
} else {
|
||||
raycastHit.blockState.block.use(renderWindow.connection, raycastHit.blockState, raycastHit.blockPosition, raycastHit, Hands.MAIN_HAND, itemInHand)
|
||||
raycastHit.blockState.block.onUse(renderWindow.connection, raycastHit.blockState, raycastHit.blockPosition, raycastHit, Hands.MAIN_HAND, itemInHand)
|
||||
}
|
||||
|
||||
if (currentTime - lastInteractionSent < ProtocolDefinition.TICK_TIME) {
|
||||
|
@ -20,7 +20,6 @@ import de.bixilon.minosoft.gui.rendering.Renderer
|
||||
import de.bixilon.minosoft.gui.rendering.RendererBuilder
|
||||
import de.bixilon.minosoft.gui.rendering.modding.events.CameraMatrixChangeEvent
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.Particle
|
||||
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.CampfireSmokeParticle
|
||||
import de.bixilon.minosoft.gui.rendering.shader.Shader
|
||||
import de.bixilon.minosoft.gui.rendering.textures.Texture
|
||||
import de.bixilon.minosoft.gui.rendering.textures.TextureArray
|
||||
@ -32,7 +31,6 @@ import de.bixilon.minosoft.util.KUtil.toSynchronizedSet
|
||||
import de.bixilon.minosoft.util.MMath
|
||||
import glm_.vec3.Vec3
|
||||
import org.lwjgl.opengl.GL11.glDepthMask
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
class ParticleRenderer(
|
||||
@ -78,7 +76,6 @@ class ParticleRenderer(
|
||||
particles += particle
|
||||
}
|
||||
|
||||
var lastTickTime = System.currentTimeMillis()
|
||||
|
||||
override fun draw() {
|
||||
particleShader.use()
|
||||
@ -86,25 +83,6 @@ class ParticleRenderer(
|
||||
particleMesh.unload()
|
||||
particleMesh = ParticleMesh()
|
||||
|
||||
// ToDo: Remove, this ist just for testing purposes
|
||||
if (System.currentTimeMillis() - lastTickTime > ProtocolDefinition.TICK_TIME) {
|
||||
val blockPosition = Vec3(0, 5, 0)
|
||||
if (Random.nextFloat() < 0.11f) {
|
||||
for (i in 0 until Random.nextInt(2) + 2) {
|
||||
val horizontal = { 0.5f + Random.nextFloat() / 3.0f * if (Random.nextBoolean()) 1.0f else -1.0f }
|
||||
val position = Vec3(
|
||||
blockPosition.x + horizontal(),
|
||||
blockPosition.y + Random.nextFloat() + Random.nextFloat(),
|
||||
blockPosition.z + horizontal()
|
||||
)
|
||||
|
||||
val data = connection.registries.particleTypeRegistry[CampfireSmokeParticle.CosySmokeParticleFactory]!!
|
||||
val particle = CampfireSmokeParticle(connection, this, position, Vec3(0.0f, 0.07f, 0.0f), data.simple(), true)
|
||||
add(particle)
|
||||
}
|
||||
}
|
||||
lastTickTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
for (particle in particles.toSynchronizedSet()) {
|
||||
particle.tick()
|
||||
|
@ -62,7 +62,6 @@ abstract class Particle(
|
||||
var spacing: Vec3 = Vec3.EMPTY
|
||||
set(value) {
|
||||
if (field == value) {
|
||||
return
|
||||
}
|
||||
field = value
|
||||
|
||||
|
@ -150,33 +150,27 @@ object VecUtil {
|
||||
return Pair(Vec2(this[0].asFloat, BlockModelElement.BLOCK_RESOLUTION - this[1].asFloat), Vec2(this[2].asFloat, BlockModelElement.BLOCK_RESOLUTION - this[3].asFloat))
|
||||
}
|
||||
|
||||
fun Int.chunkPosition(multiplier: Int): Int {
|
||||
return if (this >= 0) {
|
||||
this / multiplier
|
||||
} else {
|
||||
((this + 1) / multiplier) - 1
|
||||
}
|
||||
}
|
||||
|
||||
val Vec3i.chunkPosition: Vec2i
|
||||
get() {
|
||||
val chunkX = if (this.x >= 0) {
|
||||
this.x / ProtocolDefinition.SECTION_WIDTH_X
|
||||
} else {
|
||||
((this.x + 1) / ProtocolDefinition.SECTION_WIDTH_X) - 1
|
||||
get() = Vec2i(this.x.chunkPosition(ProtocolDefinition.SECTION_WIDTH_X), this.z.chunkPosition(ProtocolDefinition.SECTION_WIDTH_Z))
|
||||
|
||||
fun Int.inChunkPosition(multiplier: Int): Int {
|
||||
var coordinate: Int = this % multiplier
|
||||
if (coordinate < 0) {
|
||||
coordinate += multiplier
|
||||
}
|
||||
val chunkY = if (this.z >= 0) {
|
||||
this.z / ProtocolDefinition.SECTION_WIDTH_Z
|
||||
} else {
|
||||
((this.z + 1) / ProtocolDefinition.SECTION_WIDTH_Z) - 1
|
||||
}
|
||||
return Vec2i(chunkX, chunkY)
|
||||
return coordinate
|
||||
}
|
||||
|
||||
val Vec3i.inChunkPosition: Vec3i
|
||||
get() {
|
||||
var x: Int = this.x % ProtocolDefinition.SECTION_WIDTH_X
|
||||
if (x < 0) {
|
||||
x += ProtocolDefinition.SECTION_WIDTH_X
|
||||
}
|
||||
var z: Int = this.z % ProtocolDefinition.SECTION_WIDTH_Z
|
||||
if (z < 0) {
|
||||
z += ProtocolDefinition.SECTION_WIDTH_Z
|
||||
}
|
||||
return Vec3i(x, y, z)
|
||||
}
|
||||
get() = Vec3i(this.x.inChunkPosition(ProtocolDefinition.SECTION_WIDTH_X), y, this.z.inChunkPosition(ProtocolDefinition.SECTION_WIDTH_Z))
|
||||
|
||||
val Vec3i.inChunkSectionPosition: Vec3i
|
||||
get() {
|
||||
@ -199,20 +193,20 @@ object VecUtil {
|
||||
}
|
||||
|
||||
val Vec3i.entityPosition: Vec3
|
||||
get() = Vec3(x + 0.5f, y, z + 0.5f) // ToDo
|
||||
get() = Vec3(x + 0.5f, y, z + 0.5f) // ToDo: Confirm
|
||||
|
||||
val Vec3.blockPosition: Vec3i
|
||||
get() = Vec3i((x - 0.5f).toInt(), y.toInt(), (z - 0.5f).toInt()) // ToDo
|
||||
get() = Vec3i((x - 0.5f).toInt(), y.toInt(), (z - 0.5f).toInt()) // ToDo: Confirm
|
||||
|
||||
val Vec3i.center: Vec3
|
||||
get() = Vec3(x + 0.5f, y + 0.5f, z + 0.5f) // ToDo
|
||||
get() = Vec3(x + 0.5f, y + 0.5f, z + 0.5f) // ToDo: Confirm
|
||||
|
||||
fun Vec3i.Companion.of(chunkPosition: Vec2i, sectionHeight: Int, inChunkSectionPosition: Vec3i): Vec3i {
|
||||
return Vec3i(
|
||||
chunkPosition.x * ProtocolDefinition.SECTION_WIDTH_X + inChunkSectionPosition.x,
|
||||
sectionHeight * ProtocolDefinition.SECTION_HEIGHT_Y + inChunkSectionPosition.y,
|
||||
chunkPosition.y * ProtocolDefinition.SECTION_WIDTH_Z + inChunkSectionPosition.z
|
||||
) // ToDo
|
||||
) // ToDo: Confirm
|
||||
}
|
||||
|
||||
infix operator fun Vec3i.plus(vec3: Vec3i?): Vec3i {
|
||||
|
@ -80,6 +80,7 @@ class PlayConnection(
|
||||
|
||||
lateinit var velocityHandlerTask: TimeWorkerTask
|
||||
private var velocityHandlerLastExecutionTime: Long = 0L
|
||||
lateinit var worldTickTask: TimeWorkerTask
|
||||
val collisionDetector = CollisionDetector(this)
|
||||
|
||||
override var connectionState: ConnectionStates = ConnectionStates.DISCONNECTED
|
||||
@ -137,6 +138,11 @@ class PlayConnection(
|
||||
}
|
||||
TimeWorker.addTask(velocityHandlerTask)
|
||||
|
||||
worldTickTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME) {
|
||||
world.realTick()
|
||||
}
|
||||
TimeWorker.addTask(worldTickTask)
|
||||
|
||||
registerEvent(CallbackEventInvoker.of<ChatMessageReceiveEvent> {
|
||||
val additionalPrefix = when (it.position) {
|
||||
ChatTextPositions.SYSTEM_MESSAGE -> "[SYSTEM] "
|
||||
@ -157,6 +163,9 @@ class PlayConnection(
|
||||
if (this::velocityHandlerTask.isInitialized) {
|
||||
TimeWorker.removeTask(velocityHandlerTask)
|
||||
}
|
||||
if (this::worldTickTask.isInitialized) {
|
||||
TimeWorker.removeTask(worldTickTask)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
}
|
||||
|
@ -43,18 +43,18 @@ class ContainerOpenS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
}
|
||||
}
|
||||
val title: ChatComponent = buffer.readChatComponent()
|
||||
val slotCount: Int = if (buffer.versionId < V_19W02A || buffer.versionId >= V_19W11A) {
|
||||
val slotCount: Int = if (buffer.versionId <= V_19W11A) { // ToDo: This is completely guessed, it is not present in 1.16.5 (unchecked)
|
||||
buffer.readUnsignedByte()
|
||||
} else {
|
||||
// ToDo: load from pixlyzer
|
||||
0
|
||||
}
|
||||
val hasTitle: Boolean = if (buffer.versionId > V_14W03B) {
|
||||
val hasTitle: Boolean = if (buffer.versionId > V_14W03B && buffer.versionId <= V_1_16) { // also completely guessed
|
||||
buffer.readBoolean()
|
||||
} else {
|
||||
true
|
||||
}
|
||||
var entityId: Int? = if (containerType.resourceLocation == DefaultInventoryTypes.HORSE || buffer.versionId < V_14W03B) {
|
||||
var entityId: Int? = if (containerType.resourceLocation == DefaultInventoryTypes.HORSE || buffer.versionId < V_14W03B) { // ToDo: This was removed at some point
|
||||
buffer.readInt()
|
||||
} else {
|
||||
null
|
||||
|
@ -12,18 +12,27 @@ object TimeWorker {
|
||||
while (true) {
|
||||
val currentTime = System.currentTimeMillis()
|
||||
for (task in TASKS.toSynchronizedSet()) {
|
||||
if (!task.getsExecuted && currentTime - task.lastExecution >= task.interval) {
|
||||
if (task.getsExecuted) {
|
||||
continue
|
||||
}
|
||||
if (currentTime - task.lastExecution <= task.interval) {
|
||||
continue
|
||||
}
|
||||
Minosoft.THREAD_POOL.execute {
|
||||
synchronized(task.getsExecuted) {
|
||||
if (task.getsExecuted) {
|
||||
return@execute
|
||||
}
|
||||
task.getsExecuted = true
|
||||
task.runnable.run()
|
||||
task.lastExecution = currentTime
|
||||
task.getsExecuted = false
|
||||
}
|
||||
}
|
||||
if (task.runOnce) {
|
||||
TASKS -= task
|
||||
}
|
||||
}
|
||||
}
|
||||
Thread.sleep(1)
|
||||
}
|
||||
}, "TimeWorkerThread").start()
|
||||
|
Loading…
x
Reference in New Issue
Block a user