Item repairer block
This commit is contained in:
parent
aa31ff4cce
commit
e3993f439e
@ -365,6 +365,8 @@ private fun blocks(provider: MatteryLanguageProvider) {
|
||||
add(MBlocks.COBBLESTONE_GENERATOR, "Cobblestone Generator")
|
||||
add(MBlocks.ESSENCE_STORAGE, "Essence Storage")
|
||||
add(MBlocks.ESSENCE_STORAGE, "desc", "Allows to store and retrieve experience levels")
|
||||
add(MBlocks.ITEM_REPAIRER, "Matter Reconstructor")
|
||||
add(MBlocks.ITEM_REPAIRER, "desc", "Repairs tools using matter")
|
||||
|
||||
add(MBlocks.ENGINE, "Ship Engine")
|
||||
add(MBlocks.HOLO_SIGN, "Holo Sign")
|
||||
|
@ -372,6 +372,8 @@ private fun blocks(provider: MatteryLanguageProvider) {
|
||||
add(MBlocks.COBBLESTONE_GENERATOR, "Генератор булыжника")
|
||||
add(MBlocks.ESSENCE_STORAGE, "Хранилище эссенции")
|
||||
add(MBlocks.ESSENCE_STORAGE, "desc", "Позволяет хранить очки опыта")
|
||||
add(MBlocks.ITEM_REPAIRER, "Материальный реконструктор")
|
||||
add(MBlocks.ITEM_REPAIRER, "desc", "Чинит инструменты используя материю")
|
||||
|
||||
add(MBlocks.ENGINE, "Двигатель корабля")
|
||||
add(MBlocks.HOLO_SIGN, "Голографическая табличка")
|
||||
|
@ -137,6 +137,7 @@ fun addLootTables(lootTables: LootTables) {
|
||||
|
||||
lootTables.tile(MBlocks.COBBLESTONE_GENERATOR)
|
||||
lootTables.tile(MBlocks.ESSENCE_STORAGE)
|
||||
lootTables.tile(MBlocks.ITEM_REPAIRER)
|
||||
|
||||
lootTables.tile(MBlocks.ENERGY_SERVO)
|
||||
lootTables.tile(MBlocks.ENERGY_COUNTER)
|
||||
|
@ -172,6 +172,7 @@ fun addTags(tagsProvider: TagsProvider) {
|
||||
MBlocks.HOLO_SIGN,
|
||||
MBlocks.COBBLESTONE_GENERATOR,
|
||||
MBlocks.ESSENCE_STORAGE,
|
||||
MBlocks.ITEM_REPAIRER,
|
||||
), Tiers.IRON)
|
||||
|
||||
tagsProvider.requiresPickaxe(MBlocks.TRITANIUM_ANVIL, Tiers.IRON)
|
||||
|
@ -0,0 +1,290 @@
|
||||
package ru.dbotthepony.mc.otm.block.entity.matter
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.nbt.StringTag
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerLevel
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.inventory.AbstractContainerMenu
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import net.minecraftforge.common.ForgeConfigSpec
|
||||
import net.minecraftforge.common.ForgeConfigSpec.ConfigValue
|
||||
import net.minecraftforge.registries.ForgeRegistries
|
||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.energy.BlockEnergyStorageImpl
|
||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.matter.IMatterStorage
|
||||
import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
|
||||
import ru.dbotthepony.mc.otm.config.ConciseBalanceValues
|
||||
import ru.dbotthepony.mc.otm.container.HandlerFilter
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.math.DecimalConfigValue
|
||||
import ru.dbotthepony.mc.otm.core.math.defineDecimal
|
||||
import ru.dbotthepony.mc.otm.core.registryName
|
||||
import ru.dbotthepony.mc.otm.core.util.WriteOnce
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
|
||||
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
|
||||
import ru.dbotthepony.mc.otm.matter.IMatterValue
|
||||
import ru.dbotthepony.mc.otm.matter.MatterManager
|
||||
import ru.dbotthepony.mc.otm.menu.matter.ItemRepairerMenu
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.registry.MNames
|
||||
|
||||
class ItemRepairerBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.ITEM_REPAIRER, blockPos, blockState), IMatterGraphNode {
|
||||
val repairContainer = MatteryContainer(::containerChanged, 1).also(::addDroppableContainer)
|
||||
|
||||
private var matterPerTick = Decimal.ZERO
|
||||
private var progressPerTick = 0.0
|
||||
private var repairProgress = 0.0
|
||||
private var lastItem: Item? = null
|
||||
|
||||
var canNotWork = false
|
||||
|
||||
override val matterNode = Graph6Node<IMatterGraphNode>(this)
|
||||
val matter = MatterStorageImpl(::setChangedLight, FlowDirection.INPUT, ::CAPACITY)
|
||||
val energy = WorkerEnergyStorage(::setChangedLight, ENERGY_VALUES)
|
||||
|
||||
init {
|
||||
exposeGlobally(MatteryCapability.MATTER, matter)
|
||||
exposeGlobally(MatteryCapability.MATTER_NODE, this)
|
||||
|
||||
savetables.stateful(::repairContainer)
|
||||
savetables.stateful(::matter)
|
||||
savetables.stateful(::energy)
|
||||
|
||||
savetables.decimal(::matterPerTick)
|
||||
savetables.double(::progressPerTick)
|
||||
savetables.double(::repairProgress)
|
||||
|
||||
savetables.Stateless(::lastItem, type = StringTag::class.java)
|
||||
.withSerializer { it?.registryName?.toString()?.let(StringTag::valueOf) }
|
||||
.withDeserializer { ResourceLocation.tryParse(it.asString)?.let { ForgeRegistries.ITEMS.getValue(it) } }
|
||||
}
|
||||
|
||||
val energyConfig = ConfigurableEnergy(energy)
|
||||
val itemConfig = ConfigurableItemHandler(
|
||||
input = repairContainer.handler(object : HandlerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
if (!stack.isRepairable || !stack.isDamaged) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (!ONLY_ANVIL) {
|
||||
if (MatterManager.get(stack.item).hasMatterValue) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return (matterNode.graph as MatterNetworkGraph?)
|
||||
?.patterns
|
||||
?.filter { stack.item.isValidRepairItem(stack, ItemStack(it.item, 1)) }
|
||||
?.findFirst()?.orElse(null).let {
|
||||
if (it == null) {
|
||||
IMatterValue.ZERO
|
||||
} else {
|
||||
MatterManager.get(it.item)
|
||||
}
|
||||
}.hasMatterValue
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return false
|
||||
}
|
||||
}),
|
||||
|
||||
output = repairContainer.handler(object : HandlerFilter {
|
||||
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
|
||||
return progressPerTick <= 0.0 || matterPerTick <= Decimal.ZERO
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
|
||||
return ItemRepairerMenu(containerID, inventory, this)
|
||||
}
|
||||
|
||||
override fun getMatterHandler(): IMatterStorage {
|
||||
return matter
|
||||
}
|
||||
|
||||
override fun setRemoved() {
|
||||
super.setRemoved()
|
||||
matterNode.destroy(::MatterNetworkGraph)
|
||||
}
|
||||
|
||||
override fun setLevel(level: Level) {
|
||||
super.setLevel(level)
|
||||
|
||||
if (level is ServerLevel)
|
||||
MatterNetworkGraph.discoverFull(this, matterNode)
|
||||
}
|
||||
|
||||
private fun containerChanged() {
|
||||
matterPerTick = Decimal.ZERO
|
||||
progressPerTick = 0.0
|
||||
|
||||
val item = repairContainer[0]
|
||||
|
||||
tickList.once {
|
||||
if (lastItem != item.item) {
|
||||
lastItem = item.item
|
||||
repairProgress = 0.0
|
||||
}
|
||||
|
||||
if (item.isEmpty || !item.isRepairable || !item.isDamaged) {
|
||||
matterPerTick = Decimal.ZERO
|
||||
progressPerTick = 0.0
|
||||
} else {
|
||||
if (!ONLY_ANVIL) {
|
||||
val matter = MatterManager.get(item.item)
|
||||
|
||||
if (matter.hasMatterValue) {
|
||||
progressPerTick = (item.maxDamage / matter.complexity) / DIVISOR
|
||||
matterPerTick = (matter.matter / matter.complexity) / DIVISOR
|
||||
return@once
|
||||
}
|
||||
}
|
||||
|
||||
val found = (matterNode.graph as MatterNetworkGraph?)?.patterns?.filter { item.item.isValidRepairItem(item, ItemStack(it.item, 1)) }?.findFirst()?.orElse(null)
|
||||
|
||||
if (found != null) {
|
||||
@Suppress("name_shadowing")
|
||||
val matter = MatterManager.get(found.item) * 2
|
||||
|
||||
progressPerTick = (item.maxDamage / matter.complexity) / DIVISOR
|
||||
matterPerTick = (matter.matter / matter.complexity) / DIVISOR
|
||||
} else {
|
||||
matterPerTick = Decimal.ZERO
|
||||
progressPerTick = 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun tick() {
|
||||
super.tick()
|
||||
|
||||
if (!redstoneControl.isBlockedByRedstone) {
|
||||
canNotWork = false
|
||||
|
||||
val item = repairContainer[0]
|
||||
|
||||
if (!item.isEmpty && matterPerTick.isPositive && progressPerTick > 0.0 && item.isRepairable && item.isDamaged) {
|
||||
var progressPerTick = (repairProgress + progressPerTick).coerceAtMost(item.damageValue.toDouble()) - repairProgress
|
||||
if (progressPerTick <= 0.0) return
|
||||
|
||||
if (ENERGY_CONSUMPTION.isPositive) {
|
||||
if (!energy.batteryLevel.isPositive) return
|
||||
val multEnergy = ENERGY_CONSUMPTION * (progressPerTick / this.progressPerTick)
|
||||
progressPerTick *= (energy.extractEnergy(multEnergy, true) / multEnergy).toDouble()
|
||||
|
||||
if (progressPerTick <= 0.0) {
|
||||
canNotWork = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (matter.storedMatter < matterPerTick) {
|
||||
val graph = matterNode.graph as MatterNetworkGraph?
|
||||
|
||||
if (graph != null) {
|
||||
val toDrain = (matterPerTick * EXTRACT_TICKS.coerceAtMost(item.damageValue)).coerceAtLeast(Decimal.ZERO).coerceAtMost(matter.missingMatter)
|
||||
matter.receiveMatterInner(graph.extractMatter(toDrain, false), false)
|
||||
}
|
||||
}
|
||||
|
||||
val toDrain = matterPerTick * (progressPerTick / this.progressPerTick)
|
||||
val drain = matter.extractMatterInner(toDrain, true)
|
||||
if (!drain.isPositive) {
|
||||
canNotWork = true
|
||||
return
|
||||
}
|
||||
|
||||
progressPerTick *= (drain / toDrain).toDouble()
|
||||
if (progressPerTick <= 0.0) {
|
||||
canNotWork = true
|
||||
return
|
||||
}
|
||||
|
||||
if (FAILURE_CHANCE <= 0.0 || level!!.random.nextDouble() >= FAILURE_CHANCE)
|
||||
repairProgress += progressPerTick
|
||||
|
||||
energy.extractEnergy(ENERGY_CONSUMPTION * (progressPerTick / this.progressPerTick), false)
|
||||
matter.extractMatterInner(matterPerTick * (progressPerTick / this.progressPerTick), false)
|
||||
|
||||
if (repairProgress >= 1.0) {
|
||||
item.damageValue = (item.damageValue - repairProgress.toInt()).coerceAtLeast(0)
|
||||
repairProgress %= 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
val CAPACITY get() = _CAPACITY.get()
|
||||
val ENERGY_CONSUMPTION get() = _ENERGY_CONSUMPTION.get()
|
||||
val DIVISOR: Double get() = _DIVISOR.get()
|
||||
val EXTRACT_TICKS: Int get() = _EXTRACT_TICKS.get()
|
||||
val FAILURE_CHANCE: Double get() = _FAILURE_CHANCE.get()
|
||||
val ONLY_ANVIL: Boolean get() = _ONLY_ANVIL.get()
|
||||
|
||||
private var _CAPACITY: DecimalConfigValue by WriteOnce()
|
||||
private var _ENERGY_CONSUMPTION: DecimalConfigValue by WriteOnce()
|
||||
private var _DIVISOR: ConfigValue<Double> by WriteOnce()
|
||||
private var _FAILURE_CHANCE: ConfigValue<Double> by WriteOnce()
|
||||
private var _EXTRACT_TICKS: ConfigValue<Int> by WriteOnce()
|
||||
private var _ONLY_ANVIL: ConfigValue<Boolean> by WriteOnce()
|
||||
|
||||
var ENERGY_VALUES: ConciseBalanceValues by WriteOnce()
|
||||
private set
|
||||
|
||||
fun registerConfig(builder: ForgeConfigSpec.Builder) {
|
||||
builder.push(MNames.ITEM_REPAIRER)
|
||||
|
||||
ENERGY_VALUES = BlockEnergyStorageImpl.makeConfigEntry(builder, capacity = Decimal(400_000), throughput = Decimal(2_000))
|
||||
|
||||
_CAPACITY = builder.defineDecimal("matterCapacity", Decimal(4_000), Decimal.ONE_TENTH)
|
||||
_ENERGY_CONSUMPTION = builder.defineDecimal("energyConsumption", Decimal(600), Decimal.ONE)
|
||||
|
||||
_ONLY_ANVIL = builder
|
||||
.comment("Force repairing only by matter value of anvil materials")
|
||||
.comment("Doesn't make logical sense but might be good for balancing")
|
||||
.define("onlyAnvil", false)
|
||||
|
||||
_EXTRACT_TICKS = builder
|
||||
.comment("How much ticks of matter work will be attempted to be extracted from matter network")
|
||||
.comment("on matter starvation")
|
||||
.comment("---")
|
||||
.comment("This is a performance tuning value, do not change it if you don't know what you are doing!")
|
||||
.defineInRange("extractTicks", 200, 1, Int.MAX_VALUE)
|
||||
|
||||
_FAILURE_CHANCE = builder
|
||||
.comment("Chance that replication will fail at any given tick")
|
||||
.comment("In event of failure repair tick is wasted, wasting resources")
|
||||
.defineInRange("failureChance", 0.01, 0.0, 0.99)
|
||||
|
||||
_DIVISOR = builder
|
||||
.comment("Magnitute of **slowdown** of repairer.")
|
||||
.comment("If this value is 1, repairer will repair item from 0% to 100% in COMPLEXITY (of tool) ticks")
|
||||
.comment("(or twice the complexity of anvil repair ingredients if tool itself has no matter value)")
|
||||
.comment("---")
|
||||
.comment("If value is smaller than 1, repairer will repair items faster")
|
||||
.comment("If value is bigger than 1, repairer will repair items slower")
|
||||
.defineInRange("divisor", 3.0, 0.1, Double.MAX_VALUE)
|
||||
|
||||
builder.pop()
|
||||
}
|
||||
}
|
||||
}
|
@ -317,7 +317,5 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
||||
|
||||
builder.pop()
|
||||
}
|
||||
|
||||
const val IS_BOTTLING_KEY = "isBottling"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,24 @@
|
||||
package ru.dbotthepony.mc.otm.block.matter
|
||||
|
||||
import net.minecraft.core.BlockPos
|
||||
import net.minecraft.world.level.Level
|
||||
import net.minecraft.world.level.block.EntityBlock
|
||||
import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import net.minecraft.world.level.block.entity.BlockEntityTicker
|
||||
import net.minecraft.world.level.block.entity.BlockEntityType
|
||||
import net.minecraft.world.level.block.state.BlockState
|
||||
import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.ItemRepairerBlockEntity
|
||||
|
||||
class ItemRepairerBlock : RotatableMatteryBlock(), EntityBlock {
|
||||
override fun newBlockEntity(pPos: BlockPos, pState: BlockState): BlockEntity {
|
||||
return ItemRepairerBlockEntity(pPos, pState)
|
||||
}
|
||||
|
||||
override fun <T : BlockEntity?> getTicker(pLevel: Level, pState: BlockState, pBlockEntityType: BlockEntityType<T>): BlockEntityTicker<T>? {
|
||||
if (pLevel.isClientSide)
|
||||
return null
|
||||
|
||||
return BlockEntityTicker { _, _, _, pBlockEntity -> if (pBlockEntity is ItemRepairerBlockEntity) pBlockEntity.tick() }
|
||||
}
|
||||
}
|
@ -1315,11 +1315,13 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
return
|
||||
}
|
||||
|
||||
val iterator = inventory.player.matteryPlayer?.exoPackContainer?.iterator()?.nonEmpty() ?: return
|
||||
val iterator = inventory.player.matteryPlayer?.exoPackContainer?.iterator() ?: return
|
||||
|
||||
for (item in iterator) {
|
||||
inventory.player.drop(item, true, false)
|
||||
iterator.remove()
|
||||
if (!item.isEmpty) {
|
||||
inventory.player.drop(item, true, false)
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1338,10 +1340,10 @@ class MatteryPlayerCapability(val ply: Player) : ICapabilityProvider, INBTSerial
|
||||
return
|
||||
}
|
||||
|
||||
val iterator = player.matteryPlayer?.exoPackContainer?.iterator()?.nonEmpty() ?: return
|
||||
val iterator = player.matteryPlayer?.exoPackContainer?.iterator() ?: return
|
||||
|
||||
for (item in iterator) {
|
||||
if (hasVanishingCurse(item)) {
|
||||
if (!item.isEmpty && hasVanishingCurse(item)) {
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,26 @@
|
||||
package ru.dbotthepony.mc.otm.client.screen.matter
|
||||
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.menu.matter.ItemRepairerMenu
|
||||
|
||||
class ItemRepairerScreen(menu: ItemRepairerMenu, inventory: Inventory, title: Component) : MatteryScreen<ItemRepairerMenu>(menu, inventory, title) {
|
||||
override fun makeMainFrame(): FramePanel<MatteryScreen<*>> {
|
||||
val frame = super.makeMainFrame()!!
|
||||
|
||||
val p = PowerGaugePanel(this, frame, menu.powerWidget, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT)
|
||||
MatterGaugePanel(this, frame, menu.matterWidget, LEFT_MARGIN + p.width, GAUGE_TOP_WITH_SLOT)
|
||||
|
||||
BatterySlotPanel(this, frame, menu.batterySlot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
|
||||
|
||||
SlotPanel(this, frame, menu.slot, 80f, PROGRESS_SLOT_TOP)
|
||||
|
||||
return frame
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.config
|
||||
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.ItemRepairerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterBottlerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterDecomposerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.MatterRecyclerBlockEntity
|
||||
@ -20,6 +21,7 @@ object MachinesConfig : AbstractConfig("machines") {
|
||||
MatterReplicatorBlockEntity.registerConfig(builder)
|
||||
MatterScannerBlockEntity.registerConfig(builder)
|
||||
MatterDecomposerBlockEntity.registerConfig(builder)
|
||||
ItemRepairerBlockEntity.registerConfig(builder)
|
||||
}
|
||||
|
||||
val PLATE_PRESS = BlockEnergyStorageImpl.makeConfigEntry(builder, MNames.PLATE_PRESS)
|
||||
|
@ -2,5 +2,4 @@ package ru.dbotthepony.mc.otm.core.collect
|
||||
|
||||
import net.minecraft.world.item.ItemStack
|
||||
|
||||
fun Iterator<ItemStack>.nonEmpty() = PredicateIterator(this) { !it.isEmpty }
|
||||
fun MutableIterator<ItemStack>.nonEmpty() = MutablePredicateIterator(this) { !it.isEmpty }
|
||||
fun Iterator<ItemStack>.nonEmpty() = FilteredIterator(this) { !it.isEmpty }
|
||||
|
@ -1,99 +0,0 @@
|
||||
package ru.dbotthepony.mc.otm.core.collect
|
||||
|
||||
import java.util.function.Consumer
|
||||
import java.util.function.Predicate
|
||||
|
||||
class PredicateIterator<T> : Iterator<T> {
|
||||
private val parent: Iterator<T>
|
||||
private val predicate: Predicate<in T>
|
||||
private val consumer: Consumer<in T>?
|
||||
|
||||
constructor(parent: Iterator<T>, predicate: Predicate<in T>) {
|
||||
this.parent = parent
|
||||
this.predicate = predicate
|
||||
this.consumer = null
|
||||
}
|
||||
|
||||
constructor(parent: Iterator<T>, predicate: Predicate<in T>, consumer: Consumer<in T>) {
|
||||
this.parent = parent
|
||||
this.predicate = predicate
|
||||
this.consumer = consumer
|
||||
}
|
||||
|
||||
private var foundValue: Any? = Companion
|
||||
|
||||
var once: Boolean = false
|
||||
private set
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
if (foundValue === Companion) {
|
||||
while (parent.hasNext()) {
|
||||
val next = parent.next()
|
||||
|
||||
if (predicate.test(next)) {
|
||||
foundValue = next
|
||||
once = true
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
override fun next(): T {
|
||||
if (!hasNext()) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
|
||||
val foundValue = foundValue
|
||||
|
||||
if (foundValue === Companion) {
|
||||
throw ConcurrentModificationException()
|
||||
}
|
||||
|
||||
this.foundValue = Companion
|
||||
consumer?.accept(foundValue as T)
|
||||
return foundValue as T
|
||||
}
|
||||
|
||||
private companion object
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.filter(condition: Predicate<in T>) = PredicateIterator(this, condition)
|
||||
|
||||
class MutablePredicateIterator<T> : MutableIterator<T> {
|
||||
private val parent: MutableIterator<T>
|
||||
private val predicateParent: PredicateIterator<T>
|
||||
|
||||
constructor(parent: MutableIterator<T>, predicate: Predicate<in T>) {
|
||||
this.parent = parent
|
||||
this.predicateParent = PredicateIterator(parent, predicate)
|
||||
}
|
||||
|
||||
constructor(parent: MutableIterator<T>, predicate: Predicate<in T>, consumer: Consumer<in T>) {
|
||||
this.parent = parent
|
||||
this.predicateParent = PredicateIterator(parent, predicate, consumer)
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return predicateParent.hasNext()
|
||||
}
|
||||
|
||||
override fun next(): T {
|
||||
return predicateParent.next()
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
if (!predicateParent.once) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
|
||||
return parent.remove()
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> MutableIterator<T>.filter(condition: Predicate<in T>) = MutablePredicateIterator(this, condition)
|
@ -0,0 +1,210 @@
|
||||
package ru.dbotthepony.mc.otm.core.collect
|
||||
|
||||
import java.util.Optional
|
||||
import java.util.function.BinaryOperator
|
||||
import java.util.function.Predicate
|
||||
import java.util.stream.Collector
|
||||
|
||||
class FilteredIterator<T>(private val parent: Iterator<T>, private val predicate: Predicate<in T>) : Iterator<T> {
|
||||
private var foundValue: Any? = Companion
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
if (foundValue === Companion) {
|
||||
while (parent.hasNext()) {
|
||||
val next = parent.next()
|
||||
|
||||
if (predicate.test(next)) {
|
||||
foundValue = next
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@Suppress("unchecked_cast")
|
||||
override fun next(): T {
|
||||
var foundValue = foundValue
|
||||
|
||||
if (foundValue === Companion) {
|
||||
if (!hasNext()) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
|
||||
foundValue = this.foundValue
|
||||
|
||||
if (foundValue === Companion) {
|
||||
throw ConcurrentModificationException()
|
||||
}
|
||||
}
|
||||
|
||||
this.foundValue = Companion
|
||||
return foundValue as T
|
||||
}
|
||||
|
||||
private companion object
|
||||
}
|
||||
|
||||
class MappingIterator<T, R>(private val parent: Iterator<T>, private val transform: (T) -> R) : Iterator<R> {
|
||||
override fun hasNext(): Boolean {
|
||||
return parent.hasNext()
|
||||
}
|
||||
|
||||
override fun next(): R {
|
||||
return transform.invoke(parent.next())
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.filter(condition: Predicate<in T>): Iterator<T> = FilteredIterator(this, condition)
|
||||
fun <T, R> Iterator<T>.map(mapper: (T) -> R): Iterator<R> = MappingIterator(this, mapper)
|
||||
fun <T, R> Iterator<T>.map(mapper: java.util.function.Function<T, R>): Iterator<R> = MappingIterator(this, mapper::apply)
|
||||
|
||||
fun <T> Iterator<T>.reduce(identity: T, reducer: (T, T) -> T): T {
|
||||
var result = identity
|
||||
|
||||
for (value in this) {
|
||||
result = reducer.invoke(result, value)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.reduce(identity: T, reducer: BinaryOperator<T>): T = reduce(identity, reducer::apply)
|
||||
fun <T> Iterator<T?>.filterNotNull(): Iterator<T> = filter { it != null } as Iterator<T>
|
||||
|
||||
fun <T> Iterator<T>.anyMatch(predicate: Predicate<in T>): Boolean {
|
||||
for (value in this) {
|
||||
if (predicate.test(value)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.allMatch(predicate: Predicate<in T>): Boolean {
|
||||
for (value in this) {
|
||||
if (!predicate.test(value)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.noneMatch(predicate: Predicate<in T>): Boolean {
|
||||
for (value in this) {
|
||||
if (predicate.test(value)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
fun <T, A, R> Iterator<T>.collect(collector: Collector<T, A, R>): R {
|
||||
val accumulator = collector.accumulator()
|
||||
val instance = collector.supplier().get()
|
||||
|
||||
for (value in this) {
|
||||
accumulator.accept(instance, value)
|
||||
}
|
||||
|
||||
return collector.finisher().apply(instance)
|
||||
}
|
||||
|
||||
fun <T : Any> Iterator<T>.findFirst(): Optional<T> {
|
||||
if (hasNext()) {
|
||||
return Optional.of(next())
|
||||
}
|
||||
|
||||
return Optional.empty<T>()
|
||||
}
|
||||
|
||||
fun <T : Any> Iterator<T>.findAny() = findFirst()
|
||||
|
||||
fun <T> Iterator<T>.limit(limit: Long): Iterator<T> {
|
||||
require(limit > 0) { "Invalid limit $limit" }
|
||||
|
||||
return object : Iterator<T> {
|
||||
var found = 0L
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
return found < limit && this@limit.hasNext()
|
||||
}
|
||||
|
||||
override fun next(): T {
|
||||
if (found >= limit) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
|
||||
return this@limit.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Iterator<T>.skip(skip: Long): Iterator<T> {
|
||||
require(skip > 0) { "Invalid skip $skip" }
|
||||
|
||||
return object : Iterator<T> {
|
||||
var found = skip
|
||||
|
||||
override fun hasNext(): Boolean {
|
||||
while (this@skip.hasNext() && found > 0L) {
|
||||
found--
|
||||
this@skip.next()
|
||||
}
|
||||
|
||||
return this@skip.hasNext()
|
||||
}
|
||||
|
||||
override fun next(): T {
|
||||
if (!hasNext()) {
|
||||
throw NoSuchElementException()
|
||||
}
|
||||
|
||||
return this@skip.next()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T> Iterator<T>.forEach(action: (T) -> Unit) {
|
||||
for (value in this) {
|
||||
action.invoke(value)
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : Any> Iterator<T>.min(comparator: Comparator<T>): Optional<T> {
|
||||
if (!hasNext()) {
|
||||
return Optional.empty<T>()
|
||||
}
|
||||
|
||||
var min = next()
|
||||
|
||||
for (value in this) {
|
||||
if (comparator.compare(min, value) > 0) {
|
||||
min = value
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.of(min)
|
||||
}
|
||||
|
||||
fun <T : Any> Iterator<T>.max(comparator: Comparator<T>): Optional<T> {
|
||||
if (!hasNext()) {
|
||||
return Optional.empty<T>()
|
||||
}
|
||||
|
||||
var max = next()
|
||||
|
||||
for (value in this) {
|
||||
if (comparator.compare(max, value) < 0) {
|
||||
max = value
|
||||
}
|
||||
}
|
||||
|
||||
return Optional.of(max)
|
||||
}
|
@ -7,6 +7,7 @@ import net.minecraft.world.level.block.entity.BlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.FlowDirection
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.matter.*
|
||||
import ru.dbotthepony.mc.otm.core.filterNotNull
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.graph.Abstract6Graph
|
||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||
@ -206,7 +207,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
||||
}
|
||||
|
||||
val patterns: Stream<out IPatternState> get() {
|
||||
return Streams.concat(*nodes.mapNotNull { it.value.getPatternHandler()?.patterns }.toTypedArray())
|
||||
return nodes.stream().map { it.value.getPatternHandler()?.patterns }.filterNotNull().flatMap { it }
|
||||
}
|
||||
|
||||
val patternCount: Long get() {
|
||||
|
@ -50,6 +50,8 @@ interface IMatterValue : Comparable<IMatterValue> {
|
||||
* ZERO
|
||||
*/
|
||||
companion object : IMatterValue {
|
||||
val ZERO: IMatterValue get() = this
|
||||
|
||||
override val matter: Decimal
|
||||
get() = Decimal.ZERO
|
||||
override val complexity: Double
|
||||
|
@ -6,6 +6,7 @@ import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import ru.dbotthepony.mc.otm.block.entity.RedstoneSetting
|
||||
import ru.dbotthepony.mc.otm.capability.matter.matter
|
||||
import ru.dbotthepony.mc.otm.capability.matteryEnergy
|
||||
import ru.dbotthepony.mc.otm.menu.input.EnumInputWithFeedback
|
||||
|
||||
@ -16,14 +17,11 @@ abstract class MatteryPoweredMenu protected constructor(
|
||||
tile: MatteryPoweredBlockEntity? = null
|
||||
) : MatteryMenu(menuType, containerID, inventory, tile) {
|
||||
val powerWidget = LevelGaugeWidget(this, tile?.matteryEnergy)
|
||||
val batterySlot: BatterySlot
|
||||
val batterySlot = BatterySlot(tile?.batteryContainer ?: SimpleContainer(1), 0)
|
||||
val redstone = EnumInputWithFeedback(this, RedstoneSetting::class.java)
|
||||
|
||||
init {
|
||||
if (tile == null) {
|
||||
batterySlot = BatterySlot(SimpleContainer(1), 0)
|
||||
} else {
|
||||
batterySlot = BatterySlot(tile.batteryContainer, 0)
|
||||
if (tile != null) {
|
||||
redstone.with(tile.redstoneControl::redstoneSetting)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
package ru.dbotthepony.mc.otm.menu.matter
|
||||
|
||||
import net.minecraft.world.SimpleContainer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.item.ItemStack
|
||||
import ru.dbotthepony.mc.otm.block.entity.matter.ItemRepairerBlockEntity
|
||||
import ru.dbotthepony.mc.otm.capability.matter.matter
|
||||
import ru.dbotthepony.mc.otm.menu.MatteryPoweredMenu
|
||||
import ru.dbotthepony.mc.otm.menu.MatterySlot
|
||||
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
|
||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||
|
||||
class ItemRepairerMenu(
|
||||
containerId: Int,
|
||||
inventory: Inventory,
|
||||
tile: ItemRepairerBlockEntity? = null
|
||||
) : MatteryPoweredMenu(MMenus.ITEM_REPAIER, containerId, inventory, tile) {
|
||||
val matterWidget = LevelGaugeWidget(this, tile?.matter)
|
||||
val slot = object : MatterySlot(tile?.repairContainer ?: SimpleContainer(1), 0) {
|
||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||
return itemStack.isRepairable && itemStack.isDamaged && super.mayPlace(itemStack)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
addStorageSlot(slot)
|
||||
addInventorySlots()
|
||||
}
|
||||
}
|
@ -57,6 +57,7 @@ object MBlockEntities {
|
||||
val ENERGY_SERVO: BlockEntityType<EnergyServoBlockEntity> by registry.register(MNames.ENERGY_SERVO) { BlockEntityType.Builder.of(::EnergyServoBlockEntity, MBlocks.ENERGY_SERVO).build(null) }
|
||||
val COBBLESTONE_GENERATOR: BlockEntityType<CobblerBlockEntity> by registry.register(MNames.COBBLESTONE_GENERATOR) { BlockEntityType.Builder.of(::CobblerBlockEntity, MBlocks.COBBLESTONE_GENERATOR).build(null) }
|
||||
val ESSENCE_STORAGE: BlockEntityType<EssenceStorageBlockEntity> by registry.register(MNames.ESSENCE_STORAGE) { BlockEntityType.Builder.of(::EssenceStorageBlockEntity, MBlocks.ESSENCE_STORAGE).build(null) }
|
||||
val ITEM_REPAIRER: BlockEntityType<ItemRepairerBlockEntity> by registry.register(MNames.ITEM_REPAIRER) { BlockEntityType.Builder.of(::ItemRepairerBlockEntity, MBlocks.ITEM_REPAIRER).build(null) }
|
||||
|
||||
val STORAGE_BUS: BlockEntityType<StorageBusBlockEntity> by registry.register(MNames.STORAGE_BUS) { BlockEntityType.Builder.of(::StorageBusBlockEntity, MBlocks.STORAGE_BUS).build(null) }
|
||||
val STORAGE_IMPORTER: BlockEntityType<StorageImporterBlockEntity> by registry.register(MNames.STORAGE_IMPORTER) { BlockEntityType.Builder.of(::StorageImporterBlockEntity, MBlocks.STORAGE_IMPORTER).build(null) }
|
||||
|
@ -48,6 +48,7 @@ import ru.dbotthepony.mc.otm.block.tech.PlatePressBlock
|
||||
import ru.dbotthepony.mc.otm.block.StorageCableBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.EngineBlock
|
||||
import ru.dbotthepony.mc.otm.block.decorative.HoloSignBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.ItemRepairerBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterBottlerBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterCapacitorBankBlock
|
||||
import ru.dbotthepony.mc.otm.block.matter.MatterDecomposerBlock
|
||||
@ -93,6 +94,7 @@ object MBlocks {
|
||||
val ENERGY_SERVO: Block by registry.register(MNames.ENERGY_SERVO) { EnergyServoBlock() }
|
||||
val COBBLESTONE_GENERATOR: Block by registry.register(MNames.COBBLESTONE_GENERATOR) { CobblerBlock() }
|
||||
val ESSENCE_STORAGE: EssenceStorageBlock by registry.register(MNames.ESSENCE_STORAGE) { EssenceStorageBlock() }
|
||||
val ITEM_REPAIRER: ItemRepairerBlock by registry.register(MNames.ITEM_REPAIRER) { ItemRepairerBlock() }
|
||||
|
||||
val STORAGE_BUS: Block by registry.register(MNames.STORAGE_BUS) { StorageBusBlock() }
|
||||
val STORAGE_IMPORTER: Block by registry.register(MNames.STORAGE_IMPORTER) { StorageImporterBlock() }
|
||||
|
@ -109,13 +109,22 @@ object MItems {
|
||||
}
|
||||
}
|
||||
|
||||
val ITEM_REPAIRER: BlockItem by registry.register(MNames.ITEM_REPAIRER) {
|
||||
object : BlockItem(MBlocks.ITEM_REPAIRER, DEFAULT_PROPERTIES) {
|
||||
override fun appendHoverText(p_40572_: ItemStack, p_40573_: Level?, p_40574_: MutableList<Component>, p_40575_: TooltipFlag) {
|
||||
super.appendHoverText(p_40572_, p_40573_, p_40574_, p_40575_)
|
||||
p_40574_.add(TranslatableComponent("$descriptionId.desc").withStyle(ChatFormatting.GRAY))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val MACHINES = SupplierList(
|
||||
::ANDROID_STATION, ::BATTERY_BANK, ::MATTER_DECOMPOSER, ::MATTER_CAPACITOR_BANK, ::MATTER_CABLE, ::PATTERN_STORAGE,
|
||||
::MATTER_SCANNER, ::MATTER_PANEL, ::MATTER_REPLICATOR, ::MATTER_BOTTLER, ::ENERGY_COUNTER, ::CHEMICAL_GENERATOR,
|
||||
::PLATE_PRESS, ::MATTER_RECYCLER, ::STORAGE_BUS, ::STORAGE_IMPORTER, ::STORAGE_EXPORTER, ::DRIVE_VIEWER,
|
||||
::DRIVE_RACK, ::ITEM_MONITOR, ::STORAGE_CABLE, ::STORAGE_POWER_SUPPLIER, ::ENERGY_SERVO,
|
||||
::PHANTOM_ATTRACTOR,
|
||||
::GRAVITATION_STABILIZER, ::COBBLESTONE_GENERATOR, ::ESSENCE_STORAGE
|
||||
::PHANTOM_ATTRACTOR, ::GRAVITATION_STABILIZER, ::COBBLESTONE_GENERATOR, ::ESSENCE_STORAGE,
|
||||
::ITEM_REPAIRER
|
||||
)
|
||||
|
||||
val DEBUG_EXPLOSION_SMALL: Item by registry.register(MNames.DEBUG_EXPLOSION_SMALL) { BlockItem(MBlocks.DEBUG_EXPLOSION_SMALL, Item.Properties().stacksTo(64)) }
|
||||
|
@ -10,6 +10,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
|
||||
import ru.dbotthepony.mc.otm.client.screen.decorative.CargoCrateScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.decorative.HoloSignScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.decorative.MinecartCargoCrateScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.matter.ItemRepairerScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.matter.MatterBottlerScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.matter.MatterCapacitorBankScreen
|
||||
import ru.dbotthepony.mc.otm.client.screen.matter.MatterDecomposerScreen
|
||||
@ -36,6 +37,7 @@ import ru.dbotthepony.mc.otm.client.screen.tech.PlatePressScreen
|
||||
import ru.dbotthepony.mc.otm.menu.decorative.CargoCrateMenu
|
||||
import ru.dbotthepony.mc.otm.menu.decorative.HoloSignMenu
|
||||
import ru.dbotthepony.mc.otm.menu.decorative.MinecartCargoCrateMenu
|
||||
import ru.dbotthepony.mc.otm.menu.matter.ItemRepairerMenu
|
||||
import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu
|
||||
import ru.dbotthepony.mc.otm.menu.matter.MatterCapacitorBankMenu
|
||||
import ru.dbotthepony.mc.otm.menu.matter.MatterDecomposerMenu
|
||||
@ -85,6 +87,7 @@ object MMenus {
|
||||
val HOLO_SIGN: MenuType<HoloSignMenu> by registry.register(MNames.HOLO_SIGN) { MenuType(::HoloSignMenu) }
|
||||
val COBBLESTONE_GENERATOR: MenuType<CobblerMenu> by registry.register(MNames.COBBLESTONE_GENERATOR) { MenuType(::CobblerMenu) }
|
||||
val ESSENCE_STORAGE: MenuType<EssenceStorageMenu> by registry.register(MNames.ESSENCE_STORAGE) { MenuType(::EssenceStorageMenu) }
|
||||
val ITEM_REPAIER: MenuType<ItemRepairerMenu> by registry.register(MNames.ITEM_REPAIRER) { MenuType(::ItemRepairerMenu) }
|
||||
|
||||
val STORAGE_BUS: MenuType<*> by registry.register(MNames.STORAGE_BUS) { MenuType(::StorageBusMenu) }
|
||||
val STORAGE_EXPORTER: MenuType<*> by registry.register(MNames.STORAGE_EXPORTER) { MenuType(::StorageExporterMenu) }
|
||||
@ -125,6 +128,7 @@ object MMenus {
|
||||
MenuScreens.register(HOLO_SIGN, ::HoloSignScreen)
|
||||
MenuScreens.register(COBBLESTONE_GENERATOR, ::CobblerScreen)
|
||||
MenuScreens.register(ESSENCE_STORAGE, ::EssenceStorageScreen)
|
||||
MenuScreens.register(ITEM_REPAIER, ::ItemRepairerScreen)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ object MNames {
|
||||
const val MATTER_PANEL = "matter_panel"
|
||||
const val MATTER_REPLICATOR = "matter_replicator"
|
||||
const val MATTER_BOTTLER = "matter_bottler"
|
||||
const val ITEM_REPAIRER = "item_repairer"
|
||||
const val DRIVE_VIEWER = "drive_viewer"
|
||||
const val DRIVE_RACK = "drive_rack"
|
||||
const val ITEM_MONITOR = "item_monitor"
|
||||
|
Loading…
Reference in New Issue
Block a user