"Low power" HUD element

This commit is contained in:
DBotThePony 2024-11-03 12:21:12 +07:00
parent 604999ebe3
commit 56e2e70a5c
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 169 additions and 7 deletions

View File

@ -134,6 +134,14 @@ private fun sounds(provider: MatteryLanguageProvider) {
private fun misc(provider: MatteryLanguageProvider) {
with(provider.english) {
misc("pwr_alert1", "[%s]")
misc("pwr_alert2", "PWR: ALERT")
misc("pwr_alert3", "WARNING ERROR:")
misc("pwr_alert4", "system_crash_log")
// Error 06E has occurred at 0027F:C0082E2270273 in VXE VMMXDE
// Error <Code> has occurred at <Server Block>:<RAM Address> in <Register?>
misc("pwr_alert5", "Error %s has occurred at %s:%s in %s")
gui("double_processing", "Processes two items at once")
misc("painted.black", "Painted Black")

View File

@ -146,6 +146,10 @@ private fun sounds(provider: MatteryLanguageProvider) {
private fun misc(provider: MatteryLanguageProvider) {
with(provider.russian) {
misc("pwr_alert2", "ПТН: ВНИМАНИЕ")
misc("pwr_alert3", "ПРЕДУПРЕЖДЕНИЕ ОБ ОШИБКЕ:")
misc("pwr_alert5", "Ошибка %s была обнаружена по адресу %s:%s в %s")
gui("double_processing", "Обрабатывает два предмета одновременно")
misc("painted.black", "Окрашено в чёрный")

View File

@ -1,6 +1,8 @@
package ru.dbotthepony.mc.otm.client
import com.google.common.collect.ImmutableList
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.Font
import net.minecraft.client.gui.Gui
import net.minecraft.client.gui.GuiGraphics
@ -9,7 +11,6 @@ import net.minecraft.client.gui.screens.DeathScreen
import net.minecraft.client.gui.screens.InBedChatScreen
import net.minecraft.client.player.LocalPlayer
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.effect.MobEffects
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
@ -20,11 +21,9 @@ import net.neoforged.neoforge.client.event.RenderGuiLayerEvent
import net.neoforged.neoforge.client.event.ScreenEvent
import net.neoforged.neoforge.client.gui.VanillaGuiLayers
import net.neoforged.neoforge.common.ItemAbilities
import net.neoforged.neoforge.common.ItemAbility
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.android.feature.NanobotsArmorFeature
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.MatteryPlayer
import ru.dbotthepony.mc.otm.capability.matteryPlayer
import ru.dbotthepony.mc.otm.client.render.*
@ -34,6 +33,8 @@ import ru.dbotthepony.mc.otm.config.ClientConfig
import ru.dbotthepony.mc.otm.core.TextComponent
import ru.dbotthepony.kommons.math.RGBAColor
import ru.dbotthepony.mc.otm.core.ResourceLocation
import ru.dbotthepony.mc.otm.core.math.Decimal
import ru.dbotthepony.mc.otm.core.random
import ru.dbotthepony.mc.otm.core.util.formatPower
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import java.util.*
@ -118,10 +119,6 @@ object MatteryGUI {
val deathLog = ArrayList<Pair<Int, Component>>()
private fun showIteration(event: RenderGuiEvent.Post) {
if (minecraft.player?.matteryPlayer?.isAndroid != true) {
return
}
val time = System.currentTimeMillis()
if (time > showIterationUntilFade) {
@ -190,8 +187,129 @@ object MatteryGUI {
popScissorRect()
}
private val powerAlert = TranslatableComponent(
"otm.pwr_alert1",
TranslatableComponent("otm.pwr_alert2").withStyle(ChatFormatting.RED)
).withStyle(ChatFormatting.YELLOW)
private val powerAlert2 = TranslatableComponent("otm.pwr_alert3").withStyle(ChatFormatting.YELLOW)
private val powerAlert3 = TranslatableComponent("otm.pwr_alert4").withStyle(ChatFormatting.YELLOW)
private val errorCodes = ImmutableList.of(
"005", "06E", "004", "0F1", "7FF", "F0A"
)
private var errorCode = errorCodes[1]
private var errorAddress = "0".repeat(16)
private val registerParts = ImmutableList.of("A", "B", "C", "D", "E", "F", "M", "D", "X", "Y", "Z")
private var errorRegister = "VXE VMMXDE"
private val errorServerNode by lazy {
(minecraft.player!!.uuid.leastSignificantBits and 0xFFFFFF).toString(16).uppercase()
}
private var displayPowerError = false
private var lastDisplayPowerErrorUpdate = System.nanoTime()
private var targetErrorAlpha = System.nanoTime()
private fun drawLowPower(event: RenderGuiEvent.Post, player: LocalPlayer) {
// yes, this is a reference to movie Transcendence (2014)
if (player.matteryPlayer.androidEnergy.batteryLevel > Decimal.TEN)
return
if (System.nanoTime() - lastDisplayPowerErrorUpdate > 100_000_000L) {
lastDisplayPowerErrorUpdate = System.nanoTime()
val newStatus = player.random.nextBoolean()
if (newStatus != displayPowerError && newStatus) {
targetErrorAlpha = System.nanoTime()
errorCode = errorCodes[player.random.nextInt(errorCodes.size)]
errorRegister = "V${registerParts.random(player.random)}${registerParts.random(player.random)} V${registerParts.random(player.random)}${registerParts.random(player.random)}${registerParts.random(player.random)}${registerParts.random(player.random)}${registerParts.random(player.random)}"
errorAddress = java.lang.Long.toUnsignedString(player.random.nextLong(), 16).uppercase()
if (errorAddress.length < 16) {
errorAddress = "0".repeat(16 - errorAddress.length) + errorAddress
}
}
displayPowerError = newStatus
}
if (!displayPowerError) return
val alpha: Float
val diff = System.nanoTime() - targetErrorAlpha
if (diff > 50_000_000L) {
alpha = 1f
} else {
alpha = diff / 50_000_000f
}
if (alpha != 1f) RenderSystem.setShaderColor(1f, 1f, 1f, alpha)
val window = minecraft.window
val x = window.guiScaledWidth / 2f
var y = window.guiScaledHeight / 2.5f
minecraft.font.draw(
event.guiGraphics.pose(),
powerAlert,
x, y,
scale = 4f,
gravity = RenderGravity.CENTER_CENTER,
drawShadow = true
)
y += 20f + minecraft.font.lineHeight * 4f
minecraft.font.draw(
event.guiGraphics.pose(),
powerAlert2,
x, y,
gravity = RenderGravity.CENTER_CENTER,
drawShadow = true
)
y += minecraft.font.lineHeight + 2f
minecraft.font.draw(
event.guiGraphics.pose(),
powerAlert3,
x, y,
gravity = RenderGravity.CENTER_CENTER,
drawShadow = true
)
y += minecraft.font.lineHeight * 2f + 4f
minecraft.font.draw(
event.guiGraphics.pose(),
TranslatableComponent(
"otm.pwr_alert5",
errorCode,
errorServerNode,
errorAddress,
errorRegister
).withStyle(ChatFormatting.YELLOW),
x, y,
gravity = RenderGravity.CENTER_CENTER,
drawShadow = true,
)
if (alpha != 1f) RenderSystem.setShaderColor(1f, 1f, 1f, 1f)
}
fun onRenderGuiEvent(event: RenderGuiEvent.Post) {
val player = minecraft.player ?: return
if (!player.matteryPlayer.isAndroid) {
return
}
showIteration(event)
drawLowPower(event, player)
}
private fun renderFoodAndAir(event: RenderGuiLayerEvent.Pre, gui: Gui) {

View File

@ -28,6 +28,7 @@ import net.minecraft.network.chat.contents.TranslatableContents
import net.minecraft.resources.ResourceKey
import net.minecraft.resources.ResourceLocation
import net.minecraft.tags.TagKey
import net.minecraft.util.RandomSource
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
@ -63,6 +64,7 @@ import java.util.function.Supplier
import java.util.random.RandomGenerator
import java.util.stream.Stream
import java.util.stream.StreamSupport
import kotlin.NoSuchElementException
import kotlin.jvm.optionals.getOrNull
import kotlin.reflect.KProperty
@ -178,6 +180,36 @@ fun <T> MutableList<T>.shuffle(random: RandomGenerator) {
}
}
fun IntArray.shuffle(random: RandomSource) {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
}
fun <T> MutableList<T>.shuffle(random: RandomSource) {
for (i in lastIndex downTo 1) {
val j = random.nextInt(i + 1)
val copy = this[i]
this[i] = this[j]
this[j] = copy
}
}
fun <T> List<T>.random(random: RandomGenerator): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
fun <T> List<T>.random(random: RandomSource): T {
if (isEmpty())
throw NoSuchElementException("This list is empty")
return get(random.nextInt(size))
}
inline fun <T : Any> immutableList(size: Int, initializer: (index: Int) -> T): ImmutableList<T> {
require(size >= 0) { "Invalid list size $size" }