Custom deferred register with parallel entry initialization

This commit is contained in:
DBotThePony 2024-01-05 21:35:14 +07:00
parent 2dcfa99f9c
commit e55764c10d
Signed by: DBot
GPG Key ID: DCC23B5715498507
19 changed files with 253 additions and 119 deletions

View File

@ -8,22 +8,22 @@ import ru.dbotthepony.mc.otm.android.DummyAndroidFeature
import ru.dbotthepony.mc.otm.android.feature.* import ru.dbotthepony.mc.otm.android.feature.*
object AndroidFeatures { object AndroidFeatures {
private val registry = DeferredRegister.create(MRegistry.ANDROID_FEATURES_KEY, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(MRegistry.ANDROID_FEATURES_KEY)
val AIR_BAGS: AndroidFeatureType<DummyAndroidFeature> by registry.register(MNames.AIR_BAGS) { AndroidFeatureType(::DummyAndroidFeature) } val AIR_BAGS by registry.register(MNames.AIR_BAGS) { AndroidFeatureType(::DummyAndroidFeature) }
val STEP_ASSIST: AndroidFeatureType<StepAssistFeature> by registry.register(MNames.STEP_ASSIST) { AndroidFeatureType(::StepAssistFeature) } val STEP_ASSIST by registry.register(MNames.STEP_ASSIST) { AndroidFeatureType(::StepAssistFeature) }
val SWIM_BOOSTERS: AndroidFeatureType<SwimBoostersFeature> by registry.register(MNames.SWIM_BOOSTERS) { AndroidFeatureType(::SwimBoostersFeature) } val SWIM_BOOSTERS by registry.register(MNames.SWIM_BOOSTERS) { AndroidFeatureType(::SwimBoostersFeature) }
val LIMB_OVERCLOCKING: AndroidFeatureType<LimbOverclockingFeature> by registry.register(MNames.LIMB_OVERCLOCKING) { AndroidFeatureType(::LimbOverclockingFeature) } val LIMB_OVERCLOCKING by registry.register(MNames.LIMB_OVERCLOCKING) { AndroidFeatureType(::LimbOverclockingFeature) }
val ATTACK_BOOST: AndroidFeatureType<AttackBoostFeature> by registry.register(MNames.ATTACK_BOOST) { AndroidFeatureType(::AttackBoostFeature) } val ATTACK_BOOST by registry.register(MNames.ATTACK_BOOST) { AndroidFeatureType(::AttackBoostFeature) }
val NANOBOTS_REGENERATION: AndroidFeatureType<NanobotsRegenerationFeature> by registry.register(MNames.NANOBOTS_REGENERATION) { AndroidFeatureType(::NanobotsRegenerationFeature) } val NANOBOTS_REGENERATION by registry.register(MNames.NANOBOTS_REGENERATION) { AndroidFeatureType(::NanobotsRegenerationFeature) }
val NANOBOTS_ARMOR: AndroidFeatureType<NanobotsArmorFeature> by registry.register(MNames.NANOBOTS_ARMOR) { AndroidFeatureType(::NanobotsArmorFeature) } val NANOBOTS_ARMOR by registry.register(MNames.NANOBOTS_ARMOR) { AndroidFeatureType(::NanobotsArmorFeature) }
val EXTENDED_REACH: AndroidFeatureType<ExtendedReachFeature> by registry.register(MNames.EXTENDED_REACH) { AndroidFeatureType(::ExtendedReachFeature) } val EXTENDED_REACH by registry.register(MNames.EXTENDED_REACH) { AndroidFeatureType(::ExtendedReachFeature) }
val NIGHT_VISION: AndroidFeatureType<NightVisionFeature> by registry.register(MNames.NIGHT_VISION) { AndroidFeatureType(::NightVisionFeature) } val NIGHT_VISION by registry.register(MNames.NIGHT_VISION) { AndroidFeatureType(::NightVisionFeature) }
val SHOCKWAVE: AndroidFeatureType<ShockwaveFeature> by registry.register(MNames.SHOCKWAVE) { AndroidFeatureType(::ShockwaveFeature) } val SHOCKWAVE by registry.register(MNames.SHOCKWAVE) { AndroidFeatureType(::ShockwaveFeature) }
val ITEM_MAGNET: AndroidFeatureType<ItemMagnetFeature> by registry.register(MNames.ITEM_MAGNET) { AndroidFeatureType(::ItemMagnetFeature) } val ITEM_MAGNET by registry.register(MNames.ITEM_MAGNET) { AndroidFeatureType(::ItemMagnetFeature) }
val FALL_DAMPENERS: AndroidFeatureType<FallDampenersFeature> by registry.register(MNames.FALL_DAMPENERS) { AndroidFeatureType(::FallDampenersFeature) } val FALL_DAMPENERS by registry.register(MNames.FALL_DAMPENERS) { AndroidFeatureType(::FallDampenersFeature) }
val JUMP_BOOST: AndroidFeatureType<JumpBoostFeature> by registry.register(MNames.JUMP_BOOST) { AndroidFeatureType(::JumpBoostFeature) } val JUMP_BOOST by registry.register(MNames.JUMP_BOOST) { AndroidFeatureType(::JumpBoostFeature) }
val ENDER_TELEPORTER: AndroidFeatureType<EnderTeleporterFeature> by registry.register(MNames.ENDER_TELEPORTER) { AndroidFeatureType(::EnderTeleporterFeature) } val ENDER_TELEPORTER by registry.register(MNames.ENDER_TELEPORTER) { AndroidFeatureType(::EnderTeleporterFeature) }
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
registry.register(bus) registry.register(bus)

View File

@ -1,25 +0,0 @@
package ru.dbotthepony.mc.otm.registry
import net.minecraft.world.item.DyeColor
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.RegistryObject
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import java.util.function.Supplier
import kotlin.reflect.KProperty
operator fun <T : Any> RegistryObject<T>.getValue(thisRef: Any, property: KProperty<*>): T {
return get()
}
internal fun <T, R : T> DeferredRegister<T>.colored(prefix: String, factory: (color: DyeColor) -> R): Map<DyeColor, R> {
return SupplierMap(MRegistry.DYE_ORDER.map { it to register(prefix + "_" + it.name.lowercase()) { factory.invoke(it) } })
}
internal fun <T, R : T> DeferredRegister<T>.coloredWithBase(prefix: String, factory: (color: DyeColor?) -> R): Map<DyeColor?, R> {
val values = ArrayList<Pair<DyeColor?, Supplier<R>>>()
values.add(null to register(prefix) { factory.invoke(null) })
MRegistry.DYE_ORDER.forEach { values.add(it to register(prefix + "_" + it.name.lowercase()) { factory.invoke(it) }) }
return SupplierMap(values)
}

View File

@ -38,13 +38,13 @@ import java.util.function.Supplier
@Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") // Type<*> is unused in BlockEntityType.Builder @Suppress("NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS") // Type<*> is unused in BlockEntityType.Builder
object MBlockEntities { object MBlockEntities {
private val registry = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(ForgeRegistries.BLOCK_ENTITY_TYPES)
private fun <T : BlockEntity> register(name: String, factory: BlockEntityType.BlockEntitySupplier<T>, vararg blocks: Supplier<Block>): RegistryObject<BlockEntityType<T>> { private fun <T : BlockEntity> register(name: String, factory: BlockEntityType.BlockEntitySupplier<T>, vararg blocks: Supplier<Block>): MDeferredRegister<*>.Entry<BlockEntityType<T>> {
return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.map { it.get() }.toTypedArray()).build(null) } return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.map { it.get() }.toTypedArray()).build(null) }
} }
private fun <T : BlockEntity> register(name: String, factory: BlockEntityType.BlockEntitySupplier<T>, blocks: Map<*, Block>): RegistryObject<BlockEntityType<T>> { private fun <T : BlockEntity> register(name: String, factory: BlockEntityType.BlockEntitySupplier<T>, blocks: Map<*, Block>): MDeferredRegister<*>.Entry<BlockEntityType<T>> {
return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.values.toTypedArray()).build(null) } return registry.register(name) { BlockEntityType.Builder.of(factory, *blocks.values.toTypedArray()).build(null) }
} }

View File

@ -80,7 +80,7 @@ import ru.dbotthepony.mc.otm.shapes.BlockShapes
import java.util.function.Supplier import java.util.function.Supplier
object MBlocks { object MBlocks {
private val registry = DeferredRegister.create(ForgeRegistries.BLOCKS, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(ForgeRegistries.BLOCKS)
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
registry.register(bus) registry.register(bus)
@ -222,7 +222,7 @@ object MBlocks {
val TRITANIUM_TRAPDOOR = registry.coloredWithBase(MNames.TRITANIUM_TRAPDOOR, ::TritaniumTrapdoorBlock) val TRITANIUM_TRAPDOOR = registry.coloredWithBase(MNames.TRITANIUM_TRAPDOOR, ::TritaniumTrapdoorBlock)
val TRITANIUM_STRIPED_BLOCK: Block by registry.register(MNames.TRITANIUM_STRIPED_BLOCK) { Block( val TRITANIUM_STRIPED_BLOCK: Block by registry.register(MNames.TRITANIUM_STRIPED_BLOCK, true) { Block(
BlockBehaviour.Properties.of() BlockBehaviour.Properties.of()
.mapColor(MapColor.COLOR_LIGHT_BLUE) .mapColor(MapColor.COLOR_LIGHT_BLUE)
.sound(SoundType.BASALT) .sound(SoundType.BASALT)

View File

@ -273,7 +273,7 @@ private fun addDecorativeTabItems(consumer: CreativeModeTab.Output) {
} }
object MCreativeTabs { object MCreativeTabs {
private val registry = DeferredRegister.create(Registries.CREATIVE_MODE_TAB, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(Registries.CREATIVE_MODE_TAB)
val MAIN: CreativeModeTab by registry.register("main") { val MAIN: CreativeModeTab by registry.register("main") {
CreativeModeTab.builder() CreativeModeTab.builder()

View File

@ -0,0 +1,157 @@
package ru.dbotthepony.mc.otm.registry
import it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap
import net.minecraft.Util
import net.minecraft.core.Registry
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.DyeColor
import net.minecraftforge.eventbus.api.IEventBus
import net.minecraftforge.registries.IForgeRegistry
import net.minecraftforge.registries.RegisterEvent
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.SystemTime
import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import java.util.LinkedList
import java.util.concurrent.FutureTask
import java.util.concurrent.locks.LockSupport
import java.util.function.Supplier
import kotlin.reflect.KProperty
/**
* DeferredRegister which allows parallel initialization
*/
class MDeferredRegister<R : Any>(val registry: ResourceKey<Registry<R>>, val modId: String = OverdriveThatMatters.MOD_ID) {
constructor(registry: IForgeRegistry<R>, modId: String = OverdriveThatMatters.MOD_ID) : this(registry.registryKey, modId)
private val entries = Object2ObjectLinkedOpenHashMap<String, Entry<R>>()
private var allowRegistration = true
private var eventRegistered = false
private val stages = ArrayList<RegistrationStage>()
private inner class RegistrationStage(val serial: Boolean) {
private val entries = ArrayList<Entry<R>>()
fun add(entry: Entry<R>) {
entries.add(entry)
}
fun run(): List<Entry<R>> {
if (serial) {
LOGGER.debug("Serial registration of {} entries from {} for {}...", entries.size, modId, registry.location())
val t = SystemTime()
entries.forEach { it.initialize() }
LOGGER.debug("Serial registration of {} entries from {} for {} took {} ms", entries.size, modId, registry.location(), t.millis)
} else {
LOGGER.debug("Parallel registration of {} entries from {} for {}...", entries.size, modId, registry.location())
val t = SystemTime()
val futures = LinkedList<FutureTask<R>>()
entries.forEach { futures.add(FutureTask(it::initialize)) }
futures.forEach { Util.backgroundExecutor().submit(it) }
while (futures.isNotEmpty()) {
futures.removeIf { it.run(); it.isDone } // help executor threads to minimize thread stalling
// especially true when executor threads are busy with work created by other mods
// so we keep worst-case scenario where every registry entry is initialized and registered serially as it was before
LockSupport.parkNanos(1_000_000L)
}
// memory barrier to avoid specifying _value as @Volatile
LockSupport.parkNanos(1_000_000L)
LOGGER.debug("Parallel registration of {} entries from {} for {} took {} ms", entries.size, modId, registry.location(), t.millis)
}
return entries
}
}
inner class Entry<out T : R>(val name: String, private val factory: Supplier<T>, serial: Boolean) : Supplier<@UnsafeVariance T>, Lazy<T> {
constructor(name: String, factory: Supplier<T>) : this(name, factory, false)
init {
check(allowRegistration) { "Unable to register new entries after RegisterEvent has been fired" }
require(entries.put(name, this) == null) { "Duplicate entry $name for registry $registry" }
if (stages.isEmpty() || stages.last().serial != serial) {
val stage = RegistrationStage(serial)
stage.add(this)
stages.add(stage)
} else {
stages.last().add(this)
}
}
val key = ResourceLocation(modId, name)
private var _value: T? = null
override val value: T get() {
return _value ?: throw IllegalStateException("Trying to access $name of $registry before it is initialized")
}
override fun isInitialized(): Boolean {
return _value != null
}
override fun get(): T {
return value
}
operator fun getValue(receiver: Any?, property: KProperty<*>): T {
return value
}
fun initialize(): T {
check(_value == null) { "Already initialized $name of $registry!" }
val getValue = try {
factory.get()
} catch (err: Throwable) {
throw RuntimeException("Unable to initialize registry entry $name of $registry", err)
}
_value = getValue
return value
}
}
fun <T : R> colored(prefix: String, factory: (color: DyeColor) -> T): Map<DyeColor, T> {
return SupplierMap(MRegistry.DYE_ORDER.map { it to Entry(prefix + "_" + it.name.lowercase()) { factory.invoke(it) } })
}
fun <T : R> coloredWithBase(prefix: String, factory: (color: DyeColor?) -> T): Map<DyeColor?, T> {
val values = ArrayList<Pair<DyeColor?, Supplier<T>>>()
values.add(null to Entry(prefix) { factory.invoke(null) })
MRegistry.DYE_ORDER.forEach { values.add(it to Entry(prefix + "_" + it.name.lowercase()) { factory.invoke(it) }) }
return SupplierMap(values)
}
fun <T : R> register(name: String, factory: Supplier<T>) = Entry(name, factory)
fun <T : R> register(name: String, factory: Supplier<T>, serial: Boolean) = Entry(name, factory, serial)
fun <T : R> register(name: String, serial: Boolean, factory: Supplier<T>) = Entry(name, factory, serial)
private fun onRegisterEvent(event: RegisterEvent) {
if (event.registryKey == registry) {
allowRegistration = false
for (stage in stages) {
stage.run().forEach {
event.register(registry, it.key, it)
}
}
}
}
fun register(bus: IEventBus) {
check(!eventRegistered) { "Already registered!" }
eventRegistered = true
bus.addListener(this::onRegisterEvent)
}
companion object {
private val LOGGER = LogManager.getLogger()
}
}

View File

@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.entity.MinecartCargoCrate
import ru.dbotthepony.mc.otm.entity.PlasmaProjectile import ru.dbotthepony.mc.otm.entity.PlasmaProjectile
object MEntityTypes { object MEntityTypes {
private val registry: DeferredRegister<EntityType<*>> = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(ForgeRegistries.ENTITY_TYPES)
val PLASMA: EntityType<*> by registry.register(MNames.PLASMA) { val PLASMA: EntityType<*> by registry.register(MNames.PLASMA) {
EntityType.Builder.of<PlasmaProjectile>({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA) EntityType.Builder.of<PlasmaProjectile>({ _, level -> PlasmaProjectile(level) }, MobCategory.MISC).sized(0.4f, 0.4f).build(MNames.PLASMA)

View File

@ -15,8 +15,8 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
import java.util.function.Consumer import java.util.function.Consumer
object MFluids { object MFluids {
private val types: DeferredRegister<FluidType> = DeferredRegister.create(ForgeRegistries.FLUID_TYPES, OverdriveThatMatters.MOD_ID) private val types = MDeferredRegister(ForgeRegistries.Keys.FLUID_TYPES)
private val fluids: DeferredRegister<Fluid> = DeferredRegister.create(ForgeRegistries.FLUIDS, OverdriveThatMatters.MOD_ID) private val fluids = MDeferredRegister(ForgeRegistries.FLUIDS)
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
types.register(bus) types.register(bus)

View File

@ -10,7 +10,7 @@ import ru.dbotthepony.mc.otm.item.ProceduralBatteryItem
import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.exopack.ProceduralExopackSlotUpgradeItem
object MItemFunctionTypes { object MItemFunctionTypes {
private val registry = DeferredRegister.create(Registries.LOOT_FUNCTION_TYPE, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(Registries.LOOT_FUNCTION_TYPE, OverdriveThatMatters.MOD_ID)
val COPY_TILE_NBT: LootItemFunctionType by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.CODEC) } val COPY_TILE_NBT: LootItemFunctionType by registry.register("copy_tile_nbt") { LootItemFunctionType(CopyTileNbtFunction.CODEC) }
val PROCEDURAL_BATTERY: LootItemFunctionType by registry.register(MNames.PROCEDURAL_BATTERY) { LootItemFunctionType(ProceduralBatteryItem.Randomizer.CODEC) } val PROCEDURAL_BATTERY: LootItemFunctionType by registry.register(MNames.PROCEDURAL_BATTERY) { LootItemFunctionType(ProceduralBatteryItem.Randomizer.CODEC) }

View File

@ -48,7 +48,7 @@ import java.util.function.Supplier
object MItems { object MItems {
private val DEFAULT_PROPERTIES = Properties() private val DEFAULT_PROPERTIES = Properties()
private val registry: DeferredRegister<Item> = DeferredRegister.create(ForgeRegistries.ITEMS, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(ForgeRegistries.ITEMS)
private fun register(name: String, blocks: Map<DyeColor?, Block>, properties: Properties = DEFAULT_PROPERTIES): Map<DyeColor?, BlockItem> { private fun register(name: String, blocks: Map<DyeColor?, Block>, properties: Properties = DEFAULT_PROPERTIES): Map<DyeColor?, BlockItem> {
return registry.coloredWithBase(name) { color -> BlockItem(blocks[color]!!, properties) } return registry.coloredWithBase(name) { color -> BlockItem(blocks[color]!!, properties) }

View File

@ -15,7 +15,7 @@ import ru.dbotthepony.mc.otm.data.condition.KilledByRealPlayerOrIndirectly
import ru.dbotthepony.mc.otm.data.condition.ChanceCondition import ru.dbotthepony.mc.otm.data.condition.ChanceCondition
object MLootItemConditions { object MLootItemConditions {
private val registry = DeferredRegister.create(Registries.LOOT_CONDITION_TYPE, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(Registries.LOOT_CONDITION_TYPE, OverdriveThatMatters.MOD_ID)
val HAS_EXOPACK: LootItemConditionType by registry.register("has_exopack") { LootItemConditionType(SingletonCodec(HasExoPackCondition)) } val HAS_EXOPACK: LootItemConditionType by registry.register("has_exopack") { LootItemConditionType(SingletonCodec(HasExoPackCondition)) }
val CHANCE_WITH_PLAYTIME: LootItemConditionType by registry.register("chance_with_playtime") { LootItemConditionType(ChanceWithPlaytimeCondition.CODEC) } val CHANCE_WITH_PLAYTIME: LootItemConditionType by registry.register("chance_with_playtime") { LootItemConditionType(ChanceWithPlaytimeCondition.CODEC) }

View File

@ -75,43 +75,43 @@ import ru.dbotthepony.mc.otm.menu.tech.PoweredFurnaceMenu
import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu import ru.dbotthepony.mc.otm.menu.tech.TwinPlatePressMenu
object MMenus { object MMenus {
private val registry = DeferredRegister.create(ForgeRegistries.MENU_TYPES, OverdriveThatMatters.MOD_ID) private val registry = MDeferredRegister(ForgeRegistries.MENU_TYPES)
val ANDROID_STATION: MenuType<AndroidStationMenu> by registry.register(MNames.ANDROID_STATION) { MenuType(::AndroidStationMenu, FeatureFlags.VANILLA_SET) } val ANDROID_STATION by registry.register(MNames.ANDROID_STATION) { MenuType(::AndroidStationMenu, FeatureFlags.VANILLA_SET) }
val ANDROID_CHARGER: MenuType<AndroidChargerMenu> by registry.register(MNames.ANDROID_CHARGER) { MenuType({ a, b -> AndroidChargerMenu(a, b, null as AndroidChargerBlockEntity?) }, FeatureFlags.VANILLA_SET) } val ANDROID_CHARGER by registry.register(MNames.ANDROID_CHARGER) { MenuType({ a, b -> AndroidChargerMenu(a, b, null as AndroidChargerBlockEntity?) }, FeatureFlags.VANILLA_SET) }
val BATTERY_BANK: MenuType<BatteryBankMenu> by registry.register(MNames.BATTERY_BANK) { MenuType(::BatteryBankMenu, FeatureFlags.VANILLA_SET) } val BATTERY_BANK by registry.register(MNames.BATTERY_BANK) { MenuType(::BatteryBankMenu, FeatureFlags.VANILLA_SET) }
val MATTER_DECOMPOSER: MenuType<MatterDecomposerMenu> by registry.register(MNames.MATTER_DECOMPOSER) { MenuType(::MatterDecomposerMenu, FeatureFlags.VANILLA_SET) } val MATTER_DECOMPOSER by registry.register(MNames.MATTER_DECOMPOSER) { MenuType(::MatterDecomposerMenu, FeatureFlags.VANILLA_SET) }
val MATTER_CAPACITOR_BANK: MenuType<MatterCapacitorBankMenu> by registry.register(MNames.MATTER_CAPACITOR_BANK) { MenuType(::MatterCapacitorBankMenu, FeatureFlags.VANILLA_SET) } val MATTER_CAPACITOR_BANK by registry.register(MNames.MATTER_CAPACITOR_BANK) { MenuType(::MatterCapacitorBankMenu, FeatureFlags.VANILLA_SET) }
val PATTERN_STORAGE: MenuType<PatternStorageMenu> by registry.register(MNames.PATTERN_STORAGE) { MenuType(::PatternStorageMenu, FeatureFlags.VANILLA_SET) } val PATTERN_STORAGE by registry.register(MNames.PATTERN_STORAGE) { MenuType(::PatternStorageMenu, FeatureFlags.VANILLA_SET) }
val MATTER_SCANNER: MenuType<MatterScannerMenu> by registry.register(MNames.MATTER_SCANNER) { MenuType(::MatterScannerMenu, FeatureFlags.VANILLA_SET) } val MATTER_SCANNER by registry.register(MNames.MATTER_SCANNER) { MenuType(::MatterScannerMenu, FeatureFlags.VANILLA_SET) }
val MATTER_PANEL: MenuType<MatterPanelMenu> by registry.register(MNames.MATTER_PANEL) { MenuType(::MatterPanelMenu, FeatureFlags.VANILLA_SET) } val MATTER_PANEL by registry.register(MNames.MATTER_PANEL) { MenuType(::MatterPanelMenu, FeatureFlags.VANILLA_SET) }
val MATTER_REPLICATOR: MenuType<MatterReplicatorMenu> by registry.register(MNames.MATTER_REPLICATOR) { MenuType(::MatterReplicatorMenu, FeatureFlags.VANILLA_SET) } val MATTER_REPLICATOR by registry.register(MNames.MATTER_REPLICATOR) { MenuType(::MatterReplicatorMenu, FeatureFlags.VANILLA_SET) }
val MATTER_BOTTLER: MenuType<MatterBottlerMenu> by registry.register(MNames.MATTER_BOTTLER) { MenuType(::MatterBottlerMenu, FeatureFlags.VANILLA_SET) } val MATTER_BOTTLER by registry.register(MNames.MATTER_BOTTLER) { MenuType(::MatterBottlerMenu, FeatureFlags.VANILLA_SET) }
val DRIVE_VIEWER: MenuType<DriveViewerMenu> by registry.register(MNames.DRIVE_VIEWER) { MenuType(::DriveViewerMenu, FeatureFlags.VANILLA_SET) } val DRIVE_VIEWER by registry.register(MNames.DRIVE_VIEWER) { MenuType(::DriveViewerMenu, FeatureFlags.VANILLA_SET) }
val CARGO_CRATE: MenuType<CargoCrateMenu> by registry.register(MNames.CARGO_CRATE) { MenuType(::CargoCrateMenu, FeatureFlags.VANILLA_SET) } val CARGO_CRATE by registry.register(MNames.CARGO_CRATE) { MenuType(::CargoCrateMenu, FeatureFlags.VANILLA_SET) }
val MINECART_CARGO_CRATE: MenuType<MinecartCargoCrateMenu> by registry.register(MNames.MINECART_CARGO_CRATE) { MenuType(::MinecartCargoCrateMenu, FeatureFlags.VANILLA_SET) } val MINECART_CARGO_CRATE by registry.register(MNames.MINECART_CARGO_CRATE) { MenuType(::MinecartCargoCrateMenu, FeatureFlags.VANILLA_SET) }
val DRIVE_RACK: MenuType<DriveRackMenu> by registry.register(MNames.DRIVE_RACK) { MenuType(::DriveRackMenu, FeatureFlags.VANILLA_SET) } val DRIVE_RACK by registry.register(MNames.DRIVE_RACK) { MenuType(::DriveRackMenu, FeatureFlags.VANILLA_SET) }
val ITEM_MONITOR: MenuType<ItemMonitorMenu> by registry.register(MNames.ITEM_MONITOR) { MenuType(::ItemMonitorMenu, FeatureFlags.VANILLA_SET) } val ITEM_MONITOR by registry.register(MNames.ITEM_MONITOR) { MenuType(::ItemMonitorMenu, FeatureFlags.VANILLA_SET) }
val ENERGY_COUNTER: MenuType<EnergyCounterMenu> by registry.register(MNames.ENERGY_COUNTER) { MenuType(::EnergyCounterMenu, FeatureFlags.VANILLA_SET) } val ENERGY_COUNTER by registry.register(MNames.ENERGY_COUNTER) { MenuType(::EnergyCounterMenu, FeatureFlags.VANILLA_SET) }
val CHEMICAL_GENERATOR: MenuType<ChemicalGeneratorMenu> by registry.register(MNames.CHEMICAL_GENERATOR) { MenuType(::ChemicalGeneratorMenu, FeatureFlags.VANILLA_SET) } val CHEMICAL_GENERATOR by registry.register(MNames.CHEMICAL_GENERATOR) { MenuType(::ChemicalGeneratorMenu, FeatureFlags.VANILLA_SET) }
val PLATE_PRESS: MenuType<PlatePressMenu> by registry.register(MNames.PLATE_PRESS) { MenuType(::PlatePressMenu, FeatureFlags.VANILLA_SET) } val PLATE_PRESS by registry.register(MNames.PLATE_PRESS) { MenuType(::PlatePressMenu, FeatureFlags.VANILLA_SET) }
val POWERED_FURNACE: MenuType<PoweredFurnaceMenu> by registry.register(MNames.POWERED_FURNACE) { MenuType(PoweredFurnaceMenu::furnace, FeatureFlags.VANILLA_SET) } val POWERED_FURNACE by registry.register(MNames.POWERED_FURNACE) { MenuType(PoweredFurnaceMenu::furnace, FeatureFlags.VANILLA_SET) }
val POWERED_BLAST_FURNACE: MenuType<PoweredFurnaceMenu> by registry.register(MNames.POWERED_BLAST_FURNACE) { MenuType(PoweredFurnaceMenu::blasting, FeatureFlags.VANILLA_SET) } val POWERED_BLAST_FURNACE by registry.register(MNames.POWERED_BLAST_FURNACE) { MenuType(PoweredFurnaceMenu::blasting, FeatureFlags.VANILLA_SET) }
val POWERED_SMOKER: MenuType<PoweredFurnaceMenu> by registry.register(MNames.POWERED_SMOKER) { MenuType(PoweredFurnaceMenu::smoking, FeatureFlags.VANILLA_SET) } val POWERED_SMOKER by registry.register(MNames.POWERED_SMOKER) { MenuType(PoweredFurnaceMenu::smoking, FeatureFlags.VANILLA_SET) }
val TWIN_PLATE_PRESS: MenuType<TwinPlatePressMenu> by registry.register(MNames.TWIN_PLATE_PRESS) { MenuType(::TwinPlatePressMenu, FeatureFlags.VANILLA_SET) } val TWIN_PLATE_PRESS by registry.register(MNames.TWIN_PLATE_PRESS) { MenuType(::TwinPlatePressMenu, FeatureFlags.VANILLA_SET) }
val MATTER_RECYCLER: MenuType<MatterRecyclerMenu> by registry.register(MNames.MATTER_RECYCLER) { MenuType(::MatterRecyclerMenu, FeatureFlags.VANILLA_SET) } val MATTER_RECYCLER by registry.register(MNames.MATTER_RECYCLER) { MenuType(::MatterRecyclerMenu, FeatureFlags.VANILLA_SET) }
val ENERGY_SERVO: MenuType<EnergyServoMenu> by registry.register(MNames.ENERGY_SERVO) { MenuType(::EnergyServoMenu, FeatureFlags.VANILLA_SET) } val ENERGY_SERVO by registry.register(MNames.ENERGY_SERVO) { MenuType(::EnergyServoMenu, FeatureFlags.VANILLA_SET) }
val HOLO_SIGN: MenuType<HoloSignMenu> by registry.register(MNames.HOLO_SIGN) { MenuType(::HoloSignMenu, FeatureFlags.VANILLA_SET) } val HOLO_SIGN by registry.register(MNames.HOLO_SIGN) { MenuType(::HoloSignMenu, FeatureFlags.VANILLA_SET) }
val COBBLESTONE_GENERATOR: MenuType<CobblerMenu> by registry.register(MNames.COBBLESTONE_GENERATOR) { MenuType(::CobblerMenu, FeatureFlags.VANILLA_SET) } val COBBLESTONE_GENERATOR by registry.register(MNames.COBBLESTONE_GENERATOR) { MenuType(::CobblerMenu, FeatureFlags.VANILLA_SET) }
val ESSENCE_STORAGE: MenuType<EssenceStorageMenu> by registry.register(MNames.ESSENCE_STORAGE) { MenuType(::EssenceStorageMenu, FeatureFlags.VANILLA_SET) } val ESSENCE_STORAGE by registry.register(MNames.ESSENCE_STORAGE) { MenuType(::EssenceStorageMenu, FeatureFlags.VANILLA_SET) }
val ITEM_REPAIER: MenuType<MatterReconstructorMenu> by registry.register(MNames.MATTER_RECONSTRUCTOR) { MenuType(::MatterReconstructorMenu, FeatureFlags.VANILLA_SET) } val ITEM_REPAIER by registry.register(MNames.MATTER_RECONSTRUCTOR) { MenuType(::MatterReconstructorMenu, FeatureFlags.VANILLA_SET) }
val FLUID_TANK: MenuType<FluidTankMenu> by registry.register(MNames.FLUID_TANK) { MenuType(::FluidTankMenu, FeatureFlags.VANILLA_SET) } val FLUID_TANK by registry.register(MNames.FLUID_TANK) { MenuType(::FluidTankMenu, FeatureFlags.VANILLA_SET) }
val PAINTER: MenuType<PainterMenu> by registry.register(MNames.PAINTER) { MenuType(::PainterMenu, FeatureFlags.VANILLA_SET) } val PAINTER by registry.register(MNames.PAINTER) { MenuType(::PainterMenu, FeatureFlags.VANILLA_SET) }
val MATTER_ENTANGLER: MenuType<MatterEntanglerMenu> by registry.register(MNames.MATTER_ENTANGLER) { MenuType(::MatterEntanglerMenu, FeatureFlags.VANILLA_SET) } val MATTER_ENTANGLER by registry.register(MNames.MATTER_ENTANGLER) { MenuType(::MatterEntanglerMenu, FeatureFlags.VANILLA_SET) }
val STORAGE_BUS: MenuType<StorageBusMenu> by registry.register(MNames.STORAGE_BUS) { MenuType(::StorageBusMenu, FeatureFlags.VANILLA_SET) } val STORAGE_BUS by registry.register(MNames.STORAGE_BUS) { MenuType(::StorageBusMenu, FeatureFlags.VANILLA_SET) }
val STORAGE_IMPORTER_EXPORTER: MenuType<StorageImporterExporterMenu> by registry.register(MNames.STORAGE_IMPORTER) { MenuType(::StorageImporterExporterMenu, FeatureFlags.VANILLA_SET) } val STORAGE_IMPORTER_EXPORTER by registry.register(MNames.STORAGE_IMPORTER) { MenuType(::StorageImporterExporterMenu, FeatureFlags.VANILLA_SET) }
val STORAGE_POWER_SUPPLIER: MenuType<StoragePowerSupplierMenu> by registry.register(MNames.STORAGE_POWER_SUPPLIER) { MenuType(::StoragePowerSupplierMenu, FeatureFlags.VANILLA_SET) } val STORAGE_POWER_SUPPLIER by registry.register(MNames.STORAGE_POWER_SUPPLIER) { MenuType(::StoragePowerSupplierMenu, FeatureFlags.VANILLA_SET) }
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
registry.register(bus) registry.register(bus)

View File

@ -20,15 +20,15 @@ object MRecipes {
} }
} }
private val types = DeferredRegister.create(ForgeRegistries.RECIPE_TYPES, OverdriveThatMatters.MOD_ID) private val types = MDeferredRegister(ForgeRegistries.RECIPE_TYPES, OverdriveThatMatters.MOD_ID)
private val serializers = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, OverdriveThatMatters.MOD_ID) private val serializers = MDeferredRegister(ForgeRegistries.RECIPE_SERIALIZERS, OverdriveThatMatters.MOD_ID)
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
types.register(bus) types.register(bus)
serializers.register(bus) serializers.register(bus)
} }
private fun <T : Recipe<*>> register(name: String): RegistryObject<Type<T>> { private fun <T : Recipe<*>> register(name: String): MDeferredRegister<*>.Entry<Type<T>> {
return types.register(name) { Type(name) } return types.register(name) { Type(name) }
} }

View File

@ -114,11 +114,11 @@ object MRegistry : IBlockItemRegistryAcceptor {
private val decorativeBlocks = ArrayList<IBlockItemRegistryAcceptor>() private val decorativeBlocks = ArrayList<IBlockItemRegistryAcceptor>()
override fun registerItems(registry: DeferredRegister<Item>) { override fun registerItems(registry: MDeferredRegister<Item>) {
decorativeBlocks.forEach { it.registerItems(registry) } decorativeBlocks.forEach { it.registerItems(registry) }
} }
override fun registerBlocks(registry: DeferredRegister<Block>) { override fun registerBlocks(registry: MDeferredRegister<Block>) {
decorativeBlocks.forEach { it.registerBlocks(registry) } decorativeBlocks.forEach { it.registerBlocks(registry) }
} }

View File

@ -11,19 +11,19 @@ import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
object MSoundEvents { object MSoundEvents {
private val registry: DeferredRegister<SoundEvent> = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, OverdriveThatMatters.MOD_ID) private val registry: MDeferredRegister<SoundEvent> = MDeferredRegister(ForgeRegistries.SOUND_EVENTS, OverdriveThatMatters.MOD_ID)
// TODO: 1.19.3 // TODO: 1.19.3
private fun make(name: String) = registry.register(name) { SoundEvent.createVariableRangeEvent(ResourceLocation(OverdriveThatMatters.MOD_ID, name)) } private fun make(name: String): MDeferredRegister<SoundEvent>.Entry<SoundEvent> = registry.register(name) { SoundEvent.createVariableRangeEvent(ResourceLocation(OverdriveThatMatters.MOD_ID, name)) }
val RIFLE_SHOT: SoundEvent by make("item.rifle_shot") val RIFLE_SHOT by make("item.rifle_shot")
val PLASMA_WEAPON_OVERHEAT: SoundEvent by make("item.plasma_weapon_overheat") val PLASMA_WEAPON_OVERHEAT by make("item.plasma_weapon_overheat")
val PLAYER_BECOME_ANDROID: SoundEvent by make("player_become_android") val PLAYER_BECOME_ANDROID by make("player_become_android")
val CARGO_CRATE_OPEN: SoundEvent by make("cargo_crate_open") val CARGO_CRATE_OPEN by make("cargo_crate_open")
val ANDROID_JUMP_BOOST: SoundEvent by make("android.jump_boost") val ANDROID_JUMP_BOOST by make("android.jump_boost")
val ANDROID_SHOCKWAVE: SoundEvent by make("android.shockwave") val ANDROID_SHOCKWAVE by make("android.shockwave")
val ANDROID_PROJ_PARRY: SoundEvent by make("android.projectile_parry") val ANDROID_PROJ_PARRY by make("android.projectile_parry")
internal fun register(bus: IEventBus) { internal fun register(bus: IEventBus) {
registry.register(bus) registry.register(bus)

View File

@ -8,8 +8,10 @@ import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraftforge.registries.DeferredRegister import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.RegistryObject import net.minecraftforge.registries.RegistryObject
import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import java.util.EnumMap import java.util.EnumMap
import java.util.function.Supplier
/** /**
* Colored only * Colored only
@ -25,8 +27,8 @@ open class ColoredDecorativeBlock(
var registeredBlocks = false var registeredBlocks = false
private set private set
protected val itemMap = EnumMap<DyeColor, RegistryObject<Item>>(DyeColor::class.java) protected val itemMap = EnumMap<DyeColor, Supplier<Item>>(DyeColor::class.java)
protected val blockMap = EnumMap<DyeColor, RegistryObject<Block>>(DyeColor::class.java) protected val blockMap = EnumMap<DyeColor, Supplier<Block>>(DyeColor::class.java)
fun forEachItem(consumer: (String, DyeColor, Item) -> Unit) { fun forEachItem(consumer: (String, DyeColor, Item) -> Unit) {
MRegistry.DYE_ORDER.forEach { MRegistry.DYE_ORDER.forEach {
@ -60,7 +62,7 @@ open class ColoredDecorativeBlock(
SupplierMap(MRegistry.DYE_ORDER.map { it to itemMap[it]!! }) SupplierMap(MRegistry.DYE_ORDER.map { it to itemMap[it]!! })
} }
override fun registerBlocks(registry: DeferredRegister<Block>) { override fun registerBlocks(registry: MDeferredRegister<Block>) {
check(blockMap.isEmpty()) { "( ͡° ͜ʖ ͡°) No. \\(• ε •)/ ( ͠° ل͜ ͡°) ( ͠° ͟ ͟ʖ ͡°) (ง ͠° ͟ل͜ ͡°)ง ( ͡°︺͡°) ('ω')" } check(blockMap.isEmpty()) { "( ͡° ͜ʖ ͡°) No. \\(• ε •)/ ( ͠° ل͜ ͡°) ( ͠° ͟ ͟ʖ ͡°) (ง ͠° ͟ل͜ ͡°)ง ( ͡°︺͡°) ('ω')" }
MRegistry.DYE_ORDER.forEach { MRegistry.DYE_ORDER.forEach {
@ -72,7 +74,7 @@ open class ColoredDecorativeBlock(
private val properties = Item.Properties().stacksTo(64) private val properties = Item.Properties().stacksTo(64)
override fun registerItems(registry: DeferredRegister<Item>) { override fun registerItems(registry: MDeferredRegister<Item>) {
check(itemMap.isEmpty()) { "( ͡° ͜ʖ ͡°) No. \\(• ε •)/ ( ͠° ل͜ ͡°) ( ͠° ͟ ͟ʖ ͡°) (ง ͠° ͟ل͜ ͡°)ง ( ͡°︺͡°) ('ω')" } check(itemMap.isEmpty()) { "( ͡° ͜ʖ ͡°) No. \\(• ε •)/ ( ͠° ل͜ ͡°) ( ͠° ͟ ͟ʖ ͡°) (ง ͠° ͟ل͜ ͡°)ง ( ͡°︺͡°) ('ω')" }
check(registeredBlocks) { "wtffffff???????????" } check(registeredBlocks) { "wtffffff???????????" }

View File

@ -11,17 +11,16 @@ import net.minecraft.world.level.block.state.BlockBehaviour
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.VoxelShape import net.minecraft.world.phys.shapes.VoxelShape
import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.RegistryObject
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.getShapeForEachState import ru.dbotthepony.mc.otm.block.getShapeForEachState
import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom
import ru.dbotthepony.mc.otm.core.util.WriteOnce import ru.dbotthepony.mc.otm.core.util.WriteOnce
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import ru.dbotthepony.mc.otm.registry.MRegistry import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.shapes.BlockShape import ru.dbotthepony.mc.otm.shapes.BlockShape
import ru.dbotthepony.mc.otm.shapes.BlockShapes import java.util.function.Supplier
import java.util.stream.Stream import java.util.stream.Stream
/** /**
@ -31,8 +30,8 @@ class DecorativeBlock(
baseName: String, baseName: String,
private val provider: (DyeColor?) -> Block, private val provider: (DyeColor?) -> Block,
) : ColoredDecorativeBlock(baseName, provider) { ) : ColoredDecorativeBlock(baseName, provider) {
private var _block: RegistryObject<Block> by WriteOnce() private var _block: Supplier<Block> by WriteOnce()
private var _item: RegistryObject<Item> by WriteOnce() private var _item: Supplier<Item> by WriteOnce()
val block: Block get() = _block.get() val block: Block get() = _block.get()
val item: Item get() = _item.get() val item: Item get() = _item.get()
@ -47,12 +46,12 @@ class DecorativeBlock(
SupplierMap(Streams.concat(MRegistry.DYE_ORDER.stream().map { it to itemMap[it]!! }, Stream.of(null to _item))) SupplierMap(Streams.concat(MRegistry.DYE_ORDER.stream().map { it to itemMap[it]!! }, Stream.of(null to _item)))
} }
override fun registerBlocks(registry: DeferredRegister<Block>) { override fun registerBlocks(registry: MDeferredRegister<Block>) {
_block = registry.register(baseName) { provider.invoke(null) } _block = registry.register(baseName) { provider.invoke(null) }
super.registerBlocks(registry) super.registerBlocks(registry)
} }
override fun registerItems(registry: DeferredRegister<Item>) { override fun registerItems(registry: MDeferredRegister<Item>) {
_item = registry.register(baseName) { BlockItem(_block.get(), Item.Properties().stacksTo(64)) } _item = registry.register(baseName) { BlockItem(_block.get(), Item.Properties().stacksTo(64)) }
super.registerItems(registry) super.registerItems(registry)
} }

View File

@ -2,9 +2,9 @@ package ru.dbotthepony.mc.otm.registry.objects
import net.minecraft.world.item.Item import net.minecraft.world.item.Item
import net.minecraft.world.level.block.Block import net.minecraft.world.level.block.Block
import net.minecraftforge.registries.DeferredRegister import ru.dbotthepony.mc.otm.registry.MDeferredRegister
interface IBlockItemRegistryAcceptor { interface IBlockItemRegistryAcceptor {
fun registerItems(registry: DeferredRegister<Item>) fun registerItems(registry: MDeferredRegister<Item>)
fun registerBlocks(registry: DeferredRegister<Block>) fun registerBlocks(registry: MDeferredRegister<Block>)
} }

View File

@ -10,6 +10,7 @@ import net.minecraftforge.registries.DeferredRegister
import net.minecraftforge.registries.RegistryObject import net.minecraftforge.registries.RegistryObject
import ru.dbotthepony.mc.otm.core.collect.SupplierList import ru.dbotthepony.mc.otm.core.collect.SupplierList
import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.collect.SupplierMap
import ru.dbotthepony.mc.otm.registry.MDeferredRegister
import java.util.EnumMap import java.util.EnumMap
import java.util.function.Supplier import java.util.function.Supplier
@ -21,8 +22,8 @@ class StripedColoredDecorativeBlock(
BlockItem(block, Item.Properties().stacksTo(64)) BlockItem(block, Item.Properties().stacksTo(64))
} }
) : IBlockItemRegistryAcceptor { ) : IBlockItemRegistryAcceptor {
private val mapBlocks = EnumMap<DyeColor, EnumMap<DyeColor, RegistryObject<Block>>>(DyeColor::class.java) private val mapBlocks = EnumMap<DyeColor, EnumMap<DyeColor, Supplier<Block>>>(DyeColor::class.java)
private val mapItems = EnumMap<DyeColor, EnumMap<DyeColor, RegistryObject<Item>>>(DyeColor::class.java) private val mapItems = EnumMap<DyeColor, EnumMap<DyeColor, Supplier<Item>>>(DyeColor::class.java)
fun getBlockNullable(base: DyeColor, stripe: DyeColor): Block? { fun getBlockNullable(base: DyeColor, stripe: DyeColor): Block? {
check(registeredBlocks) { "Didn't register items yet" } check(registeredBlocks) { "Didn't register items yet" }
@ -82,7 +83,7 @@ class StripedColoredDecorativeBlock(
SupplierList(mapBlocks.flatMap { it.value.values }) SupplierList(mapBlocks.flatMap { it.value.values })
} }
override fun registerItems(registry: DeferredRegister<Item>) { override fun registerItems(registry: MDeferredRegister<Item>) {
for (base in DyeColor.entries) { for (base in DyeColor.entries) {
for (stripe in DyeColor.entries) { for (stripe in DyeColor.entries) {
if (base == stripe) { if (base == stripe) {
@ -97,7 +98,7 @@ class StripedColoredDecorativeBlock(
registeredItems = true registeredItems = true
} }
override fun registerBlocks(registry: DeferredRegister<Block>) { override fun registerBlocks(registry: MDeferredRegister<Block>) {
for (base in DyeColor.entries) { for (base in DyeColor.entries) {
for (stripe in DyeColor.entries) { for (stripe in DyeColor.entries) {
if (base == stripe) { if (base == stripe) {