Attempting to research something that will block other research now requires confirmation
This commit is contained in:
parent
5e95a97704
commit
672441021d
@ -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")
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
}
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user