Initial direct Mekanism energy support
This commit is contained in:
parent
ddf2c178e6
commit
98c91b01b0
@ -96,6 +96,9 @@ dependencies {
|
||||
implementation(fg.deobf(create("mcjty.theoneprobe:theoneprobe:${mc_version_weak}-${the_one_probe_version}", closureOf<Any> {
|
||||
(this as ExternalModuleDependency).isTransitive = false
|
||||
} as Closure<Any>)))
|
||||
|
||||
//compileOnly(fg.deobf("blank:Mekanism-1.18.1:10.1.2.homebaked-api"))
|
||||
implementation(fg.deobf("blank:Mekanism-1.18.1:10.1.2.homebaked-all"))
|
||||
}
|
||||
|
||||
configurations {
|
||||
@ -177,9 +180,9 @@ repositories {
|
||||
}
|
||||
|
||||
// If you have mod jar dependencies in ./libs, you can declare them as a repository like so:
|
||||
//flatDir {
|
||||
// dir "libs"
|
||||
//}
|
||||
flatDir {
|
||||
dir("libs")
|
||||
}
|
||||
}
|
||||
|
||||
// Example configuration to allow publishing using the maven-publish plugin
|
||||
|
@ -10,9 +10,9 @@ mod_version=0.1
|
||||
mc_version=1.18.1
|
||||
mc_version_weak=1.18
|
||||
forge_gradle_version=5.1.27
|
||||
forge_version=39.0.64
|
||||
forge_version=39.0.85
|
||||
|
||||
jei_version=9.1.1.48
|
||||
jei_version=9.4.1.106
|
||||
jupiter_version=5.8.2
|
||||
the_one_probe_version=5.0.1-5
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package ru.dbotthepony.mc.otm.capability;
|
||||
|
||||
import mekanism.api.energy.IStrictEnergyHandler;
|
||||
import net.minecraftforge.common.capabilities.*;
|
||||
import ru.dbotthepony.mc.otm.capability.android.IAndroidCapability;
|
||||
import ru.dbotthepony.mc.otm.capability.drive.IMatteryDrive;
|
||||
@ -19,6 +20,8 @@ public class MatteryCapability {
|
||||
public static final Capability<IMatteryDrive> DRIVE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||
public static final Capability<IStorageGraphNode> STORAGE_NODE = CapabilityManager.get(new CapabilityToken<>() {});
|
||||
|
||||
public static final Capability<IStrictEnergyHandler> MEKANISM_ENERGY = CapabilityManager.get(new CapabilityToken<>() {});
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public static void register(final RegisterCapabilitiesEvent event) {
|
||||
event.register(IMatteryEnergyStorage.class);
|
||||
|
@ -179,11 +179,11 @@ public class FormattingHelper {
|
||||
new ImpreciseFraction("0.001"), // "otm.suffix.milli": "m%s",
|
||||
new ImpreciseFraction("0.000001"), // "otm.suffix.micro": "μ%s",
|
||||
new ImpreciseFraction("0.000000001"), // "otm.suffix.nano": "n%s",
|
||||
new ImpreciseFraction("0.000000000001"), // "otm.suffix.pico": "p%s",
|
||||
new ImpreciseFraction("0.000000000000001"), // "otm.suffix.femto": "f%s",
|
||||
new ImpreciseFraction("0.000000000000000001"), // "otm.suffix.atto": "a%s",
|
||||
new ImpreciseFraction("0.000000000000000000001"), // "otm.suffix.zepto": "z%s",
|
||||
new ImpreciseFraction("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s",
|
||||
//new ImpreciseFraction("0.000000000001"), // "otm.suffix.pico": "p%s",
|
||||
//new ImpreciseFraction("0.000000000000001"), // "otm.suffix.femto": "f%s",
|
||||
//new ImpreciseFraction("0.000000000000000001"), // "otm.suffix.atto": "a%s",
|
||||
//new ImpreciseFraction("0.000000000000000000001"), // "otm.suffix.zepto": "z%s",
|
||||
//new ImpreciseFraction("0.000000000000000000000001"), // "otm.suffix.yocto": "y%s",
|
||||
};
|
||||
|
||||
public static String formatDecimal(BigDecimal value, int decimals) {
|
||||
|
@ -86,7 +86,3 @@ inline fun <T> LazyOptional<T>.ifPresentK(lambda: (T) -> Unit) {
|
||||
lambda.invoke(value)
|
||||
}
|
||||
}
|
||||
|
||||
val ItemStack.energy get() = getCapability(CapabilityEnergy.ENERGY).orNull()
|
||||
val ItemStack.matteryEnergy get() = getCapability(MatteryCapability.ENERGY).orNull()
|
||||
val LivingEntity.android get() = getCapability(MatteryCapability.ANDROID).orNull()
|
||||
|
@ -21,13 +21,12 @@ import net.minecraftforge.energy.IEnergyStorage
|
||||
import net.minecraftforge.items.CapabilityItemHandler
|
||||
import ru.dbotthepony.mc.otm.block.BatteryBankBlock
|
||||
import ru.dbotthepony.mc.otm.block.BlockMatteryRotatable
|
||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.extractEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.*
|
||||
import ru.dbotthepony.mc.otm.container.MatteryContainer
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.ifPresentK
|
||||
import ru.dbotthepony.mc.otm.menu.BatteryBankMenu
|
||||
import ru.dbotthepony.mc.otm.orNull
|
||||
import ru.dbotthepony.mc.otm.registry.MBlockEntities
|
||||
import ru.dbotthepony.mc.otm.set
|
||||
import ru.dbotthepony.mc.otm.unaryMinus
|
||||
@ -86,33 +85,20 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
||||
val stack = container.getItem(i)
|
||||
|
||||
if (!stack.isEmpty) {
|
||||
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
stack.energy?.let {
|
||||
val diff: ImpreciseFraction
|
||||
|
||||
if (mode) {
|
||||
diff = it.receiveEnergyOuter(ImpreciseFraction.LONG_MAX_VALUE, true)
|
||||
} else {
|
||||
diff = it.extractEnergyOuter(ImpreciseFraction.LONG_MAX_VALUE, true)
|
||||
}
|
||||
|
||||
distribution[i] = diff
|
||||
summ += diff
|
||||
} else {
|
||||
val diff: Int
|
||||
|
||||
if (mode) {
|
||||
diff = it.receiveEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
|
||||
} else {
|
||||
diff = it.extractEnergy(ImpreciseFraction.LONG_MAX_VALUE, true)
|
||||
}
|
||||
|
||||
distribution[i] = ImpreciseFraction(diff)
|
||||
distribution[i] = diff
|
||||
summ += distribution[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!summ.isZero) {
|
||||
for (i in 0 until container.containerSize) {
|
||||
@ -137,28 +123,16 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
||||
val stack = container.getItem(i)
|
||||
|
||||
if (!stack.isEmpty) {
|
||||
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
stack.energy?.let {
|
||||
val diff: ImpreciseFraction
|
||||
|
||||
if (mode) {
|
||||
diff = it.receiveEnergyOuter(howMuch * distList[i], simulate)
|
||||
} else {
|
||||
diff = it.extractEnergyOuter(howMuch * distList[i], simulate)
|
||||
}
|
||||
|
||||
summ += diff
|
||||
} else {
|
||||
val diff: Int
|
||||
|
||||
if (mode) {
|
||||
diff = it.receiveEnergy(howMuch * distList[i], simulate)
|
||||
} else {
|
||||
diff = it.extractEnergy(howMuch * distList[i], simulate)
|
||||
}
|
||||
|
||||
summ += ImpreciseFraction(diff)
|
||||
}
|
||||
summ += diff
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,12 +167,8 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
||||
val stack = container.getItem(i)
|
||||
|
||||
if (!stack.isEmpty) {
|
||||
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
result += it.batteryLevel
|
||||
} else {
|
||||
result += it.energyStored
|
||||
}
|
||||
stack.energy?.let {
|
||||
result += it.energyStoredMattery
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -213,12 +183,8 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
||||
val stack = container.getItem(i)
|
||||
|
||||
if (!stack.isEmpty) {
|
||||
stack.getCapability(CapabilityEnergy.ENERGY).ifPresent {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
result += it.maxBatteryLevel
|
||||
} else {
|
||||
result += it.maxEnergyStored
|
||||
}
|
||||
stack.energy?.let {
|
||||
result += it.maxEnergyStoredMattery
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -315,6 +281,7 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
||||
CapabilityEnergy.ENERGY,
|
||||
-blockState.getValue(BlockMatteryRotatable.FACING)
|
||||
) {
|
||||
@Suppress("name_shadowing")
|
||||
val level = this.level
|
||||
|
||||
if (level is ServerLevel)
|
||||
@ -326,25 +293,17 @@ class BatteryBankBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Matte
|
||||
if (isBlockedByRedstone)
|
||||
return
|
||||
|
||||
outputCapability.ifPresent {
|
||||
outputCapability.ifPresentK {
|
||||
val (_, maxThroughput) = energy.getDistribution(false)
|
||||
|
||||
if (maxThroughput.isZero)
|
||||
return@ifPresent
|
||||
return@ifPresentK
|
||||
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
val diff = it.receiveEnergyOuter(maxThroughput, false)
|
||||
val diff = it.receiveEnergy(maxThroughput, false)
|
||||
|
||||
if (!diff.isZero) {
|
||||
energy.extractEnergyInner(diff, false)
|
||||
}
|
||||
} else {
|
||||
val diff = it.receiveEnergy(maxThroughput, false)
|
||||
|
||||
if (diff != 0) {
|
||||
energy.extractEnergyInner(diff, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,9 +119,9 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
|
||||
if (direction == blockState.getValue(BlockMatteryRotatable.FACING))
|
||||
continue
|
||||
|
||||
val resolver = level.getBlockEntity(blockPos + direction)?.getCapability(CapabilityEnergy.ENERGY, -direction)
|
||||
val resolver = level.getBlockEntity(blockPos + direction)?.getEnergySided(-direction)
|
||||
|
||||
resolver?.ifPresent {
|
||||
resolver?.ifPresentK {
|
||||
if (!known.contains(resolver)) {
|
||||
val ref = WeakReference(this)
|
||||
|
||||
@ -168,23 +168,12 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
|
||||
private var check = true
|
||||
|
||||
private fun workWithPower(it: IEnergyStorage) {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
val demand = it.missingPower
|
||||
val extracted = energy.extractEnergyInner(demand, true)
|
||||
val received = it.receiveEnergyOuter(extracted, false)
|
||||
val extracted = energy.extractEnergyInner(THROUGHPUT, true)
|
||||
val received = it.receiveEnergy(extracted, false)
|
||||
|
||||
if (!received.isZero) {
|
||||
energy.extractEnergyInner(received, false)
|
||||
}
|
||||
} else {
|
||||
val demand = it.receiveEnergy(THROUGHPUT_INT, true)
|
||||
val extracted = energy.extractEnergyInner(demand, true)
|
||||
val received = it.receiveEnergy(extracted, false)
|
||||
|
||||
if (received != 0) {
|
||||
energy.extractEnergyInner(received, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun tick() {
|
||||
@ -235,7 +224,7 @@ class ChemicalGeneratorBlockEntity(pos: BlockPos, state: BlockState) : MatteryBl
|
||||
val item = container[SLOT_BATTERY]
|
||||
|
||||
if (!item.isEmpty) {
|
||||
item.getCapability(CapabilityEnergy.ENERGY).ifPresent(this::workWithPower)
|
||||
item.energy?.let(this::workWithPower)
|
||||
if (energy.batteryLevel.isZero) return
|
||||
}
|
||||
|
||||
|
@ -24,10 +24,8 @@ import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
import ru.dbotthepony.mc.otm.*
|
||||
import ru.dbotthepony.mc.otm.block.EnergyCounterBlock
|
||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.extractEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.receiveEnergy
|
||||
import ru.dbotthepony.mc.otm.capability.*
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.menu.EnergyCounterMenu
|
||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||
@ -138,6 +136,8 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
|
||||
for (num in history)
|
||||
list.add(num.serializeNBT())
|
||||
|
||||
ioLimit?.let { nbt["io_limit"] = it.serializeNBT() }
|
||||
}
|
||||
|
||||
override fun load(nbt: CompoundTag) {
|
||||
@ -147,6 +147,10 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
passed = ImpreciseFraction.deserializeNBT(it)
|
||||
}
|
||||
|
||||
nbt.ifHas(("io_limit")) {
|
||||
ioLimit = ImpreciseFraction.deserializeNBT(it)
|
||||
}
|
||||
|
||||
nbt.ifHas(("history_tick"), IntTag::class.java) {
|
||||
historyTick = it.asInt
|
||||
}
|
||||
@ -195,17 +199,9 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
val ioLimit = ioLimit
|
||||
|
||||
if (ioLimit != null) {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
diff = it.extractEnergyOuter(howMuch.min(ioLimit), simulate)
|
||||
diff = it.extractEnergy(howMuch.min(ioLimit), simulate)
|
||||
} else {
|
||||
diff = ImpreciseFraction(it.extractEnergy(howMuch.min(ioLimit), simulate))
|
||||
}
|
||||
} else {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
diff = it.extractEnergyOuter(howMuch, simulate)
|
||||
} else {
|
||||
diff = ImpreciseFraction(it.extractEnergy(howMuch, simulate))
|
||||
}
|
||||
diff = it.extractEnergy(howMuch, simulate)
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
@ -235,17 +231,9 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
val ioLimit = ioLimit
|
||||
|
||||
if (ioLimit != null) {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
diff = it.receiveEnergyOuter(howMuch.min(ioLimit), simulate)
|
||||
diff = it.receiveEnergy(howMuch.min(ioLimit), simulate)
|
||||
} else {
|
||||
diff = ImpreciseFraction(it.receiveEnergy(howMuch.min(ioLimit), simulate))
|
||||
}
|
||||
} else {
|
||||
if (it is IMatteryEnergyStorage) {
|
||||
diff = it.receiveEnergyOuter(howMuch, simulate)
|
||||
} else {
|
||||
diff = ImpreciseFraction(it.receiveEnergy(howMuch, simulate))
|
||||
}
|
||||
diff = it.receiveEnergy(howMuch, simulate)
|
||||
}
|
||||
|
||||
if (!simulate) {
|
||||
@ -346,13 +334,19 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
|
||||
private var resolverInput = LazyOptional.of<IMatteryEnergyStorage> { energyInput }
|
||||
private var resolverOutput = LazyOptional.of<IMatteryEnergyStorage> { energyOutput }
|
||||
|
||||
private var resolverInputMekanism = if (isMekanismLoaded) LazyOptional.of { MatteryToMekanismEnergyWrapper(energyInput) } else null
|
||||
private var resolverOutputMekanism = if (isMekanismLoaded) LazyOptional.of { MatteryToMekanismEnergyWrapper(energyInput) } else null
|
||||
|
||||
private var valid = true
|
||||
|
||||
override fun invalidateCaps() {
|
||||
super.invalidateCaps()
|
||||
valid = false
|
||||
resolverInput.invalidate()
|
||||
resolverInputMekanism?.invalidate()
|
||||
resolverOutput.invalidate()
|
||||
resolverOutputMekanism?.invalidate()
|
||||
}
|
||||
|
||||
override fun reviveCaps() {
|
||||
@ -360,6 +354,11 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
valid = true
|
||||
resolverInput = LazyOptional.of { energyInput }
|
||||
resolverOutput = LazyOptional.of { energyOutput }
|
||||
|
||||
if (isMekanismLoaded) {
|
||||
resolverInputMekanism = LazyOptional.of { MatteryToMekanismEnergyWrapper(energyInput) }
|
||||
resolverOutputMekanism = LazyOptional.of { MatteryToMekanismEnergyWrapper(energyInput) }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("deprecation")
|
||||
@ -369,10 +368,18 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
|
||||
if (new !== old && new.getValue(EnergyCounterBlock.INPUT_DIRECTION) != old.getValue(EnergyCounterBlock.INPUT_DIRECTION)) {
|
||||
resolverInput.invalidate()
|
||||
resolverInputMekanism?.invalidate()
|
||||
resolverOutput.invalidate()
|
||||
resolverOutputMekanism?.invalidate()
|
||||
|
||||
resolverInput = LazyOptional.of { energyInput }
|
||||
resolverOutput = LazyOptional.of { energyOutput }
|
||||
|
||||
if (isMekanismLoaded) {
|
||||
resolverInputMekanism = LazyOptional.of { MatteryToMekanismEnergyWrapper(energyInput) }
|
||||
resolverOutputMekanism = LazyOptional.of { MatteryToMekanismEnergyWrapper(energyInput) }
|
||||
}
|
||||
|
||||
if (level != null)
|
||||
checkSurroundings(level)
|
||||
}
|
||||
@ -384,7 +391,7 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
side: Direction
|
||||
): LazyOptional<IEnergyStorage> {
|
||||
val ent = level.getBlockEntity(blockPos.offset(side.normal)) ?: return LazyOptional.empty()
|
||||
val resolve = ent.getCapability(CapabilityEnergy.ENERGY, side.opposite)
|
||||
val resolve = ent.getEnergySided(-side)
|
||||
|
||||
if (resolve !== old) {
|
||||
val weak = WeakReference(this)
|
||||
@ -427,10 +434,14 @@ class EnergyCounterBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) : Mat
|
||||
if (side == blockState.getValue(EnergyCounterBlock.INPUT_DIRECTION)) {
|
||||
if (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY) {
|
||||
return resolverInput.cast()
|
||||
} else if (cap === MatteryCapability.MEKANISM_ENERGY) {
|
||||
return resolverInputMekanism!!.cast()
|
||||
}
|
||||
} else if (side == blockState.getValue(EnergyCounterBlock.INPUT_DIRECTION).opposite) {
|
||||
if (cap === MatteryCapability.ENERGY || cap === CapabilityEnergy.ENERGY) {
|
||||
return resolverOutput.cast()
|
||||
} else if (cap === MatteryCapability.MEKANISM_ENERGY) {
|
||||
return resolverOutputMekanism!!.cast()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,45 +1,119 @@
|
||||
package ru.dbotthepony.mc.otm.capability
|
||||
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraft.world.entity.LivingEntity
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.CapabilityEnergy
|
||||
import net.minecraftforge.energy.IEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.core.Fraction
|
||||
import net.minecraftforge.fml.ModList
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.getMekanismEnergySided
|
||||
import ru.dbotthepony.mc.otm.compat.mekanism.mekanismEnergy
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.orNull
|
||||
|
||||
fun IEnergyStorage.receiveEnergy(amount: Fraction, simulate: Boolean): Int {
|
||||
if (amount.isZero())
|
||||
return 0
|
||||
fun IEnergyStorage.receiveEnergy(amount: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
if (this is IMatteryEnergyStorage)
|
||||
return receiveEnergyOuter(amount, simulate)
|
||||
|
||||
if (amount > Fraction.INT_MAX_VALUE)
|
||||
return receiveEnergy(Int.MAX_VALUE, simulate)
|
||||
|
||||
return receiveEnergy(amount.wholePart().toInt(), simulate)
|
||||
}
|
||||
|
||||
fun IEnergyStorage.extractEnergy(amount: Fraction, simulate: Boolean): Int {
|
||||
if (amount.isZero())
|
||||
return 0
|
||||
|
||||
if (amount > Fraction.INT_MAX_VALUE)
|
||||
return extractEnergy(Int.MAX_VALUE, simulate)
|
||||
|
||||
return extractEnergy(amount.wholePart().toInt(), simulate)
|
||||
}
|
||||
|
||||
fun IEnergyStorage.receiveEnergy(amount: ImpreciseFraction, simulate: Boolean): Int {
|
||||
if (amount.isZero)
|
||||
return 0
|
||||
if (!amount.isPositive)
|
||||
return ImpreciseFraction.ZERO
|
||||
|
||||
if (amount > ImpreciseFraction.INT_MAX_VALUE)
|
||||
return receiveEnergy(Int.MAX_VALUE, simulate)
|
||||
return ImpreciseFraction.valueOf(receiveEnergy(Int.MAX_VALUE, simulate))
|
||||
|
||||
return receiveEnergy(amount.toInt(), simulate)
|
||||
return ImpreciseFraction.valueOf(receiveEnergy(amount.toInt(), simulate))
|
||||
}
|
||||
|
||||
fun IEnergyStorage.extractEnergy(amount: ImpreciseFraction, simulate: Boolean): Int {
|
||||
if (amount.isZero)
|
||||
return 0
|
||||
fun IEnergyStorage.extractEnergy(amount: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
if (this is IMatteryEnergyStorage)
|
||||
return extractEnergyOuter(amount, simulate)
|
||||
|
||||
if (!amount.isPositive)
|
||||
return ImpreciseFraction.ZERO
|
||||
|
||||
if (amount > ImpreciseFraction.INT_MAX_VALUE)
|
||||
return extractEnergy(Int.MAX_VALUE, simulate)
|
||||
return ImpreciseFraction.valueOf(extractEnergy(Int.MAX_VALUE, simulate))
|
||||
|
||||
return extractEnergy(amount.toInt(), simulate)
|
||||
return ImpreciseFraction.valueOf(extractEnergy(amount.toInt(), simulate))
|
||||
}
|
||||
|
||||
val IEnergyStorage.maxEnergyStoredMattery: ImpreciseFraction get() {
|
||||
if (this is IMatteryEnergyStorage) {
|
||||
return maxBatteryLevel
|
||||
}
|
||||
|
||||
return ImpreciseFraction.valueOf(maxEnergyStored)
|
||||
}
|
||||
|
||||
val IEnergyStorage.energyStoredMattery: ImpreciseFraction get() {
|
||||
if (this is IMatteryEnergyStorage) {
|
||||
return batteryLevel
|
||||
}
|
||||
|
||||
return ImpreciseFraction.valueOf(energyStored)
|
||||
}
|
||||
|
||||
val isMekanismLoaded by lazy { ModList.get().isLoaded("mekanism") }
|
||||
|
||||
/**
|
||||
* Shortcut for getting [IEnergyStorage], including wrappers for it
|
||||
*/
|
||||
val ICapabilityProvider.energy: IEnergyStorage? get() {
|
||||
if (isMekanismLoaded) {
|
||||
val mekanismEnergy = mekanismEnergy
|
||||
|
||||
if (mekanismEnergy != null) {
|
||||
return mekanismEnergy
|
||||
}
|
||||
}
|
||||
|
||||
return getCapability(CapabilityEnergy.ENERGY).orNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for getting [IMatteryEnergyStorage], including wrappers for it
|
||||
*/
|
||||
val ICapabilityProvider.matteryEnergy: IMatteryEnergyStorage? get() {
|
||||
if (isMekanismLoaded) {
|
||||
val mekanismEnergy = mekanismEnergy
|
||||
|
||||
if (mekanismEnergy != null) {
|
||||
return mekanismEnergy
|
||||
}
|
||||
}
|
||||
|
||||
return getCapability(MatteryCapability.ENERGY).orNull()
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for getting [LazyOptional] with [IEnergyStorage], including wrappers for it
|
||||
*/
|
||||
fun ICapabilityProvider.getEnergySided(side: Direction? = null): LazyOptional<IEnergyStorage> {
|
||||
if (isMekanismLoaded) {
|
||||
val mekanismEnergy = getMekanismEnergySided(side)
|
||||
|
||||
if (mekanismEnergy.isPresent) {
|
||||
return mekanismEnergy.cast()
|
||||
}
|
||||
}
|
||||
|
||||
return getCapability(CapabilityEnergy.ENERGY, side)
|
||||
}
|
||||
|
||||
/**
|
||||
* Shortcut for getting [LazyOptional] with [IMatteryEnergyStorage], including wrappers for it
|
||||
*/
|
||||
fun ICapabilityProvider.getMatteryEnergySided(side: Direction? = null): LazyOptional<IMatteryEnergyStorage> {
|
||||
if (isMekanismLoaded) {
|
||||
val mekanismEnergy = getMekanismEnergySided(side)
|
||||
|
||||
if (mekanismEnergy.isPresent) {
|
||||
return mekanismEnergy
|
||||
}
|
||||
}
|
||||
|
||||
return getCapability(MatteryCapability.ENERGY, side)
|
||||
}
|
||||
|
||||
val LivingEntity.android get() = getCapability(MatteryCapability.ANDROID).orNull()
|
||||
|
@ -7,12 +7,16 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
// IEnergyStorage for direct compat with Forge Energy
|
||||
interface IMatteryEnergyStorage : IEnergyStorage {
|
||||
/**
|
||||
* such as cables. This is something that would work only with energy storage
|
||||
* Such as cables. This is something that would work only with energy storage
|
||||
*
|
||||
* @return energy extracted
|
||||
*/
|
||||
fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
|
||||
/**
|
||||
* All or nothing
|
||||
*
|
||||
* @return energy extracted
|
||||
*/
|
||||
fun extractEnergyOuterExact(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
val extracted = extractEnergyOuter(howMuch, true)
|
||||
@ -32,11 +36,15 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
||||
* for internal needs, e.g. for work
|
||||
* CAN also be used by something that does evil
|
||||
* e.g. sucking out energy anomaly should use this
|
||||
*
|
||||
* @return energy extracted
|
||||
*/
|
||||
fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
|
||||
/**
|
||||
* All or nothing
|
||||
*
|
||||
* @return energy extracted
|
||||
*/
|
||||
fun extractEnergyInnerExact(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
val extracted = extractEnergyInner(howMuch, true)
|
||||
@ -54,6 +62,8 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
||||
|
||||
/**
|
||||
* For energy receiving from outside, e.g. cables
|
||||
*
|
||||
* @return energy accepted
|
||||
*/
|
||||
fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
|
||||
@ -73,11 +83,15 @@ interface IMatteryEnergyStorage : IEnergyStorage {
|
||||
|
||||
/**
|
||||
* For energy receiving from inside, e.g. generator generates power
|
||||
*
|
||||
* @return energy accepted
|
||||
*/
|
||||
fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction
|
||||
|
||||
/**
|
||||
* All or nothing
|
||||
*
|
||||
* @return energy accepted
|
||||
*/
|
||||
fun receiveEnergyInnerExact(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
val extracted = receiveEnergyInner(howMuch, true)
|
||||
|
@ -0,0 +1,30 @@
|
||||
package ru.dbotthepony.mc.otm.compat.mekanism
|
||||
|
||||
import mekanism.api.math.FloatingLong
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import java.math.BigInteger
|
||||
|
||||
private val LONG_OVERFLOW = BigInteger.valueOf(Long.MAX_VALUE) + BigInteger.valueOf(Long.MAX_VALUE) + BigInteger.TWO
|
||||
private val LONG_OVERFLOW1 = BigInteger.valueOf(Long.MAX_VALUE) + BigInteger.valueOf(Long.MAX_VALUE) + BigInteger.ONE
|
||||
|
||||
fun ImpreciseFraction.toFloatingLong(): FloatingLong {
|
||||
if (isNegative) {
|
||||
// Floating long can't be negative
|
||||
return FloatingLong.ZERO
|
||||
}
|
||||
|
||||
if (whole >= LONG_OVERFLOW1) {
|
||||
return FloatingLong.MAX_VALUE
|
||||
}
|
||||
|
||||
return FloatingLong.create(whole.toLong(), (decimal * 10_000.0).toInt().toShort())
|
||||
}
|
||||
|
||||
fun FloatingLong.toImpreciseFraction(): ImpreciseFraction {
|
||||
// Overflow
|
||||
if (value < 0L) {
|
||||
return ImpreciseFraction(LONG_OVERFLOW + BigInteger.valueOf(value), decimal / 10_000.0)
|
||||
}
|
||||
|
||||
return ImpreciseFraction(value, decimal / 10_000.0)
|
||||
}
|
194
src/main/kotlin/ru/dbotthepony/mc/otm/compat/mekanism/Power.kt
Normal file
194
src/main/kotlin/ru/dbotthepony/mc/otm/compat/mekanism/Power.kt
Normal file
@ -0,0 +1,194 @@
|
||||
package ru.dbotthepony.mc.otm.compat.mekanism
|
||||
|
||||
import mekanism.api.Action
|
||||
import mekanism.api.energy.IStrictEnergyHandler
|
||||
import mekanism.api.math.FloatingLong
|
||||
import mekanism.common.config.MekanismConfig
|
||||
import net.minecraft.core.Direction
|
||||
import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.fml.ModList
|
||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.isMekanismLoaded
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import java.lang.ref.WeakReference
|
||||
import java.util.WeakHashMap
|
||||
|
||||
private val mekanismJoulesToFE by lazy {
|
||||
try {
|
||||
val conf = MekanismConfig.general
|
||||
return@lazy conf.TO_FORGE.get().toImpreciseFraction()
|
||||
} catch(_: Throwable) {
|
||||
|
||||
}
|
||||
|
||||
return@lazy ImpreciseFraction.ONE
|
||||
}
|
||||
|
||||
private val mekanismJoulesFromFE by lazy {
|
||||
try {
|
||||
val conf = MekanismConfig.general
|
||||
return@lazy conf.FROM_FORGE.get().toImpreciseFraction()
|
||||
} catch(_: Throwable) {
|
||||
|
||||
}
|
||||
|
||||
return@lazy ImpreciseFraction.ONE
|
||||
}
|
||||
|
||||
class MekanismEnergyWrapper(private val power: IStrictEnergyHandler) : IMatteryEnergyStorage {
|
||||
override fun extractEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
val action = when (simulate) {
|
||||
true -> Action.SIMULATE
|
||||
false -> Action.EXECUTE
|
||||
}
|
||||
|
||||
return howMuch - power.extractEnergy((howMuch * mekanismJoulesFromFE).toFloatingLong(), action).toImpreciseFraction() * mekanismJoulesToFE
|
||||
}
|
||||
|
||||
override fun extractEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
return extractEnergyOuter(howMuch, simulate)
|
||||
}
|
||||
|
||||
override fun receiveEnergyOuter(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
val action = when (simulate) {
|
||||
true -> Action.SIMULATE
|
||||
false -> Action.EXECUTE
|
||||
}
|
||||
|
||||
return howMuch - power.insertEnergy((howMuch * mekanismJoulesFromFE).toFloatingLong(), action).toImpreciseFraction() * mekanismJoulesToFE
|
||||
}
|
||||
|
||||
override fun receiveEnergyInner(howMuch: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
|
||||
return receiveEnergyOuter(howMuch, simulate)
|
||||
}
|
||||
|
||||
override val batteryLevel: ImpreciseFraction
|
||||
get() {
|
||||
var sum = ImpreciseFraction.ZERO
|
||||
|
||||
for (i in 0 until power.energyContainerCount) {
|
||||
sum += power.getEnergy(i).toImpreciseFraction()
|
||||
}
|
||||
|
||||
return sum * mekanismJoulesToFE
|
||||
}
|
||||
|
||||
override val maxBatteryLevel: ImpreciseFraction
|
||||
get() {
|
||||
var sum = ImpreciseFraction.ZERO
|
||||
|
||||
for (i in 0 until power.energyContainerCount) {
|
||||
sum += power.getMaxEnergy(i).toImpreciseFraction()
|
||||
}
|
||||
|
||||
return sum * mekanismJoulesToFE
|
||||
}
|
||||
}
|
||||
|
||||
class MatteryToMekanismEnergyWrapper(private val power: IMatteryEnergyStorage) : IStrictEnergyHandler {
|
||||
override fun getEnergyContainerCount(): Int = 1
|
||||
|
||||
override fun getEnergy(container: Int): FloatingLong {
|
||||
if (container != 0) {
|
||||
return FloatingLong.ZERO
|
||||
}
|
||||
|
||||
return (power.batteryLevel * mekanismJoulesFromFE).toFloatingLong()
|
||||
}
|
||||
|
||||
override fun setEnergy(container: Int, value: FloatingLong) {
|
||||
// no op
|
||||
}
|
||||
|
||||
override fun getMaxEnergy(container: Int): FloatingLong {
|
||||
if (container != 0) {
|
||||
return FloatingLong.ZERO
|
||||
}
|
||||
|
||||
return (power.maxBatteryLevel * mekanismJoulesFromFE).toFloatingLong()
|
||||
}
|
||||
|
||||
override fun getNeededEnergy(container: Int): FloatingLong {
|
||||
if (container != 0) {
|
||||
return FloatingLong.ZERO
|
||||
}
|
||||
|
||||
return (power.missingPower * mekanismJoulesFromFE).toFloatingLong()
|
||||
}
|
||||
|
||||
override fun insertEnergy(container: Int, howMuch: FloatingLong, action: Action): FloatingLong {
|
||||
val copy = howMuch.copy()
|
||||
return copy.minusEqual((power.receiveEnergyOuter(howMuch.toImpreciseFraction() * mekanismJoulesToFE, action.simulate()) * mekanismJoulesFromFE).toFloatingLong())
|
||||
}
|
||||
|
||||
override fun extractEnergy(container: Int, howMuch: FloatingLong, action: Action): FloatingLong {
|
||||
val copy = howMuch.copy()
|
||||
return copy.minusEqual((power.extractEnergyOuter(howMuch.toImpreciseFraction() * mekanismJoulesToFE, action.simulate()) * mekanismJoulesFromFE).toFloatingLong())
|
||||
}
|
||||
}
|
||||
|
||||
val ICapabilityProvider.mekanismEnergy: IMatteryEnergyStorage? get() {
|
||||
if (!isMekanismLoaded) {
|
||||
return null
|
||||
}
|
||||
|
||||
val capability = getCapability(MatteryCapability.MEKANISM_ENERGY)
|
||||
|
||||
if (!capability.isPresent) {
|
||||
return null
|
||||
}
|
||||
|
||||
return MekanismEnergyWrapper(capability.orElseThrow(::IllegalStateException))
|
||||
}
|
||||
|
||||
private val lazyCache by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
private val lazyCacheDown by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
private val lazyCacheUp by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
private val lazyCacheSouth by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
private val lazyCacheNorth by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
private val lazyCacheEast by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
private val lazyCacheWest by lazy { WeakHashMap<LazyOptional<IStrictEnergyHandler>, WeakReference<LazyOptional<MekanismEnergyWrapper>>>() }
|
||||
|
||||
fun ICapabilityProvider.getMekanismEnergySided(side: Direction? = null): LazyOptional<IMatteryEnergyStorage> {
|
||||
if (!isMekanismLoaded) {
|
||||
return LazyOptional.empty()
|
||||
}
|
||||
|
||||
val lazyOptional = getCapability(MatteryCapability.MEKANISM_ENERGY, side)
|
||||
|
||||
if (!lazyOptional.isPresent) {
|
||||
return LazyOptional.empty()
|
||||
}
|
||||
|
||||
val cache = when (side) {
|
||||
Direction.DOWN -> lazyCacheDown
|
||||
Direction.UP -> lazyCacheUp
|
||||
Direction.NORTH -> lazyCacheNorth
|
||||
Direction.SOUTH -> lazyCacheSouth
|
||||
Direction.WEST -> lazyCacheWest
|
||||
Direction.EAST -> lazyCacheEast
|
||||
null -> lazyCache
|
||||
}
|
||||
|
||||
val cached = cache[lazyOptional]?.get()
|
||||
|
||||
if (cached != null) {
|
||||
return cached.cast()
|
||||
}
|
||||
|
||||
val resolver = LazyOptional.of {
|
||||
MekanismEnergyWrapper(lazyOptional.orElseThrow(::IllegalStateException))
|
||||
}
|
||||
|
||||
val ref = WeakReference(resolver)
|
||||
cache[lazyOptional] = ref
|
||||
|
||||
lazyOptional.addListener {
|
||||
ref.get()?.invalidate()
|
||||
}
|
||||
|
||||
return resolver.cast()
|
||||
}
|
||||
|
@ -541,6 +541,30 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
|
||||
@JvmField val DOUBLE_MAX_VALUE = ImpreciseFraction(BI_DOUBLE_MAX)
|
||||
@JvmField val DOUBLE_MIN_VALUE = ImpreciseFraction(BI_DOUBLE_MIN)
|
||||
|
||||
private val cache = Array(256) { ImpreciseFraction(it - 128) }
|
||||
|
||||
/**
|
||||
* Returns pooled value if present, otherwise constructs new object
|
||||
*/
|
||||
fun valueOf(value: Int): ImpreciseFraction {
|
||||
if (value in -128 .. 127) {
|
||||
return cache[value + 128]
|
||||
}
|
||||
|
||||
return ImpreciseFraction(value)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns pooled value if present, otherwise constructs new object
|
||||
*/
|
||||
fun valueOf(value: Long): ImpreciseFraction {
|
||||
if (value in -128 .. 127) {
|
||||
return cache[value.toInt()]
|
||||
}
|
||||
|
||||
return ImpreciseFraction(value)
|
||||
}
|
||||
|
||||
@JvmField val NaN = ImpreciseFraction(0, Double.NaN)
|
||||
|
||||
@JvmStatic
|
||||
|
@ -26,8 +26,7 @@ import net.minecraftforge.common.capabilities.ICapabilityProvider
|
||||
import net.minecraftforge.common.util.LazyOptional
|
||||
import net.minecraftforge.energy.CapabilityEnergy
|
||||
import ru.dbotthepony.mc.otm.*
|
||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.capability.MatteryCapability
|
||||
import ru.dbotthepony.mc.otm.capability.*
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
import ru.dbotthepony.mc.otm.menu.FormattingHelper
|
||||
import ru.dbotthepony.mc.otm.registry.EMPDamageSource
|
||||
|
Loading…
Reference in New Issue
Block a user