Redo mattery energy storage

This commit is contained in:
DBotThePony 2023-01-14 14:22:15 +07:00
parent 9073ae1b08
commit b9cb5db9ac
Signed by: DBot
GPG Key ID: DCC23B5715498507
30 changed files with 349 additions and 293 deletions

View File

@ -35,8 +35,8 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
get() = MBlocks.ANDROID_STATION.name
override val energy = object : WorkerEnergyStorage(this@AndroidStationBlockEntity::setChangedLight, ::CAPACITY, ::MAX_IO, { null }) {
override fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
return super.extractEnergyInner(howMuch, simulate).also {
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
return super.extractEnergy(howMuch, simulate).also {
if (!simulate && this.batteryLevel.isZero) {
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.IDLE), Block.UPDATE_CLIENTS)
@ -45,8 +45,8 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
}
}
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
return super.receiveEnergyInner(howMuch, simulate).also {
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
return super.receiveEnergy(howMuch, simulate).also {
if (!simulate && it.isPositive) {
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) {
level?.setBlock(blockPos, blockState.setValue(WorkerState.SEMI_WORKER_STATE, WorkerState.WORKING), Block.UPDATE_CLIENTS)
@ -85,11 +85,11 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
val missing = it.androidEnergy.missingPower
if (missing > Decimal.ZERO) {
val extract = energy.extractEnergyInner(missing, true)
val extract = energy.extractEnergy(missing, true)
if (extract > Decimal.ZERO) {
val received = it.androidEnergy.receiveEnergy(extract, false)
energy.extractEnergyInner(received, false)
energy.extractEnergy(received, false)
}
}
}

View File

@ -72,17 +72,10 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
)
private data class BatteryBankDistribution(val distribution: Array<Decimal>, val maxThroughput: Decimal)
private enum class BankMode { RECEIVE, EXTRACT, BIDIRECTIONAL }
private inner class BatteryBankEnergy(private val mode: BankMode) : IMatteryEnergyStorage {
override fun canExtract() = mode != BankMode.RECEIVE
override fun canReceive() = mode != BankMode.EXTRACT
private inner class BatteryBankEnergy(override val energyFlow: FlowDirection) : IMatteryEnergyStorage {
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (mode == BankMode.RECEIVE)
return Decimal.ZERO
return extractEnergyInner(howMuch, simulate)
return distributeEnergy(isReceiving = false, howMuch, simulate)
}
fun getDistribution(isReceiving: Boolean): BatteryBankDistribution {
@ -157,18 +150,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
return summ
}
fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
return distributeEnergy(isReceiving = false, howMuch, simulate)
}
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (mode == BankMode.EXTRACT)
return Decimal.ZERO
return receiveEnergyInner(howMuch, simulate)
}
fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
return distributeEnergy(isReceiving = true, howMuch, simulate)
}
@ -212,9 +194,9 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
}
}
private val energyReceiver = BatteryBankEnergy(BankMode.RECEIVE)
private val energyExtractor = BatteryBankEnergy(BankMode.EXTRACT)
private val energy = BatteryBankEnergy(BankMode.BIDIRECTIONAL)
private val energyReceiver = BatteryBankEnergy(FlowDirection.INPUT)
private val energyExtractor = BatteryBankEnergy(FlowDirection.OUTPUT)
private val energy = BatteryBankEnergy(FlowDirection.BI_DIRECTIONAL)
private var resolverEnergyReceiver = LazyOptional.of { energyReceiver }
private var resolverEnergyExtractor = LazyOptional.of { energyExtractor }
@ -347,14 +329,14 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
val diff = it.receiveEnergy(maxThroughput, true)
if (!diff.isZero) {
val newExtract = energy.extractEnergyInner(diff, true)
val newExtract = energy.extractEnergy(diff, true)
val newReceive = it.receiveEnergy(newExtract, true)
val extracted = energy.extractEnergyInner(newReceive, false)
val extracted = energy.extractEnergy(newReceive, false)
val received = it.receiveEnergy(extracted, false)
if (received < extracted) {
energy.receiveEnergyInner(extracted - received, false)
energy.receiveEnergy(extracted - received, false)
}
}
}

View File

@ -165,18 +165,18 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
private var check = true
private fun workWithPower(it: IEnergyStorage) {
val extracted = energy.extractEnergyInner(THROUGHPUT, true)
val extracted = energy.extractEnergy(THROUGHPUT, true)
val received = it.receiveEnergy(extracted, false)
if (!received.isZero) {
energy.extractEnergyInner(received, false)
energy.extractEnergy(received, false)
}
}
fun tick() {
if (workTicks > 0) {
workTicks--
energy.receiveEnergyInner(GENERATION_SPEED, false)
energy.receiveEnergy(GENERATION_SPEED, false)
if (workTicks == 0) {
workTicksTotal = 0

View File

@ -126,11 +126,10 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
tickOnceServer(this::checkSurroundings)
}
private inner class EnergyCounterCap(val isInput: Boolean) : IMatteryEnergyStorage {
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (isInput)
return Decimal.ZERO
private inner class EnergyCounterCap(isInput: Boolean) : IMatteryEnergyStorage {
override val energyFlow = FlowDirection.input(isInput)
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (inputCapability.isPresent) {
val it = inputCapability.resolve().get()
@ -156,9 +155,6 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
}
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (!isInput)
return Decimal.ZERO
if (outputCapability.isPresent) {
val it = outputCapability.resolve().get()
@ -188,7 +184,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
override var batteryLevel: Decimal
get() {
if (isInput) {
if (energyFlow.input) {
if (outputCapability.isPresent) {
val it = outputCapability.resolve().get()
@ -218,7 +214,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
override val maxBatteryLevel: Decimal
get() {
if (isInput) {
if (energyFlow.input) {
if (outputCapability.isPresent) {
val it = outputCapability.resolve().get()
@ -245,7 +241,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
override val missingPower: Decimal
get() {
if (isInput) {
if (energyFlow.input) {
if (outputCapability.isPresent) {
val it = outputCapability.resolve().get()
@ -269,9 +265,6 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
return Decimal.ZERO
}
override fun canExtract() = !isInput
override fun canReceive() = isInput
}
private var resolverInput = LazyOptional.of<IMatteryEnergyStorage> { energyInput }

View File

@ -14,6 +14,7 @@ import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.block.IDroppableContainer
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.canSetBatteryMattery
@ -59,6 +60,12 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
})
val energy = object : IMatteryEnergyStorage {
override val energyFlow: FlowDirection get() {
val discharge = container[SLOT_DISCHARGE].energy
val charge = container[SLOT_CHARGE].energy
return FlowDirection.of(input = charge?.canReceive() ?: false, output = discharge?.canExtract() ?: false)
}
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
return container[SLOT_DISCHARGE].energy?.extractEnergy(howMuch, simulate) ?: Decimal.ZERO
}

View File

@ -32,18 +32,8 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
val batteryContainer = MatteryContainer(this::setChangedLight, 1)
protected fun batteryChargeLoop() {
var hit = false
for (stack in batteryContainer) {
if (!stack.isEmpty) {
hit = true
break
}
}
if (!hit) {
if (!batteryContainer.any { !it.isEmpty })
return
}
var demand = energy.receiveEnergy(energy.missingPower, true)
if (demand.isZero) return
@ -51,15 +41,9 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
for (stack in batteryContainer) {
if (!stack.isEmpty) {
stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
if (it is IMatteryEnergyStorage) {
val diff = it.extractEnergy(demand, false)
energy.receiveEnergyInner(diff, false)
demand -= diff
} else {
val diff = it.extractEnergy(demand, false)
energy.receiveEnergyInner(diff, false)
demand -= diff
}
val diff = it.extractEnergy(demand, false)
energy.receiveEnergy(diff, false)
demand -= diff
}
if (demand <= Decimal.ZERO)

View File

@ -303,7 +303,7 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
ticksAdvanced = availableTicks.coerceAtMost(ticksLeft)
} else {
requiredPower = currentJob.powerUsage * ticksLeft.coerceAtMost(availableTicks)
extractedPower = energy.extractEnergyInner(requiredPower, true)
extractedPower = energy.extractEnergy(requiredPower, true)
ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft).coerceAtMost(availableTicks)
}
@ -333,7 +333,7 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
extractedPower = status.newDrainedPower ?: extractedPower
if (extractedPower != null) {
energy.extractEnergyInner(extractedPower, false)
energy.extractEnergy(extractedPower, false)
}
continue

View File

@ -115,7 +115,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
})
val matter: MatterStorageImpl = object : MatterStorageImpl(this::setChangedLight, FlowDirection.BI_DIRECTIONAL, ::CAPACITY) {
override val matterDirection: FlowDirection get() {
override val matterFlow: FlowDirection get() {
return if (this@MatterBottlerBlockEntity.isBottling) FlowDirection.INPUT else FlowDirection.OUTPUT
}
}
@ -241,7 +241,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
if (!itemStack.isEmpty) {
val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: continue
if (cap.matterDirection != unexpectedDirection) {
if (cap.matterFlow != unexpectedDirection) {
if (this.isBottling && cap.missingMatter > Decimal.ZERO || !this.isBottling && cap.storedMatter > Decimal.ZERO) {
work_stack = itemStack
capability = cap
@ -280,13 +280,13 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
}
if (matter.storedMatter > Decimal.ZERO) {
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
val energyExtracted = energy.extractEnergy(ENERGY_CONSUMPTION, true)
if (!energyExtracted.isZero) {
val matter = capability.receiveMatter(MATTER_EXCHANGE_RATE.coerceAtMost(matter.storedMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
if (!matter.isZero) {
energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE, false)
energy.extractEnergy(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE, false)
capability.receiveMatter(matter, false)
this.matter.extractMatterInner(matter, false)
@ -304,13 +304,13 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
}
}
} else {
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
val energyExtracted = energy.extractEnergy(ENERGY_CONSUMPTION, true)
if (!energyExtracted.isZero) {
val matter = capability.extractMatter(MATTER_EXCHANGE_RATE.coerceAtMost(matter.missingMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
if (!matter.isZero) {
this.energy.extractEnergyInner(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false)
this.energy.extractEnergy(ENERGY_CONSUMPTION * matter / MATTER_EXCHANGE_RATE,false)
capability.extractMatter(matter, false)
this.matter.receiveMatterInner(matter, false)

View File

@ -128,7 +128,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
return summ
}
override val matterDirection: FlowDirection
override val matterFlow: FlowDirection
get() = FlowDirection.BI_DIRECTIONAL
private var resolver = LazyOptional.of { this }

View File

@ -484,7 +484,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
return stack
val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * stack.count
val maxExtractEnergy = energy.extractEnergyInner(maxPossibleDemand, true)
val maxExtractEnergy = energy.extractEnergy(maxPossibleDemand, true)
var leftover: ItemStackWrapper = stack.copy()
var additional: BigInteger = BigInteger.ZERO
@ -499,7 +499,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
leftover = ItemStackWrapper(parent.insertItem(slot, leftover.stack, simulate))
if (oldCount != leftover.count && !simulate) {
energy.extractEnergyInner(ITEM_STORAGE.energyPerOperation * (oldCount - leftover.count), false)
energy.extractEnergy(ITEM_STORAGE.energyPerOperation * (oldCount - leftover.count), false)
if (scanned.size <= slot) {
sizeScan()
@ -529,7 +529,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
return ItemStackWrapper.EMPTY
val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * amount
val maxExtractEnergy = energy.extractEnergyInner(maxPossibleDemand, true)
val maxExtractEnergy = energy.extractEnergy(maxPossibleDemand, true)
@Suppress("NAME_SHADOWING")
var amount = amount
@ -555,7 +555,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
totalExtracted += extracted.count
if (extracted.count != 0 && !simulate) {
energy.extractEnergyInner(ITEM_STORAGE.energyPerOperation * extracted.count, false)
energy.extractEnergy(ITEM_STORAGE.energyPerOperation * extracted.count, false)
}
if (totalExtracted >= intAmount) {

View File

@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.capability.*
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact
import ru.dbotthepony.mc.otm.container.ItemFilter
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.graph.Graph6Node
@ -187,7 +188,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
return stack
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return stack
val maxMove = energy.extractStepInnerBi(ITEM_STORAGE.energyPerOperation, stack.count, true)
val maxMove = energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, stack.count.toBigInteger(), true)
if (maxMove == BigInteger.ZERO)
return stack
@ -197,7 +198,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
if (simulate)
return leftover.stack
energy.extractStepInner(ITEM_STORAGE.energyPerOperation, maxMove - leftover.count, false)
energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, maxMove - leftover.count, false)
return leftover.stack
}
@ -229,7 +230,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
lastSlot = 0
}
val maxMove = energy.extractStepInner(ITEM_STORAGE.energyPerOperation, MAX_MOVE_PER_OPERATION, true)
val maxMove = energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, MAX_MOVE_PER_OPERATION, true)
var extracted = resolved.extractItem(lastSlot, maxMove, true)
if (extracted.isEmpty || !filter.match(extracted)) {
@ -239,7 +240,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
if (leftOver.count.toInt() != extracted.count) {
extracted = resolved.extractItem(lastSlot, extracted.count - leftOver.count.toInt(), false)
energy.extractStepInner(ITEM_STORAGE.energyPerOperation, extracted.count, false)
energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, extracted.count, false)
items.insertStack(ItemStackWrapper(extracted), false)
} else {
nextTick += INTERVAL * 4
@ -353,7 +354,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
continue
}
var exportAmount = energy.extractStepInner(ITEM_STORAGE.energyPerOperation, exportAmountA, true)
var exportAmount = energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, exportAmountA, true).toIntSafe()
if (exportAmount == 0) {
break
@ -365,7 +366,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
hit = true
exportAmount = items.extractStack(stack.first, (exportAmount - leftover.count).toBigInteger(), false).count.toInt()
resolved.insertItem(lastSlot, stack.second.stack.also { it.count = exportAmount }, false)
energy.extractStepInner(ITEM_STORAGE.energyPerOperation, exportAmount, false)
energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, exportAmount, false)
break
}
}

View File

@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.energy.transferChecked
import ru.dbotthepony.mc.otm.core.Decimal
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
@ -103,13 +104,13 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
return
} else if (demand < available) {
for (demanding in graph.powerDemandingNodes) {
powerPassed += energy.transferInner(demanding, available, false)
powerPassed += energy.transferChecked(demanding, available, false)
}
} else {
val forEach = available / i
for (demanding in graph.powerDemandingNodes) {
powerPassed += energy.transferInner(demanding, forEach, false)
powerPassed += energy.transferChecked(demanding, forEach, false)
}
}
}

View File

@ -30,9 +30,12 @@ import java.util.stream.Stream
val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()
fun IEnergyStorage.receiveEnergy(amount: Decimal, simulate: Boolean): Decimal {
/**
* Does a checked energy receive, calls [IMatteryEnergyStorage.receiveEnergyChecked] if possible
*/
internal fun IEnergyStorage.receiveEnergy(amount: Decimal, simulate: Boolean): Decimal {
if (this is IMatteryEnergyStorage)
return receiveEnergy(amount, simulate)
return receiveEnergyChecked(amount, simulate)
if (!amount.isPositive)
return Decimal.ZERO
@ -43,9 +46,12 @@ fun IEnergyStorage.receiveEnergy(amount: Decimal, simulate: Boolean): Decimal {
return Decimal.valueOf(receiveEnergy(amount.toInt(), simulate))
}
fun IEnergyStorage.extractEnergy(amount: Decimal, simulate: Boolean): Decimal {
/**
* Does a checked energy extraction, calls [IMatteryEnergyStorage.extractEnergyChecked] if possible
*/
internal fun IEnergyStorage.extractEnergy(amount: Decimal, simulate: Boolean): Decimal {
if (this is IMatteryEnergyStorage)
return extractEnergy(amount, simulate)
return extractEnergyChecked(amount, simulate)
if (!amount.isPositive)
return Decimal.ZERO

View File

@ -4,6 +4,21 @@ import java.util.function.Predicate
/**
* Represents possible flow direction, both for matter and for energy
*
* To dynamically get this enum by two booleans (by input and output states), use [FlowDirection.of]
*
* Also, this enum implements [Predicate], you can check incoming flow direction for "compatibility" with
* this flow direction, more precisely:
* [test] will return true and only true if [input] and [output] of incoming flow are assignable to this flow
*
* Example:
* * `INPUT.test(OUTPUT)` = `false`
* * `OUTPUT.test(INPUT)` = `false`
* * `INPUT.test(BI_DIRECTIONAL)` = `true`
* * `OUTPUT.test(BI_DIRECTIONAL)` = `true`
* * `BI_DIRECTIONAL.test(BI_DIRECTIONAL)` = `true`
* * `BI_DIRECTIONAL.test(OUTPUT)` = `false`
* * `BI_DIRECTIONAL.test(INPUT)` = `false`
*/
enum class FlowDirection(val input: Boolean, val output: Boolean) : Predicate<FlowDirection> {
/**
@ -29,4 +44,51 @@ enum class FlowDirection(val input: Boolean, val output: Boolean) : Predicate<Fl
override fun test(t: FlowDirection): Boolean {
return t === this || (!input || t.input) && (!output || t.output)
}
companion object {
@JvmStatic
fun of(input: Boolean, output: Boolean): FlowDirection {
if (input && output) {
return BI_DIRECTIONAL
} else if (input) {
return INPUT
} else if (output) {
return OUTPUT
} else {
return NONE
}
}
/**
* @return [INPUT] if [flag] is true, [OUTPUT] otherwise
*/
@JvmStatic
fun input(flag: Boolean): FlowDirection {
return of(flag, !flag)
}
/**
* @return [OUTPUT] if [flag] is true, [INPUT] otherwise
*/
@JvmStatic
fun output(flag: Boolean): FlowDirection {
return of(!flag, flag)
}
/**
* @return [INPUT] if [flag] is true, [NONE] otherwise
*/
@JvmStatic
fun orInput(flag: Boolean): FlowDirection {
return of(flag, false)
}
/**
* @return [OUTPUT] if [flag] is true, [NONE] otherwise
*/
@JvmStatic
fun orOutput(flag: Boolean): FlowDirection {
return of(false, flag)
}
}
}

View File

@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.util.INBTSerializable
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.extractEnergy
import ru.dbotthepony.mc.otm.capability.receiveEnergy
import ru.dbotthepony.mc.otm.core.Decimal
@ -23,6 +24,9 @@ class AndroidPowerSource(
initialCharge: Decimal,
maxCharge: Decimal
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
override val energyFlow: FlowDirection
get() = FlowDirection.INPUT
private var battery by synchronizer.fraction(initialCharge, name = "android battery")
private var maxBattery by synchronizer.fraction(maxCharge, name = "android max battery")

View File

@ -25,7 +25,7 @@ import ru.dbotthepony.mc.otm.core.set
sealed class BlockEnergyStorageImpl(
protected val listener: () -> Unit,
final override val direction: FlowDirection,
final override val energyFlow: FlowDirection,
private val maxBatteryLevelProvider: () -> Decimal,
private val maxInputProvider: () -> Decimal?,
private val maxOutputProvider: () -> Decimal?,
@ -78,20 +78,6 @@ sealed class BlockEnergyStorageImpl(
}
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (direction == FlowDirection.INPUT)
return Decimal.ZERO
return extractEnergyInner(howMuch, simulate)
}
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (direction == FlowDirection.OUTPUT)
return Decimal.ZERO
return receiveEnergyInner(howMuch, simulate)
}
override fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive)
return Decimal.ZERO
@ -116,7 +102,7 @@ sealed class BlockEnergyStorageImpl(
return diff
}
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive)
return Decimal.ZERO
@ -141,14 +127,6 @@ sealed class BlockEnergyStorageImpl(
return diff
}
override fun canExtract(): Boolean {
return direction != FlowDirection.INPUT
}
override fun canReceive(): Boolean {
return direction != FlowDirection.OUTPUT
}
override fun serializeNBT(): CompoundTag {
val tag = CompoundTag()
tag[ENERGY_STORED_KEY] = batteryLevel.serializeNBT()

View File

@ -12,77 +12,6 @@ import java.math.BigInteger
sealed interface IEnergyStorageImpl {
val maxInput: Decimal?
val maxOutput: Decimal?
val direction: FlowDirection
fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal
fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal
fun extractStepInner(base: Decimal, multiplier: Int, simulate: Boolean): Int {
return (extractEnergyInner(base * multiplier, simulate) / base).toInt()
}
fun extractStepInnerBi(base: Decimal, multiplier: Int, simulate: Boolean): BigInteger {
return (extractEnergyInner(base * multiplier, simulate) / base).whole
}
fun extractStepInner(base: Decimal, multiplier: BigInteger, simulate: Boolean): Int {
return (extractEnergyInner(base * multiplier, simulate) / base).toInt()
}
fun extractStepInnerBi(base: Decimal, multiplier: BigInteger, simulate: Boolean): BigInteger {
return (extractEnergyInner(base * multiplier, simulate) / base).whole
}
fun transferInner(other: IMatteryEnergyStorage, amount: Decimal, simulate: Boolean): Decimal {
if (!amount.isPositive)
return Decimal.ZERO
val extracted = extractEnergyInner(amount, true)
val received = other.receiveEnergy(extracted, simulate)
if (!simulate)
extractEnergyInner(received, false)
return received
}
/**
* All or nothing
*
* @return energy accepted
*/
fun extractEnergyInnerExact(howMuch: Decimal, simulate: Boolean): Decimal {
val extracted = extractEnergyInner(howMuch, true)
if (extracted != howMuch) {
return Decimal.ZERO
}
if (!simulate) {
extractEnergyInner(howMuch, false)
}
return extracted
}
/**
* All or nothing
*
* @return energy accepted
*/
fun receiveEnergyInnerExact(howMuch: Decimal, simulate: Boolean): Decimal {
val extracted = receiveEnergyInner(howMuch, true)
if (extracted != howMuch) {
return Decimal.ZERO
}
if (!simulate) {
receiveEnergyInner(howMuch, false)
}
return extracted
}
}
internal fun batteryLevel(it: IEnergyStorage, tooltips: MutableList<Component>) {
@ -103,7 +32,7 @@ internal fun batteryLevel(it: IMatteryEnergyStorage, tooltips: MutableList<Compo
).withStyle(ChatFormatting.GRAY))
if (it is IEnergyStorageImpl) {
when (it.direction) {
when (it.energyFlow) {
FlowDirection.INPUT -> {
if (it.maxInput != null) {
tooltips.add(

View File

@ -1,29 +1,99 @@
package ru.dbotthepony.mc.otm.capability.energy
import net.minecraftforge.energy.IEnergyStorage
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.core.Decimal
import ru.dbotthepony.mc.otm.core.RGBAColor
import java.math.BigInteger
import kotlin.math.roundToInt
/**
* Energy interface in Overdrive That Matters, which is backward compatible with [IEnergyStorage]
* Energy interface in Overdrive That Matters, which also implements backward compatible methods to implement [IEnergyStorage]
*
* Details of this energy system are as follows:
* * [extractEnergy] and [receiveEnergy] are *unchecked*, which means, they will generally work regardless of energy storage type ([energyFlow]), be it tool, battery or generator.
* What this means is that, despite making no sense to use tool as a battery in machine, [extractEnergy] will work regardless.
* To avoid such cases, [extractEnergyChecked] and [receiveEnergyChecked] are provided
* * Instead of [canReceive] and [canExtract] of [IEnergyStorage], this interface employs [energyFlow] enum property, which is cleaner and easier to use,
* see [FlowDirection] for details
* * This interface allows to set energy stored *directly*. With great power comes great responsibility though, since, sometimes it is technically
* cumbersome or straight up impossible to set stored energy value, therefore, setter of [batteryLevel] is free to throw [UnsupportedOperationException].
* To avoid try/catch block, check [canSetBatteryLevel] property first
* * Due to limitations of setting [batteryLevel] directly, two methods are also provided: [fillBattery] and [drainBattery]. If you ever
* need to only fill or drain this energy storage, call these two methods and do not use [batteryLevel] directly.
* * Lastly, there is [missingPower]. It returns whatever it has in name. What it makes better than writing your own "[maxBatteryLevel] - [batteryLevel]" logic is that
* implementations can use different and more precise logic to determine actually missing power. **Please use [missingPower] instead of writing your own logic to determine
* whenever storage is missing energy, it will make players not experience silly bugs and make you avoid headaches**.
*/
interface IMatteryEnergyStorage : IEnergyStorage {
/**
* Energy extraction by external interacts
* Extracts up to [howMuch] energy from this storage
*
* In general, this method *does not* obey [energyFlow] and will allow to extract energy
* even if [energyFlow] and [canExtract] say otherwise, unlike [IEnergyStorage.extractEnergy], which, in general,
* obeys return value of [IEnergyStorage.canExtract].
*
* Therefore, if you want/need to obey [energyFlow], use [extractEnergyChecked]
*
* General contracts:
* * Negative values are not allowed, failing to comply with this contract will result in undefined behavior (worst case) or exception (best case)
* * Returned value CAN NOT be bigger than requested [howMuch], implementations failing to obey this contract will cause undefined behavior in upstream code.
* Upstream code SHOULD NOT check for this contract.
*
* @return energy extracted
*/
fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal
/**
* Energy insertion by external interacts
* Extracts up to [howMuch] energy from this storage, while obeying [energyFlow]. See [extractEnergy].
*
* @return energy accepted
* Interface implementations generally do not need to override this.
*
* @return energy extracted
*/
fun extractEnergyChecked(howMuch: Decimal, simulate: Boolean): Decimal {
require(!howMuch.isNegative) { "Negative amount of energy: $howMuch" }
if (!energyFlow.output)
return Decimal.ZERO
return extractEnergy(howMuch, simulate)
}
/**
* Inserts up to [howMuch] energy into this storage
*
* In general, this method *does not* obey [energyFlow] and will allow to insert energy
* even if [energyFlow] and [canReceive] say otherwise, unlike [IEnergyStorage.receiveEnergy], which, in general,
* obeys return value of [IEnergyStorage.canReceive].
*
* Therefore, if you want/need to obey [energyFlow], use [receiveEnergyChecked]
*
* General contracts:
* * Negative values are not allowed, failing to comply with this contract will result in undefined behavior (worst case) or exception (best case)
* * Returned value CAN NOT be bigger than requested [howMuch], implementations failing to obey this contract will cause undefined behavior in upstream code.
* Upstream code SHOULD NOT check for this contract.
*
* @return energy extracted
*/
fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal
/**
* Inserts up to [howMuch] energy into this storage, while obeying [energyFlow]. See [receiveEnergy].
*
* Interface implementations generally do not need to override this.
*
* @return energy extracted
*/
fun receiveEnergyChecked(howMuch: Decimal, simulate: Boolean): Decimal {
require(!howMuch.isNegative) { "Negative amount of energy: $howMuch" }
if (!energyFlow.output)
return Decimal.ZERO
return extractEnergy(howMuch, simulate)
}
/**
* If this is false, then [batteryLevel] will throw [UnsupportedOperationException] when trying to set it
*/
@ -55,26 +125,47 @@ interface IMatteryEnergyStorage : IEnergyStorage {
/**
* Empties power of this energy storage
*
* @throws [UnsupportedOperationException]
* @see batteryLevel
* @return whenever operation was successful
*/
fun drainBattery() {
batteryLevel = Decimal.ZERO
fun drainBattery(): Boolean {
try {
batteryLevel = Decimal.ZERO
} catch(err: UnsupportedOperationException) {
return false
}
return true
}
/**
* Fully fills power in this energy storage
*
* @throws [UnsupportedOperationException]
* @see batteryLevel
* @return whenever operation was successful
*/
fun fillBattery() {
batteryLevel = maxBatteryLevel
fun fillBattery(): Boolean {
try {
batteryLevel = maxBatteryLevel
} catch(err: UnsupportedOperationException) {
return false
}
return true
}
/**
* Flow direction of energy possible for this energy storage, see [FlowDirection]
*/
val energyFlow: FlowDirection
// -------- Forge Energy stuff
override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
// follow contract of IEnergyStorage
if (!energyFlow.input)
return 0
val received = receiveEnergy(Decimal(maxReceive), true).toInt()
// Receiving only a fraction
@ -85,6 +176,10 @@ interface IMatteryEnergyStorage : IEnergyStorage {
}
override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int {
// follow contract of IEnergyStorage
if (energyFlow.output)
return 0
val extracted = extractEnergy(Decimal(maxReceive), true).toInt()
// Extracting only a fraction
@ -103,14 +198,19 @@ interface IMatteryEnergyStorage : IEnergyStorage {
}
override fun canExtract(): Boolean {
return extractEnergy(Decimal.ONE, true) > Decimal.ZERO
return energyFlow.output
}
override fun canReceive(): Boolean {
return receiveEnergy(Decimal.ONE, true) > Decimal.ZERO
return energyFlow.input
}
}
/**
* Performs *unchecked* extraction of energy
*
* @return whenever can (or we did) extract exactly [howMuch] energy from this storage
*/
fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, simulate: Boolean): Boolean {
if (extractEnergy(howMuch, true) == howMuch) {
if (!simulate) {
@ -123,6 +223,11 @@ fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, simulate: Boolean
return false
}
/**
* Performs *unchecked* insertion of energy
*
* @return whenever can (or we did) receive exactly [howMuch] energy into this storage
*/
fun IMatteryEnergyStorage.receiveEnergyExact(howMuch: Decimal, simulate: Boolean): Boolean {
if (receiveEnergy(howMuch, true) == howMuch) {
if (!simulate) {
@ -135,23 +240,56 @@ fun IMatteryEnergyStorage.receiveEnergyExact(howMuch: Decimal, simulate: Boolean
return false
}
/**
* Performs *unchecked* extraction of energy
*
* @return how much times can (or we did) extract exactly [howMuch] * [times] energy from this storage
*/
fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, times: Int, simulate: Boolean): Int {
if (times == 0)
return 0
require(times >= 0) { "times $times >= 0" }
require(howMuch >= Decimal.ZERO) { "howMuch $howMuch >= 0" }
return (extractEnergy(howMuch * times, simulate) / times).toInt()
@Suppress("name_shadowing")
val times = (extractEnergy(howMuch * times, true) / times).toInt()
if (simulate)
return times
return (extractEnergy(howMuch * times, false) / times).toInt()
}
/**
* Performs *unchecked* extraction of energy
*
* @return how much times can (or we did) extract exactly [howMuch] * [times] energy from this storage
*/
fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, multiplier: BigInteger, simulate: Boolean): BigInteger {
return (extractEnergy(howMuch * multiplier, simulate) / howMuch).whole
}
/**
* @see [IMatteryEnergyStorage.extractEnergy]
*/
fun IMatteryEnergyStorage.extractEnergy(howMuch: Long, simulate: Boolean): Decimal {
return extractEnergy(Decimal(howMuch), simulate)
}
/**
* @see [IMatteryEnergyStorage.receiveEnergy]
*/
fun IMatteryEnergyStorage.receiveEnergy(howMuch: Long, simulate: Boolean): Decimal {
return receiveEnergy(Decimal(howMuch), simulate)
}
/**
* Performs *unchecked* energy transfer from this storage to [other]
*
* @see IMatteryEnergyStorage.extractEnergy
* @see IMatteryEnergyStorage.receiveEnergy
*/
fun IMatteryEnergyStorage.transfer(other: IMatteryEnergyStorage, amount: Decimal, simulate: Boolean): Decimal {
if (!amount.isPositive)
return Decimal.ZERO
@ -160,25 +298,28 @@ fun IMatteryEnergyStorage.transfer(other: IMatteryEnergyStorage, amount: Decimal
val received = other.receiveEnergy(extracted, simulate)
if (!simulate)
extractEnergy(received, false)
return extractEnergy(received, false)
return received
}
fun IMatteryEnergyStorage.extractStepOuter(base: Decimal, multiplier: BigInteger, simulate: Boolean): Int {
return (extractEnergy(base * multiplier, simulate) / base).toInt()
}
/**
* Performs checked energy transfer from this storage to [other]
*
* @see IMatteryEnergyStorage.extractEnergy
* @see IMatteryEnergyStorage.receiveEnergy
*/
fun IMatteryEnergyStorage.transferChecked(other: IMatteryEnergyStorage, amount: Decimal, simulate: Boolean): Decimal {
if (!amount.isPositive)
return Decimal.ZERO
fun IMatteryEnergyStorage.extractStepOuter(base: Decimal, multiplier: Int, simulate: Boolean): Int {
return (extractEnergy(base * multiplier, simulate) / base).toInt()
}
val extracted = extractEnergy(amount, true)
val received = other.receiveEnergyChecked(extracted, simulate)
fun IMatteryEnergyStorage.extractStepOuterBi(base: Decimal, multiplier: Int, simulate: Boolean): BigInteger {
return (extractEnergy(base * multiplier, simulate) / base).whole
}
if (!simulate)
return extractEnergy(received, false)
fun IMatteryEnergyStorage.extractStepOuterBi(base: Decimal, multiplier: BigInteger, simulate: Boolean): BigInteger {
return (extractEnergy(base * multiplier, simulate) / base).whole
return received
}
fun IMatteryEnergyStorage.getBarWidth(): Int {

View File

@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.core.tagNotNull
sealed class ItemEnergyStorageImpl(
final override val direction: FlowDirection,
final override val energyFlow: FlowDirection,
protected val itemStack: ItemStack,
maxBatteryLevel: Decimal,
maxInput: Decimal?,
@ -56,20 +56,6 @@ sealed class ItemEnergyStorageImpl(
}
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (direction == FlowDirection.INPUT)
return Decimal.ZERO
return extractEnergyInner(howMuch, simulate)
}
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (direction == FlowDirection.OUTPUT)
return Decimal.ZERO
return receiveEnergyInner(howMuch, simulate)
}
override fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive || itemStack.count != 1)
return Decimal.ZERO
@ -96,7 +82,7 @@ sealed class ItemEnergyStorageImpl(
return diff
}
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive || itemStack.count != 1)
return Decimal.ZERO
@ -123,14 +109,6 @@ sealed class ItemEnergyStorageImpl(
return diff
}
override fun canExtract(): Boolean {
return direction != FlowDirection.INPUT
}
override fun canReceive(): Boolean {
return direction != FlowDirection.OUTPUT
}
companion object {
const val ENERGY_KEY = "energy"

View File

@ -81,13 +81,13 @@ interface IMatterStorage {
/**
* Which direction does matter flows
*/
val matterDirection: FlowDirection
val matterFlow: FlowDirection
}
inline val IMatterStorage.canExtractMatter: Boolean
get() = matterDirection.output
get() = matterFlow.output
inline val IMatterStorage.canReceiveMatter: Boolean
get() = matterDirection.input
get() = matterFlow.input
fun IMatterStorage.getBarWidth(): Int {
return ((storedMatter / maxStoredMatter).toFloat().coerceAtLeast(0f).coerceAtMost(1f) * 13f).roundToInt()

View File

@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.core.set
open class MatterStorageImpl @JvmOverloads constructor(
protected val listener: Runnable?,
override val matterDirection: FlowDirection,
override val matterFlow: FlowDirection,
protected val maxStoredMatterSupplier: () -> Decimal,
protected val maxReceiveSupplier: () -> Decimal? = { null },
protected val maxExtractSupplier: () -> Decimal? = maxReceiveSupplier

View File

@ -10,6 +10,7 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider
import net.minecraftforge.common.util.LazyOptional
import net.minecraftforge.energy.IEnergyStorage
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.capability.FlowDirection
import ru.dbotthepony.mc.otm.capability.energy.IMatteryEnergyStorage
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.isMekanismLoaded
@ -70,8 +71,7 @@ private val mtj2Mekanism by DoubleLazy lazy@{
return@lazy lazyOf(Decimal.ONE)
}
class Mekanism2MatteryEnergyWrapper(private val power: IStrictEnergyHandler, private val forgePower: IEnergyStorage? = null) :
IMatteryEnergyStorage {
class Mekanism2MatteryEnergyWrapper(private val power: IStrictEnergyHandler, private val forgePower: IEnergyStorage? = null) : IMatteryEnergyStorage {
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
val action = when (simulate) {
true -> Action.SIMULATE
@ -121,19 +121,8 @@ class Mekanism2MatteryEnergyWrapper(private val power: IStrictEnergyHandler, pri
return sum * mekanism2MtJ
}
override fun canExtract(): Boolean {
if (forgePower != null)
return forgePower.canExtract()
return super.canExtract()
}
override fun canReceive(): Boolean {
if (forgePower != null)
return forgePower.canReceive()
return super.canReceive()
}
override val energyFlow: FlowDirection
get() = FlowDirection.of(output = forgePower?.canExtract() ?: power.extractEnergy(FloatingLong.MAX_VALUE, Action.SIMULATE).greaterThan(FloatingLong.ZERO), input = forgePower?.canReceive() ?: power.insertEnergy(FloatingLong.MAX_VALUE, Action.SIMULATE).greaterThan(FloatingLong.ZERO))
}
class Mattery2MekanismEnergyWrapper(private val power: IMatteryEnergyStorage) : IStrictEnergyHandler {

View File

@ -80,7 +80,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.matterDirection == FlowDirection.BI_DIRECTIONAL) {
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
level += matter.storedMatter
}
}
@ -94,7 +94,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.matterDirection == FlowDirection.BI_DIRECTIONAL) {
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
level += matter.maxStoredMatter
}
}
@ -137,7 +137,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.matterDirection == FlowDirection.BI_DIRECTIONAL) {
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
val value = matter.receiveMatter(howMuch, simulate)
howMuch -= value
received += value
@ -161,7 +161,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
for (node in nodes) {
val matter = node.value.getMatterHandler()
if (matter != null && matter.matterDirection != FlowDirection.OUTPUT) {
if (matter != null && matter.matterFlow != FlowDirection.OUTPUT) {
val value = matter.receiveMatter(howMuch, simulate)
howMuch -= value
received += value

View File

@ -29,14 +29,14 @@ import kotlin.math.roundToInt
open class BatteryItem : Item {
private inner class Power(stack: ItemStack) : EnergyCapacitorItem(stack, this@BatteryItem.capacity, this@BatteryItem.receive, this@BatteryItem.extract, initialBatteryLevel = this@BatteryItem.initialBatteryLevel) {
override fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (isCreative) return howMuch
return super.extractEnergyInner(howMuch, simulate)
return super.extractEnergy(howMuch, simulate)
}
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
if (isCreative) return howMuch
return super.receiveEnergyInner(howMuch, simulate)
return super.receiveEnergy(howMuch, simulate)
}
override val missingPower: Decimal get() {

View File

@ -76,7 +76,7 @@ class MatterCapacitorItem : Item {
return diff
}
override val matterDirection = FlowDirection.BI_DIRECTIONAL
override val matterFlow = FlowDirection.BI_DIRECTIONAL
}
private val _capacity: () -> Decimal

View File

@ -78,6 +78,9 @@ class QuantumBatteryItem : Item {
private val resolver = LazyOptional.of { this }
private val resolverMekanism = if (isMekanismLoaded) LazyOptional.of { Mattery2MekanismEnergyWrapper(this) } else null
override val energyFlow: FlowDirection
get() = FlowDirection.BI_DIRECTIONAL
var data = Data()
override fun <T : Any?> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
@ -225,14 +228,6 @@ class QuantumBatteryItem : Item {
override val missingPower: Decimal
get() = if (isCreative) Decimal.LONG_MAX_VALUE else super.missingPower
override fun canExtract(): Boolean {
return true
}
override fun canReceive(): Boolean {
return true
}
private fun determineQuantumLink() {
if (data.parent == null && isServerThread()) {
val existing = stack.tag?.getInt("link_id")

View File

@ -50,7 +50,7 @@ class PlasmaRifleItem : PlasmaWeaponItem<PlasmaWeaponDataTable>(PlasmaWeaponData
)
if (!player.abilities.instabuild)
energyData(itemStack).extractEnergyInner(ENERGY_PER_SHOT, false)
energyData(itemStack).extractEnergy(ENERGY_PER_SHOT, false)
return true
}

View File

@ -24,11 +24,13 @@ import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.registry.MSoundEvents
import kotlin.reflect.KClass
class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Decimal) :
IMatteryEnergyStorage, ICapabilityProvider, INBTSerializable<CompoundTag> {
class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Decimal) : IMatteryEnergyStorage, ICapabilityProvider, INBTSerializable<CompoundTag> {
private val energyResolver = LazyOptional.of { this }
private var innerBatteryLevel = Decimal.ZERO
override val energyFlow: FlowDirection
get() = FlowDirection.INPUT
var battery: ItemStack = ItemStack.EMPTY
override fun <T : Any> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
@ -52,10 +54,6 @@ class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: De
}
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
return Decimal.ZERO
}
fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
if (!howMuch.isPositive)
return Decimal.ZERO
@ -129,20 +127,28 @@ class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: De
}
}
override fun canExtract(): Boolean {
return false
}
override fun drainBattery(): Boolean {
innerBatteryLevel = Decimal.ZERO
if (!battery.isEmpty) {
battery.getCapability(MatteryCapability.ENERGY).ifPresentK {
return it.drainBattery()
}
}
override fun canReceive(): Boolean {
return true
}
override fun drainBattery() {
innerBatteryLevel = Decimal.ZERO
}
override fun fillBattery() {
override fun fillBattery(): Boolean {
innerBatteryLevel = innerCapacity
if (!battery.isEmpty) {
battery.getCapability(MatteryCapability.ENERGY).ifPresentK {
return it.fillBattery()
}
}
return true
}
override var batteryLevel: Decimal

View File

@ -56,7 +56,7 @@ class AndroidStationMenu @JvmOverloads constructor(
if (p_18942_ != 0 || powerWidget.level < AndroidStationBlockEntity.ENERGY_PER_OPERATION || item.isEmpty)
return ItemStack.EMPTY
(tile as AndroidStationBlockEntity).energy.extractEnergyInner(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
(tile as AndroidStationBlockEntity).energy.extractEnergy(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
return removeItemNoUpdate(p_18942_)
}
@ -73,7 +73,7 @@ class AndroidStationMenu @JvmOverloads constructor(
if (p_18944_ != 0)
return
(tile as AndroidStationBlockEntity).energy.extractEnergyInner(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
(tile as AndroidStationBlockEntity).energy.extractEnergy(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
item = p_18945_
}

View File

@ -48,7 +48,7 @@ open class MatterContainerInputSlot @JvmOverloads constructor(
override fun mayPlace(itemStack: ItemStack): Boolean {
val handler = itemStack.getCapability(MatteryCapability.MATTER).resolve()
if (handler.isEmpty) return false
return super.mayPlace(itemStack) && this.direction.test(handler.get().matterDirection)
return super.mayPlace(itemStack) && this.direction.test(handler.get().matterFlow)
}
}