Compare commits

...

3 Commits

3 changed files with 136 additions and 107 deletions

View File

@ -22,7 +22,6 @@ import ru.dbotthepony.mc.otm.capability.matter.MatterStorageImpl
import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage import ru.dbotthepony.mc.otm.capability.matter.ProfiledMatterStorage
import ru.dbotthepony.mc.otm.config.MachinesConfig import ru.dbotthepony.mc.otm.config.MachinesConfig
import ru.dbotthepony.mc.otm.container.UpgradeContainer import ru.dbotthepony.mc.otm.container.UpgradeContainer
import ru.dbotthepony.mc.otm.container.slotted.ContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot import ru.dbotthepony.mc.otm.container.slotted.FilteredContainerSlot
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu import ru.dbotthepony.mc.otm.menu.matter.MatterBottlerMenu
@ -35,7 +34,7 @@ import java.util.function.BooleanSupplier
class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) : class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, blockPos, blockState) { MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, blockPos, blockState) {
val upgrades = UpgradeContainer(3, UpgradeType.BASIC_MATTER, BooleanSupplier { blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE }, ::markDirtyFast) val upgrades = UpgradeContainer(3, UpgradeType.BASIC_MATTER, BooleanSupplier { this.blockState.getValue(WorkerState.SEMI_WORKER_STATE) !== WorkerState.IDLE }, ::markDirtyFast)
override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, upgrades.transform(MachinesConfig.MatterBottler.VALUES))) override val energy = ProfiledEnergyStorage(WorkerEnergyStorage(this::markDirtyFast, upgrades.transform(MachinesConfig.MatterBottler.VALUES)))
val energyConfig = ConfigurableEnergy(energy) val energyConfig = ConfigurableEnergy(energy)
@ -141,7 +140,7 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
} }
if (state !== blockState) { if (state !== blockState) {
level.setBlock(blockPos, state, Block.UPDATE_CLIENTS) level.setBlock(blockPos, state, Block.UPDATE_ALL)
} }
} }
@ -154,83 +153,85 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
} }
private val workerState by countingLazy(blockStateChangesCounter) { private val workerState by countingLazy(blockStateChangesCounter) {
blockState.getValue(WorkerState.SEMI_WORKER_STATE) this.blockState.getValue(WorkerState.SEMI_WORKER_STATE)
} }
private fun blockstateToWorking() { private fun blockstateToWorking() {
if (workerState !== WorkerState.WORKING) { if (workerState !== WorkerState.WORKING) {
level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_ALL)
} }
} }
private fun blockstateToIdle() { private fun blockstateToIdle() {
if (workerState !== WorkerState.IDLE) { if (workerState !== WorkerState.IDLE) {
level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS) level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_ALL)
} }
} }
override fun tick() { private fun tickBottling() {
super.tick() var isWorking = false
var hasCapacitors = false
if (redstoneControl.isBlockedByRedstone) {
blockstateToIdle()
return
}
if (isBottling) {
var any = false
var idle = false
for (slot in bottling.slotIterator()) { for (slot in bottling.slotIterator()) {
val item = slot.item val item = slot.item
val capability = item.getCapability(MatteryCapability.MATTER_ITEM) ?: continue
item.getCapability(MatteryCapability.MATTER_ITEM)?.let { if (!capability.receiveMatterChecked(Decimal.LONG_MAX_VALUE, true).isPositive) {
if (!it.missingMatter.isPositive) {
unbottling.consumeItem(item, false) unbottling.consumeItem(item, false)
slot.setChanged() slot.setChanged()
} else { continue
any = true }
initialCapacity = initialCapacity ?: it.storedMatter
hasCapacitors = true
initialCapacity = initialCapacity ?: capability.storedMatter
val rate = MachinesConfig.MatterBottler.RATE * (1.0 + upgrades.speedBonus) val rate = MachinesConfig.MatterBottler.RATE * (1.0 + upgrades.speedBonus)
val energyRate = MachinesConfig.MatterBottler.VALUES.energyConsumption * (1.0 + upgrades.speedBonus)
if (matter.storedMatter < rate) { if (matter.storedMatter < rate) {
matter.receiveMatter(matterNode.graph.extractMatter(matter.missingMatter val toExtract = matter.missingMatter
.coerceAtMost(rate * 200) .coerceAtMost(rate * 200)
.coerceAtMost(it.missingMatter - matter.storedMatter), false), false) .coerceAtMost(capability.missingMatter - matter.storedMatter)
matter.receiveMatter(matterNode.graph.extractMatter(toExtract, false), false)
} }
if (matter.storedMatter.isPositive) { if (matter.storedMatter.isPositive) {
matter.extractMatter(it.receiveMatter(rate.coerceAtMost(matter.storedMatter), false), false) val energyRatio = if (energyRate <= Decimal.ZERO) Decimal.ONE else energy.extractEnergy(energyRate, true) / energyRate
val matterRatio = matter.extractMatter(capability.receiveMatter(rate.coerceAtMost(matter.storedMatter), true), true) / rate
if (!it.missingMatter.isPositive) { val minRatio = minOf(matterRatio, energyRatio)
initialCapacity = null
workProgress = 0f if (minRatio > Decimal.ZERO) {
} else { isWorking = true
workProgress = ((it.storedMatter - initialCapacity!!) / it.maxStoredMatter).toFloat() energy.extractEnergy(energyRate * minRatio, false)
matter.extractMatter(capability.receiveMatter(rate * minRatio, false), false)
workProgress = ((capability.storedMatter - initialCapacity!!) / capability.maxStoredMatter).toFloat()
slot.setChanged()
} }
} else { } else {
idle = true
if (spitItemsWhenCantWork) { if (spitItemsWhenCantWork) {
unbottling.consumeItem(item, false) unbottling.consumeItem(item, false)
slot.setChanged() slot.setChanged()
} }
} }
}
}
if (any) {
break break
} }
}
if (any && !idle) { if (isWorking) {
blockstateToWorking() blockstateToWorking()
} else { } else {
matter.extractMatter(matterNode.graph.receiveMatter(matter.storedMatter, false), false)
blockstateToIdle() blockstateToIdle()
} }
} else {
if (!hasCapacitors) {
matter.extractMatter(matterNode.graph.receiveMatter(matter.storedMatter, false), false)
initialCapacity = null
workProgress = 0f
}
}
private fun tickUnbottling() {
matter.extractMatter(matterNode.graph.receiveMatter(matter.storedMatter, false), false) matter.extractMatter(matterNode.graph.receiveMatter(matter.storedMatter, false), false)
if (!matter.missingMatter.isPositive) { if (!matter.missingMatter.isPositive) {
@ -246,38 +247,64 @@ class MatterBottlerBlockEntity(blockPos: BlockPos, blockState: BlockState) :
} }
var any = false var any = false
var hasCapacitors = false
for (slot in unbottling.slotIterator()) { for (slot in unbottling.slotIterator()) {
val item = slot.item val item = slot.item
val it = item.getCapability(MatteryCapability.MATTER_ITEM) ?: continue
item.getCapability(MatteryCapability.MATTER_ITEM)?.let { if (!it.extractMatterChecked(Decimal.LONG_MAX_VALUE, true).isPositive) {
if (!it.storedMatter.isPositive) {
bottling.consumeItem(item, false) bottling.consumeItem(item, false)
slot.setChanged() slot.setChanged()
} else { continue
any = true }
initialCapacity = initialCapacity ?: it.storedMatter
matter.receiveMatter(it.extractMatter(MachinesConfig.MatterBottler.RATE, false), false) initialCapacity = initialCapacity ?: it.storedMatter
hasCapacitors = true
val rate = MachinesConfig.MatterBottler.RATE * (1.0 + upgrades.speedBonus)
val energyRate = MachinesConfig.MatterBottler.VALUES.energyConsumption * (1.0 + upgrades.speedBonus)
val energyRatio = if (energyRate <= Decimal.ZERO) Decimal.ONE else energy.extractEnergy(energyRate, true) / energyRate
val matterRatio = matter.receiveMatter(it.extractMatterChecked(rate, true), true) / rate
val minRatio = minOf(energyRatio, matterRatio)
if (minRatio > Decimal.ZERO) {
any = true
energy.extractEnergy(energyRate * energyRatio, false)
matter.receiveMatter(it.extractMatterChecked(rate * minRatio, false), false)
if (!it.storedMatter.isPositive) {
initialCapacity = null
workProgress = 0f
} else {
workProgress = 1f - (it.storedMatter / initialCapacity!!).toFloat() workProgress = 1f - (it.storedMatter / initialCapacity!!).toFloat()
} }
}
}
if (any) {
break break
} }
}
if (any) { if (any) {
blockstateToWorking() blockstateToWorking()
} else { } else {
blockstateToIdle() blockstateToIdle()
} }
if (!hasCapacitors) {
initialCapacity = null
workProgress = 0f
}
}
override fun tick() {
super.tick()
if (redstoneControl.isBlockedByRedstone) {
blockstateToIdle()
return
}
if (isBottling) {
tickBottling()
} else {
tickUnbottling()
} }
} }
} }

View File

@ -60,7 +60,7 @@ object MachinesConfig : AbstractConfig("machines") {
private val MATTER_BOTTLER = workerValues( private val MATTER_BOTTLER = workerValues(
MNames.MATTER_BOTTLER, MNames.MATTER_BOTTLER,
energyStorage = Decimal(40_000), energyStorage = Decimal(40_000),
energyConsumption = Decimal(10), energyConsumption = Decimal(40),
energyThroughput = Decimal(200), energyThroughput = Decimal(200),
matterCapacity = Decimal(400), matterCapacity = Decimal(400),
workTimeMultiplier = null workTimeMultiplier = null
@ -85,7 +85,7 @@ object MachinesConfig : AbstractConfig("machines") {
object MatterBottler { object MatterBottler {
val VALUES by ::MATTER_BOTTLER val VALUES by ::MATTER_BOTTLER
val RATE by builder.comment("Matter transferred per tick").defineDecimal("RATE", Decimal("2.0"), Decimal.ONE_TENTH) val RATE by builder.comment("Matter transferred per tick").defineDecimal("RATE", Decimal("10.0"), Decimal.ONE_TENTH)
} }
object MatterRecycler { object MatterRecycler {

View File

@ -274,6 +274,7 @@ class SlottedContainer(
for ((item, slot) in items) { for ((item, slot) in items) {
if (slot in 0 until containerSize) { if (slot in 0 until containerSize) {
slots[slot].item = item slots[slot].item = item
bitmap[slot] = item.isNotEmpty
} else if (item.isNotEmpty) { } else if (item.isNotEmpty) {
ItemStack.CODEC.encodeStart(provider.createSerializationContext(NbtOps.INSTANCE), item) ItemStack.CODEC.encodeStart(provider.createSerializationContext(NbtOps.INSTANCE), item)
.ifError { LOGGER.warn("Unable to serialize 'lost' item: ${it.message()}") } .ifError { LOGGER.warn("Unable to serialize 'lost' item: ${it.message()}") }
@ -307,6 +308,7 @@ class SlottedContainer(
if (i in 0 until containerSize) { if (i in 0 until containerSize) {
slots[i].deserializeNBT(provider, element) slots[i].deserializeNBT(provider, element)
bitmap[i] = slots[i].isNotEmpty
} else { } else {
lostItems.add(element) lostItems.add(element)
this.provider = provider this.provider = provider