From 03c04178e7ebf542f6be640003a41170ef33475a Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sun, 30 Jan 2022 16:43:30 +0700 Subject: [PATCH] Failure chance in matter replicator, fix tick precision in worker, various fixes --- .../java/ru/dbotthepony/mc/otm/Registry.java | 3 +- .../entity/BlockEntityMatterDecomposer.kt | 104 ++++++++++-------- .../entity/BlockEntityMatterReplicator.kt | 44 ++++++-- .../block/entity/BlockEntityMatterScanner.kt | 6 +- .../entity/worker/BlockEntityMatteryWorker.kt | 15 ++- .../mc/otm/block/entity/worker/WorkerLogic.kt | 4 +- .../client/screen/ScreenMatterReplicator.kt | 15 ++- .../mc/otm/container/MatteryContainer.kt | 21 ++-- .../otm/container/MatteryContainerHandler.kt | 36 +++++- .../mc/otm/core/ImpreciseFraction.kt | 38 ++++--- .../dbotthepony/mc/otm/item/ItemMatterDust.kt | 5 + .../mc/otm/menu/MenuMatterReplicator.kt | 69 ++++++------ .../overdrive_that_matters/lang/en_us.json | 1 + 13 files changed, 225 insertions(+), 136 deletions(-) diff --git a/src/main/java/ru/dbotthepony/mc/otm/Registry.java b/src/main/java/ru/dbotthepony/mc/otm/Registry.java index a3e0b32dc..d9dbec09a 100644 --- a/src/main/java/ru/dbotthepony/mc/otm/Registry.java +++ b/src/main/java/ru/dbotthepony/mc/otm/Registry.java @@ -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 PATTERN_STORAGE = new MenuType<>(MenuPatternStorage::new); public static final MenuType MATTER_SCANNER = new MenuType<>(MenuMatterScanner::new); public static final MenuType MATTER_PANEL = new MenuType<>(MenuMatterPanel::new); - public static final MenuType MATTER_REPLICATOR = new MenuType<>(MatterReplicatorMenu::new); + public static final MenuType MATTER_REPLICATOR = new MenuType<>(MenuMatterReplicator::new); public static final MenuType MATTER_BOTTLER = new MenuType<>(MenuMatterBottler::new); public static final MenuType DRIVE_VIEWER = new MenuType<>(MenuDriveViewer::new); public static final MenuType CARGO_CRATE = new MenuType<>(MenuCargoCrate::new); diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt index 93b7e7fa7..17c65f627 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterDecomposer.kt @@ -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() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt index 9fc51e31f..15c4f36fe 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterReplicator.kt @@ -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 } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt index 5e80cea9c..c7d56469f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/BlockEntityMatterScanner.kt @@ -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) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt index 97b662717..e87979e81 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/BlockEntityMatteryWorker.kt @@ -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) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/WorkerLogic.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/WorkerLogic.kt index 67d60b2da..87c73438d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/WorkerLogic.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/worker/WorkerLogic.kt @@ -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( diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ScreenMatterReplicator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ScreenMatterReplicator.kt index 329e0c469..43c934843 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ScreenMatterReplicator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ScreenMatterReplicator.kt @@ -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(p_97741_, p_97742_, p_97743_) { +class ScreenMatterReplicator(p_97741_: MenuMatterReplicator, p_97742_: Inventory, p_97743_: Component) : + MatteryScreen(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 } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index 314d4f164..0cb52e245 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -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 { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.kt index 69b68d68f..4d624392c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainerHandler.kt @@ -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 { this } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt index 29e950b24..b5457904c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/ImpreciseFraction.kt @@ -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) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterDust.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterDust.kt index dffd50c9d..278d8a7f1 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterDust.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/ItemMatterDust.kt @@ -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) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterReplicator.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterReplicator.kt index d590417b9..b9825a024 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterReplicator.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/MenuMatterReplicator.kt @@ -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 - 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 } -} +} \ No newline at end of file diff --git a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json index a0bcfc300..ed00092bd 100644 --- a/src/main/resources/assets/overdrive_that_matters/lang/en_us.json +++ b/src/main/resources/assets/overdrive_that_matters/lang/en_us.json @@ -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",