Failure chance in matter replicator, fix tick precision in worker, various fixes

This commit is contained in:
DBotThePony 2022-01-30 16:43:30 +07:00
parent 052a29d005
commit 03c04178e7
Signed by: DBot
GPG Key ID: DCC23B5715498507
13 changed files with 225 additions and 136 deletions

View File

@ -53,7 +53,6 @@ import ru.dbotthepony.mc.otm.client.render.BlackHoleRenderer;
import ru.dbotthepony.mc.otm.client.render.EnergyCounterRenderer;
import ru.dbotthepony.mc.otm.client.render.GravitationStabilizerRenderer;
import ru.dbotthepony.mc.otm.client.render.SkinElement;
import ru.dbotthepony.mc.otm.core.Fraction;
import ru.dbotthepony.mc.otm.core.ImpreciseFraction;
import ru.dbotthepony.mc.otm.item.*;
import ru.dbotthepony.mc.otm.menu.*;
@ -1291,7 +1290,7 @@ public class Registry {
public static final MenuType<MenuPatternStorage> PATTERN_STORAGE = new MenuType<>(MenuPatternStorage::new);
public static final MenuType<MenuMatterScanner> MATTER_SCANNER = new MenuType<>(MenuMatterScanner::new);
public static final MenuType<MenuMatterPanel> MATTER_PANEL = new MenuType<>(MenuMatterPanel::new);
public static final MenuType<MatterReplicatorMenu> MATTER_REPLICATOR = new MenuType<>(MatterReplicatorMenu::new);
public static final MenuType<MenuMatterReplicator> MATTER_REPLICATOR = new MenuType<>(MenuMatterReplicator::new);
public static final MenuType<MenuMatterBottler> MATTER_BOTTLER = new MenuType<>(MenuMatterBottler::new);
public static final MenuType<MenuDriveViewer> DRIVE_VIEWER = new MenuType<>(MenuDriveViewer::new);
public static final MenuType<MenuCargoCrate> CARGO_CRATE = new MenuType<>(MenuCargoCrate::new);

View File

@ -37,6 +37,59 @@ import ru.dbotthepony.mc.otm.matter.getMatterValue
import ru.dbotthepony.mc.otm.menu.MenuMatterDecomposer
import ru.dbotthepony.mc.otm.set
fun moveMatterAsDustIntoContainer(_matterValue: ImpreciseFraction, container: MatteryContainer, OUTPUT_DUST_MAIN: Int, OUTPUT_DUST_STACKING: Int): ImpreciseFraction {
var matterValue = _matterValue
val item = Registry.Items.MATTER_DUST
while (matterValue > ImpreciseFraction.ZERO) {
val stack = container[OUTPUT_DUST_MAIN]
// первый слот пустой
if (stack.isEmpty) {
container[OUTPUT_DUST_MAIN] = ItemStack(item, 1).also {
matterValue -= item.addMatterValue(it, matterValue, false)
}
// первый слот не пустой, но мы можем влить туда материю
} else if (!item.isFull(stack) && stack.count == 1) {
matterValue -= item.addMatterValue(stack, matterValue, false)
container.setChanged(OUTPUT_DUST_MAIN)
// первый слот не пустой и мы не можем влить туда материю
} else {
val stack2 = container[OUTPUT_DUST_STACKING]
// второй слот пустой
if (stack2.isEmpty) {
container[OUTPUT_DUST_STACKING] = ItemStack(item, 1).also {
matterValue -= item.addMatterValue(it, matterValue, false)
}
// второй слот не пустой, но мы можем влить туда материю
} else if (!item.isFull(stack2)) {
if (stack2.count != 1) {
return matterValue
}
matterValue -= item.addMatterValue(stack2, matterValue, false)
container.setChanged(OUTPUT_DUST_STACKING)
}
// можем ли мы стакнуть материю из второго слота в первый?
if (!stack2.isEmpty && item.isFull(stack2)) {
if (ItemStack.isSameItemSameTags(stack, stack2) && container.getMaxStackSizeWithItem(OUTPUT_DUST_MAIN) >= stack.count + 1) {
stack.count++
stack2.count--
container.setChanged(OUTPUT_DUST_MAIN)
container.setChanged(OUTPUT_DUST_STACKING)
} else {
return matterValue
}
}
}
}
return ImpreciseFraction.ZERO
}
class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
: BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_DECOMPOSER, pos, state), IMatterGraphNode {
@ -118,54 +171,11 @@ class BlockEntityMatterDecomposer(pos: BlockPos, state: BlockState)
var matterValue = ImpreciseFraction.deserializeNBT(job.data["value"])
if (job.data.getBoolean("to_dust")) {
val item = Registry.Items.MATTER_DUST
matterValue = moveMatterAsDustIntoContainer(matterValue, container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
while (matterValue > ImpreciseFraction.ZERO) {
val stack = container[OUTPUT_DUST_MAIN]
// первый слот пустой
if (stack.isEmpty) {
container[OUTPUT_DUST_MAIN] = ItemStack(item, 1).also {
matterValue -= item.addMatterValue(it, matterValue, false)
}
// первый слот не пустой, но мы можем влить туда материю
} else if (!item.isFull(stack) && stack.count == 1) {
matterValue -= item.addMatterValue(stack, matterValue, false)
container.setChanged(OUTPUT_DUST_MAIN)
// первый слот не пустой и мы не можем влить туда материю
} else {
val stack2 = container[OUTPUT_DUST_STACKING]
// второй слот пустой
if (stack2.isEmpty) {
container[OUTPUT_DUST_STACKING] = ItemStack(item, 1).also {
matterValue -= item.addMatterValue(it, matterValue, false)
}
// второй слот не пустой, но мы можем влить туда материю
} else if (!item.isFull(stack2)) {
if (stack2.count != 1) {
job.data["value"] = matterValue.serializeNBT()
return WorkerJobStatus(false, 20)
}
matterValue -= item.addMatterValue(stack2, matterValue, false)
container.setChanged(OUTPUT_DUST_STACKING)
}
// можем ли мы стакнуть материю из второго слота в первый?
if (!stack2.isEmpty && item.isFull(stack2)) {
if (ItemStack.isSameItemSameTags(stack, stack2) && container.getMaxStackSizeWithItem(OUTPUT_DUST_MAIN) >= stack.count + 1) {
stack.count++
stack2.count--
container.setChanged(OUTPUT_DUST_MAIN)
container.setChanged(OUTPUT_DUST_STACKING)
} else {
job.data["value"] = matterValue.serializeNBT()
return WorkerJobStatus(false, 20)
}
}
}
if (!matterValue.isZero) {
job.data["value"] = matterValue.serializeNBT()
return WorkerJobStatus(20)
}
return WorkerJobStatus()

View File

@ -24,6 +24,8 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.container.MatteryContainerFilterOnlyOut
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.graph.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
@ -31,8 +33,9 @@ import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.matter.baselineComplexityReplicateTicks
import ru.dbotthepony.mc.otm.matter.getMatterValue
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
import ru.dbotthepony.mc.otm.menu.MenuMatterReplicator
import ru.dbotthepony.mc.otm.set
import kotlin.math.pow
class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
BlockEntityMatteryWorker(Registry.BlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_), IMatterGraphNode {
@ -54,24 +57,36 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
// обычные запросы
@JvmField
val regularSlots = MatteryContainer(this::setChangedLight, 3)
private val itemHandler = regularSlots.handler { slot: Int, stack: ItemStack? -> false }
val container = MatteryContainer(this::setChangedLight, 5)
private val itemHandler = container.handler(MatteryContainerFilterOnlyOut)
override fun getDefaultDisplayName(): Component {
return NAME
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
return MatterReplicatorMenu(containerID, inventory, this)
return MenuMatterReplicator(containerID, inventory, this)
}
override fun onJobFinish(job: WorkerJob): WorkerJobStatus {
if (!regularSlots.fullyAddItem(job.stack)) {
if (job.data.getBoolean("as_dust")) {
val matterValue = moveMatterAsDustIntoContainer(ImpreciseFraction.deserializeNBT(job["matter"]), container, OUTPUT_DUST_MAIN, OUTPUT_DUST_STACKING)
if (!matterValue.isZero) {
job["matter"] = matterValue.serializeNBT()
return WorkerJobStatus(false, 20)
}
(node.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job["task"])!!)
return WorkerJobStatus()
}
if (!container.fullyAddItem(job.stack, FIRST_ACTUAL_OUTPUT_SLOT .. LAST_ACTUAL_OUTPUT_SLOT)) {
return WorkerJobStatus(false, 20)
}
(node.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job.data["task"])!!)
(node.graph as MatterNetworkGraph?)?.notifyTaskCompletion(MatterTask.deserializeNBT(job["task"])!!)
return WorkerJobStatus()
}
@ -113,9 +128,13 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
return WorkerJob(stack, ticks, BASE_CONSUMPTION, CompoundTag().also {
it["matter_per_tick"] = (matter.value / ticks).serializeNBT()
it["task"] = allocation.task.serializeNBT()
it["matter"] = matter.value.serializeNBT()
if (allocation.pattern != null)
it["pattern"] = allocation.pattern!!.serializeNBT()
it["pattern"] = allocation.pattern.serializeNBT()
if ((level?.random?.nextDouble() ?: 1.0) > (allocation.pattern?.research ?: 2.0).pow(2.0))
it["as_dust"] = true
})
}
@ -173,13 +192,13 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
override fun saveAdditional(nbt: CompoundTag) {
super.saveAdditional(nbt)
nbt["container"] = regularSlots.serializeNBT()
nbt["container"] = container.serializeNBT()
nbt["matter"] = matter.serializeNBT()
}
override fun load(nbt: CompoundTag) {
super.load(nbt)
regularSlots.deserializeNBT(nbt["container"])
container.deserializeNBT(nbt["container"])
nbt.ifHas("matter", CompoundTag::class.java) {
matter.deserializeNBT(it)
@ -215,5 +234,10 @@ class BlockEntityMatterReplicator(p_155229_: BlockPos, p_155230_: BlockState) :
private val DRAIN_MULT = ImpreciseFraction(200)
private val STORAGE = ImpreciseFraction(200_000)
private val MAX_IO = ImpreciseFraction(4_000)
const val FIRST_ACTUAL_OUTPUT_SLOT = 0
const val LAST_ACTUAL_OUTPUT_SLOT = 2
const val OUTPUT_DUST_MAIN = 3
const val OUTPUT_DUST_STACKING = 4
}
}

View File

@ -153,16 +153,16 @@ class BlockEntityMatterScanner(p_155229_: BlockPos, p_155230_: BlockState) :
var findState: PatternState? = null
for (state in getState) {
if (state.item() === stack.item && state.research() < 1.0) {
if (state.item === stack.item && state.research < 1.0) {
findState = state
} else if (state.item() === stack.item && state.research() >= 1.0) {
} else if (state.item === stack.item && state.research >= 1.0) {
return null
}
}
val new: PatternState =
if (findState != null) {
PatternState(findState.id, stack.item, findState.research_percent + 0.2)
PatternState(findState.id, stack.item, findState.research + 0.2)
} else {
PatternState(UUID.randomUUID(), stack.item, 0.2)
}

View File

@ -8,6 +8,8 @@ import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.DoubleTag
import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.weakGreaterOrEqual
import ru.dbotthepony.mc.otm.core.weakLessThan
import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.set
@ -152,7 +154,7 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
idleTicksAnim = 0
if (workTicks < currentJob.ticks) {
if (weakLessThan(workTicks, currentJob.ticks)) {
if (!currentJob.power.isZero) {
// сколько осталось тиков работать
val ticksLeft = currentJob.ticks - workTicks
@ -165,12 +167,13 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
requiredPower = currentJob.power * ticksLeft
}
val extractedPower = energy.extractEnergyInner(requiredPower, true)
val extractedPower = if (requiredPower.isZero) ImpreciseFraction.ZERO else energy.extractEnergyInner(requiredPower, true)
// сколько тиков мы "проработали"
// может быть меньше, чем единица, если недостаточно питания или мы завершаем работу,
// для которой осталось дробное количество тиков
val ticksAdvanced = (extractedPower / requiredPower).toDouble().coerceAtMost(ticksLeft)
val ticksAdvancedWeak = if (requiredPower.isZero) 1.0 else ticksAdvanced
val status = onWorkTick(WorkerTickContext(currentJob, requiredPower, extractedPower, ticksAdvanced))
if (!status.valid) {
@ -181,9 +184,9 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
workingTicksAnim++
errorTicksAnim = 0
val updatedWorkTicks = workTicks + ticksAdvanced
val updatedWorkTicks = (workTicks + ticksAdvancedWeak).coerceAtMost(currentJob.ticks)
if (updatedWorkTicks >= currentJob.ticks) {
if (weakGreaterOrEqual(updatedWorkTicks, currentJob.ticks)) {
workTicks = currentJob.ticks
energy.extractEnergyInner(extractedPower * (1.0 - (updatedWorkTicks - currentJob.ticks)), false)
@ -210,9 +213,9 @@ abstract class BlockEntityMatteryWorker(p_155228_: BlockEntityType<*>, p_155229_
workingTicksAnim++
errorTicksAnim = 0
workTicks += 1.0
workTicks = (workTicks + 1.0).coerceAtMost(currentJob.ticks)
if (workTicks >= currentJob.ticks) {
if (weakGreaterOrEqual(workTicks, currentJob.ticks)) {
val finish = onJobFinish(currentJob)
if (finish.valid) {

View File

@ -35,7 +35,9 @@ enum class WorkerState : StringRepresentable {
}
@JvmRecord
data class WorkerJobStatus @JvmOverloads constructor(val valid: Boolean = true, val throttle: Int = 0)
data class WorkerJobStatus @JvmOverloads constructor(val valid: Boolean = true, val throttle: Int = 0) {
constructor(throttle: Int) : this(false, throttle)
}
@JvmRecord
data class WorkerJob @JvmOverloads constructor(

View File

@ -1,7 +1,7 @@
package ru.dbotthepony.mc.otm.client.screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
import ru.dbotthepony.mc.otm.menu.MenuMatterReplicator
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.SlotPanel
@ -9,20 +9,23 @@ import ru.dbotthepony.mc.otm.client.screen.widget.MatterGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
class ScreenMatterReplicator(p_97741_: MatterReplicatorMenu, p_97742_: Inventory, p_97743_: Component) :
MatteryScreen<MatterReplicatorMenu>(p_97741_, p_97742_, p_97743_) {
class ScreenMatterReplicator(p_97741_: MenuMatterReplicator, p_97742_: Inventory, p_97743_: Component) :
MatteryScreen<MenuMatterReplicator>(p_97741_, p_97742_, p_97743_) {
override fun makeMainFrame(): FramePanel {
val frame = super.makeMainFrame()!!
val m = PowerGaugePanel(this, frame, menu.powerWidget, LEFT_MARGIN, GAUGE_TOP_WITH_SLOT)
MatterGaugePanel(this, frame, menu.matter_widget, LEFT_MARGIN + m.width, GAUGE_TOP_WITH_SLOT)
MatterGaugePanel(this, frame, menu.matter, LEFT_MARGIN + m.width, GAUGE_TOP_WITH_SLOT)
SlotPanel(this, frame, menu.batterySlot, LEFT_MARGIN, SLOT_TOP_UNDER_GAUGE)
ProgressGaugePanel(this, frame, menu.progress, 54f, PROGRESS_ARROW_TOP)
for (i in 0 until menu.output_slots.size)
SlotPanel(this, frame, menu.output_slots[i], 80f + i * 18, PROGRESS_SLOT_TOP)
for (i in 0 until 3)
SlotPanel(this, frame, menu.outputSlots[i], 80f + i * 18, PROGRESS_SLOT_TOP)
SlotPanel(this, frame, menu.outputSlots[3], 80f, PROGRESS_SLOT_TOP + 22f)
SlotPanel(this, frame, menu.outputSlots[4], 80f + 18f, PROGRESS_SLOT_TOP + 22f)
return frame
}

View File

@ -167,14 +167,17 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
@JvmOverloads
fun addItem(stack: ItemStack, start: Int = 0, end: Int = size - 1, simulate: Boolean = false): ItemStack {
if (stack.isEmpty || start < 0 || end >= size || start > end)
fun addItem(stack: ItemStack, range: IntRange, simulate: Boolean = false): ItemStack {
if (range.last >= size || range.first < 0)
throw IllegalArgumentException("Invalid range: $range")
if (stack.isEmpty)
return stack
val copy = stack.copy()
// двигаем в одинаковые слоты
for (slot in start .. end) {
for (slot in range) {
if (ItemStack.isSameItemSameTags(slots[slot], copy)) {
val slotStack = slots[slot]
val slotLimit = Math.min(getMaxStackSize(slot), slotStack.maxStackSize)
@ -200,7 +203,7 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
// двигаем в пустые слоты
for (slot in start .. end) {
for (slot in range) {
if (slots[slot].isEmpty) {
val diff = Math.min(copy.count, Math.min(getMaxStackSize(slot), copy.maxStackSize))
@ -222,15 +225,19 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
fun addItem(stack: ItemStack, simulate: Boolean): ItemStack {
return addItem(stack, 0, size - 1, simulate)
return addItem(stack, 0 until size, simulate)
}
@JvmOverloads
fun fullyAddItem(stack: ItemStack, start: Int = 0, end: Int = size - 1): Boolean {
if (!addItem(stack, start, end, true).isEmpty)
return fullyAddItem(stack, start .. end)
}
fun fullyAddItem(stack: ItemStack, range: IntRange): Boolean {
if (!addItem(stack, range, true).isEmpty)
return false
return addItem(stack, start, end, false).isEmpty
return addItem(stack, range, false).isEmpty
}
override fun isEmpty(): Boolean {

View File

@ -9,13 +9,39 @@ interface MatteryContainerFilter {
fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean
}
object MatteryContainerFilterOnlyIn : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return true
}
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
return false
}
}
object MatteryContainerFilterOnlyOut : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return false
}
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
return true
}
}
object MatteryContainerFilterBoth : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack): Boolean {
return true
}
override fun canExtract(slot: Int, amount: Int, stack: ItemStack): Boolean {
return true
}
}
class MatteryContainerHandler @JvmOverloads internal constructor(
private val container: MatteryContainer,
private val filter: MatteryContainerFilter = object : MatteryContainerFilter {
override fun canInsert(slot: Int, stack: ItemStack) = true
override fun canExtract(slot: Int, amount: Int, stack: ItemStack) = true
},
private val filter: MatteryContainerFilter = MatteryContainerFilterBoth,
) : IItemHandler {
private var handler = LazyOptional.of<IItemHandler> { this }

View File

@ -7,7 +7,6 @@ import net.minecraft.network.FriendlyByteBuf
import java.math.BigDecimal
import java.math.BigInteger
import java.math.MathContext
import java.nio.ByteBuffer
import kotlin.math.absoluteValue
//private fun isZero(value: BigInteger) = value == BigInteger.ZERO
@ -69,15 +68,30 @@ private fun bytesToLongBE(
)
}
const val EPSILON = 0.0000000000001
const val EPSILON = 0.000000000001
private fun cmpDouble(a: Double, b: Double): Boolean {
fun weakEqualDoubles(a: Double, b: Double): Boolean {
if (a == b)
return true
return (a - b).absoluteValue <= EPSILON
}
fun weakCompareDoubles(a: Double, b: Double): Int {
if (weakEqualDoubles(a, b))
return 0
if (a > b)
return 1
return -1
}
fun weakLessThan(a: Double, b: Double) = weakCompareDoubles(a, b) < 0
fun weakGreaterThan(a: Double, b: Double) = weakCompareDoubles(a, b) > 0
fun weakLessOrEqual(a: Double, b: Double) = weakCompareDoubles(a, b) <= 0
fun weakGreaterOrEqual(a: Double, b: Double) = weakCompareDoubles(a, b) >= 0
private val BI_INT_MAX = BigInteger.valueOf(Int.MAX_VALUE.toLong())
private val BI_INT_MIN = BigInteger.valueOf(Int.MIN_VALUE.toLong())
private val BI_LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE)
@ -163,8 +177,8 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
val a = whole
val c = other.whole
val bZero = cmpDouble(decimal, 0.0)
val dZero = cmpDouble(other.decimal, 0.0)
val bZero = weakEqualDoubles(decimal, 0.0)
val dZero = weakEqualDoubles(other.decimal, 0.0)
if (bZero && dZero) {
if (isZero(a) || isZero(c))
@ -287,7 +301,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return false
if (other is ImpreciseFraction) {
return other.whole == whole && cmpDouble(decimal, other.decimal)
return other.whole == whole && weakEqualDoubles(decimal, other.decimal)
}
return super.equals(other)
@ -356,7 +370,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return sign
}
if (cmpDouble(decimal, 0.0))
if (weakEqualDoubles(decimal, 0.0))
return 0
return if (decimal > 0.0) 1 else -1
@ -377,11 +391,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return 1
if (other.whole == whole) {
if (cmpDouble(decimal, other.decimal)) {
return 0
}
return if (other.decimal < decimal) 1 else -1
return weakCompareDoubles(decimal, other.decimal)
}
return whole.compareTo(other.whole)
@ -421,7 +431,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return ByteArrayTag(toByteArray())
}
val isZero get() = cmpDouble(decimal, 0.0) && isZero(whole)
val isZero get() = weakEqualDoubles(decimal, 0.0) && isZero(whole)
val isPositive get() = this > ZERO
val isNegative get() = this < ZERO
@ -493,7 +503,7 @@ class ImpreciseFraction @JvmOverloads constructor(whole: BigInteger, decimal: Do
return Fraction.ZERO
}
if (cmpDouble(decimal, 0.0)) {
if (weakEqualDoubles(decimal, 0.0)) {
return Fraction(whole)
}

View File

@ -43,6 +43,10 @@ class ItemMatterDust : Item(Properties().tab(OverdriveThatMatters.CREATIVE_TAB).
}
p_41423_.add(DESC2)
if (matter != null) {
p_41423_.add(DESC3)
}
}
fun addMatterValue(stack: ItemStack, matter: ImpreciseFraction, simulate: Boolean): ImpreciseFraction {
@ -70,6 +74,7 @@ class ItemMatterDust : Item(Properties().tab(OverdriveThatMatters.CREATIVE_TAB).
companion object {
private val DESC = TranslatableComponent("item.overdrive_that_matters.matter_dust.desc").withStyle(ChatFormatting.DARK_GRAY)
private val DESC2 = TranslatableComponent("item.overdrive_that_matters.matter_dust.desc2").withStyle(ChatFormatting.GRAY)
private val DESC3 = TranslatableComponent("item.overdrive_that_matters.matter_dust.desc3").withStyle(ChatFormatting.DARK_GRAY)
val MAX_MATTER_IN_ITEM = ImpreciseFraction(4)
}
}

View File

@ -1,50 +1,49 @@
package ru.dbotthepony.mc.otm.menu;
package ru.dbotthepony.mc.otm.menu
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Inventory;
import ru.dbotthepony.mc.otm.Registry;
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterReplicator;
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget;
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget;
import kotlin.jvm.JvmOverloads
import net.minecraft.world.entity.player.Inventory
import ru.dbotthepony.mc.otm.block.entity.BlockEntityMatterReplicator
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import net.minecraft.world.SimpleContainer
import ru.dbotthepony.mc.otm.Registry
public class MatterReplicatorMenu extends MenuMatteryPowered {
public MatterReplicatorMenu(int p_38852_, Inventory inventory) {
this(p_38852_, inventory, null);
}
class MenuMatterReplicator @JvmOverloads constructor(
p_38852_: Int,
inventory: Inventory,
tile: BlockEntityMatterReplicator? = null
) : MenuMatteryPowered(
Registry.Menus.MATTER_REPLICATOR, p_38852_, inventory, tile
) {
val matter: LevelGaugeWidget
val progress: ProgressGaugeWidget
val outputSlots: Array<MachineOutputSlot>
public LevelGaugeWidget matter_widget;
public ProgressGaugeWidget progress;
public MachineOutputSlot[] output_slots = new MachineOutputSlot[3];
init {
val container = tile?.container ?: SimpleContainer(5)
public MatterReplicatorMenu(int p_38852_, Inventory inventory, BlockEntityMatterReplicator tile) {
super(Registry.Menus.MATTER_REPLICATOR, p_38852_, inventory, tile);
Container container = tile != null ? tile.regularSlots : new SimpleContainer(3);
for (int i = 0; i < container.getContainerSize(); i++) {
output_slots[i] = new MachineOutputSlot(container, i, 64 + 18 * i, 38);
addSlot(output_slots[i]);
outputSlots = Array(5) {
val slot = MachineOutputSlot(container, it)
addSlot(slot)
return@Array slot
}
if (tile != null) {
matter_widget = new LevelGaugeWidget(this, tile.matter);
progress = new ProgressGaugeWidget(this, () -> (float) tile.getWorkProgress(), tile::isUnableToProcess);
matter = LevelGaugeWidget(this, tile.matter)
progress = ProgressGaugeWidget(this, tile::workProgress, tile::isUnableToProcess)
} else {
matter_widget = new LevelGaugeWidget(this);
progress = new ProgressGaugeWidget(this);
matter = LevelGaugeWidget(this)
progress = ProgressGaugeWidget(this)
}
addInventorySlots();
addInventorySlots()
}
@Override
protected int getWorkingSlotStart() {
return 0;
override fun getWorkingSlotStart(): Int {
return 0
}
@Override
protected int getWorkingSlotEnd() {
return 5;
override fun getWorkingSlotEnd(): Int {
return 5
}
}
}

View File

@ -235,6 +235,7 @@
"item.overdrive_that_matters.matter_dust": "Matter Dust",
"item.overdrive_that_matters.matter_dust.desc": "This item is product of failed decomposition or replication attempt",
"item.overdrive_that_matters.matter_dust.desc2": "Throw into matter recycler to get some of it's value back!",
"item.overdrive_that_matters.matter_dust.desc3": "Do not smell, throw at strangers or pour on donuts",
"item.overdrive_that_matters.portable_condensation_drive": "Portable Condensation Drive",
"item.overdrive_that_matters.portable_dense_condensation_drive": "Portable Dense Condensation Drive",