Button for manual stored experience drain from machine

This commit is contained in:
DBotThePony 2025-01-06 16:45:03 +07:00
parent c5edd9ff59
commit 65cbaf95b1
Signed by: DBot
GPG Key ID: DCC23B5715498507
12 changed files with 134 additions and 6 deletions

View File

@ -1025,7 +1025,9 @@ private fun gui(provider: MatteryLanguageProvider) {
gui("matter_panel.complexity", "Total complexity: %s")
gui("experience", "%s experience points")
gui("experience_with_limit", "%s / %s experience points")
gui("experience_levels", "%s experience levels")
gui("experience_levels_with_limit", "%s / %s experience levels")
gui("experience.store", "Store %s experience levels")
gui("experience.store_all", "Store all experience levels")

View File

@ -1022,7 +1022,9 @@ private fun gui(provider: MatteryLanguageProvider) {
gui("matter_panel.complexity", "Общая сложность: %s")
gui("experience", "%s очков опыта")
gui("experience_with_limit", "%s / %s очков опыта")
gui("experience_levels", "%s уровней опыта")
gui("experience_levels_with_limit", "%s / %s уровней опыта")
gui("experience.store", "Передать %s уровней опыта")
gui("experience.store_all", "Передать все уровни опыта")

View File

@ -9,6 +9,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel
@ -55,6 +56,8 @@ class GrillScreen(menu: GrillMenu, inventory: Inventory, title: Component) : Mat
frame.sizeToContents()
DeviceControls(this, frame, experience = menu.experience)
return frame
}
}

View File

@ -71,7 +71,7 @@ class MatterEntanglerScreen(menu: MatterEntanglerMenu, inventory: Inventory, tit
it.dockRight = 20f
}
DeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, upgrades = menu.upgrades, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig)
DeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, upgrades = menu.upgrades, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, experience = menu.experience)
return frame
}

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.screen.panels.button
import com.mojang.blaze3d.platform.InputConstants
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
@ -29,12 +30,14 @@ import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.util.GridPanel
import ru.dbotthepony.mc.otm.client.screen.tech.EssenceStorageScreen
import ru.dbotthepony.mc.otm.config.ClientConfig
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.immutableList
import ru.dbotthepony.mc.otm.core.math.RelativeSide
import ru.dbotthepony.mc.otm.core.util.ItemStackSorter
import ru.dbotthepony.mc.otm.core.util.getLevelFromXp
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.UpgradeSlots
@ -43,9 +46,15 @@ import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.FluidConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.IPlayerInputWithFeedback
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import java.util.*
import java.util.function.IntConsumer
import java.util.function.Predicate
import kotlin.NoSuchElementException
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.math.ceil
import kotlin.math.max
import kotlin.math.pow
private val gunpowder = ItemStackIcon(ItemStack(Items.GUNPOWDER)).fixed()
@ -314,6 +323,7 @@ class DeviceControls<out S : MatteryScreen<*>>(
val fluidConfig: FluidConfigPlayerInput? = null,
val balanceInputs: BooleanInputWithFeedback? = null,
val upgrades: UpgradeSlots? = null,
val experience: TakeExperienceWidget? = null
) : EditablePanel<S>(screen, parent, x = parent.width + 3f, height = 0f, width = 0f) {
val itemConfigButton: ButtonPanel<S>?
val energyConfigButton: ButtonPanel<S>?
@ -321,6 +331,7 @@ class DeviceControls<out S : MatteryScreen<*>>(
val redstoneControlsButton: EnumButtonPanel<S, RedstoneSetting>?
val balanceInputsButton: BooleanButtonPanel<S>?
val upgradesButton: ButtonPanel<S>?
val experienceButton: ButtonPanel<S>?
init {
childrenOrder = -1000
@ -334,14 +345,35 @@ class DeviceControls<out S : MatteryScreen<*>>(
buttons.removeIf { it.isRemoved || it.parent != this }
var y = 0f
var x = 0f
var currentWidth = 0f
var totalWidth = 0f
var totalHeight = 0f
for (button in buttons) {
button.setPos(button.dockLeft, y + button.dockTop)
if (y != 0f && button.height + y > parent!!.height) {
totalHeight = totalHeight.coerceAtLeast(y - 2f)
y = 0f
x += currentWidth + 2f
totalWidth += currentWidth
currentWidth = 0f
}
button.setPos(x + button.dockLeft, y + button.dockTop)
y += button.height + button.dockMargin.vertical + 2f
width = width.coerceAtLeast(button.width + button.dockMargin.horizontal)
currentWidth = currentWidth.coerceAtLeast(button.width + button.dockMargin.horizontal)
}
height = height.coerceAtLeast(y - 2f)
if (currentWidth != 0f) {
totalWidth += currentWidth
}
if (y != 0f) {
totalHeight = totalHeight.coerceAtLeast(y - 2f)
}
width = max(totalWidth, width)
height = max(totalHeight, height)
}
fun removeButton(button: EditablePanel<*>) {
@ -633,6 +665,68 @@ class DeviceControls<out S : MatteryScreen<*>>(
} else {
fluidConfigButton = null
}
if (experience != null) {
experienceButton = addButton(ExperienceButton(experience))
} else {
experienceButton = null
}
}
private inner class ExperienceButton(val widget: TakeExperienceWidget) : ButtonPanel<S>(this@DeviceControls.screen, this@DeviceControls, 0f, 0f, 18f, 18f) {
override fun onClick(mouseButton: Int) {
widget.input.accept(null)
}
override val icon: IGUIRenderable
get() = EssenceStorageScreen.DISPENSE_ALL
override var isDisabled: Boolean
get() = !widget.input.test(minecraft.player!!)
set(value) {}
override fun innerRenderTooltips(
graphics: MGUIGraphics,
mouseX: Float,
mouseY: Float,
partialTick: Float
): Boolean {
if (widget.maxAmount.get().isInfinite()) {
if (minecraft.window.isShiftDown) {
graphics.renderComponentTooltip(
font,
listOf(TranslatableComponent("otm.gui.experience_levels", getLevelFromXp(widget.amount.get().toLong()).toString())),
mouseX.toInt(),
mouseY.toInt()
)
} else {
graphics.renderComponentTooltip(
font,
listOf(TranslatableComponent("otm.gui.experience", "%.1f".format(Locale.ROOT, widget.amount.get()))),
mouseX.toInt(),
mouseY.toInt()
)
}
} else {
if (minecraft.window.isShiftDown) {
graphics.renderComponentTooltip(
font,
listOf(TranslatableComponent("otm.gui.experience_levels_with_limit", getLevelFromXp(widget.amount.get().toLong()).toString(), "~" + getLevelFromXp(widget.maxAmount.get().toLong()).toString())),
mouseX.toInt(),
mouseY.toInt()
)
} else {
graphics.renderComponentTooltip(
font,
listOf(TranslatableComponent("otm.gui.experience_with_limit", "%.1f".format(Locale.ROOT, widget.amount.get()), widget.maxAmount.get().toString())),
mouseX.toInt(),
mouseY.toInt()
)
}
}
return true
}
}
override fun preRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {

View File

@ -8,7 +8,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.DockResizeMode
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel
import ru.dbotthepony.mc.otm.client.screen.panels.ScrollbarBackgroundPanel
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.button.DeviceControls
import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.BatterySlotPanel
import ru.dbotthepony.mc.otm.client.screen.panels.slot.SlotPanel
@ -66,7 +66,7 @@ open class AbstractProcessingMachineScreen<M : AbstractProcessingMachineMenu>(me
}
}
makeDeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, balanceInputs = menu.balanceInputs, upgrades = menu.upgrades)
DeviceControls(this, frame, redstoneConfig = menu.redstoneConfig, energyConfig = menu.energyConfig, itemConfig = menu.itemConfig, balanceInputs = menu.balanceInputs, upgrades = menu.upgrades, experience = menu.experience)
if (isJeiLoaded) {
val recipeTypes = menu.recipeTypes

View File

@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.menu.MatterySlot
import ru.dbotthepony.mc.otm.menu.OutputSlot
import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.widget.IProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import ru.dbotthepony.mc.otm.registry.MMenus
import java.util.function.Supplier
@ -69,6 +70,8 @@ class GrillMenu(
override val totalTicks: Int by mSynchronizer.computedInt(Supplier { tile?.fuelTotalTicks ?: 0 })
}
val experience = TakeExperienceWidget(this, tile?.experience)
init {
addInventorySlots()
addStorageSlot(fuelSlot)

View File

@ -26,6 +26,7 @@ import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots
import ru.dbotthepony.mc.otm.menu.widget.LevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import ru.dbotthepony.mc.otm.registry.MMenus
import ru.dbotthepony.mc.otm.registry.MRecipes
import java.util.*
@ -62,6 +63,7 @@ class MatterEntanglerMenu(
val outputs = makeSlots(tile?.output ?: SimpleContainer(1)) { a, b -> OutputSlot(a, b) { tile?.experience?.popExperience(player as ServerPlayer) } }
val upgrades = makeUpgradeSlots(3, tile?.upgrades)
val experience = TakeExperienceWidget(this, tile?.experience)
private val entangling: Container = if (tile == null) object : SimpleContainer(2) {
override fun getMaxStackSize(): Int {

View File

@ -12,6 +12,7 @@ import ru.dbotthepony.mc.otm.menu.input.EnergyConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.input.ItemConfigPlayerInput
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import java.util.function.Supplier
abstract class AbstractProcessingMachineMenu(
@ -33,6 +34,7 @@ abstract class AbstractProcessingMachineMenu(
abstract val profiledEnergy: ProfiledLevelGaugeWidget<*>
abstract val balanceInputs: BooleanInputWithFeedback?
abstract val upgrades: UpgradeSlots?
abstract val experience: TakeExperienceWidget?
open val recipeTypes: Supplier<List<RecipeType<*>>>?
get() = null

View File

@ -19,6 +19,7 @@ import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import ru.dbotthepony.mc.otm.registry.MMenus
import java.util.function.Supplier
@ -39,6 +40,7 @@ class PlatePressMenu(
override val balanceInputs = if (isTwin) BooleanInputWithFeedback(this) else null
override val upgrades = makeUpgradeSlots(if (isTwin) 4 else 3, tile?.upgrades)
override val experience = TakeExperienceWidget(this, tile?.experience)
override val processingTuples: List<ProcessingTuple> = immutableList(if (isTwin) 2 else 1) {
ProcessingTuple(inputSlots[it], outputSlots[it], gauges[it])

View File

@ -23,6 +23,7 @@ import ru.dbotthepony.mc.otm.menu.makeSlots
import ru.dbotthepony.mc.otm.menu.makeUpgradeSlots
import ru.dbotthepony.mc.otm.menu.widget.ProfiledLevelGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.ProgressGaugeWidget
import ru.dbotthepony.mc.otm.menu.widget.TakeExperienceWidget
import ru.dbotthepony.mc.otm.registry.MMenus
import java.util.function.Supplier
@ -41,6 +42,7 @@ class PoweredFurnaceMenu(
override val profiledEnergy = ProfiledLevelGaugeWidget(this, tile?.energy, energyWidget)
override val balanceInputs = BooleanInputWithFeedback(this)
override val upgrades = makeUpgradeSlots(2, tile?.upgrades)
override val experience = TakeExperienceWidget(this, tile?.experience)
override val processingTuples: List<ProcessingTuple> = immutableList(2) {
ProcessingTuple(inputSlots[it], outputSlots[it], progressGauge[it])

View File

@ -0,0 +1,16 @@
package ru.dbotthepony.mc.otm.menu.widget
import net.minecraft.server.level.ServerPlayer
import ru.dbotthepony.mc.otm.block.entity.ExperienceStorage
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import java.util.function.DoubleSupplier
class TakeExperienceWidget(menu: MatteryMenu, storage: ExperienceStorage?) {
val input = menu.oneWayInput { storage!!.popExperience(menu.player as ServerPlayer) }
val amount = menu.mSynchronizer.computedDouble(DoubleSupplier { storage?.experience ?: 0.0 })
val maxAmount = menu.mSynchronizer.computedDouble(DoubleSupplier { storage?.maxExperience?.asDouble ?: Double.MAX_VALUE })
init {
input.filter { amount.get() >= 1.0 }
}
}