From 0161e4ef290b417eef2862bcd78cad7a15103c2d Mon Sep 17 00:00:00 2001 From: Bixilon Date: Mon, 15 Mar 2021 15:41:17 +0100 Subject: [PATCH] materials, WannabeBlockState, fix some multipart rendering issues --- .../data/commands/parser/BlockStateParser.kt | 5 +- .../minosoft/data/mappings/blocks/Block.kt | 2 +- .../data/mappings/blocks/BlockState.kt | 68 +++++++++---------- .../data/mappings/blocks/WannabeBlockState.kt | 22 ++++++ .../data/mappings/materials/Material.kt | 54 +++++++++++++++ .../data/mappings/materials/PushReactions.kt | 20 ++++++ .../data/mappings/tweaker/TweakBlocks.kt | 7 +- .../data/mappings/tweaker/VersionTweaker.kt | 13 +--- .../data/mappings/versions/VersionMapping.kt | 4 ++ .../chunk/models/loading/BlockCondition.kt | 8 ++- 10 files changed, 147 insertions(+), 56 deletions(-) create mode 100644 src/main/java/de/bixilon/minosoft/data/mappings/blocks/WannabeBlockState.kt create mode 100644 src/main/java/de/bixilon/minosoft/data/mappings/materials/Material.kt create mode 100644 src/main/java/de/bixilon/minosoft/data/mappings/materials/PushReactions.kt diff --git a/src/main/java/de/bixilon/minosoft/data/commands/parser/BlockStateParser.kt b/src/main/java/de/bixilon/minosoft/data/commands/parser/BlockStateParser.kt index 14e84f8f9..dd7b179f9 100644 --- a/src/main/java/de/bixilon/minosoft/data/commands/parser/BlockStateParser.kt +++ b/src/main/java/de/bixilon/minosoft/data/commands/parser/BlockStateParser.kt @@ -17,6 +17,7 @@ import de.bixilon.minosoft.data.commands.parser.exceptions.* import de.bixilon.minosoft.data.commands.parser.properties.ParserProperties import de.bixilon.minosoft.data.mappings.blocks.BlockRotations import de.bixilon.minosoft.data.mappings.blocks.BlockState +import de.bixilon.minosoft.data.mappings.blocks.WannabeBlockState import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties import de.bixilon.minosoft.protocol.network.Connection @@ -59,13 +60,13 @@ class BlockStateParser : CommandParser() { allProperties[parsedGroup] = parsedValue } for (state in block.states) { - if (state.bareEquals(BlockState(block, allProperties, rotation ?: BlockRotations.NONE))) { + if (state.equals(WannabeBlockState(block.resourceLocation, allProperties, rotation))) { blockState = state break } } } else { - blockState = BlockState(block) + blockState = block.states.iterator().next() } check(blockState != null) { throw BlockNotFoundCommandParseException(stringReader, resourceLocation.key) diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/Block.kt b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/Block.kt index 377b534d8..c3b195fe8 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/Block.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/Block.kt @@ -73,7 +73,7 @@ data class Block( for ((stateId, stateJson) in data["states"].asJsonObject.entrySet()) { check(stateJson is JsonObject) { "Not a state element!" } - val state = BlockState.deserialize(block, stateJson, mappings.models) + val state = BlockState.deserialize(block, mappings, stateJson, mappings.models) mappings.blockStateIdMap[stateId.toInt()] = state } return block diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt index 7e6e27cea..37de0bf71 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/BlockState.kt @@ -18,6 +18,8 @@ import com.google.gson.JsonPrimitive import de.bixilon.minosoft.Minosoft import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties +import de.bixilon.minosoft.data.mappings.materials.Material +import de.bixilon.minosoft.data.mappings.versions.VersionMapping import de.bixilon.minosoft.data.text.RGBColor import de.bixilon.minosoft.data.world.BlockPosition import de.bixilon.minosoft.gui.rendering.TintColorCalculator @@ -34,6 +36,7 @@ data class BlockState( val rotation: BlockRotations = BlockRotations.NONE, val renders: Set = setOf(), val tintColor: RGBColor? = null, + val material: Material, ) { override fun hashCode(): Int { @@ -47,6 +50,27 @@ data class BlockState( if (other == null) { return false } + if (other is WannabeBlockState) { + if (owner.resourceLocation != other.resourceLocation) { + return false + } + + other.rotation?.let { + if (rotation != it) { + return false + } + } + other.properties?.let { + for ((state, value) in it) { + if (properties[state] != value) { + return false + } + } + } + + return true + } + if (hashCode() != other.hashCode()) { return false } @@ -59,36 +83,6 @@ data class BlockState( return false } - fun bareEquals(obj: Any): Boolean { - if (this === obj) { - return true - } - if (obj is BlockState) { - if (owner.resourceLocation.namespace != obj.owner.resourceLocation.namespace || owner.resourceLocation.path != obj.owner.resourceLocation.path) { - return false - } - if (obj.rotation != BlockRotations.NONE) { - if (obj.rotation != rotation) { - return false - } - } - for ((property, value) in obj.properties) { - properties[property]?.let { - if (it != value) { - return false - } - } ?: return false - - return true - } - } - return if (obj is ResourceLocation) { - super.equals(obj) - } else { - false - } - } - override fun toString(): String { val out = StringBuilder() if (rotation != BlockRotations.NONE) { @@ -123,12 +117,12 @@ data class BlockState( companion object { val ROTATION_PROPERTIES = setOf("facing", "rotation", "orientation", "axis") - val SPECIAL_RENDERERS = mutableMapOf( - Pair("water", FluidRenderer("block/water_still", "block/water_flow", "water")), - Pair("lava", FluidRenderer("block/lava_still", "block/lava_flow", "lava")), - ) + private val SPECIAL_RENDERERS = mutableMapOf( + "water" to FluidRenderer("block/water_still", "block/water_flow", "water"), + "lava" to FluidRenderer("block/lava_still", "block/lava_flow", "lava"), + ) // ToDo: Don't like this - fun deserialize(owner: Block, data: JsonObject, models: Map): BlockState { + fun deserialize(owner: Block, versionMapping: VersionMapping, data: JsonObject, models: Map): BlockState { val (rotation, properties) = data["properties"]?.asJsonObject?.let { getProperties(it) } ?: Pair(BlockRotations.NONE, mutableMapOf()) @@ -168,12 +162,14 @@ data class BlockState( } } + val material = versionMapping.materialRegistry.get(ResourceLocation(data["material"].asString))!! return BlockState( owner = owner, properties = properties.toMap(), rotation = rotation, renders = renders.toSet(), - tintColor = tintColor + tintColor = tintColor, + material = material, ) } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/blocks/WannabeBlockState.kt b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/WannabeBlockState.kt new file mode 100644 index 000000000..d779b849c --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/mappings/blocks/WannabeBlockState.kt @@ -0,0 +1,22 @@ +/* + * Minosoft + * Copyright (C) 2020 Moritz Zwerger, Lukas Eisenhauer + * + * 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.data.mappings.blocks + +import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties + +data class WannabeBlockState( + val resourceLocation: ResourceLocation, + val properties: Map? = null, + val rotation: BlockRotations? = null, +) diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/materials/Material.kt b/src/main/java/de/bixilon/minosoft/data/mappings/materials/Material.kt new file mode 100644 index 000000000..6d580f0b9 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/mappings/materials/Material.kt @@ -0,0 +1,54 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ +package de.bixilon.minosoft.data.mappings.materials + +import com.google.gson.JsonObject +import de.bixilon.minosoft.data.mappings.RegistryItem +import de.bixilon.minosoft.data.mappings.ResourceLocation +import de.bixilon.minosoft.data.mappings.ResourceLocationDeserializer +import de.bixilon.minosoft.data.mappings.versions.VersionMapping +import de.bixilon.minosoft.data.text.RGBColor +import de.bixilon.minosoft.gui.rendering.TintColorCalculator + +data class Material( + val resourceLocation: ResourceLocation, + val color: RGBColor?, + val pushReaction: PushReactions, + val blockMotion: Boolean, + val flammable: Boolean, + val liquid: Boolean, + val solidBlocking: Boolean, + val replaceable: Boolean, + val solid: Boolean, +) : RegistryItem { + + override fun toString(): String { + return resourceLocation.toString() + } + + companion object : ResourceLocationDeserializer { + override fun deserialize(mappings: VersionMapping, resourceLocation: ResourceLocation, data: JsonObject): Material { + return Material( + resourceLocation = resourceLocation, + color = TintColorCalculator.getJsonColor(data["color"]?.asInt ?: 0), + pushReaction = data["push_reaction"]?.asString?.let { PushReactions.valueOf(it.toUpperCase()) } ?: PushReactions.NORMAL, + blockMotion = data["blocks_motion"]?.asBoolean ?: false, + flammable = data["flammable"]?.asBoolean ?: false, + liquid = data["liquid"]?.asBoolean ?: false, + solidBlocking = data["solid_blocking"]?.asBoolean ?: false, + replaceable = data["replaceable"]?.asBoolean ?: false, + solid = data["solid"]?.asBoolean ?: false, + ) + } + } +} diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/materials/PushReactions.kt b/src/main/java/de/bixilon/minosoft/data/mappings/materials/PushReactions.kt new file mode 100644 index 000000000..8a1c48fa5 --- /dev/null +++ b/src/main/java/de/bixilon/minosoft/data/mappings/materials/PushReactions.kt @@ -0,0 +1,20 @@ +/* + * 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 . + * + * This software is not affiliated with Mojang AB, the original developer of Minecraft. + */ + +package de.bixilon.minosoft.data.mappings.materials + +enum class PushReactions { + NORMAL, + DESTROY, + BLOCK, +} diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/TweakBlocks.kt b/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/TweakBlocks.kt index 4eb606447..f884fcc3c 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/TweakBlocks.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/TweakBlocks.kt @@ -13,13 +13,12 @@ package de.bixilon.minosoft.data.mappings.tweaker import de.bixilon.minosoft.data.mappings.ResourceLocation -import de.bixilon.minosoft.data.mappings.blocks.Block -import de.bixilon.minosoft.data.mappings.blocks.BlockState +import de.bixilon.minosoft.data.mappings.blocks.WannabeBlockState import de.bixilon.minosoft.data.mappings.blocks.properties.BlockProperties object TweakBlocks { - val GRASS_BLOCK_SNOWY_YES = BlockState(Block(ResourceLocation("grass")), mapOf(BlockProperties.SNOWY to true)) - val GRASS_BLOCK_SNOWY_NO = BlockState(Block(ResourceLocation("grass")), mapOf(BlockProperties.SNOWY to false)) + val GRASS_BLOCK_SNOWY_YES = WannabeBlockState(ResourceLocation("grass"), mapOf(BlockProperties.SNOWY to true)) + val GRASS_BLOCK_SNOWY_NO = WannabeBlockState(ResourceLocation("grass"), mapOf(BlockProperties.SNOWY to false)) val SNOW_RESOURCE_LOCATION = ResourceLocation("snow") val SNOW_LAYER_RESOURCE_LOCAION = ResourceLocation("snow_layer") diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt b/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt index e071ac38b..3991aa09c 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/tweaker/VersionTweaker.kt @@ -18,7 +18,6 @@ import de.bixilon.minosoft.data.entities.entities.Entity import de.bixilon.minosoft.data.entities.entities.animal.horse.* import de.bixilon.minosoft.data.entities.entities.monster.* import de.bixilon.minosoft.data.entities.entities.vehicle.* -import de.bixilon.minosoft.data.mappings.ResourceLocation import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.world.ChunkSection import de.bixilon.minosoft.data.world.InChunkSectionPosition @@ -111,19 +110,9 @@ object VersionTweaker { } - // ToDo: Broken @JvmStatic fun transformBlock(originalBlock: BlockState, sections: Map, position: InChunkSectionPosition, sectionHeight: Int): BlockState? { - when (originalBlock.owner.resourceLocation) { - ResourceLocation("minecraft:grass") -> { - getBlockAbove(sections, position, sectionHeight)?.let { - if (it.owner.resourceLocation == TweakBlocks.SNOW_RESOURCE_LOCATION || it.owner.resourceLocation == TweakBlocks.SNOW_LAYER_RESOURCE_LOCAION) { - return TweakBlocks.GRASS_BLOCK_SNOWY_YES - } - } - return TweakBlocks.GRASS_BLOCK_SNOWY_NO - } - } + // ToDo: Broken return originalBlock } diff --git a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt index ebf9ba079..ceadb2a6d 100644 --- a/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt +++ b/src/main/java/de/bixilon/minosoft/data/mappings/versions/VersionMapping.kt @@ -25,6 +25,7 @@ import de.bixilon.minosoft.data.mappings.biomes.BiomePrecipation import de.bixilon.minosoft.data.mappings.blocks.Block import de.bixilon.minosoft.data.mappings.blocks.BlockState import de.bixilon.minosoft.data.mappings.items.ItemRegistry +import de.bixilon.minosoft.data.mappings.materials.Material import de.bixilon.minosoft.data.mappings.particle.Particle import de.bixilon.minosoft.data.mappings.statistics.Statistic import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel @@ -44,6 +45,7 @@ class VersionMapping(var version: Version?) { val statisticRegistry: Registry = Registry() val biomeRegistry: Registry = Registry() val dimensionRegistry: Registry = Registry() + val materialRegistry: Registry = Registry() val biomePrecipitationRegistry: EnumRegistry = EnumRegistry() val biomeCategoryRegistry: EnumRegistry = EnumRegistry() @@ -78,6 +80,7 @@ class VersionMapping(var version: Version?) { dimensionRegistry.setParent(value?.dimensionRegistry) biomePrecipitationRegistry.setParent(value?.biomePrecipitationRegistry) biomeCategoryRegistry.setParent(value?.biomeCategoryRegistry) + materialRegistry.setParent(value?.materialRegistry) } fun getBlockState(blockState: Int): BlockState? { @@ -108,6 +111,7 @@ class VersionMapping(var version: Version?) { biomePrecipitationRegistry.initialize(pixlyzerData["biome_precipations"]?.asJsonObject, this, BiomePrecipation.Companion) // id resource location stuff + materialRegistry.initialize(pixlyzerData["materials"]?.asJsonObject, this, Material.Companion) motiveRegistry.initialize(pixlyzerData["motives"]?.asJsonObject, this, Motive.Companion, version!!.isFlattened()) blockRegistry.initialize(pixlyzerData["blocks"]?.asJsonObject, this, Block.Companion, version!!.isFlattened(), Registry.MetaTypes.BITS_4) itemRegistry.initialize(pixlyzerData["items"]?.asJsonObject, this, Item.Companion, version!!.isFlattened(), Registry.MetaTypes.BITS_16) diff --git a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockCondition.kt b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockCondition.kt index 592bf05d4..6dcf686f1 100644 --- a/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockCondition.kt +++ b/src/main/java/de/bixilon/minosoft/gui/rendering/chunk/models/loading/BlockCondition.kt @@ -94,9 +94,15 @@ open class BlockCondition { } outerLoop@ for (propertiesSubSet in blockProperties) { for (properties in propertiesSubSet) { - if (testProperties.keys.intersect(properties.keys).isEmpty()) { // ToDo: Just keys or also values??? + val intersects = testProperties.keys.intersect(properties.keys) + if (intersects.isEmpty()) { // ToDo: Improve this continue@outerLoop } + for (intersect in intersects) { + if (testProperties[intersect] != properties[intersect]) { + continue@outerLoop + } + } } return true }