Energy counter limit input using panel instead of widget
This commit is contained in:
parent
064fbd0f36
commit
b80da0e214
@ -13,6 +13,7 @@ import net.minecraft.client.gui.navigation.ScreenRectangle
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.renderer.Rect2i
|
||||
import net.minecraft.network.chat.Component
|
||||
import net.minecraft.util.RandomSource
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import ru.dbotthepony.mc.otm.SystemTime
|
||||
import ru.dbotthepony.mc.otm.client.CursorType
|
||||
@ -134,6 +135,14 @@ open class EditablePanel<out S : Screen>(
|
||||
}
|
||||
}
|
||||
|
||||
val random: RandomSource by lazy {
|
||||
if (screen is MatteryScreen<*>) {
|
||||
screen.menu.random
|
||||
} else {
|
||||
RandomSource.create()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bigger values means lesser priority while docking, rendering and processing inputs.
|
||||
*/
|
||||
|
@ -200,6 +200,10 @@ open class TextInputPanel<out S : Screen>(
|
||||
snapshotTimer = null
|
||||
redo.clear()
|
||||
}
|
||||
|
||||
if (!isFocusedThis && snapshotTimer == null) {
|
||||
idleCallback?.invoke()
|
||||
}
|
||||
}
|
||||
|
||||
private fun pushbackSnapshot() {
|
||||
@ -1062,6 +1066,8 @@ open class TextInputPanel<out S : Screen>(
|
||||
return characterFilter?.acceptsCharacter(codepoint, mods, index) ?: true
|
||||
}
|
||||
|
||||
protected var rejectCharacterTimer: Long? = null
|
||||
|
||||
override fun charTypedInternal(codepoint: Char, mods: Int): Boolean {
|
||||
if (!isActive) {
|
||||
killFocus()
|
||||
@ -1087,6 +1093,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
|
||||
if (!acceptsCharacter(codepoint, mods, index)) {
|
||||
playGuiClickSound()
|
||||
rejectCharacterTimer = milliTime + SHAKE_MILLIS
|
||||
return true
|
||||
}
|
||||
|
||||
@ -1145,6 +1152,19 @@ open class TextInputPanel<out S : Screen>(
|
||||
|
||||
val selectedLine = this[cursorLine]
|
||||
|
||||
val shakeX: Float
|
||||
val shakeY: Float
|
||||
|
||||
if (rejectCharacterTimer != null && rejectCharacterTimer!! > milliTime) {
|
||||
val strength = (rejectCharacterTimer!! - milliTime).toFloat() / SHAKE_MILLIS.toFloat()
|
||||
shakeX = (random.nextFloat() - 0.5f) * strength
|
||||
shakeY = (random.nextFloat() - 0.5f) * strength
|
||||
} else {
|
||||
rejectCharacterTimer = null
|
||||
shakeX = 0f
|
||||
shakeY = 0f
|
||||
}
|
||||
|
||||
if (selectedLine != null) {
|
||||
val w = width(selectedLine, end = cursorRow) - scrollPixels
|
||||
|
||||
@ -1162,14 +1182,14 @@ open class TextInputPanel<out S : Screen>(
|
||||
stack.pushPose()
|
||||
stack.translate(-scrollPixels, 0f, 0f)
|
||||
|
||||
var y = topPadding
|
||||
var y = topPadding + shakeY
|
||||
|
||||
if (lines.isEmpty() || lines.size == 1 && lines[0] == "") {
|
||||
graphics.draw(
|
||||
font = font,
|
||||
text = placeholder,
|
||||
gravity = RenderGravity.TOP_LEFT,
|
||||
x = dockPadding.left,
|
||||
x = dockPadding.left + shakeX,
|
||||
y = y,
|
||||
color = placeholderColor
|
||||
)
|
||||
@ -1182,7 +1202,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
graphics.draw(
|
||||
text = line,
|
||||
gravity = RenderGravity.TOP_LEFT,
|
||||
x = dockPadding.left,
|
||||
x = dockPadding.left + shakeX,
|
||||
y = y,
|
||||
color = textColor
|
||||
)
|
||||
@ -1190,7 +1210,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
if (selection != null && selection.isValid) {
|
||||
val (before, selected) = selection.sub(line)
|
||||
|
||||
var x = dockPadding.left
|
||||
var x = dockPadding.left + shakeX
|
||||
|
||||
if (before.isNotEmpty()) {
|
||||
x += font.width(before).toFloat()
|
||||
@ -1233,16 +1253,16 @@ open class TextInputPanel<out S : Screen>(
|
||||
graphics.draw(
|
||||
text = "_",
|
||||
gravity = RenderGravity.TOP_LEFT,
|
||||
x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()),
|
||||
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
|
||||
x = dockPadding.left + (if (activeLine == null) 0f else font.width(activeLine).toFloat()) + shakeX,
|
||||
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing) + shakeY,
|
||||
color = cursorColor
|
||||
)
|
||||
} else {
|
||||
graphics.draw(
|
||||
text = "|",
|
||||
gravity = RenderGravity.TOP_LEFT,
|
||||
x = dockPadding.left + font.width(activeLine.substring(0, cursorRow)).toFloat() - 1f,
|
||||
y = topPadding + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
|
||||
x = dockPadding.left + font.width(activeLine.substring(0, cursorRow)).toFloat() - 1f + shakeX,
|
||||
y = topPadding + shakeY + (cursorLine - scrollLines) * (font.lineHeight + rowSpacing),
|
||||
color = cursorColor
|
||||
)
|
||||
}
|
||||
@ -1393,11 +1413,16 @@ open class TextInputPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
protected var changeCallback: ((new: String, old: String) -> Unit)? = null
|
||||
protected var idleCallback: (() -> Unit)? = null
|
||||
|
||||
fun onTextChange(callback: (new: String, old: String) -> Unit) {
|
||||
changeCallback = callback
|
||||
}
|
||||
|
||||
fun onIdle(callback: () -> Unit) {
|
||||
idleCallback = callback
|
||||
}
|
||||
|
||||
private enum class CharType {
|
||||
SPACES {
|
||||
override fun contains(input: Char): Boolean {
|
||||
@ -1446,6 +1471,7 @@ open class TextInputPanel<out S : Screen>(
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val SHAKE_MILLIS = 600L
|
||||
val NEWLINES = Regex("\r?\n")
|
||||
private val BUFFER = DynamicBufferSource()
|
||||
|
||||
|
@ -34,9 +34,11 @@ import ru.dbotthepony.mc.otm.client.screen.widget.WideProfiledPowerGaugePanel
|
||||
import ru.dbotthepony.mc.otm.config.MachinesConfig
|
||||
import ru.dbotthepony.kommons.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.capability.matteryPlayer
|
||||
import ru.dbotthepony.mc.otm.core.RandomSource2Generator
|
||||
import ru.dbotthepony.mc.otm.menu.tech.AndroidStationMenu
|
||||
import ru.dbotthepony.mc.otm.network.AndroidResearchRequestPacket
|
||||
import java.util.*
|
||||
import java.util.random.RandomGenerator
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
@ -440,8 +442,8 @@ private class AndroidResearchButton(
|
||||
}
|
||||
|
||||
private enum class PreviewScrollers(
|
||||
val init: (EditablePanel<*>, Random) -> Unit,
|
||||
val scroll: (EditablePanel<*>, Random) -> Boolean
|
||||
val init: (EditablePanel<*>, RandomGenerator) -> Unit,
|
||||
val scroll: (EditablePanel<*>, RandomGenerator) -> Boolean
|
||||
) {
|
||||
LEFT_TO_RIGHT(
|
||||
init = { it, random ->
|
||||
@ -499,8 +501,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
||||
val rows = Int2ObjectOpenHashMap<EditablePanel<AndroidStationScreen>>()
|
||||
|
||||
val canvas = object : DraggableCanvasPanel<AndroidStationScreen>(this@AndroidStationScreen, null) {
|
||||
private val random = Random()
|
||||
private var scroller: PreviewScrollers = PreviewScrollers.values().let { it[random.nextInt(it.size)] }
|
||||
private var scroller: PreviewScrollers = PreviewScrollers.entries.let { it[random.nextInt(it.size)] }
|
||||
private var firstTick = false
|
||||
|
||||
override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
|
||||
@ -522,14 +523,14 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
|
||||
|
||||
if (isPreview && !layoutInvalidated) {
|
||||
if (firstTick) {
|
||||
scroller.init.invoke(this, random)
|
||||
scroller.init.invoke(this, RandomSource2Generator(random))
|
||||
}
|
||||
|
||||
val status = scroller.scroll.invoke(this, random)
|
||||
val status = scroller.scroll.invoke(this, RandomSource2Generator(random))
|
||||
|
||||
if (!status) {
|
||||
scroller = PreviewScrollers.values().let { it[random.nextInt(it.size)] }
|
||||
scroller.init.invoke(this, random)
|
||||
scroller = PreviewScrollers.entries.let { it[random.nextInt(it.size)] }
|
||||
scroller.init.invoke(this, RandomSource2Generator(random))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.CheckBoxLabelInputPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.button.makeDeviceControls
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.input.NetworkNumberInputPanel
|
||||
import ru.dbotthepony.mc.otm.client.screen.panels.input.TextInputPanel
|
||||
import ru.dbotthepony.mc.otm.core.math.Decimal
|
||||
import ru.dbotthepony.mc.otm.core.util.formatPower
|
||||
import ru.dbotthepony.mc.otm.menu.tech.EnergyCounterMenu
|
||||
|
||||
@ -85,9 +87,28 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
|
||||
it.dockTop = 10f
|
||||
}
|
||||
|
||||
NetworkNumberInputPanel(this, limitsTab.canvas, widget = menu.maxIOInput, networkValue = menu::maxIO).also {
|
||||
TextInputPanel(this, limitsTab.canvas).also {
|
||||
it.dock = Dock.TOP
|
||||
it.dockTop = 4f
|
||||
|
||||
it.allowNumbersAndSign()
|
||||
it.onTextChange { new, old ->
|
||||
try {
|
||||
var value = Decimal(new)
|
||||
|
||||
if (value < Decimal.ZERO)
|
||||
value = Decimal.MINUS_ONE
|
||||
|
||||
if (value != menu.maxIOInput)
|
||||
menu.maxIOInput.accept(value)
|
||||
} catch (err: NumberFormatException) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
it.onIdle {
|
||||
it.text = menu.maxIO.toString()
|
||||
}
|
||||
}
|
||||
|
||||
makeDeviceControls(this, frame, redstoneConfig = menu.redstone)
|
||||
|
@ -0,0 +1,30 @@
|
||||
package ru.dbotthepony.mc.otm.core
|
||||
|
||||
import net.minecraft.util.RandomSource
|
||||
import java.util.random.RandomGenerator
|
||||
|
||||
class RandomSource2Generator(private val parent: RandomSource) : RandomGenerator {
|
||||
override fun nextLong(): Long {
|
||||
return parent.nextLong()
|
||||
}
|
||||
|
||||
override fun nextInt(): Int {
|
||||
return parent.nextInt()
|
||||
}
|
||||
|
||||
override fun nextFloat(): Float {
|
||||
return parent.nextFloat()
|
||||
}
|
||||
|
||||
override fun nextDouble(): Double {
|
||||
return parent.nextDouble()
|
||||
}
|
||||
|
||||
override fun nextBoolean(): Boolean {
|
||||
return parent.nextBoolean()
|
||||
}
|
||||
|
||||
override fun nextGaussian(): Double {
|
||||
return parent.nextGaussian()
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import net.minecraft.network.RegistryFriendlyByteBuf
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload
|
||||
import net.minecraft.resources.ResourceLocation
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.util.RandomSource
|
||||
import net.minecraft.world.Container
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
@ -78,6 +79,7 @@ abstract class MatteryMenu(
|
||||
val mSynchronizer = Syncher()
|
||||
val synchronizerRemote = mSynchronizer.Remote()
|
||||
val player: Player get() = inventory.player
|
||||
val random: RandomSource = RandomSource.create()
|
||||
|
||||
private val _playerInventorySlots = ArrayList<InventorySlot>()
|
||||
private val _playerHotbarSlots = ArrayList<InventorySlot>()
|
||||
|
Loading…
Reference in New Issue
Block a user