diff --git a/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt b/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt index 6a0f17d03..82a126966 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/StatusEffectInstance.kt @@ -18,4 +18,10 @@ data class StatusEffectInstance( val statusEffect: StatusEffect, val amplifier: Int, val duration: Int, -) +) { + private val startMillis = System.currentTimeMillis() + + val remainingMillis: Long + get() = System.currentTimeMillis() - startMillis +} + diff --git a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt index 60891f99d..ce6af3dfe 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/entities/Entity.kt @@ -31,6 +31,7 @@ import de.bixilon.minosoft.gui.rendering.util.VecUtil.chunkPosition import de.bixilon.minosoft.gui.rendering.util.VecUtil.inChunkPosition import de.bixilon.minosoft.protocol.network.connection.PlayConnection import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition +import de.bixilon.minosoft.util.KUtil.synchronizedMapOf import glm_.vec3.Vec3 import java.lang.reflect.InvocationTargetException import java.util.* @@ -42,8 +43,8 @@ abstract class Entity( var position: Vec3, var rotation: EntityRotation, ) { - val equipment: MutableMap = mutableMapOf() - val effectList: MutableSet = mutableSetOf() + val equipment: MutableMap = synchronizedMapOf() + val activeStatusEffects: MutableMap = synchronizedMapOf() @JvmField protected val versionId: Int = connection.version.versionId @@ -69,12 +70,11 @@ abstract class Entity( fun addEffect(effect: StatusEffectInstance) { // effect already applied, maybe the duration or the amplifier changed? - effectList.removeIf { (statusEffect) -> statusEffect === effect.statusEffect } - effectList.add(effect) + activeStatusEffects[effect.statusEffect] = effect } fun removeEffect(effect: StatusEffect) { - effectList.removeIf { (statusEffect) -> statusEffect === effect } + activeStatusEffects.remove(effect) } fun attachTo(vehicleId: Int?) { @@ -278,7 +278,7 @@ abstract class Entity( return delta } - fun tick(deltaMillis: Long) { + private fun tickMovement(deltaMillis: Long) { if (connection.world.getChunk(position.blockPosition.chunkPosition)?.isFullyLoaded != true) { return // ignore update if chunk is not loaded yet } @@ -301,6 +301,12 @@ abstract class Entity( move(velocity * deltaTime) } + fun tick(deltaMillis: Long) { + check(deltaMillis > 0L) { "Delta tick time is <= 0: $deltaMillis" } + + tickMovement(deltaMillis) + } + private val aabb: AABB get() = defaultAABB + position diff --git a/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.kt b/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.kt index ad573d5f1..e37255f9c 100644 --- a/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.kt +++ b/src/main/java/de/bixilon/minosoft/data/entities/meta/EntityMetaData.kt @@ -40,6 +40,10 @@ class EntityMetaData( ) { val sets: MetaDataHashMap = MetaDataHashMap() + override fun toString(): String { + return sets.toString() + } + fun getData(type: EntityMetaDataDataTypes, buffer: PlayInByteBuffer): Any? { return when (type) { EntityMetaDataDataTypes.BYTE -> buffer.readByte() @@ -128,8 +132,8 @@ class EntityMetaData( get(index)?.let { try { return it as K - } catch (e: ClassCastException) { - Log.log(LogMessageType.OTHER, level = LogLevels.WARN, message = e) + } catch (exception: ClassCastException) { + Log.log(LogMessageType.OTHER, level = LogLevels.WARN, message = exception) } } return field.getDefaultValue() @@ -197,7 +201,7 @@ class EntityMetaData( } fun getChatComponent(field: EntityMetaDataFields): ChatComponent? { - return ChatComponent.of(get(field), connection.version.localeManager) + return get(field)?.let { ChatComponent.of(it, connection.version.localeManager) } } fun getString(field: EntityMetaDataFields): String? { diff --git a/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt b/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt index 92d0112ea..f69afd8fd 100644 --- a/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt +++ b/src/main/java/de/bixilon/minosoft/data/inventory/ItemStack.kt @@ -161,11 +161,6 @@ data class ItemStack( return nbt } - - override fun toString(): String { - return fullDisplayName - } - val displayName: ChatComponent get() { customDisplayName?.let { return it } @@ -173,10 +168,6 @@ data class ItemStack( return ChatComponent.of(item.toString()) } - // ToDo all properties - val fullDisplayName: String - get() = displayName.legacyText + ": " + super.toString() - fun shouldHideEnchantments(): Boolean { return BitByte.isBitSet(hideFlags, HIDE_ENCHANTMENT_BIT) } diff --git a/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt b/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt index 1775f72d3..e68653833 100644 --- a/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt +++ b/src/main/java/de/bixilon/minosoft/data/world/WorldEntities.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.world import de.bixilon.minosoft.data.entities.entities.Entity import de.bixilon.minosoft.util.KUtil.synchronizedMapOf +import de.bixilon.minosoft.util.KUtil.toSynchronizedMap import java.util.* class WorldEntities : Iterable { @@ -72,6 +73,6 @@ class WorldEntities : Iterable { } override fun iterator(): Iterator { - return idEntityMap.values.iterator() + return idEntityMap.toSynchronizedMap().values.iterator() } } diff --git a/src/main/java/de/bixilon/minosoft/protocol/network/connection/PlayConnection.kt b/src/main/java/de/bixilon/minosoft/protocol/network/connection/PlayConnection.kt index bec15c7b3..f6bb11dfd 100644 --- a/src/main/java/de/bixilon/minosoft/protocol/network/connection/PlayConnection.kt +++ b/src/main/java/de/bixilon/minosoft/protocol/network/connection/PlayConnection.kt @@ -117,10 +117,12 @@ class PlayConnection( velocityHandlerTask = TimeWorkerTask(ProtocolDefinition.TICK_TIME / 5) { val currentTime = System.currentTimeMillis() val deltaTime = currentTime - velocityHandlerLastExecutionTime - for (entity in world.entities) { - entity.tick(deltaTime) + if (deltaTime > 0L) { + for (entity in world.entities) { + entity.tick(deltaTime) + } + renderer?.renderWindow?.inputHandler?.camera?.checkPosition() } - renderer?.renderWindow?.inputHandler?.camera?.checkPosition() velocityHandlerLastExecutionTime = currentTime } TimeWorker.addTask(velocityHandlerTask) diff --git a/src/main/java/de/bixilon/minosoft/terminal/commands/commands/CommandEntities.java b/src/main/java/de/bixilon/minosoft/terminal/commands/commands/CommandEntities.java index 11c326536..06ab29c0d 100644 --- a/src/main/java/de/bixilon/minosoft/terminal/commands/commands/CommandEntities.java +++ b/src/main/java/de/bixilon/minosoft/terminal/commands/commands/CommandEntities.java @@ -55,7 +55,7 @@ public class CommandEntities extends Command { tableData.add(new Object[]{"Location", entity.getPosition()}); tableData.add(new Object[]{"Rotation", entity.getRotation()}); tableData.add(new Object[]{"Equipment", entity.getEquipment()}); - tableData.add(new Object[]{"Effects", entity.getEffectList()}); + tableData.add(new Object[]{"Effects", entity.getActiveStatusEffects()}); tableData.add(new Object[]{"Attached to", entity.getAttachedEntity() == -1 ? "" : entity.getAttachedEntity()}); for (var entry : entity.getEntityMetaDataFormatted().entrySet()) { diff --git a/src/main/java/de/bixilon/minosoft/util/time/TimeWorker.kt b/src/main/java/de/bixilon/minosoft/util/time/TimeWorker.kt index b60369014..02eafaf9f 100644 --- a/src/main/java/de/bixilon/minosoft/util/time/TimeWorker.kt +++ b/src/main/java/de/bixilon/minosoft/util/time/TimeWorker.kt @@ -1,20 +1,25 @@ package de.bixilon.minosoft.util.time import de.bixilon.minosoft.Minosoft -import de.bixilon.minosoft.util.KUtil.synchronizedListOf -import de.bixilon.minosoft.util.KUtil.toSynchronizedList +import de.bixilon.minosoft.util.KUtil.synchronizedSetOf +import de.bixilon.minosoft.util.KUtil.toSynchronizedSet object TimeWorker { - private val TASKS: MutableList = synchronizedListOf() + private val TASKS: MutableSet = synchronizedSetOf() init { Thread({ while (true) { val currentTime = System.currentTimeMillis() - for (task in TASKS.toSynchronizedList()) { - if (currentTime - task.lastExecution >= task.interval) { - Minosoft.THREAD_POOL.execute(task.runnable) - task.lastExecution = currentTime + for (task in TASKS.toSynchronizedSet()) { + if (!task.getsExecuted && currentTime - task.lastExecution >= task.interval) { + Minosoft.THREAD_POOL.execute { + task.getsExecuted = true + task.runnable.run() + task.lastExecution = currentTime + task.getsExecuted = false + } + TASKS -= task } } Thread.sleep(1) @@ -22,6 +27,16 @@ object TimeWorker { }, "TimeWorkerThread").start() } + fun runIn(millis: Int, runnable: Runnable) { + val task = TimeWorkerTask( + interval = millis, + runnable = runnable, + runOnce = true, + ) + task.lastExecution = System.currentTimeMillis() + TASKS += task + } + fun addTask(task: TimeWorkerTask) { TASKS += task } diff --git a/src/main/java/de/bixilon/minosoft/util/time/TimeWorkerTask.kt b/src/main/java/de/bixilon/minosoft/util/time/TimeWorkerTask.kt index 22fb5077a..0361d02a6 100644 --- a/src/main/java/de/bixilon/minosoft/util/time/TimeWorkerTask.kt +++ b/src/main/java/de/bixilon/minosoft/util/time/TimeWorkerTask.kt @@ -2,7 +2,9 @@ package de.bixilon.minosoft.util.time data class TimeWorkerTask( val interval: Int, + val runOnce: Boolean = true, val runnable: Runnable, ) { + var getsExecuted: Boolean = false var lastExecution: Long = 0L }