Compare commits

...

9 Commits

7 changed files with 155 additions and 73 deletions

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.block.entity package ru.dbotthepony.mc.otm.block.entity
import it.unimi.dsi.fastutil.booleans.BooleanConsumer
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.longs.Long2ObjectFunction import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
@ -46,15 +47,18 @@ import ru.dbotthepony.mc.otm.core.collect.WeakHashSet
import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.math.BlockRotation import ru.dbotthepony.mc.otm.core.math.BlockRotation
import ru.dbotthepony.mc.otm.core.math.RelativeSide import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.core.math.plus
import ru.dbotthepony.mc.otm.core.util.IntCounter import ru.dbotthepony.mc.otm.core.util.IntCounter
import ru.dbotthepony.mc.otm.core.util.Savetables import ru.dbotthepony.mc.otm.core.util.Savetables
import ru.dbotthepony.mc.otm.core.util.TickList import ru.dbotthepony.mc.otm.core.util.TickList
import ru.dbotthepony.mc.otm.core.util.countingLazy import ru.dbotthepony.mc.otm.core.util.countingLazy
import ru.dbotthepony.mc.otm.network.BlockEntitySyncPacket import ru.dbotthepony.mc.otm.network.BlockEntitySyncPacket
import ru.dbotthepony.mc.otm.onceServer import ru.dbotthepony.mc.otm.onceServer
import ru.dbotthepony.mc.otm.registry.MBlocks
import ru.dbotthepony.mc.otm.sometimeServer import ru.dbotthepony.mc.otm.sometimeServer
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import java.util.* import java.util.*
import java.util.function.BooleanSupplier
import java.util.function.Consumer import java.util.function.Consumer
import java.util.function.Predicate import java.util.function.Predicate
import java.util.function.Supplier import java.util.function.Supplier
@ -69,7 +73,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
private val sidelessCaps = Reference2ObjectOpenHashMap<BlockCapability<*, *>, Any>() private val sidelessCaps = Reference2ObjectOpenHashMap<BlockCapability<*, *>, Any>()
private val sidedCaps = Array(RelativeSide.entries.size) { private val sidedCaps = Array(RelativeSide.entries.size) {
Reference2ObjectOpenHashMap<BlockCapability<*, *>, Any>() Reference2ObjectOpenHashMap<BlockCapability<*, *>, ControllableCapability<*>>()
} }
protected val tickList = TickList() protected val tickList = TickList()
@ -119,33 +123,97 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
tickList.tick() tickList.tick()
} }
interface CapabilityControl : BooleanSupplier, BooleanConsumer {
var isEnabled: Boolean
fun doDispatchInvalidation()
fun dontDispatchInvalidation()
override fun getAsBoolean(): Boolean {
return isEnabled
}
override fun accept(t: Boolean) {
isEnabled = t
}
}
private inner class ControllableCapability<T : Any>(val capability: T) : CapabilityControl {
override var isEnabled: Boolean = true
set(value) {
if (value != field) {
field = value
if (dispatchInvalidation) level?.invalidateCapabilities(blockPos)
}
}
private var dispatchInvalidation = true
override fun doDispatchInvalidation() {
dispatchInvalidation = true
}
override fun dontDispatchInvalidation() {
dispatchInvalidation = false
}
fun getOrNull(): T? {
return if (isEnabled) capability else null
}
}
private inner class ControllableCapabilitySet(val capabilities: List<CapabilityControl>) : CapabilityControl {
override var isEnabled: Boolean
get() = capabilities.all { it.isEnabled }
set(value) {
capabilities.forEach { it.dontDispatchInvalidation() }
try {
capabilities.forEach { it.isEnabled = value }
} finally {
capabilities.forEach { it.doDispatchInvalidation() }
level?.invalidateCapabilities(blockPos)
}
}
override fun doDispatchInvalidation() {
capabilities.forEach { it.doDispatchInvalidation() }
}
override fun dontDispatchInvalidation() {
capabilities.forEach { it.dontDispatchInvalidation() }
}
}
/** /**
* exposes capability when no side is specified * exposes capability when no side is specified
*/ */
protected fun <T : Any> exposeSideless(capability: BlockCapability<T, *>, value: T) { protected fun <T : Any> exposeSideless(capability: BlockCapability<T, *>, value: T) {
check(!sidelessCaps.containsKey(capability)) { "Already has globally exposed $capability!" } check(!sidelessCaps.containsKey(capability)) { "Already has globally exposed $capability!" }
MBlocks.ensureCapabilityIsKnown(capability)
sidelessCaps[capability] = value sidelessCaps[capability] = value
setChanged() setChanged()
level?.invalidateCapabilities(blockPos) level?.invalidateCapabilities(blockPos)
} }
protected fun <T : Any> exposeSided(side: RelativeSide, capability: BlockCapability<T, *>, value: T) { protected fun <T : Any> exposeSided(side: RelativeSide, capability: BlockCapability<T, *>, value: T): CapabilityControl {
val map = sidedCaps[side.ordinal] val map = sidedCaps[side.ordinal]
check(!map.containsKey(capability)) { "Already has exposed $capability on $side!" } check(!map.containsKey(capability)) { "Already has exposed $capability on $side!" }
map[capability] = value MBlocks.ensureCapabilityIsKnown(capability)
val wrapper = ControllableCapability(value)
map[capability] = wrapper
setChanged() setChanged()
level?.invalidateCapabilities(blockPos) level?.invalidateCapabilities(blockPos)
return wrapper
} }
/** /**
* Exposes capability unconditionally, on all sides and sideless * Exposes capability unconditionally, on all sides and sideless
*/ */
protected fun <T : Any> exposeGlobally(capability: BlockCapability<T, *>, value: T, predicate: Predicate<RelativeSide> = Predicate { true }) { protected fun <T : Any> exposeGlobally(capability: BlockCapability<T, *>, value: T, predicate: Predicate<RelativeSide> = Predicate { true }): CapabilityControl {
exposeSideless(capability, value) exposeSideless(capability, value)
for (side in RelativeSide.entries) return ControllableCapabilitySet(RelativeSide.entries.stream().filter(predicate).map { exposeSided(it, capability, value) }.toList())
if (predicate.test(side))
exposeSided(side, capability, value)
} }
protected fun exposeEnergySideless(value: IMatteryEnergyStorage) { protected fun exposeEnergySideless(value: IMatteryEnergyStorage) {
@ -153,14 +221,22 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
exposeSideless(MatteryCapability.BLOCK_ENERGY, value) exposeSideless(MatteryCapability.BLOCK_ENERGY, value)
} }
protected fun exposeEnergyGlobally(value: IMatteryEnergyStorage) { protected fun exposeEnergyGlobally(value: IMatteryEnergyStorage): CapabilityControl {
exposeGlobally(Capabilities.EnergyStorage.BLOCK, value) return ControllableCapabilitySet(
exposeGlobally(MatteryCapability.BLOCK_ENERGY, value) listOf(
exposeGlobally(Capabilities.EnergyStorage.BLOCK, value),
exposeGlobally(MatteryCapability.BLOCK_ENERGY, value)
)
)
} }
protected fun exposeEnergySided(side: RelativeSide, value: IMatteryEnergyStorage) { protected fun exposeEnergySided(side: RelativeSide, value: IMatteryEnergyStorage): CapabilityControl {
exposeSided(side, Capabilities.EnergyStorage.BLOCK, value) return ControllableCapabilitySet(
exposeSided(side, MatteryCapability.BLOCK_ENERGY, value) listOf(
exposeSided(side, Capabilities.EnergyStorage.BLOCK, value),
exposeSided(side, MatteryCapability.BLOCK_ENERGY, value)
)
)
} }
protected fun waitForServerLevel(lambda: () -> Unit) { protected fun waitForServerLevel(lambda: () -> Unit) {
@ -173,7 +249,7 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
fun <T : Any> getCapability(cap: BlockCapability<T, *>, side: Direction?): T? { fun <T : Any> getCapability(cap: BlockCapability<T, *>, side: Direction?): T? {
if (side != null) { if (side != null) {
return sidedCaps[blockRotation.dir2Side(side).ordinal][cap] as T? return sidedCaps[blockRotation.dir2Side(side).ordinal][cap]?.getOrNull() as T?
} }
return sidelessCaps[cap] as T? return sidelessCaps[cap] as T?
@ -277,9 +353,10 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc
val creationVersion = ++currentVersion val creationVersion = ++currentVersion
val direction = blockRotation.side2Dir(side)
cache = BlockCapabilityCache.create( cache = BlockCapabilityCache.create(
capability, level, blockPos, capability, level, blockPos + direction.normal, direction.opposite,
blockRotation.side2Dir(side),
{ !isRemoved || creationVersion != currentVersion }, { !isRemoved || creationVersion != currentVersion },
// IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!") // IllegalStateException("Do not call getCapability on an invalid cache or from the invalidation listener!")
// what a shame. // what a shame.

View File

@ -147,10 +147,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
inner class Piece(val side: RelativeSide) : IFluidHandler, ITickable { inner class Piece(val side: RelativeSide) : IFluidHandler, ITickable {
private val ticker = tickList.Ticker(this) private val ticker = tickList.Ticker(this)
private val neighbour = CapabilityCache(side, Capabilities.FluidHandler.BLOCK) private val neighbour = CapabilityCache(side, Capabilities.FluidHandler.BLOCK)
private val control = exposeSided(side, Capabilities.FluidHandler.BLOCK, this)
init {
exposeSided(side, Capabilities.FluidHandler.BLOCK, this)
}
private fun updateTickerState() { private fun updateTickerState() {
ticker.isEnabled = ticker.isEnabled =
@ -174,7 +171,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
access.accept(value) access.accept(value)
markDirtyFast() markDirtyFast()
updateTickerState() updateTickerState()
level?.invalidateCapabilities(blockPos) control.isEnabled = value != FlowDirection.NONE
} }
}) })
@ -273,6 +270,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
return FluidStack.EMPTY return FluidStack.EMPTY
} }
} }
init {
if (flow == FlowDirection.NONE) {
control.isEnabled = false
}
}
} }
} }
@ -350,10 +353,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
inner class Piece(val side: RelativeSide, val possibleModes: FlowDirection) : IMatteryEnergyStorage, ITickable { inner class Piece(val side: RelativeSide, val possibleModes: FlowDirection) : IMatteryEnergyStorage, ITickable {
private val neighbour = CapabilityCache(side, Capabilities.EnergyStorage.BLOCK) private val neighbour = CapabilityCache(side, Capabilities.EnergyStorage.BLOCK)
private val control = exposeEnergySided(side, this)
init {
exposeEnergySided(side, this)
}
override var batteryLevel: Decimal by energy::batteryLevel override var batteryLevel: Decimal by energy::batteryLevel
override val maxBatteryLevel: Decimal by energy::maxBatteryLevel override val maxBatteryLevel: Decimal by energy::maxBatteryLevel
@ -453,9 +453,15 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
access.accept(value) access.accept(value)
markDirtyFast() markDirtyFast()
updateTickerState() updateTickerState()
level?.invalidateCapabilities(blockPos) control.isEnabled = value != FlowDirection.NONE
} }
}).delegate }).delegate
init {
if (energyFlow == FlowDirection.NONE) {
control.isEnabled = false
}
}
} }
} }
@ -566,10 +572,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
private val neighbour = CapabilityCache(side, Capabilities.ItemHandler.BLOCK) private val neighbour = CapabilityCache(side, Capabilities.ItemHandler.BLOCK)
private val ticker = tickList.Ticker(this) private val ticker = tickList.Ticker(this)
private val control = exposeSided(side, Capabilities.ItemHandler.BLOCK, this)
init {
exposeSided(side, Capabilities.ItemHandler.BLOCK, this)
}
private var innerSlotPull = 0 private var innerSlotPull = 0
private var outerSlotPull = 0 private var outerSlotPull = 0
@ -601,7 +604,7 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
ItemHandlerMode.BATTERY -> battery!! ItemHandlerMode.BATTERY -> battery!!
} }
level?.invalidateCapabilities(blockPos) control.isEnabled = value != ItemHandlerMode.DISABLED
} }
}).delegate }).delegate
@ -705,6 +708,12 @@ abstract class MatteryDeviceBlockEntity(blockEntityType: BlockEntityType<*>, blo
override fun isItemValid(slot: Int, stack: ItemStack): Boolean { override fun isItemValid(slot: Int, stack: ItemStack): Boolean {
return currentHandler.isItemValid(slot, stack) return currentHandler.isItemValid(slot, stack)
} }
init {
if (mode == ItemHandlerMode.DISABLED) {
control.isEnabled = false
}
}
} }
} }

View File

@ -3,6 +3,7 @@ package ru.dbotthepony.mc.otm.client.screen
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import it.unimi.dsi.fastutil.ints.Int2ObjectFunction import it.unimi.dsi.fastutil.ints.Int2ObjectFunction
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ObjectArrayList
import net.minecraft.ChatFormatting import net.minecraft.ChatFormatting
import net.minecraft.client.gui.Font import net.minecraft.client.gui.Font
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
@ -54,6 +55,7 @@ import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import java.util.* import java.util.*
import kotlin.collections.ArrayDeque import kotlin.collections.ArrayDeque
import kotlin.collections.ArrayList
import kotlin.collections.List import kotlin.collections.List
import kotlin.collections.MutableSet import kotlin.collections.MutableSet
import kotlin.collections.isNotEmpty import kotlin.collections.isNotEmpty
@ -471,7 +473,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
override fun onClose() { override fun onClose() {
super.onClose() super.onClose()
panels.forEach { it.markRemoved() } ObjectArrayList(panels).forEach { it.markRemoved() }
} }
public override fun recalculateQuickCraftRemaining() { public override fun recalculateQuickCraftRemaining() {
@ -506,7 +508,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
var click = false var click = false
var focusKilled = false var focusKilled = false
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (click || !panel.mouseClickedChecked(x, y, button)) { if (click || !panel.mouseClickedChecked(x, y, button)) {
focusKilled = panel.killFocus() || focusKilled focusKilled = panel.killFocus() || focusKilled
} else { } else {
@ -525,7 +527,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
private var lastDragSlot: Slot? = null private var lastDragSlot: Slot? = null
override fun mouseDragged(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean { override fun mouseDragged(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean {
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (panel.mouseDraggedChecked(x, y, button, xDelta, yDelta)) { if (panel.mouseDraggedChecked(x, y, button, xDelta, yDelta)) {
if (returnSlot != null) { if (returnSlot != null) {
super.mouseDragged(x, y, button, xDelta, yDelta) super.mouseDragged(x, y, button, xDelta, yDelta)
@ -553,7 +555,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
} }
} }
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (panel.mouseReleasedChecked(p_97812_, p_97813_, p_97814_)) { if (panel.mouseReleasedChecked(p_97812_, p_97813_, p_97814_)) {
if (returnSlot != null) { if (returnSlot != null) {
super.mouseReleased(p_97812_, p_97813_, p_97814_) super.mouseReleased(p_97812_, p_97813_, p_97814_)
@ -569,7 +571,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
} }
override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean { override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean {
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (panel.mouseScrolledChecked(mouseX, mouseY, scrollY)) { if (panel.mouseScrolledChecked(mouseX, mouseY, scrollY)) {
return true return true
} }
@ -579,7 +581,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
} }
override fun keyReleased(p_94715_: Int, p_94716_: Int, p_94717_: Int): Boolean { override fun keyReleased(p_94715_: Int, p_94716_: Int, p_94717_: Int): Boolean {
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (panel.keyReleased(p_94715_, p_94716_, p_94717_)) { if (panel.keyReleased(p_94715_, p_94716_, p_94717_)) {
return true return true
} }
@ -589,7 +591,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
} }
override fun charTyped(p_94683_: Char, p_94684_: Int): Boolean { override fun charTyped(p_94683_: Char, p_94684_: Int): Boolean {
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (panel.charTyped(p_94683_, p_94684_)) { if (panel.charTyped(p_94683_, p_94684_)) {
return true return true
} }
@ -599,7 +601,7 @@ abstract class MatteryScreen<T : MatteryMenu>(menu: T, inventory: Inventory, tit
} }
override fun keyPressed(key: Int, scancode: Int, mods: Int): Boolean { override fun keyPressed(key: Int, scancode: Int, mods: Int): Boolean {
for (panel in panels) { for (panel in ObjectArrayList(panels)) {
if (panel.keyPressed(key, scancode, mods)) { if (panel.keyPressed(key, scancode, mods)) {
if (returnSlot != null) { if (returnSlot != null) {
super.keyPressed(key, scancode, mods) super.keyPressed(key, scancode, mods)

View File

@ -32,6 +32,7 @@ import ru.dbotthepony.mc.otm.core.collect.count
import ru.dbotthepony.mc.otm.core.collect.emptyIterator import ru.dbotthepony.mc.otm.core.collect.emptyIterator
import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filter
import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.collect.toList
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.registryName
@ -286,29 +287,13 @@ open class MatteryContainer(var listener: ContainerListener, private val size: I
} }
override fun serializeNBT(registries: HolderLookup.Provider): CompoundTag { override fun serializeNBT(registries: HolderLookup.Provider): CompoundTag {
return CompoundTag().also { val state = SerializedState(
it["items"] = ListTag().also { slotIterator(true).map { SerializedItem(it.item, it.slot) }.toList(size),
for ((i, item) in slots.withIndex()) { filters.withIndex().iterator().filter { it.value != null }.map { SerializedFilter(it.value!!, it.index) }.toList()
if (!item.isEmpty) { )
it.add(item.save(registries).also {
it as CompoundTag
it["slotIndex"] = i
})
}
}
}
it["filters"] = ListTag().also { return SerializedState.CODEC.encodeStart(registries.createSerializationContext(NbtOps.INSTANCE), state)
for ((i, filter) in filters.withIndex()) { .resultOrPartial { throw RuntimeException("Failed to encode container contents: $it") }.get() as CompoundTag
if (filter != null) {
it.add(CompoundTag().also {
it["filter"] = filter.registryName!!.toString()
it["slotIndex"] = i
})
}
}
}
}
} }
final override fun isEmpty(): Boolean { final override fun isEmpty(): Boolean {

View File

@ -1,7 +0,0 @@
package ru.dbotthepony.mc.otm.item.armor
import net.minecraft.world.item.ArmorItem
import ru.dbotthepony.mc.otm.registry.MArmorMaterials
class SimpleTritaniumArmorItem(slot: Type) : ArmorItem(MArmorMaterials.SIMPLE_TRITANIUM, slot, Properties().stacksTo(1)) {
}

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.registry package ru.dbotthepony.mc.otm.registry
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import net.minecraft.core.Direction import net.minecraft.core.Direction
import net.minecraft.core.registries.BuiltInRegistries import net.minecraft.core.registries.BuiltInRegistries
import net.minecraft.util.valueproviders.UniformInt import net.minecraft.util.valueproviders.UniformInt
@ -19,6 +20,7 @@ import net.minecraft.world.level.material.MapColor
import net.minecraft.world.level.material.PushReaction import net.minecraft.world.level.material.PushReaction
import net.neoforged.bus.api.IEventBus import net.neoforged.bus.api.IEventBus
import net.neoforged.neoforge.capabilities.BlockCapability import net.neoforged.neoforge.capabilities.BlockCapability
import net.neoforged.neoforge.capabilities.Capabilities
import net.neoforged.neoforge.capabilities.IBlockCapabilityProvider import net.neoforged.neoforge.capabilities.IBlockCapabilityProvider
import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent import net.neoforged.neoforge.capabilities.RegisterCapabilitiesEvent
import ru.dbotthepony.mc.otm.block.BlackHoleBlock import ru.dbotthepony.mc.otm.block.BlackHoleBlock
@ -77,6 +79,7 @@ import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredBlastFurnaceBlock import ru.dbotthepony.mc.otm.block.tech.PoweredBlastFurnaceBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock import ru.dbotthepony.mc.otm.block.tech.PoweredFurnaceBlock
import ru.dbotthepony.mc.otm.block.tech.PoweredSmokerBlock import ru.dbotthepony.mc.otm.block.tech.PoweredSmokerBlock
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.config.CablesConfig import ru.dbotthepony.mc.otm.config.CablesConfig
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
@ -85,9 +88,23 @@ import java.util.function.Supplier
object MBlocks { object MBlocks {
private val registry = MDeferredRegister(BuiltInRegistries.BLOCK) private val registry = MDeferredRegister(BuiltInRegistries.BLOCK)
private val knownCaps = ObjectOpenHashSet<BlockCapability<*, *>>()
fun ensureCapabilityIsKnown(cap: BlockCapability<*, *>) {
check(cap in knownCaps) { "Tried to expose capability which wasn't known on mod startup. This is unfortunately limitation with new capability system and can not be fixed, unless NeoForge team decides to rethink their decision to remove per block(entity) dynamic capabilities." }
}
private fun registerCapabilities(event: RegisterCapabilitiesEvent) { private fun registerCapabilities(event: RegisterCapabilitiesEvent) {
// static initializers
MatteryCapability.BLOCK_ENERGY
Capabilities.FluidHandler.BLOCK
Capabilities.EnergyStorage.BLOCK
Capabilities.ItemHandler.BLOCK
// ugly // ugly
for (cap in BlockCapability.getAll()) { for (cap in BlockCapability.getAll()) {
knownCaps.add(cap)
val provider = IBlockCapabilityProvider<Any?, Direction?> { level, pos, state, be, context: Direction? -> val provider = IBlockCapabilityProvider<Any?, Direction?> { level, pos, state, be, context: Direction? ->
if (be is MatteryBlockEntity) { if (be is MatteryBlockEntity) {
return@IBlockCapabilityProvider be.getCapability(cap as BlockCapability<Any, Direction?>, context) return@IBlockCapabilityProvider be.getCapability(cap as BlockCapability<Any, Direction?>, context)

View File

@ -55,7 +55,6 @@ import ru.dbotthepony.mc.otm.item.SimpleUpgrade
import ru.dbotthepony.mc.otm.item.ZPMItem import ru.dbotthepony.mc.otm.item.ZPMItem
import ru.dbotthepony.mc.otm.item.addSimpleDescription import ru.dbotthepony.mc.otm.item.addSimpleDescription
import ru.dbotthepony.mc.otm.item.armor.PortableGravitationStabilizerItem import ru.dbotthepony.mc.otm.item.armor.PortableGravitationStabilizerItem
import ru.dbotthepony.mc.otm.item.armor.SimpleTritaniumArmorItem
import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem import ru.dbotthepony.mc.otm.item.armor.TritaniumArmorItem
import ru.dbotthepony.mc.otm.item.exopack.ExopackProbeItem import ru.dbotthepony.mc.otm.item.exopack.ExopackProbeItem
import ru.dbotthepony.mc.otm.item.exopack.ExopackSlotUpgradeItem import ru.dbotthepony.mc.otm.item.exopack.ExopackSlotUpgradeItem
@ -363,10 +362,10 @@ object MItems {
val TRITANIUM_PANTS: TritaniumArmorItem by registry.register(MNames.TRITANIUM_PANTS) { TritaniumArmorItem(ArmorItem.Type.LEGGINGS) } val TRITANIUM_PANTS: TritaniumArmorItem by registry.register(MNames.TRITANIUM_PANTS) { TritaniumArmorItem(ArmorItem.Type.LEGGINGS) }
val TRITANIUM_BOOTS: TritaniumArmorItem by registry.register(MNames.TRITANIUM_BOOTS) { TritaniumArmorItem(ArmorItem.Type.BOOTS) } val TRITANIUM_BOOTS: TritaniumArmorItem by registry.register(MNames.TRITANIUM_BOOTS) { TritaniumArmorItem(ArmorItem.Type.BOOTS) }
val SIMPLE_TRITANIUM_HELMET: SimpleTritaniumArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_HELMET) { SimpleTritaniumArmorItem(ArmorItem.Type.HELMET) } val SIMPLE_TRITANIUM_HELMET: ArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_HELMET) { ArmorItem(MArmorMaterials.SIMPLE_TRITANIUM, ArmorItem.Type.HELMET, Properties().stacksTo(1)) }
val SIMPLE_TRITANIUM_CHESTPLATE: SimpleTritaniumArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_CHESTPLATE) { SimpleTritaniumArmorItem(ArmorItem.Type.CHESTPLATE) } val SIMPLE_TRITANIUM_CHESTPLATE: ArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_CHESTPLATE) { ArmorItem(MArmorMaterials.SIMPLE_TRITANIUM, ArmorItem.Type.CHESTPLATE, Properties().stacksTo(1)) }
val SIMPLE_TRITANIUM_PANTS: SimpleTritaniumArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_PANTS) { SimpleTritaniumArmorItem(ArmorItem.Type.LEGGINGS) } val SIMPLE_TRITANIUM_PANTS: ArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_PANTS) { ArmorItem(MArmorMaterials.SIMPLE_TRITANIUM, ArmorItem.Type.LEGGINGS, Properties().stacksTo(1)) }
val SIMPLE_TRITANIUM_BOOTS: SimpleTritaniumArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_BOOTS) { SimpleTritaniumArmorItem(ArmorItem.Type.BOOTS) } val SIMPLE_TRITANIUM_BOOTS: ArmorItem by registry.register(MNames.SIMPLE_TRITANIUM_BOOTS) { ArmorItem(MArmorMaterials.SIMPLE_TRITANIUM, ArmorItem.Type.BOOTS, Properties().stacksTo(1)) }
val TRITANIUM_ARMOR = SupplierList( val TRITANIUM_ARMOR = SupplierList(
::TRITANIUM_HELMET, ::TRITANIUM_HELMET,