mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 09:26:11 -04:00
minosoft meta, handle unavailable game features more gracefully, pre flattening fixes, fixes
This commit is contained in:
parent
823cd21a07
commit
cf5143d9fb
@ -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() {
|
||||
|
@ -154,7 +154,7 @@ object VerifyIntegratedBlockRegistry {
|
||||
continue
|
||||
}
|
||||
val parsed = PixLyzerBlock.deserialize(registries, identifier, value).unsafeCast<PixLyzerBlock>()
|
||||
registries.block.updateStates(parsed, value, registries)
|
||||
registries.block.flattened(parsed, value, registries)
|
||||
parsed.postInit(registries)
|
||||
parsed.inject(registries)
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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")
|
||||
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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!")
|
||||
|
@ -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)
|
||||
|
23
src/main/java/de/bixilon/minosoft/assets/meta/MetaObject.kt
Normal file
23
src/main/java/de/bixilon/minosoft/assets/meta/MetaObject.kt
Normal file
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* This software is not affiliated with Mojang AB, the original developer of Minecraft.
|
||||
*/
|
||||
|
||||
package de.bixilon.minosoft.assets.meta
|
||||
|
||||
|
||||
typealias MetaRoot = Map<String, MetaTypeEntry>
|
||||
typealias MetaTypeEntry = List<MetaVersionEntry>
|
||||
|
||||
data class MetaVersionEntry(
|
||||
val version: String,
|
||||
val hash: String,
|
||||
)
|
@ -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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* 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<MetaRoot>()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
@ -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())
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,23 @@ class BlockRegistry(
|
||||
) : Registry<Block>(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<BlockProperties, MutableSet<Any>> = mutableMapOf()
|
||||
|
||||
val states: MutableSet<BlockState> = 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
|
||||
}
|
||||
|
@ -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<String, EntityDataField> = 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) {
|
||||
|
@ -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<BlockState?>
|
||||
idMap[id] = state
|
||||
}
|
||||
|
||||
private fun _get(id: Int): BlockState? {
|
||||
return idMap[id] ?: parent.unsafeCast<BlockStateRegistry?>()?._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<BlockState?>
|
||||
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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
||||
|
||||
|
@ -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<ExplosionEvent> {
|
||||
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<ParticleSpawnEvent> {
|
||||
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<ExplosionEvent> {
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user