Cardinal Components API

Cardinal Components API

21M Downloads

Attach data to vanilla Block (not BlockEntity) [Help wanted]

Krysztal112233 opened this issue ยท 1 comments

commented

I'm sorry to say that after reading the Wiki I'm still not sure if I'm doing this right.

I wanted to attach some data to vanilla Block, namely FARMLAND, and after reading the CCA Wiki I found that this part of the functionality is now mainly implemented by fabric lookup api, so I wrote the following code

package dev.krysztal.advagri.foundation.component

import dev.krysztal.advagri.extender.toIdentifier
import dev.onyxstudios.cca.api.v3.block.BlockComponentFactoryRegistry
import dev.onyxstudios.cca.api.v3.block.BlockComponentInitializer
import dev.onyxstudios.cca.api.v3.block.BlockComponents
import net.fabricmc.fabric.api.lookup.v1.block.BlockApiLookup
import net.minecraft.block.Block
import net.minecraft.block.Blocks.*
import net.minecraft.nbt.NbtCompound

// Inspired by TFC
class BlockMacronutrientComponent() : MacronutrientComponent, BlockComponentInitializer {
    private var nitrogen = 0
    private var phosphorus = 0
    private var potassium = 0

    constructor(block: Block) : this()

    override fun getPhosphorus(): Int = phosphorus
    override fun getPotassium(): Int = potassium
    override fun getNitrogen(): Int = nitrogen

    override fun setNitrogen(n: Int) {
        nitrogen = n
    }

    override fun setPhosphorus(p: Int) {
        phosphorus = p
    }

    override fun setPotassium(k: Int) {
        potassium = k
    }

    override fun readFromNbt(tag: NbtCompound) {
        nitrogen = tag.getInt("Nitrogen")
        phosphorus = tag.getInt("Phosphorus")
        potassium = tag.getInt("Potassium")
    }

    override fun writeToNbt(tag: NbtCompound) {
        tag.putInt("Nitrogen", nitrogen)
        tag.putInt("Phosphorus", phosphorus)
        tag.putInt("Potassium", potassium)
    }

    override fun registerBlockComponentFactories(registry: BlockComponentFactoryRegistry) {
       // Before that, I wrote these codes.
       //   registry.registerFor(FARMLAND::class.java, MacronutrientComponent.COMPONENT) { BlockMacronutrientComponent(it) }
       // But there must be BlockEntity type.

}

    companion object {
        private val LOOKUP_API: BlockApiLookup<MacronutrientComponent, Block> = BlockApiLookup.get(
            ("macronutrient").toIdentifier(),
            MacronutrientComponent::class.java,
            FARMLAND.javaClass,
        )

// Invoke this funtion at ModInitializer
        fun init() {
            BlockComponents.exposeApi(
                MacronutrientComponent.COMPONENT,
                LOOKUP_API,
            )
        }
    }
}

I would like to know if it is in order for me to write code this way? Because I want to store some information to the original block.

Forgive my stupidity, but I didn't find an example that fits my usage too well.

commented

Blocks can not store any per-position data, that is what Block Entities are for.
Either attach a block entity to store your data with, or store the data somewhere else (chunk, world, ...) and delegate access to that.