diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/MinosoftSIT.kt b/src/integration-test/kotlin/de/bixilon/minosoft/MinosoftSIT.kt index 8c60f6e31..1e16fc950 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/MinosoftSIT.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/MinosoftSIT.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft import de.bixilon.kutil.latch.SimpleLatch +import de.bixilon.minosoft.assets.meta.MinosoftMeta import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperties import de.bixilon.minosoft.data.registries.fallback.FallbackRegistries import de.bixilon.minosoft.data.registries.fallback.tags.FallbackTags @@ -71,6 +72,7 @@ internal object MinosoftSIT { fun loadDefaultRegistries() { FallbackTags.load() FallbackRegistries.load() + MinosoftMeta.load() } fun loadPixlyzerData() { diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/blocks/factory/VerifyIntegratedBlockRegistry.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/blocks/factory/VerifyIntegratedBlockRegistry.kt index f8bebcda1..1f1b0060f 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/blocks/factory/VerifyIntegratedBlockRegistry.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/blocks/factory/VerifyIntegratedBlockRegistry.kt @@ -154,7 +154,7 @@ object VerifyIntegratedBlockRegistry { continue } val parsed = PixLyzerBlock.deserialize(registries, identifier, value).unsafeCast() - registries.block.updateStates(parsed, value, registries) + registries.block.flattened(parsed, value, registries) parsed.postInit(registries) parsed.inject(registries) diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/RegistryLoadingTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/RegistryLoadingTest.kt index bc53c37ca..6e7e2a7ef 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/RegistryLoadingTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/RegistryLoadingTest.kt @@ -15,12 +15,14 @@ package de.bixilon.minosoft.data.registries.versions.registries import de.bixilon.minosoft.data.entities.entities.monster.Zombie import de.bixilon.minosoft.data.registries.blocks.MinecraftBlocks -import de.bixilon.minosoft.data.registries.blocks.factory.VerifyIntegratedBlockRegistry +import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.item.MinecraftItems import de.bixilon.minosoft.data.registries.registries.Registries +import de.bixilon.minosoft.protocol.protocol.ProtocolVersions.V_1_19_3 import de.bixilon.minosoft.protocol.versions.Version import de.bixilon.minosoft.protocol.versions.Versions -import org.testng.Assert +import org.testng.Assert.assertEquals +import org.testng.Assert.assertNotNull import org.testng.SkipException import org.testng.annotations.Test @@ -39,18 +41,24 @@ abstract class RegistryLoadingTest(val versionName: String) { fun testItemSimple() { - Assert.assertNotNull(registries.item[MinecraftItems.COAL]) + assertNotNull(registries.item[MinecraftItems.COAL]) } fun testBlockSimple() { - Assert.assertNotNull(registries.block[MinecraftBlocks.DIRT]) - } - - fun testBlockIntegrated() { - VerifyIntegratedBlockRegistry.verify(registries, version) + assertNotNull(registries.block[MinecraftBlocks.DIRT]) } fun testEntitySimple() { - Assert.assertNotNull(registries.entityType[Zombie]) + assertNotNull(registries.entityType[Zombie]) + } + + fun biome() { + if (version > V_1_19_3) return // biomes are datapack only in those versions -> empty registry + + assertNotNull(registries.biome[minecraft("plains")]?.identifier) + } + + fun entities() { + assertEquals(registries.entityType[minecraft("player")]?.height, 1.8f) } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_12_2.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_12_2.kt index b1cd68d5a..65c5e5ace 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_12_2.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_12_2.kt @@ -13,11 +13,7 @@ package de.bixilon.minosoft.data.registries.versions.registries.legacy -import org.testng.SkipException import org.testng.annotations.Test @Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], priority = Int.MAX_VALUE, timeOut = 15000L) -class `1_12_2` : LegacyLoadingTest("1.12.2") { - - override fun loadVersion() = throw SkipException("") -} +class `1_12_2` : LegacyLoadingTest("1.12.2") diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_7_10.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_7_10.kt index 002cb02ac..a9c61adb1 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_7_10.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_7_10.kt @@ -13,11 +13,7 @@ package de.bixilon.minosoft.data.registries.versions.registries.legacy -import org.testng.SkipException import org.testng.annotations.Test @Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], priority = Int.MAX_VALUE, timeOut = 15000L) -class `1_7_10` : LegacyLoadingTest("1.7.10") { - - override fun loadVersion() = throw SkipException("") -} +class `1_7_10` : LegacyLoadingTest("1.7.10") diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_8_9.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_8_9.kt index d9f3b0deb..db5318b2b 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_8_9.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/1_8_9.kt @@ -13,11 +13,7 @@ package de.bixilon.minosoft.data.registries.versions.registries.legacy -import org.testng.SkipException import org.testng.annotations.Test @Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], priority = Int.MAX_VALUE, timeOut = 15000L) -class `1_8_9` : LegacyLoadingTest("1.8.9") { - - override fun loadVersion() = throw SkipException("") -} +class `1_8_9` : LegacyLoadingTest("1.8.9") diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/LegacyLoadingTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/LegacyLoadingTest.kt index b2b4721b0..d201c4ada 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/LegacyLoadingTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/legacy/LegacyLoadingTest.kt @@ -13,8 +13,51 @@ package de.bixilon.minosoft.data.registries.versions.registries.legacy +import de.bixilon.minosoft.data.registries.identified.Namespaces.minecraft import de.bixilon.minosoft.data.registries.versions.registries.RegistryLoadingTest +import de.bixilon.minosoft.test.ITUtil +import org.testng.Assert.assertEquals +import org.testng.Assert.assertNull import org.testng.annotations.Test @Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], singleThreaded = false, threadPoolSize = 8, priority = Int.MAX_VALUE, timeOut = 15000L) -abstract class LegacyLoadingTest(version: String) : RegistryLoadingTest(version) +abstract class LegacyLoadingTest(version: String) : RegistryLoadingTest(version) { + + @Test(priority = 100000) + open fun loadRegistries() { + this._registries = ITUtil.loadPreFlatteningData(version) + } + + fun dimension() { + assertEquals(registries.dimension[0].identifier, minecraft("overworld")) + assertEquals(registries.dimension[1].identifier, minecraft("the_end")) + assertEquals(registries.dimension[-1].identifier, minecraft("the_nether")) + } + + + fun biomeId() { + assertEquals(registries.biome[1].identifier, minecraft("plains")) + } + + fun enchantmentId() { + assertEquals(registries.enchantment[16].identifier, minecraft("sharpness")) + } + + fun effectId() { + assertEquals(registries.statusEffect[10].identifier, minecraft("regeneration")) + } + + fun blockId() { + assertNull(registries.block.getOrNull(0)) + assertEquals(registries.block[1 shl 4 or 0].identifier, minecraft("stone")) + assertEquals(registries.block[1 shl 4 or 1].identifier, minecraft("granite")) + assertEquals(registries.block[1 shl 4 or 3].identifier, minecraft("diorite")) + assertEquals(registries.block[41 shl 4 or 0].identifier, minecraft("gold_block")) + assertEquals(registries.block[166 shl 4 or 0].identifier, minecraft("barrier")) + } + + fun itemId() { + assertEquals(registries.item[256].identifier, minecraft("iron_shovel")) + assertEquals(registries.item[2256].identifier, minecraft("music_disk")) + } +} diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/PixLyzerLoadingTest.kt b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/PixLyzerLoadingTest.kt index 9b9e4d578..58042ed49 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/PixLyzerLoadingTest.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/data/registries/versions/registries/pixlyzer/PixLyzerLoadingTest.kt @@ -13,8 +13,10 @@ package de.bixilon.minosoft.data.registries.versions.registries.pixlyzer +import de.bixilon.minosoft.data.registries.blocks.factory.VerifyIntegratedBlockRegistry import de.bixilon.minosoft.data.registries.versions.registries.RegistryLoadingTest import de.bixilon.minosoft.test.ITUtil +import org.testng.SkipException import org.testng.annotations.Test @Test(groups = ["pixlyzer"], dependsOnGroups = ["version"], priority = Int.MAX_VALUE, timeOut = 15000L) @@ -22,6 +24,11 @@ abstract class PixLyzerLoadingTest(version: String) : RegistryLoadingTest(versio @Test(priority = 100000) open fun loadRegistries() { + throw SkipException("temp") this._registries = ITUtil.loadPixlyzerData(version) } + + fun testBlockIntegrated() { + VerifyIntegratedBlockRegistry.verify(registries, version) + } } diff --git a/src/integration-test/kotlin/de/bixilon/minosoft/test/ITUtil.kt b/src/integration-test/kotlin/de/bixilon/minosoft/test/ITUtil.kt index 938e508d8..fca93a065 100644 --- a/src/integration-test/kotlin/de/bixilon/minosoft/test/ITUtil.kt +++ b/src/integration-test/kotlin/de/bixilon/minosoft/test/ITUtil.kt @@ -14,6 +14,7 @@ package de.bixilon.minosoft.test import de.bixilon.kutil.latch.SimpleLatch +import de.bixilon.minosoft.assets.properties.version.PreFlattening import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile import de.bixilon.minosoft.data.registries.VersionRegistry import de.bixilon.minosoft.data.registries.registries.PixLyzerUtil @@ -49,6 +50,10 @@ object ITUtil { return registries } + fun loadPreFlatteningData(version: Version): Registries { + return PreFlattening.loadRegistry(profile, version, CountUpAndDownLatch(0)) + } + @Deprecated("Its not implemented") fun todo() { throw SkipException("Not yet implemented!") diff --git a/src/main/java/de/bixilon/minosoft/Minosoft.kt b/src/main/java/de/bixilon/minosoft/Minosoft.kt index 3cb3cfa26..79ed27e27 100644 --- a/src/main/java/de/bixilon/minosoft/Minosoft.kt +++ b/src/main/java/de/bixilon/minosoft/Minosoft.kt @@ -31,6 +31,7 @@ import de.bixilon.kutil.shutdown.ShutdownManager import de.bixilon.kutil.time.TimeUtil.nanos import de.bixilon.kutil.unit.UnitFormatter.formatNanos import de.bixilon.minosoft.assets.file.ResourcesAssetsUtil +import de.bixilon.minosoft.assets.meta.MinosoftMeta import de.bixilon.minosoft.assets.properties.version.AssetsVersionProperties import de.bixilon.minosoft.config.profile.GlobalProfileManager import de.bixilon.minosoft.config.profile.profiles.eros.ErosProfileManager @@ -103,7 +104,7 @@ object Minosoft { taskWorker += WorkerTask(identifier = BootTasks.LANGUAGE_FILES, dependencies = arrayOf(BootTasks.PROFILES), executor = this::loadLanguageFiles) taskWorker += WorkerTask(identifier = BootTasks.ASSETS_PROPERTIES, dependencies = arrayOf(BootTasks.PROFILES), executor = AssetsVersionProperties::load) - taskWorker += WorkerTask(identifier = BootTasks.DEFAULT_REGISTRIES, dependencies = arrayOf(BootTasks.PROFILES), executor = { FallbackTags.load(); FallbackRegistries.load(); EntityEvents.load(); }) + taskWorker += WorkerTask(identifier = BootTasks.DEFAULT_REGISTRIES, dependencies = arrayOf(BootTasks.PROFILES), executor = { MinosoftMeta.load(); FallbackTags.load(); FallbackRegistries.load(); EntityEvents.load() }) taskWorker += WorkerTask(identifier = BootTasks.LAN_SERVERS, dependencies = arrayOf(BootTasks.PROFILES), executor = LANServerListener::listen) diff --git a/src/main/java/de/bixilon/minosoft/assets/meta/MetaObject.kt b/src/main/java/de/bixilon/minosoft/assets/meta/MetaObject.kt new file mode 100644 index 000000000..e5c95c032 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/assets/meta/MetaObject.kt @@ -0,0 +1,23 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.assets.meta + + +typealias MetaRoot = Map +typealias MetaTypeEntry = List + +data class MetaVersionEntry( + val version: String, + val hash: String, +) diff --git a/src/main/java/de/bixilon/minosoft/assets/meta/MinosoftMeta.kt b/src/main/java/de/bixilon/minosoft/assets/meta/MinosoftMeta.kt new file mode 100644 index 000000000..63f39392a --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/assets/meta/MinosoftMeta.kt @@ -0,0 +1,54 @@ +/* + * Minosoft + * Copyright (C) 2020-2023 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.assets.meta + +import de.bixilon.kutil.cast.CastUtil.unsafeNull +import de.bixilon.kutil.json.JsonObject +import de.bixilon.minosoft.assets.util.InputStreamUtil.readJson +import de.bixilon.minosoft.assets.util.InputStreamUtil.readJsonObject +import de.bixilon.minosoft.protocol.versions.Version +import de.bixilon.minosoft.protocol.versions.Versions +import java.io.FileInputStream + +object MinosoftMeta { + var root: MetaRoot = unsafeNull() + private set + + + fun load() { + val file = FileInputStream("/home/moritz/git/gitlab.bixilon.de/bixilon/minosoft-meta/index.json") + this.root = file.readJson() + } + + private fun MetaVersionEntry.load(type: String): JsonObject { + val file = FileInputStream("/home/moritz/git/gitlab.bixilon.de/bixilon/minosoft-meta/${this.version}/$type.json") + return file.readJsonObject() + } + + fun MetaTypeEntry.load(type: String, version: Version): JsonObject? { + var previous: MetaVersionEntry? = null + for (entry in this) { + if (entry.version == "_") { + previous = entry + continue + } + val entryVersion = Versions[entry.version] ?: throw IllegalArgumentException("Unknown meta version ${entry.version}") + if (entryVersion > version) break + previous = entry + } + if (previous == null) return null + + return previous.load(type) + } +} diff --git a/src/main/java/de/bixilon/minosoft/assets/properties/version/PreFlattening.kt b/src/main/java/de/bixilon/minosoft/assets/properties/version/PreFlattening.kt index 27baee693..c24fce932 100644 --- a/src/main/java/de/bixilon/minosoft/assets/properties/version/PreFlattening.kt +++ b/src/main/java/de/bixilon/minosoft/assets/properties/version/PreFlattening.kt @@ -13,34 +13,32 @@ package de.bixilon.minosoft.assets.properties.version +import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf +import de.bixilon.kutil.json.MutableJsonObject import de.bixilon.kutil.latch.CountUpAndDownLatch +import de.bixilon.minosoft.assets.meta.MinosoftMeta +import de.bixilon.minosoft.assets.meta.MinosoftMeta.load import de.bixilon.minosoft.config.profile.profiles.resources.ResourcesProfile -import de.bixilon.minosoft.data.entities.entities.player.RemotePlayerEntity -import de.bixilon.minosoft.data.registries.dimension.Dimension -import de.bixilon.minosoft.data.registries.dimension.DimensionProperties -import de.bixilon.minosoft.data.registries.entities.EntityType import de.bixilon.minosoft.data.registries.registries.Registries import de.bixilon.minosoft.protocol.versions.Version -import de.bixilon.minosoft.util.KUtil.toResourceLocation object PreFlattening { const val VERSION = "1.12.2" fun loadRegistry(profile: ResourcesProfile, version: Version, latch: CountUpAndDownLatch): Registries { val registries = Registries() - registries.loadEntities(version) - registries.loadDimensions() + + val json: MutableJsonObject = synchronizedMapOf() + + // val worker = UnconditionalWorker() + for ((type, data) in MinosoftMeta.root) { + // worker += { data.load(type, version) } + json[type] = data.load(type, version) ?: continue + } + // worker.work(latch) + + registries.load(version, json, latch) return registries } - - @Deprecated("test only") - private fun Registries.loadEntities(version: Version) { - entityType[RemotePlayerEntity] = EntityType(RemotePlayerEntity.identifier, null, 1.0f, 1.0f, false, false, mutableMapOf(), RemotePlayerEntity, null) - } - - @Deprecated("test only") - private fun Registries.loadDimensions() { - dimension[0] = Dimension("minecraft:overworld".toResourceLocation(), DimensionProperties()) - } } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockRegistry.kt b/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockRegistry.kt index f9259d86c..b766daca0 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockRegistry.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/blocks/BlockRegistry.kt @@ -40,7 +40,23 @@ class BlockRegistry( ) : Registry(parent = parent, codec = PixLyzerBlock, flattened = flattened, metaType = MetaTypes.BLOCK) { - fun updateStates(block: Block, data: JsonObject, registries: Registries) { + private fun legacy(block: Block, data: JsonObject, registries: Registries) { + val json = data["states"] + val id = data["id"]?.toInt() + val meta = data["meta"]?.toInt() + if (json == null) { + // block has only a single state + val settings = BlockStateSettings.of(registries, data) + val state = if (block is BlockStateBuilder) block.buildState(settings) else AdvancedBlockState(block, settings) + block.updateStates(setOf(state), state, emptyMap()) + registries.blockState[id!! shl 4 or (meta ?: 0)] = state + return + } + + println("TODO") + } + + fun flattened(block: Block, data: JsonObject, registries: Registries) { val properties: MutableMap> = mutableMapOf() val states: MutableSet = ObjectOpenHashSet() @@ -69,7 +85,11 @@ class BlockRegistry( val block = factory?.build(registries, BlockSettings.of(registries, data)) ?: this.codec!!.deserialize(registries, resourceLocation, data) ?: return null - updateStates(block, data, registries) + if (flattened) { + flattened(block, data, registries) + } else { + legacy(block, data, registries) + } return block } diff --git a/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt b/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt index d77c14297..ad57daf92 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/entities/EntityType.kt @@ -37,6 +37,7 @@ import de.bixilon.minosoft.util.KUtil.toResourceLocation import de.bixilon.minosoft.util.logging.Log import de.bixilon.minosoft.util.logging.LogLevels import de.bixilon.minosoft.util.logging.LogMessageType +import de.bixilon.minosoft.util.nbt.tag.NBTUtil.get import java.lang.reflect.Modifier import java.util.* import kotlin.reflect.KProperty1 @@ -68,11 +69,11 @@ data class EntityType( check(registries != null) { "Registries is null!" } val factory = DefaultEntityFactories[resourceLocation] - data["meta"]?.toJsonObject()?.let { + data["meta", "data"]?.toJsonObject()?.let { val fields: MutableMap = mutableMapOf() val dataClass = DefaultEntityFactories.ABSTRACT_ENTITY_DATA_CLASSES[resourceLocation]?.companionObject ?: if (factory != null) factory::class else null if (dataClass == null) { - Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Can not find class for entity data ($resourceLocation)" } + Log.log(LogMessageType.LOADING, LogLevels.VERBOSE) { "Can not find entity data class for $resourceLocation, fields $it" } return@let } for (member in dataClass.members) { diff --git a/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/BlockStateRegistry.kt b/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/BlockStateRegistry.kt index c5c2f36fe..d6232b9f0 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/BlockStateRegistry.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/BlockStateRegistry.kt @@ -13,6 +13,7 @@ package de.bixilon.minosoft.data.registries.registries.registry +import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.exception.Broken import de.bixilon.kutil.json.JsonObject import de.bixilon.minosoft.data.registries.blocks.state.BlockState @@ -54,14 +55,15 @@ class BlockStateRegistry(var flattened: Boolean) : AbstractRegistry idMap[id] = state } + private fun _get(id: Int): BlockState? { + return idMap[id] ?: parent.unsafeCast()?._get(id) + } + fun forceGet(id: Int): BlockState? { - return idMap[id] ?: parent?.getOrNull(id) ?: let { - if (flattened) { - null - } else { - idMap[(id shr 4) shl 4] // Remove metadata and test again - } - } + val state = _get(id) + if (state != null) return state + + return _get((id shr 4) shl 4) // Remove meta and try again } @Deprecated("Use getOrNull", ReplaceWith("getOrNull(id)")) @@ -74,6 +76,7 @@ class BlockStateRegistry(var flattened: Boolean) : AbstractRegistry if (id == ProtocolDefinition.AIR_BLOCK_ID) { return null } + if (!flattened && id shr 4 == ProtocolDefinition.AIR_BLOCK_ID) return null val state = forceGet(id) ?: return null if (state.block is AirBlock) { return null diff --git a/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/MetaTypes.kt b/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/MetaTypes.kt index 71186c20a..3b217724b 100644 --- a/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/MetaTypes.kt +++ b/src/main/java/de/bixilon/minosoft/data/registries/registries/registry/MetaTypes.kt @@ -22,6 +22,6 @@ enum class MetaTypes(val bits: Int) { private val metaMask = (1 shl bits) - 1 fun modify(id: Int, meta: Int): Int { - return (id shr bits) or (meta and metaMask) + return (id shl bits) or (meta and metaMask) } } diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarAirElement.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarAirElement.kt index 168f64dec..7148d0f22 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarAirElement.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/gui/hud/elements/hotbar/HotbarAirElement.kt @@ -26,7 +26,6 @@ import de.bixilon.minosoft.gui.rendering.gui.mesh.GUIVertexOptions import de.bixilon.minosoft.gui.rendering.util.vec.vec2.Vec2Util.EMPTY class HotbarAirElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollable { - private val water = guiRenderer.context.connection.registries.fluid[WaterFluid]!! private val airBubble = guiRenderer.atlasManager["minecraft:air_bubble"] private val poppingAirBubble = guiRenderer.atlasManager["minecraft:popping_air_bubble"] @@ -65,7 +64,7 @@ class HotbarAirElement(guiRenderer: GUIRenderer) : Element(guiRenderer), Pollabl var bubbles = 0 var poppingCount = 0 - if (submergedFluid == water || (air in 1 until FULL_AIR)) { + if (submergedFluid is WaterFluid || (air in 1 until FULL_AIR)) { bubbles = ((air - 2) / AIR_PER_BUBBLE.toFloat()).ceil // 2 ticks for the popping "animation" diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt index da48d80b1..71276f369 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/particle/DefaultParticleBehavior.kt @@ -15,6 +15,7 @@ package de.bixilon.minosoft.gui.rendering.particle import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kutil.concurrent.pool.DefaultThreadPool +import de.bixilon.minosoft.config.profile.profiles.particle.ParticleProfile import de.bixilon.minosoft.gui.rendering.particle.types.norender.ExplosionEmitterParticle import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.explosion.ExplosionParticle import de.bixilon.minosoft.gui.rendering.util.VecUtil.times @@ -22,30 +23,21 @@ import de.bixilon.minosoft.modding.event.events.ExplosionEvent import de.bixilon.minosoft.modding.event.events.ParticleSpawnEvent import de.bixilon.minosoft.modding.event.listener.CallbackEventListener import de.bixilon.minosoft.protocol.network.connection.play.PlayConnection +import java.util.* object DefaultParticleBehavior { - fun register(connection: PlayConnection, particleRenderer: ParticleRenderer) { - val random = java.util.Random() - val explosionParticleType = connection.registries.particleType[ExplosionParticle]!! - val explosionEmitterParticleType = connection.registries.particleType[ExplosionEmitterParticle]!! - val typesConfig = connection.profiles.particle.types + fun register(connection: PlayConnection, renderer: ParticleRenderer) { + val random = Random() + val profile = connection.profiles.particle val invokers = listOf( - CallbackEventListener.of { - if (!typesConfig.explosions) { - return@of - } - if (it.power >= 2.0f) { - particleRenderer += ExplosionEmitterParticle(connection, Vec3d(it.position), explosionEmitterParticleType.default()) - } else { - particleRenderer += ExplosionParticle(connection, Vec3d(it.position), explosionParticleType.default()) - } - }, + connection.explosion(renderer, random, profile), + CallbackEventListener.of { DefaultThreadPool += add@{ fun spawn(position: Vec3d, velocity: Vec3d) { val factory = it.data.type.factory ?: return - particleRenderer += factory.build(connection, position, velocity, it.data) ?: return + renderer += factory.build(connection, position, velocity, it.data) ?: return } // ToDo: long distance = always spawn? if (it.count == 0) { @@ -63,7 +55,22 @@ object DefaultParticleBehavior { } }, ) + connection.events.register(*invokers.filterNotNull().toTypedArray()) + } - connection.events.register(*invokers.toTypedArray()) + private fun PlayConnection.explosion(renderer: ParticleRenderer, random: Random, profile: ParticleProfile): CallbackEventListener<*>? { + val explosion = registries.particleType[ExplosionParticle] ?: return null + val emitter = registries.particleType[ExplosionEmitterParticle] ?: return null + + return CallbackEventListener.of { + if (!profile.types.explosions) { + return@of + } + if (it.power >= 2.0f) { + renderer += ExplosionEmitterParticle(this, Vec3d(it.position), emitter.default()) + } else { + renderer += ExplosionParticle(this, Vec3d(it.position), explosion.default()) + } + } } }