Compare commits

...

5 Commits

8 changed files with 111 additions and 20 deletions

View File

@ -1624,7 +1624,7 @@ class MatteryPlayer(val ply: Player) {
@JvmStatic
fun inventoryClearContent(inventory: Inventory) {
val mattery = inventory.player.matteryPlayer ?: return
val mattery = inventory.player.matteryPlayer
if (!mattery.hasExopack) {
return
@ -1632,7 +1632,8 @@ class MatteryPlayer(val ply: Player) {
mattery.exopackContainer.clearContent()
mattery.exopackChargeSlots.clearContent()
// mattery.exoPackEnergy.parent.clearContent()
mattery.exopackEnergy.parent.clearContent()
mattery.exopackEnergy.parent.drainBattery()
for (smelter in mattery.smelters) {
smelter.input.clearContent()

View File

@ -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.
*/

View File

@ -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()

View File

@ -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))
}
}
}

View File

@ -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
@ -44,6 +46,7 @@ class EnergyCounterScreen(menu: EnergyCounterMenu, inventory: Inventory, title:
val current = i++
val button = CheckBoxLabelInputPanel(this, tab.canvas, menu.displayChartOnBlock.map({ it == current }, { current }), TranslatableComponent("block.overdrive_that_matters.energy_counter.display_this"))
button.dock = Dock.BOTTOM
button.dockTop = 2f
}
}
@ -84,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)

View File

@ -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()
}
}

View File

@ -48,7 +48,7 @@ class MatterDustItem : Item(Properties().stacksTo(64)), IMatterItem {
companion object {
val CODEC: MapCodec<Randomizer> = RecordCodecBuilder.mapCodec {
it.group(
DecimalProvider.CODEC.fieldOf("slots").forGetter(Randomizer::matter),
DecimalProvider.CODEC.fieldOf("matter").forGetter(Randomizer::matter),
IntProvider.CODEC.optionalFieldOf("luck_bias", ConstantInt.ZERO).forGetter(Randomizer::luckBias),
).apply(it, ::Randomizer)
}

View File

@ -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>()