improve registry item post mapping

This commit is contained in:
Bixilon 2021-06-29 20:42:58 +02:00
parent e592a02581
commit 657dcbc268
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
32 changed files with 195 additions and 75 deletions

View File

@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
class EntityObjectType( class EntityObjectType(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
) : RegistryItem { ) : RegistryItem() {
companion object : ResourceLocationDeserializer<EntityObjectType> { companion object : ResourceLocationDeserializer<EntityObjectType> {
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): EntityObjectType { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): EntityObjectType {

View File

@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
class BlockEntityMetaType( class BlockEntityMetaType(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
) : RegistryItem { ) : RegistryItem() {
companion object : ResourceLocationDeserializer<BlockEntityMetaType> { companion object : ResourceLocationDeserializer<BlockEntityMetaType> {
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): BlockEntityMetaType { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): BlockEntityMetaType {

View File

@ -37,7 +37,7 @@ data class Dimension(
val ultraWarm: Boolean = false, val ultraWarm: Boolean = false,
val height: Int = 256, val height: Int = 256,
val supports3DBiomes: Boolean = true, val supports3DBiomes: Boolean = true,
) : RegistryItem { ) : RegistryItem() {
val lowestSection = if (minY < 0) { val lowestSection = if (minY < 0) {
(minY + 1) / ProtocolDefinition.SECTION_HEIGHT_Y - 1 (minY + 1) / ProtocolDefinition.SECTION_HEIGHT_Y - 1
} else { } else {

View File

@ -21,7 +21,7 @@ data class Motive(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
val width: Int, val width: Int,
val height: Int, val height: Int,
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
data class PluginChannel( data class PluginChannel(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
val name: ResourceLocation, val name: ResourceLocation,
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -41,7 +41,7 @@ data class Biome(
val grassColorOverride: RGBColor?, val grassColorOverride: RGBColor?,
val descriptionId: String?, val descriptionId: String?,
val grassColorModifier: GrassColorModifiers = GrassColorModifiers.NONE, val grassColorModifier: GrassColorModifiers = GrassColorModifiers.NONE,
) : RegistryItem { ) : RegistryItem() {
val temperatureColorMapCoordinate = getColorMapCoordinate(temperature) val temperatureColorMapCoordinate = getColorMapCoordinate(temperature)
val downfallColorMapCoordinate = getColorMapCoordinate(downfall * temperature) val downfallColorMapCoordinate = getColorMapCoordinate(downfall * temperature)

View File

@ -26,22 +26,9 @@ import de.bixilon.minosoft.protocol.network.connection.PlayConnection
data class BlockEntityType( data class BlockEntityType(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
private var blockIds: Set<Int>?, val blocks: Set<Block>,
val factory: BlockEntityFactory<out BlockEntity>, val factory: BlockEntityFactory<out BlockEntity>,
) : RegistryItem { ) : RegistryItem() {
lateinit var blocks: Set<Block>
private set
override fun postInit(registries: Registries) {
val blocks: MutableSet<Block> = mutableSetOf()
for (blockId in blockIds!!) {
blocks += registries.blockRegistry[blockId]
}
this.blockIds = null
this.blocks = blocks.toSet()
}
fun build(connection: PlayConnection): BlockEntity { fun build(connection: PlayConnection): BlockEntity {
return DefaultBlockEntityMetaDataFactory.buildBlockEntity(factory, connection) return DefaultBlockEntityMetaDataFactory.buildBlockEntity(factory, connection)
@ -49,17 +36,18 @@ data class BlockEntityType(
companion object : ResourceLocationDeserializer<BlockEntityType> { companion object : ResourceLocationDeserializer<BlockEntityType> {
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): BlockEntityType? { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): BlockEntityType? {
check(registries != null)
val factory = DefaultBlockEntityMetaDataFactory[resourceLocation] ?: return null // ToDo val factory = DefaultBlockEntityMetaDataFactory[resourceLocation] ?: return null // ToDo
val blockIds: MutableSet<Int> = mutableSetOf() val blocks: MutableSet<Block> = mutableSetOf()
for (blockId in data["blocks"].asJsonArray) { for (block in data["blocks"].asJsonArray) {
blockIds += blockId.asInt blocks += registries.blockRegistry[block]?:continue
} }
return BlockEntityType( return BlockEntityType(
resourceLocation = resourceLocation, resourceLocation = resourceLocation,
blockIds = blockIds, blocks = blocks,
factory = factory, factory = factory,
) )
} }

View File

@ -13,27 +13,32 @@
package de.bixilon.minosoft.data.registries.blocks.entites package de.bixilon.minosoft.data.registries.blocks.entites
import com.google.gson.JsonObject
import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.blocks.types.Block import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.registry.Registry import de.bixilon.minosoft.data.registries.registry.Registry
import de.bixilon.minosoft.data.registries.registry.ResourceLocationDeserializer
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
class BlockEntityTypeRegistry( class BlockEntityTypeRegistry(
parentRegistry: BlockEntityTypeRegistry? = null, parentRegistry: BlockEntityTypeRegistry? = null,
) : Registry<BlockEntityType>(parentRegistry) { ) : Registry<BlockEntityType>(parentRegistry) {
private lateinit var blockTypeMap: MutableMap<Block, BlockEntityType> private val blockTypeMap: MutableMap<Block, BlockEntityType> = mutableMapOf()
fun getByBlock(block: Block): BlockEntityType? { operator fun get(block: Block): BlockEntityType? {
val parentRegistry = super.parent as BlockEntityTypeRegistry? val parentRegistry = super.parent as BlockEntityTypeRegistry?
return blockTypeMap[block] ?: parentRegistry?.getByBlock(block) return blockTypeMap[block] ?: parentRegistry?.get(block)
} }
override fun postInit(registries: Registries) { override fun initialize(data: Map<ResourceLocation, JsonObject>?, registries: Registries?, deserializer: ResourceLocationDeserializer<BlockEntityType>, flattened: Boolean, metaType: MetaTypes, alternative: Registry<BlockEntityType>?): Registry<BlockEntityType> {
super.postInit(registries) super.initialize(data, registries, deserializer, flattened, metaType, alternative)
blockTypeMap = mutableMapOf()
for ((_, type) in resourceLocationMap) { for ((_, type) in resourceLocationMap) {
for (block in type.blocks) { for (block in type.blocks) {
blockTypeMap[block] = type blockTypeMap[block] = type
} }
} }
return this
} }
} }

View File

@ -44,7 +44,7 @@ open class Block(
final override val resourceLocation: ResourceLocation, final override val resourceLocation: ResourceLocation,
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : RegistryItem { ) : RegistryItem() {
open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f open val explosionResistance: Float = data["explosion_resistance"]?.asFloat ?: 0.0f
open val tintColor: RGBColor? = data["tint_color"]?.asInt?.let { TintColorCalculator.getJsonColor(it) } 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 randomOffsetType: RandomOffsetTypes? = data["offset_type"]?.asString?.let { RandomOffsetTypes[it] }
@ -53,22 +53,22 @@ open class Block(
open var blockEntityType: BlockEntityType? = null open var blockEntityType: BlockEntityType? = null
protected set protected set
private val itemId: Int = data["item"]?.asInt ?: 0
open lateinit var states: Set<BlockState> open lateinit var states: Set<BlockState>
protected set protected set
open lateinit var defaultState: BlockState open lateinit var defaultState: BlockState
protected set protected set
open lateinit var item: Item val item: Item? = null
protected set
open lateinit var properties: Map<BlockProperties, List<Any>> open lateinit var properties: Map<BlockProperties, List<Any>>
open val friction = data["friction"]?.asDouble ?: 0.6 open val friction = data["friction"]?.asDouble ?: 0.6
open val velocityMultiplier = data["velocity_multiplier"]?.asDouble ?: 1.0 // ToDo: They exist since ~1.15 open val velocityMultiplier = data["velocity_multiplier"]?.asDouble ?: 1.0 // ToDo: They exist since ~1.15
open val jumpVelocityMultiplier = data["jump_velocity_multiplier"]?.asDouble ?: 1.0 open val jumpVelocityMultiplier = data["jump_velocity_multiplier"]?.asDouble ?: 1.0
init {
this::item.inject(data["item"]?.asInt)
}
override fun postInit(registries: Registries) { override fun postInit(registries: Registries) {
item = registries.itemRegistry[itemId] blockEntityType = registries.blockEntityTypeRegistry[this]
blockEntityType = registries.blockEntityTypeRegistry.getByBlock(this)
} }
override fun toString(): String { override fun toString(): String {

View File

@ -31,7 +31,7 @@ data class StatusEffect(
val color: RGBColor, val color: RGBColor,
val attributes: Map<ResourceLocation, StatusEffectAttribute>, val attributes: Map<ResourceLocation, StatusEffectAttribute>,
val uuidAttributes: Map<UUID, StatusEffectAttribute>, val uuidAttributes: Map<UUID, StatusEffectAttribute>,
) : RegistryItem, Translatable { ) : RegistryItem(), Translatable {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -21,7 +21,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
data class Enchantment( data class Enchantment(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
// ToDo // ToDo
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -38,7 +38,7 @@ data class EntityType(
val fireImmune: Boolean, val fireImmune: Boolean,
val attributes: Map<ResourceLocation, Double>, val attributes: Map<ResourceLocation, Double>,
val factory: EntityFactory<out Entity>, val factory: EntityFactory<out Entity>,
) : RegistryItem, Translatable { ) : RegistryItem(), Translatable {
fun build(connection: PlayConnection, position: Vec3d, rotation: EntityRotation, entityMetaData: EntityMetaData?, versionId: Int): Entity? { fun build(connection: PlayConnection, position: Vec3d, rotation: EntityRotation, entityMetaData: EntityMetaData?, versionId: Int): Entity? {
return DefaultEntityFactories.buildEntity(factory, connection, position, rotation, entityMetaData, versionId) return DefaultEntityFactories.buildEntity(factory, connection, position, rotation, entityMetaData, versionId)

View File

@ -22,7 +22,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
data class VillagerProfession( data class VillagerProfession(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
// ToDo // ToDo
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -37,21 +37,20 @@ open class Fluid(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : RegistryItem { ) : RegistryItem() {
private val bucketItemId = data["bucket"]?.asInt
val dripParticle: ParticleType? = data["drip_particle_type"]?.asInt?.let { registries.particleTypeRegistry[it] }
open val stillTexture: ResourceLocation? = null open val stillTexture: ResourceLocation? = null
var bucketItem: Item? = null val dripParticle: ParticleType? = null
private set val bucketItem: Item? = null
init {
this::bucketItem.inject(data["bucket"])
this::dripParticle.inject(data["drip_particle_type"])
}
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full
} }
override fun postInit(registries: Registries) {
bucketItem = bucketItemId?.let { registries.itemRegistry[it] }
}
open fun matches(other: Fluid): Boolean { open fun matches(other: Fluid): Boolean {
return other == this return other == this
} }

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.fluid.DefaultFluids import de.bixilon.minosoft.data.registries.fluid.DefaultFluids
import de.bixilon.minosoft.data.registries.fluid.FlowableFluid import de.bixilon.minosoft.data.registries.fluid.FlowableFluid
import de.bixilon.minosoft.data.registries.fluid.Fluid import de.bixilon.minosoft.data.registries.fluid.Fluid
import de.bixilon.minosoft.data.registries.particle.ParticleType
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava.LavaParticle import de.bixilon.minosoft.gui.rendering.particle.types.render.texture.simple.lava.LavaParticle
import de.bixilon.minosoft.gui.rendering.util.VecUtil.horizontal import de.bixilon.minosoft.gui.rendering.util.VecUtil.horizontal
@ -39,10 +40,14 @@ class LavaFluid(
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : FlowableFluid(resourceLocation, registries, data) { ) : FlowableFluid(resourceLocation, registries, data) {
private val lavaParticleType = registries.particleTypeRegistry[LavaParticle] private val lavaParticleType: ParticleType? = null
override val stillTexture: ResourceLocation = "minecraft:block/lava_still".asResourceLocation() override val stillTexture: ResourceLocation = "minecraft:block/lava_still".asResourceLocation()
override val flowingTexture: ResourceLocation = "minecraft:block/lava_flow".asResourceLocation() override val flowingTexture: ResourceLocation = "minecraft:block/lava_flow".asResourceLocation()
init {
this::lavaParticleType.inject(LavaParticle)
}
override fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double { override fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double {
return (connection.world.dimension?.ultraWarm == true).decide(0.007, 0.0023333333333333335) return (connection.world.dimension?.ultraWarm == true).decide(0.007, 0.0023333333333333335)
} }

View File

@ -20,7 +20,9 @@ import de.bixilon.minosoft.data.registries.blocks.BlockState
import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties import de.bixilon.minosoft.data.registries.blocks.properties.BlockProperties
import de.bixilon.minosoft.data.registries.blocks.types.FluidFillable import de.bixilon.minosoft.data.registries.blocks.types.FluidFillable
import de.bixilon.minosoft.data.registries.effects.DefaultStatusEffects import de.bixilon.minosoft.data.registries.effects.DefaultStatusEffects
import de.bixilon.minosoft.data.registries.effects.StatusEffect
import de.bixilon.minosoft.data.registries.enchantment.DefaultEnchantments import de.bixilon.minosoft.data.registries.enchantment.DefaultEnchantments
import de.bixilon.minosoft.data.registries.enchantment.Enchantment
import de.bixilon.minosoft.data.registries.fluid.FlowableFluid import de.bixilon.minosoft.data.registries.fluid.FlowableFluid
import de.bixilon.minosoft.data.registries.fluid.Fluid import de.bixilon.minosoft.data.registries.fluid.Fluid
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
@ -40,11 +42,17 @@ class WaterFluid(
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : FlowableFluid(resourceLocation, registries, data) { ) : FlowableFluid(resourceLocation, registries, data) {
private val depthStriderEnchantment = registries.enchantmentRegistry[DefaultEnchantments.DEPTH_STRIDER] private val depthStriderEnchantment: Enchantment? = null
private val dolphinsGraceStatusEffect = registries.statusEffectRegistry[DefaultStatusEffects.DOLPHINS_GRACE] private val dolphinsGraceStatusEffect: StatusEffect? = null
override val stillTexture: ResourceLocation = "minecraft:block/water_still".asResourceLocation() override val stillTexture: ResourceLocation = "minecraft:block/water_still".asResourceLocation()
override val flowingTexture: ResourceLocation = "minecraft:block/water_flow".asResourceLocation() override val flowingTexture: ResourceLocation = "minecraft:block/water_flow".asResourceLocation()
init {
this::depthStriderEnchantment.inject(DefaultEnchantments.DEPTH_STRIDER)
this::dolphinsGraceStatusEffect.inject(DefaultStatusEffects.DOLPHINS_GRACE)
}
override fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double { override fun getVelocityMultiplier(connection: PlayConnection, blockState: BlockState, blockPosition: Vec3i): Double {
return VELOCITY_MULTIPLIER return VELOCITY_MULTIPLIER
} }

View File

@ -33,7 +33,11 @@ open class BlockItem(
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : Item(resourceLocation, registries, data) { ) : Item(resourceLocation, registries, data) {
val block: Block = registries.blockRegistry[data["block"].asInt] val block: Block? = null
init {
this::block.inject(data["block"])
}
override fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages { override fun use(connection: PlayConnection, raycastHit: RaycastHit, hands: Hands, itemStack: ItemStack): BlockUsages {
if (!connection.player.gamemode.canBuild) { if (!connection.player.gamemode.canBuild) {
@ -56,7 +60,7 @@ open class BlockItem(
} }
val placeBlockState = block.getPlacementState(connection, raycastHit) ?: return BlockUsages.PASS val placeBlockState = block!!.getPlacementState(connection, raycastHit) ?: return BlockUsages.PASS
connection.world[placePosition] = placeBlockState connection.world[placePosition] = placeBlockState

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.registries.items
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.fluid.Fluid
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
@ -23,5 +24,9 @@ open class BucketItem(
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : Item(resourceLocation, registries, data) { ) : Item(resourceLocation, registries, data) {
val fluid = registries.fluidRegistry[data["bucked_fluid_type"].asInt] val fluid: Fluid? = null
init {
this::fluid.inject(data["bucked_fluid_type"])
}
} }

View File

@ -34,7 +34,7 @@ open class Item(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
registries: Registries, registries: Registries,
data: JsonObject, data: JsonObject,
) : RegistryItem, Translatable { ) : RegistryItem(), Translatable {
val rarity: Rarities = data["rarity"]?.asInt?.let { Rarities[it] } ?: Rarities.COMMON val rarity: Rarities = data["rarity"]?.asInt?.let { Rarities[it] } ?: Rarities.COMMON
val maxStackSize: Int = data["max_stack_size"]?.asInt ?: 64 val maxStackSize: Int = data["max_stack_size"]?.asInt ?: 64
val maxDamage: Int = data["max_damage"]?.asInt ?: 1 val maxDamage: Int = data["max_damage"]?.asInt ?: 1

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.registries.items
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.sounds.SoundEvent
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
open class MusicDiscItem( open class MusicDiscItem(
@ -23,5 +24,9 @@ open class MusicDiscItem(
data: JsonObject, data: JsonObject,
) : Item(resourceLocation, registries, data) { ) : Item(resourceLocation, registries, data) {
val analogOutput = data["analog_output"]?.asInt ?: 0 val analogOutput = data["analog_output"]?.asInt ?: 0
val sound = data["sound"]?.asInt?.let { registries.soundEventRegistry[it] } val sound:SoundEvent? = null
init {
this::sound.inject(data["sound"])
}
} }

View File

@ -15,6 +15,7 @@ package de.bixilon.minosoft.data.registries.items
import com.google.gson.JsonObject import com.google.gson.JsonObject
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
import de.bixilon.minosoft.data.registries.entities.EntityType
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.data.text.RGBColor.Companion.asRGBColor import de.bixilon.minosoft.data.text.RGBColor.Companion.asRGBColor
@ -25,5 +26,9 @@ open class SpawnEggItem(
) : Item(resourceLocation, registries, data) { ) : Item(resourceLocation, registries, data) {
val color1 = data["spawn_egg_color_1"]?.asInt?.asRGBColor() val color1 = data["spawn_egg_color_1"]?.asInt?.asRGBColor()
val color2 = data["spawn_egg_color_2"]?.asInt?.asRGBColor() val color2 = data["spawn_egg_color_2"]?.asInt?.asRGBColor()
val entityType = data["spawn_egg_entity_type"]?.asInt?.let { registries.entityTypeRegistry[it] } val entityType: EntityType? = null
init {
this::entityType.inject(data["spawn_egg_entity_type"])
}
} }

View File

@ -32,7 +32,7 @@ data class Material(
val solidBlocking: Boolean, val solidBlocking: Boolean,
val replaceable: Boolean, val replaceable: Boolean,
val solid: Boolean, val solid: Boolean,
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
data class ContainerType( data class ContainerType(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.toString() return resourceLocation.toString()

View File

@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
data class GameEvent( data class GameEvent(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.toString() return resourceLocation.toString()

View File

@ -28,7 +28,7 @@ data class ParticleType(
val textures: List<ResourceLocation>, val textures: List<ResourceLocation>,
val overrideLimiter: Boolean = false, val overrideLimiter: Boolean = false,
val factory: ParticleFactory<out Particle>? = null, val factory: ParticleFactory<out Particle>? = null,
) : RegistryItem { ) : RegistryItem() {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -22,6 +22,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.util.KUtil.asResourceLocation import de.bixilon.minosoft.util.KUtil.asResourceLocation
import de.bixilon.minosoft.util.KUtil.nullCast import de.bixilon.minosoft.util.KUtil.nullCast
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
import kotlin.reflect.KClass
open class Registry<T : RegistryItem>( open class Registry<T : RegistryItem>(
override var parent: AbstractRegistry<T>? = null, override var parent: AbstractRegistry<T>? = null,
@ -133,6 +134,7 @@ open class Registry<T : RegistryItem>(
open fun postInit(registries: Registries) { open fun postInit(registries: Registries) {
for ((_, value) in resourceLocationMap) { for ((_, value) in resourceLocationMap) {
value.inject(registries)
value.postInit(registries) value.postInit(registries)
} }
} }

View File

@ -14,9 +14,42 @@
package de.bixilon.minosoft.data.registries.registry package de.bixilon.minosoft.data.registries.registry
import de.bixilon.minosoft.data.registries.ResourceLocationAble import de.bixilon.minosoft.data.registries.ResourceLocationAble
import de.bixilon.minosoft.data.registries.blocks.types.Block
import de.bixilon.minosoft.data.registries.items.BlockItem
import de.bixilon.minosoft.data.registries.versions.Registries import de.bixilon.minosoft.data.registries.versions.Registries
import de.bixilon.minosoft.util.KUtil.setValue
import kotlin.reflect.KProperty
import kotlin.reflect.jvm.javaField
interface RegistryItem : ResourceLocationAble { abstract class RegistryItem : ResourceLocationAble {
private val injects: MutableMap<KProperty<RegistryItem?>, List<Any>> = mutableMapOf()
fun postInit(registries: Registries) {} fun KProperty<RegistryItem?>.inject(vararg keys: Any?) {
val keyList: MutableList<Any> = mutableListOf()
for (key in keys) {
key ?: continue
keyList += key
}
if (keyList.isEmpty()) {
return
}
injects[this] = keyList
}
fun inject(registries: Registries) {
for ((field, keys) in injects) {
val javaField = field.javaField ?: continue
var value: Any? = null
for (key in keys) {
val currentValue = registries[javaField.type as Class<out RegistryItem>]?.get(key) ?: continue
value = currentValue
break
}
value ?: continue
javaField.setValue(this, value)
}
}
open fun postInit(registries: Registries) { }
} }

View File

@ -20,7 +20,7 @@ import de.bixilon.minosoft.data.registries.versions.Registries
data class SoundEvent( data class SoundEvent(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
) : RegistryItem { ) : RegistryItem() {
companion object : ResourceLocationDeserializer<SoundEvent> { companion object : ResourceLocationDeserializer<SoundEvent> {
override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): SoundEvent { override fun deserialize(registries: Registries?, resourceLocation: ResourceLocation, data: JsonObject): SoundEvent {

View File

@ -20,7 +20,7 @@ data class Statistic(
override val resourceLocation: ResourceLocation, override val resourceLocation: ResourceLocation,
override val translationKey: String?, override val translationKey: String?,
val subStatistics: Map<ResourceLocation, SubStatistic>, val subStatistics: Map<ResourceLocation, SubStatistic>,
) : RegistryItem, Translatable { ) : RegistryItem(), Translatable {
override fun toString(): String { override fun toString(): String {
return resourceLocation.full return resourceLocation.full

View File

@ -50,9 +50,11 @@ import de.bixilon.minosoft.gui.rendering.chunk.models.loading.BlockModel
import de.bixilon.minosoft.protocol.packets.c2s.play.EntityActionC2SP import de.bixilon.minosoft.protocol.packets.c2s.play.EntityActionC2SP
import de.bixilon.minosoft.protocol.packets.s2c.play.EntityAnimationS2CP import de.bixilon.minosoft.protocol.packets.s2c.play.EntityAnimationS2CP
import de.bixilon.minosoft.protocol.packets.s2c.play.title.TitleS2CF import de.bixilon.minosoft.protocol.packets.s2c.play.title.TitleS2CF
import de.bixilon.minosoft.util.KUtil.unsafeCast
import de.bixilon.minosoft.util.collections.Clearable import de.bixilon.minosoft.util.collections.Clearable
import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap import de.bixilon.minosoft.util.json.ResourceLocationJsonMap.toResourceLocationMap
import java.lang.reflect.Field import java.lang.reflect.Field
import java.lang.reflect.ParameterizedType
class Registries { class Registries {
@ -159,7 +161,6 @@ class Registries {
containerTypeRegistry.initialize(pixlyzerData["container_types"]?.asJsonObject, this, ContainerType, alternative = DefaultRegistries.CONTAINER_TYPE_REGISTRY.forVersion(version)) 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)) gameEventRegistry.initialize(pixlyzerData["game_events"]?.asJsonObject, this, GameEvent, alternative = DefaultRegistries.GAME_EVENT_REGISTRY.forVersion(version))
blockEntityTypeRegistry.initialize(pixlyzerData["block_entities"]?.asJsonObject, this, BlockEntityType)
entityTypeRegistry.initialize(pixlyzerData["entities"]?.asJsonObject, this, EntityType) entityTypeRegistry.initialize(pixlyzerData["entities"]?.asJsonObject, this, EntityType)
@ -175,6 +176,8 @@ class Registries {
blockRegistry.initialize(pixlyzerData["blocks"]?.asJsonObject, this, Block, version.isFlattened(), Registry.MetaTypes.BITS_4) blockRegistry.initialize(pixlyzerData["blocks"]?.asJsonObject, this, Block, version.isFlattened(), Registry.MetaTypes.BITS_4)
itemRegistry.initialize(pixlyzerData["items"]?.asJsonObject, this, Item, version.isFlattened(), Registry.MetaTypes.BITS_16) itemRegistry.initialize(pixlyzerData["items"]?.asJsonObject, this, Item, version.isFlattened(), Registry.MetaTypes.BITS_16)
blockEntityTypeRegistry.initialize(pixlyzerData["block_entities"]?.asJsonObject, this, BlockEntityType)
villagerProfessionRegistry.initialize(pixlyzerData["villager_professions"]?.asJsonObject, this, VillagerProfession) villagerProfessionRegistry.initialize(pixlyzerData["villager_professions"]?.asJsonObject, this, VillagerProfession)
@ -182,10 +185,10 @@ class Registries {
// post init // post init
biomeRegistry.postInit(this) for (field in TYPE_MAP.values) {
fluidRegistry.postInit(this) val registry = field.get(this) as Registry<*>
blockEntityTypeRegistry.postInit(this) registry.postInit(this)
blockRegistry.postInit(this) }
isFullyLoaded = true isFullyLoaded = true
} }
@ -248,9 +251,21 @@ class Registries {
} }
} }
operator fun <T : RegistryItem> get(type: Class<T>): Registry<T>? {
var currentField: Field?
var currentClass: Class<*> = type
do {
currentField = TYPE_MAP[currentClass]
currentClass = currentClass.superclass
} while (currentField == null && currentClass != Object::class.java)
return currentField?.get(this) as Registry<T>?
}
companion object { companion object {
private val PARENTABLE_FIELDS: List<Field> private val PARENTABLE_FIELDS: List<Field>
private val PARENTABLE_SET_PARENT_METHOD = Parentable::class.java.getDeclaredMethod("setParent", Any::class.java) private val PARENTABLE_SET_PARENT_METHOD = Parentable::class.java.getDeclaredMethod("setParent", Any::class.java)
private val TYPE_MAP: Map<Class<*>, Field>
init { init {
val fields: MutableList<Field> = mutableListOf() val fields: MutableList<Field> = mutableListOf()
@ -264,5 +279,37 @@ class Registries {
PARENTABLE_FIELDS = fields.toList() PARENTABLE_FIELDS = fields.toList()
} }
init {
val types: MutableMap<Class<*>, Field> = mutableMapOf()
for (field in Registries::class.java.declaredFields) {
if (!Registry::class.java.isAssignableFrom(field.type)) {
continue
}
field.isAccessible = true
var generic = field.genericType
if (field.type != Registry::class.java) {
var type = field.type
while (type != Object::class.java) {
if (type.superclass == Registry::class.java) {
generic = type.genericSuperclass
break
}
type = type.superclass
}
}
types[generic.unsafeCast<ParameterizedType>().actualTypeArguments.first() as Class<*>] = field
}
types[Item::class.java] = Registries::class.java.getDeclaredField("itemRegistry")
TYPE_MAP = types.toMap()
}
} }
} }

View File

@ -111,9 +111,9 @@ data class Version(
registries.load(this, pixlyzerData) registries.load(this, pixlyzerData)
latch.dec() latch.dec()
if (pixlyzerData.size() > 0) { if (pixlyzerData.size() > 0) {
Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.INFO) { "Loaded registries for $this $versionName in ${System.currentTimeMillis() - startTime}ms" } Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.INFO) { "Loaded registries for $versionName in ${System.currentTimeMillis() - startTime}ms" }
} else { } else {
Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.WARN) { "Could not load registries for $this (${versionName}. Some features might not work." } Log.log(LogMessageType.VERSION_LOADING, level = LogLevels.WARN) { "Could not load registries for ${versionName}. Some features might not work." }
} }
isLoaded = true isLoaded = true
latch.dec() latch.dec()

View File

@ -21,6 +21,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
import de.bixilon.minosoft.util.collections.SynchronizedMap import de.bixilon.minosoft.util.collections.SynchronizedMap
import de.bixilon.minosoft.util.enum.AliasableEnum import de.bixilon.minosoft.util.enum.AliasableEnum
import sun.misc.Unsafe import sun.misc.Unsafe
import java.lang.reflect.Field
import java.util.* import java.util.*
import kotlin.Pair import kotlin.Pair
import kotlin.random.Random import kotlin.random.Random
@ -208,4 +209,17 @@ object KUtil {
else -> this.toString() else -> this.toString()
}) })
} }
fun Field.setValue(instance: Any, value: Any) {
this.isAccessible = true
// ToDo
// if (Modifier.isFinal(this.modifiers)) {
// FieldUtils.removeFinalModifier(this)
// }
this.set(instance, value)
}
} }