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")
.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 {
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.gui.overlay.ForgeGui
import net.minecraftforge.client.gui.overlay.GuiOverlayManager
import ru.dbotthepony.mc.otm.ClientConfig
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.MatteryCapability
@ -30,13 +31,23 @@ import java.util.*
import kotlin.math.ceil
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_BG = BARS.subElement(y = 9f, height = 9f)
val CHARGE_HUNGER = BARS.subElement(y = 18f, 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 originalBedButtonY = -1
@ -99,6 +110,10 @@ object MatteryGUI {
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "air_level"))
}
private val PLAYER_HEALTH_ELEMENT by lazy {
GuiOverlayManager.findOverlay(ResourceLocation("minecraft", "player_health"))
}
var iteration = 0
var showIterationUntil = 0L
var showIterationUntilFade = 0L
@ -177,7 +192,7 @@ object MatteryGUI {
showIteration(event)
}
fun onLayerRenderEvent(event: RenderGuiOverlayEvent.Pre) {
private fun renderFoodAndAir(event: RenderGuiOverlayEvent.Pre) {
if (event.overlay != FOOD_LEVEL_ELEMENT && event.overlay != AIR_LEVEL_ELEMENT) {
return
}
@ -208,6 +223,8 @@ object MatteryGUI {
return
}
if (!gui.shouldDrawSurvivalElements()) return
var level: Float
if (mattery.androidEnergy.maxBatteryLevel.isZero) {
@ -228,14 +245,14 @@ object MatteryGUI {
val top: Int = height - gui.rightHeight
gui.rightHeight += 10
val leftPadding = ceil(level * 79f - 0.5f)
val leftPadding = ceil(level * 80f - 0.5f)
if (ply.hasEffect(MobEffects.HUNGER)) {
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 {
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()
@ -249,4 +266,87 @@ object MatteryGUI {
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