Failure chance in matter replicator, fix tick precision in worker, various fixes
This commit is contained in:
parent
052a29d005
commit
03c04178e7
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user