mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-17 11:24:56 -04:00
store block entity type in block
This commit is contained in:
parent
93dc93eea7
commit
fc04dc9235
@ -17,6 +17,7 @@ import de.bixilon.minosoft.data.entities.block.container.*
|
||||
import de.bixilon.minosoft.data.entities.block.container.storage.*
|
||||
import de.bixilon.minosoft.data.entities.block.piston.PistonBlockEntity
|
||||
import de.bixilon.minosoft.data.entities.block.piston.StickyPistonBlockEntity
|
||||
import de.bixilon.minosoft.data.mappings.MultiResourceLocationAble
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
|
||||
@ -67,6 +68,11 @@ object DefaultBlockEntityMetaDataFactory {
|
||||
|
||||
for (entityFactory in entityFactories) {
|
||||
ret[entityFactory.RESOURCE_LOCATION] = entityFactory
|
||||
if (entityFactory is MultiResourceLocationAble) {
|
||||
for (resourceLocation in entityFactory.ALIASES) {
|
||||
ret[resourceLocation] = entityFactory
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLOCK_ENTITY_FACTORY_MAP = ret.toMap()
|
||||
|
@ -14,14 +14,23 @@
|
||||
package de.bixilon.minosoft.data.entities.block.container.storage
|
||||
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
|
||||
import de.bixilon.minosoft.data.mappings.MultiResourceLocationAble
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.util.KUtil.toResourceLocationList
|
||||
|
||||
class ShulkerBoxBlockEntity(connection: PlayConnection) : StorageBlockEntity(connection) {
|
||||
|
||||
|
||||
companion object : BlockEntityFactory<ShulkerBoxBlockEntity> {
|
||||
companion object : BlockEntityFactory<ShulkerBoxBlockEntity>, MultiResourceLocationAble {
|
||||
override val RESOURCE_LOCATION: ResourceLocation = ResourceLocation("minecraft:shulker_box")
|
||||
override val ALIASES: Set<ResourceLocation> = setOf(
|
||||
"minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box",
|
||||
"minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box",
|
||||
"minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box",
|
||||
"minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box",
|
||||
).toResourceLocationList()
|
||||
|
||||
|
||||
override fun build(connection: PlayConnection): ShulkerBoxBlockEntity {
|
||||
return ShulkerBoxBlockEntity(connection)
|
||||
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
interface MultiResourceLocationAble {
|
||||
val ALIASES: Set<ResourceLocation>
|
||||
}
|
@ -14,6 +14,7 @@ package de.bixilon.minosoft.data.mappings.blocks
|
||||
|
||||
import com.google.gson.JsonObject
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.entites.BlockEntityType
|
||||
import de.bixilon.minosoft.data.mappings.items.Item
|
||||
import de.bixilon.minosoft.data.mappings.registry.RegistryItem
|
||||
import de.bixilon.minosoft.data.mappings.registry.ResourceLocationDeserializer
|
||||
@ -22,12 +23,14 @@ import de.bixilon.minosoft.data.text.RGBColor
|
||||
import de.bixilon.minosoft.gui.rendering.TintColorCalculator
|
||||
import de.bixilon.minosoft.gui.rendering.chunk.models.renderable.BlockLikeRenderer
|
||||
|
||||
open class Block(override val resourceLocation: ResourceLocation, mappings: VersionMapping, data: JsonObject) : RegistryItem {
|
||||
open class Block(final override val resourceLocation: ResourceLocation, mappings: VersionMapping, data: JsonObject) : RegistryItem {
|
||||
open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f
|
||||
open val tintColor: RGBColor? = data["tint_color"]?.asInt?.let { TintColorCalculator.getJsonColor(it) }
|
||||
open val randomOffsetType: RandomOffsetTypes? = data["offset_type"]?.asString?.let { RandomOffsetTypes[it] }
|
||||
open val tint: ResourceLocation? = data["tint"]?.asString?.let { ResourceLocation(it) }
|
||||
open val renderOverride: List<BlockLikeRenderer>? = null
|
||||
open var blockEntityType: BlockEntityType? = null
|
||||
protected set
|
||||
|
||||
private val itemId: Int = data["item"]?.asInt ?: 0
|
||||
|
||||
@ -39,7 +42,8 @@ open class Block(override val resourceLocation: ResourceLocation, mappings: Vers
|
||||
protected set
|
||||
|
||||
override fun postInit(versionMapping: VersionMapping) {
|
||||
item = versionMapping.itemRegistry.get(itemId)
|
||||
item = versionMapping.itemRegistry[itemId]
|
||||
blockEntityType = versionMapping.blockEntityTypeRegistry.getByBlock(this)
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
|
@ -18,6 +18,7 @@ import de.bixilon.minosoft.data.entities.block.BlockEntity
|
||||
import de.bixilon.minosoft.data.entities.block.BlockEntityFactory
|
||||
import de.bixilon.minosoft.data.entities.block.DefaultBlockEntityMetaDataFactory
|
||||
import de.bixilon.minosoft.data.mappings.ResourceLocation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.registry.RegistryItem
|
||||
import de.bixilon.minosoft.data.mappings.registry.ResourceLocationDeserializer
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
@ -25,9 +26,22 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
|
||||
data class BlockEntityType(
|
||||
override val resourceLocation: ResourceLocation,
|
||||
// ToDo: Block ids, more?
|
||||
private var blockIds: Set<Int>?,
|
||||
val factory: BlockEntityFactory<out BlockEntity>,
|
||||
) : RegistryItem {
|
||||
lateinit var blocks: Set<Block>
|
||||
private set
|
||||
|
||||
override fun postInit(versionMapping: VersionMapping) {
|
||||
val blocks: MutableSet<Block> = mutableSetOf()
|
||||
|
||||
for (blockId in blockIds!!) {
|
||||
blocks += versionMapping.blockRegistry[blockId]
|
||||
}
|
||||
this.blockIds = null
|
||||
|
||||
this.blocks = blocks.toSet()
|
||||
}
|
||||
|
||||
fun build(connection: PlayConnection): BlockEntity {
|
||||
return DefaultBlockEntityMetaDataFactory.buildBlockEntity(factory, connection)
|
||||
@ -37,8 +51,15 @@ data class BlockEntityType(
|
||||
override fun deserialize(mappings: VersionMapping?, resourceLocation: ResourceLocation, data: JsonObject): BlockEntityType? {
|
||||
val factory = DefaultBlockEntityMetaDataFactory.getEntityFactory(resourceLocation) ?: return null // ToDo
|
||||
|
||||
val blockIds: MutableSet<Int> = mutableSetOf()
|
||||
|
||||
for (blockId in data["blocks"].asJsonArray) {
|
||||
blockIds += blockId.asInt
|
||||
}
|
||||
|
||||
return BlockEntityType(
|
||||
resourceLocation = resourceLocation,
|
||||
blockIds = blockIds,
|
||||
factory = factory,
|
||||
)
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.entites
|
||||
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.registry.Registry
|
||||
import de.bixilon.minosoft.data.mappings.versions.VersionMapping
|
||||
|
||||
class BlockEntityTypeRegistry(
|
||||
private val versionMapping: VersionMapping,
|
||||
private var parentRegistry: BlockEntityTypeRegistry? = null,
|
||||
) : Registry<BlockEntityType>() {
|
||||
private lateinit var blockTypeMap: MutableMap<Block, BlockEntityType>
|
||||
|
||||
fun getByBlock(block: Block): BlockEntityType? {
|
||||
return blockTypeMap[block] ?: parentRegistry?.getByBlock(block)
|
||||
}
|
||||
|
||||
fun setParent(parent: BlockEntityTypeRegistry?) {
|
||||
super.setParent(parent)
|
||||
this.parentRegistry = parent
|
||||
}
|
||||
|
||||
override fun postInit(versionMapping: VersionMapping) {
|
||||
super.postInit(versionMapping)
|
||||
blockTypeMap = mutableMapOf()
|
||||
for ((_, type) in resourceLocationMap) {
|
||||
for (block in type.blocks) {
|
||||
blockTypeMap[block] = type
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -23,20 +23,20 @@ open class Registry<T : RegistryItem>(
|
||||
private var parentRegistry: Registry<T>? = null,
|
||||
) : Iterable<T>, Clearable, Parentable<Registry<T>> {
|
||||
private var initialized = false
|
||||
private val idValueMap: MutableMap<Int, T> = mutableMapOf()
|
||||
private val valueIdMap: MutableMap<T, Int> = mutableMapOf()
|
||||
private val resourceLocationMap: MutableMap<ResourceLocation, T> = mutableMapOf()
|
||||
protected val idValueMap: MutableMap<Int, T> = mutableMapOf()
|
||||
protected val valueIdMap: MutableMap<T, Int> = mutableMapOf()
|
||||
protected val resourceLocationMap: MutableMap<ResourceLocation, T> = mutableMapOf()
|
||||
|
||||
|
||||
open fun get(resourceLocation: ResourceLocation): T? {
|
||||
open operator fun get(resourceLocation: ResourceLocation): T? {
|
||||
return resourceLocationMap[resourceLocation] ?: parentRegistry?.get(resourceLocation)
|
||||
}
|
||||
|
||||
open fun get(resourceLocation: String): T? {
|
||||
open operator fun get(resourceLocation: String): T? {
|
||||
return get(ResourceLocation.getPathResourceLocation(resourceLocation))
|
||||
}
|
||||
|
||||
open fun get(id: Int): T {
|
||||
open operator fun get(id: Int): T {
|
||||
return idValueMap[id] ?: parentRegistry?.get(id)!!
|
||||
}
|
||||
|
||||
@ -95,7 +95,7 @@ open class Registry<T : RegistryItem>(
|
||||
}
|
||||
|
||||
|
||||
fun postInit(versionMapping: VersionMapping) {
|
||||
open fun postInit(versionMapping: VersionMapping) {
|
||||
for ((_, value) in resourceLocationMap) {
|
||||
value.postInit(versionMapping)
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ import de.bixilon.minosoft.data.mappings.biomes.BiomePrecipitation
|
||||
import de.bixilon.minosoft.data.mappings.blocks.Block
|
||||
import de.bixilon.minosoft.data.mappings.blocks.BlockState
|
||||
import de.bixilon.minosoft.data.mappings.blocks.entites.BlockEntityType
|
||||
import de.bixilon.minosoft.data.mappings.blocks.entites.BlockEntityTypeRegistry
|
||||
import de.bixilon.minosoft.data.mappings.effects.StatusEffect
|
||||
import de.bixilon.minosoft.data.mappings.entities.EntityType
|
||||
import de.bixilon.minosoft.data.mappings.entities.villagers.VillagerProfession
|
||||
@ -92,7 +93,7 @@ class VersionMapping {
|
||||
val entityMetaIndexMap: MutableMap<EntityMetaDataFields, Int> = mutableMapOf()
|
||||
val entityRegistry: Registry<EntityType> = Registry()
|
||||
|
||||
val blockEntityRegistry: Registry<BlockEntityType> = Registry()
|
||||
val blockEntityTypeRegistry = BlockEntityTypeRegistry(this)
|
||||
val blockEntityMetaDataTypeRegistry: Registry<BlockEntityMetaType> = Registry()
|
||||
|
||||
val containerTypeRegistry: Registry<ContainerType> = Registry()
|
||||
@ -173,6 +174,8 @@ class VersionMapping {
|
||||
containerTypeRegistry.initialize(pixlyzerData["container_types"]?.asJsonObject, this, ContainerType, alternative = DefaultRegistries.CONTAINER_TYPE_REGISTRY.forVersion(version))
|
||||
gameEventRegistry.initialize(pixlyzerData["game_events"]?.asJsonObject, this, GameEvent, alternative = DefaultRegistries.GAME_EVENT_REGISTRY.forVersion(version))
|
||||
|
||||
blockEntityTypeRegistry.initialize(pixlyzerData["block_entities"]?.asJsonObject, this, BlockEntityType)
|
||||
|
||||
soundEventRegistry.initialize(pixlyzerData["sound_events"]?.asJsonObject, this, SoundEvent)
|
||||
particleTypeRegistry.initialize(pixlyzerData["particles"]?.asJsonObject, this, ParticleType)
|
||||
materialRegistry.initialize(pixlyzerData["materials"]?.asJsonObject, this, Material)
|
||||
@ -189,13 +192,14 @@ class VersionMapping {
|
||||
|
||||
entityRegistry.initialize(pixlyzerData["entities"]?.asJsonObject, this, EntityType)
|
||||
|
||||
blockEntityRegistry.initialize(pixlyzerData["block_entities"]?.asJsonObject, this, BlockEntityType)
|
||||
blockEntityMetaDataTypeRegistry.initialize(pixlyzerData["block_entity_meta_data_types"]?.asJsonObject, this, BlockEntityMetaType, alternative = DefaultRegistries.BLOCK_ENTITY_META_TYPE_REGISTRY.forVersion(version))
|
||||
|
||||
|
||||
// post init
|
||||
biomeRegistry.postInit(this)
|
||||
fluidRegistry.postInit(this)
|
||||
blockEntityTypeRegistry.postInit(this)
|
||||
blockRegistry.postInit(this)
|
||||
isFullyLoaded = true
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ class BlockOutlineRenderer(
|
||||
}
|
||||
|
||||
if (connection.player.entity.gamemode == Gamemodes.ADVENTURE || connection.player.entity.gamemode == Gamemodes.SPECTATOR) {
|
||||
if (connection.mapping.blockEntityRegistry.get(raycastHit.blockState.block.resourceLocation) == null) {
|
||||
if (raycastHit.blockState.block.blockEntityType == null) {
|
||||
unload()
|
||||
return
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
|
||||
import de.bixilon.minosoft.protocol.packets.s2c.PlayS2CPacket
|
||||
import de.bixilon.minosoft.protocol.protocol.PlayInByteBuffer
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolVersions
|
||||
import de.bixilon.minosoft.util.KUtil.asResourceLocation
|
||||
import de.bixilon.minosoft.util.logging.Log
|
||||
import de.bixilon.minosoft.util.logging.LogLevels
|
||||
import de.bixilon.minosoft.util.logging.LogMessageType
|
||||
@ -36,20 +35,11 @@ class BlockActionS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
val block: Block = buffer.connection.mapping.blockRegistry.get(buffer.readVarInt())
|
||||
|
||||
override fun handle(connection: PlayConnection) {
|
||||
val blockEntityTypeResourceLocation = when (block.resourceLocation.full) {
|
||||
"minecraft:white_shulker_box", "minecraft:orange_shulker_box", "minecraft:magenta_shulker_box", "minecraft:light_blue_shulker_box",
|
||||
"minecraft:yellow_shulker_box", "minecraft:lime_shulker_box", "minecraft:pink_shulker_box", "minecraft:gray_shulker_box",
|
||||
"minecraft:silver_shulker_box", "minecraft:cyan_shulker_box", "minecraft:purple_shulker_box", "minecraft:blue_shulker_box",
|
||||
"minecraft:brown_shulker_box", "minecraft:green_shulker_box", "minecraft:red_shulker_box", "minecraft:black_shulker_box",
|
||||
-> "minecraft:shulker_box"
|
||||
else -> block.resourceLocation.full
|
||||
}.asResourceLocation()
|
||||
|
||||
val blockEntity = connection.world.getBlockEntity(position) ?: let {
|
||||
val factory = connection.mapping.blockEntityRegistry.get(blockEntityTypeResourceLocation)?.factory
|
||||
?: DefaultBlockEntityMetaDataFactory.getEntityFactory(blockEntityTypeResourceLocation)
|
||||
val factory = connection.mapping.blockEntityTypeRegistry[block.resourceLocation]?.factory
|
||||
?: DefaultBlockEntityMetaDataFactory.getEntityFactory(block.resourceLocation)
|
||||
?: let {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, LogLevels.WARN) { "Unknown block entity $blockEntityTypeResourceLocation" }
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, LogLevels.WARN) { "Unknown block entity ${block.resourceLocation}" }
|
||||
return
|
||||
}
|
||||
val blockEntity = factory.build(connection)
|
||||
|
@ -106,7 +106,7 @@ class ChunkDataS2CP(buffer: PlayInByteBuffer) : PlayS2CPacket() {
|
||||
val nbt = buffer.readNBT()?.compoundCast()!!
|
||||
val position = Vec3i(nbt["x"]?.nullCast<Int>()!!, nbt["y"]?.nullCast<Int>()!!, nbt["z"]?.nullCast<Int>()!!)
|
||||
val resourceLocation = ResourceLocation(nbt["id"]?.nullCast<String>()!!)
|
||||
val type = buffer.connection.mapping.blockEntityRegistry.get(resourceLocation) ?: let {
|
||||
val type = buffer.connection.mapping.blockEntityTypeRegistry.get(resourceLocation) ?: let {
|
||||
Log.log(LogMessageType.NETWORK_PACKETS_IN, level = LogLevels.WARN) { "Unknown block entity: $resourceLocation" }
|
||||
null
|
||||
} ?: continue
|
||||
|
@ -86,4 +86,14 @@ object KUtil {
|
||||
fun <V> Set<V>.toSynchronizedSet(): MutableSet<V> {
|
||||
return synchronizedCopy { Collections.synchronizedSet(this.toMutableSet()) }
|
||||
}
|
||||
|
||||
fun Set<String>.toResourceLocationList(): Set<ResourceLocation> {
|
||||
val ret: MutableSet<ResourceLocation> = mutableSetOf()
|
||||
|
||||
for (resourceLocation in this) {
|
||||
ret += resourceLocation.asResourceLocation()
|
||||
}
|
||||
|
||||
return ret.toSet()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user