Attempting to research something that will block other research now requires confirmation

This commit is contained in:
DBotThePony 2022-09-22 22:48:03 +07:00
parent 5e95a97704
commit 672441021d
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 239 additions and 11 deletions

View File

@ -51,6 +51,9 @@ private fun sounds(provider: MatteryLanguageProvider) {
private fun misc(provider: MatteryLanguageProvider) {
with(provider.english) {
gui("cancel", "Cancel")
gui("confirm", "Confirm")
gui("recipe.ticks", "%s Ticks")
gui("exosuit", "Exosuit Inventory")
@ -236,6 +239,9 @@ private fun misc(provider: MatteryLanguageProvider) {
misc("android_station.research.item", "Requires %s x%s")
misc("android_station.research.missing_predecessors", "%s needs to be researched first")
misc("android_station.research.confirm", "Confirm researching %s")
misc("android_station.research.research_will_be_blocked", "Next research will be blocked:")
misc("android_station.low_power_0", "Not enough power; Can't swap parts")
misc("android_station.low_power_1", "Low power; Can't research")
misc("android_station.power_ok", "Power OK")

View File

@ -257,8 +257,8 @@ private class AndroidResearchButton(
parent,
0f,
0f,
AndroidStationScreen.BUTTON_SIZE.toFloat(),
AndroidStationScreen.BUTTON_SIZE.toFloat()
AndroidStationScreen.BUTTON_SIZE,
AndroidStationScreen.BUTTON_SIZE
) {
init {
setDockMargin(2f, 2f, 2f, 2f)
@ -267,19 +267,19 @@ private class AndroidResearchButton(
override fun onHovered() {
super.onHovered()
(screen as AndroidStationScreen).hoveredResearch = node
screen.hoveredResearch = node
}
override fun onUnHovered() {
super.onUnHovered()
if ((screen as AndroidStationScreen).hoveredResearch == node) {
if (screen.hoveredResearch == node) {
screen.hoveredResearch = null
}
}
override fun innerRender(stack: PoseStack, mouseX: Float, mouseY: Float, partialTick: Float) {
val hovered = (screen as AndroidStationScreen).hoveredResearch
val hovered = screen.hoveredResearch
val isBlockedByHovered = hovered != null && node.type in hovered.type.allBlocking
@ -379,7 +379,20 @@ private class AndroidResearchButton(
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
if (button == InputConstants.MOUSE_BUTTON_LEFT && minecraft.player?.isSpectator != true) {
if (node.canResearch && !node.isResearched && (parent?.screen as AndroidStationScreen).menu.powerWidget.level >= AndroidStationBlockEntity.ENERGY_PER_RESEARCH) {
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
if (node.type.flatBlocking.isNotEmpty()) {
queryUser(
TranslatableComponent("otm.android_station.research.confirm", node.type.displayName),
listOf(
TranslatableComponent("otm.android_station.research.research_will_be_blocked"),
*node.type.flatBlocking.map { it.displayName }.toTypedArray()
),
onConfirm = {
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
}
)
} else {
MatteryPlayerNetworkChannel.sendToServer(AndroidResearchRequestPacket(node.type))
}
}
playGuiClickSound()
@ -593,7 +606,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
bottom.dock = Dock.BOTTOM
close.dock = Dock.LEFT
close.dock = Dock.RIGHT
close.bind { research!!.remove() }
bottom.setDockMargin(0f, 0f, 4f, 4f)
@ -686,7 +699,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
companion object {
const val GRID_WIDTH = 5
const val BUTTON_SIZE = 18
const val BUTTON_SIZE = 18f
val RESEARCHED = RGBAColor(150, 150, 200)
val CAN_BE_RESEARCHED = RGBAColor(150, 200, 150)
val CAN_NOT_BE_RESEARCHED = RGBAColor(200, 150, 150)
@ -696,4 +709,4 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I
private val LOW_POWER_1 = TranslatableComponent("otm.android_station.low_power_1")
private val POWER_OK = TranslatableComponent("otm.android_station.power_ok")
}
}
}

View File

@ -77,6 +77,19 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
value?.onParent(this)
}
val topMostParent: EditablePanel<*>?
get() {
var parent = parent
var parent2 = parent
while (parent2 != null) {
parent = parent2
parent2 = parent.parent
}
return parent
}
var x: Float = 0f
set(value) {
if (field == value) return
@ -282,6 +295,98 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
field = value
}
var blockingWindow: EditablePanel<*>? = null
get() {
if (field?.isRemoved != true) {
return field
}
return null
}
var flashingSince: Long = Long.MIN_VALUE
private set
var isFlashing: Boolean
get() = flashingSince != Long.MIN_VALUE && (System.nanoTime() - flashingSince) <= 1_000_000_000
set(value) {
if (value) {
flashingSince = System.nanoTime()
} else {
flashingSince = Long.MIN_VALUE
}
}
fun flash() {
isFlashing = true
if (parent == null) {
popup()
}
}
val isFlashFrame: Boolean
get() = isFlashing && (System.nanoTime() - flashingSince) % 400_000_000 <= 200_000_000
val isFlashFrameRecursive: Boolean
get() {
if (isFlashFrame) {
return true
}
var parent = parent
while (parent != null) {
if (parent.isFlashFrame) {
return true
}
parent = parent.parent
}
return false
}
private fun flashAnyBlockerInner(doFlash: Boolean): Boolean {
val blockingWindow = blockingWindow
if (blockingWindow != null) {
if (doFlash) {
blockingWindow.flash()
}
return true
}
for (children in children) {
if (children.flashAnyBlockerInner(doFlash)) {
return true
}
}
return false
}
protected fun flashAnyBlocker(doFlash: Boolean = true): Boolean {
var blockingWindow = blockingWindow
var parent = parent
while (blockingWindow == null && parent != null) {
blockingWindow = parent.blockingWindow
parent = parent.parent
}
if (blockingWindow == null) {
return flashAnyBlockerInner(doFlash)
}
if (doFlash) {
blockingWindow.flash()
}
return true
}
@JvmOverloads
fun setDockMargin(left: Float = 0f, top: Float = 0f, right: Float = 0f, bottom: Float = 0f) {
dockMargin = DockProperty(left, top, right, bottom)
@ -497,8 +602,9 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
clearDepth(poseStack, absoluteX, absoluteY, width, height)
poseStack.pushPose()
poseStack.translate(absoluteX.toDouble(), absoluteY.toDouble(), 10.0)
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
RenderSystem.setShaderColor(1f, 1f, 1f, if (isFlashFrameRecursive) 0.5f else 1f)
innerRender(poseStack, mouseX, mouseY, partialTick)
RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
poseStack.popPose()
}
@ -1090,6 +1196,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
final override fun mouseClicked(x: Double, y: Double, button: Int): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (flashAnyBlocker()) {
return true
}
if (grabMouseInput) return mouseClickedInner(x, y, button)
for (child in children) {
@ -1138,6 +1248,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
final override fun mouseReleased(x: Double, y: Double, button: Int): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (flashAnyBlocker(false)) {
return true
}
if (grabMouseInput) return mouseReleasedInner(x, y, button)
for (child in children) {
@ -1178,6 +1292,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
final override fun mouseDragged(x: Double, y: Double, button: Int, xDelta: Double, yDelta: Double): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (flashAnyBlocker(false)) {
return true
}
if (grabMouseInput) return mouseDraggedInner(x, y, button, xDelta, yDelta)
for (child in children) {
@ -1219,6 +1337,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
final override fun mouseScrolled(x: Double, y: Double, scroll: Double): Boolean {
if (!isVisible() || !acceptMouseInput) return false
if (flashAnyBlocker(true)) {
return true
}
if (grabMouseInput) return mouseScrolledInner(x, y, scroll)
for (child in children) {
@ -1260,6 +1382,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
if (!isVisible() || !acceptKeyboardInput) return false
if (!focusedAsParent) return false
if (flashAnyBlocker(true)) {
return true
}
if (isFocused) return keyPressedInternal(key, scancode, mods)
for (child in children) {
@ -1275,10 +1401,14 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
return false
}
final override fun keyReleased(key: Int, scancode: Int, mods: Int): Boolean {
final override fun keyReleased(key: Int, scancode: Int, mods: Int): Boolean {
if (!isVisible() || !acceptKeyboardInput) return false
if (!focusedAsParent) return false
if (flashAnyBlocker(false)) {
return true
}
if (isFocused) return keyReleasedInternal(key, scancode, mods)
for (child in children) {
@ -1298,6 +1428,10 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
if (!isVisible() || !acceptKeyboardInput) return false
if (!focusedAsParent) return false
if (flashAnyBlocker()) {
return true
}
if (isFocused) return charTypedInternal(codepoint, mods)
for (child in children) {
@ -1387,4 +1521,12 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
* See [ru.dbotthepony.mc.otm.client.render.clearDepth]
*/
fun clearDepth(stack: PoseStack, x: Float = 0f, y: Float = 0f, width: Float = this.width, height: Float = this.height) = ru.dbotthepony.mc.otm.client.render.clearDepth(stack, x, y, width, height)
fun queryUser(title: Component, text: Component, onConfirm: Runnable, onCancel: Runnable? = null): QueryUserPanel<S> {
return QueryUserPanel(screen, title, listOf(text), onConfirm, onCancel).also { blockingWindow = it }
}
fun queryUser(title: Component, text: Collection<Component>, onConfirm: Runnable, onCancel: Runnable? = null): QueryUserPanel<S> {
return QueryUserPanel(screen, title, text, onConfirm, onCancel).also { blockingWindow = it }
}
}

View File

@ -0,0 +1,67 @@
package ru.dbotthepony.mc.otm.client.screen.panels
import net.minecraft.client.gui.screens.Screen
import net.minecraft.network.chat.Component
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen
import ru.dbotthepony.mc.otm.core.TranslatableComponent
open class QueryUserPanel<out S: Screen>(
screen: S,
title: Component,
description: Collection<Component>,
protected val onConfirm: Runnable?,
protected val onCancel: Runnable? = null,
) : FramePanel<S>(screen, 100f, 10f, title) {
protected val description: MutableList<Label<@UnsafeVariance S>> = ArrayList()
init {
if (screen is MatteryScreen<*>) {
screen.addPanel(this as EditablePanel<MatteryScreen<*>>)
}
dockPadding = dockPadding.copy(top = PADDING_TOP + 4f)
var maxWidth = font.width(title) + PADDING * 2f
var height = 0f
for (line in description) {
Label(screen, this, text = line).also {
it.dock = Dock.TOP
height += it.height
this.description.add(it)
}
maxWidth = maxWidth.coerceAtLeast(font.width(line).toFloat())
}
val bottom = EditablePanel(screen, this, height = ButtonPanel.HEIGHT)
bottom.dock = Dock.BOTTOM
this.height = height + bottom.height + PADDING + PADDING_TOP + 4f
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.cancel")) + 12f, label = TranslatableComponent("otm.gui.cancel")).also {
it.bind {
onCancel?.run()
this.remove()
}
it.dock = Dock.RIGHT
}
if (onConfirm != null) {
ButtonPanel(screen, bottom, width = font.width(TranslatableComponent("otm.gui.confirm")) + 12f, label = TranslatableComponent("otm.gui.confirm")).also {
it.bind {
onConfirm.run()
this.remove()
}
it.dock = Dock.RIGHT
it.dockRight = 2f
}
}
this.width = maxWidth.coerceAtLeast(bottom.childrenView.stream().mapToDouble { it.width.toDouble() }.sum().toFloat() + 2f) + PADDING * 2f
toScreenCenter()
}
}