android health bar + 1px wider energy bar

This commit is contained in:
YuRaNnNzZZ 2023-03-12 20:16:18 +03:00
parent 006cbc75e3
commit cbaf89d4a7
Signed by: YuRaNnNzZZ
GPG Key ID: 5F71738C85A6006D
4 changed files with 109 additions and 5 deletions

View File

@ -22,6 +22,10 @@ object ClientConfig {
.comment("Allow to scroll Exopack inventory in non OTM inventories when hovering just over inventory slots, not only scrollbar") .comment("Allow to scroll Exopack inventory in non OTM inventories when hovering just over inventory slots, not only scrollbar")
.define("exopackFreeScroll", true) .define("exopackFreeScroll", true)
var ANDROID_HEALTH_HUD: Boolean by specBuilder
.comment("Replace hearts with health bar on HUD when you are an android")
.define("ANDROID_HEALTH_HUD", true)
init { init {
spec = specBuilder.build() spec = specBuilder.build()
} }

View File

@ -17,6 +17,7 @@ import net.minecraftforge.client.event.RenderLevelStageEvent
import net.minecraftforge.client.event.ScreenEvent import net.minecraftforge.client.event.ScreenEvent
import net.minecraftforge.client.gui.overlay.ForgeGui import net.minecraftforge.client.gui.overlay.ForgeGui
import net.minecraftforge.client.gui.overlay.GuiOverlayManager import net.minecraftforge.client.gui.overlay.GuiOverlayManager
import ru.dbotthepony.mc.otm.ClientConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.MatteryCapability import ru.dbotthepony.mc.otm.capability.MatteryCapability
@ -30,13 +31,23 @@ import java.util.*
import kotlin.math.ceil import kotlin.math.ceil
object MatteryGUI { object MatteryGUI {
private val BARS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars"), 80f, 36f) private val BARS = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars"), 81f, 36f)
val CHARGE = BARS.subElement(height = 9f) val CHARGE = BARS.subElement(height = 9f)
val CHARGE_BG = BARS.subElement(y = 9f, height = 9f) val CHARGE_BG = BARS.subElement(y = 9f, height = 9f)
val CHARGE_HUNGER = BARS.subElement(y = 18f, height = 9f) val CHARGE_HUNGER = BARS.subElement(y = 18f, height = 9f)
val CHARGE_HUNGER_BG = BARS.subElement(y = 27f, height = 9f) val CHARGE_HUNGER_BG = BARS.subElement(y = 27f, height = 9f)
private val BARS_HP = AtlasSkinElement(ResourceLocation(OverdriveThatMatters.MOD_ID, "player_bars_health"), 81f, 54f)
val HEALTH = BARS_HP.subElement(height = 9f)
val HEALTH_BG = BARS_HP.subElement(y = 9f, height = 9f)
val HEALTH_POISON = BARS_HP.subElement(y = 18f, height = 9f)
val HEALTH_WITHER = BARS_HP.subElement(y = 27f, height = 9f)
val HEALTH_ABSORB = BARS_HP.subElement(y = 36f, height = 9f)
val HEALTH_FROZEN = BARS_HP.subElement(y = 45f, height = 9f)
private var originalBedButtonX = -1 private var originalBedButtonX = -1
private var originalBedButtonY = -1 private var originalBedButtonY = -1
@ -99,6 +110,10 @@ object MatteryGUI {
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level")) GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level"))
} }
private val PLAYER_HEALTH_ELEMENT by lazy {
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "player_health"))
}
var iteration = 0 var iteration = 0
var showIterationUntil = 0L var showIterationUntil = 0L
var showIterationUntilFade = 0L var showIterationUntilFade = 0L
@ -177,7 +192,7 @@ object MatteryGUI {
showIteration(event) showIteration(event)
} }
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) { private fun renderFoodAndAir(event: RenderGuiOverlayEvent.Pre) {
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) { if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
return return
} }
@ -208,6 +223,8 @@ object MatteryGUI {
return return
} }
if (!gui.shouldDrawSurvivalElements()) return
var level: Float var level: Float
if (mattery.androidEnergy.maxBatteryLevel.isZero) { if (mattery.androidEnergy.maxBatteryLevel.isZero) {
@ -228,14 +245,14 @@ object MatteryGUI {
val top: Int = height - gui.rightHeight val top: Int = height - gui.rightHeight
gui.rightHeight += 10 gui.rightHeight += 10
val leftPadding = ceil(level * 79f - 0.5f) val leftPadding = ceil(level * 80f - 0.5f)
if (ply.hasEffect(MobEffects.HUNGER)) { if (ply.hasEffect(MobEffects.HUNGER)) {
CHARGE_HUNGER_BG.render(event.poseStack, left.toFloat(), top.toFloat()) CHARGE_HUNGER_BG.render(event.poseStack, left.toFloat(), top.toFloat())
CHARGE_HUNGER.renderPartial(event.poseStack, left.toFloat() - leftPadding + 79f, top.toFloat(), width = leftPadding) CHARGE_HUNGER.renderPartial(event.poseStack, left.toFloat() - leftPadding + 80f, top.toFloat(), width = leftPadding)
} else { } else {
CHARGE_BG.render(event.poseStack, left.toFloat(), top.toFloat()) CHARGE_BG.render(event.poseStack, left.toFloat(), top.toFloat())
CHARGE.renderPartial(event.poseStack, left.toFloat() - leftPadding + 79f, top.toFloat(), width = leftPadding) CHARGE.renderPartial(event.poseStack, left.toFloat() - leftPadding + 80f, top.toFloat(), width = leftPadding)
} }
val formattedPower = mattery.androidEnergy.batteryLevel.formatPower() val formattedPower = mattery.androidEnergy.batteryLevel.formatPower()
@ -249,4 +266,87 @@ object MatteryGUI {
event.poseStack.popPose() event.poseStack.popPose()
} }
} }
private fun getSpriteForPlayer(player: Player): SubSkinElement {
if (player.hasEffect(MobEffects.POISON)) {
return HEALTH_POISON
} else if (player.hasEffect(MobEffects.WITHER)) {
return HEALTH_WITHER
} else if (player.isFullyFrozen()) {
return HEALTH_FROZEN
}
return HEALTH
}
private fun getHealthColorForPlayer(player: Player): Int {
if (player.hasEffect(MobEffects.POISON)) {
return RGBAColor.DARK_GREEN.toInt()
} else if (player.hasEffect(MobEffects.WITHER)) {
return RGBAColor.WHITE.toInt()
} else if (player.isFullyFrozen()) {
return RGBAColor.AQUA.toInt()
}
return RGBAColor.RED.toInt()
} // можно вынести в конфиг, но для этого нужен селектор цвета
private fun renderPlayerHealth(event: RenderGuiOverlayEvent.Pre) {
if (!ClientConfig.ANDROID_HEALTH_HUD) return
val ply: LocalPlayer = minecraft.player ?: return
var mattery = ply.matteryPlayer
if (!ply.isAlive && mattery == null) {
mattery = lastState
}
val gui = minecraft.gui as? ForgeGui ?: return
if (mattery != null && mattery.isAndroid) {
event.isCanceled = true
lastState = mattery
if (!gui.shouldDrawSurvivalElements()) return
val level: Float = (ply.health / ply.maxHealth).coerceIn(0.0f, 1.0f)
val levelAbsorb: Float = (ply.absorptionAmount / ply.maxHealth).coerceIn(0.0f, 1.0f)
gui.setupOverlayRenderState(true, false)
RenderSystem.setShaderColor(1.0f, 1.0f, 1.0f, 1.0f)
val width = event.window.guiScaledWidth
val height = event.window.guiScaledHeight
val left = width / 2 - 10 - 81
val top: Int = height - gui.leftHeight
gui.leftHeight += 10
HEALTH_BG.render(event.poseStack, left.toFloat(), top.toFloat())
getSpriteForPlayer(ply).renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(level * 80f - 0.5f))
if (levelAbsorb > 0) {
HEALTH_ABSORB.renderPartial(event.poseStack, left.toFloat(), top.toFloat(), width = ceil(levelAbsorb * 80f - 0.5f))
}
var formattedHealth = "%d/%d".format(ply.health.toInt(), ply.maxHealth.toInt())
if (ply.absorptionAmount > 0)
formattedHealth = "%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt())
event.poseStack.pushPose()
event.poseStack.scale(0.5f, 0.5f, 0.5f)
minecraft.font.drawAligned(event.poseStack, formattedHealth, TextAlign.CENTER_RIGHT, (left - 1f) * 2f, (top + 5.5f) * 2f, RGBAColor.BLACK.toInt())
minecraft.font.drawAligned(event.poseStack, formattedHealth, TextAlign.CENTER_RIGHT, (left - 2f) * 2f, (top + 4.5f) * 2f, getHealthColorForPlayer(ply))
event.poseStack.popPose()
}
}
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
if (event.overlay == FOOD_LEVEL_ELEMENT || event.overlay == AIR_LEVEL_ELEMENT) {
renderFoodAndAir(event)
} else if (event.overlay == PLAYER_HEALTH_ELEMENT) {
renderPlayerHealth(event)
}
}
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 B