Redo mattery energy storage
This commit is contained in:
parent
9073ae1b08
commit
b9cb5db9ac
@ -35,8 +35,8 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
get() = MBlocks.ANDROID_STATION.name
|
get() = MBlocks.ANDROID_STATION.name
|
||||||
|
|
||||||
override val energy = object : WorkerEnergyStorage(this@AndroidStationBlockEntity::setChangedLight, ::CAPACITY, ::MAX_IO, { null }) {
|
override val energy = object : WorkerEnergyStorage(this@AndroidStationBlockEntity::setChangedLight, ::CAPACITY, ::MAX_IO, { null }) {
|
||||||
override fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
return super.extractEnergyInner(howMuch, simulate).also {
|
return super.extractEnergy(howMuch, simulate).also {
|
||||||
if (!simulate && this.batteryLevel.isZero) {
|
if (!simulate && this.batteryLevel.isZero) {
|
||||||
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.IDLE) {
|
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != 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_CLIENTS)
|
||||||
@ -45,8 +45,8 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
|
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
return super.receiveEnergyInner(howMuch, simulate).also {
|
return super.receiveEnergy(howMuch, simulate).also {
|
||||||
if (!simulate && it.isPositive) {
|
if (!simulate && it.isPositive) {
|
||||||
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != WorkerState.WORKING) {
|
if (blockState.getValue(WorkerState.SEMI_WORKER_STATE) != 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_CLIENTS)
|
||||||
@ -85,11 +85,11 @@ class AndroidStationBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
val missing = it.androidEnergy.missingPower
|
val missing = it.androidEnergy.missingPower
|
||||||
|
|
||||||
if (missing > Decimal.ZERO) {
|
if (missing > Decimal.ZERO) {
|
||||||
val extract = energy.extractEnergyInner(missing, true)
|
val extract = energy.extractEnergy(missing, true)
|
||||||
|
|
||||||
if (extract > Decimal.ZERO) {
|
if (extract > Decimal.ZERO) {
|
||||||
val received = it.androidEnergy.receiveEnergy(extract, false)
|
val received = it.androidEnergy.receiveEnergy(extract, false)
|
||||||
energy.extractEnergyInner(received, false)
|
energy.extractEnergy(received, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 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 {
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
if (mode == BankMode.RECEIVE)
|
return distributeEnergy(isReceiving = false, howMuch, simulate)
|
||||||
return Decimal.ZERO
|
|
||||||
|
|
||||||
return extractEnergyInner(howMuch, simulate)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDistribution(isReceiving: Boolean): BatteryBankDistribution {
|
fun getDistribution(isReceiving: Boolean): BatteryBankDistribution {
|
||||||
@ -157,18 +150,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
|||||||
return summ
|
return summ
|
||||||
}
|
}
|
||||||
|
|
||||||
fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
|
|
||||||
return distributeEnergy(isReceiving = false, howMuch, simulate)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
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)
|
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 energyReceiver = BatteryBankEnergy(FlowDirection.INPUT)
|
||||||
private val energyExtractor = BatteryBankEnergy(BankMode.EXTRACT)
|
private val energyExtractor = BatteryBankEnergy(FlowDirection.OUTPUT)
|
||||||
private val energy = BatteryBankEnergy(BankMode.BIDIRECTIONAL)
|
private val energy = BatteryBankEnergy(FlowDirection.BI_DIRECTIONAL)
|
||||||
|
|
||||||
private var resolverEnergyReceiver = LazyOptional.of { energyReceiver }
|
private var resolverEnergyReceiver = LazyOptional.of { energyReceiver }
|
||||||
private var resolverEnergyExtractor = LazyOptional.of { energyExtractor }
|
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)
|
val diff = it.receiveEnergy(maxThroughput, true)
|
||||||
|
|
||||||
if (!diff.isZero) {
|
if (!diff.isZero) {
|
||||||
val newExtract = energy.extractEnergyInner(diff, true)
|
val newExtract = energy.extractEnergy(diff, true)
|
||||||
val newReceive = it.receiveEnergy(newExtract, 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)
|
val received = it.receiveEnergy(extracted, false)
|
||||||
|
|
||||||
if (received < extracted) {
|
if (received < extracted) {
|
||||||
energy.receiveEnergyInner(extracted - received, false)
|
energy.receiveEnergy(extracted - received, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,18 +165,18 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
|
|||||||
private var check = true
|
private var check = true
|
||||||
|
|
||||||
private fun workWithPower(it: IEnergyStorage) {
|
private fun workWithPower(it: IEnergyStorage) {
|
||||||
val extracted = energy.extractEnergyInner(THROUGHPUT, true)
|
val extracted = energy.extractEnergy(THROUGHPUT, true)
|
||||||
val received = it.receiveEnergy(extracted, false)
|
val received = it.receiveEnergy(extracted, false)
|
||||||
|
|
||||||
if (!received.isZero) {
|
if (!received.isZero) {
|
||||||
energy.extractEnergyInner(received, false)
|
energy.extractEnergy(received, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun tick() {
|
fun tick() {
|
||||||
if (workTicks > 0) {
|
if (workTicks > 0) {
|
||||||
workTicks--
|
workTicks--
|
||||||
energy.receiveEnergyInner(GENERATION_SPEED, false)
|
energy.receiveEnergy(GENERATION_SPEED, false)
|
||||||
|
|
||||||
if (workTicks == 0) {
|
if (workTicks == 0) {
|
||||||
workTicksTotal = 0
|
workTicksTotal = 0
|
||||||
|
@ -126,11 +126,10 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
tickOnceServer(this::checkSurroundings)
|
tickOnceServer(this::checkSurroundings)
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class EnergyCounterCap(val isInput: Boolean) : IMatteryEnergyStorage {
|
private inner class EnergyCounterCap(isInput: Boolean) : IMatteryEnergyStorage {
|
||||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
override val energyFlow = FlowDirection.input(isInput)
|
||||||
if (isInput)
|
|
||||||
return Decimal.ZERO
|
|
||||||
|
|
||||||
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
if (inputCapability.isPresent) {
|
if (inputCapability.isPresent) {
|
||||||
val it = inputCapability.resolve().get()
|
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 {
|
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
if (!isInput)
|
|
||||||
return Decimal.ZERO
|
|
||||||
|
|
||||||
if (outputCapability.isPresent) {
|
if (outputCapability.isPresent) {
|
||||||
val it = outputCapability.resolve().get()
|
val it = outputCapability.resolve().get()
|
||||||
|
|
||||||
@ -188,7 +184,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
|
|
||||||
override var batteryLevel: Decimal
|
override var batteryLevel: Decimal
|
||||||
get() {
|
get() {
|
||||||
if (isInput) {
|
if (energyFlow.input) {
|
||||||
if (outputCapability.isPresent) {
|
if (outputCapability.isPresent) {
|
||||||
val it = outputCapability.resolve().get()
|
val it = outputCapability.resolve().get()
|
||||||
|
|
||||||
@ -218,7 +214,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
|
|
||||||
override val maxBatteryLevel: Decimal
|
override val maxBatteryLevel: Decimal
|
||||||
get() {
|
get() {
|
||||||
if (isInput) {
|
if (energyFlow.input) {
|
||||||
if (outputCapability.isPresent) {
|
if (outputCapability.isPresent) {
|
||||||
val it = outputCapability.resolve().get()
|
val it = outputCapability.resolve().get()
|
||||||
|
|
||||||
@ -245,7 +241,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
|
|
||||||
override val missingPower: Decimal
|
override val missingPower: Decimal
|
||||||
get() {
|
get() {
|
||||||
if (isInput) {
|
if (energyFlow.input) {
|
||||||
if (outputCapability.isPresent) {
|
if (outputCapability.isPresent) {
|
||||||
val it = outputCapability.resolve().get()
|
val it = outputCapability.resolve().get()
|
||||||
|
|
||||||
@ -269,9 +265,6 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
|||||||
|
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canExtract() = !isInput
|
|
||||||
override fun canReceive() = isInput
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private var resolverInput = LazyOptional.of<IMatteryEnergyStorage> { energyInput }
|
private var resolverInput = LazyOptional.of<IMatteryEnergyStorage> { energyInput }
|
||||||
|
@ -14,6 +14,7 @@ import net.minecraftforge.common.capabilities.Capability
|
|||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.block.IDroppableContainer
|
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.energy.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.canSetBatteryMattery
|
import ru.dbotthepony.mc.otm.capability.canSetBatteryMattery
|
||||||
@ -59,6 +60,12 @@ class EnergyServoBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matte
|
|||||||
})
|
})
|
||||||
|
|
||||||
val energy = object : IMatteryEnergyStorage {
|
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 {
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
return container[SLOT_DISCHARGE].energy?.extractEnergy(howMuch, simulate) ?: Decimal.ZERO
|
return container[SLOT_DISCHARGE].energy?.extractEnergy(howMuch, simulate) ?: Decimal.ZERO
|
||||||
}
|
}
|
||||||
|
@ -32,18 +32,8 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
|
|||||||
val batteryContainer = MatteryContainer(this::setChangedLight, 1)
|
val batteryContainer = MatteryContainer(this::setChangedLight, 1)
|
||||||
|
|
||||||
protected fun batteryChargeLoop() {
|
protected fun batteryChargeLoop() {
|
||||||
var hit = false
|
if (!batteryContainer.any { !it.isEmpty })
|
||||||
|
|
||||||
for (stack in batteryContainer) {
|
|
||||||
if (!stack.isEmpty) {
|
|
||||||
hit = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hit) {
|
|
||||||
return
|
return
|
||||||
}
|
|
||||||
|
|
||||||
var demand = energy.receiveEnergy(energy.missingPower, true)
|
var demand = energy.receiveEnergy(energy.missingPower, true)
|
||||||
if (demand.isZero) return
|
if (demand.isZero) return
|
||||||
@ -51,15 +41,9 @@ abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229
|
|||||||
for (stack in batteryContainer) {
|
for (stack in batteryContainer) {
|
||||||
if (!stack.isEmpty) {
|
if (!stack.isEmpty) {
|
||||||
stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
stack.getCapability(ForgeCapabilities.ENERGY).ifPresentK {
|
||||||
if (it is IMatteryEnergyStorage) {
|
val diff = it.extractEnergy(demand, false)
|
||||||
val diff = it.extractEnergy(demand, false)
|
energy.receiveEnergy(diff, false)
|
||||||
energy.receiveEnergyInner(diff, false)
|
demand -= diff
|
||||||
demand -= diff
|
|
||||||
} else {
|
|
||||||
val diff = it.extractEnergy(demand, false)
|
|
||||||
energy.receiveEnergyInner(diff, false)
|
|
||||||
demand -= diff
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (demand <= Decimal.ZERO)
|
if (demand <= Decimal.ZERO)
|
||||||
|
@ -303,7 +303,7 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
|
|||||||
ticksAdvanced = availableTicks.coerceAtMost(ticksLeft)
|
ticksAdvanced = availableTicks.coerceAtMost(ticksLeft)
|
||||||
} else {
|
} else {
|
||||||
requiredPower = currentJob.powerUsage * ticksLeft.coerceAtMost(availableTicks)
|
requiredPower = currentJob.powerUsage * ticksLeft.coerceAtMost(availableTicks)
|
||||||
extractedPower = energy.extractEnergyInner(requiredPower, true)
|
extractedPower = energy.extractEnergy(requiredPower, true)
|
||||||
ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft).coerceAtMost(availableTicks)
|
ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft).coerceAtMost(availableTicks)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ abstract class MatteryWorkerBlockEntity<JobType : MatteryWorkerBlockEntity.Job>(
|
|||||||
extractedPower = status.newDrainedPower ?: extractedPower
|
extractedPower = status.newDrainedPower ?: extractedPower
|
||||||
|
|
||||||
if (extractedPower != null) {
|
if (extractedPower != null) {
|
||||||
energy.extractEnergyInner(extractedPower, false)
|
energy.extractEnergy(extractedPower, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
continue
|
continue
|
||||||
|
@ -115,7 +115,7 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
})
|
})
|
||||||
|
|
||||||
val matter: MatterStorageImpl = object : MatterStorageImpl(this::setChangedLight, FlowDirection.BI_DIRECTIONAL, ::CAPACITY) {
|
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
|
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) {
|
if (!itemStack.isEmpty) {
|
||||||
val cap = itemStack.getCapability(MatteryCapability.MATTER).orNull() ?: continue
|
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) {
|
if (this.isBottling && cap.missingMatter > Decimal.ZERO || !this.isBottling && cap.storedMatter > Decimal.ZERO) {
|
||||||
work_stack = itemStack
|
work_stack = itemStack
|
||||||
capability = cap
|
capability = cap
|
||||||
@ -280,13 +280,13 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (matter.storedMatter > Decimal.ZERO) {
|
if (matter.storedMatter > Decimal.ZERO) {
|
||||||
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
|
val energyExtracted = energy.extractEnergy(ENERGY_CONSUMPTION, true)
|
||||||
|
|
||||||
if (!energyExtracted.isZero) {
|
if (!energyExtracted.isZero) {
|
||||||
val matter = capability.receiveMatter(MATTER_EXCHANGE_RATE.coerceAtMost(matter.storedMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
|
val matter = capability.receiveMatter(MATTER_EXCHANGE_RATE.coerceAtMost(matter.storedMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
|
||||||
|
|
||||||
if (!matter.isZero) {
|
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)
|
capability.receiveMatter(matter, false)
|
||||||
this.matter.extractMatterInner(matter, false)
|
this.matter.extractMatterInner(matter, false)
|
||||||
@ -304,13 +304,13 @@ class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val energyExtracted = energy.extractEnergyInner(ENERGY_CONSUMPTION, true)
|
val energyExtracted = energy.extractEnergy(ENERGY_CONSUMPTION, true)
|
||||||
|
|
||||||
if (!energyExtracted.isZero) {
|
if (!energyExtracted.isZero) {
|
||||||
val matter = capability.extractMatter(MATTER_EXCHANGE_RATE.coerceAtMost(matter.missingMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
|
val matter = capability.extractMatter(MATTER_EXCHANGE_RATE.coerceAtMost(matter.missingMatter) * energyExtracted / ENERGY_CONSUMPTION, true)
|
||||||
|
|
||||||
if (!matter.isZero) {
|
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)
|
capability.extractMatter(matter, false)
|
||||||
this.matter.receiveMatterInner(matter, false)
|
this.matter.receiveMatterInner(matter, false)
|
||||||
|
@ -128,7 +128,7 @@ class MatterCapacitorBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState)
|
|||||||
return summ
|
return summ
|
||||||
}
|
}
|
||||||
|
|
||||||
override val matterDirection: FlowDirection
|
override val matterFlow: FlowDirection
|
||||||
get() = FlowDirection.BI_DIRECTIONAL
|
get() = FlowDirection.BI_DIRECTIONAL
|
||||||
|
|
||||||
private var resolver = LazyOptional.of { this }
|
private var resolver = LazyOptional.of { this }
|
||||||
|
@ -484,7 +484,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
return stack
|
return stack
|
||||||
|
|
||||||
val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * stack.count
|
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 leftover: ItemStackWrapper = stack.copy()
|
||||||
var additional: BigInteger = BigInteger.ZERO
|
var additional: BigInteger = BigInteger.ZERO
|
||||||
@ -499,7 +499,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
leftover = ItemStackWrapper(parent.insertItem(slot, leftover.stack, simulate))
|
leftover = ItemStackWrapper(parent.insertItem(slot, leftover.stack, simulate))
|
||||||
|
|
||||||
if (oldCount != leftover.count && !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) {
|
if (scanned.size <= slot) {
|
||||||
sizeScan()
|
sizeScan()
|
||||||
@ -529,7 +529,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
return ItemStackWrapper.EMPTY
|
return ItemStackWrapper.EMPTY
|
||||||
|
|
||||||
val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * amount
|
val maxPossibleDemand = ITEM_STORAGE.energyPerOperation * amount
|
||||||
val maxExtractEnergy = energy.extractEnergyInner(maxPossibleDemand, true)
|
val maxExtractEnergy = energy.extractEnergy(maxPossibleDemand, true)
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
var amount = amount
|
var amount = amount
|
||||||
@ -555,7 +555,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
totalExtracted += extracted.count
|
totalExtracted += extracted.count
|
||||||
|
|
||||||
if (extracted.count != 0 && !simulate) {
|
if (extracted.count != 0 && !simulate) {
|
||||||
energy.extractEnergyInner(ITEM_STORAGE.energyPerOperation * extracted.count, false)
|
energy.extractEnergy(ITEM_STORAGE.energyPerOperation * extracted.count, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (totalExtracted >= intAmount) {
|
if (totalExtracted >= intAmount) {
|
||||||
|
@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.*
|
import ru.dbotthepony.mc.otm.capability.*
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
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.container.ItemFilter
|
||||||
import ru.dbotthepony.mc.otm.core.*
|
import ru.dbotthepony.mc.otm.core.*
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
@ -187,7 +188,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
return stack
|
return stack
|
||||||
|
|
||||||
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: 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)
|
if (maxMove == BigInteger.ZERO)
|
||||||
return stack
|
return stack
|
||||||
@ -197,7 +198,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
if (simulate)
|
if (simulate)
|
||||||
return leftover.stack
|
return leftover.stack
|
||||||
|
|
||||||
energy.extractStepInner(ITEM_STORAGE.energyPerOperation, maxMove - leftover.count, false)
|
energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, maxMove - leftover.count, false)
|
||||||
return leftover.stack
|
return leftover.stack
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +230,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
lastSlot = 0
|
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)
|
var extracted = resolved.extractItem(lastSlot, maxMove, true)
|
||||||
|
|
||||||
if (extracted.isEmpty || !filter.match(extracted)) {
|
if (extracted.isEmpty || !filter.match(extracted)) {
|
||||||
@ -239,7 +240,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
|
|||||||
|
|
||||||
if (leftOver.count.toInt() != extracted.count) {
|
if (leftOver.count.toInt() != extracted.count) {
|
||||||
extracted = resolved.extractItem(lastSlot, extracted.count - leftOver.count.toInt(), false)
|
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)
|
items.insertStack(ItemStackWrapper(extracted), false)
|
||||||
} else {
|
} else {
|
||||||
nextTick += INTERVAL * 4
|
nextTick += INTERVAL * 4
|
||||||
@ -353,7 +354,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var exportAmount = energy.extractStepInner(ITEM_STORAGE.energyPerOperation, exportAmountA, true)
|
var exportAmount = energy.extractEnergyExact(ITEM_STORAGE.energyPerOperation, exportAmountA, true).toIntSafe()
|
||||||
|
|
||||||
if (exportAmount == 0) {
|
if (exportAmount == 0) {
|
||||||
break
|
break
|
||||||
@ -365,7 +366,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
hit = true
|
hit = true
|
||||||
exportAmount = items.extractStack(stack.first, (exportAmount - leftover.count).toBigInteger(), false).count.toInt()
|
exportAmount = items.extractStack(stack.first, (exportAmount - leftover.count).toBigInteger(), false).count.toInt()
|
||||||
resolved.insertItem(lastSlot, stack.second.stack.also { it.count = exportAmount }, false)
|
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
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
|
|||||||
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage
|
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.core.Decimal
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
|
||||||
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
|
||||||
@ -103,13 +104,13 @@ class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState
|
|||||||
return
|
return
|
||||||
} else if (demand < available) {
|
} else if (demand < available) {
|
||||||
for (demanding in graph.powerDemandingNodes) {
|
for (demanding in graph.powerDemandingNodes) {
|
||||||
powerPassed += energy.transferInner(demanding, available, false)
|
powerPassed += energy.transferChecked(demanding, available, false)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val forEach = available / i
|
val forEach = available / i
|
||||||
|
|
||||||
for (demanding in graph.powerDemandingNodes) {
|
for (demanding in graph.powerDemandingNodes) {
|
||||||
powerPassed += energy.transferInner(demanding, forEach, false)
|
powerPassed += energy.transferChecked(demanding, forEach, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,12 @@ import java.util.stream.Stream
|
|||||||
|
|
||||||
val ICapabilityProvider.matteryPlayer: MatteryPlayerCapability? get() = getCapability(MatteryCapability.MATTERY_PLAYER).orNull()
|
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)
|
if (this is IMatteryEnergyStorage)
|
||||||
return receiveEnergy(amount, simulate)
|
return receiveEnergyChecked(amount, simulate)
|
||||||
|
|
||||||
if (!amount.isPositive)
|
if (!amount.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
@ -43,9 +46,12 @@ fun IEnergyStorage.receiveEnergy(amount: Decimal, simulate: Boolean): Decimal {
|
|||||||
return Decimal.valueOf(receiveEnergy(amount.toInt(), simulate))
|
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)
|
if (this is IMatteryEnergyStorage)
|
||||||
return extractEnergy(amount, simulate)
|
return extractEnergyChecked(amount, simulate)
|
||||||
|
|
||||||
if (!amount.isPositive)
|
if (!amount.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
@ -4,6 +4,21 @@ import java.util.function.Predicate
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents possible flow direction, both for matter and for energy
|
* 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> {
|
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 {
|
override fun test(t: FlowDirection): Boolean {
|
||||||
return t === this || (!input || t.input) && (!output || t.output)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import net.minecraft.world.entity.player.Player
|
|||||||
import net.minecraft.world.item.ItemStack
|
import net.minecraft.world.item.ItemStack
|
||||||
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
import net.minecraftforge.common.capabilities.ForgeCapabilities
|
||||||
import net.minecraftforge.common.util.INBTSerializable
|
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.extractEnergy
|
||||||
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||||
import ru.dbotthepony.mc.otm.core.Decimal
|
import ru.dbotthepony.mc.otm.core.Decimal
|
||||||
@ -23,6 +24,9 @@ class AndroidPowerSource(
|
|||||||
initialCharge: Decimal,
|
initialCharge: Decimal,
|
||||||
maxCharge: Decimal
|
maxCharge: Decimal
|
||||||
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
) : IMatteryEnergyStorage, INBTSerializable<CompoundTag> {
|
||||||
|
override val energyFlow: FlowDirection
|
||||||
|
get() = FlowDirection.INPUT
|
||||||
|
|
||||||
private var battery by synchronizer.fraction(initialCharge, name = "android battery")
|
private var battery by synchronizer.fraction(initialCharge, name = "android battery")
|
||||||
private var maxBattery by synchronizer.fraction(maxCharge, name = "android max battery")
|
private var maxBattery by synchronizer.fraction(maxCharge, name = "android max battery")
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ import ru.dbotthepony.mc.otm.core.set
|
|||||||
|
|
||||||
sealed class BlockEnergyStorageImpl(
|
sealed class BlockEnergyStorageImpl(
|
||||||
protected val listener: () -> Unit,
|
protected val listener: () -> Unit,
|
||||||
final override val direction: FlowDirection,
|
final override val energyFlow: FlowDirection,
|
||||||
private val maxBatteryLevelProvider: () -> Decimal,
|
private val maxBatteryLevelProvider: () -> Decimal,
|
||||||
private val maxInputProvider: () -> Decimal?,
|
private val maxInputProvider: () -> Decimal?,
|
||||||
private val maxOutputProvider: () -> Decimal?,
|
private val maxOutputProvider: () -> Decimal?,
|
||||||
@ -78,20 +78,6 @@ sealed class BlockEnergyStorageImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
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)
|
if (!howMuch.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
|
||||||
@ -116,7 +102,7 @@ sealed class BlockEnergyStorageImpl(
|
|||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
|
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
if (!howMuch.isPositive)
|
if (!howMuch.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
|
||||||
@ -141,14 +127,6 @@ sealed class BlockEnergyStorageImpl(
|
|||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canExtract(): Boolean {
|
|
||||||
return direction != FlowDirection.INPUT
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canReceive(): Boolean {
|
|
||||||
return direction != FlowDirection.OUTPUT
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun serializeNBT(): CompoundTag {
|
override fun serializeNBT(): CompoundTag {
|
||||||
val tag = CompoundTag()
|
val tag = CompoundTag()
|
||||||
tag[ENERGY_STORED_KEY] = batteryLevel.serializeNBT()
|
tag[ENERGY_STORED_KEY] = batteryLevel.serializeNBT()
|
||||||
|
@ -12,77 +12,6 @@ import java.math.BigInteger
|
|||||||
sealed interface IEnergyStorageImpl {
|
sealed interface IEnergyStorageImpl {
|
||||||
val maxInput: Decimal?
|
val maxInput: Decimal?
|
||||||
val maxOutput: 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>) {
|
internal fun batteryLevel(it: IEnergyStorage, tooltips: MutableList<Component>) {
|
||||||
@ -103,7 +32,7 @@ internal fun batteryLevel(it: IMatteryEnergyStorage, tooltips: MutableList<Compo
|
|||||||
).withStyle(ChatFormatting.GRAY))
|
).withStyle(ChatFormatting.GRAY))
|
||||||
|
|
||||||
if (it is IEnergyStorageImpl) {
|
if (it is IEnergyStorageImpl) {
|
||||||
when (it.direction) {
|
when (it.energyFlow) {
|
||||||
FlowDirection.INPUT -> {
|
FlowDirection.INPUT -> {
|
||||||
if (it.maxInput != null) {
|
if (it.maxInput != null) {
|
||||||
tooltips.add(
|
tooltips.add(
|
||||||
|
@ -1,29 +1,99 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.energy
|
package ru.dbotthepony.mc.otm.capability.energy
|
||||||
|
|
||||||
import net.minecraftforge.energy.IEnergyStorage
|
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.Decimal
|
||||||
import ru.dbotthepony.mc.otm.core.RGBAColor
|
import ru.dbotthepony.mc.otm.core.RGBAColor
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import kotlin.math.roundToInt
|
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 {
|
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
|
* @return energy extracted
|
||||||
*/
|
*/
|
||||||
fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal
|
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
|
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
|
* 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
|
* Empties power of this energy storage
|
||||||
*
|
*
|
||||||
* @throws [UnsupportedOperationException]
|
|
||||||
* @see batteryLevel
|
* @see batteryLevel
|
||||||
|
* @return whenever operation was successful
|
||||||
*/
|
*/
|
||||||
fun drainBattery() {
|
fun drainBattery(): Boolean {
|
||||||
batteryLevel = Decimal.ZERO
|
try {
|
||||||
|
batteryLevel = Decimal.ZERO
|
||||||
|
} catch(err: UnsupportedOperationException) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fully fills power in this energy storage
|
* Fully fills power in this energy storage
|
||||||
*
|
*
|
||||||
* @throws [UnsupportedOperationException]
|
|
||||||
* @see batteryLevel
|
* @see batteryLevel
|
||||||
|
* @return whenever operation was successful
|
||||||
*/
|
*/
|
||||||
fun fillBattery() {
|
fun fillBattery(): Boolean {
|
||||||
batteryLevel = maxBatteryLevel
|
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
|
// -------- Forge Energy stuff
|
||||||
|
|
||||||
override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
|
override fun receiveEnergy(maxReceive: Int, simulate: Boolean): Int {
|
||||||
|
// follow contract of IEnergyStorage
|
||||||
|
if (!energyFlow.input)
|
||||||
|
return 0
|
||||||
|
|
||||||
val received = receiveEnergy(Decimal(maxReceive), true).toInt()
|
val received = receiveEnergy(Decimal(maxReceive), true).toInt()
|
||||||
|
|
||||||
// Receiving only a fraction
|
// Receiving only a fraction
|
||||||
@ -85,6 +176,10 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int {
|
override fun extractEnergy(maxReceive: Int, simulate: Boolean): Int {
|
||||||
|
// follow contract of IEnergyStorage
|
||||||
|
if (energyFlow.output)
|
||||||
|
return 0
|
||||||
|
|
||||||
val extracted = extractEnergy(Decimal(maxReceive), true).toInt()
|
val extracted = extractEnergy(Decimal(maxReceive), true).toInt()
|
||||||
|
|
||||||
// Extracting only a fraction
|
// Extracting only a fraction
|
||||||
@ -103,14 +198,19 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun canExtract(): Boolean {
|
override fun canExtract(): Boolean {
|
||||||
return extractEnergy(Decimal.ONE, true) > Decimal.ZERO
|
return energyFlow.output
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canReceive(): Boolean {
|
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 {
|
fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, simulate: Boolean): Boolean {
|
||||||
if (extractEnergy(howMuch, true) == howMuch) {
|
if (extractEnergy(howMuch, true) == howMuch) {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
@ -123,6 +223,11 @@ fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, simulate: Boolean
|
|||||||
return false
|
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 {
|
fun IMatteryEnergyStorage.receiveEnergyExact(howMuch: Decimal, simulate: Boolean): Boolean {
|
||||||
if (receiveEnergy(howMuch, true) == howMuch) {
|
if (receiveEnergy(howMuch, true) == howMuch) {
|
||||||
if (!simulate) {
|
if (!simulate) {
|
||||||
@ -135,23 +240,56 @@ fun IMatteryEnergyStorage.receiveEnergyExact(howMuch: Decimal, simulate: Boolean
|
|||||||
return false
|
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 {
|
fun IMatteryEnergyStorage.extractEnergyExact(howMuch: Decimal, times: Int, simulate: Boolean): Int {
|
||||||
if (times == 0)
|
if (times == 0)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
require(times >= 0) { "times $times >= 0" }
|
require(times >= 0) { "times $times >= 0" }
|
||||||
require(howMuch >= Decimal.ZERO) { "howMuch $howMuch >= 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 {
|
fun IMatteryEnergyStorage.extractEnergy(howMuch: Long, simulate: Boolean): Decimal {
|
||||||
return extractEnergy(Decimal(howMuch), simulate)
|
return extractEnergy(Decimal(howMuch), simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see [IMatteryEnergyStorage.receiveEnergy]
|
||||||
|
*/
|
||||||
fun IMatteryEnergyStorage.receiveEnergy(howMuch: Long, simulate: Boolean): Decimal {
|
fun IMatteryEnergyStorage.receiveEnergy(howMuch: Long, simulate: Boolean): Decimal {
|
||||||
return receiveEnergy(Decimal(howMuch), simulate)
|
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 {
|
fun IMatteryEnergyStorage.transfer(other: IMatteryEnergyStorage, amount: Decimal, simulate: Boolean): Decimal {
|
||||||
if (!amount.isPositive)
|
if (!amount.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
@ -160,25 +298,28 @@ fun IMatteryEnergyStorage.transfer(other: IMatteryEnergyStorage, amount: Decimal
|
|||||||
val received = other.receiveEnergy(extracted, simulate)
|
val received = other.receiveEnergy(extracted, simulate)
|
||||||
|
|
||||||
if (!simulate)
|
if (!simulate)
|
||||||
extractEnergy(received, false)
|
return extractEnergy(received, false)
|
||||||
|
|
||||||
return received
|
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 {
|
val extracted = extractEnergy(amount, true)
|
||||||
return (extractEnergy(base * multiplier, simulate) / base).toInt()
|
val received = other.receiveEnergyChecked(extracted, simulate)
|
||||||
}
|
|
||||||
|
|
||||||
fun IMatteryEnergyStorage.extractStepOuterBi(base: Decimal, multiplier: Int, simulate: Boolean): BigInteger {
|
if (!simulate)
|
||||||
return (extractEnergy(base * multiplier, simulate) / base).whole
|
return extractEnergy(received, false)
|
||||||
}
|
|
||||||
|
|
||||||
fun IMatteryEnergyStorage.extractStepOuterBi(base: Decimal, multiplier: BigInteger, simulate: Boolean): BigInteger {
|
return received
|
||||||
return (extractEnergy(base * multiplier, simulate) / base).whole
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IMatteryEnergyStorage.getBarWidth(): Int {
|
fun IMatteryEnergyStorage.getBarWidth(): Int {
|
||||||
|
@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.core.set
|
|||||||
import ru.dbotthepony.mc.otm.core.tagNotNull
|
import ru.dbotthepony.mc.otm.core.tagNotNull
|
||||||
|
|
||||||
sealed class ItemEnergyStorageImpl(
|
sealed class ItemEnergyStorageImpl(
|
||||||
final override val direction: FlowDirection,
|
final override val energyFlow: FlowDirection,
|
||||||
protected val itemStack: ItemStack,
|
protected val itemStack: ItemStack,
|
||||||
maxBatteryLevel: Decimal,
|
maxBatteryLevel: Decimal,
|
||||||
maxInput: Decimal?,
|
maxInput: Decimal?,
|
||||||
@ -56,20 +56,6 @@ sealed class ItemEnergyStorageImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
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)
|
if (!howMuch.isPositive || itemStack.count != 1)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
|
||||||
@ -96,7 +82,7 @@ sealed class ItemEnergyStorageImpl(
|
|||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun receiveEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
|
override fun receiveEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
if (!howMuch.isPositive || itemStack.count != 1)
|
if (!howMuch.isPositive || itemStack.count != 1)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
|
||||||
@ -123,14 +109,6 @@ sealed class ItemEnergyStorageImpl(
|
|||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canExtract(): Boolean {
|
|
||||||
return direction != FlowDirection.INPUT
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canReceive(): Boolean {
|
|
||||||
return direction != FlowDirection.OUTPUT
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val ENERGY_KEY = "energy"
|
const val ENERGY_KEY = "energy"
|
||||||
|
|
||||||
|
@ -81,13 +81,13 @@ interface IMatterStorage {
|
|||||||
/**
|
/**
|
||||||
* Which direction does matter flows
|
* Which direction does matter flows
|
||||||
*/
|
*/
|
||||||
val matterDirection: FlowDirection
|
val matterFlow: FlowDirection
|
||||||
}
|
}
|
||||||
|
|
||||||
inline val IMatterStorage.canExtractMatter: Boolean
|
inline val IMatterStorage.canExtractMatter: Boolean
|
||||||
get() = matterDirection.output
|
get() = matterFlow.output
|
||||||
inline val IMatterStorage.canReceiveMatter: Boolean
|
inline val IMatterStorage.canReceiveMatter: Boolean
|
||||||
get() = matterDirection.input
|
get() = matterFlow.input
|
||||||
|
|
||||||
fun IMatterStorage.getBarWidth(): Int {
|
fun IMatterStorage.getBarWidth(): Int {
|
||||||
return ((storedMatter / maxStoredMatter).toFloat().coerceAtLeast(0f).coerceAtMost(1f) * 13f).roundToInt()
|
return ((storedMatter / maxStoredMatter).toFloat().coerceAtLeast(0f).coerceAtMost(1f) * 13f).roundToInt()
|
||||||
|
@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.core.set
|
|||||||
|
|
||||||
open class MatterStorageImpl @JvmOverloads constructor(
|
open class MatterStorageImpl @JvmOverloads constructor(
|
||||||
protected val listener: Runnable?,
|
protected val listener: Runnable?,
|
||||||
override val matterDirection: FlowDirection,
|
override val matterFlow: FlowDirection,
|
||||||
protected val maxStoredMatterSupplier: () -> Decimal,
|
protected val maxStoredMatterSupplier: () -> Decimal,
|
||||||
protected val maxReceiveSupplier: () -> Decimal? = { null },
|
protected val maxReceiveSupplier: () -> Decimal? = { null },
|
||||||
protected val maxExtractSupplier: () -> Decimal? = maxReceiveSupplier
|
protected val maxExtractSupplier: () -> Decimal? = maxReceiveSupplier
|
||||||
|
@ -10,6 +10,7 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider
|
|||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import net.minecraftforge.energy.IEnergyStorage
|
import net.minecraftforge.energy.IEnergyStorage
|
||||||
import org.apache.logging.log4j.LogManager
|
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.energy.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||||
import ru.dbotthepony.mc.otm.capability.isMekanismLoaded
|
import ru.dbotthepony.mc.otm.capability.isMekanismLoaded
|
||||||
@ -70,8 +71,7 @@ private val mtj2Mekanism by DoubleLazy lazy@{
|
|||||||
return@lazy lazyOf(Decimal.ONE)
|
return@lazy lazyOf(Decimal.ONE)
|
||||||
}
|
}
|
||||||
|
|
||||||
class Mekanism2MatteryEnergyWrapper(private val power: IStrictEnergyHandler, private val forgePower: IEnergyStorage? = null) :
|
class Mekanism2MatteryEnergyWrapper(private val power: IStrictEnergyHandler, private val forgePower: IEnergyStorage? = null) : IMatteryEnergyStorage {
|
||||||
IMatteryEnergyStorage {
|
|
||||||
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
val action = when (simulate) {
|
val action = when (simulate) {
|
||||||
true -> Action.SIMULATE
|
true -> Action.SIMULATE
|
||||||
@ -121,19 +121,8 @@ class Mekanism2MatteryEnergyWrapper(private val power: IStrictEnergyHandler, pri
|
|||||||
return sum * mekanism2MtJ
|
return sum * mekanism2MtJ
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canExtract(): Boolean {
|
override val energyFlow: FlowDirection
|
||||||
if (forgePower != null)
|
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))
|
||||||
return forgePower.canExtract()
|
|
||||||
|
|
||||||
return super.canExtract()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun canReceive(): Boolean {
|
|
||||||
if (forgePower != null)
|
|
||||||
return forgePower.canReceive()
|
|
||||||
|
|
||||||
return super.canReceive()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Mattery2MekanismEnergyWrapper(private val power: IMatteryEnergyStorage) : IStrictEnergyHandler {
|
class Mattery2MekanismEnergyWrapper(private val power: IMatteryEnergyStorage) : IStrictEnergyHandler {
|
||||||
|
@ -80,7 +80,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null && matter.matterDirection == FlowDirection.BI_DIRECTIONAL) {
|
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
||||||
level += matter.storedMatter
|
level += matter.storedMatter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +94,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
val matter = node.value.getMatterHandler()
|
||||||
|
|
||||||
if (matter != null && matter.matterDirection == FlowDirection.BI_DIRECTIONAL) {
|
if (matter != null && matter.matterFlow == FlowDirection.BI_DIRECTIONAL) {
|
||||||
level += matter.maxStoredMatter
|
level += matter.maxStoredMatter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,7 +137,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
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)
|
val value = matter.receiveMatter(howMuch, simulate)
|
||||||
howMuch -= value
|
howMuch -= value
|
||||||
received += value
|
received += value
|
||||||
@ -161,7 +161,7 @@ class MatterNetworkGraph : Abstract6Graph<IMatterGraphNode>(), IMatterGraphListe
|
|||||||
for (node in nodes) {
|
for (node in nodes) {
|
||||||
val matter = node.value.getMatterHandler()
|
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)
|
val value = matter.receiveMatter(howMuch, simulate)
|
||||||
howMuch -= value
|
howMuch -= value
|
||||||
received += value
|
received += value
|
||||||
|
@ -29,14 +29,14 @@ import kotlin.math.roundToInt
|
|||||||
|
|
||||||
open class BatteryItem : Item {
|
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) {
|
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
|
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
|
if (isCreative) return howMuch
|
||||||
return super.receiveEnergyInner(howMuch, simulate)
|
return super.receiveEnergy(howMuch, simulate)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val missingPower: Decimal get() {
|
override val missingPower: Decimal get() {
|
||||||
|
@ -76,7 +76,7 @@ class MatterCapacitorItem : Item {
|
|||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
override val matterDirection = FlowDirection.BI_DIRECTIONAL
|
override val matterFlow = FlowDirection.BI_DIRECTIONAL
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _capacity: () -> Decimal
|
private val _capacity: () -> Decimal
|
||||||
|
@ -78,6 +78,9 @@ class QuantumBatteryItem : Item {
|
|||||||
private val resolver = LazyOptional.of { this }
|
private val resolver = LazyOptional.of { this }
|
||||||
private val resolverMekanism = if (isMekanismLoaded) LazyOptional.of { Mattery2MekanismEnergyWrapper(this) } else null
|
private val resolverMekanism = if (isMekanismLoaded) LazyOptional.of { Mattery2MekanismEnergyWrapper(this) } else null
|
||||||
|
|
||||||
|
override val energyFlow: FlowDirection
|
||||||
|
get() = FlowDirection.BI_DIRECTIONAL
|
||||||
|
|
||||||
var data = Data()
|
var data = Data()
|
||||||
|
|
||||||
override fun <T : Any?> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
override fun <T : Any?> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
||||||
@ -225,14 +228,6 @@ class QuantumBatteryItem : Item {
|
|||||||
override val missingPower: Decimal
|
override val missingPower: Decimal
|
||||||
get() = if (isCreative) Decimal.LONG_MAX_VALUE else super.missingPower
|
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() {
|
private fun determineQuantumLink() {
|
||||||
if (data.parent == null && isServerThread()) {
|
if (data.parent == null && isServerThread()) {
|
||||||
val existing = stack.tag?.getInt("link_id")
|
val existing = stack.tag?.getInt("link_id")
|
||||||
|
@ -50,7 +50,7 @@ class PlasmaRifleItem : PlasmaWeaponItem<PlasmaWeaponDataTable>(PlasmaWeaponData
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (!player.abilities.instabuild)
|
if (!player.abilities.instabuild)
|
||||||
energyData(itemStack).extractEnergyInner(ENERGY_PER_SHOT, false)
|
energyData(itemStack).extractEnergy(ENERGY_PER_SHOT, false)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -24,11 +24,13 @@ import ru.dbotthepony.mc.otm.core.*
|
|||||||
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
import ru.dbotthepony.mc.otm.registry.MSoundEvents
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Decimal) :
|
class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: Decimal) : IMatteryEnergyStorage, ICapabilityProvider, INBTSerializable<CompoundTag> {
|
||||||
IMatteryEnergyStorage, ICapabilityProvider, INBTSerializable<CompoundTag> {
|
|
||||||
private val energyResolver = LazyOptional.of { this }
|
private val energyResolver = LazyOptional.of { this }
|
||||||
private var innerBatteryLevel = Decimal.ZERO
|
private var innerBatteryLevel = Decimal.ZERO
|
||||||
|
|
||||||
|
override val energyFlow: FlowDirection
|
||||||
|
get() = FlowDirection.INPUT
|
||||||
|
|
||||||
var battery: ItemStack = ItemStack.EMPTY
|
var battery: ItemStack = ItemStack.EMPTY
|
||||||
|
|
||||||
override fun <T : Any> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
|
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 {
|
override fun extractEnergy(howMuch: Decimal, simulate: Boolean): Decimal {
|
||||||
return Decimal.ZERO
|
|
||||||
}
|
|
||||||
|
|
||||||
fun extractEnergyInner(howMuch: Decimal, simulate: Boolean): Decimal {
|
|
||||||
if (!howMuch.isPositive)
|
if (!howMuch.isPositive)
|
||||||
return Decimal.ZERO
|
return Decimal.ZERO
|
||||||
|
|
||||||
@ -129,20 +127,28 @@ class PlasmaWeaponEnergy(val itemStack: ItemStack, private val innerCapacity: De
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun canExtract(): Boolean {
|
override fun drainBattery(): Boolean {
|
||||||
return false
|
innerBatteryLevel = Decimal.ZERO
|
||||||
}
|
|
||||||
|
if (!battery.isEmpty) {
|
||||||
|
battery.getCapability(MatteryCapability.ENERGY).ifPresentK {
|
||||||
|
return it.drainBattery()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun canReceive(): Boolean {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun drainBattery() {
|
override fun fillBattery(): Boolean {
|
||||||
innerBatteryLevel = Decimal.ZERO
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun fillBattery() {
|
|
||||||
innerBatteryLevel = innerCapacity
|
innerBatteryLevel = innerCapacity
|
||||||
|
|
||||||
|
if (!battery.isEmpty) {
|
||||||
|
battery.getCapability(MatteryCapability.ENERGY).ifPresentK {
|
||||||
|
return it.fillBattery()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override var batteryLevel: Decimal
|
override var batteryLevel: Decimal
|
||||||
|
@ -56,7 +56,7 @@ class AndroidStationMenu @JvmOverloads constructor(
|
|||||||
if (p_18942_ != 0 || powerWidget.level < AndroidStationBlockEntity.ENERGY_PER_OPERATION || item.isEmpty)
|
if (p_18942_ != 0 || powerWidget.level < AndroidStationBlockEntity.ENERGY_PER_OPERATION || item.isEmpty)
|
||||||
return ItemStack.EMPTY
|
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_)
|
return removeItemNoUpdate(p_18942_)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ class AndroidStationMenu @JvmOverloads constructor(
|
|||||||
if (p_18944_ != 0)
|
if (p_18944_ != 0)
|
||||||
return
|
return
|
||||||
|
|
||||||
(tile as AndroidStationBlockEntity).energy.extractEnergyInner(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
|
(tile as AndroidStationBlockEntity).energy.extractEnergy(AndroidStationBlockEntity.ENERGY_PER_OPERATION, false)
|
||||||
item = p_18945_
|
item = p_18945_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ open class MatterContainerInputSlot @JvmOverloads constructor(
|
|||||||
override fun mayPlace(itemStack: ItemStack): Boolean {
|
override fun mayPlace(itemStack: ItemStack): Boolean {
|
||||||
val handler = itemStack.getCapability(MatteryCapability.MATTER).resolve()
|
val handler = itemStack.getCapability(MatteryCapability.MATTER).resolve()
|
||||||
if (handler.isEmpty) return false
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user